diff options
Diffstat (limited to 'lib/libpcap/libpcap/msdos/pkt_rx0.asm')
-rw-r--r-- | lib/libpcap/libpcap/msdos/pkt_rx0.asm | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/lib/libpcap/libpcap/msdos/pkt_rx0.asm b/lib/libpcap/libpcap/msdos/pkt_rx0.asm new file mode 100644 index 0000000..d604fa1 --- /dev/null +++ b/lib/libpcap/libpcap/msdos/pkt_rx0.asm @@ -0,0 +1,197 @@ +PAGE 60,132 +NAME PKT_RX + +ifdef ??version ; using TASM + masm + jumps +endif + +PUBLIC _pktDrop, _pktRxBuf, _pktTxBuf, _pktTemp +PUBLIC _rxOutOfs, _rxInOfs, _PktReceiver, _pktRxEnd + +; +; these sizes MUST be equal to the sizes in PKTDRVR.H +; + +RX_BUF_SIZE = 1500 ; max message size on Ethernet +TX_BUF_SIZE = 1500 + +ifdef DOSX + .386 + NUM_RX_BUF = 32 ; # of RX element buffers + _TEXT SEGMENT PUBLIC DWORD USE16 'CODE' + _TEXT ENDS + _DATA SEGMENT PUBLIC DWORD USE16 'CODE' + _DATA ENDS + D_SEG EQU <_TEXT SEGMENT> + D_END EQU <_TEXT ENDS> + ASSUME CS:_TEXT,DS:_TEXT +else + .286 + NUM_RX_BUF = 10 + _TEXT SEGMENT PUBLIC DWORD 'CODE' + _TEXT ENDS + _DATA SEGMENT PUBLIC DWORD 'DATA' + _DATA ENDS + D_SEG EQU <_DATA SEGMENT> + D_END EQU <_DATA ENDS> + ASSUME CS:_TEXT,DS:_DATA +endif + +;------------------------------------------- + +D_SEG + +RX_ELEMENT STRUC + firstCount dw 0 ; # of bytes on 1st call + secondCount dw 0 ; # of bytes on 2nd call + handle dw 0 ; handle for upcall + destinAdr db 6 dup (0) ; packet destination address + sourceAdr db 6 dup (0) ; packet source address + protocol dw 0 ; packet protocol number + rxBuffer db RX_BUF_SIZE dup (0) ; RX buffer +ENDS + align 4 +_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets +_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf +_pktDrop dw 0,0 ; packet drop counter +_pktTemp db 20 dup (0) ; temp work area +_pktTxBuf db (TX_BUF_SIZE+14) dup (0) ; TX buffer +_pktRxBuf RX_ELEMENT NUM_RX_BUF dup (<>) ; RX structures + LAST_OFS = offset $ + + screenSeg dw 0B800h + newInOffset dw 0 + + fanChars db '-\|/' + fanIndex dw 0 + +D_END + +_TEXT SEGMENT + + +SHOW_RX MACRO + push es + push bx + mov bx, screenSeg + mov es, bx ;; r-mode segment of colour screen + mov di, 158 ;; upper right corner - 1 + mov bx, fanIndex + mov al, fanChars[bx] ;; get write char + mov ah, 15 ;; and white colour + stosw ;; write to screen at ES:EDI + inc fanIndex ;; update next index + and fanIndex, 3 + pop bx + pop es +ENDM + +;------------------------------------------------------------------------ +; +; This macro return ES:DI to tail of Rx queue + +ENQUEUE MACRO + LOCAL @noWrap + mov ax, _rxInOfs ;; DI = current in-offset + add ax, SIZE RX_ELEMENT ;; point to next _pktRxBuf buffer + cmp ax, LAST_OFS ;; pointing past last ? + jb @noWrap ;; no - jump + lea ax, _pktRxBuf ;; yes, point to 1st buffer + align 4 +@noWrap: cmp ax, _rxOutOfs ;; in-ofs = out-ofs ? + je @dump ;; yes, queue is full + mov di, _rxInOfs ;; ES:DI -> buffer at queue input + mov newInOffset, ax ;; remember new input offset + + ;; NOTE. rxInOfs is updated after the packet has been copied + ;; to ES:DI (= DS:SI on 2nd call) by the packet driver + +ENDM + +;------------------------------------------------------------------------ +; +; This routine gets called by the packet driver twice: +; 1st time (AX=0) it requests an address where to put the packet +; +; 2nd time (AX=1) the packet has been copied to this location (DS:SI) +; BX has client handle (stored in RX_ELEMENT.handle). +; CX has # of bytes in packet on both call. They should be equal. +; +; A test for equality is done by putting CX in _pktRxBuf [n].firstCount +; and _pktRxBuf[n].secondCount, and CL on first call in +; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive" +; (PKTDRVR.C) +; +;--------------------------------------------------------------------- + +_PktReceiver: + pushf + cli ; no distraction wanted ! + push ds + push bx +ifdef DOSX + mov bx, cs +else + mov bx, SEG _DATA +endif + mov ds, bx + mov es, bx ; ES = DS = CS or seg _DATA + pop bx ; restore handle + + cmp ax, 0 ; first call? (AX=0) + jne @post ; AX=1: second call, do post process + +ifdef DEBUG + SHOW_RX ; show that a packet is received +endif + cmp cx, RX_BUF_SIZE+14 ; size OK ? + ja @skip ; no, packet to large for us + + ENQUEUE ; ES:DI -> _pktRxBuf[n] + + mov [di].firstCount, cx ; remember the first count. + mov [di].handle, bx ; remember the handle. + add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr + pop ds + popf + retf ; far return to driver with ES:DI + + align 4 +@dump: inc _pktDrop[0] ; discard the packet on 1st call + adc _pktDrop[2], 0 ; increment packets lost + +@skip: xor di, di ; return ES:DI = NIL pointer + xor ax, ax + mov es, ax + pop ds + popf + retf + + align 4 +@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr + jz @discard ; make sure we don't use NULL-pointer + + sub si, 6 ; DS:SI -> _pktRxBuf[n].destinAdr + ; + ; push si + ; push [si].firstCount + ; call bpf_filter_match ; run the filter here some day? + ; add sp, 4 + ; cmp ax, 0 + ; je @discard + + mov [si].secondCount, cx + mov ax, newInOffset + mov _rxInOfs, ax ; update _pktRxBuf input offset + + align 4 +@discard:pop ds + popf + retf + +_pktRxEnd db 0 ; marker for end of r-mode code/data + +_TEXT ENDS + +END |