1. iwconfig代码框架
一、基本概念
iwconfig 作用域WLAN层,和ifconfig类似, 但仅作用于80211设备。
射频层不支持iwconfig。
二、主要接口
iw_sockets_open //函数根据不同的协议创建对应的socket,以便和无线设备驱动进行交互。 iw_enum_devices //当输入的一个参入时,则罗列出全部接口,如果是网络接口,则输出网络接口状态信息。 print_info //获取参数信息传入后,打印出与参数对应的需求信息。 set_info //设置参数输入后,进行ioctl操作,向无线设备驱动传参,并生效。
三、数据结构体
/* * The structure to exchange data for ioctl. * This structure is the same as 'struct ifreq', but (re)defined for * convenience... * Do I need to remind you about structure size (32 octets) ? */ struct iwreq { union { char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" 接口名称*/ } ifr_ifrn; /* Data part (defined just above) */ union iwreq_data u; //存放数据的地方 };
/* ------------------------ IOCTL REQUEST ------------------------ */ /* * This structure defines the payload of an ioctl, and is used * below. * * Note that this structure should fit on the memory footprint * of iwreq (which is the same as ifreq), which mean a max size of * 16 octets = 128 bits. Warning, pointers might be 64 bits wide... * You should check this when increasing the structures defined * above in this file... */ union iwreq_data { /* Config - generic */ char name[IFNAMSIZ]; /* Name : used to verify the presence of wireless extensions. * Name of the protocol/provider... */ struct iw_point essid; /* Extended network name */ struct iw_param nwid; /* network id (or domain - the cell) */ struct iw_freq freq; /* frequency or channel : * 0-1000 = channel * > 1000 = frequency in Hz */ struct iw_param sens; /* signal level threshold */ struct iw_param bitrate; /* default bit rate */ struct iw_param txpower; /* default transmit power */ struct iw_param rts; /* RTS threshold threshold */ struct iw_param frag; /* Fragmentation threshold */ __u32 mode; /* Operation mode */ struct iw_param retry; /* Retry limits & lifetime */ struct iw_point encoding; /* Encoding stuff : tokens */ struct iw_param power; /* PM duration/timeout */ struct iw_quality qual; /* Quality part of statistics */ struct sockaddr ap_addr; /* Access point address */ struct sockaddr addr; /* Destination address (hw/mac) */ struct iw_param param; /* Other small parameters */ struct iw_point data; /* Other large parameters */ };
四、接口解析
1. iw_enum_device
1 /*------------------------------------------------------------------*/ 2 /* 3 * Enumerate devices and call specified routine 4 * The new way just use /proc/net/wireless, so get all wireless interfaces, 5 * whether configured or not. This is the default if available. 6 * The old way use SIOCGIFCONF, so get only configured interfaces (wireless 7 * or not). 8 */ 9 void 10 iw_enum_devices(int skfd, 11 iw_enum_handler fn, 12 char * args[], 13 int count) 14 { 15 char buff[1024]; 16 FILE * fh; 17 struct ifconf ifc; 18 struct ifreq *ifr; 19 int i; 20 21 #ifndef IW_RESTRIC_ENUM 22 /* Check if /proc/net/dev is available */ 23 fh = fopen(PROC_NET_DEV, "r"); 24 #else 25 /* Check if /proc/net/wireless is available */ 26 fh = fopen(PROC_NET_WIRELESS, "r"); 27 #endif 28 29 if(fh != NULL) 30 { 31 /* Success : use data from /proc/net/wireless */ 32 33 /* Eat 2 lines of header 跳过2行开头 */ 34 fgets(buff, sizeof(buff), fh); 35 fgets(buff, sizeof(buff), fh); 36 37 /* Read each device line */ 38 while(fgets(buff, sizeof(buff), fh)) 39 { 40 char name[IFNAMSIZ + 1]; 41 char *s; 42 43 /* Skip empty or almost empty lines. It seems that in some 44 * cases fgets return a line with only a newline. 跳过空行 */ 45 if((buff[0] == '\0') || (buff[1] == '\0')) 46 continue; 47 48 /* Extract interface name 获取接口名称 easy skip */ 49 s = iw_get_ifname(name, sizeof(name), buff); 50 51 if(!s) 52 { 53 /* Failed to parse, complain and continue */ 54 #ifndef IW_RESTRIC_ENUM 55 fprintf(stderr, "Cannot parse " PROC_NET_DEV "\n"); 56 #else 57 fprintf(stderr, "Cannot parse " PROC_NET_WIRELESS "\n"); 58 #endif 59 } 60 else 61 /* Got it, print info about this interface */ 62 (*fn)(skfd, name, args, count); 63 } 64 65 fclose(fh); 66 } 67 else 68 { 69 /* Get list of configured devices using "traditional" way */ 70 ifc.ifc_len = sizeof(buff); 71 ifc.ifc_buf = buff; 72 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0) 73 { 74 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno)); 75 return; 76 } 77 ifr = ifc.ifc_req; 78 79 /* Print them */ 80 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)c 81 (*fn)(skfd, ifr->ifr_name, args, count); 82 } 83 }
从代码和图片可以看到,iwconfig列出来的所有接口是从/proc/dev/net 这个文件中读出来的。