Overview
Discovers hosts and routing information from devices running RIPv2 on the LAN. It does so by sending a RIPv2 Request command and collects the responses from all devices responding to the request.
Discovers hosts and routing information from devices running RIPv2 on the LAN. It does so by sending a RIPv2 Request command and collects the responses from all devices responding to the request.
Ports
Any
Protocols
n/a
Attribution
Nmap Project
Copy the command and adjust the target or script arguments as needed.
nmap --script broadcast-rip-discover The full script source is stored with this entry and is hidden by default to keep the page easier to scan.
local ipOps = require "ipOps"
local nmap = require "nmap"
local stdnse = require "stdnse"
local string = require "string"
local tab = require "tab"
local table = require "table"
description=[[
Discovers hosts and routing information from devices running RIPv2 on the
LAN. It does so by sending a RIPv2 Request command and collects the responses
from all devices responding to the request.
]]
---
-- @usage
-- nmap --script broadcast-rip-discover
--
-- @output
-- Pre-scan script results:
-- | broadcast-rip-discover:
-- | Discovered RIPv2 devices
-- | 10.0.200.107
-- | ip netmask nexthop metric
-- | 10.46.100.0 255.255.255.0 0.0.0.0 1
-- | 10.46.110.0 255.255.255.0 0.0.0.0 1
-- | 10.46.120.0 255.255.255.0 0.0.0.0 1
-- | 10.46.123.0 255.255.255.0 10.0.200.123 1
-- | 10.46.124.0 255.255.255.0 10.0.200.124 1
-- | 10.46.125.0 255.255.255.0 10.0.200.125 1
-- | 10.0.200.101
-- | ip netmask nexthop metric
-- |_ 0.0.0.0 0.0.0.0 10.0.200.1 1
--
-- @args broadcast-rip-discover.timeout timespec defining how long to wait for
-- a response. (default 5s)
--
-- Version 0.1
-- Created 29/10/2011 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
--
author = "Patrik Karlsson"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"broadcast", "safe"}
prerule = function() return not( nmap.address_family() == "inet6") end
RIPv2 = {
Command = {
Request = 1,
Response = 2,
},
AddressFamily = {
IP = 2,
},
-- The Request class contains functions to build a RIPv2 Request
Request = {
-- Creates a new Request instance
--
-- @param command number containing the RIPv2 Command to use
-- @return o instance of request
new = function(self, command)
local o = {
version = 2,
command = command,
domain = 0,
family = 0,
tag = 0,
address = 0,
subnet = 0,
nexthop = 0,
metric = 16
}
setmetatable(o, self)
self.__index = self
return o
end,
-- Converts the whole request to a string
__tostring = function(self)
assert(self.command, "No command was supplied")
assert(self.metric, "No metric was supplied")
assert(self.address, "No address was supplied")
local RESERVED = 0
-- RIPv2 stuff, should be 0 for RIPv1
local tag, subnet, nexthop = 0, 0, 0
local data = string.pack(">BB I2 I2 I2 I4 I4 I4 I4",
self.command, self.version, self.domain, self.family, self.tag,
self.address, self.subnet, self.nexthop, self.metric)
return data
end,
},
-- The Response class contains code needed to parse a RIPv2 response
Response = {
-- Creates a new Response instance based on raw socket data
--
-- @param data string containing the raw socket response
-- @return o Response instance
new = function(self, data)
local o = { data = data }
if ( not(data) or #data < 3 ) then
return
end
local pos, _
o.command, o.version, _, pos = string.unpack(">BBI2", data)
if ( o.command ~= RIPv2.Command.Response or o.version ~= 2 ) then
return
end
local routes = tab.new(2)
tab.addrow(routes, "ip", "netmask", "nexthop", "metric")
while( #data - pos >= 20 ) do
local family, address, metric, netmask, nexthop
family, _, address, netmask, nexthop,
metric, pos = string.unpack(">I2 I2 I4 I4 I4 I4", data, pos)
if ( family == RIPv2.AddressFamily.IP ) then
local ip = ipOps.fromdword(address)
netmask = ipOps.fromdword(netmask)
nexthop = ipOps.fromdword(nexthop)
tab.addrow(routes, ip, netmask, nexthop, metric)
end
end
if ( #routes > 1 ) then o.routes = routes end
setmetatable(o, self)
self.__index = self
return o
end,
}
}
action = function()
local timeout = stdnse.parse_timespec(stdnse.get_script_args('broadcast-rip-discover.timeout'))
timeout = (timeout or 5) * 1000
local socket = nmap.new_socket("udp")
socket:set_timeout(timeout)
local rip = RIPv2.Request:new(RIPv2.Command.Request)
local status, err = socket:sendto("224.0.0.9",
{ number = 520, protocol = "udp" },
tostring(rip))
local result = {}
repeat
local data
status, data = socket:receive()
if ( status ) then
local status, _, _, rhost, _ = socket:get_info()
local response = RIPv2.Response:new(data)
table.insert(result, rhost)
if ( response and response.routes and #response.routes > 0 ) then
--response.routes.name = "Routes"
table.insert(result, { tab.dump(response.routes) } )
end
end
until( not(status) )
if ( #result > 0 ) then
result.name = "Discovered RIPv2 devices"
end
return stdnse.format_output(true, result)
end
Discovers hosts and routing information from devices running RIPv2 on the LAN. It does so by sending a RIPv2 Request command and collects the responses from all devices responding to the request.