how to use the libnl library to trigger nl80211 commands?

前端 未结 1 1309
挽巷
挽巷 2020-12-13 11:34

Please can someone give an simple example on how to use libnl to use nl80211. I tried to go through iw source code but it is very confusing. Can any one give a simple progra

相关标签:
1条回答
  • 2020-12-13 12:07

    Here is a very basic program sending a NL80211_CMD_GET_INTERFACE, and parsing out the interface type returned in the NL80211_CMD_GET_INTERFACE attribute.

    Beware, there is very little error checking here, you should not use any of this program as is! Almost all these functions can fail.

    #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;
    }
    
    0 讨论(0)
提交回复
热议问题