Translated using Weblate (French)
[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 = htonl(lua_tointeger(L, index));
410
411 if (family == AF_INET6)
412 {
413 cidr.family = AF_INET6;
414 cidr.addr.v6.s6_addr[12] = n;
415 cidr.addr.v6.s6_addr[13] = (n >> 8);
416 cidr.addr.v6.s6_addr[14] = (n >> 16);
417 cidr.addr.v6.s6_addr[15] = (n >> 24);
418 }
419 else if (family == AF_INET)
420 {
421 cidr.family = AF_INET;
422 cidr.addr.v4.s_addr = n;
423 }
424 else
425 {
426 cidr.family = AF_PACKET;
427 cidr.addr.mac.ether_addr_octet[2] = n;
428 cidr.addr.mac.ether_addr_octet[3] = (n >> 8);
429 cidr.addr.mac.ether_addr_octet[4] = (n >> 16);
430 cidr.addr.mac.ether_addr_octet[5] = (n >> 24);
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[8] = p1->addr.u8[0] ^ 0x02;
841 p2->addr.u8[9] = p1->addr.u8[1];
842 p2->addr.u8[10] = p1->addr.u8[2];
843 p2->addr.u8[11] = 0xFF;
844 p2->addr.u8[12] = 0xFE;
845 p2->addr.u8[13] = p1->addr.u8[3];
846 p2->addr.u8[14] = p1->addr.u8[4];
847 p2->addr.u8[15] = p1->addr.u8[5];
848
849 luaL_getmetatable(L, LUCI_IP_CIDR);
850 lua_setmetatable(L, -2);
851 return 1;
852 }
853
854 static int cidr_tomac(lua_State *L)
855 {
856 cidr_t *p1 = L_checkcidr(L, 1, NULL);
857 cidr_t *p2;
858 int i;
859
860 if (p1->family != AF_INET6 ||
861 p1->addr.u8[0] != 0xFE ||
862 p1->addr.u8[1] != 0x80 ||
863 p1->addr.u8[2] != 0x00 ||
864 p1->addr.u8[3] != 0x00 ||
865 p1->addr.u8[4] != 0x00 ||
866 p1->addr.u8[5] != 0x00 ||
867 p1->addr.u8[6] != 0x00 ||
868 p1->addr.u8[7] != 0x00 ||
869 p1->addr.u8[11] != 0xFF ||
870 p1->addr.u8[12] != 0xFE)
871 return 0;
872
873 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
874 return 0;
875
876 p2->scope = 0;
877 p2->family = AF_PACKET;
878 p2->bits = AF_BITS(AF_PACKET);
879 p2->addr.u8[0] = p1->addr.u8[8] ^ 0x02;
880 p2->addr.u8[1] = p1->addr.u8[9];
881 p2->addr.u8[2] = p1->addr.u8[10];
882 p2->addr.u8[3] = p1->addr.u8[13];
883 p2->addr.u8[4] = p1->addr.u8[14];
884 p2->addr.u8[5] = p1->addr.u8[15];
885
886 luaL_getmetatable(L, LUCI_IP_CIDR);
887 lua_setmetatable(L, -2);
888 return 1;
889 }
890
891 static int cidr_contains(lua_State *L)
892 {
893 cidr_t *p1 = L_checkcidr(L, 1, NULL);
894 cidr_t *p2 = L_checkcidr(L, 2, NULL);
895 cidr_t a = *p1, b = *p2;
896 bool rv = false;
897
898 if (p1->family == p2->family && p1->bits <= p2->bits)
899 {
900 _apply_mask(&a, p1->bits, false);
901 _apply_mask(&b, p1->bits, false);
902
903 rv = !memcmp(&a.addr.v6, &b.addr.v6, AF_BYTES(a.family));
904 }
905
906 lua_pushboolean(L, rv);
907 return 1;
908 }
909
910 #define BYTE(a, i) \
911 (a)->addr.u8[AF_BYTES((a)->family) - (i) - 1]
912
913 static int _cidr_add_sub(lua_State *L, bool add)
914 {
915 cidr_t *p1 = L_checkcidr(L, 1, NULL);
916 cidr_t *p2 = L_checkcidr(L, 2, p1);
917 cidr_t r = *p1;
918 bool inplace = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : false;
919 bool ok = true;
920 uint8_t i, carry;
921 uint32_t a, b;
922
923 if (p1->family == p2->family)
924 {
925 if (p1->family == AF_INET)
926 {
927 a = ntohl(p1->addr.v4.s_addr);
928 b = ntohl(p2->addr.v4.s_addr);
929
930 /* would over/underflow */
931 if ((add && (UINT_MAX - a) < b) || (!add && a < b))
932 {
933 r.addr.v4.s_addr = add * 0xFFFFFFFF;
934 ok = false;
935 }
936 else
937 {
938 r.addr.v4.s_addr = add ? htonl(a + b) : htonl(a - b);
939 }
940 }
941 else
942 {
943 for (i = 0, carry = 0; i < AF_BYTES(p1->family); i++)
944 {
945 if (add)
946 {
947 BYTE(&r, i) = BYTE(p1, i) + BYTE(p2, i) + carry;
948 carry = (BYTE(p1, i) + BYTE(p2, i) + carry) / 256;
949 }
950 else
951 {
952 BYTE(&r, i) = (BYTE(p1, i) - BYTE(p2, i) - carry);
953 carry = (BYTE(p1, i) < (BYTE(p2, i) + carry));
954 }
955 }
956
957 /* would over/underflow */
958 if (carry)
959 {
960 memset(&r.addr.u8, add * 0xFF, AF_BYTES(r.family));
961 ok = false;
962 }
963 }
964 }
965 else
966 {
967 ok = false;
968 }
969
970 if (inplace)
971 {
972 *p1 = r;
973 lua_pushboolean(L, ok);
974 return 1;
975 }
976
977 if (!(p1 = lua_newuserdata(L, sizeof(*p1))))
978 return 0;
979
980 *p1 = r;
981
982 luaL_getmetatable(L, LUCI_IP_CIDR);
983 lua_setmetatable(L, -2);
984 return 1;
985 }
986
987 static int cidr_add(lua_State *L)
988 {
989 return _cidr_add_sub(L, true);
990 }
991
992 static int cidr_sub(lua_State *L)
993 {
994 return _cidr_add_sub(L, false);
995 }
996
997 static int cidr_minhost(lua_State *L)
998 {
999 cidr_t *p = L_checkcidr(L, 1, NULL);
1000 cidr_t r = *p;
1001 uint8_t i, rest, carry;
1002
1003 _apply_mask(&r, r.bits, false);
1004
1005 if (r.family == AF_INET && r.bits < AF_BITS(AF_INET))
1006 {
1007 r.bits = AF_BITS(AF_INET);
1008 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) + 1);
1009 }
1010 else if (r.bits < AF_BITS(r.family))
1011 {
1012 r.bits = AF_BITS(r.family);
1013
1014 for (i = 0, carry = 1; i < AF_BYTES(r.family); i++)
1015 {
1016 rest = (BYTE(&r, i) + carry) > 255;
1017 BYTE(&r, i) += carry;
1018 carry = rest;
1019 }
1020 }
1021
1022 if (!(p = lua_newuserdata(L, sizeof(*p))))
1023 return 0;
1024
1025 *p = r;
1026
1027 luaL_getmetatable(L, LUCI_IP_CIDR);
1028 lua_setmetatable(L, -2);
1029 return 1;
1030 }
1031
1032 static int cidr_maxhost(lua_State *L)
1033 {
1034 cidr_t *p = L_checkcidr(L, 1, NULL);
1035 cidr_t r = *p;
1036
1037 _apply_mask(&r, r.bits, true);
1038
1039 if (r.family == AF_INET && r.bits < AF_BITS(AF_INET))
1040 {
1041 r.bits = AF_BITS(AF_INET);
1042 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) - 1);
1043 }
1044 else
1045 {
1046 r.bits = AF_BITS(r.family);
1047 }
1048
1049 if (!(p = lua_newuserdata(L, sizeof(*p))))
1050 return 0;
1051
1052 *p = r;
1053
1054 luaL_getmetatable(L, LUCI_IP_CIDR);
1055 lua_setmetatable(L, -2);
1056 return 1;
1057 }
1058
1059 static int cidr_gc (lua_State *L)
1060 {
1061 return 0;
1062 }
1063
1064 static int cidr_tostring (lua_State *L)
1065 {
1066 cidr_t *p = L_checkcidr(L, 1, NULL);
1067 return format_cidr(L, p);
1068 }
1069
1070 /*
1071 * route functions
1072 */
1073
1074 static bool diff_prefix(int family, void *addr, int bits, bool exact, cidr_t *p)
1075 {
1076 uint8_t i, b, r, *a;
1077 uint32_t m;
1078
1079 if (!p->family)
1080 return false;
1081
1082 if (!addr || p->family != family || p->bits > bits)
1083 return true;
1084
1085 if (family == AF_INET)
1086 {
1087 m = p->bits ? htonl(~((1 << (AF_BITS(AF_INET) - p->bits)) - 1)) : 0;
1088
1089 if ((((struct in_addr *)addr)->s_addr & m) != (p->addr.v4.s_addr & m))
1090 return true;
1091 }
1092 else
1093 {
1094 for (i = 0, a = addr, r = p->bits; i < AF_BYTES(p->family); i++)
1095 {
1096 b = r ? (0xFF << (8 - ((r > 8) ? 8 : r))) : 0;
1097
1098 if ((a[i] & b) != (p->addr.u8[i] & b))
1099 return true;
1100
1101 r -= ((r > 8) ? 8 : r);
1102 }
1103 }
1104
1105 return (exact && p->bits != bits);
1106 }
1107
1108 static int cb_dump_route(struct nl_msg *msg, void *arg)
1109 {
1110 struct dump_state *s = arg;
1111 struct dump_filter *f = s->filter;
1112 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1113 struct rtmsg *rt = NLMSG_DATA(hdr);
1114 struct nlattr *tb[RTA_MAX+1];
1115 struct in6_addr *src, *dst, *gw, *from, def = { };
1116 int iif, oif, bitlen;
1117 uint32_t table;
1118
1119 if (hdr->nlmsg_type != RTM_NEWROUTE ||
1120 (rt->rtm_family != AF_INET && rt->rtm_family != AF_INET6))
1121 return NL_SKIP;
1122
1123 nlmsg_parse(hdr, sizeof(*rt), tb, RTA_MAX, NULL);
1124
1125 iif = tb[RTA_IIF] ? RTA_INT(tb[RTA_IIF]) : 0;
1126 oif = tb[RTA_OIF] ? RTA_INT(tb[RTA_OIF]) : 0;
1127 table = tb[RTA_TABLE] ? RTA_U32(tb[RTA_TABLE]) : rt->rtm_table;
1128 from = tb[RTA_SRC] ? RTA_DATA(tb[RTA_SRC]) : NULL;
1129 src = tb[RTA_PREFSRC] ? RTA_DATA(tb[RTA_PREFSRC]) : NULL;
1130 dst = tb[RTA_DST] ? RTA_DATA(tb[RTA_DST]) : &def;
1131 gw = tb[RTA_GATEWAY] ? RTA_DATA(tb[RTA_GATEWAY]) : NULL;
1132
1133 bitlen = AF_BITS(rt->rtm_family);
1134
1135 if (!f->get) {
1136 if ((f->type && rt->rtm_type != f->type) ||
1137 (f->family && rt->rtm_family != f->family) ||
1138 (f->proto && rt->rtm_protocol != f->proto) ||
1139 (f->scope && rt->rtm_scope != f->scope) ||
1140 (f->iif && iif != f->iif) ||
1141 (f->oif && oif != f->oif) ||
1142 (f->table && table != f->table) ||
1143 diff_prefix(rt->rtm_family, from, rt->rtm_src_len,
1144 f->from_exact, &f->from) ||
1145 diff_prefix(rt->rtm_family, dst, rt->rtm_dst_len,
1146 f->dst_exact, &f->dst) ||
1147 diff_prefix(rt->rtm_family, gw, bitlen,
1148 false, &f->gw) ||
1149 diff_prefix(rt->rtm_family, src, bitlen,
1150 false, &f->src))
1151 goto out;
1152 }
1153
1154 if (s->callback)
1155 lua_pushvalue(s->L, 2);
1156
1157 lua_newtable(s->L);
1158
1159 L_setint(s->L, "type", rt->rtm_type);
1160 L_setint(s->L, "family", (rt->rtm_family == AF_INET) ? 4 : 6);
1161
1162 L_setaddr(s->L, "dest", rt->rtm_family, dst, rt->rtm_dst_len);
1163
1164 if (gw)
1165 L_setaddr(s->L, "gw", rt->rtm_family, gw, -1);
1166
1167 if (from)
1168 L_setaddr(s->L, "from", rt->rtm_family, from, rt->rtm_src_len);
1169
1170 if (iif)
1171 L_setdev(s->L, "iif", tb[RTA_IIF]);
1172
1173 if (oif)
1174 L_setdev(s->L, "dev", tb[RTA_OIF]);
1175
1176 L_setint(s->L, "table", table);
1177 L_setint(s->L, "proto", rt->rtm_protocol);
1178 L_setint(s->L, "scope", rt->rtm_scope);
1179
1180 if (src)
1181 L_setaddr(s->L, "src", rt->rtm_family, src, -1);
1182
1183 if (tb[RTA_PRIORITY])
1184 L_setint(s->L, "metric", RTA_U32(tb[RTA_PRIORITY]));
1185
1186 if (rt->rtm_family == AF_INET6 && tb[RTA_CACHEINFO])
1187 {
1188 struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]);
1189
1190 if (ci->rta_expires)
1191 {
1192 if (ci->rta_expires)
1193 L_setint(s->L, "expires", ci->rta_expires / hz);
1194
1195 if (ci->rta_error != 0)
1196 L_setint(s->L, "error", ci->rta_error);
1197 }
1198 }
1199
1200 s->index++;
1201
1202 if (s->callback)
1203 lua_call(s->L, 1, 0);
1204 else if (hdr->nlmsg_flags & NLM_F_MULTI)
1205 lua_rawseti(s->L, -2, s->index);
1206
1207 out:
1208 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1209 return NL_SKIP;
1210 }
1211
1212 static int
1213 cb_done(struct nl_msg *msg, void *arg)
1214 {
1215 struct dump_state *s = arg;
1216 s->pending = 0;
1217 return NL_STOP;
1218 }
1219
1220 static int
1221 cb_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
1222 {
1223 struct dump_state *s = arg;
1224 s->pending = 0;
1225 return NL_STOP;
1226 }
1227
1228 static int _error(lua_State *L, int code, const char *msg)
1229 {
1230 lua_pushnil(L);
1231 lua_pushnumber(L, code ? code : errno);
1232 lua_pushstring(L, msg ? msg : strerror(errno));
1233
1234 return 3;
1235 }
1236
1237 static int _route_dump(lua_State *L, struct dump_filter *filter)
1238 {
1239 int flags = NLM_F_REQUEST;
1240 struct dump_state s = {
1241 .L = L,
1242 .pending = 1,
1243 .index = 0,
1244 .callback = lua_isfunction(L, 2),
1245 .filter = filter
1246 };
1247
1248 if (!hz)
1249 hz = sysconf(_SC_CLK_TCK);
1250
1251 if (!sock)
1252 {
1253 sock = nl_socket_alloc();
1254 if (!sock)
1255 return _error(L, -1, "Out of memory");
1256
1257 if (nl_connect(sock, NETLINK_ROUTE))
1258 return _error(L, 0, NULL);
1259 }
1260
1261 struct nl_msg *msg;
1262 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1263 struct rtmsg rtm = {
1264 .rtm_family = filter->family,
1265 .rtm_dst_len = filter->dst.bits,
1266 .rtm_src_len = filter->src.bits
1267 };
1268
1269 if (!filter->get)
1270 flags |= NLM_F_DUMP;
1271
1272 msg = nlmsg_alloc_simple(RTM_GETROUTE, flags);
1273 if (!msg)
1274 goto out;
1275
1276 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
1277
1278 if (filter->get) {
1279 nla_put(msg, RTA_DST, AF_BYTES(filter->dst.family),
1280 &filter->dst.addr.v6);
1281
1282 if (filter->src.family)
1283 nla_put(msg, RTA_SRC, AF_BYTES(filter->src.family),
1284 &filter->src.addr.v6);
1285 }
1286
1287 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_route, &s);
1288 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &s);
1289 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &s);
1290
1291 nl_send_auto_complete(sock, msg);
1292
1293 if (!filter->get && !s.callback)
1294 lua_newtable(L);
1295
1296 while (s.pending > 0)
1297 nl_recvmsgs(sock, cb);
1298
1299 nlmsg_free(msg);
1300
1301 out:
1302 nl_cb_put(cb);
1303
1304 if (s.callback)
1305 return 0;
1306
1307 if (!filter->get)
1308 return 1;
1309
1310 return (s.index > 0);
1311 }
1312
1313 static int route_get(lua_State *L)
1314 {
1315 struct dump_filter filter = { .get = true };
1316 const char *dest = luaL_checkstring(L, 1);
1317 const char *from = luaL_optstring(L, 2, NULL);
1318
1319 if (!parse_cidr(dest, &filter.dst))
1320 return _error(L, -1, "Invalid destination");
1321
1322 if (from && !parse_cidr(from, &filter.src))
1323 return _error(L, -1, "Invalid source");
1324
1325 if (filter.src.family != 0 &&
1326 filter.src.family != filter.dst.family)
1327 return _error(L, -1, "Different source/destination family");
1328
1329 filter.family = filter.dst.family;
1330
1331 return _route_dump(L, &filter);
1332 }
1333
1334 static int route_dump(lua_State *L)
1335 {
1336 const char *s;
1337 cidr_t p = { };
1338 struct dump_filter filter = { };
1339
1340 if (lua_type(L, 1) == LUA_TTABLE)
1341 {
1342 filter.family = L_getint(L, 1, "family");
1343
1344 if (filter.family == 4)
1345 filter.family = AF_INET;
1346 else if (filter.family == 6)
1347 filter.family = AF_INET6;
1348 else
1349 filter.family = 0;
1350
1351 if ((s = L_getstr(L, 1, "iif")) != NULL)
1352 filter.iif = if_nametoindex(s);
1353
1354 if ((s = L_getstr(L, 1, "oif")) != NULL)
1355 filter.oif = if_nametoindex(s);
1356
1357 filter.type = L_getint(L, 1, "type");
1358 filter.scope = L_getint(L, 1, "scope");
1359 filter.proto = L_getint(L, 1, "proto");
1360 filter.table = L_getint(L, 1, "table");
1361
1362 if ((s = L_getstr(L, 1, "gw")) != NULL && parse_cidr(s, &p))
1363 filter.gw = p;
1364
1365 if ((s = L_getstr(L, 1, "from")) != NULL && parse_cidr(s, &p))
1366 filter.from = p;
1367
1368 if ((s = L_getstr(L, 1, "src")) != NULL && parse_cidr(s, &p))
1369 filter.src = p;
1370
1371 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1372 filter.dst = p;
1373
1374 if ((s = L_getstr(L, 1, "from_exact")) != NULL && parse_cidr(s, &p))
1375 filter.from = p, filter.from_exact = true;
1376
1377 if ((s = L_getstr(L, 1, "dest_exact")) != NULL && parse_cidr(s, &p))
1378 filter.dst = p, filter.dst_exact = true;
1379 }
1380
1381 return _route_dump(L, &filter);
1382 }
1383
1384
1385 static bool diff_macaddr(struct ether_addr *mac1, struct ether_addr *mac2)
1386 {
1387 struct ether_addr empty = { };
1388
1389 if (!memcmp(mac2, &empty, sizeof(empty)))
1390 return false;
1391
1392 if (!mac1 || memcmp(mac1, mac2, sizeof(empty)))
1393 return true;
1394
1395 return false;
1396 }
1397
1398 static int cb_dump_neigh(struct nl_msg *msg, void *arg)
1399 {
1400 char buf[32];
1401 struct ether_addr *mac;
1402 struct in6_addr *dst;
1403 struct dump_state *s = arg;
1404 struct dump_filter *f = s->filter;
1405 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1406 struct ndmsg *nd = NLMSG_DATA(hdr);
1407 struct nlattr *tb[NDA_MAX+1];
1408 int bitlen;
1409
1410 if (hdr->nlmsg_type != RTM_NEWNEIGH ||
1411 (nd->ndm_family != AF_INET && nd->ndm_family != AF_INET6))
1412 return NL_SKIP;
1413
1414 nlmsg_parse(hdr, sizeof(*nd), tb, NDA_MAX, NULL);
1415
1416 mac = tb[NDA_LLADDR] ? RTA_DATA(tb[NDA_LLADDR]) : NULL;
1417 dst = tb[NDA_DST] ? RTA_DATA(tb[NDA_DST]) : NULL;
1418
1419 bitlen = AF_BITS(nd->ndm_family);
1420
1421 if ((f->family && nd->ndm_family != f->family) ||
1422 (f->iif && nd->ndm_ifindex != f->iif) ||
1423 (f->type && !(f->type & nd->ndm_state)) ||
1424 diff_prefix(nd->ndm_family, dst, bitlen, false, &f->dst) ||
1425 diff_macaddr(mac, &f->mac))
1426 goto out;
1427
1428 if (s->callback)
1429 lua_pushvalue(s->L, 2);
1430
1431 lua_newtable(s->L);
1432
1433 L_setint(s->L, "family", (nd->ndm_family == AF_INET) ? 4 : 6);
1434 L_setstr(s->L, "dev", if_indextoname(nd->ndm_ifindex, buf));
1435
1436 L_setbool(s->L, "router", (nd->ndm_flags & NTF_ROUTER));
1437 L_setbool(s->L, "proxy", (nd->ndm_flags & NTF_PROXY));
1438
1439 L_setbool(s->L, "incomplete", (nd->ndm_state & NUD_INCOMPLETE));
1440 L_setbool(s->L, "reachable", (nd->ndm_state & NUD_REACHABLE));
1441 L_setbool(s->L, "stale", (nd->ndm_state & NUD_STALE));
1442 L_setbool(s->L, "delay", (nd->ndm_state & NUD_DELAY));
1443 L_setbool(s->L, "probe", (nd->ndm_state & NUD_PROBE));
1444 L_setbool(s->L, "failed", (nd->ndm_state & NUD_FAILED));
1445 L_setbool(s->L, "noarp", (nd->ndm_state & NUD_NOARP));
1446 L_setbool(s->L, "permanent", (nd->ndm_state & NUD_PERMANENT));
1447
1448 if (dst)
1449 L_setaddr(s->L, "dest", nd->ndm_family, dst, -1);
1450
1451 if (mac)
1452 L_setaddr(s->L, "mac", AF_PACKET, mac, -1);
1453
1454 s->index++;
1455
1456 if (s->callback)
1457 lua_call(s->L, 1, 0);
1458 else if (hdr->nlmsg_flags & NLM_F_MULTI)
1459 lua_rawseti(s->L, -2, s->index);
1460
1461 out:
1462 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1463 return NL_SKIP;
1464 }
1465
1466 static int neighbor_dump(lua_State *L)
1467 {
1468 cidr_t p = { };
1469 const char *s;
1470 struct ether_addr *mac;
1471 struct dump_filter filter = { .type = 0xFF & ~NUD_NOARP };
1472 struct dump_state st = {
1473 .callback = lua_isfunction(L, 2),
1474 .pending = 1,
1475 .filter = &filter,
1476 .L = L
1477 };
1478
1479 if (lua_type(L, 1) == LUA_TTABLE)
1480 {
1481 filter.family = L_getint(L, 1, "family");
1482
1483 if (filter.family == 4)
1484 filter.family = AF_INET;
1485 else if (filter.family == 6)
1486 filter.family = AF_INET6;
1487 else
1488 filter.family = 0;
1489
1490 if ((s = L_getstr(L, 1, "dev")) != NULL)
1491 filter.iif = if_nametoindex(s);
1492
1493 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1494 filter.dst = p;
1495
1496 if ((s = L_getstr(L, 1, "mac")) != NULL &&
1497 (mac = ether_aton(s)) != NULL)
1498 filter.mac = *mac;
1499 }
1500
1501 if (!sock)
1502 {
1503 sock = nl_socket_alloc();
1504 if (!sock)
1505 return _error(L, -1, "Out of memory");
1506
1507 if (nl_connect(sock, NETLINK_ROUTE))
1508 return _error(L, 0, NULL);
1509 }
1510
1511 struct nl_msg *msg;
1512 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1513 struct ndmsg ndm = {
1514 .ndm_family = filter.family
1515 };
1516
1517 msg = nlmsg_alloc_simple(RTM_GETNEIGH, NLM_F_REQUEST | NLM_F_DUMP);
1518 if (!msg)
1519 goto out;
1520
1521 nlmsg_append(msg, &ndm, sizeof(ndm), 0);
1522
1523 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_neigh, &st);
1524 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1525 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1526
1527 nl_send_auto_complete(sock, msg);
1528
1529 if (!st.callback)
1530 lua_newtable(L);
1531
1532 while (st.pending > 0)
1533 nl_recvmsgs(sock, cb);
1534
1535 nlmsg_free(msg);
1536
1537 out:
1538 nl_cb_put(cb);
1539 return (st.callback == 0);
1540 }
1541
1542
1543 static int cb_dump_link(struct nl_msg *msg, void *arg)
1544 {
1545 char buf[48];
1546 struct dump_state *s = arg;
1547 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1548 struct ifinfomsg *ifm = NLMSG_DATA(hdr);
1549 struct nlattr *tb[IFLA_MAX+1];
1550 int i, len;
1551
1552 if (hdr->nlmsg_type != RTM_NEWLINK)
1553 return NL_SKIP;
1554
1555 nlmsg_parse(hdr, sizeof(*ifm), tb, IFLA_MAX, NULL);
1556
1557 L_setbool(s->L, "up", (ifm->ifi_flags & IFF_RUNNING));
1558 L_setint(s->L, "type", ifm->ifi_type);
1559 L_setstr(s->L, "name", if_indextoname(ifm->ifi_index, buf));
1560
1561 if (tb[IFLA_MTU])
1562 L_setint(s->L, "mtu", RTA_U32(tb[IFLA_MTU]));
1563
1564 if (tb[IFLA_TXQLEN])
1565 L_setint(s->L, "qlen", RTA_U32(tb[IFLA_TXQLEN]));
1566
1567 if (tb[IFLA_MASTER])
1568 L_setdev(s->L, "master", tb[IFLA_MASTER]);
1569
1570 if (tb[IFLA_ADDRESS] && nla_len(tb[IFLA_ADDRESS]) == AF_BYTES(AF_PACKET))
1571 L_setaddr(s->L, "mac", AF_PACKET, nla_get_string(tb[IFLA_ADDRESS]), -1);
1572
1573 s->pending = 0;
1574 return NL_SKIP;
1575 }
1576
1577 static int link_get(lua_State *L)
1578 {
1579 const char *dev = luaL_checkstring(L, 1);
1580 struct dump_state st = {
1581 .pending = 1,
1582 .L = L
1583 };
1584
1585 if (!sock)
1586 {
1587 sock = nl_socket_alloc();
1588 if (!sock)
1589 return _error(L, -1, "Out of memory");
1590
1591 if (nl_connect(sock, NETLINK_ROUTE))
1592 return _error(L, 0, NULL);
1593 }
1594
1595 struct nl_msg *msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST);
1596 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1597 struct ifinfomsg ifm = { .ifi_index = if_nametoindex(dev) };
1598
1599 if (!msg || !cb)
1600 return 0;
1601
1602 nlmsg_append(msg, &ifm, sizeof(ifm), 0);
1603
1604 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_link, &st);
1605 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1606 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1607
1608 lua_newtable(L);
1609
1610 nl_send_auto_complete(sock, msg);
1611
1612 while (st.pending > 0)
1613 nl_recvmsgs(sock, cb);
1614
1615 nlmsg_free(msg);
1616 nl_cb_put(cb);
1617
1618 return 1;
1619 }
1620
1621
1622 static const luaL_reg ip_methods[] = {
1623 { "new", cidr_new },
1624 { "IPv4", cidr_ipv4 },
1625 { "IPv6", cidr_ipv6 },
1626 { "MAC", cidr_mac },
1627
1628 { "checkip4", cidr_checkip4 },
1629 { "checkip6", cidr_checkip6 },
1630 { "checkmac", cidr_checkmac },
1631
1632 { "route", route_get },
1633 { "routes", route_dump },
1634
1635 { "neighbors", neighbor_dump },
1636
1637 { "link", link_get },
1638
1639 { }
1640 };
1641
1642 static const luaL_reg ip_cidr_methods[] = {
1643 { "is4", cidr_is4 },
1644 { "is4rfc1918", cidr_is4rfc1918 },
1645 { "is4linklocal", cidr_is4linklocal },
1646 { "is6", cidr_is6 },
1647 { "is6linklocal", cidr_is6linklocal },
1648 { "is6mapped4", cidr_is6mapped4 },
1649 { "ismac", cidr_ismac },
1650 { "ismaclocal", cidr_ismaclocal },
1651 { "ismacmcast", cidr_ismacmcast },
1652 { "lower", cidr_lower },
1653 { "higher", cidr_higher },
1654 { "equal", cidr_equal },
1655 { "prefix", cidr_prefix },
1656 { "network", cidr_network },
1657 { "host", cidr_host },
1658 { "mask", cidr_mask },
1659 { "broadcast", cidr_broadcast },
1660 { "mapped4", cidr_mapped4 },
1661 { "unscoped", cidr_unscoped },
1662 { "tomac", cidr_tomac },
1663 { "tolinklocal", cidr_tolinklocal },
1664 { "contains", cidr_contains },
1665 { "add", cidr_add },
1666 { "sub", cidr_sub },
1667 { "minhost", cidr_minhost },
1668 { "maxhost", cidr_maxhost },
1669 { "string", cidr_tostring },
1670
1671 { "__lt", cidr_lower },
1672 { "__le", cidr_lower_equal },
1673 { "__eq", cidr_equal },
1674 { "__add", cidr_add },
1675 { "__sub", cidr_sub },
1676 { "__gc", cidr_gc },
1677 { "__tostring", cidr_tostring },
1678
1679 { }
1680 };
1681
1682 int luaopen_luci_ip(lua_State *L)
1683 {
1684 luaL_register(L, LUCI_IP, ip_methods);
1685
1686 luaL_newmetatable(L, LUCI_IP_CIDR);
1687 luaL_register(L, NULL, ip_cidr_methods);
1688 lua_pushvalue(L, -1);
1689 lua_setfield(L, -2, "__index");
1690 lua_pop(L, 1);
1691
1692 return 1;
1693 }