Установите беспроводной канал, используя Netlink API
Я разрабатываю инструмент WiFi в среде Ubuntu Linux 12.04, и мне нужно переключить интерфейс WiFi между разными каналами.
В настоящее время я нашел решение в исходном коде Wireshark ws80211_utils.c в функции ws80211_set_freq, но я не знаю, как внедрить его в мой исходный код и какие библиотеки включить и как его скомпилировать, чтобы я мог его протестировать.
Проблема в том, что вам нужно использовать слишком много аргументов и флагов. Кроме того, это первый раз, когда я разрабатываю инструмент Wi-Fi Netlink.
Если есть хорошие руководства, с которых можно начать и как использовать вызовы netlink для WiFi, предоставьте мне ссылку.
Большое спасибо, я заранее!
1 ответ
В текущих версиях Linux nl80211 является правильным способом "общаться" с беспроводной подсистемой. Имейте в виду, что вы не можете произвольно установить канал для каждого драйвера и для каждого режима работы (мастер, клиент, монитор и т. Д.). Некоторые драйверы позволяют изменять канал только в том случае, если соответствующий интерфейс не работает. В таких режимах, как клиент ("управляемый"), канал вообще не может быть установлен, поскольку он определяется точкой доступа.
Также обратите внимание, что не все драйверы беспроводных устройств используют mac80211/cfg80211. Для тех драйверов, которые его не используют, вы должны либо использовать старый API-интерфейс беспроводных расширений, либо (что еще хуже) собственный API-интерфейс конкретного драйвера.
К сожалению, кажется, что нет современной и полной документации интерфейса nl80211. Пожалуйста, поправьте меня, если я ошибаюсь!
Ваш подход к изучению исходного кода других программ кажется разумным. Вы также можете использовать исходный код iw
утилита командной строки. iw
имеет возможность установить канал:
$ iw --help
Usage: iw [options] command
Options:
--debug enable netlink debugging
--version show version (3.2)
Commands:
…
dev <devname> set channel <channel> [HT20|HT40+|HT40-]
…
В iw
phy.c, строка 91ff. Вы можете найти код, который называется, когда iw wlan0 set channel
выполнен. Тем не менее, этот код определенно не легко читать. Похоже, NL80211_CMD_SET_WIPHY
Команда в сочетании с NL80211_ATTR_WIPHY_FREQ
Атрибут это путь.
В этом SO ответе вы можете найти скелетную программу для использования nl80211. Также код Aircrack-ng (src/osdep/linux.c
функция linux_set_channel_nl80211
) может выступать в качестве плана.
Принятый ответ в настоящее время правильный, но пока еще не опубликован пример кода, который решает вопрос ОП (даже если он опоздал почти на 4 года), поэтому я подумал, что добавлю это сюда для любых будущих пользователей поисковой системы. Он адаптирован из этого вопроса SO и конкретного файла Aircrack-ng ( /src/aircrack-osdep/linux.c, строка 1050), которые оба были упомянуты ранее.
#include <net/if.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <linux/nl80211.h>
int main(int argc, char *argv[])
{
/* The device's name and the frequency we wish to set it to. */
char *device = "wlan1";
int frequencyMhz = 2442;
/* Create the socket and connect to it. */
struct nl_sock *sckt = nl_socket_alloc();
genl_connect(sckt);
/* Allocate a new message. */
struct nl_msg *mesg = nlmsg_alloc();
/* Check /usr/include/linux/nl80211.h for a list of commands and attributes. */
enum nl80211_commands command = NL80211_CMD_SET_WIPHY;
/* Create the message so it will send a command to the nl80211 interface. */
genlmsg_put(mesg, 0, 0, genl_ctrl_resolve(sckt, "nl80211"), 0, 0, command, 0);
/* Add specific attributes to change the frequency of the device. */
NLA_PUT_U32(mesg, NL80211_ATTR_IFINDEX, if_nametoindex(device));
NLA_PUT_U32(mesg, NL80211_ATTR_WIPHY_FREQ, frequencyMhz);
/* Finally send it and receive the amount of bytes sent. */
int ret = nl_send_auto_complete(sckt, mesg);
printf("%d Bytes Sent\n", ret);
nlmsg_free(mesg);
return EXIT_SUCCESS;
nla_put_failure:
nlmsg_free(mesg);
printf("PUT Failure\n");
return EXIT_FAILURE;
}
Скомпилируйте это с gcc main.c $(pkg-config --cflags --libs libnl-3.0 libnl-genl-3.0)
, После выполнения проверьте частоту / канал вашего устройства, например, iw wlan1 info
или же iwconfig
, Здесь нет серьезной проверки ошибок, поэтому все, что вы заметите, это сообщение отправлено или нет. Надеюсь, это поможет любому, как я, перейти с Wireless Extensions на cfg80211 и nl80211.