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