diff --git a/Makefile.in b/Makefile.in index b7097dadab..1fa6530c14 100644 --- a/Makefile.in +++ b/Makefile.in @@ -60,9 +60,9 @@ INSTALLZENMAP=@INSTALLZENMAP@ UNINSTALLZENMAP=@UNINSTALLZENMAP@ ifneq (@LIBLUA_LIBS@,) -NSE_SRC=nse_main.cc nse_nsock.cc nse_init.cc nse_nmaplib.cc nse_debug.cc nse_pcrelib.cc nse_string.cc -NSE_HDRS=nse_main.h nse_nsock.h nse_init.h nse_nmaplib.h nse_debug.h nse_macros.h nse_pcrelib.h nse_string.h -NSE_OBJS=nse_main.o nse_nsock.o nse_init.o nse_nmaplib.o nse_debug.o nse_pcrelib.o nse_string.o +NSE_SRC=nse_main.cc nse_nsock.cc nse_init.cc nse_fs.cc nse_nmaplib.cc nse_debug.cc nse_pcrelib.cc nse_string.cc +NSE_HDRS=nse_main.h nse_nsock.h nse_init.h nse_fs.h nse_nmaplib.h nse_debug.h nse_macros.h nse_pcrelib.h nse_string.h +NSE_OBJS=nse_main.o nse_nsock.o nse_init.o nse_fs.o nse_nmaplib.o nse_debug.o nse_pcrelib.o nse_string.o NSESTDLIB=nsestdlib endif diff --git a/mswin32/nmap.vcproj b/mswin32/nmap.vcproj index 234bb250be..21193bb29d 100644 --- a/mswin32/nmap.vcproj +++ b/mswin32/nmap.vcproj @@ -259,6 +259,10 @@ RelativePath="..\nse_init.cc" > + + @@ -433,15 +437,15 @@ > = 0 - stack_height; i--) { log_write(LOG_PLAIN, "%d: ", i); - l_dumpValue(l, i); + l_dumpValue(L, i); } log_write(LOG_PLAIN, "-== Stack Dump End ==-\n"); } -void l_dumpValue(lua_State* l, int i) { - switch (lua_type(l, i)) +void l_dumpValue(lua_State *L, int i) { + switch (lua_type(L, i)) { case LUA_TTABLE: - l_dumpTable(l, i); + l_dumpTable(L, i); break; case LUA_TFUNCTION: - l_dumpFunction(l, i); + l_dumpFunction(L, i); break; case LUA_TSTRING: - log_write(LOG_PLAIN, "string '%s'\n", lua_tostring(l, i)); + log_write(LOG_PLAIN, "string '%s'\n", lua_tostring(L, i)); break; case LUA_TBOOLEAN: log_write(LOG_PLAIN, "boolean: %s\n", - lua_toboolean(l, i) ? "true" : "false"); + lua_toboolean(L, i) ? "true" : "false"); break; case LUA_TNUMBER: - log_write(LOG_PLAIN, "number: %g\n", lua_tonumber(l, i)); + log_write(LOG_PLAIN, "number: %g\n", lua_tonumber(L, i)); break; default: - log_write(LOG_PLAIN, "%s\n", lua_typename(l, lua_type(l, i))); + log_write(LOG_PLAIN, "%s\n", lua_typename(L, lua_type(L, i))); } } -void l_dumpTable(lua_State *l, int index) { +void l_dumpTable(lua_State *L, int index) { log_write(LOG_PLAIN, "table\n"); - lua_pushnil(l); + lua_pushnil(L); if (index<0) --index; - while(lua_next(l, index) != 0) + while(lua_next(L, index) != 0) { - l_dumpValue(l, -2); - l_dumpValue(l, -1); - lua_pop(l, 1); + l_dumpValue(L, -2); + l_dumpValue(L, -1); + lua_pop(L, 1); } } -void l_dumpFunction(lua_State* l, int index) { +void l_dumpFunction(lua_State *L, int index) { // lua_Debug ar; log_write(LOG_PLAIN, "function\n"); -// lua_pushvalue(l, index); -// lua_getinfo(l, ">n", &ar); +// lua_pushvalue(L, index); +// lua_getinfo(L, ">n", &ar); // // log_write(LOG_PLAIN, "\tname: %s %s\n", ar.namewhat, ar.name); fflush(stdout); diff --git a/nse_fs.cc b/nse_fs.cc new file mode 100644 index 0000000000..03d30aa965 --- /dev/null +++ b/nse_fs.cc @@ -0,0 +1,190 @@ +#ifndef WIN32 + #include "dirent.h" +#endif + +#include "errno.h" +#include "nse_macros.h" +#include "nse_fs.h" +#include "nmap.h" +#include "nmap_error.h" +#include "NmapOps.h" + +extern NmapOps o; + +static bool filename_is_absolute(const char *file) { + if (file[0] == '/') + return true; +#ifdef WIN32 + if ((file[0] != '\0' && file[1] == ':') || file[0] == '\\') + return true; +#endif + return false; +} + +/* This is simply the most portable way to check + * if a file has a given extension. + * The portability comes at the price of reduced + * flexibility. + */ +int nse_check_extension (const char* ext, const char* path) +{ + int pathlen = strlen(path); + int extlen = strlen(ext); + if (extlen > pathlen || pathlen > MAX_FILENAME_LEN) + return 0; + else + return strcmp(path + pathlen - extlen, ext) == 0; +} + +int nse_fetchfile(char *path, size_t path_len, const char *file) { + int type = nmap_fetchfile(path, path_len, file); + + // lets look in /scripts too + if(type == 0) { + std::string alt_path = std::string(SCRIPT_ENGINE_LUA_DIR) + std::string(file); + type = nmap_fetchfile(path, path_len, alt_path.c_str()); + } + + return type; +} + +/* This is a modification of nse_fetchfile that first looks for an + * absolute file name. + */ +int nse_fetchfile_absolute(char *path, size_t path_len, const char *file) { + if (filename_is_absolute(file)) { + if (o.debugging > 1) + log_write(LOG_STDOUT, "%s: Trying absolute path %s\n", SCRIPT_ENGINE, file); + Strncpy(path, file, path_len); + return nmap_fileexistsandisreadable(file); + } + + return nse_fetchfile(path, path_len, file); +} + +#ifdef WIN32 + +int nse_scandir (lua_State *L) + HANDLE dir; + WIN32_FIND_DATA entry; + std::string path; + BOOL morefiles = FALSE; + char *dirname = luaL_checkstring(L, 1); + int files_or_dirs = luaL_checkint(L, 2); + + lua_createtable(L, 100, 0); // 100 files average + + dir = FindFirstFile((std::string(dirname) + "\\*").c_str(), &entry); + + if (dir == INVALID_HANDLE_VALUE) + { + error("%s: No files in '%s\\*'", SCRIPT_ENGINE, dirname); + return SCRIPT_ENGINE_ERROR; + } + + while(!(morefiles == FALSE && GetLastError() == ERROR_NO_MORE_FILES)) { + // if we are looking for files and this file doesn't end with .nse or + // is a directory, then we don't look further at it + if(files_or_dirs == FILES) { + if(!( + (check_extension(SCRIPT_ENGINE_EXTENSION, entry.cFileName) == MATCH) + && !(entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + )) { + morefiles = FindNextFile(dir, &entry); + continue; + } + + // if we are looking for dirs and this dir + // isn't a directory, then we don't look further at it + } else if(files_or_dirs == DIRS) { + if(!( + (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + )) { + morefiles = FindNextFile(dir, &entry); + continue; + } + + // they have passed an invalid value for files_or_dirs + } else { + fatal("%s: In: %s:%i This should never happen.", + SCRIPT_ENGINE, __FILE__, __LINE__); + } + + // otherwise we add it to the results + // we assume that dirname ends with a directory separator of some kind + path = std::string(dirname) + "\\" + std::string(entry.cFileName); + lua_pushstring(L, path.c_str()); + lua_rawseti(L, -2, lua_objlen(L, -2) + 1); + morefiles = FindNextFile(dir, &entry); + } + + + return 1; +} + +#else + +int nse_scandir (lua_State *L) { + DIR* dir; + struct dirent* entry; + struct stat stat_entry; + const char *dirname = luaL_checkstring(L, 1); + int files_or_dirs = luaL_checkint(L, 2); + + lua_createtable(L, 100, 0); // 100 files average + + dir = opendir(dirname); + if(dir == NULL) { + error("%s: Could not open directory '%s'.", SCRIPT_ENGINE, dirname); + return SCRIPT_ENGINE_ERROR; + } + + // note that if there is a symlink in the dir, we have to rely on + // the .nse extension + // if they provide a symlink to a dir which ends with .nse, things + // break :/ + while((entry = readdir(dir)) != NULL) { + std::string path = std::string(dirname) + "/" + std::string(entry->d_name); + + if(stat(path.c_str(), &stat_entry) != 0) + fatal("%s: In: %s:%i This should never happen.", + SCRIPT_ENGINE, __FILE__, __LINE__); + + // if we are looking for files and this file doesn't end with .nse and + // isn't a file or a link, then we don't look further at it + if(files_or_dirs == FILES) { + if(!( + (nse_check_extension(SCRIPT_ENGINE_EXTENSION, entry->d_name)) + && (S_ISREG(stat_entry.st_mode) + || S_ISLNK(stat_entry.st_mode)) + )) { + continue; + } + + // if we are looking for dirs and this dir + // isn't a dir or a link, then we don't look further at it + } else if(files_or_dirs == DIRS) { + if(!( + (S_ISDIR(stat_entry.st_mode) + || S_ISLNK(stat_entry.st_mode)) + )) { + continue; + } + + // they have passed an invalid value for files_or_dirs + } else { + fatal("%s: In: %s:%i This should never happen.", + SCRIPT_ENGINE, __FILE__, __LINE__); + } + + // otherwise we add it to the results + lua_pushstring(L, path.c_str()); + lua_rawseti(L, -2, lua_objlen(L, -2) + 1); + } + + closedir(dir); + + return 1; +} + +#endif diff --git a/nse_fs.h b/nse_fs.h new file mode 100644 index 0000000000..204c04d45a --- /dev/null +++ b/nse_fs.h @@ -0,0 +1,22 @@ +#ifndef NSE_FS +#define NSE_FS + +extern "C" { + #include "lua.h" + #include "lualib.h" + #include "lauxlib.h" +} + +#include +#include +#include + +int nse_check_extension (const char* ext, const char* path); + +int nse_fetchfile(char *path, size_t path_len, const char *file); + +int nse_fetchfile_absolute(char *path, size_t path_len, const char *file); + +int nse_scandir (lua_State *L); + +#endif diff --git a/nse_init.cc b/nse_init.cc index 5d97113c23..e437f54953 100644 --- a/nse_init.cc +++ b/nse_init.cc @@ -2,6 +2,7 @@ #include "nse_nmaplib.h" #include "nse_macros.h" #include "nse_debug.h" +#include "nse_fs.h" // 3rd Party libs #include "nse_pcrelib.h" @@ -12,801 +13,669 @@ #include "nmap_error.h" #include "NmapOps.h" -#ifndef WIN32 - #include "dirent.h" -#endif - #include "errno.h" #include -int init_setlualibpath(lua_State* l); -int init_setargs(lua_State *l); -int init_parseargs(lua_State* l); -int init_loadfile(lua_State* l, char* filename); -int init_loaddir(lua_State* l, char* dirname); -int init_loadcategories(lua_State* l, std::vector categories, std::vector &unusedTags); -int init_scandir(char* dirname, std::vector& result, int files_or_dirs); -int init_fetchfile(char *result, size_t result_max_len, char* file); -int init_fetchfile_absolute(char *path, size_t path_len, char *file); -int init_updatedb(lua_State* l); -int init_pick_default_categories(std::vector& chosenScripts); - -int check_extension(const char* ext, const char* path); extern NmapOps o; -/* open the standard libs */ -int init_lua(lua_State* l) { // FIXME: Use cpcall, let Lua error normally. - static const luaL_Reg lualibs[] = { - {"", luaopen_base}, - {LUA_LOADLIBNAME, luaopen_package}, - {LUA_TABLIBNAME, luaopen_table}, - {LUA_IOLIBNAME, luaopen_io}, - {LUA_OSLIBNAME, luaopen_os}, - {LUA_STRLIBNAME, luaopen_string}, - {LUA_MATHLIBNAME, luaopen_math}, - {LUA_DBLIBNAME, luaopen_debug}, - {NSE_PCRELIBNAME, luaopen_pcrelib}, - {NULL, NULL} - }; - - const luaL_Reg* lib; - for (lib = lualibs; lib->func; lib++) { - lua_pushcfunction(l, lib->func); - lua_pushstring(l, lib->name); - SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 1, 0, 0)); - } - - - /* publish the nmap bindings to the script */ - lua_newtable(l); - SCRIPT_ENGINE_TRY(set_nmaplib(l)); - lua_setglobal(l, "nmap"); - SCRIPT_ENGINE_TRY(init_setlualibpath(l)); - return SCRIPT_ENGINE_SUCCESS; +extern int current_hosts; +extern int errfunc; + +/* TODO: keep? +// Error function if a user script attempts to create a new global +static int global_error(lua_State *L) +{ + lua_pushvalue(L, lua_upvalueindex(1)); + lua_pushvalue(L, 2); + if (!lua_tostring(L, -1)) + { + lua_pushliteral(L, "? (of type "); + lua_pushstring(L, lua_typename(L, lua_type(L, -2))); + lua_pushliteral(L, ")"); + lua_concat(L, 3); + lua_replace(L, -2); + } + lua_pushvalue(L, lua_upvalueindex(2)); + lua_concat(L, 3); + fprintf(stderr, "%s\n", lua_tostring(L, -1)); + return lua_error(L); +} */ + +/* int error_function (lua_State *L) + * + * Arguments: + * -- error_message (passed by Lua) + * + * This function is for use with lua_pcall as the error handler. + * Because the stack is not unwound when this is called, + * we are able to obtain a traceback of the current stack frame. + * We use debug.traceback (an upvalue set in init_lua) for the real work. + */ +static int error_function (lua_State *L) // for use with lua_pcall +{ + luaL_where(L, 1); + lua_insert(L, 1); + lua_pushvalue(L, lua_upvalueindex(1)); // debug.traceback + lua_pushthread(L); + lua_pushliteral(L, ""); + lua_pushinteger(L, 2); + lua_call(L, 3, 1); + lua_concat(L, 3); + return 1; } -/*sets two variables, which control where lua looks for modules (implemented in C or lua */ -int init_setlualibpath(lua_State* l){ - char path[MAX_FILENAME_LEN]; - char cpath[MAX_FILENAME_LEN]; - - const char*oldpath, *oldcpath; - std::string luapath, luacpath; - /* set the path lua searches for modules*/ - if(nmap_fetchfile(path, MAX_FILENAME_LEN, SCRIPT_ENGINE_LIB_DIR)!=2){ - /*SCRIPT_ENGINE_LIB_DIR is not a directory - error */ - error("%s: %s not a directory", SCRIPT_ENGINE, SCRIPT_ENGINE_LIB_DIR); - return SCRIPT_ENGINE_ERROR; - } - - if(nmap_fetchfile(cpath, MAX_FILENAME_LEN, SCRIPT_ENGINE_LIBEXEC_DIR)!=2){ - error("%s: %s not a directory", SCRIPT_ENGINE, SCRIPT_ENGINE_LIBEXEC_DIR); - return SCRIPT_ENGINE_ERROR; - } - - /* the path lua uses to search for modules is setted to the - * SCRIPT_ENGINE_LIBDIR/ *.lua with the default path - * (which is read from the package-module) appended - - * the path for C-modules is as above but it searches for shared libs (*.so) */ - luapath= std::string(path) + "?.lua;"; +/* load an nmap-lua script + * create a new closure to store the script + * tell the closure where to find the standard + * lua libs and the nmap bindings + * we do some error checking to make sure that + * the script is well formed + * the script is then added to either the hostrules + * or the portrules + * */ + +/* int loadfile (lua_State *L) + * + * Arguments + * -- filename File to load + * + * This function loads a file as a new script. + * The file is loaded with it's own environment that has access to the Global + * Environment. The function is tested to be sure it set a global with a valid + * required_fields[?] ("action", "description", ...), port or host rule. + * If it did, the script's environment (table) is saved in the global PORTTESTS + * or HOSTTESTS table. + */ +static int loadfile (lua_State *L) +{ + int i; + const char *filename = luaL_checkstring(L, 1); + static const char *required_fields[] = {ACTION, DESCRIPTION}; + lua_settop(L, 1); // removes other arguments + + lua_createtable(L, 0, 11); // Environment for script + + lua_pushvalue(L, 1); // tell the script about its filename + lua_setfield(L, -2, "filename"); + + lua_pushnumber(L, 1.0); // set a default RUNLEVEL + lua_setfield(L, -2, RUNLEVEL); + + lua_createtable(L, 0, 1); // script gets access to global env + lua_pushvalue(L, LUA_GLOBALSINDEX); // We may want to use G(L)->mainthread + // later if this function becomes + // exposed. See lstate.h + lua_setfield(L, -2, "__index"); + lua_setmetatable(L, -2); + + // TODO: Allow scripts to modify globals? + /* finally we make sure nobody tampers with the global name space any more + * and prepare for runlevel sorting + */ + /* lua_getmetatable(L, -1); + + lua_pushliteral(L, "Attempted to change the global '"); + lua_pushliteral(L, "' in "); + lua_pushstring(L, filename); + lua_pushliteral(L, " - use nmap.registry if you really want to share " + "data between scripts."); + lua_concat(L, 3); + lua_pushcclosure(L, global_error, 2); + lua_setfield(L, -2, "__newindex"); + lua_pop(L, 1); */ + + if (luaL_loadfile(L, filename) != 0) // load the file + luaL_error(L, "'%s' could not be loaded!", filename); + lua_pushvalue(L, -2); // push environment table + lua_setfenv(L, -2); // set it + lua_call(L, 0, 0); // Call the function (loads globals) + + /* Check some required fields */ + for (i = 0; i < ARRAY_LEN(required_fields); i++) + { + lua_pushstring(L, required_fields[i]); + lua_gettable(L, -2); + if (lua_isnil(L, -1)) + luaL_error(L, "No '%s' field in script '%s'.", required_fields[i], + filename); + lua_pop(L, 1); + } + /* store the initialized test in either + * the hosttests or the porttests + */ + lua_getfield(L, -1, PORTRULE); // script's portrule + lua_getfield(L, -2, HOSTRULE); // script's hostrule + + /* if we are looking at a portrule then store it in the porttestsets table, + * else if it is a hostrule, then it goes into the hosttestsets table, + * otherwise we fail if there. + */ + if (!lua_isnil(L, -2)) + { + lua_pop(L, 2); // pop port/host rules + lua_getglobal(L, PORTTESTS); // Get global PORTTESTS table + lua_pushvalue(L, -2); // script's environment + lua_rawseti(L, -2, lua_objlen(L, -2) + 1); // add it + lua_pop(L, 1); // pop the porttests table + } + else if (!lua_isnil(L, -1)) + { + lua_pop(L, 2); + lua_getglobal(L, HOSTTESTS); + lua_pushvalue(L, -2); + lua_rawseti(L, -2, lua_objlen(L, -2) + 1); + lua_pop(L, 1); // pop the hosttests table + } + else + luaL_error(L, "No rules in script '%s'.", filename); + return 0; +} + +/* int loaddir (lua_State *L) + * + * Arguments + * -- directory Directory (string) to load. + * + * Loads all the scripts (files with a .nse extension), using loadfile. + */ +static int loaddir(lua_State *L) +{ + int i; + luaL_checkstring(L, 1); // directory to load + + lua_pushcclosure(L, nse_scandir, 0); + lua_pushvalue(L, 1); + lua_pushinteger(L, FILES); + lua_call(L, 2, 1); + + lua_pushcclosure(L, loadfile, 0); + for (i = 1; i <= (int) lua_objlen(L, -2); i++) + { + lua_pushvalue(L, -1); // loadfile closure + lua_rawgeti(L, -3, i); // filename + lua_call(L, 1, 0); // load it + } + return 0; +} + +/* int init_setpath (lua_State *L) + * + * Sets the search path of require function to include: + * ./nselib/ For Lua Path (.lua files) + * ./nselib-bin/ For C Path (.so files) + */ +static int init_setpath (lua_State *L) +{ + char path[MAX_FILENAME_LEN], cpath[MAX_FILENAME_LEN]; + + /* set the path lua searches for modules*/ + if (nmap_fetchfile(path, MAX_FILENAME_LEN, SCRIPT_ENGINE_LIB_DIR) != 2) + luaL_error(L, "'%s' not a directory", SCRIPT_ENGINE_LIB_DIR); + if (nmap_fetchfile(cpath, MAX_FILENAME_LEN, SCRIPT_ENGINE_LIBEXEC_DIR) != 2) + luaL_error(L, "'%s' not a directory", SCRIPT_ENGINE_LIBEXEC_DIR); + + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, -1, LUA_LOADLIBNAME); /* "package" */ + lua_pushstring(L, cpath); #ifdef WIN32 - luacpath= std::string(cpath) + "?.dll;"; + lua_pushliteral(L, "?.dll;"); #else - luacpath= std::string(cpath) + "?.so;"; + lua_pushliteral(L, "?.so;"); #endif - - lua_getglobal(l,"package"); - if(!lua_istable(l,-1)){ - error("%s: the lua global-variable package is not a table?!", SCRIPT_ENGINE); - return SCRIPT_ENGINE_ERROR; - } - lua_getfield(l,-1, "path"); - lua_getfield(l,-2, "cpath"); - if(!lua_isstring(l,-1)||!lua_isstring(l,-2)){ - error("%s: no default paths setted in package table (needed in %s at line %d) -- probably a problem of the lua-configuration?!", SCRIPT_ENGINE, __FILE__, __LINE__); - return SCRIPT_ENGINE_ERROR; - } - oldcpath= lua_tostring(l,-1); - oldpath = lua_tostring(l,-2); - luacpath= luacpath + oldcpath; - luapath= luapath + oldpath; - lua_pop(l,2); - lua_pushstring(l, luapath.c_str()); - lua_setfield(l, -2, "path"); - lua_pushstring(l, luacpath.c_str()); - lua_setfield(l, -2, "cpath"); - lua_getfield(l,-1, "path"); - lua_getfield(l,-2, "cpath"); - SCRIPT_ENGINE_DEBUGGING(log_write(LOG_STDOUT, "%s: Using %s to search for C-modules and %s for Lua-modules\n", SCRIPT_ENGINE, lua_tostring(l,-1), lua_tostring(l,-2));) - /*pop the two strings (luapath and luacpath) and the package table off - * the stack */ - lua_pop(l,3); - return SCRIPT_ENGINE_SUCCESS; + lua_getfield(L, -3, "cpath"); /* package.cpath */ + lua_concat(L, 3); + lua_setfield(L, -2, "cpath"); + + lua_pushstring(L, path); + lua_pushliteral(L, "?.lua;"); + lua_getfield(L, -3, "path"); /* package.path */ + lua_concat(L, 3); + lua_setfield(L, -2, "path"); + + return 0; } -/* parses the argument provided to --script-args and leaves the processed - * string on the stack, after this it only has to be prepended with - * "={" and appended by "}", before it can be called by - * luaL_loadbuffer() +/* int init_lua (lua_State *L) + * + * Initializes the Lua State. + * Opens standard libraries as well as nmap and pcre. + * Sets an error function for use by pcall. + * Sets the path for require. */ -int init_parseargs(lua_State* l){ - //FIXME - free o.script-args after we're finished!!! - - if (o.scriptargs==NULL) - return SCRIPT_ENGINE_SUCCESS; //if no arguments are provided we're done - - lua_pushstring(l, o.scriptargs); - luaL_getmetafield(l, -1, "__index"); - lua_getfield(l, -1, "gsub"); - lua_pushvalue(l, -3); - lua_pushliteral(l, "=([^{},]+)"); - lua_pushliteral(l, "=\"%1\""); - SCRIPT_ENGINE_TRY(lua_pcall(l,3,1,0)); - lua_replace(l, 1); - lua_settop(l,1); //clear stack - - return SCRIPT_ENGINE_SUCCESS; +int init_lua (lua_State *L) +{ + int i; + static const luaL_Reg libs[] = { + {NSE_PCRELIBNAME, luaopen_pcrelib}, // pcre library + {"nmap", luaopen_nmap} // nmap bindings + }; + + luaL_openlibs(L); // opens all standard libraries + + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); /* Loaded libraries */ + for (i = 0; i < ARRAY_LEN(libs); i++) // for each in libs + { + lua_pushstring(L, libs[i].name); + lua_pushcclosure(L, libs[i].func, 0); + lua_pushvalue(L, -2); + lua_call(L, 1, 1); + if (lua_isnil(L, -1)) + { + lua_pushboolean(L, 1); + lua_replace(L, -2); + } + lua_settable(L, -3); + } + lua_getfield(L, -1, "debug"); // _LOADED.debug + lua_getfield(L, -1, "traceback"); + lua_pushcclosure(L, error_function, 1); + errfunc = luaL_ref(L, LUA_REGISTRYINDEX); + + lua_pushcclosure(L, init_setpath, 0); + lua_call(L, 0, 0); + + lua_newtable(L); + current_hosts = luaL_ref(L, LUA_REGISTRYINDEX); + + return 0; } -/* set the arguments inside the nmap.registry, for use by scripts + +/* int init_parseargs (lua_State *L) + * + * Arguments + * args Arguments passed through --script-args + * Returns + * function Function that returns a table with the arguments, or an error + * message describing why the arguments could not be parsed. */ -int init_setargs(lua_State *l){ - const char *argbuf; - size_t argbuflen; - if(o.scriptargs==NULL){ - return SCRIPT_ENGINE_SUCCESS; - } - /* we'll concatenate the stuff we need to prepend and append to the - * processed using lua's functionality - */ - SCRIPT_ENGINE_TRY(init_parseargs(l)); - lua_pushliteral(l,"nmap.registry.args={"); - lua_insert(l,-2); - lua_pushliteral(l,"}"); - lua_concat(l,3); - argbuf=lua_tolstring(l,-1,&argbuflen); - luaL_loadbuffer(l,argbuf,argbuflen, "Script-Arguments"); - lua_replace(l, -2); // remove argbuf string - if(lua_pcall(l,0,0,0)!=0){ - error("error loading --script-args: %s",lua_tostring(l,-1)); - return SCRIPT_ENGINE_ERROR; - } - return SCRIPT_ENGINE_SUCCESS; -} -/* if there were no command line arguments specifying - * which scripts should be run, a default script set is - * chosen - * otherwise the script locators given at the command line - * (either directories with lua files or lua files) are - * loaded - * */ -int init_rules(lua_State* l, std::vector chosenScripts) { - char path[MAX_FILENAME_LEN]; - int type; - char* c_iter; - std::vector unusedTags; - - lua_newtable(l); - lua_setglobal(l, PORTTESTS); - - lua_newtable(l); - lua_setglobal(l, HOSTTESTS); - - SCRIPT_ENGINE_TRY(init_pick_default_categories(chosenScripts)); - - // we try to interpret the choices as categories - SCRIPT_ENGINE_TRY(init_loadcategories(l, chosenScripts, unusedTags)); - - // if there's more, we try to interpret as directory or file - std::vector::iterator iter; - bool extension_not_matched = false; - for(iter = unusedTags.begin(); iter != unusedTags.end(); iter++) { - - c_iter = strdup((*iter).c_str()); - type = init_fetchfile_absolute(path, sizeof(path), c_iter); - free(c_iter); - - if (type == 0) { - c_iter = strdup((*iter + std::string(SCRIPT_ENGINE_EXTENSION)).c_str()); - type = init_fetchfile_absolute(path, sizeof(path), c_iter); - free(c_iter); - } - - switch(type) { - case 0: // no such path - error("%s: No such category, file or directory: '%s'", SCRIPT_ENGINE, (*iter).c_str()); - return SCRIPT_ENGINE_ERROR; - break; - case 1: // nmap_fetchfile returned a file - if(check_extension(SCRIPT_ENGINE_EXTENSION, path) != MATCH - && extension_not_matched == false) { - error("%s: Warning: Loading '%s' - the recommended file extension is '.nse'.", - SCRIPT_ENGINE, path); - extension_not_matched = true; - } - SCRIPT_ENGINE_TRY(init_loadfile(l, path)); - break; - case 2: // nmap_fetchfile returned a dir - SCRIPT_ENGINE_TRY(init_loaddir(l, path)); - break; - default: - fatal("%s: In: %s:%i This should never happen.", - SCRIPT_ENGINE, __FILE__, __LINE__); - } - } - - // Compute some stats - SCRIPT_ENGINE_DEBUGGING( - int rules_count; - - lua_getglobal(l, HOSTTESTS); - rules_count = lua_objlen(l, -1); - - lua_getglobal(l, PORTTESTS); - rules_count += lua_objlen(l, -1); - lua_pop(l, 2); - log_write(LOG_STDOUT, "%s: Initialized %d rules\n", SCRIPT_ENGINE, rules_count); - ) - - return SCRIPT_ENGINE_SUCCESS; -} +int init_parseargs (lua_State *L) +{ + const char *arg; + size_t len; + + luaL_checkstring(L, 1); + luaL_getmetafield(L, 1, "__index"); // string library + lua_getfield(L, -1, "gsub"); // string.gsub + lua_pushvalue(L, 1); + lua_pushliteral(L, "=([^{},]+)"); // make strings quoted + lua_pushliteral(L, "=\"%1\""); + lua_call(L, 3, 1); + + lua_pushliteral(L, "return {"); + lua_insert(L, -2); + lua_pushliteral(L, "}"); + lua_concat(L, 3); + arg = lua_tolstring(L, -1, &len); + luaL_loadbuffer(L, arg, len, "Script-Args"); -class ExtensionalCategory { -public: - std::string category; - int option; - - ExtensionalCategory(std::string _category, int _option) { - category = _category; - option = _option; - } -}; - -int init_pick_default_categories(std::vector& chosenScripts) { - std::vector reserved_categories; - std::vector::iterator rcat_iter; - - reserved_categories.push_back(ExtensionalCategory(std::string("version"), o.scriptversion)); - - // if they tried to explicitely select an implicit category, we complain - if(o.script) { - for( rcat_iter = reserved_categories.begin(); - rcat_iter != reserved_categories.end(); - rcat_iter++) { - if( (*rcat_iter).option == 0 - && std::find( - chosenScripts.begin(), - chosenScripts.end(), - (*rcat_iter).category) != chosenScripts.end()) - fatal("%s: specifying the \"%s\" category explicitly is not allowed.", - SCRIPT_ENGINE, (*rcat_iter).category.c_str()); - } - } - - // if no scripts were chosen, we use a default set - if( (o.script == 1 - && chosenScripts.size() == 0) ) - { - chosenScripts.push_back(std::string("default")); - } - - // we append the implicitely selected categories - for( rcat_iter = reserved_categories.begin(); - rcat_iter != reserved_categories.end(); - rcat_iter++) { - if((*rcat_iter).option == 1) - chosenScripts.push_back((*rcat_iter).category); - } - - return SCRIPT_ENGINE_SUCCESS; + return 1; // return function from luaL_loadbuffer or error message returned } -int init_updatedb(lua_State* l) { - char path[MAX_FILENAME_LEN]; - FILE* scriptdb; - std::vector files; - std::vector::iterator iter; - char* c_iter; - - if(nmap_fetchfile(path, sizeof(path)-sizeof(SCRIPT_ENGINE_DATABASE)-1, SCRIPT_ENGINE_LUA_DIR) == 0) { - error("%s: Couldn't find '%s'", SCRIPT_ENGINE, SCRIPT_ENGINE_LUA_DIR); - return SCRIPT_ENGINE_ERROR; - } - - SCRIPT_ENGINE_TRY(init_scandir(path, files, FILES)); - - // we rely on the fact that nmap_fetchfile returned a string which leaves enough room - // to append the db filename (see call to nmap_fetchfile above) - strncat(path, SCRIPT_ENGINE_DATABASE, MAX_FILENAME_LEN-1); - - scriptdb = fopen(path, "w"); - if(scriptdb == NULL) { - error("%s: Could not open '%s' for writing: %s", - SCRIPT_ENGINE, path, strerror(errno)); - return SCRIPT_ENGINE_ERROR; - } - - SCRIPT_ENGINE_DEBUGGING( - log_write(LOG_STDOUT, "%s: Trying to add %d scripts to the database.\n", - SCRIPT_ENGINE, (int) files.size()); - ) - - lua_newtable(l); - /*give the script global namespace access*/ - lua_newtable(l); - lua_pushvalue(l, LUA_GLOBALSINDEX); - lua_setfield(l, -2, "__index"); - lua_setmetatable(l, -2); - - std::sort(files.begin(), files.end()); - - for(iter = files.begin(); iter != files.end(); iter++) { - c_iter = strdup((*iter).c_str()); - if(check_extension(SCRIPT_ENGINE_EXTENSION, c_iter) == MATCH - && strstr(c_iter, SCRIPT_ENGINE_DATABASE) == NULL) { - - SCRIPT_ENGINE_LUA_TRY(luaL_loadfile(l, c_iter)); - lua_pushvalue(l, -2); - lua_setfenv(l, -2); - SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0)); - - lua_getfield(l, -1, "categories"); - if(lua_isnil(l, -1)) { - error("%s: Script '%s' does not contain any category categories.", SCRIPT_ENGINE, c_iter); - return SCRIPT_ENGINE_ERROR; - } - - lua_pushnil(l); - while(lua_next(l, -2) != 0) { - char *filename = path_get_basename(c_iter); - if (filename == NULL) { - error("%s: Could not allocate temporary memory.", SCRIPT_ENGINE); - return SCRIPT_ENGINE_ERROR; - } - fprintf(scriptdb, - "Entry{ category = \"%s\", filename = \"%s\" }\n", - lua_tostring(l, -1), filename); - free(filename); - lua_pop(l, 1); - } - lua_pop(l, 1); // pop the categories table - } - - free(c_iter); - } - lua_pop(l, 1); // pop the closure - - if(fclose(scriptdb) != 0) { - error("%s: Could not close %s: %s", SCRIPT_ENGINE, path, strerror(errno)); - return SCRIPT_ENGINE_ERROR; - } - - return SCRIPT_ENGINE_SUCCESS; -} +/* int init_setargs (lua_State *L) + * + * Takes the function returned by init_parseargs(), calls it, and puts + * the returned table in nmap.registry.args + */ +int init_setargs (lua_State *L) +{ + if (o.scriptargs == NULL) + return 0; -int init_loadcategories(lua_State* l, std::vector categories, std::vector &unusedTags) { - std::vector::iterator iter; - std::vector files; - std::string dbpath = std::string(SCRIPT_ENGINE_LUA_DIR) + std::string(SCRIPT_ENGINE_DATABASE); - char* c_dbpath_buf; - char c_dbpath[MAX_FILENAME_LEN]; - const char* stub = "\ -files = {}\n\ -Entry = function(e)\n\ - if (categories[e.category] ~= nil) then\n\ - categories[e.category] = categories[e.category] + 1\n\ - files[e.filename] = true\n\ - end\n\ - if (categories[\"all\"] ~= nil and e.category ~= \"version\") then\n\ - categories[\"all\"] = categories[\"all\"] + 1\n\ - files[e.filename] = true\n\ - end\n\ -end\n"; - int categories_usage; - char* c_iter; - char script_path[MAX_FILENAME_LEN]; - int type; - - // closure - lua_newtable(l); - - // categories table - lua_newtable(l); - for(iter = categories.begin(); iter != categories.end(); iter++) { - lua_pushinteger(l, 0); - lua_setfield(l, -2, (*iter).c_str()); - } - lua_setfield(l, -2, "categories"); - - // we load the stub - // the strlen is safe in this case because the stub is a constant string - SCRIPT_ENGINE_LUA_TRY(luaL_loadbuffer(l, stub, strlen(stub), "Database Stub")); - lua_pushvalue(l, -2); - lua_setfenv(l, -2); - SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0)); - - // if we can't find the database we try to create it - c_dbpath_buf = strdup(dbpath.c_str()); - if(nmap_fetchfile(c_dbpath, sizeof(c_dbpath), c_dbpath_buf) == 0) { - SCRIPT_ENGINE_TRY(init_updatedb(l)); - } - free(c_dbpath_buf); - - SCRIPT_ENGINE_LUA_TRY(luaL_loadfile(l, c_dbpath)); - lua_pushvalue(l, -2); - lua_setfenv(l, -2); - SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0)); - - // retrieve the filenames produced by the stub - lua_getfield(l, -1, "files"); - lua_pushnil(l); - while(lua_next(l, -2) != 0) { - if(lua_isstring(l, -2)) - files.push_back(std::string(lua_tostring(l, -2))); - else { - error("%s: One of the filenames in '%s' is not a string?!", - SCRIPT_ENGINE, - SCRIPT_ENGINE_DATABASE); - return SCRIPT_ENGINE_ERROR; - } - lua_pop(l, 1); - } - lua_pop(l, 1); - - // find out which categories didn't produce any filenames - lua_getfield(l, -1, "categories"); - lua_pushnil(l); - while(lua_next(l, -2) != 0) { - categories_usage = lua_tointeger(l, -1); - if(categories_usage == 0) { - unusedTags.push_back(std::string(lua_tostring(l, -2))); - } - lua_pop(l, 1); - } - lua_pop(l, 2); - - // load all the files we have found for the given categories - for(iter = files.begin(); iter != files.end(); iter++) { - c_iter = strdup((*iter).c_str()); - type = init_fetchfile(script_path, sizeof(script_path), c_iter); - - if(type != 1) { - error("%s: %s is not a file.", SCRIPT_ENGINE, c_iter); - return SCRIPT_ENGINE_ERROR; - } - - free(c_iter); - - SCRIPT_ENGINE_TRY(init_loadfile(l, script_path)); - } - - return SCRIPT_ENGINE_SUCCESS; -} + lua_getglobal(L, "nmap"); + lua_getfield(L, -1, "registry"); -int init_fetchfile(char *path, size_t path_len, char* file) { - int type; + lua_pushcclosure(L, init_parseargs, 0); + lua_pushstring(L, o.scriptargs); + lua_call(L, 1, 1); - type = nmap_fetchfile(path, path_len, file); + if (!lua_isfunction(L, -1)) + luaL_error(L, "Bad script arguments!\n\t%s", lua_tostring(L, -1)); - // lets look in /scripts too - if(type == 0) { - char* alt_path = strdup((std::string(SCRIPT_ENGINE_LUA_DIR) + std::string(file)).c_str()); - type = nmap_fetchfile(path, path_len, alt_path); - free(alt_path); - - } + lua_call(L, 0, 1); /* get returned table */ - return type; + lua_setfield(L, -2, "args"); + + return 0; } -static bool filename_is_absolute(const char *file) { - if (file[0] == '/') - return true; -#ifdef WIN32 - if ((file[0] != '\0' && file[1] == ':') || file[0] == '\\') - return true; -#endif - return false; +/* int init_updatedb (lua_State *L) + * + * Loads all the files in ./scripts and puts them in the database. + * Each file is loaded and for each of its categories, an entry in the + * database is made in the following format: + * Entry{ category = "category1", filename = "somefile" }\n" + * Entry{ category = "category2", filename = "somefile" }\n" + * Each file will have an entry per category. + */ +int init_updatedb (lua_State *L) +{ + int i; + char path[MAX_FILENAME_LEN]; + FILE *scriptdb; + lua_settop(L, 0); // clear all args + + if (nmap_fetchfile(path, sizeof(path) - sizeof(SCRIPT_ENGINE_DATABASE), + SCRIPT_ENGINE_LUA_DIR) == 0) + luaL_error(L, "Couldn't find '%s'", SCRIPT_ENGINE_LUA_DIR); + + lua_pushcclosure(L, nse_scandir, 0); + lua_pushstring(L, path); + lua_pushinteger(L, FILES); + lua_call(L, 2, 1); // get all the .nse files in ./scripts + + // we rely on the fact that nmap_fetchfile returned a string which leaves enough room + // to append the db filename (see call to nmap_fetchfile above) + strncat(path, SCRIPT_ENGINE_DATABASE, MAX_FILENAME_LEN-1); + + scriptdb = fopen(path, "w"); + if (scriptdb == NULL) + luaL_error(L, "Could not open file '%s' for writing.", path); + + SCRIPT_ENGINE_DEBUGGING( + log_write(LOG_STDOUT, "%s: Trying to add %u scripts to the database.\n", + SCRIPT_ENGINE, lua_objlen(L, 1)); + ) + + // give the script global namespace access + lua_createtable(L, 0, 1); // metatable + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setfield(L, -2, "__index"); + + for (i = 1; i <= (int) lua_objlen(L, 1); i++) + { + const char *file; + lua_rawgeti(L, 1, i); // integer key from scan_dir() table + file = lua_tostring(L, -1); + if (nse_check_extension(SCRIPT_ENGINE_EXTENSION, file) && + strstr(file, SCRIPT_ENGINE_DATABASE) == NULL) + { + char *filebase = path_get_basename(file); + lua_newtable(L); // script environment + lua_pushvalue(L, -3); // script metatable + lua_setmetatable(L, -2); // set it + luaL_loadfile(L, file); // load file + lua_pushvalue(L, -2); // push environment + lua_setfenv(L, -2); // set it + lua_call(L, 0, 0); + + lua_getfield(L, -1, "categories"); + if (lua_isnil(L, -1)) + luaL_error(L, "Script, '%s', being added to the database " + "has no categories.", file); + + if (filebase == NULL) + luaL_error(L, "filename basename could not be generated"); + + lua_pushnil(L); + while (lua_next(L, -2) != 0) + { + fprintf(scriptdb, "Entry{ category = \"%s\", filename = \"%s\" }\n", + lua_tostring(L, -1), filebase); + lua_pop(L, 1); + } + lua_pop(L, 2); // script environment and categories + free(filebase); + } + lua_pop(L, 1); // filename + } + + if (fclose(scriptdb) != 0) + luaL_error(L, "Could not close script.db: %s.", strerror(errno)); + + return 0; } -/* This is a modification of init_fetchfile that first looks for an - * absolute file name. +typedef struct extensional_category { + char *category; + int option; +} extensional_category; + +/* int pick_default_categories (lua_State *L) + * + * The function is passed all the scripts/directories/categories passed + * through --scripts argument. For each of these, we check if a reserved + * category (currently "version") has been chosen, and raise a fatal error + * if so. Finally the reserved categories are added. Basically, explicitly + * adding the reserved categories is illegal. */ -int init_fetchfile_absolute(char *path, size_t path_len, char *file) { - if (filename_is_absolute(file)) { - if (o.debugging > 1) - log_write(LOG_STDOUT, "%s: Trying absolute path %s\n", SCRIPT_ENGINE, file); - Strncpy(path, file, path_len); - return nmap_fileexistsandisreadable(file); - } - - return init_fetchfile(path, path_len, file); +static int pick_default_categories (lua_State *L) +{ + int i, top = lua_gettop(L); + extensional_category reserved_categories[] = { + {"version", o.scriptversion}, + }; + + if (top > 0) + { + // if they tried to explicitely select an implicit category, we complain + // ... for each in reserved_categories + for (i = 0; i < ARRAY_LEN(reserved_categories); i++) + { + int j; + lua_pushstring(L, reserved_categories[i].category); + for (j = 1; j <= top; j++) + if (lua_equal(L, j, -1)) + { + fatal("%s: specifying the \"%s\" category explicitly is not allowed.", + SCRIPT_ENGINE, lua_tostring(L, -1)); + } + lua_pop(L, 1); + } + } + else if (o.script == 1) + { + // default set of categories + lua_pushliteral(L, "default"); + } + + // for each in reserved_categories + for (i = 0; i < ARRAY_LEN(reserved_categories); i++) + if (reserved_categories[i].option == 1) + lua_pushstring(L, reserved_categories[i].category); + + return lua_gettop(L); } -/* This is simply the most portable way to check - * if a file has a given extension. - * The portability comes at the price of reduced - * flexibility. +/* int entry (lua_State *L) + * + * This function is called from the script.db file. It has two upvalues: + * [1] Categories The categories/files/directories passed via --script. + * [2] Files The Files currently loaded (initially an empty table). + * A table is passed from the script database with a category and filename. + * The function tests if either the script's (filename's) category was chosen + * by checking [1]. Or, it loads the file if [1] has the 'category' "all" and + * the script's category is not "version". */ -int check_extension(const char* ext, const char* path) { - int pathlen = strlen(path); - int extlen = strlen(ext); - const char* offset; - - if( extlen > pathlen - || pathlen > MAX_FILENAME_LEN) - return -1; - - offset = path + pathlen - extlen; - - if(strcmp(offset, ext) != MATCH) - return 1; - else - return MATCH; +static int entry (lua_State *L) +{ + char script_path[MAX_FILENAME_LEN]; + int not_all; + + luaL_checktype(L, 1, LUA_TTABLE); // Sole argument is a table + lua_settop(L, 1); + lua_getfield(L, 1, "category"); // index 2 + lua_getfield(L, 1, "filename"); // index 3 + if (!(lua_isstring(L, 2) && lua_isstring(L, 3))) + luaL_error(L, "bad entry in script database"); + lua_pushvalue(L, 3); // filename + lua_gettable(L, lua_upvalueindex(2)); // already loaded? + if (!lua_isnil(L, -1)) + return 0; + lua_pushvalue(L, 2); // category + lua_gettable(L, lua_upvalueindex(1)); // check 1 + lua_pushliteral(L, "version"); // check 2 + lua_getfield(L, lua_upvalueindex(1), "all"); // check 3 + + // if category chosen OR category != "version" and [1].all exists + if ((not_all = (!lua_isnil(L, -3))) || + (!(lua_isnil(L, -1) || lua_equal(L, 2, -2)))) + { + if (not_all) + lua_pushvalue(L, 2); + else + lua_pushliteral(L, "all"); + lua_pushboolean(L, 1); // set category to true + lua_settable(L, lua_upvalueindex(1)); + + if (nse_fetchfile(script_path, sizeof(script_path), + lua_tostring(L, 3)) != 1) + luaL_error(L, "%s: %s is not a file!", lua_tostring(L, 3)); + + lua_pushvalue(L, 3); // filename + lua_pushboolean(L, 1); + lua_settable(L, lua_upvalueindex(2)); // loaded + lua_pushcclosure(L, loadfile, 0); + lua_pushstring(L, script_path); + lua_call(L, 1, 0); + } + return 0; } -int init_loaddir(lua_State* l, char* dirname) { - std::vector files; - char* c_iter; +/* int loadcategories (lua_State *L) + * + * This function takes all the categories/scripts/directories + * passed to it and puts them in a table. + * This table along with an empty one are used as upvalues to the + * Entry closure (see entry above). Finally, the ./scripts/script.db + * file is loaded and it's environment set to only include the Entry + * closure. The entry function will do the work to load all script files with + * chosen categories. After the script database is executed. Any remainining + * fields (files/directories and possibly unused categories) are left in the + * table to be handled later. + */ +static int loadcategories (lua_State *L) +{ + int i, top = lua_gettop(L); + char c_dbpath[MAX_FILENAME_LEN]; + static const char *dbpath = SCRIPT_ENGINE_LUA_DIR SCRIPT_ENGINE_DATABASE; - SCRIPT_ENGINE_TRY(init_scandir(dirname, files, FILES)); - - std::vector::iterator iter; - for(iter = files.begin(); iter != files.end(); iter++) { - c_iter = strdup((*iter).c_str()); - SCRIPT_ENGINE_TRY(init_loadfile(l, c_iter)); - free(c_iter); - } + if (nmap_fetchfile(c_dbpath, sizeof(c_dbpath), dbpath) == 0) + { + lua_pushcclosure(L, init_updatedb, 0); + lua_call(L, 0, 0); + } - return SCRIPT_ENGINE_SUCCESS; -} + lua_createtable(L, 0, top); // categories table + for (i = 1; i <= top; i++) + { + lua_pushvalue(L, i); // category/files/directory + lua_pushboolean(L, 0); // false (not used) + lua_settable(L, -3); + } -#ifdef WIN32 + luaL_loadfile(L, c_dbpath); + lua_createtable(L, 0, 1); + lua_pushliteral(L, "Entry"); + lua_pushvalue(L, -4); // categories table + lua_newtable(L); // files loaded + lua_pushcclosure(L, entry, 2); + lua_settable(L, -3); + lua_setfenv(L, -2); + lua_call(L, 0, 0); // Let errors go through + + lua_pushnil(L); + while (lua_next(L, -2) != 0) + { + if (lua_toboolean(L, -1)) // category was used? + { + lua_pushvalue(L, -2); + lua_pushnil(L); + lua_settable(L, -5); // remove the category + } + lua_pop(L, 1); + } -int init_scandir(char* dirname, std::vector& result, int files_or_dirs) { - HANDLE dir; - WIN32_FIND_DATA entry; - std::string path; - BOOL morefiles = FALSE; - - dir = FindFirstFile((std::string(dirname) + "\\*").c_str(), &entry); - - if (dir == INVALID_HANDLE_VALUE) - { - error("%s: No files in '%s\\*'", SCRIPT_ENGINE, dirname); - return SCRIPT_ENGINE_ERROR; - } - - while(!(morefiles == FALSE && GetLastError() == ERROR_NO_MORE_FILES)) { - // if we are looking for files and this file doesn't end with .nse or - // is a directory, then we don't look further at it - if(files_or_dirs == FILES) { - if(!( - (check_extension(SCRIPT_ENGINE_EXTENSION, entry.cFileName) == MATCH) - && !(entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - )) { - morefiles = FindNextFile(dir, &entry); - continue; - } - - // if we are looking for dirs and this dir - // isn't a directory, then we don't look further at it - } else if(files_or_dirs == DIRS) { - if(!( - (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - )) { - morefiles = FindNextFile(dir, &entry); - continue; - } - - // they have passed an invalid value for files_or_dirs - } else { - fatal("%s: In: %s:%i This should never happen.", - SCRIPT_ENGINE, __FILE__, __LINE__); - } - - // otherwise we add it to the results - // we assume that dirname ends with a directory separator of some kind - path = std::string(dirname) + "\\" + std::string(entry.cFileName); - result.push_back(path); - morefiles = FindNextFile(dir, &entry); - } - - - return SCRIPT_ENGINE_SUCCESS; + return 1; // unused tags (what's left in categories table) } -#else +/* int init_rules (lua_State *L) + * + * Arguments + * ... All the categories/scripts/directories passed via --script + * + * This function adds the PORTTESTS and HOSTTESTS globals to the main state. + * Then it calls pick_default_categories to check for illegally passed implicit + * categories (which it will add otherwise). Next, loadcategories is called + * to load all the viable files for which a category was chosen. The unused + * tags (files/directories, and possibly unused or invalid categories) are + * then each loaded (attempted). If any do not load then an error is raised. + */ +int init_rules (lua_State *L) +{ + int top = lua_gettop(L); // number of categories/scripts -int init_scandir(char* dirname, std::vector& result, int files_or_dirs) { - DIR* dir; - struct dirent* entry; - std::string path; - struct stat stat_entry; - - dir = opendir(dirname); - if(dir == NULL) { - error("%s: Could not open directory '%s'.", SCRIPT_ENGINE, dirname); - return SCRIPT_ENGINE_ERROR; - } - - // note that if there is a symlink in the dir, we have to rely on - // the .nse extension - // if they provide a symlink to a dir which ends with .nse, things - // break :/ - while((entry = readdir(dir)) != NULL) { - path = std::string(dirname) + "/" + std::string(entry->d_name); - - if(stat(path.c_str(), &stat_entry) != 0) - fatal("%s: In: %s:%i This should never happen.", - SCRIPT_ENGINE, __FILE__, __LINE__); - - // if we are looking for files and this file doesn't end with .nse and - // isn't a file or a link, then we don't look further at it - if(files_or_dirs == FILES) { - if(!( - (check_extension(SCRIPT_ENGINE_EXTENSION, entry->d_name) == MATCH) - && (S_ISREG(stat_entry.st_mode) - || S_ISLNK(stat_entry.st_mode)) - )) { - continue; - } - - // if we are looking for dirs and this dir - // isn't a dir or a link, then we don't look further at it - } else if(files_or_dirs == DIRS) { - if(!( - (S_ISDIR(stat_entry.st_mode) - || S_ISLNK(stat_entry.st_mode)) - )) { - continue; - } - - // they have passed an invalid value for files_or_dirs - } else { - fatal("%s: In: %s:%i This should never happen.", - SCRIPT_ENGINE, __FILE__, __LINE__); - } - - // otherwise we add it to the results - result.push_back(path); - } - - closedir(dir); - - return SCRIPT_ENGINE_SUCCESS; -} + lua_newtable(L); + lua_setglobal(L, PORTTESTS); -#endif + lua_newtable(L); + lua_setglobal(L, HOSTTESTS); -/* Error function if a user script attempts to create a new global */ -/* TODO: Why wasn't _changing_ globals handled? */ -static int global_error(lua_State *L) -{ - lua_pushvalue(L, lua_upvalueindex(1)); - lua_pushvalue(L, 2); - if (!lua_tostring(L, -1)) + lua_pushcclosure(L, pick_default_categories, 0); + lua_insert(L, 1); + lua_call(L, top, LUA_MULTRET); + top = lua_gettop(L); // new number of categories & scripts + + lua_pushcclosure(L, loadcategories, 0); + lua_insert(L, 1); + lua_call(L, top, 1); // returns unused tags table + + lua_pushcclosure(L, loadfile, 0); + lua_pushnil(L); + while (lua_next(L, -3) != 0) { - lua_pushliteral(L, "? (of type "); - lua_pushstring(L, lua_typename(L, lua_type(L, -2))); - lua_pushliteral(L, ")"); - lua_concat(L, 3); - lua_replace(L, -2); + char path[MAX_FILENAME_LEN]; + int type = nse_fetchfile_absolute(path, sizeof(path), + lua_tostring(L, -2)); + + if (type == 0) + { + lua_pushvalue(L, -2); // copy of key + lua_pushliteral(L, SCRIPT_ENGINE_EXTENSION); + lua_concat(L, 2); + lua_replace(L, -2); // remove value + type = nse_fetchfile_absolute(path, sizeof(path), lua_tostring(L, -1)); + } + + switch (type) + { + case 0: // no such path + luaL_error(L, "No such category, file or directory: '%s'", + lua_tostring(L, -2)); + case 1: // nmap_fetchfile returned a file + if (!nse_check_extension(SCRIPT_ENGINE_EXTENSION, path)) + { + error("%s: Warning: Loading '%s' - the recommended file extension is '.nse'.", + SCRIPT_ENGINE, path); + } + lua_pushvalue(L, -3); // loadfile closure + lua_pushstring(L, path); + lua_call(L, 1, 0); + break; + case 2: // nmap_fetchfile returned a dir + lua_pushcclosure(L, loaddir, 0); + lua_pushstring(L, path); + lua_call(L, 1, 0); + break; + default: + fatal("%s: In: %s:%i This should never happen.", + SCRIPT_ENGINE, __FILE__, __LINE__); + } + lua_pop(L, 1); } - lua_pushvalue(L, lua_upvalueindex(2)); - lua_concat(L, 3); - fprintf(stderr, "%s\n", lua_tostring(L, -1)); - return lua_error(L); -} -/* load an nmap-lua script - * create a new closure to store the script - * tell the closure where to find the standard - * lua libs and the nmap bindings - * we do some error checking to make sure that - * the script is well formed - * the script is then added to either the hostrules - * or the portrules - * */ -int init_loadfile(lua_State* l, char* filename) { - int rule_count; - - /* create a closure for encapsuled execution - * give the closure access to the global enviroment - */ - lua_newtable(l); - - /* tell the script about its filename */ - lua_pushstring(l, filename); - lua_setfield(l, -2, "filename"); - - /* we give the script access to the global name space - * */ - lua_newtable(l); - lua_pushvalue(l, LUA_GLOBALSINDEX); - lua_setfield(l, -2, "__index"); - lua_setmetatable(l, -2); - - /* load the *.nse file, set the closure and execute (init) the test - * */ - SCRIPT_ENGINE_LUA_TRY(luaL_loadfile(l, filename)); - lua_pushvalue(l, -2); - lua_setfenv(l, -2); - SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0)); - - /* look at the runlevel, if it is not set, we set it to 1.0 - * */ - lua_getfield(l, -1, RUNLEVEL); - if(lua_isnil(l, -1)) { - lua_pushnumber(l, 1.0); - lua_setfield(l, -3, RUNLEVEL); - } - lua_pop(l, 1); - - /* finally we make sure nobody tampers with the global name space any more - * and prepare for runlevel sorting - * */ - lua_getmetatable(l, -1); - - lua_pushliteral(l, "Attempted to change the global '"); - lua_pushliteral(l, "' in "); - lua_pushstring(l, filename); - lua_pushliteral(l, " - use nmap.registry if you really want to share " - "data between scripts."); - lua_concat(l, 3); - lua_pushcclosure(l, global_error, 2); - lua_setfield(l, -2, "__newindex"); - - lua_setmetatable(l, -2); - - /* store the initialized test in either - * the hosttests or the porttests - * */ - lua_getfield(l, -1, PORTRULE); - lua_getfield(l, -2, HOSTRULE); - - /* if we are looking at a portrule then store it in the porttestsets table - * if it is a hostrule, then it goes into the hosttestsets table - * otherwise we fail - * if there is no action in the script we also fail - * */ - if(lua_isnil(l, -2) == 0) { - lua_pop(l, 2); - lua_getglobal(l, PORTTESTS); - rule_count = lua_objlen(l, -1); - lua_pushvalue(l, -2); - lua_rawseti(l, -2, (rule_count + 1)); - lua_pop(l, 1); // pop the porttests table - } else if(lua_isnil(l, -1) == 0) { - lua_pop(l, 2); - lua_getglobal(l, HOSTTESTS); - rule_count = lua_objlen(l, -1); - lua_pushvalue(l, -2); - lua_rawseti(l, -2, (rule_count + 1)); - lua_pop(l, 1); // pop the hosttests table - } else { - error("%s: No rules in script '%s'.", SCRIPT_ENGINE, filename); - return SCRIPT_ENGINE_ERROR; - } - - std::vector required_fields; - required_fields.push_back(std::string(ACTION)); - required_fields.push_back(std::string(DESCRIPTION)); - - std::vector::iterator iter; - for(iter = required_fields.begin(); iter != required_fields.end(); iter++) { - lua_getfield(l, -1, (*iter).c_str()); - if(lua_isnil(l, -1) == 1) { - error("%s: No '%s' field in script '%s'.", SCRIPT_ENGINE, (*iter).c_str(), filename); - return SCRIPT_ENGINE_ERROR; - } - lua_pop(l, 1); // pop the action - } - - - lua_pop(l, 1); // pop the closure - - return SCRIPT_ENGINE_SUCCESS; + // Compute some stats + SCRIPT_ENGINE_DEBUGGING( + int rules_count; + + lua_getglobal(L, HOSTTESTS); + rules_count = lua_objlen(L, -1); + + lua_getglobal(L, PORTTESTS); + rules_count += lua_objlen(L, -1); + lua_pop(L, 2); + log_write(LOG_STDOUT, "%s: Initialized %d rules\n", SCRIPT_ENGINE, rules_count); + ) + return 0; } - diff --git a/nse_init.h b/nse_init.h index 83d1d4f3fc..ac9f52dcf6 100644 --- a/nse_init.h +++ b/nse_init.h @@ -13,19 +13,18 @@ extern "C" { // initialize the lua state // opens the standard libraries and the nmap lua library -int init_lua(lua_State* l); +int init_lua(lua_State* L); //takes the script arguments provided to nmap through --script-args and //processes and checks them - leaves the processed string on the stack -int init_parseargs(lua_State* l); +int init_parseargs(lua_State* L); //sets the previously parsed args inside nmap.registry -int init_setargs(lua_State* l); +int init_setargs(lua_State* L); // you give it a description of scripts to run and it // populates the tables 'hosttests' and 'porttests' in l with // activation records for tests -int init_rules(lua_State* l, std::vector chosenScripts); -int init_updatedb(lua_State* l); +int init_rules(lua_State *L); +int init_updatedb(lua_State* L); #endif - diff --git a/nse_macros.h b/nse_macros.h index 07e89d132a..e099a24793 100644 --- a/nse_macros.h +++ b/nse_macros.h @@ -32,7 +32,7 @@ #define SCRIPT_ENGINE_EXTENSION ".nse" #define SCRIPT_ENGINE_LUA_TRY(func) if (func != 0) {\ - error("LUA INTERPRETER in %s:%d: %s", __FILE__, __LINE__, (char *)lua_tostring(l, -1));\ + error("LUA INTERPRETER in %s:%d: %s", __FILE__, __LINE__, (char *)lua_tostring(L, -1));\ return SCRIPT_ENGINE_LUA_ERROR;\ } @@ -40,10 +40,11 @@ return SCRIPT_ENGINE_ERROR;\ } +#define ARRAY_LEN(a) ((int)(sizeof(a) / sizeof(a[0]))) + #define SCRIPT_ENGINE_VERBOSE(msg) if (o.debugging || o.verbose > 0) {msg}; #define SCRIPT_ENGINE_DEBUGGING(msg) if (o.debugging) {msg}; -#define MATCH 0 #define MAX_FILENAME_LEN 4096 #define NOT_PRINTABLE '.' diff --git a/nse_main.cc b/nse_main.cc index 1c04fa6d32..c6b4435cc9 100644 --- a/nse_main.cc +++ b/nse_main.cc @@ -39,7 +39,8 @@ struct thread_record { run_record* rr; }; -std::map current_hosts; +int current_hosts = 0; +int errfunc = 0; std::list > torun_scripts; std::list running_scripts; std::list waiting_scripts; @@ -53,88 +54,118 @@ class CompareRunlevels { // prior execution int process_preparerunlevels(std::list torun_threads); -int process_preparehost(lua_State* l, Target* target, std::list& torun_threads); -int process_preparethread(lua_State* l, struct run_record rr, struct thread_record* tr); +int process_preparehost(lua_State* L, Target* target, std::list& torun_threads); +int process_preparethread(lua_State* L, struct run_record rr, struct thread_record* tr); // helper functions -int process_getScriptId(lua_State* l, struct script_scan_result* ssr); +int process_getScriptId(lua_State* L, struct script_scan_result* ssr); int process_pickScriptsForPort( - lua_State* l, + lua_State* L, Target* target, Port* port, std::vector& torun); // execution -int process_mainloop(lua_State* l); -int process_waiting2running(lua_State* l, int resume_arguments); -int process_finalize(lua_State* l, unsigned int registry_idx); - -int script_updatedb() { - int status; - lua_State* l; - - SCRIPT_ENGINE_VERBOSE( - log_write(LOG_STDOUT, "%s: Updating rule database.\n", - SCRIPT_ENGINE); - ) - - l = luaL_newstate(); - if(l == NULL) { - error("%s: Failed luaL_newstate()", SCRIPT_ENGINE); - return 0; - } - - status = init_lua(l); - if(status != SCRIPT_ENGINE_SUCCESS) { - goto finishup; - } - - status = init_updatedb(l); - if(status != SCRIPT_ENGINE_SUCCESS) { - goto finishup; - } - - log_write(LOG_STDOUT, "NSE script database updated successfully.\n"); +int process_mainloop(lua_State* L); +int process_waiting2running(lua_State* L, int resume_arguments); +int process_finalize(lua_State* L, unsigned int registry_idx); + +static int panic (lua_State *L) +{ + const char *err = lua_tostring(L, 1); + fatal("Unprotected error in Lua:\n%s\n", err); + return 0; +} -finishup: - lua_close(l); - if(status != SCRIPT_ENGINE_SUCCESS) { - error("%s: Aborting database update.\n", SCRIPT_ENGINE); - return SCRIPT_ENGINE_ERROR; - } else { - return SCRIPT_ENGINE_SUCCESS; - } +int script_updatedb (void) +{ + int status; + int ret; + lua_State *L; + + SCRIPT_ENGINE_VERBOSE( + log_write(LOG_STDOUT, "%s: Updating rule database.\n", + SCRIPT_ENGINE); + ) + + L = luaL_newstate(); + if (L == NULL) + { + error("%s: Failed luaL_newstate()", SCRIPT_ENGINE); + return 0; + } + lua_atpanic(L, panic); + + status = lua_cpcall(L, init_lua, NULL); + if (status != 0) + { + error("%s: error while initializing Lua State:\n%s\n", + SCRIPT_ENGINE, lua_tostring(L, -1)); + ret = SCRIPT_ENGINE_ERROR; + goto finishup; + } + + lua_settop(L, 0); // safety, is 0 anyway + lua_rawgeti(L, LUA_REGISTRYINDEX, errfunc); // index 1 + + lua_pushcclosure(L, init_updatedb, 0); + status = lua_pcall(L, 0, 0, 1); + if(status != 0) + { + error("%s: error while updating Script Database:\n%s\n", + SCRIPT_ENGINE, lua_tostring(L, -1)); + ret = SCRIPT_ENGINE_ERROR; + goto finishup; + } + + log_write(LOG_STDOUT, "NSE script database updated successfully.\n"); + + finishup: + lua_close(L); + if (ret != SCRIPT_ENGINE_SUCCESS) + { + error("%s: Aborting database update.\n", SCRIPT_ENGINE); + return SCRIPT_ENGINE_ERROR; + } + else + return SCRIPT_ENGINE_SUCCESS; } -//int check_scripts(){ -//} /* check the script-arguments provided to nmap (--script-args) before * scanning starts - otherwise the whole scan will run through and be * aborted before script-scanning */ -int script_check_args(){ - lua_State* l; - const char *argbuf; - size_t argbuflen; - - l= luaL_newstate(); - if(l==NULL){ - fatal("Error opening lua, for checking arguments\n"); - } - /* set all global libraries (we'll need the string-lib) */ - SCRIPT_ENGINE_TRY(init_lua(l)); - SCRIPT_ENGINE_TRY(init_parseargs(l)); - lua_pushstring(l,"t={"); - lua_insert(l,-2); - lua_pushstring(l,"}"); - lua_concat(l,3); - argbuf=lua_tolstring(l,-1,&argbuflen); - luaL_loadbuffer(l,argbuf,argbuflen,"Script-Arguments-prerun"); - SCRIPT_ENGINE_TRY(lua_pcall(l,0,0,0)); - - lua_close(l); - return SCRIPT_ENGINE_SUCCESS; +int script_check_args (void) +{ + int ret = SCRIPT_ENGINE_SUCCESS, status; + lua_State* L = luaL_newstate(); + + if (L == NULL) + fatal("Error opening lua, for checking arguments\n"); + lua_atpanic(L, panic); + + /* set all global libraries (we'll need the string-lib) */ + status = lua_cpcall(L, init_lua, NULL); + if (status != 0) + { + error("%s: error while initializing Lua State:\n%s\n", + SCRIPT_ENGINE, lua_tostring(L, -1)); + ret = SCRIPT_ENGINE_ERROR; + goto finishup; + } + + lua_pushcclosure(L, init_parseargs, 0); + lua_pushstring(L, o.scriptargs); + lua_pcall(L, 1, 1, 0); + + if (!lua_isfunction(L, -1)) + ret = SCRIPT_ENGINE_ERROR; + + finishup: + lua_close(L); + return ret; } + /* open a lua instance * open the lua standard libraries * open all the scripts and prepare them for execution @@ -147,7 +178,8 @@ int script_scan(std::vector &targets) { std::list >::iterator runlevel_iter; std::list::iterator thr_iter; std::list torun_threads; - lua_State* l; + std::vector::iterator script_iter; + lua_State* L; o.current_scantype = SCRIPT_SCAN; @@ -166,34 +198,66 @@ int script_scan(std::vector &targets) { SCRIPT_ENGINE, (*targets.begin())->NameIP(targetstr, sizeof(targetstr))); ) - l = luaL_newstate(); - if(l == NULL) { + L = luaL_newstate(); + if(L == NULL) { error("%s: Failed luaL_newstate()", SCRIPT_ENGINE); - return 0; + return SCRIPT_ENGINE_ERROR; } + lua_atpanic(L, panic); - status = init_lua(l); - if(status != SCRIPT_ENGINE_SUCCESS) { - goto finishup; - } - //set the arguments - if provided - status = init_setargs(l); - if(status != SCRIPT_ENGINE_SUCCESS) { - goto finishup; - } + status = lua_cpcall(L, init_lua, NULL); + if (status != 0) + { + error("%s: error while initializing Lua State:\n%s\n", + SCRIPT_ENGINE, lua_tostring(L, -1)); + status = SCRIPT_ENGINE_ERROR; + goto finishup; + } - status = init_rules(l, o.chosenScripts); - if(status != SCRIPT_ENGINE_SUCCESS) { - goto finishup; - } + //set the arguments - if provided + status = lua_cpcall(L, init_setargs, NULL); + if (status != 0) + { + error("%s: error while setting arguments for scripts:\n%s\n", + SCRIPT_ENGINE, lua_tostring(L, -1)); + status = SCRIPT_ENGINE_ERROR; + goto finishup; + } + + lua_settop(L, 0); // safety, is 0 anyway + lua_rawgeti(L, LUA_REGISTRYINDEX, errfunc); // index 1 + + if (!lua_checkstack(L, o.chosenScripts.size() + 1)) + { + error("%s: stack overflow at %s:%d", SCRIPT_ENGINE, __FILE__, __LINE__); + status = SCRIPT_ENGINE_ERROR; + goto finishup; + } + lua_pushcclosure(L, init_rules, 0); + for (script_iter = o.chosenScripts.begin(); + script_iter != o.chosenScripts.end(); + script_iter++) + lua_pushstring(L, script_iter->c_str()); + status = lua_pcall(L, o.chosenScripts.size(), 0, 1); + if (status != 0) + { + error("%s: error while initializing script rules:\n%s\n", + SCRIPT_ENGINE, lua_tostring(L, -1)); + status = SCRIPT_ENGINE_ERROR; + goto finishup; + } SCRIPT_ENGINE_DEBUGGING(log_write(LOG_STDOUT, "%s: Matching rules.\n", SCRIPT_ENGINE);) for(target_iter = targets.begin(); target_iter != targets.end(); target_iter++) { std::string key = ((Target*) (*target_iter))->targetipstr(); - current_hosts[key] = (Target*) *target_iter; + lua_rawgeti(L, LUA_REGISTRYINDEX, current_hosts); + lua_pushstring(L, key.c_str()); + lua_pushlightuserdata(L, (void *) *target_iter); + lua_settable(L, -3); + lua_pop(L, 1); - status = process_preparehost(l, *target_iter, torun_threads); + status = process_preparehost(L, *target_iter, torun_threads); if(status != SCRIPT_ENGINE_SUCCESS){ goto finishup; } @@ -222,7 +286,7 @@ int script_scan(std::vector &targets) { if (!thr_iter->rr->host->timeOutClockRunning()) thr_iter->rr->host->startTimeOutClock(NULL); - status = process_mainloop(l); + status = process_mainloop(L); if(status != SCRIPT_ENGINE_SUCCESS){ goto finishup; } @@ -233,8 +297,7 @@ int script_scan(std::vector &targets) { SCRIPT_ENGINE_DEBUGGING( log_write(LOG_STDOUT, "%s: Script scanning completed.\n", SCRIPT_ENGINE); ) - lua_close(l); - current_hosts.clear(); + lua_close(L); torun_scripts.clear(); if(status != SCRIPT_ENGINE_SUCCESS) { error("%s: Aborting script scan.", SCRIPT_ENGINE); @@ -244,7 +307,7 @@ int script_scan(std::vector &targets) { } } -int process_mainloop(lua_State* l) { +int process_mainloop(lua_State *L) { int state; int unfinished = running_scripts.size() + waiting_scripts.size(); struct script_scan_result ssr; @@ -333,8 +396,8 @@ int process_mainloop(lua_State* l) { lua_pop(current.thread, 2); } - SCRIPT_ENGINE_TRY(process_finalize(l, current.registry_idx)); - SCRIPT_ENGINE_TRY(lua_gc(l, LUA_GCCOLLECT, 0)); + SCRIPT_ENGINE_TRY(process_finalize(L, current.registry_idx)); + SCRIPT_ENGINE_TRY(lua_gc(L, LUA_GCCOLLECT, 0)); } else { // this script returned because of an error // print the failing reason if the verbose level is high enough @@ -342,7 +405,7 @@ int process_mainloop(lua_State* l) { const char* errmsg = lua_tostring(current.thread, -1); log_write(LOG_STDOUT, "%s: %s\n", SCRIPT_ENGINE, errmsg); ) - SCRIPT_ENGINE_TRY(process_finalize(l, current.registry_idx)); + SCRIPT_ENGINE_TRY(process_finalize(L, current.registry_idx)); } } // while } @@ -368,8 +431,8 @@ int has_target_finished(Target *target) { return 1; } -int process_finalize(lua_State* l, unsigned int registry_idx) { - luaL_unref(l, LUA_REGISTRYINDEX, registry_idx); +int process_finalize(lua_State* L, unsigned int registry_idx) { + luaL_unref(L, LUA_REGISTRYINDEX, registry_idx); struct thread_record thr = running_scripts.front(); running_scripts.pop_front(); @@ -380,12 +443,12 @@ int process_finalize(lua_State* l, unsigned int registry_idx) { return SCRIPT_ENGINE_SUCCESS; } -int process_waiting2running(lua_State* l, int resume_arguments) { +int process_waiting2running(lua_State* L, int resume_arguments) { std::list::iterator iter; // find the lua state which has received i/o for( iter = waiting_scripts.begin(); - (*iter).thread != l; + (*iter).thread != L; iter++) { // It is very unlikely that a thread which @@ -417,23 +480,23 @@ int process_waiting2running(lua_State* l, int resume_arguments) { * if no 'id' field is found, the filename field is used which we set in the * setup phase. If someone changed the filename field to a nonstring we complain * */ -int process_getScriptId(lua_State* l, struct script_scan_result *ssr) { +int process_getScriptId(lua_State* L, struct script_scan_result *ssr) { - lua_getfield(l, -2, "id"); - lua_getfield(l, -3, "filename"); + lua_getfield(L, -2, "id"); + lua_getfield(L, -3, "filename"); - if(lua_isstring(l, -2)) { - ssr->id = strdup(lua_tostring (l, -2)); - } else if(lua_isstring(l, -1)) { - ssr->id = strdup(lua_tostring (l, -1)); + if(lua_isstring(L, -2)) { + ssr->id = strdup(lua_tostring (L, -2)); + } else if(lua_isstring(L, -1)) { + ssr->id = strdup(lua_tostring (L, -1)); } else { error("%s: The script has no 'id' entry, the 'filename' entry was changed to:", SCRIPT_ENGINE); - l_dumpValue(l, -1); + l_dumpValue(L, -1); return SCRIPT_ENGINE_ERROR; } - lua_pop(l, 2); + lua_pop(L, 2); return SCRIPT_ENGINE_SUCCESS; } @@ -444,7 +507,7 @@ int process_getScriptId(lua_State* l, struct script_scan_result *ssr) { * which want to run * process all scripts in the list * */ -int process_preparehost(lua_State* l, Target* target, std::list& torun_threads) { +int process_preparehost(lua_State* L, Target* target, std::list& torun_threads) { PortList* plist = &(target->ports); Port* current = NULL; size_t rules_count; @@ -455,20 +518,20 @@ int process_preparehost(lua_State* l, Target* target, std::listtargetipstr()); - lua_pop(l, 1); + lua_pop(L, 1); ) } - lua_pop(l, 2); + lua_pop(L, 2); } /* find the matching port rules * */ - lua_getglobal(l, PORTTESTS); + lua_getglobal(L, PORTTESTS); /* we only publish hostinfo once per portrule */ - lua_newtable(l); - set_hostinfo(l, target); + lua_newtable(L); + set_hostinfo(L, target); /* because of the port iteration API we need to awkwardly iterate * over the kinds of ports we're interested in explictely. * */ current = NULL; while((current = plist->nextPort(current, TCPANDUDP, PORT_OPEN)) != NULL) { - SCRIPT_ENGINE_TRY(process_pickScriptsForPort(l, target, current, torun)); + SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun)); } while((current = plist->nextPort(current, TCPANDUDP, PORT_OPENFILTERED)) != NULL) { - SCRIPT_ENGINE_TRY(process_pickScriptsForPort(l, target, current, torun)); + SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun)); } while((current = plist->nextPort(current, TCPANDUDP, PORT_UNFILTERED)) != NULL) { - SCRIPT_ENGINE_TRY(process_pickScriptsForPort(l, target, current, torun)); + SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun)); } // pop the hostinfo, we don't need it anymore - lua_pop(l, 1); + lua_pop(L, 1); /* ok, let's setup threads for the scripts which said they'd like * to run @@ -531,14 +594,14 @@ int process_preparehost(lua_State* l, Target* target, std::list torun_threads) { } /* Because we can't iterate over all ports of interest in one go - * we need to du port matching in a separate function (unlike host + * we need to do port matching in a separate function (unlike host * rule matching) * Note that we assume that at -2 on the stack we can find the portrules * and at -1 the hostinfo table * */ int process_pickScriptsForPort( - lua_State* l, + lua_State* L, Target* target, Port* port, std::vector& torun) { - size_t rules_count = lua_objlen(l, -2); + size_t rules_count = lua_objlen(L, -2); struct run_record rr; unsigned int i; for(i = 1; i <= rules_count; i++) { - lua_rawgeti(l, -2, i); + lua_rawgeti(L, -2, i); - lua_getfield(l, -1, PORTRULE); + lua_getfield(L, -1, PORTRULE); - lua_pushvalue(l, -3); + lua_pushvalue(L, -3); - lua_newtable(l); - set_portinfo(l, port); + lua_newtable(L); + set_portinfo(L, port); - SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 2, 1, 0)); + SCRIPT_ENGINE_LUA_TRY(lua_pcall(L, 2, 1, 0)); - if(lua_isboolean (l, -1) && lua_toboolean(l, -1)) { + if(lua_isboolean (L, -1) && lua_toboolean(L, -1)) { rr.type = 1; rr.index = i; rr.port = port; @@ -613,23 +676,23 @@ int process_pickScriptsForPort( torun.push_back(rr); SCRIPT_ENGINE_DEBUGGING( - lua_getfield(l, -2, "filename"); + lua_getfield(L, -2, "filename"); log_write(LOG_STDOUT, "%s: Will run %s against %s:%d\n", SCRIPT_ENGINE, - lua_tostring(l, -1), + lua_tostring(L, -1), target->targetipstr(), port->portno); - lua_pop(l, 1); + lua_pop(L, 1); ) - } else if(!lua_isboolean (l, -1)) { - lua_getfield(l, -2, "filename"); + } else if(!lua_isboolean (L, -1)) { + lua_getfield(L, -2, "filename"); error("%s: Rule in %s returned %s but boolean was expected.", SCRIPT_ENGINE, - lua_tostring(l, -1), - lua_typename(l, lua_type(l, -2))); + lua_tostring(L, -1), + lua_typename(L, lua_type(L, -2))); return SCRIPT_ENGINE_LUA_ERROR; } - lua_pop(l, 2); + lua_pop(L, 2); } return SCRIPT_ENGINE_SUCCESS; @@ -639,14 +702,14 @@ int process_pickScriptsForPort( * we store target info in the thread so that the mainloop * knows where to put the script result * */ -int process_preparethread(lua_State* l, struct run_record rr, struct thread_record* tr){ +int process_preparethread(lua_State* L, struct run_record rr, struct thread_record* tr){ - lua_State *thread = lua_newthread(l); + lua_State *thread = lua_newthread(L); - lua_rawgeti(l, -2, rr.index); // get the script closure + lua_rawgeti(L, -2, rr.index); // get the script closure // move the script closure into the thread - lua_xmove(l, thread, 1); + lua_xmove(L, thread, 1); // store the target of this thread in the thread struct run_record *rr_thread = (struct run_record*) safe_malloc(sizeof(struct run_record)); @@ -674,7 +737,7 @@ int process_preparethread(lua_State* l, struct run_record rr, struct thread_reco // we store the thread in the registry to prevent // garbage collection + - tr->registry_idx = luaL_ref(l, LUA_REGISTRYINDEX); + tr->registry_idx = luaL_ref(L, LUA_REGISTRYINDEX); /* if this is a host rule we don't have * a port state diff --git a/nse_nmaplib.cc b/nse_nmaplib.cc index 22eb8d64b2..3f33c6f99f 100644 --- a/nse_nmaplib.cc +++ b/nse_nmaplib.cc @@ -14,40 +14,41 @@ #define SCRIPT_ENGINE_GETSTRING(name) \ char* name; \ - lua_getfield(l, -1, #name); \ - if(lua_isnil(l, -1)) \ + lua_getfield(L, -1, #name); \ + if(lua_isnil(L, -1)) \ name = NULL; \ else \ - name = strdup(lua_tostring(l, -1)); \ - lua_pop(l, 1); \ + name = strdup(lua_tostring(L, -1)); \ + lua_pop(L, 1); \ #define SCRIPT_ENGINE_PUSHSTRING_NOTNULL(c_str, str) if(c_str != NULL) {\ - lua_pushstring(l, c_str); \ - lua_setfield(l, -2, str); \ + lua_pushstring(L, c_str); \ + lua_setfield(L, -2, str); \ } extern NmapOps o; -extern std::map current_hosts; +/* extern std::map current_hosts; */ +extern int current_hosts; -void set_version(lua_State* l, struct serviceDeductions sd); +void set_version(lua_State *L, struct serviceDeductions sd); -static int l_exc_newtry(lua_State *l); -static int l_port_accessor(lua_State* l); -static int l_print_debug_unformatted(lua_State *l); -static int l_get_port_state(lua_State* l, Target* target, Port* port); -static int l_set_port_state(lua_State* l, Target* target, Port* port); -static int l_set_port_version(lua_State* l, Target* target, Port* port); +static int l_exc_newtry(lua_State *L); +static int l_port_accessor(lua_State *L); +static int l_print_debug_unformatted(lua_State *L); +static int l_get_port_state(lua_State *L, Target* target, Port* port); +static int l_set_port_state(lua_State *L, Target* target, Port* port); +static int l_set_port_version(lua_State *L, Target* target, Port* port); static int l_get_verbosity(lua_State *); static int l_get_debugging(lua_State *); -static int l_get_have_ssl(lua_State *l); -static int l_fetchfile(lua_State *l); +static int l_get_have_ssl(lua_State *L); +static int l_fetchfile(lua_State *L); -int l_clock_ms(lua_State* l); +int l_clock_ms(lua_State *L); /* register the nmap lib * we assume that we can write to a table at -1 on the stack * */ -int set_nmaplib(lua_State* l) { +/* int set_nmaplib(lua_State *L) { static luaL_reg nmaplib [] = { {"get_port_state", l_port_accessor}, {"set_port_state", l_port_accessor}, @@ -67,52 +68,82 @@ int set_nmaplib(lua_State* l) { const luaL_Reg* lib; for (lib = nmaplib; lib->func; lib++) { - lua_pushcfunction(l, lib->func); - lua_setfield(l, -2, lib->name); + lua_pushcfunction(L, lib->func); + lua_setfield(L, -2, lib->name); } - lua_newtable(l); - lua_setfield(l, -2, "registry"); + lua_newtable(L); + lua_setfield(L, -2, "registry"); - SCRIPT_ENGINE_TRY(l_nsock_open(l)); - SCRIPT_ENGINE_TRY(l_dnet_open(l)); + SCRIPT_ENGINE_TRY(l_nsock_open(L)); + SCRIPT_ENGINE_TRY(l_dnet_open(L)); return SCRIPT_ENGINE_SUCCESS; +} */ + +int luaopen_nmap (lua_State *L) +{ + static luaL_reg nmaplib [] = { + {"get_port_state", l_port_accessor}, + {"set_port_state", l_port_accessor}, + {"set_port_version", l_port_accessor}, + {"new_socket", l_nsock_new}, + {"new_dnet", l_dnet_new}, + {"get_interface_link", l_dnet_get_interface_link}, + {"clock_ms", l_clock_ms}, + {"print_debug_unformatted", l_print_debug_unformatted}, + {"new_try", l_exc_newtry}, + {"verbosity", l_get_verbosity}, + {"debugging", l_get_debugging}, + {"have_ssl", l_get_have_ssl}, + {"fetchfile", l_fetchfile}, + {NULL, NULL} + }; + + luaL_register(L, "nmap", nmaplib); + + lua_newtable(L); + lua_setfield(L, -2, "registry"); + + SCRIPT_ENGINE_TRY(l_nsock_open(L)); + SCRIPT_ENGINE_TRY(l_dnet_open(L)); + + return 0; } /* set some port state information onto the * table which is currently on the stack * */ -void set_portinfo(lua_State* l, Port* port) { +void set_portinfo(lua_State *L, Port* port) { struct serviceDeductions sd; port->getServiceDeductions(&sd); - lua_pushnumber(l, (double) port->portno); - lua_setfield(l, -2, "number"); + lua_pushnumber(L, (double) port->portno); + lua_setfield(L, -2, "number"); - lua_pushstring(l, sd.name); - lua_setfield(l, -2, "service"); + lua_pushstring(L, sd.name); + lua_setfield(L, -2, "service"); - lua_pushstring(l, (port->proto == IPPROTO_TCP)? "tcp": "udp"); - lua_setfield(l, -2, "protocol"); + lua_pushstring(L, (port->proto == IPPROTO_TCP)? "tcp": "udp"); + lua_setfield(L, -2, "protocol"); - lua_newtable(l); - set_version(l, sd); - lua_setfield(l, -2, "version"); + lua_newtable(L); + set_version(L, sd); + lua_setfield(L, -2, "version"); - lua_pushstring(l, statenum2str(port->state)); - lua_setfield(l, -2, "state"); + lua_pushstring(L, statenum2str(port->state)); + lua_setfield(L, -2, "state"); - lua_pushstring(l, reason_str(port->reason.reason_id, 1)); - lua_setfield(l, -2, "reason"); + lua_pushstring(L, reason_str(port->reason.reason_id, 1)); + lua_setfield(L, -2, "reason"); } -void set_version(lua_State* l, struct serviceDeductions sd) { +void set_version(lua_State *L, struct serviceDeductions sd) { SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.name, "name"); - lua_pushnumber(l, sd.name_confidence); - lua_setfield(l, -2, "name_confidence"); + lua_pushnumber(L, sd.name_confidence); + lua_setfield(L, -2, "name_confidence"); SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.product, "product"); SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.version, "version"); @@ -169,14 +200,14 @@ void set_version(lua_State* l, struct serviceDeductions sd) { } if(sd.rpc_status == RPC_STATUS_GOOD_PROG) { - lua_pushnumber(l, sd.rpc_program); - lua_setfield(l, -2, "rpc_program"); + lua_pushnumber(L, sd.rpc_program); + lua_setfield(L, -2, "rpc_program"); - lua_pushnumber(l, sd.rpc_lowver); - lua_setfield(l, -2, "rpc_lowver"); + lua_pushnumber(L, sd.rpc_lowver); + lua_setfield(L, -2, "rpc_lowver"); - lua_pushnumber(l, sd.rpc_highver); - lua_setfield(l, -2, "rpc_highver"); + lua_pushnumber(L, sd.rpc_highver); + lua_setfield(L, -2, "rpc_highver"); } } @@ -189,47 +220,47 @@ void set_version(lua_State* l, struct serviceDeductions sd) { * if an os scan wasn't performed, the array * points to nil! * */ -void set_hostinfo(lua_State* l, Target *currenths) { +void set_hostinfo(lua_State *L, Target *currenths) { unsigned int i; char hostname[1024]; - lua_pushstring(l, strncpy(hostname, currenths->targetipstr(), 1024)); - lua_setfield(l, -2, "ip"); + lua_pushstring(L, strncpy(hostname, currenths->targetipstr(), 1024)); + lua_setfield(L, -2, "ip"); - lua_pushstring(l, strncpy(hostname, currenths->HostName(), 1024)); - lua_setfield(l, -2, "name"); + lua_pushstring(L, strncpy(hostname, currenths->HostName(), 1024)); + lua_setfield(L, -2, "name"); if ( currenths->TargetName() ) { // else nil - lua_pushstring(l, strncpy(hostname, currenths->TargetName(), 1024)); - lua_setfield(l, -2, "targetname"); + lua_pushstring(L, strncpy(hostname, currenths->TargetName(), 1024)); + lua_setfield(L, -2, "targetname"); } if(currenths->directlyConnectedOrUnset() != -1){ - lua_pushboolean(l, currenths->directlyConnected()); - lua_setfield(l, -2, "directly_connected"); + lua_pushboolean(L, currenths->directlyConnected()); + lua_setfield(L, -2, "directly_connected"); } if(currenths->MACAddress()){ // else nil - lua_pushlstring (l, (const char*)currenths->MACAddress() , 6); - lua_setfield(l, -2, "mac_addr"); + lua_pushlstring (L, (const char*)currenths->MACAddress() , 6); + lua_setfield(L, -2, "mac_addr"); } if(currenths->SrcMACAddress()){ // else nil - lua_pushlstring(l, (const char*)currenths->SrcMACAddress(), 6); - lua_setfield(l, -2, "mac_addr_src"); + lua_pushlstring(L, (const char*)currenths->SrcMACAddress(), 6); + lua_setfield(L, -2, "mac_addr_src"); } if(currenths->deviceName()){ - lua_pushstring(l, strncpy(hostname, currenths->deviceName(), 1024)); - lua_setfield(l, -2, "interface"); + lua_pushstring(L, strncpy(hostname, currenths->deviceName(), 1024)); + lua_setfield(L, -2, "interface"); } if( (u32)(currenths->v4host().s_addr) ){ struct in_addr adr = currenths->v4host(); - lua_pushlstring(l, (char*)&adr, 4); - lua_setfield(l, -2, "bin_ip"); + lua_pushlstring(L, (char*)&adr, 4); + lua_setfield(L, -2, "bin_ip"); } if( (u32)(currenths->v4source().s_addr) ){ struct in_addr adr = currenths->v4source(); - lua_pushlstring(l, (char*)&adr, 4); - lua_setfield(l, -2, "bin_ip_src"); + lua_pushlstring(L, (char*)&adr, 4); + lua_setfield(L, -2, "bin_ip_src"); } FingerPrintResults *FPR = NULL; @@ -246,22 +277,22 @@ void set_hostinfo(lua_State* l, Target *currenths) { FPR->num_perfect_matches > 0 && FPR->num_perfect_matches <= 8 ) { - lua_newtable(l); + lua_newtable(L); // this will run at least one time and at most 8 times, see if condition for(i = 0; FPR->accuracy[i] == 1; i++) { - lua_pushstring(l, FPR->prints[i]->OS_name); - lua_rawseti(l, -2, i); + lua_pushstring(L, FPR->prints[i]->OS_name); + lua_rawseti(L, -2, i); } - lua_setfield(l, -2, "os"); + lua_setfield(L, -2, "os"); } } -static int l_port_accessor(lua_State* l) { +static int l_port_accessor(lua_State *L) { int retvalues = 0; char* function_name; - char* target_ip; + const char *target_ip; int portno; int proto; @@ -270,36 +301,38 @@ static int l_port_accessor(lua_State* l) { Port* port; lua_Debug ldebug; - lua_getstack(l, 0, &ldebug); - lua_getinfo(l, "n", &ldebug); + lua_getstack(L, 0, &ldebug); + lua_getinfo(L, "n", &ldebug); function_name = strdup(ldebug.name); - luaL_checktype(l, 1, LUA_TTABLE); - luaL_checktype(l, 2, LUA_TTABLE); - - lua_getfield(l, 1, "ip"); - luaL_checktype(l, -1, LUA_TSTRING); - target_ip = strdup(lua_tostring(l, -1)); - lua_pop(l, 1); - - lua_getfield(l, 2, "number"); - luaL_checktype(l, -1, LUA_TNUMBER); - portno = lua_tointeger(l, -1); - lua_pop(l, 1); - - lua_getfield(l, 2, "protocol"); - luaL_checktype(l, -1, LUA_TSTRING); - proto = (strcmp(lua_tostring(l, -1), "tcp") == 0)? IPPROTO_TCP : IPPROTO_UDP; - lua_pop(l, 1); - - std::string key = std::string(target_ip); - std::map::iterator iter = current_hosts.find(key); - if(iter == current_hosts.end()) { - luaL_argerror (l, 1, "Host isn't being processed right now."); - return 0; - } else { - target = (Target*) iter->second; - } + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checktype(L, 2, LUA_TTABLE); + + lua_getfield(L, 1, "ip"); + luaL_checktype(L, -1, LUA_TSTRING); + target_ip = lua_tostring(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 2, "number"); + luaL_checktype(L, -1, LUA_TNUMBER); + portno = lua_tointeger(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 2, "protocol"); + luaL_checktype(L, -1, LUA_TSTRING); + proto = (strcmp(lua_tostring(L, -1), "tcp") == 0)? IPPROTO_TCP : IPPROTO_UDP; + lua_pop(L, 1); + + lua_rawgeti(L, LUA_REGISTRYINDEX, current_hosts); + lua_pushstring(L, target_ip); + lua_gettable(L, -2); + if (lua_isnil(L, -1)) + return luaL_argerror(L, 1, "Host isn't being processed right now."); + else + { + target = (Target *) lua_touserdata(L, -1); + lua_pop(L, 2); + } plist = &(target->ports); port = NULL; @@ -311,22 +344,20 @@ static int l_port_accessor(lua_State* l) { // if the port wasn't scanned we return nil if(port == NULL) { - free(target_ip); free(function_name); return 0; } - if(strcmp(function_name, "set_port_state") == MATCH) - retvalues = l_set_port_state(l, target, port); - else if(strcmp(function_name, "set_port_version") == MATCH) - retvalues = l_set_port_version(l, target, port); - else if(strcmp(function_name, "get_port_state") == MATCH) - retvalues = l_get_port_state(l, target, port); + if(strcmp(function_name, "set_port_state") == 0) + retvalues = l_set_port_state(L, target, port); + else if(strcmp(function_name, "set_port_version") == 0) + retvalues = l_set_port_version(L, target, port); + else if(strcmp(function_name, "get_port_state") == 0) + retvalues = l_get_port_state(L, target, port); // remove host and port argument from the stack - lua_remove(l, 2); - lua_remove(l, 1); - free(target_ip); + lua_remove(L, 2); + lua_remove(L, 1); free(function_name); return retvalues; } @@ -341,9 +372,9 @@ static int l_port_accessor(lua_State* l) { * this function is useful if we want rules which want to know * the state of more than one port * */ -static int l_get_port_state(lua_State* l, Target* target, Port* port) { - lua_newtable(l); - set_portinfo(l, port); +static int l_get_port_state(lua_State *L, Target* target, Port* port) { + lua_newtable(L); + set_portinfo(L, port); return 1; } @@ -352,18 +383,18 @@ static int l_get_port_state(lua_State* l, Target* target, Port* port) { * if for example a udp port was seen by the script as open instead of * filtered, the script is free to say so. * */ -static int l_set_port_state(lua_State* l, Target* target, Port* port) { +static int l_set_port_state(lua_State *L, Target* target, Port* port) { char* state; PortList* plist = &(target->ports); - luaL_checktype(l, -1, LUA_TSTRING); - state = strdup(lua_tostring(l, -1)); - lua_pop(l, 1); + luaL_checktype(L, -1, LUA_TSTRING); + state = strdup(lua_tostring(L, -1)); + lua_pop(L, 1); switch(state[0]) { case 'o': if (strcmp(state, "open")) - luaL_argerror (l, 4, "Invalid port state."); + luaL_argerror (L, 4, "Invalid port state."); if (port->state == PORT_OPEN) goto noset; plist->addPort(port->portno, port->proto, NULL, PORT_OPEN); @@ -371,14 +402,14 @@ static int l_set_port_state(lua_State* l, Target* target, Port* port) { break; case 'c': if (strcmp(state, "closed")) - luaL_argerror (l, 4, "Invalid port state."); + luaL_argerror (L, 4, "Invalid port state."); if (port->state == PORT_CLOSED) goto noset; plist->addPort(port->portno, port->proto, NULL, PORT_CLOSED); port->state = PORT_CLOSED; break; default: - luaL_argerror (l, 4, "Invalid port state."); + luaL_argerror (L, 4, "Invalid port state."); } port->reason.reason_id = ER_SCRIPT; @@ -388,15 +419,15 @@ static int l_set_port_state(lua_State* l, Target* target, Port* port) { return 0; } -static int l_set_port_version(lua_State* l, Target* target, Port* port) { - luaL_checktype(l, 3, LUA_TSTRING); - char* c_probestate = strdup(lua_tostring(l, -1)); - lua_pop(l, 1); +static int l_set_port_version(lua_State *L, Target* target, Port* port) { + luaL_checktype(L, 3, LUA_TSTRING); + char* c_probestate = strdup(lua_tostring(L, -1)); + lua_pop(L, 1); enum service_tunnel_type tunnel = SERVICE_TUNNEL_NONE; enum serviceprobestate probestate = PROBESTATE_INITIAL; - lua_getfield(l, -1, "version"); + lua_getfield(L, -1, "version"); SCRIPT_ENGINE_GETSTRING(name); SCRIPT_ENGINE_GETSTRING(product); SCRIPT_ENGINE_GETSTRING(version); @@ -414,8 +445,8 @@ static int l_set_port_version(lua_State* l, Target* target, Port* port) { else if(strcmp(service_tunnel, "ssl") == 0) tunnel = SERVICE_TUNNEL_SSL; else - luaL_argerror(l, 2, "Invalid value for port.version.service_tunnel"); - lua_pop(l, 1); + luaL_argerror(L, 2, "Invalid value for port.version.service_tunnel"); + lua_pop(L, 1); if(c_probestate == NULL) probestate = PROBESTATE_INITIAL; @@ -430,7 +461,7 @@ static int l_set_port_version(lua_State* l, Target* target, Port* port) { else if(strcmp(c_probestate, "incomplete") == 0) probestate = PROBESTATE_INCOMPLETE; else - luaL_argerror(l, 3, "Invalid value for probestate."); + luaL_argerror(L, 3, "Invalid value for probestate."); // port->setServiceProbeResults(probestate, name, // tunnel, product, version, @@ -464,33 +495,33 @@ static int l_set_port_version(lua_State* l, Target* target, Port* port) { return 0; } -static int l_print_debug_unformatted(lua_State *l) { +static int l_print_debug_unformatted(lua_State *L) { int verbosity=1; const char *out; - if (lua_gettop(l) != 2) return luaL_error(l, "Incorrect number of arguments\n"); + if (lua_gettop(L) != 2) return luaL_error(L, "Incorrect number of arguments\n"); - verbosity = luaL_checkinteger(l, 1); + verbosity = luaL_checkinteger(L, 1); if (verbosity > o.verbose) return 0; - out = luaL_checkstring(l, 2); + out = luaL_checkstring(L, 2); log_write(LOG_STDOUT, "%s DEBUG: %s\n", SCRIPT_ENGINE, out); return 0; } -static int l_exc_finalize(lua_State *l) { - if (!lua_toboolean(l, 1)) { +static int l_exc_finalize(lua_State *L) { + if (!lua_toboolean(L, 1)) { /* false or nil. */ - lua_pushvalue(l, lua_upvalueindex(1)); - lua_call(l, 0, 0); - lua_settop(l, 2); - lua_error(l); + lua_pushvalue(L, lua_upvalueindex(1)); + lua_call(L, 0, 0); + lua_settop(L, 2); + lua_error(L); return 0; - } else if(lua_isboolean(l, 1) && lua_toboolean(l, 1)) { + } else if(lua_isboolean(L, 1) && lua_toboolean(L, 1)) { /* true. */ - lua_remove(l, 1); - return lua_gettop(l); + lua_remove(L, 1); + return lua_gettop(L); } else { fatal("%s: In: %s:%i Trying to finalize a non conforming function. Are you sure you return true on success followed by the remaining return values and nil on failure followed by an error string?", SCRIPT_ENGINE, __FILE__, __LINE__); @@ -499,44 +530,44 @@ static int l_exc_finalize(lua_State *l) { } } -static int l_exc_do_nothing(lua_State *l) { - (void) l; +static int l_exc_do_nothing(lua_State *L) { + (void) L; return 0; } -static int l_exc_newtry(lua_State *l) { - lua_settop(l, 1); - if (lua_isnil(l, 1)) - lua_pushcfunction(l, l_exc_do_nothing); - lua_pushcclosure(l, l_exc_finalize, 1); +static int l_exc_newtry(lua_State *L) { + lua_settop(L, 1); + if (lua_isnil(L, 1)) + lua_pushcfunction(L, l_exc_do_nothing); + lua_pushcclosure(L, l_exc_finalize, 1); return 1; } -static int l_get_verbosity(lua_State *l) +static int l_get_verbosity(lua_State *L) { - lua_pushnumber(l, o.verbose); + lua_pushnumber(L, o.verbose); return 1; } -static int l_get_debugging(lua_State *l) +static int l_get_debugging(lua_State *L) { - lua_pushnumber(l, o.debugging); + lua_pushnumber(L, o.debugging); return 1; } -static int l_get_have_ssl(lua_State *l) { +static int l_get_have_ssl(lua_State *L) { #if HAVE_OPENSSL - lua_pushboolean(l, true); + lua_pushboolean(L, true); #else - lua_pushboolean(l, false); + lua_pushboolean(L, false); #endif return 1; } -static int l_fetchfile(lua_State *l) +static int l_fetchfile(lua_State *L) { char buf[FILENAME_MAX]; - const char *req = lua_tostring(l, -1); + const char *req = lua_tostring(L, -1); if (!req) goto err; @@ -544,12 +575,12 @@ static int l_fetchfile(lua_State *l) if (nmap_fetchfile(buf, sizeof buf, (char *) req) != 1) goto err; - lua_pop(l, 1); - lua_pushstring(l, buf); + lua_pop(L, 1); + lua_pushstring(L, buf); return 1; err: - lua_pop(l, 1); - lua_pushnil(l); + lua_pop(L, 1); + lua_pushnil(L); return 0; } diff --git a/nse_nmaplib.h b/nse_nmaplib.h index fb612448d0..bfa014460d 100644 --- a/nse_nmaplib.h +++ b/nse_nmaplib.h @@ -10,7 +10,7 @@ extern "C" { class Target; class Port; -int set_nmaplib(lua_State* l); +int luaopen_nmap(lua_State* l); void set_hostinfo(lua_State* l, Target* currenths); void set_portinfo(lua_State* l, Port* port); diff --git a/nse_nsock.cc b/nse_nsock.cc index 3ba0ed17be..23ca643aa3 100644 --- a/nse_nsock.cc +++ b/nse_nsock.cc @@ -37,24 +37,24 @@ extern NmapOps o; // defined in nse_main.cc but also declared here // to keep the .h files clean -int process_waiting2running(lua_State* l, int resume_arguments); - -static int l_nsock_connect(lua_State* l); -static int l_nsock_connect_queued(lua_State* l); -static int l_nsock_send(lua_State* l); -static int l_nsock_receive(lua_State* l); -static int l_nsock_receive_lines(lua_State* l); -static int l_nsock_receive_bytes(lua_State* l); -static int l_nsock_get_info(lua_State* l); -static int l_nsock_gc(lua_State* l); -static int l_nsock_close(lua_State* l); -static int l_nsock_set_timeout(lua_State* l); -static int l_nsock_receive_buf(lua_State* l); - -static int l_nsock_ncap_open(lua_State* l); -static int l_nsock_ncap_close(lua_State* l); -static int l_nsock_ncap_register(lua_State *l); -static int l_nsock_pcap_receive(lua_State* l); +int process_waiting2running(lua_State *L, int resume_arguments); + +static int l_nsock_connect(lua_State *L); +static int l_nsock_connect_queued(lua_State *L); +static int l_nsock_send(lua_State *L); +static int l_nsock_receive(lua_State *L); +static int l_nsock_receive_lines(lua_State *L); +static int l_nsock_receive_bytes(lua_State *L); +static int l_nsock_get_info(lua_State *L); +static int l_nsock_gc(lua_State *L); +static int l_nsock_close(lua_State *L); +static int l_nsock_set_timeout(lua_State *L); +static int l_nsock_receive_buf(lua_State *L); + +static int l_nsock_ncap_open(lua_State *L); +static int l_nsock_ncap_close(lua_State *L); +static int l_nsock_ncap_register(lua_State *L); +static int l_nsock_pcap_receive(lua_State *L); void l_nsock_connect_handler(nsock_pool nsp, nsock_event nse, void *lua_state); @@ -62,9 +62,9 @@ void l_nsock_send_handler(nsock_pool nsp, nsock_event nse, void *lua_state); void l_nsock_receive_handler(nsock_pool nsp, nsock_event nse, void *lua_state); void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_state); -int l_nsock_check_buf(lua_State* l); +int l_nsock_check_buf(lua_State *L); -int l_nsock_checkstatus(lua_State* l, nsock_event nse); +int l_nsock_checkstatus(lua_State *L, nsock_event nse); void l_nsock_trace(nsock_iod nsiod, const char* message, int direction); const char* inet_ntop_both(int af, const void* v_addr, char* ipstring); @@ -113,7 +113,7 @@ struct ncap_socket{ */ struct ncap_request{ int suspended; /* is the thread suspended? (lua_yield) */ - lua_State *l; /* lua_State of current process + lua_State *L; /* lua_State of current process * or NULL if process isn't suspended */ nsock_event_id nseid; /* nse for this specific lua_State */ struct timeval end_time; @@ -151,18 +151,18 @@ struct l_nsock_udata { int ncap_cback_ref; }; -void l_nsock_clear_buf(lua_State* l, l_nsock_udata* udata); +void l_nsock_clear_buf(lua_State *L, l_nsock_udata* udata); -int l_nsock_open(lua_State* l) { - luaL_newmetatable(l, "nsock"); - lua_createtable(l, 20, 0); - luaL_register(l, NULL, l_nsock); - lua_setfield(l, -2, "__index"); - lua_pushcclosure(l, l_nsock_gc, 0); - lua_setfield(l, -2, "__gc"); - lua_pushliteral(l, ""); - lua_setfield(l, -2, "__metatable"); // protect metatable - lua_pop(l, 1); +int l_nsock_open(lua_State *L) { + luaL_newmetatable(L, "nsock"); + lua_createtable(L, 0, 20); + luaL_register(L, NULL, l_nsock); + lua_setfield(L, -2, "__index"); + lua_pushcclosure(L, l_nsock_gc, 0); + lua_setfield(L, -2, "__gc"); + lua_pushliteral(L, ""); + lua_setfield(L, -2, "__metatable"); // protect metatable + lua_pop(L, 1); nsp = nsp_new(NULL); //nsp_settrace(nsp, o.debugging, o.getStartTime()); @@ -172,11 +172,11 @@ int l_nsock_open(lua_State* l) { return NSOCK_WRAPPER_SUCCESS; } -int l_nsock_new(lua_State* l) { +int l_nsock_new(lua_State *L) { struct l_nsock_udata* udata; - udata = (struct l_nsock_udata*) lua_newuserdata(l, sizeof(struct l_nsock_udata)); - luaL_getmetatable(l, "nsock"); - lua_setmetatable(l, -2); + udata = (struct l_nsock_udata*) lua_newuserdata(L, sizeof(struct l_nsock_udata)); + luaL_getmetatable(L, "nsock"); + lua_setmetatable(L, -2); udata->nsiod = NULL; udata->ssl_session = NULL; udata->timeout = DEFAULT_TIMEOUT; @@ -193,12 +193,12 @@ int l_nsock_loop(int tout) { return nsock_loop(nsp, tout); } -int l_nsock_checkstatus(lua_State* l, nsock_event nse) { +int l_nsock_checkstatus(lua_State *L, nsock_event nse) { enum nse_status status = nse_status(nse); switch (status) { case NSE_STATUS_SUCCESS: - lua_pushboolean(l, true); + lua_pushboolean(L, true); return NSOCK_WRAPPER_SUCCESS; break; case NSE_STATUS_ERROR: @@ -206,8 +206,8 @@ int l_nsock_checkstatus(lua_State* l, nsock_event nse) { case NSE_STATUS_CANCELLED: case NSE_STATUS_KILL: case NSE_STATUS_EOF: - lua_pushnil(l); - lua_pushstring(l, nse_status2str(status)); + lua_pushnil(L); + lua_pushstring(L, nse_status2str(status)); return NSOCK_WRAPPER_ERROR; break; case NSE_STATUS_NONE: @@ -222,7 +222,7 @@ int l_nsock_checkstatus(lua_State* l, nsock_event nse) { } -static int l_nsock_connect_queued(lua_State* l) { +static int l_nsock_connect_queued(lua_State *L) { /* We allow at least 10 even max_parallelism is 1 because a single script might open a few sockets at once and we don't want it to @@ -230,7 +230,7 @@ static int l_nsock_connect_queued(lua_State* l) { const int max_descriptors_allowed = MAX(o.max_parallelism, 10); - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); if(udata->nsiod!=NULL){ /*should a script try to connect a socket, which is already connected @@ -240,65 +240,65 @@ static int l_nsock_connect_queued(lua_State* l) { if(o.scriptTrace()){ log_write(LOG_STDOUT,"%s: Trying to connect already connected socket - closing!\n",SCRIPT_ENGINE); } - l_nsock_close(l); - lua_pop(l,1); + l_nsock_close(L); + lua_pop(L,1); } if(nsock_descriptors_used >= max_descriptors_allowed){ /* wait for free descriptor */ - nsock_connect_queue.push_back(l); + nsock_connect_queue.push_back(L); /* I must know how many arguments are passed to nsock_connect. * is there a better way? */ int arguments = 3; - const char *how = luaL_optstring(l, 4, ""); + const char *how = luaL_optstring(L, 4, ""); if(*how != '\0'){ arguments = 4; - int port = luaL_optinteger(l, 5, -1); + int port = luaL_optinteger(L, 5, -1); if(port!=-1) arguments = 5; } if(o.scriptTrace()) - log_write(LOG_STDOUT, "NSOCK_connect_queued: thread queued (%i args) %p\n", arguments, (void *)l); + log_write(LOG_STDOUT, "NSOCK_connect_queued: thread queued (%i args) %p\n", arguments, (void *)L); - return lua_yield(l, arguments); + return lua_yield(L, arguments); } - return l_nsock_connect(l); + return l_nsock_connect(L); } void l_nsock_connect_queued_handler(nsock_pool nsp, nsock_event nse, void *lua_state) { - lua_State* l = (lua_State*) lua_state; + lua_State *L = (lua_State*) lua_state; /* well, this is really hackish, we can't just do process_waiting2running, because * nsock_connect() can do lua_yield(). * Instead, we first execute nsock_connect, and if it returns lua_yield() (ie. -1) * than we don't do process_waiting2running. * So, in summary we can do two lua_yield() on thread (one in l_nsock_connect_queued, * second in l_nsock_connect). But it works for me. */ - int r = l_nsock_connect(l); + int r = l_nsock_connect(L); if(r != -1) process_waiting2running((lua_State*) lua_state, 0); } -static int l_nsock_connect(lua_State* l) { - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); - const char* addr = luaL_checkstring(l, 2); - unsigned short port = (unsigned short) luaL_checkint(l, 3); - const char *how = luaL_optstring(l, 4, "tcp"); +static int l_nsock_connect(lua_State *L) { + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); + const char* addr = luaL_checkstring(L, 2); + unsigned short port = (unsigned short) luaL_checkint(L, 3); + const char *how = luaL_optstring(L, 4, "tcp"); const char* error; struct addrinfo *dest; int error_id; - l_nsock_clear_buf(l, udata); + l_nsock_clear_buf(L, udata); error_id = getaddrinfo(addr, NULL, NULL, &dest); if (error_id) { error = gai_strerror(error_id); - lua_pushboolean(l, false); - lua_pushstring(l, error); + lua_pushboolean(L, false); + lua_pushstring(L, error); return 2; } @@ -309,23 +309,23 @@ static int l_nsock_connect(lua_State* l) { case 't': if (strcmp(how, "tcp")) goto error; nsock_connect_tcp(nsp, udata->nsiod, l_nsock_connect_handler, - udata->timeout, l, dest->ai_addr, dest->ai_addrlen, port); + udata->timeout, L, dest->ai_addr, dest->ai_addrlen, port); break; case 'u': if (strcmp(how, "udp")) goto error; nsock_connect_udp(nsp, udata->nsiod, l_nsock_connect_handler, - l, dest->ai_addr, dest->ai_addrlen, port); + L, dest->ai_addr, dest->ai_addrlen, port); break; case 's': if (strcmp(how, "ssl")) goto error; #ifdef HAVE_OPENSSL nsock_connect_ssl(nsp, udata->nsiod, l_nsock_connect_handler, - udata->timeout, l, dest->ai_addr, dest->ai_addrlen, port, + udata->timeout, L, dest->ai_addr, dest->ai_addrlen, port, udata->ssl_session); break; #else - lua_pushboolean(l, false); - lua_pushstring(l, "Sorry, you don't have OpenSSL\n"); + lua_pushboolean(L, false); + lua_pushstring(L, "Sorry, you don't have OpenSSL\n"); return 2; #endif default: @@ -334,39 +334,39 @@ static int l_nsock_connect(lua_State* l) { } freeaddrinfo(dest); - return lua_yield(l, 0); + return lua_yield(L, 0); error: freeaddrinfo(dest); - luaL_argerror(l, 4, "invalid connection method"); + luaL_argerror(L, 4, "invalid connection method"); return 0; } void l_nsock_connect_handler(nsock_pool nsp, nsock_event nse, void *lua_state) { - lua_State* l = (lua_State*) lua_state; + lua_State *L = (lua_State*) lua_state; if(o.scriptTrace()) { l_nsock_trace(nse_iod(nse), "CONNECT", TO); } - if(l_nsock_checkstatus(l, nse) == NSOCK_WRAPPER_SUCCESS) { + if(l_nsock_checkstatus(L, nse) == NSOCK_WRAPPER_SUCCESS) { process_waiting2running((lua_State*) lua_state, 1); } else { process_waiting2running((lua_State*) lua_state, 2); } } -static int l_nsock_send(lua_State* l) { - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); - const char* string = luaL_checkstring(l, 2); - size_t string_len = lua_objlen (l, 2); +static int l_nsock_send(lua_State *L) { + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); + const char* string = luaL_checkstring(L, 2); + size_t string_len = lua_objlen (L, 2); char* hexified; - l_nsock_clear_buf(l,udata); + l_nsock_clear_buf(L,udata); if(udata->nsiod == NULL) { - lua_pushboolean(l, false); - lua_pushstring(l, "Trying to send through a closed socket\n"); + lua_pushboolean(L, false); + lua_pushstring(L, "Trying to send through a closed socket\n"); return 2; } @@ -376,76 +376,76 @@ static int l_nsock_send(lua_State* l) { free(hexified); } - nsock_write(nsp, udata->nsiod, l_nsock_send_handler, udata->timeout, l, string, string_len); - return lua_yield(l, 0); + nsock_write(nsp, udata->nsiod, l_nsock_send_handler, udata->timeout, L, string, string_len); + return lua_yield(L, 0); } void l_nsock_send_handler(nsock_pool nsp, nsock_event nse, void *lua_state) { - lua_State* l = (lua_State*) lua_state; + lua_State *L = (lua_State*) lua_state; - if(l_nsock_checkstatus(l, nse) == NSOCK_WRAPPER_SUCCESS) { + if(l_nsock_checkstatus(L, nse) == NSOCK_WRAPPER_SUCCESS) { process_waiting2running((lua_State*) lua_state, 1); } else { process_waiting2running((lua_State*) lua_state, 2); } } -static int l_nsock_receive(lua_State* l) { - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); - l_nsock_clear_buf(l, udata); +static int l_nsock_receive(lua_State *L) { + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); + l_nsock_clear_buf(L, udata); if(udata->nsiod == NULL) { - lua_pushboolean(l, false); - lua_pushstring(l, "Trying to receive through a closed socket\n"); + lua_pushboolean(L, false); + lua_pushstring(L, "Trying to receive through a closed socket\n"); return 2; } - nsock_read(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, l); + nsock_read(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, L); - return lua_yield(l, 0); + return lua_yield(L, 0); } -static int l_nsock_receive_lines(lua_State* l) { - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); - int nlines = (int) luaL_checknumber(l, 2); +static int l_nsock_receive_lines(lua_State *L) { + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); + int nlines = (int) luaL_checknumber(L, 2); - l_nsock_clear_buf(l, udata); + l_nsock_clear_buf(L, udata); if(udata->nsiod == NULL) { - lua_pushboolean(l, false); - lua_pushstring(l, "Trying to receive lines through a closed socket\n"); + lua_pushboolean(L, false); + lua_pushstring(L, "Trying to receive lines through a closed socket\n"); return 2; } - nsock_readlines(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, l, nlines); + nsock_readlines(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, L, nlines); - return lua_yield(l, 0); + return lua_yield(L, 0); } -static int l_nsock_receive_bytes(lua_State* l) { - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); - int nbytes = (int) luaL_checknumber(l, 2); +static int l_nsock_receive_bytes(lua_State *L) { + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); + int nbytes = (int) luaL_checknumber(L, 2); - l_nsock_clear_buf(l, udata); + l_nsock_clear_buf(L, udata); if(udata->nsiod == NULL) { - lua_pushboolean(l, false); - lua_pushstring(l, "Trying to receive bytes through a closed socket\n"); + lua_pushboolean(L, false); + lua_pushstring(L, "Trying to receive bytes through a closed socket\n"); return 2; } - nsock_readbytes(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, l, nbytes); + nsock_readbytes(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, L, nbytes); - return lua_yield(l, 0); + return lua_yield(L, 0); } void l_nsock_receive_handler(nsock_pool nsp, nsock_event nse, void *lua_state) { - lua_State* l = (lua_State*) lua_state; + lua_State *L = (lua_State*) lua_state; char* rcvd_string; int rcvd_len = 0; char* hexified; - if(l_nsock_checkstatus(l, nse) == NSOCK_WRAPPER_SUCCESS) { + if(l_nsock_checkstatus(L, nse) == NSOCK_WRAPPER_SUCCESS) { rcvd_string = nse_readbuf(nse, &rcvd_len); if(o.scriptTrace()) { @@ -454,7 +454,7 @@ void l_nsock_receive_handler(nsock_pool nsp, nsock_event nse, void *lua_state) { free(hexified); } - lua_pushlstring(l, rcvd_string, rcvd_len); + lua_pushlstring(L, rcvd_string, rcvd_len); process_waiting2running((lua_State*) lua_state, 2); } else { process_waiting2running((lua_State*) lua_state, 2); @@ -532,8 +532,8 @@ unsigned short inet_port_both(int af, const void* v_addr) { return ntohs(port); } -static int l_nsock_get_info(lua_State* l) { - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); +static int l_nsock_get_info(lua_State *L) { + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); int status; int protocol; // tcp or udp @@ -544,50 +544,50 @@ static int l_nsock_get_info(lua_State* l) { char* ipstring_remote = (char*) safe_malloc(sizeof(char) * INET6_ADDRSTRLEN); if(udata->nsiod == NULL) { - lua_pushboolean(l, false); - lua_pushstring(l, "Trying to get info from a closed socket\n"); + lua_pushboolean(L, false); + lua_pushstring(L, "Trying to get info from a closed socket\n"); return 2; } status = nsi_getlastcommunicationinfo(udata->nsiod, &protocol, &af, &local, &remote, sizeof(sockaddr)); - lua_pushboolean(l, true); + lua_pushboolean(L, true); - lua_pushstring(l, inet_ntop_both(af, &local, ipstring_local)); - lua_pushnumber(l, inet_port_both(af, &local)); + lua_pushstring(L, inet_ntop_both(af, &local, ipstring_local)); + lua_pushnumber(L, inet_port_both(af, &local)); - lua_pushstring(l, inet_ntop_both(af, &remote, ipstring_remote)); - lua_pushnumber(l, inet_port_both(af, &remote)); + lua_pushstring(L, inet_ntop_both(af, &remote, ipstring_remote)); + lua_pushnumber(L, inet_port_both(af, &remote)); free(ipstring_local); free(ipstring_remote); return 5; } -static int l_nsock_gc(lua_State* l){ - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); +static int l_nsock_gc(lua_State *L){ + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); if(udata->nsiod == NULL) { //socket obviously got closed already - so no finalization needed return 0; }else{ //FIXME - check wheter close returned true!! - l_nsock_close(l); + l_nsock_close(L); } return 0; } -static int l_nsock_close(lua_State* l) { - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); +static int l_nsock_close(lua_State *L) { + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); /* Never ever collect nse-pcap connections. */ if(udata->ncap_socket){ return 0; } - l_nsock_clear_buf(l, udata); + l_nsock_clear_buf(L, udata); if(udata->nsiod == NULL) { - lua_pushboolean(l, false); - lua_pushstring(l, "Trying to close a closed socket\n"); + lua_pushboolean(L, false); + lua_pushstring(L, "Trying to close a closed socket\n"); return 2; } @@ -615,13 +615,13 @@ static int l_nsock_close(lua_State* l) { udata->nsiod = NULL; - lua_pushboolean(l, true); + lua_pushboolean(L, true); return 1; } -static int l_nsock_set_timeout(lua_State* l) { - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); - int timeout = (unsigned short) luaL_checkint(l, 2); +static int l_nsock_set_timeout(lua_State *L) { + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); + int timeout = (unsigned short) luaL_checkint(L, 2); udata->timeout = timeout; @@ -629,53 +629,53 @@ static int l_nsock_set_timeout(lua_State* l) { } /* buffered I/O */ -static int l_nsock_receive_buf(lua_State* l) { - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); - if(lua_gettop(l)==2){ +static int l_nsock_receive_buf(lua_State *L) { + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); + if(lua_gettop(L)==2){ /*we were called with 2 arguments only - push the default third one*/ - lua_pushboolean(l,true); + lua_pushboolean(L,true); } if(udata->nsiod == NULL) { - lua_pushboolean(l, false); - lua_pushstring(l, "Trying to receive through a closed socket\n"); + lua_pushboolean(L, false); + lua_pushstring(L, "Trying to receive through a closed socket\n"); return 2; } if(udata->bufused==0){ - lua_pushstring(l,""); - udata->bufidx = luaL_ref(l, LUA_REGISTRYINDEX); + lua_pushstring(L,""); + udata->bufidx = luaL_ref(L, LUA_REGISTRYINDEX); udata->bufused=1; - nsock_read(nsp, udata->nsiod, l_nsock_receive_buf_handler, udata->timeout, l); + nsock_read(nsp, udata->nsiod, l_nsock_receive_buf_handler, udata->timeout, L); }else if(udata->bufused==-1){ /*error message is inside the buffer*/ - lua_pushboolean(l,false); - lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); + lua_pushboolean(L,false); + lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx); return 2; }else{ /*buffer contains already some data */ /*we keep track here of how many calls to receive_buf are made */ udata->bufused++; - if(l_nsock_check_buf(l)==NSOCK_WRAPPER_BUFFER_MOREREAD){ + if(l_nsock_check_buf(L)==NSOCK_WRAPPER_BUFFER_MOREREAD){ /*if we didn't have enough data in the buffer another nsock_read() * was scheduled - its callback will put us in running state again */ - return lua_yield(l,3); + return lua_yield(L,3); } return 2; } /*yielding with 3 arguments since we need them when the callback arrives */ - return lua_yield(l, 3); + return lua_yield(L, 3); } void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_state) { - lua_State* l = (lua_State*) lua_state; + lua_State *L = (lua_State*) lua_state; char* rcvd_string; int rcvd_len = 0; char* hexified; int tmpidx; - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); - if(l_nsock_checkstatus(l, nse) == NSOCK_WRAPPER_SUCCESS) { + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); + if(l_nsock_checkstatus(L, nse) == NSOCK_WRAPPER_SUCCESS) { //l_nsock_checkstatus pushes true on the stack in case of success // we do this on our own here - lua_pop(l,1); + lua_pop(L,1); rcvd_string = nse_readbuf(nse, &rcvd_len); @@ -686,12 +686,12 @@ void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_stat } /* push the buffer and what we received from nsock on the stack and * concatenate both*/ - lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); - lua_pushlstring(l, rcvd_string, rcvd_len); - lua_concat (l, 2); - luaL_unref(l, LUA_REGISTRYINDEX, udata->bufidx); - udata->bufidx = luaL_ref(l, LUA_REGISTRYINDEX); - if(l_nsock_check_buf(l)==NSOCK_WRAPPER_BUFFER_MOREREAD){ + lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx); + lua_pushlstring(L, rcvd_string, rcvd_len); + lua_concat (L, 2); + luaL_unref(L, LUA_REGISTRYINDEX, udata->bufidx); + udata->bufidx = luaL_ref(L, LUA_REGISTRYINDEX); + if(l_nsock_check_buf(L)==NSOCK_WRAPPER_BUFFER_MOREREAD){ /*if there wasn't enough data in the buffer and we've issued another * nsock_read() the next callback will schedule the script for running */ @@ -705,12 +705,12 @@ void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_stat * and clean the buffer afterwards */ /*save the error message inside the buffer*/ - tmpidx=luaL_ref(l, LUA_REGISTRYINDEX); + tmpidx=luaL_ref(L, LUA_REGISTRYINDEX); /*pop the status (==false) of the stack*/ - lua_pop(l,1); - lua_pushboolean(l, true); - lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); - l_nsock_clear_buf(l, udata); + lua_pop(L,1); + lua_pushboolean(L, true); + lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx); + l_nsock_clear_buf(L, udata); udata->bufidx=tmpidx; udata->bufused=-1; process_waiting2running((lua_State*) lua_state, 2); @@ -720,55 +720,55 @@ void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_stat } } -int l_nsock_check_buf(lua_State* l ){ +int l_nsock_check_buf(lua_State *L ){ l_nsock_udata* udata; size_t startpos, endpos, bufsize; const char *tmpbuf; int tmpidx; int keeppattern; /*should we return the string including the pattern or without it */ - keeppattern= lua_toboolean(l,-1); - lua_pop(l,1); - udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); - if(lua_isfunction(l,2)){ - lua_pushvalue(l,2); - lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); /* the buffer is the only argument to the function */ - if(lua_pcall(l,1,2,0)!=0){ - lua_pushboolean(l,false); - lua_pushfstring(l,"Error inside splitting-function: %s\n", lua_tostring(l,-1)); + keeppattern= lua_toboolean(L,-1); + lua_pop(L,1); + udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); + if(lua_isfunction(L,2)){ + lua_pushvalue(L,2); + lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx); /* the buffer is the only argument to the function */ + if(lua_pcall(L,1,2,0)!=0){ + lua_pushboolean(L,false); + lua_pushfstring(L,"Error inside splitting-function: %s\n", lua_tostring(L,-1)); return NSOCK_WRAPPER_BUFFER_OK; - //luaL_error(l,"Error inside splitting-function, given as argument to nsockobj:receive_buf: %s\n", lua_tostring(l,-1)); + //luaL_error(L,"Error inside splitting-function, given as argument to nsockobj:receive_buf: %s\n", lua_tostring(L,-1)); } - }else if(lua_isstring(l,2)){ - lua_getglobal(l,"string"); - lua_getfield(l,-1,"find"); - lua_remove(l, -2); /*drop the string-table, since we don't need it! */ - lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); - lua_pushvalue(l,2); /*the pattern we are searching for */ - if(lua_pcall(l,2,2,0)!=0){ - lua_pushboolean(l,false); - lua_pushstring(l,"Error in string.find (nsockobj:receive_buf)!"); + }else if(lua_isstring(L,2)){ + lua_getglobal(L,"string"); + lua_getfield(L,-1,"find"); + lua_remove(L, -2); /*drop the string-table, since we don't need it! */ + lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx); + lua_pushvalue(L,2); /*the pattern we are searching for */ + if(lua_pcall(L,2,2,0)!=0){ + lua_pushboolean(L,false); + lua_pushstring(L,"Error in string.find (nsockobj:receive_buf)!"); return NSOCK_WRAPPER_BUFFER_OK; } }else{ - lua_pushboolean(l,false); - lua_pushstring(l,"Expected either a function or a string!"); + lua_pushboolean(L,false); + lua_pushstring(L,"Expected either a function or a string!"); return NSOCK_WRAPPER_BUFFER_OK; - //luaL_argerror(l,2,"expected either a function or a string!"); + //luaL_argerror(L,2,"expected either a function or a string!"); } /*the stack contains on top the indices where we want to seperate */ - if(lua_isnil(l,-1)){ /*not found anything try to read more data*/ - lua_pop(l,2); - nsock_read(nsp, udata->nsiod, l_nsock_receive_buf_handler, udata->timeout, l); - lua_pushboolean(l,keeppattern); + if(lua_isnil(L,-1)){ /*not found anything try to read more data*/ + lua_pop(L,2); + nsock_read(nsp, udata->nsiod, l_nsock_receive_buf_handler, udata->timeout, L); + lua_pushboolean(L,keeppattern); return NSOCK_WRAPPER_BUFFER_MOREREAD; }else{ - startpos = (size_t) lua_tointeger(l, -2); - endpos = (size_t) lua_tointeger(l, -1); - lua_settop(l,0); /* clear the stack for returning */ + startpos = (size_t) lua_tointeger(L, -2); + endpos = (size_t) lua_tointeger(L, -1); + lua_settop(L,0); /* clear the stack for returning */ if(startpos>endpos){ - lua_pushboolean(l,false); - lua_pushstring(l,"Delimiter has negative size!"); + lua_pushboolean(L,false); + lua_pushstring(L,"Delimiter has negative size!"); return NSOCK_WRAPPER_BUFFER_OK; }else if(startpos==endpos){ /* if the delimter has a size of zero we keep it, since otherwise @@ -776,34 +776,34 @@ int l_nsock_check_buf(lua_State* l ){ */ keeppattern=1; } - lua_settop(l,0); /* clear the stack for returning */ - lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); - tmpbuf = lua_tolstring(l, -1, &bufsize); - lua_pop(l,1); /* pop the buffer off the stack, should be safe since it + lua_settop(L,0); /* clear the stack for returning */ + lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx); + tmpbuf = lua_tolstring(L, -1, &bufsize); + lua_pop(L,1); /* pop the buffer off the stack, should be safe since it it is still in the registry */ if(tmpbuf==NULL){ fatal("%s: In: %s:%i The buffer is not a string?! - please report this to nmap-dev@insecure.org.", SCRIPT_ENGINE, __FILE__, __LINE__); } /*first push the remains of the buffer */ - lua_pushlstring(l,tmpbuf+endpos,(bufsize-endpos)); - tmpidx = luaL_ref(l,LUA_REGISTRYINDEX); - lua_pushboolean(l,true); + lua_pushlstring(L,tmpbuf+endpos,(bufsize-endpos)); + tmpidx = luaL_ref(L,LUA_REGISTRYINDEX); + lua_pushboolean(L,true); if(keeppattern){ - lua_pushlstring(l,tmpbuf,endpos); + lua_pushlstring(L,tmpbuf,endpos); }else{ - lua_pushlstring(l,tmpbuf,startpos-1); + lua_pushlstring(L,tmpbuf,startpos-1); } - luaL_unref(l,LUA_REGISTRYINDEX,udata->bufidx); + luaL_unref(L,LUA_REGISTRYINDEX,udata->bufidx); udata->bufidx=tmpidx; - //l_dumpStack(l); + //l_dumpStack(L); return NSOCK_WRAPPER_BUFFER_OK; } assert(0); return 1;//unreachable } -void l_nsock_clear_buf(lua_State* l, l_nsock_udata* udata){ - luaL_unref (l, LUA_REGISTRYINDEX, udata->bufidx); +void l_nsock_clear_buf(lua_State *L, l_nsock_udata* udata){ + luaL_unref (L, LUA_REGISTRYINDEX, udata->bufidx); udata->bufidx=LUA_NOREF; udata->bufused=0; } @@ -866,29 +866,29 @@ char *dnet_to_pcap_device_name(const char *device){ * 4) callback- callback function, that will create hash string from packet * 5) bpf - berkeley packet filter, see tcpdump(8) * */ -static int l_nsock_ncap_open(lua_State* l){ - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); - const char* device = luaL_checkstring(l, 2); - int snaplen = luaL_checkint(l, 3); - int promisc = luaL_checkint(l, 4); - luaL_checktype(l, 5, LUA_TFUNCTION); /* callback function that creates hash */ - const char* bpf = luaL_checkstring(l, 6); +static int l_nsock_ncap_open(lua_State *L){ + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); + const char* device = luaL_checkstring(L, 2); + int snaplen = luaL_checkint(L, 3); + int promisc = luaL_checkint(L, 4); + luaL_checktype(L, 5, LUA_TFUNCTION); /* callback function that creates hash */ + const char* bpf = luaL_checkstring(L, 6); if(udata->nsiod || udata->ncap_request || udata->ncap_socket) { - luaL_argerror(l, 1, "Trying to open nsock-pcap, but this connection is already opened"); + luaL_argerror(L, 1, "Trying to open nsock-pcap, but this connection is already opened"); return 0; } char *pcapdev = dnet_to_pcap_device_name(device); if(!strlen(device) || !strlen(pcapdev)) { - luaL_argerror(l, 1, "Trying to open nsock-pcap, but you're passing empty or wrong device name."); + luaL_argerror(L, 1, "Trying to open nsock-pcap, but you're passing empty or wrong device name."); return 0; } - lua_pop(l, 1); // pop bpf + lua_pop(L, 1); // pop bpf /* take func from top of stack and store it in the Registry */ - int hash_func_ref = luaL_ref(l, LUA_REGISTRYINDEX); + int hash_func_ref = luaL_ref(L, LUA_REGISTRYINDEX); /* push function on the registry-stack */ - lua_rawgeti(l, LUA_REGISTRYINDEX, hash_func_ref); + lua_rawgeti(L, LUA_REGISTRYINDEX, hash_func_ref); struct ncap_socket *ns; @@ -907,7 +907,7 @@ static int l_nsock_ncap_open(lua_State* l){ /* error messages are passed here */ char *emsg = nsock_pcap_open(nsp, ns->nsiod, pcapdev, snaplen, promisc, bpf); if(emsg){ - luaL_argerror(l, 1, emsg); + luaL_argerror(L, 1, emsg); return 0; } ncap_socket_map_set(key, ns); @@ -921,16 +921,16 @@ static int l_nsock_ncap_open(lua_State* l){ /* (LUA) Close nsock-pcap socket. * */ -static int l_nsock_ncap_close(lua_State* l){ - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); +static int l_nsock_ncap_close(lua_State *L){ + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); struct ncap_socket *ns = udata->ncap_socket; if(!udata->nsiod || !udata->ncap_socket) { - luaL_argerror(l, 1, "Trying to close nsock-pcap, but it was never opened."); + luaL_argerror(L, 1, "Trying to close nsock-pcap, but it was never opened."); return 0; } if(udata->ncap_request) { - luaL_argerror(l, 1, "Trying to close nsock-pcap, but it has active event."); + luaL_argerror(L, 1, "Trying to close nsock-pcap, but it has active event."); return 0; } @@ -946,10 +946,10 @@ static int l_nsock_ncap_close(lua_State* l){ udata->nsiod = NULL; udata->ncap_socket = NULL; - lua_unref(l, udata->ncap_cback_ref); + lua_unref(L, udata->ncap_cback_ref); udata->ncap_cback_ref = 0; - lua_pushboolean(l, true); + lua_pushboolean(L, true); return 1; } @@ -1010,19 +1010,19 @@ void ncap_request_map_add(char *key, struct ncap_request *nr){ * 1) hash - hash for packet that should be matched. or empty string if you * want to receive first packet * */ -static int l_nsock_ncap_register(lua_State *l){ - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); +static int l_nsock_ncap_register(lua_State *L){ + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); size_t testdatasz; - const char* testdata = luaL_checklstring(l, 2, &testdatasz); + const char* testdata = luaL_checklstring(L, 2, &testdatasz); struct timeval now = *nsock_gettimeofday(); if(!udata->nsiod || !udata->ncap_socket) { - luaL_argerror(l, 1, "You can't register to nsock-pcap if it wasn't opened."); + luaL_argerror(L, 1, "You can't register to nsock-pcap if it wasn't opened."); return 0; } if(udata->ncap_request){ - luaL_argerror(l, 1, "You are already registered to this socket."); + luaL_argerror(L, 1, "You are already registered to this socket."); return 0; } @@ -1033,7 +1033,7 @@ static int l_nsock_ncap_register(lua_State *l){ TIMEVAL_MSEC_ADD(nr->end_time, now, udata->timeout); nr->key = strdup(hex((char*)testdata, testdatasz)); - nr->l = l; + nr->L = L; nr->ncap_cback_ref = udata->ncap_cback_ref; /* always create new event. */ nr->nseid = nsock_pcap_read_packet(nsp, @@ -1052,14 +1052,14 @@ static int l_nsock_ncap_register(lua_State *l){ * * return values: status(true/false), capture_len/error_msg, layer2data, layer3data * */ -int l_nsock_pcap_receive(lua_State *l){ - l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock"); +int l_nsock_pcap_receive(lua_State *L){ + l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock"); if(!udata->nsiod || !udata->ncap_socket) { - luaL_argerror(l, 1, "You can't receive to nsock-pcap if it wasn't opened."); + luaL_argerror(L, 1, "You can't receive to nsock-pcap if it wasn't opened."); return 0; } if(!udata->ncap_request){ - luaL_argerror(l, 1, "You can't it's not registered"); + luaL_argerror(L, 1, "You can't it's not registered"); return 0; } @@ -1075,26 +1075,26 @@ int l_nsock_pcap_receive(lua_State *l){ /* no data yet? suspend thread */ nr->suspended = 1; - return lua_yield(l, 0); + return lua_yield(L, 0); } /* (free) excute callback function from lua script */ -char* ncap_request_do_callback(nsock_event nse, lua_State *l, int ncap_cback_ref){ +char* ncap_request_do_callback(nsock_event nse, lua_State *L, int ncap_cback_ref){ const unsigned char *l2_data, *l3_data; size_t l2_len, l3_len, packet_len; nse_readpcap(nse, &l2_data, &l2_len, &l3_data, &l3_len, &packet_len, NULL); - lua_rawgeti(l, LUA_REGISTRYINDEX, ncap_cback_ref); - lua_pushnumber(l, packet_len); - lua_pushlstring(l, (char*)l2_data, l2_len); - lua_pushlstring(l, (char*)l3_data, l3_len); + lua_rawgeti(L, LUA_REGISTRYINDEX, ncap_cback_ref); + lua_pushnumber(L, packet_len); + lua_pushlstring(L, (char*)l2_data, l2_len); + lua_pushlstring(L, (char*)l3_data, l3_len); - lua_call(l, 3, 1); + lua_call(L, 3, 1); /* get string from top of the stack*/ size_t testdatasz; - const char* testdata = lua_tolstring(l, -1, &testdatasz); - // lua_pop(l, 1);/* just in case [nope, it's not needed]*/ + const char* testdata = lua_tolstring(L, -1, &testdatasz); + // lua_pop(L, 1);/* just in case [nope, it's not needed]*/ char *key = strdup(hex((char*)testdata, testdatasz)); return key; @@ -1110,7 +1110,7 @@ void l_nsock_pcap_receive_handler(nsock_pool nsp, nsock_event nse, void *userdat switch(nse_status(nse)) { case NSE_STATUS_SUCCESS:{ - char *key = ncap_request_do_callback(nse, nr->l, nr->ncap_cback_ref); + char *key = ncap_request_do_callback(nse, nr->L, nr->ncap_cback_ref); /* processes threads that receive every packet */ this_event_restored += ncap_request_set_results(nse, ""); @@ -1221,21 +1221,21 @@ void ncap_request_set_result(nsock_event nse, struct ncap_request *nr) { /* if lua thread was suspended, restore it. If it wasn't, just return results * (push them on the stack and return) */ int ncap_restore_lua(ncap_request *nr){ - lua_State *l = nr->l; + lua_State *L = nr->L; if(nr->r_success){ - lua_pushboolean(l, true); - lua_pushnumber(l, nr->packetsz); - lua_pushlstring(l, (char*)nr->r_layer2, nr->r_layer2_len); - lua_pushlstring(l, (char*)nr->r_layer3, nr->r_layer3_len); + lua_pushboolean(L, true); + lua_pushnumber(L, nr->packetsz); + lua_pushlstring(L, (char*)nr->r_layer2, nr->r_layer2_len); + lua_pushlstring(L, (char*)nr->r_layer3, nr->r_layer3_len); }else{ - lua_pushnil(l); - lua_pushstring(l, nr->r_status); - lua_pushnil(l); - lua_pushnil(l); + lua_pushnil(L); + lua_pushstring(L, nr->r_status); + lua_pushnil(L); + lua_pushnil(L); } bool suspended = nr->suspended; - nr->l = NULL; + nr->L = NULL; nr->ncap_cback_ref = 0; /* this ref is freed in different place (on udata->ncap_cback_ref) */ if(nr->key) free(nr->key); if(nr->r_status) free(nr->r_status); @@ -1245,7 +1245,7 @@ int ncap_restore_lua(ncap_request *nr){ free(nr); if(suspended) /* lua process is suspended */ - return process_waiting2running(l, 4); + return process_waiting2running(L, 4); else /* not suspended, just pass output */ return 4; } @@ -1254,9 +1254,9 @@ int ncap_restore_lua(ncap_request *nr){ /****************** DNET ******************************************************/ -static int l_dnet_open_ethernet(lua_State* l); -static int l_dnet_close_ethernet(lua_State* l); -static int l_dnet_send_ethernet(lua_State* l); +static int l_dnet_open_ethernet(lua_State *L); +static int l_dnet_close_ethernet(lua_State *L); +static int l_dnet_send_ethernet(lua_State *L); static luaL_reg l_dnet [] = { {"ethernet_open", l_dnet_open_ethernet}, @@ -1265,14 +1265,14 @@ static luaL_reg l_dnet [] = { {NULL, NULL} }; -int l_dnet_open(lua_State* l) { - luaL_newmetatable(l, "dnet"); - lua_createtable(l, 5, 0); - luaL_register(l, NULL, l_dnet); - lua_setfield(l, -2, "__index"); - lua_pushliteral(l, ""); - lua_setfield(l, -2, "__metatable"); // protect metatable - lua_pop(l, 1); +int l_dnet_open(lua_State *L) { + luaL_newmetatable(L, "dnet"); + lua_createtable(L, 0, 5); + luaL_register(L, NULL, l_dnet); + lua_setfield(L, -2, "__index"); + lua_pushliteral(L, ""); + lua_setfield(L, -2, "__metatable"); // protect metatable + lua_pop(L, 1); return NSOCK_WRAPPER_SUCCESS; } @@ -1281,23 +1281,23 @@ struct l_dnet_udata { eth_t *eth; }; -int l_dnet_new(lua_State* l) { +int l_dnet_new(lua_State *L) { struct l_dnet_udata* udata; - udata = (struct l_dnet_udata*) lua_newuserdata(l, sizeof(struct l_dnet_udata)); - luaL_getmetatable(l, "dnet"); - lua_setmetatable(l, -2); + udata = (struct l_dnet_udata*) lua_newuserdata(L, sizeof(struct l_dnet_udata)); + luaL_getmetatable(L, "dnet"); + lua_setmetatable(L, -2); udata->interface= NULL; udata->eth = NULL; return 1; } -int l_dnet_get_interface_link(lua_State* l) { - const char* interface_name = luaL_checkstring(l, 1); +int l_dnet_get_interface_link(lua_State *L) { + const char* interface_name = luaL_checkstring(L, 1); struct interface_info *ii = getInterfaceByName((char*)interface_name); if(!ii){ - lua_pushnil(l); + lua_pushnil(L); return 1; } const char *s= NULL; @@ -1317,9 +1317,9 @@ int l_dnet_get_interface_link(lua_State* l) { break; } if(s) - lua_pushstring(l, s); + lua_pushstring(L, s); else - lua_pushnil(l); + lua_pushnil(L); return 1; } @@ -1365,13 +1365,13 @@ void ldnet_eth_close_cached(const char *device) { return; } -static int l_dnet_open_ethernet(lua_State* l){ - l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(l, 1, "dnet"); - const char* interface_name = luaL_checkstring(l, 2); +static int l_dnet_open_ethernet(lua_State *L){ + l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(L, 1, "dnet"); + const char* interface_name = luaL_checkstring(L, 2); struct interface_info *ii = getInterfaceByName((char*)interface_name); if(!ii || ii->device_type!=devt_ethernet){ - luaL_argerror(l, 2, "device is not valid ethernet interface"); + luaL_argerror(L, 2, "device is not valid ethernet interface"); return 0; } udata->interface= strdup(interface_name); @@ -1380,10 +1380,10 @@ static int l_dnet_open_ethernet(lua_State* l){ return 0; } -static int l_dnet_close_ethernet(lua_State* l){ - l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(l, 1, "dnet"); +static int l_dnet_close_ethernet(lua_State *L){ + l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(L, 1, "dnet"); if(!udata->interface || !udata->eth){ - luaL_argerror(l, 1, "dnet is not valid opened ethernet interface"); + luaL_argerror(L, 1, "dnet is not valid opened ethernet interface"); return 0; } @@ -1394,20 +1394,20 @@ static int l_dnet_close_ethernet(lua_State* l){ return 0; } -static int l_dnet_send_ethernet(lua_State* l){ - l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(l, 1, "dnet"); +static int l_dnet_send_ethernet(lua_State *L){ + l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(L, 1, "dnet"); size_t packetsz = 0; - const char* packet = luaL_checklstring(l, 2, &packetsz); + const char* packet = luaL_checklstring(L, 2, &packetsz); if(!udata->interface || !udata->eth){ - luaL_argerror(l, 1, "dnet is not valid opened ethernet interface"); + luaL_argerror(L, 1, "dnet is not valid opened ethernet interface"); return 0; } eth_send(udata->eth, packet, packetsz); return 0; } -int l_clock_ms(lua_State* l){ +int l_clock_ms(lua_State *L){ struct timeval tv; gettimeofday(&tv, NULL); // no rounding error @@ -1416,10 +1416,6 @@ int l_clock_ms(lua_State* l){ usec = tv.tv_sec*1000; usec += (int)(tv.tv_usec/1000); // make sure it's integer. - lua_pushnumber(l, usec); + lua_pushnumber(L, usec); return 1; } - - - -