Rev 2301 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2301 | Rev 2305 | ||
---|---|---|---|
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: 2301 $ |
17 | $Revision: 2305 $ |
18 | 18 | ||
19 | ;----------------------------------------------------------------- |
19 | ;----------------------------------------------------------------- |
20 | ; |
20 | ; |
Line 37... | Line 37... | ||
37 | TCP_input: |
37 | TCP_input: |
Line 38... | Line 38... | ||
38 | 38 | ||
39 | DEBUGF 1,"TCP_input size=%u ", ecx |
39 | DEBUGF 1,"TCP_input size=%u ", ecx |
Line 40... | Line 40... | ||
40 | ; 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. |
40 | ; 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. |
41 | 41 | ||
42 | movzx eax, [edx + TCP_segment.DataOffset] |
42 | movzx eax, [edx + TCP_header.DataOffset] |
Line 43... | Line 43... | ||
43 | and eax, 0xf0 |
43 | and eax, 0xf0 |
Line 44... | Line 44... | ||
44 | shr al, 2 |
44 | shr al, 2 |
45 | 45 | ||
Line 46... | Line 46... | ||
46 | DEBUGF 1,"headersize=%u\n", eax |
46 | DEBUGF 1,"headersize=%u\n", eax |
47 | 47 | ||
Line 48... | Line 48... | ||
48 | cmp eax, TCP_segment.DataOffset |
48 | cmp eax, TCP_header.DataOffset |
49 | jb .drop_not_locked |
49 | jb .drop_not_locked |
50 | 50 | ||
51 | ;------------------------------- |
51 | ;------------------------------- |
52 | ; Now, re-calculate the checksum |
52 | ; Now, re-calculate the checksum |
53 | 53 | ||
54 | push eax ecx edx |
54 | push eax ecx edx |
55 | pushw [edx + TCP_segment.Checksum] |
55 | pushw [edx + TCP_header.Checksum] |
Line 70... | Line 70... | ||
70 | DEBUGF 1,"we got %u bytes of data\n", ecx |
70 | DEBUGF 1,"we got %u bytes of data\n", ecx |
Line 71... | Line 71... | ||
71 | 71 | ||
72 | ;----------------------------------------------------------------------------------------- |
72 | ;----------------------------------------------------------------------------------------- |
Line 73... | Line 73... | ||
73 | ; Check if this packet has a timestamp option (We do it here so we can process it quickly) |
73 | ; Check if this packet has a timestamp option (We do it here so we can process it quickly) |
74 | 74 | ||
75 | cmp esi, TCP_segment.DataOffset + 12 ; Timestamp option is 12 bytes |
75 | cmp esi, TCP_header.DataOffset + 12 ; Timestamp option is 12 bytes |
Line 76... | Line 76... | ||
76 | jb .no_timestamp |
76 | jb .no_timestamp |
77 | je .is_ok |
77 | je .is_ok |
Line 78... | Line 78... | ||
78 | 78 | ||
79 | cmp byte [edx + TCP_segment.Data + 12], TCP_OPT_EOL ; end of option list |
79 | cmp byte [edx + sizeof.TCP_header + 12], TCP_OPT_EOL ; end of option list |
80 | jne .no_timestamp |
80 | jne .no_timestamp |
Line 81... | Line 81... | ||
81 | 81 | ||
82 | .is_ok: |
82 | .is_ok: |
Line 83... | Line 83... | ||
83 | test [edx + TCP_segment.Flags], TH_SYN ; SYN flag must not be set |
83 | test [edx + TCP_header.Flags], TH_SYN ; SYN flag must not be set |
Line 84... | Line 84... | ||
84 | jnz .no_timestamp |
84 | jnz .no_timestamp |
Line 94... | Line 94... | ||
94 | .no_timestamp: |
94 | .no_timestamp: |
Line 95... | Line 95... | ||
95 | 95 | ||
96 | ;------------------------------------------- |
96 | ;------------------------------------------- |
Line 97... | Line 97... | ||
97 | ; Convert Big-endian values to little endian |
97 | ; Convert Big-endian values to little endian |
98 | 98 | ||
Line 99... | Line 99... | ||
99 | ntohd [edx + TCP_segment.SequenceNumber] |
99 | ntohd [edx + TCP_header.SequenceNumber] |
100 | ntohd [edx + TCP_segment.AckNumber] |
100 | ntohd [edx + TCP_header.AckNumber] |
101 | 101 | ||
102 | ntohw [edx + TCP_segment.Window] |
102 | ntohw [edx + TCP_header.Window] |
Line 103... | Line 103... | ||
103 | ntohw [edx + TCP_segment.UrgentPointer] |
103 | ntohw [edx + TCP_header.UrgentPointer] |
104 | ntohw [edx + TCP_segment.SourcePort] |
104 | ntohw [edx + TCP_header.SourcePort] |
Line 105... | Line 105... | ||
105 | ntohw [edx + TCP_segment.DestinationPort] |
105 | ntohw [edx + TCP_header.DestinationPort] |
Line 122... | Line 122... | ||
122 | jne .socket_loop |
122 | jne .socket_loop |
Line 123... | Line 123... | ||
123 | 123 | ||
124 | cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP |
124 | cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP |
Line 125... | Line 125... | ||
125 | jne .socket_loop |
125 | jne .socket_loop |
126 | 126 | ||
127 | mov ax, [edx + TCP_segment.DestinationPort] |
127 | mov ax, [edx + TCP_header.DestinationPort] |
Line 128... | Line 128... | ||
128 | cmp [ebx + TCP_SOCKET.LocalPort], ax |
128 | cmp [ebx + TCP_SOCKET.LocalPort], ax |
129 | jne .socket_loop |
129 | jne .socket_loop |
Line 134... | Line 134... | ||
134 | test eax, eax |
134 | test eax, eax |
135 | jnz .socket_loop |
135 | jnz .socket_loop |
136 | @@: |
136 | @@: |
Line 137... | Line 137... | ||
137 | 137 | ||
138 | mov ax, [ebx + TCP_SOCKET.RemotePort] |
138 | mov ax, [ebx + TCP_SOCKET.RemotePort] |
139 | cmp [edx + TCP_segment.SourcePort] , ax |
139 | cmp [edx + TCP_header.SourcePort] , ax |
140 | je .found_socket |
140 | je .found_socket |
141 | test ax, ax |
141 | test ax, ax |
142 | jnz .socket_loop |
142 | jnz .socket_loop |
143 | .found_socket: |
143 | .found_socket: |
Line 166... | Line 166... | ||
166 | DEBUGF 1,"Socket locked\n" |
166 | DEBUGF 1,"Socket locked\n" |
Line 167... | Line 167... | ||
167 | 167 | ||
168 | ;--------------------------------------- |
168 | ;--------------------------------------- |
Line 169... | Line 169... | ||
169 | ; unscale the window into a 32 bit value |
169 | ; unscale the window into a 32 bit value |
170 | 170 | ||
171 | movzx eax, [edx + TCP_segment.Window] |
171 | movzx eax, [edx + TCP_header.Window] |
172 | push ecx |
172 | push ecx |
173 | mov cl, [ebx + TCP_SOCKET.SND_SCALE] |
173 | mov cl, [ebx + TCP_SOCKET.SND_SCALE] |
174 | shl eax, cl |
174 | shl eax, cl |
Line 175... | Line 175... | ||
175 | mov dword [edx + TCP_segment.Window], eax ; word after window is checksum, we dont need checksum anymore |
175 | mov dword [edx + TCP_header.Window], eax ; word after window is checksum, we dont need checksum anymore |
176 | pop ecx |
176 | pop ecx |
Line 187... | Line 187... | ||
187 | call SOCKET_fork |
187 | call SOCKET_fork |
Line 188... | Line 188... | ||
188 | 188 | ||
189 | test eax, eax |
189 | test eax, eax |
Line 190... | Line 190... | ||
190 | jz .drop |
190 | jz .drop |
191 | 191 | ||
Line 192... | Line 192... | ||
192 | push [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.DestinationAddress] ;;; FIXME |
192 | push [edx - sizeof.IPv4_header + IPv4_header.DestinationAddress] ;;; FIXME |
193 | pop [eax + IP_SOCKET.LocalIP] |
193 | pop [eax + IP_SOCKET.LocalIP] |
Line 194... | Line 194... | ||
194 | 194 | ||
Line 195... | Line 195... | ||
195 | push [edx + TCP_segment.DestinationPort] |
195 | push [edx + TCP_header.DestinationPort] |
Line 211... | Line 211... | ||
211 | mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval |
211 | mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval |
Line 212... | Line 212... | ||
212 | 212 | ||
213 | ;-------------------- |
213 | ;-------------------- |
Line 214... | Line 214... | ||
214 | ; Process TCP options |
214 | ; Process TCP options |
215 | 215 | ||
Line 216... | Line 216... | ||
216 | cmp esi, TCP_segment.DataOffset ; esi is headersize |
216 | cmp esi, TCP_header.DataOffset ; esi is headersize |
Line 217... | Line 217... | ||
217 | je .no_options |
217 | je .no_options |
218 | 218 | ||
Line 219... | Line 219... | ||
219 | DEBUGF 1,"Segment has options\n" |
219 | DEBUGF 1,"Segment has options\n" |
220 | 220 | ||
Line 221... | Line 221... | ||
221 | cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state |
221 | cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state |
222 | jz .not_uni_xfer ; also no header prediction |
222 | jz .not_uni_xfer ; also no header prediction |
223 | 223 | ||
Line 251... | Line 251... | ||
251 | 251 | ||
252 | .opt_maxseg: |
252 | .opt_maxseg: |
253 | cmp byte [edi+1], 4 |
253 | cmp byte [edi+1], 4 |
Line 254... | Line 254... | ||
254 | jne .no_options ; error occured, ignore all options! |
254 | jne .no_options ; error occured, ignore all options! |
255 | 255 | ||
Line 256... | Line 256... | ||
256 | test [edx + TCP_segment.Flags], TH_SYN |
256 | test [edx + TCP_header.Flags], TH_SYN |
257 | jz @f |
257 | jz @f |
258 | 258 | ||
Line 269... | Line 269... | ||
269 | 269 | ||
270 | .opt_window: |
270 | .opt_window: |
271 | cmp byte [edi+1], 3 |
271 | cmp byte [edi+1], 3 |
Line 272... | Line 272... | ||
272 | jne .no_options |
272 | jne .no_options |
273 | 273 | ||
Line 274... | Line 274... | ||
274 | test [edx + TCP_segment.Flags], TH_SYN |
274 | test [edx + TCP_header.Flags], TH_SYN |
Line 275... | Line 275... | ||
275 | jz @f |
275 | jz @f |
Line 316... | Line 316... | ||
316 | ; If the packets are in order (data queue is empty), add the data to the socket buffer and request a delayed ACK |
316 | ; If the packets are in order (data queue is empty), add the data to the socket buffer and request a delayed ACK |
Line 317... | Line 317... | ||
317 | 317 | ||
318 | cmp [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED |
318 | cmp [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED |
Line 319... | Line 319... | ||
319 | jnz .not_uni_xfer |
319 | jnz .not_uni_xfer |
320 | 320 | ||
Line 321... | Line 321... | ||
321 | test [edx + TCP_segment.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG |
321 | test [edx + TCP_header.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG |
322 | jnz .not_uni_xfer |
322 | jnz .not_uni_xfer |
Line 323... | Line 323... | ||
323 | 323 | ||
324 | test [edx + TCP_segment.Flags], TH_ACK |
324 | test [edx + TCP_header.Flags], TH_ACK |
325 | jz .not_uni_xfer |
325 | jz .not_uni_xfer |
Line 326... | Line 326... | ||
326 | 326 | ||
327 | mov eax, [edx + TCP_segment.SequenceNumber] |
327 | mov eax, [edx + TCP_header.SequenceNumber] |
328 | cmp eax, [ebx + TCP_SOCKET.RCV_NXT] |
328 | cmp eax, [ebx + TCP_SOCKET.RCV_NXT] |
Line 329... | Line 329... | ||
329 | jne .not_uni_xfer |
329 | jne .not_uni_xfer |
330 | 330 | ||
Line 350... | Line 350... | ||
350 | mov eax, [ebx + TCP_SOCKET.SND_CWND] |
350 | mov eax, [ebx + TCP_SOCKET.SND_CWND] |
351 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
351 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
352 | jb .not_uni_xfer |
352 | jb .not_uni_xfer |
Line 353... | Line 353... | ||
353 | 353 | ||
354 | ; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent. |
354 | ; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent. |
355 | mov eax, [edx + TCP_segment.AckNumber] |
355 | mov eax, [edx + TCP_header.AckNumber] |
356 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
356 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
Line 357... | Line 357... | ||
357 | ja .not_uni_xfer |
357 | ja .not_uni_xfer |
358 | 358 | ||
Line 375... | Line 375... | ||
375 | lea eax, [ebx + STREAM_SOCKET.snd] |
375 | lea eax, [ebx + STREAM_SOCKET.snd] |
376 | call SOCKET_ring_free |
376 | call SOCKET_ring_free |
377 | popa |
377 | popa |
Line 378... | Line 378... | ||
378 | 378 | ||
379 | ; update window pointers |
379 | ; update window pointers |
380 | mov eax, [edx + TCP_segment.AckNumber] |
380 | mov eax, [edx + TCP_header.AckNumber] |
Line 381... | Line 381... | ||
381 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
381 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
382 | 382 | ||
Line 398... | Line 398... | ||
398 | 398 | ||
399 | .not_sender: |
399 | .not_sender: |
Line 400... | Line 400... | ||
400 | ; - The amount of data in the segment is greater than 0 (data count is in ecx) |
400 | ; - The amount of data in the segment is greater than 0 (data count is in ecx) |
401 | 401 | ||
402 | ; - The acknowledgment field equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment. |
402 | ; - The acknowledgment field equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment. |
403 | mov eax, [edx + TCP_segment.AckNumber] |
403 | mov eax, [edx + TCP_header.AckNumber] |
Line 404... | Line 404... | ||
404 | cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
404 | cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
Line 439... | Line 439... | ||
439 | 439 | ||
Line 440... | Line 440... | ||
440 | DEBUGF 1,"Header prediction failed\n" |
440 | DEBUGF 1,"Header prediction failed\n" |
Line -... | Line 441... | ||
- | 441 | ||
- | 442 | ; Calculate receive window size |
|
- | 443 | ||
- | 444 | ; mov eax, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.size] |
|
- | 445 | ; neg eax |
|
- | 446 | ; add eax, SOCKETBUFFSIZE |
|
- | 447 | ; mov edx, [ebx + TCP_SOCKET.RCV_ADV] |
|
- | 448 | ; sub edx, [ebx + TCP_SOCKET.RCV_NXT] |
|
441 | 449 | ; cmp eax, edx |
|
Line 442... | Line 450... | ||
442 | ; Calculate receive window size |
450 | ; jae @f |
443 | 451 | ; mov eax, edx |
|
Line 444... | Line 452... | ||
444 | ;;;; TODO: 444 |
452 | ; @@: |
Line 459... | Line 467... | ||
459 | align 4 |
467 | align 4 |
460 | .LISTEN: |
468 | .LISTEN: |
Line 461... | Line 469... | ||
461 | 469 | ||
Line 462... | Line 470... | ||
462 | DEBUGF 1,"TCP state: listen\n" |
470 | DEBUGF 1,"TCP state: listen\n" |
463 | 471 | ||
Line 464... | Line 472... | ||
464 | test [edx + TCP_segment.Flags], TH_RST ;;; TODO: kill new socket on error |
472 | test [edx + TCP_header.Flags], TH_RST ;;; TODO: kill new socket on error |
465 | jnz .drop |
473 | jnz .drop |
Line 466... | Line 474... | ||
466 | 474 | ||
467 | test [edx + TCP_segment.Flags], TH_ACK |
475 | test [edx + TCP_header.Flags], TH_ACK |
Line 468... | Line 476... | ||
468 | jnz .drop_with_reset |
476 | jnz .drop_with_reset |
Line 469... | Line 477... | ||
469 | 477 | ||
470 | test [edx + TCP_segment.Flags], TH_SYN |
478 | test [edx + TCP_header.Flags], TH_SYN |
Line 471... | Line 479... | ||
471 | jz .drop |
479 | jz .drop |
472 | 480 | ||
Line 473... | Line 481... | ||
473 | ;;; TODO: check if it's a broadcast or multicast, and drop if so |
481 | ;;; TODO: check if it's a broadcast or multicast, and drop if so |
474 | 482 | ||
Line 475... | Line 483... | ||
475 | push [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.SourceAddress] ;;; FIXME |
483 | push [edx - sizeof.IPv4_header + IPv4_header.SourceAddress] ;;; FIXME |
476 | pop [ebx + IP_SOCKET.RemoteIP] |
484 | pop [ebx + IP_SOCKET.RemoteIP] |
477 | 485 | ||
Line 520... | Line 528... | ||
520 | align 4 |
528 | align 4 |
521 | .SYN_SENT: |
529 | .SYN_SENT: |
Line 522... | Line 530... | ||
522 | 530 | ||
Line 523... | Line 531... | ||
523 | DEBUGF 1,"TCP state: syn_sent\n" |
531 | DEBUGF 1,"TCP state: syn_sent\n" |
524 | 532 | ||
Line 525... | Line 533... | ||
525 | test [edx + TCP_segment.Flags], TH_ACK |
533 | test [edx + TCP_header.Flags], TH_ACK |
526 | jz @f |
534 | jz @f |
527 | 535 | ||
Line 528... | Line 536... | ||
528 | mov eax, [edx + TCP_segment.AckNumber] |
536 | mov eax, [edx + TCP_header.AckNumber] |
529 | cmp eax, [ebx + TCP_SOCKET.ISS] |
537 | cmp eax, [ebx + TCP_SOCKET.ISS] |
530 | jbe .drop_with_reset |
538 | jbe .drop_with_reset |
Line 531... | Line 539... | ||
531 | 539 | ||
532 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
540 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
Line 533... | Line 541... | ||
533 | ja .drop_with_reset |
541 | ja .drop_with_reset |
534 | @@: |
542 | @@: |
Line 535... | Line 543... | ||
535 | 543 | ||
536 | test [edx + TCP_segment.Flags], TH_RST |
544 | test [edx + TCP_header.Flags], TH_RST |
537 | jz @f |
545 | jz @f |
Line 538... | Line 546... | ||
538 | 546 | ||
539 | test [edx + TCP_segment.Flags], TH_ACK |
547 | test [edx + TCP_header.Flags], TH_ACK |
Line 540... | Line 548... | ||
540 | jz .drop |
548 | jz .drop |
541 | 549 | ||
Line 542... | Line 550... | ||
542 | mov eax, ebx |
550 | mov eax, ebx |
Line 543... | Line 551... | ||
543 | mov ebx, ECONNREFUSED |
551 | mov ebx, ECONNREFUSED |
544 | call TCP_drop |
552 | call TCP_drop |
Line 545... | Line 553... | ||
545 | 553 | ||
Line 546... | Line 554... | ||
546 | jmp .drop |
554 | jmp .drop |
547 | @@: |
555 | @@: |
548 | 556 | ||
549 | test [edx + TCP_segment.Flags], TH_SYN |
557 | test [edx + TCP_header.Flags], TH_SYN |
550 | jz .drop |
558 | jz .drop |
551 | 559 | ||
Line 552... | Line 560... | ||
552 | ; at this point, segment seems to be valid |
560 | ; at this point, segment seems to be valid |
Line 553... | Line 561... | ||
553 | 561 | ||
Line 554... | Line 562... | ||
554 | test [edx + TCP_segment.Flags], TH_ACK |
562 | test [edx + TCP_header.Flags], TH_ACK |
555 | jz .no_syn_ack |
563 | jz .no_syn_ack |
Line 556... | Line 564... | ||
556 | 564 | ||
Line 557... | Line 565... | ||
557 | ; now, process received SYN in response to an active open |
565 | ; now, process received SYN in response to an active open |
Line 558... | Line 566... | ||
558 | 566 | ||
559 | mov eax, [edx + TCP_segment.AckNumber] |
567 | mov eax, [edx + TCP_header.AckNumber] |
560 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
568 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
Line 561... | Line 569... | ||
561 | cmp eax, [ebx + TCP_SOCKET.SND_NXT] |
569 | cmp eax, [ebx + TCP_SOCKET.SND_NXT] |
562 | jbe @f |
570 | jbe @f |
Line 563... | Line 571... | ||
563 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
571 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
Line 564... | Line 572... | ||
564 | @@: |
572 | @@: |
Line 611... | Line 619... | ||
611 | ;------------------------------------- |
619 | ;------------------------------------- |
612 | ; Common processing for receipt of SYN |
620 | ; Common processing for receipt of SYN |
Line 613... | Line 621... | ||
613 | 621 | ||
Line 614... | Line 622... | ||
614 | .trim_then_step6: |
622 | .trim_then_step6: |
Line 615... | Line 623... | ||
615 | 623 | ||
Line 616... | Line 624... | ||
616 | inc [edx + TCP_segment.SequenceNumber] |
624 | inc [edx + TCP_header.SequenceNumber] |
617 | 625 | ||
618 | ;;; TODO: Drop any received data that follows receive window (590) |
626 | ;;; TODO: Drop any received data that follows receive window (590) |
619 | 627 | ||
Line 620... | Line 628... | ||
620 | mov eax, [edx + TCP_segment.SequenceNumber] |
628 | mov eax, [edx + TCP_header.SequenceNumber] |
Line 657... | Line 665... | ||
657 | ; trim any data not in window |
665 | ; trim any data not in window |
Line 658... | Line 666... | ||
658 | 666 | ||
Line 659... | Line 667... | ||
659 | ; check for duplicate data at beginning of segment |
667 | ; check for duplicate data at beginning of segment |
660 | 668 | ||
661 | mov eax, [ebx + TCP_SOCKET.RCV_NXT] |
669 | mov eax, [ebx + TCP_SOCKET.RCV_NXT] |
Line 662... | Line 670... | ||
662 | sub eax, [edx + TCP_segment.SequenceNumber] |
670 | sub eax, [edx + TCP_header.SequenceNumber] |
Line 663... | Line 671... | ||
663 | jbe .no_duplicate |
671 | jbe .no_duplicate |
664 | 672 | ||
Line 665... | Line 673... | ||
665 | DEBUGF 1,"Uh oh.. %u bytes of duplicate data!\n", eax |
673 | DEBUGF 1,"Uh oh.. %u bytes of duplicate data!\n", eax |
Line 666... | Line 674... | ||
666 | 674 | ||
667 | test [edx + TCP_segment.Flags], TH_SYN |
675 | test [edx + TCP_header.Flags], TH_SYN |
Line 668... | Line 676... | ||
668 | jz .no_dup_syn |
676 | jz .no_dup_syn |
669 | 677 | ||
670 | ; remove duplicate syn |
678 | ; remove duplicate syn |
671 | 679 | ||
672 | and [edx + TCP_segment.Flags], not (TH_SYN) |
680 | and [edx + TCP_header.Flags], not (TH_SYN) |
673 | inc [edx + TCP_segment.SequenceNumber] |
681 | inc [edx + TCP_header.SequenceNumber] |
674 | 682 | ||
675 | cmp [edx + TCP_segment.UrgentPointer], 1 |
683 | cmp [edx + TCP_header.UrgentPointer], 1 |
676 | jbe @f |
684 | jbe @f |
Line 677... | Line 685... | ||
677 | dec [edx + TCP_segment.UrgentPointer] |
685 | dec [edx + TCP_header.UrgentPointer] |
Line 693... | Line 701... | ||
693 | 701 | ||
Line 694... | Line 702... | ||
694 | ;;; TODO: apply figure 28.30 |
702 | ;;; TODO: apply figure 28.30 |
Line 695... | Line 703... | ||
695 | 703 | ||
696 | ; Check for duplicate FIN |
704 | ; Check for duplicate FIN |
697 | 705 | ||
698 | test [edx + TCP_segment.Flags], TH_FIN |
706 | test [edx + TCP_header.Flags], TH_FIN |
699 | jz @f |
707 | jz @f |
700 | inc ecx |
708 | inc ecx |
Line 701... | Line 709... | ||
701 | cmp eax, ecx |
709 | cmp eax, ecx |
702 | dec ecx |
710 | dec ecx |
703 | jne @f |
711 | jne @f |
704 | 712 | ||
705 | mov eax, ecx |
713 | mov eax, ecx |
Line 706... | Line 714... | ||
706 | and [edx + TCP_segment.Flags], not TH_FIN |
714 | and [edx + TCP_header.Flags], not TH_FIN |
Line 717... | Line 725... | ||
717 | ; This code also handles simultaneous half-open or self-connects |
725 | ; This code also handles simultaneous half-open or self-connects |
Line 718... | Line 726... | ||
718 | 726 | ||
719 | test eax, eax |
727 | test eax, eax |
Line 720... | Line 728... | ||
720 | jnz .drop_after_ack |
728 | jnz .drop_after_ack |
721 | 729 | ||
Line 722... | Line 730... | ||
722 | cmp [edx + TCP_segment.Flags], TH_ACK |
730 | cmp [edx + TCP_header.Flags], TH_ACK |
Line 723... | Line 731... | ||
723 | jz .drop_after_ack |
731 | jz .drop_after_ack |
Line 736... | Line 744... | ||
736 | .no_duplicate: |
744 | .no_duplicate: |
Line 737... | Line 745... | ||
737 | 745 | ||
738 | ;----------------------------------------------- |
746 | ;----------------------------------------------- |
Line 739... | Line 747... | ||
739 | ; Remove duplicate data and update urgent offset |
747 | ; Remove duplicate data and update urgent offset |
Line 740... | Line 748... | ||
740 | 748 | ||
Line 741... | Line 749... | ||
741 | add [edx + TCP_segment.SequenceNumber], eax |
749 | add [edx + TCP_header.SequenceNumber], eax |
742 | 750 | ||
Line 743... | Line 751... | ||
743 | ;;; TODO |
751 | ;;; TODO |
744 | 752 | ||
745 | sub [edx + TCP_segment.UrgentPointer], ax |
753 | sub [edx + TCP_header.UrgentPointer], ax |
Line 746... | Line 754... | ||
746 | ja @f |
754 | ja @f |
747 | 755 | ||
Line 768... | Line 776... | ||
768 | @@: |
776 | @@: |
Line 769... | Line 777... | ||
769 | 777 | ||
770 | ;---------------------------------------- |
778 | ;---------------------------------------- |
Line 771... | Line 779... | ||
771 | ; Remove data beyond right edge of window |
779 | ; Remove data beyond right edge of window |
772 | 780 | ||
773 | mov eax, [edx + TCP_segment.SequenceNumber] |
781 | mov eax, [edx + TCP_header.SequenceNumber] |
774 | add eax, ecx |
782 | add eax, ecx |
Line 775... | Line 783... | ||
775 | sub eax, [ebx + TCP_SOCKET.RCV_NXT] |
783 | sub eax, [ebx + TCP_SOCKET.RCV_NXT] |
Line 807... | Line 815... | ||
807 | 815 | ||
808 | 816 | ||
Line 809... | Line 817... | ||
809 | ;------------------ |
817 | ;------------------ |
810 | ; Process RST flags |
818 | ; Process RST flags |
Line 811... | Line 819... | ||
811 | 819 | ||
Line 812... | Line 820... | ||
812 | test [edx + TCP_segment.Flags], TH_RST |
820 | test [edx + TCP_header.Flags], TH_RST |
Line 868... | Line 876... | ||
868 | 876 | ||
869 | 877 | ||
Line 870... | Line 878... | ||
870 | ;-------------------------------------- |
878 | ;-------------------------------------- |
871 | ; handle SYN-full and ACK-less segments |
879 | ; handle SYN-full and ACK-less segments |
Line 872... | Line 880... | ||
872 | 880 | ||
873 | test [edx + TCP_segment.Flags], TH_SYN |
881 | test [edx + TCP_header.Flags], TH_SYN |
874 | jz @f |
882 | jz @f |
875 | 883 | ||
Line 876... | Line 884... | ||
876 | mov eax, ebx |
884 | mov eax, ebx |
877 | mov ebx, ECONNRESET |
885 | mov ebx, ECONNRESET |
878 | call TCP_drop |
886 | call TCP_drop |
Line 894... | Line 902... | ||
894 | cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED |
902 | cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED |
895 | jnz .no_syn_rcv |
903 | jnz .no_syn_rcv |
Line 896... | Line 904... | ||
896 | 904 | ||
Line 897... | Line 905... | ||
897 | DEBUGF 1,"TCP state = syn received\n" |
905 | DEBUGF 1,"TCP state = syn received\n" |
898 | 906 | ||
899 | mov eax, [edx + TCP_segment.AckNumber] |
907 | mov eax, [edx + TCP_header.AckNumber] |
900 | cmp [ebx + TCP_SOCKET.SND_UNA], eax |
908 | cmp [ebx + TCP_SOCKET.SND_UNA], eax |
901 | ja .drop_with_reset |
909 | ja .drop_with_reset |
Line 918... | Line 926... | ||
918 | 926 | ||
Line 919... | Line 927... | ||
919 | @@: |
927 | @@: |
Line 920... | Line 928... | ||
920 | 928 | ||
921 | ;;; 813 ? |
929 | ;;; 813 ? |
922 | 930 | ||
923 | mov eax, [edx + TCP_segment.SequenceNumber] |
931 | mov eax, [edx + TCP_header.SequenceNumber] |
Line 924... | Line 932... | ||
924 | dec eax |
932 | dec eax |
Line 925... | Line 933... | ||
925 | mov [ebx + TCP_SOCKET.SND_WL1], eax |
933 | mov [ebx + TCP_SOCKET.SND_WL1], eax |
Line 926... | Line 934... | ||
926 | jmp .not_dup_ack |
934 | jmp .not_dup_ack |
927 | 935 | ||
928 | .no_syn_rcv: |
936 | .no_syn_rcv: |
Line 929... | Line 937... | ||
929 | 937 | ||
930 | ; check for duplicate ACK |
938 | ; check for duplicate ACK |
Line 931... | Line 939... | ||
931 | 939 | ||
932 | mov eax, [edx + TCP_segment.AckNumber] |
940 | mov eax, [edx + TCP_header.AckNumber] |
933 | cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
941 | cmp eax, [ebx + TCP_SOCKET.SND_UNA] |
Line 934... | Line 942... | ||
934 | ja .not_dup_ack |
942 | ja .not_dup_ack |
Line 935... | Line 943... | ||
935 | 943 | ||
936 | test ecx, ecx |
944 | test ecx, ecx |
Line 937... | Line 945... | ||
937 | jnz .reset_dupacks |
945 | jnz .reset_dupacks |
938 | 946 | ||
939 | mov eax, dword [edx + TCP_segment.Window] |
947 | mov eax, dword [edx + TCP_header.Window] |
Line 940... | Line 948... | ||
940 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
948 | cmp eax, [ebx + TCP_SOCKET.SND_WND] |
941 | jne .reset_dupacks |
949 | jne .reset_dupacks |
Line 975... | Line 983... | ||
975 | pop edx |
983 | pop edx |
976 | mov [ebx + TCP_SOCKET.SND_SSTHRESH], eax |
984 | mov [ebx + TCP_SOCKET.SND_SSTHRESH], eax |
Line 977... | Line 985... | ||
977 | 985 | ||
978 | mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; turn off retransmission timer |
986 | mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; turn off retransmission timer |
979 | mov [ebx + TCP_SOCKET.t_rtt], 0 |
987 | mov [ebx + TCP_SOCKET.t_rtt], 0 |
980 | mov eax, [edx + TCP_segment.AckNumber] |
988 | mov eax, [edx + TCP_header.AckNumber] |
981 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
989 | mov [ebx + TCP_SOCKET.SND_NXT], eax |
982 | mov eax, [ebx + TCP_SOCKET.t_maxseg] |
990 | mov eax, [ebx + TCP_SOCKET.t_maxseg] |
Line 983... | Line 991... | ||
983 | mov [ebx + TCP_SOCKET.SND_CWND], eax |
991 | mov [ebx + TCP_SOCKET.SND_CWND], eax |
Line 1034... | Line 1042... | ||
1034 | mov [ebx + TCP_SOCKET.SND_CWND], eax |
1042 | mov [ebx + TCP_SOCKET.SND_CWND], eax |
1035 | @@: |
1043 | @@: |
Line 1036... | Line 1044... | ||
1036 | 1044 | ||
Line 1037... | Line 1045... | ||
1037 | mov [ebx + TCP_SOCKET.t_dupacks], 0 |
1045 | mov [ebx + TCP_SOCKET.t_dupacks], 0 |
1038 | 1046 | ||
1039 | mov eax, [edx + TCP_segment.AckNumber] |
1047 | mov eax, [edx + TCP_header.AckNumber] |
Line 1040... | Line 1048... | ||
1040 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
1048 | cmp eax, [ebx + TCP_SOCKET.SND_MAX] |
1041 | jbe @f |
1049 | jbe @f |
Line 1042... | Line 1050... | ||
1042 | 1050 | ||
Line 1043... | Line 1051... | ||
1043 | ;;; TODO: update stats |
1051 | ;;; TODO: update stats |
1044 | jmp .drop_after_ack |
1052 | jmp .drop_after_ack |
Line 1045... | Line 1053... | ||
1045 | 1053 | ||
Line 1064... | Line 1072... | ||
1064 | ;;;;; 912 - 926 |
1072 | ;;;;; 912 - 926 |
Line 1065... | Line 1073... | ||
1065 | 1073 | ||
Line 1066... | Line 1074... | ||
1066 | mov [ebx + TCP_SOCKET.timer_retransmission], 0 |
1074 | mov [ebx + TCP_SOCKET.timer_retransmission], 0 |
1067 | 1075 | ||
1068 | mov eax, [ebx + TCP_SOCKET.SND_MAX] |
1076 | mov eax, [ebx + TCP_SOCKET.SND_MAX] |
1069 | cmp eax, [edx + TCP_segment.AckNumber] |
1077 | cmp eax, [edx + TCP_header.AckNumber] |
1070 | je .all_outstanding |
1078 | je .all_outstanding |
Line 1129... | Line 1137... | ||
1129 | mov eax, ebx |
1137 | mov eax, ebx |
1130 | call SOCKET_notify_owner |
1138 | call SOCKET_notify_owner |
Line 1131... | Line 1139... | ||
1131 | 1139 | ||
Line 1132... | Line 1140... | ||
1132 | ; Update TCPS |
1140 | ; Update TCPS |
1133 | 1141 | ||
Line 1134... | Line 1142... | ||
1134 | mov eax, [edx + TCP_segment.AckNumber] |
1142 | mov eax, [edx + TCP_header.AckNumber] |
1135 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
1143 | mov [ebx + TCP_SOCKET.SND_UNA], eax |
1136 | 1144 | ||
Line 1219... | Line 1227... | ||
1219 | DEBUGF 1,"ACK processed\n" |
1227 | DEBUGF 1,"ACK processed\n" |
Line 1220... | Line 1228... | ||
1220 | 1228 | ||
1221 | ;---------------------------------------------- |
1229 | ;---------------------------------------------- |
Line 1222... | Line 1230... | ||
1222 | ; check if we need to update window information |
1230 | ; check if we need to update window information |
1223 | 1231 | ||
Line 1224... | Line 1232... | ||
1224 | test [edx + TCP_segment.Flags], TH_ACK |
1232 | test [edx + TCP_header.Flags], TH_ACK |
1225 | jz .no_window_update |
1233 | jz .no_window_update |
1226 | 1234 | ||
1227 | mov eax, [ebx + TCP_SOCKET.SND_WL1] |
1235 | mov eax, [ebx + TCP_SOCKET.SND_WL1] |
Line 1228... | Line 1236... | ||
1228 | cmp eax, [edx + TCP_segment.SequenceNumber] |
1236 | cmp eax, [edx + TCP_header.SequenceNumber] |
1229 | jb .update_window |
1237 | jb .update_window |
1230 | ja @f |
1238 | ja @f |
1231 | 1239 | ||
1232 | mov eax, [ebx + TCP_SOCKET.SND_WL2] |
1240 | mov eax, [ebx + TCP_SOCKET.SND_WL2] |
Line 1233... | Line 1241... | ||
1233 | cmp eax, [edx + TCP_segment.AckNumber] |
1241 | cmp eax, [edx + TCP_header.AckNumber] |
1234 | jb .update_window |
1242 | jb .update_window |
1235 | ja .no_window_update |
1243 | ja .no_window_update |
Line 1236... | Line 1244... | ||
1236 | @@: |
1244 | @@: |
1237 | 1245 | ||
1238 | mov eax, [ebx + TCP_SOCKET.SND_WL2] |
1246 | mov eax, [ebx + TCP_SOCKET.SND_WL2] |
Line 1239... | Line 1247... | ||
1239 | cmp eax, [edx + TCP_segment.AckNumber] |
1247 | cmp eax, [edx + TCP_header.AckNumber] |
Line 1251... | Line 1259... | ||
1251 | 1259 | ||
1252 | ; test ecx, ecx |
1260 | ; test ecx, ecx |
1253 | ; jz @f |
1261 | ; jz @f |
1254 | ; |
1262 | ; |
1255 | ; mov eax, [ebx + TCP_SOCKET.SND_WL2] |
1263 | ; mov eax, [ebx + TCP_SOCKET.SND_WL2] |
1256 | ; cmp eax, [edx + TCP_segment.AckNumber] |
1264 | ; cmp eax, [edx + TCP_header.AckNumber] |
1257 | ; jne @f |
1265 | ; jne @f |
1258 | ; |
1266 | ; |
1259 | ; ;; mov eax, tiwin |
1267 | ; ;; mov eax, tiwin |
1260 | ; cmp eax, [ebx + TCP_SOCKET.SND_WND] |
1268 | ; cmp eax, [ebx + TCP_SOCKET.SND_WND] |
1261 | ; jbe @f |
1269 | ; jbe @f |
1262 | ; |
1270 | ; |
1263 | ; ;;; update stats |
1271 | ; ;;; update stats |
1264 | ; |
1272 | ; |
Line 1265... | Line 1273... | ||
1265 | ; @@: |
1273 | ; @@: |
1266 | 1274 | ||
1267 | mov eax, dword [edx + TCP_segment.Window] |
1275 | mov eax, dword [edx + TCP_header.Window] |
1268 | cmp eax, [ebx + TCP_SOCKET.max_sndwnd] |
1276 | cmp eax, [ebx + TCP_SOCKET.max_sndwnd] |
1269 | jbe @f |
1277 | jbe @f |
1270 | mov [ebx + TCP_SOCKET.max_sndwnd], eax |
1278 | mov [ebx + TCP_SOCKET.max_sndwnd], eax |
Line 1271... | Line 1279... | ||
1271 | @@: |
1279 | @@: |
1272 | mov [ebx + TCP_SOCKET.SND_WND], eax |
1280 | mov [ebx + TCP_SOCKET.SND_WND], eax |
Line 1273... | Line 1281... | ||
1273 | 1281 | ||
1274 | push [edx + TCP_segment.SequenceNumber] |
1282 | push [edx + TCP_header.SequenceNumber] |
Line 1275... | Line 1283... | ||
1275 | pop [ebx + TCP_SOCKET.SND_WL1] |
1283 | pop [ebx + TCP_SOCKET.SND_WL1] |
Line 1276... | Line 1284... | ||
1276 | 1284 | ||
Line 1288... | Line 1296... | ||
1288 | 1296 | ||
1289 | 1297 | ||
Line 1290... | Line 1298... | ||
1290 | ;----------------- |
1298 | ;----------------- |
1291 | ; process URG flag |
1299 | ; process URG flag |
Line 1292... | Line 1300... | ||
1292 | 1300 | ||
1293 | test [edx + TCP_segment.Flags], TH_URG |
1301 | test [edx + TCP_header.Flags], TH_URG |
Line 1294... | Line 1302... | ||
1294 | jz .not_urgent |
1302 | jz .not_urgent |
1295 | 1303 | ||
Line 1296... | Line 1304... | ||
1296 | cmp [edx + TCP_segment.UrgentPointer], 0 |
1304 | cmp [edx + TCP_header.UrgentPointer], 0 |
Line 1297... | Line 1305... | ||
1297 | jz .not_urgent |
1305 | jz .not_urgent |
Line 1298... | Line 1306... | ||
1298 | 1306 | ||
1299 | cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT |
1307 | cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT |
1300 | je .not_urgent |
1308 | je .not_urgent |
1301 | 1309 | ||
Line 1302... | Line 1310... | ||
1302 | ; Ignore bogus urgent offsets |
1310 | ; Ignore bogus urgent offsets |
1303 | 1311 | ||
1304 | ;;; 1040-1050 |
1312 | ;;; 1040-1050 |
Line 1305... | Line 1313... | ||
1305 | 1313 | ||
Line 1306... | Line 1314... | ||
1306 | movzx eax, [edx + TCP_segment.UrgentPointer] |
1314 | movzx eax, [edx + TCP_header.UrgentPointer] |
Line 1330... | Line 1338... | ||
1330 | 1338 | ||
Line 1331... | Line 1339... | ||
1331 | .do_data: |
1339 | .do_data: |
Line 1332... | Line 1340... | ||
1332 | 1340 | ||
1333 | DEBUGF 1,"TCP: do data (%u)\n", ecx |
1341 | DEBUGF 1,"TCP: do data (%u)\n", ecx |
Line 1334... | Line 1342... | ||
1334 | 1342 | ||
1335 | test [edx + TCP_segment.Flags], TH_FIN |
1343 | test [edx + TCP_header.Flags], TH_FIN |
Line 1343... | Line 1351... | ||
1343 | 1351 | ||
Line 1344... | Line 1352... | ||
1344 | DEBUGF 1,"Processing data in segment\n" |
1352 | DEBUGF 1,"Processing data in segment\n" |
Line 1345... | Line 1353... | ||
1345 | 1353 | ||
1346 | ;; TODO: check if data is in sequence ! |
1354 | ;; TODO: check if data is in sequence ! |
1347 | 1355 | ||
Line 1348... | Line 1356... | ||
1348 | movzx eax, [edx + TCP_segment.DataOffset] ;;; todo: remember this in.. edi ? |
1356 | movzx eax, [edx + TCP_header.DataOffset] ;;; todo: remember this in.. edi ? |
Line 1485... | Line 1493... | ||
1485 | align 4 |
1493 | align 4 |
1486 | .drop_after_ack: |
1494 | .drop_after_ack: |
Line 1487... | Line 1495... | ||
1487 | 1495 | ||
Line 1488... | Line 1496... | ||
1488 | DEBUGF 1,"Drop after ACK\n" |
1496 | DEBUGF 1,"Drop after ACK\n" |
1489 | 1497 | ||
Line 1490... | Line 1498... | ||
1490 | test [edx + TCP_segment.Flags], TH_RST |
1498 | test [edx + TCP_header.Flags], TH_RST |
Line 1491... | Line 1499... | ||
1491 | jnz .drop |
1499 | jnz .drop |
Line 1522... | Line 1530... | ||
1522 | 1530 | ||
Line 1523... | Line 1531... | ||
1523 | .drop_with_reset_not_locked: |
1531 | .drop_with_reset_not_locked: |
Line 1524... | Line 1532... | ||
1524 | 1532 | ||
1525 | DEBUGF 1,"Drop with reset\n" |
1533 | DEBUGF 1,"Drop with reset\n" |
Line 1526... | Line 1534... | ||
1526 | 1534 | ||
Line 1527... | Line 1535... | ||
1527 | test [edx + TCP_segment.Flags], TH_RST |
1535 | test [edx + TCP_header.Flags], TH_RST |
1528 | jnz .drop |
1536 | jnz .drop |
Line 1529... | Line 1537... | ||
1529 | 1537 | ||
1530 | ;;; if its a multicast/broadcast, also drop |
1538 | ;;; if its a multicast/broadcast, also drop |
Line 1531... | Line 1539... | ||
1531 | 1539 | ||
1532 | test [edx + TCP_segment.Flags], TH_ACK |
1540 | test [edx + TCP_header.Flags], TH_ACK |
1533 | jnz .respond_ack |
1541 | jnz .respond_ack |