Netzwerkprogrammierung mit IPX

Netzwerkprogrammierung mit IPX

Das IPX (Internetwork Packet Exchange) Protokoll ist eine Umsetzung des Internetworkpacket - Protokolls von Xerox. Der Zweck von IPX ist es Applikationen die M├Âglichkeit zu geben im Netzwerk mit anderen Rechnern und Ger├Ąten zu kommunizieren. Dieses Protokoll stellt eine Schnittstelle f├╝r Anwendungs - programme, zum Empfang und Senden von Informationen im Netzwerk, zur Verf├╝gung. Diese Informationen setzen sich aus Pakete zusammen, die nacheinander ├╝bertragen werden und Daten sowie einen Organisations - block, der aus IPX - header und Event Control Block (ECB), besteht. Diese Pakete haben eine minimale Gr├Â├če von 30 und maximal von 576 Byte. Jedem Rechner ist eine eindeutige Adresse zugeordnet mit der er Daten von jedem anderen Rechner empfangen und senden kann, sofern er IPX unterst├╝tzt. Der physikalische Transport geschieht automatisch und transparent. Das Protokoll versucht die beste M├Âglichkeit die Ressourcen auszusch├Âpfen, aber kann keinen Transport garantieren, dieser muss von der Anwendung kontrolliert und gegebenenfalls wiederholt werden. IPX unterst├╝tzt alle Netzwerkarten, die auch von Novell Netware 2.0 unterst├╝tzt werden.
IPX ben├Âtigt viele Parameter im Bigendian Format, dieses unterscheidet sich vom Format in dem INTEL die Werte in den Variablen ablegt. Um das Bigendian Format zu erhalten muss die Reihenfolge der Bytes vertauscht werden.
Die von IPX zur Verf├╝gung gestellten Funktionen werden ├╝ber den Interrupt $7A aufgerufen. Damit diese Funktionen zur Verf├╝gung stehen, muss ein Netzwerktreiber(TSR), wie z.B. IPX.EXE speicherfest in den RAM geladen werden.

Net address field

Name
Size(Byte)
Description
network
4
Netzadresse
node
6
Rechneraddresse
socket
2
Socketnummer

In der Struktur - Net address field - wird die Netzadresse des Rechners oder Ger├Ątes gespeichert, dazu geh├Ârt die Netzwerk und die Nodeaddresse(Benutzeradresse), sowie die Socketnummer.


IPXheader :

Name
Size(Byte)
Description
Check
2
Bigendian Checksummme
Length
2
Bigendian - L├Ąnge des Paketes
tc
1
Transport Kontrolle
pType
1
Paket Type
dest
12
Adresse des Zieles
src
12
Adresse der Quelle

Der IPXheader enth├Ąlt Informationen ├╝ber das Paket das versendet oder empfangen werden soll.

Format of the ECB

Name
Size(Byte)
Description
Link
4
Pointer zum n├Ąchsten ECB
ESR
4
Pointer zur Event Service Routine
InUse
1
ECB Status
complete
1
ECB Ende - Status
socket
2
Bigendian Socket Nummer
IPXwork
4
Arbeitsspeicher f├╝r IPX
Dwork
12
Arbeitsspeicher f├╝r Treiber
immedAddr
12
Adresse an die gesendet werden soll
fragCount
2
Anzahl der Datenfragmente
Fragdata
4
Pointer des Datenfragments
Fragsize
2
Gr├Â├če des Datenfragments

Die event control block Struktur beinhaltet Anzahl, Gr├Â├če und Zeiger auf Daten, sowie Informationen ├╝ber die Ausf├╝hrung des Transports.




Beispiel f├╝r Datenteil des Paketes:

struct daten {
char name[10]; Benutzername
char command[10]; Kommandos
char str[80]; Rohdaten
};

Beispiel f├╝r Komplettes Paket:

struct packet {
struct ECBType ecb; Event Control Block
struct IPXheader ipx; IPX Header
struct dat data; Datenblock
} ;


IPX - Bibliothek

