How do I output my host’s IP addresses from a C program?

38,476

Solution 1

#include <stdio.h>
#include <stropts.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/netdevice.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>

int print_addresses(const int domain)
{
  int s;
  struct ifconf ifconf;
  struct ifreq ifr[50];
  int ifs;
  int i;

  s = socket(domain, SOCK_STREAM, 0);
  if (s < 0) {
    perror("socket");
    return 0;
  }

  ifconf.ifc_buf = (char *) ifr;
  ifconf.ifc_len = sizeof ifr;

  if (ioctl(s, SIOCGIFCONF, &ifconf) == -1) {
    perror("ioctl");
    return 0;
  }

  ifs = ifconf.ifc_len / sizeof(ifr[0]);
  printf("interfaces = %d:\n", ifs);
  for (i = 0; i < ifs; i++) {
    char ip[INET_ADDRSTRLEN];
    struct sockaddr_in *s_in = (struct sockaddr_in *) &ifr[i].ifr_addr;

    if (!inet_ntop(domain, &s_in->sin_addr, ip, sizeof(ip))) {
      perror("inet_ntop");
      return 0;
    }

    printf("%s - %s\n", ifr[i].ifr_name, ip);
  }

  close(s);

  return 1;
}

int main(int argc, char *argv[])
{
  int domains[] = { AF_INET, AF_INET6 };
  int i;

  for (i = 0; i < sizeof(domains) / sizeof(domains[0]); i++)
    if (!print_addresses(domains[i]))
      return 1;

  return 0;
}

Solution 2

Your question might be imprecise but I am not sure why everyone is breaking your chops.

I think you are asking the basics in which case you probably want is getifaddrs. The man page has a little example program.

You can also get similar info using the SIOCGIFCONF option with ioctl(). There is some sample code on here and the web.

If you search around for these and similar terms you will find this question has been asked in various forms before. You have to dig around a bit.

Also note, these will not give you the public facing IP of your network if you are behind NAT.

Solution 3

Another way to do it in C. I do have to say though.... there are so many ways to do it from the shell, what's the point?

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>

#include <errno.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>


void show_address_info( struct ifaddrs *ifa ){
  struct sockaddr_in *s4;
  struct sockaddr_in6 *s6;
  /* ipv6 addresses have to fit in this buffer */
  char buf[64];

  if (AF_INET == ifa->ifa_addr->sa_family){
    s4 = (struct sockaddr_in *)(ifa->ifa_addr);
    if (NULL == inet_ntop(ifa->ifa_addr->sa_family, (void *)&(s4->sin_addr), buf, sizeof(buf))){
      printf("%s: inet_ntop failed!\n", ifa->ifa_name);
    } else {
      printf("IPv4 addr %s: %s\n", ifa->ifa_name, buf);
    }
  }
  else if (AF_INET6 == ifa->ifa_addr->sa_family) {
    s6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
    if (NULL == inet_ntop(ifa->ifa_addr->sa_family, (void *)&(s6->sin6_addr), buf, sizeof(buf))) {
      printf("%s: inet_ntop failed!\n", ifa->ifa_name);
    } else {
      printf("IPv6 addr %s: %s\n", ifa->ifa_name, buf);
      }
  }

}


int main(int argc, char **argv){
  struct ifaddrs *myaddrs, *ifa;
  int status;

  status = getifaddrs(&myaddrs);
  if (status != 0){
    perror("getifaddrs failed!");
    exit(1);
  }

  for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next){
    if (NULL == ifa->ifa_addr){
      continue;
    }
    if ((ifa->ifa_flags & IFF_UP) == 0) {
      continue;
    }
    show_address_info(ifa);
  }
  freeifaddrs(myaddrs);
  return 0;
}

Solution 4

How about you simply cheat and look at the source of /sbin/ifconfig/ ? Nothing wrong with standing on the shoulders of other giants...

Solution 5

Not a complete solution yet, but take a look in /proc/net!

  • dev lists the available interface devices by name,
  • route lists some routes, as does ipv6_route,
  • arp lists devices in the actual routing table (does not include localhost).

Not as high-tech as the other solution, but it can be done with simple file reading. Linux specific, though.

Share:
38,476
Emanuel
Author by

Emanuel

Updated on March 26, 2020

Comments

  • Emanuel
    Emanuel about 4 years

    I need to display all the IP addresses from my local computer, using the C language. How can this be done?