IPX

Vývojový tým: general project manager Soňa NEHYBOVÁ,
programmers Martin KOŠTUŘÍK, Martin SCHOVÁNEK

Úkol: Implementujte ovladač protokolu IPX pro operační systém TUOX.

Zdrojove kody

 

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.

IPX driver

IPX driver je implementován jako integrální součást File Systému. Tj. využívá stejné task number, tj.přijímá zprávy z hlavní smyčky File Systému.

Jeho úkolem je:

  1. zaregistrovat se u driveru síťové karty jako ovladač protokolu IPX. Od této chvíle, kdykoli driver síťové karty obdrží rámec obsahující IPX packet, zasílá na IPX driver zprávu C_NOTIFY. IPX, driver si packet přebírá zasíláním zprávy C_READ na driver síťové karty (DSK).

  2. převzaté packety rozbalit a data předat aplikaci, uložit do cache nebo zahodit, podle toho, je-li daný socket otevřen a čeká-li aplikace na data

  3. předat aplikacím data uložená v cache

  4. přebírat od aplikací data, balit je do packetů a odesílat je na driver síťové karty (DSK)

  5. otevírat a zavírat sockety

Skládá se z níže uvedených částí.

Aplikační rozhraní IPX:

Socket (local_port, remote_port, remote_node, remote_net, protocol, dev_num).

Učel:
Vytváří soket. Tj. najde a vyplní volný záznam v tabulce TOS.

Parametry:
local_port - číslo otvíraného soketu
remote_port - číslo soketu na vzdáleném stroji
remote_node - adresa uzlu v rámci remoute_net
remote_net - adresa vzdálené sítě
protocol - číslo protokolu
device_num - číslo síťové karty

Vrací:
Deskriptor vytvořeného soketu, nebo ERR (záporná hodnota).

Formát vstupní zprávy:
m_type = C_SOCKET
m4_l1 = ipx_sc_lport_prot = local_port(16b) + protocol(16b)
m4_l2 = ipx_sc_rport_rnodeh = r_port(16b) + r_node_h(16b)
m4_l3 = ipx_sc_rnodel = r_node_l(32b)
m4_l4 = ipx_sc_rnet = r_net(32b)
m4_l5 = ipx_sc_devnum = null(16b) + dev_num(16b)

Formát výstupní zprávy:
m1_i1 = ipx_rp_fd

Relizováno funkcí:
int ipx_do_socket()

Popis algoritmu:
- zjisti zda již není socket otevřen
- najdi volný záznam v TOS
- vygeneruj descriptor soketu

Read (file_descriptor, dest_segment, dest_offset, nbytes).

Účel:
Na požadovaée místo v adr. prostoru aplikace uloží data z otevřeného soketu, max. však lenght bytů a max 1 paket.

  1. pokud není co číst nastaví se blokovací flag v TOS (wait_proc bude obsahovat číslo čekajícího procesu) a do TOS se uloží položky potřebné pro pozdější odeslání dat aplikaci jako délka požadovaných dat, cílový segment a offset dat. Aplikaci neodpovíme zprávou, čímž ji zablokujeme, protože ta čeká na odpověď. Když data příjdou (IPX driver dostane zprávu notify, zkontroluje se TOS a je-li nastaven blokovací flag, tj. existuje požadavek na čtení, data z paketu se zkopírují do adr. prostoru aplikace), a aplikace se odblokuje tím, že ji konečně pošleme odpověď.
  2. Pakety jsou odesílány aplikaci v tom pořadí v jakém byly přijaty.
  3. aplikace požaduje méně dat něž je délka aktuálniho paketu -> aplikaci je předáno požadované množství dat a zbylá část paketu je zahozena.
  4. aplikace požaduje více dat něž je délka aktuálniho paketu -> aplikaci je předán celý paket. Požadavek na zbylá data je ignorován.
  5. k přenosu dat do adresního prostoru aplikace se použije systémové volání SYS_COPY.

Parametry:
file_descriptor - descriptor soketu
dest_segment -
cílový segment dat
dest_offset -
cílový offset dat
nbytes
- délka požadovaných dat

Vrací:
Vrací počet skutečně přenesených dat, ERR (záporná hodnota) nebo NIC.

Formát vstupní zprávy:
m_type = C_READ
m1_i1 = ipx_rw_ fd = file_descriptor
m1_i2 = ipx_rw_segment = dest_segment
m1_i3 = ipx_rw_nbytes = nbytes
m1_p1 = ipx_rw_offset = dest_offset

Formát výstupní zprávy:
m1_i1 = ipx_rp_nbytes

Relizováno funkcí:
int ipx_do_read()

Popis algoritmu:
- jestliže daný soket neobsahuje data uspi volající proces (dont_replay = 0) a skonči
- jinak, pošli data uživateli
- uvolni datový buffer

 

Write (file_descriptor, dest_segment, dest_offset, nbytes).

Účel:
Odešle data z uživatelské oblasti na otevřený socket, maximálně však jeden packet.

