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);
225 if (!parse_mask(pp->family, p, &pp->bits))
230 pp->bits = AF_BITS(pp->family);
236 static int format_cidr(lua_State *L, cidr_t *p)
238 char *s, buf[INET6_ADDRSTRLEN + 1 + IF_NAMESIZE + 4];
240 if (p->family == AF_PACKET)
242 snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X",
243 p->addr.mac.ether_addr_octet[0],
244 p->addr.mac.ether_addr_octet[1],
245 p->addr.mac.ether_addr_octet[2],
246 p->addr.mac.ether_addr_octet[3],
247 p->addr.mac.ether_addr_octet[4],
248 p->addr.mac.ether_addr_octet[5]);
250 if (p->bits < AF_BITS(AF_PACKET))
251 lua_pushfstring(L, "%s/%d", buf, p->bits);
253 lua_pushstring(L, buf);
257 inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf));
259 s = buf + strlen(buf);
261 if (p->scope != 0 && if_indextoname(p->scope, s + 1) != NULL) {
266 if (p->bits < AF_BITS(p->family))
267 s += sprintf(s, "/%d", p->bits);
269 lua_pushstring(L, buf);
275 static int L_getint(lua_State *L, int index, const char *name)
279 lua_getfield(L, index, name);
281 if (lua_type(L, -1) == LUA_TNUMBER)
282 rv = lua_tonumber(L, -1);
289 static const char * L_getstr(lua_State *L, int index, const char *name)
291 const char *rv = NULL;
293 lua_getfield(L, index, name);
295 if (lua_type(L, -1) == LUA_TSTRING)
296 rv = lua_tostring(L, -1);
303 static void L_setint(struct lua_State *L, const char *name, uint32_t n)
305 lua_pushinteger(L, n);
306 lua_setfield(L, -2, name);
309 static void L_setbool(struct lua_State *L, const char *name, bool val)
311 lua_pushboolean(L, val);
312 lua_setfield(L, -2, name);
315 static void L_setaddr(struct lua_State *L, const char *name,
316 int family, void *addr, int bits)
323 p = lua_newuserdata(L, sizeof(*p));
328 if (family == AF_INET)
331 p->bits = (bits < 0) ? AF_BITS(AF_INET) : bits;
332 p->addr.v4 = *(struct in_addr *)addr;
335 else if (family == AF_INET6)
337 p->family = AF_INET6;
338 p->bits = (bits < 0) ? AF_BITS(AF_INET6) : bits;
339 p->addr.v6 = *(struct in6_addr *)addr;
344 p->family = AF_PACKET;
345 p->bits = (bits < 0) ? AF_BITS(AF_PACKET) : bits;
346 p->addr.mac = *(struct ether_addr *)addr;
350 luaL_getmetatable(L, LUCI_IP_CIDR);
351 lua_setmetatable(L, -2);
352 lua_setfield(L, -2, name);
355 static void L_setstr(struct lua_State *L, const char *name, const char *val)
357 lua_pushstring(L, val);
358 lua_setfield(L, -2, name);
361 static void L_setdev(struct lua_State *L, const char *name,
366 if (if_indextoname(RTA_INT(attr), buf))
367 L_setstr(L, name, buf);
370 static int L_checkbits(lua_State *L, int index, cidr_t *p)
375 if (lua_gettop(L) < index || lua_isnil(L, index))
379 else if (lua_type(L, index) == LUA_TNUMBER)
381 bits = lua_tointeger(L, index);
383 if (bits < 0 || bits > AF_BITS(p->family))
384 return luaL_error(L, "Invalid prefix size");
386 else if (lua_type(L, index) == LUA_TSTRING)
388 if (!parse_mask(p->family, lua_tostring(L, index), &s16))
389 return luaL_error(L, "Invalid netmask format");
395 return luaL_error(L, "Invalid data type");
401 static int _cidr_new(lua_State *L, int index, int family, bool mask)
405 cidr_t cidr = { }, *cidrp;
407 if (lua_type(L, index) == LUA_TNUMBER)
409 n = htonl(lua_tointeger(L, index));
411 if (family == AF_INET6)
413 cidr.family = AF_INET6;
414 cidr.addr.v6.s6_addr[12] = n;
415 cidr.addr.v6.s6_addr[13] = (n >> 8);
416 cidr.addr.v6.s6_addr[14] = (n >> 16);
417 cidr.addr.v6.s6_addr[15] = (n >> 24);
419 else if (family == AF_INET)
421 cidr.family = AF_INET;
422 cidr.addr.v4.s_addr = n;
426 cidr.family = AF_PACKET;
427 cidr.addr.mac.ether_addr_octet[2] = n;
428 cidr.addr.mac.ether_addr_octet[3] = (n >> 8);
429 cidr.addr.mac.ether_addr_octet[4] = (n >> 16);
430 cidr.addr.mac.ether_addr_octet[5] = (n >> 24);
433 cidr.bits = AF_BITS(cidr.family);
437 addr = luaL_checkstring(L, index);
439 if (!parse_cidr(addr, &cidr))
442 if (family && cidr.family != family)
446 cidr.bits = L_checkbits(L, index + 1, &cidr);
449 if (!(cidrp = lua_newuserdata(L, sizeof(*cidrp))))
453 luaL_getmetatable(L, LUCI_IP_CIDR);
454 lua_setmetatable(L, -2);
458 static int cidr_new(lua_State *L)
460 return _cidr_new(L, 1, 0, true);
463 static int cidr_ipv4(lua_State *L)
465 return _cidr_new(L, 1, AF_INET, true);
468 static int cidr_ipv6(lua_State *L)
470 return _cidr_new(L, 1, AF_INET6, true);
473 static int cidr_mac(lua_State *L)
475 return _cidr_new(L, 1, AF_PACKET, true);
478 static int cidr_check(lua_State *L, int family)
480 cidr_t cidr = { }, *cidrp;
483 if (lua_type(L, 1) == LUA_TSTRING)
485 addr = lua_tostring(L, 1);
487 if (addr && parse_cidr(addr, &cidr) && cidr.family == family)
488 return format_cidr(L, &cidr);
492 cidrp = lua_touserdata(L, 1);
497 if (!lua_getmetatable(L, 1))
500 lua_getfield(L, LUA_REGISTRYINDEX, LUCI_IP_CIDR);
502 if (!lua_rawequal(L, -1, -2))
507 if (cidrp != NULL && cidrp->family == family)
508 return format_cidr(L, cidrp);
514 static int cidr_checkip4(lua_State *L)
516 return cidr_check(L, AF_INET);
519 static int cidr_checkip6(lua_State *L)
521 return cidr_check(L, AF_INET6);
524 static int cidr_checkmac(lua_State *L)
526 return cidr_check(L, AF_PACKET);
529 static int cidr_is4(lua_State *L)
531 cidr_t *p = L_checkcidr(L, 1, NULL);
533 lua_pushboolean(L, p->family == AF_INET);
537 static int cidr_is4rfc1918(lua_State *L)
539 cidr_t *p = L_checkcidr(L, 1, NULL);
540 uint32_t a = htonl(p->addr.v4.s_addr);
542 lua_pushboolean(L, (p->family == AF_INET &&
543 ((a >= 0x0A000000 && a <= 0x0AFFFFFF) ||
544 (a >= 0xAC100000 && a <= 0xAC1FFFFF) ||
545 (a >= 0xC0A80000 && a <= 0xC0A8FFFF))));
550 static int cidr_is4linklocal(lua_State *L)
552 cidr_t *p = L_checkcidr(L, 1, NULL);
553 uint32_t a = htonl(p->addr.v4.s_addr);
555 lua_pushboolean(L, (p->family == AF_INET &&
562 static bool _is_mapped4(cidr_t *p)
564 return (p->family == AF_INET6 &&
565 p->addr.v6.s6_addr[0] == 0 &&
566 p->addr.v6.s6_addr[1] == 0 &&
567 p->addr.v6.s6_addr[2] == 0 &&
568 p->addr.v6.s6_addr[3] == 0 &&
569 p->addr.v6.s6_addr[4] == 0 &&
570 p->addr.v6.s6_addr[5] == 0 &&
571 p->addr.v6.s6_addr[6] == 0 &&
572 p->addr.v6.s6_addr[7] == 0 &&
573 p->addr.v6.s6_addr[8] == 0 &&
574 p->addr.v6.s6_addr[9] == 0 &&
575 p->addr.v6.s6_addr[10] == 0xFF &&
576 p->addr.v6.s6_addr[11] == 0xFF);
579 static int cidr_is6mapped4(lua_State *L)
581 cidr_t *p = L_checkcidr(L, 1, NULL);
583 lua_pushboolean(L, _is_mapped4(p));
587 static int cidr_is6(lua_State *L)
589 cidr_t *p = L_checkcidr(L, 1, NULL);
591 lua_pushboolean(L, p->family == AF_INET6);
595 static int cidr_is6linklocal(lua_State *L)
597 cidr_t *p = L_checkcidr(L, 1, NULL);
599 lua_pushboolean(L, (p->family == AF_INET6 &&
600 p->addr.v6.s6_addr[0] == 0xFE &&
601 p->addr.v6.s6_addr[1] >= 0x80 &&
602 p->addr.v6.s6_addr[1] <= 0xBF));
607 static int cidr_ismac(lua_State *L)
609 cidr_t *p = L_checkcidr(L, 1, NULL);
611 lua_pushboolean(L, p->family == AF_PACKET);
615 static int cidr_ismacmcast(lua_State *L)
617 cidr_t *p = L_checkcidr(L, 1, NULL);
619 lua_pushboolean(L, (p->family == AF_PACKET &&
620 (p->addr.mac.ether_addr_octet[0] & 0x1)));
625 static int cidr_ismaclocal(lua_State *L)
627 cidr_t *p = L_checkcidr(L, 1, NULL);
629 lua_pushboolean(L, (p->family == AF_PACKET &&
630 (p->addr.mac.ether_addr_octet[0] & 0x2)));
635 static int _cidr_cmp(lua_State *L)
637 cidr_t *a = L_checkcidr(L, 1, NULL);
638 cidr_t *b = L_checkcidr(L, 2, NULL);
640 if (a->family != b->family)
641 return (a->family - b->family);
643 return memcmp(&a->addr.v6, &b->addr.v6, AF_BYTES(a->family));
646 static int cidr_lower(lua_State *L)
648 lua_pushboolean(L, _cidr_cmp(L) < 0);
652 static int cidr_higher(lua_State *L)
654 lua_pushboolean(L, _cidr_cmp(L) > 0);
658 static int cidr_equal(lua_State *L)
660 lua_pushboolean(L, _cidr_cmp(L) == 0);
664 static int cidr_lower_equal(lua_State *L)
666 lua_pushboolean(L, _cidr_cmp(L) <= 0);
670 static int cidr_prefix(lua_State *L)
672 cidr_t *p = L_checkcidr(L, 1, NULL);
673 int bits = L_checkbits(L, 2, p);
676 lua_pushinteger(L, p->bits);
680 static void _apply_mask(cidr_t *p, int bits, bool inv)
686 memset(&p->addr.u8, inv * 0xFF, AF_BYTES(p->family));
688 else if (p->family == AF_INET && bits <= AF_BITS(AF_INET))
691 p->addr.v4.s_addr |= ntohl((1 << (AF_BITS(AF_INET) - bits)) - 1);
693 p->addr.v4.s_addr &= ntohl(~((1 << (AF_BITS(AF_INET) - bits)) - 1));
695 else if (bits <= AF_BITS(p->family))
697 for (i = 0; i < AF_BYTES(p->family); i++)
699 b = (bits > 8) ? 8 : bits;
701 p->addr.u8[i] |= ~((uint8_t)(0xFF << (8 - b)));
703 p->addr.u8[i] &= (uint8_t)(0xFF << (8 - b));
709 static int cidr_network(lua_State *L)
711 cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
712 int bits = L_checkbits(L, 2, p1);
714 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
718 p2->bits = AF_BITS(p1->family);
719 _apply_mask(p2, bits, false);
721 luaL_getmetatable(L, LUCI_IP_CIDR);
722 lua_setmetatable(L, -2);
726 static int cidr_host(lua_State *L)
728 cidr_t *p1 = L_checkcidr(L, 1, NULL);
729 cidr_t *p2 = lua_newuserdata(L, sizeof(*p2));
735 p2->bits = AF_BITS(p1->family);
737 luaL_getmetatable(L, LUCI_IP_CIDR);
738 lua_setmetatable(L, -2);
742 static int cidr_mask(lua_State *L)
744 cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
745 int bits = L_checkbits(L, 2, p1);
747 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
751 p2->bits = AF_BITS(p1->family);
752 p2->family = p1->family;
754 memset(&p2->addr.v6.s6_addr, 0xFF, sizeof(p2->addr.v6.s6_addr));
755 _apply_mask(p2, bits, false);
757 luaL_getmetatable(L, LUCI_IP_CIDR);
758 lua_setmetatable(L, -2);
762 static int cidr_broadcast(lua_State *L)
764 cidr_t *p1 = L_checkcidr(L, 1, NULL);
766 int bits = L_checkbits(L, 2, p1);
768 if (p1->family != AF_INET)
771 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
775 p2->bits = AF_BITS(AF_INET);
776 _apply_mask(p2, bits, true);
778 luaL_getmetatable(L, LUCI_IP_CIDR);
779 lua_setmetatable(L, -2);
783 static int cidr_mapped4(lua_State *L)
785 cidr_t *p1 = L_checkcidr(L, 1, NULL);
788 if (!_is_mapped4(p1))
791 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
795 p2->family = AF_INET;
796 p2->bits = (p1->bits > AF_BITS(AF_INET)) ? AF_BITS(AF_INET) : p1->bits;
797 memcpy(&p2->addr.v4, p1->addr.v6.s6_addr + 12, sizeof(p2->addr.v4));
799 luaL_getmetatable(L, LUCI_IP_CIDR);
800 lua_setmetatable(L, -2);
804 static int cidr_unscoped(lua_State *L)
806 cidr_t *p1 = L_checkcidr(L, 1, NULL);
809 if (p1->family != AF_INET6)
812 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
818 luaL_getmetatable(L, LUCI_IP_CIDR);
819 lua_setmetatable(L, -2);
823 static int cidr_tolinklocal(lua_State *L)
825 cidr_t *p1 = L_checkcidr(L, 1, NULL);
829 if (p1->family != AF_PACKET)
832 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
835 p2->scope = p1->scope;
836 p2->family = AF_INET6;
837 p2->bits = AF_BITS(AF_INET6);
838 p2->addr.u8[0] = 0xFE;
839 p2->addr.u8[1] = 0x80;
840 p2->addr.u8[8] = p1->addr.u8[0] ^ 0x02;
841 p2->addr.u8[9] = p1->addr.u8[1];
842 p2->addr.u8[10] = p1->addr.u8[2];
843 p2->addr.u8[11] = 0xFF;
844 p2->addr.u8[12] = 0xFE;
845 p2->addr.u8[13] = p1->addr.u8[3];
846 p2->addr.u8[14] = p1->addr.u8[4];
847 p2->addr.u8[15] = p1->addr.u8[5];
849 luaL_getmetatable(L, LUCI_IP_CIDR);
850 lua_setmetatable(L, -2);
854 static int cidr_tomac(lua_State *L)
856 cidr_t *p1 = L_checkcidr(L, 1, NULL);
860 if (p1->family != AF_INET6 ||
861 p1->addr.u8[0] != 0xFE ||
862 p1->addr.u8[1] != 0x80 ||
863 p1->addr.u8[2] != 0x00 ||
864 p1->addr.u8[3] != 0x00 ||
865 p1->addr.u8[4] != 0x00 ||
866 p1->addr.u8[5] != 0x00 ||
867 p1->addr.u8[6] != 0x00 ||
868 p1->addr.u8[7] != 0x00 ||
869 p1->addr.u8[11] != 0xFF ||
870 p1->addr.u8[12] != 0xFE)
873 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
877 p2->family = AF_PACKET;
878 p2->bits = AF_BITS(AF_PACKET);
879 p2->addr.u8[0] = p1->addr.u8[8] ^ 0x02;
880 p2->addr.u8[1] = p1->addr.u8[9];
881 p2->addr.u8[2] = p1->addr.u8[10];
882 p2->addr.u8[3] = p1->addr.u8[13];
883 p2->addr.u8[4] = p1->addr.u8[14];
884 p2->addr.u8[5] = p1->addr.u8[15];
886 luaL_getmetatable(L, LUCI_IP_CIDR);
887 lua_setmetatable(L, -2);
891 static int cidr_contains(lua_State *L)
893 cidr_t *p1 = L_checkcidr(L, 1, NULL);
894 cidr_t *p2 = L_checkcidr(L, 2, NULL);
895 cidr_t a = *p1, b = *p2;
898 if (p1->family == p2->family && p1->bits <= p2->bits)
900 _apply_mask(&a, p1->bits, false);
901 _apply_mask(&b, p1->bits, false);
903 rv = !memcmp(&a.addr.v6, &b.addr.v6, AF_BYTES(a.family));
906 lua_pushboolean(L, rv);
911 (a)->addr.u8[AF_BYTES((a)->family) - (i) - 1]
913 static int _cidr_add_sub(lua_State *L, bool add)
915 cidr_t *p1 = L_checkcidr(L, 1, NULL);
916 cidr_t *p2 = L_checkcidr(L, 2, p1);
918 bool inplace = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : false;
923 if (p1->family == p2->family)
925 if (p1->family == AF_INET)
927 a = ntohl(p1->addr.v4.s_addr);
928 b = ntohl(p2->addr.v4.s_addr);
930 /* would over/underflow */
931 if ((add && (UINT_MAX - a) < b) || (!add && a < b))
933 r.addr.v4.s_addr = add * 0xFFFFFFFF;
938 r.addr.v4.s_addr = add ? htonl(a + b) : htonl(a - b);
943 for (i = 0, carry = 0; i < AF_BYTES(p1->family); i++)
947 BYTE(&r, i) = BYTE(p1, i) + BYTE(p2, i) + carry;
948 carry = (BYTE(p1, i) + BYTE(p2, i) + carry) / 256;
952 BYTE(&r, i) = (BYTE(p1, i) - BYTE(p2, i) - carry);
953 carry = (BYTE(p1, i) < (BYTE(p2, i) + carry));
957 /* would over/underflow */
960 memset(&r.addr.u8, add * 0xFF, AF_BYTES(r.family));
973 lua_pushboolean(L, ok);
977 if (!(p1 = lua_newuserdata(L, sizeof(*p1))))
982 luaL_getmetatable(L, LUCI_IP_CIDR);
983 lua_setmetatable(L, -2);
987 static int cidr_add(lua_State *L)
989 return _cidr_add_sub(L, true);
992 static int cidr_sub(lua_State *L)
994 return _cidr_add_sub(L, false);
997 static int cidr_minhost(lua_State *L)
999 cidr_t *p = L_checkcidr(L, 1, NULL);
1001 uint8_t i, rest, carry;
1003 _apply_mask(&r, r.bits, false);
1005 if (r.family == AF_INET && r.bits < AF_BITS(AF_INET))
1007 r.bits = AF_BITS(AF_INET);
1008 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) + 1);
1010 else if (r.bits < AF_BITS(r.family))
1012 r.bits = AF_BITS(r.family);
1014 for (i = 0, carry = 1; i < AF_BYTES(r.family); i++)
1016 rest = (BYTE(&r, i) + carry) > 255;
1017 BYTE(&r, i) += carry;
1022 if (!(p = lua_newuserdata(L, sizeof(*p))))
1027 luaL_getmetatable(L, LUCI_IP_CIDR);
1028 lua_setmetatable(L, -2);
1032 static int cidr_maxhost(lua_State *L)
1034 cidr_t *p = L_checkcidr(L, 1, NULL);
1037 _apply_mask(&r, r.bits, true);
1039 if (r.family == AF_INET && r.bits < AF_BITS(AF_INET))
1041 r.bits = AF_BITS(AF_INET);
1042 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) - 1);
1046 r.bits = AF_BITS(r.family);
1049 if (!(p = lua_newuserdata(L, sizeof(*p))))
1054 luaL_getmetatable(L, LUCI_IP_CIDR);
1055 lua_setmetatable(L, -2);
1059 static int cidr_gc (lua_State *L)
1064 static int cidr_tostring (lua_State *L)
1066 cidr_t *p = L_checkcidr(L, 1, NULL);
1067 return format_cidr(L, p);
1074 static bool diff_prefix(int family, void *addr, int bits, bool exact, cidr_t *p)
1076 uint8_t i, b, r, *a;
1082 if (!addr || p->family != family || p->bits > bits)
1085 if (family == AF_INET)
1087 m = p->bits ? htonl(~((1 << (AF_BITS(AF_INET) - p->bits)) - 1)) : 0;
1089 if ((((struct in_addr *)addr)->s_addr & m) != (p->addr.v4.s_addr & m))
1094 for (i = 0, a = addr, r = p->bits; i < AF_BYTES(p->family); i++)
1096 b = r ? (0xFF << (8 - ((r > 8) ? 8 : r))) : 0;
1098 if ((a[i] & b) != (p->addr.u8[i] & b))
1101 r -= ((r > 8) ? 8 : r);
1105 return (exact && p->bits != bits);
1108 static int cb_dump_route(struct nl_msg *msg, void *arg)
1110 struct dump_state *s = arg;
1111 struct dump_filter *f = s->filter;
1112 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1113 struct rtmsg *rt = NLMSG_DATA(hdr);
1114 struct nlattr *tb[RTA_MAX+1];
1115 struct in6_addr *src, *dst, *gw, *from, def = { };
1116 int iif, oif, bitlen;
1119 if (hdr->nlmsg_type != RTM_NEWROUTE ||
1120 (rt->rtm_family != AF_INET && rt->rtm_family != AF_INET6))
1123 nlmsg_parse(hdr, sizeof(*rt), tb, RTA_MAX, NULL);
1125 iif = tb[RTA_IIF] ? RTA_INT(tb[RTA_IIF]) : 0;
1126 oif = tb[RTA_OIF] ? RTA_INT(tb[RTA_OIF]) : 0;
1127 table = tb[RTA_TABLE] ? RTA_U32(tb[RTA_TABLE]) : rt->rtm_table;
1128 from = tb[RTA_SRC] ? RTA_DATA(tb[RTA_SRC]) : NULL;
1129 src = tb[RTA_PREFSRC] ? RTA_DATA(tb[RTA_PREFSRC]) : NULL;
1130 dst = tb[RTA_DST] ? RTA_DATA(tb[RTA_DST]) : &def;
1131 gw = tb[RTA_GATEWAY] ? RTA_DATA(tb[RTA_GATEWAY]) : NULL;
1133 bitlen = AF_BITS(rt->rtm_family);
1136 if ((f->type && rt->rtm_type != f->type) ||
1137 (f->family && rt->rtm_family != f->family) ||
1138 (f->proto && rt->rtm_protocol != f->proto) ||
1139 (f->scope && rt->rtm_scope != f->scope) ||
1140 (f->iif && iif != f->iif) ||
1141 (f->oif && oif != f->oif) ||
1142 (f->table && table != f->table) ||
1143 diff_prefix(rt->rtm_family, from, rt->rtm_src_len,
1144 f->from_exact, &f->from) ||
1145 diff_prefix(rt->rtm_family, dst, rt->rtm_dst_len,
1146 f->dst_exact, &f->dst) ||
1147 diff_prefix(rt->rtm_family, gw, bitlen,
1149 diff_prefix(rt->rtm_family, src, bitlen,
1155 lua_pushvalue(s->L, 2);
1159 L_setint(s->L, "type", rt->rtm_type);
1160 L_setint(s->L, "family", (rt->rtm_family == AF_INET) ? 4 : 6);
1162 L_setaddr(s->L, "dest", rt->rtm_family, dst, rt->rtm_dst_len);
1165 L_setaddr(s->L, "gw", rt->rtm_family, gw, -1);
1168 L_setaddr(s->L, "from", rt->rtm_family, from, rt->rtm_src_len);
1171 L_setdev(s->L, "iif", tb[RTA_IIF]);
1174 L_setdev(s->L, "dev", tb[RTA_OIF]);
1176 L_setint(s->L, "table", table);
1177 L_setint(s->L, "proto", rt->rtm_protocol);
1178 L_setint(s->L, "scope", rt->rtm_scope);
1181 L_setaddr(s->L, "src", rt->rtm_family, src, -1);
1183 if (tb[RTA_PRIORITY])
1184 L_setint(s->L, "metric", RTA_U32(tb[RTA_PRIORITY]));
1186 if (rt->rtm_family == AF_INET6 && tb[RTA_CACHEINFO])
1188 struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]);
1190 if (ci->rta_expires)
1192 if (ci->rta_expires)
1193 L_setint(s->L, "expires", ci->rta_expires / hz);
1195 if (ci->rta_error != 0)
1196 L_setint(s->L, "error", ci->rta_error);
1203 lua_call(s->L, 1, 0);
1204 else if (hdr->nlmsg_flags & NLM_F_MULTI)
1205 lua_rawseti(s->L, -2, s->index);
1208 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1213 cb_done(struct nl_msg *msg, void *arg)
1215 struct dump_state *s = arg;
1221 cb_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
1223 struct dump_state *s = arg;
1228 static int _error(lua_State *L, int code, const char *msg)
1231 lua_pushnumber(L, code ? code : errno);
1232 lua_pushstring(L, msg ? msg : strerror(errno));
1237 static int _route_dump(lua_State *L, struct dump_filter *filter)
1239 int flags = NLM_F_REQUEST;
1240 struct dump_state s = {
1244 .callback = lua_isfunction(L, 2),
1249 hz = sysconf(_SC_CLK_TCK);
1253 sock = nl_socket_alloc();
1255 return _error(L, -1, "Out of memory");
1257 if (nl_connect(sock, NETLINK_ROUTE))
1258 return _error(L, 0, NULL);
1262 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1263 struct rtmsg rtm = {
1264 .rtm_family = filter->family,
1265 .rtm_dst_len = filter->dst.bits,
1266 .rtm_src_len = filter->src.bits
1270 flags |= NLM_F_DUMP;
1272 msg = nlmsg_alloc_simple(RTM_GETROUTE, flags);
1276 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
1279 nla_put(msg, RTA_DST, AF_BYTES(filter->dst.family),
1280 &filter->dst.addr.v6);
1282 if (filter->src.family)
1283 nla_put(msg, RTA_SRC, AF_BYTES(filter->src.family),
1284 &filter->src.addr.v6);
1287 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_route, &s);
1288 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &s);
1289 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &s);
1291 nl_send_auto_complete(sock, msg);
1293 if (!filter->get && !s.callback)
1296 while (s.pending > 0)
1297 nl_recvmsgs(sock, cb);
1310 return (s.index > 0);
1313 static int route_get(lua_State *L)
1315 struct dump_filter filter = { .get = true };
1316 const char *dest = luaL_checkstring(L, 1);
1317 const char *from = luaL_optstring(L, 2, NULL);
1319 if (!parse_cidr(dest, &filter.dst))
1320 return _error(L, -1, "Invalid destination");
1322 if (from && !parse_cidr(from, &filter.src))
1323 return _error(L, -1, "Invalid source");
1325 if (filter.src.family != 0 &&
1326 filter.src.family != filter.dst.family)
1327 return _error(L, -1, "Different source/destination family");
1329 filter.family = filter.dst.family;
1331 return _route_dump(L, &filter);
1334 static int route_dump(lua_State *L)
1338 struct dump_filter filter = { };
1340 if (lua_type(L, 1) == LUA_TTABLE)
1342 filter.family = L_getint(L, 1, "family");
1344 if (filter.family == 4)
1345 filter.family = AF_INET;
1346 else if (filter.family == 6)
1347 filter.family = AF_INET6;
1351 if ((s = L_getstr(L, 1, "iif")) != NULL)
1352 filter.iif = if_nametoindex(s);
1354 if ((s = L_getstr(L, 1, "oif")) != NULL)
1355 filter.oif = if_nametoindex(s);
1357 filter.type = L_getint(L, 1, "type");
1358 filter.scope = L_getint(L, 1, "scope");
1359 filter.proto = L_getint(L, 1, "proto");
1360 filter.table = L_getint(L, 1, "table");
1362 if ((s = L_getstr(L, 1, "gw")) != NULL && parse_cidr(s, &p))
1365 if ((s = L_getstr(L, 1, "from")) != NULL && parse_cidr(s, &p))
1368 if ((s = L_getstr(L, 1, "src")) != NULL && parse_cidr(s, &p))
1371 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1374 if ((s = L_getstr(L, 1, "from_exact")) != NULL && parse_cidr(s, &p))
1375 filter.from = p, filter.from_exact = true;
1377 if ((s = L_getstr(L, 1, "dest_exact")) != NULL && parse_cidr(s, &p))
1378 filter.dst = p, filter.dst_exact = true;
1381 return _route_dump(L, &filter);
1385 static bool diff_macaddr(struct ether_addr *mac1, struct ether_addr *mac2)
1387 struct ether_addr empty = { };
1389 if (!memcmp(mac2, &empty, sizeof(empty)))
1392 if (!mac1 || memcmp(mac1, mac2, sizeof(empty)))
1398 static int cb_dump_neigh(struct nl_msg *msg, void *arg)
1401 struct ether_addr *mac;
1402 struct in6_addr *dst;
1403 struct dump_state *s = arg;
1404 struct dump_filter *f = s->filter;
1405 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1406 struct ndmsg *nd = NLMSG_DATA(hdr);
1407 struct nlattr *tb[NDA_MAX+1];
1410 if (hdr->nlmsg_type != RTM_NEWNEIGH ||
1411 (nd->ndm_family != AF_INET && nd->ndm_family != AF_INET6))
1414 nlmsg_parse(hdr, sizeof(*nd), tb, NDA_MAX, NULL);
1416 mac = tb[NDA_LLADDR] ? RTA_DATA(tb[NDA_LLADDR]) : NULL;
1417 dst = tb[NDA_DST] ? RTA_DATA(tb[NDA_DST]) : NULL;
1419 bitlen = AF_BITS(nd->ndm_family);
1421 if ((f->family && nd->ndm_family != f->family) ||
1422 (f->iif && nd->ndm_ifindex != f->iif) ||
1423 (f->type && !(f->type & nd->ndm_state)) ||
1424 diff_prefix(nd->ndm_family, dst, bitlen, false, &f->dst) ||
1425 diff_macaddr(mac, &f->mac))
1429 lua_pushvalue(s->L, 2);
1433 L_setint(s->L, "family", (nd->ndm_family == AF_INET) ? 4 : 6);
1434 L_setstr(s->L, "dev", if_indextoname(nd->ndm_ifindex, buf));
1436 L_setbool(s->L, "router", (nd->ndm_flags & NTF_ROUTER));
1437 L_setbool(s->L, "proxy", (nd->ndm_flags & NTF_PROXY));
1439 L_setbool(s->L, "incomplete", (nd->ndm_state & NUD_INCOMPLETE));
1440 L_setbool(s->L, "reachable", (nd->ndm_state & NUD_REACHABLE));
1441 L_setbool(s->L, "stale", (nd->ndm_state & NUD_STALE));
1442 L_setbool(s->L, "delay", (nd->ndm_state & NUD_DELAY));
1443 L_setbool(s->L, "probe", (nd->ndm_state & NUD_PROBE));
1444 L_setbool(s->L, "failed", (nd->ndm_state & NUD_FAILED));
1445 L_setbool(s->L, "noarp", (nd->ndm_state & NUD_NOARP));
1446 L_setbool(s->L, "permanent", (nd->ndm_state & NUD_PERMANENT));
1449 L_setaddr(s->L, "dest", nd->ndm_family, dst, -1);
1452 L_setaddr(s->L, "mac", AF_PACKET, mac, -1);
1457 lua_call(s->L, 1, 0);
1458 else if (hdr->nlmsg_flags & NLM_F_MULTI)
1459 lua_rawseti(s->L, -2, s->index);
1462 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1466 static int neighbor_dump(lua_State *L)
1470 struct ether_addr *mac;
1471 struct dump_filter filter = { .type = 0xFF & ~NUD_NOARP };
1472 struct dump_state st = {
1473 .callback = lua_isfunction(L, 2),
1479 if (lua_type(L, 1) == LUA_TTABLE)
1481 filter.family = L_getint(L, 1, "family");
1483 if (filter.family == 4)
1484 filter.family = AF_INET;
1485 else if (filter.family == 6)
1486 filter.family = AF_INET6;
1490 if ((s = L_getstr(L, 1, "dev")) != NULL)
1491 filter.iif = if_nametoindex(s);
1493 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1496 if ((s = L_getstr(L, 1, "mac")) != NULL &&
1497 (mac = ether_aton(s)) != NULL)
1503 sock = nl_socket_alloc();
1505 return _error(L, -1, "Out of memory");
1507 if (nl_connect(sock, NETLINK_ROUTE))
1508 return _error(L, 0, NULL);
1512 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1513 struct ndmsg ndm = {
1514 .ndm_family = filter.family
1517 msg = nlmsg_alloc_simple(RTM_GETNEIGH, NLM_F_REQUEST | NLM_F_DUMP);
1521 nlmsg_append(msg, &ndm, sizeof(ndm), 0);
1523 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_neigh, &st);
1524 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1525 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1527 nl_send_auto_complete(sock, msg);
1532 while (st.pending > 0)
1533 nl_recvmsgs(sock, cb);
1539 return (st.callback == 0);
1543 static int cb_dump_link(struct nl_msg *msg, void *arg)
1546 struct dump_state *s = arg;
1547 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1548 struct ifinfomsg *ifm = NLMSG_DATA(hdr);
1549 struct nlattr *tb[IFLA_MAX+1];
1552 if (hdr->nlmsg_type != RTM_NEWLINK)
1555 nlmsg_parse(hdr, sizeof(*ifm), tb, IFLA_MAX, NULL);
1557 L_setbool(s->L, "up", (ifm->ifi_flags & IFF_RUNNING));
1558 L_setint(s->L, "type", ifm->ifi_type);
1559 L_setstr(s->L, "name", if_indextoname(ifm->ifi_index, buf));
1562 L_setint(s->L, "mtu", RTA_U32(tb[IFLA_MTU]));
1564 if (tb[IFLA_TXQLEN])
1565 L_setint(s->L, "qlen", RTA_U32(tb[IFLA_TXQLEN]));
1567 if (tb[IFLA_MASTER])
1568 L_setdev(s->L, "master", tb[IFLA_MASTER]);
1570 if (tb[IFLA_ADDRESS] && nla_len(tb[IFLA_ADDRESS]) == AF_BYTES(AF_PACKET))
1571 L_setaddr(s->L, "mac", AF_PACKET, nla_get_string(tb[IFLA_ADDRESS]), -1);
1577 static int link_get(lua_State *L)
1579 const char *dev = luaL_checkstring(L, 1);
1580 struct dump_state st = {
1587 sock = nl_socket_alloc();
1589 return _error(L, -1, "Out of memory");
1591 if (nl_connect(sock, NETLINK_ROUTE))
1592 return _error(L, 0, NULL);
1595 struct nl_msg *msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST);
1596 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1597 struct ifinfomsg ifm = { .ifi_index = if_nametoindex(dev) };
1602 nlmsg_append(msg, &ifm, sizeof(ifm), 0);
1604 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_link, &st);
1605 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1606 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1610 nl_send_auto_complete(sock, msg);
1612 while (st.pending > 0)
1613 nl_recvmsgs(sock, cb);
1622 static const luaL_reg ip_methods[] = {
1623 { "new", cidr_new },
1624 { "IPv4", cidr_ipv4 },
1625 { "IPv6", cidr_ipv6 },
1626 { "MAC", cidr_mac },
1628 { "checkip4", cidr_checkip4 },
1629 { "checkip6", cidr_checkip6 },
1630 { "checkmac", cidr_checkmac },
1632 { "route", route_get },
1633 { "routes", route_dump },
1635 { "neighbors", neighbor_dump },
1637 { "link", link_get },
1642 static const luaL_reg ip_cidr_methods[] = {
1643 { "is4", cidr_is4 },
1644 { "is4rfc1918", cidr_is4rfc1918 },
1645 { "is4linklocal", cidr_is4linklocal },
1646 { "is6", cidr_is6 },
1647 { "is6linklocal", cidr_is6linklocal },
1648 { "is6mapped4", cidr_is6mapped4 },
1649 { "ismac", cidr_ismac },
1650 { "ismaclocal", cidr_ismaclocal },
1651 { "ismacmcast", cidr_ismacmcast },
1652 { "lower", cidr_lower },
1653 { "higher", cidr_higher },
1654 { "equal", cidr_equal },
1655 { "prefix", cidr_prefix },
1656 { "network", cidr_network },
1657 { "host", cidr_host },
1658 { "mask", cidr_mask },
1659 { "broadcast", cidr_broadcast },
1660 { "mapped4", cidr_mapped4 },
1661 { "unscoped", cidr_unscoped },
1662 { "tomac", cidr_tomac },
1663 { "tolinklocal", cidr_tolinklocal },
1664 { "contains", cidr_contains },
1665 { "add", cidr_add },
1666 { "sub", cidr_sub },
1667 { "minhost", cidr_minhost },
1668 { "maxhost", cidr_maxhost },
1669 { "string", cidr_tostring },
1671 { "__lt", cidr_lower },
1672 { "__le", cidr_lower_equal },
1673 { "__eq", cidr_equal },
1674 { "__add", cidr_add },
1675 { "__sub", cidr_sub },
1676 { "__gc", cidr_gc },
1677 { "__tostring", cidr_tostring },
1682 int luaopen_luci_ip(lua_State *L)
1684 luaL_register(L, LUCI_IP, ip_methods);
1686 luaL_newmetatable(L, LUCI_IP_CIDR);
1687 luaL_register(L, NULL, ip_cidr_methods);
1688 lua_pushvalue(L, -1);
1689 lua_setfield(L, -2, "__index");