一、首先认识一个iwinfo_ops结构体(include/iwinfo.h),初始化的时候该结构体指针就会指向对应网卡驱动的结构
struct iwinfo_ops {
const char *name;
int (*mode)(const char *, int *);
int (*channel)(const char *, int *);
int (*frequency)(const char *, int *);
int (*frequency_offset)(const char *, int *);
int (*txpower)(const char *, int *);
int (*txpower_offset)(const char *, int *);
int (*bitrate)(const char *, int *);
int (*signal)(const char *, int *);
int (*noise)(const char *, int *);
int (*quality)(const char *, int *);
int (*quality_max)(const char *, int *);
int (*mbssid_support)(const char *, int *);
int (*hwmodelist)(const char *, int *);
int (*ssid)(const char *, char *);
int (*bssid)(const char *, char *);
int (*country)(const char *, char *);
int (*hardware_id)(const char *, char *);
int (*hardware_name)(const char *, char *);
int (*encryption)(const char *, char *);
int (*assoclist)(const char *, char *, int *);
int (*txpwrlist)(const char *, char *, int *);
int (*scanlist)(const char *, char *, int *);
int (*freqlist)(const char *, char *, int *);
int (*countrylist)(const char *, char *, int *);
int (*beacon_int)(const char *, int *);
void (*close)(void);
};
二、iwinfo源码:
1)、入口文件iwinfo_cli.c
int main(int argc, char **argv)
{
int i;
char *p;
//定义一个iwinfo_ops结构指针iw
const struct iwinfo_ops *iw;
glob_t globbuf;
//命令行参数为2个时候提示命令输入格式
if (argc > 1 && argc < 3)
{
fprintf(stderr,
"Usage:\n"
" iwinfo <device> info\n"
" iwinfo <device> scan\n"
" iwinfo <device> txpowerlist\n"
" iwinfo <device> freqlist\n"
" iwinfo <device> assoclist\n"
" iwinfo <device> countrylist\n"
);
return 1;
}
//命令行只有iwinfo时候执行glob函数,遍历/sys/class/net/下的device并将所有可用的device信息打印
if (argc == 1)
{
glob("/sys/class/net/*", 0, NULL, &globbuf);
for (i = 0; i < globbuf.gl_pathc; i++)
{
p = strrchr(globbuf.gl_pathv[i], '/');
if (!p)
continue;
iw = iwinfo_backend(++p);
if (!iw)
continue;
print_info(iw, p);
printf("\n");
}
globfree(&globbuf);
return 0;
}
//参数在三个以上
//iwinfo_backend初始化并获取对应device驱动的iwinfo_ops结构指针iw
iw = iwinfo_backend(argv[1]);
if (!iw)
{
fprintf(stderr, "No such wireless device: %s\n", argv[1]);
return 1;
}
for (i = 2; i < argc; i++)
{
switch(argv[i][0]) //只匹配第一个字母 所以用iwinfo wlan0 s 也就等于 iwinfo wlan0 scan
{
case 'i':
print_info(iw, argv[1]); //iwinfo <device> info
break;
case 's':
print_scanlist(iw, argv[1]); //iwinfo <device> scan
break;
case 't':
print_txpwrlist(iw, argv[1]); //iwinfo <device> txpowerlist
break;
case 'f':
print_freqlist(iw, argv[1]); //iwinfo <device> freqlist
break;
case 'a':
print_assoclist(iw, argv[1]); //iwinfo <device> assoclist
break;
case 'c':
print_countrylist(iw, argv[1]); //iwinfo <device> countrylist
break;
default:
fprintf(stderr, "Unknown command: %s\n", argv[i]);
return 1;
}
}
//关闭socket
iwinfo_finish();
return 0;
}
2)、关于入口函数iwinfo_backend(argv[1])说明:
iwinfo_backend()函数来初始化并获取对应驱动的iwinfo_ops结构指针,文件 iwinfo_lib.c
const struct iwinfo_ops * iwinfo_backend(const char *ifname)
{
int i;
for (i = 0; i < ARRAY_SIZE(backends); i++)
if (backends[i]->probe(ifname))
return backends[i]; //返回ifname的ops
return NULL;
}
封装了nl80211、madwifi、qcawifi、wl_ops等驱动接口,然后将这些接口封装成统一的API接口
static const struct iwinfo_ops *backends[] = {
#ifdef USE_NL80211
&nl80211_ops,
#endif
#ifdef USE_MADWIFI
&madwifi_ops,
#endif
#ifdef USE_WL
&wl_ops,
#endif
&wext_ops,
};
3)、iwinfo mesh0 XXX(cmd) 命令执行函数
以iwinfo mesh0 assoclist 命令为例
/********************************************
-
iwinfo mesh0 assoclist 命令执行函数
-
参数
-
iw: 获取对应驱动的iwinfo_ops结构指针
-
ifname: device
-
******************************************/
static void print_assoclist(const struct iwinfo_ops *iw, const char *ifname)
{
int i, len;
char buf[IWINFO_BUFSIZE];
struct iwinfo_assoclist_entry *e;if (iw->assoclist(ifname, buf, &len))
{
printf(“No information available\n”);
return;
}
else if (len <= 0)
{
printf(“No station connected\n”);
return;
}for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry))
{
e = (struct iwinfo_assoclist_entry *) &buf[i];printf("%s %s / %s (SNR %d) %d ms ago\n", format_bssid(e->mac), format_signal(e->signal), format_noise(e->noise), (e->signal - e->noise), e->inactive); printf(" RX: %-38s %8d Pkts.\n", format_assocrate(&e->rx_rate), e->rx_packets ); printf(" TX: %-38s %8d Pkts.\n", format_assocrate(&e->tx_rate), e->tx_packets ); printf(" TX: %-38s %8d Pkts.\n", format_assocrate(&e->tx_rate), e->tx_packets ); printf(" expected throughput: %s\n\n", format_rate(e->thr));
}
}