diff --git a/CHANGELOG b/CHANGELOG index 0201daa52..31488fb7e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,14 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] Added the nmap.resolve() function which takes a host name and + optionally an address family (such as "inet") and returns a table + containing all of its matching addresses. If no address family is + specified, then all of the addresses are returned for the name. [Kris] + +o [NSE] Added the nmap.address_family() function which returns the address + family Nmap is using as a string (e.g., "inet6" is returned if Nmap is + called with the -6 option). [Kris] + o [NSE] Added the path-mtu script to perform Path MTU Discovery to the target host using TCP or UDP. The script tries to conserve bandwidth and time by starting with the outgoing interface's MTU and properly handling diff --git a/nse_nmaplib.cc b/nse_nmaplib.cc index edba40cab..e108e0994 100644 --- a/nse_nmaplib.cc +++ b/nse_nmaplib.cc @@ -676,6 +676,59 @@ static int l_is_privileged(lua_State *L) return 1; } +/* Takes a host and optional address family and returns a table of + * addresses + */ +static int l_resolve(lua_State *L) +{ + static const char *fam_op[] = { "inet", "inet6", "unspec", NULL }; + static const int fams[] = { AF_INET, AF_INET6, AF_UNSPEC }; + struct sockaddr_storage ss; + struct addrinfo *addr, *addrs; + int i; + char *host; + int af = fams[luaL_checkoption(L, 2, "unspec", fam_op)]; + + if (!lua_isstring(L, 1)) + luaL_error(L, "Host to resolve must be a string"); + host = (char *) lua_tostring(L, 1); + + addrs = resolve_all(host, af); + + if (!addrs) { + lua_pushboolean(L, false); + lua_pushstring(L, "Failed to resolve"); + return 2; + } + + lua_pushboolean(L, true); + + lua_newtable(L); + + for (addr = addrs, i = 1; addr != NULL; addr = addr->ai_next) { + if (af != AF_UNSPEC && addr->ai_family != af) + continue; + if (addr->ai_addrlen > sizeof(ss)) + continue; + memcpy(&ss, addr->ai_addr, addr->ai_addrlen); + lua_pushstring(L, inet_socktop(&ss)); + lua_rawseti(L, -2, i++); + } + + freeaddrinfo(addrs); + + return 2; +} + +static int l_address_family(lua_State *L) +{ + if (o.af() == AF_INET) + lua_pushstring(L, "inet"); + else + lua_pushstring(L, "inet6"); + return 1; +} + int luaopen_nmap (lua_State *L) { static const luaL_reg nmaplib [] = { @@ -698,6 +751,8 @@ int luaopen_nmap (lua_State *L) {"timing_level", l_get_timing_level}, {"get_dns_servers", l_get_dns_servers}, {"is_privileged", l_is_privileged}, + {"resolve", l_resolve}, + {"address_family", l_address_family}, {NULL, NULL} }; diff --git a/nselib/nmap.luadoc b/nselib/nmap.luadoc index 5d7dfb837..7925af3f7 100644 --- a/nselib/nmap.luadoc +++ b/nselib/nmap.luadoc @@ -37,6 +37,28 @@ function verbosity() -- @return True if Nmap is running privileged, false otherwise. function is_privileged() +--- Resolves the specified host name using the optional address family and +-- returns a table containing all of the matching addresses. +-- +-- If no address family is given, resolve() will return all addresses for the +-- name. +-- +-- @param host Host name to resolve +-- @param family Address family string (such as "inet") to specify the type +-- of addresses returned +-- @see address_family +-- @return Table containing addresses resolved from the host name +-- @usage local t = nmap.resolve("www.kame.net", nmap.address_family()) +function resolve(host, family) + +--- Returns the address family Nmap is using. +-- +-- For example, if Nmap is run with the -6 option, then "inet6" is returned. +-- +-- @return The address family as a string ("inet" or "inet6") +-- @usage local family = nmap.address_family() +function address_family() + --- Searches for the specified file and returns a string containing its path if -- it is found and readable (to the process). --