c799419e53e0571c0cb983838ba161c925c4bec3
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
);
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))
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
)
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
[15] = n
;
303 cidr
.addr
.v6
.s6_addr
[14] = (n
>> 8);
304 cidr
.addr
.v6
.s6_addr
[13] = (n
>> 16);
305 cidr
.addr
.v6
.s6_addr
[12] = (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 if (!(cidrp
= lua_newuserdata(L
, sizeof(*cidrp
))))
330 luaL_getmetatable(L
, LUCI_IP_CIDR
);
331 lua_setmetatable(L
, -2);
335 static int cidr_new(lua_State
*L
)
337 return _cidr_new(L
, 1, 0);
340 static int cidr_ipv4(lua_State
*L
)
342 return _cidr_new(L
, 1, AF_INET
);
345 static int cidr_ipv6(lua_State
*L
)
347 return _cidr_new(L
, 1, AF_INET6
);
350 static int cidr_is4(lua_State
*L
)
352 cidr_t
*p
= L_checkcidr(L
, 1, NULL
);
354 lua_pushboolean(L
, p
->family
== AF_INET
);
358 static int cidr_is4rfc1918(lua_State
*L
)
360 cidr_t
*p
= L_checkcidr(L
, 1, NULL
);
361 uint32_t a
= htonl(p
->addr
.v4
.s_addr
);
363 lua_pushboolean(L
, (p
->family
== AF_INET
&&
364 ((a
>= 0x0A000000 && a
<= 0x0AFFFFFF) ||
365 (a
>= 0xAC100000 && a
<= 0xAC1FFFFF) ||
366 (a
>= 0xC0A80000 && a
<= 0xC0A8FFFF))));
371 static int cidr_is4linklocal(lua_State
*L
)
373 cidr_t
*p
= L_checkcidr(L
, 1, NULL
);
374 uint32_t a
= htonl(p
->addr
.v4
.s_addr
);
376 lua_pushboolean(L
, (p
->family
== AF_INET
&&
383 static int cidr_is6(lua_State
*L
)
385 cidr_t
*p
= L_checkcidr(L
, 1, NULL
);
387 lua_pushboolean(L
, p
->family
== AF_INET6
);
391 static int cidr_is6linklocal(lua_State
*L
)
393 cidr_t
*p
= L_checkcidr(L
, 1, NULL
);
395 lua_pushboolean(L
, (p
->family
== AF_INET6
&&
396 p
->addr
.v6
.s6_addr
[0] == 0xFE &&
397 p
->addr
.v6
.s6_addr
[1] >= 0x80 &&
398 p
->addr
.v6
.s6_addr
[1] <= 0xBF));
403 static int _cidr_cmp(lua_State
*L
)
405 cidr_t
*a
= L_checkcidr(L
, 1, NULL
);
406 cidr_t
*b
= L_checkcidr(L
, 2, NULL
);
408 if (a
->family
!= b
->family
)
409 return (a
->family
- b
->family
);
411 return memcmp(&a
->addr
.v6
, &b
->addr
.v6
, a
->len
);
414 static int cidr_lower(lua_State
*L
)
416 lua_pushboolean(L
, _cidr_cmp(L
) < 0);
420 static int cidr_higher(lua_State
*L
)
422 lua_pushboolean(L
, _cidr_cmp(L
) > 0);
426 static int cidr_equal(lua_State
*L
)
428 lua_pushboolean(L
, _cidr_cmp(L
) == 0);
432 static int cidr_lower_equal(lua_State
*L
)
434 lua_pushboolean(L
, _cidr_cmp(L
) <= 0);
438 static int cidr_prefix(lua_State
*L
)
440 cidr_t
*p
= L_checkcidr(L
, 1, NULL
);
441 int bits
= L_checkbits(L
, 2, p
);
444 lua_pushinteger(L
, p
->bits
);
448 static void _apply_mask(cidr_t
*p
, int bits
, bool inv
)
454 memset(&p
->addr
.v6
, inv
* 0xFF, p
->len
);
456 else if (p
->family
== AF_INET
&& bits
<= 32)
459 p
->addr
.v4
.s_addr
|= ntohl((1 << (32 - bits
)) - 1);
461 p
->addr
.v4
.s_addr
&= ntohl(~((1 << (32 - bits
)) - 1));
463 else if (p
->family
== AF_INET6
&& bits
<= 128)
465 for (i
= 0; i
< sizeof(p
->addr
.v6
.s6_addr
); i
++)
467 b
= (bits
> 8) ? 8 : bits
;
469 p
->addr
.v6
.s6_addr
[i
] |= ~((uint8_t)(0xFF << (8 - b
)));
471 p
->addr
.v6
.s6_addr
[i
] &= (uint8_t)(0xFF << (8 - b
));
477 static int cidr_network(lua_State
*L
)
479 cidr_t
*p1
= L_checkcidr(L
, 1, NULL
), *p2
;
480 int bits
= L_checkbits(L
, 2, p1
);
482 if (!(p2
= lua_newuserdata(L
, sizeof(*p2
))))
486 p2
->bits
= (p1
->family
== AF_INET
) ? 32 : 128;
487 _apply_mask(p2
, bits
, false);
489 luaL_getmetatable(L
, LUCI_IP_CIDR
);
490 lua_setmetatable(L
, -2);
494 static int cidr_host(lua_State
*L
)
496 cidr_t
*p1
= L_checkcidr(L
, 1, NULL
);
497 cidr_t
*p2
= lua_newuserdata(L
, sizeof(*p2
));
503 p2
->bits
= (p1
->family
== AF_INET
) ? 32 : 128;
505 luaL_getmetatable(L
, LUCI_IP_CIDR
);
506 lua_setmetatable(L
, -2);
510 static int cidr_mask(lua_State
*L
)
512 cidr_t
*p1
= L_checkcidr(L
, 1, NULL
), *p2
;
513 int bits
= L_checkbits(L
, 2, p1
);
515 if (!(p2
= lua_newuserdata(L
, sizeof(*p2
))))
518 p2
->bits
= (p1
->family
== AF_INET
) ? 32 : 128;
519 p2
->family
= p1
->family
;
521 memset(&p2
->addr
.v6
.s6_addr
, 0xFF, sizeof(p2
->addr
.v6
.s6_addr
));
522 _apply_mask(p2
, bits
, false);
524 luaL_getmetatable(L
, LUCI_IP_CIDR
);
525 lua_setmetatable(L
, -2);
529 static int cidr_broadcast(lua_State
*L
)
531 cidr_t
*p1
= L_checkcidr(L
, 1, NULL
);
533 int bits
= L_checkbits(L
, 2, p1
);
535 if (p1
->family
== AF_INET6
)
538 if (!(p2
= lua_newuserdata(L
, sizeof(*p2
))))
542 p2
->bits
= (p1
->family
== AF_INET
) ? 32 : 128;
543 _apply_mask(p2
, bits
, true);
545 luaL_getmetatable(L
, LUCI_IP_CIDR
);
546 lua_setmetatable(L
, -2);
550 static int cidr_contains(lua_State
*L
)
552 cidr_t
*p1
= L_checkcidr(L
, 1, NULL
);
553 cidr_t
*p2
= L_checkcidr(L
, 2, NULL
);
554 cidr_t a
= *p1
, b
= *p2
;
557 if (p1
->family
== p2
->family
&& p1
->bits
<= p2
->bits
)
559 _apply_mask(&a
, p1
->bits
, false);
560 _apply_mask(&b
, p1
->bits
, false);
562 rv
= !memcmp(&a
.addr
.v6
, &b
.addr
.v6
, a
.len
);
565 lua_pushboolean(L
, rv
);
569 #define S6_BYTE(a, i) \
570 (a)->addr.v6.s6_addr[sizeof((a)->addr.v6.s6_addr) - (i) - 1]
572 static int _cidr_add_sub(lua_State
*L
, bool add
)
574 cidr_t
*p1
= L_checkcidr(L
, 1, NULL
);
575 cidr_t
*p2
= L_checkcidr(L
, 2, p1
);
577 bool inplace
= lua_isboolean(L
, 3) ? lua_toboolean(L
, 3) : false;
582 if (p1
->family
== p2
->family
)
584 if (p1
->family
== AF_INET6
)
586 for (i
= 0, carry
= 0; i
< sizeof(r
); i
++)
590 S6_BYTE(&r
, i
) = S6_BYTE(p1
, i
) + S6_BYTE(p2
, i
) + carry
;
591 carry
= (S6_BYTE(p1
, i
) + S6_BYTE(p2
, i
) + carry
) / 256;
595 S6_BYTE(&r
, i
) = (S6_BYTE(p1
, i
) - S6_BYTE(p2
, i
) - carry
);
596 carry
= (S6_BYTE(p1
, i
) < (S6_BYTE(p2
, i
) + carry
));
600 /* would over/underflow */
603 memset(&r
.addr
.v6
, add
* 0xFF, sizeof(r
.addr
.v6
));
609 a
= ntohl(p1
->addr
.v4
.s_addr
);
610 b
= ntohl(p2
->addr
.v4
.s_addr
);
612 /* would over/underflow */
613 if ((add
&& (UINT_MAX
- a
) < b
) || (!add
&& a
< b
))
615 r
.addr
.v4
.s_addr
= add
* 0xFFFFFFFF;
620 r
.addr
.v4
.s_addr
= add
? htonl(a
+ b
) : htonl(a
- b
);
632 lua_pushboolean(L
, ok
);
636 if (!(p1
= lua_newuserdata(L
, sizeof(*p1
))))
641 luaL_getmetatable(L
, LUCI_IP_CIDR
);
642 lua_setmetatable(L
, -2);
646 static int cidr_add(lua_State
*L
)
648 return _cidr_add_sub(L
, true);
651 static int cidr_sub(lua_State
*L
)
653 return _cidr_add_sub(L
, false);
656 static int cidr_minhost(lua_State
*L
)
658 cidr_t
*p
= L_checkcidr(L
, 1, NULL
);
660 uint8_t i
, rest
, carry
;
662 _apply_mask(&r
, r
.bits
, false);
664 if (r
.family
== AF_INET6
&& r
.bits
< 128)
668 for (i
= 0, carry
= 1; i
< sizeof(r
.addr
.v6
.s6_addr
); i
++)
670 rest
= (S6_BYTE(&r
, i
) + carry
) > 255;
671 S6_BYTE(&r
, i
) += carry
;
675 else if (r
.family
== AF_INET
&& r
.bits
< 32)
678 r
.addr
.v4
.s_addr
= htonl(ntohl(r
.addr
.v4
.s_addr
) + 1);
681 if (!(p
= lua_newuserdata(L
, sizeof(*p
))))
686 luaL_getmetatable(L
, LUCI_IP_CIDR
);
687 lua_setmetatable(L
, -2);
691 static int cidr_maxhost(lua_State
*L
)
693 cidr_t
*p
= L_checkcidr(L
, 1, NULL
);
696 _apply_mask(&r
, r
.bits
, true);
698 if (r
.family
== AF_INET
&& r
.bits
< 32)
701 r
.addr
.v4
.s_addr
= htonl(ntohl(r
.addr
.v4
.s_addr
) - 1);
703 else if (r
.family
== AF_INET6
)
708 if (!(p
= lua_newuserdata(L
, sizeof(*p
))))
713 luaL_getmetatable(L
, LUCI_IP_CIDR
);
714 lua_setmetatable(L
, -2);
718 static int cidr_gc (lua_State
*L
)
723 static int cidr_tostring (lua_State
*L
)
725 char buf
[INET6_ADDRSTRLEN
];
726 cidr_t
*p
= L_checkcidr(L
, 1, NULL
);
728 if ((p
->family
== AF_INET
&& p
->bits
< 32) ||
729 (p
->family
== AF_INET6
&& p
->bits
< 128))
731 lua_pushfstring(L
, "%s/%d",
732 inet_ntop(p
->family
, &p
->addr
.v6
, buf
, sizeof(buf
)),
737 lua_pushstring(L
, inet_ntop(p
->family
, &p
->addr
.v6
, buf
, sizeof(buf
)));
747 static bool diff_prefix(int family
, void *addr
, int bits
, cidr_t
*p
)
755 if (!addr
|| p
->family
!= family
|| p
->bits
> bits
)
758 if (family
== AF_INET6
)
760 for (i
= 0, r
= p
->bits
; i
< sizeof(struct in6_addr
); i
++)
762 b
= r
? (0xFF << (8 - ((r
> 8) ? 8 : r
))) : 0;
764 if ((((struct in6_addr
*)addr
)->s6_addr
[i
] & b
) !=
765 (p
->addr
.v6
.s6_addr
[i
] & b
))
768 r
-= ((r
> 8) ? 8 : r
);
773 m
= p
->bits
? htonl(~((1 << (32 - p
->bits
)) - 1)) : 0;
775 if ((((struct in_addr
*)addr
)->s_addr
& m
) != (p
->addr
.v4
.s_addr
& m
))
779 return (p
->exact
&& p
->bits
!= bits
);
782 static int cb_dump_route(struct nl_msg
*msg
, void *arg
)
784 struct dump_state
*s
= arg
;
785 struct dump_filter
*f
= s
->filter
;
786 struct nlmsghdr
*hdr
= nlmsg_hdr(msg
);
787 struct rtmsg
*rt
= NLMSG_DATA(hdr
);
788 struct nlattr
*tb
[RTA_MAX
+1];
789 struct in6_addr
*src
, *dst
, *gw
, *from
, def
= { };
790 int iif
, oif
, bitlen
;
793 if (hdr
->nlmsg_type
!= RTM_NEWROUTE
||
794 (rt
->rtm_family
!= AF_INET
&& rt
->rtm_family
!= AF_INET6
))
797 nlmsg_parse(hdr
, sizeof(*rt
), tb
, RTA_MAX
, NULL
);
799 iif
= tb
[RTA_IIF
] ? RTA_INT(tb
[RTA_IIF
]) : 0;
800 oif
= tb
[RTA_OIF
] ? RTA_INT(tb
[RTA_OIF
]) : 0;
801 table
= tb
[RTA_TABLE
] ? RTA_U32(tb
[RTA_TABLE
]) : rt
->rtm_table
;
802 from
= tb
[RTA_SRC
] ? RTA_DATA(tb
[RTA_SRC
]) : NULL
;
803 src
= tb
[RTA_PREFSRC
] ? RTA_DATA(tb
[RTA_PREFSRC
]) : NULL
;
804 dst
= tb
[RTA_DST
] ? RTA_DATA(tb
[RTA_DST
]) : &def
;
805 gw
= tb
[RTA_GATEWAY
] ? RTA_DATA(tb
[RTA_GATEWAY
]) : NULL
;
807 bitlen
= (rt
->rtm_family
== AF_INET6
) ? 128 : 32;
809 if ((f
->type
&& rt
->rtm_type
!= f
->type
) ||
810 (f
->family
&& rt
->rtm_family
!= f
->family
) ||
811 (f
->proto
&& rt
->rtm_protocol
!= f
->proto
) ||
812 (f
->scope
&& rt
->rtm_scope
!= f
->scope
) ||
813 (f
->iif
&& iif
!= f
->iif
) ||
814 (f
->oif
&& oif
!= f
->oif
) ||
815 (f
->table
&& table
!= f
->table
) ||
816 diff_prefix(rt
->rtm_family
, from
, rt
->rtm_src_len
, &f
->from
) ||
817 diff_prefix(rt
->rtm_family
, dst
, rt
->rtm_dst_len
, &f
->dst
) ||
818 diff_prefix(rt
->rtm_family
, gw
, bitlen
, &f
->gw
) ||
819 diff_prefix(rt
->rtm_family
, src
, bitlen
, &f
->src
))
823 lua_pushvalue(s
->L
, 2);
827 L_setint(s
->L
, "type", rt
->rtm_type
);
828 L_setint(s
->L
, "family", (rt
->rtm_family
== AF_INET
) ? 4 : 6);
830 L_setaddr(s
->L
, "dest", rt
->rtm_family
, dst
, rt
->rtm_dst_len
);
833 L_setaddr(s
->L
, "gw", rt
->rtm_family
, gw
, -1);
836 L_setaddr(s
->L
, "from", rt
->rtm_family
, from
, rt
->rtm_src_len
);
839 L_setdev(s
->L
, "iif", tb
[RTA_IIF
]);
842 L_setdev(s
->L
, "dev", tb
[RTA_OIF
]);
844 L_setint(s
->L
, "table", table
);
845 L_setint(s
->L
, "proto", rt
->rtm_protocol
);
846 L_setint(s
->L
, "scope", rt
->rtm_scope
);
849 L_setaddr(s
->L
, "src", rt
->rtm_family
, src
, -1);
851 if (tb
[RTA_PRIORITY
])
852 L_setint(s
->L
, "metric", RTA_U32(tb
[RTA_PRIORITY
]));
854 if (rt
->rtm_family
== AF_INET6
&& tb
[RTA_CACHEINFO
])
856 struct rta_cacheinfo
*ci
= RTA_DATA(tb
[RTA_CACHEINFO
]);
861 L_setint(s
->L
, "expires", ci
->rta_expires
/ hz
);
863 if (ci
->rta_error
!= 0)
864 L_setint(s
->L
, "error", ci
->rta_error
);
871 lua_call(s
->L
, 1, 0);
872 else if (hdr
->nlmsg_flags
& NLM_F_MULTI
)
873 lua_rawseti(s
->L
, -2, s
->index
);
876 s
->pending
= !!(hdr
->nlmsg_flags
& NLM_F_MULTI
);
881 cb_done(struct nl_msg
*msg
, void *arg
)
883 struct dump_state
*s
= arg
;
889 cb_error(struct sockaddr_nl
*nla
, struct nlmsgerr
*err
, void *arg
)
891 struct dump_state
*s
= arg
;
896 static int _error(lua_State
*L
, int code
, const char *msg
)
899 lua_pushnumber(L
, code
? code
: errno
);
900 lua_pushstring(L
, msg
? msg
: strerror(errno
));
905 static int _route_dump(lua_State
*L
, struct dump_filter
*filter
)
907 int flags
= NLM_F_REQUEST
;
908 struct dump_state s
= {
912 .callback
= lua_isfunction(L
, 2),
917 hz
= sysconf(_SC_CLK_TCK
);
921 sock
= nl_socket_alloc();
923 return _error(L
, -1, "Out of memory");
925 if (nl_connect(sock
, NETLINK_ROUTE
))
926 return _error(L
, 0, NULL
);
930 struct nl_cb
*cb
= nl_cb_alloc(NL_CB_DEFAULT
);
932 .rtm_family
= filter
->family
,
933 .rtm_dst_len
= filter
->dst
.bits
,
934 .rtm_src_len
= filter
->src
.bits
940 msg
= nlmsg_alloc_simple(RTM_GETROUTE
, flags
);
944 nlmsg_append(msg
, &rtm
, sizeof(rtm
), 0);
947 nla_put(msg
, RTA_DST
, filter
->dst
.len
, &filter
->dst
.addr
.v6
);
949 nl_cb_set(cb
, NL_CB_VALID
, NL_CB_CUSTOM
, cb_dump_route
, &s
);
950 nl_cb_set(cb
, NL_CB_FINISH
, NL_CB_CUSTOM
, cb_done
, &s
);
951 nl_cb_err(cb
, NL_CB_CUSTOM
, cb_error
, &s
);
953 nl_send_auto_complete(sock
, msg
);
955 if (!filter
->get
&& !s
.callback
)
958 while (s
.pending
> 0)
959 nl_recvmsgs(sock
, cb
);
965 return (s
.callback
== 0);
968 static int route_get(lua_State
*L
)
970 struct dump_filter filter
= { .get
= true };
971 const char *dest
= luaL_checkstring(L
, 1);
973 if (!parse_cidr(dest
, &filter
.dst
))
974 return _error(L
, -1, "Invalid destination");
976 filter
.family
= filter
.dst
.family
;
978 return _route_dump(L
, &filter
);
981 static int route_dump(lua_State
*L
)
985 struct dump_filter filter
= { };
987 if (lua_type(L
, 1) == LUA_TTABLE
)
989 filter
.family
= L_getint(L
, 1, "family");
991 if (filter
.family
== 4)
992 filter
.family
= AF_INET
;
993 else if (filter
.family
== 6)
994 filter
.family
= AF_INET6
;
998 if ((s
= L_getstr(L
, 1, "iif")) != NULL
)
999 filter
.iif
= if_nametoindex(s
);
1001 if ((s
= L_getstr(L
, 1, "oif")) != NULL
)
1002 filter
.oif
= if_nametoindex(s
);
1004 filter
.type
= L_getint(L
, 1, "type");
1005 filter
.scope
= L_getint(L
, 1, "scope");
1006 filter
.proto
= L_getint(L
, 1, "proto");
1007 filter
.table
= L_getint(L
, 1, "table");
1009 if ((s
= L_getstr(L
, 1, "gw")) != NULL
&& parse_cidr(s
, &p
))
1012 if ((s
= L_getstr(L
, 1, "from")) != NULL
&& parse_cidr(s
, &p
))
1015 if ((s
= L_getstr(L
, 1, "src")) != NULL
&& parse_cidr(s
, &p
))
1018 if ((s
= L_getstr(L
, 1, "dest")) != NULL
&& parse_cidr(s
, &p
))
1021 if ((s
= L_getstr(L
, 1, "from_exact")) != NULL
&& parse_cidr(s
, &p
))
1022 filter
.from
= p
, filter
.from
.exact
= true;
1024 if ((s
= L_getstr(L
, 1, "dest_exact")) != NULL
&& parse_cidr(s
, &p
))
1025 filter
.dst
= p
, filter
.dst
.exact
= true;
1028 return _route_dump(L
, &filter
);
1032 static bool diff_macaddr(struct ether_addr
*mac1
, struct ether_addr
*mac2
)
1034 struct ether_addr empty
= { };
1036 if (!memcmp(mac2
, &empty
, sizeof(empty
)))
1039 if (!mac1
|| memcmp(mac1
, mac2
, sizeof(empty
)))
1045 static int cb_dump_neigh(struct nl_msg
*msg
, void *arg
)
1048 struct ether_addr
*mac
;
1049 struct in6_addr
*dst
;
1050 struct dump_state
*s
= arg
;
1051 struct dump_filter
*f
= s
->filter
;
1052 struct nlmsghdr
*hdr
= nlmsg_hdr(msg
);
1053 struct ndmsg
*nd
= NLMSG_DATA(hdr
);
1054 struct nlattr
*tb
[NDA_MAX
+1];
1057 if (hdr
->nlmsg_type
!= RTM_NEWNEIGH
||
1058 (nd
->ndm_family
!= AF_INET
&& nd
->ndm_family
!= AF_INET6
))
1061 nlmsg_parse(hdr
, sizeof(*nd
), tb
, NDA_MAX
, NULL
);
1063 mac
= tb
[NDA_LLADDR
] ? RTA_DATA(tb
[NDA_LLADDR
]) : NULL
;
1064 dst
= tb
[NDA_DST
] ? RTA_DATA(tb
[NDA_DST
]) : NULL
;
1066 bitlen
= (nd
->ndm_family
== AF_INET
) ? 32 : 128;
1068 if ((f
->family
&& nd
->ndm_family
!= f
->family
) ||
1069 (f
->iif
&& nd
->ndm_ifindex
!= f
->iif
) ||
1070 (f
->type
&& !(f
->type
& nd
->ndm_state
)) ||
1071 diff_prefix(nd
->ndm_family
, dst
, bitlen
, &f
->dst
) ||
1072 diff_macaddr(mac
, &f
->mac
))
1076 lua_pushvalue(s
->L
, 2);
1080 L_setint(s
->L
, "family", (nd
->ndm_family
== AF_INET
) ? 4 : 6);
1081 L_setstr(s
->L
, "dev", if_indextoname(nd
->ndm_ifindex
, buf
));
1083 L_setbool(s
->L
, "router", (nd
->ndm_flags
& NTF_ROUTER
));
1084 L_setbool(s
->L
, "proxy", (nd
->ndm_flags
& NTF_PROXY
));
1086 L_setbool(s
->L
, "incomplete", (nd
->ndm_state
& NUD_INCOMPLETE
));
1087 L_setbool(s
->L
, "reachable", (nd
->ndm_state
& NUD_REACHABLE
));
1088 L_setbool(s
->L
, "stale", (nd
->ndm_state
& NUD_STALE
));
1089 L_setbool(s
->L
, "delay", (nd
->ndm_state
& NUD_DELAY
));
1090 L_setbool(s
->L
, "probe", (nd
->ndm_state
& NUD_PROBE
));
1091 L_setbool(s
->L
, "failed", (nd
->ndm_state
& NUD_FAILED
));
1092 L_setbool(s
->L
, "noarp", (nd
->ndm_state
& NUD_NOARP
));
1093 L_setbool(s
->L
, "permanent", (nd
->ndm_state
& NUD_PERMANENT
));
1096 L_setaddr(s
->L
, "dest", nd
->ndm_family
, dst
, -1);
1100 snprintf(buf
, sizeof(buf
), "%02x:%02x:%02x:%02x:%02x:%02x",
1101 mac
->ether_addr_octet
[0], mac
->ether_addr_octet
[1],
1102 mac
->ether_addr_octet
[2], mac
->ether_addr_octet
[3],
1103 mac
->ether_addr_octet
[4], mac
->ether_addr_octet
[5]);
1105 lua_pushstring(s
->L
, buf
);
1106 lua_setfield(s
->L
, -2, "mac");
1112 lua_call(s
->L
, 1, 0);
1113 else if (hdr
->nlmsg_flags
& NLM_F_MULTI
)
1114 lua_rawseti(s
->L
, -2, s
->index
);
1117 s
->pending
= !!(hdr
->nlmsg_flags
& NLM_F_MULTI
);
1121 static int neighbor_dump(lua_State
*L
)
1125 struct ether_addr
*mac
;
1126 struct dump_filter filter
= { .type
= 0xFF & ~NUD_NOARP
};
1127 struct dump_state st
= {
1128 .callback
= lua_isfunction(L
, 2),
1134 if (lua_type(L
, 1) == LUA_TTABLE
)
1136 filter
.family
= L_getint(L
, 1, "family");
1138 if (filter
.family
== 4)
1139 filter
.family
= AF_INET
;
1140 else if (filter
.family
== 6)
1141 filter
.family
= AF_INET6
;
1145 if ((s
= L_getstr(L
, 1, "dev")) != NULL
)
1146 filter
.iif
= if_nametoindex(s
);
1148 if ((s
= L_getstr(L
, 1, "dest")) != NULL
&& parse_cidr(s
, &p
))
1151 if ((s
= L_getstr(L
, 1, "mac")) != NULL
&&
1152 (mac
= ether_aton(s
)) != NULL
)
1158 sock
= nl_socket_alloc();
1160 return _error(L
, -1, "Out of memory");
1162 if (nl_connect(sock
, NETLINK_ROUTE
))
1163 return _error(L
, 0, NULL
);
1167 struct nl_cb
*cb
= nl_cb_alloc(NL_CB_DEFAULT
);
1168 struct ndmsg ndm
= {
1169 .ndm_family
= filter
.family
1172 msg
= nlmsg_alloc_simple(RTM_GETNEIGH
, NLM_F_REQUEST
| NLM_F_DUMP
);
1176 nlmsg_append(msg
, &ndm
, sizeof(ndm
), 0);
1178 nl_cb_set(cb
, NL_CB_VALID
, NL_CB_CUSTOM
, cb_dump_neigh
, &st
);
1179 nl_cb_set(cb
, NL_CB_FINISH
, NL_CB_CUSTOM
, cb_done
, &st
);
1180 nl_cb_err(cb
, NL_CB_CUSTOM
, cb_error
, &st
);
1182 nl_send_auto_complete(sock
, msg
);
1187 while (st
.pending
> 0)
1188 nl_recvmsgs(sock
, cb
);
1194 return (st
.callback
== 0);
1198 static int cb_dump_link(struct nl_msg
*msg
, void *arg
)
1200 char *p
, *addr
, buf
[32];
1201 struct dump_state
*s
= arg
;
1202 struct nlmsghdr
*hdr
= nlmsg_hdr(msg
);
1203 struct ifinfomsg
*ifm
= NLMSG_DATA(hdr
);
1204 struct nlattr
*tb
[IFLA_MAX
+1];
1207 if (hdr
->nlmsg_type
!= RTM_NEWLINK
)
1210 nlmsg_parse(hdr
, sizeof(*ifm
), tb
, IFLA_MAX
, NULL
);
1212 L_setbool(s
->L
, "up", (ifm
->ifi_flags
& IFF_RUNNING
));
1213 L_setint(s
->L
, "type", ifm
->ifi_type
);
1214 L_setstr(s
->L
, "name", if_indextoname(ifm
->ifi_index
, buf
));
1217 L_setint(s
->L
, "mtu", RTA_U32(tb
[IFLA_MTU
]));
1219 if (tb
[IFLA_TXQLEN
])
1220 L_setint(s
->L
, "qlen", RTA_U32(tb
[IFLA_TXQLEN
]));
1222 if (tb
[IFLA_MASTER
])
1223 L_setdev(s
->L
, "master", tb
[IFLA_MASTER
]);
1225 if (tb
[IFLA_ADDRESS
])
1227 addr
= nla_get_string(tb
[IFLA_ADDRESS
]);
1229 for (p
= buf
, i
= 0; i
< nla_len(tb
[IFLA_ADDRESS
]); i
++)
1230 p
+= sprintf(p
, "%s%02x", (i
? ":" : ""), (uint8_t)*addr
++);
1232 L_setstr(s
->L
, "mac", buf
);
1239 static int link_get(lua_State
*L
)
1241 const char *dev
= luaL_checkstring(L
, 1);
1242 struct dump_state st
= {
1249 sock
= nl_socket_alloc();
1251 return _error(L
, -1, "Out of memory");
1253 if (nl_connect(sock
, NETLINK_ROUTE
))
1254 return _error(L
, 0, NULL
);
1257 struct nl_msg
*msg
= nlmsg_alloc_simple(RTM_GETLINK
, NLM_F_REQUEST
);
1258 struct nl_cb
*cb
= nl_cb_alloc(NL_CB_DEFAULT
);
1259 struct ifinfomsg ifm
= { .ifi_index
= if_nametoindex(dev
) };
1264 nlmsg_append(msg
, &ifm
, sizeof(ifm
), 0);
1266 nl_cb_set(cb
, NL_CB_VALID
, NL_CB_CUSTOM
, cb_dump_link
, &st
);
1267 nl_cb_set(cb
, NL_CB_FINISH
, NL_CB_CUSTOM
, cb_done
, &st
);
1268 nl_cb_err(cb
, NL_CB_CUSTOM
, cb_error
, &st
);
1272 nl_send_auto_complete(sock
, msg
);
1273 nl_recvmsgs(sock
, cb
);
1282 static const luaL_reg ip_methods
[] = {
1283 { "new", cidr_new
},
1284 { "IPv4", cidr_ipv4
},
1285 { "IPv6", cidr_ipv6
},
1287 { "route", route_get
},
1288 { "routes", route_dump
},
1290 { "neighbors", neighbor_dump
},
1292 { "link", link_get
},
1297 static const luaL_reg ip_cidr_methods
[] = {
1298 { "is4", cidr_is4
},
1299 { "is4rfc1918", cidr_is4rfc1918
},
1300 { "is4linklocal", cidr_is4linklocal
},
1301 { "is6", cidr_is6
},
1302 { "is6linklocal", cidr_is6linklocal
},
1303 { "lower", cidr_lower
},
1304 { "higher", cidr_higher
},
1305 { "equal", cidr_equal
},
1306 { "prefix", cidr_prefix
},
1307 { "network", cidr_network
},
1308 { "host", cidr_host
},
1309 { "mask", cidr_mask
},
1310 { "broadcast", cidr_broadcast
},
1311 { "contains", cidr_contains
},
1312 { "add", cidr_add
},
1313 { "sub", cidr_sub
},
1314 { "minhost", cidr_minhost
},
1315 { "maxhost", cidr_maxhost
},
1316 { "string", cidr_tostring
},
1318 { "__lt", cidr_lower
},
1319 { "__le", cidr_lower_equal
},
1320 { "__eq", cidr_equal
},
1321 { "__add", cidr_add
},
1322 { "__sub", cidr_sub
},
1323 { "__gc", cidr_gc
},
1324 { "__tostring", cidr_tostring
},
1329 int luaopen_luci_ip(lua_State
*L
)
1331 luaL_register(L
, LUCI_IP
, ip_methods
);
1333 luaL_newmetatable(L
, LUCI_IP_CIDR
);
1334 luaL_register(L
, NULL
, ip_cidr_methods
);
1335 lua_pushvalue(L
, -1);
1336 lua_setfield(L
, -2, "__index");