How to get my non-loopback network ip address in C?

12,651

Solution 1

There is POSIX function getaddrinfo() that returns linked list of addresses for given hostname, so you just need to go through that list and find non-loopback address.

See man getaddrinfo.

Solution 2

Not an answer, but a relevant comment: be aware that as soon as you start sending addressing information in the content of packets, you run the risk of making your application unable to work across NAT:ing routers and/or through firewalls.

These technologies rely on the information in IP packet headers to keep track of the traffic, and if applications exchange addressing information inside packets, where they remain invisible to this inspection, they might break.

Of course, this might be totally irrelevant to your application, but I thought it worth pointing out in this context.

Solution 3

The originating address will be included in the packet sent... there's no need to duplicate this information. It's obtained when accepting the communication from the remote host (see beej's guide to networking, specifically the part on accept())

Solution 4

Look at this: Discovering public IP programmatically

Note that in some cases a computer can have more than one non-loopback IP address, and in that case the answers to that question tell you how to get the one that is exposed to the internet.

Share:
12,651
Roalt
Author by

Roalt

R&D senior developer in aerospace industry (air traffic control, environment). Developer of Open Source track&field meeting organisation software Atdor.com

Updated on June 27, 2022

Comments

  • Roalt
    Roalt almost 2 years

    For a communication between two hosts, I need to send the IP address of my host to the other site. The problem is that if I request my IP address, it might be that I get back my local loopback IP addres (127.x.x.x) , not the network (ethernet) IP address.

    I use the following code:

    char myhostname[32];
    
    
    gethostname(myhostname, 32);
    hp = gethostbyname(myhostname);
    unsigned my_ip = *(unsigned*)(hp->h_addr);
    
    if( (my_ip % 256) == 127) {
      /* Wrong IP adress as it's 127.x.x.x */
      printf("Error, local IP address!");
      return;
    }
    

    The only way to solve it is to make sure my hostname in /etc/hosts is behind the real network address, not the local loopback (the default for e.g. Ubuntu).

    Is there a way to solve this without relying on the content of /etc/hosts?

    Edit: I changed the above code so it makes use of getaddrinfo, but I still get back the loopback device's number (127.0,0,1) instead of the real IP address:

    struct addrinfo hint = {0};
    struct addrinfo *aip = NULL;
    unsigned ip = 0;
    struct sockaddr_in *sinp = NULL;
    
    hint.ai_family = AF_INET; /* IPv4 */
    hint.ai_socktype = SOCK_STREAM;
    
    if(getaddrinfo(hostname, NULL, &hint, &aip) != 0) {
        return 0;
    }
    sinp = (struct sockaddr_in *) aip->ai_addr;
    ip   = *(unsigned *) &sinp->sin_addr;
    

    (I used to get back a list of 3 addrinfo's with the three SOCK_STREAM,SOCK_DGRAM and SOCK_RAW, but the hint prevents that)

    So my question still stands...