Diese Bibliothek stellt wichtige Funktionen zur Kommunikation zwischen verschiedenen Rechnern mit den IPX - Protokoll zur Verf├╝gung. Diese sind in der Header - Datei IPX.h zusammengefa├čt und in der dazugeh├Ârigen IPX.c - Datei implementiert.
Um sie nutzen zu k├Ânnen, muss die IPX.h mit der Anweisung #include "IPX.h" in den Quelltext eingebunden werden. Die obengenannten Strukturen werden von den Funktionen ben├Âtigt, sie sind ebenfalls in IPX.h vereinbart.

Der Header stellt folgende Funktionen zur Verf├╝gung:



- Getlocaladdress();

Ermittelt die Nodeadresse des lokalen Rechners und legt sie in der globalen Variable localaddr ab, die aus IPX.c exportiert wird.

Interruptaufruf :
├ťbergabeparameter: AH=$0009 ES:Segment der Adresse DS:Offset der Adresse


- void initIPX();

├ťberpr├╝ft das Vorhanden sein des IPX - Protokolls und initialisiert dieses. Die Funktionen werden mit dem Interrupt 7Ah zur Verf├╝gung gestellt.
Hier wird der Multiplexerinterrupt $2F mit AX=$7f00 aufgerufen, um zu ├╝berpr├╝fen ob das IPX - Programm (TSR) installiert ist. Im Register AL wird der R├╝ckgabewert abgelegt, betr├Ągt er $FF ist IPX nicht installiert.


- byte IPXopenSocket(byte longevity);

├ľffnet einen IPX - Socket und gibt den Fehlerstatus zur├╝ck. Mit longevity kann man angeben wie sich IPX verhalten soll, wenn die Applikation geschlossen wird. Wird 0 ├╝bergeben wird der Socket auch geschlossen, wenn das Programm beendet wird. Bei 255 bleibt der Socket in diesem fall offen und muss explizit mit IPXcloseSocket geschlossen werden.

Interruptaufruf :
├ťbergabeparameter: AH=$0000 AL=Longvity DX=Socketnummer
Ausgabeparameter : AL=Error Code DX=Socketnummer






- void IPXcloseSocket();

Schlie├čt eine mit IPXopenSocket ge├Âffneten IPX - Socket wieder;

Interruptaufruf :
├ťbergabeparameter: AH=$0001 DX=Socketnummer


- void InitSendPacket(struct ECBType *ecb,struct IPXheader *ipx,word size);

Initialisiert die zum Senden eines Pakets wichtigen Parameter des IPXheaders und des ECB - Blockes. Dazu geh├Âren zum Beispiel die Nodeadresse des Absenders und die Nodeadresse des Empf├Ąngers. Sollen alle Teilnehmer angesprochen werden muss die Nodeadresse vollst├Ąndig auf 255 gesetzt werden. Dieser Vorgang wird auch Broadcast genannt. Der Socket muss invertiert werden, da er im Bigendianformat ├╝bergeben werden muss.


- void IPXsendPacket(struct ECBType *ecb);

Sendet ein Datenpaket das aus einem IPXheader, eine ECB - Block und den Daten besteht. Es muss getestet werden ob das Netzwerk frei ist bevor gesendet wird, damit das Paket nicht verloren geht.
Bsp.: do {} while (send.ecb.inUse!=0)

Interruptaufruf :
├ťbergabeparameter: AH=$0003 ES:Segment des ECB’s DS:Offset des ECB’s


- byte IPXListenPacket(struct ECBType *ecb);

Ermittelt, ob ein Paket angekommen ist, und liefert diese Struktur zur├╝ck (IPXheader, ECB - Block, Daten).Auch hier muss gewartet werden bis das Netzwerk frei ist !

Interruptaufruf :
├ťbergabeparameter: AH=$0003 ES:Segment des ECB’s DS:Offset des ECB’s
R├╝ckgabeparameter: AL=Error Code


- void ImIdle()

Signalisiert dem IPX - Treiber dass, das Programm nicht auf das Netzwerk zugreift. Damit kann das Netzwerk entlastet werden.

Interruptaufruf:
├ťbergabeparameter: AH=$000A


