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