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