home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Encyclopedia 96-1
/
novell-nsepro-1996-1-cd2.iso
/
download
/
netware
/
ipxasm.exe
/
IPXEX.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-09-12
|
16KB
|
533 lines
;*** Copyright (c) 1992 Novell, Inc. All Rights Reserved.
;***
;*** THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
;*** TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE
;*** LICENSE AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK)
;*** THAT CONTAINS THIS WORK.
;***
;*** Pursuant to the SDK License Agreement, Novell hereby grants to
;*** Developer a royalty-free, non-exclusive license to include the
;*** sample code IPXEX.ASM and derivative binaries in its product.
;*** Novell grants to Developer worldwide distribution rights to market,
;*** distribute or sell the sample code IPXEX.ASM and derivative
;*** binaries as a component of Developer's product(s). Novell shall
;*** have no obligations to Developer or Developer's customers with
;*** respect to this code.
;***
;*** DISCLAIMER:
;***
;*** Novell, Inc. makes no representations or warranties with respect
;*** to the contents or use of this code, and specifically disclaims any
;*** express or implied warranties of merchantability or fitness for any
;*** particular purpose. Further, Novell, Inc. reserves the right to revise
;*** this publication and to make changes to its content, at any time,
;*** without obligation to notify any person or entity of such revisions or
;*** changes.
;***
;*** Further, Novell, Inc. makes no representations or warranties with
;*** respect to any software, and specifically disclaims any express or
;*** implied warranties of merchantability or fitness for any particular
;*** purpose. Further, Novell, Inc. reserves the right to make changes to
;*** any and all parts of the software, at any time, without obligation to
;*** notify any person or entity of such changes.
;***
;***
;*** **********************************************************************
;*** IPXEX.C
;*** **********************************************************************
;***
;*** Description: This is sample code that demonstrates how to send and
;*** receive an IPX packet using the Assembly Language Interface.
;*** IPXEX takes a server type from the command line, builds
;*** Get Nearest Server Query for that server type then sends
;*** the broadcast. It then receives the response (if one arrives
;*** within one minute) and prints the name of the server from
;*** the response packet.
;***
;***
;***
;*** Programmer: Karl Bunnell
;*** Date: 09/12/95
;***
;*** Built with: Borland TASM
Ideal
Model Tiny
P286
CodeSeg
Org 100h
Start: jmp INIT_CODE
;--------------------------------------------------------------------------
;** IPX Structures
;
Struc IPXHeaderStructure
IPXChecksum dw ?
IPXLength dw ?
IPXTransportControl db ?
IPXPacketType db ?
IPXDestinationNet dw 2 dup (?)
IPXDestinationNode dw 3 dup (?)
IPXDestinationSocket dw ?
IPXSourceNet dw 2 dup (?)
IPXSourceNode dw 3 dup (?)
IPXSourceSocket dw ?
EndS IPXHeaderStructure
Struc ECB_Structure
Link dd ?
ESR_AddressOff dw ?
ESR_AddressSeg dw ?
In_Use_Flag db ?
CompletionCode db ?
ECB_Socket dw ?
IPXWorkspace db 4 dup (?)
DriverWorkSpace db 12 dup (?)
ImmediateAddress db 6 dup (?)
FragmentCount dw ?
FragmentAddressOff1 dw ?
FragmentAddressSeg1 dw ?
FragmentLength1 dw ?
FragmentAddressOff2 dw ?
FragmentAddressSeg2 dw ?
FragmentLength2 dw ?
EndS ECB_Structure
Struc SAPIDPacket
ResponseType dw ?
ServerType dw ?
ServerName db 48 dup (?)
NetWork dw 2 dup (?)
Node dw 3 dup (?)
Socket dw ?
IntermediateNetworks dw ?
EndS SAPIDPacket
Struc SAPQueryPacket
QueryType dw ?
ServerType dw ?
EndS SAPQueryPacket
CR equ 13 ;carriage return
LF equ 10 ;line feed
STDOUT equ 1
ONE_MIN equ 044Ch
USE_INFO equ 0 ;Index for Usage INFO Screen
IPX_NOT_LOADED equ 1 ;Index for IPX not loaded Failure
OPEN_SOCKET_FAIL equ 2 ;Index to Open Socket Failed
LONGER_T_MIN equ 3 ;Index to wait longer than minute
UseInfo DB CR,LF,"Usage: IPXEX XXXX"
DB CR,LF," Where:"
DB CR,LF," XXXX is the Server type in Hex. "
DB CR,LF,42
IPXNotLoaded DB CR,LF,"IPX is NOT loaded, Please Load IPX and try again!"
DB CR,LF,42
OpenSocketFail DB CR,LF,"Attempt to open IPX Socket Failed!"
DB CR,LF,"Socket may already be open or Socket Table is full!"
DB CR,LF,42
LongerThanMin DB CR,LF,"Receive Wait Time Out! Waited One minute without a Response."
DB CR,LF,42
Transmit DB CR,LF,"Attempting to establish connection..."
DB CR,LF,42
Receive DB CR,LF,"Waiting to receive initial SAP packet...Will wait 61 Sec."
DB CR,LF,42
Connected DB CR,LF,"Received SAP Response!"
DB CR,LF,42
MsgStrTable DW UseInfo ;0
DW IPXNotLoaded ;1
DW OpenSocketFail ;2
DW LongerThanMin ;3
IPXH_T IPXHeaderStructure ? ;packet header storage
IPXH_R IPXHeaderStructure ? ;Receive IPX header storage
ECB_TR ECB_Structure ? ;Transmit ECB storage
ECB_R ECB_Structure ? ;Receive ECB Storage
SAP_ID SAPIDPacket ? ;buffer to receive SAP S Info
SAP_QR SAPQueryPacket ? ;Sap query storage
IPXEntry dd ?
SAPServType dw ?
Broadcast db 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
MySocket dw ?
RecTryCount dw 0
TimeCompare dw 0
save dw 0
plf dw 0
Int28Flg dw -1
;--------------------------------------------------------------------------
; This is where the Initialization code begins.
; This code first checks to see if IPX is loaded, if not it exits.
; If nothing is entered on the command line, it exits.
; Otherwise it continues on
;--------------------------------------------------------------------------
Assume ds:DGROUP
INIT_CODE: mov ax, 7A00h ; Check and see if IPX
int 2Fh ; is loaded!
cmp al, 0FFh ; If FF is returned in AL
je IPXLoadPass
mov cx, IPX_NOT_LOADED
jmp MsgPrint
IPXLoadPass: mov [WORD PTR IPXEntry], di ; Get IPX entry address
mov ax, es
mov [WORD PTR IPXEntry+2], ax
mov bx, 080h ;load pointer to char count
mov dx, 081h ;load pointer to command line buffer
xor ch, ch ;zero high half of count register
mov cl, [bx] ;load character count
mov bx, dx ;get address passed in DX
add dx, cx ;move DX to end of string
jmp PreInst1 ;jump to condition test
PreInst0: mov al, [bx] ;get first character
cmp al, ' ' ;is it a space?
je PreInst00
cmp al, '/' ;is it a slash?
je PreInst00
cmp al, '-' ;is it a dash?
je PreInst00
jmp short PreInst01 ;none of the above, continue...
PreInst00: inc bx ;skip whitespace and separators
jmp PreInst0
PreInst01: mov ah, [bx]
inc bx ;get Server Type Number from
mov al, [bx] ;command line and convert to HEX.
call AsciiToHexByte
mov [BYTE SAPServType], al
inc bx
mov ah, [bx]
inc bx ;get second char
mov al, [bx]
call AsciiToHexByte
mov [BYTE SAPServType+1], al
mov ah, [BYTE SAPServType]
mov al, [BYTE SAPServType+1]
ContIPXInit: push cs ;set ds = cs
pop ds
push cs
pop es ;set es = cs
mov bx, 0 ;Open socket upon which to X and R.
mov al, 0FFh ;Leave sock open until close sock.
mov dx, 0 ;Dynamically assigned socket.
call [cs:IPXEntry]
cmp al, 00h
je IPXOpenSckPass
mov cx, OPEN_SOCKET_FAIL
jmp MsgPrint
;*** Set up the Receive ECB fields
IPXOpenSckPass:
xor ax, ax
mov [ECB_R.ESR_AddressOff], ax
mov [ECB_R.ESR_AddressSeg], ax
mov [WORD MySocket], dx ;Dynm. socket returned in dx
mov [ECB_R.ECB_Socket], dx
mov [ECB_R.FragmentCount], 2
mov [WORD ECB_R.FragmentAddressOff1], offset IPXH_R
mov ax, ds
mov [WORD ECB_R.FragmentAddressSeg1], ax
mov [ECB_R.FragmentLength1], 30
mov [WORD ECB_R.FragmentAddressOff2], offset SAP_ID
mov [WORD ECB_R.FragmentAddressSeg2], ax
mov [ECB_R.FragmentLength2], 66
push cs
pop es ;set es = cs
mov bx, 04h ;Start listening for SAP reply pack.
mov si, offset ECB_R
call [cs:IPXEntry]
push cs ;set ds = cs
pop ds
push cs
pop es ;set es = cs
; *** Fill in necessary fields for IPX header.
mov [IPXH_T.IPXPacketType], 4 ; Packet Type IPX
mov si, offset IPXH_T.IPXDestinationNet
mov bx, 09h ;Get Internet Address call
call [cs:IPXEntry]
mov si, offset Broadcast
mov di, offset IPXH_T.IPXDestinationNode
mov cx, 6 ; Set Dest. Node to FF FF FF FF FF FF
rep movsb
mov [IPXH_T.IPXDestinationSocket], 5204h
;*** Fill in SAP Query Packet fields
mov [WORD SAP_QR.QueryType], 0100h ;Nearest Query
mov dx, [SAPServType]
mov [WORD SAP_QR.ServerType], dx
;*** Fill in Transmit ECB fields
mov dx, [MySocket]
mov [ECB_TR.ECB_Socket], dx
xor ax, ax
mov [ECB_TR.ESR_AddressOff], ax
mov [ECB_TR.ESR_AddressSeg], ax
mov si, offset Broadcast
mov di, offset ECB_TR.ImmediateAddress
mov cx, 6
rep movsb
mov [ECB_TR.FragmentCount], 2
mov [WORD ECB_TR.FragmentAddressOff1], offset IPXH_T
mov ax, ds
mov [WORD ECB_TR.FragmentAddressSeg1], ax
mov [ECB_TR.FragmentLength1], 30
mov [WORD ECB_TR.FragmentAddressOff2], offset SAP_QR
mov [WORD ECB_TR.FragmentAddressSeg2], ax
mov [ECB_TR.FragmentLength2], 4
push cs ;Transmit Packet!
pop es
mov bx, 03h
mov si, offset ECB_TR
call [cs:IPXEntry]
mov ax, offset Transmit
call Print
QXmitWait: mov bx, 0Ah ;IPX Relinquish control
call [cs:IPXEntry] ;Until Packet is Xmitted.
cmp [ECB_TR.In_Use_Flag], 0
jne QXmitWait ;Loop until In Use Flag = 0
mov ax, offset Receive
call Print
TimeSet: mov ah,0 ;Get Current Time
int 1ah
add dx, ONE_MIN ;Add one minute
mov [TimeCompare], dx
QRecWait: mov bx, 0Ah ;IPX Relinquish control
call [cs:IPXEntry] ;Until Packet is received.
int 1ah
cmp [TimeCompare], dx
jbe ExitRec
cmp [ECB_R.In_Use_Flag], 0
jne QRecWait ;Loop until In Use Flag = 0
mov di, offset SAP_ID.ServerName
add di, 48
mov [BYTE di], 42
; mov [SAP_ID.ServerName+47], 42 ;add * to end of server name
mov ax, offset SAP_ID.ServerName
call Print
mov ax, [SAPServType]
cmp [SAP_ID.ServerType], ax
je CleanUp
inc [RecTryCount]
mov [TimeCompare], 00h
push cs
pop es
mov bx, 04h ;Start listening for SAP reply pack.
mov si, offset ECB_R
call [cs:IPXEntry]
push cs ;Send query packet again
pop es
mov bx, 03h
mov si, offset ECB_TR
call [cs:IPXEntry]
cmp [RecTryCount], 20
jne QXmitWait
ExitRec: mov cx, LONGER_T_MIN
jmp CleanUp
Jumper2: jmp PreInst0
PreInst1: cmp bx, dx
jl Jumper2 ;Used to extend relative jump
mov cx, USE_INFO
jmp MsgPrint
CleanUp:
push cs
pop es
mov bx, 06 ;Cancel IPX event for Xmit ECB
mov si, offset ECB_TR
call [cs:IPXEntry]
mov bx, 06 ;Cancel IPX event for Rec ECB
mov si, offset ECB_R
call [cs:IPXEntry]
mov bx, 01h ;Close Socket
mov dx, [MySocket]
call [cs:IPXEntry]
jmp EndItHere
;*** Print Message
MsgPrint: mov bx, cx ;get index value
shl bx, 1 ;mulitply by 2 to index words
mov ax, [MsgStrTable+bx] ;get address of error msg
call Print
EndItHere: mov ah, 04Ch ;Return mem. used back to DOS
mov al, 01h ;And terminate program.
int 21h
;-------------------------------------------------------------------------
;
; Prints Character strings. Stings must end with '*'.
;
;
;-------------------------------------------------------------------------
Proc Print
push ax
push di
push bx
push cs
pop ds
mov [save], ax ;save address of message
mov [plf], 0 ;clear print loop flag
LP: mov ax, [save] ;get message address
mov di, ax
cmp [BYTE PTR di],42 ;check for a '*'
jne PRNT ;jump if not equal to '*'
mov [plf],1 ;set print loop flag
jmp LPE ;go to check loop flag
PRNT: mov al, [BYTE PTR di] ;get character to print
mov bh, 0
mov ah, 0eh
int 10H
inc [save] ;increment pointer
LPE: cmp [BYTE PTR plf], 1 ;check for end of loop
jne LP ;loop if flag is clear
pop bx
pop di
pop ax
ret
Endp Print
;------------------------------------------------------------------------
; StringLength
;
; Should be called with DS:DX pointing to start of string.
; Destroys AX, BX. Does NOT destroy DS:DX.
;
; Returns number of bytes in string in CX.
;------------------------------------------------------------------------
Proc StringLength
xor bx, bx ;zero BX
mov si, dx ;get starting address
jmp short StrLen1 ;jump to compare function
StrLen0: inc bx ;increment pointer
StrLen1: mov al, [si+bx] ;get character at si[bx]
or al, al ;test character
jnz StrLen0 ;get next character
mov cx, bx ;return count in CX
ret ;return to caller
EndP StringLength
;------------------------------------------------------------------------
; AsciiToHexByte
;
; Takes Ascii hex characters in AH / AL and converts it to a byte
; in AL register.
;------------------------------------------------------------------------
Proc AsciiToHexByte
mov cx, 2
ATH0: xchg al, ah ;switch high and low characters
cmp al, '9'
ja ATH1
sub al, '0'
jmp short ATH2
ATH1: and al, 0DFh ;convert to upper case - strip bit 6
sub al, 'A'-10
ATH2: dec cx
jcxz ATH3 ;jump out on second pass
push cx ;save pass count
mov cl, 4 ;shift into upper nibble
shl al, cl
pop cx
cmp cx, 0
ja ATH0
ATH3: and ah, 0F0h ;mask high nibble
or al, ah ;put them together
ret
EndP AsciiToHexByte
;------------------------------------------------------------------------
; Close the Socket
;------------------------------------------------------------------------
Proc CloseMySocket
mov bx, 01h ;Close Socket
mov dx, [MySocket]
call [cs:IPXEntry]
ret
EndP CloseMySocket
End Start