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
|
|
|
|
diff --git a/src/if.c b/src/if.c
|
|
new file mode 100644
|
|
index 0000000..db231aa
|
|
--- /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;
|
|
+}
|
|
diff --git a/src/if.h b/src/if.h
|
|
new file mode 100644
|
|
index 0000000..dc7faf8
|
|
--- /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 */
|
|
diff --git a/src/luasocket.c b/src/luasocket.c
|
|
index e6ee747..85d41a6 100644
|
|
--- 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}
|
|
};
|
|
|
|
diff --git a/src/makefile b/src/makefile
|
|
index 8d3521e..09d4882 100644
|
|
--- 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 \
|
|
diff --git a/src/options.c b/src/options.c
|
|
index 8ac2a14..1c73e6f 100644
|
|
--- 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");
|
|
}
|
|
--
|
|
1.8.4.rc3
|