Parametry:
file_descriptor - descriptor soketu
dest_segment -
zdrojový segment dat
dest_offset -
zdrojový offset dat
nbytes
- délka odesílaných dat

Vrací:
Vrací počet skutečně přenesených dat nebo ERR (záporná hodnota).

Formát vstupní zprávy:
m_type = C_WRITE
m1_i1 = ipx_rw_ fd = file_descriptor
m1_i2 = ipx_rw_segment = dest_segment
m1_i3 = ipx_rw_nbytes = nbytes
m1_p1 = ipx_rw_offset = dest_offset

Formát výstupní zprávy:
m1_i1 = ipx_rp_nbytes

Relizováno funkcí:
int ipx_do_write()

Popis algoritmu:
- zkontroluj jestli je daný soket otevřený
- vytvoř paket a zkopíruj do něj data z uživatelské oblasti
- odešli paket driveru siťové karty

Close (file_descriptor)

Učel:
Uzavře otevřený socket, a uvolní jim obsazené buffery.

Parametry:
file_descriptor - descriptor soketu

Vrací:
OK nebo ERR (záporná hodnota).

Formát vstupní zprávy:
m_type = C_CLOSE
m1_i1 = ipx_rw_ fd = file_descriptor

Formát výstupní zprávy:
m1_i1 = ipx_rp_err

Relizováno funkcí:
int ipx_do_close()

Popis algoritmu:
- zkontroluj jestli je daný soket otevřený
- uvolni buffery obsazené soketem
- zneplatni patřičný záznam v tabulce TOS

SetLocalNet (local_net)

Učel:
Nastaví adresu lokální sítě.

Parametry:
local_net - adresa lokální sítě.

Vrací:
Nic.

Formát vstupní zprávy:
m_type = C_SETLNET
m2_l1 = ipx_sn_lnet = local_net

Relizováno funkcí:
int ipx_set_lnet()

Popis algoritmu:
- přiřaď proměnné "local_net" hodnotu local_net

SetLocalNode (local_node)

Účel:
Nastaví adresu uzlu lokální sítě.

Parametry:
local_node - adresa uzlu lokální sítě (48b).

Vrací:
Nic.

Formát vstupní zprávy:
m_type = C_SETLNODE
m2_i1 = ipx_sn_lnodeh = local_node (horních 16b)
m2_l1 = ipx_sn_lnodel = local_node (dolních 32b)

Relizováno funkcí:
int ipx_set_lnode()

Popis algoritmu:
- přiřaď proměnné "local_node" hodnotu local_node

SetGateway (gateway)

Účel:
Nastaví adresu brány.

Parametry:
gateway - adresa brány (48b).

Vrací:
Nic.

Formát vstupní zprávy:
m_type = C_SETGATEWAY
m2_i1 = ipx_s_lneth = local_net (horních 16b)
m2_l1 = ipx_s_lnetl = local_net (dolních 32b)

Relizováno funkcí:
int ipx_set_gateway()

Popis algoritmu:
- přiřaď proměnné "gateway" hodnotu gateway

Rozhraní IPX driveru a driveru síťové karty (DSK)

Rozhraní obsahuje čtyři funkce (služby).

Notify( )

Účel:
- Převezme paket od DSK, pokud soket (číslo soketu) uvedený v těle paketu není otevřený, paket je zahozen. Jinak jsou data paketu uložena do bufferu nebo přímo zaslána aplikaci pokud na ně apliiace již čeká. V případě že všechny buffery vyhrazené soketu jsou obsazeny, paket je zahozen.
- Volání provádí driver siťové karty (DSK) vždy, když přijde nějaký rámec s IPX paketem.

Parametry:
Bez parametrů.

Vrací:
Nic.

Relizováno funkcí:
int ipx_do_notify()

Popis algoritmu:
- pošli zprávu READ na síťovou kartu (převzatí paketu)
- vytáhni z packetu číslo soketu (portu)
- pokud daný soket není otevřený, tak paket zahoď, Konec
- jestli aplikace čeká na data, tak ji je pošli, Konec
- jinak, najdi volný datový buffer a zkopiruj do něj data z paketu
- index datové bufferu přidej do kruhového bufferu soketu
- pokud volný datový buffer není paket zahoď

Read (user_task, nbytes, dest_segment, dest_offset).

Účel:
Na místo určené "dest_segment:dest_offset" v mém adr. prostoru uloží data z doručeného paketu max. však "nbytes" bytů a max. 1 paket. Funkce DSK.

Parametry:
user_task - číslo uživatelského procesu
nbytes
- max. délka paketu, kterou jsme ochotni převzít
dest_segment -
cílový segment dat
dest_offset -
cílový offset dat

Vrací:
Funkce vrací skutečně načtený počet bytů nebo ERR.

Write (user_task, nbytes, source_segment, source_offset).

Účel:
Odešle paket o délce nbytes, který je umístěn v adr. prostoru "source_segment:source_offset", na DSK. Funkce DSK.

Parametry:
user_task - číslo uživatelského procesu
nbytes
- délka paketu, který odesíláme
source_segment -
zdrojový segment dat
source_offset -
zdrojový offset dat

