我正在尝试在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中,多播组为:
但是在Android中,他们会获得不同的组ID
我不知道他们是否应该具有相同的组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上正常工作,我还应该做些其他事情吗?