1; 2; This file requires NASM 0.97+ to assemble 3; 4; Currently used only for djgpp + DOS4GW targets 5; 6; these sizes MUST be equal to the sizes in PKTDRVR.H 7; 8%define ETH_MTU 1500 ; max data size on Ethernet 9%define ETH_MIN 60 ; min/max total frame size 10%define ETH_MAX (ETH_MTU+2*6+2) ; =1514 11%define NUM_RX_BUF 32 ; # of RX element buffers 12%define RX_SIZE (ETH_MAX+6) ; sizeof(RX_ELEMENT) = 1514+6 13%idefine offset 14 15struc RX_ELEMENT 16 .firstCount resw 1 ; # of bytes on 1st call 17 .secondCount resw 1 ; # of bytes on 2nd call 18 .handle resw 1 ; handle for upcall 19 ; .timeStamp resw 4 ; 64-bit RDTSC value 20 .destinAdr resb 6 ; packet destination address 21 .sourceAdr resb 6 ; packet source address 22 .protocol resw 1 ; packet protocol number 23 .rxBuffer resb ETH_MTU ; RX buffer 24endstruc 25 26;------------------------------------------- 27 28[org 0] ; assemble to .bin file 29 30_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets 31_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf 32_pktDrop dw 0,0 ; packet drop counter 33_pktTemp resb 20 ; temp work area 34_pktTxBuf resb (ETH_MAX) ; TX buffer 35_pktRxBuf resb (RX_SIZE*NUM_RX_BUF) ; RX structures 36 LAST_OFS equ $ 37 38screenSeg dw 0B800h 39newInOffset dw 0 40 41fanChars db '-\|/' 42fanIndex dw 0 43 44%macro SHOW_RX 0 45 push es 46 push bx 47 mov bx, [screenSeg] 48 mov es, bx ;; r-mode segment of colour screen 49 mov di, 158 ;; upper right corner - 1 50 mov bx, [fanIndex] 51 mov al, [fanChars+bx] ;; get write char 52 mov ah, 15 ;; and white colour 53 cld ;; Needed? 54 stosw ;; write to screen at ES:EDI 55 inc word [fanIndex] ;; update next index 56 and word [fanIndex], 3 57 pop bx 58 pop es 59%endmacro 60 61;PutTimeStamp 62; rdtsc 63; mov [si].timeStamp, eax 64; mov [si+4].timeStamp, edx 65; ret 66 67 68;------------------------------------------------------------------------ 69; 70; This routine gets called by the packet driver twice: 71; 1st time (AX=0) it requests an address where to put the packet 72; 73; 2nd time (AX=1) the packet has been copied to this location (DS:SI) 74; BX has client handle (stored in RX_ELEMENT.handle). 75; CX has # of bytes in packet on both call. They should be equal. 76; A test for equality is done by putting CX in _pktRxBuf [n].firstCount 77; and _pktRxBuf[n].secondCount, and CL on first call in 78; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive" 79; (PKTDRVR.C) 80; 81;--------------------------------------------------------------------- 82 83_PktReceiver: 84 pushf 85 cli ; no distraction wanted ! 86 push ds 87 push bx 88 mov bx, cs 89 mov ds, bx 90 mov es, bx ; ES = DS = CS or seg _DATA 91 pop bx ; restore handle 92 93 cmp ax, 0 ; first call? (AX=0) 94 jne @post ; AX=1: second call, do post process 95 96%ifdef DEBUG 97 SHOW_RX ; show that a packet is received 98%endif 99 100 cmp cx, ETH_MAX ; size OK ? 101 ja @skip ; no, too big 102 103 mov ax, [_rxInOfs] 104 add ax, RX_SIZE 105 cmp ax, LAST_OFS 106 jb @noWrap 107 mov ax, offset _pktRxBuf 108@noWrap: 109 cmp ax, [_rxOutOfs] 110 je @dump 111 mov di, [_rxInOfs] ; ES:DI -> _pktRxBuf[n] 112 mov [newInOffset], ax 113 114 mov [di], cx ; remember firstCount. 115 mov [di+4], bx ; remember handle. 116 add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr 117 pop ds 118 popf 119 retf ; far return to driver with ES:DI 120 121@dump: add word [_pktDrop+0], 1 ; discard the packet on 1st call 122 adc word [_pktDrop+2], 0 ; increment packets lost 123 124@skip: xor di, di ; return ES:DI = NIL pointer 125 xor ax, ax 126 mov es, ax 127 pop ds 128 popf 129 retf 130 131@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr 132 jz @discard ; make sure we don't use NULL-pointer 133 134 ; 135 ; push si 136 ; call bpf_filter_match ; run the filter here some day 137 ; pop si 138 ; cmp ax, 0 139 ; je @discard 140 141 mov [si-6+2], cx ; store _pktRxBuf[n].secondCount 142 mov ax, [newInOffset] 143 mov [_rxInOfs], ax ; update _pktRxBuf input offset 144 145 ; call PutTimeStamp 146 147@discard: 148 pop ds 149 popf 150 retf 151 152_pktRxEnd db 0 ; marker for end of r-mode code/data 153 154END 155 156