2014-02-06 18 views
3

請有人給一個簡單的例子來說明如何使用libnl來使用nl80211。 我試圖通過iw源代碼,但它很混亂。 任何人都可以給出一個簡單的程序,瞭解如何使用libnl觸發NL80211_CMD_GET_WIPHY等nl80211命令。如何使用libnl庫觸發nl80211命令?

+0

我同意,iw很難進入。很多宏,並沒有太多評論! – Inductiveload

回答

9

這是一個非常基本的程序,發送一個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; 
} 
+0

非常感謝程序給了我一個關於如何使用netlink套接字進行nl80211命令的概述。但是,如何使用netlinks獲得掃描結果,以及我們在掃描結束時如何知道。 –

+1

那麼這是一個不同的問題,但基本上,你發送'NL80211_CMD_TRIGGER_SCAN'開始掃描。如果您在運行時嘗試啓動另一個,則會失敗。發送完畢後,當你收到一個'NL80211_CMD_NEW_SCAN_RESULTS'時,你會聽完掃描完成。然後您可以發送一個'NL80211_CMD_GET_SCAN'命令來詢問結果。每找到一個電臺,你都會收到一條消息,所以準備好處理多條消息。 – Inductiveload

+0

感謝您的幫助。我明白了,並發現如何掃描。我的代碼現在工作正常,並掃描所有周圍的接入點。 –