You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
5.5 KiB

  1. From 96fdf07acf78ecfc9be76a8b0591f38fe6f1a875 Mon Sep 17 00:00:00 2001
  2. From: Steven Barth <steven@midlink.org>
  3. Date: Sat, 9 Nov 2013 12:01:42 +0100
  4. Subject: [PATCH] Add interface resolving
  5. ---
  6. src/if.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7. src/if.h | 27 ++++++++++++++
  8. src/luasocket.c | 2 +
  9. src/makefile | 2 +
  10. src/options.c | 9 +++++
  11. 5 files changed, 153 insertions(+)
  12. create mode 100644 src/if.c
  13. create mode 100644 src/if.h
  14. --- /dev/null
  15. +++ b/src/if.c
  16. @@ -0,0 +1,117 @@
  17. +/*
  18. + * $Id: if.c $
  19. + *
  20. + * Author: Markus Stenberg <fingon@iki.fi>
  21. + *
  22. + * Copyright (c) 2012 cisco Systems, Inc.
  23. + *
  24. + * Created: Tue Dec 4 14:50:34 2012 mstenber
  25. + * Last modified: Wed Dec 5 18:51:08 2012 mstenber
  26. + * Edit time: 24 min
  27. + *
  28. + */
  29. +
  30. +#include <sys/types.h>
  31. +#include <sys/socket.h>
  32. +#include <net/if.h>
  33. +
  34. +#include "if.h"
  35. +
  36. +#include "lauxlib.h"
  37. +
  38. +static int if_global_indextoname(lua_State *L);
  39. +static int if_global_nametoindex(lua_State *L);
  40. +static int if_global_nameindex(lua_State *L);
  41. +
  42. +static luaL_Reg func[] = {
  43. + { "indextoname", if_global_indextoname},
  44. + { "nametoindex", if_global_nametoindex},
  45. + { "nameindex", if_global_nameindex},
  46. + { NULL, NULL}
  47. +};
  48. +
  49. +int if_open(lua_State *L)
  50. +{
  51. + lua_pushstring(L, "iface");
  52. + lua_newtable(L);
  53. +#if LUA_VERSION_NUM < 503
  54. + luaL_openlib(L, NULL, func, 0);
  55. +#else
  56. + luaL_setfuncs(L, func, 0);
  57. +#endif
  58. + lua_settable(L, -3);
  59. + return 0;
  60. +}
  61. +
  62. +int if_global_indextoname(lua_State *L)
  63. +{
  64. + unsigned int ifnumber;
  65. + const char *name;
  66. + char buf[IF_NAMESIZE+1];
  67. +
  68. + if (!lua_isnumber(L, 1))
  69. + {
  70. + lua_pushnil(L);
  71. + lua_pushstring(L, "indextoname expects only number argument");
  72. + return 2;
  73. + }
  74. + ifnumber = lua_tonumber(L, 1);
  75. + if (!(name = if_indextoname(ifnumber, buf)))
  76. + {
  77. + lua_pushnil(L);
  78. + lua_pushstring(L, "nonexistent interface");
  79. + return 2;
  80. + }
  81. + lua_pushstring(L, name);
  82. + return 1;
  83. +}
  84. +
  85. +int if_global_nametoindex(lua_State *L)
  86. +{
  87. + unsigned int ifnumber;
  88. + if (!lua_isstring(L, 1))
  89. + {
  90. + lua_pushnil(L);
  91. + lua_pushstring(L, "nametoindex expects only string argument");
  92. + return 2;
  93. + }
  94. + if (!(ifnumber = if_nametoindex(lua_tostring(L, 1))))
  95. + {
  96. + lua_pushnil(L);
  97. + lua_pushstring(L, "nonexistent interface");
  98. + return 2;
  99. + }
  100. + lua_pushnumber(L, ifnumber);
  101. + return 1;
  102. +}
  103. +
  104. +int if_global_nameindex(lua_State *L)
  105. +{
  106. + struct if_nameindex *ni, *oni;
  107. + int i = 1;
  108. + oni = ni = if_nameindex();
  109. + lua_newtable(L);
  110. + while (ni && ni->if_index && *(ni->if_name))
  111. + {
  112. + /* at result[i], we store.. */
  113. + lua_pushnumber(L, i);
  114. +
  115. + /* new table with two items - index, name*/
  116. + lua_newtable(L);
  117. + lua_pushstring(L, "index");
  118. + lua_pushnumber(L, ni->if_index);
  119. + lua_settable(L, -3);
  120. +
  121. + lua_pushstring(L, "name");
  122. + lua_pushstring(L, ni->if_name);
  123. + lua_settable(L, -3);
  124. +
  125. + /* Then, actually store it */
  126. + lua_settable(L, -3);
  127. +
  128. + i++;
  129. + ni++;
  130. + }
  131. + if_freenameindex(oni);
  132. + return 1;
  133. +}
  134. --- /dev/null
  135. +++ b/src/if.h
  136. @@ -0,0 +1,27 @@
  137. +/*
  138. + * $Id: if.h $
  139. + *
  140. + * Author: Markus Stenberg <fingon@iki.fi>
  141. + *
  142. + * Copyright (c) 2012 cisco Systems, Inc.
  143. + *
  144. + * Created: Tue Dec 4 14:37:24 2012 mstenber
  145. + * Last modified: Tue Dec 4 14:51:43 2012 mstenber
  146. + * Edit time: 7 min
  147. + *
  148. + */
  149. +
  150. +/* This module provides Lua wrapping for the advanced socket API
  151. + * defined in RFC3542, or mainly, the access to the system's interface
  152. + * list. It is necessary for use of recvmsg/sendmsg.
  153. + *
  154. + * TODO - Do something clever with Windows?
  155. + */
  156. +#ifndef IF_H
  157. +#define IF_H
  158. +
  159. +#include "lua.h"
  160. +
  161. +int if_open(lua_State *L);
  162. +
  163. +#endif /* IF_H */
  164. --- a/src/luasocket.c
  165. +++ b/src/luasocket.c
  166. @@ -21,6 +21,7 @@
  167. #include "tcp.h"
  168. #include "udp.h"
  169. #include "select.h"
  170. +#include "if.h"
  171. /*-------------------------------------------------------------------------*\
  172. * Internal function prototypes
  173. @@ -41,6 +42,7 @@ static const luaL_Reg mod[] = {
  174. {"tcp", tcp_open},
  175. {"udp", udp_open},
  176. {"select", select_open},
  177. + {"iface", if_open},
  178. {NULL, NULL}
  179. };
  180. --- a/src/makefile
  181. +++ b/src/makefile
  182. @@ -303,6 +303,7 @@ SOCKET_OBJS= \
  183. compat.$(O) \
  184. options.$(O) \
  185. inet.$(O) \
  186. + if.$(O) \
  187. $(SOCKET) \
  188. except.$(O) \
  189. select.$(O) \
  190. @@ -440,6 +441,7 @@ auxiliar.$(O): auxiliar.c auxiliar.h
  191. buffer.$(O): buffer.c buffer.h io.h timeout.h
  192. except.$(O): except.c except.h
  193. inet.$(O): inet.c inet.h socket.h io.h timeout.h usocket.h
  194. +if.$(O): if.c if.h
  195. io.$(O): io.c io.h timeout.h
  196. luasocket.$(O): luasocket.c luasocket.h auxiliar.h except.h \
  197. timeout.h buffer.h io.h inet.h socket.h usocket.h tcp.h \
  198. --- a/src/options.c
  199. +++ b/src/options.c
  200. @@ -7,7 +7,10 @@
  201. #include "options.h"
  202. #include "inet.h"
  203. #include <string.h>
  204. -
  205. +#include <sys/types.h>
  206. +#include <sys/socket.h>
  207. +#include <net/if.h>
  208. +
  209. /*=========================================================================*\
  210. * Internal functions prototypes
  211. \*=========================================================================*/
  212. @@ -388,6 +391,12 @@ static int opt_ip6_setmembership(lua_Sta
  213. if (!lua_isnil(L, -1)) {
  214. if (lua_isnumber(L, -1)) {
  215. val.ipv6mr_interface = (unsigned int) lua_tonumber(L, -1);
  216. + } else if (lua_isstring(L, -1)) {
  217. + if (!(val.ipv6mr_interface = if_nametoindex(lua_tostring(L, -1)))) {
  218. + lua_pushnil(L);
  219. + lua_pushstring(L, "nonexistent interface");
  220. + return 2;
  221. + }
  222. } else
  223. luaL_argerror(L, -1, "number 'interface' field expected");
  224. }