Net(work) Str(ings)

release ¦ build ¦ ex: tcp/arp dump ¦ ex: passive ¦ ex: scan6 ¦ ex: scan

The netstr program sports host port scanning, tcp dump, arp traffic sniffing and passive scan capabilities while maintaining a relatively small code base. Originally it was written as only a tiny port scanner. Eventually I decided I wanted my own specifically formatted tcp packet reader plus decoder which then led to all sorts of interesting things like a kinda sorta passive scanner, a decent 6 portcheck etc. At some point (I really do not remember when) I rewrote the entire thing to use program registered and loaded modules (all in C) to make it easier to bolt on (or off) program capabilities. It is super important to note that a program module in this context is an independent program that registers with the main program and does not mean a software module which is a self contained set of functions. Because - this program has both and if one intends to work with it - one needs to really look over the code to understand how things work.

A few (not all) Features
  • ipv4 port scans with variable timers, speed hacks, a common ports list or input a range, and an isup check (bail after first successful connect).
  • Simple, but working, single port/single host ipv6 port check.
  • Fuzzy passive scanner that can countercheck inbound port connection attempts from other systems.
  • Simple tcpdump program which can also decode raw packets and accepts {pcap-expressions}.
  • Simple arpsniff program which can also decode raw packets and accepts {pcap-expressions}.

It can also be compiled to only build the scan4 & scan6 code if libpcap-dev is not installed on a platform.

  download netstr v0.19 git-hub repo

Before you hit ENTER

I really encourage reading the examples given on this web page or the manual page that ships with the source distribution. In particular heed the warnings about using passive capabilities and understand the timers.

Release Cycles

Even numbered releases have features. Odd numbered releases have bugfixes (usually caused by features...). The numbering is such that by version 1.nN I hope to have something competetively useful in the Open Sorce ecosystem.

release-0.18 and 0.19

Major changes:

  • Bugfixes in v0.19
  • Massive speed improvements for ipv4 scan on LAN & long hauls (across a continent in seconds)
  • Cleaner output and options for ipv4 scan
  • ipv4 connection software abstracted and reusable resulting in a 50% reduction in code...
  • Input bug in passive scanning fixed, there was a bug that somehow creeped in that rendered this function nearly unusable
  • ... and many more see the Changelog below ...

Full release Changelog:

version 0.18

 - The --time was improper, it was looking for -time by accident
 - Timer bugfix, if fast and a timer lower than 0.3 secons was specified
   fast would accidentally raise connects back up to 0.3 seconds.
 - Set default timeouts for passive calls to socket connections
 - Added start/stop times to scan6
 - Dropped support for subnet scanning. The way the connection software works
   makes it stupid and figuring out how to endlessly support things like
   subnetting and supernetting is a black hole. Deferred this to wrapper
 - Created an ipv4_conn software module (NOT PROGRAM MODULE) that can be used
   by multiple programs. For now passive and scan both use it.
 - Revamped the entire scanning software for ipv4. It now uses base case loops
   for strobes and ranges. The DEFAULT has changed to using a common ports
   list which is only configurable at build time. The result is better
 - Redid the timeval bits for scan and passive. The timeouts were insanely
 - Added a --fast capability which will drop to the minimum safe long haul
   timeval (routed). This adds about 20-30% performance gains on ipv4 scans.
 - Fixed a major bug in passive with options parsing, as in it wasn't doing
   them at all. I think (not sure) an old copy of the code must have been
   dumped into place and royally screwed this up.
 - Added line print which means print the ports out for v4 scans on a single
 - Gutted well over 300 lines of old garbage code that is not longer needed
 - Slapped up some prototypes in certain header files to get vim-enhanced to
   STFU and stop complaining.
 - Fixed up usage print so it is readable.
 - Documentia updates galore, like examples that work
 - isroot_uid() utility added in utils.*

Building & Usage

tar xzvf netstr-version.tgz
cd netstr-version/
make {your-platform}

Where platform is uname -s without the caps.


Usage: netstr <command> <args> ...
netstr scan     --isup <host> || --port [n]-N| | --strobe |
                --time s.usec | -V <host>
netstr scan6    --dgram | --port N <ipv6addr>
netstr passive  --if <dev> | --polls <count> | --threshold <n> |  
                --extra | --no-verify {pcap-expr}
netstr tcpdump  --if <dev> | --polls <count> | --decode {pcap-expr}
netstr arpsniff --if <dev> | --polls <count> | --decode {pcap-expr}

That is a lot to take in so I've provided examples ... lots of examples....


tcpdump & arpsniff

Using arpsniff and tcpdump operationally are the same: use pcap to dump out simple packet data about tcp/udp (in the case of tcpdump or arp traffic.) Additionally raw packet decoding is supported plus standard pcap expressions. Following is an example watching port 22:

 sudo netstr tcpdump --if eth0 --polls 3 port 22
Starting capturing engine on eth0...
Tue Feb 23 18:48:48 2016 : > \ tcp len 60 off 16384 ttl 64   \
     cksum 46613 seq 3162571457 ack 0 win 4210
Tue Feb 23 18:48:48 2016 : >  \ tcp len 60 off 16384 ttl\
       64 cksum 24759 seq 3605267132 ack 3179348673 win 36920
