Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
57 / 43 / 12
Регистрация: 27.10.2018
Сообщений: 454

Как получить информацию из объекта nla_policy?

24.03.2021, 18:05. Показов 1393. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Моя задача написать wifi сканер с помощью интерфейса nl80221.
Функция, отправляющая запрос ядру на получение информации о доступных сетях, выглядит так:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
int request_wlan_netw(struct nl_sock *socket, char *wlan_if, int if_index,
                      int driver_id) {
  int family_id = scanner_get_family_id(socket, "nl80211", "scan");
  nl_socket_add_membership(socket, family_id);
  struct nl_msg *msg = nlmsg_alloc(), *ssids_to_scan = nlmsg_alloc();
  if (NULL == msg) {
    printf("Allocating netlink message failed: %s %d\n", __func__, __LINE__);
    return -1;
  } else if (NULL == ssids_to_scan) {
    printf("Allocating ssid message failed: %s %d\n", __func__, __LINE__);
    return -1;
  }
  struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
  if (!cb) {
    printf("Allocating cb failed: %s %d\n", __func__, __LINE__);
    nlmsg_free(msg);
    nlmsg_free(ssids_to_scan);
    return -1;
  }
  genlmsg_put(msg, 0, 0, driver_id, 0, 0, NL80211_CMD_TRIGGER_SCAN, 0);
  nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index);
  nla_put(ssids_to_scan, 1, 0, "");
  nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids_to_scan);
  nlmsg_free(ssids_to_scan);
  int err;
  struct scanner_cb_result result = {.done = 0, .aborted = 0};
  nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, scanner_scan_cb, &result);
  nl_cb_err(cb, NL_CB_CUSTOM, scanner_error_handler_cb, &err);
  nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, scanner_finish_handler_cb, &err);
  nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, scanner_ack_handler_cb, &err);
  nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, scanner_no_seq_check, NULL);
  err = 1;
  int ret = nl_send_auto(socket, msg);
  printf("NL80211_CMD_TRIGGER_SCAN sent %d bytes to the kernel.\n", ret);
  printf("Waiting for scan to complete...\n");
  while (err > 0) ret = nl_recvmsgs(socket, cb);
  if (err < 0) {
    printf("WARNING: err has a value of %d.\n", err);
  }
  if (ret < 0) {
    printf("ERROR: nl_recvmsgs() returned %d (%s).\n", ret, nl_geterror(ret));
    return ret;
  }
  while (!result.done) nl_recvmsgs(socket, cb);
  if (result.aborted) {
    printf("ERROR: Kernel aborted scan.\n");
    return 1;
  }
  printf("Scan is done.\n");
  nlmsg_free(msg);
  nl_cb_put(cb);
  nl_socket_drop_membership(socket, family_id);
  return 0;
}
Сообщение отправляется ядру, и следующая функция (коллбек) выводит полученную информацию:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
int scanner_print_wlan_cb(struct nl_msg *msg, void *arg) {
  struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
  char mac_addr[20];
  memset(mac_addr,0,20);
  struct nlattr *tb[NL80211_ATTR_MAX + 1];
  struct nlattr *bss[NL80211_BSS_MAX + 1];
  struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
      [NL80211_BSS_TSF] = {.type = NLA_U64},
      [NL80211_BSS_FREQUENCY] = {.type = NLA_U32},
      [NL80211_BSS_BSSID] = {},
      [NL80211_BSS_BEACON_INTERVAL] = {.type = NLA_U16},
      [NL80211_BSS_CAPABILITY] = {.type = NLA_U16},
      [NL80211_BSS_INFORMATION_ELEMENTS] = {},
      [NL80211_BSS_SIGNAL_MBM] = {.type = NLA_S32},
      [NL80211_BSS_SIGNAL_UNSPEC] = {.type = NLA_U8},
      [NL80211_BSS_STATUS] = {.type = NLA_U32},
      [NL80211_BSS_SEEN_MS_AGO] = {.type = NLA_U32},
      [NL80211_BSS_BEACON_IES] = {},
  };
  nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
            genlmsg_attrlen(gnlh, 0), NULL);
  if (!tb[NL80211_ATTR_BSS]) {
    printf("bss info missing!\n");
    return NL_SKIP;
  }
  if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
                       bss_policy)) {
    printf("failed to parse nested attributes!\n");
    return NL_SKIP;
  }
  if (!bss[NL80211_BSS_BSSID]) return NL_SKIP;
  if (!bss[NL80211_BSS_INFORMATION_ELEMENTS]) return NL_SKIP;
 
  mac_addr_n2a(mac_addr, nla_data(bss[NL80211_BSS_BSSID]));
  printf("%s, ", mac_addr);
  printf("%u MHz, %hu %d  ", nla_get_u32(bss[NL80211_BSS_FREQUENCY]),
         nla_get_u16(bss[NL80211_BSS_CAPABILITY]),
         nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM])
         //nla_get_u32(bss[NL80211_BSS_STATUS])
         //nla_get_u16(bss[NL80211_BSS_SIGNAL_UNSPEC])
         );
  print_ssid(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]),
             nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]));
  printf("\n");
 
  return NL_SKIP;
}
моя программа работает и вместе с вспомогательными функциями, которые я использую там, она выводит, например:

11: 11: 22: 22: 44: 44, 5180 МГц, 1297 -5100 first_network
11: 55: 55: 44: 88: 88, 2412 МГц, 1041 -8500 second_network

