Komunikační protokol IPX

Komunikační protokol IPX (Internetwork Packet Exchange) je nespojově orientovaným (datagramovým) protokolem, který zaručuje předávání nezávislých paketů v intersíti. Pohybujeme se tedy na úrovni síťové vrstvy OSI modelu. Každý paket se sítí šíří samostatně bez vazby na ostatní pakety a bez garance, že vůbec bude doručen. Z principu vzájemné nezávislosti paketů plyne, že obecně nemůžeme spoléhat na to, že pořadí, v jakém byly pakety odeslány bude nutně odpovídat pořadí, v jakém budou přijaty. Může rovněž dojít k duplikaci paketu, to znamená, že jednou vyslaný paket přijmeme dva i vícekrát. Problémy duplikace a změny pořadí se ovšem mohou vyskytnout pouze v sítích obsahujících alternativní cesty - paket může být přebrán více routery a pokud se cesty opět spojí, dojde tím k jeho duplikaci. Změna pořadí paketů rovněž připadá v úvahu v sítích s více cestami, protože cesty mohou mít obecně různé zpoždění a každý paket se může k příjemci pohybovat jinou cestou. Je tedy možné, že paket vyslaný později se k přijemci dostane cestou s nižším zpožděním dříve než předcházející paket, který byl ovšem směrován "pomalejší" cestou.

Protokol IPX byl odvozen ze standardu XNS zavedeného firmou Xerox.

Adresace v intersíti s protokolem IPX

Než přikročíme k vysvětlení chování protokolu IPX, je nutné objasnit, jakým způsobem jsou jednotlivé uzly sítě identifikovány. Učiňmě proto na tomto místě krátkou vsuvku o adresaci v intersítích používajících protokol IPX.

Adresa každého uzlu v síti s IPX protokolem je dána jednak dvaatřicetibitovou adresou sítě (Network Address] a osmačtyřicetibitovou adresou uzlu v rámci této sítě (Node Address]. Adresa sítě je přidělována administrátorem a musí být samozřejmě v rámci celé intersítě jednoznačná. Jako adresa uzlu na úrovni síťové vrstvy se téměř vždy přebírá hardwarová adresa adaptéru (z linkové vrstvy]. V případě sítí Ethernet je takovéto mapování adres přímé, zatímco u sítí s adresami sestávajícími z nižšího počtu bitů (ArcNet, Token Ring] jsou zbývající významnější bity doplněny nulami. Adresa uzlu s hodnotou 0xFFFFFFFFFFFF je vyhrazena pro všesměrové vysílání (broadcast], hodnota 0 síťové adresy označuje implicitní síť, tj. síť, ke které je stanice přímo připojena (default network).

Mimo adres uzlů jsou komunikující procesy navíc identifikovány tzv. číslem socketu. Na každé komunikující stanici (uzlu) totiž může současně běžet celá řada procesů, které budou chtít nezávisle na sobě komunikovat. Proto je každému procesu (službě) přiděleno 16-bitové číslo socketu, které jej v rámci stanice jednoznačně identifikuje. Všechny pakety vyslané tímto procesem pak spolu s adresou odesílatele ponesou i číslo socketu vysílajícího procesu. Naopak při příjmu paketu stanicí zaručí ovladače síťového adaptéru, že paket bude doručen právě jen procesu, jenž je identifikován číslem soketu příjemce v hlavičce IPX paketu. Některá čísla socketů mohou být uživatelem používána libovolně (0x4000-0x8000], zatímco jiná jsou vyhrazena pro standardní síťové služby (Novell) nebo rezervována jednotlivými výrobci síťových aplikací (hodnoty 0x8000-0xFFFF]. Tak například příjde-li Novell file serveru paket s číslem socketu 453, okamžitě z toho pozná, že se jedná o paket nesoucí informaci pro budování směrovacích tabulek (RIP) a podle toho s ním naloží.

Není podmínkou, aby proces přijímal pouze pakety s jediným číslem soketu - může zaregistrovat zájem o celou řadu čísel. Podrobněji se sockety budeme zabývat při popisu jednotlivých funkcí pro komunikaci prostřednictvím IPX.

Struktura paketu IPX

Dobrým vodítkem k pochopení práce protokolu IPX je znalost významů jednotlivých polí hlavičky paketu. Zopakujme, že paket je obsahem datové části rámce druhé vrstvy a během šíření sítí není (s výjimkou jednoho pole hlavičky) modifikován.

