C program to show all network interfaces (IP and MAC) on a linux system
Feb 16th, 2009 by Adam
Edit: This code has an updated version, here!
This simple C program lists all of the “up” network interfaces on a linux system, along with their IP address and MAC address.
It prints off the bound IP address as well as the MAC address of the interface. A older version of this program can be found at http://www.doctort.org/adam/. The updates made to this version are IPv6 compatability and a fix of the “segfault” bug that was a problem in the first version. This version should compile and run on any linux system.
/* * Updated code to obtain IP and MAC address for all "up" network * interfaces on a linux system. Now IPv6 friendly and updated to use * inet_ntop instead of the deprecated inet_ntoa function. This version * should not seg fault on newer linux systems * Authors: Adam Pierce, Adam Risi * Date: 2/17/2009 * http://www.adamrisi.com * http://www.doctort.org/adam/ * * Previous file header follows: * * Example code to obtain IP and MAC for all available interfaces on * Linux. * by Adam Pierce * http://www.doctort.org/adam/ */ #include #include #include #include #include /* * this is straight from beej's network tutorial. It is a nice wrapper * for inet_ntop and helpes to make the program IPv6 ready */ char *get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen) { switch(sa->sa_family) { case AF_INET: inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), s, maxlen); break; case AF_INET6: inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), s, maxlen); break; default: strncpy(s, "Unknown AF", maxlen); return NULL; } return s; } int main(void) { char buf[1024] = {0}; struct ifconf ifc = {0}; struct ifreq *ifr = NULL; int sck = 0; int nInterfaces = 0; int i = 0; /* Get a socket handle. */ sck = socket(AF_INET, SOCK_DGRAM, 0); if(sck < 0) { perror("socket"); return 1; } /* Query available interfaces. */ ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if(ioctl(sck, SIOCGIFCONF, &ifc) < 0) { perror("ioctl(SIOCGIFCONF)"); return 1; } /* Iterate through the list of interfaces. */ ifr = ifc.ifc_req; nInterfaces = ifc.ifc_len / sizeof(struct ifreq); for(i = 0; i < nInterfaces; i++) { struct ifreq *item = &ifr[i]; /* Show the device name and IP address */ struct sockaddr *addr = &(item->ifr_addr); char ip[INET6_ADDRSTRLEN]; printf("%s: IP %s", item->ifr_name, get_ip_str(addr, ip, INET6_ADDRSTRLEN)); /* Get the MAC address */ if(ioctl(sck, SIOCGIFHWADDR, item) < 0) { perror("ioctl(SIOCGIFHWADDR)"); return 1; } /* display result */ printf(", MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", (unsigned char)item->ifr_hwaddr.sa_data[0], (unsigned char)item->ifr_hwaddr.sa_data[1], (unsigned char)item->ifr_hwaddr.sa_data[2], (unsigned char)item->ifr_hwaddr.sa_data[3], (unsigned char)item->ifr_hwaddr.sa_data[4], (unsigned char)item->ifr_hwaddr.sa_data[5]); } return 0; }
This code can be compiled by running:
$ gcc -o ifenum ifenum.c
Enjoy!
[...] UPDATE: Adam Risi has been kind enough to publish an updated version to handle IPv6 on his website. [...]
Thanks your code , but I have test in IP6 system , it’s can’t show the IP6 address , do you have any idea ?
Thanks! I’ve been looking for a snippet to enumerate network-interfaces and happened to stumble upon this post.
[...] wrote some code a while ago that got a bit of attention, so I have decided to do a little bit of a re-write and [...]
There was an update to this code! Check it out, its linked to at the top of the blog post.
I have a modified version that runs on Solaris (possibly all SVR4) and BSD as well as Linux you can find the source to it at:
http://teotwawki.steubentech.com/cvsweb/cvsweb.cgi/src/gluecode/ifenum.c
Thanks for your contribution William! I have added the changes you made (most of them) to the master branch of the updated version of this software project.
[...] software I contributed, and blogged about a while ago has gone v2.0. The newly modified source code now compiles and works on a larger [...]
Thank you so much for this. I just found this post and ran your program. It lists only the ipv4 addresses even though I have ipv6 addresses configured. Any ideas? I can’t find any information online about how to get this to work. Any help would be appreciated. Thanks!
I don’t have any IPv6 interfaces on my system, but if you email me the output from the program in your system, I would be happy to get it working with IPv6. Drop me a line! adam@adamrisi.com
Hi Adam, excellent post!
I’m having problems compiling the code,
First the “#include” lines are not showed in the code you posted.
Second, the switch(sa->sa_family) is showing me an error:
ifenum.c: In function âget_ip_strâ:
ifenum.c:31: error: âgtâ undeclared (first use in this function)
Any help on this? Thanks.
It looks like a plugin update caused the source to display wrong – you can still get the working version by checking it out of the git repository. Heres the address of the github page! http://github.com/ajrisi/lsif