home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
packetdrivers.tar.gz
/
pd.tar
/
src
/
pktring.asm
< prev
next >
Wrap
Assembly Source File
|
1992-02-10
|
11KB
|
565 lines
version equ 0
;History:4,1
; Copyright, 1989-1992, Russell Nelson, Crynwr Software
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, version 1.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
include defs.asm
code segment word public
assume cs:code, ds:code
org 80h
phd_dioa label byte
org 100h
start:
jmp start_1
copyleft_msg label byte
db "Packet ringer version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version," copyright 1990, Russell Nelson.",CR,LF
db "This program is free software; see the file COPYING for details.",CR,LF
db "NO WARRANTY; see the file COPYING for details.",CR,LF
crlf_msg db CR,LF,'$'
int_pkt macro num
pushf
cli
call their_isr_&num
endm
their_isr_1 dd ?
their_isr_2 dd ?
packet_int_1 db ?,?,?,?
packet_int_2 db ?,?,?,?
send_count dw RUNT
handle dw ?
transmit_count dw ?
receive_count dw ?
packet_mode dw ?
this_mode dw ?
signature db 'PKT DRVR',0
signature_len equ $-signature
no_signature_msg db "No packet driver at that address",'$'
usage_msg db "usage: pktring [-m] <packet_int_1> <packet_int_2>",'$'
sending_msg db "Sending from ",'$'
to_msg db " to ",'$'
not_implemented db "xx ",'$'
current_mode db "-> ",'$'
two_spaces db " ",'$'
test_modes db ? ;nonzero if we should test the modes.
mode_names dw mode_1_msg,mode_2_msg,mode_3_msg,mode_4_msg
dw mode_5_msg,mode_6_msg
mode_1_msg db "1) Turn off receiver",'$'
mode_2_msg db "2) Receive only packets sent to this interface",'$'
mode_3_msg db "3) Mode 2 plus broadcast",'$'
mode_4_msg db "4) Mode 3 plus limited multicast",'$'
mode_5_msg db "5) Mode 3 plus all multicast",'$'
mode_6_msg db "6) All packets",'$'
mode_code dw mode_1_tester,mode_2_tester,mode_3_tester,mode_4_tester
dw mode_5_tester,mode_6_tester
mode_good_msg db " passed",CR,LF,'$'
mode_bad_msg db " FAILED!",7,CR,LF,'$'
usage_error:
mov dx,offset usage_msg
error:
mov ah,9
int 21h
int 20h
start_1:
cld
mov dx,offset copyleft_msg
mov ah,9
int 21h
mov si,offset phd_dioa+1
cmp byte ptr [si],CR ;end of line?
je usage_error
another_switch:
call skip_blanks
cmp al,'-' ;did they specify a switch?
jne not_switch
cmp byte ptr [si+1],'m' ;did they specify '-m'?
je got_mode_switch
jmp usage_error ;no, must be an error.
got_mode_switch:
mov test_modes,1
add si,2
jmp another_switch
not_switch:
mov di,offset packet_int_1
call get_number
mov di,offset packet_int_2
call get_number
call skip_blanks ;check for the end of the line.
cmp al,CR
jne usage_error
mov sp,offset start ;now that we're finished with
;the parameters, put our stack there.
mov ah,35h ;get their packet interrupt.
mov al,packet_int_1
int 21h
mov their_isr_1.offs,bx
mov their_isr_1.segm,es
lea di,3[bx]
mov si,offset signature
mov cx,signature_len
repe cmpsb
je signature_1_ok
jmp no_signature_err
signature_1_ok:
mov ah,35h ;get their packet interrupt.
mov al,packet_int_2
int 21h
mov their_isr_2.offs,bx
mov their_isr_2.segm,es
lea di,3[bx]
mov si,offset signature
mov cx,signature_len
repe cmpsb
je signature_2_ok
jmp no_signature_err
signature_2_ok:
mov dx,offset sending_msg
mov ah,9
int 21h
push ds
mov ax,1ffh ;driver_info
int_pkt 2
jc saying_2_1
pushf
saying_2:
lodsb
call chrout
cmp byte ptr ds:[si],0
jne saying_2
popf
saying_2_1:
pop ds
call fatal_error
mov dx,offset to_msg
mov ah,9
int 21h
push ds
mov ax,1ffh ;driver_info
int_pkt 1
jc saying_1_1
pushf
push ax
saying_1:
lodsb
call chrout
cmp byte ptr ds:[si],0
jne saying_1
pop ax
popf
saying_1_1:
pop ds
call fatal_error
push ax
push dx
mov dx,offset crlf_msg
mov ah,9
int 21h
pop dx
pop ax
mov ah,2 ;access all packets.
mov al,ch ;their class from driver_info().
mov bx,dx ;their type from driver_info().
mov dl,cl ;their number from driver_info().
mov cx,0 ;type length of zero.
push cs ;es:di -> our receiver.
pop es
mov di,offset our_recv
int_pkt 1
call fatal_error
mov handle,ax
cmp test_modes,0 ;should we test the receive modes?
je get_their_address ;no.
mov ah,21 ;get the receive mode.
mov bx,handle
int_pkt 1
jc bad_1
mov packet_mode,ax
mov this_mode,1 ;start trying with mode 1.
try_mode:
cmp this_mode,4 ;skip modes 4 and 5 (don't work yet).
jne try_mode_1
mov this_mode,6
try_mode_1:
cmp this_mode,6 ;have we hit the last mode?
ja no_more_modes ;yes.
mov ah,20 ;set the receive mode.
mov bx,handle
mov cx,this_mode
int_pkt 1
jc tried_mode ;we tried it, and it didn't work.
mov bx,this_mode ;print the name of this mode.
shl bx,1
mov ah,9
mov dx,mode_names[bx-2]
int 21h
mov bx,this_mode ;do the test for this mode.
shl bx,1
call mode_code[bx-2]
mov dx,offset mode_good_msg ;report success.
jnc mode_good
mov dx,offset mode_bad_msg ;report failure.
mode_good:
mov ah,9
int 21h
tried_mode:
inc this_mode ;try the next mode.
jmp try_mode
no_more_modes:
mov ah,20 ;set the receive mode.
mov bx,handle
mov cx,packet_mode
int_pkt 1
bad_1:
jnc get_their_address
jmp bad
get_their_address:
mov ah,6 ;get the destination's address.
mov bx,handle
mov cx,EADDR_LEN
push cs ;es:di -> to address.
pop es
mov di,offset our_buffer
int_pkt 1
jc bad_1
wait_for_key:
inc send_count
cmp send_count,GIANT ;too big?
jbe length_ok
mov transmit_count,0 ;zero the counts.
mov receive_count,0
mov send_count,RUNT ;yes, reset it back down again.
length_ok:
mov cx,send_count
call send_packet
jc bad
inc transmit_count
mov ax,transmit_count
call wordout
mov al,' '
call chrout
mov ax,receive_count
call wordout
mov al,CR
call chrout
mov ah,1 ;check for any key.
int 16h
je wait_for_key ;no key -- keep waiting.
mov ah,0 ;read a key.
int 16h
mov ah,3 ;release the handle.
mov bx,handle
int_pkt 1
jc bad
int 20h
all_done:
xor bx,bx ;only release the handle once.
xchg bx,handle
or bx,bx
je all_done_1 ;we've already released it.
mov ah,3 ;release_type
int_pkt 1
jc bad
all_done_1:
int 20h
bad:
call print_error
okay:
jmp all_done
no_signature_err:
mov dx,offset no_signature_msg
mov ah,9
int 21h
int 20h
assume ds:nothing
our_recv:
or ax,ax ;first or second call?
jne our_recv_1 ;second -- we ignore the packet
push cs
pop es
mov di,offset our_buffer + GIANT
db 0cbh ;masm 4.0 doesn't grok "retf"
our_recv_1:
add si,EADDR_LEN+EADDR_LEN
lodsw
mov cx,ax
sub cx,EADDR_LEN+EADDR_LEN+2
our_recv_2:
lodsb
cmp al,cl
loope our_recv_2
jne our_recv_3 ;if they don't match, don't increment the count.
inc receive_count
our_recv_3:
db 0cbh ;masm 4.0 doesn't grok "retf"
;two macros to return an error code.
rz macro
stc
jne $+3
ret
endm
rnz macro
stc
je $+3
ret
endm
mode_1_tester:
call send_bcast ;don't receive broadcast,
rnz
call send_to_them ;don't receive their address,
rnz
call send_random ;don't receive other addresses,
rnz
call send_multi ;don't receive multicasts.
rnz
clc
ret
mode_2_tester:
call send_bcast ;don't receive broadcast,
rnz
call send_random ;don't receive other addresses,
rnz
call send_multi ;don't receive multicasts.
rnz
call send_to_them ;do receive their address,
rz
clc
ret
mode_3_tester:
call send_bcast ;do receive broadcast,
rz
call send_random ;don't receive other addresses,
rnz
call send_multi ;don't receive multicasts.
rnz
call send_to_them ;do receive their address,
rz
clc
ret
mode_4_tester:
;;; set up 01:01:01:01:01:01 in the multicast list.
call send_bcast ;do receive broadcast,
rz
call send_random ;don't receive other addresses,
rnz
call send_multi ;do receive multicasts.
rz
call send_to_them ;do receive their address,
rz
clc
ret
mode_5_tester:
;;; set up an empty mullticast list.
call send_bcast ;do receive broadcast,
rz
call send_random ;don't receive other addresses,
rnz
call send_multi ;do receive multicasts.
rz
call send_to_them ;do receive their address,
rz
clc
ret
mode_6_tester:
call send_bcast ;do receive broadcast,
rz
call send_random ;do receive other addresses,
rz
call send_multi ;do receive multicasts.
rz
call send_to_them ;do receive their address,
rz
clc
ret
send_bcast:
mov dl,'B'
mov ah,6
int 21h
mov al,0ffh ;all-ones is broadcast.
jmp short send_fixed_addr
send_random:
mov dl,'R'
mov ah,6
int 21h
mov al,002h ;all twos is an okay address.
jmp short send_fixed_addr
send_multi:
mov dl,'M'
mov ah,6
int 21h
mov al,001h ;first bit set is multicast.
send_fixed_addr:
push cs
pop es
mov di,offset our_buffer
mov cx,EADDR_LEN
rep stosb
jmp short send_to_addr
send_to_them:
mov dl,'T'
mov ah,6
int 21h
mov ah,6 ;get the destination's address.
mov bx,handle
mov cx,EADDR_LEN
push cs ;es:di -> to address.
pop es
mov di,offset our_buffer
int_pkt 1
jnc send_to_addr
send_to_addr_bad:
jmp bad
send_to_addr:
;send the packet in our_buffer.
;return zr if we didn't receive it, and ne if we did.
;we'll know we got a packet if the receive count gets bumped.
mov receive_count,0
mov cx,100
call send_packet
jc send_to_addr_3
mov ax,2
call set_timeout
send_to_addr_1:
cmp receive_count,0 ;did we receive it?
jne send_to_addr_2
call do_timeout
jne send_to_addr_1
mov dl,'0'
mov ah,6
int 21h
xor al,al
ret
send_to_addr_2:
mov dl,'1'
mov ah,6
int 21h
or sp,sp
ret
send_to_addr_3:
xor al,al
ret
send_packet:
;enter with cx = length of packet.
;stuff the standard contents into our_buffer.
;return the results of sending the packet.
push cx
push cs ;es:di -> our buffer.
pop es
mov di,offset our_buffer+EADDR_LEN+EADDR_LEN
mov ax,cx
stosw
sub cx,EADDR_LEN+EADDR_LEN+2
send_packet_1:
mov al,cl
stosb
loop send_packet_1
pop cx
mov ah,4 ;send_pkt
mov si,offset our_buffer ;ds:si -> buffer.
int_pkt 2
ret
include timeout.asm
include pkterr.asm
include getnum.asm
include getdig.asm
include skipblk.asm
include chrout.asm
include digout.asm
our_buffer label byte
code ends
end start