如何使用nl80211.h在Android上捕获所有Wifi扫描/MLME事件?

如何使用nl80211.h在Android上捕获所有Wifi扫描/MLME事件?,android,wifi,netlink,Android,Wifi,Netlink,我正在尝试在Android上编写一个简单的本机应用程序,通过Netlink MLME和扫描事件捕获所有Wifi相关事件(特别是我需要Wifi扫描、关联、解除关联、身份验证、取消身份验证、漫游等事件) 我开发了一个本机应用程序,并使用adb将其推送到设备(/system/bin),以root用户身份运行。但是,我只有在打开/关闭wifi时才会收到连接/断开事件。我没有收到任何其他事件,如:扫描触发、扫描结果、(DIS)关联、(DE)身份验证、漫游等 我已经分享了下面的代码。你能帮我解决这个问题吗(

我正在尝试在Android上编写一个简单的本机应用程序,通过Netlink MLME和扫描事件捕获所有Wifi相关事件(特别是我需要Wifi扫描、关联、解除关联、身份验证、取消身份验证、漫游等事件)

我开发了一个本机应用程序,并使用adb将其推送到设备(/system/bin),以root用户身份运行。但是,我只有在打开/关闭wifi时才会收到连接/断开事件。我没有收到任何其他事件,如:扫描触发、扫描结果、(DIS)关联、(DE)身份验证、漫游等

我已经分享了下面的代码。你能帮我解决这个问题吗(如果有的话),这样它可以适用于所有Wifi活动?提前谢谢

#include <netlink/netlink.h>
#include <netlink/attr.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <net/if.h>
#include <signal.h>
#include <stdint.h>
#include <linux/nl80211.h>

#define print_err(...) fprintf(stderr, __VA_ARGS__)

static struct nl_sock *sk = NULL;

static int nlCallback(struct nl_msg* msg, void* arg)
{
printf("\n\t nlCallback Start\n");
struct nlmsghdr* ret_hdr = nlmsg_hdr(msg);
struct genlmsghdr *gnlh = nlmsg_data(ret_hdr);

printf("nlCallback: Event Commmand: %d\n", gnlh->cmd);

switch(gnlh->cmd) {
    case NL80211_CMD_TRIGGER_SCAN :
        printf("nlCallback: cmd: NL80211_CMD_TRIGGER_SCAN \n");
        break;
    case NL80211_CMD_SCAN_ABORTED : 
        printf("nlCallback: cmd: NL80211_CMD_SCAN_ABORTED \n");
        break;
    case NL80211_CMD_NEW_SCAN_RESULTS :
        printf("nlCallback: cmd: NL80211_CMD_NEW_SCAN_RESULTS \n");
        break;
    case NL80211_CMD_CONNECT :
        printf("nlCallback: cmd: NL80211_CMD_CONNECT \n");
        break;
    case NL80211_CMD_DISCONNECT :
        printf("nlCallback: cmd: NL80211_CMD_DISCONNECT \n");
        break;
    case NL80211_CMD_NEW_STATION:
        printf("nlCallback: cmd: NL80211_CMD_NEW_STATION \n");
        break;
    case NL80211_CMD_DEL_STATION:
        printf("nlCallback: cmd: NL80211_CMD_DEL_STATION\n");
        break;
    case NL80211_CMD_AUTHENTICATE:
        printf("nlCallback: cmd: NL80211_CMD_AUTHENTICATE\n");
        break;
    case NL80211_CMD_DEAUTHENTICATE:
        printf("nlCallback: cmd: NL80211_CMD_DEAUTHENTICATE\n");
        break;
    case NL80211_CMD_ASSOCIATE:
        printf("nlCallback: cmd: NL80211_CMD_ASSOCIATE\n");
        break;
    case NL80211_CMD_DISASSOCIATE:
        printf("nlCallback: cmd: NL80211_CMD_DISASSOCIATE\n");
        break;
    case NL80211_CMD_ROAM:
        printf("nlCallback: cmd: NL80211_CMD_ROAM\n");
        break;
    default:
        printf("nlCallback: Default multicast event: %d\n", gnlh->cmd);
        return NL_SKIP;
    }

return 0;
}

static int cleanup_and_exit(int ret)
{
if (sk != NULL)
    nl_socket_free(sk);
exit(ret);
}

static void signal_handler(int sig)
{
cleanup_and_exit(EXIT_SUCCESS);
}

int main()
{
printf("\n\t ****** main() Start *******\n");
int ret;
int sk_fd;
fd_set rfds;

signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);

sk = nl_socket_alloc();
if (sk == NULL) {
    print_err(" main(): ERROR : Unable to allocate Netlink socket\n");
    exit(EXIT_FAILURE);
}

ret = genl_connect(sk);
if (ret < 0) {
    print_err(" main(): ERROR : no connect %d\n", ret);
    cleanup_and_exit(EXIT_FAILURE);
}

int mc_grp1 = genl_ctrl_resolve_grp(sk, "nl80211", "mlme");// will return 5.
if (mc_grp1 < 0) {
    print_err("main(): ERROR : MLME group not found : %d\n", mc_grp1);
    cleanup_and_exit(EXIT_FAILURE);
}

int mc_grp2 = genl_ctrl_resolve_grp(sk, "nl80211", "scan");// will return 3.
if (mc_grp2 < 0) {
    print_err("main(): ERROR : SCAN group not found : %d\n", mc_grp2);
    cleanup_and_exit(EXIT_FAILURE);
}

printf("\n\t main() Subcribed group ids:: MLME: %d, SCAN: %d\n", mc_grp1, mc_grp2);
ret = nl_socket_add_memberships(sk, mc_grp1, mc_grp2, 0);
if (ret < 0) {
    print_err("main(): ERROR : Unable to join multicast group %d\n", ret);
    cleanup_and_exit(EXIT_FAILURE);
}

nl_socket_disable_seq_check(sk);
ret = nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, nlCallback, NULL);
if (ret < 0) {
    print_err(" main(): ERROR : Unable to register callback %d\n", ret);
    cleanup_and_exit(EXIT_FAILURE);
}

