How to get ip address from sock structure in c?
Asked Answered
P

3

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

Parietal answered 17/6, 2010 at 10:48 Comment(0)
B
61

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 );
Burnejones answered 17/6, 2010 at 10:53 Comment(3)
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).Xylo
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?).Burnejones
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.Seymourseys
L
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.

Loxodromic answered 18/4, 2013 at 8:2 Comment(0)
T
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));
Theirs answered 17/6, 2010 at 10:54 Comment(3)
You should use inet_ntoa() instead of fiddling with the bits manually.Dramatics
inet_ntoa is not thread-safe, although that might not be important for most cases where it's used. A safe alternative is inet_ntop.Aaberg
@RemyLebeau Nice and simple. I like it.Spicate

© 2022 - 2024 — McMap. All rights reserved.