Sign in to follow this  
Wibbs

[.net] Testing whether a given IP address is on the local network

Recommended Posts

Hi all,

I'm sure there's a simple answer to this, but I've read through loads of stuff and not be able to find it. Basically, for a given IP address, what is the most straightforward way of testing whether it is part of the local network or not?

Thanks in advance for your help,

Phil

Share this post


Link to post
Share on other sites
erik: i think he wants to distinguish between external and internal ip-adresses. doing a dns lookup of, say, www.google.com, results in an ip, which is an external one. doing a dns lookup of, say, my-pc results in an ip, which is an internal one.

the non-programming way would be to use ipconfig to see your current ip + mask settings, then ping to get the dns lookup, then compare the ip you got with your current ip using the mask, to verify if they have overlap. if not, it's external.

how to do it in code? i've never done it. no clue.

Share this post


Link to post
Share on other sites
See this: http://support.microsoft.com/kb/164015 and this: http://en.wikipedia.org/wiki/IPv4.

You will basically want to take the IP address and convert it to binary and then get the details from that. You will mainly want the address range. This will be the same as cisco's shorthand address (i.e. 192.168.0.1 /21). This 21 will actually tell you how many IP addresses there are available. It's a little more complicated than that, but you will end up with, for instance, 192.168.0.1-192.168.7.255. Then you can check the given IP address against that.

It shouldn't be too hard to do in code since you basically convert everything to binary and work from there (XOR'ing and OR'ing the bits).

If you need help let me know. I have no time to provide the actual details, but I can later if you want me to.

Share this post


Link to post
Share on other sites
Thanks for the pointers. This is the rough code I've ended up with...

First I get info on the local host's network interfaces:

hostIPAddressesAndSubnetMasks = new Dictionary<IPAddress, IPAddress>();

// get the network interfaces for the host machine
NetworkInterface[] hostNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

// for each interface, loop through and get all of the unicast IP addresses and their associated subnet masks
foreach (NetworkInterface interfaceToCheck in hostNetworkInterfaces)
{
if (interfaceToCheck.NetworkInterfaceType == NetworkInterfaceType.Loopback)
{
continue;
}

UnicastIPAddressInformationCollection IPAddressInfoCollection = interfaceToCheck.GetIPProperties().UnicastAddresses;

foreach (UnicastIPAddressInformation info in IPAddressInfoCollection)
{
if (!hostIPAddressesAndSubnetMasks.ContainsKey(info.Address))
{
hostIPAddressesAndSubnetMasks.Add(info.Address, info.IPv4Mask);
}
}
}


I have a utility function which returns the network address for a given IP address and subnet mask:

protected IPAddress GetNetworkAddressFromIPAddress(IPAddress address, IPAddress subnetMask)
{
byte[] ipAddressAsBytes = address.GetAddressBytes();
byte[] subnetMaskAsBytes = subnetMask.GetAddressBytes();

if (ipAddressAsBytes.Length != subnetMaskAsBytes.Length)
{
throw new ArgumentException("address and subnet mask must be the same length");
}

byte[] networkAddress = new byte[ipAddressAsBytes.Length];

for (int i = 0; i < networkAddress.Length; i++)
{
networkAddress[i] = (byte)(ipAddressAsBytes[i] & (subnetMaskAsBytes[i]));
}

return new IPAddress(networkAddress);
}

And finally, I have a function which checks a given address as follows:

public bool IsInternal(int ipAddress)
{
IPAddress addressToCheck = new IPAddress(ipAddress);

foreach (KeyValuePair<IPAddress, IPAddress> localAddress in hostIPAddressesAndSubnetMasks)
{
IPAddress localNetworkAddress = GetNetworkAddressFromIPAddress(localAddress.Key, localAddress.Value);
IPAddress addressToCheckNetworkAddress = GetNetworkAddressFromIPAddress(addressToCheck, localAddress.Value);

if (localNetworkAddress.Equals(addressToCheckNetworkAddress))
{
return true;
}
}

return false;
}


I know there needs to be a fair bit more error checking and such like, but I would appreciate it if anyone could point out if I'm missing anything obvious.

Thanks,

Phil

Share this post


Link to post
Share on other sites
If you can guarantee ICMP is available then simple traceroute and checking there are no intermediate hops is one option. If you've got to go via the default gateway you're hopping outside the "local" network from a networking point of view, but physically whatever network you're hopping to may still be in the same building- it really depends what you're trying to achieve as to how many hops you check for.

Similarly depending on what you're trying to achieve it may also be acceptable to simply check the IP in question is in the same subnet as you.

Of course, again, depending on what you're trying to do, it may not be that you need to care about being physically local at all and you may just want to check you have a fast connection to the machine- in this case, just ping it and check that the ping time is within acceptable bounds, less than 5ms for example.

Don't just check the IP is in one of the local address ranges though, as not everyone follows the standards (as stupid as that is). I've worked somewhere that used 80.*.*.* addresses before, which, obviously, was quite stupid as it meant they conflicted with internet addresses they couldn't communicate with because the network searched for them locally. They changed it eventually though.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this