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