<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 網(wǎng)絡與存儲 > 設計應用 > Linux下C語言操作網(wǎng)卡的幾個代碼實例?特別實用

          Linux下C語言操作網(wǎng)卡的幾個代碼實例?特別實用

          作者: 時間:2024-02-28 來源:一口linux 收藏

          那么如何使用直接操作

          本文引用地址:http://www.ex-cimer.com/article/202402/455806.htm

          比如讀寫IP地址、讀寫MAC地址等。

          一、原理

          主要通過系統(tǒng)用socket()、ioctl()、實現(xiàn)

          int socket(int domain, int type, int protocol);
          功能:
              創(chuàng)建套接字
          參數(shù):
           domain: 
            Name                Purpose                          Man page
            AF_UNIX, AF_LOCAL   Local communication              unix(7)
            AF_INET             IPv4 Internet protocols          ip(7)
          
           type:
            SOCK_STREAM     Provides sequenced, reliable, two-way, connection-based                      byte  streams.  An out-of-band data transmission mecha‐
                                nism may be supported.
                SOCK_DGRAM      Supports datagrams (connectionless, unreliable messages
                                of a fixed maximum length).
           protocol:
            通常為0
          返回值:
           成功:新的套接字的文件描述符
           失?。哄e誤碼,負值
          int ioctl(int fd, unsigned long request, ...);
          參數(shù):
             fd :文件描述符
             request:命令
             ... :參數(shù)

          其中網(wǎng)絡用到的request定義頭文件位于:

          /usr/include/linux/sockios.h
          /* Linux-specific socket ioctls */#define SIOCINQ  FIONREAD#define SIOCOUTQ TIOCOUTQ        /* output queue size (not sent + not acked) *//* Routing table calls. */#define SIOCADDRT 0x890B  /* add routing table entry */#define SIOCDELRT 0x890C  /* delete routing table entry */#define SIOCRTMSG 0x890D  /* call to routing system *//* Socket configuration controls. */#define SIOCGIFNAME 0x8910  /* get iface name  */#define SIOCSIFLINK 0x8911  /* set iface channel  */#define SIOCGIFCONF 0x8912  /* get iface list  */#define SIOCGIFFLAGS 0x8913  /* get flags   */#define SIOCSIFFLAGS 0x8914  /* set flags   */#define SIOCGIFADDR 0x8915  /* get PA address  */#define SIOCSIFADDR 0x8916  /* set PA address  */#define SIOCGIFDSTADDR 0x8917  /* get remote PA address */#define SIOCSIFDSTADDR 0x8918  /* set remote PA address */#define SIOCGIFBRDADDR 0x8919  /* get broadcast PA address */#define SIOCSIFBRDADDR 0x891a  /* set broadcast PA address */#define SIOCGIFNETMASK 0x891b  /* get network PA mask  */#define SIOCSIFNETMASK 0x891c  /* set network PA mask  */#define SIOCGIFMETRIC 0x891d  /* get metric   */#define SIOCSIFMETRIC 0x891e  /* set metric   */#define SIOCGIFMEM 0x891f  /* get memory address (BSD) */#define SIOCSIFMEM 0x8920  /* set memory address (BSD) */#define SIOCGIFMTU 0x8921  /* get MTU size   */#define SIOCSIFMTU 0x8922  /* set MTU size   */#define SIOCSIFNAME 0x8923  /* set interface name */#define SIOCSIFHWADDR 0x8924  /* set hardware address  */#define SIOCGIFENCAP 0x8925  /* get/set encapsulations       */#define SIOCSIFENCAP 0x8926  #define SIOCGIFHWADDR 0x8927  /* Get hardware address  */#define SIOCGIFSLAVE 0x8929  /* Driver slaving support */#define SIOCSIFSLAVE 0x8930#define SIOCADDMULTI 0x8931  /* Multicast address lists */#define SIOCDELMULTI 0x8932#define SIOCGIFINDEX 0x8933  /* name -> if_index mapping */#define SIOGIFINDEX SIOCGIFINDEX /* misprint compatibility :-) */#define SIOCSIFPFLAGS 0x8934  /* set/get extended flags set */#define SIOCGIFPFLAGS 0x8935#define SIOCDIFADDR 0x8936  /* delete PA address  */#define SIOCSIFHWBROADCAST 0x8937 /* set hardware broadcast addr */#define SIOCGIFCOUNT 0x8938  /* get number of devices */……

          其中ioctl的參數(shù)需要借助結構體struct ifreq, 定義頭文件:

          /usr/include/linux/if.h
          #if __UAPI_DEF_IF_IFREQstruct ifreq {#define IFHWADDRLEN 6
           union
           {  char ifrn_name[IFNAMSIZ];  /* if name, e.g. "en0" */
           } ifr_ifrn; 
           union {  struct sockaddr ifru_addr;
            struct sockaddr ifru_dstaddr;
            struct sockaddr ifru_broadaddr;
            struct sockaddr ifru_netmask;
            struct  sockaddr ifru_hwaddr;
            short ifru_flags;  int ifru_ivalue;  int ifru_mtu;  struct  ifmap ifru_map;
            char ifru_slave[IFNAMSIZ]; /* Just fits the size */
            char ifru_newname[IFNAMSIZ];  void * ifru_data;  struct if_settings ifru_settings;
           } ifr_ifru;
          };#endif /* __UAPI_DEF_IF_IFREQ */#define ifr_name ifr_ifrn.ifrn_name /* interface name  */#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address   */#define ifr_addr ifr_ifru.ifru_addr /* address  */#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */#define ifr_flags ifr_ifru.ifru_flags /* flags  */#define ifr_metric ifr_ifru.ifru_ivalue /* metric  */#define ifr_mtu  ifr_ifru.ifru_mtu /* mtu   */#define ifr_map  ifr_ifru.ifru_map /* device map  */#define ifr_slave ifr_ifru.ifru_slave /* slave device  */#define ifr_data ifr_ifru.ifru_data /* for use by interface */#define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */#define ifr_bandwidth ifr_ifru.ifru_ivalue    /* link bandwidth */#define ifr_qlen ifr_ifru.ifru_ivalue /* Queue length  */#define ifr_newname ifr_ifru.ifru_newname /* New name  */#define ifr_settings ifr_ifru.ifru_settings /* Device/proto settings*/

          二、函數(shù)實現(xiàn)

          下面將實現(xiàn)不同功能的函數(shù)一一列舉。

          0. 列出所有可用

          int list_all_port(){        struct ifconf ifconf;
                  struct ifreq *ifr;
                  int m, n, s, fd;        if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {            return -11;
                  }
          
                  s = sizeof(struct ifreq)*5;        for (;;) {
                      ifr = malloc(s);
          
                      ifconf.ifc_len = s;
                      ifconf.ifc_req = ifr;            
                      if (ioctl(fd, SIOCGIFCONF, &ifconf) < 0) {
              perror("SIOCGIFCONF:");                free(ifr);
                          close(fd);                return 1;
                      }                
                      
                      if (ifconf.ifc_len != s)                break;                
                      free(ifr);
                      s *= 2;
                  }
          
                  close(fd);
                  
                  m = ifconf.ifc_len/sizeof(struct ifreq);        for (n = 0; n < m; n++)
            {   printf("port:t%sn",ifconf.ifc_req[n].ifr_name);
            }        free(ifr);
          }

          1. 獲取指定網(wǎng)卡IP

          int getLocalIp(const char *eth, char *ip) {    struct ifreq ifr;
              struct sockaddr_in sin;
              int fd;
              bzero(&ifr, sizeof(ifr));    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {        return -1;
              }    strcpy(ifr.ifr_name, eth);    if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
                  close(fd);        return -1;
              }    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));    snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));
              close(fd);    return 0;
          }

          2. 設置本網(wǎng)卡IP地址

          int setIpAddrManual(const char *eth, char *ipstr) {    int fd;    struct sockaddr_in sin;
              struct ifreq ifr;
              bzero(&ifr, sizeof(ifr));    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
              {        return -1;
              }    strcpy(ifr.ifr_name, eth); sin.sin_addr.s_addr = inet_addr(ipstr); 
           sin.sin_family = AF_INET;    memcpy(&ifr.ifr_addr, &sin, sizeof(sin)); 
              if (ioctl(fd, SIOCSIFADDR, &ifr) < 0)
              {
               perror("");
                  close(fd);        return -1;
              }
              close(fd);    return 0;
          }

          3. 獲取本機網(wǎng)卡Mac地址

          int getLocalMac(const char *eth, char *mac) {    int fd;    struct ifreq ifr;
              bzero(&ifr, sizeof(ifr));    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
              {        return -1;
              }    strcpy(ifr.ifr_name, eth);    if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
              {
                  close(fd);        return -1;
              }   snprintf(mac,18, "%02x:%02x:%02x:%02x:%02x:%02x",
                   (unsigned char) ifr.ifr_hwaddr.sa_data[0],
                   (unsigned char) ifr.ifr_hwaddr.sa_data[1],
                   (unsigned char) ifr.ifr_hwaddr.sa_data[2],
                   (unsigned char) ifr.ifr_hwaddr.sa_data[3],
                   (unsigned char) ifr.ifr_hwaddr.sa_data[4],
                   (unsigned char) ifr.ifr_hwaddr.sa_data[5]);
              close(fd);    return 0;
          
          }

          4. 設置網(wǎng)卡mac地址

          /*
          support format [00:11:22:33:44:55]
          */#define MAC_ARRAY(mac_array)  (unsigned int *)&mac_array[0],(unsigned int *)&mac_array[1],(unsigned int *)&mac_array[2],(unsigned int *)&mac_array[3],(unsigned int *)&mac_array[4],(unsigned int *)&mac_array[5] int setLocalMac(const char *eth, char *mac) {    int fd;    struct ifreq ifr;
           unsigned char mac_array[6] = {0};
           
              bzero(&ifr, sizeof(ifr));    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
              {        return -1;
              }    strcpy(ifr.ifr_name, eth);
           ifr.ifr_hwaddr.sa_family = AF_LOCAL; 
           sscanf(mac,"%02x:%02x:%02x:%02x:%02x:%02x",
            MAC_ARRAY(mac_array)); memcpy(ifr.ifr_hwaddr.sa_data,mac_array,6);    if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0)
              {
               perror("SIOCSIFHWADDR:");
                  close(fd);        return -1;
              }
          
              close(fd);    return 0;
          }

          注意:

          • 網(wǎng)卡地址的第一字節(jié)必須是偶數(shù)

          • sa_family 值必須為:AF_LOCAL

          5. 獲取網(wǎng)卡mtu

          int getMtu(const char *eth, char *mtu) {    int fd;    struct ifreq ifr;
              bzero(&ifr, sizeof(ifr));    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
              {        return -1;
              }    strcpy(ifr.ifr_name, eth);    if (ioctl(fd, SIOCGIFMTU, &ifr) < 0)
              {
                  close(fd);        return -1;
              } 
              snprintf(mtu,64, "%d", (unsigned char) ifr.ifr_mtu);
              close(fd);    return 0;
          }

          6. 獲取廣播地址

          int getBroadAddr(const char *eth, char *ip) {    int fd;    struct sockaddr_in sin;
              struct ifreq ifr;
              bzero(&ifr, sizeof(ifr));    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
              {        return -1;
              }    strcpy(ifr.ifr_name, eth);    if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0)
              {
               perror("");
                  close(fd);        return -1;
              }    memcpy(&sin, &ifr.ifr_broadaddr, sizeof(sin));    snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));
          
              close(fd);    return 0;
          }

          7. 獲取掩碼

          int getNetMask(const char *eth, char *mask) {    int fd;    struct sockaddr_in sin;
              struct ifreq ifr;
              bzero(&ifr, sizeof(ifr));    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
              {        return -1;
              }    strcpy(ifr.ifr_name, eth);    if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0)
              {
               perror("");
                  close(fd);        return -1;
              }    memcpy(&sin, &ifr.ifr_netmask, sizeof(sin));    snprintf(mask, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));
          
              close(fd);    return 0;
          }

          8. 獲取網(wǎng)卡flag

          int getFlags(const char *eth, char *fg) {    int fd;    struct sockaddr_in sin;
              struct ifreq ifr;
              bzero(&ifr, sizeof(ifr));    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
              {        return -1;
              }    strcpy(ifr.ifr_name, eth);    if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0)
              {
               perror("");
                  close(fd);        return -1;
              } snprintf(fg, IP_SIZE, "%x", ifr.ifr_flags);
          
              close(fd);    return 0;
          }

          三、測試

          1. 測試程序

          int main(int argc, char **argv){ int fg=0; char mac[32]={}; char ip[IP_SIZE]={0}; char buf[64];
          
           getBroadAddr(ethname,ip); printf("broad ip:t%sn",ip);
          
           getNetMask(ethname,ip); printf("mask:t%sn",ip);
           
           setIpAddrManual(ethname, "1.1.1.1");
           getLocalIp(ethname,ip); printf("ip:t%sn",ip);
           
           setLocalMac(ethname,"00:11:22:33:44:55");
           getLocalMac(ethname,mac); printf("mac:t%sn",mac);
          
           getMtu(ethname,buf); printf("mtu:t%sn",buf); 
          
           return 1;
          }

          2. 執(zhí)行結果



          執(zhí)行后結果:

          peng@ubuntu:~/work/test/ip$ ifconfig 
          eth0      Link encap:Ethernet  HWaddr 00:11:22:33:44:55  
                    inet addr:1.1.1.1  Bcast:1.255.255.255  Mask:255.0.0.0
                    inet6 addr: fe80::d9d4:d42b:a04a:9d40/64 Scope:Link
                    UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                    RX packets:188577 errors:0 dropped:0 overruns:0 frame:0
                    TX packets:208116 errors:0 dropped:0 overruns:0 carrier:0
                    collisions:0 txqueuelen:1000 
                    RX bytes:53762370 (53.7 MB)  TX bytes:172094089 (172.0 MB)




          關鍵詞: C語言 網(wǎng)口

          評論


          相關推薦

          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();