Poll field names via SIOCGIFCONF on Linux

I am trying to query the names of network devices. I put it together from different fragments,

But my conclusion is just gibberish.

#include <stdio.h> #include <stdlib.h> #include <net/route.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #define BUFLEN 1024 #define SEQ 9999 int main (int argc, const char* argv[]) { // File descriptor for socket int socketfd; struct ifconf conf; struct ifreq req[10]; struct ifreq *ifr; printf("Opening socket..."); socketfd = socket(AF_ROUTE, SOCK_RAW, 0); if (socketfd >= 0) { printf(" OK\n"); conf.ifc_len = sizeof(req); conf.ifc_buf = (__caddr_t) req; ioctl(socketfd,SIOCGIFCONF,&conf); printf("Discovering interfaces...\n"); int i; for (i=0; i<conf.ifc_len/sizeof(req[0]); i++) { ifr = &conf.ifc_req[i]; printf("%d. %s\n", i+1, req[i].ifr_name); } } else { printf("Failed!\n"); } return 0; } 

Output:

 Opening socket... OK Discovering interfaces... ?u???}??Gh??? 2. p?9}? 3. 4. v?=?n??u?`?y??]g?<?~?v?? 5. 6. 7. 8. ?v?T? 9. ?|?mw??j??v??h??|??v?T00~??v?$?|??| ?@ 10. T00~??v?$?|??| ?@ 

I tried to pull each char from the ifr_name array one by one to see if they were empty, but that didn't change much. Each iteration of my program outputs something else, so it makes me think that I am referencing something incorrectly. Can someone give me some idea of ​​what I can do wrong?

+4
source share
3 answers

See http://git.netfilter.org/cgi-bin/gitweb.cgi?p=libmnl.git;a=blob;f=examples/rtnl/rtnl-link-dump.c;hb=HEAD about how to get a list of interfaces in linux. AF_ROUTE is some kind of BSD thing, and using ioctl is not recommended for Linux for its obvious limitations (for example, for transferring multiple addresses on the same interface).

-4
source

Here is the code I compiled for Mac OS X:

 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <arpa/inet.h> #include <netinet/in.h> /* This is defined on Mac OS X */ #ifndef _SIZEOF_ADDR_IFREQ #define _SIZEOF_ADDR_IFREQ sizeof #endif int main (int argc, const char* argv[]) { // File descriptor for socket int socketfd; struct ifconf conf; char data[4096]; struct ifreq *ifr; char addrbuf[1024]; int i; printf("Opening socket..."); socketfd = socket(AF_INET, SOCK_DGRAM, 0); if (socketfd >= 0) { printf(" OK\n"); conf.ifc_len = sizeof(data); conf.ifc_buf = (caddr_t) data; if (ioctl(socketfd,SIOCGIFCONF,&conf) < 0) { perror("ioctl"); } printf("Discovering interfaces...\n"); i = 0; ifr = (struct ifreq*)data; while ((char*)ifr < data+conf.ifc_len) { switch (ifr->ifr_addr.sa_family) { case AF_INET: ++i; printf("%d. %s : %s\n", i, ifr->ifr_name, inet_ntop(ifr->ifr_addr.sa_family, &((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr, addrbuf, sizeof(addrbuf))); break; #if 0 case AF_INET6: ++i; printf("%d. %s : %s\n", i, ifr->ifr_name, inet_ntop(ifr->ifr_addr.sa_family, &((struct sockaddr_in6*)&ifr->ifr_addr)->sin6_addr, addrbuf, sizeof(addrbuf))); break; #endif } ifr = (struct ifreq*)((char*)ifr +_SIZEOF_ADDR_IFREQ(*ifr)); } close(socketfd); } else { printf(" Failed!\n"); } return 0; } 
+7
source

Poll How do you want to be notified if an interface is added or removed? Or asked how you just want to know the interface names once from the system? If the latter, see getifaddrs () .

+1
source

Source: https://habr.com/ru/post/1338925/


All Articles