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