luci-lib-ip: fix creating address instances from integers
[project/luci.git] / libs / luci-lib-ip / src / ip.c
1 /*
2 Copyright 2015-2018 Jo-Philipp Wich <jo@mein.io>
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 #define _GNU_SOURCE
18
19 #include <stdio.h>
20 #include <stdint.h>
21 #include <stdbool.h>
22 #include <unistd.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <limits.h>
26
27 #include <lua.h>
28 #include <lualib.h>
29 #include <lauxlib.h>
30
31 #include <net/if.h>
32 #include <netinet/ether.h>
33 #include <arpa/inet.h>
34 #include <netlink/msg.h>
35 #include <netlink/attr.h>
36 #include <netlink/socket.h>
37 #include <linux/rtnetlink.h>
38
39 #define LUCI_IP "luci.ip"
40 #define LUCI_IP_CIDR "luci.ip.cidr"
41
42 #define RTA_INT(x) (*(int *)RTA_DATA(x))
43 #define RTA_U32(x) (*(uint32_t *)RTA_DATA(x))
44
45 #define AF_BITS(f) \
46 ((f) == AF_INET ? 32 : \
47 ((f) == AF_INET6 ? 128 : \
48 ((f) == AF_PACKET ? 48 : 0)))
49
50 #define AF_BYTES(f) \
51 ((f) == AF_INET ? 4 : \
52 ((f) == AF_INET6 ? 16 : \
53 ((f) == AF_PACKET ? 6 : 0)))
54
55 static int hz = 0;
56 static struct nl_sock *sock = NULL;
57
58 typedef struct {
59 union {
60 struct in_addr v4;
61 struct in6_addr v6;
62 struct ether_addr mac;
63 uint8_t u8[16];
64 } addr;
65 uint32_t scope;
66 uint16_t family;
67 int16_t bits;
68 } cidr_t;
69
70 struct dump_filter {
71 bool get;
72 int family;
73 int iif;
74 int oif;
75 int type;
76 int scope;
77 int proto;
78 int table;
79 cidr_t gw;
80 cidr_t from;
81 cidr_t src;
82 cidr_t dst;
83 struct ether_addr mac;
84 bool from_exact;
85 bool dst_exact;
86 };
87
88 struct dump_state {
89 int index;
90 int pending;
91 int callback;
92 struct lua_State *L;
93 struct dump_filter *filter;
94 };
95
96
97 static int _cidr_new(lua_State *L, int index, int family, bool mask);
98
99 static cidr_t *L_checkcidr (lua_State *L, int index, cidr_t *p)
100 {
101 if (lua_type(L, index) == LUA_TUSERDATA)
102 return luaL_checkudata(L, index, LUCI_IP_CIDR);
103
104 if (_cidr_new(L, index, p ? p->family : 0, false))
105 return lua_touserdata(L, -1);
106
107 luaL_error(L, "Invalid operand");
108 return NULL;
109 }
110
111 static bool parse_mac(const char *mac, struct ether_addr *ea)
112 {
113 unsigned long int n;
114 char *e, sep = 0;
115 int i;
116
117 for (i = 0; i < 6; i++)
118 {
119 if (i > 0)
120 {
121 if (sep == 0 && (mac[0] == ':' || mac[0] == '-'))
122 sep = mac[0];
123
124 if (sep == 0 || mac[0] != sep)
125 return false;
126
127 mac++;
128 }
129
130 n = strtoul(mac, &e, 16);
131
132 if (n > 0xFF)
133 return false;
134
135 mac += (e - mac);
136 ea->ether_addr_octet[i] = n;
137 }
138
139 if (mac[0] != 0)
140 return false;
141
142 return true;
143 }
144
145 static bool parse_mask(int family, const char *mask, int16_t *bits)
146 {
147 char *e;
148 union {
149 struct in_addr v4;
150 struct in6_addr v6;
151 struct ether_addr mac;
152 uint8_t u8[16];
153 } m;
154
155 if (family == AF_INET && inet_pton(AF_INET, mask, &m.v4))
156 {
157 for (*bits = 0, m.v4.s_addr = ntohl(m.v4.s_addr);
158 *bits < AF_BITS(AF_INET) && (m.v4.s_addr << *bits) & 0x80000000;
159 ++*bits);
160 }
161 else if ((family == AF_INET6 && inet_pton(AF_INET6, mask, &m.v6)) ||
162 (family == AF_PACKET && parse_mac(mask, &m.mac)))
163 {
164 for (*bits = 0;
165 *bits < AF_BITS(family) && (m.u8[*bits / 8] << (*bits % 8)) & 128;
166 ++*bits);
167 }
168 else
169 {
170 *bits = strtoul(mask, &e, 10);
171
172 if (e == mask || *e != 0 || *bits > AF_BITS(family))
173 return false;
174 }
175
176 return true;
177 }
178
179 static bool parse_cidr(const char *dest, cidr_t *pp)
180 {
181 char *p, *s, buf[INET6_ADDRSTRLEN * 2 + 2];
182
183 strncpy(buf, dest, sizeof(buf) - 1);
184
185 p = strchr(buf, '/');
186
187 if (p)
188 *p++ = 0;
189
190 s = strchr(buf, '%');
191
192 if (s)
193 *s++ = 0;
194
195 if (inet_pton(AF_INET, buf, &pp->addr.v4))
196 pp->family = AF_INET;
197 else if (inet_pton(AF_INET6, buf, &pp->addr.v6))
198 pp->family = AF_INET6;
199 else if (parse_mac(buf, &pp->addr.mac))
200 pp->family = AF_PACKET;
201 else
202 return false;
203
204 if (s)
205 {
206 if (pp->family != AF_INET6)
207 return false;
208
209 if (!(pp->addr.v6.s6_addr[0] == 0xFE &&
210 pp->addr.v6.s6_addr[1] >= 0x80 &&
211 pp->addr.v6.s6_addr[2] <= 0xBF))
212 return false;
213
214 pp->scope = if_nametoindex(s);
215
216 if (pp->scope == 0)
217 return false;
218 }
219 else {
220 pp->scope = 0;
221 }
222
223 if (p)
224 {
225 if (!parse_mask(pp->family, p, &pp->bits))
226 return false;
227 }
228 else
229 {
230 pp->bits = AF_BITS(pp->family);
231 }
232
233 return true;
234 }
235
236 static int format_cidr(lua_State *L, cidr_t *p)
237 {
238 char *s, buf[INET6_ADDRSTRLEN + 1 + IF_NAMESIZE + 4];
239
240 if (p->family == AF_PACKET)
241 {
242 snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X",
243 p->addr.mac.ether_addr_octet[0],
244 p->addr.mac.ether_addr_octet[1],
245 p->addr.mac.ether_addr_octet[2],
246 p->addr.mac.ether_addr_octet[3],
247 p->addr.mac.ether_addr_octet[4],
248 p->addr.mac.ether_addr_octet[5]);
249
250 if (p->bits < AF_BITS(AF_PACKET))
251 lua_pushfstring(L, "%s/%d", buf, p->bits);
252 else
253 lua_pushstring(L, buf);
254 }
255 else
256 {
257 inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf));
258
259 s = buf + strlen(buf);
260
261 if (p->scope != 0 && if_indextoname(p->scope, s + 1) != NULL) {
262 *s++ = '%';
263 s += strlen(s);
264 }
265
266 if (p->bits < AF_BITS(p->family))
267 s += sprintf(s, "/%d", p->bits);
268
269 lua_pushstring(L, buf);
270 }
271
272 return 1;
273 }
274
275 static int L_getint(lua_State *L, int index, const char *name)
276 {
277 int rv = 0;
278
279 lua_getfield(L, index, name);
280
281 if (lua_type(L, -1) == LUA_TNUMBER)
282 rv = lua_tonumber(L, -1);
283
284 lua_pop(L, 1);
285
286 return rv;
287 }
288
289 static const char * L_getstr(lua_State *L, int index, const char *name)
290 {
291 const char *rv = NULL;
292
293 lua_getfield(L, index, name);
294
295 if (lua_type(L, -1) == LUA_TSTRING)
296 rv = lua_tostring(L, -1);
297
298 lua_pop(L, 1);
299
300 return rv;
301 }
302
303 static void L_setint(struct lua_State *L, const char *name, uint32_t n)
304 {
305 lua_pushinteger(L, n);
306 lua_setfield(L, -2, name);
307 }
308
309 static void L_setbool(struct lua_State *L, const char *name, bool val)
310 {
311 lua_pushboolean(L, val);
312 lua_setfield(L, -2, name);
313 }
314
315 static void L_setaddr(struct lua_State *L, const char *name,
316 int family, void *addr, int bits)
317 {
318 cidr_t *p;
319
320 if (!addr)
321 return;
322
323 p = lua_newuserdata(L, sizeof(*p));
324
325 if (!p)
326 return;
327
328 if (family == AF_INET)
329 {
330 p->family = AF_INET;
331 p->bits = (bits < 0) ? AF_BITS(AF_INET) : bits;
332 p->addr.v4 = *(struct in_addr *)addr;
333 p->scope = 0;
334 }
335 else if (family == AF_INET6)
336 {
337 p->family = AF_INET6;
338 p->bits = (bits < 0) ? AF_BITS(AF_INET6) : bits;
339 p->addr.v6 = *(struct in6_addr *)addr;
340 p->scope = 0;
341 }
342 else
343 {
344 p->family = AF_PACKET;
345 p->bits = (bits < 0) ? AF_BITS(AF_PACKET) : bits;
346 p->addr.mac = *(struct ether_addr *)addr;
347 p->scope = 0;
348 }
349
350 luaL_getmetatable(L, LUCI_IP_CIDR);
351 lua_setmetatable(L, -2);
352 lua_setfield(L, -2, name);
353 }
354
355 static void L_setstr(struct lua_State *L, const char *name, const char *val)
356 {
357 lua_pushstring(L, val);
358 lua_setfield(L, -2, name);
359 }
360
361 static void L_setdev(struct lua_State *L, const char *name,
362 struct nlattr *attr)
363 {
364 char buf[32];
365
366 if (if_indextoname(RTA_INT(attr), buf))
367 L_setstr(L, name, buf);
368 }
369
370 static int L_checkbits(lua_State *L, int index, cidr_t *p)
371 {
372 int16_t s16;
373 int bits;
374
375 if (lua_gettop(L) < index || lua_isnil(L, index))
376 {
377 bits = p->bits;
378 }
379 else if (lua_type(L, index) == LUA_TNUMBER)
380 {
381 bits = lua_tointeger(L, index);
382
383 if (bits < 0 || bits > AF_BITS(p->family))
384 return luaL_error(L, "Invalid prefix size");
385 }
386 else if (lua_type(L, index) == LUA_TSTRING)
387 {
388 if (!parse_mask(p->family, lua_tostring(L, index), &s16))
389 return luaL_error(L, "Invalid netmask format");
390
391 bits = s16;
392 }
393 else
394 {
395 return luaL_error(L, "Invalid data type");
396 }
397
398 return bits;
399 }
400
401 static int _cidr_new(lua_State *L, int index, int family, bool mask)
402 {
403 uint32_t n;
404 const char *addr;
405 cidr_t cidr = { }, *cidrp;
406
407 if (lua_type(L, index) == LUA_TNUMBER)
408 {
409 n = lua_tointeger(L, index);
410
411 if (family == AF_INET6)
412 {
413 cidr.family = AF_INET6;
414 cidr.addr.v6.s6_addr[12] = n / 0x1000000;
415 cidr.addr.v6.s6_addr[13] = n % 0x1000000 / 0x10000;
416 cidr.addr.v6.s6_addr[14] = n % 0x10000 / 0x100;
417 cidr.addr.v6.s6_addr[15] = n % 0x100;
418 }
419 else if (family == AF_INET)
420 {
421 cidr.family = AF_INET;
422 cidr.addr.v4.s_addr = htonl(n);
423 }
424 else
425 {
426 cidr.family = AF_PACKET;
427 cidr.addr.mac.ether_addr_octet[2] = n / 0x1000000;
428 cidr.addr.mac.ether_addr_octet[3] = n % 0x1000000 / 0x10000;
429 cidr.addr.mac.ether_addr_octet[4] = n % 0x10000 / 0x100;
430 cidr.addr.mac.ether_addr_octet[5] = n % 0x100;
431 }
432
433 cidr.bits = AF_BITS(cidr.family);
434 }
435 else
436 {
437 addr = luaL_checkstring(L, index);
438
439 if (!parse_cidr(addr, &cidr))
440 return 0;
441
442 if (family && cidr.family != family)
443 return 0;
444
445 if (mask)
446 cidr.bits = L_checkbits(L, index + 1, &cidr);
447 }
448
449 if (!(cidrp = lua_newuserdata(L, sizeof(*cidrp))))
450 return 0;
451
452 *cidrp = cidr;
453 luaL_getmetatable(L, LUCI_IP_CIDR);
454 lua_setmetatable(L, -2);
455 return 1;
456 }
457
458 static int cidr_new(lua_State *L)
459 {
460 return _cidr_new(L, 1, 0, true);
461 }
462
463 static int cidr_ipv4(lua_State *L)
464 {
465 return _cidr_new(L, 1, AF_INET, true);
466 }
467
468 static int cidr_ipv6(lua_State *L)
469 {
470 return _cidr_new(L, 1, AF_INET6, true);
471 }
472
473 static int cidr_mac(lua_State *L)
474 {
475 return _cidr_new(L, 1, AF_PACKET, true);
476 }
477
478 static int cidr_check(lua_State *L, int family)
479 {
480 cidr_t cidr = { }, *cidrp;
481 const char *addr;
482
483 if (lua_type(L, 1) == LUA_TSTRING)
484 {
485 addr = lua_tostring(L, 1);
486
487 if (addr && parse_cidr(addr, &cidr) && cidr.family == family)
488 return format_cidr(L, &cidr);
489 }
490 else
491 {
492 cidrp = lua_touserdata(L, 1);
493
494 if (cidrp == NULL)
495 return 0;
496
497 if (!lua_getmetatable(L, 1))
498 return 0;
499
500 lua_getfield(L, LUA_REGISTRYINDEX, LUCI_IP_CIDR);
501
502 if (!lua_rawequal(L, -1, -2))
503 cidrp = NULL;
504
505 lua_pop(L, 2);
506
507 if (cidrp != NULL && cidrp->family == family)
508 return format_cidr(L, cidrp);
509 }
510
511 return 0;
512 }
513
514 static int cidr_checkip4(lua_State *L)
515 {
516 return cidr_check(L, AF_INET);
517 }
518
519 static int cidr_checkip6(lua_State *L)
520 {
521 return cidr_check(L, AF_INET6);
522 }
523
524 static int cidr_checkmac(lua_State *L)
525 {
526 return cidr_check(L, AF_PACKET);
527 }
528
529 static int cidr_is4(lua_State *L)
530 {
531 cidr_t *p = L_checkcidr(L, 1, NULL);
532
533 lua_pushboolean(L, p->family == AF_INET);
534 return 1;
535 }
536
537 static int cidr_is4rfc1918(lua_State *L)
538 {
539 cidr_t *p = L_checkcidr(L, 1, NULL);
540 uint32_t a = htonl(p->addr.v4.s_addr);
541
542 lua_pushboolean(L, (p->family == AF_INET &&
543 ((a >= 0x0A000000 && a <= 0x0AFFFFFF) ||
544 (a >= 0xAC100000 && a <= 0xAC1FFFFF) ||
545 (a >= 0xC0A80000 && a <= 0xC0A8FFFF))));
546
547 return 1;
548 }
549
550 static int cidr_is4linklocal(lua_State *L)
551 {
552 cidr_t *p = L_checkcidr(L, 1, NULL);
553 uint32_t a = htonl(p->addr.v4.s_addr);
554
555 lua_pushboolean(L, (p->family == AF_INET &&
556 a >= 0xA9FE0000 &&
557 a <= 0xA9FEFFFF));
558
559 return 1;
560 }
561
562 static bool _is_mapped4(cidr_t *p)
563 {
564 return (p->family == AF_INET6 &&
565 p->addr.v6.s6_addr[0] == 0 &&
566 p->addr.v6.s6_addr[1] == 0 &&
567 p->addr.v6.s6_addr[2] == 0 &&
568 p->addr.v6.s6_addr[3] == 0 &&
569 p->addr.v6.s6_addr[4] == 0 &&
570 p->addr.v6.s6_addr[5] == 0 &&
571 p->addr.v6.s6_addr[6] == 0 &&
572 p->addr.v6.s6_addr[7] == 0 &&
573 p->addr.v6.s6_addr[8] == 0 &&
574 p->addr.v6.s6_addr[9] == 0 &&
575 p->addr.v6.s6_addr[10] == 0xFF &&
576 p->addr.v6.s6_addr[11] == 0xFF);
577 }
578
579 static int cidr_is6mapped4(lua_State *L)
580 {
581 cidr_t *p = L_checkcidr(L, 1, NULL);
582
583 lua_pushboolean(L, _is_mapped4(p));
584 return 1;
585 }
586
587 static int cidr_is6(lua_State *L)
588 {
589 cidr_t *p = L_checkcidr(L, 1, NULL);
590
591 lua_pushboolean(L, p->family == AF_INET6);
592 return 1;
593 }
594
595 static int cidr_is6linklocal(lua_State *L)
596 {
597 cidr_t *p = L_checkcidr(L, 1, NULL);
598
599 lua_pushboolean(L, (p->family == AF_INET6 &&
600 p->addr.v6.s6_addr[0] == 0xFE &&
601 p->addr.v6.s6_addr[1] >= 0x80 &&
602 p->addr.v6.s6_addr[1] <= 0xBF));
603
604 return 1;
605 }
606
607 static int cidr_ismac(lua_State *L)
608 {
609 cidr_t *p = L_checkcidr(L, 1, NULL);
610
611 lua_pushboolean(L, p->family == AF_PACKET);
612 return 1;
613 }
614
615 static int cidr_ismacmcast(lua_State *L)
616 {
617 cidr_t *p = L_checkcidr(L, 1, NULL);
618
619 lua_pushboolean(L, (p->family == AF_PACKET &&
620 (p->addr.mac.ether_addr_octet[0] & 0x1)));
621
622 return 1;
623 }
624
625 static int cidr_ismaclocal(lua_State *L)
626 {
627 cidr_t *p = L_checkcidr(L, 1, NULL);
628
629 lua_pushboolean(L, (p->family == AF_PACKET &&
630 (p->addr.mac.ether_addr_octet[0] & 0x2)));
631
632 return 1;
633 }
634
635 static int _cidr_cmp(lua_State *L)
636 {
637 cidr_t *a = L_checkcidr(L, 1, NULL);
638 cidr_t *b = L_checkcidr(L, 2, NULL);
639
640 if (a->family != b->family)
641 return (a->family - b->family);
642
643 return memcmp(&a->addr.v6, &b->addr.v6, AF_BYTES(a->family));
644 }
645
646 static int cidr_lower(lua_State *L)
647 {
648 lua_pushboolean(L, _cidr_cmp(L) < 0);
649 return 1;
650 }
651
652 static int cidr_higher(lua_State *L)
653 {
654 lua_pushboolean(L, _cidr_cmp(L) > 0);
655 return 1;
656 }
657
658 static int cidr_equal(lua_State *L)
659 {
660 lua_pushboolean(L, _cidr_cmp(L) == 0);
661 return 1;
662 }
663
664 static int cidr_lower_equal(lua_State *L)
665 {
666 lua_pushboolean(L, _cidr_cmp(L) <= 0);
667 return 1;
668 }
669
670 static int cidr_prefix(lua_State *L)
671 {
672 cidr_t *p = L_checkcidr(L, 1, NULL);
673 int bits = L_checkbits(L, 2, p);
674
675 p->bits = bits;
676 lua_pushinteger(L, p->bits);
677 return 1;
678 }
679
680 static void _apply_mask(cidr_t *p, int bits, bool inv)
681 {
682 uint8_t b, i;
683
684 if (bits <= 0)
685 {
686 memset(&p->addr.u8, inv * 0xFF, AF_BYTES(p->family));
687 }
688 else if (p->family == AF_INET && bits <= AF_BITS(AF_INET))
689 {
690 if (inv)
691 p->addr.v4.s_addr |= ntohl((1 << (AF_BITS(AF_INET) - bits)) - 1);
692 else
693 p->addr.v4.s_addr &= ntohl(~((1 << (AF_BITS(AF_INET) - bits)) - 1));
694 }
695 else if (bits <= AF_BITS(p->family))
696 {
697 for (i = 0; i < AF_BYTES(p->family); i++)
698 {
699 b = (bits > 8) ? 8 : bits;
700 if (inv)
701 p->addr.u8[i] |= ~((uint8_t)(0xFF << (8 - b)));
702 else
703 p->addr.u8[i] &= (uint8_t)(0xFF << (8 - b));
704 bits -= b;
705 }
706 }
707 }
708
709 static int cidr_network(lua_State *L)
710 {
711 cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
712 int bits = L_checkbits(L, 2, p1);
713
714 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
715 return 0;
716
717 *p2 = *p1;
718 p2->bits = AF_BITS(p1->family);
719 _apply_mask(p2, bits, false);
720
721 luaL_getmetatable(L, LUCI_IP_CIDR);
722 lua_setmetatable(L, -2);
723 return 1;
724 }
725
726 static int cidr_host(lua_State *L)
727 {
728 cidr_t *p1 = L_checkcidr(L, 1, NULL);
729 cidr_t *p2 = lua_newuserdata(L, sizeof(*p2));
730
731 if (!p2)
732 return 0;
733
734 *p2 = *p1;
735 p2->bits = AF_BITS(p1->family);
736
737 luaL_getmetatable(L, LUCI_IP_CIDR);
738 lua_setmetatable(L, -2);
739 return 1;
740 }
741
742 static int cidr_mask(lua_State *L)
743 {
744 cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
745 int bits = L_checkbits(L, 2, p1);
746
747 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
748 return 0;
749
750 p2->scope = 0;
751 p2->bits = AF_BITS(p1->family);
752 p2->family = p1->family;
753
754 memset(&p2->addr.v6.s6_addr, 0xFF, sizeof(p2->addr.v6.s6_addr));
755 _apply_mask(p2, bits, false);
756
757 luaL_getmetatable(L, LUCI_IP_CIDR);
758 lua_setmetatable(L, -2);
759 return 1;
760 }
761
762 static int cidr_broadcast(lua_State *L)
763 {
764 cidr_t *p1 = L_checkcidr(L, 1, NULL);
765 cidr_t *p2;
766 int bits = L_checkbits(L, 2, p1);
767
768 if (p1->family != AF_INET)
769 return 0;
770
771 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
772 return 0;
773
774 *p2 = *p1;
775 p2->bits = AF_BITS(AF_INET);
776 _apply_mask(p2, bits, true);
777
778 luaL_getmetatable(L, LUCI_IP_CIDR);
779 lua_setmetatable(L, -2);
780 return 1;
781 }
782
783 static int cidr_mapped4(lua_State *L)
784 {
785 cidr_t *p1 = L_checkcidr(L, 1, NULL);
786 cidr_t *p2;
787
788 if (!_is_mapped4(p1))
789 return 0;
790
791 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
792 return 0;
793
794 p2->scope = 0;
795 p2->family = AF_INET;
796 p2->bits = (p1->bits > AF_BITS(AF_INET)) ? AF_BITS(AF_INET) : p1->bits;
797 memcpy(&p2->addr.v4, p1->addr.v6.s6_addr + 12, sizeof(p2->addr.v4));
798
799 luaL_getmetatable(L, LUCI_IP_CIDR);
800 lua_setmetatable(L, -2);
801 return 1;
802 }
803
804 static int cidr_unscoped(lua_State *L)
805 {
806 cidr_t *p1 = L_checkcidr(L, 1, NULL);
807 cidr_t *p2;
808
809 if (p1->family != AF_INET6)
810 return 0;
811
812 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
813 return 0;
814
815 *p2 = *p1;
816 p2->scope = 0;
817
818 luaL_getmetatable(L, LUCI_IP_CIDR);
819 lua_setmetatable(L, -2);
820 return 1;
821 }
822
823 static int cidr_tolinklocal(lua_State *L)
824 {
825 cidr_t *p1 = L_checkcidr(L, 1, NULL);
826 cidr_t *p2;
827 int i;
828
829 if (p1->family != AF_PACKET)
830 return 0;
831
832 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
833 return 0;
834
835 p2->scope = p1->scope;
836 p2->family = AF_INET6;
837 p2->bits = AF_BITS(AF_INET6);
838 p2->addr.u8[0] = 0xFE;
839 p2->addr.u8[1] = 0x80;
840 p2->addr.u8[2] = 0x00;
841 p2->addr.u8[3] = 0x00;
842 p2->addr.u8[4] = 0x00;
843 p2->addr.u8[5] = 0x00;
844 p2->addr.u8[6] = 0x00;
845 p2->addr.u8[7] = 0x00;
846 p2->addr.u8[8] = p1->addr.u8[0] ^ 0x02;
847 p2->addr.u8[9] = p1->addr.u8[1];
848 p2->addr.u8[10] = p1->addr.u8[2];
849 p2->addr.u8[11] = 0xFF;
850 p2->addr.u8[12] = 0xFE;
851 p2->addr.u8[13] = p1->addr.u8[3];
852 p2->addr.u8[14] = p1->addr.u8[4];
853 p2->addr.u8[15] = p1->addr.u8[5];
854
855 luaL_getmetatable(L, LUCI_IP_CIDR);
856 lua_setmetatable(L, -2);
857 return 1;
858 }
859
860 static int cidr_tomac(lua_State *L)
861 {
862 cidr_t *p1 = L_checkcidr(L, 1, NULL);
863 cidr_t *p2;
864 int i;
865
866 if (p1->family != AF_INET6 ||
867 p1->addr.u8[0] != 0xFE ||
868 p1->addr.u8[1] != 0x80 ||
869 p1->addr.u8[2] != 0x00 ||
870 p1->addr.u8[3] != 0x00 ||
871 p1->addr.u8[4] != 0x00 ||
872 p1->addr.u8[5] != 0x00 ||
873 p1->addr.u8[6] != 0x00 ||
874 p1->addr.u8[7] != 0x00 ||
875 p1->addr.u8[11] != 0xFF ||
876 p1->addr.u8[12] != 0xFE)
877 return 0;
878
879 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
880 return 0;
881
882 p2->scope = 0;
883 p2->family = AF_PACKET;
884 p2->bits = AF_BITS(AF_PACKET);
885 p2->addr.u8[0] = p1->addr.u8[8] ^ 0x02;
886 p2->addr.u8[1] = p1->addr.u8[9];
887 p2->addr.u8[2] = p1->addr.u8[10];
888 p2->addr.u8[3] = p1->addr.u8[13];
889 p2->addr.u8[4] = p1->addr.u8[14];
890 p2->addr.u8[5] = p1->addr.u8[15];
891
892 luaL_getmetatable(L, LUCI_IP_CIDR);
893 lua_setmetatable(L, -2);
894 return 1;
895 }
896
897 static int cidr_contains(lua_State *L)
898 {
899 cidr_t *p1 = L_checkcidr(L, 1, NULL);
900 cidr_t *p2 = L_checkcidr(L, 2, NULL);
901 cidr_t a = *p1, b = *p2;
902 bool rv = false;
903
904 if (p1->family == p2->family && p1->bits <= p2->bits)
905 {
906 _apply_mask(&a, p1->bits, false);
907 _apply_mask(&b, p1->bits, false);
908
909 rv = !memcmp(&a.addr.v6, &b.addr.v6, AF_BYTES(a.family));
910 }
911
912 lua_pushboolean(L, rv);
913 return 1;
914 }
915
916 #define BYTE(a, i) \
917 (a)->addr.u8[AF_BYTES((a)->family) - (i) - 1]
918
919 static int _cidr_add_sub(lua_State *L, bool add)
920 {
921 cidr_t *p1 = L_checkcidr(L, 1, NULL);
922 cidr_t *p2 = L_checkcidr(L, 2, p1);
923 cidr_t r = *p1;
924 bool inplace = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : false;
925 bool ok = true;
926 uint8_t i, carry;
927 uint32_t a, b;
928
929 if (p1->family == p2->family)
930 {
931 if (p1->family == AF_INET)
932 {
933 a = ntohl(p1->addr.v4.s_addr);
934 b = ntohl(p2->addr.v4.s_addr);
935
936 /* would over/underflow */
937 if ((add && (UINT_MAX - a) < b) || (!add && a < b))
938 {
939 r.addr.v4.s_addr = add * 0xFFFFFFFF;
940 ok = false;
941 }
942 else
943 {
944 r.addr.v4.s_addr = add ? htonl(a + b) : htonl(a - b);
945 }
946 }
947 else
948 {
949 for (i = 0, carry = 0; i < AF_BYTES(p1->family); i++)
950 {
951 if (add)
952 {
953 BYTE(&r, i) = BYTE(p1, i) + BYTE(p2, i) + carry;
954 carry = (BYTE(p1, i) + BYTE(p2, i) + carry) / 256;
955 }
956 else
957 {
958 BYTE(&r, i) = (BYTE(p1, i) - BYTE(p2, i) - carry);
959 carry = (BYTE(p1, i) < (BYTE(p2, i) + carry));
960 }
961 }
962
963 /* would over/underflow */
964 if (carry)
965 {
966 memset(&r.addr.u8, add * 0xFF, AF_BYTES(r.family));
967 ok = false;
968 }
969 }
970 }
971 else
972 {
973 ok = false;
974 }
975
976 if (inplace)
977 {
978 *p1 = r;
979 lua_pushboolean(L, ok);
980 return 1;
981 }
982
983 if (!(p1 = lua_newuserdata(L, sizeof(*p1))))
984 return 0;
985
986 *p1 = r;
987
988 luaL_getmetatable(L, LUCI_IP_CIDR);
989 lua_setmetatable(L, -2);
990 return 1;
991 }
992
993 static int cidr_add(lua_State *L)
994 {
995 return _cidr_add_sub(L, true);
996 }
997
998 static int cidr_sub(lua_State *L)
999 {
1000 return _cidr_add_sub(L, false);
1001 }
1002
1003 static int cidr_minhost(lua_State *L)
1004 {
1005 cidr_t *p = L_checkcidr(L, 1, NULL);
1006 cidr_t r = *p;
1007 uint8_t i, rest, carry;
1008
1009 _apply_mask(&r, r.bits, false);
1010
1011 if (r.family == AF_INET && r.bits < AF_BITS(AF_INET))
1012 {
1013 r.bits = AF_BITS(AF_INET);
1014 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) + 1);
1015 }
1016 else if (r.bits < AF_BITS(r.family))
1017 {
1018 r.bits = AF_BITS(r.family);
1019
1020 for (i = 0, carry = 1; i < AF_BYTES(r.family); i++)
1021 {
1022 rest = (BYTE(&r, i) + carry) > 255;
1023 BYTE(&r, i) += carry;
1024 carry = rest;
1025 }
1026 }
1027
1028 if (!(p = lua_newuserdata(L, sizeof(*p))))
1029 return 0;
1030
1031 *p = r;
1032
1033 luaL_getmetatable(L, LUCI_IP_CIDR);
1034 lua_setmetatable(L, -2);
1035 return 1;
1036 }
1037
1038 static int cidr_maxhost(lua_State *L)
1039 {
1040 cidr_t *p = L_checkcidr(L, 1, NULL);
1041 cidr_t r = *p;
1042
1043 _apply_mask(&r, r.bits, true);
1044
1045 if (r.family == AF_INET && r.bits < AF_BITS(AF_INET))
1046 {
1047 r.bits = AF_BITS(AF_INET);
1048 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) - 1);
1049 }
1050 else
1051 {
1052 r.bits = AF_BITS(r.family);
1053 }
1054
1055 if (!(p = lua_newuserdata(L, sizeof(*p))))
1056 return 0;
1057
1058 *p = r;
1059
1060 luaL_getmetatable(L, LUCI_IP_CIDR);
1061 lua_setmetatable(L, -2);
1062 return 1;
1063 }
1064
1065 static int cidr_gc (lua_State *L)
1066 {
1067 return 0;
1068 }
1069
1070 static int cidr_tostring (lua_State *L)
1071 {
1072 cidr_t *p = L_checkcidr(L, 1, NULL);
1073 return format_cidr(L, p);
1074 }
1075
1076 /*
1077 * route functions
1078 */
1079
1080 static bool diff_prefix(int family, void *addr, int bits, bool exact, cidr_t *p)
1081 {
1082 uint8_t i, b, r, *a;
1083 uint32_t m;
1084
1085 if (!p->family)
1086 return false;
1087
1088 if (!addr || p->family != family || p->bits > bits)
1089 return true;
1090
1091 if (family == AF_INET)
1092 {
1093 m = p->bits ? htonl(~((1 << (AF_BITS(AF_INET) - p->bits)) - 1)) : 0;
1094
1095 if ((((struct in_addr *)addr)->s_addr & m) != (p->addr.v4.s_addr & m))
1096 return true;
1097 }
1098 else
1099 {
1100 for (i = 0, a = addr, r = p->bits; i < AF_BYTES(p->family); i++)
1101 {
1102 b = r ? (0xFF << (8 - ((r > 8) ? 8 : r))) : 0;
1103
1104 if ((a[i] & b) != (p->addr.u8[i] & b))
1105 return true;
1106
1107 r -= ((r > 8) ? 8 : r);
1108 }
1109 }
1110
1111 return (exact && p->bits != bits);
1112 }
1113
1114 static int cb_dump_route(struct nl_msg *msg, void *arg)
1115 {
1116 struct dump_state *s = arg;
1117 struct dump_filter *f = s->filter;
1118 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1119 struct rtmsg *rt = NLMSG_DATA(hdr);
1120 struct nlattr *tb[RTA_MAX+1];
1121 struct in6_addr *src, *dst, *gw, *from, def = { };
1122 int iif, oif, bitlen;
1123 uint32_t table;
1124
1125 if (hdr->nlmsg_type != RTM_NEWROUTE ||
1126 (rt->rtm_family != AF_INET && rt->rtm_family != AF_INET6))
1127 return NL_SKIP;
1128
1129 nlmsg_parse(hdr, sizeof(*rt), tb, RTA_MAX, NULL);
1130
1131 iif = tb[RTA_IIF] ? RTA_INT(tb[RTA_IIF]) : 0;
1132 oif = tb[RTA_OIF] ? RTA_INT(tb[RTA_OIF]) : 0;
1133 table = tb[RTA_TABLE] ? RTA_U32(tb[RTA_TABLE]) : rt->rtm_table;
1134 from = tb[RTA_SRC] ? RTA_DATA(tb[RTA_SRC]) : NULL;
1135 src = tb[RTA_PREFSRC] ? RTA_DATA(tb[RTA_PREFSRC]) : NULL;
1136 dst = tb[RTA_DST] ? RTA_DATA(tb[RTA_DST]) : &def;
1137 gw = tb[RTA_GATEWAY] ? RTA_DATA(tb[RTA_GATEWAY]) : NULL;
1138
1139 bitlen = AF_BITS(rt->rtm_family);
1140
1141 if (!f->get) {
1142 if ((f->type && rt->rtm_type != f->type) ||
1143 (f->family && rt->rtm_family != f->family) ||
1144 (f->proto && rt->rtm_protocol != f->proto) ||
1145 (f->scope && rt->rtm_scope != f->scope) ||
1146 (f->iif && iif != f->iif) ||
1147 (f->oif && oif != f->oif) ||
1148 (f->table && table != f->table) ||
1149 diff_prefix(rt->rtm_family, from, rt->rtm_src_len,
1150 f->from_exact, &f->from) ||
1151 diff_prefix(rt->rtm_family, dst, rt->rtm_dst_len,
1152 f->dst_exact, &f->dst) ||
1153 diff_prefix(rt->rtm_family, gw, bitlen,
1154 false, &f->gw) ||
1155 diff_prefix(rt->rtm_family, src, bitlen,
1156 false, &f->src))
1157 goto out;
1158 }
1159
1160 if (s->callback)
1161 lua_pushvalue(s->L, 2);
1162
1163 lua_newtable(s->L);
1164
1165 L_setint(s->L, "type", rt->rtm_type);
1166 L_setint(s->L, "family", (rt->rtm_family == AF_INET) ? 4 : 6);
1167
1168 L_setaddr(s->L, "dest", rt->rtm_family, dst, rt->rtm_dst_len);
1169
1170 if (gw)
1171 L_setaddr(s->L, "gw", rt->rtm_family, gw, -1);
1172
1173 if (from)
1174 L_setaddr(s->L, "from", rt->rtm_family, from, rt->rtm_src_len);
1175
1176 if (iif)
1177 L_setdev(s->L, "iif", tb[RTA_IIF]);
1178
1179 if (oif)
1180 L_setdev(s->L, "dev", tb[RTA_OIF]);
1181
1182 L_setint(s->L, "table", table);
1183 L_setint(s->L, "proto", rt->rtm_protocol);
1184 L_setint(s->L, "scope", rt->rtm_scope);
1185
1186 if (src)
1187 L_setaddr(s->L, "src", rt->rtm_family, src, -1);
1188
1189 if (tb[RTA_PRIORITY])
1190 L_setint(s->L, "metric", RTA_U32(tb[RTA_PRIORITY]));
1191
1192 if (rt->rtm_family == AF_INET6 && tb[RTA_CACHEINFO])
1193 {
1194 struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]);
1195
1196 if (ci->rta_expires)
1197 {
1198 if (ci->rta_expires)
1199 L_setint(s->L, "expires", ci->rta_expires / hz);
1200
1201 if (ci->rta_error != 0)
1202 L_setint(s->L, "error", ci->rta_error);
1203 }
1204 }
1205
1206 s->index++;
1207
1208 if (s->callback)
1209 lua_call(s->L, 1, 0);
1210 else if (hdr->nlmsg_flags & NLM_F_MULTI)
1211 lua_rawseti(s->L, -2, s->index);
1212
1213 out:
1214 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1215 return NL_SKIP;
1216 }
1217
1218 static int
1219 cb_done(struct nl_msg *msg, void *arg)
1220 {
1221 struct dump_state *s = arg;
1222 s->pending = 0;
1223 return NL_STOP;
1224 }
1225
1226 static int
1227 cb_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
1228 {
1229 struct dump_state *s = arg;
1230 s->pending = 0;
1231 return NL_STOP;
1232 }
1233
1234 static int _error(lua_State *L, int code, const char *msg)
1235 {
1236 lua_pushnil(L);
1237 lua_pushnumber(L, code ? code : errno);
1238 lua_pushstring(L, msg ? msg : strerror(errno));
1239
1240 return 3;
1241 }
1242
1243 static int _route_dump(lua_State *L, struct dump_filter *filter)
1244 {
1245 int flags = NLM_F_REQUEST;
1246 struct dump_state s = {
1247 .L = L,
1248 .pending = 1,
1249 .index = 0,
1250 .callback = lua_isfunction(L, 2),
1251 .filter = filter
1252 };
1253
1254 if (!hz)
1255 hz = sysconf(_SC_CLK_TCK);
1256
1257 if (!sock)
1258 {
1259 sock = nl_socket_alloc();
1260 if (!sock)
1261 return _error(L, -1, "Out of memory");
1262
1263 if (nl_connect(sock, NETLINK_ROUTE))
1264 return _error(L, 0, NULL);
1265 }
1266
1267 struct nl_msg *msg;
1268 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1269 struct rtmsg rtm = {
1270 .rtm_family = filter->family,
1271 .rtm_dst_len = filter->dst.bits,
1272 .rtm_src_len = filter->src.bits
1273 };
1274
1275 if (!filter->get)
1276 flags |= NLM_F_DUMP;
1277
1278 msg = nlmsg_alloc_simple(RTM_GETROUTE, flags);
1279 if (!msg)
1280 goto out;
1281
1282 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
1283
1284 if (filter->get) {
1285 nla_put(msg, RTA_DST, AF_BYTES(filter->dst.family),
1286 &filter->dst.addr.v6);
1287
1288 if (filter->src.family)
1289 nla_put(msg, RTA_SRC, AF_BYTES(filter->src.family),
1290 &filter->src.addr.v6);
1291 }
1292
1293 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_route, &s);
1294 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &s);
1295 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &s);
1296
1297 nl_send_auto_complete(sock, msg);
1298
1299 if (!filter->get && !s.callback)
1300 lua_newtable(L);
1301
1302 while (s.pending > 0)
1303 nl_recvmsgs(sock, cb);
1304
1305 nlmsg_free(msg);
1306
1307 out:
1308 nl_cb_put(cb);
1309
1310 if (s.callback)
1311 return 0;
1312
1313 if (!filter->get)
1314 return 1;
1315
1316 return (s.index > 0);
1317 }
1318
1319 static int route_get(lua_State *L)
1320 {
1321 struct dump_filter filter = { .get = true };
1322 const char *dest = luaL_checkstring(L, 1);
1323 const char *from = luaL_optstring(L, 2, NULL);
1324
1325 if (!parse_cidr(dest, &filter.dst))
1326 return _error(L, -1, "Invalid destination");
1327
1328 if (from && !parse_cidr(from, &filter.src))
1329 return _error(L, -1, "Invalid source");
1330
1331 if (filter.src.family != 0 &&
1332 filter.src.family != filter.dst.family)
1333 return _error(L, -1, "Different source/destination family");
1334
1335 filter.family = filter.dst.family;
1336
1337 return _route_dump(L, &filter);
1338 }
1339
1340 static int route_dump(lua_State *L)
1341 {
1342 const char *s;
1343 cidr_t p = { };
1344 struct dump_filter filter = { };
1345
1346 if (lua_type(L, 1) == LUA_TTABLE)
1347 {
1348 filter.family = L_getint(L, 1, "family");
1349
1350 if (filter.family == 4)
1351 filter.family = AF_INET;
1352 else if (filter.family == 6)
1353 filter.family = AF_INET6;
1354 else
1355 filter.family = 0;
1356
1357 if ((s = L_getstr(L, 1, "iif")) != NULL)
1358 filter.iif = if_nametoindex(s);
1359
1360 if ((s = L_getstr(L, 1, "oif")) != NULL)
1361 filter.oif = if_nametoindex(s);
1362
1363 filter.type = L_getint(L, 1, "type");
1364 filter.scope = L_getint(L, 1, "scope");
1365 filter.proto = L_getint(L, 1, "proto");
1366 filter.table = L_getint(L, 1, "table");
1367
1368 if ((s = L_getstr(L, 1, "gw")) != NULL && parse_cidr(s, &p))
1369 filter.gw = p;
1370
1371 if ((s = L_getstr(L, 1, "from")) != NULL && parse_cidr(s, &p))
1372 filter.from = p;
1373
1374 if ((s = L_getstr(L, 1, "src")) != NULL && parse_cidr(s, &p))
1375 filter.src = p;
1376
1377 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1378 filter.dst = p;
1379
1380 if ((s = L_getstr(L, 1, "from_exact")) != NULL && parse_cidr(s, &p))
1381 filter.from = p, filter.from_exact = true;
1382
1383 if ((s = L_getstr(L, 1, "dest_exact")) != NULL && parse_cidr(s, &p))
1384 filter.dst = p, filter.dst_exact = true;
1385 }
1386
1387 return _route_dump(L, &filter);
1388 }
1389
1390
1391 static bool diff_macaddr(struct ether_addr *mac1, struct ether_addr *mac2)
1392 {
1393 struct ether_addr empty = { };
1394
1395 if (!memcmp(mac2, &empty, sizeof(empty)))
1396 return false;
1397
1398 if (!mac1 || memcmp(mac1, mac2, sizeof(empty)))
1399 return true;
1400
1401 return false;
1402 }
1403
1404 static int cb_dump_neigh(struct nl_msg *msg, void *arg)
1405 {
1406 char buf[32];
1407 struct ether_addr *mac;
1408 struct in6_addr *dst;
1409 struct dump_state *s = arg;
1410 struct dump_filter *f = s->filter;
1411 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1412 struct ndmsg *nd = NLMSG_DATA(hdr);
1413 struct nlattr *tb[NDA_MAX+1];
1414 int bitlen;
1415
1416 if (hdr->nlmsg_type != RTM_NEWNEIGH ||
1417 (nd->ndm_family != AF_INET && nd->ndm_family != AF_INET6))
1418 return NL_SKIP;
1419
1420 nlmsg_parse(hdr, sizeof(*nd), tb, NDA_MAX, NULL);
1421
1422 mac = tb[NDA_LLADDR] ? RTA_DATA(tb[NDA_LLADDR]) : NULL;
1423 dst = tb[NDA_DST] ? RTA_DATA(tb[NDA_DST]) : NULL;
1424
1425 bitlen = AF_BITS(nd->ndm_family);
1426
1427 if ((f->family && nd->ndm_family != f->family) ||
1428 (f->iif && nd->ndm_ifindex != f->iif) ||
1429 (f->type && !(f->type & nd->ndm_state)) ||
1430 diff_prefix(nd->ndm_family, dst, bitlen, false, &f->dst) ||
1431 diff_macaddr(mac, &f->mac))
1432 goto out;
1433
1434 if (s->callback)
1435 lua_pushvalue(s->L, 2);
1436
1437 lua_newtable(s->L);
1438
1439 L_setint(s->L, "family", (nd->ndm_family == AF_INET) ? 4 : 6);
1440 L_setstr(s->L, "dev", if_indextoname(nd->ndm_ifindex, buf));
1441
1442 L_setbool(s->L, "router", (nd->ndm_flags & NTF_ROUTER));
1443 L_setbool(s->L, "proxy", (nd->ndm_flags & NTF_PROXY));
1444
1445 L_setbool(s->L, "incomplete", (nd->ndm_state & NUD_INCOMPLETE));
1446 L_setbool(s->L, "reachable", (nd->ndm_state & NUD_REACHABLE));
1447 L_setbool(s->L, "stale", (nd->ndm_state & NUD_STALE));
1448 L_setbool(s->L, "delay", (nd->ndm_state & NUD_DELAY));
1449 L_setbool(s->L, "probe", (nd->ndm_state & NUD_PROBE));
1450 L_setbool(s->L, "failed", (nd->ndm_state & NUD_FAILED));
1451 L_setbool(s->L, "noarp", (nd->ndm_state & NUD_NOARP));
1452 L_setbool(s->L, "permanent", (nd->ndm_state & NUD_PERMANENT));
1453
1454 if (dst)
1455 L_setaddr(s->L, "dest", nd->ndm_family, dst, -1);
1456
1457 if (mac)
1458 L_setaddr(s->L, "mac", AF_PACKET, mac, -1);
1459
1460 s->index++;
1461
1462 if (s->callback)
1463 lua_call(s->L, 1, 0);
1464 else if (hdr->nlmsg_flags & NLM_F_MULTI)
1465 lua_rawseti(s->L, -2, s->index);
1466
1467 out:
1468 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1469 return NL_SKIP;
1470 }
1471
1472 static int neighbor_dump(lua_State *L)
1473 {
1474 cidr_t p = { };
1475 const char *s;
1476 struct ether_addr *mac;
1477 struct dump_filter filter = { .type = 0xFF & ~NUD_NOARP };
1478 struct dump_state st = {
1479 .callback = lua_isfunction(L, 2),
1480 .pending = 1,
1481 .filter = &filter,
1482 .L = L
1483 };
1484
1485 if (lua_type(L, 1) == LUA_TTABLE)
1486 {
1487 filter.family = L_getint(L, 1, "family");
1488
1489 if (filter.family == 4)
1490 filter.family = AF_INET;
1491 else if (filter.family == 6)
1492 filter.family = AF_INET6;
1493 else
1494 filter.family = 0;
1495
1496 if ((s = L_getstr(L, 1, "dev")) != NULL)
1497 filter.iif = if_nametoindex(s);
1498
1499 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1500 filter.dst = p;
1501
1502 if ((s = L_getstr(L, 1, "mac")) != NULL &&
1503 (mac = ether_aton(s)) != NULL)
1504 filter.mac = *mac;
1505 }
1506
1507 if (!sock)
1508 {
1509 sock = nl_socket_alloc();
1510 if (!sock)
1511 return _error(L, -1, "Out of memory");
1512
1513 if (nl_connect(sock, NETLINK_ROUTE))
1514 return _error(L, 0, NULL);
1515 }
1516
1517 struct nl_msg *msg;
1518 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1519 struct ndmsg ndm = {
1520 .ndm_family = filter.family
1521 };
1522
1523 msg = nlmsg_alloc_simple(RTM_GETNEIGH, NLM_F_REQUEST | NLM_F_DUMP);
1524 if (!msg)
1525 goto out;
1526
1527 nlmsg_append(msg, &ndm, sizeof(ndm), 0);
1528
1529 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_neigh, &st);
1530 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1531 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1532
1533 nl_send_auto_complete(sock, msg);
1534
1535 if (!st.callback)
1536 lua_newtable(L);
1537
1538 while (st.pending > 0)
1539 nl_recvmsgs(sock, cb);
1540
1541 nlmsg_free(msg);
1542
1543 out:
1544 nl_cb_put(cb);
1545 return (st.callback == 0);
1546 }
1547
1548
1549 static int cb_dump_link(struct nl_msg *msg, void *arg)
1550 {
1551 char buf[48];
1552 struct dump_state *s = arg;
1553 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1554 struct ifinfomsg *ifm = NLMSG_DATA(hdr);
1555 struct nlattr *tb[IFLA_MAX+1];
1556 int i, len;
1557
1558 if (hdr->nlmsg_type != RTM_NEWLINK)
1559 return NL_SKIP;
1560
1561 nlmsg_parse(hdr, sizeof(*ifm), tb, IFLA_MAX, NULL);
1562
1563 L_setbool(s->L, "up", (ifm->ifi_flags & IFF_RUNNING));
1564 L_setint(s->L, "type", ifm->ifi_type);
1565 L_setstr(s->L, "name", if_indextoname(ifm->ifi_index, buf));
1566
1567 if (tb[IFLA_MTU])
1568 L_setint(s->L, "mtu", RTA_U32(tb[IFLA_MTU]));
1569
1570 if (tb[IFLA_TXQLEN])
1571 L_setint(s->L, "qlen", RTA_U32(tb[IFLA_TXQLEN]));
1572
1573 if (tb[IFLA_MASTER])
1574 L_setdev(s->L, "master", tb[IFLA_MASTER]);
1575
1576 if (tb[IFLA_ADDRESS] && nla_len(tb[IFLA_ADDRESS]) == AF_BYTES(AF_PACKET))
1577 L_setaddr(s->L, "mac", AF_PACKET, nla_get_string(tb[IFLA_ADDRESS]), -1);
1578
1579 s->pending = 0;
1580 return NL_SKIP;
1581 }
1582
1583 static int link_get(lua_State *L)
1584 {
1585 const char *dev = luaL_checkstring(L, 1);
1586 struct dump_state st = {
1587 .pending = 1,
1588 .L = L
1589 };
1590
1591 if (!sock)
1592 {
1593 sock = nl_socket_alloc();
1594 if (!sock)
1595 return _error(L, -1, "Out of memory");
1596
1597 if (nl_connect(sock, NETLINK_ROUTE))
1598 return _error(L, 0, NULL);
1599 }
1600
1601 struct nl_msg *msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST);
1602 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1603 struct ifinfomsg ifm = { .ifi_index = if_nametoindex(dev) };
1604
1605 if (!msg || !cb)
1606 return 0;
1607
1608 nlmsg_append(msg, &ifm, sizeof(ifm), 0);
1609
1610 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_link, &st);
1611 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1612 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1613
1614 lua_newtable(L);
1615
1616 nl_send_auto_complete(sock, msg);
1617
1618 while (st.pending > 0)
1619 nl_recvmsgs(sock, cb);
1620
1621 nlmsg_free(msg);
1622 nl_cb_put(cb);
1623
1624 return 1;
1625 }
1626
1627
1628 static const luaL_reg ip_methods[] = {
1629 { "new", cidr_new },
1630 { "IPv4", cidr_ipv4 },
1631 { "IPv6", cidr_ipv6 },
1632 { "MAC", cidr_mac },
1633
1634 { "checkip4", cidr_checkip4 },
1635 { "checkip6", cidr_checkip6 },
1636 { "checkmac", cidr_checkmac },
1637
1638 { "route", route_get },
1639 { "routes", route_dump },
1640
1641 { "neighbors", neighbor_dump },
1642
1643 { "link", link_get },
1644
1645 { }
1646 };
1647
1648 static const luaL_reg ip_cidr_methods[] = {
1649 { "is4", cidr_is4 },
1650 { "is4rfc1918", cidr_is4rfc1918 },
1651 { "is4linklocal", cidr_is4linklocal },
1652 { "is6", cidr_is6 },
1653 { "is6linklocal", cidr_is6linklocal },
1654 { "is6mapped4", cidr_is6mapped4 },
1655 { "ismac", cidr_ismac },
1656 { "ismaclocal", cidr_ismaclocal },
1657 { "ismacmcast", cidr_ismacmcast },
1658 { "lower", cidr_lower },
1659 { "higher", cidr_higher },
1660 { "equal", cidr_equal },
1661 { "prefix", cidr_prefix },
1662 { "network", cidr_network },
1663 { "host", cidr_host },
1664 { "mask", cidr_mask },
1665 { "broadcast", cidr_broadcast },
1666 { "mapped4", cidr_mapped4 },
1667 { "unscoped", cidr_unscoped },
1668 { "tomac", cidr_tomac },
1669 { "tolinklocal", cidr_tolinklocal },
1670 { "contains", cidr_contains },
1671 { "add", cidr_add },
1672 { "sub", cidr_sub },
1673 { "minhost", cidr_minhost },
1674 { "maxhost", cidr_maxhost },
1675 { "string", cidr_tostring },
1676
1677 { "__lt", cidr_lower },
1678 { "__le", cidr_lower_equal },
1679 { "__eq", cidr_equal },
1680 { "__add", cidr_add },
1681 { "__sub", cidr_sub },
1682 { "__gc", cidr_gc },
1683 { "__tostring", cidr_tostring },
1684
1685 { }
1686 };
1687
1688 int luaopen_luci_ip(lua_State *L)
1689 {
1690 luaL_register(L, LUCI_IP, ip_methods);
1691
1692 luaL_newmetatable(L, LUCI_IP_CIDR);
1693 luaL_register(L, NULL, ip_cidr_methods);
1694 lua_pushvalue(L, -1);
1695 lua_setfield(L, -2, "__index");
1696 lua_pop(L, 1);
1697
1698 return 1;
1699 }