2 Copyright 2015-2018 Jo-Philipp Wich <jo@mein.io>
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
8 http://www.apache.org/licenses/LICENSE-2.0
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.
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>
39 #define LUCI_IP "luci.ip"
40 #define LUCI_IP_CIDR "luci.ip.cidr"
42 #define RTA_INT(x) (*(int *)RTA_DATA(x))
43 #define RTA_U32(x) (*(uint32_t *)RTA_DATA(x))
46 ((f) == AF_INET ? 32 : \
47 ((f) == AF_INET6 ? 128 : \
48 ((f) == AF_PACKET ? 48 : 0)))
51 ((f) == AF_INET ? 4 : \
52 ((f) == AF_INET6 ? 16 : \
53 ((f) == AF_PACKET ? 6 : 0)))
56 static struct nl_sock *sock = NULL;
62 struct ether_addr mac;
83 struct ether_addr mac;
93 struct dump_filter *filter;
97 static int _cidr_new(lua_State *L, int index, int family, bool mask);
99 static cidr_t *L_checkcidr (lua_State *L, int index, cidr_t *p)
101 if (lua_type(L, index) == LUA_TUSERDATA)
102 return luaL_checkudata(L, index, LUCI_IP_CIDR);
104 if (_cidr_new(L, index, p ? p->family : 0, false))
105 return lua_touserdata(L, -1);
107 luaL_error(L, "Invalid operand");
111 static bool parse_mac(const char *mac, struct ether_addr *ea)
117 for (i = 0; i < 6; i++)
121 if (sep == 0 && (mac[0] == ':' || mac[0] == '-'))
124 if (sep == 0 || mac[0] != sep)
130 n = strtoul(mac, &e, 16);
136 ea->ether_addr_octet[i] = n;
145 static bool parse_mask(int family, const char *mask, int16_t *bits)
151 struct ether_addr mac;
155 if (family == AF_INET && inet_pton(AF_INET, mask, &m.v4))
157 for (*bits = 0, m.v4.s_addr = ntohl(m.v4.s_addr);
158 *bits < AF_BITS(AF_INET) && (m.v4.s_addr << *bits) & 0x80000000;
161 else if ((family == AF_INET6 && inet_pton(AF_INET6, mask, &m.v6)) ||
162 (family == AF_PACKET && parse_mac(mask, &m.mac)))
165 *bits < AF_BITS(family) && (m.u8[*bits / 8] << (*bits % 8)) & 128;
170 *bits = strtoul(mask, &e, 10);
172 if (e == mask || *e != 0 || *bits > AF_BITS(family))
179 static bool parse_cidr(const char *dest, cidr_t *pp)
181 char *p, *s, buf[INET6_ADDRSTRLEN * 2 + 2];
183 strncpy(buf, dest, sizeof(buf) - 1);
185 p = strchr(buf, '/');
190 s = strchr(buf, '%');
195 if (inet_pton(AF_INET, buf, &pp->addr.v4))
196 pp->family = AF_INET;
197 else if (inet_pton(AF_INET6, buf, &pp->addr.v6))
198 pp->family = AF_INET6;
199 else if (parse_mac(buf, &pp->addr.mac))
200 pp->family = AF_PACKET;
206 if (pp->family != AF_INET6)
209 if (!(pp->addr.v6.s6_addr[0] == 0xFE &&
210 pp->addr.v6.s6_addr[1] >= 0x80 &&
211 pp->addr.v6.s6_addr[2] <= 0xBF))
214 pp->scope = if_nametoindex(s);
222 if (!parse_mask(pp->family, p, &pp->bits))
227 pp->bits = AF_BITS(pp->family);
233 static int format_cidr(lua_State *L, cidr_t *p)
235 char *s, buf[INET6_ADDRSTRLEN + 1 + IF_NAMESIZE + 4];
237 if (p->family == AF_PACKET)
239 snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X",
240 p->addr.mac.ether_addr_octet[0],
241 p->addr.mac.ether_addr_octet[1],
242 p->addr.mac.ether_addr_octet[2],
243 p->addr.mac.ether_addr_octet[3],
244 p->addr.mac.ether_addr_octet[4],
245 p->addr.mac.ether_addr_octet[5]);
247 if (p->bits < AF_BITS(AF_PACKET))
248 lua_pushfstring(L, "%s/%d", buf, p->bits);
250 lua_pushstring(L, buf);
254 inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf));
256 s = buf + strlen(buf);
258 if (p->scope != 0 && if_indextoname(p->scope, s + 1) != NULL) {
263 if (p->bits < AF_BITS(p->family))
264 s += sprintf(s, "/%d", p->bits);
266 lua_pushstring(L, buf);
272 static int L_getint(lua_State *L, int index, const char *name)
276 lua_getfield(L, index, name);
278 if (lua_type(L, -1) == LUA_TNUMBER)
279 rv = lua_tonumber(L, -1);
286 static const char * L_getstr(lua_State *L, int index, const char *name)
288 const char *rv = NULL;
290 lua_getfield(L, index, name);
292 if (lua_type(L, -1) == LUA_TSTRING)
293 rv = lua_tostring(L, -1);
300 static void L_setint(struct lua_State *L, const char *name, uint32_t n)
302 lua_pushinteger(L, n);
303 lua_setfield(L, -2, name);
306 static void L_setbool(struct lua_State *L, const char *name, bool val)
308 lua_pushboolean(L, val);
309 lua_setfield(L, -2, name);
312 static void L_setaddr(struct lua_State *L, const char *name,
313 int family, void *addr, int bits)
320 p = lua_newuserdata(L, sizeof(*p));
325 if (family == AF_INET)
328 p->bits = (bits < 0) ? AF_BITS(AF_INET) : bits;
329 p->addr.v4 = *(struct in_addr *)addr;
331 else if (family == AF_INET6)
333 p->family = AF_INET6;
334 p->bits = (bits < 0) ? AF_BITS(AF_INET6) : bits;
335 p->addr.v6 = *(struct in6_addr *)addr;
339 p->family = AF_PACKET;
340 p->bits = (bits < 0) ? AF_BITS(AF_PACKET) : bits;
341 p->addr.mac = *(struct ether_addr *)addr;
344 luaL_getmetatable(L, LUCI_IP_CIDR);
345 lua_setmetatable(L, -2);
346 lua_setfield(L, -2, name);
349 static void L_setstr(struct lua_State *L, const char *name, const char *val)
351 lua_pushstring(L, val);
352 lua_setfield(L, -2, name);
355 static void L_setdev(struct lua_State *L, const char *name,
360 if (if_indextoname(RTA_INT(attr), buf))
361 L_setstr(L, name, buf);
364 static int L_checkbits(lua_State *L, int index, cidr_t *p)
369 if (lua_gettop(L) < index || lua_isnil(L, index))
373 else if (lua_type(L, index) == LUA_TNUMBER)
375 bits = lua_tointeger(L, index);
377 if (bits < 0 || bits > AF_BITS(p->family))
378 return luaL_error(L, "Invalid prefix size");
380 else if (lua_type(L, index) == LUA_TSTRING)
382 if (!parse_mask(p->family, lua_tostring(L, index), &s16))
383 return luaL_error(L, "Invalid netmask format");
389 return luaL_error(L, "Invalid data type");
395 static int _cidr_new(lua_State *L, int index, int family, bool mask)
399 cidr_t cidr = { }, *cidrp;
401 if (lua_type(L, index) == LUA_TNUMBER)
403 n = htonl(lua_tointeger(L, index));
405 if (family == AF_INET6)
407 cidr.family = AF_INET6;
408 cidr.addr.v6.s6_addr[12] = n;
409 cidr.addr.v6.s6_addr[13] = (n >> 8);
410 cidr.addr.v6.s6_addr[14] = (n >> 16);
411 cidr.addr.v6.s6_addr[15] = (n >> 24);
413 else if (family == AF_INET)
415 cidr.family = AF_INET;
416 cidr.addr.v4.s_addr = n;
420 cidr.family = AF_PACKET;
421 cidr.addr.mac.ether_addr_octet[2] = n;
422 cidr.addr.mac.ether_addr_octet[3] = (n >> 8);
423 cidr.addr.mac.ether_addr_octet[4] = (n >> 16);
424 cidr.addr.mac.ether_addr_octet[5] = (n >> 24);
427 cidr.bits = AF_BITS(cidr.family);
431 addr = luaL_checkstring(L, index);
433 if (!parse_cidr(addr, &cidr))
436 if (family && cidr.family != family)
440 cidr.bits = L_checkbits(L, index + 1, &cidr);
443 if (!(cidrp = lua_newuserdata(L, sizeof(*cidrp))))
447 luaL_getmetatable(L, LUCI_IP_CIDR);
448 lua_setmetatable(L, -2);
452 static int cidr_new(lua_State *L)
454 return _cidr_new(L, 1, 0, true);
457 static int cidr_ipv4(lua_State *L)
459 return _cidr_new(L, 1, AF_INET, true);
462 static int cidr_ipv6(lua_State *L)
464 return _cidr_new(L, 1, AF_INET6, true);
467 static int cidr_mac(lua_State *L)
469 return _cidr_new(L, 1, AF_PACKET, true);
472 static int cidr_check(lua_State *L, int family)
474 cidr_t cidr = { }, *cidrp;
477 if (lua_type(L, 1) == LUA_TSTRING)
479 addr = lua_tostring(L, 1);
481 if (addr && parse_cidr(addr, &cidr) && cidr.family == family)
482 return format_cidr(L, &cidr);
486 cidrp = lua_touserdata(L, 1);
491 if (!lua_getmetatable(L, 1))
494 lua_getfield(L, LUA_REGISTRYINDEX, LUCI_IP_CIDR);
496 if (!lua_rawequal(L, -1, -2))
501 if (cidrp != NULL && cidrp->family == family)
502 return format_cidr(L, cidrp);
508 static int cidr_checkip4(lua_State *L)
510 return cidr_check(L, AF_INET);
513 static int cidr_checkip6(lua_State *L)
515 return cidr_check(L, AF_INET6);
518 static int cidr_checkmac(lua_State *L)
520 return cidr_check(L, AF_PACKET);
523 static int cidr_is4(lua_State *L)
525 cidr_t *p = L_checkcidr(L, 1, NULL);
527 lua_pushboolean(L, p->family == AF_INET);
531 static int cidr_is4rfc1918(lua_State *L)
533 cidr_t *p = L_checkcidr(L, 1, NULL);
534 uint32_t a = htonl(p->addr.v4.s_addr);
536 lua_pushboolean(L, (p->family == AF_INET &&
537 ((a >= 0x0A000000 && a <= 0x0AFFFFFF) ||
538 (a >= 0xAC100000 && a <= 0xAC1FFFFF) ||
539 (a >= 0xC0A80000 && a <= 0xC0A8FFFF))));
544 static int cidr_is4linklocal(lua_State *L)
546 cidr_t *p = L_checkcidr(L, 1, NULL);
547 uint32_t a = htonl(p->addr.v4.s_addr);
549 lua_pushboolean(L, (p->family == AF_INET &&
556 static bool _is_mapped4(cidr_t *p)
558 return (p->family == AF_INET6 &&
559 p->addr.v6.s6_addr[0] == 0 &&
560 p->addr.v6.s6_addr[1] == 0 &&
561 p->addr.v6.s6_addr[2] == 0 &&
562 p->addr.v6.s6_addr[3] == 0 &&
563 p->addr.v6.s6_addr[4] == 0 &&
564 p->addr.v6.s6_addr[5] == 0 &&
565 p->addr.v6.s6_addr[6] == 0 &&
566 p->addr.v6.s6_addr[7] == 0 &&
567 p->addr.v6.s6_addr[8] == 0 &&
568 p->addr.v6.s6_addr[9] == 0 &&
569 p->addr.v6.s6_addr[10] == 0xFF &&
570 p->addr.v6.s6_addr[11] == 0xFF);
573 static int cidr_is6mapped4(lua_State *L)
575 cidr_t *p = L_checkcidr(L, 1, NULL);
577 lua_pushboolean(L, _is_mapped4(p));
581 static int cidr_is6(lua_State *L)
583 cidr_t *p = L_checkcidr(L, 1, NULL);
585 lua_pushboolean(L, p->family == AF_INET6);
589 static int cidr_is6linklocal(lua_State *L)
591 cidr_t *p = L_checkcidr(L, 1, NULL);
593 lua_pushboolean(L, (p->family == AF_INET6 &&
594 p->addr.v6.s6_addr[0] == 0xFE &&
595 p->addr.v6.s6_addr[1] >= 0x80 &&
596 p->addr.v6.s6_addr[1] <= 0xBF));
601 static int cidr_ismac(lua_State *L)
603 cidr_t *p = L_checkcidr(L, 1, NULL);
605 lua_pushboolean(L, p->family == AF_PACKET);
609 static int cidr_ismacmcast(lua_State *L)
611 cidr_t *p = L_checkcidr(L, 1, NULL);
613 lua_pushboolean(L, (p->family == AF_PACKET &&
614 (p->addr.mac.ether_addr_octet[0] & 0x1)));
619 static int cidr_ismaclocal(lua_State *L)
621 cidr_t *p = L_checkcidr(L, 1, NULL);
623 lua_pushboolean(L, (p->family == AF_PACKET &&
624 (p->addr.mac.ether_addr_octet[0] & 0x2)));
629 static int _cidr_cmp(lua_State *L)
631 cidr_t *a = L_checkcidr(L, 1, NULL);
632 cidr_t *b = L_checkcidr(L, 2, NULL);
634 if (a->family != b->family)
635 return (a->family - b->family);
637 return memcmp(&a->addr.v6, &b->addr.v6, AF_BYTES(a->family));
640 static int cidr_lower(lua_State *L)
642 lua_pushboolean(L, _cidr_cmp(L) < 0);
646 static int cidr_higher(lua_State *L)
648 lua_pushboolean(L, _cidr_cmp(L) > 0);
652 static int cidr_equal(lua_State *L)
654 lua_pushboolean(L, _cidr_cmp(L) == 0);
658 static int cidr_lower_equal(lua_State *L)
660 lua_pushboolean(L, _cidr_cmp(L) <= 0);
664 static int cidr_prefix(lua_State *L)
666 cidr_t *p = L_checkcidr(L, 1, NULL);
667 int bits = L_checkbits(L, 2, p);
670 lua_pushinteger(L, p->bits);
674 static void _apply_mask(cidr_t *p, int bits, bool inv)
680 memset(&p->addr.u8, inv * 0xFF, AF_BYTES(p->family));
682 else if (p->family == AF_INET && bits <= AF_BITS(AF_INET))
685 p->addr.v4.s_addr |= ntohl((1 << (AF_BITS(AF_INET) - bits)) - 1);
687 p->addr.v4.s_addr &= ntohl(~((1 << (AF_BITS(AF_INET) - bits)) - 1));
689 else if (bits <= AF_BITS(p->family))
691 for (i = 0; i < AF_BYTES(p->family); i++)
693 b = (bits > 8) ? 8 : bits;
695 p->addr.u8[i] |= ~((uint8_t)(0xFF << (8 - b)));
697 p->addr.u8[i] &= (uint8_t)(0xFF << (8 - b));
703 static int cidr_network(lua_State *L)
705 cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
706 int bits = L_checkbits(L, 2, p1);
708 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
712 p2->bits = AF_BITS(p1->family);
713 _apply_mask(p2, bits, false);
715 luaL_getmetatable(L, LUCI_IP_CIDR);
716 lua_setmetatable(L, -2);
720 static int cidr_host(lua_State *L)
722 cidr_t *p1 = L_checkcidr(L, 1, NULL);
723 cidr_t *p2 = lua_newuserdata(L, sizeof(*p2));
729 p2->bits = AF_BITS(p1->family);
731 luaL_getmetatable(L, LUCI_IP_CIDR);
732 lua_setmetatable(L, -2);
736 static int cidr_mask(lua_State *L)
738 cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
739 int bits = L_checkbits(L, 2, p1);
741 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
744 p2->bits = AF_BITS(p1->family);
745 p2->family = p1->family;
747 memset(&p2->addr.v6.s6_addr, 0xFF, sizeof(p2->addr.v6.s6_addr));
748 _apply_mask(p2, bits, false);
750 luaL_getmetatable(L, LUCI_IP_CIDR);
751 lua_setmetatable(L, -2);
755 static int cidr_broadcast(lua_State *L)
757 cidr_t *p1 = L_checkcidr(L, 1, NULL);
759 int bits = L_checkbits(L, 2, p1);
761 if (p1->family != AF_INET)
764 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
768 p2->bits = AF_BITS(AF_INET);
769 _apply_mask(p2, bits, true);
771 luaL_getmetatable(L, LUCI_IP_CIDR);
772 lua_setmetatable(L, -2);
776 static int cidr_mapped4(lua_State *L)
778 cidr_t *p1 = L_checkcidr(L, 1, NULL);
781 if (!_is_mapped4(p1))
784 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
787 p2->family = AF_INET;
788 p2->bits = (p1->bits > AF_BITS(AF_INET)) ? AF_BITS(AF_INET) : p1->bits;
789 memcpy(&p2->addr.v4, p1->addr.v6.s6_addr + 12, sizeof(p2->addr.v4));
791 luaL_getmetatable(L, LUCI_IP_CIDR);
792 lua_setmetatable(L, -2);
796 static int cidr_unscoped(lua_State *L)
798 cidr_t *p1 = L_checkcidr(L, 1, NULL);
801 if (p1->family != AF_INET6)
804 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
810 luaL_getmetatable(L, LUCI_IP_CIDR);
811 lua_setmetatable(L, -2);
815 static int cidr_tolinklocal(lua_State *L)
817 cidr_t *p1 = L_checkcidr(L, 1, NULL);
821 if (p1->family != AF_PACKET)
824 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
827 p2->family = AF_INET6;
828 p2->bits = AF_BITS(AF_INET6);
829 p2->addr.u8[0] = 0xFE;
830 p2->addr.u8[1] = 0x80;
831 p2->addr.u8[8] = p1->addr.u8[0] ^ 0x02;
832 p2->addr.u8[9] = p1->addr.u8[1];
833 p2->addr.u8[10] = p1->addr.u8[2];
834 p2->addr.u8[11] = 0xFF;
835 p2->addr.u8[12] = 0xFE;
836 p2->addr.u8[13] = p1->addr.u8[3];
837 p2->addr.u8[14] = p1->addr.u8[4];
838 p2->addr.u8[15] = p1->addr.u8[5];
840 luaL_getmetatable(L, LUCI_IP_CIDR);
841 lua_setmetatable(L, -2);
845 static int cidr_tomac(lua_State *L)
847 cidr_t *p1 = L_checkcidr(L, 1, NULL);
851 if (p1->family != AF_INET6 ||
852 p1->addr.u8[0] != 0xFE ||
853 p1->addr.u8[1] != 0x80 ||
854 p1->addr.u8[2] != 0x00 ||
855 p1->addr.u8[3] != 0x00 ||
856 p1->addr.u8[4] != 0x00 ||
857 p1->addr.u8[5] != 0x00 ||
858 p1->addr.u8[6] != 0x00 ||
859 p1->addr.u8[7] != 0x00 ||
860 p1->addr.u8[11] != 0xFF ||
861 p1->addr.u8[12] != 0xFE)
864 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
867 p2->family = AF_PACKET;
868 p2->bits = AF_BITS(AF_PACKET);
869 p2->addr.u8[0] = p1->addr.u8[8] ^ 0x02;
870 p2->addr.u8[1] = p1->addr.u8[9];
871 p2->addr.u8[2] = p1->addr.u8[10];
872 p2->addr.u8[3] = p1->addr.u8[13];
873 p2->addr.u8[4] = p1->addr.u8[14];
874 p2->addr.u8[5] = p1->addr.u8[15];
876 luaL_getmetatable(L, LUCI_IP_CIDR);
877 lua_setmetatable(L, -2);
881 static int cidr_contains(lua_State *L)
883 cidr_t *p1 = L_checkcidr(L, 1, NULL);
884 cidr_t *p2 = L_checkcidr(L, 2, NULL);
885 cidr_t a = *p1, b = *p2;
888 if (p1->family == p2->family && p1->bits <= p2->bits)
890 _apply_mask(&a, p1->bits, false);
891 _apply_mask(&b, p1->bits, false);
893 rv = !memcmp(&a.addr.v6, &b.addr.v6, AF_BYTES(a.family));
896 lua_pushboolean(L, rv);
901 (a)->addr.u8[AF_BYTES((a)->family) - (i) - 1]
903 static int _cidr_add_sub(lua_State *L, bool add)
905 cidr_t *p1 = L_checkcidr(L, 1, NULL);
906 cidr_t *p2 = L_checkcidr(L, 2, p1);
908 bool inplace = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : false;
913 if (p1->family == p2->family)
915 if (p1->family == AF_INET)
917 a = ntohl(p1->addr.v4.s_addr);
918 b = ntohl(p2->addr.v4.s_addr);
920 /* would over/underflow */
921 if ((add && (UINT_MAX - a) < b) || (!add && a < b))
923 r.addr.v4.s_addr = add * 0xFFFFFFFF;
928 r.addr.v4.s_addr = add ? htonl(a + b) : htonl(a - b);
933 for (i = 0, carry = 0; i < AF_BYTES(p1->family); i++)
937 BYTE(&r, i) = BYTE(p1, i) + BYTE(p2, i) + carry;
938 carry = (BYTE(p1, i) + BYTE(p2, i) + carry) / 256;
942 BYTE(&r, i) = (BYTE(p1, i) - BYTE(p2, i) - carry);
943 carry = (BYTE(p1, i) < (BYTE(p2, i) + carry));
947 /* would over/underflow */
950 memset(&r.addr.u8, add * 0xFF, AF_BYTES(r.family));
963 lua_pushboolean(L, ok);
967 if (!(p1 = lua_newuserdata(L, sizeof(*p1))))
972 luaL_getmetatable(L, LUCI_IP_CIDR);
973 lua_setmetatable(L, -2);
977 static int cidr_add(lua_State *L)
979 return _cidr_add_sub(L, true);
982 static int cidr_sub(lua_State *L)
984 return _cidr_add_sub(L, false);
987 static int cidr_minhost(lua_State *L)
989 cidr_t *p = L_checkcidr(L, 1, NULL);
991 uint8_t i, rest, carry;
993 _apply_mask(&r, r.bits, false);
995 if (r.family == AF_INET && r.bits < AF_BITS(AF_INET))
997 r.bits = AF_BITS(AF_INET);
998 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) + 1);
1000 else if (r.bits < AF_BITS(r.family))
1002 r.bits = AF_BITS(r.family);
1004 for (i = 0, carry = 1; i < AF_BYTES(r.family); i++)
1006 rest = (BYTE(&r, i) + carry) > 255;
1007 BYTE(&r, i) += carry;
1012 if (!(p = lua_newuserdata(L, sizeof(*p))))
1017 luaL_getmetatable(L, LUCI_IP_CIDR);
1018 lua_setmetatable(L, -2);
1022 static int cidr_maxhost(lua_State *L)
1024 cidr_t *p = L_checkcidr(L, 1, NULL);
1027 _apply_mask(&r, r.bits, true);
1029 if (r.family == AF_INET && r.bits < AF_BITS(AF_INET))
1031 r.bits = AF_BITS(AF_INET);
1032 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) - 1);
1036 r.bits = AF_BITS(r.family);
1039 if (!(p = lua_newuserdata(L, sizeof(*p))))
1044 luaL_getmetatable(L, LUCI_IP_CIDR);
1045 lua_setmetatable(L, -2);
1049 static int cidr_gc (lua_State *L)
1054 static int cidr_tostring (lua_State *L)
1056 cidr_t *p = L_checkcidr(L, 1, NULL);
1057 return format_cidr(L, p);
1064 static bool diff_prefix(int family, void *addr, int bits, bool exact, cidr_t *p)
1066 uint8_t i, b, r, *a;
1072 if (!addr || p->family != family || p->bits > bits)
1075 if (family == AF_INET)
1077 m = p->bits ? htonl(~((1 << (AF_BITS(AF_INET) - p->bits)) - 1)) : 0;
1079 if ((((struct in_addr *)addr)->s_addr & m) != (p->addr.v4.s_addr & m))
1084 for (i = 0, a = addr, r = p->bits; i < AF_BYTES(p->family); i++)
1086 b = r ? (0xFF << (8 - ((r > 8) ? 8 : r))) : 0;
1088 if ((a[i] & b) != (p->addr.u8[i] & b))
1091 r -= ((r > 8) ? 8 : r);
1095 return (exact && p->bits != bits);
1098 static int cb_dump_route(struct nl_msg *msg, void *arg)
1100 struct dump_state *s = arg;
1101 struct dump_filter *f = s->filter;
1102 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1103 struct rtmsg *rt = NLMSG_DATA(hdr);
1104 struct nlattr *tb[RTA_MAX+1];
1105 struct in6_addr *src, *dst, *gw, *from, def = { };
1106 int iif, oif, bitlen;
1109 if (hdr->nlmsg_type != RTM_NEWROUTE ||
1110 (rt->rtm_family != AF_INET && rt->rtm_family != AF_INET6))
1113 nlmsg_parse(hdr, sizeof(*rt), tb, RTA_MAX, NULL);
1115 iif = tb[RTA_IIF] ? RTA_INT(tb[RTA_IIF]) : 0;
1116 oif = tb[RTA_OIF] ? RTA_INT(tb[RTA_OIF]) : 0;
1117 table = tb[RTA_TABLE] ? RTA_U32(tb[RTA_TABLE]) : rt->rtm_table;
1118 from = tb[RTA_SRC] ? RTA_DATA(tb[RTA_SRC]) : NULL;
1119 src = tb[RTA_PREFSRC] ? RTA_DATA(tb[RTA_PREFSRC]) : NULL;
1120 dst = tb[RTA_DST] ? RTA_DATA(tb[RTA_DST]) : &def;
1121 gw = tb[RTA_GATEWAY] ? RTA_DATA(tb[RTA_GATEWAY]) : NULL;
1123 bitlen = AF_BITS(rt->rtm_family);
1126 if ((f->type && rt->rtm_type != f->type) ||
1127 (f->family && rt->rtm_family != f->family) ||
1128 (f->proto && rt->rtm_protocol != f->proto) ||
1129 (f->scope && rt->rtm_scope != f->scope) ||
1130 (f->iif && iif != f->iif) ||
1131 (f->oif && oif != f->oif) ||
1132 (f->table && table != f->table) ||
1133 diff_prefix(rt->rtm_family, from, rt->rtm_src_len,
1134 f->from_exact, &f->from) ||
1135 diff_prefix(rt->rtm_family, dst, rt->rtm_dst_len,
1136 f->dst_exact, &f->dst) ||
1137 diff_prefix(rt->rtm_family, gw, bitlen,
1139 diff_prefix(rt->rtm_family, src, bitlen,
1145 lua_pushvalue(s->L, 2);
1149 L_setint(s->L, "type", rt->rtm_type);
1150 L_setint(s->L, "family", (rt->rtm_family == AF_INET) ? 4 : 6);
1152 L_setaddr(s->L, "dest", rt->rtm_family, dst, rt->rtm_dst_len);
1155 L_setaddr(s->L, "gw", rt->rtm_family, gw, -1);
1158 L_setaddr(s->L, "from", rt->rtm_family, from, rt->rtm_src_len);
1161 L_setdev(s->L, "iif", tb[RTA_IIF]);
1164 L_setdev(s->L, "dev", tb[RTA_OIF]);
1166 L_setint(s->L, "table", table);
1167 L_setint(s->L, "proto", rt->rtm_protocol);
1168 L_setint(s->L, "scope", rt->rtm_scope);
1171 L_setaddr(s->L, "src", rt->rtm_family, src, -1);
1173 if (tb[RTA_PRIORITY])
1174 L_setint(s->L, "metric", RTA_U32(tb[RTA_PRIORITY]));
1176 if (rt->rtm_family == AF_INET6 && tb[RTA_CACHEINFO])
1178 struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]);
1180 if (ci->rta_expires)
1182 if (ci->rta_expires)
1183 L_setint(s->L, "expires", ci->rta_expires / hz);
1185 if (ci->rta_error != 0)
1186 L_setint(s->L, "error", ci->rta_error);
1193 lua_call(s->L, 1, 0);
1194 else if (hdr->nlmsg_flags & NLM_F_MULTI)
1195 lua_rawseti(s->L, -2, s->index);
1198 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1203 cb_done(struct nl_msg *msg, void *arg)
1205 struct dump_state *s = arg;
1211 cb_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
1213 struct dump_state *s = arg;
1218 static int _error(lua_State *L, int code, const char *msg)
1221 lua_pushnumber(L, code ? code : errno);
1222 lua_pushstring(L, msg ? msg : strerror(errno));
1227 static int _route_dump(lua_State *L, struct dump_filter *filter)
1229 int flags = NLM_F_REQUEST;
1230 struct dump_state s = {
1234 .callback = lua_isfunction(L, 2),
1239 hz = sysconf(_SC_CLK_TCK);
1243 sock = nl_socket_alloc();
1245 return _error(L, -1, "Out of memory");
1247 if (nl_connect(sock, NETLINK_ROUTE))
1248 return _error(L, 0, NULL);
1252 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1253 struct rtmsg rtm = {
1254 .rtm_family = filter->family,
1255 .rtm_dst_len = filter->dst.bits,
1256 .rtm_src_len = filter->src.bits
1260 flags |= NLM_F_DUMP;
1262 msg = nlmsg_alloc_simple(RTM_GETROUTE, flags);
1266 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
1269 nla_put(msg, RTA_DST, AF_BYTES(filter->dst.family),
1270 &filter->dst.addr.v6);
1272 if (filter->src.family)
1273 nla_put(msg, RTA_SRC, AF_BYTES(filter->src.family),
1274 &filter->src.addr.v6);
1277 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_route, &s);
1278 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &s);
1279 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &s);
1281 nl_send_auto_complete(sock, msg);
1283 if (!filter->get && !s.callback)
1286 while (s.pending > 0)
1287 nl_recvmsgs(sock, cb);
1300 return (s.index > 0);
1303 static int route_get(lua_State *L)
1305 struct dump_filter filter = { .get = true };
1306 const char *dest = luaL_checkstring(L, 1);
1307 const char *from = luaL_optstring(L, 2, NULL);
1309 if (!parse_cidr(dest, &filter.dst))
1310 return _error(L, -1, "Invalid destination");
1312 if (from && !parse_cidr(from, &filter.src))
1313 return _error(L, -1, "Invalid source");
1315 if (filter.src.family != 0 &&
1316 filter.src.family != filter.dst.family)
1317 return _error(L, -1, "Different source/destination family");
1319 filter.family = filter.dst.family;
1321 return _route_dump(L, &filter);
1324 static int route_dump(lua_State *L)
1328 struct dump_filter filter = { };
1330 if (lua_type(L, 1) == LUA_TTABLE)
1332 filter.family = L_getint(L, 1, "family");
1334 if (filter.family == 4)
1335 filter.family = AF_INET;
1336 else if (filter.family == 6)
1337 filter.family = AF_INET6;
1341 if ((s = L_getstr(L, 1, "iif")) != NULL)
1342 filter.iif = if_nametoindex(s);
1344 if ((s = L_getstr(L, 1, "oif")) != NULL)
1345 filter.oif = if_nametoindex(s);
1347 filter.type = L_getint(L, 1, "type");
1348 filter.scope = L_getint(L, 1, "scope");
1349 filter.proto = L_getint(L, 1, "proto");
1350 filter.table = L_getint(L, 1, "table");
1352 if ((s = L_getstr(L, 1, "gw")) != NULL && parse_cidr(s, &p))
1355 if ((s = L_getstr(L, 1, "from")) != NULL && parse_cidr(s, &p))
1358 if ((s = L_getstr(L, 1, "src")) != NULL && parse_cidr(s, &p))
1361 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1364 if ((s = L_getstr(L, 1, "from_exact")) != NULL && parse_cidr(s, &p))
1365 filter.from = p, filter.from_exact = true;
1367 if ((s = L_getstr(L, 1, "dest_exact")) != NULL && parse_cidr(s, &p))
1368 filter.dst = p, filter.dst_exact = true;
1371 return _route_dump(L, &filter);
1375 static bool diff_macaddr(struct ether_addr *mac1, struct ether_addr *mac2)
1377 struct ether_addr empty = { };
1379 if (!memcmp(mac2, &empty, sizeof(empty)))
1382 if (!mac1 || memcmp(mac1, mac2, sizeof(empty)))
1388 static int cb_dump_neigh(struct nl_msg *msg, void *arg)
1391 struct ether_addr *mac;
1392 struct in6_addr *dst;
1393 struct dump_state *s = arg;
1394 struct dump_filter *f = s->filter;
1395 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1396 struct ndmsg *nd = NLMSG_DATA(hdr);
1397 struct nlattr *tb[NDA_MAX+1];
1400 if (hdr->nlmsg_type != RTM_NEWNEIGH ||
1401 (nd->ndm_family != AF_INET && nd->ndm_family != AF_INET6))
1404 nlmsg_parse(hdr, sizeof(*nd), tb, NDA_MAX, NULL);
1406 mac = tb[NDA_LLADDR] ? RTA_DATA(tb[NDA_LLADDR]) : NULL;
1407 dst = tb[NDA_DST] ? RTA_DATA(tb[NDA_DST]) : NULL;
1409 bitlen = AF_BITS(nd->ndm_family);
1411 if ((f->family && nd->ndm_family != f->family) ||
1412 (f->iif && nd->ndm_ifindex != f->iif) ||
1413 (f->type && !(f->type & nd->ndm_state)) ||
1414 diff_prefix(nd->ndm_family, dst, bitlen, false, &f->dst) ||
1415 diff_macaddr(mac, &f->mac))
1419 lua_pushvalue(s->L, 2);
1423 L_setint(s->L, "family", (nd->ndm_family == AF_INET) ? 4 : 6);
1424 L_setstr(s->L, "dev", if_indextoname(nd->ndm_ifindex, buf));
1426 L_setbool(s->L, "router", (nd->ndm_flags & NTF_ROUTER));
1427 L_setbool(s->L, "proxy", (nd->ndm_flags & NTF_PROXY));
1429 L_setbool(s->L, "incomplete", (nd->ndm_state & NUD_INCOMPLETE));
1430 L_setbool(s->L, "reachable", (nd->ndm_state & NUD_REACHABLE));
1431 L_setbool(s->L, "stale", (nd->ndm_state & NUD_STALE));
1432 L_setbool(s->L, "delay", (nd->ndm_state & NUD_DELAY));
1433 L_setbool(s->L, "probe", (nd->ndm_state & NUD_PROBE));
1434 L_setbool(s->L, "failed", (nd->ndm_state & NUD_FAILED));
1435 L_setbool(s->L, "noarp", (nd->ndm_state & NUD_NOARP));
1436 L_setbool(s->L, "permanent", (nd->ndm_state & NUD_PERMANENT));
1439 L_setaddr(s->L, "dest", nd->ndm_family, dst, -1);
1442 L_setaddr(s->L, "mac", AF_PACKET, mac, -1);
1447 lua_call(s->L, 1, 0);
1448 else if (hdr->nlmsg_flags & NLM_F_MULTI)
1449 lua_rawseti(s->L, -2, s->index);
1452 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1456 static int neighbor_dump(lua_State *L)
1460 struct ether_addr *mac;
1461 struct dump_filter filter = { .type = 0xFF & ~NUD_NOARP };
1462 struct dump_state st = {
1463 .callback = lua_isfunction(L, 2),
1469 if (lua_type(L, 1) == LUA_TTABLE)
1471 filter.family = L_getint(L, 1, "family");
1473 if (filter.family == 4)
1474 filter.family = AF_INET;
1475 else if (filter.family == 6)
1476 filter.family = AF_INET6;
1480 if ((s = L_getstr(L, 1, "dev")) != NULL)
1481 filter.iif = if_nametoindex(s);
1483 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1486 if ((s = L_getstr(L, 1, "mac")) != NULL &&
1487 (mac = ether_aton(s)) != NULL)
1493 sock = nl_socket_alloc();
1495 return _error(L, -1, "Out of memory");
1497 if (nl_connect(sock, NETLINK_ROUTE))
1498 return _error(L, 0, NULL);
1502 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1503 struct ndmsg ndm = {
1504 .ndm_family = filter.family
1507 msg = nlmsg_alloc_simple(RTM_GETNEIGH, NLM_F_REQUEST | NLM_F_DUMP);
1511 nlmsg_append(msg, &ndm, sizeof(ndm), 0);
1513 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_neigh, &st);
1514 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1515 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1517 nl_send_auto_complete(sock, msg);
1522 while (st.pending > 0)
1523 nl_recvmsgs(sock, cb);
1529 return (st.callback == 0);
1533 static int cb_dump_link(struct nl_msg *msg, void *arg)
1536 struct dump_state *s = arg;
1537 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1538 struct ifinfomsg *ifm = NLMSG_DATA(hdr);
1539 struct nlattr *tb[IFLA_MAX+1];
1542 if (hdr->nlmsg_type != RTM_NEWLINK)
1545 nlmsg_parse(hdr, sizeof(*ifm), tb, IFLA_MAX, NULL);
1547 L_setbool(s->L, "up", (ifm->ifi_flags & IFF_RUNNING));
1548 L_setint(s->L, "type", ifm->ifi_type);
1549 L_setstr(s->L, "name", if_indextoname(ifm->ifi_index, buf));
1552 L_setint(s->L, "mtu", RTA_U32(tb[IFLA_MTU]));
1554 if (tb[IFLA_TXQLEN])
1555 L_setint(s->L, "qlen", RTA_U32(tb[IFLA_TXQLEN]));
1557 if (tb[IFLA_MASTER])
1558 L_setdev(s->L, "master", tb[IFLA_MASTER]);
1560 if (tb[IFLA_ADDRESS] && nla_len(tb[IFLA_ADDRESS]) == AF_BYTES(AF_PACKET))
1561 L_setaddr(s->L, "mac", AF_PACKET, nla_get_string(tb[IFLA_ADDRESS]), -1);
1567 static int link_get(lua_State *L)
1569 const char *dev = luaL_checkstring(L, 1);
1570 struct dump_state st = {
1577 sock = nl_socket_alloc();
1579 return _error(L, -1, "Out of memory");
1581 if (nl_connect(sock, NETLINK_ROUTE))
1582 return _error(L, 0, NULL);
1585 struct nl_msg *msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST);
1586 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1587 struct ifinfomsg ifm = { .ifi_index = if_nametoindex(dev) };
1592 nlmsg_append(msg, &ifm, sizeof(ifm), 0);
1594 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_link, &st);
1595 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1596 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1600 nl_send_auto_complete(sock, msg);
1602 while (st.pending > 0)
1603 nl_recvmsgs(sock, cb);
1612 static const luaL_reg ip_methods[] = {
1613 { "new", cidr_new },
1614 { "IPv4", cidr_ipv4 },
1615 { "IPv6", cidr_ipv6 },
1616 { "MAC", cidr_mac },
1618 { "checkip4", cidr_checkip4 },
1619 { "checkip6", cidr_checkip6 },
1620 { "checkmac", cidr_checkmac },
1622 { "route", route_get },
1623 { "routes", route_dump },
1625 { "neighbors", neighbor_dump },
1627 { "link", link_get },
1632 static const luaL_reg ip_cidr_methods[] = {
1633 { "is4", cidr_is4 },
1634 { "is4rfc1918", cidr_is4rfc1918 },
1635 { "is4linklocal", cidr_is4linklocal },
1636 { "is6", cidr_is6 },
1637 { "is6linklocal", cidr_is6linklocal },
1638 { "is6mapped4", cidr_is6mapped4 },
1639 { "ismac", cidr_ismac },
1640 { "ismaclocal", cidr_ismaclocal },
1641 { "ismacmcast", cidr_ismacmcast },
1642 { "lower", cidr_lower },
1643 { "higher", cidr_higher },
1644 { "equal", cidr_equal },
1645 { "prefix", cidr_prefix },
1646 { "network", cidr_network },
1647 { "host", cidr_host },
1648 { "mask", cidr_mask },
1649 { "broadcast", cidr_broadcast },
1650 { "mapped4", cidr_mapped4 },
1651 { "unscoped", cidr_unscoped },
1652 { "tomac", cidr_tomac },
1653 { "tolinklocal", cidr_tolinklocal },
1654 { "contains", cidr_contains },
1655 { "add", cidr_add },
1656 { "sub", cidr_sub },
1657 { "minhost", cidr_minhost },
1658 { "maxhost", cidr_maxhost },
1659 { "string", cidr_tostring },
1661 { "__lt", cidr_lower },
1662 { "__le", cidr_lower_equal },
1663 { "__eq", cidr_equal },
1664 { "__add", cidr_add },
1665 { "__sub", cidr_sub },
1666 { "__gc", cidr_gc },
1667 { "__tostring", cidr_tostring },
1672 int luaopen_luci_ip(lua_State *L)
1674 luaL_register(L, LUCI_IP, ip_methods);
1676 luaL_newmetatable(L, LUCI_IP_CIDR);
1677 luaL_register(L, NULL, ip_cidr_methods);
1678 lua_pushvalue(L, -1);
1679 lua_setfield(L, -2, "__index");