2

In my Linux C++ application I'm using getpeername in order to get the peer IP. my problem is: when I enable the IPv6 on my machine the IP I got from the peer is with family IF_INET6 although it is IPv4.

code:

int GetSockPeerIP( int sock)
{
     struct sockaddr_storage ss;
     struct socklen_t salen = sizeof(ss);
     struct sockaddr *sa;
     memset(&ss,0,salen);
     sa = (sockaddr *)&ss;

     if(getpeername(sock,sa,&salen) != 0)
     {
        return -1;
     }

     char * ip=NULL:
     if(sa->sa_family == AF_INET)
     {
        ip = inet_ntoa((struct sockaddr_in *)sa)->sin_addr);
     }
     else
     {
         //ip = how to convert IPv6 to char IP?
     }

     return 0;
}

how can I fix it?

thanks1

gln
  • 1,011
  • 5
  • 31
  • 61

2 Answers2

1

You can use getnameinfo, which can handle all address types, and is shorter than inet_ntop to use:

char host[256];
getnameinfo(&ss, salen, host, sizeof(host), NULL, 0, 0);
user562374
  • 3,817
  • 1
  • 22
  • 19
0

You can use the inet_ntop() function, which can handle both IPv4 and IPv6 addresses:

char ip[INET6_ADDRSTRLEN];
switch(sa->sa_family) {
    case AF_INET:
        inet_ntop(AF_INET, ((struct sockaddr_in *) sa)->sin_addr, ip, salen);
        break;

    case AF_INET6:
        inet_ntop(AF_INET6, ((struct sockaddr_in6 *) sa)->sin6_addr, ip, salen);
        break;

    default:
        // Unknown address family.
        return -1;
}
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479