user442020
user442020

Reputation:

getsockname always returning 0.0.0.0?

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

Answers (3)

Ian
Ian

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

Brian Roach
Brian Roach

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

vishal_ratna
vishal_ratna

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

Related Questions