--- Common communication functions for network discovery tasks like -- banner grabbing and data exchange. -- \n\n -- The functions in this module return values appropriate for use with -- exception handling via nmap.new_try(). -- \n\n -- These functions may be passed a table of options, but it's not -- required. The keys for the options table are "bytes", "lines", -- "proto", and "timeout". "bytes" sets a minimum number of bytes to -- read. "lines" does the same for lines. "proto" sets the protocol to -- communicate with, defaulting to "tcp" if not provided. "timeout" sets -- the socket timeout (see the socket function set_timeout() for -- details). -- \n\n -- If both "bytes" and "lines" are provided, "lines" takes precedence. -- If neither are given, the functions read as many bytes as possible. -- @author Kris Katterjohn 04/2008 module(... or "comm", package.seeall) -- Makes sure that opts exists and the default proto is there local initopts = function(opts) if not opts then opts = {} end if not opts.proto then opts.proto = "tcp" end return opts end -- Sets up the socket and connects to host:port local setup_connect = function(host, port, opts) if type(host) ~= "table" then host = {ip = host} end local target = host.targetname or host.ip or host.name if type(port) ~= "table" then port = {number = port} end local sock = nmap.new_socket() if opts.timeout then sock:set_timeout(opts.timeout) end local status, err = sock:connect(target, port.number, opts.proto) if not status then return status, err end -- If nothing is given, specify bytes=1 so NSE reads everything if not opts.lines and not opts.bytes then opts.bytes = 1 end return true, sock end local read = function(sock, opts) local response, status if opts.lines then status, response = sock:receive_lines(opts.lines) return status, response end status, response = sock:receive_bytes(opts.bytes) return status, response end --- This function simply connects to the specified port number on the -- specified host and returns any data received. bool is a Boolean value -- indicating success. If bool is true, then the second returned value -- is the response from the target host. If bool is false, an error -- message is returned as the second value instead of a response. -- @param host The host to connect to. -- @param port The port on the host. -- @param opts The options. See module description. -- @return bool, data get_banner = function(host, port, opts) opts = initopts(opts) local status, sock = setup_connect(host, port, opts) local ret if not status then -- sock is an error message in this case return status, sock end status, ret = read(sock, opts) sock:close() return status, ret end --- This function connects to the specified port number on the specified -- host, sends data, then waits for and returns the response, if any. -- bool is a Boolean value indicating success. If bool is true, then the -- second returned value is the response from the target host. If bool is -- false, an error message is returned as the second value instead of a -- response. -- @param host The host to connect to. -- @param port The port on the host. -- @param data The data to send initially. -- @param opts The options. See module description. -- @return bool, data exchange = function(host, port, data, opts) opts = initopts(opts) local status, sock = setup_connect(host, port, opts) local ret if not status then -- sock is an error message in this case return status, sock end status, ret = sock:send(data) if not status then sock:close() return status, ret end status, ret = read(sock, opts) sock:close() return status, ret end