Index: nse_nmaplib.cc =================================================================== --- nse_nmaplib.cc (revision 20225) +++ nse_nmaplib.cc (working copy) @@ -17,6 +17,7 @@ #include "nmap_dns.h" #include "osscan.h" #include "protocols.h" +#include "libnetutil/netutil.h" #include "nse_nmaplib.h" #include "nse_nsock.h" @@ -807,6 +808,81 @@ return 1; } +/* return a detailed list of Nmap interfaces */ +static int l_get_interfaces (lua_State *L) +{ + int numifs = 0; + struct interface_info *iflist; + char errstr[256]; + + memset(&errstr, 0, sizeof(errstr)); + iflist = getinterfaces(&numifs, errstr, sizeof(errstr)); + + if (iflist == NULL || numifs <= 0) { + log_write(LOG_PLAIN, "INTERFACES: NONE FOUND(!)\n"); + if (o.debugging) + log_write(LOG_STDOUT, "Reason: %s\n", errstr); + + lua_pushboolean(L, false); + lua_pushfstring(L, "Failed to get interfaces: %s", errstr); + } else { + int i; + lua_pushboolean(L, true); + lua_createtable(L, numifs, 0); + + for (i = 0; i < numifs; i++) { + char mac[18]; + memset(&mac, 0, sizeof(mac)); + + lua_pushstring(L, iflist[i].devfullname); + lua_newtable(L); + + setsfield(L, -1, "dev", iflist[i].devfullname); + setsfield(L, -1, "shortname", iflist[i].devname); + setsfield(L, -1, "address", + inet_ntop_ez(&(iflist[i].addr), sizeof(iflist[i].addr))); + setnfield(L, -1, "netmask", iflist[i].netmask_bits); + + switch (iflist[i].device_type) { + case devt_ethernet: + setsfield(L, -1, "type", "ethernet"); + Snprintf(mac, sizeof(mac), + "%02X:%02X:%02X:%02X:%02X:%02X", + iflist[i].mac[0], iflist[i].mac[1], + iflist[i].mac[2], iflist[i].mac[3], + iflist[i].mac[4], iflist[i].mac[5]); + setsfield(L, -1, "mac", mac); + setsfield(L, -1, "broadcast", + inet_ntop_ez(&(iflist[i].broadaddr), + sizeof(iflist[i].broadaddr))); + break; + case devt_loopback: + setsfield(L, -1, "type", "loopback"); + break; + case devt_p2p: + setsfield(L, -1, "type", "p2p"); + break; + default: + setsfield(L, -1, "type", "other"); + } + + setsfield(L, -1, "up", (iflist[i].device_up ? "up" : "down")); + setnfield(L, -1, "mtu", iflist[i].mtu); + + lua_settable(L, -3); + } + } + return 2; +} + +/* return the interface name that was specified with + * the -e option */ +static int l_get_iface (lua_State *L) +{ + lua_pushstring(L, o.device); + return 1; +} + int luaopen_nmap (lua_State *L) { static const luaL_reg nmaplib [] = { @@ -833,6 +909,8 @@ {"is_privileged", l_is_privileged}, {"resolve", l_resolve}, {"address_family", l_address_family}, + {"get_interfaces", l_get_interfaces}, + {"get_iface", l_get_iface}, {NULL, NULL} }; Index: nselib/nmap.luadoc =================================================================== --- nselib/nmap.luadoc (revision 20225) +++ nselib/nmap.luadoc (working copy) @@ -59,6 +59,55 @@ -- @usage local family = nmap.address_family() function address_family() +--- Returns a detailed table of Nmap interfaces informations. +-- +-- @return true on success, or false on failures. +-- @return a table of Nmap interfaces on success, each interface is stored +-- in on its own table. On failures an error message is returned. +-- @usage +-- local status, iflist = nmap.get_interfaces() +-- if status then +-- for iface in pairs(iflist) do +-- ... +-- end +-- end +-- +-- iflist[iface].dev The interface name, can include alias info. +-- It has the same value of the 'iface' key. +-- iflist[iface].shortname A simple short name of the device. +-- iflist[iface].address The IP address assigned to the interface. +-- iflist[iface].netmask The netmask bits (CIDR) of the interface. +-- iflist[iface].type The Interface hardware type, possible +-- values are: "ethernet", "loopback", +-- "p2p" or "other". +-- iflist[iface].up The state of the interface, possible +-- values are: "up" or "down". +-- iflist[iface].mtu The MTU size of the interface. +-- iflist[iface].mac The Interface MAC address if the type of +-- the interface is "ethernet", otherwise it is nil. +-- iflist[iface].broadcast The Interface broadcast address if +-- the type of the interface is "ethernet", otherwise it is nil. +function get_interfaces() + +--- Returns the interface name that Nmap is using. +-- +-- For example in the pre-scanning ("prerule" scripts) phase +-- if Nmap is run with the -e eth0, then "eth0" can be +-- returned, however Nmap can return an other interface name since it +-- can determine the best interface suited for the job. +-- +-- Other "portrule" and "hostrule" scripts +-- should use the interface field of the host table: +-- host.interface. +-- The result of this function can be used to index Nmap interfaces +-- table, to get the interface informations that were returned by +-- nmap.get_interfaces() call. +-- +-- @return The interface name if the -e option was given, +-- or a nil value. +-- @usage local iface = nmap.get_iface() +function get_iface() + --- Searches for the specified file and returns a string containing its path if -- it is found and readable (to the process). --