Každý paket sestává z hlavičky (header) a datové části. Hlavička obsahuje servisní informace, jako je adresa odesílatele a adresa příjemce, zatímco v datové části jsou uživatelská data. Během šíření paketu sítí je routery analyzována pouze hlavička paketu, uživatelská data zůstávájí netknuta.

Celková délka paketu IPX je maximálně 576 bajtů, takže s ohledem na velikost hlavičky 30 B zbývá 546 bajtů na užitečnou informaci. Poznamenejme, že implementace IPX dodávané spolu s novějšími verzemi Novellu umožňují nakonfigurovat i větší délku paketu (v terminologii Novellu označovaných zkratkou LIP - Large Internet Packet). Tím dosáhneme lepšího využití sítě, jelikož se zvýší poměr přenášené užitečné informace k informaci servisní. Při konfigurování větších maximálních velikostí paketů než standardních 576 byte však musíme být opatrní s ohledem na to, že starší verze routerů nemusí být schopny takto dlouhé pakety zpracovat a v horším případě routeru s méně robustním software může teoreticky dojít i k jeho zhroucení. V případě použití LIP nesmíme pochopitelně překročit maximální délku rámce linkové vrstvy žádné ze sítí, jimiž mají takovéto pakety procházet, protože IPX nepodporuje (narozdíl např. od protokolu IP) fragmentaci a znovusestavování (reassembling) paketů.

Podívejme se nyní podrobněji na jednotlivé položky hlavičky paketů IPX, která je vyobrazena na obr. I.1.

Obrázek I.1

OffsetObsah
0 Checksum
2 Length
4 Transport Control
5 Packet Type
6 Destination Network
10 Destination Node
16 Destination Socket
18 Source Network
22 Source Node
28 Source Socket

Checksum kontrolní součet. Je-li paket IPX nesen přímo v rámci ETHERNET_802.3 (bez pole LLC), je zde hodnota 0xFFFF. Zabezpečení dat se provádí také na úrovni linkové vrstvy nebo uživatelsky (tedy ve vyšších vrstvách).

Length délka paketu včetně záhlaví. Z tohoto pole můžeme vyčíst délku přijatého paketu. Délka vysílaného paketu se do tohoto pole doplní na základě součtu délek z deskriptorů fragmentů v ECB (viz. dále)

Transport Control pole používané směrovači pro likvidaci bloudivých paketů (někdy označované TTL - Time to Live). Před vysláním paketu se nastaví na nulu (to učiní driver IPX). Při průchodu směrovačem se hodnota zvýší o jedničku a když dosáhne určité hranice (zpravidla 16, ale lze i nastavit), paket se zruší se. Tím se zamezuje cyklickému předávání paketů a zahlcení sítě zbloudilými pakety. Je si však nutné uvědomit, že rozsah sítě (co do počtu směrovačů mezi nejvzdálenějšími stanicemi) je omezen maximální hodnotou TTL.

Packet Type typ paketu, blíže definuje určení údajů v datové části paketu. Některé hodnoty jsou shrnuty v tab. I.1

Tabulka I.1

0Neznámý paket
1RIP Paket (Routing Information Protocol]
4Packet Exchange Packet
5SPX (Sequenced Packet Exchange ]
16-31experimentální protokoly
17NCP (NetWare Core Protocol ]

Pro účely experimentování bychom měli používat hodnoty 0 nebo 4.

Destination Network - adresa sítě, na níž je připojen uzel příjemce

Destination Node - adresa uzlu příjemce

Destination Socket číslo socketu příjemce, HI-LO format

Source Network - adresa sítě odesílatele

Source Node - adresa uzlu odesílatele

Source Socket - číslo socketu odesílatele, HI-LO

Je třeba upozornit, že v souladu s konvencemi používanými v počítačových sítích jsou vícebajtové binární hodnoty ukládány v pořadí významnější_bajt-méně_významný_bajt (HI-LO], což je opačný způsob, než je zvykem např. na mikroprocesorech INTEL. Tato konvence se samozřejmě vztahuje jen da číselné hodnoty určené pro předávání přes síť. Musíme s ní tedy počítat při sestavování hlavičky IPX, nikoliv však např. při předávání parametrů dále popisovaným funkcím.

Blok řízení událostí ECB (Event Control Block)

