Getting IPV4 address from a sockaddr structure Getting IPV4 address from a sockaddr structure c c

Getting IPV4 address from a sockaddr structure


Just cast the entire sockaddr structure to a sockaddr_in. Then you can use:

char *ip = inet_ntoa(their_addr.sin_addr)

To retrieve the standard ip representation.


inet_ntoa() works for IPv4; inet_ntop() works for both IPv4 and IPv6.

Given an input struct sockaddr *res, here are two snippets of code (tested on macOS):

Using inet_ntoa()

#include <arpa/inet.h>struct sockaddr_in *addr_in = (struct sockaddr_in *)res;char *s = inet_ntoa(addr_in->sin_addr);printf("IP address: %s\n", s);

Using inet_ntop()

#include <arpa/inet.h>#include <stdlib.h>// obviously INET6_ADDRSTRLEN is expected to be larger// than INET_ADDRSTRLEN, but this may be required in case// if for some unexpected reason IPv6 is not supported, and// INET6_ADDRSTRLEN is defined as 0// but this is not very likely and I am aware of no cases of// this in practice (editor)char s[INET6_ADDRSTRLEN > INET_ADDRSTRLEN ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN]    = '\0';switch(res->sa_family) {    case AF_INET: {        struct sockaddr_in *addr_in = (struct sockaddr_in *)res;        ////char s[INET_ADDRSTRLEN] = '\0';            // this is large enough to include terminating null        inet_ntop(AF_INET, &(addr_in->sin_addr), s, INET_ADDRSTRLEN);        break;    }    case AF_INET6: {        struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)res;                ////char s[INET6_ADDRSTRLEN] = '\0';            // not sure if large enough to include terminating null?        inet_ntop(AF_INET6, &(addr_in6->sin6_addr), s, INET6_ADDRSTRLEN);        break;    }    default:        break;}printf("IP address: %s\n", s);


Emil's answer is correct, but it's my understanding that inet_ntoa is deprecated and that instead you should use inet_ntop. If you are using IPv4, cast your struct sockaddr to sockaddr_in. Your code will look something like this:

struct addrinfo *res;   // populated elsewhere in your codestruct sockaddr_in *ipv4 = (struct sockaddr_in *)res->ai_addr;char ipAddress[INET_ADDRSTRLEN];inet_ntop(AF_INET, &(ipv4->sin_addr), ipAddress, INET_ADDRSTRLEN);printf("The IP address is: %s\n", ipAddress);

Take a look at this great resource for more explanation, including how to do this for IPv6 addresses.