Технология Wi-Fi занимает сейчас лидирующее место на рынке, и сдавать свои позиции никак не собирается. Огромный штат инженеров занимается его развитием, а планы расписаны уже на десятилетия вперёд. Например нашумевший Wi-Fi поколения 7 официально вышел только в этом 2024-ом году, а следующее поколение 8 ожидается в 2028-ом. Так в чём-же его преимущества и недостатки? Попробуем разобраться в теории, после чего напишем примитивный сканер сети WLAN.
1. Технические детали сигнала Wi-Fi
Беспроводную сеть Wi-Fi (Wireless Fidelity, дословно беспроводная точность) описывает стандарт IEEE 802.11, который поддерживает организация «Wi-Fi Alliance» (WECA, Wireless Ethernet Compatibility Alliance). С момента выхода в 1997 году технология постоянно совершенствовалась, а поправки отмечались комбинациями букв 802.11a/b/g/n/ac/ad/ax/be и прочими. На данный момент имеем 4 версии стандарта: Wi-Fi 4,5,6,7 и как правило у старших есть обратная совместимость с предыдущими, что сказывается на общей производительности сети. Например, когда обнаруживается устаревший девайс 802.11а, то распределяющий сигнал маршрутизатор (роутер) будет вынужден подстроится именно под него – как результ, более современные и высокоскоростные устройства 802.11n/ax не смогут уже в полной мере реализовать свой потенциал. Это нужно учитывать при настройки и организации WLAN сети.
Из основных можно выделить 5 поправок технологий Wi-Fi – это a, b, g, n, ac и ах.
B и G ограничены только несущей частотой 2,4 ГГц; A и AC используют частоту 5 ГГц; а N и AX использует сразу обе частоты 2,4 и 5 ГГц. Наш выбор для дома сводится к трём поправкам: Wireless G, N или AC, АХ (роутеры 802.11b уже сняты с производства). По сути 802.11n это Wi-Fi поколения(4), 802.11ac это Wi-Fi 5, 802.11ax = Wi-Fi 6, и 802.11be последний на данный момент Wi-Fi 7.
Несмотря на то, что приёмо-передающие устройства в сети WLAN являются цифровыми, будучи беспроводным сигнал Wi-Fi распространяется по эфиру в виде радиоволн на высоких частотах или 2.4 ГГц, или-же 5 ГГц. При работе роутера в режиме 2.4 длина радиоволны
Ссылка скрыта от гостей
, а на частоте 5 ГГц один период не превышает 6 см. Широкая волна способна лучше огибать препятствия на своём пути, а потому на частоте 2.4 ГГц передатчики охватывают в 2-раза большую площадь (до 100 метров), чем работающее на частоте 5 ГГц аналогичное устройство. Зато на открытых пространствах последнее выигрывает в скорости передачи данных, хотя и тут есть масса нюансов, о которых и пойдёт речь далее.Модуляция как способ кодирования информации
В проводной сети Ethernet цифровой сигнал передаётся в виде двоичных данных, при этом логическую(1) определяет напряжение +5v, а логический(0) соответственно +1v (в некоторых случаях наоборот +5v логический нуль, инверсная схема). Поскольку передача электричества по воздуху не получила пока широкого распространения, для беспроводного Wi-Fi такой способ уже не подходит и требуется аналоговый обмен. Поэтому здесь информация кодируется при помощи т.н. «модуляции радиоволн», когда оригинальная синусоида в виде «несущей» подвергается различного рода изменениям.
В базовый набор входит всего 3 типа модуляций – это амплитудная АМ, частотная ЧМ, и фазовая ФМ (смещение волны влево/вправо от начальной), а их союз позволяет создавать более сложные схемы. Подробнее о принципах модуляции цифровых сигналов можно ознакомиться например
Ссылка скрыта от гостей
.Канал и его пропускная способность
Здесь важно понять, что на самом деле 2.4 ГГц для Wi-Fi это не одна частота несущей волны, а целый диапазон радиочастот от 2.401 до 2.483 ГГц. Разницу между верхним и нижним порогом этих частот называют «шириной канала связи» Channel-Width, и в данном случае она будет равна: 2483 – 2401 = 82 МГц (спектр на частоте 2.4 ГГц). От ширины канала напрямую зависит и его «пропускная способность» Band-Width, которая измеряется в Мбит/сек. Таким образом, для передачи данных по каналу Wi-Fi в нашем распоряжении всего 82 млн периодов волны в секунду, и если теоретически для кодирования 1-бита мы будем расходовать по 10 периодов (колебаний волны), то получим 8 млн бит/сек, или всего 1 МБайт. Ясно, что такая скорость не преемлема в наши дни, и требовались технологии для её повышения.
Ещё в первой версии протокола 802.11а инженеры использовали модуляцию радиоволн не только для кодирования информации, но и для изменения способа передачи данных по каналу. Кодировать каналы можно каким-угодно способом, но для Wi-Fi cейчас как-правило используют QAM-64,128,256 (Quadrature Amplitude Modulation, квадратурно-амплитудная модуляция). Основным преимуществом QAM является эффективное использование полосы пропускания, т.к. при этом на несущую за раз накладывается не 1, а намного больше бит информации. Например QAM-16 позволяет передавать сразу 4 бита за один сигнал, а QAM-256 вообще 8 бит. Достигается это за счёт модуляции самой несущей как по амплитуде (вертикали), так и по фазе (горизонтали), в результате чего пропускная способность канала увеличивает в геометрической прогрессии.
Но помимо 2.4 ГГц технология Wi-Fi способна работать и на несущей частоте 5 ГГц, в диапазоне от 5.170 до 5.835 ГГц. В этом случае ширина канала увеличивается уже с 80-ти до 665 МГц, задирая теоритическую пропускную способность до космических высот 7 и более Гигабит/сек (класс 802.11be).
Мультиплекс и уплотнение
Схемы мультиплексирования позволяют использовать один канал сразу нескольким устройствам Wi-Fi. В самом притивном случае, для этого достаточно разделить по-братски глобальный канал в 82 МГц, например на 8 подканалов по 10 МГц каждый. Такую схему назвали FDM или «Frequency Division Multiplexing». Но как показывает рисунок ниже, это слишком расточительно, поэтому на сл.шаге было решено использовать более эффективную схему OFDM «Orthogonale FDM», когда смещаясь по фазе каналы накладываются друг на друга. Пусть OFDM и сложно реализовать технически (на стороне приёмо-передатчиков), зато на выходе получаем экономию полосы пропускания более 50%, т.е. при той-же ширине канала мы сможем передать в 2-раза больше информации.
Многопоточность для поддержки MIMO
В современных роутерах часто применяется технология MIMO (Multiple Input – Multiple Output, множественные входы/выходы). Она распределяет данные между несколькими антеннами, и они передаются в несколько потоков. Но польза от этого будет только в том случае, если её поддерживают передатчик с приёмником. Суть в том, что в зависимости от кол-ва антенн на роутере, его передатчики генерируют не одну несущую волну на частоте 2.4 или 5 ГГц, а сразу несколько! Тогда каждая из независимых радиоволн будет олицетворять самостоятельный поток, который можно использовать отдельно только на приём, или только на передачу. Сейчас в продаже можно встретить роутеры Wi-Fi даже с 8-ми антеннами, и соответственно потоков в них тоже 8.
Более того, расширение MU-MIMO (Multi-User) позволяет сажать юзеров на отдельные потоки, при этом каждая из 8-ми антенн в этом случае будет работать как на приём, так и на передачу. То-есть фактически получаем 8 роутеров в одном, и это реально круто. Подробнее с технологией MIMO можно ознакомиться например
Ссылка скрыта от гостей
.Характеристики каналов Wi-Fi
Каналы Wi-Fi и диапазоны их частот чётко оговариваются в спецификации 802.11. На несущей частоте 2.4 ГГц всего доступно 14 независимых канала (на каждом из которых могут сидеть сразу по несколько устройств), а на частоте 5 ГГц кол-во каналов увеличивается аж до 33. На рис.ниже видно, что на частоте 2.4 ширина каждого из 14-ти каналов равна 22 МГц, при этом по фазе они смещены друг от друга всего на 5 МГц. На территории бывшего СНГ канал #14 не используется, превращаясь в буферную зону. Каналы расположены так, что выделенные синим 1-6-11 не пересекаются между собой, в результате чего помех на них будет меньше.
В поправках спеки 802.11 предусмотрено и объединение соседних каналов, чтобы увеличить их ширину и соответственно пропускную способность. Так, современные роутеры могут сами выбирать параметр «Channel Width» в диапазоне 20,40 МГц для несущей в 2.4 ГГц, или 80,160 МГц для несущей 5 ГГц.
2. Практическая часть – пишем сканер на WinAPI
Поверхностно ознакомившись с транспортной частью протокола Wi-Fi перейдём к практике, где на чистом Win-API напишем сканер доступных беспроводных сетей в нашей зоне. Сразу отметим, что в нёдрах Win официальный стандарт 802.11 числится как DOT11. Ещё начиная с Win-XP в штат cистемы были прописаны с десяток библиотек с префиксом Wlan_XX.dll (см.папку system32), в числе которых и наш клиент WlanApi.dll. На моей Win-7 данная библиотека выдаёт на экспорт всего 48 функций – вызывая их мы можем сканировать сети, подключаться к ним, менять настройки профилей, и многое другое.
Как это водится на территории Win, для начала нам нужно функцией WlanOpenHandle() получить дескриптор соединения с сервером Wi-Fi, в качестве которого выступает здесь сама ОС. Теперь этот дескриптор будем использовать для вызова буквально всех остальных API, пока не закончим текущий сеанс связи с драйвером беспроводной сети. На следующем этапе зовём на помощь функцию WlanEnumInterfaces() для перечисления доступных соединений, и на выходе получим указатель на структуру такого вида:
C-подобный:
struct WLAN_INTERFACE_INFO_LIST
dwNumberOfItems dd 0 ;// найдено всего точек-доступа АР (Access Point)
dwIndex dd 0 ;// номер первой точки в списке (как-правило нуль)
InterfaceGuid rb 16 ;// идентификатор GUID нашего интерфейса
strInterfaceDesc du 256 dup(0) ;// Unicode-имя нашего Wi-Fi
isState dd 0 ;// текущий статус вкл/выкл
ends
Из пяти членов этой структуры нам нужен только GUID, чтобы передать его в функцию непосредственного сканирования эфира WlanScan(). Согласно документации, драйверу WLAN отводится 4-сек на эту процедуру, хотя WlanScan() не ждёт и возвращает управление сразу. Поэтому мы сами должны организовать задержку, например функцией Sleep(), или зарегать специальное уведомление через WlanRegisterNotification(). Поскольку сон на 5-сек реализовать проще, мы будем использовать именно его.
Ну и на финишной прямой остаётся дёрнуть за функцию WlanGetNetworkBssList(), и получить таким образом огромный массив данных сразу для всех доступных точек АР. Каждую точку-доступа будет описывать структура «WLAN_BSS_ENTRY» размером в 360-байт, а общее кол-во таких структур в массиве функция вернёт в поле «NumberOfItems» структуры «WLAN_BSS_LIST». Символы BSS означают здесь «Basic-Service-Set» или набор базовой информации о сети. Отметим, что функция WlanGetNetworkBssList() сама под капотом выделяет память для массива, возвращая нам уже готовый указатель на неё. Поэтому освобождение этой памяти через WlanFreeMemory() полностью лежит в зоне нашей ответственности:
C-подобный:
struct WLAN_BSS_LIST
dwTotalSize dd 0 ;// общий размер данных в байтах
dwNumberOfItems dd 0 ;// кол-во структур в массиве
wlanBssEntries WLAN_BSS_ENTRY ;// массив структур WLAN_BSS_ENTRY ниже
ends
struct WLAN_BSS_ENTRY ;//<----------------- Всего 360 байт!
dot11Ssid DOT11_SSID ;// имя WiFi-сети
uPhyId dd 0 ;// Element ID
dot11Bssid DOT11_MAC_ADDRESS ;// 6-байтный МАС девайса Wi-Fi
Alignment1 dw 0 ;// <---- выравнивание структуры на 4-байтную границу
dot11BssType dd 0 ;// DOT11_BSS_TYPE
dot11BssPhyType dd 0 ;// DOT11_PHY_TYPE
lRssi dd 0 ;// уровень сигнала в децибелах dB
uLinkQuality dd 0 ;// качество связи в %
bInRegDomain db 0 ;// Bool
Alignment2 db 0 ;//
usBeaconPeriod dw 0 ;// интервал маяка "Beacon" в 1024 микросек (мкс = сек/1000)
Alignment3 dd 0 ;//
ullTimestamp dq 0 ;// время отправки,
ullHostTimestamp dq 0 ;// ..и получения хостом маяка "Beacon"
usCapabilityInformation dw 0 ;// прочие сведения о маяке..
Alignment4 dw 0 ;//
ulChCenterFrequency dd 0 ;// частота канала в кГц
wlanRateSet WLAN_RATE_SET ;// набор поддерживаемых скоростей
ulIeOffset dd 0 ;// указатель на BLOB
ulIeSize dd 0 ;// ..... размер ^^^^
ends
Некоторые поля этой структуры требуют объяснений, поэтому разберём их подробней.
• В поле dot11BssType возможны всего три варианта:
C-подобный:
;// enum _DOT11_BSS_TYPE
DOT11_BSS_TYPE_INFRASTRUCTURE = 1 ;// Basic Service Set (BSS) (инфраструктура с маршрутизатором/роутером)
DOT11_BSS_TYPE_INDEPENDENT = 2 ;// AdHoc или Independent BSS, (без роутера, децентрализованная)
DOT11_BSS_TYPE_ANY = 3 ;// Расширенная зона обслуживания ESS – Extended Service Set.
• В поле dot11BssPhyType закодирован тип физического девайса Physical по спеке 802.11xx – возможные варианты:
C-подобный:
;// enum _DOT11_PHY_TYPE
DOT11_PHY_TYPE_UNKNOWN = 0
DOT11_PHY_TYPE_FHSS = 1 ;// Bluetooth
DOT11_PHY_TYPE_DSSS = 2 ;// Direct sequence spread spectrum
DOT11_PHY_TYPE_IRBASEBAND = 3 ;// Инфракрасный датчик IR
DOT11_PHY_TYPE_OFDM = 4 ;// 802.11a Wi-Fi*5 мультиплекс с ортогональным частотным разделением каналов
DOT11_PHY_TYPE_HRDSSS = 5 ;// 802.11b высокоскоростной (снят с производства)
DOT11_PHY_TYPE_ERP = 6 ;// 802.11g расширенная скорость
DOT11_PHY_TYPE_HT = 7 ;// 802.11n Wi-Fi*5 высокопроизводительный 2-диапазонный 2.4/5 ГГц
DOT11_PHY_TYPE_VHT = 8 ;// 802.11ac с очень высокой пропускной способностью
DOT11_PHY_TYPE_DMG = 9 ;// 802.11ad направленный мульти-гигабитный
DOT11_PHY_TYPE_HE = 10 ;// 802.11ax Wi-Fi*6 высокоэффективный (6 ГГц)
DOT11_PHY_TYPE_EHT = 11 ;// 802.11be Wi-Fi*7 с высокой пропускной способностью
• Поле usBeaconPeriod хранит частоту сигнала маячка, который устройства Wi-Fi периодически посылают в открытый эфир, давая знать о своём присутсвии. По этому маяку можно отследить время, когда юзер заходит и выходит из WLAN сети.
• Как и следует из его названия, в поле ulChCenterFrequency прописывается средняя частота канала, на котором работает обнаруженный роутер. Обратите внимание, что непосредственно номер самого канала 1-13 нигде в структуре не указан, и его нужно будет вычислять по значению частоты. Например
Ссылка скрыта от гостей
можно найти таблицы для обоих несущих 2.4 и 5 ГГц, с центральными частотами всех каналов. Остаётся только сравнить их со-значением в данном поле, и получим номер.• Последние 2 поля ulIeOffset/Size хранят указатель на дополнительные двочные данные BLOB (Binary Long Object), содержимое и формат которых зависит от настроения производителя маршрутизатора/роутера, поэтому мы их упустим.
А вот собственно и сам исходник, надеюсь комменты немного прояснят ситуацию.
C-подобный:
format pe console
entry start
include 'win32ax.inc'
include 'equates\wlanapi.inc'
;//----------
.data
negVer dd 0
wlanHndl dd 0
bssAddr dd 0
nextBss dd 0
itemCount dd 0
divide dd 1000*1000
gHz dq 0
align 16
buff db 0
;//----------
.code
start: invoke SetConsoleTitle,<'*** WlanGetNetworkBssList ***',0>
;//----- Запрашиваем дескриптор -------------------------------------
invoke WlanOpenHandle, WLAN_API_VERSION_2, 0, negVer, wlanHndl
or eax,eax
jz @f
@err: cinvoke printf,<10,10,' WlanOpen Error!',0>
jmp @exit
;//----- Перечисляем интерфейсы, чтобы получить GUID ----------------
@@: cinvoke printf,<10,' Please wait.. Scan Wi-Fi network..',0>
invoke WlanEnumInterfaces,[wlanHndl],0,buff
mov eax,dword[buff]
add eax,8 ;// EAX = указатель на GUID
;//----- Просканируем эфир в поисках точек АР -----------------------
push eax
invoke WlanScan,[wlanHndl],eax,0,0,0
invoke Sleep,5000 ;// 5-сек на поиск..
pop eax
;//----- Запрашиваем у драйвера глобальный массив данных ------------
invoke WlanGetNetworkBssList,[wlanHndl],eax,0,0,0,0,buff
or eax,eax
jnz @err
mov esi,dword[buff]
mov [bssAddr],esi
;//----- Вывод инфы из BSS для всех точек ---------------------------
mov eax,[esi+WLAN_BSS_LIST.dwTotalSize]
mov ebx,[esi+WLAN_BSS_LIST.dwNumberOfItems]
mov [itemCount],ebx
push esi
cinvoke printf,<10,10,' BSS total size...: %d bytes',\
10,' Number of items..: %d',\
10,' MAC data-base....: %d entries',10,10,0>,eax,ebx,[macCount]
cinvoke printf,<' Ssid Rssi Power Freq Channel PHY Device MAC Device Vendor',10,\
' -------------------------------------------------------------------------------------------------------------------',0>
pop esi
lea esi,[esi+WLAN_BSS_LIST.wlanBssEntries]
mov [nextBss],esi
;//----- Цикл для обхода всех структур в массиве --------------------
@@: mov esi,[nextBss]
lea eax,[esi+WLAN_BSS_ENTRY.dot11Ssid+4]
mov ebx,[esi+WLAN_BSS_ENTRY.lRssi]
mov ecx,[esi+WLAN_BSS_ENTRY.uLinkQuality]
mov edx,[esi+WLAN_BSS_ENTRY.ulChCenterFrequency]
push 0 edx
finit
fild qword[esp]
fidiv [divide]
fstp [gHz]
add esp,8
push esi esi esi esi
cinvoke printf,<10,' %-17s %d dB %3d %% %0.3f GHz ',0>,eax,ebx,ecx,\
dword[gHz],dword[gHz+4]
pop esi
mov ebx,[esi+WLAN_BSS_ENTRY.ulChCenterFrequency]
GetChannel
pop esi
mov ebx,[esi+WLAN_BSS_ENTRY.dot11BssPhyType]
GetPhy
pop esi
lea eax,[esi+WLAN_BSS_ENTRY.dot11Bssid]
GetMac eax
pop esi
mov eax,[esi+WLAN_BSS_ENTRY.dot11Bssid]
bswap eax
shr eax,8
GetVendor eax
add [nextBss],360 ;// переход к сл.структуре в массиве
dec [itemCount]
jnz @b ;// мотаем цикл, пока itemCount не станет нуль
;//----- Освободить выделенную память и на выход --------------------
invoke WlanFreeMemory,[bssAddr]
@exit: cinvoke getch
cinvoke exit,0
;//----------
section '.idata' import data readable
library msvcrt,'msvcrt.dll',kernel32,'kernel32.dll',wlanapi,'wlanapi.dll'
import msvcrt,printf,'printf',scanf,'scanf',getch,'_getch',exit,'exit'
include 'api\kernel32.inc'
include 'api\wlanapi.inc'
Чтобы не засорять исходник, здесь я использовал свои макросы GetChannel_Phy_Mac_Vendor(), которые можно будет найти в инклуде (см.скрепку). Кроме того была предпринята вялая попытка определить вендора по МАС-адресу девайса Wi-Fi, для чего я создал небольшую базу из официальных доков OUI (Organization Unique ID). При желании вы можете дополнять эту базу сами, т.к. шаблоны уже имеются в инклуде. Тогда в столбце «Device Vendor» будет меньше неопознанных Unknown.
А вот и результ проделанных вызовов где видно, что функция WlanScan() обнаружила всего 19 роутеров Wi-Fi в радиусе моего местоположения, причём только 2 из них воркают на частоте 5 ГГц. Общий размер данных BSS превышает 11 Кбайт, а в базе МАС-адресов имеется пока всего 88 записей.
Заключение
Столкнувшись с деталями организации канального уровня понимаешь, как всё-таки сложно там всё устроено. В рамках данной статьи я не охватил и 10-ти процентов от общей теории. За бортом осталась огромная тема аутентификации и шифрования самих информационных потоков, где помимо штатных WEP, WPA-WPA3 можно найти очень много интересного. Может когда-нибудь мы ещё вернёмся к этой теме, а пока цепляю в скрепку исполняемый файл для тестов, инклуд WlanApi.inc с макросами и описанием структур, а так-же сырую базу MAC-адресов xListOUI.txt, из которой можно будет узнать вендоров. Всем удачи, до скорого!
Вложения
Последнее редактирование: