diff --git a/src/if.c b/src/if.c new file mode 100644 index 0000000..3654e93 --- /dev/null +++ b/src/if.c @@ -0,0 +1,112 @@ +/* + * $Id: if.c $ + * + * Author: Markus Stenberg + * + * Copyright (c) 2012 Markus Stenberg + * All rights reserved + * + * Created: Tue Dec 4 14:50:34 2012 mstenber + * Last modified: Wed Dec 5 09:50:59 2012 mstenber + * Edit time: 22 min + * + */ + +#include + +#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); + luaL_openlib(L, NULL, func, 0); + 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 + * + * 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 b43114e..88b7e71 100644 --- a/src/luasocket.c +++ b/src/luasocket.c @@ -34,6 +34,7 @@ #include "tcp.h" #include "udp.h" #include "select.h" +#include "if.h" /*-------------------------------------------------------------------------*\ * Internal function prototypes @@ -54,6 +55,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 7e5f2e2..3b1eada 100644 --- a/src/makefile +++ b/src/makefile @@ -26,7 +26,7 @@ LUAV?=5.1 DEBUG?=NODEBUG # where lua headers are found for macosx builds -# LUAINC_macosx: +# LUAINC_macosx: # /opt/local/include LUAINC_macosx_base?=/opt/local/include LUAINC_macosx?=$(LUAINC_macosx_base)/lua$(LUAV) @@ -34,9 +34,9 @@ LUAINC_macosx?=$(LUAINC_macosx_base)/lua$(LUAV) # What happens when more than one Lua version is installed? LUAPREFIX_macosx?=/opt/local/ -# LUAINC_linux: -# /usr/include/lua$(LUAV) -# /usr/local/include +# LUAINC_linux: +# /usr/include/lua$(LUAV) +# /usr/local/include # /usr/local/include/lua$(LUAV) # where lua headers are found for linux builds LUAINC_linux_base?=/usr/include @@ -104,7 +104,7 @@ DEF_macosx= -DLUASOCKET_$(DEBUG) -DUNIX_HAS_SUN_LEN -DLUA_COMPAT_MODULE \ -DMIME_API='__attribute__((visibility("default")))' CFLAGS_macosx= -I$(LUAINC) $(DEF) -pedantic -Wall -O2 -fno-common \ -fvisibility=hidden -LDFLAGS_macosx= -bundle -undefined dynamic_lookup -o +LDFLAGS_macosx= -bundle -undefined dynamic_lookup -o LD_macosx= export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc SOCKET_macosx=usocket.o @@ -119,7 +119,7 @@ DEF_linux=-DLUASOCKET_$(DEBUG) \ -DMIME_API='__attribute__((visibility("default")))' CFLAGS_linux= -I$(LUAINC) $(DEF) -pedantic -Wall -Wshadow -Wextra -Wimplicit -O2 -ggdb3 -fpic \ -fvisibility=hidden -LDFLAGS_linux=-O -shared -fpic -o +LDFLAGS_linux=-O -shared -fpic -o LD_linux=gcc SOCKET_linux=usocket.o @@ -183,6 +183,7 @@ SOCKET_OBJS= \ auxiliar.$(O) \ options.$(O) \ inet.$(O) \ + if.$(O) \ $(SOCKET) \ except.$(O) \ select.$(O) \ @@ -258,20 +259,20 @@ none: all: $(SOCKET_SO) $(MIME_SO) $(SOCKET_SO): $(SOCKET_OBJS) - $(LD) $(SOCKET_OBJS) $(LDFLAGS)$@ + $(LD) $(SOCKET_OBJS) $(LDFLAGS)$@ $(MIME_SO): $(MIME_OBJS) - $(LD) $(MIME_OBJS) $(LDFLAGS)$@ + $(LD) $(MIME_OBJS) $(LDFLAGS)$@ all-unix: all $(UNIX_SO) $(SERIAL_SO) $(UNIX_SO): $(UNIX_OBJS) - $(LD) $(UNIX_OBJS) $(LDFLAGS)$@ + $(LD) $(UNIX_OBJS) $(LDFLAGS)$@ $(SERIAL_SO): $(SERIAL_OBJS) $(LD) $(SERIAL_OBJS) $(LDFLAGS)$@ -install: +install: $(INSTALL_DIR) $(INSTALL_TOP_SHARE) $(INSTALL_DATA) $(TO_TOP_SHARE) $(INSTALL_TOP_SHARE) $(INSTALL_DIR) $(INSTALL_SOCKET_SHARE) @@ -301,6 +302,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/test/ifacetest.lua b/test/ifacetest.lua new file mode 100644 index 0000000..158f114 --- /dev/null +++ b/test/ifacetest.lua @@ -0,0 +1,27 @@ +#!/usr/bin/env lua +-- -*-lua-*- +-- +-- $Id: ifacetest.lua $ +-- +-- Author: Markus Stenberg +-- +-- Copyright (c) 2012 cisco Systems, Inc. +-- +-- Created: Wed Dec 5 09:42:12 2012 mstenber +-- Last modified: Wed Dec 5 09:51:17 2012 mstenber +-- Edit time: 3 min +-- + +local socket = require 'socket' +local iface = socket.iface + +local a = iface.nameindex() +assert(#a > 0) +local o = a[1] +assert(o.index) +assert(o.name) +assert(iface.nametoindex(o.name)) +assert(not iface.nametoindex('gargle')) +assert(iface.indextoname(o.index)) +assert(not iface.indextoname(-123)) +