views:

316

answers:

3
+2  Q: 

IPv6 parsing in C

I wanted to know how i can parse an IPv6 address in 'C' and convert it to a 128 bit value? So a hex address like 1:22:333:aaaa:b:c:d:e:f needs to be converted to its 128 bit equivalent binary. The problem is the IP address could be of the type ::2 and its variant since they are valid IPv6 address.

The input is from the keyboard and hence is in ASCII format.

Any suggestions or pointers will be appreciated. Thanks!!!

+5  A: 

getaddrinfo() can understand IPv6 addresses. Pass AF_INET6 to it in the hints, as well as AI_NUMERICHOST (to prevent a DNS lookup). Linux has it, Windows has it as of Windows XP.

Thanatos
Don't forget to use `freeaddrinfo` if the function succeeded.
dreamlax
+3  A: 

You can use POSIX inet_pton to convert a string to a struct in6_addr.

#include <arpa/inet.h>

  ...

const char *ip6str = "::2";
struct in6_addr result;

if (inet_pton(AF_INET6, ip6str, &result) == 1) // success!
{
    //successfully parsed string into "result"
}
else
{
    //failed, perhaps not a valid representation of IPv6?
}
dreamlax
You can pass anything big enough to hold the result, for example, an array of 8 `short` will do as well; just as long as the buffer is at least 128-bits in length.
dreamlax
I personally like this a bit more than `getaddrinfo()`, which I suggested below. Sadly, it seems that Windows only has `inet_pton()` starting with Vista. (And I'd almost bet that it doesn't parse according to RFC 2373, and only does your typical IPv6 address... anyone know?)
Thanatos
@Thanatos: [This link](http://msdn.microsoft.com/en-us/library/cc805844\(VS.85\).aspx) refers to [RFC 2553](http://www.ietf.org/rfc/rfc2553) which declares the function `inet_pton` as a function that converts IPv4 and IPv6 textual representations into binary form, and it says that it must accept IPv6 addresses in the representations described in section 2.2 of [RFC 2373](http://www.ietf.org/rfc/rfc2373).
dreamlax
Thanks Thanatos and dreamlax for the answers. I used them in my Linux enviroment and it worked perfectly.But the problem is my actual code where i wanted to incorporate this is a stripped down version of Linux and does not have all the libraries.Unfortunately the inet.h header file is not present in the enviroment so inet_pton is not supported... Looks like I might end up writing my own function as YeenFei pointed out.. Need some help as to how to go forward on this...Thanks !!Regards-TG
The Stig
A: 

To parse IPv6 in C, you need to build yourself a utility function, which tokenized string (colon for hex blocks, and forward-slash for subnet bits).

  1. Tokenize raw IPv6 string into smaller substring.
  2. Convert non-empty substring into hex blocks. (ASCII to decimal conversion)
  3. Expand hex block into 2-bytes by padding zero in front. (only leading zeroes get trimmed)
  4. Complete IPv6 should have 8 hex blocks, calculate missing hex-block(s). (zeroes grouping can happen only once)
  5. Reinsert missing hex-block. (use index of the empty substring)
YeenFei
Good description if someone wants to learn IPv6 parsing. Buf it he just wants to actually parse addresses, the other answers are much simpler.
bortzmeyer
Thanks YeenFei for the description. I might end up writing the function..
The Stig