Documente Academic
Documente Profesional
Documente Cultură
Nume camp Adresa legatura Adresa ESR Indicator stare (in-use flag) Cod terminare operatie Numar socket Spatiu IPX
Observatii Folosit de driver pentru organizarea listei de ECB NULL daca nu folosesc ESR Verificat continuu de aplicatie Completat de catre driver Trebuie sa existe deja socket deschis!
50
Spatiu driver Adresa imediata Numar fragmente Adresa fragment 1 Marime fragment 1
Valorile mai intalnite ale indicatorului de stare: Cod 0h F8h FAh FBh FCh FDh FEh FFh Semnificatie Disponibil Aplicatia a incercat sa trimita un pachet si IPX era ocupat. ECB si pachetul stau in asteptare in coada. IPX tocmai proceseaza ECB IPX foloseste ECB pentru un eveniment care tocmai a sosit. ECB sta in asteptare in coada. IPX foloseste ECB pentru un eveniment programat de AES (nu de IPX) care inca nu s-a declansat IPX foloseste ECB pentru un eveniment programat care inca nu s-a declansat IPX asteapta pachete pe socket IPX foloseste ECB pentru a trimite pachetul
Cateva din codurile de completare, in functie de contextul folosirii ECB-ului: Cod 00h FCh FDh FEh FFh F9h Emisie succes anulat pachet eronat transmisie nereusita eroare fizica --Ascultare succes anulat depasire --socket inchis esec Programare eveniment succes anulat --------Anulare eveniment succes -----------
ESR: Nu vom intra in prea multe amanunte in legatura cu Event Service Routine. Ideea este ca putem sa-I spunem driverului de protocol IPX sa apeleze aceasta functie de cate ori primeste un pachet, pentru a ne anunta astfel. Utilizarea este deci similara nnotiunii de intrerupere. Aceasta functie este apelata cu: AL=FFh (identificator IPX), ES:SI adresa ECB si intreruperile dezactivate. Prezenta sau absenta acestei functii se comunica driverului prin intermediul ECB. Dar, in afara de anumite cazuri in care viteza programului este absolut necesara, putem folosi linistiti polling-ul pentru verificarea starii cozii de pachete. Fragment: Intr-un ECB pot preciza mai multe fragmente ale informatiei care trebuie transmisa sub forma unui singur pachet. De exemplu un fragment ar putea fi antetul (header) pachetului IPX, pe cand al doilea fragment ar fi datele ce urmeaza sa fie transmise in el. Daca tot am vorbit de acest header, sa-I discutam structura:
51
Offset 0 2 4 5 6 18 Tipul pachetului poate fi: 0. 1. 2. 3. 4. 5. 16-31. 17. Tip necunoscut Pachet de informatii rutare Ecou Eroare Pachet IPX Pachet SPX Protocoale experimentale NetWare Core Protocol
Nume camp Suma de control Lungime Control transport Tip pachet Adresa destinatie Adresa sursa
6.3 Programarea IPX Acestea fiind spuse, putem trece la studiul interfetei de programare API pe care ne-o pune la dispozitie driverul IPX. Aceasta este intreruperea 7Ah. Vom observa ca selectia subserviciului acestei intreruperi se face cu ajutorul registrului BX, nu cu AH cum eram obisnuiti la alte intreruperi. Bineinteles ca in cazul absentei driverului IPX, nimeni nu a instalat in memorie rutinele acestei intreruperi, iar programele noastre nu vor face nimic. Desi este pastrata in continuare, folosirea intreruperii 7A nu este recomandata la versiuni Netware mai mari de 2.0, in locul acesteia folosesc serviciul 7A al INT 2F pentru a obtine o adresa FAR de salt, la care sar cu registrii pregatiti ca si la apelul intreruperii vechi. Vom prezenta aici doar cateva functii, utilizarea celorlalte reiesind din documentatie. Deschidere socket: BX = 0000h AL = durata de viata socket: 00h - deschis pana la inchidere explicita sau terminare program FFh - deschis pana la inchidere explicita DX = numar socket: 0000h alocat dinamic (intre 4000h-7FFFh) altfel, numarul dorit la returnare, vom avea in AL codul: 00h succes, cu numarul alocat socket in DX FEh tabela de socket plina FFh socket deschis deja BX = 0001h
52
Inchidere socket:
DX = numarul socket (octetii aranjati astfel incat MSB va fi in DL!) (un program trebuie sa-si inchida toate sockets deschise de el) Obtinerea adresei: BX = 0009h ES:SI -> un buffer unde se va afla adresa locala (la retur SI nu mai e valabil!) Adresa are formatul: 4 octeti identificator retea (big endian) 6 octeti identificator nod (big endian) BX = 0003h ES:SI -> ECB bufferul de transfer date catre/de la driverul IPX Functia returneaza imediat, pachetul fiind trimis in fundal! E sarcina mea sa verific indicatorul de stare din ECB, iar la terminare sa citesc codul de completare sa vad cum s-a terminat tentativa de trimitere a pachetului.
Trimitere pachet:
Cedare control: BX = 000Ah E o functie foarte importanta! Dupa cum stim, DOS nu este multitasking, adica nu permite rularea mai multor progranme in acelasi timp. Deci aplicatia noastra monopolizeaza procesorul, iar driverul IPX nuu are cand sa trimita pachetul. De aceea apelam aceasta intrerupere din cand in cand ca sa cedam controlul driverului IPX sa-si faca si el treaba un timp. Asteptare pachet: BX = 0004h ES:SI -> ECB pentru primirea pachetului Returneaza: AL = starea: 00h succes, FFh nu exista socket respectiv Nici aceasta functie nu asteapta primirea pachetului! De asemenea trebuie sa citesc periodic ECBul pentru a afla despre terminarea primirii din fundal (indicatorul de stare). 6.4 Exemplu de program Iata codul pentru o aplicatie simpla care trimite un pachet in retea: STIVA SEGMENT PARA STACK STACK dw 256 dup (0) STIVA ENDS DATE SEGMENT PARA PUBLIC DATA eroareSock db Eroare alocare socket,0Dh,0Ah,$ initiatTrimis db Pachet trimis,0Dh,0Ah,$ terminat db Program terminat cu succes,0Dh,0Ah,$ ECBtip struc{ LinkAdr dw 0 LinkSeg dw 0 ESRAdr dw 0 ESRSeg dw 0 InUse db 0 CompCode db 0 Sock dw 0
53
}ECB
IPXWs db 4 dup(0) DrvWs db 12 dup (0) ImmAddr db 6 dup(0FFh) FragCount dw 1 FragAdr dw 0 FragSeg dw 0 FragSize dw 0
IPXtip struc{ Suma dw 0 ;nu calculez CRC Lung dw 40 ;e valabila doar pentru ACEST pachet Control db 0 Tip db 0 DestNet db 4 dup (0) ;reteaua implicita = cea in care ma aflu DestNod db 6 dup (0FFh) ;adresa broadcast DestSock dw 5555h ;presupun ca destinatia asculta aici SursaNet db 4 dup (0) SursaNod db 6 dup (0) SursaSock dw 0 DateUtile db Salut draga! ;continutul efectiv de date }IPXsend DATE ENDS COD SEGMENT PARA PUBLIC CODE ASSUME CS:COD, DS:DATE, ES:DATE, SS:STIVA MAIN PROC FAR push DS xor AX,AX push AX mov AX,DATE mov DS,AX mov mov mov mov int cmp jnz mov mov mov mov int mov mov mov mov mov ES,AX BX,0 AL,0 DX,0 7Ah AL,0 mesajSock ;incerc sa deschid un socket alocat dinamic ;(nu ma intereseaza un anumit numar de socket)
ECB.Sock,DX IPXsend.SursaSock,DX SI, offset IPXsend.SursaNet BX,9 ;citesc adresa locala direct in struct header IPX 7Ah ECB.FragAdr, offset IPXsend.Suma ECB.FragSeg, segment IPXsend.Suma AX, IPXsend.Lung ECB.FragSize, AX ;am completat ce campuri mai ramasesera BX,3
54
SI, offset ECB.LinkAdr 7Ah ;trimit pachetul format dintr-un singur fragment DX,offset initiatTrimis AH,9 21h
netrimis: mov BX,0Ah int 7Ah cmp ECB.InUse,0 jnz netrimis mov BX,1 mov DX, ECB.Sock int 7Ah mov DX,offset terminat mov AH,9 int 21h ret mesajSock: mov DX,offset eroareSock mov AH,9 int 21h ret MAIN ENDP COD ENDS END MAIN
6.6 Teme Ca posibile dezvoltari ale acestei aplicatii, mentionam si necesitatea unui test initial al existentei intreruperii 7Ah. Evident daca nu exista driverul IPX care sa lase rezidente in memorie rutinele apelate de INT 7Ah si care sa scrie adresa lor in TVI, primul apel al intreruperii ne va bloca sistemul In continuare, se poate scrie absolut analog si aplicatia care sa receptioneze pachetul IPX, si eventual sa si afiseze datele receptionate. Apoi se vor integra cele 2 aplicatii intr-una singura care sa implementeze un dialog simplu intre 2 statii.
55