как да използвам библиотеката libnl за задействане на команди nl80211?

Моля, може ли някой да даде прост пример за това как да използвате libnl за използване на nl80211. Опитах се да прегледам iw изходния код, но е много объркващо. Може ли някой да даде проста програма за това как да задействате команди nl80211 като NL80211_CMD_GET_WIPHY с помощта на libnl.


person shashank hegde    schedule 06.02.2014    source източник
comment
Съгласен съм, в iw се влиза много трудно. Много макроси и малко коментари!   -  person Inductiveload    schedule 06.02.2014


Отговори (1)


Ето една много проста програма, която изпраща NL80211_CMD_GET_INTERFACE и анализира типа интерфейс, върнат в атрибута NL80211_CMD_GET_INTERFACE.

Внимавайте, тук има много малко проверка за грешки, не трябва да използвате никоя от тази програма такава, каквато е! Почти всички тези функции могат да се провалят.

#include "netlink/netlink.h"
#include "netlink/genl/genl.h"
#include "netlink/genl/ctrl.h"
#include <net/if.h>

//copy this from iw
#include "nl80211.h"

static int expectedId;

static int nlCallback(struct nl_msg* msg, void* arg)
{
    struct nlmsghdr* ret_hdr = nlmsg_hdr(msg);
    struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];

    if (ret_hdr->nlmsg_type != expectedId)
    {
        // what is this??
        return NL_STOP;
    }

    struct genlmsghdr *gnlh = (struct genlmsghdr*) nlmsg_data(ret_hdr);

    nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
              genlmsg_attrlen(gnlh, 0), NULL);

    if (tb_msg[NL80211_ATTR_IFTYPE]) {
        int type = nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]);

        printf("Type: %d", type);
    }
}

int main(int argc, char** argv)
{
    int ret;
    //allocate socket
    nl_sock* sk = nl_socket_alloc();

    //connect to generic netlink
    genl_connect(sk);

    //find the nl80211 driver ID
    expectedId = genl_ctrl_resolve(sk, "nl80211");

    //attach a callback
    nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM,
            nlCallback, NULL);

    //allocate a message
    nl_msg* msg = nlmsg_alloc();

    nl80211_commands cmd = NL80211_CMD_GET_INTERFACE;
    int ifIndex = if_nametoindex("wlan0");
    int flags = 0;

    // setup the message
    genlmsg_put(msg, 0, 0, expectedId, 0, flags, cmd, 0);

    //add message attributes
    NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifIndex);

    //send the messge (this frees it)
    ret = nl_send_auto_complete(sk, msg);

    //block for message to return
    nl_recvmsgs_default(sk);

    return 0;

nla_put_failure:
    nlmsg_free(msg);
    return 1;
}
person Inductiveload    schedule 06.02.2014
comment
Благодаря много, програмата ми даде общ преглед на това как да използвам netlink гнездата за команди nl80211. Но как да получим резултатите от сканирането с помощта на мрежови връзки и как ще разберем, че сканирането е приключило. - person shashank hegde; 08.02.2014
comment
Е, това е друг въпрос, но по същество изпращате NL80211_CMD_TRIGGER_SCAN, за да започнете сканиране. Ако се опитате да стартирате друг, докато един работи, това ще се провали. След като изпратите това, след това изслушате сканирането да завърши, когато получите NL80211_CMD_NEW_SCAN_RESULTS. След това можете да изпратите команда NL80211_CMD_GET_SCAN, за да поискате резултатите. Ще получите едно съобщение обратно за всяка намерена станция, така че бъдете готови да обработите множество съобщения. - person Inductiveload; 11.02.2014
comment
Благодаря за помощта. Най-накрая го получих и открих как да сканирам. Моят код вече работи добре и сканира всички околни AP. - person shashank hegde; 12.02.2014
comment
как да го компилирам с g++? какво трябва да се свърже в linux? - person Mateusz; 16.10.2016
comment
gcc -Wall -I/usr/include/libnl3/ main.c -o main -lnl-3 -lnl-genl-3 - person user1934513; 18.04.2017
comment
Моля, имайте предвид, че nl_send_auto_complete е отхвърлен. Използвайте nl_send_auto(sk, msg); nlmsg_free(msg); вместо това. - person phip1611; 08.09.2020