Tue Feb 23 18:48:48 2016 : >\ tcp len 52 off 16384 ttl 64\
       cksum 48405 seq 3179348673 ack 3622044348 win 58624
Closing capturing engine...

A few things to note: --polls n means exit after we have dumped n packets. In the above example that was 4. Also to keep from unending lines I purposely used slashes to show long lines: it does actually wrap in the console (although now I am thinking maybe a format option would be cool?)

Here is a similar command but with decoding turned on:

 sudo netstr tcpdump --decode --polls 3 
Starting capturing engine on eth0...
Tue Feb 23 18:56:17 2016 : > udp len 
31608 sum 43200 off 16384 ttl 64 cksum 31608 seq 1459467520 
ack 1313751371 win 20005
Packet RECV Size: 215 Payload:
. . . . . . . . . . . . . . E . . 
. . . & . & . x { . . . . . . . 
. . S . . . . . V K A N N O U % 
N . . . . . . . . . . . W N D R 
4 3 0 0 . . . . . . . . W N D R 
4 3 0 0 . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . 
1 . 0 2 . 0 3 . . . . . . . . . 
. . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . 
. . . . . . 
Closing capturing engine...

See that? That is my Dlink router which apparently was actually built by Wind River Systems....


Passive is a very fuzzy kind of sort of passive scanning program. Be careful when using it: sometimes other systems will push back. All sorts of interesting things can go wrong using this, however, I've always wanted one, I know people who want one so I added it. Here is a simple enough example using all the options, basically I am looking at my own login from another system:

sudo netstr passive --if eth0 --polls 64 --threshold 4 --extra port 22
Starting capturing engine on eth0...
Closing capturing engine... 22 udp  42270 udp 22 udp  34314 udp  34315 udp 

What just happened? I monitored port 22, decided I didn't want to care unless I saw more than 4 connects to a proto/port pair and will poll a total of 64 times. I saw handshaking between address .2 (mine) and .9 (another host). If I wanted to rule out my own address I can add that to the filter.

sudo netstr passive --if eth0 --polls 64 --threshold 4 --extra port 22 \
 and not host


This program, proudly, actually works. The trick is if you are doing a long haul 6 scan at it has to actually be on at either end. I was able to verify this at work across routed networks but really: your mileage WILL vary. In any case it is super straightforward and does not have a lot of bells and whistles yet:

netstr scan6 --port 22  fe80::a00:27ff:fe40:3528%eth0
Port 22 is open on fe80::a00:27ff:fe40:3528%eth0

There is a little bit of a bug and I am going to fix it during the next patch cycle (that means sometime in the next 6-8 months) if an address cannot be reached the program will hang. For instance, a closed port isn't a problem on a host that can be resolved (which also means we can see it):

netstr scan6 --port 23  fe80::a00:27ff:fe40:3528%eth0
Was able to resolve fe80::a00:27ff:fe40:3528%eth0 \
  but could not connect to port 23

The fix is to use the built in shell timeout or the time out wrapper command.


Someday this will be known as scan4 and scan will default to ipv6.... someday. In the meantime, this is what we got. The scan can do a few cool things like exit as soon as it finds an open port:

netstr scan --isup is up

If a host does not have open ports it won't print anything at all. It can also strobe ports 1-1024 in order, do a port range or if the default is used, a predefined portlist with a 0 terminator defined in prog.h, regardless the output generally looks the same but the default mode (which will not look for certain ports) is the fastest without adding the --fast option. Here are two examples one that uses a range and one default:

$ time ./netstr scan --port 22-112
22    ssh                           
37    time                          

real    0m0.053s
user    0m0.000s
sys     0m0.008s
$ time /netstr scan
22    ssh                           
37    time                          
113   auth                          

real    0m0.023s
user    0m0.000s
sys     0m0.008s

Although the timing in this example is small, imagine looping through an entire subnet or going across a continent (which we will get to later...) A single port is also supported:

$ netstr scan  --port 22
22    ssh 
Scan Timers

Some hosts don't need a whole lot of time to answer while others do. What I did manage to figure out was once a connection could be established with one port, I could ratchet down the default port connect timeout to about 300,000 usecs or 0.3 seconds if I wanted to. The --fast option does this. Here is an example with -V which prints the start and stop times.

without autoadjust:

$ netstr scan -V
Timeout: 0.500000
Scan start: Tue Feb 23 19:48:12 2016
22    ssh                           
80    http                          
Scan end  : Tue Feb 23 19:48:22 2016

with autoadjust:

$ netstr scan -V --fast
Timeout: 0.500000
Scan start: Tue Feb 23 19:48:27 2016
22    ssh                           
80    http                          
Scan end  : Tue Feb 23 19:48:33 2016

Roughly a 30% performance boost. Note that this option isn't all that fantastic for LANs and really only helps when one is, well crossing a continent. To the human eye not much of a difference but to the network and computer the speed improvement is a lot.


This is a lot of stuff. I am actually thinking about writing a full on sepearate guide for this program. The manual page for it is pretty good too and I recommend reading it to try other interesting things. The code is licensed, please DO READ the license if you wish to modify the code or use it somewhere else.