2011-02-09 15 views
25

क्या सी कोड का उपयोग करके लिनक्स में कोई तरीका है, "ifconfig eth0" वापस आने वाली जानकारी प्राप्त करने के लिए लिनक्स में कोई तरीका है? मुझे आईपी एड्रेस, लिंक स्टेटस और मैक एड्रेस जैसी चीजों में दिलचस्पी है।सी कोड का उपयोग करते हुए 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' की नकल की प्रयोग करें 'आईपी' के बजाय कई वर्षों के लिए लिनक्स पर नहीं रखा गया है। **। http://serverfault.com/questions/633087/where-is-the-statement-of-deprecation-of-ifconfig-on-linux – mikemaccana

उत्तर

34

हाँ, ifconfig ही सी में लिखा है :) देखें: http://cvsweb.netbsd.org/bsdweb.cgi/src/sbin/ifconfig/ifconfig.c?rev=1.169&content-type=text/x-cvsweb-markup

man netdevice करो (लिनक्स पर) विवरण देखने के लिए। आप ioctl() सिस्टम कॉल का उपयोग करते हैं।

+0

धन्यवाद, मैन नेटडेविस में जानकारी उपयोगी है। – Ravi

67

इस तरह की समस्याओं के निचले भाग तक पहुंचने का एक तरीका, विशेष रूप से जिन मामलों में आपके पास स्रोत नहीं है, strace है।

यह आपको उनके तर्कों और वापसी मूल्यों के साथ-साथ आपके द्वारा पास किए गए किसी भी कार्यक्रम द्वारा किए गए सभी सिस्टम कॉल की एक सूची देता है। यदि आपका प्रोग्राम केवल विस्तारित समय के लिए चलाने के बजाए कुछ जानकारी और छोड़ देता है, तो यह देखने के लिए कि आप जो सिस्टम सिस्टम देख रहे हैं, वह सभी सिस्टम कॉल पर एक आदमी को बस इतना सरल हो सकता है।

जब मैं चलाने

strace ifconfig 

दिलचस्प कॉल से कुछ हैं:

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

ioctls का एक समूह द्वारा पीछा किया, @ पायने जवाब की पुष्टि:

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

+0

मुझे यह सुझाव पसंद है। – Ravi

+11

एक उत्तर के लिए +1 जो दिखाता है कि आपको जवाब कैसे मिला, और अन्य समस्याओं के लिए तकनीक को कैसे लागू करें –

7

एक आसान तरीका पॉपन फ़ंक्शन का उपयोग करना है: http://pubs.opengroup.org/onlinepubs/009696899/functions/popen.html

कुछ

उपयोग की तरह:

FILE *fp; 

char returnData[64]; 

fp = popen("/sbin/ifconfig eth0", "r"); 

while (fgets(returnData, 64, fp) != NULL) 
{ 
    printf("%s", returnData); 
} 

pclose(fp); 
+2

लोग इसे पसंद नहीं करेंगे, लेकिन यह एक महान पोर्टेबल उत्तर है, और ioctls का उपयोग करके अपना खुद का रोलिंग बेहोश दिल के लिए नहीं है! –

+1

मजेदार जवाब। अगर आप मूल्यों को पार्स करने के लिए इसे 'awk' पर भी पाइप करते हैं तो मैं ऊपर हट जाऊंगा।चूंकि आपने पहले से ही 'पॉपन' के साथ खोल को फोर्क किया है और आह्वान किया है, इसलिए मैं सी – mctylr

8

यहाँ कैसे मैं अपने कोड में मैक और 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]); 
    } 
+0

में 'strtok', 'strstr', आदि के बजाय डेटा पार्स करने के लिए क्लासिक यूनिक्स विकल्प के रूप में' awk' का उपयोग करने का सुझाव दूंगा। मैं क्या पास करूं 'हस्ताक्षरित चार मैक [6]' में ?? – ppumkin

+0

@ppumkin: मैक [6] एक आउटपुट पैरामीटर है, वह वापसी मूल्य के बजाय इसका उपयोग करता है। तो अपने हस्ताक्षर किए गए वर्णों की अपनी सरणी में एक पॉइंटर दर्ज करें। इस तरह: 'हस्ताक्षरित चार आउट मैक [6]; getMACAddress ("eth0", outMac); ' – Youda008

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); 
    } 
संबंधित मुद्दे