]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libpcap/msdos/pkt_rx1.s
MFV r333789: libpcap 1.9.0 (pre-release)
[FreeBSD/FreeBSD.git] / contrib / libpcap / msdos / pkt_rx1.s
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
15 struc 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
24 endstruc
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
38 screenSeg   dw  0B800h
39 newInOffset dw  0
40
41 fanChars    db  '-\|/'
42 fanIndex    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
154 END
155