Vrací:
Vrací počet skutečně přenesených bytů nebo ERR (záporná hodnota).

Register(user_task, protocol).

Účel:
Zaregistruje IPX driver u DSK.Funkce DSK.

Parametry:
user_task - číslo registrovaného procesu
protocol
- ID protokolu, který daný proces obsluhuje

Vrací:
Funkce vrací OK nebo ERR.

Odbočka v hlavní smyčce File Systému

Odchytává zprávy určené pro IPX. Smyčka je aktivní, pokud globální proměnná "ipx_ready" = TRUE (nastavuje funkce ipx_init(), pokud inicializace IPX driveru proběhla úspěšně).

Což jsou:
a) veškeré zprávy C_SOCKET, C_NOTIFY, C_SETLNET, C_SETLNODE, C_SETGATEWAY
b) C_READ, C_WRITE, C_CLOSE, které mají file descriptor větší než IPX_SOCK_PREF

Datové struktury

Datová cache

Obsahuje:

Data z doručených a aplikací dosud nepřečtených paketů.

Je tvořena:

- Polem struktur "IPX_BUF buffers[]". Struktura obsahuje datový buffer "char buf[]", proměnnou "len" - délka platných dat a proměnnou "next" - ukazuje na následující neobsazenou strukturu IPX_BUF nebo obsahuje -1 v případě, že je poslední.

- "Kruhovým bufferem" indexů do pole "buffers[]" v každé zaznamu TOS_ELEMENT pole TOS. Ke každému "kruhovému bufferu" existují dvě proměnné, "buf_start" - ukazuje na začátek "kruhového bufferu" a "buff_len" - udavá počet záznamů v "kruhovému bufferu".

- Globální proměnnou "first_buf" - ukazuje na první neobsazenou strukturu IPX_BUF nebo obsahuje -1 v případě, že všechny struktury jsou obsazeny.

Použití:

Uložení dat do cache:
1) pokud "first_buf" neobsahuje -1 použij strukturu na kterou "first_buf" ukazuje
2) do první neobsazené položky "kruhového bufferu" přiřaď hodnotu "first_buf"
3) inkrementuj odpovídající "buff_len"
4) nakopíruj do struktury data + vyplň proměnnou "len"
5) nastav "first_buf" na následující volnou strukturu

Uvolnění cache:
1) zpracuj data uložená v sruktuře IPX_BUF na niž ukazuje patřičný "buf_start"
2) nastav "first_buf" na uvolněnou strukturu
3) nastav proměnnou "next" uvolněné struktury na původní hodnotu "first_buf"
4) posuň "buf_start" na následující položku "kruhového bufferu"
5) dekrementuj "buff_len"

Tabulka otevřených soketů -TOS

Je reprezentována polem struktur TOS_ELEMENT. Záznam tabulky představuje jeden momentálně otevřený soket.

Struktura obsahuje:
local_port -
číslo otevřeného soketu
remote_port -
číslo soketu na vzdáleném stroji
remote_node -
adresa uzlu v rámci remoute_net
remote_net -
adresa vzdálené sítě
device_num -
číslo síťové karty
in_use_flag -
indikuje platná data
wait_proc -
číslo čekajícího procesu
wait_data_len -
požadovaná délka dat čekajícího procesu
wait_segment -
cílový segment dat čekajícího procesu
wait_offset -
cílový offset dat čekajícího procesu
buffers[] -
kruhový buffer indexů do pole "buffers[]"
buf_start -
ukazuje na začátek kruhového bufferu
buf_len -
udavá počet záznamů v kruhovému bufferu

IPX Packet

Jedná se o strukturu sloužící k sestavování packetu a k vybalování dat z doručených packetů.

Struktura obsahuje:
checksum - kontrolní součet packetu (počítá driver síťové karty)
length -
délka datové části packetu
transport_control -
pole používané směrovači pro likvidaci bloudivých paketů
packet_type -
typ paketu, blíže definuje určení údajů v datové části paketu
destination_network -
adresa cílové síťě
destination_node -
adresa cílového uzlu
destination_socket -
číslo cílového socketu
source_network -
zdrojová adresa síťě
source_node -
adresa zdrojového uzlu
source_socket -
číslo zdrojového socketu
data -
datová část packetu

NODE_ADR

Struktura určená pro ukladání 48b adresy uzlu.

Struktura obsahuje:
node_h16 - horních 16b adresy uzlu
node_l32 -
dolních 32b adresy uzlu

Globální proměnné:

local_net
adresa lokální sítě.
local_node
adresa lokálního uzlu.
gateway
adresa routeru.
netdrv_task
task number driveru síťové karty.
ipx_msg
struktura zprávy pro různé použití v rámci IPX.
first_buf
ukazuje na první neobsazenou strukturu IPX_BUF nebo obsahuje -1 v případě, že všechny struktury jsou obsazeny.
ipx_ready
indikuje úspěšnou inicializaci IPX driveru, aktivuje - deaktivuje odbočku v hlavní smyčce FS

Poslední změna : 27. 7. 1999