Variablen in IPX.c:

extern struct localaddrT localaddr; Diese Variable speichert die Nodeadresse des lokalen Rechners.

Intern verwendet das IPX.c - Modul die Variablen mysocket und invsocket. In diesen wird die Socketnummer gespeichert. In invsocket ist sie im Bigendian - Format abgelegt.







Beispielprogramm zum Benutzen der IPX - Bibliothek:



#include
#include
#include "ipx.h" /*IPX - Bibliothek*/

struct packet {
struct ECBType ecb;
struct IPXheader ipx;
char data[80];
} send,receive;


void main()
{
if (initIPX()==255)
{
switch (IPXopenSocket(0))
{
case 0: printf("Socket etabliert\n");break;
case 255:printf("Socket bereits offen\n");break;
case 254:printf("Sockettabelle voll\n");break;
}
InitSendPacket(&send.ecb,&send.ipx,sizeof(send.data));
InitReceivePacket(&receive.ecb,&receive.ipx,sizeof(receive.data));

/*** Senden von Daten ***/
printf("Daten zum senden(Leerstring=nicht senden) :");
scanf("%s",&send.data);
if (strlen(send.data)!=0)
{
/**** Erhalte Daten, wenn Netzwerk frei ist ***/
do {} while (send.ecb.inUse!=0)
IPXsendPacket(&send.ecb);
}

if (IPXListenPacket(&receive.ecb)!=0)
printf("Fehler beim Versuch ein Packet zu erhalten !");
else
printf("Daten wurden empfangen: %s",receive.data);

IPXcloseSocket();
}

















IPX - Bibliothek Buchhorn/J├╝ngel

#include
#include "ipx.h"

struct localaddrT localaddr;

word mysocket=0x869c; /* offizielles Doom Socket */
word invsocket=0x9c86;

union REGS regs;
struct SREGS sregs;

/****** Ermittelt lokale Adresse *******/
void Getlocaladdress()
{
regs.x.bx= 9;
sregs.es =FP_SEG(&localaddr);
regs.x.si = FP_OFF(&localaddr);
int86x(0x7A,®s,®s,&sregs);
}

/******* Initalisiert IPX ******/
void initIPX()
{
regs.x.ax=0x7a00;
int86x(0x2f,®s,®s,&sregs);
if (regs.h.al!=255)
printf("\nFehler beim Initialiesieren von IPX \n");
else printf("IPX initalisiert \n");
Getlocaladdress();
}

/********** ├Âffnet IPX Socket und šbergibt Al - Register **********/
byte IPXopenSocket(byte longevity)
{
byte status;
regs.x.bx=0x0000;
regs.h.al=longevity;
regs.x.dx=invsocket;
int86x(0x7a,®s,®s,&sregs);
status=regs.h.al;
return (status);
}

/******* Schlie├čt IPX Socket ********/
void IPXcloseSocket()
{
regs.x.bx=0x0001;
regs.x.dx=invsocket;
int86x(0x7a,®s,®s,&sregs);
}

/****** Initialisierung von SendPacket ******/
void InitSendPacket(struct ECBType *ecb,
struct IPXheader *ipx,word size)
{
byte i;
memset(ecb,0x0000,sizeof(*ecb));
memset(ipx,0x0000,sizeof(*ipx));
ecb - >socket=invsocket;
ecb - >fragCount=1;
ecb - >fragData=ipx;
ecb - >fragSize=sizeof(*ipx)+size;
for(i=0;i<6;ecb - >immedAddr[i]=255,i++);
ipx - >check=0xffff;
ipx - >pType=0;
for(i=0;i<4;i++,ipx - >dest.net[i]=localaddr.net[i]);
for(i=0;i<6;i++,ipx - >dest.node[i]=0xff);
ipx - >dest.socket=invsocket;
for(i=0;i<4;i++,ipx - >src.net[i]=localaddr.net[i]);
for(i=0;i<6;i++,ipx - >src.node[i]=localaddr.node[i]);
ipx - >src.socket=invsocket;
}



/**** Sende Packet ***************/
void IPXsendPacket(struct ECBType *ecb)
{
regs.x.bx=0x0003;
sregs.es=FP_SEG(ecb);
regs.x.si=FP_OFF(ecb);
int86x(0x7a,®s,®s,&sregs);
}


/**** Warte auf Packet ***************/
byte IPXListenPacket(struct ECBType *ecb)
{
byte status;
regs.x.bx=0x0004;
sregs.es=FP_SEG(ecb);
regs.x.si=FP_OFF(ecb);
int86x(0x7a,®s,®s,&sregs);
status=regs.h.al;
return(status);
}

/******* Bin Frei !!! *******/
void ImIdle()
{
regs.x.bx=0x000a;
int86x(0x7a,®s,®s,&sregs);
}

/**********Initialiesieren von ReceivePacket *******/
void InitReceivePacket(struct ECBType *ecb,struct IPXheader *ipx,word size)
{
memset(ecb,0x0000,sizeof(*ecb));
memset(ipx,0x0000,sizeof(*ipx));
ecb - >inUse=0x1d;
ecb - >socket=invsocket;
ecb - >fragCount=1;
ecb - >fragData=ipx;
ecb - >fragSize=sizeof(*ipx)+size;
if (IPXListenPacket(ecb)!=0);
}










Headerdatei IPX.h:


#ifndef __IPX_H
#define __IPX_H

typedef unsigned char byte;
typedef unsigned short word;

typedef byte netaddr[4];
typedef byte nodeaddr[6];

struct netaddress
{ netaddr net;
nodeaddr node;
unsigned int socket;
};

struct localaddrT
{ netaddr net;
nodeaddr node;
};

struct ECBType
{
void far *link;
void far *ESR;
byte inUse;
byte complete;
word socket;
byte IPXwork[4];
byte Dwork[12];
nodeaddr immedAddr;
word fragCount;
void *far fragData;
word fragSize;
};
struct IPXheader{
word check;
word lenght;
byte tc;
byte pType;
struct netaddress dest;
struct netaddress src;
};

extern struct localaddrT localaddr;

void Getlocaladdress();
byte initIPX();
byte IPXopenSocket(byte longevity);
void IPXcloseSocket();
void InitSendPacket(struct ECBType *ecb,struct IPXheader *ipx,word size);
void IPXsendPacket(struct ECBType *ecb);
byte IPXListenPacket(struct ECBType *ecb);

#endif



Headerdatei Tools.h:



#ifndef __IPX_H
#define __IPX_H

#include
#include
#include

void Scrolldown (char y1,char y2);
void Scrollup(char y1,char y2);
void win(int x1,int y1,int x2,int y2);

#endif



Benutzeranleitung CHAT 97

Der Benutzer startet mit dem Eingangsbildschirm, wo ihm eine kurze Einf├╝hrung und Informationen ├╝ber IPX zur Verf├╝gung gestellt wird. Weiterhin wird das Benutzerhandle abgefragt, mit dem man sich anmeldet.

Das Programm schickt das Handle, die Adresse und einen Befehlsflag, der auffordert den Header zu schicken, an alle Rechner und meldet sich so bei allen Rechnern an.

Ein neuer Textbildschirm wird aufgebaut, der sich in drei Teile gliedert: dem Inputfenster (Daten zum senden), dem Outputfenster (emfangende Daten) und Chatpartnerfenster (zeigt angemeldeten Benutzer).
Man schickt seine eingegebene Nachricht mit Enter oder mit dem Zeilende ab.

Mit den Funktionstasten F1 - F10 k├Ânnen Teilnehmer 1 - 10 und mit Strg + F1 - F3, Teilnehmer 10 - 13 angesprochen werden, die Nachricht erh├Ąlt also nur dieser Rechner. Die F12 - Taste schaltet wieder auf Broadcast um.

Mit wird das Programm beendet.












Initaliesiere IPX

Schlie├čeIPXSocket

Initialisiere SendPacket
InitialisiereReceivePacket
Startscreen

START

1557 Worte in "deutsch"  als "hilfreich"  bewertet