Z hlediska programátorského se jednotlivé funkce, jako je žádost o vyslání paketu nebo čekání na paket realizují zadáváním požadavků prostřednictvím řídící struktury událostí - ECB (Event Control Block]. Jednotlivé položky struktury podávají doplňující parametry k požadované akci, samotné funkce realizující jednotlivé činnosti se volají s parametrem, jímž je odkaz na strukturu ECB. Protože zde pracujeme se službami, které mohou trvat obecně libovolnou dobu (jako je např. čekání na příjem paketu), je jejich zpracování řešeno asynchronně. Jednotlivé požadavky si ovladač ukláda do fronty a vyřizuje je v pořadí, v jakém je to možné. Každý proces může vydat libovolné množství takovýchto požadavků zároveň (ve skutečnosti je maximální hodnota konfiguračním parametrem ovladače IPX). Poznamenejme, že pořadí zpracování událostí není garantováno, tedy např. při vydání více žádostí o vyslání paketu mohou být tyto pakety vyslány v různém pořadí. Tomu je samozřejmě možné předejít tím, že program vydá v jednom okamžiku jen jeden požadavek na vysílání a před vydáním dalšího počká na dokončení požadavku předchozího.

O dokončení události svázané s jistým požadavkem (definovaným konkrétní instancí struktury ECB] je uživatel informován nastavením položky ECB InUse na nulu. Z položky CompletionCode se může dozvědět, jak požadovaná akce skončila. Nulová hodnota znamená úspěch, ostatní hodnoty identifikují chybu.

Existuje ještě i jiný způsob, kterým se mohou programy o ukončení provádění požadavku dozvědět. Je jím vyvolání obslužné rutiny přerušení - ESR (Event Service Routine]. Jednou z položek struktury ECB je totiž položka ESR Address, do níž je možné vložit (32-bitovou,segment:offset) adresu rutiny, která má být při (úspěšném či neúspěšném) dokončení akce vyvolána. Je-li zde uvedena hodnota NULL, žádná rutina se nevyvolává a program musí ukončení akce testovat pollingem, tj. periodickým testováním hodnoty položky InUse příslušné struktury ECB.

Podívejme se nyní podrobněji na strukturu ECB, jejíž rozložení můžeme vysledovat z I.2. Některé položky jsme již diskutovali.

Obrázek I.2

OffsetObsahŘazení
0Link Addressoffset-segment
4ESR Addressoffset-segmnent
8In Use Flag
9Completion Code
10Socket NumberHI-LO
12IPX Workspace
16Driver Workspace
28Immediate Address
34Fragment CountLO-HI
36Fragment Address 1
40Fragment Size 1LO-HI
42Fragment Address N
46Fragment Size NLO-HI

Význam jednotlivých položek ECB je následující:

Link Address - Slouží pro vnitřní potřebu IPX, (používá jako link na další ECB strukturu ve zřetězeném seznamu]

ESR Address far adresa rutiny, která  se provede po ukončení události definované příslušným ECB. NULL pokud se žádná rutina nemá provádět

In Use Flag- příznak, který určuje, zda se ECB stále vede v patrnosti (nenulová hodnota) nebo je požadovaná akce již ukončena (nula) a ECB struktura může být zrušena.

Z nenulové hodnoty můžeme blíže rozpoznat činnost, která je právě prováděna (viz Tab. I.2).

Tabulka I.2

Hodnota In Use FlagOdpovídající činnost
FBhvyslání nebo přijetí proběhlo, ale ECB dočasně čeká na dodatečné zpracování
FDhUdálost byla naplánována a IPX čeká na vypršení intervalu - při použití AES
FEhČeká se na příchod paketu
FFhProbíhá vysílání paketu
FAhECB je právě zpracováván ovladačem IPX

Completion Code - Po ukončení akce (tedy po nastavení příznaku InUse na nulu) určuje hodnota tohoto pole výsledek operace. Nulová hodnota znamená úspěch, nenulová hodnota chybový kód.

Socket - představuje číslo socketu, se kterým má být událost popsaná ECB strukturou svázaná. Socket musí být nejprve otevřen funkcí IPXOpenSocket(). IPX Workspace slouží pro vnitřní potřebu ovladače IPX. Po dobu InUse<>0 se nesmí měnit.

Driver Workspace - slouží pro vnitřní potřebu ovladače síťového adaptéru. Po dobu InUse<>0 se nesmí měnit.

Immediate Address - adresa uzlu, jehož směrem se bude vysílat nebo z jehož směru má být přijat paket. V případě lokální sítě je to přímo adresa příjemce, resp. odesílatele. Složitější situace nastává u intersítí, kde se do této položky vkládá adresa nejvhodnějšího routeru, který je nejbližší na cestě k partnerské stanici (popř. k síti v případě všesměrového vysílání na určitou síť)

