summaryrefslogtreecommitdiffhomepage
path: root/libs/luci-lib-ip
diff options
context:
space:
mode:
Diffstat (limited to 'libs/luci-lib-ip')
-rw-r--r--libs/luci-lib-ip/src/ip.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/libs/luci-lib-ip/src/ip.c b/libs/luci-lib-ip/src/ip.c
index affd5e1d6..c799419e5 100644
--- a/libs/luci-lib-ip/src/ip.c
+++ b/libs/luci-lib-ip/src/ip.c
@@ -1195,6 +1195,90 @@ out:
}
+static int cb_dump_link(struct nl_msg *msg, void *arg)
+{
+ char *p, *addr, buf[32];
+ struct dump_state *s = arg;
+ struct nlmsghdr *hdr = nlmsg_hdr(msg);
+ struct ifinfomsg *ifm = NLMSG_DATA(hdr);
+ struct nlattr *tb[IFLA_MAX+1];
+ int i;
+
+ if (hdr->nlmsg_type != RTM_NEWLINK)
+ return NL_SKIP;
+
+ nlmsg_parse(hdr, sizeof(*ifm), tb, IFLA_MAX, NULL);
+
+ L_setbool(s->L, "up", (ifm->ifi_flags & IFF_RUNNING));
+ L_setint(s->L, "type", ifm->ifi_type);
+ L_setstr(s->L, "name", if_indextoname(ifm->ifi_index, buf));
+
+ if (tb[IFLA_MTU])
+ L_setint(s->L, "mtu", RTA_U32(tb[IFLA_MTU]));
+
+ if (tb[IFLA_TXQLEN])
+ L_setint(s->L, "qlen", RTA_U32(tb[IFLA_TXQLEN]));
+
+ if (tb[IFLA_MASTER])
+ L_setdev(s->L, "master", tb[IFLA_MASTER]);
+
+ if (tb[IFLA_ADDRESS])
+ {
+ addr = nla_get_string(tb[IFLA_ADDRESS]);
+
+ for (p = buf, i = 0; i < nla_len(tb[IFLA_ADDRESS]); i++)
+ p += sprintf(p, "%s%02x", (i ? ":" : ""), (uint8_t)*addr++);
+
+ L_setstr(s->L, "mac", buf);
+ }
+
+ s->pending = 0;
+ return NL_SKIP;
+}
+
+static int link_get(lua_State *L)
+{
+ const char *dev = luaL_checkstring(L, 1);
+ struct dump_state st = {
+ .pending = 1,
+ .L = L
+ };
+
+ if (!sock)
+ {
+ sock = nl_socket_alloc();
+ if (!sock)
+ return _error(L, -1, "Out of memory");
+
+ if (nl_connect(sock, NETLINK_ROUTE))
+ return _error(L, 0, NULL);
+ }
+
+ struct nl_msg *msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST);
+ struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
+ struct ifinfomsg ifm = { .ifi_index = if_nametoindex(dev) };
+
+ if (!msg || !cb)
+ return 0;
+
+ nlmsg_append(msg, &ifm, sizeof(ifm), 0);
+
+ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_link, &st);
+ nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
+ nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &st);
+
+ lua_newtable(L);
+
+ nl_send_auto_complete(sock, msg);
+ nl_recvmsgs(sock, cb);
+
+ nlmsg_free(msg);
+ nl_cb_put(cb);
+
+ return 1;
+}
+
+
static const luaL_reg ip_methods[] = {
{ "new", cidr_new },
{ "IPv4", cidr_ipv4 },
@@ -1205,6 +1289,8 @@ static const luaL_reg ip_methods[] = {
{ "neighbors", neighbor_dump },
+ { "link", link_get },
+
{ }
};