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