Blame view

libs/libpcap-1.9.0/msdos/pkt_rx0.asm 5.95 KB
fee2cbd6   amoreau   ajout des librairies
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
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