nellie.c (1833B)
1 #include <lua.h> 2 #include <lualib.h> 3 #include <lauxlib.h> 4 5 #include <linux/netlink.h> 6 #include <sys/socket.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <unistd.h> 10 11 static int l_close_socket(lua_State *L) { 12 lua_getfield(L, 1, "fileno"); 13 int fd = (int) lua_tointeger(L, -1); 14 close(fd); 15 return 0; 16 } 17 18 static int l_read_from_socket(lua_State *L) { 19 int length = 32; 20 21 if(lua_isnumber(L, 2)) 22 length = lua_tointeger(L, 2); 23 24 lua_getfield(L, 1, "fileno"); 25 int fd = (int) lua_tointeger(L, -1); 26 char *buf = (char *) malloc(length); 27 int bytes = recv(fd, buf, length, 0); 28 29 if(bytes > 0) { 30 lua_pushlstring(L, buf, bytes); 31 free(buf); 32 return 1; 33 } else { 34 free(buf); 35 return 0; 36 } 37 } 38 39 static int l_open_socket(lua_State *L) { 40 int netlink_fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT); 41 42 struct sockaddr_nl sa; 43 memset(&sa, 0, sizeof(sa)); 44 sa.nl_family = AF_NETLINK; 45 sa.nl_pid = getpid(); 46 47 if(lua_isnumber(L, 1)) { 48 sa.nl_groups = lua_tointeger(L, 1); 49 lua_pop(L, 1); 50 } 51 else { 52 sa.nl_groups = 4; /* group 4 is rebroadcasts from mdevd */ 53 } 54 55 if(bind(netlink_fd, (struct sockaddr *) &sa, sizeof(sa))==0) { 56 lua_newtable(L); 57 58 lua_pushliteral(L, "fileno"); 59 lua_pushinteger(L, netlink_fd); 60 lua_settable(L, 1); 61 62 lua_pushliteral(L, "read"); 63 lua_pushcfunction(L, l_read_from_socket); 64 lua_settable(L, 1); 65 66 lua_pushliteral(L, "close"); 67 lua_pushcfunction(L, l_close_socket); 68 lua_settable(L, 1); 69 70 return 1; 71 } else { 72 return 0; 73 } 74 } 75 76 77 static const struct luaL_Reg funcs [] = { 78 {"open", l_open_socket}, 79 {NULL, NULL} /* sentinel */ 80 }; 81 82 83 /* "luaopen_" prefix is magic and tells lua to run this function 84 * when it dlopens the library 85 */ 86 87 int luaopen_nellie (lua_State *L) { 88 luaL_newlib(L, funcs); 89 return 1; 90 }