Je třeba si ujasnit, že se zde v podstatě jedná o adresu použitou pro přenos paketu rámcem linkové vrstvy. Všimněme si, že pole ImmediateAddress sestává pouze se šesti bajtů, tedy adresy uzlu - předpokládá se totiž, že adresa bude použita linkovou vrstvou, která zajišťuje přenos rámců pouze v rámci jediné sítě. Pokud je adresát na společné síti s odesílatelem, zašle se rámec přímo jemu. V opačném případě se rámec zašle na vhodný router, ten z něj vybalí IPX paket (jenž ve své hlavičce nese informaci o adresátovi) a na základě svých směrovacích tabulek paket opět zabalí do rámce odpovídající síťové technologie výstupního interface a směruje jej na další směrovač v cestě nebo na cílovou stanici, pokud je připojena ke stejné síti. Nejvhodnější router pro směrování rámce je možné zjistit pomocí funkce IPXGetLocalTarget(), která si k tomu účelu vyžádá informace od protokolu RIP.

Zbývající položky již pouze definují buffer, v němž je připraven paket určený k vyslání, resp. buffer, do nějž má být uložen příchozí paket. Jak můžeme předpokládat, je buffer určen adresou a délkou. V bloku ECB se buffer zadává poněkud obecněji a to tak, že máme možnost sestavit buffer z několika nezávislých paměťových bloků obecně různých délek - fragmentů. Každý fragment je v ECB reprezentován dvěma položkami - deskriptorem fragmentu, jenž vždy sestává z adresy (Fragment Address) a délky (Fragment Size) bloku. Počet fragmentů zadaných deskriptory fragmentů určuje položka Fragment Count, z jejíž hodnoty takto plyne i celková velikost ECB struktury. Paket bude sestaven z obsahu paměťových bloků v pořadí, v jakém jsou uvedeny jejich deskriptory. Je třeba pamatovat na to, že první fragment musí pojmout celou hlavičku IPX (tedy 30 bajtů], hlavička nesmí být rozdělena do více fragmentů.

Koncept fragmentace bufferu má sloužit pro omezení přesunů dat v paměti. Představme si například, že chceme poslat paket, jehož datová část má sestávat z obsahu několika objektů umístěných na různých místech v paměti. Pokud by fragmentace bufferu nebyla implementována, museli bychom nejprve sami alokovat buffer pro paket patřičné délky, do něj nakopírovat všechny požadované objekty a poté jej předat k vyslání. Jelikož můžeme předpokládat, že i samotný ovladač karty provádí kopírování dat do vnitřních bufferů, procesor by byl zbytečně zatěžován mnohonásobným zbytečným kopírovním dat mezi buffery.

Pro jednoduchost budeme v následujících příkladech pracovat vždy s jediným fragmentem.

Rutina obsluhy událostí (Event Service Routine)

V předchozím textu jsme se zmínili o rutině ESR, která se může vyvolávat po ukončení akce spojené s určitým zadaným požadavkem. Je třeba si uvědomit, že rutina ESR je vyvolávána jako reakce na asynchronní událost (přerušení od adaptéru] a jako s obslužnou rutinou přerušení s ní je také třeba zacházet. V okamžiku vstupu do rutiny jsou zakázána přerušení a registrový pár ES:SI ukazuje na ECB, ke kterému se ohlašovaná událost váže. V tomto ECB jsou již doplněny položky InUseFlag=0 a CompletionCode. Registr AL indikuje, zda k vyvolání obslužné rutiny došlo v důsledku události ovladače IPX (0xFF) nebo modulu AES (0x00). Zkratkou AES je v terminologii Novellu označován tzv. asynchronní plánovač událostí (Asynchronous Event Scheduller), který slouží jako podpora pro vytváření síťových aplikací. O AES se ještě později stručně zmíníme.

Při výstupu z ESR rutiny se předpokládají zakázaná přerušení a návrat se provádí instrukcí RETF.

V souvislosti s ESR ještě poznamenejme, že všechny funkce IPX jsou reentrantní a že je lze s výjimkou funkce IPXCloseSocket()volat z ESR. V souvislosti s tím však musíme zvažovat nutnost povolení přerušení a z toho případně vyplývající požadavek na reentrantnost naší obslužné rutiny.

Volání služeb IPX

V následujících odstavcích si objasníme programátorské rozhraní ovladače protokolu IPX v jeho verzi pro MS-DOS. Verze pro MS-Windows či např. OS/2 jsou velmi podobné, pouze způsob volání jednotlivých funkcí je odlišný (jelikož jde o DLL)-

Služby ovladače IPX pro DOS je možné volat několika způsoby. Firma Novell doporučuje použít při vytváření nových aplikací následující způsob:

