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