while (1) {
    printf("\nmain(): While(1): Waiting for MLME/SCAN events \n");
    ret = nl_recvmsgs_default(sk);
    if (ret < 0) {
        cleanup_and_exit(EXIT_FAILURE);
    }
    printf("main(): While(1): MLME/SCAN event received: %d \n", ret);
}

printf("\n\t ****** main() End *******\n");
cleanup_and_exit(EXIT_FAILURE);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义打印错误(…)fprintf(标准、变量、参数)
静态结构nl_sock*sk=NULL;
静态int-nlCallback(结构nl_-msg*msg,void*arg)
{
printf(“\n\t nlCallback Start\n”);
结构nlmsghdr*ret_hdr=nlmsg_hdr(msg);
结构genlmsghdr*gnlh=nlmsg_数据(ret_hdr);
printf(“nlCallback:事件命令:%d\n”,gnlh->cmd);
开关(gnlh->cmd){
案例NL80211\命令\触发\扫描:
printf(“nlCallback:cmd:NL80211_cmd_TRIGGER_SCAN\n”);
打破
案例NL80211\u命令\u扫描\u中止:
printf(“nlCallback:cmd:NL80211_cmd_SCAN_ABORTED\n”);
打破
案例NL80211\u命令\u新建\u扫描\u结果:
printf(“nlCallback:cmd:NL80211_cmd_NEW_SCAN_RESULTS\n”);
打破
案例NL80211\u命令\u连接:
printf(“nlCallback:cmd:NL80211_cmd_CONNECT\n”);
打破
案例NL80211_CMD_断开:
printf(“nlCallback:cmd:NL80211_cmd_DISCONNECT\n”);
打破
案例NL80211_CMD_新_站:
printf(“nlCallback:cmd:NL80211_cmd_NEW_STATION\n”);
打破
案例NL80211_CMD_DEL_车站:
printf(“nlCallback:cmd:NL80211_cmd_DEL_STATION\n”);
打破
案例NL80211_CMD_认证:
printf(“nlCallback:cmd:NL80211_cmd_AUTHENTICATE\n”);
打破
案例NL80211_命令_取消认证:
printf(“nlCallback:cmd:NL80211_cmd_DEAUTHENTICATE\n”);
打破
案例NL80211\U CMD\U合伙人:
printf(“nlCallback:cmd:NL80211_cmd_ASSOCIATE\n”);
打破
案例NL80211_CMD_解除关联:
printf(“nlCallback:cmd:NL80211_cmd_DISASSOCIATE\n”);
打破
案例NL80211_CMD_ROAM:
printf(“nlCallback:cmd:NL80211_cmd_ROAM\n”);
打破
违约:
printf(“nlCallback:默认多播事件:%d\n”,gnlh->cmd);
返回NL_SKIP;
}
返回0;
}
静态整型清理和退出(整型ret)
{
if(sk!=NULL)
无插座(sk);
出口(ret);
}
静态无效信号处理器(int sig)
{
清理和退出(退出成功);
}
int main()
{
printf(“\n\t*******main()Start*********\n”);
int ret;
int sk_fd;
fd_集rfds;
信号(SIGTERM,信号处理器);
信号(SIGINT,信号处理器);
sk=nl_socket_alloc();
if(sk==NULL){
print_err(“main():错误:无法分配Netlink套接字\n”);
退出(退出失败);
}
ret=genl_连接(sk);
如果(ret<0){
打印错误(“main():错误:没有连接%d\n”,ret);
清理和退出(退出失败);
}
int mc_grp1=genl_ctrl_resolve_grp(sk,“nl80211”,“mlme”);//将返回5。
如果(mc_grp1<0){
打印错误(“main():错误:未找到MLME组:%d\n”,mc\U grp1);
清理和退出(退出失败);
}
int mc_grp2=genl_ctrl_resolve_grp(sk,“nl80211”,“scan”);//将返回3。
if(mc_grp2<0){
打印错误(“main():错误:找不到扫描组:%d\n”,mc\U grp2);
清理和退出(退出失败);
}
printf(“\n\t main()子组ID::MLME:%d,扫描:%d\n”,mc\u grp1,mc\u grp2);
ret=nl_套接字_添加_成员资格(sk、mc_grp1、mc_grp2、0);
如果(ret<0){
打印错误(“main():错误:无法加入多播组%d\n”,ret);
清理和退出(退出失败);
}
nl_插座_禁用_顺序检查(sk);
ret=nl_套接字_修改_cb(sk,nl_cb_有效,nl_cb_自定义,nl回调,NULL);
如果(ret<0){
打印错误(“main():错误:无法注册回调%d\n”,ret);
清理和退出(退出失败);
}
而(1){
printf(“\nmain():While(1):等待MLME/扫描事件\n”);
ret=nl_recvmsgs_默认值(sk);
如果(ret<0){
清理和退出(退出失败);
}
printf(“main():While(1):接收到的MLME/扫描事件:%d\n”,ret);
}
printf(“\n\t*******main()End*********\n”);
清理和退出(退出失败);
}