luci-lib-ip: support scoped IPv6 addresses
[oweals/luci.git] / libs / luci-lib-ip / src / ip.luadoc
1 --- LuCI IP calculation and netlink access library.
2 module "luci.ip"
3
4 ---[[
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.
8 @class function
9 @sort 1
10 @name new
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
18 address/mask range.
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
23
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`
28 @see IPv4
29 @see IPv6
30 @see MAC
31 ]]
32
33 ---[[
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.
37 @class function
38 @sort 2
39 @name IPv4
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`
50 @see IPv6
51 @see MAC
52 ]]
53
54 ---[[
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.
58 @class function
59 @sort 3
60 @name IPv6
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`
71 @see IPv4
72 @see MAC
73 ]]
74
75 ---[[
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.
79 @class function
80 @sort 4
81 @name MAC
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`
92 @see IPv4
93 @see IPv6
94 ]]
95
96 ---[[
97 Verify an IPv4 address.
98
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.
102
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
105 with exceptions.
106 @class function
107 @sort 5
108 @name checkip4
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`
118 @see checkip6
119 @see checkmac
120 ]]
121
122 ---[[
123 Verify an IPv6 address.
124
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.
128
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
131 with exceptions.
132 @class function
133 @sort 6
134 @name checkip6
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`
144 @see checkip4
145 @see checkmac
146 ]]
147
148 ---[[
149 Verify an ethernet MAC address.
150
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.
154
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
157 with exceptions.
158 @class function
159 @sort 7
160 @name checkmac
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`
170 @see checkip4
171 @see checkip6
172 ]]
173
174 ---[[
175 Determine the route leading to the given destination.
176 @class function
177 @sort 8
178 @name route
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>
186 <tr><td>`type`<td>
187   <p>Route type with one of the following numeric values:</p>
188   <table>
189   <tr>
190         <td>`1`</td>
191         <td>`RTN_UNICAST` - Gateway or direct route</td>
192   </tr>
193   <tr>
194         <td>`2`</td>
195         <td>`RTN_LOCAL` - Accept locally</td>
196   </tr>
197   <tr>
198         <td>`3`</td>
199         <td>`RTN_BROADCAST` -
200             Accept locally as broadcast send as broadcast</td>
201   </tr>
202   <tr>
203         <td>`4`</td>
204         <td>`RTN_ANYCAST` -
205         Accept locally as broadcast but send as unicast</td>
206   </tr>
207   <tr>
208         <td>`5`</td>
209         <td>`RTN_MULTICAST` - Multicast route</td>
210   </tr>
211   </table>
212 </td></tr>
213 <tr>
214   <td>`family`</td>
215   <td>Number containing the route family, `4` for IPv4 or
216       `6` for IPv6</td>
217 </tr>
218 <tr>
219   <td>`dest`</td>
220   <td>Destination `luci.ip.cidr` instance</td>
221 </tr>
222 <tr>
223   <td>`gw`</td>
224   <td>Gateway `luci.ip.cidr` instance (optional)</td>
225 </tr>
226 <tr>
227   <td>`from`</td>
228   <td>Source address `luci.ip.cidr` instance (optional)</td>
229 </tr>
230 <tr>
231   <td>`src`</td>
232   <td>Preferred source `luci.ip.cidr` instance (optional)</td>
233 </tr>
234 <tr>
235   <td>`dev`</td>
236   <td>String containing the name of the outgoing interface</td>
237 </tr>
238 <tr>
239   <td>`iif`</td>
240   <td>String containing the name of the incoming interface (optional)</td>
241 </tr>
242 <tr>
243   <td>`table`</td>
244   <td>Number of the associated routing table (`0..65535`)</td>
245 </tr>
246 <tr>
247   <td>`proto`</td>
248   <td>Number of the associated routing protocol</td>
249 </tr>
250 <tr>
251   <td>`scope`</td>
252   <td>Number describing the scope of the route, most commonly
253       `0` for global or `253` for on-link</td>
254 </tr>
255 <tr>
256   <td>`metric`</td>
257   <td>Number describing the route metric (optional)</td>
258 </tr>
259 <tr>
260   <td>`expires`</td>
261   <td>Number of seconds the prefix is valid (IPv6 only, optional)</td>
262 </tr>
263 <tr>
264   <td>`error`</td>
265   <td>Route destination error code (optional)</td>
266 </tr>
267 </table>
268 @usage <ul>
269 <li>Find default gateway by getting route to Google's public NS server
270 `rt = luci.ip.route("8.8.8.8")
271 if rt ~= nil then
272         print("gateway is", rt.gw)
273 end`</li>
274 <li>Determine IPv6 upstream interface `rt = luci.ip.route("2001::/7")
275 if rt ~= nil then
276         print("ipv6 upstream device is", rt.dev)
277 end`</li>
278 </ul>
279 @see routes
280 ]]
281
282 ---[[
283 Fetch all routes, optionally matching the given criteria.
284 @class function
285 @sort 9
286 @name routes
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.
293 </td></tr>
294 <tr><td>`iif`</td><td>
295  String containing the incoming route interface to match.
296 </td></tr>
297 <tr><td>`oif`</td><td>
298  String containing the outgoing route interface to match.
299 </td></tr>
300 <tr><td>`type`</td><td>
301  Numeric type to match, e.g. `1` for unicast.
302 </td></tr>
303 <tr><td>`scope`</td><td>
304  Numeric scope to match, e.g. `253` for onlink.
305 </td></tr>
306 <tr><td>`proto`</td><td>
307  Numeric protocol to match, e.g. `2` for boot.
308 </td></tr>
309 <tr><td>`table`</td><td>
310  Numeric routing table to match (`0..65535`).
311 </td></tr>
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`.
317 </td></tr>
318 <tr><td>`dest`</td><td>
319  String containing the destination to match. Prefix matching is performed.
320 </td></tr>
321 <tr><td>`from`</td><td>
322  String containing the source address to match. Prefix matching is performed.
323 </td></tr>
324 <tr><td>`src`</td><td>
325  String containing the preferred source address to match.
326  Prefix matching is performed.
327 </td></tr>
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
332  default route.
333 </td></tr>
334 <tr><td>`from_exact`</td><td>
335  String containing the source address to match. Exact matching is performed.
336 </td></tr>
337 </table>
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.
344 @see route
345 @usage <ul>
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)
349 end)`</li>
350 <li>Find all global IPv6 prefixes on the current system:
351 `luci.ip.routes({ from = "2001::/7" }, function(rt)
352         print(rt.from)
353 end)`</li>
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)
358 end`</li>
359 </ul>
360 ]]
361
362 ---[[
363 Fetches entries from the IPv4 ARP and IPv6 neighbour kernel table
364 @class function
365 @sort 10
366 @name neighbors
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
373  selects both.
374 </td></tr>
375 <tr><td>`dev`</td><td>
376  String containing the associated interface to match.
377 </td></tr>
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`.
383 </td></tr>
384 <tr><td>`mac`</td><td>
385  String containing MAC address to match.
386 </td></tr>
387 </table>
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.
393
394 A neighbour entry is a table containing the following fields:
395
396 <table>
397 <tr><th>Field</th><th>Description</th></tr>
398 <tr>
399   <td>`family`</td>
400   <td>Number containing the neighbour entry family, `4` for IPv4
401       ARP or `6` for IPv6 NDP</td>
402 </tr>
403 <tr>
404   <td>`dev`</td>
405   <td>String containing the associated device of the neighbour entry</td>
406 </tr>
407 <tr>
408   <td>`dest`</td>
409   <td>IP address `luci.ip.cidr` instance</td>
410 </tr>
411 <tr>
412   <td>`mac`</td>
413   <td>MAC address `luci.ip.cidr` instance</td>
414 </tr>
415 <tr>
416   <td>`router`</td>
417   <td>Boolean "true" if the neighbour entry is a router (IPv6, optional)</td>
418 </tr>
419 <tr>
420   <td>`proxy`</td>
421   <td>Boolean "true" if this is a proxy entry (optional)</td>
422 </tr>
423 <tr>
424   <td>`incomplete`</td>
425   <td>Boolean "true" if the entry is in incomplete state (optional)</td>
426 </tr>
427 <tr>
428   <td>`reachable`</td>
429   <td>Boolean "true" if the entry is in reachable state (optional)</td>
430 </tr>
431 <tr>
432   <td>`stale`</td>
433   <td>Boolean "true" if the entry is stale (optional)</td>
434 </tr>
435 <tr>
436   <td>`delay`</td>
437   <td>Boolean "true" if the entry is delayed (optional)</td>
438 </tr>
439 <tr>
440   <td>`probe`</td>
441   <td>Boolean "true" if the entry is in probe state (optional)</td>
442 </tr>
443 <tr>
444   <td>`failed`</td>
445   <td>Boolean "true" if the entry is in failed state (optional)</td>
446 </tr>
447 <tr>
448   <td>`noarp`</td>
449   <td>Boolean "true" if the entry is not caused by NDP or
450       ARP (optional)</td>
451 </tr>
452 <tr>
453   <td>`permanent`</td>
454   <td>Boolean "true" if the entry was statically configured from
455       userspace (optional)</td>
456 </tr>
457 </table>
458 @usage <ul>
459 <li>Find all ARP neighbours in the LAN:
460 `luci.ip.neighbors({ dest = "192.168.0.0/16" }, function(n)
461         print(n.dest, n.mac)
462 end)`</li>
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" },
465         function(n)
466                 print(n.dest)
467         end)`</li>
468 </ul>
469 ]]
470
471 ---[[
472 Fetch basic device information
473 @class function
474 @sort 11
475 @name link
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.
479
480 <table>
481 <tr><th>Field</th><th>Description</th></tr>
482 <tr>
483   <td>`up`</td>
484   <td>Boolean indicating whether the device is in IFF_RUNNING state</td>
485 </tr>
486 <tr>
487   <td>`type`</td>
488   <td>Numeric value indicating the type of the device, e.g. `1`
489       for ethernet.</td>
490 </tr>
491 <tr>
492   <td>`name`</td>
493   <td>String containing the name of the device</td>
494 </tr>
495 <tr>
496   <td>`master`</td>
497   <td>If queried device is a bridge port, string containing the name of
498       parent bridge device (optional)</td>
499 </tr>
500 <tr>
501   <td>`mtu`</td>
502   <td>Number containing the current MTU of the device</td>
503 </tr>
504 <tr>
505   <td>`qlen`</td>
506   <td>Number containing the TX queue length of the device</td>
507 </tr>
508 <tr>
509   <td>`mac`</td>
510   <td>MAC address `luci.ip.cidr` instance representing the device ethernet
511       address</td>
512 </tr>
513 </table>
514 @usage <ul>
515 <li>Test whether device br-lan exists:
516 `print(luci.ip.link("br-lan").name ~= nil)
517 `</li>
518 <li>Query MAC address of eth0:
519 `print(luci.ip.link("eth0").mac)
520 `</li>
521 </ul>
522 ]]
523
524
525 --- IP CIDR Object.
526 -- Represents an IPv4 or IPv6 address range.
527 -- @cstyle instance
528 module "luci.ip.cidr"
529
530 ---[[
531 Checks whether the CIDR instance is an IPv4 address range
532
533 @class function
534 @sort 1
535 @name cidr.is4
536 @see cidr.is6
537 @see cidr.ismac
538 @return `true` if the CIDR is an IPv4 range, else `false`
539 ]]
540
541 ---[[
542 Checks whether the CIDR instance is within the private RFC1918 address space
543
544 @class function
545 @sort 2
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")
554 end`
555 ]]
556
557 ---[[
558 Checks whether the CIDR instance is an IPv4 link local (Zeroconf) address
559
560 @class function
561 @sort 3
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")
568 end`
569 ]]
570
571 ---[[
572 Checks whether the CIDR instance is an IPv6 address range
573
574 @class function
575 @sort 4
576 @name cidr.is6
577 @see cidr.is4
578 @see cidr.ismac
579 @return `true` if the CIDR is an IPv6 range, else `false`
580 ]]
581
582 ---[[
583 Checks whether the CIDR instance is an IPv6 link local address
584
585 @class function
586 @sort 5
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")
593 end`
594 ]]
595
596 ---[[
597 Checks whether the CIDR instance is an IPv6 mapped IPv4 address
598
599 @class function
600 @sort 6
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")
607 end`
608 ]]
609
610 ---[[
611 Checks whether the CIDR instance is an ethernet MAC address range
612
613 @class function
614 @sort 7
615 @name cidr.ismac
616 @see cidr.is4
617 @see cidr.is6
618 @return `true` if the CIDR is a MAC address range, else `false`
619 ]]
620
621 ---[[
622 Checks whether the CIDR instance is a locally administered (LAA) MAC address
623
624 @class function
625 @sort 8
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")
631 end`
632 ]]
633
634 ---[[
635 Checks whether the CIDR instance is a multicast MAC address
636
637 @class function
638 @sort 9
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")
644 end`
645 ]]
646
647 ---[[
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>
653
654 @class function
655 @sort 10
656 @name cidr.lower
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,
660         else `false`.
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`
667 @see cidr.higher
668 @see cidr.equal
669 ]]
670
671 ---[[
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>
677
678 @class function
679 @sort 11
680 @name cidr.higher
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,
684         else `false`.
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`
691 @see cidr.lower
692 @see cidr.equal
693 ]]
694
695 ---[[
696 Checks whether this CIDR instance is equal to the given argument.
697
698 @class function
699 @sort 12
700 @name cidr.equal
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,
704         else `false`.
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
709
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
713
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`
717 @see cidr.lower
718 @see cidr.higher
719 ]]
720
721 ---[[
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.
725
726 @class function
727 @sort 13
728 @name cidr.prefix
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
735
736 range:prefix(16)
737 print(range:prefix()) -- 16
738
739 range:prefix("255.255.255.255")
740 print(range:prefix()) -- 32`
741 ]]
742
743 ---[[
744 Derive network address of CIDR instance.
745
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.
749
750 @class function
751 @sort 14
752 @name cidr.network
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"
761
762 local range6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
763 print(range6:network())               -- "fd9b:62b3:9cc5::"`
764 ]]
765
766 ---[[
767 Derive host address of CIDR instance.
768
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.
771
772 @class function
773 @sort 15
774 @name cidr.host
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"`
779 ]]
780
781 ---[[
782 Derive netmask of CIDR instance.
783
784 Constructs a CIDR instance representing the netmask of this instance. The used
785 prefix size can be overridden by the optional mask parameter.
786
787 @class function
788 @sort 16
789 @name cidr.mask
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"`
798 ]]
799
800 ---[[
801 Derive broadcast address of CIDR instance.
802
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.
805
806 This function has no effect on IPv6 or MAC address instances, it will return
807 nothing in this case.
808
809 @class function
810 @sort 17
811 @name cidr.broadcast
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"`
820 ]]
821
822 ---[[
823 Derive mapped IPv4 address of CIDR instance.
824
825 Constructs a CIDR instance representing the IPv4 address of the IPv6 mapped
826 IPv4 address in this instance.
827
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.
830
831 @class function
832 @sort 18
833 @name cidr.mapped4
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"`
838 ]]
839
840 ---[[
841 Derive unscoped IPv6 address of CIDR instance.
842
843 Construct a copy of the given IPv6 CIDR instance and drop the associated
844 address scope information.
845
846 This function has no effect on IPv4 instances or MAC address instances,
847 it will return nothing in this case.
848
849 @class function
850 @sort 19
851 @name cidr.unscoped
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"`
855 ]]
856
857 ---[[
858 Derive MAC address of IPv6 link local CIDR instance.
859
860 Constructs a CIDR instance representing the MAC address contained in the IPv6
861 link local address of this instance.
862
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
865 case.
866
867 @class function
868 @sort 20
869 @name cidr.tomac
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"`
874 ]]
875
876 ---[[
877 Derive IPv6 link local address from MAC address CIDR instance.
878
879 Constructs a CIDR instance representing the IPv6 link local address of the
880 MAC address represented by this instance.
881
882 This function has no effect on IPv4 instances or IPv6 instances, it will return
883 nothing in this case.
884
885 @class function
886 @sort 21
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"`
891 ]]
892
893 ---[[
894 Test whether CIDR contains given range.
895
896 @class function
897 @sort 22
898 @name cidr.contains
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
902         `false`.
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
907
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
911
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`
915 ]]
916
917 ---[[
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.
920
921 @class function
922 @sort 23
923 @name cidr.add
924 @param amount A numeric value between 0 and 0xFFFFFFFF, a
925         `luci.ip.cidr` instance or a string convertible by
926         `luci.ip.new()`.
927 @param inplace If `true`, modify this instance instead of returning
928         a new derived CIDR instance.
929 @return <ul>
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"
938
939 addr:add(256, true)            -- true
940 print(addr)                    -- "192.168.2.1/24
941
942 addr:add("255.0.0.0", true)    -- false (overflow)
943 print(addr)                    -- "255.255.255.255/24
944
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"
948
949 addr6:add(256, true)           -- true
950 print(addr6)                   -- "fe80::221:63f:fe75:ab17/64
951
952 addr6:add("ffff::", true)      -- false (overflow)
953 print(addr6)                   -- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64"
954
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"
958
959 mac:add(256, true)             -- true
960 print(mac)                     -- "00:14:22:01:24:45"
961
962 mac:add("FF:FF:0:0:0:0", true) -- false (overflow)
963 print(mac)                     -- "FF:FF:FF:FF:FF:FF"`
964 ]]
965
966 ---[[
967 Subtract given amount from CIDR instance. If the result would under, the lowest
968 possible address is returned.
969
970 @class function
971 @sort 24
972 @name cidr.sub
973 @param amount A numeric value between 0 and 0xFFFFFFFF, a
974         `luci.ip.cidr` instance or a string convertible by
975         `luci.ip.new()`.
976 @param inplace If `true`, modify this instance instead of returning
977         a new derived CIDR instance.
978 @return <ul>
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"
987
988 addr:sub(256, true)          -- true
989 print(addr)                  -- "192.168.0.1/24
990
991 addr:sub("255.0.0.0", true)  -- false (underflow)
992 print(addr)                  -- "0.0.0.0/24
993
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"
997
998 addr:sub(256, true)          -- true
999 print(addr)                  -- "fe80::221:63f:fe75:a917/64"
1000
1001 addr:sub("ffff::", true)     -- false (underflow)
1002 print(addr)                  -- "::/64"
1003
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"
1007
1008 mac:sub(256, true)             -- true
1009 print(mac)                     -- "00:14:22:01:22:45"
1010
1011 mac:sub("FF:FF:0:0:0:0", true) -- false (overflow)
1012 print(mac)                     -- "00:00:00:00:00:00"`
1013 ]]
1014
1015 ---[[
1016 Calculate the lowest possible host address within this CIDR instance.
1017
1018 @class function
1019 @sort 25
1020 @name cidr.minhost
1021 @return Returns a new CIDR instance representing the lowest host address
1022         within this range.
1023 @usage `local addr = luci.ip.new("192.168.123.56/24")
1024 print(addr:minhost())  -- "192.168.123.1"
1025
1026 local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
1027 print(addr6:minhost()) -- "fd9b:62b3:9cc5::1"
1028
1029 local mac = luci.ip.new("00:14:22:01:22:45/32")
1030 print(mac:minhost())   -- "00:14:22:01:00:01"`
1031 ]]
1032
1033 ---[[
1034 Calculate the highest possible host address within this CIDR instance.
1035
1036 @class function
1037 @sort 26
1038 @name cidr.maxhost
1039 @return Returns a new CIDR instance representing the highest host address
1040         within this range.
1041 @usage `local addr = luci.ip.new("192.168.123.56/24")
1042 print(addr:maxhost())  -- "192.168.123.254" (.255 is broadcast)
1043
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"
1046
1047 local mac = luci.ip.new("00:14:22:01:22:45/32")
1048 print(mac:maxhost())   -- "00:14:22:01:FF:FF"`
1049 ]]
1050
1051 ---[[
1052 Convert CIDR instance into string representation.
1053
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
1056 "address".
1057
1058 It is usually not required to call this function directly as CIDR objects
1059 define it as __tostring function in the associated metatable.
1060
1061 @class function
1062 @sort 27
1063 @name cidr.string
1064 @return Returns a string representing the range or address of this CIDR instance
1065 ]]