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