49

I'm writing simple server/client and trying to get client IP address and save it on server side to decide which client should get into critical section. I googled it several times but couldn't find proper way to get IP address from sock structure.

I believe this is a way to get IP from sock struct after server accept request from client. More specifically in c after server execute

csock = accept(ssock, (struct sockaddr *)&client_addr, &clen) 

Thanks

jww
  • 97,681
  • 90
  • 411
  • 885
REALFREE
  • 4,378
  • 7
  • 40
  • 73

3 Answers3

60

OK assuming you are using IPV4 then do the following:

struct sockaddr_in* pV4Addr = (struct sockaddr_in*)&client_addr;
struct in_addr ipAddr = pV4Addr->sin_addr;

If you then want the ip address as a string then do the following:

char str[INET_ADDRSTRLEN];
inet_ntop( AF_INET, &ipAddr, str, INET_ADDRSTRLEN );

IPV6 is pretty easy as well ...

struct sockaddr_in6* pV6Addr = (struct sockaddr_in6*)&client_addr;
struct in6_addr ipAddr       = pV6Addr->sin6_addr;

and getting a string is almost identical to IPV4

char str[INET6_ADDRSTRLEN];
inet_ntop( AF_INET6, &ipAddr, str, INET6_ADDRSTRLEN );
Goz
  • 61,365
  • 24
  • 124
  • 204
  • 2
    You forgot to pass the `str` buffer to `inet_ntop()`. And `sin_addr` is a struct - one has to use `sin_addr.s_addr`. Worth noting that IPv4 address is stored in network byte order and to see it as a hex number one would need to use `ntohl(pV4Addr->sin_addr.s_addr)`. – Dummy00001 Jun 17 '10 at 12:22
  • Points taken ... you also missed my not using a lowercase "in6_addr" ;) On the ntohl front I don't often bother as I can still do equality checks (provided both are in network order) and it would break the inet_ntop (wouldn't it?). – Goz Jun 17 '10 at 12:58
  • 2
    This question is tagged C - you can't leave out the `struct` in types like `struct sockaddr_in *`. Also, the IPV4 method should use `struct in_addr` instead of `int` to store addresses, analagous to the IPV6 method you show. – caf Jun 18 '10 at 05:57
46

The easier and correct way for extracting IP address and port number would be:

printf("IP address is: %s\n", inet_ntoa(client_addr.sin_addr));
printf("port is: %d\n", (int) ntohs(client_addr.sin_port));

The SoapBox's accepted answer won't be correct for all architectures. See Big and Little Endian.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
Misha
  • 5,260
  • 6
  • 35
  • 63
27

Assuming client_addr is a struct sockaddr_in (which it usually is). You can get the IP address (as a 32-bit unsigned integer) from client_addr.sin_addr.s_addr.

You can convert it to a string this way:

printf("%d.%d.%d.%d\n",
  int(client.sin_addr.s_addr&0xFF),
  int((client.sin_addr.s_addr&0xFF00)>>8),
  int((client.sin_addr.s_addr&0xFF0000)>>16),
  int((client.sin_addr.s_addr&0xFF000000)>>24));
SoapBox
  • 20,457
  • 3
  • 51
  • 87