Rev 1519 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1519 | Rev 1529 | ||
---|---|---|---|
Line 12... | Line 12... | ||
12 | ;; GNU GENERAL PUBLIC LICENSE ;; |
12 | ;; GNU GENERAL PUBLIC LICENSE ;; |
13 | ;; Version 2, June 1991 ;; |
13 | ;; Version 2, June 1991 ;; |
14 | ;; ;; |
14 | ;; ;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 16... | Line 16... | ||
16 | 16 | ||
Line 17... | Line 17... | ||
17 | $Revision: 1519 $ |
17 | $Revision: 1529 $ |
18 | 18 | ||
19 | 19 | ||
Line 38... | Line 38... | ||
38 | ; |
38 | ; |
39 | ; UDP_init |
39 | ; UDP_init |
40 | ; |
40 | ; |
41 | ; This function resets all UDP variables |
41 | ; This function resets all UDP variables |
42 | ; |
42 | ; |
43 | ; IN: / |
- | |
44 | ; OUT: / |
- | |
45 | ; |
- | |
46 | ;----------------------------------------------------------------- |
43 | ;----------------------------------------------------------------- |
47 | align 4 |
- | |
48 | UDP_init: |
44 | macro UDP_init { |
Line 49... | Line 45... | ||
49 | 45 | ||
50 | xor eax, eax |
46 | xor eax, eax |
51 | mov edi, UDP_PACKETS_TX |
47 | mov edi, UDP_PACKETS_TX |
52 | mov ecx, 2*MAX_IP |
48 | mov ecx, 2*MAX_IP |
- | 49 | rep stosd |
|
Line -... | Line 50... | ||
- | 50 | } |
|
- | 51 | ||
- | 52 | ||
- | 53 | ||
- | 54 | ||
- | 55 | macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size, destroys: ecx, edx |
|
- | 56 | ||
- | 57 | ; Pseudoheader |
|
- | 58 | mov edx, IP_PROTO_UDP |
|
- | 59 | ||
- | 60 | add dl, [IP1+1+4] |
|
- | 61 | adc dh, [IP1+0+4] |
|
- | 62 | adc dl, [IP1+3+4] |
|
- | 63 | adc dh, [IP1+2+4] |
|
- | 64 | ||
- | 65 | adc dl, [IP2+1+8] |
|
- | 66 | adc dh, [IP2+0+8] |
|
- | 67 | adc dl, [IP2+3+8] |
|
- | 68 | adc dh, [IP2+2+8] |
|
- | 69 | ||
- | 70 | adc dl, cl ; byte[esi+UDP_Packet.Length+1] |
|
- | 71 | adc dh, ch ; byte[esi+UDP_Packet.Length+0] |
|
- | 72 | ||
- | 73 | ; Done with pseudoheader, now do real header |
|
- | 74 | adc dl, byte[esi+UDP_Packet.SourcePort+1] |
|
- | 75 | adc dh, byte[esi+UDP_Packet.SourcePort+0] |
|
- | 76 | ||
- | 77 | adc dl, byte[esi+UDP_Packet.DestinationPort+1] |
|
- | 78 | adc dh, byte[esi+UDP_Packet.DestinationPort+0] |
|
- | 79 | ||
- | 80 | adc dl, byte[esi+UDP_Packet.Length+1] |
|
- | 81 | adc dh, byte[esi+UDP_Packet.Length+0] |
|
- | 82 | ||
- | 83 | adc edx, 0 |
|
- | 84 | ||
- | 85 | ; Done with header, now do data |
|
- | 86 | push esi |
|
- | 87 | movzx ecx, [esi+UDP_Packet.Length] |
|
- | 88 | rol cx , 8 |
|
- | 89 | sub cx , UDP_Packet.Data |
|
- | 90 | add esi, UDP_Packet.Data |
|
- | 91 | ||
53 | rep stosd |
92 | call checksum_1 |
- | 93 | call checksum_2 |
|
- | 94 | pop esi |
|
- | 95 | ||
- | 96 | add [esi+UDP_Packet.Checksum], dx ; this final instruction will set or clear ZF :) |
|
Line 54... | Line 97... | ||
54 | 97 | ||
55 | ret |
98 | } |
56 | 99 | ||
57 | 100 | ||
58 | ;----------------------------------------------------------------- |
101 | ;----------------------------------------------------------------- |
59 | ; |
102 | ; |
60 | ; UDP_input: |
103 | ; UDP_input: |
61 | ; |
104 | ; |
62 | ; Called by IPv4_input, |
105 | ; Called by IPv4_input, |
63 | ; this procedure will inject the udp data diagrams in the application sockets. |
106 | ; this procedure will inject the udp data diagrams in the application sockets. |
64 | ; |
107 | ; |
65 | ; IN: Pointer to buffer in [esp] |
108 | ; IN: [esp] = Pointer to buffer |
66 | ; size of buffer in [esp+4] |
109 | ; [esp+4] = size of buffer |
67 | ; pointer to device struct in ebx |
110 | ; ebx = ptr to device struct |
68 | ; UDP Packet size in ecx |
111 | ; ecx = UDP Packet size |
69 | ; pointer to UDP Packet in edx |
112 | ; edx = ptr to UDP header |
70 | ; |
113 | ; |
Line 78... | Line 121... | ||
78 | UDP_input: |
121 | UDP_input: |
Line 79... | Line 122... | ||
79 | 122 | ||
Line 80... | Line 123... | ||
80 | DEBUGF 1,"UDP_input, size:%u\n", ecx |
123 | DEBUGF 1,"UDP_input, size:%u\n", ecx |
81 | 124 | ||
82 | ; First validate, checksum: |
125 | ; First validate, checksum: |
83 | cmp [edx + UDP_Packet.Checksum], 0 |
- | |
84 | jz .no_checksum |
126 | neg [esi+UDP_Packet.Checksum] ; substract chechksum from 0 |
Line 85... | Line 127... | ||
85 | 127 | jz .no_checksum ; if checksum is zero, it is considered valid and we continue processing |
|
- | 128 | ; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct |
|
86 | xchg edi, esi ; save ipv4 source address to edi so we can use it later |
129 | |
87 | 130 | push edx |
|
- | 131 | push edi |
|
- | 132 | push esi |
|
88 | push edx |
133 | mov esi, edx |
89 | push esi edi |
134 | UDP_checksum (esp), (esp+4) |
90 | mov esi, edx |
- | |
91 | call UDP_checksum ; this destroys edx, ecx and esi (but not edi...) |
- | |
92 | pop edx |
135 | pop edi |
Line 93... | Line 136... | ||
93 | 136 | pop esi ; we dont need it, but it is smaller then add esp, 4 |
|
94 | cmp [edx + UDP_Packet.Checksum], 0 |
137 | pop edx |
Line 166... | Line 209... | ||
166 | 209 | ||
Line 167... | Line 210... | ||
167 | .checksum_mismatch: |
210 | .checksum_mismatch: |
Line 168... | Line -... | ||
168 | - | ||
169 | DEBUGF 2,"UDP_Handler - checksum mismatch\n" |
- | |
170 | - | ||
171 | ; mov esi, edx |
- | |
172 | ; @@: ; |
- | |
173 | ; lodsb ; |
- | |
174 | ; DEBUGF 2,"%x ", eax:2 ; |
211 | |
175 | ; loop @r ; |
212 | DEBUGF 2,"UDP_Handler - checksum mismatch\n" |
176 | 213 | ||
177 | .dump: |
214 | .dump: |
Line 205... | Line 242... | ||
205 | rol edx, 16 |
242 | rol edx, 16 |
206 | mov dx, [eax + UDP_SOCKET.LocalPort] |
243 | mov dx, [eax + UDP_SOCKET.LocalPort] |
207 | DEBUGF 1,"local port: %u\n", dx |
244 | DEBUGF 1,"local port: %u\n", dx |
208 | rol dx, 8 |
245 | rol dx, 8 |
Line 209... | Line -... | ||
209 | - | ||
210 | 246 | ||
211 | mov ebx, [eax + IP_SOCKET.LocalIP] |
247 | mov ebx, [eax + IP_SOCKET.LocalIP] |
Line 212... | Line 248... | ||
212 | mov eax, [eax + IP_SOCKET.RemoteIP] |
248 | mov eax, [eax + IP_SOCKET.RemoteIP] |
213 | 249 | ||
214 | mov di , IP_PROTO_UDP |
250 | mov di, IP_PROTO_UDP shl 8 + 128 |
Line 215... | Line 251... | ||
215 | sub esp, 8 ; Data ptr and data size will be placed here |
251 | sub esp, 8 ; Data ptr and data size will be placed here |
216 | add ecx, UDP_Packet.Data |
- | |
217 | 252 | add ecx, UDP_Packet.Data |
|
218 | ;;; TODO: fragment id |
253 | |
219 | 254 | ;;; TODO: fragment id |
|
Line 220... | Line 255... | ||
220 | push edx esi |
255 | push edx esi |
221 | call IPv4_create_packet |
256 | call IPv4_output |
Line 222... | Line -... | ||
222 | jz .fail |
- | |
223 | 257 | jz .fail |
|
224 | mov [esp + 8], eax ; pointer to buffer start |
258 | |
Line 225... | Line 259... | ||
225 | mov [esp + 8 + 4], edx ; buffer size |
259 | mov [esp + 8], eax ; pointer to buffer start |
226 | 260 | mov [esp + 8 + 4], edx ; buffer size |
|
227 | rol cx, 8 |
261 | |
228 | mov [edi + UDP_Packet.Length], cx |
262 | mov [edi + UDP_Packet.Length], cx |
Line 238... | Line 272... | ||
238 | and ecx, 3 |
272 | and ecx, 3 |
239 | rep movsb |
273 | rep movsb |
240 | pop ecx edi |
274 | pop ecx edi |
Line 241... | Line 275... | ||
241 | 275 | ||
242 | pop dword [edi + UDP_Packet.SourcePort] |
- | |
Line 243... | Line 276... | ||
243 | mov [edi + UDP_Packet.Checksum], 0 ; set it to zero, to calculate checksum |
276 | pop dword [edi + UDP_Packet.SourcePort] |
244 | 277 | ||
- | 278 | ; Checksum |
|
245 | ; Checksum |
279 | mov esi, edi |
246 | mov esi, edi |
- | |
247 | pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. |
- | |
Line 248... | Line 280... | ||
248 | pushd [edi-8] ; source address |
280 | mov [edi + UDP_Packet.Checksum], 0 |
Line 249... | Line 281... | ||
249 | call UDP_checksum |
281 | UDP_checksum (edi-4), (edi-8) ; TODO: fix this, IPv4 packet could have options.. |
Line 250... | Line 282... | ||
250 | 282 | ||
251 | inc [UDP_PACKETS_TX] |
283 | inc [UDP_PACKETS_TX] |
- | 284 | ||
252 | 285 | DEBUGF 1,"Sending UDP Packet to device %x\n", ebx |
|
- | 286 | ||
253 | DEBUGF 1,"Sending UDP Packet to device %x\n", ebx |
287 | call [ebx + NET_DEVICE.transmit] |
- | 288 | ret |
|
254 | 289 | ||
Line 255... | Line -... | ||
255 | call [ebx + NET_DEVICE.transmit] |
- | |
256 | ret |
- | |
257 | .fail: |
- | |
258 | add esp, 8+8 |
- | |
259 | ret |
- | |
260 | - | ||
261 | - | ||
262 | - | ||
263 | - | ||
264 | ;----------------------------------------------------------------- |
- | |
265 | ; |
- | |
266 | ; UDP_checksum |
- | |
267 | ; |
- | |
268 | ; This is the fast procedure to create or check a UDP header |
- | |
269 | ; - To create a new checksum, the checksum field must be set to 0 before computation |
- | |
270 | ; - To check an existing checksum, leave the checksum as is, |
- | |
271 | ; and it will be 0 after this procedure, if it was correct |
- | |
272 | ; |
- | |
273 | ; IN: push source ip |
- | |
274 | ; push dest ip |
- | |
275 | ; esi = packet ptr |
- | |
276 | ; |
- | |
277 | ; OUT: checksum is filled in in packet! (but also in dx) |
- | |
278 | ; |
- | |
279 | ;----------------------------------------------------------------- |
- | |
280 | - | ||
281 | align 4 |
- | |
282 | UDP_checksum: |
- | |
283 | - | ||
284 | ; Pseudoheader |
- | |
285 | mov edx, IP_PROTO_UDP ; NO shl 8 here ! (it took me ages to figure this one out) |
- | |
286 | - | ||
287 | add dl, [esp+1+4] |
- | |
288 | adc dh, [esp+0+4] |
- | |
289 | adc dl, [esp+3+4] |
- | |
290 | adc dh, [esp+2+4] |
- | |
291 | - | ||
292 | adc dl, [esp+1+8] |
- | |
293 | adc dh, [esp+0+8] |
- | |
294 | adc dl, [esp+3+8] |
- | |
295 | adc dh, [esp+2+8] |
- | |
296 | - | ||
297 | - | ||
298 | adc dl, cl ; byte[esi+UDP_Packet.Length+1] |
- | |
299 | adc dh, ch ; byte[esi+UDP_Packet.Length+0] |
- | |
300 | - | ||
301 | ; Done with pseudoheader, now do real header |
- | |
302 | adc dl, byte[esi+UDP_Packet.SourcePort+1] |
- | |
303 | adc dh, byte[esi+UDP_Packet.SourcePort+0] |
- | |
304 | - | ||
305 | adc dl, byte[esi+UDP_Packet.DestinationPort+1] |
- | |
306 | adc dh, byte[esi+UDP_Packet.DestinationPort+0] |
- | |
307 | - | ||
308 | adc dl, byte[esi+UDP_Packet.Length+1] |
- | |
309 | adc dh, byte[esi+UDP_Packet.Length+0] |
- | |
310 | - | ||
311 | adc edx, 0 |
- | |
312 | - | ||
313 | ; Done with header, now do data |
- | |
314 | push esi |
- | |
315 | movzx ecx, [esi+UDP_Packet.Length] |
- | |
316 | rol cx , 8 |
- | |
317 | sub cx , UDP_Packet.Data |
- | |
318 | add esi, UDP_Packet.Data |
- | |
319 | - | ||
320 | call checksum_1 |
- | |
321 | call checksum_2 |
- | |
322 | pop esi |
- | |
323 | - | ||
324 | neg [esi+UDP_Packet.Checksum] ; zero will stay zero so we just get the checksum |
290 | .fail: |
325 | add [esi+UDP_Packet.Checksum], dx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :) |
291 | DEBUGF 1,"UDP_output: failed\n" |
326 | 292 | add esp, 4+4+8 |
|
327 | ret 8 |
293 | xor eax, eax |
328 | 294 | ret |