Tracking down those connections

Locating IP addresses

ip map paul fenwick
flickr / Paul Fenwick (Creative Commons BY or BY-SA)

Whether you're looking at firewall logs or connections to your web servers, one interesting question that you might just be asking yourself is "Where are all these connectins coming from?". There are plenty of web sites that can help you pinpoint the location of an IP address, but this isn't necessarily covenient if you want to track down 7,342 of them. Well, happily for those of us who sometimes need to evaluate where connections are coming from, there are some easy, fairly efficient, and inexpensive options.

One way to get geolocation information for your visitors (of the welcome or the unwelcome variety) is to try a reverse lookup of the addresses but, alas, almost none of the addresses that you're like to be curious about will be set up with PTR (pointer) records. Another option is to map the address to a range of IPs that has a known location. To do this, you might consider acquiring extensive information on IP address ranges from an organization such as IP2location. This kind of data can pinpoint IP addresses not just to particular countries, but to states, cities, zipcodes, latitude/longitude values, etc.

IP2Location claims to be supporting IP address lookups for 249 countries (as recognized in ISO 3166) with 99.5% accuracy at the country level detection and greater than 75% of accuracy in city level. I don't know what other organizations might provide this kind of data as well, but I found the data quite easy to understand and use.

My sample data looks like this:

"851712432","851712495","US","UNITED STATES","OREGON","PORTLAND"
"851718216","851718223","US","UNITED STATES","PENNSYLVANIA", "HATFIELD"

This particular database service level obviously goes down to the country/state/city level. But what hit me right away was how accessible it is. Those really big numbers that you see are just IPv4 addresses expressed as decimal numbers. The conversion from IPv4 to decimal and back again isn't all that difficult and there are probably plenty of tools available to do this kind of conversion, but I wanted to think through the process on my own. So, I started out with this Perl syntax to convert an IPv4 address into its decimal equivalent.

my @octets=split /\./, $IP;
$decIP=$octets[3] + $octets[2]*256 + $octets[1]*256*256 + $octets[0]*256*256*256;
print "$decIP\n";

What we're doing here is simply taking each byte in the IPv4 address and evaluating its decimal value. First we split on the IP address, sticking the four octets into an array. Then, starting with the rightmost octet (the lowest level) byte, we add each byte's value to the $decIP variable. Sure, I could have used used 65536 instead of 256*256 and 16777216 instead of 256*256*256 to save Perl from having to multiply for me, but I like the look of this for making it so obvious what we're doing and why.

Here's an example converting the loopback address:

$ convertIP2Dec

To do the reverse, we could take the decimal representation of an IP address and figure out the size of each octet. Here we start with the highest value octet and figure out how much it contributes to the decimal value by dividing the full decimal value by 16777216 (256*256*256) and then rounding down the result. Then we figure what's left of the original value and move to the processing next smaller octet.

#!/bin/perl -w


print "decimal IP> ";
chomp ($decIP = <STDIN>);

$p4=$decIP / $octet4;
$rounded = int($p4);

$p3=$decIP / $octet3;
$rounded = int($p3);
$IP=$IP . ".$rounded";

$p2=$decIP / $octet2;
$rounded = int($p2);
$IP=$IP . ".$rounded";

$IP=$IP . ".$decIP";
print "$IP\n";

Trying the address shown above for Hatfield, PA above, we get this:

$ convertDec2IP
decimal IP> 851718216

Once you have your converters ready, you can take an IP that you're wondering about and find where it fits in the IP2location listing. In the script below, we're calculating the decimal version of an IP address entered as an argument and then running through the IP2location list to find the entry representing the range of IP addresses into which it fits. The @regs array ends up being filled with the low IP, high IP, country code, country name, state and city values. I'm only display the last three of these, but you could easily choose to display all of them if that proved helpful.

#!/bin/perl -w

if ($#ARGV < 0) {
    print "Enter IP> ";
} else {

my @octets=split /\./, $IP;
$newIP=$octets[3] + $octets[2]*256 + $octets[1]*256*256 + $octets[0]*256*256*256;


while ( <IPLIST> ) {
    next if /^\"0\"/;
    my @regs=split /,/, $_;
    if ($newIP >= $regs[0] && $newIP <= $regs[1]) {
# display location print "$regs[3],$regs[4],$regs[5]\n"; exit; } }

The interaction would look something like this:

$ findIP

This script could easily be converted to one that runs through a file of IP addresses and locates each one.

The IP2location folks offer databases with different levels of detail and various options for developers, but I enjoyed discovering how easily this kind of data could be used to pinpoint the location of systems connecting to (or trying to connect to) systems that I manage.

Sometimes understanding where your customers or your potential attackers are coming from can be valuable.

As for the image used with this post, it seems that tube stations in London might just have their own IP addresses. How cool is that?

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.

Copyright © 2015 IDG Communications, Inc.

SD-WAN buyers guide: Key questions to ask vendors (and yourself)