C语言获取无线连接状态(Wireless Linux)
一、概述
在linux当中,当本端是STA时,有很多获取无线连接状态的方法,比如说
1. ifconfig获取STA网卡的IP,有IP说明连接上,无IP说明没连接上。前提是STA网卡为DHCP,而非static ip;
2. 如果支持wpa_cli,可以进入wpa_cli,输入status命令来查看;
3. 通过iwconfig命令来查看,可以根据Access Point:
的状态来判断,连接成功后会显示对端的MAC地址,不成功会显示Not-Associated
。不过有个缺点,他无法判断鉴权是否成功,如果SSID正确而密钥不正确,会出现短暂的连接成功;
4. cat /proc/net/wireless显示的status状态,status为1时即连接成功,status为0时是未连接,但这个跟iwconfig也是同理,如果SSID正确,密钥不正确,也会出现端在的已连接状态。
root@root:~# cat /proc/net/wireless
Inter-| sta-| Quality | Discarded packets | Missed | WE
face | tus | link level noise | nwid crypt frag retry misc | beacon | 22
wifi0: 0000 0 0 0 0 0 0 0 0 0
ath01: 0000 94. -96. -95. 0 0 0 0 0 0
ath0: 0001 94. -96. -95. 676 0 0 0 0 0
5 参考wpa_cli的实现。如果使用wpa_supplicant作为STA端的鉴权连接管理程序,那么它在运行时,一般会提供socket fd用于其他进程的与之通信,具体需要看运行时的参数,比如:
root@root:~# ps |grep wpa
2296 root 1404 S wpa_supplicant -B -P /var/run/wifi-ath01.pid -D athr -i ath01 -c /var/run/wpa_supplicant-ath01.conf -s
2509 root 1480 S grep wpa
root@root:~#
root@root:~# cat /var/run/wpa_supplicant-ath01.conf
ctrl_interface=/var/run/wpa_supplicant-ath01
......
root@root:~#
看配置,socket fd在/var/run/wpa_supplicant-ath01/
下,因此可以写代码与之通讯,查询当前连接的状态。
还有其他很多方法,不再一一例举了,本文主要想说明,基于方法4的C代码。
二、基于/proc/net/wireless,C代码查看无线状态
/usr/include/linux/wireless.h
中提供iwreq
结构体,利用它制作req通过ioctrl
查询
源码如下:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/wireless.h>
/*
获取无线网卡的连接状态
(/proc/net/wireless的status)
return 0:未连接
return 1:已连接
*/
int get_wireless_if_status(char *ath)
{
int sock_fd;
int ret = 0;
struct iwreq iwr;
struct iw_statistics stats;
if (NULL == ath)
{
printf("ath is NULL/n");
return -1;
}
/* make socket fd */
if ((sock_fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
{
printf("socket err/n");
return -1;
}
/* make iwreq */
memset(&iwr, 0, sizeof(iwr));
memset(&stats, 0, sizeof(stats));
iwr.u.data.pointer = (caddr_t) &stats; /* result value */
iwr.u.data.length = sizeof(stats);
iwr.u.data.flags = 1; /* clear updated flag */
/* ifname is reqired */
strncpy(iwr.ifr_ifrn.ifrn_name, ath, IFNAMSIZ - 1);
/* get SIOCGIWSTATS */
if (ioctl(sock_fd, SIOCGIWSTATS, &iwr) < 0)
{
printf("No Such Device %s/n",ath);
close(sock_fd);
return -1;
}
ret = stats.status;
close(sock_fd);
return ret;
}