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 14... | Line 14... | ||
14 | ;; GNU GENERAL PUBLIC LICENSE ;; |
14 | ;; GNU GENERAL PUBLIC LICENSE ;; |
15 | ;; Version 2, June 1991 ;; |
15 | ;; Version 2, June 1991 ;; |
16 | ;; ;; |
16 | ;; ;; |
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 18... | Line 18... | ||
18 | 18 | ||
Line 19... | Line 19... | ||
19 | $Revision: 1519 $ |
19 | $Revision: 1529 $ |
20 | 20 | ||
21 | ; Socket states |
21 | ; Socket states |
22 | TCB_CLOSED equ 0 |
22 | TCB_CLOSED equ 0 |
Line 71... | Line 71... | ||
71 | 71 | ||
72 | ; timer constants |
72 | ; timer constants |
73 | TCP_max_rxtshift equ 12 ; max retransmissions waiting for ACK |
73 | TCP_max_rxtshift equ 12 ; max retransmissions waiting for ACK |
Line -... | Line 74... | ||
- | 74 | TCP_max_keepcnt equ 8 ; max keepalive probes |
|
- | 75 | ||
- | 76 | ; |
|
Line 74... | Line 77... | ||
74 | TCP_max_keepcnt equ 8 ; max keepalive probes |
77 | TCP_max_winshift equ 14 |
75 | 78 | TCP_max_win equ 65535 |
|
76 | 79 | ||
77 | struct TCP_segment |
80 | struct TCP_segment |
Line 115... | Line 118... | ||
115 | ; |
118 | ; |
116 | ; TCP_init |
119 | ; TCP_init |
117 | ; |
120 | ; |
118 | ; This function resets all TCP variables |
121 | ; This function resets all TCP variables |
119 | ; |
122 | ; |
120 | ; IN: / |
- | |
121 | ; OUT: / |
- | |
122 | ; |
- | |
123 | ;----------------------------------------------------------------- |
123 | ;----------------------------------------------------------------- |
124 | align 4 |
- | |
125 | TCP_init: |
124 | macro TCP_init { |
Line 126... | Line 125... | ||
126 | 125 | ||
127 | xor eax, eax |
126 | xor eax, eax |
128 | mov edi, TCP_segments_tx |
127 | mov edi, TCP_segments_tx |
129 | mov ecx, (6*IP_MAX_INTERFACES) |
128 | mov ecx, (6*IP_MAX_INTERFACES) |
Line -... | Line 129... | ||
- | 129 | rep stosd |
|
130 | rep stosd |
130 | |
Line 131... | Line 131... | ||
131 | 131 | pseudo_random eax |
|
Line 132... | Line 132... | ||
132 | mov [TCP_sequence_num], 1 |
132 | mov [TCP_sequence_num], eax |
133 | 133 | ||
134 | ret |
134 | } |
135 | 135 | ||
- | 136 | ||
- | 137 | ;---------------------- |
|
136 | 138 | ; |
|
137 | ;---------------------- |
139 | ; |
Line 138... | Line 140... | ||
138 | ; |
140 | ;---------------------- |
139 | ; |
141 | macro TCP_timer_160ms { |
140 | ;---------------------- |
142 | |
141 | align 4 |
143 | local .loop |
Line 154... | Line 156... | ||
154 | jnz .loop |
156 | jnz .loop |
Line 155... | Line 157... | ||
155 | 157 | ||
Line 156... | Line 158... | ||
156 | DEBUGF 1,"TCP ack for socket %x expired, time to piggyback!\n", eax |
158 | DEBUGF 1,"TCP ack for socket %x expired, time to piggyback!\n", eax |
157 | 159 | ||
158 | push eax |
160 | push eax |
Line 159... | Line 161... | ||
159 | call TCP_respond |
161 | call TCP_respond_socket |
Line 160... | Line 162... | ||
160 | pop eax |
162 | pop eax |
Line 161... | Line 163... | ||
161 | 163 | ||
Line 162... | Line 164... | ||
162 | jmp .loop |
164 | jmp .loop |
163 | 165 | ||
164 | .exit: |
166 | .exit: |
165 | 167 | ||
- | 168 | } |
|
- | 169 | ||
166 | ret |
170 | |
167 | 171 | ;----------------------------------------------------------------- |
|
Line 168... | Line 172... | ||
168 | 172 | ; |
|
Line 169... | Line 173... | ||
169 | ;----------------------------------------------------------------- |
173 | ; |
Line 188... | Line 192... | ||
188 | jz .exit |
192 | jz .exit |
Line 189... | Line 193... | ||
189 | 193 | ||
190 | cmp [eax + SOCKET.Type], IP_PROTO_TCP |
194 | cmp [eax + SOCKET.Type], IP_PROTO_TCP |
Line -... | Line 195... | ||
- | 195 | jne .loop |
|
191 | jne .loop |
196 | |
192 | 197 | inc [eax + TCP_SOCKET.t_idle] |
|
Line 193... | Line 198... | ||
193 | dec [eax + TCP_SOCKET.timer_retransmission] |
198 | dec [eax + TCP_SOCKET.timer_retransmission] |
Line 219... | Line 224... | ||
219 | 224 | ||
Line 220... | Line 225... | ||
220 | DEBUGF 1,"socket %x: persist timer expired\n", eax |
225 | DEBUGF 1,"socket %x: persist timer expired\n", eax |
221 | 226 | ||
- | 227 | jmp .loop |
|
- | 228 | .exit: |
|
- | 229 | } |
|
- | 230 | ||
- | 231 | ||
- | 232 | ||
- | 233 | ||
- | 234 | macro TCP_checksum IP1, IP2 { |
|
- | 235 | ||
- | 236 | ;------------- |
|
- | 237 | ; Pseudoheader |
|
- | 238 | ||
- | 239 | ; protocol type |
|
- | 240 | mov edx, IP_PROTO_TCP |
|
- | 241 | ||
- | 242 | ; source address |
|
- | 243 | add dl, byte [IP1+1+4] |
|
- | 244 | adc dh, byte [IP1+0+4] |
|
- | 245 | adc dl, byte [IP1+3+4] |
|
- | 246 | adc dh, byte [IP1+2+4] |
|
- | 247 | ||
- | 248 | ; destination address |
|
- | 249 | adc dl, byte [IP2+1+8] |
|
- | 250 | adc dh, byte [IP2+0+8] |
|
- | 251 | adc dl, byte [IP2+3+8] |
|
- | 252 | adc dh, byte [IP2+2+8] |
|
- | 253 | ||
- | 254 | ; size |
|
- | 255 | adc dl, cl |
|
- | 256 | adc dh, ch |
|
- | 257 | ||
- | 258 | ;--------------------- |
|
- | 259 | ; Real header and data |
|
- | 260 | ||
- | 261 | push esi |
|
222 | jmp .loop |
262 | call checksum_1 |
- | 263 | call checksum_2 |
|
- | 264 | pop esi |
|
- | 265 | ||
Line 223... | Line 266... | ||
223 | .exit: |
266 | } ; returns in dx only |
224 | ret |
267 | |
225 | 268 | ||
Line 241... | Line 284... | ||
241 | ; |
284 | ; |
242 | ;----------------------------------------------------------------- |
285 | ;----------------------------------------------------------------- |
243 | align 4 |
286 | align 4 |
244 | TCP_input: |
287 | TCP_input: |
Line 245... | Line 288... | ||
245 | 288 | ||
246 | DEBUGF 1,"TCP_input\n" |
- | |
247 | 289 | DEBUGF 1,"TCP_input size=%u\n", ecx |
|
Line 248... | Line 290... | ||
248 | ; Offset must be greater than or equal to the size of the standard TCP header (20) and less than or equal to the TCP length. |
290 | ; Offset must be greater than or equal to the size of the standard TCP header (20) and less than or equal to the TCP length. |
249 | 291 | ||
250 | movzx eax, [edx + TCP_segment.DataOffset] |
292 | movzx eax, [edx + TCP_segment.DataOffset] |
Line 251... | Line 293... | ||
251 | and eax, 0xf0 |
293 | and eax, 0xf0 |
Line 252... | Line 294... | ||
252 | shr al , 2 |
294 | shr al, 2 |
253 | 295 | ||
Line 254... | Line -... | ||
254 | DEBUGF 1,"data offset: %u\n", eax |
- | |
255 | - | ||
256 | cmp eax, 20 |
- | |
257 | jl .drop |
296 | DEBUGF 1,"headersize=%u\n", eax |
258 | 297 | ||
Line 259... | Line 298... | ||
259 | cmp eax, ecx |
298 | cmp eax, 20 |
260 | jg .drop |
- | |
261 | 299 | jl .drop |
|
- | 300 | ||
262 | ;------------------------------- |
301 | ;------------------------------- |
263 | ; Now, re-calculate the checksum |
302 | ; Now, re-calculate the checksum |
- | 303 | ||
264 | 304 | push eax ecx edx |
|
265 | push eax edx ebx |
- | |
266 | 305 | pushw [edx + TCP_segment.Checksum] |
|
267 | push edi |
306 | mov [edx + TCP_segment.Checksum], 0 |
268 | push esi |
307 | push esi edi |
269 | mov esi, edx |
308 | mov esi, edx |
Line 270... | Line 309... | ||
270 | call TCP_checksum ; this destroys edx, ecx and esi (but not edi! :) |
309 | TCP_checksum |
Line -... | Line 310... | ||
- | 310 | pop esi edi ; yes, swap them (we dont need dest addr) |
|
- | 311 | pop cx ; previous checksum |
|
- | 312 | cmp cx, dx |
|
271 | 313 | pop edx ecx esi |
|
272 | pop ebx edx eax |
314 | jnz .drop |
Line 273... | Line 315... | ||
273 | 315 | ||
274 | cmp [edx + TCP_segment.Checksum], 0 |
316 | DEBUGF 1,"Checksum is correct\n" |
275 | jnz .drop |
317 | |
Line 276... | Line 318... | ||
276 | 318 | sub ecx, esi ; update packet size |
|
277 | DEBUGF 1,"Checksum is correct\n" |
319 | jl .drop |
Line 278... | Line 320... | ||
278 | 320 | ||
279 | ;----------------------------------------------------------------------------------------- |
321 | ;----------------------------------------------------------------------------------------- |
280 | ; Check if this packet has a timestamp option (We do it here so we can process it quickly) |
322 | ; Check if this packet has a timestamp option (We do it here so we can process it quickly) |
Line 293... | Line 335... | ||
293 | cmp dword [edx + TCP_segment.Data], 0x0101080a ; Timestamp header |
335 | cmp dword [edx + TCP_segment.Data], 0x0101080a ; Timestamp header |
294 | jne .no_timestamp |
336 | jne .no_timestamp |
Line 295... | Line 337... | ||
295 | 337 | ||
Line 296... | Line 338... | ||
296 | DEBUGF 1,"timestamp ok\n" |
338 | DEBUGF 1,"timestamp ok\n" |
297 | 339 | ||
Line 298... | Line -... | ||
298 | ; TODO: Parse the options |
- | |
299 | ; TODO: Set a Bit in the TCP to tell all options are parsed |
- | |
300 | 340 | ; TODO: Parse the option |
|
Line 301... | Line 341... | ||
301 | ret |
341 | ; TODO: Set a Bit in the TCP to tell all options are parsed |
302 | 342 | ||
Line 303... | Line 343... | ||
303 | .no_timestamp: |
343 | .no_timestamp: |
304 | 344 | ||
Line 305... | Line 345... | ||
305 | ;------------------------------------------- |
345 | ;------------------------------------------- |
306 | ; Convert Big-endian values to little endian |
346 | ; Convert Big-endian values to little endian |
- | 347 | ||
- | 348 | ntohld [edx + TCP_segment.SequenceNumber] |
|
Line 307... | Line 349... | ||
307 | 349 | ntohld [edx + TCP_segment.AckNumber] |
|
308 | ntohld [edx + TCP_segment.SequenceNumber] |
350 | |
Line 309... | Line 351... | ||
309 | ntohld [edx + TCP_segment.AckNumber] |
351 | ntohlw [edx + TCP_segment.Window] |
Line 331... | Line 373... | ||
331 | mov ax, [edx + TCP_segment.DestinationPort] |
373 | mov ax, [edx + TCP_segment.DestinationPort] |
332 | cmp [ebx + TCP_SOCKET.LocalPort], ax |
374 | cmp [ebx + TCP_SOCKET.LocalPort], ax |
333 | jne .socket_loop |
375 | jne .socket_loop |
Line 334... | Line 376... | ||
334 | 376 | ||
335 | mov eax, [ebx + IP_SOCKET.RemoteIP] |
377 | mov eax, [ebx + IP_SOCKET.RemoteIP] |
336 | cmp eax, esi |
378 | cmp eax, edi ; sender IP |
337 | je @f |
379 | je @f |
338 | test eax, eax |
380 | test eax, eax |
339 | jnz .socket_loop |
381 | jnz .socket_loop |
Line 350... | Line 392... | ||
350 | ; ebx now contains the pointer to the socket |
392 | ; ebx now contains the pointer to the socket |
Line 351... | Line 393... | ||
351 | 393 | ||
352 | ;---------------------------- |
394 | ;---------------------------- |
Line 353... | Line 395... | ||
353 | ; Check if socket isnt closed |
395 | ; Check if socket isnt closed |
354 | 396 | ||
Line 355... | Line 397... | ||
355 | cmp [TCP_SOCKET.t_state], TCB_CLOSED |
397 | cmp [ebx + TCP_SOCKET.t_state], TCB_CLOSED |
356 | je .drop |
398 | je .drop |
Line 357... | Line 399... | ||
357 | 399 | ||
358 | ;---------------- |
400 | ;---------------- |
359 | ; Lock the socket |
401 | ; Lock the socket |
360 | - | ||
361 | add ebx, SOCKET.lock ; TODO: figure out if we should lock now already |
- | |
362 | call wait_mutex |
- | |
Line 363... | Line 402... | ||
363 | sub ebx, SOCKET.lock |
402 | |
364 | - | ||
Line -... | Line 403... | ||
- | 403 | ;; add ebx, SOCKET.lock ; TODO: figure out if we should lock now already |
|
365 | ;--------------------------------------- |
404 | ;; call wait_mutex |
366 | ; unscale the window into a 32 bit value ;;;;;; |
- | |
Line -... | Line 405... | ||
- | 405 | ;; sub ebx, SOCKET.lock |
|
- | 406 | ||
367 | 407 | DEBUGF 1,"Socket locked\n" |
|
368 | movzx eax, [edx + TCP_segment.Window] |
408 | |
- | 409 | ;---------------------------------------------------------------------------------------- |
|
Line 369... | Line 410... | ||
369 | xchg al, ah |
410 | ; unscale the window into a 32 bit value (notice that SND_SCALE must be initialised to 0) |
Line 370... | Line 411... | ||
370 | 411 | ||
371 | test [edx + TCP_segment.Flags], TH_SYN |
412 | movzx eax, [edx + TCP_segment.Window] |
Line 372... | Line 413... | ||
372 | jnz .no_syn |
413 | push cx |
- | 414 | mov cl, [ebx + TCP_SOCKET.SND_SCALE] |
|
Line 373... | Line 415... | ||
373 | 415 | shl eax, cl |
|
374 | mov cl , [ebx + TCP_SOCKET.SND_SCALE] |
416 | pop cx |
Line -... | Line 417... | ||
- | 417 | ||
- | 418 | ;;;; do something with eax |
|
Line -... | Line 419... | ||
- | 419 | ||
375 | shl eax, cl |
420 | ;----------------------------------- |
Line -... | Line 421... | ||
- | 421 | ; Is this socket a listening socket? |
|
- | 422 | ||
Line 376... | Line 423... | ||
376 | 423 | ; test [ebx + SOCKET.options], SO_ACCEPTCON |
|
Line 377... | Line 424... | ||
377 | .no_syn: |
424 | ; jnz .listening_socket ;;;;; TODO |
378 | 425 | ||
Line -... | Line 426... | ||
- | 426 | ;------------------------------------- |
|
- | 427 | ; Reset idle timer and keepalive timer |
|
Line 379... | Line 428... | ||
379 | ;----------------------------------- |
428 | |
- | 429 | mov [ebx + TCP_SOCKET.t_idle], 0 |
|
- | 430 | mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval |
|
Line -... | Line 431... | ||
- | 431 | ||
- | 432 | ;-------------------- |
|
Line 380... | Line 433... | ||
380 | ; Is this socket a listening socket? |
433 | ; Process TCP options |
381 | 434 | ||
Line 382... | Line 435... | ||
382 | ; If so, create a new socket |
435 | cmp esi, 20 ; esi is headersize |
- | 436 | je .no_options |
|
Line -... | Line 437... | ||
- | 437 | ||
- | 438 | DEBUGF 1,"Segment has options\n" |
|
- | 439 | ||
- | 440 | test [ebx + TCP_SOCKET.t_state], TCB_LISTEN ; no options when in listen state |
|
- | 441 | jz .no_options |
|
- | 442 | ||
- | 443 | lea edi, [edx + TCP_segment.Data] |
|
- | 444 | lea eax, [edx + esi] |
|
- | 445 | ||
- | 446 | .opt_loop: |
|
- | 447 | cmp edi, eax |
|
- | 448 | jge .no_options |
|
- | 449 | ||
- | 450 | cmp byte [edi], TCP_OPT_EOL ; end of option list? |
|
- | 451 | jz .no_options |
|
- | 452 | ||
383 | 453 | cmp byte [edi], TCP_OPT_NOP ; nop ? |
|
- | 454 | jz .opt_nop |
|
- | 455 | ||
- | 456 | cmp byte [edi], TCP_OPT_MAXSEG |
|
- | 457 | je .opt_maxseg |
|
- | 458 | ||
- | 459 | cmp byte [edi], TCP_OPT_WINDOW |
|
- | 460 | je .opt_window |
|
- | 461 | ||
Line 384... | Line -... | ||
384 | test [ebx + SOCKET.options], SO_ACCEPTCON |
- | |
385 | jz .no_accept_conn |
- | |
Line -... | Line 462... | ||
- | 462 | cmp byte [edi], TCP_OPT_TIMESTAMP |
|
386 | 463 | je .opt_timestamp |
|
387 | 464 | ||
Line 388... | Line 465... | ||
388 | ; TODO: create a new socket |
465 | jmp .no_options ; If we reach here, some unknown options were received, skip them all! |
- | 466 | ||
Line -... | Line 467... | ||
- | 467 | .opt_nop: |
|
- | 468 | inc edi |
|
- | 469 | jmp .opt_loop |
|
- | 470 | ||
- | 471 | .opt_maxseg: |
|
- | 472 | cmp byte [edi+1], 4 |
|
- | 473 | jne .no_options ; error occured, ignore all options! |
|
- | 474 | ||
- | 475 | test [edx + TCP_segment.Flags], TH_SYN |
|
- | 476 | jz @f |
|
- | 477 | ||
- | 478 | DEBUGF 1,"Got maxseg option" |
|
- | 479 | ||
- | 480 | ;;;;; |
|
- | 481 | @@: |
|
- | 482 | add edi, 4 |
|
- | 483 | jmp .opt_loop |
|
- | 484 | ||
- | 485 | ||
389 | 486 | .opt_window: |
|
Line 390... | Line 487... | ||
390 | 487 | cmp byte [edi+1], 3 |
|
391 | .no_accept_conn: |
488 | jne .no_options |
Line 392... | Line -... | ||
392 | - | ||
393 | ;---------------------------- |
489 | |
394 | ; Compute window scale factor |
490 | test [edx + TCP_segment.Flags], TH_SYN |
395 | 491 | jz @f |
|
396 | 492 | ||
397 | ; TODO |
493 | DEBUGF 1,"Got window option" |
Line 428... | Line 524... | ||
428 | ; In this case we'll free the ACK'ed data and notify higher levels that we have free space in buffer |
524 | ; In this case we'll free the ACK'ed data and notify higher levels that we have free space in buffer |
429 | ; |
525 | ; |
430 | ; - If the length is not 0 and the ACK didn't move, we're the receiver side of the transfer. |
526 | ; - If the length is not 0 and the ACK didn't move, we're the receiver side of the transfer. |
431 | ; If the packets are in order (data queue is empty), add the data to the socket buffer and request a delayed ACK |
527 | ; If the packets are in order (data queue is empty), add the data to the socket buffer and request a delayed ACK |
Line 432... | Line 528... | ||
432 | 528 | ||
433 | cmp [TCP_SOCKET.t_state], TCB_ESTABLISHED |
529 | cmp [ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED |
Line 434... | Line 530... | ||
434 | jnz .not_uni_xfer |
530 | jnz .not_uni_xfer |
435 | 531 | ||
Line 436... | Line 532... | ||
436 | test [TCP_segment.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG |
532 | test [edx + TCP_segment.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG |
437 | jnz .not_uni_xfer |
533 | jnz .not_uni_xfer |
Line 438... | Line 534... | ||
438 | 534 | ||
439 | test [TCP_segment.Flags], TH_ACK |
535 | test [edx + TCP_segment.Flags], TH_ACK |
440 | jz .not_uni_xfer |
536 | jz .not_uni_xfer |
Line 441... | Line 537... | ||
441 | 537 | ||
442 | mov eax, [edx + TCP_segment.SequenceNumber] |
538 | mov eax, [edx + TCP_segment.SequenceNumber] |
443 | cmp eax, [ebx + TCP_SOCKET.RCV_NXT] |
539 | cmp eax, [ebx + TCP_SOCKET.RCV_NXT] |
Line 444... | Line 540... | ||
444 | jne .not_uni_xfer |
540 | jne .not_uni_xfer |
445 | 541 | ||
446 | movzx eax, [edx + TCP_segment.Window] ;;;;; |
542 | movzx eax, [edx + TCP_segment.Window] ;;;;; (should use pre-calculated value isntead: todo: figure out where to store it) |
Line 447... | Line -... | ||
447 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
- | |
448 | jne .not_uni_xfer |
- | |
449 | - | ||
450 | mov eax, [ebx + TCP_SOCKET.SND_NXT] |
- | |
451 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
- | |
452 | jne .not_uni_xfer |
- | |
453 | - | ||
454 | ;------------------------------------------------------------------------------- |
- | |
455 | ; If last ACK falls within this segment's sequence number, record the timestamp. |
543 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
456 | 544 | jne .not_uni_xfer |
|
Line 457... | Line 545... | ||
457 | ; TODO: check if it has a timestamp |
545 | |
458 | 546 | mov eax, [ebx + TCP_SOCKET.SND_NXT] |
|
459 | 547 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
|
460 | - | ||
461 | - | ||
462 | ;--------------------------------------- |
- | |
463 | ; check if we are sender in the uni-xfer |
- | |
464 | 548 | jne .not_uni_xfer |
|
465 | ; If the following 4 conditions are all true, this segment is a pure ACK. |
549 | |
Line 466... | Line -... | ||
466 | ; |
- | |
467 | ; - The segment contains no data (ti_len is 0). |
- | |
468 | - | ||
469 | movzx eax, [edx + TCP_segment.DataOffset] |
- | |
470 | and eax, 11110000b |
- | |
471 | shr eax, 2 |
- | |
472 | sub ecx, eax |
- | |
473 | jnz .not_sender |
- | |
474 | - | ||
475 | ; - The acknowledgment field in the segment (ti_ack) is greater than the largest unacknowledged sequence number (snd_una). |
- | |
476 | ; Since this test is "greater than" and not "greater than or equal to," it is true only if some positive amount of data is acknowledged by the ACK. |
- | |
477 | - | ||
478 | mov eax, [edx + TCP_segment.AckNumber] |
- | |
479 | cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
550 | ;--------------------------------------- |
480 | jle .not_uni_xfer |
551 | ; check if we are sender in the uni-xfer |
481 | - | ||
482 | ; - The acknowledgment field in the segment (ti_ack) is less than or equal to the maximum sequence number sent (snd_max). |
552 | |
483 | 553 | ; If the following 4 conditions are all true, this segment is a pure ACK. |
|
484 | ; mov eax, [edx + TCP_segment.Ack] |
554 | ; |
Line -... | Line 555... | ||
- | 555 | ; - The segment contains no data. |
|
- | 556 | test ecx, ecx |
|
- | 557 | jnz .not_sender |
|
- | 558 | ||
- | 559 | ; - The congestion window is greater than or equal to the current send window. |
|
- | 560 | ; This test is true only if the window is fully open, that is, the connection is not in the middle of slow start or congestion avoidance. |
|
- | 561 | mov eax, [ebx + TCP_SOCKET.SND_CWND] |
|
- | 562 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
|
- | 563 | jl .not_uni_xfer |
|
485 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
564 | |
Line 486... | Line 565... | ||
486 | jg .not_uni_xfer |
565 | ; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent. |
487 | 566 | mov ecx, [edx + TCP_segment.AckNumber] |
|
Line 488... | Line 567... | ||
488 | ; - The congestion window (snd_cwnd) is greater than or equal to the current send window (snd_wnd). |
567 | cmp ecx, [ebx + TCP_SOCKET.SND_MAX] |
Line 489... | Line 568... | ||
489 | ; This test is true only if the window is fully open, that is, the connection is not in the middle of slow start or congestion avoidance. |
568 | jg .not_uni_xfer |
- | 569 | ||
- | 570 | ; - The acknowledgment field in the segment is greater than the largest unacknowledged sequence number. |
|
- | 571 | sub ecx, [ebx + TCP_SOCKET.SND_UNA] |
|
- | 572 | jle .not_uni_xfer |
|
Line 490... | Line 573... | ||
490 | 573 | ||
491 | mov eax, [ebx + TCP_SOCKET.SND_CWND] |
574 | DEBUGF 1,"Header prediction: we are sender\n" |
Line 492... | Line 575... | ||
492 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
575 | |
Line 511... | Line 594... | ||
511 | ; Generate more output |
594 | ; Generate more output |
512 | call TCP_output |
595 | call TCP_output |
Line 513... | Line 596... | ||
513 | 596 | ||
Line 514... | Line -... | ||
514 | jmp .drop |
- | |
515 | - | ||
516 | - | ||
517 | 597 | jmp .drop |
|
518 | 598 | ||
Line 519... | Line 599... | ||
519 | ;------------------------------------------------- |
599 | ;------------------------------------------------- |
520 | ; maybe we are the receiver in the uni-xfer then.. |
600 | ; maybe we are the receiver in the uni-xfer then.. |
Line 521... | Line -... | ||
521 | - | ||
522 | .not_sender: |
601 | |
523 | ; The amount of data in the segment (ti_len) is greater than 0 (data count is in ecx) |
602 | .not_sender: |
524 | 603 | ; - The amount of data in the segment is greater than 0 (data count is in ecx) |
|
525 | 604 | ||
Line 526... | Line 605... | ||
526 | ; The acknowledgment field (ti_ack) equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment. |
605 | ; - The acknowledgment field equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment. |
527 | mov eax, [edx + TCP_segment.AckNumber] |
- | |
528 | cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
- | |
Line 529... | Line -... | ||
529 | jne .not_uni_xfer |
- | |
530 | - | ||
531 | ; The reassembly list of out-of-order segments for the connection is empty (seg_next equals tp). |
606 | mov eax, [edx + TCP_segment.AckNumber] |
Line 532... | Line 607... | ||
532 | ;;;; |
607 | cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
533 | jnz .not_uni_xfer |
608 | jne .not_uni_xfer |
Line 534... | Line 609... | ||
534 | 609 | ||
Line 535... | Line -... | ||
535 | ; There is room in the receive buffer for the data in the segment. |
- | |
536 | ;;;; |
- | |
537 | jnz .not_uni_xfer |
- | |
538 | - | ||
539 | ;------------------------------------- |
- | |
540 | ; Complete processing of received data |
610 | ; - The reassembly list of out-of-order segments for the connection is empty (seg_next equals tp). ;;;;;;; |
541 | 611 | ||
542 | DEBUGF 1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx |
612 | jnz .not_uni_xfer |
Line -... | Line 613... | ||
- | 613 | ||
543 | 614 | ;------------------------------------- |
|
Line 544... | Line 615... | ||
544 | ; The next expected receive sequence number (rcv_nxt) is incremented by the number of bytes of data. |
615 | ; Complete processing of received data |
Line 545... | Line -... | ||
545 | - | ||
546 | add [ebx + TCP_SOCKET.RCV_NXT], ecx |
- | |
547 | - | ||
548 | ; Add the data to the socket buffer |
- | |
549 | mov eax, ebx |
616 | |
550 | ;;; mov... |
617 | DEBUGF 1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx |
Line 551... | Line 618... | ||
551 | call SOCKET_input |
618 | |
Line 552... | Line 619... | ||
552 | 619 | add esi, edx |
|
Line 553... | Line -... | ||
553 | ; The delayed-ACK flag is set and the input processing is complete. |
- | |
554 | - | ||
555 | jmp .drop |
- | |
556 | - | ||
557 | - | ||
558 | - | ||
559 | - | ||
560 | - | ||
561 | ;---------------------------------------------------- |
- | |
562 | ; Header prediction failed, doing it the slow way.. |
- | |
563 | - | ||
564 | .not_uni_xfer: |
620 | lea eax, [ebx + rcv] |
565 | 621 | call SOCKET_ring_add ; Add the data to the socket buffer |
|
Line 566... | Line 622... | ||
566 | DEBUGF 1,"Header prediction failed\n" |
622 | |
Line 567... | Line -... | ||
567 | - | ||
568 | ;------------------------ |
623 | add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied |
569 | ; calculate header length ;;;;; we already calculated this before! |
624 | or [ebx + TCP_SOCKET.t_flags], TF_DELACK ; Set delayed ack flag |
Line 570... | Line 625... | ||
570 | movzx eax, [edx + TCP_segment.DataOffset] |
625 | |
Line 571... | Line 626... | ||
571 | and eax, 0xf0 |
626 | jmp .drop |
572 | shr eax, 2 |
627 | |
Line 573... | Line 628... | ||
573 | 628 | ;---------------------------------------------------- |
|
574 | ; Update edx to point to data.. |
629 | ; Header prediction failed, doing it the slow way.. ;;;;; current implementation of header prediction destroys some regs (ecx) !! |
Line 575... | Line -... | ||
575 | add edx, eax |
- | |
576 | ; ..and ecx to give data size |
630 | |
577 | sub ecx, eax |
631 | .not_uni_xfer: |
Line 578... | Line -... | ||
578 | - | ||
579 | ;------------------------------ |
632 | |
Line 580... | Line 633... | ||
580 | ; Calculate receive window size |
633 | DEBUGF 1,"Header prediction failed\n" |
Line 581... | Line 634... | ||
581 | 634 | ||
Line 582... | Line 635... | ||
582 | ;;;; |
635 | ;------------------------------ |
Line 583... | Line 636... | ||
583 | 636 | ; Calculate receive window size |
|
Line -... | Line 637... | ||
- | 637 | ||
- | 638 | ;;;; |
|
- | 639 | ||
584 | 640 | ;------------------------- |
|
585 | ;------------------------- |
641 | ; TCP slow input procedure |
Line 586... | Line 642... | ||
586 | ; TCP slow input procedure |
642 | |
Line 620... | Line 676... | ||
620 | jnz .drop_with_reset |
676 | jnz .drop_with_reset |
Line 621... | Line 677... | ||
621 | 677 | ||
622 | test [edx + TCP_segment.Flags], TH_SYN |
678 | test [edx + TCP_segment.Flags], TH_SYN |
Line -... | Line 679... | ||
- | 679 | jz .drop |
|
623 | jz .drop |
680 | |
Line 624... | Line 681... | ||
624 | 681 | ; TODO: find sender ip address somewhere! |
|
- | 682 | ; TODO: check if it's a broadcast or multicast, and drop if so |
|
Line -... | Line 683... | ||
- | 683 | ||
625 | ; TODO: check if it's a broadcast or multicast, and drop if so |
684 | call SOCKET_fork |
Line 626... | Line -... | ||
626 | - | ||
627 | ;;; 28.6 |
- | |
628 | - | ||
629 | ; create a new socket and fill in the nescessary variables |
- | |
630 | - | ||
631 | ;; Exit if backlog queue is full |
- | |
632 | ; mov ax, [ebx + TCP_SOCKET.backlog_cur] |
- | |
633 | ; cmp ax, [ebx + TCP_SOCKET.backlog] |
- | |
634 | ; jae .exit |
- | |
635 | - | ||
636 | ; Allocate new socket |
- | |
637 | call SOCKET_alloc |
- | |
638 | ;;; jz .fail |
685 | jz .drop ; if we could not open a new connection, drop segment (;;;; should we send RST too?) |
639 | - | ||
640 | ; Copy structure from current socket to new, (including lock!) |
- | |
Line 641... | Line 686... | ||
641 | ; We start at PID to reserve the socket num, and the 2 pointers at beginning of socket |
686 | |
642 | lea esi, [edx + SOCKET.PID] |
- | |
643 | lea edi, [eax + SOCKET.PID] |
687 | ;----------------------- |
644 | mov ecx, (TCP_SOCKET.end - SOCKET.PID + 3)/4 |
- | |
Line 645... | Line 688... | ||
645 | rep movsd |
688 | ; Fill in some variables |
- | 689 | ||
Line 646... | Line 690... | ||
646 | 690 | add [TCP_sequence_num], 64000 |
|
647 | ;; Push pointer to new socket to queue |
691 | |
Line 648... | Line 692... | ||
648 | ; movzx ecx, [ebx + TCP_SOCKET.backlog_cur] |
692 | push [edx + TCP_segment.SourcePort] |
649 | ; inc [ebx + TCP_SOCKET.backlog_cur] |
693 | pop [eax + TCP_SOCKET.RemotePort] |
- | 694 | ||
Line 650... | Line 695... | ||
650 | ; mov [ebx + TCP_SOCKET.end + ecx*4], eax |
695 | push [edx + TCP_segment.SequenceNumber] |
651 | - | ||
Line 652... | Line 696... | ||
652 | mov [eax + IP_SOCKET.RemoteIP], esi ; IP source address |
696 | pop [eax + TCP_SOCKET.IRS] |
Line -... | Line 697... | ||
- | 697 | ||
- | 698 | push [eax + TCP_SOCKET.ISS] |
|
Line 653... | Line 699... | ||
653 | 699 | pop [eax + TCP_SOCKET.SND_NXT] |
|
654 | mov cx, [edx + TCP_segment.SourcePort] |
700 | |
Line 655... | Line 701... | ||
655 | mov [eax + TCP_SOCKET.RemotePort], cx |
701 | mov [eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED |
Line 674... | Line 720... | ||
674 | 720 | ||
675 | mov eax, [edx + TCP_segment.AckNumber] |
721 | mov eax, [edx + TCP_segment.AckNumber] |
676 | cmp eax, [ebx + TCP_SOCKET.ISS] |
722 | cmp eax, [ebx + TCP_SOCKET.ISS] |
Line 677... | Line -... | ||
677 | jle .drop_with_reset |
- | |
678 | 723 | jle .drop_with_reset |
|
679 | mov eax, [edx + TCP_segment.AckNumber] |
- | |
680 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
- | |
Line -... | Line 724... | ||
- | 724 | ||
- | 725 | DEBUGF 1,"snd_max = %x\n", [ebx + TCP_SOCKET.SND_MAX] ;;; TODO: set this, but where? |
|
- | 726 | ||
- | 727 | ; mov eax, [edx + TCP_segment.AckNumber] |
|
Line 681... | Line 728... | ||
681 | jg .drop_with_reset |
728 | ;; cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
682 | @@: |
729 | ;; jg .drop_with_reset |
Line 683... | Line 730... | ||
683 | 730 | @@: |
|
Line 694... | Line 741... | ||
694 | @@: |
741 | @@: |
Line 695... | Line 742... | ||
695 | 742 | ||
696 | test [edx + TCP_segment.Flags], TH_SYN |
743 | test [edx + TCP_segment.Flags], TH_SYN |
Line 697... | Line 744... | ||
697 | jz .drop |
744 | jz .drop |
- | 745 | ||
698 | 746 | ; at this point, segment seems to be valid |
|
699 | ; now, process received SYN in response to an active open |
747 | |
- | 748 | test [edx + TCP_segment.Flags], TH_ACK |
|
- | 749 | jz .no_syn_ack |
|
Line 700... | Line 750... | ||
700 | test [edx + TCP_segment.Flags], TH_ACK |
750 | |
701 | jz @f |
751 | ; now, process received SYN in response to an active open |
702 | - | ||
703 | mov eax, [edx + TCP_segment.AckNumber] |
- | |
704 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
752 | |
705 | 753 | mov eax, [edx + TCP_segment.AckNumber] |
|
706 | mov eax, [ebx + TCP_SOCKET.SND_UNA] |
754 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
- | 755 | cmp eax, [ebx + TCP_SOCKET.SND_NXT] |
|
Line 707... | Line -... | ||
707 | cmp eax, [ebx + TCP_SOCKET.SND_NXT] |
- | |
708 | jle @f |
756 | jle @f |
Line -... | Line 757... | ||
- | 757 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
|
- | 758 | @@: |
|
709 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
759 | |
710 | 760 | .no_syn_ack: |
|
- | 761 | ||
- | 762 | mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; disable retransmission |
|
- | 763 | ||
- | 764 | push [edx + TCP_segment.SequenceNumber] |
|
- | 765 | pop [ebx + TCP_SOCKET.IRS] |
|
- | 766 | ||
- | 767 | ;;; TODO: tcp_rcvseqinit |
|
- | 768 | ||
- | 769 | mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
|
- | 770 | ||
- | 771 | mov eax, [ebx + TCP_SOCKET.SND_UNA] |
|
- | 772 | cmp eax, [ebx + TCP_SOCKET.ISS] |
|
- | 773 | jle .simultaneous_open |
|
Line -... | Line 774... | ||
- | 774 | ||
711 | mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval |
775 | test [edx + TCP_segment.Flags], TH_ACK |
Line 712... | Line 776... | ||
712 | mov [ebx + TCP_SOCKET.timer_retransmission], 0 |
776 | jz .simultaneous_open |
Line 713... | Line 777... | ||
713 | 777 | ||
714 | mov eax, [edx + TCP_segment.SequenceNumber] |
778 | DEBUGF 1,"TCP: active open\n" |
Line -... | Line 779... | ||
- | 779 | ||
Line 715... | Line 780... | ||
715 | mov [ebx + TCP_SOCKET.IRS], eax |
780 | ; TODO: update stats |
Line -... | Line 781... | ||
- | 781 | ; TODO: set socket state to connected |
|
716 | 782 | ||
717 | ; TODO: set socket state to connected |
783 | mov [ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED |
Line 718... | Line 784... | ||
718 | 784 | ||
719 | mov [ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED |
785 | ; TODO: check if we should scale the connection (567-572) |
Line 742... | Line 808... | ||
742 | ; TODO: 592 |
808 | ; TODO: 592 |
743 | mov cx, [ebx + TCP_SOCKET.RCV_WND] |
809 | mov cx, [ebx + TCP_SOCKET.RCV_WND] |
744 | ; TODO... |
810 | ; TODO... |
745 | @@: |
811 | @@: |
746 | ;;;;; |
812 | ;;;;; |
747 | ;;; jmp .step6 |
813 | jmp .step6 |
Line 748... | Line -... | ||
748 | - | ||
749 | 814 | ||
Line 750... | Line 815... | ||
750 | 815 | ||
Line 751... | Line 816... | ||
751 | 816 | ||
752 | 817 | ||
Line 753... | Line 818... | ||
753 | align 4 |
818 | |
Line 781... | Line 846... | ||
781 | and [edx + TCP_segment.Flags], not (TH_URG) |
846 | and [edx + TCP_segment.Flags], not (TH_URG) |
782 | dec eax |
847 | dec eax |
Line 783... | Line 848... | ||
783 | 848 | ||
Line 784... | Line 849... | ||
784 | .no_drop: |
849 | .no_drop: |
Line -... | Line 850... | ||
- | 850 | ||
Line 785... | Line 851... | ||
785 | 851 | DEBUGF 1,"Going to drop %u bytes of data", eax |
|
786 | ; eax holds number of bytes to drop |
852 | |
Line 787... | Line 853... | ||
787 | 853 | ; eax holds number of bytes to drop |
|
788 | 854 | ||
Line 789... | Line 855... | ||
789 | ;---------------------------------- |
855 | ;---------------------------------- |
Line 790... | Line -... | ||
790 | ; Check for entire duplicate packet |
- | |
791 | - | ||
792 | cmp eax, ecx |
- | |
793 | jge .duplicate |
- | |
794 | - | ||
795 | ;;; TODO: figure 28.30 |
856 | ; Check for entire duplicate packet |
796 | 857 | ||
Line 797... | Line 858... | ||
797 | ;; inc [TCP_segments_rx] |
858 | cmp eax, ecx |
798 | 859 | jge .duplicate |
|
Line 809... | Line 870... | ||
809 | dec ecx |
870 | dec ecx |
810 | jne @f |
871 | jne @f |
Line 811... | Line 872... | ||
811 | 872 | ||
812 | mov eax, ecx |
873 | mov eax, ecx |
813 | and [edx + TCP_segment.Flags], not TH_FIN |
874 | and [edx + TCP_segment.Flags], not TH_FIN |
814 | ;;; TODO: set ACKNOW flag |
- | |
815 | 875 | or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
|
816 | jmp .no_duplicate |
876 | jmp .no_duplicate |
Line 817... | Line 877... | ||
817 | @@: |
877 | @@: |
818 | 878 | ||
Line 819... | Line -... | ||
819 | ; Handle the case when a bound socket connects to itself |
- | |
820 | ; Allow packets with a SYN and an ACKto continue with the processing |
879 | ; Handle the case when a bound socket connects to itself |
821 | 880 | ; Allow packets with a SYN and an ACKto continue with the processing |
|
Line 822... | Line 881... | ||
822 | 881 | ||
Line 831... | Line 890... | ||
831 | cmp [edx + TCP_segment.Flags], TH_ACK |
890 | cmp [edx + TCP_segment.Flags], TH_ACK |
832 | jz .drop_after_ack |
891 | jz .drop_after_ack |
Line 833... | Line 892... | ||
833 | 892 | ||
Line -... | Line 893... | ||
- | 893 | .duplicate: |
|
- | 894 | ||
834 | .duplicate: |
895 | DEBUGF 1,"Duplicate received" |
835 | 896 | ||
Line 836... | Line 897... | ||
836 | ;---------------------------------------- |
897 | ;---------------------------------------- |
Line 837... | Line 898... | ||
837 | ; Update statistics for duplicate packets |
898 | ; Update statistics for duplicate packets |
Line 838... | Line 899... | ||
838 | 899 | ||
Line 839... | Line 900... | ||
839 | ;;; TODO |
900 | ;;; TODO |
840 | 901 | ||
Line 896... | Line 957... | ||
896 | 957 | ||
Line 897... | Line 958... | ||
897 | .dont_drop_all: |
958 | .dont_drop_all: |
Line 898... | Line -... | ||
898 | - | ||
899 | .no_excess_data: |
959 | |
900 | 960 | .no_excess_data: |
|
Line 901... | Line 961... | ||
901 | 961 | ||
Line 908... | Line 968... | ||
908 | ; Process RST flags |
968 | ; Process RST flags |
Line 909... | Line 969... | ||
909 | 969 | ||
910 | test [edx + TCP_segment.Flags], TH_RST |
970 | test [edx + TCP_segment.Flags], TH_RST |
Line -... | Line 971... | ||
- | 971 | jz .rst_skip |
|
- | 972 | ||
911 | jz .rst_skip |
973 | DEBUGF 1,"Got an RST flag" |
912 | 974 | ||
913 | mov eax, [ebx + TCP_SOCKET.t_state] |
975 | mov eax, [ebx + TCP_SOCKET.t_state] |
Line 914... | Line 976... | ||
914 | shl eax, 2 |
976 | shl eax, 2 |
Line 927... | Line 989... | ||
927 | dd .econnreset ;TCB_FIN_WAIT_2 |
989 | dd .econnreset ;TCB_FIN_WAIT_2 |
928 | dd .rst_close ;TCB_TIMED_WAIT |
990 | dd .rst_close ;TCB_TIMED_WAIT |
Line 929... | Line 991... | ||
929 | 991 | ||
Line -... | Line 992... | ||
- | 992 | .econnrefused: |
|
- | 993 | ||
930 | .econnrefused: |
994 | DEBUGF 1,"Connection refused" |
Line 931... | Line 995... | ||
931 | 995 | ||
Line 932... | Line 996... | ||
932 | ;;; TODO: debug info |
996 | ;;; TODO: debug info |
Line -... | Line 997... | ||
- | 997 | ||
- | 998 | jmp .close |
|
933 | 999 | ||
934 | jmp .close |
1000 | .econnreset: |
Line -... | Line 1001... | ||
- | 1001 | ||
- | 1002 | DEBUGF 1,"Connection reset" |
|
935 | 1003 | ||
Line 936... | Line 1004... | ||
936 | .econnreset: |
1004 | ;;; TODO: debug info |
Line -... | Line 1005... | ||
- | 1005 | .close: |
|
- | 1006 | ||
937 | 1007 | DEBUGF 1,"Closing connection" |
|
938 | ;;; TODO: debug info |
1008 | |
Line 939... | Line 1009... | ||
939 | .close: |
1009 | ;;; update stats |
Line 1004... | Line 1074... | ||
1004 | 1074 | ||
1005 | 1075 | ||
Line -... | Line 1076... | ||
- | 1076 | ;------------------------------------------ |
|
1006 | ;------------------------------------------ |
1077 | ; Remove acknowledged data from send buffer |
- | 1078 | ||
Line 1007... | Line 1079... | ||
1007 | ; Remove acknowledged data from send buffer |
1079 | lea eax, [ebx + snd] |
1008 | 1080 | mov ecx, ecx ;;;; 943 - 956 |
|
Line 1009... | Line 1081... | ||
1009 | ;;;; 943 - 956 |
1081 | call SOCKET_ring_free |
- | 1082 | ||
Line 1010... | Line 1083... | ||
1010 | 1083 | ;--------------------------------------- |
|
1011 | ;--------------------------------------- |
1084 | ; Wake up process waiting on send buffer |
1012 | ; Wake up process waiting on send buffer |
1085 | |
Line 1101... | Line 1174... | ||
1101 | 1174 | ||
Line 1102... | Line 1175... | ||
1102 | ;;; needoutput = 1 |
1175 | ;;; needoutput = 1 |
Line 1103... | Line -... | ||
1103 | - | ||
1104 | .no_window_update: |
1176 | |
1105 | 1177 | .no_window_update: |
|
Line 1106... | Line 1178... | ||
1106 | 1178 | ||
1107 | ;----------------- |
1179 | ;----------------- |
Line 1119... | Line 1191... | ||
1119 | ; Ignore bogus urgent offsets |
1191 | ; Ignore bogus urgent offsets |
Line 1120... | Line 1192... | ||
1120 | 1192 | ||
Line 1121... | Line 1193... | ||
1121 | ;;; 1040-1050 |
1193 | ;;; 1040-1050 |
1122 | 1194 | ||
1123 | movzx eax, [edx + TCP_segment.UrgentPointer] |
1195 | movzx eax, [edx + TCP_segment.UrgentPointer] |
1124 | add eax, [ebx + SOCKET.SO_RCV.SB_CC] |
1196 | add eax, [ebx + rcv.size] |
Line 1125... | Line 1197... | ||
1125 | cmp eax, SOCKET_MAXDATA |
1197 | cmp eax, SOCKET_MAXDATA |
1126 | jle .not_urgent |
1198 | jle .not_urgent |
Line 1132... | Line 1204... | ||
1132 | .not_urgent: |
1204 | .not_urgent: |
Line 1133... | Line 1205... | ||
1133 | 1205 | ||
1134 | ;-------------------------------------- |
1206 | ;-------------------------------------- |
Line 1135... | Line 1207... | ||
1135 | ; processing of received urgent pointer |
1207 | ; processing of received urgent pointer |
Line 1136... | Line 1208... | ||
1136 | 1208 | ||
1137 | ;;; 1051-1093 |
1209 | ;;; TODO (1051-1093) |
Line 1138... | Line 1210... | ||
1138 | 1210 | ||
Line 1139... | Line 1211... | ||
1139 | align 4 |
1211 | ;-------------------------------- |
Line 1140... | Line 1212... | ||
1140 | .do_data: |
1212 | ; process the data in the segment |
1141 | 1213 | ||
Line 1142... | Line 1214... | ||
1142 | DEBUGF 1,"Do data:\n" |
1214 | .do_data: |
1143 | 1215 | ||
Line 1144... | Line 1216... | ||
1144 | ; process the data in the segment |
1216 | DEBUGF 1,"TCP: do data:\n" |
Line 1145... | Line 1217... | ||
1145 | 1217 | ||
Line 1156... | Line 1228... | ||
1156 | jmp .final_processing |
1228 | jmp .final_processing |
Line 1157... | Line 1229... | ||
1157 | 1229 | ||
Line 1158... | Line -... | ||
1158 | - | ||
1159 | .dont_do_data: |
1230 | |
1160 | 1231 | .dont_do_data: |
|
Line 1161... | Line 1232... | ||
1161 | 1232 | ||
Line 1207... | Line 1278... | ||
1207 | 1278 | ||
1208 | ;test ;;;needoutput = 1 |
1279 | ;test ;;;needoutput = 1 |
Line 1209... | Line 1280... | ||
1209 | ;jnz .outputnow |
1280 | ;jnz .outputnow |
- | 1281 | ||
- | 1282 | test [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
|
- | 1283 | jnz .ack_now |
|
- | 1284 | ||
- | 1285 | mov [ebx + SOCKET.lock], 0 |
|
1210 | 1286 | call kernel_free |
|
- | 1287 | add esp, 4 |
|
- | 1288 | ret |
|
- | 1289 | ||
- | 1290 | .ack_now: |
|
Line -... | Line 1291... | ||
- | 1291 | ||
1211 | test [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
1292 | DEBUGF 1,"ACK now!\n" |
1212 | jz .ret |
1293 | |
- | 1294 | push ebx |
|
Line 1213... | Line -... | ||
1213 | - | ||
1214 | .outputnow: |
1295 | mov eax, ebx |
1215 | call TCP_output |
- | |
1216 | 1296 | call TCP_output |
|
- | 1297 | pop ebx |
|
1217 | .ret: |
1298 | |
Line 1218... | Line 1299... | ||
1218 | mov [ebx + SOCKET.lock], 0 |
1299 | mov [ebx + SOCKET.lock], 0 |
1219 | 1300 | call kernel_free |
|
Line 1220... | Line 1301... | ||
1220 | call kernel_free |
1301 | add esp, 4 |
Line 1231... | Line 1312... | ||
1231 | test [edx + TCP_segment.Flags], TH_RST |
1312 | test [edx + TCP_segment.Flags], TH_RST |
1232 | jnz .drop |
1313 | jnz .drop |
Line 1233... | Line 1314... | ||
1233 | 1314 | ||
Line -... | Line 1315... | ||
- | 1315 | and [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
|
- | 1316 | ||
1234 | and [ebx + TCP_SOCKET.t_flags], TF_ACKNOW |
1317 | push ebx |
- | 1318 | mov eax, ebx |
|
Line 1235... | Line 1319... | ||
1235 | 1319 | call TCP_output |
|
1236 | call TCP_output |
- | |
1237 | 1320 | pop ebx |
|
- | 1321 | ||
1238 | mov [ebx + SOCKET.lock], 0 |
1322 | mov [ebx + SOCKET.lock], 0 |
Line 1239... | Line 1323... | ||
1239 | 1323 | call kernel_free |
|
1240 | call kernel_free |
1324 | add esp, 4 |
Line 1259... | Line 1343... | ||
1259 | 1343 | ||
1260 | test [edx + TCP_segment.Flags], TH_SYN |
1344 | test [edx + TCP_segment.Flags], TH_SYN |
Line 1261... | Line 1345... | ||
1261 | jnz .respond_syn |
1345 | jnz .respond_syn |
1262 | - | ||
1263 | mov [ebx + SOCKET.lock], 0 |
1346 | |
- | 1347 | mov [ebx + SOCKET.lock], 0 |
|
1264 | 1348 | call kernel_free |
|
Line 1265... | Line 1349... | ||
1265 | call kernel_free |
1349 | add esp, 4 |
Line 1266... | Line 1350... | ||
1266 | ret 4 |
1350 | ret |
Line 1267... | Line 1351... | ||
1267 | 1351 | ||
Line 1268... | Line 1352... | ||
1268 | .respond_ack: |
1352 | .respond_ack: |
Line 1269... | Line 1353... | ||
1269 | 1353 | ||
Line 1270... | Line 1354... | ||
1270 | ;;;; |
1354 | ;;;; |
Line 1271... | Line 1355... | ||
1271 | 1355 | ||
Line 1272... | Line 1356... | ||
1272 | call TCP_respond |
1356 | call TCP_respond_segment |
Line 1273... | Line 1357... | ||
1273 | 1357 | ||
1274 | jmp .destroy_new_socket |
1358 | jmp .destroy_new_socket |
Line 1295... | Line 1379... | ||
1295 | .destroy_new_socket: |
1379 | .destroy_new_socket: |
Line 1296... | Line 1380... | ||
1296 | 1380 | ||
Line 1297... | Line 1381... | ||
1297 | ;;;; kill the newly created socket |
1381 | ;;;; kill the newly created socket |
1298 | - | ||
1299 | mov [ebx + SOCKET.lock], 0 |
1382 | |
1300 | - | ||
1301 | call kernel_free |
- | |
1302 | ret 4 |
- | |
1303 | - | ||
1304 | - | ||
1305 | - | ||
1306 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
- | |
1307 | - | ||
1308 | - | ||
1309 | - | ||
1310 | ;--------------------- |
- | |
1311 | ; |
- | |
1312 | ; TCP_do_options |
- | |
1313 | ; |
- | |
1314 | ;------------------- |
- | |
1315 | - | ||
1316 | align 4 |
- | |
1317 | TCP_do_options: |
- | |
1318 | - | ||
1319 | DEBUGF 1,"TCP_do_options\n" |
- | |
1320 | 1383 | mov [ebx + SOCKET.lock], 0 |
|
1321 | push eax |
- | |
1322 | sub eax, 20 |
- | |
1323 | jz .no_options |
- | |
1324 | - | ||
1325 | lea esi, [edx + TCP_segment.Data] |
- | |
1326 | - | ||
1327 | - | ||
1328 | ;------------------------------------------- |
- | |
1329 | ; Begin the loop by checking for EOL and NOP |
- | |
1330 | - | ||
1331 | .loop: |
- | |
1332 | - | ||
1333 | cmp byte [esi], TCP_OPT_EOL ; end of option list? |
- | |
1334 | jz .no_options |
- | |
1335 | - | ||
1336 | cmp byte [esi], TCP_OPT_NOP ; nop ? |
- | |
1337 | ;;; cmove edi, 1 ; if so, set option size to 1 |
- | |
1338 | jz .continue ; and continue scanning |
- | |
1339 | - | ||
1340 | ;------------------ |
- | |
1341 | ; We have an option |
- | |
1342 | - | ||
1343 | movzx edi, byte [esi + 1] ; get the length of this option in edi |
- | |
1344 | - | ||
1345 | - | ||
1346 | ;-------------------------------------- |
- | |
1347 | ; Check for Maximum segment size option |
- | |
1348 | - | ||
1349 | cmp byte [esi], TCP_OPT_MAXSEG |
- | |
1350 | jne .no_maxseg |
- | |
1351 | - | ||
1352 | cmp edi, 4 ; option length |
- | |
1353 | jne .continue |
- | |
1354 | - | ||
1355 | test [edx + TCP_segment.Flags], TH_SYN |
- | |
1356 | jz .continue |
- | |
1357 | - | ||
1358 | ; Now parse the option... |
- | |
1359 | - | ||
1360 | jmp .continue |
- | |
1361 | - | ||
1362 | .no_maxseg: |
- | |
1363 | - | ||
1364 | ;------------------------ |
1384 | call kernel_free |
1365 | ; Check for Window option |
- | |
1366 | - | ||
Line 1367... | Line -... | ||
1367 | cmp byte [esi], TCP_OPT_WINDOW |
- | |
1368 | jne .no_window |
- | |
Line 1369... | Line -... | ||
1369 | - | ||
1370 | cmp edi, 3 ; option length |
- | |
1371 | jne .continue |
- | |
1372 | - | ||
1373 | test [edx + TCP_segment.Flags], TH_SYN |
- | |
1374 | jz .continue |
- | |
1375 | - | ||
1376 | ; ... |
- | |
1377 | - | ||
1378 | jmp .continue |
- | |
1379 | - | ||
1380 | .no_window: |
- | |
1381 | - | ||
1382 | ;--------------------------- |
- | |
1383 | ; Check for Timestamp option |
- | |
1384 | - | ||
1385 | cmp byte [esi], TCP_OPT_TIMESTAMP |
- | |
1386 | jne .no_timestamp |
- | |
1387 | - | ||
1388 | cmp edi, 10 ; option length |
- | |
1389 | jne .continue |
- | |
1390 | - | ||
1391 | ; ... |
- | |
1392 | - | ||
1393 | - | ||
1394 | jmp .continue |
- | |
1395 | - | ||
1396 | .no_timestamp: |
- | |
1397 | - | ||
1398 | ;---------------------------------- |
- | |
1399 | ; Future options may be placed here |
- | |
1400 | - | ||
1401 | - | ||
1402 | - | ||
1403 | - | ||
1404 | ;------------------------------ |
- | |
1405 | ; Continue scanning for options |
- | |
1406 | - | ||
1407 | .continue: |
- | |
1408 | add esi, edi |
- | |
1409 | sub eax, edi |
- | |
1410 | jg .loop |
- | |
1411 | - | ||
1412 | .no_options: |
- | |
Line 1413... | Line 1385... | ||
1413 | 1385 | add esp, 4 |
|
Line 1439... | Line 1411... | ||
1439 | 1411 | ||
Line 1440... | Line -... | ||
1440 | ret |
- | |
1441 | - | ||
1442 | - | ||
1443 | - | ||
1444 | - | ||
1445 | - | ||
1446 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
- | |
1447 | - | ||
1448 | 1412 | ret |
|
1449 | 1413 | ||
1450 | 1414 | ||
1451 | 1415 | ||
1452 | ;----------------------------------------------------------------- |
1416 | ;----------------------------------------------------------------- |
Line 1492... | Line 1456... | ||
1492 | cmp ecx, [eax + TCP_SOCKET.SND_CWND] ; |
1456 | cmp ecx, [eax + TCP_SOCKET.SND_CWND] ; |
1493 | jl @f ; |
1457 | jl @f ; |
1494 | mov ecx, [eax + TCP_SOCKET.SND_CWND] ; |
1458 | mov ecx, [eax + TCP_SOCKET.SND_CWND] ; |
1495 | @@: ; |
1459 | @@: ; |
Line 1496... | Line 1460... | ||
1496 | 1460 | ||
Line 1497... | Line 1461... | ||
1497 | call TCP_outflags |
1461 | call TCP_outflags ; in dl |
1498 | 1462 | ||
1499 | ; If in persist timeout with window of 0, send 1 byte. |
1463 | ; If in persist timeout with window of 0, send 1 byte. |
Line 1504... | Line 1468... | ||
1504 | jz .no_persist_timeout |
1468 | jz .no_persist_timeout |
Line 1505... | Line 1469... | ||
1505 | 1469 | ||
1506 | test ecx, ecx |
1470 | test ecx, ecx |
Line 1507... | Line 1471... | ||
1507 | jnz .no_zero_window |
1471 | jnz .no_zero_window |
1508 | 1472 | ||
Line 1509... | Line 1473... | ||
1509 | cmp ebx, [eax + SOCKET.SO_SND.SB_CC] |
1473 | cmp ebx, [eax + snd.size] |
Line 1510... | Line 1474... | ||
1510 | jge @f |
1474 | jge @f |
1511 | 1475 | ||
1512 | and dl, not (TH_FIN) ; clear the FIN flag ??? how can it be set before? |
1476 | and dl, not (TH_FIN) ; clear the FIN flag ??? how can it be set before? |
Line 1513... | Line 1477... | ||
1513 | 1477 | ||
Line 1514... | Line 1478... | ||
1514 | @@: |
1478 | @@: |
1515 | inc ecx |
1479 | inc ecx |
Line 1516... | Line 1480... | ||
1516 | jmp .no_persist_timeout |
1480 | jmp .no_persist_timeout |
Line 1517... | Line 1481... | ||
1517 | 1481 | ||
Line 1518... | Line 1482... | ||
1518 | .no_zero_window: |
1482 | .no_zero_window: |
1519 | 1483 | ||
1520 | ;;; mov [eax + TCP_SOCKET.t_timer....TCPT_PERSIST], 0 |
1484 | mov [eax + TCP_SOCKET.timer_persist], 0 ;;;; |
1521 | mov [eax + TCP_SOCKET.t_rxtshift], 0 |
1485 | mov [eax + TCP_SOCKET.t_rxtshift], 0 |
1522 | 1486 | ||
1523 | .no_persist_timeout: |
1487 | .no_persist_timeout: |
Line 1544... | Line 1508... | ||
1544 | xor esi, esi |
1508 | xor esi, esi |
Line 1545... | Line 1509... | ||
1545 | 1509 | ||
1546 | test ecx, ecx |
1510 | test ecx, ecx |
Line 1547... | Line 1511... | ||
1547 | jnz @f |
1511 | jnz @f |
Line 1548... | Line 1512... | ||
1548 | 1512 | ||
1549 | ;;; mov [eax + TCP_SOCKET.t_timer..TCPT_REXMT], 0 |
1513 | mov [eax + TCP_SOCKET.timer_retransmission], 0 ; cancel retransmit |
1550 | 1514 | ||
Line 1567... | Line 1531... | ||
1567 | ;;; 128 |
1531 | ;;; 128 |
Line 1568... | Line 1532... | ||
1568 | 1532 | ||
1569 | mov edi, [eax + TCP_SOCKET.SND_NXT] |
1533 | mov edi, [eax + TCP_SOCKET.SND_NXT] |
1570 | add edi, esi ; len |
1534 | add edi, esi ; len |
1571 | sub edi, [eax + TCP_SOCKET.SND_UNA] |
1535 | sub edi, [eax + TCP_SOCKET.SND_UNA] |
1572 | add edi, [eax + SOCKET.SO_SND.SB_CC] |
1536 | add edi, [eax + snd.size] |
1573 | cmp edi, 0 |
1537 | cmp edi, 0 |
Line 1574... | Line 1538... | ||
1574 | jle @f |
1538 | jle @f |
Line 1575... | Line 1539... | ||
1575 | 1539 | ||
Line 1576... | Line 1540... | ||
1576 | and dl, not (TH_FIN) ; clear the FIN flag |
1540 | and dl, not (TH_FIN) ; clear the FIN flag |
- | 1541 | ||
Line -... | Line 1542... | ||
- | 1542 | @@: |
|
- | 1543 | ||
Line 1577... | Line 1544... | ||
1577 | 1544 | ||
1578 | @@: |
1545 | ; set ecx to space available in receive buffer |
Line 1579... | Line -... | ||
1579 | - | ||
1580 | - | ||
1581 | ;;;; 130 TODO: set window (ecx) to space in send buffer |
- | |
1582 | - | ||
1583 | 1546 | ; From now on, ecx will be the window we advertise to the other end |
|
1584 | ;------------------------------ |
1547 | |
Line 1585... | Line 1548... | ||
1585 | ; Sender silly window avoidance |
1548 | mov ecx, SOCKET_MAXDATA |
Line 1586... | Line 1549... | ||
1586 | 1549 | sub ecx, [eax + rcv.size] |
|
1587 | test esi, esi |
1550 | |
Line -... | Line 1551... | ||
- | 1551 | ;------------------------------ |
|
1588 | jz .zero_length |
1552 | ; Sender silly window avoidance |
1589 | 1553 | ||
1590 | 1554 | cmp ecx, [eax + TCP_SOCKET.t_maxseg] |
|
1591 | cmp esi, [eax + TCP_SOCKET.t_maxseg] |
1555 | je .send |
- | 1556 | ||
- | 1557 | ;;; TODO: 144-145 |
|
- | 1558 | ||
Line 1592... | Line 1559... | ||
1592 | je .send |
1559 | test [eax + TCP_SOCKET.t_force], -1 |
1593 | 1560 | jnz .send |
|
Line 1594... | Line 1561... | ||
1594 | ;;; TODO: 144-145 |
1561 | |
1595 | 1562 | mov ebx, [eax + TCP_SOCKET.max_sndwnd] |
|
Line 1596... | Line 1563... | ||
1596 | test [eax + TCP_SOCKET.t_force], -1 |
1563 | shr ebx, 1 |
Line 1597... | Line 1564... | ||
1597 | jnz .send |
1564 | cmp ecx, ebx |
Line 1639... | Line 1606... | ||
1639 | 1606 | ||
Line 1640... | Line 1607... | ||
1640 | .enter_persist: |
1607 | .enter_persist: |
Line 1641... | Line -... | ||
1641 | - | ||
1642 | DEBUGF 1,"Entering persist state\n" |
- | |
1643 | 1608 | ||
1644 | 1609 | DEBUGF 1,"Entering persist state\n" |
|
Line 1645... | Line 1610... | ||
1645 | 1610 | ||
Line 1646... | Line 1611... | ||
1646 | ;-------------------------------------- |
1611 | ;-------------------------------------- |
Line 1647... | Line -... | ||
1647 | ; No reason to send a segment, just ret |
- | |
1648 | - | ||
1649 | DEBUGF 1,"No reason to send a segment\n" |
- | |
1650 | 1612 | ; No reason to send a segment, just ret |
|
1651 | ret |
1613 | |
1652 | 1614 | DEBUGF 1,"No reason to send a segment\n" |
|
1653 | 1615 | ||
1654 | 1616 | ret |
|
1655 | 1617 | ||
1656 | 1618 | ||
1657 | ;----------------------------------------------- |
1619 | ;----------------------------------------------- |
Line 1658... | Line 1620... | ||
1658 | ; |
1620 | ; |
Line 1659... | Line 1621... | ||
1659 | ; Send a segment |
1621 | ; Send a segment |
Line 1660... | Line 1622... | ||
1660 | ; |
1622 | ; |
- | 1623 | ; eax = socket pointer |
|
- | 1624 | ; dl = flags |
|
- | 1625 | ; |
|
Line 1661... | Line 1626... | ||
1661 | ; ebx = socket pointer |
1626 | ;----------------------------------------------- |
1662 | ; dl = flags |
1627 | |
Line 1663... | Line 1628... | ||
1663 | ; |
1628 | .send: |
1664 | ;----------------------------------------------- |
1629 | |
Line 1665... | Line 1630... | ||
1665 | 1630 | DEBUGF 1,"Preparing to send a segment\n" |
|
1666 | .send: |
1631 | |
Line 1667... | Line 1632... | ||
1667 | 1632 | mov edi, TCP_segment.Data ; edi will contain headersize |
|
1668 | DEBUGF 1,"Preparing to send a segment\n" |
1633 | |
Line -... | Line 1634... | ||
- | 1634 | sub esp, 8 ; create some space on stack |
|
1669 | 1635 | push eax ; save this too.. |
|
1670 | xor edi, edi ; edi will contain the number of header option bytes |
- | |
1671 | 1636 | ||
1672 | ;------------------------------------ |
1637 | ;------------------------------------ |
1673 | ; Send options with first SYN segment |
- | |
1674 | 1638 | ; Send options with first SYN segment |
|
Line 1675... | Line 1639... | ||
1675 | test dl, TH_SYN |
1639 | |
1676 | jz .no_options |
1640 | test dl, TH_SYN |
Line 1677... | Line 1641... | ||
1677 | 1641 | jz .no_options |
|
1678 | mov eax, [ebx + TCP_SOCKET.ISS] |
1642 | |
Line 1679... | Line 1643... | ||
1679 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
1643 | push [eax + TCP_SOCKET.ISS] |
1680 | 1644 | pop [eax + TCP_SOCKET.SND_NXT] |
|
Line 1681... | Line 1645... | ||
1681 | test [ebx + TCP_SOCKET.t_flags], TF_NOOPT |
1645 | |
1682 | jnz .no_options |
- | |
1683 | - | ||
1684 | mov eax, TCP_OPT_MAXSEG shl 24 + 4 shl 16 |
1646 | test [eax + TCP_SOCKET.t_flags], TF_NOOPT |
- | 1647 | jnz .no_options |
|
1685 | mov ax, 1280 ;;;;;; |
1648 | |
1686 | bswap eax |
1649 | mov ecx, 1460 |
1687 | push eax |
- | |
1688 | 1650 | or ecx, TCP_OPT_MAXSEG shl 24 + 4 shl 16 |
|
Line 1689... | Line 1651... | ||
1689 | mov di, 4 |
1651 | bswap ecx |
Line 1690... | Line 1652... | ||
1690 | 1652 | push ecx |
|
1691 | test [ebx + TCP_SOCKET.t_flags], TF_REQ_SCALE |
1653 | add di, 4 |
Line 1692... | Line 1654... | ||
1692 | jz .no_syn |
1654 | |
1693 | 1655 | test [eax + TCP_SOCKET.t_flags], TF_REQ_SCALE |
|
Line 1694... | Line 1656... | ||
1694 | test dl, TH_ACK |
1656 | jz .no_syn |
1695 | jnz .scale_opt |
1657 | |
Line 1696... | Line 1658... | ||
1696 | 1658 | test dl, TH_ACK |
|
1697 | test [ebx + TCP_SOCKET.t_flags], TF_RCVD_SCALE |
1659 | jnz .scale_opt |
Line 1698... | Line 1660... | ||
1698 | jz .no_syn |
1660 | |
1699 | 1661 | test [eax + TCP_SOCKET.t_flags], TF_RCVD_SCALE |
|
Line 1700... | Line 1662... | ||
1700 | .scale_opt: |
1662 | jz .no_syn |
1701 | - | ||
1702 | mov eax, TCP_OPT_WINDOW shl 24 + 4 shl 16 + TCP_OPT_NOP |
1663 | |
- | 1664 | .scale_opt: |
|
1703 | mov ah, byte [ebx + TCP_SOCKET.request_r_scale] |
1665 | movzx ecx, byte [eax + TCP_SOCKET.request_r_scale] |
1704 | bswap eax |
- | |
1705 | push eax |
1666 | or ecx, TCP_OPT_WINDOW shl 24 + 4 shl 16 + TCP_OPT_NOP shl 8 |
1706 | 1667 | bswap ecx |
|
1707 | add di, 4 |
- | |
1708 | - | ||
1709 | .no_syn: |
- | |
1710 | 1668 | pushd ecx |
|
Line 1711... | Line 1669... | ||
1711 | ;------------------------------------ |
1669 | add di, 4 |
1712 | ; Make the timestamp option if needed |
- | |
1713 | 1670 | ||
Line 1714... | Line 1671... | ||
1714 | test [ebx + TCP_SOCKET.t_flags], TF_REQ_TSTMP |
1671 | .no_syn: |
1715 | jz .no_timestamp |
1672 | |
1716 | - | ||
1717 | test dl, TH_RST |
- | |
1718 | jnz .no_timestamp |
- | |
1719 | - | ||
1720 | test dl, TH_ACK |
- | |
1721 | jz .timestamp |
- | |
1722 | 1673 | ;------------------------------------ |
|
1723 | test [ebx + TCP_SOCKET.t_flags], TF_RCVD_TSTMP |
1674 | ; Make the timestamp option if needed |
1724 | jz .no_timestamp |
- | |
1725 | - | ||
1726 | .timestamp: |
- | |
1727 | 1675 | ||
1728 | DEBUGF 1,"Creating a timestamp\n" |
- | |
1729 | - | ||
1730 | push dword (TCP_OPT_TIMESTAMP shl 8 + 10 + TCP_OPT_NOP shl 16 + TCP_OPT_NOP shl 24) |
- | |
1731 | pushw 0 |
- | |
1732 | mov eax, [timer_ticks] |
- | |
1733 | bswap eax |
- | |
1734 | push eax |
- | |
1735 | - | ||
1736 | add di, 10 |
1676 | test [eax + TCP_SOCKET.t_flags], TF_REQ_TSTMP |
Line -... | Line 1677... | ||
- | 1677 | jz .no_timestamp |
|
1737 | 1678 | ||
Line 1738... | Line -... | ||
1738 | .no_timestamp: |
- | |
1739 | - | ||
1740 | ;; TODO: check if we dont exceed the max segment size |
- | |
1741 | - | ||
1742 | .no_options: |
- | |
1743 | add edi, TCP_segment.Data |
- | |
1744 | - | ||
1745 | ;----------------------------------- |
- | |
1746 | ; Check if we have some data to send |
- | |
1747 | - | ||
1748 | ;;; mov ecx, [huppeldepup] |
- | |
1749 | - | ||
1750 | test ecx, ecx |
- | |
1751 | jz .no_data |
- | |
1752 | - | ||
1753 | ;;; 278-316 |
1679 | test dl, TH_RST |
1754 | - | ||
1755 | jmp .header |
- | |
1756 | - | ||
1757 | .no_data: |
- | |
1758 | 1680 | jnz .no_timestamp |
|
1759 | ;;; 317-338 |
- | |
Line -... | Line 1681... | ||
- | 1681 | ||
1760 | 1682 | test dl, TH_ACK |
|
- | 1683 | jz .timestamp |
|
- | 1684 | ||
1761 | 1685 | test [eax + TCP_SOCKET.t_flags], TF_RCVD_TSTMP |
|
- | 1686 | jz .no_timestamp |
|
- | 1687 | ||
- | 1688 | .timestamp: |
|
- | 1689 | mov esi, [timer_ticks] |
|
- | 1690 | bswap esi |
|
1762 | ;---------- |
1691 | push esi |
- | 1692 | pushw 0 |
|
1763 | 1693 | pushd TCP_OPT_TIMESTAMP + 10 shl 8 + TCP_OPT_NOP shl 16 + TCP_OPT_NOP shl 24 |
|
- | 1694 | add di, 10 |
|
Line 1764... | Line 1695... | ||
1764 | push di dx ebx |
1695 | |
1765 | 1696 | .no_timestamp: |
|
1766 | add ecx, edi ; total TCP segment size |
- | |
1767 | - | ||
Line 1768... | Line 1697... | ||
1768 | mov eax, [ebx + IP_SOCKET.RemoteIP] |
1697 | ;; TODO: check if we dont exceed the max segment size |
1769 | mov ebx, [ebx + IP_SOCKET.LocalIP] |
1698 | |
1770 | mov di , IP_PROTO_TCP |
- | |
Line 1771... | Line -... | ||
1771 | call IPv4_create_packet |
- | |
1772 | 1699 | .no_options: |
|
1773 | ;;;; jz .fail |
- | |
Line -... | Line 1700... | ||
- | 1700 | ; eax = socket ptr |
|
- | 1701 | ; edx = flags |
|
- | 1702 | ; ecx = data size |
|
- | 1703 | ; edi = header size |
|
- | 1704 | ; esi = snd ring buff ptr |
|
- | 1705 | ||
- | 1706 | xor ecx, ecx ;;;;; |
|
- | 1707 | add ecx, edi ; total TCP segment size |
|
Line 1774... | Line -... | ||
1774 | - | ||
1775 | push edx eax |
- | |
1776 | call [ebx + NET_DEVICE.transmit] |
1708 | |
1777 | ret |
- | |
1778 | 1709 | ; Start by pushing all TCP header values in reverse order on stack |
|
Line -... | Line 1710... | ||
- | 1710 | ; (essentially, creating the tcp header!) |
|
- | 1711 | ||
1779 | ;---------------- |
1712 | pushw 0 ; .UrgentPointer dw ? |
- | 1713 | pushw 0 ; .Checksum dw ? |
|
- | 1714 | pushw 0x00a0 ; .Window dw ? ;;;;;;; |
|
- | 1715 | shl edi, 2 ; .DataOffset db ? only 4 left-most bits |
|
- | 1716 | shl dx, 8 |
|
- | 1717 | or dx, di ; .Flags db ? |
|
- | 1718 | pushw dx |
|
- | 1719 | shr edi, 2 ; .DataOffset db ? ;;;; |
|
Line -... | Line 1720... | ||
- | 1720 | ||
1780 | 1721 | push [eax + TCP_SOCKET.RCV_NXT] ; .AckNumber dd ? |
|
Line -... | Line 1722... | ||
- | 1722 | ntohld [esp] |
|
1781 | 1723 | ||
Line -... | Line 1724... | ||
- | 1724 | push [eax + TCP_SOCKET.SND_NXT] ; .SequenceNumber dd ? |
|
- | 1725 | ntohld [esp] |
|
Line 1782... | Line 1726... | ||
1782 | ;------------------------------- |
1726 | |
1783 | ; Now, create the 20-byte header |
1727 | push [eax + TCP_SOCKET.RemotePort] ; .DestinationPort dw ? |
Line 1784... | Line 1728... | ||
1784 | 1728 | ntohlw [esp] |
|
1785 | .header: |
1729 | |
1786 | 1730 | push [eax + TCP_SOCKET.LocalPort] ; .SourcePort dw ? |
|
1787 | ;----------------------- |
- | |
1788 | ; Fill in the TCP header |
1731 | ntohlw [esp] |
1789 | pop esi |
1732 | |
1790 | - | ||
1791 | push [esi + TCP_SOCKET.SND_NXT] |
- | |
1792 | rol word [esp], 8 |
- | |
1793 | rol dword [esp], 16 |
1733 | push edi ; header size |
1794 | pop [edi + TCP_segment.SequenceNumber] |
- | |
1795 | - | ||
1796 | push [esi + TCP_SOCKET.RCV_NXT] |
- | |
1797 | rol word [esp], 8 |
1734 | |
1798 | rol dword [esp], 16 |
1735 | ; Create the IP packet |
1799 | pop [edi + TCP_segment.AckNumber] |
1736 | mov ebx, [eax + IP_SOCKET.LocalIP] ; source ip |
1800 | - | ||
1801 | push [esi + TCP_SOCKET.LocalPort] |
1737 | mov eax, [eax + IP_SOCKET.RemoteIP] ; dest ip |
Line 1802... | Line 1738... | ||
1802 | rol word [esp], 8 |
1738 | ; mov ecx, ; data length |
1803 | pop [edi + TCP_segment.SourcePort] |
1739 | ; mov dx, ; fragment id |
- | 1740 | mov di, IP_PROTO_TCP shl 8 + 128 |
|
- | 1741 | call IPv4_output |
|
- | 1742 | jz .fail |
|
- | 1743 | ||
Line 1804... | Line -... | ||
1804 | - | ||
1805 | push [esi + TCP_SOCKET.RemotePort] |
1744 | ;----------------------------------------- |
1806 | rol word [esp], 8 |
1745 | ; Move TCP header from stack to TCP packet |
Line 1807... | Line 1746... | ||
1807 | pop [edi + TCP_segment.DestinationPort] |
1746 | |
1808 | 1747 | ; pop ecx ; header size |
|
Line 1809... | Line -... | ||
1809 | - | ||
1810 | mov [edi + TCP_segment.Window], 0x0005 |
- | |
1811 | ; 1280 bytes |
- | |
1812 | mov [edi + TCP_segment.UrgentPointer], 0 |
1748 | ; mov esi, esp |
1813 | 1749 | ; add esp, ecx |
|
1814 | mov [edi + TCP_segment.DataOffset], 0x50 |
1750 | ; shr ecx, 2 |
Line -... | Line 1751... | ||
- | 1751 | ; rep movsd |
|
- | 1752 | ||
- | 1753 | mov ecx, [esp] |
|
- | 1754 | lea esi, [esp+4] |
|
- | 1755 | shr ecx, 2 |
|
- | 1756 | rep movsd |
|
- | 1757 | ||
- | 1758 | pop ecx |
|
- | 1759 | add esp, ecx |
|
- | 1760 | ||
1815 | 1761 | mov [esp + 3*4+4], edx ; packet size |
|
1816 | mov [edi + TCP_segment.Flags], cl |
1762 | mov [esp + 3*4], eax ; packet ptr |
1817 | 1763 | ||
1818 | mov [edi + TCP_segment.Checksum], 0 |
1764 | mov edx, edi |
1819 | 1765 | sub edx, ecx |
|
Line 1891... | Line 1837... | ||
1891 | db TH_SYN + TH_ACK ; TCB_LAST_ACK |
1837 | db TH_SYN + TH_ACK ; TCB_LAST_ACK |
1892 | db TH_ACK ; TCB_FIN_WAIT_2 |
1838 | db TH_ACK ; TCB_FIN_WAIT_2 |
1893 | db TH_ACK ; TCB_TIMED_WAIT |
1839 | db TH_ACK ; TCB_TIMED_WAIT |
Line -... | Line 1840... | ||
- | 1840 | ||
- | 1841 | ||
1894 | 1842 | ||
1895 | 1843 | ||
1896 | ;------------------------- |
1844 | ;------------------------- |
1897 | ; |
1845 | ; |
1898 | ; TCP_drop |
1846 | ; TCP_drop |
Line 1922... | Line 1870... | ||
1922 | 1870 | ||
1923 | 1871 | ||
1924 | - | ||
1925 | ;--------------------------------------- |
- | |
1926 | ; |
1872 | |
1927 | ; TCP_ack |
1873 | ;--------------------------------------- |
1928 | ; |
1874 | ; |
1929 | ; The easy way to send an ACK/RST/keepalive segment |
- | |
1930 | ; |
- | |
1931 | ; IN: eax = socket ptr |
- | |
1932 | ; -or- |
1875 | ; The easy way to send an ACK/RST/keepalive segment |
- | 1876 | ; |
|
1933 | ; edx = packet ptr (eax must be 0) |
1877 | ; TCP_respond_socket: |
1934 | ; cl = flags |
1878 | ; |
1935 | ; |
1879 | ; IN: ebx = socket ptr |
1936 | ; OUT: / |
1880 | ; cl = flags |
1937 | ; |
1881 | ; |
Line 1938... | Line 1882... | ||
1938 | ;--------------------------------------- |
1882 | ;-------------------------------------- |
Line 1939... | Line 1883... | ||
1939 | align 4 |
1883 | align 4 |
1940 | TCP_respond: |
1884 | TCP_respond_socket: |
Line 1941... | Line 1885... | ||
1941 | 1885 | ||
1942 | DEBUGF 1,"TCP_respond\n" |
1886 | DEBUGF 1,"TCP_respond_socket\n" |
1943 | 1887 | ||
1944 | ;--------------------- |
1888 | ;--------------------- |
1945 | ; Create the IP packet |
1889 | ; Create the IP packet |
1946 | 1890 | ||
1947 | push cx eax edx |
1891 | push cx ebx |
1948 | mov ebx, [eax + IP_SOCKET.LocalIP] |
1892 | mov eax, [ebx + IP_SOCKET.RemoteIP] |
1949 | mov eax, [eax + IP_SOCKET.RemoteIP] |
- | |
1950 | mov ecx, TCP_segment.Data |
- | |
1951 | mov di , IP_PROTO_TCP |
- | |
1952 | call IPv4_create_packet |
- | |
1953 | test edi, edi |
1893 | mov ebx, [ebx + IP_SOCKET.LocalIP] |
1954 | jz .error |
- | |
1955 | - | ||
1956 | ;--------------------------- |
- | |
1957 | ; Now fill in the TCP header |
- | |
1958 | - | ||
1959 | pop ecx |
- | |
1960 | pop esi |
1894 | mov ecx, TCP_segment.Data |
Line -... | Line 1895... | ||
- | 1895 | mov di , IP_PROTO_TCP shl 8 + 128 |
|
- | 1896 | call IPv4_output |
|
- | 1897 | test edi, edi |
|
- | 1898 | jz .error |
|
- | 1899 | pop esi cx |
|
- | 1900 | push edx eax |
|
- | 1901 | ||
- | 1902 | ;----------------------------------------------- |
|
- | 1903 | ; Fill in the TCP header by using the socket ptr |
|
- | 1904 | ||
- | 1905 | mov ax, [esi + TCP_SOCKET.LocalPort] |
|
- | 1906 | rol ax, 8 |
|
- | 1907 | stosw |
|
- | 1908 | mov ax, [esi + TCP_SOCKET.RemotePort] |
|
- | 1909 | rol ax, 8 |
|
- | 1910 | stosw |
|
- | 1911 | mov eax, [esi + TCP_SOCKET.SND_NXT] |
|
- | 1912 | bswap eax |
|
- | 1913 | stosd |
|
- | 1914 | mov eax, [esi + TCP_SOCKET.RCV_NXT] |
|
- | 1915 | bswap eax |
|
1961 | 1916 | stosd |
|
1962 | test esi, esi |
1917 | mov al, 0x50 ; Dataoffset: 20 bytes |
1963 | ; jz |
1918 | stosb |
Line 1964... | Line 1919... | ||
1964 | 1919 | mov al, cl |
|
1965 | 1920 | stosb |
|
Line 1966... | Line 1921... | ||
1966 | push edx eax |
1921 | mov ax, [esi + TCP_SOCKET.RCV_WND] |
1967 | - | ||
1968 | push dword .checksum |
1922 | rol ax, 8 |
1969 | je .use_segment |
- | |
1970 | jmp .use_socket |
1923 | stosw ; window |
1971 | 1924 | xor eax, eax |
|
- | 1925 | stosd ; checksum + urgentpointer |
|
1972 | ;--------------------- |
1926 | |
Line 1973... | Line 1927... | ||
1973 | ; Fill in the checksum |
1927 | ;--------------------- |
1974 | 1928 | ; Fill in the checksum |
|
Line 1975... | Line 1929... | ||
1975 | .checksum: |
1929 | |
1976 | 1930 | .checksum: |
|
Line 1977... | Line 1931... | ||
1977 | push [esi + IP_SOCKET.LocalIP] |
1931 | sub edi, TCP_segment.Data |
1978 | push [esi + IP_SOCKET.RemoteIP] |
1932 | mov ecx, TCP_segment.Data |
1979 | lea esi, [edi - 20] |
1933 | xchg esi, edi |
Line 1980... | Line 1934... | ||
1980 | xor ecx, ecx |
1934 | TCP_checksum (edi + IP_SOCKET.LocalIP), (esi + IP_SOCKET.RemoteIP) |
Line -... | Line 1935... | ||
- | 1935 | mov [esi+TCP_segment.Checksum], dx |
|
- | 1936 | ||
- | 1937 | ;-------------------- |
|
- | 1938 | ; And send the segment |
|
- | 1939 | ||
- | 1940 | call [ebx + NET_DEVICE.transmit] |
|
- | 1941 | ret |
|
- | 1942 | ||
- | 1943 | .error: |
|
- | 1944 | DEBUGF 1,"TCP_respond failed\n" |
|
- | 1945 | add esp, 2+4 |
|
- | 1946 | ||
- | 1947 | ret |
|
- | 1948 | ||
- | 1949 | ||
- | 1950 | ||
- | 1951 | ;------------------------- |
|
- | 1952 | ; TCP_respond.segment: |
|
- | 1953 | ; |
|
- | 1954 | ; IN: edx = segment ptr (a previously received segment) |
|
- | 1955 | ; cl = flags |
|
- | 1956 | ||
- | 1957 | align 4 |
|
- | 1958 | TCP_respond_segment: |
|
- | 1959 | ||
- | 1960 | DEBUGF 1,"TCP_respond_segment\n" |
|
- | 1961 | ||
- | 1962 | ;--------------------- |
|
1981 | call TCP_checksum |
1963 | ; Create the IP packet |
1982 | 1964 | ||
Line 1983... | Line -... | ||
1983 | ;-------------------- |
- | |
1984 | ; And send the segment |
- | |
1985 | 1965 | push cx edx |
|
1986 | call [ebx + NET_DEVICE.transmit] |
1966 | mov ebx, [edx - 20 + IPv4_Packet.SourceAddress] ;;;; and what if ip packet had options?! |
1987 | ret |
1967 | mov eax, [edx - 20 + IPv4_Packet.DestinationAddress] ;;; |
1988 | 1968 | mov ecx, TCP_segment.Data |
|
1989 | .error: |
1969 | mov di , IP_PROTO_TCP shl 8 + 128 |
Line 2016... | Line 1996... | ||
2016 | rol ax, 8 |
1996 | rol ax, 8 |
2017 | stosw ; window |
1997 | stosw ; window |
2018 | xor eax, eax |
1998 | xor eax, eax |
2019 | stosd ; checksum + urgentpointer |
1999 | stosd ; checksum + urgentpointer |
Line 2020... | Line -... | ||
2020 | - | ||
2021 | ret |
- | |
2022 | - | ||
2023 | 2000 | ||
2024 | ;----------------------------------------------- |
2001 | ;--------------------- |
Line 2025... | Line 2002... | ||
2025 | ; Fill in the TCP header by using the socket ptr |
2002 | ; Fill in the checksum |
- | 2003 | ||
- | 2004 | .checksum: |
|
- | 2005 | lea esi, [edi - TCP_segment.Data] |
|
- | 2006 | mov ecx, TCP_segment.Data |
|
Line 2026... | Line -... | ||
2026 | - | ||
2027 | .use_socket: |
- | |
2028 | - | ||
2029 | mov ax, [esi + TCP_SOCKET.LocalPort] |
- | |
2030 | rol ax, 8 |
- | |
2031 | stosw |
- | |
2032 | mov ax, [esi + TCP_SOCKET.RemotePort] |
- | |
2033 | rol ax, 8 |
- | |
2034 | stosw |
- | |
2035 | mov eax, [esi + TCP_SOCKET.SND_NXT] |
- | |
2036 | bswap eax |
- | |
2037 | stosd |
- | |
2038 | mov eax, [esi + TCP_SOCKET.RCV_NXT] |
- | |
2039 | bswap eax |
- | |
2040 | stosd |
- | |
2041 | mov al, 0x50 ; Dataoffset: 20 bytes |
- | |
2042 | stosb |
- | |
2043 | mov al, cl |
- | |
2044 | stosb |
2007 | TCP_checksum (esi - 20 + IPv4_Packet.DestinationAddress), (esi - 20 + IPv4_Packet.DestinationAddress) |
2045 | mov ax, [esi + TCP_SOCKET.RCV_WND] |
- | |
2046 | rol ax, 8 |
2008 | mov [esi+TCP_segment.Checksum], dx |
Line -... | Line 2009... | ||
- | 2009 | ||
2047 | stosw ; window |
2010 | ;-------------------- |
Line -... | Line 2011... | ||
- | 2011 | ; And send the segment |
|
- | 2012 | ||
- | 2013 | call [ebx + NET_DEVICE.transmit] |
|
Line 2048... | Line -... | ||
2048 | xor eax, eax |
- | |
2049 | stosd ; checksum + urgentpointer |
- | |
2050 | - | ||
2051 | ret |
- | |
2052 | - | ||
2053 | - | ||
2054 | - | ||
2055 | ;----------------------------------------------------------------- |
- | |
2056 | ; |
- | |
2057 | ; TCP_checksum |
- | |
2058 | ; |
- | |
2059 | ; This is the fast procedure to create or check a UDP header |
- | |
2060 | ; - To create a new checksum, the checksum field must be set to 0 before computation |
- | |
2061 | ; - To check an existing checksum, leave the checksum as is, |
- | |
2062 | ; and it will be 0 after this procedure, if it was correct |
- | |
2063 | ; |
- | |
2064 | ; IN: push source ip |
- | |
2065 | ; push dest ip |
- | |
2066 | ; |
- | |
2067 | ; esi = packet ptr |
- | |
2068 | ; |
- | |
2069 | ; OUT: checksum is filled in in packet! (but also in dx) |
- | |
2070 | ; |
- | |
2071 | ;----------------------------------------------------------------- |
- | |
2072 | align 4 |
- | |
2073 | TCP_checksum: |
- | |
2074 | - | ||
2075 | ;------------- |
- | |
2076 | ; Pseudoheader |
- | |
2077 | - | ||
2078 | ; protocol type |
- | |
2079 | mov edx, IP_PROTO_TCP ; NO shl 8 here ! (it took me ages to figure this one out) |
- | |
2080 | - | ||
2081 | ; source address |
- | |
2082 | add dl, [esp+1+4] |
- | |
2083 | adc dh, [esp+0+4] |
- | |
2084 | adc dl, [esp+3+4] |
- | |
2085 | adc dh, [esp+2+4] |
- | |
2086 | - | ||
2087 | ; destination address |
- | |
2088 | adc dl, [esp+1+8] |
- | |
2089 | adc dh, [esp+0+8] |
- | |
2090 | adc dl, [esp+3+8] |
- | |
2091 | adc dh, [esp+2+8] |
- | |
2092 | - | ||
2093 | ; size |
- | |
2094 | adc dl, cl |
- | |
2095 | adc dh, ch |
- | |
2096 | - | ||
2097 | ;--------------------- |
2014 | ret |
2098 | ; Real header and data |
- | |
2099 | - | ||
2100 | push esi |
- | |
2101 | call checksum_1 |
- | |
2102 | call checksum_2 |
- | |
Line 2103... | Line 2015... | ||
2103 | pop esi |
2015 |