Politechnika Śląska w Gliwicach
Instytut Informatyki
Laboratorium Sieci Komputerowych
Temat:
„INTERFEJS PROGRAMOWY PROTOKOŁU
KOMUNIKACYJNEGO IPX/SPX”
1. Cel i zadania do wykonania w ramach laboratorium.
Laboratorium jest podzielone na dwie części. Część pierwsza poświęcona jest omówieniu przez prowadzącego zajęcia podstaw protokołu komunikacyjnego IPX/SPX jak oraz zapoznaniu się z interfejsem programowym tego protokołu komunikacyjnego.
Druga część przeznaczona jest na praktyczne wykorzystanie omawianego interfejsu do napisania programu (systemu) który komunikuje się z innymi stacjami w sieci za pomocą protokołu komunikacyjnego IPX/SPX.
2. Protokół komunikacyjny IPX/SPX.
Protokół komunikacyjny IPX/SPX jest firmową implementacją protokołu międzysieciowego rodziny XNS (Xerox Network Systems). Przeznaczenie tego protokołu to sieci typu LAN (Local Area Network).Udostępnia on podstawowe usługi komunikacyjne umożliwiające przesyłanie informacji pomiędzy stacjami roboczymi (pod pojęciem stacji roboczej mam na myśli każdy komputer) przyłączonymi do sieci, zaopatrzonymi w ten protokół. Protokół IPX/SPX jest w zasadzie połączeniem dwóch protokołów IPX i SPX:
protokół IPX (Internetwork Packet Exchange) jest protokołem realizującym transmisję bezpołączeniową. Protokół umożliwia wysłanie (i odbiór) informacji, ale nie gwarantuje, że dotrze ona do miejsca przeznaczenia (adresata). Nadawca nie jest informowany, czy informacja dotarła do adresata. Protokół IPX można porównać do protokołu komunikacyjnego UDP/IP.
protokół SPX (Sequenced Packet Exchange) jest protokołem realizującym transmisję połączeniową, który gwarantuje dostarczenie informacji do adresata (o ile po nawiązaniu połączenia stacja adresata nie uległa awarii). Stacja będąca w fazie połączenia, wysyła pakiety do momentu potwierdzenia ich otrzymania przez adresata. W przypadku, gdy otrzymanie pakietu nie zostaje potwierdzone, nadawca retransmituje go ponownie. Po kilkukrotnej, niepotwierdzonej retransmisji pakietu protokół SPX przyjmuje, że adresat lub medium transmisyjne uległo uszkodzeniu i przerywa połączenie. W przypadku zerwania połączenia ponowna wymiana informacji pomiędzy stacjami wymaga ponownego jego nawiązania. Analogią (oczywiści nie w 100%) do protokołu SPX może być np. protokół komunikacyjny TCP/IP.
Pakiet protokołu IPX/SPX ma zawsze stałą długość, która wynosi 576 bajtów z czego, w przypadku protokołu IPX 30 bajtów, w przypadku protokołu SPX 42 bajty są przeznaczone na nagłówek. Jak łatwo zauważyć, używając jednego pakietu można przesłać tylko (!) 546 bajtów informacji w przypadku protokołu IPX i 534 bajty w przypadku protokołu SPX.
Wielkość pakietu została ustalona na podstawie badań efektywności przesyłania danych ze względu na ilość kolizji bezpieczeństwo informacji (zakłócenia) itp.
Dokładna postać ramki dla obydwu protokołów przedstawiona jest w dalszej części instrukcji.
Chcąc wykorzystywać protokół IPX/SPX we własnych aplikacjach należy zwrócić uwagę na drobny, ale istotny szczegół. Otóż w procesorach rodziny INTEL przyjęto konwencję, iż w ciągu bajtów pierwszy jest najmniej znaczący (low/high byte order).W protokole IPX/SPX natomiast przyjęto konwencję odwrotną.
Podstawą wykorzystania protokołu IPX/SPX we własnych aplikacjach jest znajomość podstawowych struktur tego protokołu:
struktura adresu.
struktura bloku sterowania zdarzeniami.
struktura nagłówków (różne dla IPX i SPX).
Istnieją jeszcze inne struktury, które jednak nie będą nam potrzebne na tym etapie zaawansowania.
Przed użyciem odpowiednich struktur należy najpierw zarezerwować dla nich miejsce w pamięci operacyjnej.
2.1. Adresacja w protokole IPX/SPX.
Protokół IPX/SPX jak każdy protokół komunikacyjny posiada swój własny tryb adresacji pozwalający na jednoznaczną identyfikację procesu komunikującego się za pomocą tego protokołu. Postać adresu wykorzystywanego przez protokół IPX/SPX jest identyczny z postaciami adresów protokołów rodziny XNS. Całkowity adres składa się z dwunastu bajtów i jednoznacznie identyfikuje proces w obrębie sieci jako całości. Rysunek poniżej przedstawia postać adresu protokołu IPX/SPX.
A B C
bajt |
.. |
.. |
.. |
.. |
.. |
.. |
.. |
.. |
.. |
.. |
.. |
4b 6b 2b
Rys 1.
Postać adresu protokołu IPX/SPX.
W przedstawionej postaci adresu wyróżnia się trzy części, które w sumie tworzą adres jednoznacznie identyfikujący proces komunikujący się z wykorzystaniem protokołu IPX/SPX:
część A - pierwsza część adresu określa numer segmentu sieci i potocznie nazywany jest numerem sieci. Numer ten jest czterobajtowy i identyfikuje pojedynczy segment sieci w którym stacja korzystająca z protokołu IPX/SPX pracuje. Numer nadawany jest przez ruter (w sieci Novell NetWare - serwer) do którego segment jednostkowy jest dołączony.
część B - druga część adresu to sześciobajtowy identyfikator stacji, który często nazywany jest po prostu adresem stacji. W obrębie sieci jednostkowej identyfikator ten musi być unikalny. Identyfikator nie jest nadawany z zewnątrz lecz jest to numer nadawany fabrycznie karcie sieciowej. Adres stacji powinien jednoznacznie ją identyfikować w obrębie sieci jednostkowej.
część C - trzecia część adresu to dwubajtowy identyfikator gniazda nazywany numerem gniazda. Numer gniazda jest jednoznacznym identyfikatorem procesu w obrębie stacji. Jeden proces może korzystać z więcej niż jednego gniazda do komunikacji z innymi procesami w obrębie sieci . Dzięki mechanizmowi gniazd protokół komunikacyjny IPX/SPX może być wykorzystany także do komunikacji pomiędzy procesami w obrębie tej samej stacji. Rezerwacja konkretnego numeru gniazda polega na jego otworzeniu. Gniazda używanego przez inny proces nie można otworzyć. Protokół IPX/SPX pozwala na otworzenie wolnego gniazda o podanym numerze (jako argument funkcji otwierającej gniazdo) lub sam przydziela numer gniazda z puli gniazd nieużywanych w danym momencie przez inny proces. Niektóre numery gniazd są na stałe zarezerwowane przez pewne usługi zwłaszcza w sieciach pracujących z produktami Novell NetWare. Przykładem może być protokół RIP czy protokół SAP, które na stałe korzystają z gniazd o numerach odpowiednio 453H i 452H. Rezerwacja nie jest jednoznaczna z zablokowaniem tych gniazd do użytku „zewnętrznego” aczkolwiek nieświadome korzystanie z gniazd o takich numerach może spowodować nieprzewidziane skutki. System gniazd protokołu IPX/SPX można porównać z systemem portów protokołu TCP/IP i UDP/IP.
Poniżej przedstawiono przykładową deklarację (w języku C) struktury adresu protokołu IPX/SPX.
#define BYTE unsigned char
#define WORD unsigned int
typedef struct IPXAddress
{
BYTE network[4]; //numer sieci
BYTE node[6]; //numer stacji
WORD socket; //numer gniazda
}IPXAddress;
Przykład deklaracji struktury adresu protokołu IPX/SPX.
Ze względu na sposób przekazywania informacji wyróżnia się dwa tryby adresowania:
adresowanie bezpośrednie. Polega ono na podaniu konkretnego adresu (numeru) stacji (dokładnie chodzi o dokładny identyfikator sieciowy procesu) do którego pakiet ma być wysłany. Np. jeśli chcemy wysłać pakiet do procesu pracującego na stacji w sieci o numerze 10H i numerze karty sieciowej ef 23 0b ac 34 9a (szesnastkowo), związanego z gniazdem o numerze 4444H to kolejne bajty adresy IPX/SPX będą wyglądać następująco: 00 00 00 10 ef 23 0b ac 34 9a 44 44. Pakiet tak zaadresowany dotrze tylko do tego procesu (nawet inne procesy w obrębie tej samej stacji nie zostaną poinformowane o nadejściu pakietu). Jeżeli adresat znajduje się w innym segmencie sieci , pakiet przejdzie przez rutery łączące segmenty sieci i dotrze do niego, o ile odległość w ruterach lub mostkach będzie mniejsza od 16. Jeżeli adresat znajduje się w obrębie tego samego segmentu sieci co nadawca, podawanie numeru sieci nie jest konieczne.
adresowanie rozgłoszeniowe (broadcasting). Jeżeli chcemy przesłać informacje do wszystkich stacji w obrębie pojedynczego segmentu sieci w pole numeru stacji (część B) należy wpisać wartość: ff ff ff ff ff ff. Pakiet tak zaadresowany (broadcast) dotrze do wszystkich stacji w obrębie domeny rozgłoszeniowej, jednakże tylko te procesy zostaną o tym poinformowane, które związane są z numerem gniazda określonym w części C adresu. Pakiety takie są jednak odbierane tylko w obrębie domeny rozgłoszeniowej w której został wysłany (tzn. takie jest założenie, lecz istnieją sposoby aby pakiet taki był przesłany do innych segmentów sieci; przykładem bradcast'a który może zostać „przepuszczany” przez rutery może być np. pakiet protokołu SAP, ale opiera się to na innym mechanizmie ściśle związanych z działaniem serwisu SAP). W przypadku adresowania rozgłoszeniowego nie jest wymagane podawania numeru sieci (i tak pakiet rozgłoszeniowy dotrze tylko do stacji w obrębie jednego segmentu).
2.2. Blok sterowania zdarzeniami.
Podstawą korzystania z protokołu IPX/SPX jest znajomość struktury sterowania zdarzeniami - ECB (Event Control Block), której wymagają najważniejsze polecenia protokołu
(m.in. funkcja wysyłająca pakiety i ustawiająca nasłuch na pakiety nadchodzące). Struktura ECB składa się z szeregu pól, lecz tylko niektóre trzeba wypełnić aby móc korzystać z protokołu IPX/SPX (w zależności od używanej funkcji).
Poniżej przedstawiono przykładową deklarację (w języku C) struktury bloku sterowania zdarzeniami dla protokołu IPX i SPX.
#define BYTE unsigned char
#define WORD unsigned int
#define NWPTR far *
typedef struct ECBFragment
{
void NWPTR address; //adres bufora roboczego
WORD size; //rozmiar buf. W bajtach
}ECBFragment;
typedef struct ECB
{
void NWPTR linkAddress; //wsk. Następnego bloku
void (NWPTR ESRAddress)(); //adres procedury ESR
BYTE inUseFlag; //zaawansowanie zlecenia
BYTE completionCode; //kod realizacji zlec.
WORD socketNumber; //nr gniazda zw.ze zlec.
BYTE IPXWorkspace[4]; //pole rob. Mod. IPX/SPX
BYTE driverWorkspace[12]; //pole rob. prog. adapt.
BYTE immediateAddress[6]; //adr. stacji lub mostka
WORD fragmentCount; //ilość buf. roboczych
ECBFragment fragmentDescriptor[5]; //tablica adresów
//rozmiarów buforów
//roboczych (w tym
//przyp. 5-cio
//elementowa)
}ECB;
Przykład deklaracji struktury bloku sterowania zdarzeniami (ECB) protokołu IPX/SPX.
Poszczególne pola oznaczają:
linkAddress - wskaźnik następnego bloku w kolejce bloków. Pole to wypełniane jest w momencie wykonania zlecenia związanego z blokiem ECB i nie należy go modyfikować.
ESRAddress - w pole to można (lecz nie jest to konieczne) wprowadzić daleki adres procedury ESR (Event Service Routine). Jeżeli wartość tego pola jest różna od zera, to moduł IPX interpretuje ją jako adres procedury, którą należy uruchomić po zakończeniu zlecenia. Procedura ESR jest wywoływana z zablokowanym układem przerwań, należy więc zakończyć ja (również z zablokowanym układem przerwań) instrukcją RETF. Mechanizm wywoływania procedury ESR po zakończeniu zlecenia jest przydatny zwłaszcza w fazie oczekiwania (nasłuchiwania) na nadejście pakietu. Uwalnia to od „uciążliwego” sprawdzania stanu bloku ECB w celu określenia czy jakiś pakiet został odebrany. Mechanizm ten jednak wymaga większego zaangażowania programisty i znajomości zarządzania układem przerwań oraz zasad działania podprogramów obsługi przerwań.
inUseFlag - stan zaawansowania realizacji zlecenia. W momencie realizacji zlecenia pole to służy wyłącznie do odczytu. W każdym przypadku po przekazaniu zlecenia do realizacji pole to przybiera wartość różną od zera aż do chwili całkowitej jego realizacji. Sprawdzając czy wartość tego pola osiągnęła wartość zero można stwierdzić, czy realizacja zlecenia już się zakończyła.
completionCode - pole to przeznaczone jest tylko do odczytu i zawiera kod realizacji zlecenia ważny dopiero po zakończeniu jego realizacji. W polu ty mogą wystąpić wartości:
przy wysyłaniu:
00H - w porządku.
FCH - skasowano.
FDH - zła postać ramki.
FEH - ramka nie może być dostarczona (brak adresata, awaria itp.).
FFH - ramki nie można wysłać.
przy odbieraniu:
00H - w porządku.
FCH - skasowano.
FDH - brak miejsca w buforach.
FFH - gniazdo zamknięte.
socketNumber - numer gniazda z którym związane jest zlecenie. Właśnie w tym miejscu kojarzy się proces z konkretnym gniazdem. W danym momencie proces może być skojarzony z wieloma gniazdami (w danej fazie proces może realizować zlecenia na różnych gniazdach na raz).
IPXWorkspace - jest pole robocze modułu IPX/SPX i nie należy go modyfikować.
driverWorkspace - pole robocze dla programu obsługi adaptera sieci lokalnej. Pola tego nie należy modyfikować.
immediateAddress - w pole to wprowadza się adres stacji docelowej w obrębie sieci jednostkowej. Jeśli rzeczywista stacja docelowa jest w innej podsieci jednostkowej, to wprowadza się tu adres mostka w obrębie własnej sieci jednostkowej. Wartości w tym polu mają także inne znaczenia ale to nie należy do tematu laboratorium.
fragmentCount - wartość w tym polu określa ilość buforów roboczych, w których zapamiętano ramkę do nadania lub w których ma być zapamiętana ramka odebrana. Wartość ta musi wynosić co najmniej 1, gdyż nagłówek IPX/SPX'a jest także zaliczany do buforów roboczych i jest to zawsze pierwszy bufor roboczy (patrz pole następne).
fragmentDescriptor - tablica zawierająca kolejno: cztery bajty adresu w pamięci operacyjnej i dwa bajty długości kolejnych buforów roboczych zawierających ramkę nadawaną lub miejsce na ramkę odbieraną. Pierwszy bufor nie może mieć długości mniejszej niż długość nagłówka IPX lub SPX i mieści całą kopertę ramki. Łączna długość buforów nie może przekraczać 576 bajtów (tzn. może ale i tak zostanie obcięta do 576).
Blok ECB można modyfikować tylko wtedy gdy nie jest z nim związane żadne zlecenie (pole inUseFlag równe zero). Dla różnych zleceń wymagane jest poprawne wypełnienie tylko niektórych pól bloku ECB (patrz opis funkcji modułu IPX/SPX). W danym momencie jeden blok ECB może być związany tylko z jednym zleceniem IPX/SPX.
Nagłówek protokołu IPX/SPX.
Jak zapewne każdy zauważył nagłówek (header) IPX/SPX jest wymagany przy poprawnym konstruowaniu bloku ECB. To właśnie w nagłówku definiuje się adresy odbiorcy i nadawcy pakietu oraz inne informacje niezbędne dla poprawnej realizacji zleceń (oczywiście tych, które wymagają bloku ECB). Nagłówki protokołu IPX i SPX różnią się nieco od siebie, dlatego zarówno jeden jak i drugi zostaną przedstawione w tym punkcie.
Poniżej podano przykładowe deklaracje obydwu nagłówków wraz z opisem znaczenia poszczególnych pól.
#define BYTE unsigned char
#define WORD unsigned int
typedef struct IPXAddress
{
BYTE network[4]; //numer sieci
BYTE node[6]; //numer stacji
WORD socket; //numer gniazda
}IPXAddress;
typedef struct IPXHeader
{
WORD checkSum; //suma kontrolna
WORD length; //długość pakietu
BYTE transportControl; //pole kontrolne-licznik
BYTE packetType; //typ pakietu
IPXAddress destination; //adres przeznaczenia
IPXAddress source; //adres źródła
}IPXHeader;
Przykład deklaracji struktury nagłówka protokołu IPX.
Poszczególne pola oznaczają:
checkSum - pole to zawiera sumę kontrolną nagłówka i zawsze jest ustawiane przez moduł IPX/SPX na wartość FFFFH. Pola tego nie należy modyfikować.
length - zawiera sumę całej, kompletnej ramki IPX'a (od 30 do 576 bajtów) i jest ustawiana automatycznie przez moduł IPX/SPX. Wartość ta określa rozmiar danych pakietu, które wysyłamy lub odbieramy. Pola tego nie należy modyfikować.
transportControl - wartość w tym polu określi ilość bramek (podsieci) jaką przebył pakiet od nadawcy. Pole to wykorzystywane jest przez mostki międzysieciowe do badania ilości mostków lub ruterów jaką przebył pakiet. Pakiet może „przejść” tylko przez piętnaście mostków lub ruterów; szesnasty usuwa go (nie przekazuje dalej). Zapobiega to nieskończonemu ruchowi pakietu w sieci. Wartość w tym polu ustawiana jest na zera przez moduł IPX w momencie wysyłania pakietu.
packetType - wartość w tym polu informuje z jakim serwisem (protokołem) pakiet jest związany. Najczęściej spotykane typy pakietów to:
zdefiniwane przez firmę Xerox:
Kod |
Typ pakietu |
0 |
Nieznany typ pakietu. |
1 |
Pakiet protokołu RIP (Routing Information Packet). |
2 |
Pakiet typu „Echo” |
3 |
Pakiet typu „Error” |
zdefiniowane przez firmę Novell:
Kod |
Typ pakietu |
4 |
„Packet Exchange Packet” (IPX). |
5 |
„Sequenced Packet Protocol Packet” (SPX). |
16-31 |
Pakiety protokołów eksperymentalnych. |
17 |
Pakiet protokołu kontrolnego NCP. |
20 |
Pakiet protokołu NetBIOS. |
Korzystając z usług protokołu IPX należy wartość w tym polu ustawiać na zero lub cztery.
destination - adres odbiorcy pakietu.
source - adres nadawcy pakietu. Pole to jest wypełniane przez moduł IPX/SPX.
Nagłówek protokołu SPX:
#define BYTE unsigned char
#define WORD unsigned int
typedef struct IPXAddress
{
BYTE network[4]; //numer sieci
BYTE node[6]; //numer stacji
WORD socket; //numer gniazda
}IPXAddress;
typedef struct SPXHeader
{
WORD checkSum; //suma kontrolna
WORD length; //długość pakietu
BYTE transportControl; //pole kontrolne-licznik
BYTE packetType; //typ pakietu
IPXAddress destination; //adres przeznaczenia
IPXAddress source; //adres źródła
BYTE connectionControl; //sterowanie połączeniem
BYTE dataStreamType; //typ przes. danych
WORD sourceConnectionID;//identyfikator nadawcy
WORD destConnectionID; //identyfikator odbiorcy
WORD sequenceNumber; //licznik pak. wysłanych
WORD acknowledgeNumber; //numer spodz. pakietu
WORD allocationNumber; //ilość wolnych buforów
}SPXHeader;
Przykład deklaracji struktury nagłówka protokołu SPX.
Struktura nagłówka SPX zawiera 30 bajtów nagłówka IPX, które mają dokładnie takie samo znaczenie i przeznaczenie (z tą różnicą, że pole packetType przyjmuje wartość 5 - pakiet protokołu SPX) i siedem dodatkowych pól o następującym znaczeniu:
connectionControl - bity tego pola sterują dwukierunkowym przepływem danych w fazie połączenia SPX. Odpowiednie bity oznaczają:
Bity |
Znaczenie |
0-3 |
Nieużywane. |
4 |
Koniec wiadomości. |
5 |
Zarezerwowane. |
6 |
Żądanie potwierdzenia. |
7 |
Pakiet systemowy. |
dataStreamType - wartość tego pola identyfikuje rodzaj danych dołączonych do pakietu. Wartości od 00H do FDH są przeznaczone do użytku własnego i mogą być stosowane przez programistę do identyfikacji danych które będą przesyłane. Wartość FEH oznacza pakiet kończący połączenie. Kiedy klient żąda zamknięcia aktualnego połączenia, SPX generuje właśnie pakiet kończący połączenie (End-Of-Connection Packet). Pakiet ten jest dostarczany do partnera uczestniczącego w połączeniu jako ostatnia wiadomość w fazie połączenia. Wartość FFH oznacza potwierdzenie pakietu kończącego połączenie (End-Of-Connection-Acknowledgement Packet). Moduł SPX generuje ten pakiet automatycznie po otrzymaniu pakietu kończącego połączenie. Pakiet potwierdzający rozłączenie połączenia jest przez moduł SPX ustawiany jako pakiet systemowy i nie jest dostarczany do procesu partnera. Wartości FEH i FFH są zarezerwowane dla modułu SPX w fazie połączenia i powinny być używane.
sourceConnectionID - oznacza numer identyfikacyjny stacji będącej w fazie połączenia nadany przez moduł SPX nadawcy.
destConnectionID - oznacza numer identyfikacyjny stacji będącej w fazie połączenia nadany przez moduł SPX odbiorcy.
sequenceNumber - pole to stanowi licznik pakietów wysłanych przez proces w jedną stronę w fazie połączenia z innym procesem. Każda ze stron biorąca udział w połączeniu posiada swój własny licznik. Wartość tego pola zawiera się w granicach od 0000H do FFFFH. Przekroczenie górnej granicy tego zakresu nie powoduje żadnych skutków ubocznych.
acknowledgeNumber - pole to zawiera identyfikator pakietu, który moduł SPX spodziewa się otrzymać w fazie połączenia. Wartość ta jest inkrementowana, a po przekroczeniu wartości FFFFH jest ustawiana na 0000H.
allocationNumber - oznacza (wspólnie z polem acknowledgeNumber) ilość wolnych buforów przygotowanych do odbioru pakietów w fazie połączenia. Pole to jest używane przez moduł SPX do ustanowienia kontroli przepływu pakietów pomiędzy komunikującymi się procesami. Różnica pomiędzy wartością tego pola a wartością pola acknowledgeNumber jest równa liczbie zleceń nasłuchu w aktualnej fazie połączenia.
Struktury nagłówków nie mogą być modyfikowane jeżeli związane jest z nimi jakieś zlecenie.
Znajomość przedstawionych struktur jest niezbędna do poprawnego korzystania z usług protokołu IPX/SPX.
Interfejs programowy protokołu IPX/SPX.
Aby skorzystać z usług protokołu IPX/SPX musimy mieć pewien zbiór funkcji dostarczonych przez producenta protokołu, realizujących podstawowe usługi (zakładając, że protokół jest zainstalowany na naszej stacji ). Funkcje protokołu zarówno IPX jak i SPX są dostępne w wielu formach. Dla aplikacji tworzonych dla systemu operacyjnego DOS stworzone są specjalne biblioteki (dla protokołu IPX funkcje w systemie DOS dostępne są pod przerwaniem 7AH), dla programujących pod systemem Windows 3.x/95 istnieją różne biblioteki (DLL) np. „NWIPXSPX.DLL” (aby korzystać z tych funkcji potrzebne są jeszcze następujące pliki: „NWCALDEF.H”, „NWDIAG.H”, „NWIPXSPX.H”, „NWSAP.H” , „NXTW.H”, oraz „NWIPXSPX.LIB”), dla OS/2 (32-bit), Windows 95 i Windows NT - „NWSIPX.DLL” (oraz dodatkowe pliki nagłówkowe). Funkcje dla różnych systemów działają w identyczny sposób (różnice są na innym poziomie: przydziału pamięci, zarządzania zasobami itp.). W związku z tym poniżej zostały przedstawione funkcje dla systemu DOS (funkcja dla pozostałych systemów są analogiczne i niewiele się różnią).
Funkcje (konwencja w języku C) protokołu IPX (alfabetycznie):
int IPXCancelEvent( ECB far *eventControlBlock) - funkcja ta kasuje zlecenie (będące w kolejce zleceń modułu IPX) związane z blokiem ECB podanym jako argument funkcji (dokładnie - daleki wskaźnik na blok ECB). Wartość zwracana przez funkcję informuje o wyniku wykonania funkcji:
Kod zwracany |
Znaczenie |
00H |
Funkcja zakończyła się sukcesem. |
F9H |
Blok ECB nie może być usunięty z kolejki zdarzeń. |
FFH |
Z blokiem ECB nie było związane żadne zlecenie. |
void cdecl IPXCloseSocket( WORD socketNumber) - funkcja zamyka gniazdo o numerze podanym jako argument wywołania. Funkcja nie zwraca żadnych błędów, nawet w przypadku próby zamknięcia gniazda, które nie było wcześniej otworzone. Jeżeli korzystamy z procedury ESR (patrz blok ECB), należy najpierw zamknąć gniazdo z którym jest skojarzona a dopiero potem zniszczyć procedurę ESR (w przeciwnym wypadku może dojść do sytuacji w której moduł IPX będzie próbował procedurę ESR, której już nie ma).
void IPXDisconnectFromTarget( BYTE far *networkAddress) - funkcja informuje warstwę komunikacyjną, że żaden pakiet nie będzie wysyłany (przeznaczony) dla stacji o numerze podanym jako argument funkcji (dokładnie - daleki wskaźnik na bufor zawierający kompletny adres stacji - 12 bajtów). Funkcja nie może być wywoływana z wnętrza procedury ESR.
void IPXGetInternetworkAddress( BYTE far *networkAddress) - funkcja zwraca adres stacji (bez numeru gniazda) w sieci o podanym adresie jako argument (dokładnie - daleki wskaźnik na bufor zawierający 10 bajtowy adres: sieci i stacji - bez numer gniazda). Funkcja jest przydatna szczególnie dla aplikacji, które muszą informować inne stacje w sieci o swoim adresie sieciowym.
WORD cdecl IPXGetIntervalMarker( void ) - funkcja zwracająca aktualny stan licznika (timera) modułu IPX.
int cdecl IPXGetLocalTarget( BYTE far *networkAddress, BYTE far *immediateAddress, int far *transportTime ) - funkcja zwraca adres mostka lokalnego przez który musi przejść pakiet aby dotrzeć do stacji o numerze podanym jako argument wywołania funkcji (dokładnie - daleki wskaźnik na kompletny 12 bajtowy adres stacji). Adres (6 bajtów) jest zwracany do bufora, którego adres jest podawany jako drugi argument wywołania funkcji. Funkcja zwraca także przybliżony czas (w jednostkach zegara systemowego) wysyłania 576 bajtowego pakietu do stacji o podanym adresie. W przypadku, gdy stacja o podanym adresie znajduje się w obrębie tego samego segmentu jednostkowego, pole immendiateAddress będzie zawierało numer tej stacji (6 bajtów).
WORD cdecl IPXGetMaxPacketSize( void ) - funkcja zwraca maksymalny rozmiar pakietu dostępnego w sieci. Rozmiar tego pakietu zależy od topologii sieci.
BYTE cdecl IPXInitialize( void ) - funkcja inicjalizująca moduł IPX. Funkcja podaje modułowi IPX początkowy adres. Funkcja ta musi zostać wywołana aby pozostałe funkcje modułu IPX zadziałały poprawnie. Funkcja zwraca następujące wartości:
00H - inicjalizacja powiodła się.
F0H - IPX nie jest zainstalowany.
void IPXListenForPacket( ECB far *eventControlBlock ) - funkcja ustawiająca zlecenie nasłuchu na nadejście ramki i kojarzy z nim blok ECB podany jako argument wywołania funkcji (dokładnie - daleki wskaźnik na bufor będący blokiem ECB). Przed użyciem tej funkcji aplikacja musi otworzyć gniazdo i wypełnić następujące pola bloku ECB:
ESRAddress - adres procedury ESR wywoływanej po zakończeniu zlecenia. Wartość 0000H oznacza, że brak jest takiej procedury.
socketNumber - numer gniazda z którym skojarzone będzie zlecenie.
immediateAddress- numer mostka lub numer stacji docelowej (patrz opis pól bloku ECB).
fragmentCount - ilość buforów roboczych.
fragmentDescriptor - adresy i rozmiary buforów roboczych (patrz opis pól bloku ECB).
Moduł IPX po wywołaniu tej funkcji ustawia pole inUseFlag bloku ECB na wartość FEH oznaczającą, że blok ECB jest w stanie oczekiwania na nadejście pakietu. Dodaje go także do kolejki bloków ECB nasłuchujących na nadejście pakietu z tego samego gniazda. Moduł IPX nie wprowadza ograniczeń co do ilości bloków ECB mogących na raz nasłuchiwać na nadejście ramki. Gdy pakiet dotrze, IPX wpisuje dane do pierwszego w kolejce bloku ECB (tzn. do niego i buforów z nim skojarzonych), ustawia wartość w polu inUseFlag na 00H i wywołuje procedurę ESR (której adres był wcześniej wpisany do pola ESRAddress bloku ECB) o ile taką zdefiniowaliśmy. Funkcja zwraca następujące wartości (w polu completionCode bloku ECB):
Zwracany kod |
Znaczenie |
00H |
Operacja zakończyła się sukcesem. |
FCH |
Żądanie odrzucone. |
FDH |
Błędny pakiet |
FFH |
Gniazdo nie jest otworzone |
int cdecl IPXOpenSocket( BYTE far *socketNumber, BYTE socketType) - funkcja otwierająca gniazdo o podanym numerze jako pierwszy argument wywołania funkcji (dokładnie- daleki wskaźnik na bufor zawierający numer gniazda). Jeżeli argument ten będzie równy 00H, moduł IPX otworzy pierwsze wolne gniazdo. Drugi argument określa typ gniazda które chcemy otworzyć:
00H - określa, że gniazdo ma pozostać otwarte aż do momentu jego zamknięcia lub zakończenia programu.
FFH - określa, że gniazdo ma pozostać otwarte aż do momentu jego jawnego zamknięcia przez program. Zakończenie programu nie powoduje zamknięcia takiego gniazda.
Funkcja zwraca następujące wartości:
Zwracany kod |
Znaczenie |
0000H |
Operacja zakończyła się sukcesem. |
00F0H |
IPX nie jest zainstalowany. |
00FEH |
Brak wolnych gniazd |
00FFH |
Gniazdo jest już otworzone. |
void cdecl IPXRelinquishControl( void) - funkcja zwraca sterowanie. Funkcja pozwala na zwolnienie czasu procesora dla aplikacji wywołującej tą funkcję.
void IPXScheduleIPXEvent( WORD timeUnits, ECB far eventControlBlock) - funkcja umożliwia odmierzenie czasu zdarzenia. Wymaga skróconego wypełnienia bloku ECB (pola ESRAddress, socketNumber).
void IPXSendPacket( ECB far *eventControlBlock) - funkcja wysyłająca pakiet z danymi związanymi z blokiem ECB, którego adres jest podawany jako argument wywołania funkcji. Funkcja wymaga wypełnienia bloku ECB i nagłówka. Funkcja zwraca następujące wartości (w polu completionCode bloku ECB):
Zwracany kod |
Znaczenie |
00H |
Pakiet wysłany ale dostarczenie nie gwarantowane. |
FCH |
Żądanie odrzucone. |
FDH |
Błąd długości nagłówka IPX |
FEH |
Nie można dostarczyć pakietu. |
FFH |
Błąd sprzętowy. |
Ponieważ w ramach laboratorium będziemy realizowali programy wykorzystujące głównie protokół IPX, funkcje protokołu SPX zostaną przedstawione bez dokładnego opisu (zainteresowanych odsyłam do dokumentacji novell'owej lub na strony www firmy Novell, gdzie są one opisane dokładnie). Funkcje Protokołu SPX(konwencja C; kolejność alfabetyczna):
#define NWAPI far pascal
void NWAPI SPXAbortConnection( WORD SPXConnID ) - rozłączenie połączenia.
int NWAPI SPXEstablishConnection( DWORD IPXTaskID, BYTE retryCount,
BYTE watchDog, WORD NWPTR SPXConnID, ECB NWPTR eventControlBlock) - nawiązanie połączenia.
int NWAPI SPXGetConnectionStatus( DWORD IPXTaskID, WORD SPXConnID,
CONNECTION_INFO NWPTR connectionInfo) - zwraca informację o połączeniu.
int NWAPI SPXInitialize( DWORD NWPTR IPXTaskID, WORD maxECBs,
WORD maxPacketSize, BYTE NWPTR majorRevisionNumber,
BYTE NWPTR minorRevisionNumber, WORD NWPTR maxConnections,
WORD NWPTR availableConnections) - inicjalizuję struktury modułu SPX.
void NWAPI SPXListenForConnection( DWORD IPXTaskID, BYTE retryCount,
BYTE watchDog, ECB NWPTR eventControlBlock) - nasłuchiwanie na propozycję połączenia.
void NWAPI SPXListenForSequencedPacket( DWORD IPXTaskID,
ECB NWPTR eventControlBlock) - nasłuchiwanie pakiety (w fazie połączenia).
void NWAPI SPXSendSequencedPacket( DWORD IPXTaskID, WORD SPXConnID,
ECB NWPTR eventControlBlock) - wysyłanie pakietów (w fazie połączenia)
void NWAPI SPXTerminateConnection( DWORD IPXTaskID, WORD SPXConnID,
ECB NWPTR eventControlBlock) - przerwanie połączenia.
Etapy w programowaniu z wykorzystaniem protokołu IPX.
W punkcie tym przedstawiono schemat i kolejne kroki jakie należy wykonać aby poprawnie wykorzystać protokół komunikacyjny IPX.
Rezerwacja miejsca na potrzebne struktury (bloki ECB, nagłówki, bufory danych itp.).
Wywołanie funkcji inicjującej moduł IPX (sprawdzeni, czy IPX jest zainstalowany itp.).
Otworzenie potrzebnych gniazd.
...(przed wywołaniem funkcji wymagających bloku ECB należy pamiętać o poprawnym jego, jak i buforów skojarzonych, wypełnieniu).
Zamknięcie gniazd, które otworzyła aplikacja na czas wykonania.
Zwolnienie pamięci przydzielonej na potrzebne struktury.