Rev 593 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
431 | serge | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
3 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
||
4 | ;; Distributed under terms of the GNU General Public License ;; |
||
5 | ;; ;; |
||
6 | ;; TCP.INC ;; |
||
7 | ;; ;; |
||
8 | ;; TCP Processes for Menuet OS TCP/IP stack ;; |
||
9 | ;; ;; |
||
10 | ;; Version 0.6 4th July 2004 ;; |
||
11 | ;; ;; |
||
12 | ;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
||
13 | ;; ;; |
||
14 | ;; See file COPYING for details ;; |
||
15 | ;; v0.6 : Added reset handling in the established state ;; |
||
16 | ;; Added a timer per socket to allow delays when ;; |
||
17 | ;; rx window gets below 1KB ;; |
||
18 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1 | ha | 19 | |
593 | mikedld | 20 | $Revision: 871 $ |
21 | |||
22 | |||
261 | hidnplayr | 23 | ; TCP TCB states |
24 | TCB_LISTEN equ 1 |
||
25 | TCB_SYN_SENT equ 2 |
||
26 | TCB_SYN_RECEIVED equ 3 |
||
27 | TCB_ESTABLISHED equ 4 |
||
28 | TCB_FIN_WAIT_1 equ 5 |
||
29 | TCB_FIN_WAIT_2 equ 6 |
||
30 | TCB_CLOSE_WAIT equ 7 |
||
31 | TCB_CLOSING equ 8 |
||
32 | TCB_LAST_ACK equ 9 |
||
33 | TCB_TIME_WAIT equ 10 |
||
34 | TCB_CLOSED equ 11 |
||
1 | ha | 35 | |
261 | hidnplayr | 36 | TWOMSL equ 10 ; # of secs to wait before closing socket |
37 | |||
38 | TCP_RETRIES equ 5 ; Number of times to resend a packet |
||
39 | TCP_TIMEOUT equ 10 ; resend if not replied to in x hs |
||
40 | |||
1 | ha | 41 | ;******************************************************************* |
42 | ; Interface |
||
43 | ; |
||
44 | ; tcp_tx_handler Handles the TCP transmit queue |
||
45 | ; tcp_rx The protocol handler for received data |
||
46 | ; buildTCPPacket fills in the packet headers and data |
||
47 | ; tcpStateMachine Main state machine for received TCP packets |
||
48 | ; tcp_tcb_handler 1s timer, to erase tcb's in TIME_WAIT state |
||
49 | ; |
||
50 | ;******************************************************************* |
||
51 | |||
52 | |||
261 | hidnplayr | 53 | ; TCP Payload ( Data field in IP datagram ) |
54 | ; |
||
55 | ; 0 1 2 3 |
||
56 | ; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
||
57 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
58 | ;20 | Source Port | Destination Port | |
||
59 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
60 | ;24 | Sequence Number | |
||
61 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
62 | ;28 | Acknowledgment Number | |
||
63 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
64 | ;32 | Data | |U|A|P|R|S|F| | |
||
65 | ; | Offset| Reserved |R|C|S|S|Y|I| Window | |
||
66 | ; | | |G|K|H|T|N|N| | |
||
67 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
68 | ;36 | Checksum | Urgent Pointer | |
||
69 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
70 | ;40 | Options | Padding | |
||
71 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
72 | ; | data |
||
1 | ha | 73 | |
261 | hidnplayr | 74 | |
75 | struc TCP_PACKET |
||
76 | { .SourcePort dw ? ;+00 |
||
77 | .DestinationPort dw ? ;+02 |
||
78 | .SequenceNumber dd ? ;+04 |
||
79 | .AckNumber dd ? ;+08 |
||
80 | .DataOffset db ? ;+12 - DataOffset[0-3 bits] and Reserved[4-7] |
||
81 | .Flags db ? ;+13 - Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN |
||
82 | .Window dw ? ;+14 |
||
83 | .Checksum dw ? ;+16 |
||
84 | .UrgentPointer dw ? ;+18 |
||
85 | .Options rb 3 ;+20 |
||
86 | .Padding db ? ;+23 |
||
87 | .Data db ? ;+24 |
||
88 | } |
||
89 | |||
90 | virtual at 0 |
||
91 | TCP_PACKET TCP_PACKET |
||
92 | end virtual |
||
93 | |||
94 | |||
95 | |||
1 | ha | 96 | ;*************************************************************************** |
97 | ; Function |
||
98 | ; tcp_tcb_handler |
||
99 | ; |
||
100 | ; Description |
||
101 | ; Handles sockets in the timewait state, closing them |
||
102 | ; when the TCB timer expires |
||
103 | ; |
||
104 | ;*************************************************************************** |
||
105 | tcp_tcb_handler: |
||
106 | ; scan through all the sockets, decrementing active timers |
||
107 | |||
108 | mov eax, SOCKETBUFFSIZE * NUM_SOCKETS |
||
109 | mov ecx, NUM_SOCKETS |
||
110 | |||
111 | tth1: |
||
112 | sub eax, SOCKETBUFFSIZE |
||
113 | cmp [eax + sockets + 32], dword 0 |
||
114 | jne tth2 |
||
115 | |||
116 | tth1a: |
||
117 | cmp [eax + sockets + 72], dword 0 |
||
118 | jne tth4 |
||
119 | |||
120 | loop tth1 |
||
121 | ret |
||
122 | |||
123 | tth2: |
||
124 | ; decrement it, delete socket if TCB timer = 0 & socket in timewait state |
||
125 | pusha |
||
126 | dec dword [eax + sockets + 32] |
||
127 | cmp [eax + sockets + 32], dword 0 |
||
128 | jne tth3 |
||
129 | |||
130 | cmp [eax + sockets + 28], dword TCB_TIME_WAIT |
||
131 | jne tth3 |
||
132 | |||
133 | ; OK, delete socket |
||
134 | mov edi, eax |
||
135 | add edi, sockets |
||
136 | |||
137 | xor eax, eax |
||
138 | mov ecx, SOCKETHEADERSIZE |
||
139 | cld |
||
140 | rep stosb |
||
141 | |||
142 | tth3: |
||
143 | popa |
||
144 | |||
145 | jmp tth1a |
||
146 | |||
147 | loop tth1 |
||
148 | ret |
||
149 | |||
150 | ; TODO - prove it works! |
||
151 | tth4: |
||
152 | dec dword [eax + sockets + 72] |
||
153 | loop tth1 |
||
154 | ret |
||
155 | |||
156 | |||
157 | |||
158 | |||
159 | tth_exit: |
||
160 | ret |
||
161 | |||
162 | |||
163 | ;*************************************************************************** |
||
164 | ; Function |
||
165 | ; tcp_tx_handler |
||
166 | ; |
||
167 | ; Description |
||
168 | ; Handles queued TCP data |
||
169 | ; This is a kernel function, called by stack_handler |
||
170 | ; |
||
171 | ;*************************************************************************** |
||
172 | tcp_tx_handler: |
||
173 | ; decrement all resend buffers timers. If they |
||
174 | ; expire, queue them for sending, and restart the timer. |
||
175 | ; If the retries counter reach 0, delete the entry |
||
176 | |||
177 | mov esi, resendQ |
||
178 | mov ecx, 0 |
||
179 | |||
180 | tth001: |
||
181 | cmp ecx, NUMRESENDENTRIES |
||
182 | je tth003 ; None left |
||
183 | cmp [esi], byte 0xFF |
||
261 | hidnplayr | 184 | jne tth002 ; found one |
1 | ha | 185 | inc ecx |
186 | add esi, 4 |
||
187 | jmp tth001 |
||
188 | |||
189 | tth002: |
||
190 | ; we have one. decrement it's timer by 1 |
||
191 | dec word [esi+2] |
||
192 | mov ax, [esi+2] |
||
193 | cmp ax, 0 |
||
261 | hidnplayr | 194 | je tth002a |
1 | ha | 195 | inc ecx |
196 | add esi, 4 |
||
197 | jmp tth001 ; Timer not zero, so move on |
||
198 | |||
199 | tth002a: |
||
200 | mov bl, 0xff |
||
201 | ; restart timer, and decrement retries |
||
202 | ; After the first resend, back of on next, by a factor of 5 |
||
203 | mov [esi+2], word TCP_TIMEOUT * 5 |
||
204 | dec byte [esi+1] |
||
205 | mov al, [esi+1] |
||
206 | cmp al, 0 |
||
207 | jne tth004 |
||
208 | |||
209 | ; retries now 0, so delete from queue |
||
210 | xchg [esi], bl |
||
211 | tth004: |
||
212 | |||
213 | ; resend packet |
||
214 | pusha |
||
215 | |||
216 | mov eax, EMPTY_QUEUE |
||
217 | call dequeue |
||
218 | cmp ax, NO_BUFFER |
||
219 | jne tth004z |
||
220 | |||
221 | ; TODO - try again in 10ms. |
||
222 | cmp bl, 0xff |
||
223 | jne tth004za |
||
224 | mov [esi], bl |
||
225 | |||
226 | tth004za: |
||
227 | ; Mark it to expire in 10ms - 1 tick |
||
228 | mov [esi+1], byte 1 |
||
229 | mov [esi+2], word 1 |
||
230 | jmp tth005 |
||
231 | |||
232 | tth004z: |
||
233 | ; we have a buffer # in ax |
||
234 | |||
235 | push eax |
||
236 | push ecx |
||
237 | mov ecx, IPBUFFSIZE |
||
238 | mul ecx |
||
239 | add eax, IPbuffs |
||
240 | |||
241 | ; we have the buffer address in eax |
||
242 | mov edi, eax |
||
243 | pop ecx |
||
244 | ; get resend data address |
||
245 | inc ecx |
||
246 | ; Now get buffer location, and copy buffer across. argh! more copying,, |
||
247 | mov esi, resendBuffer - IPBUFFSIZE |
||
248 | tth004a: |
||
249 | add esi, IPBUFFSIZE |
||
250 | loop tth004a |
||
251 | |||
252 | ; we have resend buffer location in esi |
||
253 | mov ecx, IPBUFFSIZE |
||
254 | |||
255 | ; copy data across |
||
256 | cld |
||
257 | rep movsb |
||
258 | |||
259 | ; queue packet |
||
260 | |||
261 | |||
262 | |||
263 | mov eax, NET1OUT_QUEUE |
||
264 | |||
265 | mov edx, [stack_ip] |
||
266 | mov ecx, [ edi + 16 ] |
||
267 | cmp edx, ecx |
||
268 | jne tth004b |
||
269 | mov eax, IPIN_QUEUE |
||
270 | |||
271 | tth004b: |
||
272 | pop ebx |
||
273 | |||
274 | call queue |
||
275 | |||
276 | |||
277 | tth005: |
||
278 | popa |
||
279 | |||
280 | inc ecx |
||
281 | add esi, 4 |
||
282 | jmp tth001 |
||
283 | |||
284 | tth003: |
||
285 | ret |
||
286 | |||
287 | |||
288 | |||
289 | |||
290 | ;*************************************************************************** |
||
291 | ; Function |
||
292 | ; tcp_rx |
||
293 | ; |
||
294 | ; Description |
||
295 | ; TCP protocol handler |
||
296 | ; This is a kernel function, called by ip_rx |
||
297 | ; IP buffer address given in edx |
||
298 | ; IP buffer number in eax |
||
299 | ; Free up (or re-use) IP buffer when finished |
||
300 | ; |
||
301 | ;*************************************************************************** |
||
302 | tcp_rx: |
||
303 | ; The process is as follows. |
||
304 | ; Look for a socket with matching remote IP, remote port, local port |
||
305 | ; if not found, then |
||
306 | ; look for remote IP + local port match ( where sockets remote port = 0) |
||
307 | ; if not found, then |
||
308 | ; look for a socket where local socket port == IP packets remote port |
||
309 | ; where sockets remote port, remote IP = 0 |
||
310 | ; discard if not found |
||
311 | ; Call sockets tcbStateMachine, with pointer to packet. |
||
312 | ; the state machine will not delete the packet, so do that here. |
||
313 | |||
314 | push eax |
||
315 | |||
316 | ; Look for a socket where |
||
317 | ; IP Packet TCP Destination Port = local Port |
||
318 | ; IP Packet SA = Remote IP |
||
319 | ; IP Packet TCP Source Port = remote Port |
||
320 | |||
321 | mov eax, SOCKETBUFFSIZE * NUM_SOCKETS |
||
322 | mov ecx, NUM_SOCKETS |
||
323 | ss1: |
||
324 | sub eax, SOCKETBUFFSIZE |
||
325 | movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr |
||
326 | cmp [eax + sockets + 12], bx ; compare with socket's local port |
||
327 | jnz nxttst1 ; different - try next socket |
||
328 | |||
329 | movzx ebx, word [edx + 20] ; get the source port from the TCP hdr |
||
330 | cmp [eax + sockets + 20], bx ; compare with socket's remote port |
||
331 | jnz nxttst1 ; different - try next socket |
||
332 | |||
333 | |||
334 | mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr |
||
335 | cmp [eax + sockets + 16], ebx ; compare with socket's remote IP |
||
336 | jnz nxttst1 ; different - try next socket |
||
337 | |||
338 | ; We have a complete match - use this socket |
||
339 | jmp tcprx_001 |
||
340 | |||
341 | nxttst1: |
||
342 | loop ss1 ; Return back if no match |
||
343 | |||
344 | ; If we got here, there was no match |
||
345 | ; Look for a socket where |
||
346 | ; IP Packet TCP Destination Port = local Port |
||
347 | ; IP Packet SA = Remote IP |
||
348 | ; socket remote Port = 0 |
||
349 | |||
350 | mov eax, SOCKETBUFFSIZE * NUM_SOCKETS |
||
351 | mov ecx, NUM_SOCKETS |
||
352 | |||
353 | ss2: |
||
354 | sub eax, SOCKETBUFFSIZE |
||
355 | |||
356 | movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr |
||
357 | cmp [eax + sockets + 12], bx ; compare with socket's local port |
||
358 | jnz nxttst2 ; different - try next socket |
||
359 | |||
360 | mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr |
||
361 | cmp [eax + sockets + 16], ebx ; compare with socket's remote IP |
||
362 | jnz nxttst2 ; different - try next socket |
||
363 | |||
364 | mov ebx, 0 |
||
365 | cmp [eax + sockets + 20], bx ; only match a remote socket of 0 |
||
366 | jnz nxttst2 ; different - try next socket |
||
367 | |||
368 | ; We have a complete match - use this socket |
||
369 | jmp tcprx_001 |
||
370 | |||
371 | nxttst2: |
||
372 | loop ss2 ; Return back if no match |
||
373 | |||
374 | ; If we got here, there was no match |
||
375 | ; Look for a socket where |
||
376 | ; IP Packet TCP Destination Port = local Port |
||
377 | ; socket Remote IP = 0 |
||
378 | ; socket remote Port = 0 |
||
379 | |||
380 | mov eax, SOCKETBUFFSIZE * NUM_SOCKETS |
||
381 | mov ecx, NUM_SOCKETS |
||
382 | |||
383 | ss3: |
||
384 | sub eax, SOCKETBUFFSIZE |
||
385 | |||
386 | movzx ebx, word [edx + 22] ; get destination port from the TCP hdr |
||
387 | cmp [eax + sockets + 12], bx ; compare with socket's local port |
||
388 | jnz nxttst3 ; different - try next socket |
||
389 | |||
390 | mov ebx, 0 |
||
391 | cmp [eax + sockets + 20], bx ; only match a remote socket of 0 |
||
392 | jnz nxttst3 ; different - try next socket |
||
393 | |||
394 | mov ebx, 0 |
||
395 | cmp [eax + sockets + 16], ebx ; only match a socket remote IP of 0 |
||
396 | jnz nxttst3 ; different - try next socket |
||
397 | |||
398 | ; We have a complete match - use this socket |
||
399 | jmp tcprx_001 |
||
400 | |||
401 | nxttst3: |
||
402 | loop ss3 ; Return back if no match |
||
403 | |||
404 | ; If we got here, we need to reject the packet |
||
405 | inc dword [dumped_rx_count] |
||
406 | jmp tcprx_exit |
||
407 | |||
408 | tcprx_001: |
||
409 | ; We have a valid socket/TCB, so call the TCB State Machine for that skt. |
||
410 | ; socket is pointed to by [eax + sockets] |
||
411 | ; IP packet is pointed to by [edx] |
||
412 | ; IP buffer number is on stack ( it will be popped at the end) |
||
413 | call tcpStateMachine |
||
414 | |||
415 | tcprx_exit: |
||
416 | pop eax |
||
417 | call freeBuff |
||
418 | |||
419 | ret |
||
420 | |||
421 | |||
422 | |||
423 | ;*************************************************************************** |
||
424 | ; Function |
||
425 | ; buildTCPPacket |
||
426 | ; |
||
427 | ; Description |
||
428 | ; builds an IP Packet with TCP data fully populated for transmission |
||
429 | ; You may destroy any and all registers |
||
430 | ; TCP control flags specified in bl |
||
431 | ; This TCB is in [sktAddr] |
||
432 | ; User data pointed to by esi |
||
433 | ; Data length in ecx |
||
434 | ; Transmit buffer number in eax |
||
435 | ; |
||
436 | ;*************************************************************************** |
||
437 | buildTCPPacket: |
||
438 | push ecx ; Save data length |
||
439 | |||
440 | ; convert buffer pointer eax to the absolute address |
||
441 | mov ecx, IPBUFFSIZE |
||
442 | mul ecx |
||
443 | add eax, IPbuffs |
||
444 | |||
445 | mov edx, eax |
||
446 | |||
447 | mov [edx + 33], bl ; TCP flags |
||
448 | |||
449 | mov ebx, [sktAddr] |
||
450 | |||
451 | ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr |
||
452 | |||
453 | ; Fill in the IP header ( some data is in the socket descriptor) |
||
454 | mov eax, [ebx + 8] |
||
455 | mov [edx + 12], eax ; source IP |
||
456 | mov eax, [ebx + 16] |
||
457 | mov [edx + 16], eax ; Destination IP |
||
458 | |||
459 | mov al, 0x45 |
||
460 | mov [edx], al ; Version, IHL |
||
461 | xor al, al |
||
462 | mov [edx + 1], al ; Type of service |
||
463 | |||
464 | pop eax ; Get the TCP data length |
||
465 | push eax |
||
466 | |||
467 | add eax, 20 + 20 ; add IP header and TCP header lengths |
||
468 | mov [edx + 2], ah |
||
469 | mov [edx + 3], al |
||
470 | xor al, al |
||
471 | mov [edx + 4], al |
||
472 | mov [edx + 5], al |
||
473 | mov al, 0x40 |
||
474 | mov [edx + 6], al |
||
475 | xor al, al |
||
476 | mov [edx + 7], al |
||
477 | mov al, 0x20 |
||
478 | mov [edx + 8], al |
||
479 | mov al, 6 ; TCP protocol |
||
480 | mov [edx + 9], al |
||
481 | |||
482 | ; Checksum left unfilled |
||
483 | xor ax, ax |
||
484 | mov [edx + 10], ax |
||
485 | |||
486 | ; Fill in the TCP header ( some data is in the socket descriptor) |
||
487 | mov ax, [ebx + 12] |
||
488 | mov [edx + 20], ax ; Local Port |
||
489 | |||
490 | mov ax, [ebx + 20] |
||
491 | mov [edx + 20 + 2], ax ; desitination Port |
||
492 | |||
493 | ; Checksum left unfilled |
||
494 | xor ax, ax |
||
495 | mov [edx + 20 + 16], ax |
||
496 | |||
497 | ; sequence number |
||
498 | mov eax, [ebx + 48] |
||
499 | mov [edx + 20 + 4], eax |
||
500 | |||
501 | ; ack number |
||
502 | mov eax, [ebx + 56] |
||
503 | mov [edx + 20 + 8], eax |
||
504 | |||
505 | ; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size) |
||
506 | ; 768 bytes seems better |
||
507 | mov ax, 0x0003 |
||
508 | mov [edx + 20 + 14], ax |
||
509 | |||
510 | ; Urgent pointer (0) |
||
511 | mov ax, 0 |
||
512 | mov [edx + 20 + 18], ax |
||
513 | |||
514 | ; data offset ( 0x50 ) |
||
515 | mov al, 0x50 |
||
516 | mov [edx + 20 + 12], al |
||
517 | |||
518 | pop ecx ; count of bytes to send |
||
519 | mov ebx, ecx ; need the length later |
||
520 | |||
521 | cmp ebx, 0 |
||
522 | jz btp_001 |
||
523 | |||
524 | mov edi, edx |
||
525 | add edi, 40 |
||
526 | cld |
||
527 | rep movsb ; copy the data across |
||
528 | |||
529 | btp_001: |
||
530 | ; we have edx as IPbuffer ptr. |
||
531 | ; Fill in the TCP checksum |
||
532 | ; First, fill in pseudoheader |
||
533 | mov eax, [edx + 12] |
||
534 | mov [pseudoHeader], eax |
||
535 | mov eax, [edx + 16] |
||
536 | mov [pseudoHeader+4], eax |
||
537 | mov ax, 0x0600 ; 0 + protocol |
||
538 | mov [pseudoHeader+8], ax |
||
539 | add ebx, 20 |
||
540 | mov eax, ebx |
||
541 | mov [pseudoHeader+10], ah |
||
542 | mov [pseudoHeader+11], al |
||
543 | |||
544 | mov eax, pseudoHeader |
||
545 | mov [checkAdd1], eax |
||
546 | mov [checkSize1], word 12 |
||
547 | mov eax, edx |
||
548 | add eax, 20 |
||
549 | mov [checkAdd2], eax |
||
550 | mov eax, ebx |
||
551 | mov [checkSize2], ax |
||
552 | |||
553 | call checksum |
||
554 | |||
555 | ; store it in the TCP checksum ( in the correct order! ) |
||
556 | mov ax, [checkResult] |
||
557 | |||
558 | mov [edx + 20 + 16], ah |
||
559 | mov [edx + 20 + 17], al |
||
560 | |||
561 | ; Fill in the IP header checksum |
||
261 | hidnplayr | 562 | GET_IHL eax,edx ; get IP-Header length |
563 | stdcall checksum_jb,edx,eax ; buf_ptr, buf_size |
||
1 | ha | 564 | |
565 | mov [edx + 10], ah |
||
566 | mov [edx + 11], al |
||
567 | |||
568 | ret |
||
569 | |||
570 | |||
571 | ; Increments the 32 bit value pointed to by esi in internet order |
||
572 | inc_inet_esi: |
||
573 | push eax |
||
574 | add esi, 3 |
||
575 | mov al, byte[esi] |
||
576 | inc al |
||
577 | mov byte[esi], al |
||
578 | cmp al, 0 |
||
579 | jnz iie_exit |
||
580 | dec esi |
||
581 | mov al, byte[esi] |
||
582 | inc al |
||
583 | mov byte[esi], al |
||
584 | cmp al, 0 |
||
585 | jnz iie_exit |
||
586 | dec esi |
||
587 | mov al, byte[esi] |
||
588 | inc al |
||
589 | mov byte[esi], al |
||
590 | cmp al, 0 |
||
591 | jnz iie_exit |
||
592 | dec esi |
||
593 | mov al, byte[esi] |
||
594 | inc al |
||
595 | mov byte[esi], al |
||
596 | |||
597 | iie_exit: |
||
598 | pop eax |
||
599 | ret |
||
600 | |||
601 | |||
602 | ; Increments the 32 bit value pointed to by esi in internet order |
||
603 | ; by the value in ecx |
||
604 | add_inet_esi: |
||
605 | push eax |
||
606 | |||
607 | mov al, [esi] |
||
608 | shl eax, 8 |
||
609 | inc esi |
||
610 | mov al, [esi] |
||
611 | shl eax, 8 |
||
612 | inc esi |
||
613 | mov al, [esi] |
||
614 | shl eax, 8 |
||
615 | inc esi |
||
616 | mov al, [esi] |
||
617 | add eax, ecx |
||
618 | mov [esi], al |
||
619 | dec esi |
||
620 | shr eax, 8 |
||
621 | mov [esi], al |
||
622 | dec esi |
||
623 | shr eax, 8 |
||
624 | mov [esi], al |
||
625 | dec esi |
||
626 | shr eax, 8 |
||
627 | mov [esi], al |
||
628 | pop eax |
||
629 | ret |
||
630 | |||
631 | |||
632 | iglobal |
||
633 | TCBStateHandler: |
||
634 | dd stateTCB_LISTEN |
||
635 | dd stateTCB_SYN_SENT |
||
636 | dd stateTCB_SYN_RECEIVED |
||
637 | dd stateTCB_ESTABLISHED |
||
638 | dd stateTCB_FIN_WAIT_1 |
||
639 | dd stateTCB_FIN_WAIT_2 |
||
640 | dd stateTCB_CLOSE_WAIT |
||
641 | dd stateTCB_CLOSING |
||
642 | dd stateTCB_LAST_ACK |
||
643 | dd stateTCB_TIME_WAIT |
||
644 | dd stateTCB_CLOSED |
||
645 | endg |
||
646 | |||
647 | ;*************************************************************************** |
||
648 | ; Function |
||
649 | ; tcpStateMachine |
||
650 | ; |
||
651 | ; Description |
||
652 | ; TCP state machine |
||
653 | ; This is a kernel function, called by tcp_rx |
||
654 | ; |
||
655 | ; IP buffer address given in edx |
||
656 | ; Socket/TCB address in [eax + sockets] |
||
657 | ; |
||
658 | ; The IP buffer will be released by the caller |
||
659 | ;*************************************************************************** |
||
660 | tcpStateMachine: |
||
661 | mov ebx, sockets |
||
662 | add ebx, eax |
||
663 | mov [sktAddr], ebx |
||
664 | |||
665 | ; as a packet has been received, update the TCB timer |
||
666 | mov ecx, TWOMSL |
||
667 | mov [ebx + 32], ecx |
||
668 | |||
669 | ; If the received packet has an ACK bit set, |
||
670 | ; remove any packets in the resend queue that this |
||
671 | ; received packet acknowledges |
||
672 | pusha |
||
673 | mov cl, [edx + 33] |
||
674 | and cl, 0x10 |
||
675 | cmp cl, 0x10 |
||
676 | jne tsm001 ; No ACK, so no data yet |
||
677 | |||
678 | |||
679 | ; get skt number in al |
||
680 | shr eax, 12 |
||
681 | |||
682 | ; The ack number is in [edx + 28], inet format |
||
683 | ; skt in al |
||
684 | |||
685 | mov esi, resendQ |
||
686 | mov ecx, 0 |
||
687 | |||
688 | t001: |
||
689 | cmp ecx, NUMRESENDENTRIES |
||
690 | je t003 ; None left |
||
691 | cmp [esi], al |
||
692 | je t002 ; found one |
||
693 | inc ecx |
||
694 | add esi, 4 |
||
695 | jmp t001 |
||
696 | |||
697 | t002: ; Can we delete this buffer? |
||
698 | |||
699 | ; If yes, goto t004. No, goto t001 |
||
700 | ; Get packet data address |
||
701 | |||
702 | push ecx |
||
703 | inc ecx |
||
704 | ; Now get buffer location, and copy buffer across. argh! more copying,, |
||
705 | mov edi, resendBuffer - IPBUFFSIZE |
||
706 | t002a: |
||
707 | add edi, IPBUFFSIZE |
||
708 | loop t002a |
||
709 | |||
710 | ; we have dest buffer location in edi. incoming packet in edx. |
||
711 | ; Get this packets sequence number |
||
712 | ; preserve al, ecx, esi, edx |
||
713 | |||
714 | mov cl, [edi + 24] |
||
715 | shl ecx, 8 |
||
716 | mov cl, [edi + 25] |
||
717 | shl ecx, 8 |
||
718 | mov cl, [edi + 26] |
||
719 | shl ecx, 8 |
||
720 | mov cl, [edi + 27] |
||
721 | movzx ebx, byte [edi + 3] |
||
722 | mov bh, [edi + 2] |
||
723 | sub ebx, 40 |
||
724 | add ecx, ebx ; ecx is now seq# of last byte +1, intel format |
||
725 | |||
726 | ; get recievd ack #, in intel format |
||
727 | mov bl, [edx + 28] |
||
728 | shl ebx, 8 |
||
729 | mov bl, [edx + 29] |
||
730 | shl ebx, 8 |
||
731 | mov bl, [edx + 30] |
||
732 | shl ebx, 8 |
||
733 | mov bl, [edx + 31] |
||
734 | |||
735 | cmp ebx, ecx ; Finally. ecx = rx'ed ack. ebx = last byte in que |
||
736 | ; DANGER! need to handle case that we have just |
||
737 | ; passed the 2**32, and wrapped round! |
||
738 | pop ecx |
||
739 | |||
740 | jae t004 ; if rx > old, delete old |
||
741 | inc ecx |
||
742 | add esi, 4 |
||
743 | jmp t001 |
||
744 | |||
745 | |||
746 | t004: |
||
747 | dec dword [arp_rx_count] ; ************ TEST ONLY! |
||
748 | |||
749 | mov [esi], byte 0xFF |
||
750 | inc ecx |
||
751 | add esi, 4 |
||
752 | jmp t001 |
||
753 | |||
754 | t003: |
||
755 | |||
756 | tsm001: |
||
757 | popa |
||
758 | |||
759 | ; Call handler for given TCB state |
||
760 | mov ebx, [eax + sockets+28] |
||
761 | cmp ebx, TCB_LISTEN |
||
762 | jb tsm_exit |
||
763 | cmp ebx, TCB_CLOSED |
||
764 | ja tsm_exit |
||
765 | |||
766 | dec ebx |
||
767 | call dword [TCBStateHandler+ebx*4] |
||
768 | |||
769 | tsm_exit: |
||
770 | ret |
||
771 | |||
772 | |||
773 | |||
774 | stateTCB_LISTEN: |
||
775 | ; In this case, we are expecting a SYN packet |
||
776 | ; For now, if the packet is a SYN, process it, and send a response |
||
777 | ; If not, ignore it |
||
778 | |||
779 | ; Look at control flags |
||
780 | mov bl, [edx + 33] |
||
781 | and bl, 0x02 |
||
782 | cmp bl, 0x02 |
||
783 | jnz stl_exit |
||
784 | |||
785 | ; We have a SYN. update the socket with this IP packets details, |
||
786 | ; And send a response |
||
787 | |||
788 | mov ebx, [edx + 12] ; IP source address |
||
789 | mov [eax + sockets + 16], ebx |
||
790 | mov bx, [edx + 20] ; IP source port |
||
791 | mov [eax + sockets + 20], bx |
||
792 | mov ebx, [edx + 24] ; IRS |
||
793 | mov [eax + sockets + 40], ebx |
||
794 | mov [eax + sockets + 56], ebx |
||
795 | mov esi, sockets |
||
796 | add esi, eax |
||
797 | add esi, 56 |
||
798 | call inc_inet_esi ; RCV.NXT |
||
799 | mov ebx, [eax + sockets + 36] ; ISS |
||
800 | mov [eax + sockets + 48], ebx ; SND.NXT |
||
801 | |||
802 | ; Now construct the response, and queue for sending by IP |
||
803 | mov eax, EMPTY_QUEUE |
||
804 | call dequeue |
||
805 | cmp ax, NO_BUFFER |
||
806 | je stl_exit |
||
807 | |||
808 | push eax |
||
809 | mov bl, 0x12 ; SYN + ACK |
||
810 | mov ecx, 0 |
||
811 | mov esi, 0 |
||
812 | |||
813 | call buildTCPPacket |
||
814 | |||
815 | mov eax, NET1OUT_QUEUE |
||
816 | mov edx, [stack_ip] |
||
817 | mov ecx, [ sktAddr ] |
||
818 | mov ecx, [ ecx + 16 ] |
||
819 | cmp edx, ecx |
||
820 | jne stl_notlocal |
||
821 | mov eax, IPIN_QUEUE |
||
822 | |||
823 | stl_notlocal: |
||
824 | ; Send it. |
||
825 | pop ebx |
||
826 | call queue |
||
827 | |||
828 | |||
829 | mov ebx, TCB_SYN_RECEIVED |
||
830 | mov esi, [sktAddr] |
||
831 | mov [esi + 28], ebx |
||
832 | |||
833 | ; increament SND.NXT in socket |
||
834 | add esi, 48 |
||
835 | call inc_inet_esi |
||
836 | |||
837 | stl_exit: |
||
838 | ret |
||
839 | |||
840 | |||
841 | |||
842 | stateTCB_SYN_SENT: |
||
843 | ; We are awaiting an ACK to our SYN, with a SYM |
||
844 | ; Look at control flags - expecting an ACK |
||
845 | mov bl, [edx + 33] |
||
846 | and bl, 0x12 |
||
847 | cmp bl, 0x12 |
||
848 | jnz stss_exit |
||
849 | |||
850 | mov ebx, TCB_ESTABLISHED |
||
851 | mov esi, [sktAddr] |
||
852 | mov [esi + 28], ebx |
||
853 | |||
854 | ; Store the recv.nxt field |
||
855 | mov eax, [edx + 24] |
||
856 | |||
857 | ; Update our recv.nxt field |
||
858 | mov esi, [sktAddr] |
||
859 | add esi, 56 |
||
860 | mov [esi], eax |
||
861 | call inc_inet_esi |
||
862 | |||
863 | ; Send an ACK |
||
864 | ; Now construct the response, and queue for sending by IP |
||
865 | mov eax, EMPTY_QUEUE |
||
866 | call dequeue |
||
867 | cmp ax, NO_BUFFER |
||
868 | je stss_exit |
||
869 | |||
870 | push eax |
||
871 | |||
872 | mov bl, 0x10 ; ACK |
||
873 | mov ecx, 0 |
||
874 | mov esi, 0 |
||
875 | |||
876 | call buildTCPPacket |
||
877 | |||
878 | mov eax, NET1OUT_QUEUE |
||
879 | |||
880 | mov edx, [stack_ip] |
||
881 | mov ecx, [ sktAddr ] |
||
882 | mov ecx, [ ecx + 16 ] |
||
883 | cmp edx, ecx |
||
884 | jne stss_notlocal |
||
885 | mov eax, IPIN_QUEUE |
||
886 | |||
887 | stss_notlocal: |
||
888 | ; Send it. |
||
889 | pop ebx |
||
890 | call queue |
||
891 | |||
892 | stss_exit: |
||
893 | ret |
||
894 | |||
895 | |||
896 | |||
897 | stateTCB_SYN_RECEIVED: |
||
898 | ; In this case, we are expecting an ACK packet |
||
899 | ; For now, if the packet is an ACK, process it, |
||
900 | ; If not, ignore it |
||
901 | |||
902 | ; Look at control flags - expecting an ACK |
||
903 | mov bl, [edx + 33] |
||
904 | and bl, 0x10 |
||
905 | cmp bl, 0x10 |
||
906 | jnz stsr_exit |
||
907 | |||
908 | mov ebx, TCB_ESTABLISHED |
||
909 | mov esi, [sktAddr] |
||
910 | mov [esi + 28], ebx |
||
911 | |||
912 | stsr_exit: |
||
913 | ret |
||
914 | |||
915 | |||
916 | |||
917 | stateTCB_ESTABLISHED: |
||
918 | ; Here we are expecting data, or a request to close |
||
919 | ; OR both... |
||
920 | |||
921 | ; Did we receive a FIN or RST? |
||
922 | mov bl, [edx + 33] |
||
923 | and bl, 0x05 |
||
924 | cmp bl, 0 |
||
925 | je ste_chkack |
||
926 | |||
927 | ; It was a fin or reset. |
||
928 | |||
929 | ; Remove resend entries from the queue - I dont want to send any more data |
||
930 | pusha |
||
931 | |||
932 | mov ebx, [sktAddr] |
||
933 | sub ebx, sockets |
||
934 | shr ebx, 12 ; get skt # |
||
935 | |||
936 | mov esi, resendQ |
||
937 | mov ecx, 0 |
||
938 | |||
939 | ste001: |
||
940 | cmp ecx, NUMRESENDENTRIES |
||
941 | je ste003 ; None left |
||
942 | cmp [esi], bl |
||
943 | je ste002 ; found one |
||
944 | inc ecx |
||
945 | add esi, 4 |
||
946 | jmp ste001 |
||
947 | |||
948 | ste002: |
||
949 | dec dword [arp_rx_count] ; ************ TEST ONLY! |
||
950 | |||
951 | mov [esi], byte 0xFF |
||
952 | jmp ste001 |
||
953 | |||
954 | ste003: |
||
955 | popa |
||
956 | |||
957 | ; was it a reset? |
||
958 | mov bl, [edx + 33] |
||
959 | and bl, 0x04 |
||
960 | cmp bl, 0x04 |
||
961 | jne ste003a |
||
962 | |||
963 | mov esi, [sktAddr] |
||
964 | mov ebx, TCB_CLOSED |
||
965 | mov [esi + 28], ebx |
||
966 | jmp ste_exit |
||
967 | |||
968 | ste003a: |
||
969 | ; Send an ACK to that fin, and enter closewait state |
||
970 | |||
971 | mov esi, [sktAddr] |
||
972 | mov ebx, TCB_CLOSE_WAIT |
||
973 | mov [esi + 28], ebx |
||
974 | add esi, 56 |
||
975 | mov eax, [esi] ; save original |
||
976 | call inc_inet_esi |
||
977 | ;; jmp ste_ack - NO, there may be data |
||
978 | |||
979 | ste_chkack: |
||
980 | ; Check that we received an ACK |
||
981 | mov bl, [edx + 33] |
||
982 | and bl, 0x10 |
||
983 | cmp bl, 0x10 |
||
984 | jnz ste_exit |
||
985 | |||
986 | |||
987 | ; TODO - done, I think! |
||
988 | ; First, look at the incoming window. If this is less than or equal to 1024, |
||
989 | ; Set the socket window timer to 1. This will stop an additional packets being |
||
990 | ; queued. |
||
991 | ; ** I may need to tweak this value, since I do not know how many packets are already queued |
||
992 | mov ch, [edx + 34] |
||
993 | mov cl, [edx + 35] |
||
994 | cmp cx, 1024 |
||
995 | ja ste004 |
||
996 | |||
997 | mov ecx, [sktAddr] |
||
998 | mov [ecx+72], dword 1 |
||
999 | |||
1000 | ste004: |
||
1001 | |||
1002 | ; OK, here is the deal |
||
1003 | ; My recv.nct field holds the seq of the expected next rec byte |
||
1004 | ; if the recevied sequence number is not equal to this, do not |
||
1005 | ; increment the recv.nxt field, do not copy data - just send a |
||
1006 | ; repeat ack. |
||
1007 | |||
1008 | ; recv.nxt is in dword [edx+24], in inext format |
||
1009 | ; recv seq is in [sktAddr]+56, in inet format |
||
1010 | ; just do a comparision |
||
1011 | mov ecx, [sktAddr] |
||
1012 | add ecx, 56 |
||
1013 | |||
1014 | cmp [ecx - 56 + 28], dword TCB_CLOSE_WAIT |
||
1015 | mov ecx, [ecx] |
||
1016 | jne stenofin |
||
1017 | mov ecx, eax |
||
1018 | |||
1019 | stenofin: |
||
1020 | cmp ecx, [edx+24] |
||
1021 | jne ste_ack |
||
1022 | |||
1023 | |||
1024 | ; Read the data bytes, store in socket buffer |
||
1025 | xor ecx, ecx |
||
1026 | mov ch, [edx + 2] |
||
1027 | mov cl, [edx + 3] |
||
1028 | sub ecx, 40 ; Discard 40 bytes of header |
||
1029 | |||
1030 | cmp ecx, 0 |
||
1031 | jnz ste_data ; Read data, if any |
||
1032 | |||
1033 | ; If we had received a fin, we need to ACK it. |
||
1034 | mov esi, [sktAddr] |
||
1035 | mov ebx, [esi + 28] |
||
1036 | cmp ebx, TCB_CLOSE_WAIT |
||
1037 | jz ste_ack |
||
1038 | jnz ste_exit |
||
1039 | |||
1040 | ste_data: |
||
1041 | push ecx |
||
1042 | mov esi, [sktAddr] |
||
1043 | |||
1044 | add [esi + 24], ecx ; increment the count of bytes in buffer |
||
1045 | |||
1046 | mov eax, [esi + 4] ; get socket owner PID |
||
1047 | push eax |
||
1048 | |||
1049 | mov eax, [esi + 24] ; get # of bytes already in buffer |
||
1050 | |||
1051 | ; point to the location to store the data |
||
1052 | add esi, eax |
||
1053 | sub esi, ecx |
||
1054 | add esi, SOCKETHEADERSIZE |
||
1055 | |||
1056 | add edx, 40 ; edx now points to the data |
||
1057 | mov edi, esi |
||
1058 | mov esi, edx |
||
1059 | |||
1060 | cld |
||
1061 | rep movsb ; copy the data across |
||
1062 | |||
1063 | ; flag an event to the application |
||
1064 | pop eax |
||
1065 | mov ecx,1 |
||
379 | serge | 1066 | mov esi,TASK_DATA+TASKDATA.pid |
1 | ha | 1067 | |
1068 | news: |
||
1069 | cmp [esi],eax |
||
1070 | je foundPID1 |
||
1071 | inc ecx |
||
1072 | add esi,0x20 |
||
379 | serge | 1073 | cmp ecx,[TASK_COUNT] |
1 | ha | 1074 | jbe news |
1075 | |||
1076 | foundPID1: |
||
1077 | shl ecx,8 |
||
380 | serge | 1078 | or dword [ecx+SLOT_BASE+APPDATA.event_mask],dword 10000000b ; stack event |
1 | ha | 1079 | |
1080 | pop ecx |
||
1081 | |||
1082 | ; Update our recv.nxt field |
||
1083 | mov esi, [sktAddr] |
||
1084 | add esi, 56 |
||
1085 | call add_inet_esi |
||
1086 | |||
1087 | ste_ack: |
||
1088 | ; Send an ACK |
||
1089 | ; Now construct the response, and queue for sending by IP |
||
1090 | mov eax, EMPTY_QUEUE |
||
1091 | call dequeue |
||
1092 | cmp ax, NO_BUFFER |
||
1093 | je ste_exit |
||
1094 | |||
1095 | push eax |
||
1096 | |||
1097 | mov bl, 0x10 ; ACK |
||
1098 | mov ecx, 0 |
||
1099 | mov esi, 0 |
||
1100 | |||
1101 | call buildTCPPacket |
||
1102 | |||
1103 | mov eax, NET1OUT_QUEUE |
||
1104 | |||
1105 | mov edx, [stack_ip] |
||
1106 | mov ecx, [ sktAddr ] |
||
1107 | mov ecx, [ ecx + 16 ] |
||
1108 | cmp edx, ecx |
||
1109 | jne ste_notlocal |
||
1110 | mov eax, IPIN_QUEUE |
||
1111 | ste_notlocal: |
||
1112 | |||
1113 | ; Send it. |
||
1114 | pop ebx |
||
1115 | call queue |
||
1116 | |||
1117 | ste_exit: |
||
1118 | ret |
||
1119 | |||
1120 | |||
1121 | |||
1122 | stateTCB_FIN_WAIT_1: |
||
1123 | ; We can either receive an ACK of a fin, or a fin |
||
1124 | mov bl, [edx + 33] |
||
1125 | and bl, 0x10 |
||
1126 | cmp bl, 0x10 |
||
1127 | jnz stfw1_001 |
||
1128 | |||
1129 | ; It was an ACK |
||
1130 | mov esi, [sktAddr] |
||
1131 | mov ebx, TCB_FIN_WAIT_2 |
||
1132 | mov [esi + 28], ebx |
||
1133 | jmp stfw1_exit |
||
1134 | |||
1135 | stfw1_001: |
||
1136 | ; It must be a fin then |
||
1137 | mov esi, [sktAddr] |
||
1138 | mov ebx, TCB_CLOSING |
||
1139 | mov [esi + 28], ebx |
||
1140 | add esi, 56 |
||
1141 | call inc_inet_esi |
||
1142 | |||
1143 | ; Send an ACK |
||
1144 | mov eax, EMPTY_QUEUE |
||
1145 | call dequeue |
||
1146 | cmp ax, NO_BUFFER |
||
1147 | je stfw1_exit |
||
1148 | |||
1149 | push eax |
||
1150 | |||
1151 | mov bl, 0x10 ; ACK |
||
1152 | mov ecx, 0 |
||
1153 | mov esi, 0 |
||
1154 | |||
1155 | call buildTCPPacket |
||
1156 | mov eax, NET1OUT_QUEUE |
||
1157 | |||
1158 | mov edx, [stack_ip] |
||
1159 | mov ecx, [ sktAddr ] |
||
1160 | mov ecx, [ ecx + 16 ] |
||
1161 | cmp edx, ecx |
||
1162 | jne stfw1_notlocal |
||
1163 | mov eax, IPIN_QUEUE |
||
1164 | |||
1165 | stfw1_notlocal: |
||
1166 | ; Send it. |
||
1167 | pop ebx |
||
1168 | call queue |
||
1169 | |||
1170 | stfw1_exit: |
||
1171 | ret |
||
1172 | |||
1173 | |||
1174 | |||
1175 | stateTCB_FIN_WAIT_2: |
||
1176 | mov esi, [sktAddr] |
||
1177 | |||
1178 | ; Get data length |
||
1179 | xor ecx, ecx |
||
1180 | mov ch, [edx+2] |
||
1181 | mov cl, [edx+3] |
||
1182 | sub ecx, 40 |
||
1183 | |||
1184 | mov bl, [edx + 33] |
||
1185 | and bl, 0x01 |
||
1186 | cmp bl, 0x01 |
||
1187 | jne stfw2001 |
||
1188 | |||
1189 | ; Change state, as we have a fin |
||
1190 | mov ebx, TCB_TIME_WAIT |
||
1191 | mov [esi + 28], ebx |
||
1192 | |||
1193 | inc ecx ; FIN is part of the sequence space |
||
1194 | |||
1195 | stfw2001: |
||
1196 | add esi, 56 |
||
1197 | call add_inet_esi |
||
1198 | |||
1199 | ; Send an ACK |
||
1200 | mov eax, EMPTY_QUEUE |
||
1201 | call dequeue |
||
1202 | cmp ax, NO_BUFFER |
||
1203 | je stfw2_exit |
||
1204 | |||
1205 | push eax |
||
1206 | |||
1207 | mov bl, 0x10 ; ACK |
||
1208 | mov ecx, 0 |
||
1209 | mov esi, 0 |
||
1210 | |||
1211 | call buildTCPPacket |
||
1212 | |||
1213 | mov eax, NET1OUT_QUEUE |
||
1214 | |||
1215 | mov edx, [stack_ip] |
||
1216 | mov ecx, [ sktAddr ] |
||
1217 | mov ecx, [ ecx + 16 ] |
||
1218 | cmp edx, ecx |
||
1219 | jne stfw2_notlocal |
||
1220 | mov eax, IPIN_QUEUE |
||
1221 | |||
1222 | stfw2_notlocal: |
||
1223 | ; Send it. |
||
1224 | pop ebx |
||
1225 | call queue |
||
1226 | |||
1227 | ; Only delete the socket if we received the FIN |
||
1228 | |||
871 | mikedld | 1229 | mov edx, [sktAddr] |
1 | ha | 1230 | mov bl, [edx + 33] |
1231 | and bl, 0x01 |
||
1232 | cmp bl, 0x01 |
||
1233 | jne stfw2_exit |
||
1234 | |||
1235 | ; mov edi, [sktAddr] |
||
1236 | |||
1237 | ; delete the socket. Should really wait for 2MSL |
||
1238 | ; xor eax, eax |
||
1239 | ; mov ecx,SOCKETHEADERSIZE |
||
1240 | ; cld |
||
1241 | ; rep stosb |
||
1242 | |||
1243 | stfw2_exit: |
||
1244 | ret |
||
1245 | |||
1246 | |||
1247 | |||
1248 | stateTCB_CLOSE_WAIT: |
||
1249 | ; Intentionally left empty |
||
1250 | ; socket_close_tcp handles this |
||
1251 | ret |
||
1252 | |||
1253 | |||
1254 | |||
1255 | stateTCB_CLOSING: |
||
1256 | ; We can either receive an ACK of a fin, or a fin |
||
1257 | mov bl, [edx + 33] |
||
1258 | and bl, 0x10 |
||
1259 | cmp bl, 0x10 |
||
1260 | jnz stc_exit |
||
1261 | |||
1262 | ; It was an ACK |
||
1263 | |||
1264 | mov edi, [sktAddr] |
||
1265 | |||
1266 | ; delete the socket |
||
1267 | xor eax, eax |
||
1268 | mov ecx,SOCKETHEADERSIZE |
||
1269 | cld |
||
1270 | rep stosb |
||
1271 | |||
1272 | stc_exit: |
||
1273 | ret |
||
1274 | |||
1275 | |||
1276 | |||
1277 | stateTCB_LAST_ACK: |
||
1278 | ; Look at control flags - expecting an ACK |
||
1279 | mov bl, [edx + 33] |
||
1280 | and bl, 0x10 |
||
1281 | cmp bl, 0x10 |
||
1282 | jnz stla_exit |
||
1283 | |||
1284 | mov edi, [sktAddr] |
||
1285 | |||
1286 | ; delete the socket |
||
1287 | xor eax, eax |
||
1288 | mov ecx,SOCKETHEADERSIZE |
||
1289 | cld |
||
1290 | rep stosb |
||
1291 | |||
1292 | stla_exit: |
||
1293 | ret |
||
1294 | |||
1295 | |||
1296 | |||
1297 | stateTCB_TIME_WAIT: |
||
1298 | ret |
||
1299 | |||
1300 | |||
1301 | |||
1302 | stateTCB_CLOSED: |
||
1303 | ret |