Подписка на netlink (nl80211) mlme multicast group на Android - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь подписаться на события mlme на Android в C, но в пользовательской области не получено событие NL80211_CMD_FRAME.

Я собрал libnl-3 с помощью libgenl и скопировал их в / system / lib в Android, чтобы иметь возможность использовать его.

Эта функция используется для создания сокета 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;
}

И после этого я изменяю обратный вызов, а затем вхожу в бесконечный цикл, запрашивая новые сообщения:

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;
    }

}

Мое первое сомнение связано с идентификатором группы многоадресной рассылки, в Ubuntu группы многоадресной рассылки:

  • 7 -> MLME
  • 5 -> SCAN

Но в Android они получают другой идентификатор группы

  • 5 -> MLME
  • 3 -> SCAN

Я не знаю, должны ли они иметь одинаковый идентификатор группы

И еще одна мысль, которую я обнаружил, заключается в том, что мой Android-адаптер сообщает об этом из iw tool:

Поддерживаемые типы кадров 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 отладка nl80211 для mlme отключена, но я не думаю, что это может быть проблемой.

Нужно ли использовать библиотеку netlink в AOSP?

Что-нибудь еще, что я должен сделать, чтобы заставить это работать в Android?

...