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);
};
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 info\n"
" iwinfo scan\n"
" iwinfo txpowerlist\n"
" iwinfo freqlist\n"
" iwinfo assoclist\n"
" iwinfo 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 info
break;
case 's':
print_scanlist(iw, argv[1]); //iwinfo scan
break;
case 't':
print_txpwrlist(iw, argv[1]); //iwinfo txpowerlist
break;
case 'f':
print_freqlist(iw, argv[1]); //iwinfo freqlist
break;
case 'a':
print_assoclist(iw, argv[1]); //iwinfo assoclist
break;
case 'c':
print_countrylist(iw, argv[1]); //iwinfo countrylist
break;
default:
fprintf(stderr, "Unknown command: %s\n", argv[i]);
return 1;
}
}
//关闭socket
iwinfo_finish();
return 0;
}
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,
};
以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));
}
}