tags:

views:

415

answers:

4

I have an application that allows administrators to specify valid IP addresses from which web service requests can be made. I simply take the configured IP addresses and compare them against the incoming request. Comparing two IPv4 addresses is trivial and I thought comparing two IPv6 addresses would be as well.

However, my networking ignorance started to show when I noticed that IPv6 addresses are a little more complex. One issue I noticed is that if I look at the IP address on the machine (was viewing what VMWare console showed the IP address to be) versus the IP address from the web request (HttpContext.Current.Request.UserHostAddress within .NET) I noticed that one of them ended in %10 and another in %11:

  • ipconfig shows: fe80:8179:5576:c6d0:8b16%11
  • UserHostAddress shows: fe80::8179:5576:c6d0:8b16%10

The only difference is the %10 and %11 - what gives?

I have also seen IPv6 addresses end in "/" followed by 2 digits. Should I just ignore these final 3 digits (if they exist) when doing a comparison? If so, what are the valid alternate endings that I need to look for?

----------- EDIT -------------

Here is my solution based on the answer provided...

I simply store a "scrubbed" IP address and compare that with a "scrubbed" IP address. Using .NET here is how I scrub an IP address. Not the best from a performance standpoint, but it does work. I would rather just do a comparison of the GetAddressBytes() but I'm using a Dictionary and I decided against the extra step of creating my own ByteComparer.

IPAddress incomingIp = null;
bool ipAddressParsePassed = IPAddress.TryParse(userHostAddress, out incomingIp);
if (ipAddressParsePassed)
{
    IPAddress scrubbedIp = new IPAddress(incomingIp.GetAddressBytes());
    string scrubbedIpStr = scrubbedIp.ToString()
}
+2  A: 

IPv6 is just a 128-bit versus 32-bit in IPv4; you should just be able to do a byte by byte comparison.

Suroot
If that is the case, can you explain the %10 vs. %11 ending on my ip address examples above? I just added the actual values above to make this more clear. Note that these are for a single ethernet adapter. I have a wireless one as well and it is a totally different ipv6 address (ending in %12 for what it's worth).
Kirk Liemohn
A: 

Addresses with a / and a number at the end use Classless Inter-Domain Routing (CIDR) notation. They can denote an actual address or a network. If there's a zero or :: before the / then it's a network.

CIDR notation

Bedwyr Humphreys
Interesting. So, I have seen "/64" on the end of an IP address (apparently CIDR notation) as well as "%11" and "%12" on the end. Any idea what notation the % stuff is?
Kirk Liemohn
Nitpick: CIDR is an IPv4-specific term, created when IPv4 moved from classful to classless addressing. With IPv6, it does not make sense, since IPv6 was always classless.
bortzmeyer
+4  A: 

Wikipedia states:

Because all link-local addresses in a host have a common prefix, normal routing procedures cannot be used to choose the outgoing interface when sending packets to a link-local destination. A special identifier, known as a zone index, is needed to provide the additional routing information; in the case of link-local addresses, zone indices correspond to interface identifiers.

When an address is written textually, the zone index is appended to the address, separated by a percent sign "%". The actual syntax of zone indices depends on the operating system [...]

So, those suffixes are zone indicators, that associate the address with a physical interface. This also explains why the suffices differ between wired and wireless interfaces, for instance.

To help answer the question, I don't think the suffixes should be included in any comparison. IPv6 addresses are 128 bits by definition, and the suffixes are strictly local information that does not make sense outside your own machine and it's current operating system.

Comparing the 128 bits should be enough.

unwind
Excellent! I was stuck on a different page on wikipedia: [IPv6](http://en.wikipedia.org/wiki/IPv6) and didn't find the one you just gave: [IPv6 Addresses](http://en.wikipedia.org/wiki/IPv6_Addresses). Looking at it now...
Kirk Liemohn
Note well the "actual syntax of zone indices depends on the OS.." You can not assume the zone index is three characters. You can, however, assume that if present, it follows a % symbol. So, if you're comparing addresses without concern for the local interface specification, stop at the %. Conversely, if you differ between local interfaces, include the string after the %.
mpez0
The quote just above the quote you provided may also provide some insight: "All interfaces have an associated link-local address, that is only guaranteed to be unique on the attached link." So, I'm reading this and the quote you provided to mean that I'm probably better off removing the zone index which is separated by a percent sign.
Kirk Liemohn
Link-local scope addresses, i.e. those with the reserved fe80::/10 prefix, have link-local scope and need not be autoconfigured by using the well-known function from EUI addresses. Therefore the scope identifier is significant when comparing them.
james woodyatt
A: 

The only difference is the %10 and %11 - what gives?

These are IPv6 zone identifiers, link-local addresses, i.e. fe80 prefix, are only guaranteed unique on the local link. This means that the addresses fe80:8179:5576:c6d0:8b16%11 and fe80::8179:5576:c6d0:8b16%10 may refer to different machines, one has to be accessed through interface 10 and the other through interface 11.

Have a look at the definition of sockaddr_in6,

struct sockaddr_in6 {
  short sin6_family;
  u_short sin6_port;
  u_long sin6_flowinfo;
  struct in6_addr sin6_addr;
  u_long sin6_scope_id;
};

You will need to compare the family, address, and scope-id fields for a complete match.

Steve-o