]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libpcap/msdos/pkt_rx0.asm
MFV r333789: libpcap 1.9.0 (pre-release)
[FreeBSD/FreeBSD.git] / contrib / 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