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, *a, buf[INET6_ADDRSTRLEN * 2 + 2];
132 strncpy(buf, dest, sizeof(buf) - 1);
135 p = strchr(buf, '/');
140 if (!strncasecmp(buf, "::ffff:", 7))
143 if (inet_pton(AF_INET, a, &pp->addr.v4))
146 pp->family = AF_INET;
147 pp->len = sizeof(struct in_addr);
149 else if (inet_pton(AF_INET6, a, &pp->addr.v6))
152 pp->family = AF_INET6;
153 pp->len = sizeof(struct in6_addr);
160 if (!parse_mask(pp->family, p, &pp->bits))
171 static int L_getint(lua_State *L, int index, const char *name)
175 lua_getfield(L, index, name);
177 if (lua_type(L, -1) == LUA_TNUMBER)
178 rv = lua_tonumber(L, -1);
185 static const char * L_getstr(lua_State *L, int index, const char *name)
187 const char *rv = NULL;
189 lua_getfield(L, index, name);
191 if (lua_type(L, -1) == LUA_TSTRING)
192 rv = lua_tostring(L, -1);
199 static void L_setint(struct lua_State *L, const char *name, uint32_t n)
201 lua_pushinteger(L, n);
202 lua_setfield(L, -2, name);
205 static void L_setbool(struct lua_State *L, const char *name, bool val)
207 lua_pushboolean(L, val);
208 lua_setfield(L, -2, name);
211 static void L_setaddr(struct lua_State *L, const char *name,
212 int family, void *addr, int bits)
219 p = lua_newuserdata(L, sizeof(*p));
224 if (family == AF_INET)
227 p->bits = (bits < 0) ? 32 : bits;
228 p->len = sizeof(p->addr.v4);
229 p->addr.v4 = *(struct in_addr *)addr;
233 p->family = AF_INET6;
234 p->bits = (bits < 0) ? 128 : bits;
235 p->len = sizeof(p->addr.v6);
236 p->addr.v6 = *(struct in6_addr *)addr;
239 luaL_getmetatable(L, LUCI_IP_CIDR);
240 lua_setmetatable(L, -2);
241 lua_setfield(L, -2, name);
244 static void L_setstr(struct lua_State *L, const char *name, const char *val)
246 lua_pushstring(L, val);
247 lua_setfield(L, -2, name);
250 static void L_setdev(struct lua_State *L, const char *name,
255 if (if_indextoname(RTA_INT(attr), buf))
256 L_setstr(L, name, buf);
259 static int L_checkbits(lua_State *L, int index, cidr_t *p)
263 if (lua_gettop(L) < index || lua_isnil(L, index))
267 else if (lua_type(L, index) == LUA_TNUMBER)
269 bits = lua_tointeger(L, index);
271 if (bits < 0 || bits > ((p->family == AF_INET) ? 32 : 128))
272 return luaL_error(L, "Invalid prefix size");
274 else if (lua_type(L, index) == LUA_TSTRING)
276 if (!parse_mask(p->family, lua_tostring(L, index), &bits))
277 return luaL_error(L, "Invalid netmask format");
281 return luaL_error(L, "Invalid data type");
287 static int _cidr_new(lua_State *L, int index, int family, bool mask)
291 cidr_t cidr = { }, *cidrp;
293 if (lua_type(L, index) == LUA_TNUMBER)
295 n = htonl(lua_tointeger(L, index));
297 if (family == AF_INET6)
299 cidr.family = AF_INET6;
301 cidr.len = sizeof(cidr.addr.v6);
302 cidr.addr.v6.s6_addr[12] = n;
303 cidr.addr.v6.s6_addr[13] = (n >> 8);
304 cidr.addr.v6.s6_addr[14] = (n >> 16);
305 cidr.addr.v6.s6_addr[15] = (n >> 24);
309 cidr.family = AF_INET;
311 cidr.len = sizeof(cidr.addr.v4);
312 cidr.addr.v4.s_addr = n;
317 addr = luaL_checkstring(L, index);
319 if (!parse_cidr(addr, &cidr))
322 if (family && cidr.family != family)
326 cidr.bits = L_checkbits(L, index + 1, &cidr);
329 if (!(cidrp = lua_newuserdata(L, sizeof(*cidrp))))
333 luaL_getmetatable(L, LUCI_IP_CIDR);
334 lua_setmetatable(L, -2);
338 static int cidr_new(lua_State *L)
340 return _cidr_new(L, 1, 0, true);
343 static int cidr_ipv4(lua_State *L)
345 return _cidr_new(L, 1, AF_INET, true);
348 static int cidr_ipv6(lua_State *L)
350 return _cidr_new(L, 1, AF_INET6, true);
353 static int cidr_is4(lua_State *L)
355 cidr_t *p = L_checkcidr(L, 1, NULL);
357 lua_pushboolean(L, p->family == AF_INET);
361 static int cidr_is4rfc1918(lua_State *L)
363 cidr_t *p = L_checkcidr(L, 1, NULL);
364 uint32_t a = htonl(p->addr.v4.s_addr);
366 lua_pushboolean(L, (p->family == AF_INET &&
367 ((a >= 0x0A000000 && a <= 0x0AFFFFFF) ||
368 (a >= 0xAC100000 && a <= 0xAC1FFFFF) ||
369 (a >= 0xC0A80000 && a <= 0xC0A8FFFF))));
374 static int cidr_is4linklocal(lua_State *L)
376 cidr_t *p = L_checkcidr(L, 1, NULL);
377 uint32_t a = htonl(p->addr.v4.s_addr);
379 lua_pushboolean(L, (p->family == AF_INET &&
386 static int cidr_is6(lua_State *L)
388 cidr_t *p = L_checkcidr(L, 1, NULL);
390 lua_pushboolean(L, p->family == AF_INET6);
394 static int cidr_is6linklocal(lua_State *L)
396 cidr_t *p = L_checkcidr(L, 1, NULL);
398 lua_pushboolean(L, (p->family == AF_INET6 &&
399 p->addr.v6.s6_addr[0] == 0xFE &&
400 p->addr.v6.s6_addr[1] >= 0x80 &&
401 p->addr.v6.s6_addr[1] <= 0xBF));
406 static int _cidr_cmp(lua_State *L)
408 cidr_t *a = L_checkcidr(L, 1, NULL);
409 cidr_t *b = L_checkcidr(L, 2, NULL);
411 if (a->family != b->family)
412 return (a->family - b->family);
414 return memcmp(&a->addr.v6, &b->addr.v6, a->len);
417 static int cidr_lower(lua_State *L)
419 lua_pushboolean(L, _cidr_cmp(L) < 0);
423 static int cidr_higher(lua_State *L)
425 lua_pushboolean(L, _cidr_cmp(L) > 0);
429 static int cidr_equal(lua_State *L)
431 lua_pushboolean(L, _cidr_cmp(L) == 0);
435 static int cidr_lower_equal(lua_State *L)
437 lua_pushboolean(L, _cidr_cmp(L) <= 0);
441 static int cidr_prefix(lua_State *L)
443 cidr_t *p = L_checkcidr(L, 1, NULL);
444 int bits = L_checkbits(L, 2, p);
447 lua_pushinteger(L, p->bits);
451 static void _apply_mask(cidr_t *p, int bits, bool inv)
457 memset(&p->addr.v6, inv * 0xFF, p->len);
459 else if (p->family == AF_INET && bits <= 32)
462 p->addr.v4.s_addr |= ntohl((1 << (32 - bits)) - 1);
464 p->addr.v4.s_addr &= ntohl(~((1 << (32 - bits)) - 1));
466 else if (p->family == AF_INET6 && bits <= 128)
468 for (i = 0; i < sizeof(p->addr.v6.s6_addr); i++)
470 b = (bits > 8) ? 8 : bits;
472 p->addr.v6.s6_addr[i] |= ~((uint8_t)(0xFF << (8 - b)));
474 p->addr.v6.s6_addr[i] &= (uint8_t)(0xFF << (8 - b));
480 static int cidr_network(lua_State *L)
482 cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
483 int bits = L_checkbits(L, 2, p1);
485 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
489 p2->bits = (p1->family == AF_INET) ? 32 : 128;
490 _apply_mask(p2, bits, false);
492 luaL_getmetatable(L, LUCI_IP_CIDR);
493 lua_setmetatable(L, -2);
497 static int cidr_host(lua_State *L)
499 cidr_t *p1 = L_checkcidr(L, 1, NULL);
500 cidr_t *p2 = lua_newuserdata(L, sizeof(*p2));
506 p2->bits = (p1->family == AF_INET) ? 32 : 128;
508 luaL_getmetatable(L, LUCI_IP_CIDR);
509 lua_setmetatable(L, -2);
513 static int cidr_mask(lua_State *L)
515 cidr_t *p1 = L_checkcidr(L, 1, NULL), *p2;
516 int bits = L_checkbits(L, 2, p1);
518 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
521 p2->bits = (p1->family == AF_INET) ? 32 : 128;
522 p2->family = p1->family;
524 memset(&p2->addr.v6.s6_addr, 0xFF, sizeof(p2->addr.v6.s6_addr));
525 _apply_mask(p2, bits, false);
527 luaL_getmetatable(L, LUCI_IP_CIDR);
528 lua_setmetatable(L, -2);
532 static int cidr_broadcast(lua_State *L)
534 cidr_t *p1 = L_checkcidr(L, 1, NULL);
536 int bits = L_checkbits(L, 2, p1);
538 if (p1->family == AF_INET6)
541 if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
545 p2->bits = (p1->family == AF_INET) ? 32 : 128;
546 _apply_mask(p2, bits, true);
548 luaL_getmetatable(L, LUCI_IP_CIDR);
549 lua_setmetatable(L, -2);
553 static int cidr_contains(lua_State *L)
555 cidr_t *p1 = L_checkcidr(L, 1, NULL);
556 cidr_t *p2 = L_checkcidr(L, 2, NULL);
557 cidr_t a = *p1, b = *p2;
560 if (p1->family == p2->family && p1->bits <= p2->bits)
562 _apply_mask(&a, p1->bits, false);
563 _apply_mask(&b, p1->bits, false);
565 rv = !memcmp(&a.addr.v6, &b.addr.v6, a.len);
568 lua_pushboolean(L, rv);
572 #define S6_BYTE(a, i) \
573 (a)->addr.v6.s6_addr[sizeof((a)->addr.v6.s6_addr) - (i) - 1]
575 static int _cidr_add_sub(lua_State *L, bool add)
577 cidr_t *p1 = L_checkcidr(L, 1, NULL);
578 cidr_t *p2 = L_checkcidr(L, 2, p1);
580 bool inplace = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : false;
585 if (p1->family == p2->family)
587 if (p1->family == AF_INET6)
589 for (i = 0, carry = 0; i < sizeof(r.addr.v6.s6_addr); i++)
593 S6_BYTE(&r, i) = S6_BYTE(p1, i) + S6_BYTE(p2, i) + carry;
594 carry = (S6_BYTE(p1, i) + S6_BYTE(p2, i) + carry) / 256;
598 S6_BYTE(&r, i) = (S6_BYTE(p1, i) - S6_BYTE(p2, i) - carry);
599 carry = (S6_BYTE(p1, i) < (S6_BYTE(p2, i) + carry));
603 /* would over/underflow */
606 memset(&r.addr.v6, add * 0xFF, sizeof(r.addr.v6));
612 a = ntohl(p1->addr.v4.s_addr);
613 b = ntohl(p2->addr.v4.s_addr);
615 /* would over/underflow */
616 if ((add && (UINT_MAX - a) < b) || (!add && a < b))
618 r.addr.v4.s_addr = add * 0xFFFFFFFF;
623 r.addr.v4.s_addr = add ? htonl(a + b) : htonl(a - b);
635 lua_pushboolean(L, ok);
639 if (!(p1 = lua_newuserdata(L, sizeof(*p1))))
644 luaL_getmetatable(L, LUCI_IP_CIDR);
645 lua_setmetatable(L, -2);
649 static int cidr_add(lua_State *L)
651 return _cidr_add_sub(L, true);
654 static int cidr_sub(lua_State *L)
656 return _cidr_add_sub(L, false);
659 static int cidr_minhost(lua_State *L)
661 cidr_t *p = L_checkcidr(L, 1, NULL);
663 uint8_t i, rest, carry;
665 _apply_mask(&r, r.bits, false);
667 if (r.family == AF_INET6 && r.bits < 128)
671 for (i = 0, carry = 1; i < sizeof(r.addr.v6.s6_addr); i++)
673 rest = (S6_BYTE(&r, i) + carry) > 255;
674 S6_BYTE(&r, i) += carry;
678 else if (r.family == AF_INET && r.bits < 32)
681 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) + 1);
684 if (!(p = lua_newuserdata(L, sizeof(*p))))
689 luaL_getmetatable(L, LUCI_IP_CIDR);
690 lua_setmetatable(L, -2);
694 static int cidr_maxhost(lua_State *L)
696 cidr_t *p = L_checkcidr(L, 1, NULL);
699 _apply_mask(&r, r.bits, true);
701 if (r.family == AF_INET && r.bits < 32)
704 r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) - 1);
706 else if (r.family == AF_INET6)
711 if (!(p = lua_newuserdata(L, sizeof(*p))))
716 luaL_getmetatable(L, LUCI_IP_CIDR);
717 lua_setmetatable(L, -2);
721 static int cidr_gc (lua_State *L)
726 static int cidr_tostring (lua_State *L)
728 char buf[INET6_ADDRSTRLEN];
729 cidr_t *p = L_checkcidr(L, 1, NULL);
731 if ((p->family == AF_INET && p->bits < 32) ||
732 (p->family == AF_INET6 && p->bits < 128))
734 lua_pushfstring(L, "%s/%d",
735 inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf)),
740 lua_pushstring(L, inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf)));
750 static bool diff_prefix(int family, void *addr, int bits, cidr_t *p)
758 if (!addr || p->family != family || p->bits > bits)
761 if (family == AF_INET6)
763 for (i = 0, r = p->bits; i < sizeof(struct in6_addr); i++)
765 b = r ? (0xFF << (8 - ((r > 8) ? 8 : r))) : 0;
767 if ((((struct in6_addr *)addr)->s6_addr[i] & b) !=
768 (p->addr.v6.s6_addr[i] & b))
771 r -= ((r > 8) ? 8 : r);
776 m = p->bits ? htonl(~((1 << (32 - p->bits)) - 1)) : 0;
778 if ((((struct in_addr *)addr)->s_addr & m) != (p->addr.v4.s_addr & m))
782 return (p->exact && p->bits != bits);
785 static int cb_dump_route(struct nl_msg *msg, void *arg)
787 struct dump_state *s = arg;
788 struct dump_filter *f = s->filter;
789 struct nlmsghdr *hdr = nlmsg_hdr(msg);
790 struct rtmsg *rt = NLMSG_DATA(hdr);
791 struct nlattr *tb[RTA_MAX+1];
792 struct in6_addr *src, *dst, *gw, *from, def = { };
793 int iif, oif, bitlen;
796 if (hdr->nlmsg_type != RTM_NEWROUTE ||
797 (rt->rtm_family != AF_INET && rt->rtm_family != AF_INET6))
800 nlmsg_parse(hdr, sizeof(*rt), tb, RTA_MAX, NULL);
802 iif = tb[RTA_IIF] ? RTA_INT(tb[RTA_IIF]) : 0;
803 oif = tb[RTA_OIF] ? RTA_INT(tb[RTA_OIF]) : 0;
804 table = tb[RTA_TABLE] ? RTA_U32(tb[RTA_TABLE]) : rt->rtm_table;
805 from = tb[RTA_SRC] ? RTA_DATA(tb[RTA_SRC]) : NULL;
806 src = tb[RTA_PREFSRC] ? RTA_DATA(tb[RTA_PREFSRC]) : NULL;
807 dst = tb[RTA_DST] ? RTA_DATA(tb[RTA_DST]) : &def;
808 gw = tb[RTA_GATEWAY] ? RTA_DATA(tb[RTA_GATEWAY]) : NULL;
810 bitlen = (rt->rtm_family == AF_INET6) ? 128 : 32;
812 if ((f->type && rt->rtm_type != f->type) ||
813 (f->family && rt->rtm_family != f->family) ||
814 (f->proto && rt->rtm_protocol != f->proto) ||
815 (f->scope && rt->rtm_scope != f->scope) ||
816 (f->iif && iif != f->iif) ||
817 (f->oif && oif != f->oif) ||
818 (f->table && table != f->table) ||
819 diff_prefix(rt->rtm_family, from, rt->rtm_src_len, &f->from) ||
820 diff_prefix(rt->rtm_family, dst, rt->rtm_dst_len, &f->dst) ||
821 diff_prefix(rt->rtm_family, gw, bitlen, &f->gw) ||
822 diff_prefix(rt->rtm_family, src, bitlen, &f->src))
826 lua_pushvalue(s->L, 2);
830 L_setint(s->L, "type", rt->rtm_type);
831 L_setint(s->L, "family", (rt->rtm_family == AF_INET) ? 4 : 6);
833 L_setaddr(s->L, "dest", rt->rtm_family, dst, rt->rtm_dst_len);
836 L_setaddr(s->L, "gw", rt->rtm_family, gw, -1);
839 L_setaddr(s->L, "from", rt->rtm_family, from, rt->rtm_src_len);
842 L_setdev(s->L, "iif", tb[RTA_IIF]);
845 L_setdev(s->L, "dev", tb[RTA_OIF]);
847 L_setint(s->L, "table", table);
848 L_setint(s->L, "proto", rt->rtm_protocol);
849 L_setint(s->L, "scope", rt->rtm_scope);
852 L_setaddr(s->L, "src", rt->rtm_family, src, -1);
854 if (tb[RTA_PRIORITY])
855 L_setint(s->L, "metric", RTA_U32(tb[RTA_PRIORITY]));
857 if (rt->rtm_family == AF_INET6 && tb[RTA_CACHEINFO])
859 struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]);
864 L_setint(s->L, "expires", ci->rta_expires / hz);
866 if (ci->rta_error != 0)
867 L_setint(s->L, "error", ci->rta_error);
874 lua_call(s->L, 1, 0);
875 else if (hdr->nlmsg_flags & NLM_F_MULTI)
876 lua_rawseti(s->L, -2, s->index);
879 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
884 cb_done(struct nl_msg *msg, void *arg)
886 struct dump_state *s = arg;
892 cb_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
894 struct dump_state *s = arg;
899 static int _error(lua_State *L, int code, const char *msg)
902 lua_pushnumber(L, code ? code : errno);
903 lua_pushstring(L, msg ? msg : strerror(errno));
908 static int _route_dump(lua_State *L, struct dump_filter *filter)
910 int flags = NLM_F_REQUEST;
911 struct dump_state s = {
915 .callback = lua_isfunction(L, 2),
920 hz = sysconf(_SC_CLK_TCK);
924 sock = nl_socket_alloc();
926 return _error(L, -1, "Out of memory");
928 if (nl_connect(sock, NETLINK_ROUTE))
929 return _error(L, 0, NULL);
933 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
935 .rtm_family = filter->family,
936 .rtm_dst_len = filter->dst.bits,
937 .rtm_src_len = filter->src.bits
943 msg = nlmsg_alloc_simple(RTM_GETROUTE, flags);
947 nlmsg_append(msg, &rtm, sizeof(rtm), 0);
950 nla_put(msg, RTA_DST, filter->dst.len, &filter->dst.addr.v6);
952 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_route, &s);
953 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &s);
954 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &s);
956 nl_send_auto_complete(sock, msg);
958 if (!filter->get && !s.callback)
961 while (s.pending > 0)
962 nl_recvmsgs(sock, cb);
968 return (s.callback == 0);
971 static int route_get(lua_State *L)
973 struct dump_filter filter = { .get = true };
974 const char *dest = luaL_checkstring(L, 1);
976 if (!parse_cidr(dest, &filter.dst))
977 return _error(L, -1, "Invalid destination");
979 filter.family = filter.dst.family;
981 return _route_dump(L, &filter);
984 static int route_dump(lua_State *L)
988 struct dump_filter filter = { };
990 if (lua_type(L, 1) == LUA_TTABLE)
992 filter.family = L_getint(L, 1, "family");
994 if (filter.family == 4)
995 filter.family = AF_INET;
996 else if (filter.family == 6)
997 filter.family = AF_INET6;
1001 if ((s = L_getstr(L, 1, "iif")) != NULL)
1002 filter.iif = if_nametoindex(s);
1004 if ((s = L_getstr(L, 1, "oif")) != NULL)
1005 filter.oif = if_nametoindex(s);
1007 filter.type = L_getint(L, 1, "type");
1008 filter.scope = L_getint(L, 1, "scope");
1009 filter.proto = L_getint(L, 1, "proto");
1010 filter.table = L_getint(L, 1, "table");
1012 if ((s = L_getstr(L, 1, "gw")) != NULL && parse_cidr(s, &p))
1015 if ((s = L_getstr(L, 1, "from")) != NULL && parse_cidr(s, &p))
1018 if ((s = L_getstr(L, 1, "src")) != NULL && parse_cidr(s, &p))
1021 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1024 if ((s = L_getstr(L, 1, "from_exact")) != NULL && parse_cidr(s, &p))
1025 filter.from = p, filter.from.exact = true;
1027 if ((s = L_getstr(L, 1, "dest_exact")) != NULL && parse_cidr(s, &p))
1028 filter.dst = p, filter.dst.exact = true;
1031 return _route_dump(L, &filter);
1035 static bool diff_macaddr(struct ether_addr *mac1, struct ether_addr *mac2)
1037 struct ether_addr empty = { };
1039 if (!memcmp(mac2, &empty, sizeof(empty)))
1042 if (!mac1 || memcmp(mac1, mac2, sizeof(empty)))
1048 static int cb_dump_neigh(struct nl_msg *msg, void *arg)
1051 struct ether_addr *mac;
1052 struct in6_addr *dst;
1053 struct dump_state *s = arg;
1054 struct dump_filter *f = s->filter;
1055 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1056 struct ndmsg *nd = NLMSG_DATA(hdr);
1057 struct nlattr *tb[NDA_MAX+1];
1060 if (hdr->nlmsg_type != RTM_NEWNEIGH ||
1061 (nd->ndm_family != AF_INET && nd->ndm_family != AF_INET6))
1064 nlmsg_parse(hdr, sizeof(*nd), tb, NDA_MAX, NULL);
1066 mac = tb[NDA_LLADDR] ? RTA_DATA(tb[NDA_LLADDR]) : NULL;
1067 dst = tb[NDA_DST] ? RTA_DATA(tb[NDA_DST]) : NULL;
1069 bitlen = (nd->ndm_family == AF_INET) ? 32 : 128;
1071 if ((f->family && nd->ndm_family != f->family) ||
1072 (f->iif && nd->ndm_ifindex != f->iif) ||
1073 (f->type && !(f->type & nd->ndm_state)) ||
1074 diff_prefix(nd->ndm_family, dst, bitlen, &f->dst) ||
1075 diff_macaddr(mac, &f->mac))
1079 lua_pushvalue(s->L, 2);
1083 L_setint(s->L, "family", (nd->ndm_family == AF_INET) ? 4 : 6);
1084 L_setstr(s->L, "dev", if_indextoname(nd->ndm_ifindex, buf));
1086 L_setbool(s->L, "router", (nd->ndm_flags & NTF_ROUTER));
1087 L_setbool(s->L, "proxy", (nd->ndm_flags & NTF_PROXY));
1089 L_setbool(s->L, "incomplete", (nd->ndm_state & NUD_INCOMPLETE));
1090 L_setbool(s->L, "reachable", (nd->ndm_state & NUD_REACHABLE));
1091 L_setbool(s->L, "stale", (nd->ndm_state & NUD_STALE));
1092 L_setbool(s->L, "delay", (nd->ndm_state & NUD_DELAY));
1093 L_setbool(s->L, "probe", (nd->ndm_state & NUD_PROBE));
1094 L_setbool(s->L, "failed", (nd->ndm_state & NUD_FAILED));
1095 L_setbool(s->L, "noarp", (nd->ndm_state & NUD_NOARP));
1096 L_setbool(s->L, "permanent", (nd->ndm_state & NUD_PERMANENT));
1099 L_setaddr(s->L, "dest", nd->ndm_family, dst, -1);
1103 snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
1104 mac->ether_addr_octet[0], mac->ether_addr_octet[1],
1105 mac->ether_addr_octet[2], mac->ether_addr_octet[3],
1106 mac->ether_addr_octet[4], mac->ether_addr_octet[5]);
1108 lua_pushstring(s->L, buf);
1109 lua_setfield(s->L, -2, "mac");
1115 lua_call(s->L, 1, 0);
1116 else if (hdr->nlmsg_flags & NLM_F_MULTI)
1117 lua_rawseti(s->L, -2, s->index);
1120 s->pending = !!(hdr->nlmsg_flags & NLM_F_MULTI);
1124 static int neighbor_dump(lua_State *L)
1128 struct ether_addr *mac;
1129 struct dump_filter filter = { .type = 0xFF & ~NUD_NOARP };
1130 struct dump_state st = {
1131 .callback = lua_isfunction(L, 2),
1137 if (lua_type(L, 1) == LUA_TTABLE)
1139 filter.family = L_getint(L, 1, "family");
1141 if (filter.family == 4)
1142 filter.family = AF_INET;
1143 else if (filter.family == 6)
1144 filter.family = AF_INET6;
1148 if ((s = L_getstr(L, 1, "dev")) != NULL)
1149 filter.iif = if_nametoindex(s);
1151 if ((s = L_getstr(L, 1, "dest")) != NULL && parse_cidr(s, &p))
1154 if ((s = L_getstr(L, 1, "mac")) != NULL &&
1155 (mac = ether_aton(s)) != NULL)
1161 sock = nl_socket_alloc();
1163 return _error(L, -1, "Out of memory");
1165 if (nl_connect(sock, NETLINK_ROUTE))
1166 return _error(L, 0, NULL);
1170 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1171 struct ndmsg ndm = {
1172 .ndm_family = filter.family
1175 msg = nlmsg_alloc_simple(RTM_GETNEIGH, NLM_F_REQUEST | NLM_F_DUMP);
1179 nlmsg_append(msg, &ndm, sizeof(ndm), 0);
1181 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_neigh, &st);
1182 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1183 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1185 nl_send_auto_complete(sock, msg);
1190 while (st.pending > 0)
1191 nl_recvmsgs(sock, cb);
1197 return (st.callback == 0);
1201 static int cb_dump_link(struct nl_msg *msg, void *arg)
1203 char *p, *addr, buf[48];
1204 struct dump_state *s = arg;
1205 struct nlmsghdr *hdr = nlmsg_hdr(msg);
1206 struct ifinfomsg *ifm = NLMSG_DATA(hdr);
1207 struct nlattr *tb[IFLA_MAX+1];
1210 if (hdr->nlmsg_type != RTM_NEWLINK)
1213 nlmsg_parse(hdr, sizeof(*ifm), tb, IFLA_MAX, NULL);
1215 L_setbool(s->L, "up", (ifm->ifi_flags & IFF_RUNNING));
1216 L_setint(s->L, "type", ifm->ifi_type);
1217 L_setstr(s->L, "name", if_indextoname(ifm->ifi_index, buf));
1220 L_setint(s->L, "mtu", RTA_U32(tb[IFLA_MTU]));
1222 if (tb[IFLA_TXQLEN])
1223 L_setint(s->L, "qlen", RTA_U32(tb[IFLA_TXQLEN]));
1225 if (tb[IFLA_MASTER])
1226 L_setdev(s->L, "master", tb[IFLA_MASTER]);
1228 if (tb[IFLA_ADDRESS])
1230 len = nla_len(tb[IFLA_ADDRESS]);
1231 addr = nla_get_string(tb[IFLA_ADDRESS]);
1233 if ((len * 3) <= sizeof(buf))
1235 for (p = buf, i = 0; i < len; i++)
1236 p += sprintf(p, "%s%02x", (i ? ":" : ""), (uint8_t)*addr++);
1238 L_setstr(s->L, "mac", buf);
1246 static int link_get(lua_State *L)
1248 const char *dev = luaL_checkstring(L, 1);
1249 struct dump_state st = {
1256 sock = nl_socket_alloc();
1258 return _error(L, -1, "Out of memory");
1260 if (nl_connect(sock, NETLINK_ROUTE))
1261 return _error(L, 0, NULL);
1264 struct nl_msg *msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST);
1265 struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
1266 struct ifinfomsg ifm = { .ifi_index = if_nametoindex(dev) };
1271 nlmsg_append(msg, &ifm, sizeof(ifm), 0);
1273 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_link, &st);
1274 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
1275 nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
1279 nl_send_auto_complete(sock, msg);
1281 while (st.pending > 0)
1282 nl_recvmsgs(sock, cb);
1291 static const luaL_reg ip_methods[] = {
1292 { "new", cidr_new },
1293 { "IPv4", cidr_ipv4 },
1294 { "IPv6", cidr_ipv6 },
1296 { "route", route_get },
1297 { "routes", route_dump },
1299 { "neighbors", neighbor_dump },
1301 { "link", link_get },
1306 static const luaL_reg ip_cidr_methods[] = {
1307 { "is4", cidr_is4 },
1308 { "is4rfc1918", cidr_is4rfc1918 },
1309 { "is4linklocal", cidr_is4linklocal },
1310 { "is6", cidr_is6 },
1311 { "is6linklocal", cidr_is6linklocal },
1312 { "lower", cidr_lower },
1313 { "higher", cidr_higher },
1314 { "equal", cidr_equal },
1315 { "prefix", cidr_prefix },
1316 { "network", cidr_network },
1317 { "host", cidr_host },
1318 { "mask", cidr_mask },
1319 { "broadcast", cidr_broadcast },
1320 { "contains", cidr_contains },
1321 { "add", cidr_add },
1322 { "sub", cidr_sub },
1323 { "minhost", cidr_minhost },
1324 { "maxhost", cidr_maxhost },
1325 { "string", cidr_tostring },
1327 { "__lt", cidr_lower },
1328 { "__le", cidr_lower_equal },
1329 { "__eq", cidr_equal },
1330 { "__add", cidr_add },
1331 { "__sub", cidr_sub },
1332 { "__gc", cidr_gc },
1333 { "__tostring", cidr_tostring },
1338 int luaopen_luci_ip(lua_State *L)
1340 luaL_register(L, LUCI_IP, ip_methods);
1342 luaL_newmetatable(L, LUCI_IP_CIDR);
1343 luaL_register(L, NULL, ip_cidr_methods);
1344 lua_pushvalue(L, -1);
1345 lua_setfield(L, -2, "__index");