Thursday, December 15, 2011

Cat with 10 Lives

Netcat - that trusty command line utility that's the "Swiss Army Knife of networking" - works very well on IPv4. Since IPv6 is getting hot now, I looked for an IPv6 capable version of netcat and there are plenty out there. The problem is that they are all for Linux based OSs. I have Windows 7. I did find ncat from Nmap.org, but it was a bit lacking in the "GAPING_SECURITY_HOLE" feature on Windows.

Some searching lead me to a Windows version of IPv6 netcat from Sphinx Software.  It was the 1.10 NT (Windows) port of netcat upgraded from IPv4 to IPv6.  Also, it was 1 revision back as the 'latest' Windows version is 1.11.  Ultimately, I wanted an address family agnostic version of netcat, one that would do both IPv4 and IPv6 and have a switch to force either version.

Since my wife was busy writing her Master's thesis and baby is in bed by 8p, I took to editing the source of both netcat and netcat6 to combine them into the ultimate IPv4/v6 capable netcat for Windows - nc64.  It was not as easy as I expected.

I'm not a C expert, but I know it enough to edit existing source code to do what I want.  I also understand socket (winsock) progamming to a degree and with the source code for an IPv4 and an IPv6 version of a small utility like netcat (just over 2000 lines with ample comments) I expected to be done in a few days.  A week and half later I finished.

What was so hard?  Upgrading an IPv4 application to support IPv4/v6 is not that easy.  All name resolution calls need to be rewritten.  In the case of netcat, it needs to be able to resolve a hostname given in the command string to an IPv4/v6 address to connect to.  The orginal netcat source code used gethostby*() functions which don't support IPv6.  I changed those to the newer get*info() calls, but of course the return structures are not the same so I needed to update those.  Worst, netcat uses a custom structure to hold the resolution information and the structure will only hold IPv4 information (netcat) or IPv6 information (netcat6).  I needed to support both.  Enter sockaddr_structure.

The sockaddr_structure can hold both IPv4 and IPv6 socket information - but the documentation and examples were very lacking. Again, not being a C expert, this was a problem for me. Once I finally got it working, I needed to comb through the entire code and replace the original accessors with the new accessors that understoood the sockaddr_storage structure.

Ultimately, the approach I took was an upgraded name resolution routine capable of IPv4 and IPv6 and one that will determine which to use if the user doesn't force a version.  Beyond that, separate connect and listen routines were ported from each of the original netcat and netcat6 sources to support IPv4 and IPv6 connectivity.

My answer isn't the most streamlined or efficient code, but it works perfectly. This experience showed how challenging upgrading existing IPv4 code for IPv6 support is. Writing a new applications to support both address families is becoming more trivial, but adding in support for IPv6 on existing applications without breaking backward compatibility is certainly a challenge.

So now, my Windows NetCat supports both IPv4 and IPv6 -> 4+6=10.

I also took the time to add a few bug fixes, incorporate some extra options usually found in Unix versions and enable multicast listener and sender features for both IPv4 and IPv6.  The compiled versions (64-bit and 32-bit) along with the source code and MinGW Makefile can be found in the software section.

1 comment :

Anonymous said...

Now that I am finished with my Masters I am going to have to go back to school and take a computer language course so I can understand your posts! :)

 

Copyright © VinsWorld. All Rights Reserved.