linux获取网络接口信息需要用到的函数为ioctl(),结构体struct ifreq,struct ifconf
1.ioctl()函数原型及作用
1 #include <sys/ioctl.h> 2 3 int ioctl(int d, int request, ...); 4 5 //参数 6 //int d:是一个文件描述符 7 //int request :表示要请求的信息。如IP地址、网络掩码等 8 //......:可变参数,根据request而定
下面是ioctl请求的request参数以及arg地址必须指向的数据类型:
2.struct ifreq结构体
这个结构定义在include/net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的
1 /* Interface request structure used for socket ioctl‘s. All interface 2 ioctl‘s must have parameter definitions which begin with ifr_name. 3 The remainder may be interface specific. */ 4 5 struct ifreq 6 { 7 # define IFHWADDRLEN 6 8 # define IFNAMSIZ IF_NAMESIZE 9 union 10 { 11 char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */ 12 } ifr_ifrn; 13 14 union 15 { 16 struct sockaddr ifru_addr; 17 struct sockaddr ifru_dstaddr; 18 struct sockaddr ifru_broadaddr; 19 struct sockaddr ifru_netmask; 20 struct sockaddr ifru_hwaddr; 21 short int ifru_flags; 22 int ifru_ivalue; 23 int ifru_mtu; 24 struct ifmap ifru_map; 25 char ifru_slave[IFNAMSIZ]; /* Just fits the size */ 26 char ifru_newname[IFNAMSIZ]; 27 __caddr_t ifru_data; 28 } ifr_ifru; 29 }; 30 # define ifr_name ifr_ifrn.ifrn_name /* interface name */ 31 # define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ 32 # define ifr_addr ifr_ifru.ifru_addr /* address */ 33 # define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */ 34 # define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ 35 # define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ 36 # define ifr_flags ifr_ifru.ifru_flags /* flags */ 37 # define ifr_metric ifr_ifru.ifru_ivalue /* metric */ 38 # define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ 39 # define ifr_map ifr_ifru.ifru_map /* device map */ 40 # define ifr_slave ifr_ifru.ifru_slave /* slave device */ 41 # define ifr_data ifr_ifru.ifru_data /* for use by interface */ 42 # define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */ 43 # define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */ 44 # define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */ 45 # define ifr_newname ifr_ifru.ifru_newname /* New name */ 46 # define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0) 47 # define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0) 48 # define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
3.struct ifconf
ifreq包含在ifconf结构中。而ifconf结构通常是用来保存所有接口的信息的。
1 /* Structure used in SIOCGIFCONF request. Used to retrieve interface 2 configuration for machine (useful for programs which must know all 3 networks accessible). */ 4 5 struct ifconf 6 { 7 int ifc_len; /* Size of buffer. */ 8 union 9 { 10 __caddr_t ifcu_buf; 11 struct ifreq *ifcu_req; 12 } ifc_ifcu; 13 }; 14 # define ifc_buf ifc_ifcu.ifcu_buf /* Buffer address. */ 15 # define ifc_req ifc_ifcu.ifcu_req /* Array of structures. */ 16 # define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0) /* not right */ 17 #endif /* Misc. */
下面程序是获取本机的IP地址
1 #include <stdio.h> 2 #include <sys/socket.h> 3 #include <string.h> 4 #include <sys/types.h> 5 #include <netinet/in.h> 6 #include <sys/ioctl.h> 7 #include <net/if.h> 8 9 //#define ETH_NAME "eth0" 10 //#define NET_NAME "wlan1" 11 12 int main(int argc, char *argv[]) 13 { 14 if(argc != 2) { 15 printf("using %s <ETH_NAME>\n", argv[0]); 16 return 0; 17 } 18 19 int sock = 0; 20 struct sockaddr_in sin; 21 struct ifreq ifr;//用来保存接口的信息 22 23 sock = socket(AF_INET, SOCK_DGRAM, 0); 24 if(sock == -1) { 25 perror("socket"); 26 return 1; 27 } 28 29 strcpy(ifr.ifr_name, argv[1]); 30 int ret = ioctl(sock, SIOCGIFADDR, &ifr);//SIOCGIFADDR 获取接口地址 31 if(ret < 0) { 32 perror("ioctl"); 33 return 1; 34 } 35 36 memcpy(&sin, &ifr.ifr_addr, sizeof(sin));//将获得地址拷贝到 sockaddr_in 结构体中 37 printf("%s\n", inet_ntoa(sin.sin_addr));//显示 38 return 0; 39 40 }
运行结果如下:
时间: 2024-10-10 20:41:36