How to get own IP address with socket address?

I want to get the IP address of the computer where my program is running, then send it to the client, but I always get 0.0.0.1 instead of the real IP address (for example, 127.0.0.1, for example).

Currently I can get a port, but not an IP address.

How can i get it?

A better solution would be to get it using sockaddr_in . Here is what I am doing now:

 int open_connection(char* ip, int* port) { int sock; struct sockaddr_in sin; socklen_t len; int i; i = 0; len = sizeof(sin); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) return (-1); bzero(&sin, sizeof(struct sockaddr_in)); sin.sin_family = AF_INET; if (bind(sock, (struct sockaddr *) &sin, sizeof(sin)) != 0) perror("Error on bind"); if (getsockname(sock, (struct sockaddr *)&sin, &len) != 0) perror("Error on getsockname"); strcpy(ip, inet_ntoa(sin.sin_addr)); // IP = 0.0.0.0 *port = sin.sin_port; return (sock); } 

EDIT: I understand that with my thinking I went wrong. So my question is: what's the best way to get your own IP address?

+7
source share
4 answers

When you bind() socket equals 0.0.0.0, this is the only IP address available by the socket when getsockname() called. This means that the socket is bound to all local interfaces. To obtain a specific IP address from a socket, it must be bound to a specific IP address.

Using the socket API to get the local IP address of a machine is in any case the wrong approach. A common mistake is to use gethostname() with gethostbyname() or getaddrinfo() to get the local IP list. This usually works, but it has hidden gotchas that can cause false information, but people tend to ignore this fact or do not even know about it in the first place (I have not known about this for many years, but then I learned better).

Instead, you really should use platform-specific APIs to list local network interfaces. This will provide more reliable information. Windows has GetAdaptersInfo() and GetAdaptersAddresses() . Other platforms have getifaddrs() . They will tell you which local IP addresses are available. You can then bind() set the socket to 0.0.0.0 to accept clients at any of these IP addresses or bind() to a specific IP address to accept clients only at that IP address.

+10
source

The socket API allows you to list the IP addresses assigned to your network interfaces, but it will not tell you that you are a “real IP” if you connect to the Internet from behind a router.

The only way to find out is to ask someone outside. Here's how servers like FileZilla FTP Server do it. They instruct you to configure the “ip.php” script URL like this in the server’s settings so that it can ask the Internet what its public IP address is for use in passive mode.

You can also use STUN , a protocol widely used in VoIP to discover an open IP address.

+4
source

You can name ioctl (sock, SIOCGIFADDR, adr)

see netdevice (7)

0
source

Following @Remy Lebeau answer, I wrote a function that returns the current address of the machine. I tested this only on macOS High Sierra.

interfaec can be any of lo0 , en0 , etc.

ipVersion can be AF_INET or AF_INET6 .

 long int getInternalAddress(char* interface, sa_family_t ipVersion) { struct ifaddrs *ifaddrHead, *ifaddr; /* int_8 */ sa_family_t family; int n; char *interfaceName; if (getifaddrs(&ifaddrHead) != 0) { fprintf(stderr, "ifaddrs error"); } /* iterate through address list */ for (ifaddr = ifaddrHead, n = 0; ifaddr != NULL; ifaddr = ifaddr->ifa_next, n++) { family = ifaddr->ifa_addr->sa_family; interfaceName = ifaddr->ifa_name; if (!family || family != ipVersion || strcmp(interfaceName, interface)) continue; struct sockaddr *addr = ifaddr->ifa_addr; struct sockaddr_in* addr_in = (struct sockaddr_in*) addr; long int address = addr_in->sin_addr.s_addr; freeifaddrs(ifaddrHead); return address; } freeifaddrs(ifaddrHead); return 0; } 

To use it,

 int main() { long int address = getInternalAddress((char*) &"en0", AF_INET); printf("%li\n", address); return 0; } 

I'm still new to C, if something is wrong please tell me.

0
source

All Articles