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 MAC address of IPv6 link local CIDR instance.
843 Constructs a CIDR instance representing the MAC address contained in the IPv6
844 link local address of this instance.
846 This function has no effect on IPv4 instances, MAC address instances or IPv6
847 instances which are not a link local address, it will return nothing in this
853 @return Return a new CIDR instance representing the MAC address if this
854 instance is an IPv6 link local address, else return nothing.
855 @usage `local addr = luci.ip.new("fe80::6666:b3ff:fe47:e1b9")
856 print(addr:tomac()) -- "64:66:B3:47:E1:B9"`
860 Derive IPv6 link local address from MAC address CIDR instance.
862 Constructs a CIDR instance representing the IPv6 link local address of the
863 MAC address represented by this instance.
865 This function has no effect on IPv4 instances or IPv6 instances, it will return
866 nothing in this case.
870 @name cidr.tolinklocal
871 @return Return a new CIDR instance representing the IPv6 link local address.
872 @usage `local mac = luci.ip.new("64:66:B3:47:E1:B9")
873 print(mac:tolinklocal()) -- "fe80::6666:b3ff:fe47:e1b9"`
877 Test whether CIDR contains given range.
882 @param addr A `luci.ip.cidr` instance or a string convertible by
883 `luci.ip.new()` to test.
884 @return `true` if this instance fully contains the given address else
886 @usage `local range = luci.ip.new("10.24.0.0/255.255.0.0")
887 print(range:contains("10.24.5.1")) -- true
888 print(range:contains("::1")) -- false
889 print(range:contains("10.0.0.0/8")) -- false
891 local range6 = luci.ip.new("fe80::/10")
892 print(range6:contains("fe80::221:63f:fe75:aa17/64")) -- true
893 print(range6:contains("fd9b:6b3:c5:0:221:63f:fe75:aa17/64")) -- false
895 local intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/24")
896 print(intel_macs:contains("C0:B6:F9:A3:C:11")) -- true
897 print(intel_macs:contains("64:66:B3:47:E1:B9")) -- false`
901 Add given amount to CIDR instance. If the result would overflow the maximum
902 address space, the result is set to the highest possible address.
907 @param amount A numeric value between 0 and 0xFFFFFFFF, a
908 `luci.ip.cidr` instance or a string convertible by
910 @param inplace If `true`, modify this instance instead of returning
911 a new derived CIDR instance.
913 <li>When adding inplace: Return `true` if the addition succeeded
914 or `false` when the addition overflowed.</li>
915 <li>When deriving new CIDR: Return new instance representing the value of
916 this instance plus the added amount or the highest possible address if
917 the addition overflowed the available address space.</li></ul>
918 @usage `local addr = luci.ip.new("192.168.1.1/24")
919 print(addr:add(250)) -- "192.168.1.251/24"
920 print(addr:add("0.0.99.0")) -- "192.168.100.1/24"
922 addr:add(256, true) -- true
923 print(addr) -- "192.168.2.1/24
925 addr:add("255.0.0.0", true) -- false (overflow)
926 print(addr) -- "255.255.255.255/24
928 local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64")
929 print(addr6:add(256)) -- "fe80::221:63f:fe75:ab17/64"
930 print(addr6:add("::ffff:0")) -- "fe80::221:640:fe74:aa17/64"
932 addr6:add(256, true) -- true
933 print(addr6) -- "fe80::221:63f:fe75:ab17/64
935 addr6:add("ffff::", true) -- false (overflow)
936 print(addr6) -- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64"
938 local mac = luci.ip.new("00:14:22:01:23:45")
939 print(mac:add(256)) -- "00:14:22:01:24:45"
940 print(mac:add("0:0:0:0:FF:0") -- "00:14:22:02:22:45"
942 mac:add(256, true) -- true
943 print(mac) -- "00:14:22:01:24:45"
945 mac:add("FF:FF:0:0:0:0", true) -- false (overflow)
946 print(mac) -- "FF:FF:FF:FF:FF:FF"`
950 Subtract given amount from CIDR instance. If the result would under, the lowest
951 possible address is returned.
956 @param amount A numeric value between 0 and 0xFFFFFFFF, a
957 `luci.ip.cidr` instance or a string convertible by
959 @param inplace If `true`, modify this instance instead of returning
960 a new derived CIDR instance.
962 <li>When subtracting inplace: Return `true` if the subtraction
963 succeeded or `false` when the subtraction underflowed.</li>
964 <li>When deriving new CIDR: Return new instance representing the value of
965 this instance minus the subtracted amount or the lowest address if
966 the subtraction underflowed.</li></ul>
967 @usage `local addr = luci.ip.new("192.168.1.1/24")
968 print(addr:sub(256)) -- "192.168.0.1/24"
969 print(addr:sub("0.168.0.0")) -- "192.0.1.1/24"
971 addr:sub(256, true) -- true
972 print(addr) -- "192.168.0.1/24
974 addr:sub("255.0.0.0", true) -- false (underflow)
975 print(addr) -- "0.0.0.0/24
977 local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64")
978 print(addr6:sub(256)) -- "fe80::221:63f:fe75:a917/64"
979 print(addr6:sub("::ffff:0")) -- "fe80::221:63e:fe76:aa17/64"
981 addr:sub(256, true) -- true
982 print(addr) -- "fe80::221:63f:fe75:a917/64"
984 addr:sub("ffff::", true) -- false (underflow)
985 print(addr) -- "::/64"
987 local mac = luci.ip.new("00:14:22:01:23:45")
988 print(mac:sub(256)) -- "00:14:22:01:22:45"
989 print(mac:sub("0:0:0:0:FF:0") -- "00:14:22:00:24:45"
991 mac:sub(256, true) -- true
992 print(mac) -- "00:14:22:01:22:45"
994 mac:sub("FF:FF:0:0:0:0", true) -- false (overflow)
995 print(mac) -- "00:00:00:00:00:00"`
999 Calculate the lowest possible host address within this CIDR instance.
1004 @return Returns a new CIDR instance representing the lowest host address
1006 @usage `local addr = luci.ip.new("192.168.123.56/24")
1007 print(addr:minhost()) -- "192.168.123.1"
1009 local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
1010 print(addr6:minhost()) -- "fd9b:62b3:9cc5::1"
1012 local mac = luci.ip.new("00:14:22:01:22:45/32")
1013 print(mac:minhost()) -- "00:14:22:01:00:01"`
1017 Calculate the highest possible host address within this CIDR instance.
1022 @return Returns a new CIDR instance representing the highest host address
1024 @usage `local addr = luci.ip.new("192.168.123.56/24")
1025 print(addr:maxhost()) -- "192.168.123.254" (.255 is broadcast)
1027 local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
1028 print(addr6:maxhost()) -- "fd9b:62b3:9cc5:0:ffff:ffff:ffff:ffff"
1030 local mac = luci.ip.new("00:14:22:01:22:45/32")
1031 print(mac:maxhost()) -- "00:14:22:01:FF:FF"`
1035 Convert CIDR instance into string representation.
1037 If the prefix size of instance is less than 32 for IPv4, 128 for IPv6 or 48 for
1038 MACs, the address is returned in the form "address/prefix" otherwise just
1041 It is usually not required to call this function directly as CIDR objects
1042 define it as __tostring function in the associated metatable.
1047 @return Returns a string representing the range or address of this CIDR instance