Všechny služby poskytované modulem IPX se volají přes společný vstupní bod, s tím, že konkrétní služba, jež má být vyvolána, se určí hodnotou v určeném registru. Počet a rozložení ostatních parameterů se u jednotlivých služeb liší.

Po návratu ze služby bychom vždy měli ověřit chybový kód umístěny službou do registru AL. Hodnota nula indikuje úspěch, nenulové hodnoty charakterizují příčinu neúspěchu. Konkrétní hodnoty chybových kódů, které můžeme z volání jednotlivých služeb obdržet, jsou vždy uvedeny u popisů těchto služeb.

Prvotním problémem při přístupu ke službám IPX je tedy získání adresy vstupního bodu do modulu IPX. To lze provést pomocí DOSovské multiplexační služby INT 2F: do registru AX připravíme hodnotu 7A00h (identifikace Novell IPX], voláme přerušení INT 2F a testujeme návratovou hodnotu v registru AL. Pokud není modul IPX instalován, bude v AL hodnota 0 - vložil ji tam původní obslužný program INT 2F. Jestliže je však IPX instalován, přesměruje vektor INT 2Fh na sebe a filtruje volání s hodnotou AH-7A00h. Volání s ostatními hodnotami předává původní rutině. Při detekci volání s jemu odpovídající hodnotou IPX zajistí naplnění registrového páru ES:DI adresou vstupního bodu pro volání služeb IPX a registr AL nenulovou hodnotou, která indikuje volajícímu programu, že zjištění vstupního bodu proběhlo úspěšně.

Ve starší dokumentaci se můžeme také setkat ještě s jiným způsobem volání služeb IPX a to prostřednictvím vektoru přerušení 7Ah. Rozložení parametrů v registrech je naprosto stejné jako v případě volání prostřednictvím vstupního bodu získaného výše popisovaným způsobem. Použití tohoto způsobu volání však firma Novell nedoporučuje.

Funkce pro příjem a vysílání paketů

Abychom získali základní představu o způsobu implementace programů pro přenos paketů, naznačíme nejprve filosofii typických programů přijímače a vysílače a až poté podrobně rozebereme jednotlivé použité funkce.

Řekli jsme si, že pakety jsou jednotlivým procesů doručovány podle čísla socketu obsaženého v hlavičce IPX paketu. Náš proces tedy musí nejprve u ovladače zaregistrovat všechna čísla socketu, na nichž hodlá pakety přijímat - otevřít sockety. K tomu slouží funkce OpenSocket(), jejímž parametrem je požadované číslo socketu. Programy běžně otevírají i více socketů současně, v našem ukázkovém případě však postačí jediný. Před vysláním paketu je rovněž nutné otevřít socket - jeho číslo bude umístěno do hlavičky IPX jako identifikace socketu odesílatele. Na společném socketu lze současně přijímat i vysílat, proto nám v nejjednodušším případě postačí jediný socket.

Předpokládejme nyní, že hodláme implementovat vysílač. Nejprve tedy musíme v paměťovém bufferu zkonstruovat rámec IPX, který hodláme odeslat a to včetně vyplnění některých polí hlavičky. Hlavička musí odpovídat struktuře z obr. I.1; je nezbytné vyplnit položky jednoznačně identifikující adresáta (Destination Network,Node,Socket] a typ paketu (Packet Type]. Za hlavičku připojíme uživatelská data . Informaci o celkové délce paketu pro položku Length získá IPX ze struktury ECB. Zbývající položky (zejména adresu odesílatele) doplní IPX

Nyní musíme vytvořit řídící blok události (ECB), kterým ovladači IPX sdělíme náš požadavek na vyslání paketu. V instanci struktury ECB vyplníme položku FragmentCount=1 a deskriptor prvního fragmentu se odkážeme na buffer s připraveným paketem. V ECB musíme dále vyplnit položky Socket, Immediate Address a ESR Address. Poté již můžeme předat požadavek ke zpracování IPX voláním služby IPXSendPacket().

Dále už zbývá jen počkat, až bude paket skutečně odeslán - buď se o tom dozvíme prostřednictvím ESR rutiny nebo čekáme ve smyčce, až položka InUse příslušného ECB dosáhne nulové hodnoty. Poté již zbývá jen z položky Completion Code ověřit, zda vyslání paketu proběhlo úspěšně, nebo se zde nachází kód některé chyby.

