| From 96fdf07acf78ecfc9be76a8b0591f38fe6f1a875 Mon Sep 17 00:00:00 2001 |
| From: Steven Barth <steven@midlink.org> |
| Date: Sat, 9 Nov 2013 12:01:42 +0100 |
| Subject: [PATCH] Add interface resolving |
| |
| --- |
| src/if.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| src/if.h | 27 ++++++++++++++ |
| src/luasocket.c | 2 + |
| src/makefile | 2 + |
| src/options.c | 9 +++++ |
| 5 files changed, 153 insertions(+) |
| create mode 100644 src/if.c |
| create mode 100644 src/if.h |
| |
| --- /dev/null |
| +++ b/src/if.c |
| @@ -0,0 +1,117 @@ |
| +/* |
| + * $Id: if.c $ |
| + * |
| + * Author: Markus Stenberg <fingon@iki.fi> |
| + * |
| + * Copyright (c) 2012 cisco Systems, Inc. |
| + * |
| + * Created: Tue Dec 4 14:50:34 2012 mstenber |
| + * Last modified: Wed Dec 5 18:51:08 2012 mstenber |
| + * Edit time: 24 min |
| + * |
| + */ |
| + |
| +#include <sys/types.h> |
| +#include <sys/socket.h> |
| +#include <net/if.h> |
| + |
| +#include "if.h" |
| + |
| +#include "lauxlib.h" |
| + |
| +static int if_global_indextoname(lua_State *L); |
| +static int if_global_nametoindex(lua_State *L); |
| +static int if_global_nameindex(lua_State *L); |
| + |
| +static luaL_Reg func[] = { |
| + { "indextoname", if_global_indextoname}, |
| + { "nametoindex", if_global_nametoindex}, |
| + { "nameindex", if_global_nameindex}, |
| + { NULL, NULL} |
| +}; |
| + |
| +int if_open(lua_State *L) |
| +{ |
| + lua_pushstring(L, "iface"); |
| + lua_newtable(L); |
| +#if LUA_VERSION_NUM < 503 |
| + luaL_openlib(L, NULL, func, 0); |
| +#else |
| + luaL_setfuncs(L, func, 0); |
| +#endif |
| + lua_settable(L, -3); |
| + return 0; |
| +} |
| + |
| +int if_global_indextoname(lua_State *L) |
| +{ |
| + unsigned int ifnumber; |
| + const char *name; |
| + char buf[IF_NAMESIZE+1]; |
| + |
| + if (!lua_isnumber(L, 1)) |
| + { |
| + lua_pushnil(L); |
| + lua_pushstring(L, "indextoname expects only number argument"); |
| + return 2; |
| + } |
| + ifnumber = lua_tonumber(L, 1); |
| + if (!(name = if_indextoname(ifnumber, buf))) |
| + { |
| + lua_pushnil(L); |
| + lua_pushstring(L, "nonexistent interface"); |
| + return 2; |
| + } |
| + lua_pushstring(L, name); |
| + return 1; |
| +} |
| + |
| +int if_global_nametoindex(lua_State *L) |
| +{ |
| + unsigned int ifnumber; |
| + if (!lua_isstring(L, 1)) |
| + { |
| + lua_pushnil(L); |
| + lua_pushstring(L, "nametoindex expects only string argument"); |
| + return 2; |
| + } |
| + if (!(ifnumber = if_nametoindex(lua_tostring(L, 1)))) |
| + { |
| + lua_pushnil(L); |
| + lua_pushstring(L, "nonexistent interface"); |
| + return 2; |
| + } |
| + lua_pushnumber(L, ifnumber); |
| + return 1; |
| +} |
| + |
| +int if_global_nameindex(lua_State *L) |
| +{ |
| + struct if_nameindex *ni, *oni; |
| + int i = 1; |
| + oni = ni = if_nameindex(); |
| + lua_newtable(L); |
| + while (ni && ni->if_index && *(ni->if_name)) |
| + { |
| + /* at result[i], we store.. */ |
| + lua_pushnumber(L, i); |
| + |
| + /* new table with two items - index, name*/ |
| + lua_newtable(L); |
| + lua_pushstring(L, "index"); |
| + lua_pushnumber(L, ni->if_index); |
| + lua_settable(L, -3); |
| + |
| + lua_pushstring(L, "name"); |
| + lua_pushstring(L, ni->if_name); |
| + lua_settable(L, -3); |
| + |
| + /* Then, actually store it */ |
| + lua_settable(L, -3); |
| + |
| + i++; |
| + ni++; |
| + } |
| + if_freenameindex(oni); |
| + return 1; |
| +} |
| --- /dev/null |
| +++ b/src/if.h |
| @@ -0,0 +1,27 @@ |
| +/* |
| + * $Id: if.h $ |
| + * |
| + * Author: Markus Stenberg <fingon@iki.fi> |
| + * |
| + * Copyright (c) 2012 cisco Systems, Inc. |
| + * |
| + * Created: Tue Dec 4 14:37:24 2012 mstenber |
| + * Last modified: Tue Dec 4 14:51:43 2012 mstenber |
| + * Edit time: 7 min |
| + * |
| + */ |
| + |
| +/* This module provides Lua wrapping for the advanced socket API |
| + * defined in RFC3542, or mainly, the access to the system's interface |
| + * list. It is necessary for use of recvmsg/sendmsg. |
| + * |
| + * TODO - Do something clever with Windows? |
| + */ |
| +#ifndef IF_H |
| +#define IF_H |
| + |
| +#include "lua.h" |
| + |
| +int if_open(lua_State *L); |
| + |
| +#endif /* IF_H */ |
| --- a/src/luasocket.c |
| +++ b/src/luasocket.c |
| @@ -21,6 +21,7 @@ |
| #include "tcp.h" |
| #include "udp.h" |
| #include "select.h" |
| +#include "if.h" |
| |
| /*-------------------------------------------------------------------------*\ |
| * Internal function prototypes |
| @@ -41,6 +42,7 @@ static const luaL_Reg mod[] = { |
| {"tcp", tcp_open}, |
| {"udp", udp_open}, |
| {"select", select_open}, |
| + {"iface", if_open}, |
| {NULL, NULL} |
| }; |
| |
| --- a/src/makefile |
| +++ b/src/makefile |
| @@ -303,6 +303,7 @@ SOCKET_OBJS= \ |
| compat.$(O) \ |
| options.$(O) \ |
| inet.$(O) \ |
| + if.$(O) \ |
| $(SOCKET) \ |
| except.$(O) \ |
| select.$(O) \ |
| @@ -440,6 +441,7 @@ auxiliar.$(O): auxiliar.c auxiliar.h |
| buffer.$(O): buffer.c buffer.h io.h timeout.h |
| except.$(O): except.c except.h |
| inet.$(O): inet.c inet.h socket.h io.h timeout.h usocket.h |
| +if.$(O): if.c if.h |
| io.$(O): io.c io.h timeout.h |
| luasocket.$(O): luasocket.c luasocket.h auxiliar.h except.h \ |
| timeout.h buffer.h io.h inet.h socket.h usocket.h tcp.h \ |
| --- a/src/options.c |
| +++ b/src/options.c |
| @@ -7,7 +7,10 @@ |
| #include "options.h" |
| #include "inet.h" |
| #include <string.h> |
| - |
| +#include <sys/types.h> |
| +#include <sys/socket.h> |
| +#include <net/if.h> |
| + |
| /*=========================================================================*\ |
| * Internal functions prototypes |
| \*=========================================================================*/ |
| @@ -388,6 +391,12 @@ static int opt_ip6_setmembership(lua_Sta |
| if (!lua_isnil(L, -1)) { |
| if (lua_isnumber(L, -1)) { |
| val.ipv6mr_interface = (unsigned int) lua_tonumber(L, -1); |
| + } else if (lua_isstring(L, -1)) { |
| + if (!(val.ipv6mr_interface = if_nametoindex(lua_tostring(L, -1)))) { |
| + lua_pushnil(L); |
| + lua_pushstring(L, "nonexistent interface"); |
| + return 2; |
| + } |
| } else |
| luaL_argerror(L, -1, "number 'interface' field expected"); |
| } |