Native Wifi - bezdrátové sítě ve Windows - díl 2

Windows Pokročilé Native Wifi - bezdrátové sítě ve Windows - díl 2

V minulém článku jsme si připravili knihovnu wlanapi.dll. V této druhé části článku si ukážeme jak zjistit seznam přítomných Wifi karet, dostupných bezdrátových sítí jejich přístupových bodů a konečně i připojování a odpojování.

Zjištění přítomných Wifi karet

Pro účely detekce přítomných Wifi karet slouží funkce WlanEnumInter­faces. Její deklarace nepatří mezi ty záludné; předáte ji handle získané při inicializaci rozhraní Native Wifi a místo, kam si přejete uložit zjištěné informace. Ty jsou typu WLAN_INTERFACE_IN­FO_LIST, což je v podstatě pole struktur WLAN_INTERFACE_INFO plus jejich počet.

DWORD WINAPI WlanEnumInterfaces(
  _In_        HANDLE hClientHandle,
  _Reserved_  PVOID pReserved,
  _Out_       PWLAN_INTERFACE_INFO_LIST *ppInterfaceList
);

Struktura vráceného seznamu Wifi karet je též poměrně typická pro knihovnu wlanapi.dll, minimálně pro všechna naše použití. Každá ze struktur WLAN_INTERFACE_INFO obsahuje informace o jedné přítomné Wifi kartě, konkrétně se jedná o následující údaje:

  • jedinečný identifikátor karty v rámci rozhraní Native Wifi (GUID),
  • lidsky čitelný popis (název),
  • aktuální stav udávající, zda je karta připojena k nějaké bezdrátové síti či jakou činnost zrovna provádí.
typedef struct _WLAN_INTERFACE_INFO_LIST {
  DWORD               dwNumberOfItems;
  DWORD               dwIndex;
  WLAN_INTERFACE_INFO InterfaceInfo[];
} WLAN_INTERFACE_INFO_LIST, *PWLAN_INTERFACE_INFO_LIST;

Buffer pro uložení svého výsledku funkce alokuje sama. Je však na vás, abyste jej uvolnili, pokud jej již nebudete potřebovat. Za tímto účelem existuje procedura WlanFreeMemory, která jako svůj jediný parametr akceptuje adresu paměťového bloku, jenž má uvolnit.

VOID WINAPI WlanFreeMemory(
  _In_  PVOID pMemory
);

Seznam bezdrátových sítí a přístupových bodů

Jakmile se rozhodneme, kterou z nalezených Wifi karet využijeme, je na čase zjistit jaké bezdrátové sítě vidí. K tomuto účelu knihovna wlanapi.dll exportuje funkci WlanGetAvaila­bleNetworkLis­t, jejíž deklarace je lehce záludnější než v případě předchozí funkce. Kromě handle získaného při inicializaci rozhraní a identifikátoru síťové karty můžete pomocí parametru dwFlags ovlivnit jaké bezdrátové sítě má funkce hledat. Výsledek je vrácen v posledním parametru v podobném duchu jako v případě zjišťování dostupných Wifi karet.

Native Wifi umí s bezdrátovými sítěmi pracovat ve dvou režimech: pomocí síťových profilů a bez nich. Síťový profil lze chápat jako datovou strukturu (na disku je uložena ve formě XML souboru, alespoň pro Windows Vista a novější verze operačního systému) obsahující všechny informace nutné k připojení ke konkrétní bezdrátové síti. Profily tedy slouží k zapamatování jednotlivých sítí a Windows jich využívají při připojování.

Pro naše účely s profily pracovat nepotřebujeme a tak parametr dwFlags ponecháme nulový. Změnou parametru na kombinaci příznaků uvedených v dokumentaci je možné získat seznam profilů sítí ad-hoc (bezdrátových sítí vysílaných klasickým počítačem a nikoli routerem) či skrytých síťových profilů.

