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