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 @return <p>Table containing the fields described below.</p>
182 <table id="routetable">
183 <tr><th>Field</th><th>Description</th></tr>
185 <p>Route type with one of the following numeric values:</p>
189 <td>`RTN_UNICAST` - Gateway or direct route</td>
193 <td>`RTN_LOCAL` - Accept locally</td>
197 <td>`RTN_BROADCAST` -
198 Accept locally as broadcast send as broadcast</td>
203 Accept locally as broadcast but send as unicast</td>
207 <td>`RTN_MULTICAST` - Multicast route</td>
213 <td>Number containing the route family, `4` for IPv4 or
218 <td>Destination `luci.ip.cidr` instance</td>
222 <td>Gateway `luci.ip.cidr` instance (optional)</td>
226 <td>Source address `luci.ip.cidr` instance (optional)</td>
230 <td>Preferred source `luci.ip.cidr` instance (optional)</td>
234 <td>String containing the name of the outgoing interface</td>
238 <td>String containing the name of the incoming interface (optional)</td>
242 <td>Number of the associated routing table (`0..65535`)</td>
246 <td>Number of the associated routing protocol</td>
250 <td>Number describing the scope of the route, most commonly
251 `0` for global or `253` for on-link</td>
255 <td>Number describing the route metric (optional)</td>
259 <td>Number of seconds the prefix is valid (IPv6 only, optional)</td>
263 <td>Route destination error code (optional)</td>
267 <li>Find default gateway by getting route to Google's public NS server
268 `rt = luci.ip.route("8.8.8.8")
270 print("gateway is", rt.gw)
272 <li>Determine IPv6 upstream interface `rt = luci.ip.route("2001::/7")
274 print("ipv6 upstream device is", rt.dev)
281 Fetch all routes, optionally matching the given criteria.
285 @param filter <p>Table containing one or more of the possible filter
286 critera described below (optional)</p><table>
287 <tr><th>Field</th><th>Description</th></tr>
288 <tr><td>`family`</td><td>
289 Number describing the address family to return - `4` selects
290 IPv4 routes, `6` IPv6 ones. Any other value selects both.
292 <tr><td>`iif`</td><td>
293 String containing the incoming route interface to match.
295 <tr><td>`oif`</td><td>
296 String containing the outgoing route interface to match.
298 <tr><td>`type`</td><td>
299 Numeric type to match, e.g. `1` for unicast.
301 <tr><td>`scope`</td><td>
302 Numeric scope to match, e.g. `253` for onlink.
304 <tr><td>`proto`</td><td>
305 Numeric protocol to match, e.g. `2` for boot.
307 <tr><td>`table`</td><td>
308 Numeric routing table to match (`0..65535`).
310 <tr><td>`gw`</td><td>
311 String containing the gateway address to match. Can be in any notation
312 specified by `luci.ip.new()`. Prefix matching is performed when
313 comparing the routes, e.g. "192.168.1.0/24" would select routes with gateway
314 addresses `192.168.1.1 .. 192.168.1.255`.
316 <tr><td>`dest`</td><td>
317 String containing the destination to match. Prefix matching is performed.
319 <tr><td>`from`</td><td>
320 String containing the source address to match. Prefix matching is performed.
322 <tr><td>`src`</td><td>
323 String containing the preferred source address to match.
324 Prefix matching is performed.
326 <tr><td>`dest_exact`</td><td>
327 String containing the destination to match. Exact matching is performed,
328 e.g. `dest = "0.0.0.0/0"` would match <em>any</em> IPv4 route
329 while `dest_exact = "0.0.0.0/0"` will <em>only</em> match the
332 <tr><td>`from_exact`</td><td>
333 String containing the source address to match. Exact matching is performed.
336 @param callback <p>Callback function to invoke for each found route
337 instead of returning one table of route objects (optional)</p>
338 @return If no callback function is provided, a table of routes
339 <a href="#routetable">as specified by `luci.ip.route()`</a>
340 is returned. If a callback function is given, it is invoked for each route
341 and nothing is returned.
344 <li>Find all IPv4 default routes:
345 `luci.ip.routes({ dest_exact = "0.0.0.0/0" }, function(rt)
346 print(rt.type, rt.gw, rt.dev)
348 <li>Find all global IPv6 prefixes on the current system:
349 `luci.ip.routes({ from = "2001::/7" }, function(rt)
352 <li>Fetch all IPv4 routes:
353 `routes = luci.ip.routes({ family = 4 })
354 for _, rt in ipairs(routes) do
355 print(rt.dest, rt.gw, rt.dev)
361 Fetches entries from the IPv4 ARP and IPv6 neighbour kernel table
365 @param filter <p>Table containing one or more of the possible filter
366 critera described below (optional)</p><table>
367 <tr><th>Field</th><th>Description</th></tr>
368 <tr><td>`family`</td><td>
369 Number describing the address family to return - `4` selects
370 IPv4 ARP, `6` select IPv6 neighbour entries. Any other value
373 <tr><td>`dev`</td><td>
374 String containing the associated interface to match.
376 <tr><td>`dest`</td><td>
377 String containing the associated address to match. Can be in any notation
378 specified by `luci.ip.new()`. Prefix matching is performed when
379 comparing the addresses, e.g. "192.168.1.0/24" would select ARP entries
380 for `192.168.1.1 .. 192.168.1.255`.
382 <tr><td>`mac`</td><td>
383 String containing MAC address to match.
386 @param callback <p>Callback function to invoke for each found neighbour
387 entry instead of returning one table of neighbour entries (optional)</p>
388 @return If no callback function is provided, a table of neighbour entries
389 is returned. If a callback function is given, it is invoked for each entry
390 and nothing is returned.
392 A neighbour entry is a table containing the following fields:
395 <tr><th>Field</th><th>Description</th></tr>
398 <td>Number containing the neighbour entry family, `4` for IPv4
399 ARP or `6` for IPv6 NDP</td>
403 <td>String containing the associated device of the neighbour entry</td>
407 <td>IP address `luci.ip.cidr` instance</td>
411 <td>MAC address `luci.ip.cidr` instance</td>
415 <td>Boolean "true" if the neighbour entry is a router (IPv6, optional)</td>
419 <td>Boolean "true" if this is a proxy entry (optional)</td>
422 <td>`incomplete`</td>
423 <td>Boolean "true" if the entry is in incomplete state (optional)</td>
427 <td>Boolean "true" if the entry is in reachable state (optional)</td>
431 <td>Boolean "true" if the entry is stale (optional)</td>
435 <td>Boolean "true" if the entry is delayed (optional)</td>
439 <td>Boolean "true" if the entry is in probe state (optional)</td>
443 <td>Boolean "true" if the entry is in failed state (optional)</td>
447 <td>Boolean "true" if the entry is not caused by NDP or
452 <td>Boolean "true" if the entry was statically configured from
453 userspace (optional)</td>
457 <li>Find all ARP neighbours in the LAN:
458 `luci.ip.neighbors({ dest = "192.168.0.0/16" }, function(n)
461 <li>Find all active IPv6 addresses of host with given MAC:
462 `luci.ip.neighbors({ family = 6, mac = "00:21:63:75:aa:17" },
470 Fetch basic device information
474 @param device String containing the network device to query
475 @return If the given interface is found, a table containing the fields
476 described below is returned, else an empty table.
479 <tr><th>Field</th><th>Description</th></tr>
482 <td>Boolean indicating whether the device is in IFF_RUNNING state</td>
486 <td>Numeric value indicating the type of the device, e.g. `1`
491 <td>String containing the name of the device</td>
495 <td>If queried device is a bridge port, string containing the name of
496 parent bridge device (optional)</td>
500 <td>Number containing the current MTU of the device</td>
504 <td>Number containing the TX queue length of the device</td>
508 <td>MAC address `luci.ip.cidr` instance representing the device ethernet
513 <li>Test whether device br-lan exists:
514 `print(luci.ip.link("br-lan").name ~= nil)
516 <li>Query MAC address of eth0:
517 `print(luci.ip.link("eth0").mac)
524 -- Represents an IPv4 or IPv6 address range.
526 module "luci.ip.cidr"
529 Checks whether the CIDR instance is an IPv4 address range
536 @return `true` if the CIDR is an IPv4 range, else `false`
540 Checks whether the CIDR instance is within the private RFC1918 address space
544 @name cidr.is4rfc1918
545 @return `true` if the entire range of this CIDR lies within one of
546 the ranges `10.0.0.0-10.255.255.255`,
547 `172.16.0.0-172.31.0.0` or
548 `192.168.0.0-192.168.255.255`, else `false`.
549 @usage `local addr = luci.ip.new("192.168.45.2/24")
550 if addr:is4rfc1918() then
551 print("Is a private address")
556 Checks whether the CIDR instance is an IPv4 link local (Zeroconf) address
560 @name cidr.is4linklocal
561 @return `true` if the entire range of this CIDR lies within the range
562 the range `169.254.0.0-169.254.255.255`, else `false`.
563 @usage `local addr = luci.ip.new("169.254.34.125")
564 if addr:is4linklocal() then
565 print("Is a zeroconf address")
570 Checks whether the CIDR instance is an IPv6 address range
577 @return `true` if the CIDR is an IPv6 range, else `false`
581 Checks whether the CIDR instance is an IPv6 link local address
585 @name cidr.is6linklocal
586 @return `true` if the entire range of this CIDR lies within the range
587 the `fe80::/10` range, else `false`.
588 @usage `local addr = luci.ip.new("fe92:53a:3216:af01:221:63ff:fe75:aa17/64")
589 if addr:is6linklocal() then
590 print("Is a linklocal address")
595 Checks whether the CIDR instance is an IPv6 mapped IPv4 address
599 @name cidr.is6mapped4
600 @return `true` if the address is an IPv6 mapped IPv4 address in the
601 form `::ffff:1.2.3.4`.
602 @usage `local addr = luci.ip.new("::ffff:192.168.1.1")
603 if addr:is6mapped4() then
604 print("Is a mapped IPv4 address")
609 Checks whether the CIDR instance is an ethernet MAC address range
616 @return `true` if the CIDR is a MAC address range, else `false`
620 Checks whether the CIDR instance is a locally administered (LAA) MAC address
624 @name cidr.ismaclocal
625 @return `true` if the MAC address sets the locally administered bit.
626 @usage `local mac = luci.ip.new("02:C0:FF:EE:00:01")
627 if mac:ismaclocal() then
628 print("Is an LAA MAC address")
633 Checks whether the CIDR instance is a multicast MAC address
637 @name cidr.ismacmcast
638 @return `true` if the MAC address sets the multicast bit.
639 @usage `local mac = luci.ip.new("01:00:5E:7F:00:10")
640 if addr:ismacmcast() then
641 print("Is a multicast MAC address")
646 Checks whether this CIDR instance is lower than the given argument.
647 The comparisation follows these rules:
648 <ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses
649 are considered lower than MAC addresses</li>
650 <li>Prefix sizes are ignored</li></ul>
655 @param addr A `luci.ip.cidr` instance or a string convertable by
656 `luci.ip.new()` to compare against.
657 @return `true` if this CIDR is lower than the given address,
659 @usage `local addr = luci.ip.new("192.168.1.1")
660 print(addr:lower(addr)) -- false
661 print(addr:lower("10.10.10.10/24")) -- false
662 print(addr:lower(luci.ip.new("::1"))) -- true
663 print(addr:lower(luci.ip.new("192.168.200.1"))) -- true
664 print(addr:lower(luci.ip.new("00:14:22:01:23:45"))) -- true`
670 Checks whether this CIDR instance is higher than the given argument.
671 The comparisation follows these rules:
672 <ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses
673 are considered lower than MAC addresses</li>
674 <li>Prefix sizes are ignored</li></ul>
679 @param addr A `luci.ip.cidr` instance or a string convertable by
680 `luci.ip.new()` to compare against.
681 @return `true` if this CIDR is higher than the given address,
683 @usage `local addr = luci.ip.new("192.168.1.1")
684 print(addr:higher(addr)) -- false
685 print(addr:higher("10.10.10.10/24")) -- true
686 print(addr:higher(luci.ip.new("::1"))) -- false
687 print(addr:higher(luci.ip.new("192.168.200.1"))) -- false
688 print(addr:higher(luci.ip.new("00:14:22:01:23:45"))) -- false`
694 Checks whether this CIDR instance is equal to the given argument.
699 @param addr A `luci.ip.cidr` instance or a string convertable by
700 `luci.ip.new()` to compare against.
701 @return `true` if this CIDR is equal to the given address,
703 @usage `local addr = luci.ip.new("192.168.1.1")
704 print(addr:equal(addr)) -- true
705 print(addr:equal("192.168.1.1")) -- true
706 print(addr:equal(luci.ip.new("::1"))) -- false
708 local addr6 = luci.ip.new("::1")
709 print(addr6:equal("0:0:0:0:0:0:0:1/64")) -- true
710 print(addr6:equal(luci.ip.new("fe80::221:63ff:fe75:aa17"))) -- false
712 local mac = luci.ip.new("00:14:22:01:23:45")
713 print(mac:equal("0:14:22:1:23:45")) -- true
714 print(mac:equal(luci.ip.new("01:23:45:67:89:AB")) -- false`
720 Get or set prefix size of CIDR instance.
721 If the optional mask parameter is given, the prefix size of this CIDR is altered
722 else the current prefix size is returned.
727 @param mask Either a number containing the number of bits (`0..32`
728 for IPv4, `0..128` for IPv6 or `0..48` for MAC addresses) or a string
729 containing a valid netmask (optional)
730 @return Bit count of the current prefix size
731 @usage `local range = luci.ip.new("192.168.1.1/255.255.255.0")
732 print(range:prefix()) -- 24
735 print(range:prefix()) -- 16
737 range:prefix("255.255.255.255")
738 print(range:prefix()) -- 32`
742 Derive network address of CIDR instance.
744 Returns a new CIDR instance representing the network address of this instance
745 with all host parts masked out. The used prefix size can be overridden by the
746 optional mask parameter.
751 @param mask Either a number containing the number of bits (`0..32`
752 for IPv4, `0..128` for IPv6 or `0..48` for MAC addresses) or a string
753 containing a valid netmask (optional)
754 @return CIDR instance representing the network address
755 @usage `local range = luci.ip.new("192.168.62.243/255.255.0.0")
756 print(range:network()) -- "192.168.0.0"
757 print(range:network(24)) -- "192.168.62.0"
758 print(range:network("255.255.255.0")) -- "192.168.62.0"
760 local range6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
761 print(range6:network()) -- "fd9b:62b3:9cc5::"`
765 Derive host address of CIDR instance.
767 This function essentially constructs a copy of this CIDR with the prefix size
768 set to `32` for IPv4, `128` for IPv6 or `48` for MAC addresses.
773 @return CIDR instance representing the host address
774 @usage `local range = luci.ip.new("172.19.37.45/16")
775 print(range) -- "172.19.37.45/16"
776 print(range:host()) -- "172.19.37.45"`
780 Derive netmask of CIDR instance.
782 Constructs a CIDR instance representing the netmask of this instance. The used
783 prefix size can be overridden by the optional mask parameter.
788 @param mask Either a number containing the number of bits (`0..32`
789 for IPv4, `0..128` for IPv6 or `0..48` for MAC addresses) or a string
790 containing a valid netmask (optional)
791 @return CIDR instance representing the netmask
792 @usage `local range = luci.ip.new("172.19.37.45/16")
793 print(range:mask()) -- "255.255.0.0"
794 print(range:mask(24)) -- "255.255.255.0"
795 print(range:mask("255.0.0.0")) -- "255.0.0.0"`
799 Derive broadcast address of CIDR instance.
801 Constructs a CIDR instance representing the broadcast address of this instance.
802 The used prefix size can be overridden by the optional mask parameter.
804 This function has no effect on IPv6 or MAC address instances, it will return
805 nothing in this case.
810 @param mask Either a number containing the number of bits (`0..32` for IPv4) or
811 a string containing a valid netmask (optional)
812 @return Return a new CIDR instance representing the broadcast address if this
813 instance is an IPv4 range, else return nothing.
814 @usage `local range = luci.ip.new("172.19.37.45/16")
815 print(range:broadcast()) -- "172.19.255.255"
816 print(range:broadcast(24)) -- "172.19.37.255"
817 print(range:broadcast("255.0.0.0")) -- "172.255.255.255"`
821 Derive mapped IPv4 address of CIDR instance.
823 Constructs a CIDR instance representing the IPv4 address of the IPv6 mapped
824 IPv4 address in this instance.
826 This function has no effect on IPv4 instances, MAC address instances or IPv6
827 instances which are not a mapped address, it will return nothing in this case.
832 @return Return a new CIDR instance representing the IPv4 address if this
833 instance is an IPv6 mapped IPv4 address, else return nothing.
834 @usage `local addr = luci.ip.new("::ffff:172.16.19.1")
835 print(addr:mapped4()) -- "172.16.19.1"`
839 Derive MAC address of IPv6 link local CIDR instance.
841 Constructs a CIDR instance representing the MAC address contained in the IPv6
842 link local address of this instance.
844 This function has no effect on IPv4 instances, MAC address instances or IPv6
845 instances which are not a link local address, it will return nothing in this
851 @return Return a new CIDR instance representing the MAC address if this
852 instance is an IPv6 link local address, else return nothing.
853 @usage `local addr = luci.ip.new("fe80::6666:b3ff:fe47:e1b9")
854 print(addr:tomac()) -- "64:66:B3:47:E1:B9"`
858 Derive IPv6 link local address from MAC address CIDR instance.
860 Constructs a CIDR instance representing the IPv6 link local address of the
861 MAC address represented by this instance.
863 This function has no effect on IPv4 instances or IPv6 instances, it will return
864 nothing in this case.
868 @name cidr.tolinklocal
869 @return Return a new CIDR instance representing the IPv6 link local address.
870 @usage `local mac = luci.ip.new("64:66:B3:47:E1:B9")
871 print(mac:tolinklocal()) -- "fe80::6666:b3ff:fe47:e1b9"`
875 Test whether CIDR contains given range.
880 @param addr A `luci.ip.cidr` instance or a string convertable by
881 `luci.ip.new()` to test.
882 @return `true` if this instance fully contains the given address else
884 @usage `local range = luci.ip.new("10.24.0.0/255.255.0.0")
885 print(range:contains("10.24.5.1")) -- true
886 print(range:contains("::1")) -- false
887 print(range:contains("10.0.0.0/8")) -- false
889 local range6 = luci.ip.new("fe80::/10")
890 print(range6:contains("fe80::221:63f:fe75:aa17/64")) -- true
891 print(range6:contains("fd9b:6b3:c5:0:221:63f:fe75:aa17/64")) -- false
893 local intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/24")
894 print(intel_macs:contains("C0:B6:F9:A3:C:11")) -- true
895 print(intel_macs:contains("64:66:B3:47:E1:B9")) -- false`
899 Add given amount to CIDR instance. If the result would overflow the maximum
900 address space, the result is set to the highest possible address.
905 @param amount A numeric value between 0 and 0xFFFFFFFF, a
906 `luci.ip.cidr` instance or a string convertable by
908 @param inplace If `true`, modify this instance instead of returning
909 a new derived CIDR instance.
911 <li>When adding inplace: Return `true` if the addition succeded
912 or `false` when the addition overflowed.</li>
913 <li>When deriving new CIDR: Return new instance representing the value of
914 this instance plus the added amount or the highest possible address if
915 the addition overflowed the available address space.</li></ul>
916 @usage `local addr = luci.ip.new("192.168.1.1/24")
917 print(addr:add(250)) -- "192.168.1.251/24"
918 print(addr:add("0.0.99.0")) -- "192.168.100.1/24"
920 addr:add(256, true) -- true
921 print(addr) -- "192.168.2.1/24
923 addr:add("255.0.0.0", true) -- false (overflow)
924 print(addr) -- "255.255.255.255/24
926 local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64")
927 print(addr6:add(256)) -- "fe80::221:63f:fe75:ab17/64"
928 print(addr6:add("::ffff:0")) -- "fe80::221:640:fe74:aa17/64"
930 addr6:add(256, true) -- true
931 print(addr6) -- "fe80::221:63f:fe75:ab17/64
933 addr6:add("ffff::", true) -- false (overflow)
934 print(addr6) -- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64"
936 local mac = luci.ip.new("00:14:22:01:23:45")
937 print(mac:add(256)) -- "00:14:22:01:24:45"
938 print(mac:add("0:0:0:0:FF:0") -- "00:14:22:02:22:45"
940 mac:add(256, true) -- true
941 print(mac) -- "00:14:22:01:24:45"
943 mac:add("FF:FF:0:0:0:0", true) -- false (overflow)
944 print(mac) -- "FF:FF:FF:FF:FF:FF"`
948 Subtract given amount from CIDR instance. If the result would under, the lowest
949 possible address is returned.
954 @param amount A numeric value between 0 and 0xFFFFFFFF, a
955 `luci.ip.cidr` instance or a string convertable by
957 @param inplace If `true`, modify this instance instead of returning
958 a new derived CIDR instance.
960 <li>When subtracting inplace: Return `true` if the subtraction
961 succeeded or `false` when the subtraction underflowed.</li>
962 <li>When deriving new CIDR: Return new instance representing the value of
963 this instance minus the subtracted amount or the lowest address if
964 the subtraction underflowed.</li></ul>
965 @usage `local addr = luci.ip.new("192.168.1.1/24")
966 print(addr:sub(256)) -- "192.168.0.1/24"
967 print(addr:sub("0.168.0.0")) -- "192.0.1.1/24"
969 addr:sub(256, true) -- true
970 print(addr) -- "192.168.0.1/24
972 addr:sub("255.0.0.0", true) -- false (underflow)
973 print(addr) -- "0.0.0.0/24
975 local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64")
976 print(addr6:sub(256)) -- "fe80::221:63f:fe75:a917/64"
977 print(addr6:sub("::ffff:0")) -- "fe80::221:63e:fe76:aa17/64"
979 addr:sub(256, true) -- true
980 print(addr) -- "fe80::221:63f:fe75:a917/64"
982 addr:sub("ffff::", true) -- false (underflow)
983 print(addr) -- "::/64"
985 local mac = luci.ip.new("00:14:22:01:23:45")
986 print(mac:sub(256)) -- "00:14:22:01:22:45"
987 print(mac:sub("0:0:0:0:FF:0") -- "00:14:22:00:24:45"
989 mac:sub(256, true) -- true
990 print(mac) -- "00:14:22:01:22:45"
992 mac:sub("FF:FF:0:0:0:0", true) -- false (overflow)
993 print(mac) -- "00:00:00:00:00:00"`
997 Calculate the lowest possible host address within this CIDR instance.
1002 @return Returns a new CIDR instance representing the lowest host address
1004 @usage `local addr = luci.ip.new("192.168.123.56/24")
1005 print(addr:minhost()) -- "192.168.123.1"
1007 local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
1008 print(addr6:minhost()) -- "fd9b:62b3:9cc5::1"
1010 local mac = luci.ip.new("00:14:22:01:22:45/32")
1011 print(mac:minhost()) -- "00:14:22:01:00:01"`
1015 Calculate the highest possible host address within this CIDR instance.
1020 @return Returns a new CIDR instance representing the highest host address
1022 @usage `local addr = luci.ip.new("192.168.123.56/24")
1023 print(addr:maxhost()) -- "192.168.123.254" (.255 is broadcast)
1025 local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
1026 print(addr6:maxhost()) -- "fd9b:62b3:9cc5:0:ffff:ffff:ffff:ffff"
1028 local mac = luci.ip.new("00:14:22:01:22:45/32")
1029 print(mac:maxhost()) -- "00:14:22:01:FF:FF"`
1033 Convert CIDR instance into string representation.
1035 If the prefix size of instance is less than 32 for IPv4, 128 for IPv6 or 48 for
1036 MACs, the address is returned in the form "address/prefix" otherwise just
1039 It is usually not required to call this function directly as CIDR objects
1040 define it as __tostring function in the associated metatable.
1045 @return Returns a string representing the range or address of this CIDR instance