DrDee
DrDee

Reputation: 3609

How to convert IP4 and IP6 addresses to long value in C?

I need a function that works both with IP4 and IP6 addresses and I need to convert an address from it's string representation (IP4) or hexdecimal representation (IP6) to it's long value. The current code I have is:

struct addrinfo *addr;
// This converts an char* ip_address to an addrinfo, so now I know whether 
// it's a IP4 or IP6 address
int result = getaddrinfo(ip_address, NULL, NULL, &addr);
if (result ==0) {
    struct in_addr dst;
    result = inet_pton(addr->ai_family, ip_address, &dst);
    long ip_value = dst->s_addr;
    freeaddrinfo(addr);
    return ip_value;
}

I do get a long from dst->s_addr but I am pretty sure that this is incorrect. Any pointers on how to solve this are much appreciated!

Upvotes: 0

Views: 1428

Answers (1)

cnicutar
cnicutar

Reputation: 182734

First of all your dst isn't large enough for an IPv6 address:

unsigned char buf[sizeof(struct in6_addr)]; /* Since it's larger than in_addr */
int result = getaddrinfo(ip_address, NULL, NULL, buf);

If the address is IPv4, buf is an in_addr which is an uint32_t.

uint32_t u;
memcpy(&u, buf, sizeof(u));

If the address is IPv6 converting to long doesn't actually make sense. You need something that's 128 bits wide or roll your own. That last bit isn't so easy, so ask yourself: are you sure you need this ?

Upvotes: 1

Related Questions