如何使用libnl和netlink套接字以编程方式将设备连接到AP?
我正在创建一个C库,该C库管理我的嵌入式设备的许多外围设备. S.O.使用的是由yocto编译的Linux发行版.我正在尝试通过netlink(使用libnl命令)进行一些功能以将设备连接至wifi(众所周知的)路由器.在此社区的帮助下,我开发了一种功能扫描该区域中的路由器.某些人知道如何使用libnl命令将我的设备连接到路由器wifi? 我开发了以下代码,尝试连接到名为"Validator_Test"(没有身份验证密码)的AP.该软件未返回任何错误,但我的设备仍然与AP断开连接.你们中有些人知道我的代码有什么问题吗?不幸的是,我没有找到此操作的任何示例或文档.
I'm creating a C library that manages a lot of peripherical of my embedded device. The S.O. used, is a Linux distro compiled with yocto. I'm trying to make some functions to connect my device to wifi (well-know) router, with netlink (using the libnl commands). With the help of this community, I've developed a function able to scan the routers in the area. Some of you know how to use the libnl command to connecting my device to router wifi? I've developed the following code, that tries to connect to an AP called "Validator_Test" (that have no authentication password). The software return no error, but my device still remain disconnected from the AP. Some of you know what is wrong in my code? Unfortunately, i've not found any example or documentation for this operation.
static int ap_conn() {
struct nl_msg *msg = nlmsg_alloc();
int if_index = if_nametoindex("wlan0"); // Use this wireless interface for scanning.
// Open socket to kernel.
struct nl_sock *socket = nl_socket_alloc(); // Allocate new netlink socket in memory.
genl_connect(socket); // Create file descriptor and bind socket.
int driver_id = genl_ctrl_resolve(socket, "nl80211"); // Find the nl80211 driver ID.
genlmsg_put(msg, 0, 0, driver_id, 0, (NLM_F_REQUEST | NLM_F_ACK), NL80211_CMD_CONNECT, 0);
nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index); // Add message attribute, which interface to use.
nla_put(msg, NL80211_ATTR_SSID, strlen("Validator_Test"), "Validator_Test");
nla_put(msg, NL80211_ATTR_MAC, strlen("00:1e:42:21:e4:e9"), "00:1e:42:21:e4:e9");
int ret = nl_send_auto_complete(socket, msg); // Send the message.
printf("NL80211_CMD_CONNECT sent %d bytes to the kernel.\n", ret);
ret = nl_recvmsgs_default(socket); // Retrieve the kernel's answer. callback_dump() prints SSIDs to stdout.
nlmsg_free(msg);
if (ret < 0) {
printf("ERROR: nl_recvmsgs_default() returned %d (%s).\n", ret, nl_geterror(-ret));
return ret;
}
nla_put_failure:
return -ENOSPC;
}
谢谢大家!
感谢代码.
根据您的代码,我在此处进行了修改并进行了测试;有用. 源代码位于: https://github.com/neojou/nl80211/blob/master/test_connect/src/test_connect_nl80211.c
Based on your code, I modified and did the test here; it works. The source code is at: https://github.com/neojou/nl80211/blob/master/test_connect/src/test_connect_nl80211.c
一些建议:
-
确保测试环境正确
Make sure the test environment is correct
在测试代码之前,也许您可以尝试使用iw进行测试. iw是开源工具,它也使用netlink. 您可以输入"sudo iw wlan0 connect Validator_Test" 然后使用iwconfig首先查看它是否已连接. (假设您所说的AP上没有安全设置)
Before test the code, maybe you can try to use iw to do the test. iw is the open source tool, which uses netlink also. you can type "sudo iw wlan0 connect Validator_Test" and then use iwconfig to see if it is connected or not first. ( Suppose there is no security setting at the AP as you said )
您的源代码和我的源代码之间有两个区别
there are two differences between your source code and mine
(1)不需要设置NL80211_ATTR_MAC
(1) don't need to set NL80211_ATTR_MAC
(2)ret = nl_recvmsgs_default(socket);
(2) ret = nl_recvmsgs_default(socket);
不确定是否对ap_conn()的返回值有任何判断, 但是当nl_recvmsgs_default()返回0时,在ap_conn()中返回0似乎更好.
not sure if there is any judgement of the return value of your ap_conn(), but it seems better to return 0 in ap_conn(), when nl_recvmsgs_default() returns 0.