DWORD WINAPI WlanGetAvailableNetworkList(
  _In_        HANDLE hClientHandle,
  _In_        const GUID *pInterfaceGuid,
  _In_        DWORD dwFlags,
  _Reserved_  PVOID pReserved,
  _Out_       PWLAN_AVAILABLE_NETWORK_LIST *ppAvailableNetworkList
);

Funkce vrátí o každé nalezené bezdrátové síti řadu údajů. Pro naše účely je potřeba znát její název (SSID) a zda je zabezpečená, ale vlastnosti jako typ autentizace, šifrování či kvalita signálu se mohou také hodit.

Jakmile máme vybranou síť, ke které se chceme připojit, můžeme začít se zjišťováním jejich přístupových bodů, označovaných v rámci Native Wifi jako BSS (basic service set). K tomu použijeme rutinu WlanGetNetwor­kBssList, přičemž musíme opět uvést handle získané při inicializaci rozhraní a identifikátor síťové karty. Navíc můžeme specifikovat SSID sítě. Pokud tak neučiníme, funkce vrátí seznam všech dostupných BSS pro zadaný typ sítí. Hledaný typ sítě musíme specifikovat v parametru dot11BssType, pričemž máme na výběr z následujících možností:

  • dot11_BSS_type_in­frastructure – "normální" sítě (vysílané např. routerem),
  • dot11_BSS_type_in­dependent – sítě ad-hoc,
  • dot11_BSS_type_a­ny – sítě libovolného typu (lze použít pouze pokud není zadán název sítě),

Parametrem bSecurity knihovně sdělíme, zda je cílová síť zabezpečená. Tuto informaci se dozvíme při zjišťování dostupných bezdrátových sítí.

DWORD WINAPI WlanGetNetworkBssList(
  _In_        HANDLE hClientHandle,
  _In_        const GUID *pInterfaceGuid,
              const  PDOT11_SSID pDot11Ssid,
  _In_        DOT11_BSS_TYPE dot11BssType,
  _In_        BOOL bSecurityEnabled,
  _Reserved_  PVOID pReserved,
  _Out_       PWLAN_BSS_LIST *ppWlanBssList
);

Funkce vrátí seznam získaných BSS ve stejném duchu jako funkce pro získání seznamu přítomných Wifi karet a dostupných bezdrátových sítí. Jedná se o pole záznamů o jednotlivých přístupových bodech, které (to pole) musíte pomocí rutiny WlanFreeMemory uvolnit, pokud jej již dále nebudete využívat. O každé BSS se opět dozvíte mnoho údajů, přičemž pro naše účely je zajímavá MAC adresa a případně kvalita signálu.

Připojení a odpojení

Nyní již tedy máme vybranou síť, ke které se chceme připojit. Známe její charakteristiky včetně SSID a máme v ruce seznam přístupových bodů, které ji vysílají. Můžeme tedy přikročit k vlastnímu připojení, které realizuje funkce WlanConnect.

Funkci opět musíme předat handle získané při inicializaci rozhraní a identifikátor síťové karty, jež si přejeme připojit. Podrobnější parametry připojení je nutné specifikovat v argumentu pConnectionPa­rameters. WlanConnect totiž dovoluje připojit se jak přes síťový profil, tak i bez něj, přičemž je možné, ale ne nutné, specifikovat i BSS, přes které mají téci data.

DWORD WINAPI WlanConnect(
  _In_        HANDLE hClientHandle,
  _In_        const GUID *pInterfaceGuid,
  _In_        const PWLAN_CONNECTION_PARAMETERS pConnectionParameters,
  _Reserved_  PVOID pReserved
);

