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