]> The Tcpdump Group git mirrors - libpcap/blob - msdos/pkt_rx0.asm
set version to rc2
[libpcap] / msdos / pkt_rx0.asm
1 PAGE 60,132
2 NAME PKT_RX
3
4 ifdef ??version ; using TASM
5 masm
6 jumps
7 endif
8
9 PUBLIC _pktDrop, _pktRxBuf, _pktTxBuf, _pktTemp
10 PUBLIC _rxOutOfs, _rxInOfs, _PktReceiver, _pktRxEnd
11
12 ;
13 ; these sizes MUST be equal to the sizes in PKTDRVR.H
14 ;
15
16 RX_BUF_SIZE = 1500 ; max message size on Ethernet
17 TX_BUF_SIZE = 1500
18
19 ifdef DOSX
20 .386
21 NUM_RX_BUF = 32 ; # of RX element buffers
22 _TEXT SEGMENT PUBLIC DWORD USE16 'CODE'
23 _TEXT ENDS
24 _DATA SEGMENT PUBLIC DWORD USE16 'CODE'
25 _DATA ENDS
26 D_SEG EQU <_TEXT SEGMENT>
27 D_END EQU <_TEXT ENDS>
28 ASSUME CS:_TEXT,DS:_TEXT
29 else
30 .286
31 NUM_RX_BUF = 10
32 _TEXT SEGMENT PUBLIC DWORD 'CODE'
33 _TEXT ENDS
34 _DATA SEGMENT PUBLIC DWORD 'DATA'
35 _DATA ENDS
36 D_SEG EQU <_DATA SEGMENT>
37 D_END EQU <_DATA ENDS>
38 ASSUME CS:_TEXT,DS:_DATA
39 endif
40
41 ;-------------------------------------------
42
43 D_SEG
44
45 RX_ELEMENT STRUC
46 firstCount dw 0 ; # of bytes on 1st call
47 secondCount dw 0 ; # of bytes on 2nd call
48 handle dw 0 ; handle for upcall
49 destinAdr db 6 dup (0) ; packet destination address
50 sourceAdr db 6 dup (0) ; packet source address
51 protocol dw 0 ; packet protocol number
52 rxBuffer db RX_BUF_SIZE dup (0) ; RX buffer
53 ENDS
54 align 4
55 _rxOutOfs dw offset _pktRxBuf ; ring buffer offsets
56 _rxInOfs dw offset _pktRxBuf ; into _pktRxBuf
57 _pktDrop dw 0,0 ; packet drop counter
58 _pktTemp db 20 dup (0) ; temp work area
59 _pktTxBuf db (TX_BUF_SIZE+14) dup (0) ; TX buffer
60 _pktRxBuf RX_ELEMENT NUM_RX_BUF dup (<>) ; RX structures
61 LAST_OFS = offset $
62
63 screenSeg dw 0B800h
64 newInOffset dw 0
65
66 fanChars db '-\|/'
67 fanIndex dw 0
68
69 D_END
70
71 _TEXT SEGMENT
72
73
74 SHOW_RX MACRO
75 push es
76 push bx
77 mov bx, screenSeg
78 mov es, bx ;; r-mode segment of colour screen
79 mov di, 158 ;; upper right corner - 1
80 mov bx, fanIndex
81 mov al, fanChars[bx] ;; get write char
82 mov ah, 15 ;; and white colour
83 stosw ;; write to screen at ES:EDI
84 inc fanIndex ;; update next index
85 and fanIndex, 3
86 pop bx
87 pop es
88 ENDM
89
90 ;------------------------------------------------------------------------
91 ;
92 ; This macro return ES:DI to tail of Rx queue
93
94 ENQUEUE MACRO
95 LOCAL @noWrap
96 mov ax, _rxInOfs ;; DI = current in-offset
97 add ax, SIZE RX_ELEMENT ;; point to next _pktRxBuf buffer
98 cmp ax, LAST_OFS ;; pointing past last ?
99 jb @noWrap ;; no - jump
100 lea ax, _pktRxBuf ;; yes, point to 1st buffer
101 align 4
102 @noWrap: cmp ax, _rxOutOfs ;; in-ofs = out-ofs ?
103 je @dump ;; yes, queue is full
104 mov di, _rxInOfs ;; ES:DI -> buffer at queue input
105 mov newInOffset, ax ;; remember new input offset
106
107 ;; NOTE. rxInOfs is updated after the packet has been copied
108 ;; to ES:DI (= DS:SI on 2nd call) by the packet driver
109
110 ENDM
111
112 ;------------------------------------------------------------------------
113 ;
114 ; This routine gets called by the packet driver twice:
115 ; 1st time (AX=0) it requests an address where to put the packet
116 ;
117 ; 2nd time (AX=1) the packet has been copied to this location (DS:SI)
118 ; BX has client handle (stored in RX_ELEMENT.handle).
119 ; CX has # of bytes in packet on both call. They should be equal.
120 ;
121 ; A test for equality is done by putting CX in _pktRxBuf [n].firstCount
122 ; and _pktRxBuf[n].secondCount, and CL on first call in
123 ; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"
124 ; (PKTDRVR.C)
125 ;
126 ;---------------------------------------------------------------------
127
128 _PktReceiver:
129 pushf
130 cli ; no distraction wanted !
131 push ds
132 push bx
133 ifdef DOSX
134 mov bx, cs
135 else
136 mov bx, SEG _DATA
137 endif
138 mov ds, bx
139 mov es, bx ; ES = DS = CS or seg _DATA
140 pop bx ; restore handle
141
142 cmp ax, 0 ; first call? (AX=0)
143 jne @post ; AX=1: second call, do post process
144
145 ifdef DEBUG
146 SHOW_RX ; show that a packet is received
147 endif
148 cmp cx, RX_BUF_SIZE+14 ; size OK ?
149 ja @skip ; no, packet to large for us
150
151 ENQUEUE ; ES:DI -> _pktRxBuf[n]
152
153 mov [di].firstCount, cx ; remember the first count.
154 mov [di].handle, bx ; remember the handle.
155 add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr
156 pop ds
157 popf
158 retf ; far return to driver with ES:DI
159
160 align 4
161 @dump: inc _pktDrop[0] ; discard the packet on 1st call
162 adc _pktDrop[2], 0 ; increment packets lost
163
164 @skip: xor di, di ; return ES:DI = NIL pointer
165 xor ax, ax
166 mov es, ax
167 pop ds
168 popf
169 retf
170
171 align 4
172 @post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr
173 jz @discard ; make sure we don't use NULL-pointer
174
175 sub si, 6 ; DS:SI -> _pktRxBuf[n].destinAdr
176 ;
177 ; push si
178 ; push [si].firstCount
179 ; call bpf_filter_match ; run the filter here some day?
180 ; add sp, 4
181 ; cmp ax, 0
182 ; je @discard
183
184 mov [si].secondCount, cx
185 mov ax, newInOffset
186 mov _rxInOfs, ax ; update _pktRxBuf input offset
187
188 align 4
189 @discard:pop ds
190 popf
191 retf
192
193 _pktRxEnd db 0 ; marker for end of r-mode code/data
194
195 _TEXT ENDS
196
197 END