Merge pull request #1685 from dibdot/travelmate
[project/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->type   && rt->rtm_type     != f->type)   ||
1079             (f->family && rt->rtm_family   != f->family) ||
1080             (f->proto  && rt->rtm_protocol != f->proto)  ||
1081             (f->scope  && rt->rtm_scope    != f->scope)  ||
1082                 (f->iif    && iif              != f->iif)    ||
1083                 (f->oif    && oif              != f->oif)    ||
1084                 (f->table  && table            != f->table)  ||
1085             diff_prefix(rt->rtm_family, from, rt->rtm_src_len,
1086                         f->from_exact, &f->from)         ||
1087             diff_prefix(rt->rtm_family, dst,  rt->rtm_dst_len,
1088                         f->dst_exact, &f->dst)           ||
1089             diff_prefix(rt->rtm_family, gw,   bitlen,
1090                         false, &f->gw)                   ||
1091             diff_prefix(rt->rtm_family, src,  bitlen,
1092                         false, &f->src))
1093                 goto out;
1094
1095         if (s->callback)
1096                 lua_pushvalue(s->L, 2);
1097
1098         lua_newtable(s->L);
1099
1100         L_setint(s->L, "type", rt->rtm_type);
1101         L_setint(s->L, "family", (rt->rtm_family == AF_INET) ? 4 : 6);
1102
1103         L_setaddr(s->L, "dest", rt->rtm_family, dst, rt->rtm_dst_len);
1104
1105         if (gw)
1106                 L_setaddr(s->L, "gw", rt->rtm_family, gw, -1);
1107
1108         if (from)
1109                 L_setaddr(s->L, "from", rt->rtm_family, from, rt->rtm_src_len);
1110
1111         if (iif)
1112                 L_setdev(s->L, "iif", tb[RTA_IIF]);
1113
1114         if (oif)
1115                 L_setdev(s->L, "dev", tb[RTA_OIF]);
1116
1117         L_setint(s->L, "table", table);
1118         L_setint(s->L, "proto", rt->rtm_protocol);
1119         L_setint(s->L, "scope", rt->rtm_scope);
1120
1121         if (src)
1122                 L_setaddr(s->L, "src", rt->rtm_family, src, -1);
1123
1124         if (tb[RTA_PRIORITY])
1125                 L_setint(s->L, "metric", RTA_U32(tb[RTA_PRIORITY]));
1126
1127         if (rt->rtm_family == AF_INET6 && tb[RTA_CACHEINFO])
1128         {
1129                 struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]);
1130
1131                 if (ci->rta_expires)
1132                 {
1133                         if (ci->rta_expires)
1134                                 L_setint(s->L, "expires", ci->rta_expires / hz);
1135
1136                         if (ci->rta_error != 0)
1137                                 L_setint(s->L, "error", ci->rta_error);
1138                 }
1139         }
1140
1141         s->index++;
1142
1143         if (s->callback)
1144                 lua_call(s->L, 1, 0);
1145         else if (hdr->nlmsg_flags & NLM_F_MULTI)
1146                 lua_rawseti(s->L, -2, s->index);
1147
1148 out:
1149         s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1150         return NL_SKIP;
1151 }
1152
1153 static int
1154 cb_done(struct nl_msg *msg, void *arg)
1155 {
1156         struct dump_state *s = arg;
1157         s->pending = 0;
1158         return NL_STOP;
1159 }
1160
1161 static int
1162 cb_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
1163 {
1164         struct dump_state *s = arg;
1165         s->pending = 0;
1166         return NL_STOP;
1167 }
1168
1169 static int _error(lua_State *L, int code, const char *msg)
1170 {
1171         lua_pushnil(L);
1172         lua_pushnumber(L, code ? code : errno);
1173         lua_pushstring(L, msg ? msg : strerror(errno));
1174
1175         return 3;
1176 }
1177
1178 static int _route_dump(lua_State *L, struct dump_filter *filter)
1179 {
1180         int flags = NLM_F_REQUEST;
1181         struct dump_state s = {
1182                 .L = L,
1183                 .pending = 1,
1184                 .index = 0,
1185                 .callback = lua_isfunction(L, 2),
1186                 .filter = filter
1187         };
1188
1189         if (!hz)
1190                 hz = sysconf(_SC_CLK_TCK);
1191
1192         if (!sock)
1193         {
1194                 sock = nl_socket_alloc();
1195                 if (!sock)
1196                         return _error(L, -1, "Out of memory");
1197
1198                 if (nl_connect(sock, NETLINK_ROUTE))
1199                         return _error(L, 0, NULL);
1200         }
1201
1202         struct nl_msg *msg;
1203         struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1204         struct rtmsg rtm = {
1205                 .rtm_family = filter->family,
1206                 .rtm_dst_len = filter->dst.bits,
1207                 .rtm_src_len = filter->src.bits
1208         };
1209
1210         if (!filter->get)
1211                 flags |= NLM_F_DUMP;
1212
1213         msg = nlmsg_alloc_simple(RTM_GETROUTE, flags);
1214         if (!msg)
1215                 goto out;
1216
1217         nlmsg_append(msg, &rtm, sizeof(rtm), 0);
1218
1219         if (filter->get)
1220                 nla_put(msg, RTA_DST, AF_BYTES(filter->dst.family),
1221                         &filter->dst.addr.v6);
1222
1223         nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_route, &s);
1224         nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &s);
1225         nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &s);
1226
1227         nl_send_auto_complete(sock, msg);
1228
1229         if (!filter->get && !s.callback)
1230                 lua_newtable(L);
1231
1232         while (s.pending > 0)
1233                 nl_recvmsgs(sock, cb);
1234
1235         nlmsg_free(msg);
1236
1237 out:
1238         nl_cb_put(cb);
1239         return (s.callback == 0);
1240 }
1241
1242 static int route_get(lua_State *L)
1243 {
1244         struct dump_filter filter = { .get = true };
1245         const char *dest = luaL_checkstring(L, 1);
1246
1247         if (!parse_cidr(dest, &filter.dst))
1248                 return _error(L, -1, "Invalid destination");
1249
1250         filter.family = filter.dst.family;
1251
1252         return _route_dump(L, &filter);
1253 }
1254
1255 static int route_dump(lua_State *L)
1256 {
1257         const char *s;
1258         cidr_t p = { };
1259         struct dump_filter filter = { };
1260
1261         if (lua_type(L, 1) == LUA_TTABLE)
1262         {
1263                 filter.family = L_getint(L, 1, "family");
1264
1265                 if (filter.family == 4)
1266                         filter.family = AF_INET;
1267                 else if (filter.family == 6)
1268                         filter.family = AF_INET6;
1269                 else
1270                         filter.family = 0;
1271
1272                 if ((s = L_getstr(L, 1, "iif")) != NULL)
1273                         filter.iif = if_nametoindex(s);
1274
1275                 if ((s = L_getstr(L, 1, "oif")) != NULL)
1276                         filter.oif = if_nametoindex(s);
1277
1278                 filter.type = L_getint(L, 1, "type");
1279                 filter.scope = L_getint(L, 1, "scope");
1280                 filter.proto = L_getint(L, 1, "proto");
1281                 filter.table = L_getint(L, 1, "table");
1282
1283                 if ((s = L_getstr(L, 1, "gw")) != NULL && parse_cidr(s, &p))
1284                         filter.gw = p;
1285
1286                 if ((s = L_getstr(L, 1, "from")) != NULL && parse_cidr(s, &p))
1287                         filter.from = p;
1288
1289                 if ((s = L_getstr(L, 1, "src")) != NULL && parse_cidr(s, &p))
1290                         filter.src = p;
1291
1292                 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1293                         filter.dst = p;
1294
1295                 if ((s = L_getstr(L, 1, "from_exact")) != NULL && parse_cidr(s, &p))
1296                         filter.from = p, filter.from_exact = true;
1297
1298                 if ((s = L_getstr(L, 1, "dest_exact")) != NULL && parse_cidr(s, &p))
1299                         filter.dst = p, filter.dst_exact = true;
1300         }
1301
1302         return _route_dump(L, &filter);
1303 }
1304
1305
1306 static bool diff_macaddr(struct ether_addr *mac1, struct ether_addr *mac2)
1307 {
1308         struct ether_addr empty = { };
1309
1310         if (!memcmp(mac2, &empty, sizeof(empty)))
1311                 return false;
1312
1313         if (!mac1 || memcmp(mac1, mac2, sizeof(empty)))
1314                 return true;
1315
1316         return false;
1317 }
1318
1319 static int cb_dump_neigh(struct nl_msg *msg, void *arg)
1320 {
1321         char buf[32];
1322         struct ether_addr *mac;
1323         struct in6_addr *dst;
1324         struct dump_state *s = arg;
1325         struct dump_filter *f = s->filter;
1326         struct nlmsghdr *hdr = nlmsg_hdr(msg);
1327         struct ndmsg *nd = NLMSG_DATA(hdr);
1328         struct nlattr *tb[NDA_MAX+1];
1329         int bitlen;
1330
1331         if (hdr->nlmsg_type != RTM_NEWNEIGH ||
1332             (nd->ndm_family != AF_INET && nd->ndm_family != AF_INET6))
1333                 return NL_SKIP;
1334
1335         nlmsg_parse(hdr, sizeof(*nd), tb, NDA_MAX, NULL);
1336
1337         mac = tb[NDA_LLADDR] ? RTA_DATA(tb[NDA_LLADDR]) : NULL;
1338         dst = tb[NDA_DST]    ? RTA_DATA(tb[NDA_DST])    : NULL;
1339
1340         bitlen = AF_BITS(nd->ndm_family);
1341
1342         if ((f->family && nd->ndm_family  != f->family) ||
1343             (f->iif    && nd->ndm_ifindex != f->iif) ||
1344                 (f->type   && !(f->type & nd->ndm_state)) ||
1345             diff_prefix(nd->ndm_family, dst, bitlen, false, &f->dst) ||
1346             diff_macaddr(mac, &f->mac))
1347                 goto out;
1348
1349         if (s->callback)
1350                 lua_pushvalue(s->L, 2);
1351
1352         lua_newtable(s->L);
1353
1354         L_setint(s->L, "family", (nd->ndm_family == AF_INET) ? 4 : 6);
1355         L_setstr(s->L, "dev", if_indextoname(nd->ndm_ifindex, buf));
1356
1357         L_setbool(s->L, "router", (nd->ndm_flags & NTF_ROUTER));
1358         L_setbool(s->L, "proxy", (nd->ndm_flags & NTF_PROXY));
1359
1360         L_setbool(s->L, "incomplete", (nd->ndm_state & NUD_INCOMPLETE));
1361         L_setbool(s->L, "reachable", (nd->ndm_state & NUD_REACHABLE));
1362         L_setbool(s->L, "stale", (nd->ndm_state & NUD_STALE));
1363         L_setbool(s->L, "delay", (nd->ndm_state & NUD_DELAY));
1364         L_setbool(s->L, "probe", (nd->ndm_state & NUD_PROBE));
1365         L_setbool(s->L, "failed", (nd->ndm_state & NUD_FAILED));
1366         L_setbool(s->L, "noarp", (nd->ndm_state & NUD_NOARP));
1367         L_setbool(s->L, "permanent", (nd->ndm_state & NUD_PERMANENT));
1368
1369         if (dst)
1370                 L_setaddr(s->L, "dest", nd->ndm_family, dst, -1);
1371
1372         if (mac)
1373                 L_setaddr(s->L, "mac", AF_PACKET, mac, -1);
1374
1375         s->index++;
1376
1377         if (s->callback)
1378                 lua_call(s->L, 1, 0);
1379         else if (hdr->nlmsg_flags & NLM_F_MULTI)
1380                 lua_rawseti(s->L, -2, s->index);
1381
1382 out:
1383         s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1384         return NL_SKIP;
1385 }
1386
1387 static int neighbor_dump(lua_State *L)
1388 {
1389         cidr_t p = { };
1390         const char *s;
1391         struct ether_addr *mac;
1392         struct dump_filter filter = { .type = 0xFF & ~NUD_NOARP };
1393         struct dump_state st = {
1394                 .callback = lua_isfunction(L, 2),
1395                 .pending = 1,
1396                 .filter = &filter,
1397                 .L = L
1398         };
1399
1400         if (lua_type(L, 1) == LUA_TTABLE)
1401         {
1402                 filter.family = L_getint(L, 1, "family");
1403
1404                 if (filter.family == 4)
1405                         filter.family = AF_INET;
1406                 else if (filter.family == 6)
1407                         filter.family = AF_INET6;
1408                 else
1409                         filter.family = 0;
1410
1411                 if ((s = L_getstr(L, 1, "dev")) != NULL)
1412                         filter.iif = if_nametoindex(s);
1413
1414                 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1415                         filter.dst = p;
1416
1417                 if ((s = L_getstr(L, 1, "mac")) != NULL &&
1418                     (mac = ether_aton(s)) != NULL)
1419                         filter.mac = *mac;
1420         }
1421
1422         if (!sock)
1423         {
1424                 sock = nl_socket_alloc();
1425                 if (!sock)
1426                         return _error(L, -1, "Out of memory");
1427
1428                 if (nl_connect(sock, NETLINK_ROUTE))
1429                         return _error(L, 0, NULL);
1430         }
1431
1432         struct nl_msg *msg;
1433         struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1434         struct ndmsg ndm = {
1435                 .ndm_family = filter.family
1436         };
1437
1438         msg = nlmsg_alloc_simple(RTM_GETNEIGH, NLM_F_REQUEST | NLM_F_DUMP);
1439         if (!msg)
1440                 goto out;
1441
1442         nlmsg_append(msg, &ndm, sizeof(ndm), 0);
1443
1444         nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_neigh, &st);
1445         nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1446         nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1447
1448         nl_send_auto_complete(sock, msg);
1449
1450         if (!st.callback)
1451                 lua_newtable(L);
1452
1453         while (st.pending > 0)
1454                 nl_recvmsgs(sock, cb);
1455
1456         nlmsg_free(msg);
1457
1458 out:
1459         nl_cb_put(cb);
1460         return (st.callback == 0);
1461 }
1462
1463
1464 static int cb_dump_link(struct nl_msg *msg, void *arg)
1465 {
1466         char buf[48];
1467         struct dump_state *s = arg;
1468         struct nlmsghdr *hdr = nlmsg_hdr(msg);
1469         struct ifinfomsg *ifm = NLMSG_DATA(hdr);
1470         struct nlattr *tb[IFLA_MAX+1];
1471         int i, len;
1472
1473         if (hdr->nlmsg_type != RTM_NEWLINK)
1474                 return NL_SKIP;
1475
1476         nlmsg_parse(hdr, sizeof(*ifm), tb, IFLA_MAX, NULL);
1477
1478         L_setbool(s->L, "up", (ifm->ifi_flags & IFF_RUNNING));
1479         L_setint(s->L, "type", ifm->ifi_type);
1480         L_setstr(s->L, "name", if_indextoname(ifm->ifi_index, buf));
1481
1482         if (tb[IFLA_MTU])
1483                 L_setint(s->L, "mtu", RTA_U32(tb[IFLA_MTU]));
1484
1485         if (tb[IFLA_TXQLEN])
1486                 L_setint(s->L, "qlen", RTA_U32(tb[IFLA_TXQLEN]));
1487
1488         if (tb[IFLA_MASTER])
1489                 L_setdev(s->L, "master", tb[IFLA_MASTER]);
1490
1491         if (tb[IFLA_ADDRESS] && nla_len(tb[IFLA_ADDRESS]) == AF_BYTES(AF_PACKET))
1492                 L_setaddr(s->L, "mac", AF_PACKET, nla_get_string(tb[IFLA_ADDRESS]), -1);
1493
1494         s->pending = 0;
1495         return NL_SKIP;
1496 }
1497
1498 static int link_get(lua_State *L)
1499 {
1500         const char *dev = luaL_checkstring(L, 1);
1501         struct dump_state st = {
1502                 .pending = 1,
1503                 .L = L
1504         };
1505
1506         if (!sock)
1507         {
1508                 sock = nl_socket_alloc();
1509                 if (!sock)
1510                         return _error(L, -1, "Out of memory");
1511
1512                 if (nl_connect(sock, NETLINK_ROUTE))
1513                         return _error(L, 0, NULL);
1514         }
1515
1516         struct nl_msg *msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST);
1517         struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1518         struct ifinfomsg ifm = { .ifi_index = if_nametoindex(dev) };
1519
1520         if (!msg || !cb)
1521                 return 0;
1522
1523         nlmsg_append(msg, &ifm, sizeof(ifm), 0);
1524
1525         nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_link, &st);
1526         nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1527         nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1528
1529         lua_newtable(L);
1530
1531         nl_send_auto_complete(sock, msg);
1532
1533         while (st.pending > 0)
1534                 nl_recvmsgs(sock, cb);
1535
1536         nlmsg_free(msg);
1537         nl_cb_put(cb);
1538
1539         return 1;
1540 }
1541
1542
1543 static const luaL_reg ip_methods[] = {
1544         { "new",                        cidr_new          },
1545         { "IPv4",                       cidr_ipv4         },
1546         { "IPv6",                       cidr_ipv6         },
1547         { "MAC",                        cidr_mac          },
1548
1549         { "checkip4",                   cidr_checkip4     },
1550         { "checkip6",                   cidr_checkip6     },
1551         { "checkmac",                   cidr_checkmac     },
1552
1553         { "route",                      route_get         },
1554         { "routes",                     route_dump        },
1555
1556         { "neighbors",          neighbor_dump     },
1557
1558         { "link",                       link_get          },
1559
1560         { }
1561 };
1562
1563 static const luaL_reg ip_cidr_methods[] = {
1564         { "is4",                        cidr_is4          },
1565         { "is4rfc1918",         cidr_is4rfc1918   },
1566         { "is4linklocal",       cidr_is4linklocal },
1567         { "is6",                        cidr_is6          },
1568         { "is6linklocal",       cidr_is6linklocal },
1569         { "is6mapped4",         cidr_is6mapped4   },
1570         { "ismac",                      cidr_ismac        },
1571         { "ismaclocal",         cidr_ismaclocal   },
1572         { "ismacmcast",         cidr_ismacmcast   },
1573         { "lower",                      cidr_lower        },
1574         { "higher",                     cidr_higher       },
1575         { "equal",                      cidr_equal        },
1576         { "prefix",                     cidr_prefix       },
1577         { "network",            cidr_network      },
1578         { "host",                       cidr_host         },
1579         { "mask",                       cidr_mask         },
1580         { "broadcast",          cidr_broadcast    },
1581         { "mapped4",            cidr_mapped4      },
1582         { "tomac",                      cidr_tomac        },
1583         { "tolinklocal",        cidr_tolinklocal  },
1584         { "contains",           cidr_contains     },
1585         { "add",                        cidr_add          },
1586         { "sub",                        cidr_sub          },
1587         { "minhost",            cidr_minhost      },
1588         { "maxhost",            cidr_maxhost      },
1589         { "string",                     cidr_tostring     },
1590
1591         { "__lt",                       cidr_lower        },
1592         { "__le",                       cidr_lower_equal  },
1593         { "__eq",                       cidr_equal        },
1594         { "__add",                      cidr_add          },
1595         { "__sub",                      cidr_sub          },
1596         { "__gc",                       cidr_gc           },
1597         { "__tostring",         cidr_tostring     },
1598
1599         { }
1600 };
1601
1602 int luaopen_luci_ip(lua_State *L)
1603 {
1604         luaL_register(L, LUCI_IP, ip_methods);
1605
1606         luaL_newmetatable(L, LUCI_IP_CIDR);
1607         luaL_register(L, NULL, ip_cidr_methods);
1608         lua_pushvalue(L, -1);
1609         lua_setfield(L, -2, "__index");
1610         lua_pop(L, 1);
1611
1612         return 1;
1613 }