Merge pull request #305 from nmav/compression
[project/luci.git] / libs / luci-lib-ip / src / ip.c
1 /*
2 Copyright 2015 Jo-Philipp Wich <jow@openwrt.org>
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8         http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 #define _GNU_SOURCE
18
19 #include <stdio.h>
20 #include <stdint.h>
21 #include <stdbool.h>
22 #include <unistd.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <limits.h>
26
27 #include <lua.h>
28 #include <lualib.h>
29 #include <lauxlib.h>
30
31 #include <net/if.h>
32 #include <netinet/ether.h>
33 #include <arpa/inet.h>
34 #include <netlink/msg.h>
35 #include <netlink/attr.h>
36 #include <netlink/socket.h>
37 #include <linux/rtnetlink.h>
38
39 #define LUCI_IP "luci.ip"
40 #define LUCI_IP_CIDR "luci.ip.cidr"
41
42 #define RTA_INT(x)      (*(int *)RTA_DATA(x))
43 #define RTA_U32(x)      (*(uint32_t *)RTA_DATA(x))
44
45 static int hz = 0;
46 static struct nl_sock *sock = NULL;
47
48 typedef struct {
49         union {
50                 struct in_addr v4;
51                 struct in6_addr v6;
52         } addr;
53         int len;
54         int bits;
55         int family;
56         bool exact;
57 } cidr_t;
58
59 struct dump_filter {
60         bool get;
61         int family;
62         int iif;
63         int oif;
64         int type;
65         int scope;
66         int proto;
67         int table;
68         cidr_t gw;
69         cidr_t from;
70         cidr_t src;
71         cidr_t dst;
72         struct ether_addr mac;
73 };
74
75 struct dump_state {
76         int index;
77         int pending;
78         int callback;
79         struct lua_State *L;
80         struct dump_filter *filter;
81 };
82
83
84 static int _cidr_new(lua_State *L, int index, int family, bool mask);
85
86 static cidr_t *L_checkcidr (lua_State *L, int index, cidr_t *p)
87 {
88         if (lua_type(L, index) == LUA_TUSERDATA)
89                 return luaL_checkudata(L, index, LUCI_IP_CIDR);
90
91         if (_cidr_new(L, index, p ? p->family : 0, false))
92                 return lua_touserdata(L, -1);
93
94         luaL_error(L, "Invalid operand");
95         return NULL;
96 }
97
98 static bool parse_mask(int family, const char *mask, int *bits)
99 {
100         char *e;
101         struct in_addr m;
102         struct in6_addr m6;
103
104         if (family == AF_INET && inet_pton(AF_INET, mask, &m))
105         {
106                 for (*bits = 0, m.s_addr = ntohl(m.s_addr);
107                          *bits < 32 && (m.s_addr << *bits) & 0x80000000;
108                          ++*bits);
109         }
110         else if (family == AF_INET6 && inet_pton(AF_INET6, mask, &m6))
111         {
112                 for (*bits = 0;
113                          *bits < 128 && (m6.s6_addr[*bits / 8] << (*bits % 8)) & 128;
114                          ++*bits);
115         }
116         else
117         {
118                 *bits = strtoul(mask, &e, 10);
119
120                 if (e == mask || *e != 0 || *bits > ((family == AF_INET) ? 32 : 128))
121                         return false;
122         }
123
124         return true;
125 }
126
127 static bool parse_cidr(const char *dest, cidr_t *pp)
128 {
129         char *p, buf[INET6_ADDRSTRLEN * 2 + 2];
130         uint8_t bitlen = 0;
131
132         strncpy(buf, dest, sizeof(buf) - 1);
133
134         p = strchr(buf, '/');
135
136         if (p)
137                 *p++ = 0;
138
139         if (inet_pton(AF_INET, buf, &pp->addr.v4))
140         {
141                 bitlen = 32;
142                 pp->family = AF_INET;
143                 pp->len = sizeof(struct in_addr);
144         }
145         else if (inet_pton(AF_INET6, buf, &pp->addr.v6))
146         {
147                 bitlen = 128;
148                 pp->family = AF_INET6;
149                 pp->len = sizeof(struct in6_addr);
150         }
151         else
152                 return false;
153
154         if (p)
155         {
156                 if (!parse_mask(pp->family, p, &pp->bits))
157                         return false;
158         }
159         else
160         {
161                 pp->bits = bitlen;
162         }
163
164         return true;
165 }
166
167 static int L_getint(lua_State *L, int index, const char *name)
168 {
169         int rv = 0;
170
171         lua_getfield(L, index, name);
172
173         if (lua_type(L, -1) == LUA_TNUMBER)
174                 rv = lua_tonumber(L, -1);
175
176         lua_pop(L, 1);
177
178         return rv;
179 }
180
181 static const char * L_getstr(lua_State *L, int index, const char *name)
182 {
183         const char *rv = NULL;
184
185         lua_getfield(L, index, name);
186
187         if (lua_type(L, -1) == LUA_TSTRING)
188                 rv = lua_tostring(L, -1);
189
190         lua_pop(L, 1);
191
192         return rv;
193 }
194
195 static void L_setint(struct lua_State *L, const char *name, uint32_t n)
196 {
197         lua_pushinteger(L, n);
198         lua_setfield(L, -2, name);
199 }
200
201 static void L_setbool(struct lua_State *L, const char *name, bool val)
202 {
203         lua_pushboolean(L, val);
204         lua_setfield(L, -2, name);
205 }
206
207 static void L_setaddr(struct lua_State *L, const char *name,
208                       int family, void *addr, int bits)
209 {
210         cidr_t *p;
211
212         if (!addr)
213                 return;
214
215         p = lua_newuserdata(L, sizeof(*p));
216
217         if (!p)
218                 return;
219
220         if (family == AF_INET)
221         {
222                 p->family = AF_INET;
223                 p->bits = (bits < 0) ? 32 : bits;
224                 p->len = sizeof(p->addr.v4);
225                 p->addr.v4 = *(struct in_addr *)addr;
226         }
227         else
228         {
229                 p->family = AF_INET6;
230                 p->bits = (bits < 0) ? 128 : bits;
231                 p->len = sizeof(p->addr.v6);
232                 p->addr.v6 = *(struct in6_addr *)addr;
233         }
234
235         luaL_getmetatable(L, LUCI_IP_CIDR);
236         lua_setmetatable(L, -2);
237         lua_setfield(L, -2, name);
238 }
239
240 static void L_setstr(struct lua_State *L, const char *name, const char *val)
241 {
242         lua_pushstring(L, val);
243         lua_setfield(L, -2, name);
244 }
245
246 static void L_setdev(struct lua_State *L, const char *name,
247                      struct nlattr *attr)
248 {
249         char buf[32];
250
251         if (if_indextoname(RTA_INT(attr), buf))
252                 L_setstr(L, name, buf);
253 }
254
255 static int L_checkbits(lua_State *L, int index, cidr_t *p)
256 {
257         int bits;
258
259         if (lua_gettop(L) < index || lua_isnil(L, index))
260         {
261                 bits = p->bits;
262         }
263         else if (lua_type(L, index) == LUA_TNUMBER)
264         {
265                 bits = lua_tointeger(L, index);
266
267                 if (bits < 0 || bits > ((p->family == AF_INET) ? 32 : 128))
268                         return luaL_error(L, "Invalid prefix size");
269         }
270         else if (lua_type(L, index) == LUA_TSTRING)
271         {
272                 if (!parse_mask(p->family, lua_tostring(L, index), &bits))
273                         return luaL_error(L, "Invalid netmask format");
274         }
275         else
276         {
277                 return luaL_error(L, "Invalid data type");
278         }
279
280         return bits;
281 }
282
283 static int _cidr_new(lua_State *L, int index, int family, bool mask)
284 {
285         uint32_t n;
286         const char *addr;
287         cidr_t cidr = { }, *cidrp;
288
289         if (lua_type(L, index) == LUA_TNUMBER)
290         {
291                 n = htonl(lua_tointeger(L, index));
292
293                 if (family == AF_INET6)
294                 {
295                         cidr.family = AF_INET6;
296                         cidr.bits = 128;
297                         cidr.len = sizeof(cidr.addr.v6);
298                         cidr.addr.v6.s6_addr[12] = n;
299                         cidr.addr.v6.s6_addr[13] = (n >> 8);
300                         cidr.addr.v6.s6_addr[14] = (n >> 16);
301                         cidr.addr.v6.s6_addr[15] = (n >> 24);
302                 }
303                 else
304                 {
305                         cidr.family = AF_INET;
306                         cidr.bits = 32;
307                         cidr.len = sizeof(cidr.addr.v4);
308                         cidr.addr.v4.s_addr = n;
309                 }
310         }
311         else
312         {
313                 addr = luaL_checkstring(L, index);
314
315                 if (!parse_cidr(addr, &cidr))
316                         return 0;
317
318                 if (family && cidr.family != family)
319                         return 0;
320
321                 if (mask)
322                         cidr.bits = L_checkbits(L, index + 1, &cidr);
323         }
324
325         if (!(cidrp = lua_newuserdata(L, sizeof(*cidrp))))
326                 return 0;
327
328         *cidrp = cidr;
329         luaL_getmetatable(L, LUCI_IP_CIDR);
330         lua_setmetatable(L, -2);
331         return 1;
332 }
333
334 static int cidr_new(lua_State *L)
335 {
336         return _cidr_new(L, 1, 0, true);
337 }
338
339 static int cidr_ipv4(lua_State *L)
340 {
341         return _cidr_new(L, 1, AF_INET, true);
342 }
343
344 static int cidr_ipv6(lua_State *L)
345 {
346         return _cidr_new(L, 1, AF_INET6, true);
347 }
348
349 static int cidr_is4(lua_State *L)
350 {
351         cidr_t *p = L_checkcidr(L, 1, NULL);
352
353         lua_pushboolean(L, p->family == AF_INET);
354         return 1;
355 }
356
357 static int cidr_is4rfc1918(lua_State *L)
358 {
359         cidr_t *p = L_checkcidr(L, 1, NULL);
360         uint32_t a = htonl(p->addr.v4.s_addr);
361
362         lua_pushboolean(L, (p->family == AF_INET &&
363                             ((a >= 0x0A000000 && a <= 0x0AFFFFFF) ||
364                              (a >= 0xAC100000 && a <= 0xAC1FFFFF) ||
365                              (a >= 0xC0A80000 && a <= 0xC0A8FFFF))));
366
367         return 1;
368 }
369
370 static int cidr_is4linklocal(lua_State *L)
371 {
372         cidr_t *p = L_checkcidr(L, 1, NULL);
373         uint32_t a = htonl(p->addr.v4.s_addr);
374
375         lua_pushboolean(L, (p->family == AF_INET &&
376                             a >= 0xA9FE0000 &&
377                             a <= 0xA9FEFFFF));
378
379         return 1;
380 }
381
382 static bool _is_mapped4(cidr_t *p)
383 {
384         return (p->family == AF_INET6 &&
385                 p->addr.v6.s6_addr[0] == 0 &&
386                 p->addr.v6.s6_addr[1] == 0 &&
387                 p->addr.v6.s6_addr[2] == 0 &&
388                 p->addr.v6.s6_addr[3] == 0 &&
389                 p->addr.v6.s6_addr[4] == 0 &&
390                 p->addr.v6.s6_addr[5] == 0 &&
391                 p->addr.v6.s6_addr[6] == 0 &&
392                 p->addr.v6.s6_addr[7] == 0 &&
393                 p->addr.v6.s6_addr[8] == 0 &&
394                 p->addr.v6.s6_addr[9] == 0 &&
395                 p->addr.v6.s6_addr[10] == 0xFF &&
396                 p->addr.v6.s6_addr[11] == 0xFF);
397 }
398
399 static int cidr_is6mapped4(lua_State *L)
400 {
401         cidr_t *p = L_checkcidr(L, 1, NULL);
402
403         lua_pushboolean(L, _is_mapped4(p));
404         return 1;
405 }
406
407 static int cidr_is6(lua_State *L)
408 {
409         cidr_t *p = L_checkcidr(L, 1, NULL);
410
411         lua_pushboolean(L, p->family == AF_INET6);
412         return 1;
413 }
414
415 static int cidr_is6linklocal(lua_State *L)
416 {
417         cidr_t *p = L_checkcidr(L, 1, NULL);
418
419         lua_pushboolean(L, (p->family == AF_INET6 &&
420                             p->addr.v6.s6_addr[0] == 0xFE &&
421                             p->addr.v6.s6_addr[1] >= 0x80 &&
422                             p->addr.v6.s6_addr[1] <= 0xBF));
423
424         return 1;
425 }
426
427 static int _cidr_cmp(lua_State *L)
428 {
429         cidr_t *a = L_checkcidr(L, 1, NULL);
430         cidr_t *b = L_checkcidr(L, 2, NULL);
431
432         if (a->family != b->family)
433                 return (a->family - b->family);
434
435         return memcmp(&a->addr.v6, &b->addr.v6, a->len);
436 }
437
438 static int cidr_lower(lua_State *L)
439 {
440         lua_pushboolean(L, _cidr_cmp(L) < 0);
441         return 1;
442 }
443
444 static int cidr_higher(lua_State *L)
445 {
446         lua_pushboolean(L, _cidr_cmp(L) > 0);
447         return 1;
448 }
449
450 static int cidr_equal(lua_State *L)
451 {
452         lua_pushboolean(L, _cidr_cmp(L) == 0);
453         return 1;
454 }
455
456 static int cidr_lower_equal(lua_State *L)
457 {
458         lua_pushboolean(L, _cidr_cmp(L) <= 0);
459         return 1;
460 }
461
462 static int cidr_prefix(lua_State *L)
463 {
464         cidr_t *p = L_checkcidr(L, 1, NULL);
465         int bits = L_checkbits(L, 2, p);
466
467         p->bits = bits;
468         lua_pushinteger(L, p->bits);
469         return 1;
470 }
471
472 static void _apply_mask(cidr_t *p, int bits, bool inv)
473 {
474         uint8_t b, i;
475
476         if (bits <= 0)
477         {
478                 memset(&p->addr.v6, inv * 0xFF, p->len);
479         }
480         else if (p->family == AF_INET && bits <= 32)
481         {
482                 if (inv)
483                         p->addr.v4.s_addr |= ntohl((1 << (32 - bits)) - 1);
484                 else
485                         p->addr.v4.s_addr &= ntohl(~((1 << (32 - bits)) - 1));
486         }
487         else if (p->family == AF_INET6 && bits <= 128)
488         {
489                 for (i = 0; i < sizeof(p->addr.v6.s6_addr); i++)
490                 {
491                         b = (bits > 8) ? 8 : bits;
492                         if (inv)
493                                 p->addr.v6.s6_addr[i] |= ~((uint8_t)(0xFF << (8 - b)));
494                         else
495                                 p->addr.v6.s6_addr[i] &= (uint8_t)(0xFF << (8 - b));
496                         bits -= b;
497                 }
498         }
499 }
500
501 static int cidr_network(lua_State *L)
502 {
503         cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
504         int bits = L_checkbits(L, 2, p1);
505
506         if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
507                 return 0;
508
509         *p2 = *p1;
510         p2->bits = (p1->family == AF_INET) ? 32 : 128;
511         _apply_mask(p2, bits, false);
512
513         luaL_getmetatable(L, LUCI_IP_CIDR);
514         lua_setmetatable(L, -2);
515         return 1;
516 }
517
518 static int cidr_host(lua_State *L)
519 {
520         cidr_t *p1 = L_checkcidr(L, 1, NULL);
521         cidr_t *p2 = lua_newuserdata(L, sizeof(*p2));
522
523         if (!p2)
524                 return 0;
525
526         *p2 = *p1;
527         p2->bits = (p1->family == AF_INET) ? 32 : 128;
528
529         luaL_getmetatable(L, LUCI_IP_CIDR);
530         lua_setmetatable(L, -2);
531         return 1;
532 }
533
534 static int cidr_mask(lua_State *L)
535 {
536         cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
537         int bits = L_checkbits(L, 2, p1);
538
539         if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
540                 return 0;
541
542         p2->bits = (p1->family == AF_INET) ? 32 : 128;
543         p2->family = p1->family;
544
545         memset(&p2->addr.v6.s6_addr, 0xFF, sizeof(p2->addr.v6.s6_addr));
546         _apply_mask(p2, bits, false);
547
548         luaL_getmetatable(L, LUCI_IP_CIDR);
549         lua_setmetatable(L, -2);
550         return 1;
551 }
552
553 static int cidr_broadcast(lua_State *L)
554 {
555         cidr_t *p1 = L_checkcidr(L, 1, NULL);
556         cidr_t *p2;
557         int bits = L_checkbits(L, 2, p1);
558
559         if (p1->family == AF_INET6)
560                 return 0;
561
562         if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
563                 return 0;
564
565         *p2 = *p1;
566         p2->bits = (p1->family == AF_INET) ? 32 : 128;
567         _apply_mask(p2, bits, true);
568
569         luaL_getmetatable(L, LUCI_IP_CIDR);
570         lua_setmetatable(L, -2);
571         return 1;
572 }
573
574 static int cidr_mapped4(lua_State *L)
575 {
576         cidr_t *p1 = L_checkcidr(L, 1, NULL);
577         cidr_t *p2;
578
579         if (!_is_mapped4(p1))
580                 return 0;
581
582         if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
583                 return 0;
584
585         p2->family = AF_INET;
586         p2->bits = (p1->bits > 32) ? 32 : p1->bits;
587         memcpy(&p2->addr.v4, p1->addr.v6.s6_addr + 12, sizeof(p2->addr.v4));
588
589         luaL_getmetatable(L, LUCI_IP_CIDR);
590         lua_setmetatable(L, -2);
591         return 1;
592 }
593
594 static int cidr_contains(lua_State *L)
595 {
596         cidr_t *p1 = L_checkcidr(L, 1, NULL);
597         cidr_t *p2 = L_checkcidr(L, 2, NULL);
598         cidr_t a = *p1, b = *p2;
599         bool rv = false;
600
601         if (p1->family == p2->family && p1->bits <= p2->bits)
602         {
603                 _apply_mask(&a, p1->bits, false);
604                 _apply_mask(&b, p1->bits, false);
605
606                 rv = !memcmp(&a.addr.v6, &b.addr.v6, a.len);
607         }
608
609         lua_pushboolean(L, rv);
610         return 1;
611 }
612
613 #define S6_BYTE(a, i) \
614         (a)->addr.v6.s6_addr[sizeof((a)->addr.v6.s6_addr) - (i) - 1]
615
616 static int _cidr_add_sub(lua_State *L, bool add)
617 {
618         cidr_t *p1 = L_checkcidr(L, 1, NULL);
619         cidr_t *p2 = L_checkcidr(L, 2, p1);
620         cidr_t r = *p1;
621         bool inplace = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : false;
622         bool ok = true;
623         uint8_t i, carry;
624         uint32_t a, b;
625
626         if (p1->family == p2->family)
627         {
628                 if (p1->family == AF_INET6)
629                 {
630                         for (i = 0, carry = 0; i < sizeof(r.addr.v6.s6_addr); i++)
631                         {
632                                 if (add)
633                                 {
634                                         S6_BYTE(&r, i) = S6_BYTE(p1, i) + S6_BYTE(p2, i) + carry;
635                                         carry = (S6_BYTE(p1, i) + S6_BYTE(p2, i) + carry) / 256;
636                                 }
637                                 else
638                                 {
639                                         S6_BYTE(&r, i) = (S6_BYTE(p1, i) - S6_BYTE(p2, i) - carry);
640                                         carry = (S6_BYTE(p1, i) < (S6_BYTE(p2, i) + carry));
641                                 }
642                         }
643
644                         /* would over/underflow */
645                         if (carry)
646                         {
647                                 memset(&r.addr.v6, add * 0xFF, sizeof(r.addr.v6));
648                                 ok = false;
649                         }
650                 }
651                 else
652                 {
653                         a = ntohl(p1->addr.v4.s_addr);
654                         b = ntohl(p2->addr.v4.s_addr);
655
656                         /* would over/underflow */
657                         if ((add && (UINT_MAX - a) < b) || (!add && a < b))
658                         {
659                                 r.addr.v4.s_addr = add * 0xFFFFFFFF;
660                                 ok = false;
661                         }
662                         else
663                         {
664                                 r.addr.v4.s_addr = add ? htonl(a + b) : htonl(a - b);
665                         }
666                 }
667         }
668         else
669         {
670                 ok = false;
671         }
672
673         if (inplace)
674         {
675                 *p1 = r;
676                 lua_pushboolean(L, ok);
677                 return 1;
678         }
679
680         if (!(p1 = lua_newuserdata(L, sizeof(*p1))))
681                 return 0;
682
683         *p1 = r;
684
685         luaL_getmetatable(L, LUCI_IP_CIDR);
686         lua_setmetatable(L, -2);
687         return 1;
688 }
689
690 static int cidr_add(lua_State *L)
691 {
692         return _cidr_add_sub(L, true);
693 }
694
695 static int cidr_sub(lua_State *L)
696 {
697         return _cidr_add_sub(L, false);
698 }
699
700 static int cidr_minhost(lua_State *L)
701 {
702         cidr_t *p = L_checkcidr(L, 1, NULL);
703         cidr_t r = *p;
704         uint8_t i, rest, carry;
705
706         _apply_mask(&r, r.bits, false);
707
708         if (r.family == AF_INET6 && r.bits < 128)
709         {
710                 r.bits = 128;
711
712                 for (i = 0, carry = 1; i < sizeof(r.addr.v6.s6_addr); i++)
713                 {
714                         rest = (S6_BYTE(&r, i) + carry) > 255;
715                         S6_BYTE(&r, i) += carry;
716                         carry = rest;
717                 }
718         }
719         else if (r.family == AF_INET && r.bits < 32)
720         {
721                 r.bits = 32;
722                 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) + 1);
723         }
724
725         if (!(p = lua_newuserdata(L, sizeof(*p))))
726                 return 0;
727
728         *p = r;
729
730         luaL_getmetatable(L, LUCI_IP_CIDR);
731         lua_setmetatable(L, -2);
732         return 1;
733 }
734
735 static int cidr_maxhost(lua_State *L)
736 {
737         cidr_t *p = L_checkcidr(L, 1, NULL);
738         cidr_t r = *p;
739
740         _apply_mask(&r, r.bits, true);
741
742         if (r.family == AF_INET && r.bits < 32)
743         {
744                 r.bits = 32;
745                 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) - 1);
746         }
747         else if (r.family == AF_INET6)
748         {
749                 r.bits = 128;
750         }
751
752         if (!(p = lua_newuserdata(L, sizeof(*p))))
753                 return 0;
754
755         *p = r;
756
757         luaL_getmetatable(L, LUCI_IP_CIDR);
758         lua_setmetatable(L, -2);
759         return 1;
760 }
761
762 static int cidr_gc (lua_State *L)
763 {
764         return 0;
765 }
766
767 static int cidr_tostring (lua_State *L)
768 {
769         char buf[INET6_ADDRSTRLEN];
770         cidr_t *p = L_checkcidr(L, 1, NULL);
771
772         if ((p->family == AF_INET && p->bits < 32) ||
773             (p->family == AF_INET6 && p->bits < 128))
774         {
775                 lua_pushfstring(L, "%s/%d",
776                                 inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf)),
777                                                 p->bits);
778         }
779         else
780         {
781                 lua_pushstring(L, inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf)));
782         }
783
784         return 1;
785 }
786
787 /*
788  * route functions
789  */
790
791 static bool diff_prefix(int family, void *addr, int bits, cidr_t *p)
792 {
793         uint8_t i, b, r;
794         uint32_t m;
795
796         if (!p->family)
797                 return false;
798
799         if (!addr || p->family != family || p->bits > bits)
800                 return true;
801
802         if (family == AF_INET6)
803         {
804                 for (i = 0, r = p->bits; i < sizeof(struct in6_addr); i++)
805                 {
806                         b = r ? (0xFF << (8 - ((r > 8) ? 8 : r))) : 0;
807
808                         if ((((struct in6_addr *)addr)->s6_addr[i] & b) !=
809                             (p->addr.v6.s6_addr[i] & b))
810                                 return true;
811
812                         r -= ((r > 8) ? 8 : r);
813                 }
814         }
815         else
816         {
817                 m = p->bits ? htonl(~((1 << (32 - p->bits)) - 1)) : 0;
818
819                 if ((((struct in_addr *)addr)->s_addr & m) != (p->addr.v4.s_addr & m))
820                         return true;
821         }
822
823         return (p->exact && p->bits != bits);
824 }
825
826 static int cb_dump_route(struct nl_msg *msg, void *arg)
827 {
828         struct dump_state *s = arg;
829         struct dump_filter *f = s->filter;
830         struct nlmsghdr *hdr = nlmsg_hdr(msg);
831         struct rtmsg *rt = NLMSG_DATA(hdr);
832         struct nlattr *tb[RTA_MAX+1];
833         struct in6_addr *src, *dst, *gw, *from, def = { };
834         int iif, oif, bitlen;
835         uint32_t table;
836
837         if (hdr->nlmsg_type != RTM_NEWROUTE ||
838             (rt->rtm_family != AF_INET && rt->rtm_family != AF_INET6))
839                 return NL_SKIP;
840
841         nlmsg_parse(hdr, sizeof(*rt), tb, RTA_MAX, NULL);
842
843         iif   = tb[RTA_IIF]     ? RTA_INT(tb[RTA_IIF])      : 0;
844         oif   = tb[RTA_OIF]     ? RTA_INT(tb[RTA_OIF])      : 0;
845         table = tb[RTA_TABLE]   ? RTA_U32(tb[RTA_TABLE])    : rt->rtm_table;
846         from  = tb[RTA_SRC]     ? RTA_DATA(tb[RTA_SRC])     : NULL;
847         src   = tb[RTA_PREFSRC] ? RTA_DATA(tb[RTA_PREFSRC]) : NULL;
848         dst   = tb[RTA_DST]     ? RTA_DATA(tb[RTA_DST])     : &def;
849         gw    = tb[RTA_GATEWAY] ? RTA_DATA(tb[RTA_GATEWAY]) : NULL;
850
851         bitlen = (rt->rtm_family == AF_INET6) ? 128 : 32;
852
853         if ((f->type   && rt->rtm_type     != f->type)   ||
854             (f->family && rt->rtm_family   != f->family) ||
855             (f->proto  && rt->rtm_protocol != f->proto)  ||
856             (f->scope  && rt->rtm_scope    != f->scope)  ||
857                 (f->iif    && iif              != f->iif)    ||
858                 (f->oif    && oif              != f->oif)    ||
859                 (f->table  && table            != f->table)  ||
860             diff_prefix(rt->rtm_family, from, rt->rtm_src_len, &f->from) ||
861             diff_prefix(rt->rtm_family, dst,  rt->rtm_dst_len, &f->dst)  ||
862             diff_prefix(rt->rtm_family, gw,   bitlen, &f->gw)            ||
863             diff_prefix(rt->rtm_family, src,  bitlen, &f->src))
864                 goto out;
865
866         if (s->callback)
867                 lua_pushvalue(s->L, 2);
868
869         lua_newtable(s->L);
870
871         L_setint(s->L, "type", rt->rtm_type);
872         L_setint(s->L, "family", (rt->rtm_family == AF_INET) ? 4 : 6);
873
874         L_setaddr(s->L, "dest", rt->rtm_family, dst, rt->rtm_dst_len);
875
876         if (gw)
877                 L_setaddr(s->L, "gw", rt->rtm_family, gw, -1);
878
879         if (from)
880                 L_setaddr(s->L, "from", rt->rtm_family, from, rt->rtm_src_len);
881
882         if (iif)
883                 L_setdev(s->L, "iif", tb[RTA_IIF]);
884
885         if (oif)
886                 L_setdev(s->L, "dev", tb[RTA_OIF]);
887
888         L_setint(s->L, "table", table);
889         L_setint(s->L, "proto", rt->rtm_protocol);
890         L_setint(s->L, "scope", rt->rtm_scope);
891
892         if (src)
893                 L_setaddr(s->L, "src", rt->rtm_family, src, -1);
894
895         if (tb[RTA_PRIORITY])
896                 L_setint(s->L, "metric", RTA_U32(tb[RTA_PRIORITY]));
897
898         if (rt->rtm_family == AF_INET6 && tb[RTA_CACHEINFO])
899         {
900                 struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]);
901
902                 if (ci->rta_expires)
903                 {
904                         if (ci->rta_expires)
905                                 L_setint(s->L, "expires", ci->rta_expires / hz);
906
907                         if (ci->rta_error != 0)
908                                 L_setint(s->L, "error", ci->rta_error);
909                 }
910         }
911
912         s->index++;
913
914         if (s->callback)
915                 lua_call(s->L, 1, 0);
916         else if (hdr->nlmsg_flags & NLM_F_MULTI)
917                 lua_rawseti(s->L, -2, s->index);
918
919 out:
920         s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
921         return NL_SKIP;
922 }
923
924 static int
925 cb_done(struct nl_msg *msg, void *arg)
926 {
927         struct dump_state *s = arg;
928         s->pending = 0;
929         return NL_STOP;
930 }
931
932 static int
933 cb_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
934 {
935         struct dump_state *s = arg;
936         s->pending = 0;
937         return NL_STOP;
938 }
939
940 static int _error(lua_State *L, int code, const char *msg)
941 {
942         lua_pushnil(L);
943         lua_pushnumber(L, code ? code : errno);
944         lua_pushstring(L, msg ? msg : strerror(errno));
945
946         return 3;
947 }
948
949 static int _route_dump(lua_State *L, struct dump_filter *filter)
950 {
951         int flags = NLM_F_REQUEST;
952         struct dump_state s = {
953                 .L = L,
954                 .pending = 1,
955                 .index = 0,
956                 .callback = lua_isfunction(L, 2),
957                 .filter = filter
958         };
959
960         if (!hz)
961                 hz = sysconf(_SC_CLK_TCK);
962
963         if (!sock)
964         {
965                 sock = nl_socket_alloc();
966                 if (!sock)
967                         return _error(L, -1, "Out of memory");
968
969                 if (nl_connect(sock, NETLINK_ROUTE))
970                         return _error(L, 0, NULL);
971         }
972
973         struct nl_msg *msg;
974         struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
975         struct rtmsg rtm = {
976                 .rtm_family = filter->family,
977                 .rtm_dst_len = filter->dst.bits,
978                 .rtm_src_len = filter->src.bits
979         };
980
981         if (!filter->get)
982                 flags |= NLM_F_DUMP;
983
984         msg = nlmsg_alloc_simple(RTM_GETROUTE, flags);
985         if (!msg)
986                 goto out;
987
988         nlmsg_append(msg, &rtm, sizeof(rtm), 0);
989
990         if (filter->get)
991                 nla_put(msg, RTA_DST, filter->dst.len, &filter->dst.addr.v6);
992
993         nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_route, &s);
994         nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &s);
995         nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &s);
996
997         nl_send_auto_complete(sock, msg);
998
999         if (!filter->get && !s.callback)
1000                 lua_newtable(L);
1001
1002         while (s.pending > 0)
1003                 nl_recvmsgs(sock, cb);
1004
1005         nlmsg_free(msg);
1006
1007 out:
1008         nl_cb_put(cb);
1009         return (s.callback == 0);
1010 }
1011
1012 static int route_get(lua_State *L)
1013 {
1014         struct dump_filter filter = { .get = true };
1015         const char *dest = luaL_checkstring(L, 1);
1016
1017         if (!parse_cidr(dest, &filter.dst))
1018                 return _error(L, -1, "Invalid destination");
1019
1020         filter.family = filter.dst.family;
1021
1022         return _route_dump(L, &filter);
1023 }
1024
1025 static int route_dump(lua_State *L)
1026 {
1027         const char *s;
1028         cidr_t p = { };
1029         struct dump_filter filter = { };
1030
1031         if (lua_type(L, 1) == LUA_TTABLE)
1032         {
1033                 filter.family = L_getint(L, 1, "family");
1034
1035                 if (filter.family == 4)
1036                         filter.family = AF_INET;
1037                 else if (filter.family == 6)
1038                         filter.family = AF_INET6;
1039                 else
1040                         filter.family = 0;
1041
1042                 if ((s = L_getstr(L, 1, "iif")) != NULL)
1043                         filter.iif = if_nametoindex(s);
1044
1045                 if ((s = L_getstr(L, 1, "oif")) != NULL)
1046                         filter.oif = if_nametoindex(s);
1047
1048                 filter.type = L_getint(L, 1, "type");
1049                 filter.scope = L_getint(L, 1, "scope");
1050                 filter.proto = L_getint(L, 1, "proto");
1051                 filter.table = L_getint(L, 1, "table");
1052
1053                 if ((s = L_getstr(L, 1, "gw")) != NULL && parse_cidr(s, &p))
1054                         filter.gw = p;
1055
1056                 if ((s = L_getstr(L, 1, "from")) != NULL && parse_cidr(s, &p))
1057                         filter.from = p;
1058
1059                 if ((s = L_getstr(L, 1, "src")) != NULL && parse_cidr(s, &p))
1060                         filter.src = p;
1061
1062                 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1063                         filter.dst = p;
1064
1065                 if ((s = L_getstr(L, 1, "from_exact")) != NULL && parse_cidr(s, &p))
1066                         filter.from = p, filter.from.exact = true;
1067
1068                 if ((s = L_getstr(L, 1, "dest_exact")) != NULL && parse_cidr(s, &p))
1069                         filter.dst = p, filter.dst.exact = true;
1070         }
1071
1072         return _route_dump(L, &filter);
1073 }
1074
1075
1076 static bool diff_macaddr(struct ether_addr *mac1, struct ether_addr *mac2)
1077 {
1078         struct ether_addr empty = { };
1079
1080         if (!memcmp(mac2, &empty, sizeof(empty)))
1081                 return false;
1082
1083         if (!mac1 || memcmp(mac1, mac2, sizeof(empty)))
1084                 return true;
1085
1086         return false;
1087 }
1088
1089 static int cb_dump_neigh(struct nl_msg *msg, void *arg)
1090 {
1091         char buf[32];
1092         struct ether_addr *mac;
1093         struct in6_addr *dst;
1094         struct dump_state *s = arg;
1095         struct dump_filter *f = s->filter;
1096         struct nlmsghdr *hdr = nlmsg_hdr(msg);
1097         struct ndmsg *nd = NLMSG_DATA(hdr);
1098         struct nlattr *tb[NDA_MAX+1];
1099         int bitlen;
1100
1101         if (hdr->nlmsg_type != RTM_NEWNEIGH ||
1102             (nd->ndm_family != AF_INET && nd->ndm_family != AF_INET6))
1103                 return NL_SKIP;
1104
1105         nlmsg_parse(hdr, sizeof(*nd), tb, NDA_MAX, NULL);
1106
1107         mac = tb[NDA_LLADDR] ? RTA_DATA(tb[NDA_LLADDR]) : NULL;
1108         dst = tb[NDA_DST]    ? RTA_DATA(tb[NDA_DST])    : NULL;
1109
1110         bitlen = (nd->ndm_family == AF_INET) ? 32 : 128;
1111
1112         if ((f->family && nd->ndm_family  != f->family) ||
1113             (f->iif    && nd->ndm_ifindex != f->iif) ||
1114                 (f->type   && !(f->type & nd->ndm_state)) ||
1115             diff_prefix(nd->ndm_family, dst, bitlen, &f->dst) ||
1116             diff_macaddr(mac, &f->mac))
1117                 goto out;
1118
1119         if (s->callback)
1120                 lua_pushvalue(s->L, 2);
1121
1122         lua_newtable(s->L);
1123
1124         L_setint(s->L, "family", (nd->ndm_family == AF_INET) ? 4 : 6);
1125         L_setstr(s->L, "dev", if_indextoname(nd->ndm_ifindex, buf));
1126
1127         L_setbool(s->L, "router", (nd->ndm_flags & NTF_ROUTER));
1128         L_setbool(s->L, "proxy", (nd->ndm_flags & NTF_PROXY));
1129
1130         L_setbool(s->L, "incomplete", (nd->ndm_state & NUD_INCOMPLETE));
1131         L_setbool(s->L, "reachable", (nd->ndm_state & NUD_REACHABLE));
1132         L_setbool(s->L, "stale", (nd->ndm_state & NUD_STALE));
1133         L_setbool(s->L, "delay", (nd->ndm_state & NUD_DELAY));
1134         L_setbool(s->L, "probe", (nd->ndm_state & NUD_PROBE));
1135         L_setbool(s->L, "failed", (nd->ndm_state & NUD_FAILED));
1136         L_setbool(s->L, "noarp", (nd->ndm_state & NUD_NOARP));
1137         L_setbool(s->L, "permanent", (nd->ndm_state & NUD_PERMANENT));
1138
1139         if (dst)
1140                 L_setaddr(s->L, "dest", nd->ndm_family, dst, -1);
1141
1142         if (mac)
1143         {
1144                 snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
1145                          mac->ether_addr_octet[0], mac->ether_addr_octet[1],
1146                          mac->ether_addr_octet[2], mac->ether_addr_octet[3],
1147                          mac->ether_addr_octet[4], mac->ether_addr_octet[5]);
1148
1149                 lua_pushstring(s->L, buf);
1150                 lua_setfield(s->L, -2, "mac");
1151         }
1152
1153         s->index++;
1154
1155         if (s->callback)
1156                 lua_call(s->L, 1, 0);
1157         else if (hdr->nlmsg_flags & NLM_F_MULTI)
1158                 lua_rawseti(s->L, -2, s->index);
1159
1160 out:
1161         s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1162         return NL_SKIP;
1163 }
1164
1165 static int neighbor_dump(lua_State *L)
1166 {
1167         cidr_t p = { };
1168         const char *s;
1169         struct ether_addr *mac;
1170         struct dump_filter filter = { .type = 0xFF & ~NUD_NOARP };
1171         struct dump_state st = {
1172                 .callback = lua_isfunction(L, 2),
1173                 .pending = 1,
1174                 .filter = &filter,
1175                 .L = L
1176         };
1177
1178         if (lua_type(L, 1) == LUA_TTABLE)
1179         {
1180                 filter.family = L_getint(L, 1, "family");
1181
1182                 if (filter.family == 4)
1183                         filter.family = AF_INET;
1184                 else if (filter.family == 6)
1185                         filter.family = AF_INET6;
1186                 else
1187                         filter.family = 0;
1188
1189                 if ((s = L_getstr(L, 1, "dev")) != NULL)
1190                         filter.iif = if_nametoindex(s);
1191
1192                 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1193                         filter.dst = p;
1194
1195                 if ((s = L_getstr(L, 1, "mac")) != NULL &&
1196                     (mac = ether_aton(s)) != NULL)
1197                         filter.mac = *mac;
1198         }
1199
1200         if (!sock)
1201         {
1202                 sock = nl_socket_alloc();
1203                 if (!sock)
1204                         return _error(L, -1, "Out of memory");
1205
1206                 if (nl_connect(sock, NETLINK_ROUTE))
1207                         return _error(L, 0, NULL);
1208         }
1209
1210         struct nl_msg *msg;
1211         struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1212         struct ndmsg ndm = {
1213                 .ndm_family = filter.family
1214         };
1215
1216         msg = nlmsg_alloc_simple(RTM_GETNEIGH, NLM_F_REQUEST | NLM_F_DUMP);
1217         if (!msg)
1218                 goto out;
1219
1220         nlmsg_append(msg, &ndm, sizeof(ndm), 0);
1221
1222         nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_neigh, &st);
1223         nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1224         nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1225
1226         nl_send_auto_complete(sock, msg);
1227
1228         if (!st.callback)
1229                 lua_newtable(L);
1230
1231         while (st.pending > 0)
1232                 nl_recvmsgs(sock, cb);
1233
1234         nlmsg_free(msg);
1235
1236 out:
1237         nl_cb_put(cb);
1238         return (st.callback == 0);
1239 }
1240
1241
1242 static int cb_dump_link(struct nl_msg *msg, void *arg)
1243 {
1244         char *p, *addr, buf[48];
1245         struct dump_state *s = arg;
1246         struct nlmsghdr *hdr = nlmsg_hdr(msg);
1247         struct ifinfomsg *ifm = NLMSG_DATA(hdr);
1248         struct nlattr *tb[IFLA_MAX+1];
1249         int i, len;
1250
1251         if (hdr->nlmsg_type != RTM_NEWLINK)
1252                 return NL_SKIP;
1253
1254         nlmsg_parse(hdr, sizeof(*ifm), tb, IFLA_MAX, NULL);
1255
1256         L_setbool(s->L, "up", (ifm->ifi_flags & IFF_RUNNING));
1257         L_setint(s->L, "type", ifm->ifi_type);
1258         L_setstr(s->L, "name", if_indextoname(ifm->ifi_index, buf));
1259
1260         if (tb[IFLA_MTU])
1261                 L_setint(s->L, "mtu", RTA_U32(tb[IFLA_MTU]));
1262
1263         if (tb[IFLA_TXQLEN])
1264                 L_setint(s->L, "qlen", RTA_U32(tb[IFLA_TXQLEN]));
1265
1266         if (tb[IFLA_MASTER])
1267                 L_setdev(s->L, "master", tb[IFLA_MASTER]);
1268
1269         if (tb[IFLA_ADDRESS])
1270         {
1271                 len  = nla_len(tb[IFLA_ADDRESS]);
1272                 addr = nla_get_string(tb[IFLA_ADDRESS]);
1273
1274                 if ((len * 3) <= sizeof(buf))
1275                 {
1276                         for (p = buf, i = 0; i < len; i++)
1277                                 p += sprintf(p, "%s%02x", (i ? ":" : ""), (uint8_t)*addr++);
1278
1279                         L_setstr(s->L, "mac", buf);
1280                 }
1281         }
1282
1283         s->pending = 0;
1284         return NL_SKIP;
1285 }
1286
1287 static int link_get(lua_State *L)
1288 {
1289         const char *dev = luaL_checkstring(L, 1);
1290         struct dump_state st = {
1291                 .pending = 1,
1292                 .L = L
1293         };
1294
1295         if (!sock)
1296         {
1297                 sock = nl_socket_alloc();
1298                 if (!sock)
1299                         return _error(L, -1, "Out of memory");
1300
1301                 if (nl_connect(sock, NETLINK_ROUTE))
1302                         return _error(L, 0, NULL);
1303         }
1304
1305         struct nl_msg *msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST);
1306         struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1307         struct ifinfomsg ifm = { .ifi_index = if_nametoindex(dev) };
1308
1309         if (!msg || !cb)
1310                 return 0;
1311
1312         nlmsg_append(msg, &ifm, sizeof(ifm), 0);
1313
1314         nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_link, &st);
1315         nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1316         nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1317
1318         lua_newtable(L);
1319
1320         nl_send_auto_complete(sock, msg);
1321
1322         while (st.pending > 0)
1323                 nl_recvmsgs(sock, cb);
1324
1325         nlmsg_free(msg);
1326         nl_cb_put(cb);
1327
1328         return 1;
1329 }
1330
1331
1332 static const luaL_reg ip_methods[] = {
1333         { "new",                        cidr_new          },
1334         { "IPv4",                       cidr_ipv4         },
1335         { "IPv6",                       cidr_ipv6         },
1336
1337         { "route",                      route_get         },
1338         { "routes",                     route_dump        },
1339
1340         { "neighbors",          neighbor_dump     },
1341
1342         { "link",           link_get          },
1343
1344         { }
1345 };
1346
1347 static const luaL_reg ip_cidr_methods[] = {
1348         { "is4",                        cidr_is4          },
1349         { "is4rfc1918",         cidr_is4rfc1918   },
1350         { "is4linklocal",       cidr_is4linklocal },
1351         { "is6",                        cidr_is6          },
1352         { "is6linklocal",       cidr_is6linklocal },
1353         { "is6mapped4",         cidr_is6mapped4   },
1354         { "lower",                      cidr_lower        },
1355         { "higher",                     cidr_higher       },
1356         { "equal",                      cidr_equal        },
1357         { "prefix",                     cidr_prefix       },
1358         { "network",            cidr_network      },
1359         { "host",                       cidr_host         },
1360         { "mask",                       cidr_mask         },
1361         { "broadcast",          cidr_broadcast    },
1362         { "mapped4",            cidr_mapped4      },
1363         { "contains",       cidr_contains     },
1364         { "add",                        cidr_add          },
1365         { "sub",                        cidr_sub          },
1366         { "minhost",            cidr_minhost      },
1367         { "maxhost",            cidr_maxhost      },
1368         { "string",                     cidr_tostring     },
1369
1370         { "__lt",                       cidr_lower        },
1371         { "__le",                       cidr_lower_equal  },
1372         { "__eq",                       cidr_equal        },
1373         { "__add",                      cidr_add          },
1374         { "__sub",                      cidr_sub          },
1375         { "__gc",                       cidr_gc           },
1376         { "__tostring",         cidr_tostring     },
1377
1378         { }
1379 };
1380
1381 int luaopen_luci_ip(lua_State *L)
1382 {
1383         luaL_register(L, LUCI_IP, ip_methods);
1384
1385         luaL_newmetatable(L, LUCI_IP_CIDR);
1386         luaL_register(L, NULL, ip_cidr_methods);
1387         lua_pushvalue(L, -1);
1388         lua_setfield(L, -2, "__index");
1389         lua_pop(L, 1);
1390
1391         return 1;
1392 }