Odpovídající sekvenci můžeme nalézt i na straně přijímače. Nejprve se otevře soket, na kterém se budou očekávat příchozí pakety (funkcí IPXOpenSocket()]. Poté je třeba registrovat u IPX požadavek na příjem paketu, což opět vede k zadání tohoto požadavku prostřednictvím ECB. V ECB musíme vyplnit InUse=0xFF, číslo socketu, adresu ESR rutiny (nebo NULL pokud není požadována) a alespoň jeden deskriptor fragmentu nastavit na předem naalokovaný buffer určený pro uložení přijatého paketu. Pak již můžeme požadavek o přijetí paketu zaslat ovladači IPX prostřednictvím funkce IPXListenForPacket(). Čekání na dokončení akce se provede stejně jako v případě vysílání paketu (testování položky InUse) s tím, že musíne počítat s možností, že žádný vhodný paket nebude přijat a k nastavení InUse na nulu nikdy nedojde. Čekání na paket můžeme kdykoli zrušit voláním IPXCancelEvent().

Jestliže již nehodláme na socketu dále komunikovat, musíme jej jak na straně vysílače, tak na straně přijímače uzavřít voláním služby IPXCloseSocket()..

Služby související s komunikací prostřednictvím protokolu IPX

int IPXOpenSocket(BYTE* socketNumber, BYTE socketType);

ustup:

	BX: 00h
	DX: požadované číslo socketu (HI-LO) 
	AL: Příznak trvání socketu
	  00h - socket se uzavře při ukončení aplikace nebo po volání služby IPXCloseSocket
	  FFh - socket se uzavře jedině explicitně voláním IPXCloseSocket(). 

Výstup: AL - Chybový kód DX - Přiřazený socket

Služba otevře zadaný IPX socket. Pokud použijeme namísto čísla socketu hodnotu 0, IPX vybere vhodný volný socket, jehož číslo umístí do registru DX. Příznakem trvání socketu můžeme řídit, zda se socket automaticky uzavře při ukončení aplikace. Automatickému uzavření můžeme chtít předejít například v případech některých TSR programů, které během instalace otevřou socket a dále na něm hodlají komunikovat.

Počet současně otevřených socketů na jedné stanici lze konfigurovat, implicitní hodnota je 20.

Možné chybové kódy:

	FFh - Socket je již otevřen (můžeme ignorovat)
	FEh - Tabulka socketů je plná (příliš mnoho současně otevřených socketů)

void IPXCloseSocket(WORD socketNum);

Vstup:
	BX: 01h
	DX: číslo socketu - HI-LO

Výstup: žádný

Uzavře zadaný otevřený socket a zruší všechny případné požadavky svázané s tímto socketem. Každý ze zrušených požadavků obdrží v položce CompletionCode struktury ECB hodnoty FCh indikující násilné zrušení požadavku, položka InUse se překlopí do nuly. ESR rušených požadavků se nevyvolává.

Tato služba se nesmí volat z těla ESR.

Před ukončením programu je nutné zabezpečit korektní uzavření všech socketů, které byly otevřeny.

void IPXSendPacket(ECB* ecb);

Vstup:
	BX: 03h
	ES:SI: Adresa ECB

Výstup: žádný

Volání předá do fronty IPX požadavek na vyslání paketu, popsaný obsahem položek předávaného ECB. Řízení je okamžitě vráceno volajícímu a IPX se pokouší o vyslání paketu na pozadí. V ECB musí být vyplněny položky ESR Address, Socket, Immediate Address, Fragment Count a alespoň jeden deskriptor fragmentu, který musí obsahovat zkonstruovaný IPX paket, v jehož hlavičce budou vyplněna pole sítě, uzlu a socketu adresáta a Packet Type. IPX doplní položky Checksum, Transport Control a položky identifikující odesílatele.

Po uskutečnění pokusu o vyslání paketu IPX překlopí hodnotu položky InUse příslušného ECB do nuly a nastaví odpovídajícím způsobem kód CompletionCode:

00h- Úspěšné vyslání. Je nutné připomenout, že tento stav neznačí také úspěšné přijetí (paket mohl být zkreslen nebo ztracen na přenosové cestě)

	FCh - žádost zrušena aplikací (službou IPXCancelEvent())
	FDh - Chybný formát paketu (kratší než 30B, delší než 576B, nulový počet
	          fragmentů nebo první fragment kratší než 30B)
	FEh - Paket nedoručitelný
	FFh - Paket se nepodařilo vyslat z důvodu hardwarové chyby

void IPXListenForPacket(ECB* ecb);

Vstup:
	BX: 04h
	ES:SI: Adresa ECB

Výstup:	AL - chybový kód
	Chybove kódy: 
		FFh - Neexistuje čekající socket