Strukturu WLAN_CONNECTI­ON_PARAMETERS zde podrobně rozepisovat nebudu, protože je poměrně dlouhá a její kompletní popis (lepší než ten můj) můžete najít v dokumentaci. Pro naše účely potřebujeme přes ní rozhraní Native Wifi sdělit následující:

  • Režim připojení (položka wlanConnection­Mode) nastavíme na wlan_connecti­on_mode_disco­very_secure či wlan_connecti­on_mode_disco­very_unsecure podle toho, zda cílová síť podporuje či nepodporuje zabezpečení. Tuto informaci se dozvíme při zjišťování seznamu dostupných bezdrátových sítí.
  • Název profilu (strProfile) necháme prázdný, protože se žádný nepřipojujeme (hodnota NULL).
  • Vyplníme SSID cílové sítě (položka pDot11Ssid).
  • zadáme seznam přístupových bodů, se kterými si přejeme komunikovat. Jedná se o seznam MAC, přičemž jeho struktura připomíná jiné seznamy popsané výše (opět se jedná v podstatě o pole s udaným počtem položek a dalšími pomocnými údaji). Paměť pro uložení seznamu je rozumné alokovat pomocí funkce WlanAllocateMe­mory a po použití uvolnit (WlanFreeMemory). Pokud známe počet BSS dopředu, můžeme se spokojit se statickou alokací. Sémantika alokační funkce je standardní; parametrem předáme velikost požadovaného bloku v bajtech a v případě dostatku paměti takový blok i obdržíme.
  • Specifikujeme, zda je cílová síť ad-hoc či nikoliv (položka dot11BssType). Tuto informaci opět získáme při zjišťování dostupných bezdrátových sítí.
PVOID WINAPI WlanAllocateMemory(
  _In_  DWORD dwMemorySize
);

Jelikož se připojujeme bez účasti síťového profilu, v seznamu bezdrátových sítí zobrazovaném systémem Windows se nedozvíme, ke které síti jsme se připojili. Pokud ale síť poskytuje přístup k internetu, případný žlutý trojúhelníček s vykřičníkem zmizí; systém rozpozná, že se úspěšně připojil k internetu. Dalším důsledkem "bezprofilového" připojení je nutnost připojit se znovu v případě výpadku. Pokud vím, nelze v tomto režimu nastavit automatické připojování.

Poznámka: Výše zmíněné tak docela neplatí pro systémy Windows 8 a novější, které informaci o připojení ke konkrétní síti zobrazí i bez použití profilu.

Pokud se ptáte, jak se pomocí funkce WlanConnect připojíte k zabezpečené síti, tzn. její úspěšné používání vyžaduje heslo, které ale této rutině nelze zadat, odpověď je taková, že Windows v případě potřeby zobrazí okno, do kterého potřebné údaje vložíte. Musíte mít ale celkem postřeh, protože okno se objeví jen na chvíli a ve formě notifikace.

Připojování k bezdrátové síti probíhá asynchronně. To znamená, že po úspěšném volání funkce WlanConnect stále nemusíte být připojeni. K tomu obvykle dojde o pár vteřin později. Rozhraní Native Wifi poskytuje mechanismus, jak se o přesném okamžiku připojení dozvědět, jeho popis ale patří již do jiného článku.

Pro odpojení od bezdrátové sítě slouží funkce WlanDisconnect. Krom všudypřítomného handle stačí pouze určit připojené Wifi karty a vše by mělo fungovat.

DWORD WINAPI WlanDisconnect(
  _In_        HANDLE hClientHandle,
  _In_        const GUID *pInterfaceGuid,
  _Reserved_  PVOID pReserved
);

Tím končí lehká exkurze po některých funkcionalitách rozhraní Native Wifi. Abychom vše viděli i v praxi, rozhodl jsem se krom GUI aplikace vyvinuté přímo pro účely NTK vytvořit i ukázku konzolovou, jednodušší a přímočařejší.

Nwtest

Konzolová aplikace, jejíž kód se nachází v souboru připojeném k tomuto článku, získá seznam přítomných Wifi karet. Jednu si vybere a v jí detekovaném seznamu bezdrátových sítí vyhledá síť se SSID odpovídajícím řetězci zadaném v prvním parametru příkazové řádky. K této síti se připojí a to pouze přes BSS vysílající nejkvalitnější signál.

