595ac8c3a50c5311dc9c8d521ab3920a5ad56452
[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 }