2 Copyright 2015 Jo-Philipp Wich <jow@openwrt.org>
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 static struct nl_sock *sock = NULL;
72 struct ether_addr mac;
80 struct dump_filter *filter;
84 static int _cidr_new(lua_State *L, int index, int family, bool mask);
86 static cidr_t *L_checkcidr (lua_State *L, int index, cidr_t *p)
88 if (lua_type(L, index) == LUA_TUSERDATA)
89 return luaL_checkudata(L, index, LUCI_IP_CIDR);
91 if (_cidr_new(L, index, p ? p->family : 0, false))
92 return lua_touserdata(L, -1);
94 luaL_error(L, "Invalid operand");
98 static bool parse_mask(int family, const char *mask, int *bits)
104 if (family == AF_INET && inet_pton(AF_INET, mask, &m))
106 for (*bits = 0, m.s_addr = ntohl(m.s_addr);
107 *bits < 32 && (m.s_addr << *bits) & 0x80000000;
110 else if (family == AF_INET6 && inet_pton(AF_INET6, mask, &m6))
113 *bits < 128 && (m6.s6_addr[*bits / 8] << (*bits % 8)) & 128;
118 *bits = strtoul(mask, &e, 10);
120 if (e == mask || *e != 0 || *bits > ((family == AF_INET) ? 32 : 128))
127 static bool parse_cidr(const char *dest, cidr_t *pp)
129 char *p, buf[INET6_ADDRSTRLEN * 2 + 2];
132 strncpy(buf, dest, sizeof(buf) - 1);
134 p = strchr(buf, '/');
139 if (inet_pton(AF_INET, buf, &pp->addr.v4))
142 pp->family = AF_INET;
143 pp->len = sizeof(struct in_addr);
145 else if (inet_pton(AF_INET6, buf, &pp->addr.v6))
148 pp->family = AF_INET6;
149 pp->len = sizeof(struct in6_addr);
156 if (!parse_mask(pp->family, p, &pp->bits))
167 static int L_getint(lua_State *L, int index, const char *name)
171 lua_getfield(L, index, name);
173 if (lua_type(L, -1) == LUA_TNUMBER)
174 rv = lua_tonumber(L, -1);
181 static const char * L_getstr(lua_State *L, int index, const char *name)
183 const char *rv = NULL;
185 lua_getfield(L, index, name);
187 if (lua_type(L, -1) == LUA_TSTRING)
188 rv = lua_tostring(L, -1);
195 static void L_setint(struct lua_State *L, const char *name, uint32_t n)
197 lua_pushinteger(L, n);
198 lua_setfield(L, -2, name);
201 static void L_setbool(struct lua_State *L, const char *name, bool val)
203 lua_pushboolean(L, val);
204 lua_setfield(L, -2, name);
207 static void L_setaddr(struct lua_State *L, const char *name,
208 int family, void *addr, int bits)
215 p = lua_newuserdata(L, sizeof(*p));
220 if (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;
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;
235 luaL_getmetatable(L, LUCI_IP_CIDR);
236 lua_setmetatable(L, -2);
237 lua_setfield(L, -2, name);
240 static void L_setstr(struct lua_State *L, const char *name, const char *val)
242 lua_pushstring(L, val);
243 lua_setfield(L, -2, name);
246 static void L_setdev(struct lua_State *L, const char *name,
251 if (if_indextoname(RTA_INT(attr), buf))
252 L_setstr(L, name, buf);
255 static int L_checkbits(lua_State *L, int index, cidr_t *p)
259 if (lua_gettop(L) < index || lua_isnil(L, index))
263 else if (lua_type(L, index) == LUA_TNUMBER)
265 bits = lua_tointeger(L, index);
267 if (bits < 0 || bits > ((p->family == AF_INET) ? 32 : 128))
268 return luaL_error(L, "Invalid prefix size");
270 else if (lua_type(L, index) == LUA_TSTRING)
272 if (!parse_mask(p->family, lua_tostring(L, index), &bits))
273 return luaL_error(L, "Invalid netmask format");
277 return luaL_error(L, "Invalid data type");
283 static int _cidr_new(lua_State *L, int index, int family, bool mask)
287 cidr_t cidr = { }, *cidrp;
289 if (lua_type(L, index) == LUA_TNUMBER)
291 n = htonl(lua_tointeger(L, index));
293 if (family == AF_INET6)
295 cidr.family = AF_INET6;
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);
305 cidr.family = AF_INET;
307 cidr.len = sizeof(cidr.addr.v4);
308 cidr.addr.v4.s_addr = n;
313 addr = luaL_checkstring(L, index);
315 if (!parse_cidr(addr, &cidr))
318 if (family && cidr.family != family)
322 cidr.bits = L_checkbits(L, index + 1, &cidr);
325 if (!(cidrp = lua_newuserdata(L, sizeof(*cidrp))))
329 luaL_getmetatable(L, LUCI_IP_CIDR);
330 lua_setmetatable(L, -2);
334 static int cidr_new(lua_State *L)
336 return _cidr_new(L, 1, 0, true);
339 static int cidr_ipv4(lua_State *L)
341 return _cidr_new(L, 1, AF_INET, true);
344 static int cidr_ipv6(lua_State *L)
346 return _cidr_new(L, 1, AF_INET6, true);
349 static int cidr_is4(lua_State *L)
351 cidr_t *p = L_checkcidr(L, 1, NULL);
353 lua_pushboolean(L, p->family == AF_INET);
357 static int cidr_is4rfc1918(lua_State *L)
359 cidr_t *p = L_checkcidr(L, 1, NULL);
360 uint32_t a = htonl(p->addr.v4.s_addr);
362 lua_pushboolean(L, (p->family == AF_INET &&
363 ((a >= 0x0A000000 && a <= 0x0AFFFFFF) ||
364 (a >= 0xAC100000 && a <= 0xAC1FFFFF) ||
365 (a >= 0xC0A80000 && a <= 0xC0A8FFFF))));
370 static int cidr_is4linklocal(lua_State *L)
372 cidr_t *p = L_checkcidr(L, 1, NULL);
373 uint32_t a = htonl(p->addr.v4.s_addr);
375 lua_pushboolean(L, (p->family == AF_INET &&
382 static bool _is_mapped4(cidr_t *p)
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);
399 static int cidr_is6mapped4(lua_State *L)
401 cidr_t *p = L_checkcidr(L, 1, NULL);
403 lua_pushboolean(L, _is_mapped4(p));
407 static int cidr_is6(lua_State *L)
409 cidr_t *p = L_checkcidr(L, 1, NULL);
411 lua_pushboolean(L, p->family == AF_INET6);
415 static int cidr_is6linklocal(lua_State *L)
417 cidr_t *p = L_checkcidr(L, 1, NULL);
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));
427 static int _cidr_cmp(lua_State *L)
429 cidr_t *a = L_checkcidr(L, 1, NULL);
430 cidr_t *b = L_checkcidr(L, 2, NULL);
432 if (a->family != b->family)
433 return (a->family - b->family);
435 return memcmp(&a->addr.v6, &b->addr.v6, a->len);
438 static int cidr_lower(lua_State *L)
440 lua_pushboolean(L, _cidr_cmp(L) < 0);
444 static int cidr_higher(lua_State *L)
446 lua_pushboolean(L, _cidr_cmp(L) > 0);
450 static int cidr_equal(lua_State *L)
452 lua_pushboolean(L, _cidr_cmp(L) == 0);
456 static int cidr_lower_equal(lua_State *L)
458 lua_pushboolean(L, _cidr_cmp(L) <= 0);
462 static int cidr_prefix(lua_State *L)
464 cidr_t *p = L_checkcidr(L, 1, NULL);
465 int bits = L_checkbits(L, 2, p);
468 lua_pushinteger(L, p->bits);
472 static void _apply_mask(cidr_t *p, int bits, bool inv)
478 memset(&p->addr.v6, inv * 0xFF, p->len);
480 else if (p->family == AF_INET && bits <= 32)
483 p->addr.v4.s_addr |= ntohl((1 << (32 - bits)) - 1);
485 p->addr.v4.s_addr &= ntohl(~((1 << (32 - bits)) - 1));
487 else if (p->family == AF_INET6 && bits <= 128)
489 for (i = 0; i < sizeof(p->addr.v6.s6_addr); i++)
491 b = (bits > 8) ? 8 : bits;
493 p->addr.v6.s6_addr[i] |= ~((uint8_t)(0xFF << (8 - b)));
495 p->addr.v6.s6_addr[i] &= (uint8_t)(0xFF << (8 - b));
501 static int cidr_network(lua_State *L)
503 cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
504 int bits = L_checkbits(L, 2, p1);
506 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
510 p2->bits = (p1->family == AF_INET) ? 32 : 128;
511 _apply_mask(p2, bits, false);
513 luaL_getmetatable(L, LUCI_IP_CIDR);
514 lua_setmetatable(L, -2);
518 static int cidr_host(lua_State *L)
520 cidr_t *p1 = L_checkcidr(L, 1, NULL);
521 cidr_t *p2 = lua_newuserdata(L, sizeof(*p2));
527 p2->bits = (p1->family == AF_INET) ? 32 : 128;
529 luaL_getmetatable(L, LUCI_IP_CIDR);
530 lua_setmetatable(L, -2);
534 static int cidr_mask(lua_State *L)
536 cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
537 int bits = L_checkbits(L, 2, p1);
539 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
542 p2->bits = (p1->family == AF_INET) ? 32 : 128;
543 p2->family = p1->family;
545 memset(&p2->addr.v6.s6_addr, 0xFF, sizeof(p2->addr.v6.s6_addr));
546 _apply_mask(p2, bits, false);
548 luaL_getmetatable(L, LUCI_IP_CIDR);
549 lua_setmetatable(L, -2);
553 static int cidr_broadcast(lua_State *L)
555 cidr_t *p1 = L_checkcidr(L, 1, NULL);
557 int bits = L_checkbits(L, 2, p1);
559 if (p1->family == AF_INET6)
562 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
566 p2->bits = (p1->family == AF_INET) ? 32 : 128;
567 _apply_mask(p2, bits, true);
569 luaL_getmetatable(L, LUCI_IP_CIDR);
570 lua_setmetatable(L, -2);
574 static int cidr_mapped4(lua_State *L)
576 cidr_t *p1 = L_checkcidr(L, 1, NULL);
579 if (!_is_mapped4(p1))
582 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
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));
589 luaL_getmetatable(L, LUCI_IP_CIDR);
590 lua_setmetatable(L, -2);
594 static int cidr_contains(lua_State *L)
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;
601 if (p1->family == p2->family && p1->bits <= p2->bits)
603 _apply_mask(&a, p1->bits, false);
604 _apply_mask(&b, p1->bits, false);
606 rv = !memcmp(&a.addr.v6, &b.addr.v6, a.len);
609 lua_pushboolean(L, rv);
613 #define S6_BYTE(a, i) \
614 (a)->addr.v6.s6_addr[sizeof((a)->addr.v6.s6_addr) - (i) - 1]
616 static int _cidr_add_sub(lua_State *L, bool add)
618 cidr_t *p1 = L_checkcidr(L, 1, NULL);
619 cidr_t *p2 = L_checkcidr(L, 2, p1);
621 bool inplace = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : false;
626 if (p1->family == p2->family)
628 if (p1->family == AF_INET6)
630 for (i = 0, carry = 0; i < sizeof(r.addr.v6.s6_addr); i++)
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;
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));
644 /* would over/underflow */
647 memset(&r.addr.v6, add * 0xFF, sizeof(r.addr.v6));
653 a = ntohl(p1->addr.v4.s_addr);
654 b = ntohl(p2->addr.v4.s_addr);
656 /* would over/underflow */
657 if ((add && (UINT_MAX - a) < b) || (!add && a < b))
659 r.addr.v4.s_addr = add * 0xFFFFFFFF;
664 r.addr.v4.s_addr = add ? htonl(a + b) : htonl(a - b);
676 lua_pushboolean(L, ok);
680 if (!(p1 = lua_newuserdata(L, sizeof(*p1))))
685 luaL_getmetatable(L, LUCI_IP_CIDR);
686 lua_setmetatable(L, -2);
690 static int cidr_add(lua_State *L)
692 return _cidr_add_sub(L, true);
695 static int cidr_sub(lua_State *L)
697 return _cidr_add_sub(L, false);
700 static int cidr_minhost(lua_State *L)
702 cidr_t *p = L_checkcidr(L, 1, NULL);
704 uint8_t i, rest, carry;
706 _apply_mask(&r, r.bits, false);
708 if (r.family == AF_INET6 && r.bits < 128)
712 for (i = 0, carry = 1; i < sizeof(r.addr.v6.s6_addr); i++)
714 rest = (S6_BYTE(&r, i) + carry) > 255;
715 S6_BYTE(&r, i) += carry;
719 else if (r.family == AF_INET && r.bits < 32)
722 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) + 1);
725 if (!(p = lua_newuserdata(L, sizeof(*p))))
730 luaL_getmetatable(L, LUCI_IP_CIDR);
731 lua_setmetatable(L, -2);
735 static int cidr_maxhost(lua_State *L)
737 cidr_t *p = L_checkcidr(L, 1, NULL);
740 _apply_mask(&r, r.bits, true);
742 if (r.family == AF_INET && r.bits < 32)
745 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) - 1);
747 else if (r.family == AF_INET6)
752 if (!(p = lua_newuserdata(L, sizeof(*p))))
757 luaL_getmetatable(L, LUCI_IP_CIDR);
758 lua_setmetatable(L, -2);
762 static int cidr_gc (lua_State *L)
767 static int cidr_tostring (lua_State *L)
769 char buf[INET6_ADDRSTRLEN];
770 cidr_t *p = L_checkcidr(L, 1, NULL);
772 if ((p->family == AF_INET && p->bits < 32) ||
773 (p->family == AF_INET6 && p->bits < 128))
775 lua_pushfstring(L, "%s/%d",
776 inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf)),
781 lua_pushstring(L, inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf)));
791 static bool diff_prefix(int family, void *addr, int bits, cidr_t *p)
799 if (!addr || p->family != family || p->bits > bits)
802 if (family == AF_INET6)
804 for (i = 0, r = p->bits; i < sizeof(struct in6_addr); i++)
806 b = r ? (0xFF << (8 - ((r > 8) ? 8 : r))) : 0;
808 if ((((struct in6_addr *)addr)->s6_addr[i] & b) !=
809 (p->addr.v6.s6_addr[i] & b))
812 r -= ((r > 8) ? 8 : r);
817 m = p->bits ? htonl(~((1 << (32 - p->bits)) - 1)) : 0;
819 if ((((struct in_addr *)addr)->s_addr & m) != (p->addr.v4.s_addr & m))
823 return (p->exact && p->bits != bits);
826 static int cb_dump_route(struct nl_msg *msg, void *arg)
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;
837 if (hdr->nlmsg_type != RTM_NEWROUTE ||
838 (rt->rtm_family != AF_INET && rt->rtm_family != AF_INET6))
841 nlmsg_parse(hdr, sizeof(*rt), tb, RTA_MAX, NULL);
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;
851 bitlen = (rt->rtm_family == AF_INET6) ? 128 : 32;
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))
867 lua_pushvalue(s->L, 2);
871 L_setint(s->L, "type", rt->rtm_type);
872 L_setint(s->L, "family", (rt->rtm_family == AF_INET) ? 4 : 6);
874 L_setaddr(s->L, "dest", rt->rtm_family, dst, rt->rtm_dst_len);
877 L_setaddr(s->L, "gw", rt->rtm_family, gw, -1);
880 L_setaddr(s->L, "from", rt->rtm_family, from, rt->rtm_src_len);
883 L_setdev(s->L, "iif", tb[RTA_IIF]);
886 L_setdev(s->L, "dev", tb[RTA_OIF]);
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);
893 L_setaddr(s->L, "src", rt->rtm_family, src, -1);
895 if (tb[RTA_PRIORITY])
896 L_setint(s->L, "metric", RTA_U32(tb[RTA_PRIORITY]));
898 if (rt->rtm_family == AF_INET6 && tb[RTA_CACHEINFO])
900 struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]);
905 L_setint(s->L, "expires", ci->rta_expires / hz);
907 if (ci->rta_error != 0)
908 L_setint(s->L, "error", ci->rta_error);
915 lua_call(s->L, 1, 0);
916 else if (hdr->nlmsg_flags & NLM_F_MULTI)
917 lua_rawseti(s->L, -2, s->index);
920 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
925 cb_done(struct nl_msg *msg, void *arg)
927 struct dump_state *s = arg;
933 cb_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
935 struct dump_state *s = arg;
940 static int _error(lua_State *L, int code, const char *msg)
943 lua_pushnumber(L, code ? code : errno);
944 lua_pushstring(L, msg ? msg : strerror(errno));
949 static int _route_dump(lua_State *L, struct dump_filter *filter)
951 int flags = NLM_F_REQUEST;
952 struct dump_state s = {
956 .callback = lua_isfunction(L, 2),
961 hz = sysconf(_SC_CLK_TCK);
965 sock = nl_socket_alloc();
967 return _error(L, -1, "Out of memory");
969 if (nl_connect(sock, NETLINK_ROUTE))
970 return _error(L, 0, NULL);
974 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
976 .rtm_family = filter->family,
977 .rtm_dst_len = filter->dst.bits,
978 .rtm_src_len = filter->src.bits
984 msg = nlmsg_alloc_simple(RTM_GETROUTE, flags);
988 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
991 nla_put(msg, RTA_DST, filter->dst.len, &filter->dst.addr.v6);
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);
997 nl_send_auto_complete(sock, msg);
999 if (!filter->get && !s.callback)
1002 while (s.pending > 0)
1003 nl_recvmsgs(sock, cb);
1009 return (s.callback == 0);
1012 static int route_get(lua_State *L)
1014 struct dump_filter filter = { .get = true };
1015 const char *dest = luaL_checkstring(L, 1);
1017 if (!parse_cidr(dest, &filter.dst))
1018 return _error(L, -1, "Invalid destination");
1020 filter.family = filter.dst.family;
1022 return _route_dump(L, &filter);
1025 static int route_dump(lua_State *L)
1029 struct dump_filter filter = { };
1031 if (lua_type(L, 1) == LUA_TTABLE)
1033 filter.family = L_getint(L, 1, "family");
1035 if (filter.family == 4)
1036 filter.family = AF_INET;
1037 else if (filter.family == 6)
1038 filter.family = AF_INET6;
1042 if ((s = L_getstr(L, 1, "iif")) != NULL)
1043 filter.iif = if_nametoindex(s);
1045 if ((s = L_getstr(L, 1, "oif")) != NULL)
1046 filter.oif = if_nametoindex(s);
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");
1053 if ((s = L_getstr(L, 1, "gw")) != NULL && parse_cidr(s, &p))
1056 if ((s = L_getstr(L, 1, "from")) != NULL && parse_cidr(s, &p))
1059 if ((s = L_getstr(L, 1, "src")) != NULL && parse_cidr(s, &p))
1062 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1065 if ((s = L_getstr(L, 1, "from_exact")) != NULL && parse_cidr(s, &p))
1066 filter.from = p, filter.from.exact = true;
1068 if ((s = L_getstr(L, 1, "dest_exact")) != NULL && parse_cidr(s, &p))
1069 filter.dst = p, filter.dst.exact = true;
1072 return _route_dump(L, &filter);
1076 static bool diff_macaddr(struct ether_addr *mac1, struct ether_addr *mac2)
1078 struct ether_addr empty = { };
1080 if (!memcmp(mac2, &empty, sizeof(empty)))
1083 if (!mac1 || memcmp(mac1, mac2, sizeof(empty)))
1089 static int cb_dump_neigh(struct nl_msg *msg, void *arg)
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];
1101 if (hdr->nlmsg_type != RTM_NEWNEIGH ||
1102 (nd->ndm_family != AF_INET && nd->ndm_family != AF_INET6))
1105 nlmsg_parse(hdr, sizeof(*nd), tb, NDA_MAX, NULL);
1107 mac = tb[NDA_LLADDR] ? RTA_DATA(tb[NDA_LLADDR]) : NULL;
1108 dst = tb[NDA_DST] ? RTA_DATA(tb[NDA_DST]) : NULL;
1110 bitlen = (nd->ndm_family == AF_INET) ? 32 : 128;
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))
1120 lua_pushvalue(s->L, 2);
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));
1127 L_setbool(s->L, "router", (nd->ndm_flags & NTF_ROUTER));
1128 L_setbool(s->L, "proxy", (nd->ndm_flags & NTF_PROXY));
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));
1140 L_setaddr(s->L, "dest", nd->ndm_family, dst, -1);
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]);
1149 lua_pushstring(s->L, buf);
1150 lua_setfield(s->L, -2, "mac");
1156 lua_call(s->L, 1, 0);
1157 else if (hdr->nlmsg_flags & NLM_F_MULTI)
1158 lua_rawseti(s->L, -2, s->index);
1161 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1165 static int neighbor_dump(lua_State *L)
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),
1178 if (lua_type(L, 1) == LUA_TTABLE)
1180 filter.family = L_getint(L, 1, "family");
1182 if (filter.family == 4)
1183 filter.family = AF_INET;
1184 else if (filter.family == 6)
1185 filter.family = AF_INET6;
1189 if ((s = L_getstr(L, 1, "dev")) != NULL)
1190 filter.iif = if_nametoindex(s);
1192 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1195 if ((s = L_getstr(L, 1, "mac")) != NULL &&
1196 (mac = ether_aton(s)) != NULL)
1202 sock = nl_socket_alloc();
1204 return _error(L, -1, "Out of memory");
1206 if (nl_connect(sock, NETLINK_ROUTE))
1207 return _error(L, 0, NULL);
1211 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1212 struct ndmsg ndm = {
1213 .ndm_family = filter.family
1216 msg = nlmsg_alloc_simple(RTM_GETNEIGH, NLM_F_REQUEST | NLM_F_DUMP);
1220 nlmsg_append(msg, &ndm, sizeof(ndm), 0);
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);
1226 nl_send_auto_complete(sock, msg);
1231 while (st.pending > 0)
1232 nl_recvmsgs(sock, cb);
1238 return (st.callback == 0);
1242 static int cb_dump_link(struct nl_msg *msg, void *arg)
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];
1251 if (hdr->nlmsg_type != RTM_NEWLINK)
1254 nlmsg_parse(hdr, sizeof(*ifm), tb, IFLA_MAX, NULL);
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));
1261 L_setint(s->L, "mtu", RTA_U32(tb[IFLA_MTU]));
1263 if (tb[IFLA_TXQLEN])
1264 L_setint(s->L, "qlen", RTA_U32(tb[IFLA_TXQLEN]));
1266 if (tb[IFLA_MASTER])
1267 L_setdev(s->L, "master", tb[IFLA_MASTER]);
1269 if (tb[IFLA_ADDRESS])
1271 len = nla_len(tb[IFLA_ADDRESS]);
1272 addr = nla_get_string(tb[IFLA_ADDRESS]);
1274 if ((len * 3) <= sizeof(buf))
1276 for (p = buf, i = 0; i < len; i++)
1277 p += sprintf(p, "%s%02x", (i ? ":" : ""), (uint8_t)*addr++);
1279 L_setstr(s->L, "mac", buf);
1287 static int link_get(lua_State *L)
1289 const char *dev = luaL_checkstring(L, 1);
1290 struct dump_state st = {
1297 sock = nl_socket_alloc();
1299 return _error(L, -1, "Out of memory");
1301 if (nl_connect(sock, NETLINK_ROUTE))
1302 return _error(L, 0, NULL);
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) };
1312 nlmsg_append(msg, &ifm, sizeof(ifm), 0);
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);
1320 nl_send_auto_complete(sock, msg);
1322 while (st.pending > 0)
1323 nl_recvmsgs(sock, cb);
1332 static const luaL_reg ip_methods[] = {
1333 { "new", cidr_new },
1334 { "IPv4", cidr_ipv4 },
1335 { "IPv6", cidr_ipv6 },
1337 { "route", route_get },
1338 { "routes", route_dump },
1340 { "neighbors", neighbor_dump },
1342 { "link", link_get },
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 },
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 },
1381 int luaopen_luci_ip(lua_State *L)
1383 luaL_register(L, LUCI_IP, ip_methods);
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");