在Android上订阅NetLink(NL80211)MLMME多播组

时间:2019-03-28 15:08:30

标签: android events netlink

我正在尝试在Android中使用C订阅mlme事件,但是在用户区中未收到NL80211_CMD_FRAME事件。

我已经使用libgenl构建了libnl-3,并将其复制到Android中的/ system / lib中,以便能够使用它。

这是用于创建netlink套接字的功能

int initNetlink(struct Netlink *netlink, struct nlInterface *interface) {

    interface->ifIndex = if_nametoindex(interface->ifname);
    //printf("[+] %s index: %d\r\n", interface->ifname, interface->ifIndex);

    //Abre un socket Netlink
    netlink->socket = nl_socket_alloc();
    if (!netlink->socket) {
        fprintf(stderr, "Failed to allocate netlink socket.\n");
        return 1;
    } else
        printf("Socket NETLINK abierto\r\n");

    nl_socket_set_buffer_size(netlink->socket, 8192, 8192);

    //Conectamos con el socket
    if (genl_connect(netlink->socket)) {
        fprintf(stderr, "Failed to connect to netlink socket.\n");
        nl_close(netlink->socket);
        nl_socket_free(netlink->socket);
        return 1;
    } else
        printf("Socket NETLINK conectado\r\n");

    //Conectamos con el canal de control nl80211
    netlink->id = genl_ctrl_resolve(netlink->socket, "nl80211");
    if (netlink->id< 0) {
        fprintf(stderr, "Nl80211 interface not found.\n");
        nl_close(netlink->socket);
        nl_socket_free(netlink->socket);
        return 1;
    } else
        printf("Socket NETLINK conectado con wlan0\r\n");

    netlink->event_cb = nl_cb_alloc(NL_CB_DEBUG);
    nl_cb_set(netlink->event_cb, NL_CB_VALID, NL_CB_CUSTOM, &nlCallback, NULL);

    netlink->mc_grp1 = genl_ctrl_resolve_grp(netlink->socket, "nl80211", "mlme");// will return 5.
    if (netlink->mc_grp1 < 0) {
        printf("main(): ERROR : MLME group not found : %d\n", netlink->mc_grp1);
        return 1;
    } else
        printf("[+] Subscribed to MLME group %d\r\n",netlink->mc_grp1);

    netlink->mc_grp2 = genl_ctrl_resolve_grp(netlink->socket, "nl80211", "scan");// will return 3.
    if (netlink->mc_grp2 < 0) {
        printf("main(): ERROR : SCAN group not found : %d\n", netlink->mc_grp2);
        return 1;
    } else
        printf("[+] Resolved Scan group to %d\r\n",netlink->mc_grp2);
    printf("[+] Subcribed group ids:: MLME: %d, SCAN: %d\n",netlink->mc_grp1, netlink->mc_grp2);
    int ret = nl_socket_add_memberships(netlink->socket, netlink->mc_grp1, netlink->mc_grp2, 0);
    if (ret < 0) {
        printf("main(): ERROR : Unable to join multicast group %d\n", ret);
        return 1;
    }

    nl_socket_disable_seq_check(netlink->socket);

    return netlink->id;
}

创建套接字后,我注册了probeRequests

int register4probeReq(struct Netlink* netlink, struct nlInterface* interface) {
    printf("Registering probe requests\r\n");

    netlink->result = 1;

    struct nl_msg* msg = nlmsg_alloc();
    if (!msg) {
        fprintf(stderr, "Failed to allocate netlink message.\n");
        return -2;
    }

    genlmsg_put(msg,
                0,
                0,
                netlink->id,
                0,
                0,
                NL80211_CMD_REGISTER_ACTION,
                0);

    nla_put_u32(msg, NL80211_ATTR_IFINDEX, interface->ifIndex);
    nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_PROBE_REQ << 4));
    nla_put(msg, NL80211_ATTR_FRAME_MATCH, 0, NULL);
    printf("Sending Message\r\n");
    int ret = nl_send_auto_complete(netlink->socket, msg);
    int err = 1;

    printf("Registering Callbacks\r\n");
    nl_cb_err(netlink->event_cb, NL_CB_CUSTOM, error_handler, &err);
    nl_cb_set(netlink->event_cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
    nl_cb_set(netlink->event_cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
    nl_cb_set(netlink->event_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
/*
    int ret = nl_send_auto(netlink->socket, msg);  // Send the message.
    while (err > 0) ret = nl_recvmsgs(netlink->socket, netlink->cb3);  // First wait for ack_handler(). This helps with basic errors.

    //printf("----------------------- Recibiendo respuesta\r\n");
*/
    printf("Liberando el mensaje\r\n");
    nlmsg_free(msg);

    return 0;
}

然后,我修改了Callback,然后进入一个无限循环以询问新消息:

int ret = nl_socket_modify_cb(netlink.socket, NL_CB_VALID, NL_CB_CUSTOM, &nlCallback, &config);
if (ret < 0) {
    printf(" main(): ERROR : Unable to register callback %d\n", ret);
    exit(1);
}



while (1) {
    int ret = nl_recvmsgs_default(netlink.socket);
    if (ret < 0) {
        return 0;
    }

}

我的第一个疑问与多播组ID有关,在Ubuntu中,多播组为:

  • 7-> MLME
  • 5->扫描

但是在Android中,他们会获得不同的组ID

  • 5-> MLME
  • 3->扫描

我不知道他们是否应该具有相同的组ID

我发现的另一个想法是我的Android适配器通过iw工具报告了此信息:

  

支持的RX帧类型:

   * IBSS: 0xd0
   * managed: 0x40 0xd0
   * AP: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
   * AP/VLAN: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
   * P2P-client: 0x40 0xd0
   * P2P-GO: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
   * P2P-device: 0x40 0xd0

我的Ubuntu适配器报告了这一点:

  

支持的RX帧类型:

   * IBSS: 0x40 0xb0 0xc0 0xd0
   * managed: 0x40 0xd0
   * AP: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
   * AP/VLAN: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
   * mesh point: 0xb0 0xc0 0xd0
   * P2P-client: 0x40 0xd0
   * P2P-GO: 0x00 0x20 0x40 0xa0 0xb0 0xc0 0xd0
   * P2P-device: 0x40 0xd0

唯一的区别是,在IBSS模式下,适配器不接收0x4帧(我正在寻找的帧),但是适配器在iw报告时处于托管模式。

netlink和nl80211是否在Android和常规linux上以相同的方式工作?在我的Android内核中,禁用了mlme的nl80211调试功能,但是我认为这可能不是问题所在。

我需要在AOSP中使用netlink库吗?

要使其在Android上正常工作,我还应该做些其他事情吗?

0 个答案:

没有答案