Aplikaci jsem naprogramoval za použití prostředí Microsoft Visual Studio 2013, ale neměli byste mít problémy s překladem i ve starších verzích tohoto IDE. Stačí jen vytvořit nový projekt a linkovat statickou knihovnu wlanapi.lib. Projekt jsem pojmenoval nwtest.

WlanClient

Jedná se o aplikaci s grafickým rozhraním, které vás provede přes výběr síťové karty, bezdrátové sítě a přístupové, přes které se chcete připojit. Naprogramována je v Delphi XE2 a nativně přeložena pro platformy x86 a x64. Zdrojové kódy a nápověda pro běžné uživatele jsou součástí balíku. Podobně jako v případě projektu nwtest, i s touto aplikací jejím zdrojovým kódem si můžete dělat, co uznáte za vhodné, nedávám na ni žádná licenční omezení.


 

Stáhnout

Staženo 41x (8.28 kB)
Aplikace je včetně zdrojových kódů

 

  Aktivity (1)

Článek pro vás napsal Martin Dráb
Avatar
Autor se věnuje studiu obecné teorie operačních systémů, vnitřnímu uspořádání jádra OS Windows, trochu také matematice a šifrování

Jak se ti líbí článek?
Celkem (2 hlasů) :
55555


 



 

 

Komentáře

Avatar
IH8Linux
Člen
Avatar
IH8Linux:

Ahoj, četl jsem tvůj článek "nativní wifi" a je to v celku dost zajimavý a tak jsem si hned stahnul WlanClient a jsem z toho takový zmatený. Podle win 7 jsem připojenej ke svýmu wifi routeru k_1888 ale podle Wlanclient nikoliv. Viz. foto

 
Odpovědět 21. listopadu 20:34
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na IH8Linux
Martin Dráb:

Ano, to je správné chování. Ve Windows se buď můžeš připojovat k síti "na požádání" (tzn. informace o připojení se moc nikam neukládají), nebo tzv. přes síťový profil – pro cílovou síť se vytvoří minimálně jeden XML soubor, kam se zapíšou její vlastnosti (SSID, heslo (v zašifrovaném tvaru), nastavení šifrování a autentizace...) a tyto informace pak systém používá, když se připojuješ přes to klasické rozhraní.

WlanClient pracuje čistě bez profilu, tzn. pouze na základě informací ze síťové karty, dalo by se říci (je to ale nepřesné). Proto nevidí připojení skrz profil. Zároveň Windows neuvidí připojení skrz WlanClienta. Obecně se WlanClient nehodí (a ani moc nefunguje) na sítě, kde je nějaké těžší zabezpečění než heslo. Kvůli tomu, že nepracuje přs profily také nepodporuje automaticke připojení, pokud spojení vypadne.

Uvažoval jsem, že bych do WlanClienta dopsal i práci z profily, ale zatím na to nebyl čas.

Odpovědět 21. listopadu 20:42
2 + 2 = 5 for extremely large values of 2
Avatar
IH8Linux
Člen
Avatar
IH8Linux:

Popravdě od tý doby co mám win7 mám pocit že připojení k síti přes můj router není vždy stejné...je normální že mám adaptér pro tunelové připojení isatap:
Microsoft ISATAP Adapter
Microsoft ISATAP Adapter #2
Mě se WlanCllient líbi. Díky za něj

 
Odpovědět 21. listopadu 21:07
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na IH8Linux
Martin Dráb:

Ano, více verzí ISATAP adaptéru jsem si všiml na více systémech. Zdá se, že je to celkem běžná věc, i když jsem ji blíže nezkoumal.

Odpovědět 21. listopadu 22:06
2 + 2 = 5 for extremely large values of 2
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 4 zpráv z 4.