Я пытаюсь подписаться на события 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 группы многоадресной рассылки:
Но в Android они получают другой идентификатор группы
Я не знаю, должны ли они иметь одинаковый идентификатор группы
И еще одна мысль, которую я обнаружил, заключается в том, что мой 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?