local gps = require "gps" local nmap = require "nmap" local os = require "os" local shortport = require "shortport" local stdnse = require "stdnse" description = [[ Retrieves GPS time, coordinates and speed from the GPSD network daemon. ]] --- -- @usage -- nmap -p 2947 --script gpsd-info -- -- @output -- PORT STATE SERVICE REASON -- 2947/tcp open gpsd-ng syn-ack -- | gpsd-info: -- | Time of fix: Sat Apr 14 15:54:23 2012 -- | Coordinates: 59.321685,17.886493 -- |_ Speed: - knots -- -- @args gpsd-info.timeout timespec defining how long to wait for data (default 10s) author = "Patrik Karlsson" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"discovery", "safe"} portrule = shortport.port_or_service(2947, "gpsd-ng", "tcp") local arg_timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME .. ".timeout")) arg_timeout = arg_timeout or 10 local function updateData(gpsinfo, entry) for k, v in pairs(gpsinfo) do if ( entry[k] and 0 < #tostring(entry[k]) ) then gpsinfo[k] = entry[k] end end end local function hasAllData(gpsinfo) for k, v in pairs(gpsinfo) do if ( k ~= "speed" and v == '-' ) then return false end end return true end local function fail(err) return ("\n ERROR: %s"):format(err or "") end action = function(host, port) local gpsinfo = { longitude = "-", latitude = "-", speed = "-", time = "-", date = "-", } local socket = nmap.new_socket() socket:set_timeout(1000) local status = socket:connect(host, port) if ( not(status) ) then return fail("Failed to connect to server") end -- get the banner local status, line = socket:receive_lines(1) socket:send('?WATCH={"enable":true,"nmea":true}\r\n') local start_time = os.time() repeat local entry status, line = socket:receive_buf("\r\n", false) if ( status ) then status, entry = gps.NMEA.parse(line) if ( status ) then updateData(gpsinfo, entry) end end until( os.time() - start_time > arg_timeout or hasAllData(gpsinfo) ) socket:send('?WATCH={"enable":false}\r\n') if ( not(hasAllData(gpsinfo)) ) then return end local output = { ("Time of fix: %s"):format(stdnse.format_timestamp(gps.Util.convertTime(gpsinfo.date, gpsinfo.time))), ("Coordinates: %.4f,%.4f"):format(tonumber(gpsinfo.latitude), tonumber(gpsinfo.longitude)), ("Speed: %s knots"):format(gpsinfo.speed) } return stdnse.format_output(true, output) end