но есть кое-что, чего я не могу понять:
во-первых: почему вывод NL80211_BSS_SIGNAL_MBM равен например -5100 ? Я уверен, что это неправильное значение, так как сила сигнала не можеть быть отрицательной.
второе: мне также нужно получить ключ (WPA, WPA2, ESS) от сканированных сетей. Я нашел этот кусок кода:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int keynum;
char *keytype;
keynum = nla_get_u32(bss[NL80211_BSS_CAPABILITY]);
 
if(keynum==5153 || keynum == 34)
    keytype="NONE";
 
else if(keynum==5169 || keynum == 1297 || keynum==1073|| keynum == 5393)
    keytype="WPA2";
 
else if (keynum == 1041)
    keytype="WPA WPA2";
 
else
    keytype="WPA WPA2";
где было показано, как обрабатывать эти значения, но:
что делать, если нет пароля? Какой ключ у WPA3? Или где я могу найти список всех этих ключей? Я попытался, но не нашел документации о них. Нужно ли мне другое поле nla_policy для анализа?
так же после вывода всех сетей я получаю сообщение
C
1
ERROR: nl_recvmsgs_default() returned -33 (Dump inconsistency detected, interrupted).
Оно конечно не критично но хотелось бы знать где у меня ошибка.
Заранее спасибо за помощь.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.03.2021, 18:05
Ответы с готовыми решениями:

Как передавать информацию передвижения реального объекта в компьютер
Здравствуйте , я новичок в механике и роботехнике ( не уверен что в нужную тему занес). Интересует литература или статьи , по поводу того...

Получить информацию об оперативной памяти и информацию об одном из жёстких дисков
Как с помощью функций WinAPI определить информацию об оперативной памяти и информацию о памяти на одном из жёстких дисков. Заранее...

Как получить информацию
В очередной раз возникла проблема: Вот страница http://s1.world-up.ru/samp/1/SampQueryExample.php На неё после запросов выводится...

2
 Аватар для zeroalef
200 / 236 / 33
Регистрация: 29.03.2019
Сообщений: 667
26.03.2021, 18:01
plzvtl, с документацией у них не ахти. Но это не беда, там есть исходники, api reference, mailing list.
0
57 / 43 / 12
Регистрация: 27.10.2018
Сообщений: 454
01.04.2021, 18:30  [ТС]
Цитата Сообщение от plzvtl Посмотреть сообщение
Я уверен, что это неправильное значение,
https://www.dlink.ru/ru/products/5/2494.html
Цитата Сообщение от plzvtl Посмотреть сообщение
что делать, если
C
1
2
3
4
5
6
7
8
#define RSN_TAG_ID 0x30
#define VENDOR_TAG_ID 0xdd
#define BEACON_DATA_LEN 0x100
#define BSS_SSID_LEN BEACON_DATA_LEN
#define WPA1_BEACON 0x1AC0F00
#define WPA2_BEACON_1 0x2AC0F00
#define WPA2_BEACON_2 0x4AC0F00
#define WPA1_WPA2_BEACON 0x101F25000
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
if (NULL != bss[NL80211_BSS_BEACON_IES] &&
      NULL != nla_data(bss[NL80211_BSS_BEACON_IES])) {
    for (int i = 0;;) {
      bool first = i;
      uint8_t header_type =
          *(uint8_t *)((nla_data(bss[NL80211_BSS_BEACON_IES])) + i++);
      uint8_t header_len =
          *(uint8_t *)((nla_data(bss[NL80211_BSS_BEACON_IES])) + i++);
      i += header_len;
      if ((i > BEACON_DATA_LEN) || ((header_type == 0) && (first == 1))) break;
      if (header_type == VENDOR_TAG_ID) {
        long long int oui = 0;
        memcpy(&oui,
               (uint8_t *)((nla_data(bss[NL80211_BSS_BEACON_IES])) -
                           header_len + i),
               6);
        if (oui == WPA1_WPA2_BEACON) wlan_info.bss_wpa1_wpa2 = 1;
      } else if (header_type == RSN_TAG_ID) {
        int32_t oui = 0;
        memcpy(&oui,
               (uint8_t *)((nla_data(bss[NL80211_BSS_BEACON_IES])) - 6 + i), 4);
        if ((oui == WPA2_BEACON_1) || (oui == WPA2_BEACON_2))
          wlan_info.bss_wpa2 = 1;
        else if (oui == WPA1_BEACON)
          wlan_info.bss_wpa1 = 1;
      }
    }
  }
  if (bss[NL80211_BSS_CAPABILITY] != NULL) {
    wlan_info.bss_capability = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
  }
  if (!(wlan_info.bss_wpa1_wpa2 | wlan_info.bss_wpa2 | wlan_info.bss_wpa1)) {
    wlan_info.bss_wep = wlan_info.bss_capability & 16;
  }
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.04.2021, 18:30
Помогаю со студенческими работами здесь

Как получить информацию о БД
Здравтвуйте, меня интересует как получить информацию об экземпляре Oracle, в интернете нашёл код примерно такого плана: using...

Как получить информацию о файле
Необходимо получить информацию о типе файла, его атрибутах, времени создания. Подскажите как это сделать?

Как получить информацию об оборудовании ?
Всем привет, пытаюсь с помощью WMI получить информацию об оборудовании как в этом видео...

Как получить информацию о системе?
Привет. Не подскажете как можно получить всю информацию о системе? Почти как AIDA64, только не всю инфу, а допустим...

Как получить информацию о компьютере?
Господа, подскажите, пожалуйста, как в программу на Ява включить такую возможность, как получение информации о компьютере (операционная...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru