[Back to NETWORK SWAG index] [Back to Main SWAG index] [Original]

    {
    I have an IPX unit I would like to contribute to SWAG.  It uses the
    advanced calls in Netware 2.0a and above.  (INT 2F/AX = 7A00)  This is
    now the recomended way to interface the IPX unlike INT 7A.  I have seen
    a few IPX units but they all use INT 7A.  Mine is the only one I have
    seen using the new procedures.

    Thanks!
    Jack Neely
    }

    unit IPX;
    {Version 1.0  Copyright 1997 Jack Neely.  All rights reserved.}

    {This unit provides IPX interface.  Requirements are Novell
    NetWare 2.0a or higher.  This uses the new IPX call INT 2F/AX=7A00h.
    This calls no interrupts save for in the init section.  TSR safe.

    If needed (by you or anyone) there are other IPX functions that can be added
    to this unit.  If you would like to contact me for whatever reason my e-mail
    address is below.  Enjoy!

    Jack Neely
    hneely@ac.net
    http://www.ac.net/~hneely/
    }

    interface

    type
    	netAddr  = array[1..4] of byte;    { The address of a network }
    	nodeAddr = array[1..6] of byte;    { The address of a node in a network }
    	address  = array[0..1] of word;    { A pointer to the data 0=offset 1=seg }
    	netAddress = record
    		Net    : netAddr;   { network address }
    		Node   : nodeAddr;  { node address }
    		Socket : word;      { Big endian socket number}
    		end;
    	localAddrT = record
    		Net    : netAddr;   { my network address }
    		Node   : nodeAddr;  { my node address }
    		end;
    	ECBType = record
    		link      : address;    { Pointer to next ECB? }
    		ESR       : address;    { Event Service Routine 00000000h if none }
    		inUse     : byte;       { In use flag }
    		complete  : byte;       { Completeing flag }
    		socket    : word;       { Big endian socket number }
    		IPXwork   : array[1..4] of byte;  { IPX work space }
    		Dwork     : array[1..12] of byte; { Driver work space }
    		immedAddr : nodeAddr;   { Immediate local node address }
    		fragCount : word;       { Fragment count }
    		fragData  : address;    { Pointer to data fragment }
    		fragSize  : word;       { Size of data fragment }
    		end;
    	IPXheader = record
    		check  : word;                { big endian checksum }
    		length : word;                { big endian length in bytes }
    		tc     : byte;                { transport control }
    		pType  : byte;                { packet type }
    		dest   : netAddress;          { destination network address }
    		src    : netAddress;          { source network address }
    		end;

    const
    	BROADCAST : nodeAddr = ($ff,$ff,$ff,$ff,$ff,$ff);  { Address for broadcast }

    var
            IPXInstalled:boolean;  {You MUST check this BEFORE calling ANY procs}
            API:procedure;         {FAR entry point.}
            localAddr:localAddrT;   {Filled during init}
            major, minor:word;     {Verson of IPX}
            t1, t2:word;           {temps}

    procedure InitSendPacket(var ecb:ecbType; var ipx:ipxHeader; size, sock:word);
    {Constructs and preinitializes Transmission packet.  Required before usage.}

    procedure InitReceivePacket(var ecb:ecbType; var ipx:ipxHeader; size, sock:word);
    {Constructs and preinitializes reception packet.  Required before usage.}

    function  IPXopenSocket(longevity : byte; var socketNumber : word):byte;
    {Open a socket for use.  You must open a socket to use the IPX.
       LONGEVITY is 0 for open until close or terminate, FF for open until
       close.  TSRs need to use FF, non-resident programs should use 0.
       SOCKETNUMBER can by 0000 for dynamic allocation.  Retunrs 0 if
       successful.}

    procedure IPXcloseSocket(socketNumber : word);
    {Closes SOCKETNUMBER socket.  This cancels all pending events set by any
       ECBs.  Applications should close all sockets before termination.}

    procedure IPXsendPacket(var E : ECBtype);
    {E is an ECB.  This procedure attemps to send a packet in the background,
       therefore it always returns imediantly.}

    function  IPXlistenForPacket(var E : ECBtype):byte;
    {E is an ECB.  Returns 00 if successful else FF.  This provides the IPX
       with an ECB for recieving an IPX packet, but does not wait for a
       packet to arrive.  The calling app must have opend a socket and
       initilizied the ECB.  There is no limit to the number of packets that
       can be listening on the same socket.}

    procedure GetLocalAddress(var localAddr:localAddrT);
    {Returns intrernetwork address.}

    procedure Idle;
    {This call returns nothing but tells the IPX driver that the app is idle
       and permits the IPX driver to do some work.}

    implementation

    function  IPXopenSocket(longevity : byte; var socketNumber : word):byte;
    var
       return:byte;
       n:word;
    begin
       n:= swap(socketnumber);
       asm
          mov bx, 0000h;
          mov al, longevity;
          mov dx, n;
          call API;
          mov return, al;
          mov n, dx;
       end;
       socketnumber:= swap(n);
       IPXOpenSocket:= return;
    end;

    procedure IPXcloseSocket(socketNumber : word);
    begin
       socketnumber:= swap(socketnumber);
       asm
          mov bx, 0001h;
          mov dx, socketnumber;
          call API;
       end;
    end;

    procedure IPXsendPacket(var E : ECBtype);
    begin
       t1:= seg(e);
       t2:= ofs(e);
       asm
          mov bx, 0003h;
          mov es, t1;
          mov si, t2;
          call API;
       end;
    end;

    function  IPXlistenForPacket(var E : ECBtype):byte;
    var
       return:byte;
    begin
       t1:= seg(e);
       t2:= ofs(e);
       asm
          mov bx, 0004h;
          mov es, t1;
          mov si, t2;
          call API;
          mov return, al;
       end;
       IPXListenforPacket:= return;
    end;

    procedure GetLocalAddress(var localAddr:localAddrT);
    begin
       t1:= seg(localaddr);
       t2:= ofs(localaddr);
       asm
          mov bx, 0009h;
          mov es, t1;
          mov si, t2;
          call API;
       end;
    end;

    procedure Idle;
    begin
       asm
          mov bx, 000Ah;
          call API;
       end;
    end;

    procedure InitSendPacket(var ecb : ecbType; var ipx : ipxHeader; size,sock : word);
    begin
    	fillChar(ecb,sizeOf(ecb),#0);
    	fillChar(ipx,sizeOf(ipx),#0);
    	with ecb do begin
    		socket:=swap(sock);               { Big endian socket number }
    		fragCount:=1;                     { Fragment count }
    		fragData[0]:=ofs(IPX);            { Pointer to data fragment }
    		fragData[1]:=seg(IPX);
    		fragSize:=sizeof(IPX)+size;       { Size of data fragment }
    		immedAddr:=BROADCAST;             { Needs to be BROADCAST?? }
    		end;
    	with ipx do begin
    		check:=$ffff;                     { NO CHECKSUM }
    		ptype:=0;                         { Packet exchange packet }
    		dest.net:=localAddr.net;          { Send to this network }
    		dest.node:=BROADCAST;             { Send to everybody! }
    		dest.socket:=swap(sock);          { Send to my socket }
    		src.net:=localAddr.net;           { From this net }
    		src.node:=localAddr.node;         { From ME }
    		src.socket:=swap(sock);           { From my socket }
    		end;
    end;

    procedure InitReceivePacket(var ecb : ecbType; var ipx : ipxHeader; size,sock : word);
    begin
      fillChar(ecb,sizeOf(ecb),#0);
      fillChar(ipx,sizeOf(ipx),#0);
      with ecb do begin
    	inUse:=$1d;                               { ???? }
    	socket:=swap(sock);                       { Big endian socket number }
    	fragCount:=1;                             { Fragment count }
    	fragData[0]:=ofs(IPX);                    { Pointer to data fragment }
    	fragData[1]:=seg(IPX);
    	fragSize:=sizeof(IPX)+size;               { Size of data fragment }
      end;
    end;

    var
       t:byte;

    begin
       asm
          mov ax, 7a00h;
          int 2fh;
          mov t, al;
          mov major, es;
          mov minor, bx;
          mov t1, es;
          mov t2, di;
       end;
       IPXInstalled:= (t=$FF);
       if IPXInstalled then
          begin
             @API:= ptr(t1, t2);
             getlocaladdress(localaddr);
          end
       else
          @API:= nil;
    end.

[Back to NETWORK SWAG index] [Back to Main SWAG index] [Original]