Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 31 Oct 2003 20:54:06 -0800
From:      "Ronald F. Guilmette" <rfg@monkeys.com>
To:        freebsd-net@freebsd.org
Subject:   Help wanted on port scanner
Message-ID:  <22763.1067662446@monkeys.com>

next in thread | raw e-mail | index | archive | help

Greetings all,

I've got a port scanner that I built with my own two little hands.
It is built on top of libpcap and also libnet.  It works just fine,
some of the time.  It's what it does the rest of the time that bothers
me.

This is a simple-minded sort of port scanner that performs essentially
the same function as nmap with the -sS option (SYN scan mode).  But
it doesn't really work all that well and I'm hoping that somebody on
this list will be able to give me a hint.

In a nutshell, the thing uses a function in libnet to manufacture
a TCP SYN packet.  Once the packet has been manufactured, I use the
`libnet_write_ip' function to send it on its way to the scan target.
Prior to any sends however, I fork off a separate process that uses
libpcap just to listen for SYN+ACK response packets.

This all works fairly well, except that it ONLY seems to work when I
insert a delay via:

        usleep(1);

after each packet sent.  Otherwise, when I do not have the inter-packet
delay in the program, a full port scan of any given target seems to finish
almost instaneously, but then -zero- ports show up as "open" on the target.

This is extremely perplexing to me.  It seems as if the underlying
sendto() call being used within the implementation of `libnet_write_ip'
is failing to block in cases where the packet to be sent cannot either
be immediately sent or else buffered in kernel memory.

Obviously if sendto() is known to never block when called for a RAW
socket, then that could explain what I am seeing... i.e. the extra
inter-packet delays that I artifically inserted (with `usleep') are
allowing the OS and the underlying hardware to ``catch up'' with my
rate of packet sending.

So now, my questions:

#1)  Is sendto() known to never block on RAW sockets?  If so, how come I
haven't ever seen it say that anywhere on any of the numerous and sundry
man pages I have been looking at?

#2)  If sendto() does not block when writing to RAW sockets, then is there
any other way for me to match the rate at which my little program calls
sendto() to the actual rate that packets can be sent out of my ethernet
card?  (I would prefer it if packets didn't just get discarded willy-nilly,
as that makes the results of the port scan dramatically less complete.)

#3)  I read that there is another way of sending out packets, i.e. just
simply writing them to the fd of the device file that is opened in some
call to `pcap_open_live'.  Would this be a better way to send packets
out of my port scanner, i.e. better than trying to use the kernel's
apparently unreliable `sendto' function to send them?

Oh yea, and by the way, for whatever it's worth, the main platform for
my scanner is FreeBSD (only up to 4.7 at the moment - will upgrade soon),
but I _really_ do need to have the scanner work on Solaris also.

Any help would be appreciated.


Regards,
rfg


P.S.  One idea that occured to me was that maybe I should use libpcap to
_listen_ for my own outgoing packets, and then only send the next one
when/if the last one has actually gotten sent out the interface.  Is
this a totally brilliant idea or (as I suspect) a totally dumb idea?

P.P.S.  If you write to me off-list and if your message bounces, please
don't feel insulted, and please DO use the contact form on my web site
(www.monkeys.com) instead.  (I have about half of the planet filtered
out at the moment.  Damn spammers!)  I'm subscribed to freebsd-net now,
so really the simplest thing would just be to reply on-list if you have
any help or hints for me.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?22763.1067662446>