libnl/nl80211 эквивалент iw_set_ext

Я начал писать код для работы с картой Wi-Fi с помощью iwconfig/ioctl, когда понял, что он устарел и большинство приложений используют nl80211. Я начал читать его исходный код, но там нет документов, а код немного сложен. Как я могу делать простые вещи, такие как сканирование, включение/выключение, установка режима карты с помощью 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 для установки/получения интерфейса Wi-Fi или любого API с простыми функциями, такими как «set_mode» или «power_off»?


person Mateusz    schedule 12.10.2016    source источник


Ответы (1)


Я сканирую с помощью netlink, используя следующие шаги

  1. Подготовить и выполнить NL80211_CMD_TRIGGER_SCAN
  2. Подготовить и выполнить NL80211_CMD_GET_SCAN

    Вместе с NL80211_CMD_GET_SCAN регистрируется обратный вызов. В обратном вызове необработанные данные анализируются как BSS. IE анализируется. См. перечисления с NL80211_BSS_MAX, NL80211_ATTR_MAX из nl80211.h.

Перед выполнением следующего шага проверьте возвращаемые значения каждого вызова 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_BSS_INFORMATION_ELEMENTS из nl80211.h и

Но мне не удалось проверить конфиденциальность WEP. Проверить WPA или WPA2 легко, потому что есть дополнительный элемент IE с идентификатором 48 (см. IEEE Std 802.11 2012, глава 8.4.2, бесплатная загрузка со стороны ieee)

person Th. Thielemann    schedule 05.04.2017
comment
не могли бы вы объяснить немного больше, что есть что? - person Mateusz; 06.04.2017