2011-02-09 24 views
25

在Linux中,使用C代碼有沒有辦法獲得「ifconfig eth0」將返回的相同信息?我對IP地址,鏈接狀態和MAC地址等內容感興趣。使用C代碼獲取與ifconfig相同的信息

這裏的示例輸出使用ifconfig:

eth0  Link encap:Ethernet HWaddr 00:0F:20:CF:8B:42 
      inet addr:217.149.127.10 Bcast:217.149.127.63 Mask:255.255.255.192 
      UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 
      RX packets:2472694671 errors:1 dropped:0 overruns:0 frame:0 
      TX packets:44641779 errors:0 dropped:0 overruns:0 carrier:0 
      collisions:0 txqueuelen:1000 
      RX bytes:1761467179 (1679.8 Mb) TX bytes:2870928587 (2737.9 Mb) 
      Interrupt:28 
+0

**'ifconfig'在Linux上多年沒有維護**使用'ip'代替。 http://serverfault.com/questions/633087/where-is-the-statement-of-deprecation-of-ifconfig-on-linux – mikemaccana 2015-08-28 14:55:42

回答

67

找到像這樣的問題底部的一種方法,特別是在您沒有源的情況下,是strace

它給出了你傳遞它的任何程序所做的所有系統調用的列表,以及它們的參數和返回值。如果你的程序只是轉儲一些信息並退出而不是長時間運行,那麼在你看到的所有系統調用中做一個人就很容易了,看起來他們可能提供你正在尋找的信息。

當我運行

strace ifconfig 

一些有趣的電話是:

open("/proc/net/dev", O_RDONLY)   = 6 

接着一堆的ioctl,證實@佩恩的回答是:

ioctl(5, SIOCGIFFLAGS, {ifr_name="eth0", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0 
ioctl(5, SIOCGIFHWADDR, {ifr_name="eth0", ifr_hwaddr=84:2b:2b:b7:9e:6d}) = 0 
ioctl(5, SIOCGIFMETRIC, {ifr_name="eth0", ifr_metric=0}) = 0 
ioctl(5, SIOCGIFMTU, {ifr_name="eth0", ifr_mtu=1500}) = 0 
+2

不錯的技巧! – payne 2011-02-09 22:46:21

+0

我喜歡這個提示。 – Ravi 2011-02-09 22:51:08

+11

+1爲答案,顯示你如何找到答案,以及如何將該技術應用於其他問題 – 2011-02-09 23:48:34

8

這是我如何得到MAC和MTU在我的代碼:

void getMACAddress(std::string _iface,unsigned char MAC[6]) { 
     int fd = socket(AF_INET, SOCK_DGRAM, 0); 
     struct ifreq ifr; 
     ifr.ifr_addr.sa_family = AF_INET; 
     strncpy(ifr.ifr_name , _iface.c_str() , IFNAMSIZ-1); 
     ioctl(fd, SIOCGIFHWADDR, &ifr); 
     for(unsigned int i=0;i<6;i++) 
      MAC[i] = ifr.ifr_hwaddr.sa_data[i]; 
     ioctl(fd, SIOCGIFMTU, &ifr); 
     close(fd); 
     printf("MTU: %d\n",ifr.ifr_mtu); 
     printf("MAC:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",MAC[0],MAC[1],MAC[2],MAC[3],MAC[4],MAC[5]); 
    } 
5

有更簡單的方法。拷貝自http://man7.org/linux/man-pages/man3/getifaddrs.3.html

#include <arpa/inet.h> 
    #include <sys/socket.h> 
    #include <netdb.h> 
    #include <ifaddrs.h> 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <unistd.h> 
    #include <linux/if_link.h> 

    int main(int argc, char *argv[]) 
    { 
     struct ifaddrs *ifaddr, *ifa; 
     int family, s, n; 
     char host[NI_MAXHOST]; 

     if (getifaddrs(&ifaddr) == -1) { 
      perror("getifaddrs"); 
      exit(EXIT_FAILURE); 
     } 

     /* Walk through linked list, maintaining head pointer so we 
      can free list later */ 

     for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) { 
      if (ifa->ifa_addr == NULL) 
       continue; 

      family = ifa->ifa_addr->sa_family; 

      /* Display interface name and family (including symbolic 
       form of the latter for the common families) */ 

      printf("%-8s %s (%d)\n", 
        ifa->ifa_name, 
        (family == AF_PACKET) ? "AF_PACKET" : 
        (family == AF_INET) ? "AF_INET" : 
        (family == AF_INET6) ? "AF_INET6" : "???", 
        family); 

      /* For an AF_INET* interface address, display the address */ 

      if (family == AF_INET || family == AF_INET6) { 
       s = getnameinfo(ifa->ifa_addr, 
         (family == AF_INET) ? sizeof(struct sockaddr_in) : 
              sizeof(struct sockaddr_in6), 
         host, NI_MAXHOST, 
         NULL, 0, NI_NUMERICHOST); 
       if (s != 0) { 
        printf("getnameinfo() failed: %s\n", gai_strerror(s)); 
        exit(EXIT_FAILURE); 
       } 

       printf("\t\taddress: <%s>\n", host); 

      } else if (family == AF_PACKET && ifa->ifa_data != NULL) { 
       struct rtnl_link_stats *stats = (struct rtnl_link_stats *)ifa->ifa_data; 

       printf("\t\ttx_packets = %10u; rx_packets = %10u\n" 
         "\t\ttx_bytes = %10u; rx_bytes = %10u\n", 
         stats->tx_packets, stats->rx_packets, 
         stats->tx_bytes, stats->rx_bytes); 
      } 
     } 

     freeifaddrs(ifaddr); 
     exit(EXIT_SUCCESS); 
    }