iwlist
iwlist主要用来显示无线网卡的一些附加信息。
iwlist的用法:
useage: iwlist [interface] options
scanning 扫描一定范围内的无线接入点和Ad-Hoc单元信息,包括ESSID,信号质量,频段以及无线模式等
frequency 频率
channel显示设备支持的频道及当前所在的频道
rate/bitrate 设备支持的速率
encryption 加密
key 密钥
power 电源
txpower 发送功率
retry 重传机制
ap 本地无线接入点及信号质量
peers 直连
event 设备支持的无线事件
auth 当前设置的WPA认证参数
wpa 罗列设备上设置的所有WPA加密密钥
modu 罗列设备支持的调制模式及当前开启的调制模式
iwlist中的main函数,内容如下:
/*------------------------------------------------------------------*/
/*
* The main !
*/
int
main(int argc,
char ** argv)
{
int skfd; /* generic raw socket desc. */
char *dev; /* device name */
char *cmd; /* command */
char **args; /* Command arguments */
int count; /* Number of arguments */
const iwlist_cmd *iwcmd;
if(argc < 2)
iw_usage(1);
/* Those don't apply to all interfaces */
if((argc == 2) && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")))
iw_usage(0);
if((argc == 2) && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version")))
return(iw_print_version_info("iwlist"));
if(argc == 2)
{
cmd = argv[1];
dev = NULL;
args = NULL;
count = 0;
}
else
{
cmd = argv[2];
dev = argv[1];
args = argv + 3;
count = argc - 3;
}
/* find a command */
iwcmd = find_command(cmd);
if(iwcmd == NULL)
return 1;
/* Check arg numbers */
if((iwcmd->max_count >= 0) && (count > iwcmd->max_count))
{
fprintf(stderr, "iwlist: command `%s' needs fewer arguments (max %d)\n",
iwcmd->cmd, iwcmd->max_count);
return 1;
}
/* Create a channel to the NET kernel. */
if((skfd = iw_sockets_open()) < 0)
{
perror("socket");
return -1;
}
/* do the actual work */
if (dev)
(*iwcmd->fn)(skfd, dev, args, count);
else
iw_enum_devices(skfd, iwcmd->fn, args, count);
/* Close the socket. */
iw_sockets_close(skfd);
return 0;
}
iw_sockets_open
函数,该函数创建了iwlist命令使用的套接字。
iw_enum_devices
函数,该函数和iwconfig中的一样,也是在缺少参数的情况下打印出无线设备接口的配置信息。
iwlist_cmd
是定义的iwlist_entry
结构体数组,定义内容如下:
static const struct iwlist_entry iwlist_cmds[] = {
{ "scanning", print_scanning_info, -1, "[essid NNN] [last]" },
{ "frequency", print_freq_info, 0, NULL },
{ "channel", print_freq_info, 0, NULL },
{ "bitrate", print_bitrate_info, 0, NULL },
{ "rate", print_bitrate_info, 0, NULL },
{ "encryption", print_keys_info, 0, NULL },
{ "keys", print_keys_info, 0, NULL },
{ "power", print_pm_info, 0, NULL },
#ifndef WE_ESSENTIAL
{ "txpower", print_txpower_info, 0, NULL },
{ "retry", print_retry_info, 0, NULL },
{ "ap", print_ap_info, 0, NULL },
{ "accesspoints", print_ap_info, 0, NULL },
{ "peers", print_ap_info, 0, NULL },
{ "event", print_event_capa_info, 0, NULL },
{ "auth", print_auth_info, 0, NULL },
{ "wpakeys", print_wpakeys_info, 0, NULL },
{ "genie", print_gen_ie_info, 0, NULL },
{ "modulation", print_modul_info, 0, NULL },
#endif /* WE_ESSENTIAL */
{ NULL, NULL, 0, 0 },
};
iwlist_entry
结构体定义了命令行参数条目,和调用了iw_enum_handler
函数。其中scanning调用的print_scanning_info
函数,内容如下:
/*------------------------------------------------------------------*/
/*
* Perform a scanning on one device
*/
static int
print_scanning_info(int skfd,
char * ifname,
char * args[], /* Command line args */
int count) /* Args count */
{
struct iwreq wrq;
struct iw_scan_req scanopt; /* Options for 'set' */
int scanflags = 0; /* Flags for scan */
unsigned char * buffer = NULL; /* Results */
int buflen = IW_SCAN_MAX_DATA; /* Min for compat WE<17 */
struct iw_range range;
int has_range;
struct timeval tv; /* Select timeout */
int timeout = 15000000; /* 15s */
/* Avoid "Unused parameter" warning */
args = args; count = count;
/* Debugging stuff */
if((IW_EV_LCP_PK2_LEN != IW_EV_LCP_PK_LEN) || (IW_EV_POINT_PK2_LEN != IW_EV_POINT_PK_LEN))
{
fprintf(stderr, "*** Please report to jt@hpl.hp.com your platform details\n");
fprintf(stderr, "*** and the following line :\n");
fprintf(stderr, "*** IW_EV_LCP_PK2_LEN = %zu ; IW_EV_POINT_PK2_LEN = %zu\n\n",
IW_EV_LCP_PK2_LEN, IW_EV_POINT_PK2_LEN);
}
/* Get range stuff */
has_range = (iw_get_range_info(skfd, ifname, &range) >= 0);
/* Check if the interface could support scanning. */
if((!has_range) || (range.we_version_compiled < 14))
{
fprintf(stderr, "%-8.16s Interface doesn't support scanning.\n\n",
ifname);
return(-1);
}
/* Init timeout value -> 250ms between set and first get */
tv.tv_sec = 0;
tv.tv_usec = 250000;
/* Clean up set args */
memset(&scanopt, 0, sizeof(scanopt));
/* Parse command line arguments and extract options.
* Note : when we have enough options, we should use the parser
* from iwconfig... */
while(count > 0)
{
/* One arg is consumed (the option name) */
count--;
/*
* Check for Active Scan (scan with specific essid)
*/
if(!strncmp(args[0], "essid", 5))
{
if(count < 1)
{
fprintf(stderr, "Too few arguments for scanning option [%s]\n",
args[0]);
retu