From c36cf833e66c54e219313fc5cf7bd2d05708cbb6 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 5 Apr 2011 06:11:58 +0000 Subject: [PATCH] Add the nmap.get_interface and nmap.get_interface_info functions by Djalal Harouni. --- CHANGELOG | 4 +++ nse_dnet.cc | 66 ++++++++++++++++++++++++++++++++++++++++++++++ nse_dnet.h | 1 + nse_nmaplib.cc | 14 ++++++++++ nselib/nmap.luadoc | 48 +++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index a9ff7bc16..e5ebedcf1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] Added nmap.get_interface and nmap.get_interface_info functions + so scripts can access characteristics of the scanning interface. + [Djalal] + o [NSE] Added epmd-info.nse, which gets a list of Erlang node port numbers. [Toni Ruottu] diff --git a/nse_dnet.cc b/nse_dnet.cc index 7b6b69fec..1015436a6 100644 --- a/nse_dnet.cc +++ b/nse_dnet.cc @@ -47,6 +47,72 @@ LUALIB_API int l_dnet_new (lua_State *L) return 1; } +LUALIB_API int l_dnet_get_interface_info (lua_State *L) +{ + char ipstr[INET6_ADDRSTRLEN]; + struct addr src, bcast; + struct interface_info *ii = getInterfaceByName(luaL_checkstring(L, 1)); + + if (ii == NULL) { + lua_pushnil(L); + lua_pushstring(L, "failed to find interface"); + return 2; + } + + memset(ipstr, 0, INET6_ADDRSTRLEN); + memset(&src, 0, sizeof(src)); + memset(&bcast, 0, sizeof(bcast)); + lua_newtable(L); + + setsfield(L, -1, "device", ii->devfullname); + setsfield(L, -1, "shortname", ii->devname); + setnfield(L, -1, "netmask", ii->netmask_bits); + + if (ii->addr.ss_family == AF_INET) + inet_ntop(AF_INET, &((struct sockaddr_in *)&ii->addr)->sin_addr, + ipstr, INET6_ADDRSTRLEN); + else if (ii->addr.ss_family == AF_INET6) + inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&ii->addr)->sin6_addr, + ipstr, INET6_ADDRSTRLEN); + else + luaL_error(L, "unknown protocol"); + + setsfield(L, -1, "address", ipstr); + + switch (ii->device_type) { + case devt_ethernet: + setsfield(L, -1, "link", "ethernet"); + lua_pushlstring(L, (const char *) ii->mac, 6); + lua_setfield(L, -2, "mac"); + + /* calculate the broadcast address */ + if (ii->addr.ss_family == AF_INET) { + src.addr_type = ADDR_TYPE_IP; + src.addr_bits = ii->netmask_bits; + src.addr_ip = ((struct sockaddr_in *)&ii->addr)->sin_addr.s_addr; + addr_bcast(&src, &bcast); + memset(ipstr, 0, INET6_ADDRSTRLEN); + if (addr_ntop(&bcast, ipstr, INET6_ADDRSTRLEN) != NULL) + setsfield(L, -1, "broadcast", ipstr); + } + break; + case devt_loopback: + setsfield(L, -1, "link", "loopback"); + break; + case devt_p2p: + setsfield(L, -1, "link", "p2p"); + break; + case devt_other: + default: + setsfield(L, -1, "link", "other"); + } + + setsfield(L, -1, "up", (ii->device_up ? "up" : "down")); + setnfield(L, -1, "mtu", ii->mtu); + + return 1; +} + LUALIB_API int l_dnet_get_interface_link (lua_State *L) { struct interface_info *ii = getInterfaceByName(luaL_checkstring(L, 1)); diff --git a/nse_dnet.h b/nse_dnet.h index 296f8db5e..5f0a216b4 100644 --- a/nse_dnet.h +++ b/nse_dnet.h @@ -3,6 +3,7 @@ LUALIB_API int l_dnet_new (lua_State *); LUALIB_API int l_dnet_get_interface_link (lua_State *); +LUALIB_API int l_dnet_get_interface_info (lua_State *); LUALIB_API int luaopen_dnet (lua_State *L); #endif diff --git a/nse_nmaplib.cc b/nse_nmaplib.cc index a274933d7..e2d6ecb56 100644 --- a/nse_nmaplib.cc +++ b/nse_nmaplib.cc @@ -741,6 +741,18 @@ static int l_address_family(lua_State *L) return 1; } +/* return the interface name that was specified with + * the -e option + */ +static int l_get_interface (lua_State *L) +{ + if (*o.device) + lua_pushstring(L, o.device); + else + lua_pushnil(L); + return 1; +} + int luaopen_nmap (lua_State *L) { static const luaL_reg nmaplib [] = { @@ -767,6 +779,8 @@ int luaopen_nmap (lua_State *L) {"is_privileged", l_is_privileged}, {"resolve", l_resolve}, {"address_family", l_address_family}, + {"get_interface", l_get_interface}, + {"get_interface_info", l_dnet_get_interface_info}, {NULL, NULL} }; diff --git a/nselib/nmap.luadoc b/nselib/nmap.luadoc index febf28758..ca43677ca 100644 --- a/nselib/nmap.luadoc +++ b/nselib/nmap.luadoc @@ -61,6 +61,54 @@ function resolve(host, family) -- @usage local family = nmap.address_family() function address_family() +--- Returns the interface name (dnet-style) 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 "hostrule" and "portrule" scripts +-- should use the interface field of the host table: +-- host.interface. +-- +-- The result of this function can be used to get the interface information +-- table, example: nmap.get_interface_info("eth0"). +-- +-- @return A string containing the interface name (dnet-style) on +success, or a nil value on failures. +-- @usage local interface_name = nmap.get_interface() +function get_interface() + +--- Gets the interface network information. +-- +-- This function takes a dnet-style interface name and returns a table +-- containing the network information of the interface. +-- +-- @param interface_name The name of the interface. +-- @return Table containing the network information of the interface on +-- success, or nil and an error message on failures. +-- @usage local iface, err = nmap.get_interface_info("eth0") +-- +-- Keys of the returned table: +-- device The interface name, can be an interface aliase. +-- shortname A simple short name of the device. +-- netmask The netmask bits (CIDR) of the interface. +-- address The string representing the IP address assigned +-- to the interface. +-- link The string representing the hardware type of the +-- interface. Possible values are: "ethernet", +-- "loopback", "p2p" or "other". +-- mac MAC address (six-byte-long binary string) of the +-- interface if the type of the interface is "ethernet", +-- otherwise it is nil. +-- broadcast The string representing the broadcast address +-- assigned to the interface if the interface type is "ethernet" +-- and if the used address is IPv4, otherwise it is nil. +-- up The state of the interface, possible values are: +-- "up" or "down". +-- mtu The MTU size of the interface. +function get_interface_info(interface_name) + --- Searches for the specified file and returns a string containing its path if -- it is found and readable (to the process). --