Volání zařadí do fronty ovladače IPX žádost na příjem paketu, specifikovanou předaným ECB. V ECB musí být předem vyplněny položky ESR Address, Socket, Fragment Count a alespoň jeden deskriptor fragmentu.

IPX nastaví položku InUse v příslušném ECB na hodnotu FEh indikující, že se čeká na přijetí paketu. Počet žádostí o přijetí paketu na jednom socketu není omezen. V okamžiku příchodu paketu IPX vybere některý ECB popisující požadavek na příjem paketu a použije informací z něj pro umístění příchozích dat a případně vyvolání ESR rutiny. Předtím však odpovídajícím způsobem nastaví položky InUse a CompletionCode a vyplní položku ImmediateAddress adresou odesílatele, resp. posledního směrovače v cestě k naší stanici.

V případě zaslání více požadavků na příjem neni garantováno, že se ECB budou pro příchozí pakety vybírat nutně v pořadí, ve kterém byly modulu IPX předány.

CompletionCode v ECB může nabýt následujících hodnot:

	00h úspěšně přijatý paket
	FCh Požadavek na příjem zrušen aplikací (IPXCancelEvent())
	FDh Byl přijat paket, ale poskytnutý buffer nepostačuje k umístění přijatých dat
	FFh Socket definovaný v ECB není otevřen

void IPXGetLocalTarget(BYTE* netAddress, BYTE* immediateAddress, int* transportTime);

Vstup:

	BX: 02h
	ES:SI - ukazatel na buffer žádostí (tab. I.4)
	ES:DI - ukazatel na buffer odpovědi (tab I.5)

Výstup:
	AL - chybový kód:
 	    FAh - žádná cesta k cíli nebyla nalezena 

CX - odhadovaná doba přenosu rámce (Transport Time), v počtu tiků

Služba vrátí k zadané IPX adrese vzdálené stanice nejbližšího prostředníka, který je připojen s lokální stanicí na společnou sít. Je-li vzdálená stanice připojena na stejnou síť jako lokální, vrátí se přímo její adresa, v opačném případě adresa nejvhodnějšího směrovače pro daný směr. Služba navíc vrací odhad doby, kterou trvá přenos 576-bytového paketu k cílové stanici. Tato doba je měřena v počtech tiků (tj. asi 1/18 sekundy).

Tabulka I.4: Buffer žádosti pro službu IPXGetLocalTarget

OffsetObsahTyp Řazení
0Destination Networkbyte[4]HI-LO
4Destination Nodebyte[6] HI-LO
10Destination Socketbyte[2]HI-LO

Tabulka I.5: Buffer odpovědi pro službu IPXGetLocalTarget

OffsetObsahTyp
0Local Target Node Address byte[6]

Adresa prostředníka se použije pro vyplnění pole ImmediateAddress struktury ECB při vysílání paketu. Služba nesmí být volána z obslužné rutiny přerušení.

void IPXGetInternetworkAddress(BYTE* netAddress);

Vstup:
	BX: 09h
Výstup:
	ES:SI - ukazatel na buffer odpovědi (tab. I.6)

Služba vrátí adresu uzlu a sítě lokální stanice.

Tabulka I.6 - Buffer odpovědi pro službu IPXGetInternetworkAddress

OffsetObsahTyp
0Network Addressbyte[4]
4Node Addressbyte[6]

int IPXCancelEvent(ECB* ecb);

Vstup:
	BX: 06h
	ES:SI - adresa rušeného ECB

Výstup:
	AL - chybový kód 
	  F9 - Událost nemůže být zrušena
	  FF - ECB není v používání

Volání zruší požadavek dříve zadaný modulu IPX prostřednictvím bloku ECB. Při úspěšném zrušení se příznak InUse v ECB překlopí do nuly a nastaví se kód CompletionCode na hodnotu FCh. Narozdíl od korektního vyřízení požadavku se nevolá rutina ESR.

void IPXDisconnectFromTarget(BYTE* netAddress);

Této služby se využívá pro informování specifikovaného čekajícího (listening) socketu, že již žádná další data nebudou vyslána.

Vstup: 
	BX 0Bh
	ES:SI: ukazatel na buffer žádostí, tab. I.7

Výstup: žádný

Tabulka I.7: Buffer žádosti pro službu IPXDisconnectFromTarget

OffsetObsahUložení
0Destination network
4Destination Node
10Destination socketHI-LO

