当我意识到它已被删除并且大多数应用程序使用nl80211时,我开始使用iwconfig / ioctl编写代码来处理wifi卡。 我开始阅读它的源代码,但没有文档和代码有点复杂。 如何使用nl80211或libnl进行扫描,关闭/打开,设置卡模式等简单操作? 这就是我从iw开始的:
void set_card_mode(MODE mode, std::string ifname)
{
int skfd = iw_sockets_open();
struct iwreq wrq;
wrq.u.mode = static_cast<unsigned int>(mode);
power_interface(ifname, false);
if(iw_set_ext(skfd, ifname.c_str(), SIOCSIWMODE, &wrq) < 0)
throw std::runtime_error("Can set card mode");
}
MODE get_card_mode(std::string ifname)
{
int skfd = iw_sockets_open();
struct iwreq wrq;
if (iw_get_ext (skfd, ifname.c_str(), SIOCGIWMODE, &wrq) >= 0)
{
return static_cast<MODE>(wrq.u.mode);
}
}
是否有任何等效的iw_get_ext设置/获取wifi接口或任何具有简单功能的api,如“set_mode”或“power_off”?
答案 0 :(得分:1)
我使用以下步骤使用netlink进行扫描
准备并执行NL80211_CMD_GET_SCAN
与NL80211_CMD_GET_SCAN一起注册了回调。 在回调中,原始数据被解析为BSS。 IE被解析为。请参阅nl80211.h中带有NL80211_BSS_MAX,NL80211_ATTR_MAX的枚举。
在处理下一步之前,检查每个netlink调用的返回值。
代码段:
nl_sock* socket = nl_socket_alloc();
genl_connect(socket);
struct nl_msg* msg = nlmsg_alloc();
int driverId = genl_ctrl_resolve(socket, "nl80211");
genlmsg_put(msg, 0, 0, driverId, 0, 0, NL80211_CMD_TRIGGER_SCAN, 0);
并获取:
genlmsg_put(msg, 0, 0, driverId, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0);
nl_socket_modify_cb(socket, NL_CB_VALID, NL_CB_CUSTOM, onScanResult, null);
我的回调始于:
struct genlmsghdr* msgHeader = (genlmsghdr*)nlmsg_data(nlmsg_hdr(msg));
struct nlattr* attributes[NL80211_ATTR_MAX + 1];
struct nlattr* bss[NL80211_BSS_MAX + 1];
if(nla_parse(attributes, NL80211_ATTR_MAX, genlmsg_attrdata(msgHeader, 0), genlmsg_attrlen(msgHeader, 0), NULL) == 0)
{
// Read the attributes
// and check for NL80211_ATTR_BSS != 0
}
我在NL80211_BSS_INFORMATION_ELEMENTS中找到了大部分扫描结果。
if (nla_parse_nested(bss, NL80211_BSS_MAX, attributes[NL80211_ATTR_BSS], bss_policy) == 0)
{ /* read the bss attributes */ }
请参阅 nl80211.h 中的 NL80211_BSS_INFORMATION_ELEMENTS 和
但我没有检查WEP隐私。 检查WPA或WPA2很容易,因为有一个ID为48的额外IE元素(ŚeEEEEStd 802.11 2012,第8.4.2章,免费下载表格ieee)