DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T p

⟦6fc4f0762⟧ TextFile

    Length: 11387 (0x2c7b)
    Types: TextFile
    Names: »pktd.asm«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦349c9a24c⟧ »EurOpenD3/network/ka9q/pktd.tar.Z« 
        └─⟦613ecc654⟧ 
            └─⟦this⟧ »./src/pktd.asm« 

TextFile

;       @(#)pktd.asm.u	1.5    2/7/90\r
;\r
; Copyright (c) 1989, 1990 by Sun Microsystems, Inc.\r
;\r
\r
title Sun Packet Driver Interface Driver\r
page ,132\r
\r
;\r
;	The following driver is derived from two sources:\r
;	(1) Version 1.08 of the Packet Driver Specification,\r
;	    developed at FTP Software Inc.\r
;	(2) The PC-NFS Link Level Driver Kit.\r
;\r
;	In addition, Karl Auerbach (karl@asylum.sf.ca.us) contributed\r
;	a couple of fixes; his mods are marked "***KAA". Thanks, Karl.\r
;\r
;	This version includes the fixes suggested by many users to allow\r
;	PC-NFS to co-exist with Netware using the New York code. Thanks\r
;	to Russ Nelson at Clarkson and James Van Bokkelen at FTP for\r
;	their help.\r
;\r
;	This material is provided "as is." It is NOT a supported\r
;	Sun product, and has not been tested against more than\r
;	a handful of packet drivers. Please send any comments,\r
;	fixes, etc. to me (geoff@east.sun.com).\r
;\r
;		Geoff Arnold\r
\r
_OPERATING_STATISTICS equ 1\r
\r
cseg	segment para public 'code'\r
	assume	cs:cseg\r
	assume	ds:nothing\r
	assume	es:nothing\r
\r
\r
include pktdd.asm\r
include pktd.mac\r
include protocol.inc\r
include log.inc\r
include select.inc\r
\r
;\r
;	EXTRNS\r
;\r
extrn	demux:near\r
extrn	upcall:near\r
\r
;	PUBLICS\r
;\r
\r
public	select_table_pointer	       ; new name for universal demux routine\r
\r
public	log_seg\r
public	log_base\r
public	ethsend\r
\r
;	variables which live in cseg\r
;\r
\r
;\r
; Pointer to select table - used by demux.asm\r
;\r
select_table_pointer dw 2 dup (0)	; address of select table\r
\r
\r
\r
; the following are the segment & offset for the log table\r
log_seg 	dw	?\r
log_base	dw	?\r
; The log routine follows:\r
	logproc\r
;............................................................\r
; see the pop_f macro in pktd.mac for why this is here\r
iretins:\r
	iret\r
\r
;	initialize the ethernet interface and driver\r
;	es:di contains address of select table\r
ethinit proc far\r
	push	es\r
	push	ds			; save old ds and set to cs\r
	push	cs\r
	pop	ds\r
	mov	select_table_pointer,di ; save the table address away\r
	mov	select_table_pointer+2,es\r
	mov	es:sel_largest[di], largest_packet	; ret size of buffer\r
;\r
;	get log info\r
;\r
	mov	ax, es:sel_logtab_s[di]\r
	mov	log_seg, ax\r
	mov	ax, es:sel_logtab_o[di]\r
	mov	log_base, ax\r
;\r
; (we can now use the log macro)\r
;\r
	push	es\r
	call	setup\r
	pop	es\r
	push	cs\r
	pop	ds\r
	lea	di,sel_ethaddr[di]	;point to ether address entry\r
	mov	si, offset pd_addr\r
	movsw\r
	movsw\r
	movsw\r
ethinitdone:\r
	sub	ax,ax\r
	pop	ds\r
	pop	es\r
	sti\r
	ret\r
ethinit endp\r
\r
ethsend proc	far\r
	call	sender\r
	ret\r
ethsend endp\r
\r
\f

\r
\r
;--  The packet driver code looks like this:\r
;--\r
;--  setup() {\r
;--	 if(state==UP)\r
;--	     return; /* state starts out as DOWN */\r
;--	 if(find_driver() == FALSE)\r
;--	     return;\r
;--	 stuff = call_driver(DRIVER_INFO);\r
;--	 handle = call_driver(ACCESS_TYPE, IP_TYPE, 2, receiver);\r
;--	 handle = call_driver(ACCESS_TYPE, ARP_TYPE, 2, receiver);\r
;--	 handle = call_driver(ACCESS_TYPE, RARP_TYPE, 2, receiver);\r
;--	 call_driver(GET_ADDRESS, handle, &my_link_addr, &my_link_addr_len);\r
;--	 state = UP;\r
;--  }\r
;--\r
;--  find_driver() {\r
;--	 vecptr = PTR(0, 0x60*4); /* point into vectors */\r
;--	 for(vector = 0x60; vector <= 0x80; vector++) {\r
;--	     driverptr = *vecptr; /* deref ptr to dword ptr */\r
;--	     if (strcmp(*(driverptr+3), "PKT DRVR") == 0)\r
;--		 return(TRUE);\r
;--	     vecptr += 4; /* step to next vector */\r
;--	 }\r
;--	 return(FALSE);\r
;--  }\r
;--\r
;--  call_driver(func,args) {\r
;--	 load args into registers;\r
;--	 set AH = func;\r
;--	 soft int to vector; /* ?far call to driverptr with ints off? */\r
;--  }\r
;--\r
;--  sender() {\r
;--	 if(multiple fragments) {\r
;--	     marshal fragments into sendbuf;\r
;--	     call_driver(SEND_PKT, sendbuf);\r
;--	 } else {\r
;--	     call_driver(SEND_PKT, caller_buf);\r
;--	 }\r
;--  }\r
;--\r
;--  receiver(ax) {\r
;--	 if(ax == 0) {	     /* first call for a packet */\r
;--	     set es:di to pint at rcvbuf; cx = sizeof(rcvbuf);\r
;--	 } else {	     /* data copied - test and demux */\r
;--	     demux_and_upcall(rcvbuf);\r
;--	 }\r
;--  }\r
;------ The descriptions above are replicated before each routine\r
\f

\r
\r
DRIVER_INFO	equ	1\r
ACCESS_TYPE	equ	2\r
SEND_PKT	equ	4\r
GET_ADDRESS	equ	6\r
\r
buflen	    equ     1518\r
pd_sig	    db	    'PKT DRVR',0\r
pd_sig_len  equ     $-pd_sig\r
pd_int	    db	    0\r
pd_setup    db	    0\r
pd_class    db	    0\r
pd_num      db	    0\r
pd_type     dw      0\r
pd_alen     dw	    6\r
pd_addr     db	    6 dup (0)\r
pd_handle   dw	    0\r
pd_rbuf     db	    buflen dup (?)\r
pd_sbuf     db	    buflen dup (?)\r
pd_rlen     dw	    0\r
;\r
ip_type     db      8,0\r
arp_type    db      8,6\r
rarp_type   db      80h,35h\r
;\r
\r
pd_stklev   dw	    0\r
pd_stack    db	    256 dup ('x')\r
pd_stktop   dw	    0\r
; Save the SI returned by demux() in the following locations ***KAA\r
si_save	    dw	    0					    ;***KAA\r
\f

\r
;--\r
;--  call_driver(func,args) {\r
;--	 load args into registers;\r
;--	 set AH = func;\r
;--	 soft int to vector; /* ?far call to driverptr with ints off? */\r
;--  }\r
public call_driver\r
call_driver proc    near\r
	int	0\r
	ret\r
call_driver endp\r
\r
pd_patch    equ     call_driver+1\r
\r
\f

\r
;--\r
;--  setup() {\r
;--	 if(state==UP)\r
;--	     return; /* state starts out as DOWN */\r
;--	 if(find_driver() == FALSE)\r
;--	     return;\r
;--	 stuff = call_driver(DRIVER_INFO);\r
;--	 handle = call_driver(ACCESS_TYPE, IP_TYPE, 2, receiver);\r
;--	 handle = call_driver(ACCESS_TYPE, ARP_TYPE, 2, receiver);\r
;--	 handle = call_driver(ACCESS_TYPE, RARP_TYPE, 2, receiver);\r
;;--	 call_driver(GET_ADDRESS, handle, &my_link_addr, &my_link_addr_len);\r
;--	 state = UP;\r
;--  }\r
public setup\r
setup	    proc    near\r
	    push    ax\r
	    push    bx\r
	    push    cx\r
	    push    dx\r
	    push    es\r
	    push    di\r
	    push    si\r
	    cmp     pd_setup, 0\r
	    jne     se_900\r
	    inc     pd_setup\r
	    call    find_driver\r
	    jc	    se_900\r
	    mov     ah, DRIVER_INFO\r
	    call    call_driver\r
	    push    cs\r
	    pop     ds		    ; deliberately ignoring the name\r
	    jc	    se_900\r
	    mov     pd_class, ch\r
            mov     pd_num, cl\r
            mov     pd_type, dx\r
;\r
            mov     si, offset ip_type\r
            call    register_type\r
            jc      se_900\r
            mov     si, offset arp_type\r
            call    register_type\r
            jc      se_900\r
            mov     si, offset rarp_type\r
            call    register_type\r
            jc      se_900\r
\r
	    mov     bx, pd_handle\r
	    mov     ah, GET_ADDRESS\r
	    push    cs\r
	    pop     es\r
	    mov     di, offset pd_addr\r
	    mov     cx, pd_alen\r
	    call    call_driver\r
	    jc	    se_900\r
	    mov     pd_alen, cx\r
se_900:\r
	    pop     si\r
	    pop     di\r
	    pop     es\r
	    pop     dx\r
	    pop     cx\r
	    pop     bx\r
	    pop     ax\r
	    ret\r
setup	    endp\r
\r
;\r
; register_type, entered with ds:si pointing at the packet type code\r
;\r
public register_type\r
register_type proc near\r
	    mov     ah, ACCESS_TYPE\r
	    mov     al, pd_class\r
	    mov     bx, pd_type\r
	    mov     dl, pd_num\r
	    mov     cx, 2		; 2 bytes of filter\r
	    push    cs\r
	    pop     es\r
	    mov     di, offset receiver\r
	    call    call_driver\r
	    jc	    rt_900\r
	    mov     pd_handle, ax\r
            ret\r
rt_900:	\r
;		int 3\r
		ret\r
register_type endp\r
\f

\r
;--\r
;--  find_driver() {\r
;--	 vecptr = PTR(0, 0x60*4); /* point into vectors */\r
;--	 for(vector = 0x60; vector <= 0x80; vector++) {\r
;--	     driverptr = *vecptr; /* deref ptr to dword ptr */\r
;--	     if (strcmp(*(driverptr+3), "PKT DRVR") == 0)\r
;--		 return(TRUE);\r
;--	     vecptr += 4; /* step to next vector */\r
;--	 }\r
;--	 return(FALSE);\r
;--  }\r
public find_driver\r
find_driver proc    near\r
	    mov     bx, 60h*4\r
	    mov     dx, 60h\r
	    xor     ax, ax\r
	    cld\r
fd_010:\r
	    mov     es, ax\r
	    les     di, es:[bx] 	; get vector in ES:BX\r
	    lea     di, 3[di]		; point at signature\r
	    mov     si, offset pd_sig\r
	    mov     cx, pd_sig_len\r
	    repe    cmpsb\r
	    je	    fd_100		; found it\r
	    add     bx, 4\r
	    inc     dx\r
	    cmp     dx, 80h\r
	    jle     fd_010\r
	    stc\r
	    ret\r
fd_100:\r
	    mov     pd_int, dl\r
	    mov     byte ptr cs:pd_patch, dl\r
	    clc\r
	    ret\r
find_driver endp\r
\r
\f

\r
;--\r
;--  sender() {\r
;--	 if(multiple fragments) {\r
;--	     marshal fragments into sendbuf;\r
;--	     call_driver(SEND_PKT, sendbuf);\r
;--	 } else {\r
;--	     call_driver(SEND_PKT, caller_buf);\r
;--	 }\r
;--  }\r
public sender\r
sender	    proc    near\r
	    log     _LOG_ETH_XMIT\r
	    push    bx\r
	    push    cx\r
	    push    dx\r
	    push    si\r
	    push    ds\r
	    push    es\r
	    mov     ah, SEND_PKT\r
	    add     di, 2		    ; step over status\r
	    mov     cx, word ptr es:[di]\r
	    lds     si, dword ptr es:[di+2]\r
	    add     di, 6\r
	    cmp     word ptr es:[di], 0     ; any more?\r
	    jne     send_010		    ; if so, go do multiple...\r
	    call    call_driver\r
	    jmp     send_090\r
send_010:\r
;  we must copy the data into a local buffer first\r
	    push    es\r
	    push    di\r
	    mov     dx, cx		    ; save count\r
	    push    cs\r
	    pop     es\r
	    mov     di, offset pd_sbuf\r
	    call    copydata\r
	    pop     si\r
	    pop     ds\r
	    mov     cx, word ptr [si]\r
	    lds     si, dword ptr [si+2]\r
	    add     dx, cx\r
	    call    copydata\r
	    push    cs\r
	    pop     ds\r
	    mov     si, offset pd_sbuf\r
	    mov     cx, dx\r
	    call    call_driver\r
send_090:\r
	    pop     es\r
	    pop     ds\r
	    pop     si\r
	    pop     dx\r
	    pop     cx\r
	    pop     bx\r
	    sub     ax, ax	    ; no error\r
	    ret\r
sender	    endp\r
\r
public copydata\r
copydata    proc    near\r
	    inc     cx		    ; if odd (illegal?) ...\r
	    shr     cx, 1	    ; ... round up (otherwise inc is benign)\r
	    rep     movsw\r
	    ret\r
copydata    endp\r
\f

\r
;--\r
;--  receiver(ax) {\r
;--	 if(ax == 0) {	     /* first call for a packet */\r
;--	     set es:di to pint at rcvbuf; cx = sizeof(rcvbuf);\r
;--	 } else {	     /* data copied - test and demux */\r
;--	     demux_and_upcall(rcvbuf);\r
;--	 }\r
;--  }\r
public receiver\r
receiver    proc    far\r
	cmp	ax, 0\r
	jne	rcv_010\r
	push	cs\r
	pop	es\r
	mov	di, offset pd_rbuf\r
	mov	cs:pd_rlen, cx\r
	ret\r
rcv_010:\r
;	we first switch to our stack. we can trash ax/bx/dx, per spec\r
	pushf\r
	pop	dx\r
	cli\r
	cmp	cs:pd_stklev, 0\r
	jne	rcv_015\r
	inc	cs:pd_stklev\r
	mov	ax, ss\r
	mov	bx, sp\r
	push	cs\r
	pop	ss\r
	mov	sp, offset pd_stktop\r
	push	ax\r
	push	bx\r
rcv_015:\r
	push	dx		    ; saved flags\r
	popf\r
\r
	push	ds		    ; general save\r
\r
	push	ds		    ; save...\r
	push	si		    ; ... over ...\r
	push	cx		    ;	 ... demux\r
\r
	push	ds\r
	pop	es\r
\r
	push	si\r
	pop	di\r
\r
	mov	cx,64	            ; Limit demux's view (why ???) ***KAA\r
	call	demux		    ; and remember to preserve BX cookie\r
	mov	si_save,si	    ; It is necessary to save the SI returned\r
				    ; from demux and pass it to upcall ***KAA\r
\r
	pop	ax		    ; original len\r
	pop	si\r
	pop	ds\r
\r
	jc	rcv_800 	    ; carry from demux call\r
	log	_LOG_ETH_RCV\r
	cmp	ax, cx\r
	jge	rcv_200\r
	mov	cx, ax\r
rcv_200:\r
	call	copydata\r
	mov	si,si_save	    ;***KAA\r
	call	upcall\r
	jmp	rcv_900\r
rcv_800:\r
	log	_LOG_ETH_DROPPED\r
rcv_900:\r
	pop	ds\r
	pushf\r
	pop	dx		; save those flags\r
	cli\r
	dec	cs:pd_stklev\r
	jne	rcv_990\r
	pop	bx\r
	pop	ax\r
	mov	ss, ax\r
	mov	sp, bx\r
rcv_990:\r
	push	dx		; the flags, the flags....\r
	popf\r
	ret\r
receiver    endp\r
\r
cseg	ends\r
end	begin\r