Raquel de Anda
Raquel de Anda

Reputation: 31

Is there a function that checks whether a sockaddr* named sptr points to an ipv4 or ipv6 address?

Is there a function that checks whether a sockaddr * named sptr points to an ipv4 or ipv6 address? For example I have the code below, how can I add onto it to get whether the address is ipv4 or ipv6, can I use getaddrinfo()?

struct sockaddr *sptr;
struct sockaddr_in *ipv4_ptr;

Upvotes: 1

Views: 292

Answers (2)

Luis Colorado
Luis Colorado

Reputation: 12708

The structures for AF_INET and AF_INET6 address families are different, so you have to use different pointer types for them. The way to proceed is to use:

struct sockaddr *genptr;
... /* initialize genptr to point to the sockaddr structure */
switch (genptr->sa_family) {
case AF_INET: {
    struct sockaddr_in *ipv4ptr = (struct sockaddr_in *)genptr;
    /* check IPV4 addresses using ipv4ptr pointer */
    } break;
case AF_INET6: {
    struct sockaddr_in6 *ipv6ptr = (struct sockaddr_in6 *)genptr;
    /* check IPV6 addresses using ipv6ptr pointer */
    } break;
default: /* NEITHER IPV4 NOR IPV6, IPX? NETBIOS? X25? */
} /* switch */

although less efficient, you can convert your addresses with the version agnostic inet_ntop(3) routine, and use some kind of regular expression matching algorithm to partially match addresses. inet_ntop routines get the generic pointer and build the ipv4/ipv6 ascii string for the network addresses in one shot.

Upvotes: 0

caf
caf

Reputation: 239321

You can test the sa_family member:

switch (sptr->sa_family)
{
    case AF_INET:
    /* IPv4 */
    break;

    case AF_INET6:
    /* IPv6 */
    break;

    default:
    /* Something else */
}

If the sa_family member is AF_INET, that indicates an IPv4 address and the socket address is actually a struct sockaddr_in *. If the sa_family member is AF_INET6, that indicates an IPv6 address and the socket address is actually a struct sockaddr_in6.

Upvotes: 1

Related Questions