Reputation:
Here is the code. It is the same as the code from this similar question: http://monkey.org/freebsd/archive/freebsd-stable/200401/msg00032.html. When I run it I always get the output:
listening on 0.0.0.0:54493 or something. Obviously the port changes, but I have no idea why I keep getting an IP address of 0.0.0.0. Am I missing something?
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
int sock;
int len = sizeof(struct sockaddr);
struct sockaddr_in addr, foo;
if((sock=socket(AF_INET, SOCK_STREAM, 0))<0)
{
exit(0);
}
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(0);
if(bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in))<0)
{
perror("bind");
exit(0);
}
if(listen(sock, 5)<0)
{
perror("listen");
exit(0);
}
getsockname(sock, (struct sockaddr *) &foo, &len);
fprintf(stderr, "listening on %s:%d\n", inet_ntoa(foo.sin_addr),
ntohs(foo.sin_port));
return 0;
}
Upvotes: 15
Views: 27613
Reputation: 1251
As mentioned in the other answers, 0.0.0.0
is returned because INADDR_ANY
was specified as the host address for the listening socket. This makes sense if you think that, in a multi-homed host, client connections could come in on any of those interfaces (so which should be reported?)
Expanding on those answers; if the actual IP address of a client connection is required, use the SOCKET
returned from accept()
with getsockname()
. This will provide the interface address on the server to which the client connected.
Upvotes: 1
Reputation: 76908
You specify INADDR_ANY
rather than a specific IP address, so it binds to the wildcard (all interfaces) 0.0.0.0
. So, when you call getsockname()
that's what you get back.
If you specified 0.0.0.0
as the IP address rather than INADDR_ANY
you would get the same behavior; you will bind to all network interfaces on the machine.
For example, lets say you only have one network interface with the IP 192.168.1.12
assigned to it. You also have the loopback by default - 127.0.0.1
Using 0.0.0.0
or INADDR_ANY
means you'll be bound to both those addresses, rather than a specific one. You will be able to connect to to your process via either IP.
If you were to bind to a specific IP rather than INADDR_ANY
, your process would only listen on that IP and you'd get back that specific IP with getsockname()
.
Upvotes: 25
Reputation: 116
Yes, if you bind it to a LOOPBACK , u have to specify INADDR_LOOPBACK. Otherwise it attaches itself to 0.0.0.0 which represents all the network interfaces available. I was facing the same problem, while issuing getnameinfo() call.
Upvotes: 1