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

2019-01-12 05:36发布

问题:

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

回答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;
}


回答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.



回答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;
}


回答4:

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



回答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.



回答6:

You need POSIX function getaddrinfo() - it returns linked list of all IP addresses.

See man getaddrinfo for details and examples.



回答7:

$ sudo ifconfig | grep 'inet addr' | cut -d':' -f2 | cut -d' ' -f1
213.xx.xxx.xx
192.168.xx.x
127.0.0.1

And you can put that into popen():

/* not tested */
ph = popen("sudo ifconfig | grep 'inet addr' | cut -d':' -f2 | cut -d' ' -f1", "r");
while (fgets(buf, sizeof buf, ph)) {
    /* ip address, in nul-terminated string format, is in `buf` */
}
pclose(ph);


回答8:

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

/*
 * Who sez?
 * http://blog.stackoverflow.com/2010/01/stack-overflow-where-we-hate-fun/
 */
int main(int argc, char *argv[])
{
  int status;
  const char * const cmd =  /* die from END is too chatty */
    "/sbin/ifconfig -a | \
     perl -lne \
       'print $1 if /inet6? addr:\\s*(\\S+)/; \
        END { $. > 0 or \
                warn(\"no output from ifconfig\\n\"), \
                exit 1; }'";

  status = system(cmd);
  if (status < 0) {
    perror("system");
    return 1;
  }
  else if (status != 0) {
    const char *extra;
    status = WEXITSTATUS(status);
    extra = status == 127 ? " (is /bin/sh ok?)" : "";
    fprintf(stderr, "%s: command failed with status %d%s\n",
            argv[0], status, extra);
  }

  return 0;
}


标签: c linux sockets ip