summaryrefslogtreecommitdiffstats
path: root/scripts/broadcast-dhcp6-discover.nse
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/broadcast-dhcp6-discover.nse')
-rw-r--r--scripts/broadcast-dhcp6-discover.nse121
1 files changed, 121 insertions, 0 deletions
diff --git a/scripts/broadcast-dhcp6-discover.nse b/scripts/broadcast-dhcp6-discover.nse
new file mode 100644
index 0000000..71b381f
--- /dev/null
+++ b/scripts/broadcast-dhcp6-discover.nse
@@ -0,0 +1,121 @@
+local coroutine = require "coroutine"
+local dhcp6 = require "dhcp6"
+local nmap = require "nmap"
+local stdnse = require "stdnse"
+local table = require "table"
+
+description = [[
+Sends a DHCPv6 request (Solicit) to the DHCPv6 multicast address,
+parses the response, then extracts and prints the address along with
+any options returned by the server.
+
+The script requires Nmap to be run in privileged mode as it binds the socket
+to a privileged port (udp/546).
+]]
+
+---
+-- @see broadcast-dhcp-discover.nse
+-- @see dhcp-discover.nse
+--
+-- @usage
+-- nmap -6 --script broadcast-dhcp6-discover
+--
+-- @output
+-- | broadcast-dhcp6-discover:
+-- | Interface: en0
+-- | Message type: Advertise
+-- | Transaction id: 74401
+-- | Options
+-- | Client identifier: MAC: 68:AB:CD:EF:AB:CD; Time: 2012-01-24 20:36:48
+-- | Server identifier: MAC: 08:FE:DC:BA:98:76; Time: 2012-01-20 11:44:58
+-- | Non-temporary Address: 2001:db8:1:2:0:0:0:1000
+-- | DNS Servers: 2001:db8:0:0:0:0:0:35
+-- | Domain Search: example.com, sub.example.com
+-- |_ NTP Servers: 2001:db8:1111:0:0:0:0:123, 2001:db8:1111:0:0:0:0:124
+--
+
+author = "Patrik Karlsson"
+license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
+categories = {"broadcast", "safe"}
+
+
+prerule = function()
+ if not nmap.is_privileged() then
+ stdnse.verbose1("not running for lack of privileges.")
+ return false
+ end
+
+ if nmap.address_family() ~= 'inet6' then
+ stdnse.debug1("is IPv6 compatible only.")
+ return false
+ end
+ return true
+end
+
+-- Gets a list of available interfaces based on link and up filters
+--
+-- @param link string containing the link type to filter
+-- @param up string containing the interface status to filter
+-- @return result table containing the matching interfaces
+local function getInterfaces(link, up)
+ if( not(nmap.list_interfaces) ) then return end
+ local interfaces, err = nmap.list_interfaces()
+ local result
+ if ( not(err) ) then
+ for _, iface in ipairs(interfaces) do
+ if ( iface.link == link and iface.up == up ) then
+ result = result or {}
+ result[iface.device] = true
+ end
+ end
+ end
+ return result
+end
+
+local function solicit(iface, result)
+ local condvar = nmap.condvar(result)
+ local helper = dhcp6.Helper:new(iface)
+ if ( not(helper) ) then
+ condvar "signal"
+ return
+ end
+
+ local status, response = helper:solicit()
+ if ( status ) then
+ response.name=("Interface: %s"):format(iface)
+ table.insert(result, response )
+ end
+ condvar "signal"
+end
+
+action = function(host, port)
+
+ local iface = nmap.get_interface()
+ local ifs, result, threads = {}, {}, {}
+ local condvar = nmap.condvar(result)
+
+ if ( iface ) then
+ ifs[iface] = true
+ else
+ ifs = getInterfaces("ethernet", "up")
+ end
+
+ for iface in pairs(ifs) do
+ local co = stdnse.new_thread( solicit, iface, result )
+ threads[co] = true
+ end
+
+ -- wait until the probes are all done
+ repeat
+ for thread in pairs(threads) do
+ if coroutine.status(thread) == "dead" then
+ threads[thread] = nil
+ end
+ end
+ if ( next(threads) ) then
+ condvar "wait"
+ end
+ until next(threads) == nil
+
+ return stdnse.format_output(true, result)
+end