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