tags:

views:

118

answers:

3

Hello! I'm prepping for a simple work project and am trying to familiarize myself with the basics of socket programming in a Unix dev environment. At this point, I have some basic server side code setup to listen for incoming TCP connection requests from clients after the parent socket has been created and is set to listen...

int sockfd, newfd;    
unsigned int len;
socklen_t sin_size;
char msg[]="Test message sent";
char buf[MAXLEN];
int st, rv;
struct addrinfo hints, *serverinfo, *p; 
struct sockaddr_storage client;
char ip[INET6_ADDRSTRLEN];

.
. //parent socket creation and listen code omitted for simplicity
.

//wait for connection requests from clients
while(1)
  {
    //Returns the socketID and address of client connecting to socket
    if( ( newfd = accept(sockfd, (struct sockaddr *)&client, &len) ) == -1 ){
      perror("Accept");
      exit(-1);
    }

    if( (rv = recv(newfd, buf, MAXLEN-1, 0 )) == -1) {
      perror("Recv");
      exit(-1);
    }
    struct sockaddr_in *clientAddr = ( struct sockaddr_in *) get_in_addr((struct sockaddr *)&client);
    inet_ntop(client.ss_family, clientAddr, ip, sizeof ip);
    printf("Receive from %s: query type is %s\n", ip, buf);

    if( ( st = send(newfd, msg, strlen(msg), 0)) == -1 ) {
      perror("Send");
      exit(-1);
    }

    //ntohs is used to avoid big-endian and little endian compatibility issues
    printf("Send %d byte to port %d\n", ntohs(clientAddr->sin_port) );

    close(newfd);
  }

}

I found the get_in_addr function online and placed it at the top of my code and use it to obtain the IP address of the client connecting...

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
  if (sa->sa_family == AF_INET) {
    return &(((struct sockaddr_in*)sa)->sin_addr);
  }

  return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

but the function always returns the IPv6 IP address since thats what the sa_family property is set as.

My question is, is the IPv4 IP address stored anywhere in the data I'm using and, if so, how can I access it?

Thanks so much in advance for all your help!

+3  A: 

If you're getting an IPv6 address, then that's what the client is using to connect. There isn't a 1-1 correspondence between IPv6 and IPv4 addresses, nor between IP addresses and client devices.

Its a bit like saying you've received an email from someone, but you're having trouble working out their postal address from their email address.

Damien_The_Unbeliever
I thought that might be the case. Thanks for the clarification, I really appreciate it!
BeachRunnerJoe
A: 

See The need for a "getipv4addr" and "getipv6addr" function article on my website. It describes how you can obtain the IPv4 or IPv6 address of the computer on which it is running.

Michael Aaron Safyan
A: 

While you are physically getting an IPv6 address, if the client connected with IPv4 then the address will in the IPv4-mapped address format.

You can extract the IPv4 portion of the address by accessing bytes 12, 13, 14 and 15 of s6_addr.

R Samuel Klatchko