Služba IPXDisconnectFromTarget() napomáhá při komunikaci v některých sítích, kde jsou použity dvoubodové spoje na fyzické úrovni. Tato informace dovoluje síťovému ovladači iniciovat rozpad spojení, pokud adaptér takovouto službu podporuje. V případě běžných lokálních sítí není její volání nutné a uvádíme ji pouze pro úplnost.

Služba nesmí být volána zevnitř rutiny ESR

Příklad komunikace prostřednictním protokolu IPX

Prostředí: DOS; jazyk: Pascal; Překladač: Borland Pascal 6

ipx.pas Obalení funkcí ovladače - unit
snd.pas Vyslání paketu
recv.pas Příjem paketu

Modul IPX - knihovna funkcí C

Prostředí: DOS; jazyk: C++; Překladač: Borland C++ 3.1

ipx.h
ipx.c

Plánovač asynchronních událostí AES

Než přistoupíme k popisu několika zbývajících služeb pro podporu programování IPX komunikace, vraťme se alespoň stručně k již zmíněnému plánovači asynchronních událostí AES (Asynchronous Event Scheduler). Tento podpůrný prostředek napomáhá při vytváření aplikací, které vyžadují periodické provádění nějaké akce s tím, že vyvoláváním pravidelné činnosti nechceme zatěžovat strukturu hlavního programu. AES nám v zásadě dovolí naplánovat interval, po kterém má být vyvolána určená obslužná rutina přerušení a ve stanoveném čase ji také vyvolá. Komunikace s AES se děje s využitím ECB bloků. AES je významným pomocníkem při programování síťových aplikací, jelikož se zde často musíme potýkat se sledováním mnoha časových limitů souvisejících například s limity pro přijem potvrzení, nebo s dobami platností různých dat nestálého charakteru (směrovací tabulky, cache atd). Následující služby slouží právě k podpoře vykonávání asynchronních událostí.

unsigned IPXGetIntervalMarker(void);

Vstup:
	BX: 08h
Výstup:
	AX: Interval Marker

Vrací hodnotu neustále se inkrementujícího 16-bitového čítače. Čítač se inkrementuje od tiku hodin, tedy asi každou 1/18 sekundy. Dvojím voláním a odečtením hodnot můžeme změřit dobu mezi dvěmi časově blízkými událostmi.

void IPXScheduleIPXEvent(WORD timeUnits, ECB* ecb); /P>

Vstup:
	BX: 05h
	AX: Delay Time (délka intervalu v počtu tiků)
	ES:SI: Adresa ECB

Výstup: žádný 

Služba pro naplánování události . Parametrem DelayTime je udán počet tiků hodin do uskutečnění požadované události. V okamžiku vypršení zadaného časového limitu se nastaví položka InUse předaného ECB na nulu a vyvolá se příslušná ESR, je-li definována. Po dobu dekrementování čítače časového limitu je hodnota InUse rovna FDh.

Služba může být volána i z obslužné rutiny přerušení. Je tak možné například požádat o vyvolání určité obsluhy po zadaném čase, tam provést patřičné testy a pokud je třeba, událost přeplánovat (resp. naplánovat znovu) na pozdější dobu. K tomu pochopitelně můžeme využít stejného ECB, protože po vypršení časového intervalu již není v používání modulem IPX.

void IPXRelinquishControl(void);

Protokol IPX a MS Windows

V MS Windows můžeme k protokolu IPX přistupovat více způsoby. Jde zejména o využití programátorského rozhraní Windows Sockets, které od verze 2.0 podporuje mimo TCP/IP také IPX. Taktéž je možné doinstalovat klienta sítě Novell a využit API z Novell SDK (www.novell.com), které je až na několik drobností daných rozdílnými architekturami systémů, prakticky totožné se zde popisovanou DOSovskou verzí .

Závěr

Protokol IPX je protokol, který se donedávna používal jako základní protokol v sítích Novell. Je však třeba zdůraznit, jeho použítí není na sítě Novell nijak vázáno - můžeme jej použít pro komunikaci peer-to-peer v síti bez jakéhokoli standardního síťového software. Výhodou hovořící pro protokol IPX je skutečnost, že ovladače pro architekturu protokolového stacku Novell, které nás odstíní od hardwarově závislých detailů, jsou dnes dodávány prakticky s každým síťovým adaptérem a my je můžeme napojit na standardní hardwarově nezávislý modul IPXi, čímž poskytneme aplikacím definované softwarové rozhraní.

Literatura:

Netware - System Interface Technical Overview, Novell Inc., Provo, Utah

Jeger,D.: Přímá komunikace prostřednictvím IPX/SPX , LANcom 5-11/92