struct ifreq學習和實例
阿新 • • 發佈:2018-01-28
repr lin fig ack topo data- ali rem mac
一、struct ifreq結構體
這個結構定義在/usr/include/net/if.h,用來配置和獲取ip地址,掩碼,MTU等接口信息的。
[cpp] view plain copy
- /* Interface request structure used for socket ioctl‘s. All interface
- ioctl‘s must have parameter definitions which begin with ifr_name.
- The remainder may be interface specific. */
- struct ifreq
- {
- # define IFHWADDRLEN 6
- # define IFNAMSIZ IF_NAMESIZE
- union
- {
- char ifrn_name[IFNAMSIZ]; /* Interface 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 int ifru_flags;
- int ifru_ivalue;
- int ifru_mtu;
- struct ifmap ifru_map;
- char ifru_slave[IFNAMSIZ]; /* Just fits the size */
- char ifru_newname[IFNAMSIZ];
- __caddr_t ifru_data;
- } ifr_ifru;
- };
- # 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 _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
- # define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
- # define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
二、用法:
通過ioctl()函數調用
下表列出了網絡相關ioctl請求的request 參數以及arg 地址必須指向的數據類型:
類別 | Request | 說明 | 數據類型 |
套 接 口 |
SIOCATMARK SIOCSPGRP SIOCGPGRP |
是否位於帶外標記 設置套接口的進程ID 或進程組ID 獲取套接口的進程ID 或進程組ID |
int int int |
文 件 |
FIONBIN FIOASYNC FIONREAD FIOSETOWN FIOGETOWN |
設置/ 清除非阻塞I/O 標誌 設置/ 清除信號驅動異步I/O 標誌 獲取接收緩存區中的字節數 設置文件的進程ID 或進程組ID 獲取文件的進程ID 或進程組ID |
int int int int int |
接 口 |
SIOCGIFCONF SIOCSIFADDR SIOCGIFADDR SIOCSIFFLAGS SIOCGIFFLAGS SIOCSIFDSTADDR SIOCGIFDSTADDR SIOCGIFBRDADDR SIOCSIFBRDADDR SIOCGIFNETMASK SIOCSIFNETMASK SIOCGIFMETRIC SIOCSIFMETRIC SIOCGIFMTU SIOCxxx |
獲取所有接口的清單 設置接口地址 獲取接口地址 設置接口標誌 獲取接口標誌 設置點到點地址 獲取點到點地址 獲取廣播地址 設置廣播地址 獲取子網掩碼 設置子網掩碼 獲取接口的測度 設置接口的測度 獲取接口MTU (還有很多取決於系統的實現) |
struct ifconf struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq struct ifreq |
ARP | SIOCSARP SIOCGARP SIOCDARP |
創建/ 修改ARP 表項 獲取ARP 表項 刪除ARP 表項 |
struct arpreq struct arpreq struct arpreq |
路 由 |
SIOCADDRT SIOCDELRT |
增加路徑 刪除路徑 |
struct rtentry struct rtentry |
流 | I_xxx |
實例一,獲取網卡的IP地址:
[cpp] view plain copy
- #include <string.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <net/if.h>
- #include <stdio.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- int main()
- {
- int inet_sock;
- struct ifreq ifr;
- inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
- strcpy(ifr.ifr_name, "eth0");
- //SIOCGIFADDR標誌代表獲取接口地址
- if (ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0)
- perror("ioctl");
- printf("%s\n", inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));
- return 0;
- }
實例二,實現簡單ifconfig功能:
[cpp] view plain copy
- /**
- * \file getifstat.c
- * \author wzj
- * \brief 訪問這個struct ifconf 修改,查詢狀態
- * \version
- * \note
- * \date: 2012年08月11日星期六22:55:25
- */
- #include <net/if.h> /* for ifconf */
- #include <linux/sockios.h> /* for net status mask */
- #include <netinet/in.h> /* for sockaddr_in */
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <sys/ioctl.h>
- #include <stdio.h>
- #define MAX_INTERFACE (16)
- void port_status(unsigned int flags);
- /* set == 0: do clean , set == 1: do set! */
- int set_if_flags(char *pif_name, int sock, int status, int set)
- {
- struct ifreq ifr;
- int ret = 0;
- strncpy(ifr.ifr_name, pif_name, strlen(pif_name) + 1);
- ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
- if(ret)
- return -1;
- /* set or clean */
- if(set)
- ifr.ifr_flags |= status;
- else
- ifr.ifr_flags &= ~status;
- /* set flags */
- ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
- if(ret)
- return -1;
- return 0;
- }
- int get_if_info(int fd)
- {
- struct ifreq buf[MAX_INTERFACE];
- struct ifconf ifc;
- int ret = 0;
- int if_num = 0;
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = (caddr_t) buf;
- ret = ioctl(fd, SIOCGIFCONF, (char*)&ifc);
- if(ret)
- {
- printf("get if config info failed");
- return -1;
- }
- /* 網口總數 ifc.ifc_len 應該是一個出入參數 */
- if_num = ifc.ifc_len/sizeof(struct ifreq);
- printf("interface num is interface = %d\n", if_num);
- while(if_num-- > 0)
- {
- printf("net device: %s\n", buf[if_num].ifr_name);
- /* 獲取第n個網口信息 */
- ret = ioctl(fd, SIOCGIFFLAGS, (char*)&buf[if_num]);
- if(ret)
- continue;
- /* 獲取網口狀態 */
- port_status(buf[if_num].ifr_flags);
- /* 獲取當前網卡的ip地址 */
- ret = ioctl(fd, SIOCGIFADDR, (char*)&buf[if_num]);
- if(ret)
- continue;
- printf("IP address is: \n%s\n", inet_ntoa(((struct sockaddr_in *)(&buf[if_num].ifr_addr))->sin_addr));
- /* 獲取當前網卡的mac */
- ret = ioctl(fd, SIOCGIFHWADDR, (char*)&buf[if_num]);
- if(ret)
- continue;
- printf("%02x:%02x:%02x:%02x:%02x:%02x\n\n",
- (unsigned char)buf[if_num].ifr_hwaddr.sa_data[0],
- (unsigned char)buf[if_num].ifr_hwaddr.sa_data[1],
- (unsigned char)buf[if_num].ifr_hwaddr.sa_data[2],
- (unsigned char)buf[if_num].ifr_hwaddr.sa_data[3],
- (unsigned char)buf[if_num].ifr_hwaddr.sa_data[4],
- (unsigned char)buf[if_num].ifr_hwaddr.sa_data[5]
- );
- }
- }
- void port_status(unsigned int flags)
- {
- if(flags & IFF_UP)
- {
- printf("is up\n");
- }
- if(flags & IFF_BROADCAST)
- {
- printf("is broadcast\n");
- }
- if(flags & IFF_LOOPBACK)
- {
- printf("is loop back\n");
- }
- if(flags & IFF_POINTOPOINT)
- {
- printf("is point to point\n");
- }
- if(flags & IFF_RUNNING)
- {
- printf("is running\n");
- }
- if(flags & IFF_PROMISC)
- {
- printf("is promisc\n");
- }
- }
- int main()
- {
- int fd;
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if(fd > 0)
- {
- get_if_info(fd);
- close(fd);
- }
- return 0;
- }
運行結果:
interface num is interface = 2
net device: eth0
is up
is broadcast
is running
IP address is:
192.168.100.200
54:be:f7:33:57:26
net device: lo
is up
is loop back
is running
IP address is:
127.0.0.1
00:00:00:00:00:00
struct ifreq學習和實例