Технология 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 длина радиоволны равна 12.5 см, а на частоте 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
;
//
;
//----- Запрашиваем дескриптор -------------------------------------
invoke WlanOpenHandle
,
WLAN_API_VERSION_2
,
0
,
negVer
,
wlanHndl
or eax
,
eax
jz @f
@err
:
cinvoke printf
,
jmp @exit
;
//----- Перечисляем интерфейсы, чтобы получить GUID ----------------
@@
:
cinvoke printf
,
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
,
,
eax
,
ebx
,
[
macCount
]
cinvoke printf
,
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
,
,
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, из которой можно будет узнать вендоров. Всем удачи, до скорого!