1 --- LuCI IP calculation and netlink access library.
5 Construct a new luci.ip.cidr instance and autodetect the address family.
6 Throws an error if the given strings do not represent a valid address or
7 if the given optional netmask is of a different family.
11 @param address String containing a valid IPv4 or IPv6 address, optionally
12 with prefix size (CIDR notation) or netmask separated by slash.
13 @param netmask String containing a valid IPv4 or IPv6 netmask or number
14 containing a prefix size in bits (`0..32` for IPv4,
15 `0..128` for IPv6). Overrides mask embedded in the first argument
16 if specified. (optional)
17 @return A `luci.ip.cidr` object representing the given
19 @usage `addr = luci.ip.new("10.24.0.1/24")
20 addr = luci.ip.new("10.24.0.1/255.255.255.0")
21 addr = luci.ip.new("10.24.0.1", "255.255.255.0") -- separate netmask
22 addr = luci.ip.new("10.24.0.1/24", 16) -- override netmask
24 addr6 = luci.ip.new("fe80::221:63ff:fe75:aa17/64")
25 addr6 = luci.ip.new("fe80::221:63ff:fe75:aa17/ffff:ffff:ffff:ffff::")
26 addr6 = luci.ip.new("fe80::221:63ff:fe75:aa17", "ffff:ffff:ffff:ffff::")
27 addr6 = luci.ip.new("fe80::221:63ff:fe75:aa17/64", 128) -- override netmask`
34 Construct a new IPv4 luci.ip.cidr instance.
35 Throws an error if the given string does not represent a valid IPv4 address or
36 if the given optional netmask is of a different family.
40 @param address String containing a valid IPv4, optionally with prefix size
41 (CIDR notation) or netmask separated by slash.
42 @param netmask String containing a valid IPv4 netmask or number
43 containing a prefix size between `0` and `32` bit.
44 Overrides mask embedded in the first argument if specified. (optional)
45 @return A `luci.ip.cidr` object representing the given IPv4 range.
46 @usage `addr = luci.ip.IPv4("10.24.0.1/24")
47 addr = luci.ip.IPv4("10.24.0.1/255.255.255.0")
48 addr = luci.ip.IPv4("10.24.0.1", "255.255.255.0") -- separate netmask
49 addr = luci.ip.IPv4("10.24.0.1/24", 16) -- override netmask`
55 Construct a new IPv6 luci.ip.cidr instance.
56 Throws an error if the given string does not represent a valid IPv6 address or
57 if the given optional netmask is of a different family.
61 @param address String containing a valid IPv6, optionally with prefix size
62 (CIDR notation) or netmask separated by slash.
63 @param netmask String containing a valid IPv4 netmask or number
64 containing a prefix size between `0` and `128` bit.
65 Overrides mask embedded in the first argument if specified. (optional)
66 @return A `luci.ip.cidr` object representing the given IPv6 range.
67 @usage `addr6 = luci.ip.IPv6("fe80::221:63ff:fe75:aa17/64")
68 addr6 = luci.ip.IPv6("fe80::221:63ff:fe75:aa17/ffff:ffff:ffff:ffff::")
69 addr6 = luci.ip.IPv6("fe80::221:63ff:fe75:aa17", "ffff:ffff:ffff:ffff::")
70 addr6 = luci.ip.IPv6("fe80::221:63ff:fe75:aa17/64", 128) -- override netmask`
76 Construct a new MAC luci.ip.cidr instance.
77 Throws an error if the given string does not represent a valid ethernet MAC
78 address or if the given optional mask is of a different family.
82 @param address String containing a valid ethernet MAC address, optionally with
83 prefix size (CIDR notation) or mask separated by slash.
84 @param netmask String containing a valid MAC address mask or number
85 containing a prefix size between `0` and `48` bit.
86 Overrides mask embedded in the first argument if specified. (optional)
87 @return A `luci.ip.cidr` object representing the given MAC address range.
88 @usage `intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/24")
89 intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/FF:FF:FF:0:0:0")
90 intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00", "FF:FF:FF:0:0:0")
91 intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/24", 48) -- override mask`
97 Verify an IPv4 address.
99 Checks whether given argument is a preexisting luci.ip.cidr IPv4 address
100 instance or a string literal convertible to an IPv4 address and returns a
101 plain Lua string containing the canonical representation of the address.
103 If the argument is not a valid address, returns nothing. This function is
104 intended to aid in safely verifying address literals without having to deal
109 @param address String containing a valid IPv4 address or existing
110 luci.ip.cidr IPv4 instance.
111 @return A string representing the given IPv4 address.
112 @usage `ipv4 = luci.ip.checkip4(luci.ip.new("127.0.0.1")) -- "127.0.0.1"
113 ipv4 = luci.ip.checkip4("127.0.0.1") -- "127.0.0.1"
114 ipv4 = luci.ip.checkip4("nonesense") -- nothing
115 ipv4 = luci.ip.checkip4(123) -- nothing
116 ipv4 = luci.ip.checkip4(nil) -- nothing
117 ipv4 = luci.ip.checkip4() -- nothing`
123 Verify an IPv6 address.
125 Checks whether given argument is a preexisting luci.ip.cidr IPv6 address
126 instance or a string literal convertible to an IPv6 address and returns a
127 plain Lua string containing the canonical representation of the address.
129 If the argument is not a valid address, returns nothing. This function is
130 intended to aid in safely verifying address literals without having to deal
135 @param address String containing a valid IPv6 address or existing
136 luci.ip.cidr IPv6 instance.
137 @return A string representing the given IPv6 address.
138 @usage `ipv6 = luci.ip.checkip6(luci.ip.new("0:0:0:0:0:0:0:1")) -- "::1"
139 ipv6 = luci.ip.checkip6("0:0:0:0:0:0:0:1") -- "::1"
140 ipv6 = luci.ip.checkip6("nonesense") -- nothing
141 ipv6 = luci.ip.checkip6(123) -- nothing
142 ipv6 = luci.ip.checkip6(nil) -- nothing
143 ipv6 = luci.ip.checkip6() -- nothing`
149 Verify an ethernet MAC address.
151 Checks whether given argument is a preexisting luci.ip.cidr MAC address
152 instance or a string literal convertible to an ethernet MAC and returns a
153 plain Lua string containing the canonical representation of the address.
155 If the argument is not a valid address, returns nothing. This function is
156 intended to aid in safely verifying address literals without having to deal
161 @param address String containing a valid MAC address or existing luci.ip.cidr
162 MAC address instance.
163 @return A string representing the given MAC address.
164 @usage `mac = luci.ip.checkmac(luci.ip.new("00-11-22-cc-dd-ee")) -- "00:11:22:CC:DD:EE"
165 mac = luci.ip.checkmac("00:11:22:cc:dd:ee") -- "00:11:22:CC:DD:EE"
166 mac = luci.ip.checkmac("nonesense") -- nothing
167 mac = luci.ip.checkmac(123) -- nothing
168 mac = luci.ip.checkmac(nil) -- nothing
169 mac = luci.ip.checkmac() -- nothing`
175 Determine the route leading to the given destination.
179 @param address A `luci.ip.cidr` instance or a string containing
180 a valid IPv4 or IPv6 range as specified by `luci.ip.new()`.
181 @param source A `luci.ip.cidr` instance or a string containing
182 the preferred source address for route selection (optional).
183 @return <p>Table containing the fields described below.</p>
184 <table id="routetable">
185 <tr><th>Field</th><th>Description</th></tr>
187 <p>Route type with one of the following numeric values:</p>
191 <td>`RTN_UNICAST` - Gateway or direct route</td>
195 <td>`RTN_LOCAL` - Accept locally</td>
199 <td>`RTN_BROADCAST` -
200 Accept locally as broadcast send as broadcast</td>
205 Accept locally as broadcast but send as unicast</td>
209 <td>`RTN_MULTICAST` - Multicast route</td>
215 <td>Number containing the route family, `4` for IPv4 or
220 <td>Destination `luci.ip.cidr` instance</td>
224 <td>Gateway `luci.ip.cidr` instance (optional)</td>
228 <td>Source address `luci.ip.cidr` instance (optional)</td>
232 <td>Preferred source `luci.ip.cidr` instance (optional)</td>
236 <td>String containing the name of the outgoing interface</td>
240 <td>String containing the name of the incoming interface (optional)</td>
244 <td>Number of the associated routing table (`0..65535`)</td>
248 <td>Number of the associated routing protocol</td>
252 <td>Number describing the scope of the route, most commonly
253 `0` for global or `253` for on-link</td>
257 <td>Number describing the route metric (optional)</td>
261 <td>Number of seconds the prefix is valid (IPv6 only, optional)</td>
265 <td>Route destination error code (optional)</td>
269 <li>Find default gateway by getting route to Google's public NS server
270 `rt = luci.ip.route("8.8.8.8")
272 print("gateway is", rt.gw)
274 <li>Determine IPv6 upstream interface `rt = luci.ip.route("2001::/7")
276 print("ipv6 upstream device is", rt.dev)
283 Fetch all routes, optionally matching the given criteria.
287 @param filter <p>Table containing one or more of the possible filter
288 criteria described below (optional)</p><table>
289 <tr><th>Field</th><th>Description</th></tr>
290 <tr><td>`family`</td><td>
291 Number describing the address family to return - `4` selects
292 IPv4 routes, `6` IPv6 ones. Any other value selects both.
294 <tr><td>`iif`</td><td>
295 String containing the incoming route interface to match.
297 <tr><td>`oif`</td><td>
298 String containing the outgoing route interface to match.
300 <tr><td>`type`</td><td>
301 Numeric type to match, e.g. `1` for unicast.
303 <tr><td>`scope`</td><td>
304 Numeric scope to match, e.g. `253` for onlink.
306 <tr><td>`proto`</td><td>
307 Numeric protocol to match, e.g. `2` for boot.
309 <tr><td>`table`</td><td>
310 Numeric routing table to match (`0..65535`).
312 <tr><td>`gw`</td><td>
313 String containing the gateway address to match. Can be in any notation
314 specified by `luci.ip.new()`. Prefix matching is performed when
315 comparing the routes, e.g. "192.168.1.0/24" would select routes with gateway
316 addresses `192.168.1.1 .. 192.168.1.255`.
318 <tr><td>`dest`</td><td>
319 String containing the destination to match. Prefix matching is performed.
321 <tr><td>`from`</td><td>
322 String containing the source address to match. Prefix matching is performed.
324 <tr><td>`src`</td><td>
325 String containing the preferred source address to match.
326 Prefix matching is performed.
328 <tr><td>`dest_exact`</td><td>
329 String containing the destination to match. Exact matching is performed,
330 e.g. `dest = "0.0.0.0/0"` would match <em>any</em> IPv4 route
331 while `dest_exact = "0.0.0.0/0"` will <em>only</em> match the
334 <tr><td>`from_exact`</td><td>
335 String containing the source address to match. Exact matching is performed.
338 @param callback <p>Callback function to invoke for each found route
339 instead of returning one table of route objects (optional)</p>
340 @return If no callback function is provided, a table of routes
341 <a href="#routetable">as specified by `luci.ip.route()`</a>
342 is returned. If a callback function is given, it is invoked for each route
343 and nothing is returned.
346 <li>Find all IPv4 default routes:
347 `luci.ip.routes({ dest_exact = "0.0.0.0/0" }, function(rt)
348 print(rt.type, rt.gw, rt.dev)
350 <li>Find all global IPv6 prefixes on the current system:
351 `luci.ip.routes({ from = "2001::/7" }, function(rt)
354 <li>Fetch all IPv4 routes:
355 `routes = luci.ip.routes({ family = 4 })
356 for _, rt in ipairs(routes) do
357 print(rt.dest, rt.gw, rt.dev)
363 Fetches entries from the IPv4 ARP and IPv6 neighbour kernel table
367 @param filter <p>Table containing one or more of the possible filter
368 criteria described below (optional)</p><table>
369 <tr><th>Field</th><th>Description</th></tr>
370 <tr><td>`family`</td><td>
371 Number describing the address family to return - `4` selects
372 IPv4 ARP, `6` select IPv6 neighbour entries. Any other value
375 <tr><td>`dev`</td><td>
376 String containing the associated interface to match.
378 <tr><td>`dest`</td><td>
379 String containing the associated address to match. Can be in any notation
380 specified by `luci.ip.new()`. Prefix matching is performed when
381 comparing the addresses, e.g. "192.168.1.0/24" would select ARP entries
382 for `192.168.1.1 .. 192.168.1.255`.
384 <tr><td>`mac`</td><td>
385 String containing MAC address to match.
388 @param callback <p>Callback function to invoke for each found neighbour
389 entry instead of returning one table of neighbour entries (optional)</p>
390 @return If no callback function is provided, a table of neighbour entries
391 is returned. If a callback function is given, it is invoked for each entry
392 and nothing is returned.
394 A neighbour entry is a table containing the following fields:
397 <tr><th>Field</th><th>Description</th></tr>
400 <td>Number containing the neighbour entry family, `4` for IPv4
401 ARP or `6` for IPv6 NDP</td>
405 <td>String containing the associated device of the neighbour entry</td>
409 <td>IP address `luci.ip.cidr` instance</td>
413 <td>MAC address `luci.ip.cidr` instance</td>
417 <td>Boolean "true" if the neighbour entry is a router (IPv6, optional)</td>
421 <td>Boolean "true" if this is a proxy entry (optional)</td>
424 <td>`incomplete`</td>
425 <td>Boolean "true" if the entry is in incomplete state (optional)</td>
429 <td>Boolean "true" if the entry is in reachable state (optional)</td>
433 <td>Boolean "true" if the entry is stale (optional)</td>
437 <td>Boolean "true" if the entry is delayed (optional)</td>
441 <td>Boolean "true" if the entry is in probe state (optional)</td>
445 <td>Boolean "true" if the entry is in failed state (optional)</td>
449 <td>Boolean "true" if the entry is not caused by NDP or
454 <td>Boolean "true" if the entry was statically configured from
455 userspace (optional)</td>
459 <li>Find all ARP neighbours in the LAN:
460 `luci.ip.neighbors({ dest = "192.168.0.0/16" }, function(n)
463 <li>Find all active IPv6 addresses of host with given MAC:
464 `luci.ip.neighbors({ family = 6, mac = "00:21:63:75:aa:17" },
472 Fetch basic device information
476 @param device String containing the network device to query
477 @return If the given interface is found, a table containing the fields
478 described below is returned, else an empty table.
481 <tr><th>Field</th><th>Description</th></tr>
484 <td>Boolean indicating whether the device is in IFF_RUNNING state</td>
488 <td>Numeric value indicating the type of the device, e.g. `1`
493 <td>String containing the name of the device</td>
497 <td>If queried device is a bridge port, string containing the name of
498 parent bridge device (optional)</td>
502 <td>Number containing the current MTU of the device</td>
506 <td>Number containing the TX queue length of the device</td>
510 <td>MAC address `luci.ip.cidr` instance representing the device ethernet
515 <li>Test whether device br-lan exists:
516 `print(luci.ip.link("br-lan").name ~= nil)
518 <li>Query MAC address of eth0:
519 `print(luci.ip.link("eth0").mac)
526 -- Represents an IPv4 or IPv6 address range.
528 module "luci.ip.cidr"
531 Checks whether the CIDR instance is an IPv4 address range
538 @return `true` if the CIDR is an IPv4 range, else `false`
542 Checks whether the CIDR instance is within the private RFC1918 address space
546 @name cidr.is4rfc1918
547 @return `true` if the entire range of this CIDR lies within one of
548 the ranges `10.0.0.0-10.255.255.255`,
549 `172.16.0.0-172.31.0.0` or
550 `192.168.0.0-192.168.255.255`, else `false`.
551 @usage `local addr = luci.ip.new("192.168.45.2/24")
552 if addr:is4rfc1918() then
553 print("Is a private address")
558 Checks whether the CIDR instance is an IPv4 link local (Zeroconf) address
562 @name cidr.is4linklocal
563 @return `true` if the entire range of this CIDR lies within the range
564 the range `169.254.0.0-169.254.255.255`, else `false`.
565 @usage `local addr = luci.ip.new("169.254.34.125")
566 if addr:is4linklocal() then
567 print("Is a zeroconf address")
572 Checks whether the CIDR instance is an IPv6 address range
579 @return `true` if the CIDR is an IPv6 range, else `false`
583 Checks whether the CIDR instance is an IPv6 link local address
587 @name cidr.is6linklocal
588 @return `true` if the entire range of this CIDR lies within the range
589 the `fe80::/10` range, else `false`.
590 @usage `local addr = luci.ip.new("fe92:53a:3216:af01:221:63ff:fe75:aa17/64")
591 if addr:is6linklocal() then
592 print("Is a linklocal address")
597 Checks whether the CIDR instance is an IPv6 mapped IPv4 address
601 @name cidr.is6mapped4
602 @return `true` if the address is an IPv6 mapped IPv4 address in the
603 form `::ffff:1.2.3.4`.
604 @usage `local addr = luci.ip.new("::ffff:192.168.1.1")
605 if addr:is6mapped4() then
606 print("Is a mapped IPv4 address")
611 Checks whether the CIDR instance is an ethernet MAC address range
618 @return `true` if the CIDR is a MAC address range, else `false`
622 Checks whether the CIDR instance is a locally administered (LAA) MAC address
626 @name cidr.ismaclocal
627 @return `true` if the MAC address sets the locally administered bit.
628 @usage `local mac = luci.ip.new("02:C0:FF:EE:00:01")
629 if mac:ismaclocal() then
630 print("Is an LAA MAC address")
635 Checks whether the CIDR instance is a multicast MAC address
639 @name cidr.ismacmcast
640 @return `true` if the MAC address sets the multicast bit.
641 @usage `local mac = luci.ip.new("01:00:5E:7F:00:10")
642 if addr:ismacmcast() then
643 print("Is a multicast MAC address")
648 Checks whether this CIDR instance is lower than the given argument.
649 The comparisation follows these rules:
650 <ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses
651 are considered lower than MAC addresses</li>
652 <li>Prefix sizes are ignored</li></ul>
657 @param addr A `luci.ip.cidr` instance or a string convertible by
658 `luci.ip.new()` to compare against.
659 @return `true` if this CIDR is lower than the given address,
661 @usage `local addr = luci.ip.new("192.168.1.1")
662 print(addr:lower(addr)) -- false
663 print(addr:lower("10.10.10.10/24")) -- false
664 print(addr:lower(luci.ip.new("::1"))) -- true
665 print(addr:lower(luci.ip.new("192.168.200.1"))) -- true
666 print(addr:lower(luci.ip.new("00:14:22:01:23:45"))) -- true`
672 Checks whether this CIDR instance is higher than the given argument.
673 The comparisation follows these rules:
674 <ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses
675 are considered lower than MAC addresses</li>
676 <li>Prefix sizes are ignored</li></ul>
681 @param addr A `luci.ip.cidr` instance or a string convertible by
682 `luci.ip.new()` to compare against.
683 @return `true` if this CIDR is higher than the given address,
685 @usage `local addr = luci.ip.new("192.168.1.1")
686 print(addr:higher(addr)) -- false
687 print(addr:higher("10.10.10.10/24")) -- true
688 print(addr:higher(luci.ip.new("::1"))) -- false
689 print(addr:higher(luci.ip.new("192.168.200.1"))) -- false
690 print(addr:higher(luci.ip.new("00:14:22:01:23:45"))) -- false`
696 Checks whether this CIDR instance is equal to the given argument.
701 @param addr A `luci.ip.cidr` instance or a string convertible by
702 `luci.ip.new()` to compare against.
703 @return `true` if this CIDR is equal to the given address,
705 @usage `local addr = luci.ip.new("192.168.1.1")
706 print(addr:equal(addr)) -- true
707 print(addr:equal("192.168.1.1")) -- true
708 print(addr:equal(luci.ip.new("::1"))) -- false
710 local addr6 = luci.ip.new("::1")
711 print(addr6:equal("0:0:0:0:0:0:0:1/64")) -- true
712 print(addr6:equal(luci.ip.new("fe80::221:63ff:fe75:aa17"))) -- false
714 local mac = luci.ip.new("00:14:22:01:23:45")
715 print(mac:equal("0:14:22:1:23:45")) -- true
716 print(mac:equal(luci.ip.new("01:23:45:67:89:AB")) -- false`
722 Get or set prefix size of CIDR instance.
723 If the optional mask parameter is given, the prefix size of this CIDR is altered
724 else the current prefix size is returned.
729 @param mask Either a number containing the number of bits (`0..32`
730 for IPv4, `0..128` for IPv6 or `0..48` for MAC addresses) or a string
731 containing a valid netmask (optional)
732 @return Bit count of the current prefix size
733 @usage `local range = luci.ip.new("192.168.1.1/255.255.255.0")
734 print(range:prefix()) -- 24
737 print(range:prefix()) -- 16
739 range:prefix("255.255.255.255")
740 print(range:prefix()) -- 32`
744 Derive network address of CIDR instance.
746 Returns a new CIDR instance representing the network address of this instance
747 with all host parts masked out. The used prefix size can be overridden by the
748 optional mask parameter.
753 @param mask Either a number containing the number of bits (`0..32`
754 for IPv4, `0..128` for IPv6 or `0..48` for MAC addresses) or a string
755 containing a valid netmask (optional)
756 @return CIDR instance representing the network address
757 @usage `local range = luci.ip.new("192.168.62.243/255.255.0.0")
758 print(range:network()) -- "192.168.0.0"
759 print(range:network(24)) -- "192.168.62.0"
760 print(range:network("255.255.255.0")) -- "192.168.62.0"
762 local range6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
763 print(range6:network()) -- "fd9b:62b3:9cc5::"`
767 Derive host address of CIDR instance.
769 This function essentially constructs a copy of this CIDR with the prefix size
770 set to `32` for IPv4, `128` for IPv6 or `48` for MAC addresses.
775 @return CIDR instance representing the host address
776 @usage `local range = luci.ip.new("172.19.37.45/16")
777 print(range) -- "172.19.37.45/16"
778 print(range:host()) -- "172.19.37.45"`
782 Derive netmask of CIDR instance.
784 Constructs a CIDR instance representing the netmask of this instance. The used
785 prefix size can be overridden by the optional mask parameter.
790 @param mask Either a number containing the number of bits (`0..32`
791 for IPv4, `0..128` for IPv6 or `0..48` for MAC addresses) or a string
792 containing a valid netmask (optional)
793 @return CIDR instance representing the netmask
794 @usage `local range = luci.ip.new("172.19.37.45/16")
795 print(range:mask()) -- "255.255.0.0"
796 print(range:mask(24)) -- "255.255.255.0"
797 print(range:mask("255.0.0.0")) -- "255.0.0.0"`
801 Derive broadcast address of CIDR instance.
803 Constructs a CIDR instance representing the broadcast address of this instance.
804 The used prefix size can be overridden by the optional mask parameter.
806 This function has no effect on IPv6 or MAC address instances, it will return
807 nothing in this case.
812 @param mask Either a number containing the number of bits (`0..32` for IPv4) or
813 a string containing a valid netmask (optional)
814 @return Return a new CIDR instance representing the broadcast address if this
815 instance is an IPv4 range, else return nothing.
816 @usage `local range = luci.ip.new("172.19.37.45/16")
817 print(range:broadcast()) -- "172.19.255.255"
818 print(range:broadcast(24)) -- "172.19.37.255"
819 print(range:broadcast("255.0.0.0")) -- "172.255.255.255"`
823 Derive mapped IPv4 address of CIDR instance.
825 Constructs a CIDR instance representing the IPv4 address of the IPv6 mapped
826 IPv4 address in this instance.
828 This function has no effect on IPv4 instances, MAC address instances or IPv6
829 instances which are not a mapped address, it will return nothing in this case.
834 @return Return a new CIDR instance representing the IPv4 address if this
835 instance is an IPv6 mapped IPv4 address, else return nothing.
836 @usage `local addr = luci.ip.new("::ffff:172.16.19.1")
837 print(addr:mapped4()) -- "172.16.19.1"`
841 Derive unscoped IPv6 address of CIDR instance.
843 Construct a copy of the given IPv6 CIDR instance and drop the associated
844 address scope information.
846 This function has no effect on IPv4 instances or MAC address instances,
847 it will return nothing in this case.
852 @return Return a new CIDR instance representing the unscoped IPv6 address.
853 @usage `local addr = luci.ip.new("fe80::1234%eth0")
854 print(addr:unscoped()) -- "fe80::1234"`
858 Derive MAC address of IPv6 link local CIDR instance.
860 Constructs a CIDR instance representing the MAC address contained in the IPv6
861 link local address of this instance.
863 This function has no effect on IPv4 instances, MAC address instances or IPv6
864 instances which are not a link local address, it will return nothing in this
870 @return Return a new CIDR instance representing the MAC address if this
871 instance is an IPv6 link local address, else return nothing.
872 @usage `local addr = luci.ip.new("fe80::6666:b3ff:fe47:e1b9")
873 print(addr:tomac()) -- "64:66:B3:47:E1:B9"`
877 Derive IPv6 link local address from MAC address CIDR instance.
879 Constructs a CIDR instance representing the IPv6 link local address of the
880 MAC address represented by this instance.
882 This function has no effect on IPv4 instances or IPv6 instances, it will return
883 nothing in this case.
887 @name cidr.tolinklocal
888 @return Return a new CIDR instance representing the IPv6 link local address.
889 @usage `local mac = luci.ip.new("64:66:B3:47:E1:B9")
890 print(mac:tolinklocal()) -- "fe80::6666:b3ff:fe47:e1b9"`
894 Test whether CIDR contains given range.
899 @param addr A `luci.ip.cidr` instance or a string convertible by
900 `luci.ip.new()` to test.
901 @return `true` if this instance fully contains the given address else
903 @usage `local range = luci.ip.new("10.24.0.0/255.255.0.0")
904 print(range:contains("10.24.5.1")) -- true
905 print(range:contains("::1")) -- false
906 print(range:contains("10.0.0.0/8")) -- false
908 local range6 = luci.ip.new("fe80::/10")
909 print(range6:contains("fe80::221:63f:fe75:aa17/64")) -- true
910 print(range6:contains("fd9b:6b3:c5:0:221:63f:fe75:aa17/64")) -- false
912 local intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/24")
913 print(intel_macs:contains("C0:B6:F9:A3:C:11")) -- true
914 print(intel_macs:contains("64:66:B3:47:E1:B9")) -- false`
918 Add given amount to CIDR instance. If the result would overflow the maximum
919 address space, the result is set to the highest possible address.
924 @param amount A numeric value between 0 and 0xFFFFFFFF, a
925 `luci.ip.cidr` instance or a string convertible by
927 @param inplace If `true`, modify this instance instead of returning
928 a new derived CIDR instance.
930 <li>When adding inplace: Return `true` if the addition succeeded
931 or `false` when the addition overflowed.</li>
932 <li>When deriving new CIDR: Return new instance representing the value of
933 this instance plus the added amount or the highest possible address if
934 the addition overflowed the available address space.</li></ul>
935 @usage `local addr = luci.ip.new("192.168.1.1/24")
936 print(addr:add(250)) -- "192.168.1.251/24"
937 print(addr:add("0.0.99.0")) -- "192.168.100.1/24"
939 addr:add(256, true) -- true
940 print(addr) -- "192.168.2.1/24
942 addr:add("255.0.0.0", true) -- false (overflow)
943 print(addr) -- "255.255.255.255/24
945 local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64")
946 print(addr6:add(256)) -- "fe80::221:63f:fe75:ab17/64"
947 print(addr6:add("::ffff:0")) -- "fe80::221:640:fe74:aa17/64"
949 addr6:add(256, true) -- true
950 print(addr6) -- "fe80::221:63f:fe75:ab17/64
952 addr6:add("ffff::", true) -- false (overflow)
953 print(addr6) -- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64"
955 local mac = luci.ip.new("00:14:22:01:23:45")
956 print(mac:add(256)) -- "00:14:22:01:24:45"
957 print(mac:add("0:0:0:0:FF:0") -- "00:14:22:02:22:45"
959 mac:add(256, true) -- true
960 print(mac) -- "00:14:22:01:24:45"
962 mac:add("FF:FF:0:0:0:0", true) -- false (overflow)
963 print(mac) -- "FF:FF:FF:FF:FF:FF"`
967 Subtract given amount from CIDR instance. If the result would under, the lowest
968 possible address is returned.
973 @param amount A numeric value between 0 and 0xFFFFFFFF, a
974 `luci.ip.cidr` instance or a string convertible by
976 @param inplace If `true`, modify this instance instead of returning
977 a new derived CIDR instance.
979 <li>When subtracting inplace: Return `true` if the subtraction
980 succeeded or `false` when the subtraction underflowed.</li>
981 <li>When deriving new CIDR: Return new instance representing the value of
982 this instance minus the subtracted amount or the lowest address if
983 the subtraction underflowed.</li></ul>
984 @usage `local addr = luci.ip.new("192.168.1.1/24")
985 print(addr:sub(256)) -- "192.168.0.1/24"
986 print(addr:sub("0.168.0.0")) -- "192.0.1.1/24"
988 addr:sub(256, true) -- true
989 print(addr) -- "192.168.0.1/24
991 addr:sub("255.0.0.0", true) -- false (underflow)
992 print(addr) -- "0.0.0.0/24
994 local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64")
995 print(addr6:sub(256)) -- "fe80::221:63f:fe75:a917/64"
996 print(addr6:sub("::ffff:0")) -- "fe80::221:63e:fe76:aa17/64"
998 addr:sub(256, true) -- true
999 print(addr) -- "fe80::221:63f:fe75:a917/64"
1001 addr:sub("ffff::", true) -- false (underflow)
1002 print(addr) -- "::/64"
1004 local mac = luci.ip.new("00:14:22:01:23:45")
1005 print(mac:sub(256)) -- "00:14:22:01:22:45"
1006 print(mac:sub("0:0:0:0:FF:0") -- "00:14:22:00:24:45"
1008 mac:sub(256, true) -- true
1009 print(mac) -- "00:14:22:01:22:45"
1011 mac:sub("FF:FF:0:0:0:0", true) -- false (overflow)
1012 print(mac) -- "00:00:00:00:00:00"`
1016 Calculate the lowest possible host address within this CIDR instance.
1021 @return Returns a new CIDR instance representing the lowest host address
1023 @usage `local addr = luci.ip.new("192.168.123.56/24")
1024 print(addr:minhost()) -- "192.168.123.1"
1026 local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
1027 print(addr6:minhost()) -- "fd9b:62b3:9cc5::1"
1029 local mac = luci.ip.new("00:14:22:01:22:45/32")
1030 print(mac:minhost()) -- "00:14:22:01:00:01"`
1034 Calculate the highest possible host address within this CIDR instance.
1039 @return Returns a new CIDR instance representing the highest host address
1041 @usage `local addr = luci.ip.new("192.168.123.56/24")
1042 print(addr:maxhost()) -- "192.168.123.254" (.255 is broadcast)
1044 local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
1045 print(addr6:maxhost()) -- "fd9b:62b3:9cc5:0:ffff:ffff:ffff:ffff"
1047 local mac = luci.ip.new("00:14:22:01:22:45/32")
1048 print(mac:maxhost()) -- "00:14:22:01:FF:FF"`
1052 Convert CIDR instance into string representation.
1054 If the prefix size of instance is less than 32 for IPv4, 128 for IPv6 or 48 for
1055 MACs, the address is returned in the form "address/prefix" otherwise just
1058 It is usually not required to call this function directly as CIDR objects
1059 define it as __tostring function in the associated metatable.
1064 @return Returns a string representing the range or address of this CIDR instance