Nmap Development mailing list archives

Re: Nsock unconnected sockets


From: Djalal Harouni <tixxdz () gmail com>
Date: Tue, 5 Oct 2010 02:46:26 +0100

On 2010-10-03 18:03:47 -0700, David Fifield wrote:
Patrik Karlsson and I have been working on a solution to this in a
branch. The main change is the addition of a new function, nmap.setup,
that allows creating an unconnected UDP socket. With such a socket you
can receive packets from multiple addresses, and from the broadcast
address. It is used like this:

sock = nmap.new_socket()
s:setup("udp")
s:sendto("1.2.3.4", 80, "Hello world")
s:sendto("5.6.7.8", 80, "Hello world")

sock = nmap.new_socket()
s:bind(nil, 67)
s:setup("udp")
status, data = s:receive()
status, _, _, remote, remotep = s:get_info()
return string.format("\"%s\" from %s:%d", data, remote, remotep)

In other words, you use "setup" everywhere you would use "connect" for a
connected socket. The second argument to setup is the address family.
If omitted, it defaults to whatever Nmap is using; i.e., "ipv4" normally
but "ipv6" if the -6 option is used.

We've made the dhcp-discover script work without using pcap to read
replies. Patrik is also enhancing scripts to work with broadcast and
multicast sends and receives. For example, dns-service-discovery is
capable of running as a prerule and and adding the hosts that respond to
a single multicast packet.

svn co --username="guest" --password="" svn://svn.insecure.org/nmap-exp/david/nmap-unconnected

Some questions:

1. What do you think of the names nsock_setup_udp and sock:setup? The
   way to understand how it works is to know that "setup" is what you
   use instead of "connect" when you want an unconnected socket. Is
   there a name other than "setup" that conveys that better?

I think that using a name like "setsockopt" is much better, perhaps 
"set_sock_opt". This way we make sure that this function will only be
used to enable some specific behaviour on sockets, and we could make it
clear in the NSEDoc that this function is used to enable multicasting
and broadcasting. Another advantage is: from an NSE point of view,
sockets are created by the nmap.new_socket() call, so we can use
set_sock_opt to setup sockets :)

setup() => set_sock_opt("udp", ...)


This is another design suggestion, I don't know if Nsock can handle it
easily or if it will work.

Since scripts can request the list of the available network interfaces,
and after that choose which one to use based on the script arguments
and on the interface configurations (if broadcasting or multicasting is
supported, and if it is an ethernet) etc. I think that we need a design
which let us to differenciate between broadcasting and multicasting,
and to modify some of their default options.


socket:set_sock_opt(protocol, level, optname, ...)

protocol:   "udp"
level:      "socket", "inet" or "inet6" (nmap.address_family() to get it)
optname:    "broadcast", "multicast" 

* Broadcast:
sock = nmap.new_socket()
sock:set_sock_opt("udp", "socket", "broadcast")
sock:sendto("255.255.255.255", 80, "Hello world")

or get the broadcast address of the interface "eth1", which was
specified by the user as an argument, and use it to send the packet.
sock:sendto("10.1.1.255", 80, "Hello world")
sock:sendto("10.1.255.255", 80, "Hello world")


* Multicast [1]: 
sock = nmap.new_socket()

-- ttl_value: control the scope of the multicasts (more discovery).
sock:set_sock_opt("udp", "inet", "multicast", "multicast_ttl", ttl_value)

-- override the default multicast interface, by specifying the source
-- address to use, which was obtained from the user's chosen interface.
sock:set_sock_opt("udp", "inet", "multicast", "multicast_if", src_addr)


We must join a group to be able to receive multicast datagrams.
-- join a multicast group, e.g: 224.0.0.251 (Zeroconf mDNS)
-- source address: INADDR_ANY
sock:set_sock_opt("udp", "inet", "multicast",
                  "add_membership", "224.0.0.251")

-- source address obtained from the user's chosen interface.
sock:set_sock_opt("udp", "inet", "multicast",
                  "add_membership", "224.0.0.251", src_addr)

-- drop the previous group membership to terminate, or close the socket.
sock:set_sock_opt("udp", "inet", "multicast",
                  "drop_membership", "224.0.0.251", src_addr)


I didn't follow all the thread, so sorry if I'm missing something.


2. What do you think of the NSE API,
   s:setup("udp")
   s:setup("udp", "ipv4")
   s:setup("udp", "ipv6")
   We have a precedent for using "udp" as a protocol identifier. I think
   that the strings "ipv4" and "ipv6" are better than constants like
   nmap.AF_INET and nmap.AF_INET6. Another possibility would be "in" and
   "in6" but I think the ones I've chosen are easier to remember.
Like Kris I think that 'inet' and 'inet6' are better.


[1] http://www.linux.org/docs/ldp/howto/Multicast-HOWTO-6.html

-- 
tixxdz
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Current thread: