Rev 1257 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1257 | Rev 1274 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; TCP.INC ;; |
6 | ;; TCP.INC ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Part of the tcp/ip network stack for KolibriOS ;; |
8 | ;; Part of the tcp/ip network stack for KolibriOS ;; |
9 | ;; ;; |
9 | ;; ;; |
10 | ;; Written by hidnplayr@kolibrios.org ;; |
10 | ;; Written by hidnplayr@kolibrios.org ;; |
11 | ;; ;; |
11 | ;; ;; |
12 | ;; GNU GENERAL PUBLIC LICENSE ;; |
12 | ;; GNU GENERAL PUBLIC LICENSE ;; |
13 | ;; Version 2, June 1991 ;; |
13 | ;; Version 2, June 1991 ;; |
14 | ;; ;; |
14 | ;; ;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
16 | 16 | ||
17 | 17 | ||
18 | $Revision: 1257 $ |
18 | $Revision: 1274 $ |
19 | 19 | ||
20 | TCP_RETRIES equ 5 ; Number of times to resend a Packet |
20 | TCP_RETRIES equ 5 ; Number of times to resend a Packet |
21 | TCP_PACKET_TTL equ 50 ; resend if not replied to in 1/100 s |
21 | TCP_PACKET_TTL equ 50 ; resend if not replied to in 1/100 s |
22 | TCP_SOCKET_TTL equ 10 ; # of secs to wait before closing socket |
22 | TCP_SOCKET_TTL equ 10 ; # of secs to wait before closing socket |
23 | TCP_QUEUE_SIZE equ 16 |
23 | TCP_QUEUE_SIZE equ 16 |
24 | 24 | ||
25 | 25 | ||
26 | struct TCP_Packet |
26 | struct TCP_Packet |
27 | .SourcePort dw ? |
27 | .SourcePort dw ? |
28 | .DestinationPort dw ? |
28 | .DestinationPort dw ? |
29 | .SequenceNumber dd ? |
29 | .SequenceNumber dd ? |
30 | .AckNumber dd ? |
30 | .AckNumber dd ? |
31 | .DataOffset db ? ; DataOffset[0-3 bits] and Reserved[4-7] |
31 | .DataOffset db ? ; DataOffset[0-3 bits] and Reserved[4-7] |
32 | .Flags db ? ; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN |
32 | .Flags db ? ; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN |
33 | .Window dw ? |
33 | .Window dw ? |
34 | .Checksum dw ? |
34 | .Checksum dw ? |
35 | .UrgentPointer dw ? |
35 | .UrgentPointer dw ? |
36 | .Options rb 3 |
36 | ; .Options rb 3 |
37 | .Padding db ? |
37 | ; .Padding db ? |
38 | .Data: |
38 | .Data: |
39 | ends |
39 | ends |
- | 40 | ||
- | 41 | struct tcp_in_queue_entry |
|
- | 42 | .data_ptr dd ? |
|
- | 43 | .data_size dd ? |
|
- | 44 | .offset dd ? |
|
- | 45 | .size: |
|
- | 46 | ends |
|
- | 47 | ||
- | 48 | struct tcp_out_queue_entry |
|
- | 49 | .data_ptr dd ? |
|
- | 50 | .data_size dd ? |
|
- | 51 | .ttl dd ? |
|
- | 52 | .retries dd ? |
|
- | 53 | .owner dd ? |
|
- | 54 | .sendproc dd ? |
|
- | 55 | .seq_num dd ? |
|
- | 56 | .socket dd ? |
|
- | 57 | .size: |
|
- | 58 | ends |
|
40 | 59 | ||
41 | align 4 |
60 | align 4 |
42 | uglobal |
61 | uglobal |
43 | TCP_PACKETS_TX rd MAX_IP |
62 | TCP_PACKETS_TX rd MAX_IP |
44 | TCP_PACKETS_RX rd MAX_IP |
63 | TCP_PACKETS_RX rd MAX_IP |
45 | 64 | ||
46 | TCP_IN_QUEUE rd (tcp_in_queue_entry.size*TCP_QUEUE_SIZE+queue.data)/4 |
65 | TCP_IN_QUEUE rd (tcp_in_queue_entry.size*TCP_QUEUE_SIZE+queue.data)/4 |
47 | TCP_OUT_QUEUE dd ? |
66 | TCP_OUT_QUEUE dd ? |
48 | rd (tcp_out_queue_entry.size*TCP_QUEUE_SIZE)/4 |
67 | rd (tcp_out_queue_entry.size*TCP_QUEUE_SIZE)/4 |
49 | endg |
68 | endg |
50 | 69 | ||
51 | align 4 |
70 | align 4 |
52 | iglobal |
71 | iglobal |
53 | stateHandler: |
72 | stateHandler: |
54 | 73 | ||
55 | dd stateTCB_LISTEN |
74 | dd stateTCB_LISTEN |
56 | dd stateTCB_SYN_SENT |
75 | dd stateTCB_SYN_SENT |
57 | dd stateTCB_SYN_RECEIVED |
76 | dd stateTCB_SYN_RECEIVED |
58 | dd stateTCB_ESTABLISHED |
77 | dd stateTCB_ESTABLISHED |
59 | dd stateTCB_FIN_WAIT_1 |
78 | dd stateTCB_FIN_WAIT_1 |
60 | dd stateTCB_FIN_WAIT_2 |
79 | dd stateTCB_FIN_WAIT_2 |
61 | dd stateTCB_CLOSE_WAIT |
80 | dd stateTCB_CLOSE_WAIT |
62 | dd stateTCB_CLOSING |
81 | dd stateTCB_CLOSING |
63 | dd stateTCB_LAST_ACK |
82 | dd stateTCB_LAST_ACK |
64 | dd stateTCB_TIME_WAIT |
83 | dd stateTCB_TIME_WAIT |
65 | dd stateTCB_CLOSED |
84 | dd stateTCB_CLOSED |
66 | 85 | ||
67 | endg |
86 | endg |
68 | 87 | ||
69 | 88 | ||
70 | ;----------------------------------------------------------------- |
89 | ;----------------------------------------------------------------- |
71 | ; |
90 | ; |
72 | ; TCP_init |
91 | ; TCP_init |
73 | ; |
92 | ; |
74 | ; This function resets all TCP variables |
93 | ; This function resets all TCP variables |
75 | ; |
94 | ; |
76 | ; IN: / |
95 | ; IN: / |
77 | ; OUT: / |
96 | ; OUT: / |
78 | ; |
97 | ; |
79 | ;----------------------------------------------------------------- |
98 | ;----------------------------------------------------------------- |
80 | align 4 |
99 | align 4 |
81 | TCP_init: |
100 | TCP_init: |
82 | 101 | ||
83 | xor eax, eax |
102 | xor eax, eax |
84 | mov edi, TCP_PACKETS_TX |
103 | mov edi, TCP_PACKETS_TX |
85 | mov ecx, 2*MAX_IP |
104 | mov ecx, 2*MAX_IP |
86 | rep stosd |
105 | rep stosd |
87 | 106 | ||
88 | init_queue TCP_IN_QUEUE |
107 | init_queue TCP_IN_QUEUE |
89 | 108 | ||
90 | ; tcp_out_queue is a special type of queue: |
109 | ; tcp_out_queue is a special type of queue: |
91 | ; The first dword is a counter of total packets queued. |
110 | ; The first dword is a counter of total packets queued. |
92 | ; The remaining bytes are socket 'slots' wich use tcp_out_queue_entry data structure. |
111 | ; The remaining bytes are socket 'slots' wich use tcp_out_queue_entry data structure. |
93 | ; An empty slot is know by the fact that tcp_out_queue_entry.data_ptr (first dword of the slot) is set to 0 |
112 | ; An empty slot is know by the fact that tcp_out_queue_entry.data_ptr (first dword of the slot) is set to 0 |
94 | ; There are TCP_OUT_QUEUE_SIZE number of slots |
113 | ; There are TCP_OUT_QUEUE_SIZE number of slots |
95 | 114 | ||
96 | xor eax, eax |
115 | xor eax, eax |
97 | mov esi, TCP_OUT_QUEUE |
116 | mov esi, TCP_OUT_QUEUE |
98 | mov ecx, TCP_QUEUE_SIZE*tcp_out_queue_entry/4+1 |
117 | mov ecx, TCP_QUEUE_SIZE*tcp_out_queue_entry/4+1 |
99 | rep stosd |
118 | rep stosd |
100 | 119 | ||
101 | ret |
120 | ret |
102 | 121 | ||
103 | 122 | ||
104 | ;----------------------------------------------------------------- |
123 | ;----------------------------------------------------------------- |
105 | ; |
124 | ; |
106 | ; TCP_decrease_socket_ttls |
125 | ; TCP_decrease_socket_ttls |
107 | ; |
126 | ; |
108 | ; IN: / |
127 | ; IN: / |
109 | ; OUT: / |
128 | ; OUT: / |
110 | ; |
129 | ; |
111 | ;----------------------------------------------------------------- |
130 | ;----------------------------------------------------------------- |
112 | align 4 |
131 | align 4 |
113 | TCP_decrease_socket_ttls: |
132 | TCP_decrease_socket_ttls: |
114 | ; scan through all the sockets, decrementing active timers |
133 | ; scan through all the sockets, decrementing active timers |
115 | 134 | ||
116 | mov ebx, net_sockets |
135 | mov ebx, net_sockets |
117 | 136 | ||
118 | cmp [ebx + SOCKET_head.NextPtr], 0 |
137 | cmp [ebx + SOCKET_head.NextPtr], 0 |
119 | je .exit |
138 | je .exit |
120 | 139 | ||
121 | .next_socket: |
140 | .next_socket: |
122 | mov ebx, [ebx + SOCKET_head.NextPtr] |
141 | mov ebx, [ebx + SOCKET_head.NextPtr] |
123 | or ebx, ebx |
142 | or ebx, ebx |
124 | jz .exit |
143 | jz .exit |
125 | 144 | ||
126 | cmp [ebx + SOCKET_head.Type], IP_PROTO_TCP |
145 | cmp [ebx + SOCKET_head.Type], IP_PROTO_TCP |
127 | jne .next_socket |
146 | jne .next_socket |
128 | 147 | ||
129 | ; DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.state] |
148 | ; DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.state] |
130 | 149 | ||
131 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], 0 |
150 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], 0 |
132 | jne .decrement_tcb |
151 | jne .decrement_tcb |
133 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0 |
152 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0 |
134 | jne .decrement_wnd |
153 | jne .decrement_wnd |
135 | jmp .next_socket |
154 | jmp .next_socket |
136 | 155 | ||
137 | .decrement_tcb: |
156 | .decrement_tcb: |
138 | ; decrement it, delete socket if TCB timer = 0 & socket in timewait state |
157 | ; decrement it, delete socket if TCB timer = 0 & socket in timewait state |
139 | dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer] |
158 | dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer] |
140 | jnz .next_socket |
159 | jnz .next_socket |
141 | 160 | ||
142 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT |
161 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT |
143 | jne .next_socket |
162 | jne .next_socket |
144 | 163 | ||
145 | push [ebx + SOCKET_head.PrevPtr] |
164 | push [ebx + SOCKET_head.PrevPtr] |
146 | stdcall net_socket_free, ebx |
165 | stdcall net_socket_free, ebx |
147 | pop ebx |
166 | pop ebx |
148 | jmp .next_socket |
167 | jmp .next_socket |
149 | 168 | ||
150 | .decrement_wnd: |
169 | .decrement_wnd: |
151 | ; TODO - prove it works! |
- | |
152 | dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer] |
170 | dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer] |
153 | jmp .next_socket |
171 | jmp .next_socket |
154 | 172 | ||
155 | .exit: |
173 | .exit: |
156 | ret |
174 | ret |
157 | 175 | ||
158 | 176 | ||
159 | 177 | ||
160 | ;----------------------------------------------------------------- |
178 | ;----------------------------------------------------------------- |
161 | ; |
179 | ; |
162 | ; TCP_send_queued: |
180 | ; TCP_send_queued: |
163 | ; |
181 | ; |
164 | ; Decreases 'ttl' of tcp packets queued. |
182 | ; Decreases 'ttl' of tcp packets queued. |
165 | ; if 'ttl' reaches 0, resend the packet and decrease 'retries' |
183 | ; if 'ttl' reaches 0, resend the packet and decrease 'retries' |
166 | ; if 'retries' reaches zero, remove the queued packet |
184 | ; if 'retries' reaches zero, remove the queued packet |
167 | ; |
185 | ; |
168 | ; IN: / |
186 | ; IN: / |
169 | ; OUT: / |
187 | ; OUT: / |
170 | ; |
188 | ; |
171 | ;----------------------------------------------------------------- |
189 | ;----------------------------------------------------------------- |
172 | align 4 |
190 | align 4 |
173 | TCP_send_queued: |
191 | TCP_send_queued: |
174 | 192 | ||
175 | cmp [TCP_OUT_QUEUE], 0 |
193 | cmp [TCP_OUT_QUEUE], 0 |
176 | je .exit |
194 | je .exit |
177 | 195 | ||
178 | mov eax, TCP_QUEUE_SIZE |
196 | mov eax, TCP_QUEUE_SIZE |
179 | mov ecx, [TCP_OUT_QUEUE] |
197 | mov ecx, [TCP_OUT_QUEUE] |
180 | mov esi, TCP_OUT_QUEUE+4 |
198 | mov esi, TCP_OUT_QUEUE+4 |
181 | 199 | ||
182 | .loop: |
200 | .loop: |
183 | cmp [esi + tcp_out_queue_entry.data_ptr], 0 |
201 | cmp [esi + tcp_out_queue_entry.data_ptr], 0 |
184 | jnz .found_one |
202 | jnz .found_one |
185 | add esi, tcp_out_queue_entry.size |
203 | add esi, tcp_out_queue_entry.size |
186 | loop .loop |
204 | loop .loop |
187 | .exit: |
205 | .exit: |
188 | ret |
206 | ret |
189 | 207 | ||
190 | .found_one: |
208 | .found_one: |
191 | dec [esi + tcp_out_queue_entry.ttl] |
209 | dec [esi + tcp_out_queue_entry.ttl] |
192 | jz .send_it |
210 | jz .send_it |
193 | .find_next: |
211 | .find_next: |
194 | add esi, tcp_out_queue_entry.size |
212 | add esi, tcp_out_queue_entry.size |
195 | dec eax |
213 | dec eax |
196 | jz .exit |
214 | jz .exit |
197 | test ecx, ecx |
215 | test ecx, ecx |
198 | jnz .loop |
216 | jnz .loop |
199 | ret |
217 | ret |
200 | 218 | ||
201 | .send_it: |
219 | .send_it: |
202 | push eax ecx esi |
220 | push eax ecx esi |
203 | 221 | ||
204 | mov ebx, [esi + tcp_out_queue_entry.owner] |
222 | mov ebx, [esi + tcp_out_queue_entry.owner] |
205 | push [esi + tcp_out_queue_entry.data_size] |
223 | push [esi + tcp_out_queue_entry.data_size] |
206 | push [esi + tcp_out_queue_entry.data_ptr] |
224 | push [esi + tcp_out_queue_entry.data_ptr] |
207 | DEBUGF 1,"Now sending TCP packet %x, size: %u, owner: %x, sendproc %x\n", [esp], [esp+4], ebx, [esi + tcp_out_queue_entry.sendproc] |
225 | DEBUGF 1,"Now sending TCP packet %x, size: %u, owner: %x, sendproc %x\n", [esp], [esp+4], ebx, [esi + tcp_out_queue_entry.sendproc] |
208 | inc [TCP_PACKETS_TX] |
226 | inc [TCP_PACKETS_TX] |
209 | call [esi + tcp_out_queue_entry.sendproc] |
227 | call [esi + tcp_out_queue_entry.sendproc] |
210 | add esp, 8 |
228 | add esp, 8 |
211 | pop esi ecx eax |
229 | pop esi ecx eax |
212 | 230 | ||
213 | dec [esi + tcp_out_queue_entry.retries] |
231 | dec [esi + tcp_out_queue_entry.retries] |
214 | jz .remove_it |
232 | jz .remove_it |
215 | 233 | ||
216 | mov [esi + tcp_out_queue_entry.ttl], TCP_PACKET_TTL |
234 | mov [esi + tcp_out_queue_entry.ttl], TCP_PACKET_TTL |
217 | jmp .find_next |
235 | jmp .find_next |
218 | 236 | ||
219 | .remove_it: |
237 | .remove_it: |
220 | push [esi + tcp_out_queue_entry.data_ptr] |
238 | push [esi + tcp_out_queue_entry.data_ptr] |
221 | mov [esi + tcp_out_queue_entry.data_ptr], 0 |
239 | mov [esi + tcp_out_queue_entry.data_ptr], 0 |
222 | call kernel_free |
240 | call kernel_free |
223 | jmp .find_next |
241 | jmp .find_next |
224 | 242 | ||
225 | 243 | ||
226 | 244 | ||
227 | ;----------------------------------------------------------------- |
245 | ;----------------------------------------------------------------- |
228 | ; |
246 | ; |
229 | ; TCP_add_to_queue: |
- | |
230 | ; |
- | |
231 | ; Queue a TCP packet for sending |
- | |
232 | ; |
- | |
233 | ; IN: [esp] pointer to buffer |
- | |
234 | ; [esp + 4] size of buffer |
- | |
235 | ; ebx = driver struct |
- | |
236 | ; esi = sender proc |
- | |
237 | ; edx = acknum |
- | |
238 | ; OUT: / |
- | |
239 | ; |
- | |
240 | ;----------------------------------------------------------------- |
- | |
241 | align 4 |
- | |
242 | TCP_add_to_queue: |
- | |
243 | - | ||
244 | DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %x\n", [esp], [esp+4], ebx, edx |
- | |
245 | - | ||
246 | cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE |
- | |
247 | jge .full |
- | |
248 | - | ||
249 | mov ecx, TCP_QUEUE_SIZE |
- | |
250 | mov eax, TCP_OUT_QUEUE+4 |
- | |
251 | - | ||
252 | .loop: |
- | |
253 | cmp [eax + tcp_out_queue_entry.data_ptr], 0 |
- | |
254 | je .found_it |
- | |
255 | add eax, tcp_out_queue_entry.size |
- | |
256 | loop .loop |
- | |
257 | - | ||
258 | .full: ; silently discard the packet |
- | |
259 | - | ||
260 | DEBUGF 1,"TCP queue is full!\n" |
- | |
261 | - | ||
262 | call kernel_free |
- | |
263 | add esp, 4 |
- | |
264 | - | ||
265 | ret |
- | |
266 | - | ||
267 | .found_it: ; eax point to empty queue entry |
- | |
268 | - | ||
269 | pop [eax + tcp_out_queue_entry.data_ptr] |
- | |
270 | pop [eax + tcp_out_queue_entry.data_size] |
- | |
271 | mov [eax + tcp_out_queue_entry.ttl], 1 ; send immediately |
- | |
272 | mov [eax + tcp_out_queue_entry.retries], TCP_RETRIES |
- | |
273 | mov [eax + tcp_out_queue_entry.owner], ebx |
- | |
274 | mov [eax + tcp_out_queue_entry.sendproc], esi |
- | |
275 | mov [eax + tcp_out_queue_entry.seq_num], edx |
- | |
276 | - | ||
277 | inc [TCP_OUT_QUEUE] |
- | |
278 | - | ||
279 | sub eax, TCP_OUT_QUEUE+4 |
- | |
280 | DEBUGF 1,"Added to queue in pos %u\n", eax |
- | |
281 | - | ||
282 | ret |
- | |
283 | - | ||
284 | - | ||
285 | ;----------------------------------------------------------------- |
- | |
286 | ; |
- | |
287 | ; TCP_handler: |
247 | ; TCP_handler: |
288 | ; |
248 | ; |
289 | ; Called by IPv4_handler, |
249 | ; Called by IPv4_handler, |
290 | ; this procedure will inject the tcp data diagrams in the application sockets. |
250 | ; this procedure will inject the tcp data diagrams in the application sockets. |
291 | ; |
251 | ; |
292 | ; IN: Pointer to buffer in [esp] |
252 | ; IN: Pointer to buffer in [esp] |
293 | ; size of buffer in [esp+4] |
253 | ; size of buffer in [esp+4] |
294 | ; pointer to device struct in ebx |
254 | ; pointer to device struct in ebx |
295 | ; TCP Packet size in ecx |
255 | ; TCP Packet size in ecx |
296 | ; pointer to TCP Packet data in edx |
256 | ; pointer to TCP Packet in edx |
297 | ; SourceAddres in esi |
257 | ; SourceAddres (IPv4) in esi |
298 | ; OUT: / |
258 | ; OUT: / |
299 | ; |
259 | ; |
300 | ;----------------------------------------------------------------- |
260 | ;----------------------------------------------------------------- |
301 | align 4 |
261 | align 4 |
302 | TCP_handler : |
262 | TCP_handler : |
303 | 263 | ||
304 | DEBUGF 1,"TCP_Handler\n" |
264 | DEBUGF 1,"TCP_Handler\n" |
305 | 265 | ||
306 | ; TODO: validate checksum |
266 | ; TODO: validate checksum |
307 | 267 | ||
308 | ; IP Packet TCP Destination Port = local Port |
268 | ; IP Packet TCP Destination Port = local Port |
309 | ; IP Packet SA = Remote IP OR = 0 |
269 | ; IP Packet SA = Remote IP OR = 0 |
310 | ; IP Packet TCP Source Port = remote Port OR = 0 |
270 | ; IP Packet TCP Source Port = remote Port OR = 0 |
311 | 271 | ||
312 | mov ebx, net_sockets |
272 | mov ebx, net_sockets |
313 | 273 | ||
314 | .socket_loop: |
274 | .socket_loop: |
315 | mov ebx, [ebx + SOCKET_head.NextPtr] |
275 | mov ebx, [ebx + SOCKET_head.NextPtr] |
316 | or ebx, ebx |
276 | or ebx, ebx |
317 | jz .dump |
277 | jz .dump |
318 | 278 | ||
319 | mov ax, [edx + TCP_Packet.DestinationPort] |
279 | mov ax, [edx + TCP_Packet.DestinationPort] |
320 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], ax |
280 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], ax |
321 | jne .socket_loop |
281 | jne .socket_loop |
322 | 282 | ||
323 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
283 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
324 | cmp eax, esi |
284 | cmp eax, esi |
325 | je @f |
285 | je @f |
326 | test eax, eax |
286 | test eax, eax |
327 | jne .socket_loop |
287 | jne .socket_loop |
328 | @@: |
288 | @@: |
329 | 289 | ||
330 | mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort] |
290 | mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort] |
331 | cmp [edx + TCP_Packet.SourcePort] , ax |
291 | cmp [edx + TCP_Packet.SourcePort] , ax |
332 | je .change_state |
292 | je .found_socket |
333 | test ax, ax |
293 | test ax, ax |
334 | jnz .socket_loop |
294 | jnz .socket_loop |
335 | - | ||
336 | .change_state: |
295 | .found_socket: |
337 | - | ||
338 | DEBUGF 1,"Found valid socket for packet\n" |
296 | DEBUGF 1,"Found valid socket for packet\n" |
339 | 297 | ||
340 | inc [TCP_PACKETS_RX] |
298 | inc [TCP_PACKETS_RX] |
341 | - | ||
342 | push ebx |
299 | |
343 | lea ebx, [ebx + SOCKET_head.lock] |
300 | add ebx, SOCKET_head.lock |
344 | call wait_mutex |
301 | call wait_mutex |
345 | pop ebx |
302 | sub ebx, SOCKET_head.lock |
346 | 303 | ||
347 | ;---------------------------------- |
304 | ;------------------------------- |
348 | ; ebx is pointer to socket |
305 | ; ebx is pointer to socket |
349 | ; ecx is size of tcp packet |
306 | ; ecx is size of tcp packet |
350 | ; edx is pointer to tcp packet |
307 | ; edx is pointer to tcp packet |
- | 308 | ||
- | 309 | ; calculate header length |
|
- | 310 | movzx eax, [edx + TCP_Packet.DataOffset] |
|
- | 311 | and eax, 11110000b |
|
- | 312 | shr eax, 2 |
|
- | 313 | DEBUGF 1,"TCP header size: %u\n", eax |
|
- | 314 | sub ecx, eax |
|
- | 315 | ||
- | 316 | ;------------------------------- |
|
- | 317 | ; ecx is size of tcp data |
|
351 | 318 | ||
352 | ; as a Packet has been received, update the TCB timer |
319 | ; as a Packet has been received, update the TCB timer |
353 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], TCP_SOCKET_TTL |
320 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], TCP_SOCKET_TTL |
354 | 321 | ||
355 | ; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges |
322 | ; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges |
356 | test [edx + TCP_Packet.Flags], TH_ACK |
323 | test [edx + TCP_Packet.Flags], TH_ACK |
357 | jz .call_handler ; No ACK, so no data yet |
324 | jz .no_ack ; No ACK, so no data yet |
- | 325 | ||
358 | 326 | ; Calculate ACK number |
|
- | 327 | mov edi, [edx + TCP_Packet.AckNumber] |
|
359 | ; mov eax, [edx + TCP_Packet.SequenceNumber] ; Calculate sequencenumber in eax |
328 | bswap edi |
360 | ; bswap eax ; |
329 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], edi |
- | 330 | DEBUGF 1,"Setting last_ack_number to %u\n", edi |
|
361 | ; add eax, ecx ; |
331 | bswap edi |
362 | 332 | ||
363 | mov eax, [edx + TCP_Packet.AckNumber] |
333 | ; Dequeue all acknowledged packets |
364 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], eax |
334 | cmp [TCP_OUT_QUEUE], 0 ; first, check if any packets are queued at all |
365 | ;--------- |
- | |
366 | - | ||
367 | cmp [TCP_OUT_QUEUE], 0 |
335 | je .no_ack |
368 | je .call_handler |
- | |
369 | push ecx |
336 | |
370 | - | ||
371 | DEBUGF 1,"Removing all queued packets with smaller ACK\n" |
337 | push ecx |
372 | 338 | DEBUGF 1,"Removing all queued packets with smaller ACK\n" |
|
373 | mov ecx, TCP_QUEUE_SIZE |
- | |
374 | mov esi, TCP_OUT_QUEUE+4 |
339 | mov ecx, TCP_QUEUE_SIZE |
375 | 340 | mov esi, TCP_OUT_QUEUE+4 |
|
376 | .loop: |
341 | .loop: |
377 | cmp [esi + tcp_out_queue_entry.data_ptr], 0 |
342 | cmp [esi + tcp_out_queue_entry.data_ptr], 0 |
378 | je .maybe_next |
343 | je .maybe_next |
- | 344 | ||
- | 345 | cmp [esi + tcp_out_queue_entry.socket], ebx |
|
- | 346 | jne .maybe_next |
|
- | 347 | ||
379 | cmp [esi + tcp_out_queue_entry.seq_num], eax |
348 | cmp [esi + tcp_out_queue_entry.seq_num], edi |
380 | jg .maybe_next |
349 | jg .maybe_next |
381 | ; TODO: check if the packets belong to the same tcp connection ! |
- | |
382 | 350 | ||
383 | DEBUGF 1,"Removing a queued packet\n" |
351 | DEBUGF 1,"Removing a queued packet\n" |
384 | 352 | ||
385 | push [esi + tcp_out_queue_entry.data_ptr] |
353 | push [esi + tcp_out_queue_entry.data_ptr] |
386 | mov [esi + tcp_out_queue_entry.data_ptr], 0 |
354 | mov [esi + tcp_out_queue_entry.data_ptr], 0 |
387 | dec [TCP_OUT_QUEUE] |
355 | dec [TCP_OUT_QUEUE] |
388 | call kernel_free |
356 | call kernel_free |
389 | 357 | ||
390 | .maybe_next: |
358 | .maybe_next: |
391 | add esi, tcp_out_queue_entry.size |
359 | add esi, tcp_out_queue_entry.size |
392 | loop .loop |
360 | loop .loop |
393 | - | ||
394 | pop ecx |
361 | pop ecx |
- | 362 | ||
- | 363 | ||
- | 364 | ; Now call the correct handler, depending on the socket state |
|
395 | .call_handler: |
365 | .no_ack: |
396 | ; Call handler for given TCB state |
- | |
397 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state] |
366 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state] |
398 | DEBUGF 1,"Socket state: %u\n", eax |
- | |
399 | 367 | ||
400 | cmp eax, TCB_LISTEN |
368 | cmp eax, TCB_LISTEN |
401 | jb .dump |
369 | jb .dump |
402 | cmp eax, TCB_CLOSED |
370 | cmp eax, TCB_CLOSED |
403 | ja .dump |
371 | ja .dump |
404 | 372 | ||
405 | dec eax |
373 | dec eax |
406 | shl eax, 2 |
374 | shl eax, 2 |
407 | add eax, stateHandler |
375 | add eax, stateHandler |
408 | 376 | ||
409 | call dword[eax] |
377 | call dword[eax] |
410 | 378 | ||
411 | .dump: |
379 | .dump: |
412 | DEBUGF 1,"Dumping TCP packet\n" |
380 | DEBUGF 1,"Dumping TCP packet\n" |
413 | call kernel_free |
381 | call kernel_free |
414 | add esp, 4 ; pop (balance stack) |
382 | add esp, 4 ; pop (balance stack) |
415 | 383 | ||
416 | ret |
384 | ret |
417 | 385 | ||
418 | 386 | ||
419 | 387 | ||
420 | ;----------------------------------------------------------------- |
388 | ;----------------------------------------------------------------- |
421 | ; |
389 | ; |
422 | ; TCP_socket_send |
390 | ; TCP_send (Assumes socket mutex set) |
423 | ; |
391 | ; |
424 | ; IN: eax = socket pointer |
392 | ; IN: eax = socket pointer |
- | 393 | ; bl = flags |
|
425 | ; ecx = number of bytes to send |
394 | ; ecx = number of bytes to send, may be set to 0 |
426 | ; esi = pointer to data |
395 | ; esi = pointer to data |
427 | ; |
396 | ; |
428 | ;----------------------------------------------------------------- |
397 | ;----------------------------------------------------------------- |
429 | align 4 |
398 | align 4 |
430 | TCP_socket_send: |
399 | TCP_send: |
431 | 400 | ||
432 | DEBUGF 1,"Creating TCP Packet\n" |
401 | DEBUGF 1,"Creating TCP packet, socket: %x, flags: %x\n",eax, bl |
- | 402 | ||
- | 403 | mov di , IP_PROTO_TCP |
|
433 | 404 | add ecx, TCP_Packet.Data |
|
434 | mov di , IP_PROTO_TCP |
- | |
435 | 405 | ||
436 | ; Create an IPv4 Packet of the correct size |
406 | push bx eax esi |
437 | push eax |
407 | ; Create an IPv4 Packet of the correct size |
438 | mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
408 | mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
439 | mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
409 | mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
440 | - | ||
441 | ; meanwhile, create the pseudoheader in stack, |
- | |
442 | ; (now that we still have all the variables that are needed.) |
- | |
443 | push cx |
- | |
444 | push di |
- | |
445 | push eax |
- | |
446 | push ebx |
- | |
447 | - | ||
448 | - | ||
449 | push ecx esi eax ; save some variables for later |
- | |
450 | add ecx, TCP_Packet.Options |
410 | |
451 | call IPv4_create_packet |
411 | call IPv4_create_packet |
452 | cmp edi, -1 |
412 | cmp edi, -1 |
453 | je .fail |
413 | je .fail |
- | 414 | ||
454 | 415 | ; If there is any data, copy it first |
|
455 | pop esi |
- | |
456 | - | ||
457 | ; Now add the TCP header to the IPv4 packet |
- | |
458 | - | ||
459 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
- | |
460 | pop [edi + TCP_Packet.SequenceNumber] |
- | |
461 | - | ||
462 | push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] |
- | |
463 | pop dword [edi + TCP_Packet.SourcePort] |
- | |
464 | - | ||
465 | - | ||
466 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
416 | pop esi |
467 | pop [edi + TCP_Packet.AckNumber] |
- | |
468 | - | ||
469 | mov al, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.flags] |
417 | push edi |
470 | mov [edi + TCP_Packet.Flags], al |
- | |
471 | - | ||
472 | mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes |
- | |
473 | mov [edi + TCP_Packet.UrgentPointer], 0 |
- | |
474 | mov [edi + TCP_Packet.DataOffset], 0x50 |
- | |
475 | mov [edi + TCP_Packet.Checksum], 0 |
- | |
476 | - | ||
477 | ; Copy the data |
- | |
478 | mov esi, [esp] |
- | |
479 | mov ecx, [esp+4] |
418 | add edi, TCP_Packet.Data |
480 | add edi, TCP_Packet.Options |
419 | sub ecx, TCP_Packet.Data |
481 | 420 | ||
482 | shr ecx, 1 |
421 | shr ecx, 1 |
483 | jnc .nb |
422 | jnc .nb |
484 | movsb |
423 | movsb |
485 | .nb: shr ecx, 1 |
424 | .nb: shr ecx, 1 |
486 | jnc .nw |
425 | jnc .nw |
487 | movsw |
426 | movsw |
488 | .nw: rep movsd |
- | |
489 | - | ||
490 | ; Now, calculate the checksum for pseudoheader |
- | |
491 | xor edx, edx |
427 | .nw: test ecx, ecx |
492 | mov ecx, 12 |
- | |
493 | mov esi, esp |
- | |
494 | call checksum_1 |
- | |
495 | add esp, 12 ; remove the pseudoheader from stack |
- | |
496 | ; And that of the data |
- | |
497 | pop esi |
428 | jz .nd |
498 | pop ecx |
429 | rep movsd |
499 | call checksum_1 |
- | |
500 | ; Now create the final checksum and store it in TCP header |
- | |
501 | call checksum_2 |
- | |
502 | mov [edi + TCP_Packet.Checksum], dx |
- | |
503 | - | ||
504 | ; And now, send it! |
- | |
505 | DEBUGF 1,"Sending TCP Packet to device %x\n", ebx |
- | |
506 | lea esi, [ebx+ETH_DEVICE.transmit] |
- | |
507 | mov edx, [edi + TCP_Packet.AckNumber] |
- | |
508 | jmp TCP_add_to_queue |
- | |
509 | - | ||
510 | .fail: |
- | |
511 | add esp, 12+12+4 |
- | |
512 | ret |
430 | .nd: |
513 | - | ||
514 | - | ||
515 | - | ||
516 | - | ||
517 | - | ||
518 | ;----------------------------------------------------------------- |
- | |
519 | ; |
- | |
520 | ; TCP_send_ack |
- | |
521 | ; |
- | |
522 | ; IN: eax = socket pointer |
- | |
523 | ; bl = flags |
- | |
524 | ; |
- | |
525 | ;----------------------------------------------------------------- |
- | |
526 | align 4 |
- | |
527 | TCP_send_ack: |
- | |
528 | - | ||
529 | DEBUGF 1,"Creating TCP ACK, socket: %x, flags: %x\n",eax, bl |
- | |
530 | - | ||
531 | mov di , IP_PROTO_TCP |
- | |
532 | mov ecx, TCP_Packet.Options |
- | |
533 | - | ||
534 | push bx eax |
- | |
535 | - | ||
536 | ; Create an IPv4 Packet of the correct size |
- | |
537 | - | ||
538 | mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
- | |
539 | mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
- | |
540 | - | ||
541 | call IPv4_create_packet |
- | |
542 | cmp edi, -1 |
431 | pop edi |
543 | je .fail |
- | |
544 | 432 | ||
545 | ; Fill in the TCP header |
433 | ; Fill in the TCP header |
546 | pop esi |
434 | pop esi |
- | 435 | ||
547 | 436 | ; fill in tcp sequence number |
|
548 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
437 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
- | 438 | pop [edi + TCP_Packet.SequenceNumber] |
|
- | 439 | inc_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT) ;;;;;;;; |
|
549 | pop [edi + TCP_Packet.SequenceNumber] |
440 | |
550 | 441 | ; Fill in local and remote ports |
|
- | 442 | push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] |
|
551 | push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] ; both ports at once |
443 | pop dword [edi + TCP_Packet.SourcePort] |
552 | pop dword [edi + TCP_Packet.SourcePort] |
444 | |
553 | 445 | ; Acknumber |
|
554 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
446 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
555 | pop [edi + TCP_Packet.AckNumber] |
447 | pop [edi + TCP_Packet.AckNumber] |
- | 448 | ||
556 | 449 | ; Fill in other tcp options |
|
557 | pop cx |
450 | pop cx |
558 | mov [edi + TCP_Packet.Flags], cl |
451 | mov [edi + TCP_Packet.Flags], cl |
559 | mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes |
452 | mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes |
560 | mov [edi + TCP_Packet.UrgentPointer], 0 |
453 | mov [edi + TCP_Packet.UrgentPointer], 0 |
561 | mov [edi + TCP_Packet.DataOffset], 0x50 |
454 | mov [edi + TCP_Packet.DataOffset], 0x50 |
562 | mov [edi + TCP_Packet.Checksum], 0 |
455 | mov [edi + TCP_Packet.Checksum], 0 |
- | 456 | ||
563 | 457 | ; Push pointer to and size of total packet (needed for send procedure) |
|
564 | push edx eax |
458 | push edx eax |
565 | 459 | ||
566 | ; lea esi, [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
460 | ; push socket number (for TCP_add_to_queue) |
567 | ; inc_INET esi |
461 | push esi |
568 | 462 | ||
569 | ; Now, calculate the checksum |
463 | ; Now, calculate the checksum ; TODO: calculate correct checksum for packets with data |
570 | pushw TCP_Packet.Options shl 8 |
464 | pushw TCP_Packet.Data shl 8 |
571 | pushw IP_PROTO_TCP shl 8 |
465 | pushw IP_PROTO_TCP shl 8 |
572 | pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. |
466 | pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. |
573 | pushd [edi-8] ; source address |
467 | pushd [edi-8] ; source address |
574 | 468 | ||
575 | xor edx, edx |
469 | xor edx, edx |
576 | mov ecx, TCP_Packet.Options |
470 | mov ecx, TCP_Packet.Data |
577 | mov esi, edi |
471 | mov esi, edi |
578 | call checksum_1 |
472 | call checksum_1 |
579 | mov ecx, 12 |
473 | mov ecx, 12 |
580 | mov esi, esp |
474 | mov esi, esp |
581 | call checksum_1 |
475 | call checksum_1 |
582 | add esp, 12 ; remove the pseudoheader from stack |
476 | add esp, 12 ; remove the pseudoheader from stack |
583 | ; and store it in TCP header |
477 | ; and store it in TCP header |
584 | call checksum_2 |
478 | call checksum_2 |
585 | mov [edi + TCP_Packet.Checksum], dx |
479 | mov [edi + TCP_Packet.Checksum], dx |
586 | 480 | ||
587 | ; And now, send the packet! |
481 | ; At last send the packet! |
588 | DEBUGF 1,"Sending TCP Packet to device %x\n", ebx |
- | |
589 | mov esi, [ebx + ETH_DEVICE.transmit] |
482 | DEBUGF 1,"Sending TCP Packet to device %x\n", ebx |
- | 483 | mov edx, [edi + TCP_Packet.SequenceNumber] |
|
- | 484 | bswap edx |
|
- | 485 | mov esi, [ebx + ETH_DEVICE.transmit] |
|
590 | mov edx, [edi + TCP_Packet.SequenceNumber] |
486 | pop edi |
591 | jmp TCP_add_to_queue |
487 | jmp TCP_queue |
592 | 488 | ||
593 | .fail: |
489 | .fail: |
594 | add esp, 2+4 |
490 | add esp, 2+4 |
- | 491 | or eax, -1 |
|
- | 492 | ret |
|
- | 493 | ||
- | 494 | ||
- | 495 | ;----------------------------------------------------------------- |
|
- | 496 | ; |
|
- | 497 | ; Queue a TCP packet for sending |
|
- | 498 | ; |
|
- | 499 | ; IN: [esp] pointer to buffer |
|
- | 500 | ; [esp + 4] size of buffer |
|
- | 501 | ; ebx = driver struct |
|
- | 502 | ; esi = sender proc |
|
- | 503 | ; edx = sequence number of this packet in normal byte order |
|
- | 504 | ; edi = socket number |
|
- | 505 | ; OUT: / |
|
- | 506 | ; |
|
- | 507 | ;----------------------------------------------------------------- |
|
- | 508 | align 4 |
|
- | 509 | TCP_queue: |
|
- | 510 | ||
- | 511 | bswap edx |
|
- | 512 | DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %u\n", [esp], [esp+4], ebx, edx |
|
- | 513 | bswap edx |
|
- | 514 | ||
- | 515 | cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE |
|
- | 516 | jge .full |
|
- | 517 | ||
- | 518 | mov ecx, TCP_QUEUE_SIZE |
|
- | 519 | mov eax, TCP_OUT_QUEUE+4 |
|
- | 520 | ||
- | 521 | .loop: |
|
- | 522 | cmp [eax + tcp_out_queue_entry.data_ptr], 0 |
|
- | 523 | je .found_it |
|
- | 524 | add eax, tcp_out_queue_entry.size |
|
- | 525 | loop .loop |
|
- | 526 | ||
- | 527 | .full: ; silently discard the packet |
|
- | 528 | DEBUGF 1,"TCP queue is full!\n" |
|
- | 529 | ||
- | 530 | call kernel_free |
|
- | 531 | add esp, 4 |
|
- | 532 | ||
- | 533 | ret |
|
- | 534 | ||
- | 535 | .found_it: ; eax points to empty queue entry |
|
- | 536 | ||
- | 537 | pop [eax + tcp_out_queue_entry.data_ptr] |
|
- | 538 | pop [eax + tcp_out_queue_entry.data_size] |
|
- | 539 | mov [eax + tcp_out_queue_entry.ttl], 1 ; send immediately |
|
- | 540 | mov [eax + tcp_out_queue_entry.retries], TCP_RETRIES |
|
- | 541 | mov [eax + tcp_out_queue_entry.owner], ebx |
|
- | 542 | mov [eax + tcp_out_queue_entry.sendproc], esi |
|
- | 543 | mov [eax + tcp_out_queue_entry.seq_num], edx |
|
- | 544 | mov [eax + tcp_out_queue_entry.socket], edi |
|
- | 545 | ||
- | 546 | inc [TCP_OUT_QUEUE] |
|
- | 547 | ||
- | 548 | sub eax, TCP_OUT_QUEUE+4 |
|
- | 549 | DEBUGF 1,"Added to queue in pos %u\n", eax |
|
- | 550 | ||
595 | ret |
551 | ret |
596 | 552 | ||
597 | 553 | ||
598 | 554 | ||
599 | 555 | ||
600 | 556 | ||
601 | ;---------- TCB state handlers start here |
557 | ;---------- TCB state handlers start here |
602 | 558 | ||
603 | 559 | ||
604 | 560 | ||
605 | 561 | ||
606 | align 4 |
562 | align 4 |
607 | stateTCB_LISTEN: |
563 | stateTCB_LISTEN: |
608 | 564 | ||
609 | DEBUGF 1,"TCBStateHandler: Listen\n" |
565 | DEBUGF 1,"TCBStateHandler: Listen\n" |
610 | - | ||
611 | ; In this case, we are expecting a SYN Packet |
566 | |
612 | ; For now, if the Packet is a SYN, process it, and send a response |
- | |
613 | ; If not, ignore it |
- | |
614 | - | ||
615 | ; Look at control flags |
- | |
616 | test [edx + TCP_Packet.Flags], TH_SYN |
567 | test [edx + TCP_Packet.Flags], TH_SYN ; SYN packet? => send syn+ack, open new socket and set connection to established |
617 | jz .exit |
568 | jz .exit |
618 | ; Exit if backlog queue is full |
569 | ; Exit if backlog queue is full |
619 | mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
570 | mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
620 | cmp ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog] |
571 | cmp ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog] |
621 | jae .exit |
572 | jae .exit |
622 | ; Allocate new socket |
573 | ; Allocate new socket |
623 | push esi |
574 | push esi edi |
624 | call net_socket_alloc |
575 | call net_socket_alloc |
625 | pop esi |
- | |
626 | test eax, eax |
576 | test eax, eax |
627 | jz .exit |
577 | jz .fail |
628 | ; Copy structure from current socket to new, including lock |
578 | ; Copy structure from current socket to new, including lock |
629 | push esi edi |
- | |
630 | lea esi, [ebx + SOCKET_head.PID] ; yes, PID must also be copied |
579 | lea esi, [ebx + SOCKET_head.PID] ; yes, PID must also be copied |
631 | lea edi, [eax + SOCKET_head.PID] |
580 | lea edi, [eax + SOCKET_head.PID] |
632 | mov ecx, ((SOCKET_head.end - SOCKET_head.PID) + IPv4_SOCKET.end + TCP_SOCKET.end + 3)/4 |
581 | mov ecx, ((SOCKET_head.end - SOCKET_head.PID) + IPv4_SOCKET.end + TCP_SOCKET.end + 3)/4 |
633 | rep movsd |
582 | rep movsd |
634 | pop edi esi |
583 | pop edi esi |
635 | ; Push pointer to new socket to queue |
584 | ; Push pointer to new socket to queue |
636 | movzx ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
585 | movzx ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
637 | inc [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
586 | inc [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
638 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + ecx*4], eax |
587 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + ecx*4], eax |
639 | - | ||
640 | ; We have a SYN. update the socket with this IP Packets details, |
- | |
641 | ; And send a response |
- | |
642 | 588 | ||
643 | mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], esi ; IP source address |
589 | mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], esi ; IP source address |
644 | mov cx, [edx + TCP_Packet.SourcePort] |
590 | mov cx, [edx + TCP_Packet.SourcePort] |
645 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], cx |
591 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], cx |
646 | mov ecx, [edx + TCP_Packet.SequenceNumber] |
592 | mov ecx, [edx + TCP_Packet.SequenceNumber] |
647 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.IRS], ecx |
593 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.IRS], ecx |
648 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], ecx |
594 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], ecx |
649 | lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
595 | lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
650 | inc_INET esi ; RCV.NXT |
596 | inc_INET esi ; RCV.NXT |
651 | mov ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS] |
597 | mov ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS] |
652 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], ecx |
598 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], ecx |
653 | - | ||
654 | mov [eax + SOCKET_head.lock], 0 |
599 | |
655 | mov [ebx + SOCKET_head.lock], 0 |
600 | mov [ebx + SOCKET_head.lock], 0 |
656 | 601 | ||
657 | push eax |
602 | push eax |
658 | ; Now construct the response |
603 | ; Now construct the response |
659 | mov bl, TH_SYN + TH_ACK |
604 | mov bl, TH_SYN + TH_ACK |
- | 605 | xor ecx, ecx |
|
660 | call TCP_send_ack |
606 | call TCP_send |
661 | pop eax |
607 | pop eax |
- | 608 | ||
662 | 609 | mov [eax + SOCKET_head.lock], 0 |
|
663 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED |
610 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED |
664 | call notify_network_event |
- | |
665 | - | ||
666 | ; increment SND.NXT in socket |
- | |
667 | lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
- | |
668 | inc_INET esi |
611 | call notify_network_event |
669 | ret |
612 | ret |
670 | 613 | ||
671 | .exit: |
614 | .exit: |
672 | mov [ebx + SOCKET_head.lock], 0 |
615 | mov [ebx + SOCKET_head.lock], 0 |
673 | ret |
616 | ret |
- | 617 | ||
- | 618 | .fail: |
|
- | 619 | add esp, 8 |
|
- | 620 | mov [ebx + SOCKET_head.lock], 0 |
|
- | 621 | ret |
|
674 | 622 | ||
675 | 623 | ||
676 | align 4 |
624 | align 4 |
677 | stateTCB_SYN_SENT: |
625 | stateTCB_SYN_SENT: |
678 | 626 | ||
679 | DEBUGF 1,"TCBStateHandler: Syn_Sent\n" |
627 | DEBUGF 1,"TCBStateHandler: Syn_Sent\n" |
680 | 628 | ||
681 | ; We are awaiting an ACK to our SYN, with a SYM |
629 | ; We are awaiting an ACK to our SYN, with a SYM |
682 | ; Look at control flags - expecting an ACK |
630 | ; Look at control flags - expecting an ACK |
683 | 631 | ||
684 | mov al, [edx + TCP_Packet.Flags] |
632 | mov al, [edx + TCP_Packet.Flags] |
685 | and al, TH_SYN + TH_ACK |
- | |
686 | cmp al, TH_SYN + TH_ACK |
- | |
687 | je .syn_ack |
- | |
688 | 633 | ||
689 | test al, TH_SYN |
634 | test al, TH_RST |
- | 635 | jnz .reset ; jump if RST bit set |
|
690 | jz .exit |
636 | |
691 | 637 | push [edx + TCP_Packet.SequenceNumber] ;; |
|
692 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED |
- | |
693 | pushd TH_SYN + TH_ACK |
- | |
694 | jmp .send |
- | |
695 | - | ||
696 | .syn_ack: |
- | |
697 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED |
- | |
698 | pushd TH_ACK |
638 | pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] ;; |
699 | 639 | inc_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT) ;; |
|
700 | .send: |
- | |
701 | ; Store the recv.nxt field |
- | |
702 | mov eax, [edx + TCP_Packet.SequenceNumber] |
- | |
703 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.IRS], eax |
- | |
704 | bswap eax |
- | |
- | 640 | ||
705 | inc eax |
641 | |
706 | bswap eax |
- | |
- | 642 | push [edx + TCP_Packet.AckNumber] ;;;;;; |
|
- | 643 | pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] ;;;;;; |
|
- | 644 | ||
- | 645 | and al, TH_SYN + TH_ACK |
|
- | 646 | jz .exit ; jump if none of the following is set: RST, SYN, ACK |
|
- | 647 | ||
- | 648 | test al, TH_ACK |
|
- | 649 | jz .onlysyn ; jump if only SYN bit is set |
|
707 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], eax ; Update our recv.nxt field |
650 | |
708 | mov [ebx + SOCKET_head.lock], 0 |
651 | ; If we arrived here, SYN and ACK are set |
- | 652 | ||
- | 653 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED |
|
- | 654 | pushw TH_ACK |
|
- | 655 | ||
709 | 656 | .send: ; Send an ACK |
|
710 | lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
- | |
711 | inc_INET esi |
657 | mov eax, ebx |
712 | 658 | pop bx |
|
713 | ; Send an ACK |
659 | push eax |
714 | mov eax, ebx |
660 | xor ecx, ecx |
715 | pop ebx |
661 | call TCP_send |
716 | call TCP_send_ack |
662 | pop ebx |
717 | 663 | ||
718 | .exit: |
664 | .exit: |
719 | mov [ebx + SOCKET_head.lock], 0 |
665 | mov [ebx + SOCKET_head.lock], 0 |
720 | ret |
666 | ret |
- | 667 | ||
- | 668 | .reset: |
|
- | 669 | ; TODO: .... |
|
- | 670 | ||
- | 671 | ; remove all queued TCP packets for this connection ! |
|
- | 672 | ||
- | 673 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSED |
|
- | 674 | mov [ebx + SOCKET_head.lock], 0 |
|
- | 675 | ret |
|
- | 676 | ||
- | 677 | .onlysyn: |
|
- | 678 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED |
|
- | 679 | pushw TH_SYN + TH_ACK |
|
- | 680 | jmp .send |
|
721 | 681 | ||
722 | 682 | ||
723 | 683 | ||
724 | align 4 |
684 | align 4 |
725 | stateTCB_SYN_RECEIVED: |
685 | stateTCB_SYN_RECEIVED: |
726 | 686 | ||
727 | DEBUGF 1,"TCBStateHandler: Syn_received\n" |
687 | DEBUGF 1,"TCBStateHandler: Syn_received\n" |
728 | - | ||
729 | ; In this case, we are expecting an ACK Packet |
- | |
730 | ; For now, if the Packet is an ACK, process it, |
- | |
731 | ; If not, ignore it |
- | |
732 | 688 | ||
733 | test [edx + TCP_Packet.Flags], TH_RST |
689 | test [edx + TCP_Packet.Flags], TH_RST ; reset connection? => LISTEN |
734 | jz .check_ack |
690 | jz .check_ack |
735 | 691 | ||
736 | ; push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemotePort] |
692 | push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemotePort] |
737 | ; pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort] |
693 | pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort] |
738 | ; push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemoteIP] |
694 | push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemoteIP] |
739 | ; pop [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
695 | pop [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
740 | 696 | ||
741 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN |
697 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN |
742 | jmp .exit |
698 | jmp .exit |
743 | 699 | ||
744 | .check_ack: |
700 | .check_ack: |
745 | ; Look at control flags - expecting an ACK |
- | |
746 | test [edx + TCP_Packet.Flags], TH_ACK |
701 | test [edx + TCP_Packet.Flags], TH_ACK ; ACK? => connection established! |
747 | jz .exit |
702 | jz .exit |
748 | 703 | ||
749 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED |
704 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED |
750 | mov eax, ebx |
705 | mov eax, ebx |
751 | call notify_network_event |
706 | call notify_network_event |
752 | 707 | ||
753 | .exit: |
708 | .exit: |
754 | mov [ebx + SOCKET_head.lock], 0 |
709 | mov [ebx + SOCKET_head.lock], 0 |
755 | ret |
710 | ret |
756 | 711 | ||
757 | 712 | ||
758 | 713 | ||
759 | align 4 |
714 | align 4 |
760 | stateTCB_ESTABLISHED: |
715 | stateTCB_ESTABLISHED: |
761 | - | ||
762 | 716 | ||
763 | DEBUGF 1,"TCBStateHandler: Established\n" |
717 | DEBUGF 1,"TCBStateHandler: Established\n" |
764 | 718 | ||
765 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
719 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
- | 720 | bswap eax |
|
- | 721 | DEBUGF 1,"RCV_NXT is set to:%u\n", eax |
|
- | 722 | bswap eax |
|
766 | cmp eax, [edx + TCP_Packet.SequenceNumber] |
723 | cmp eax, [edx + TCP_Packet.SequenceNumber] |
767 | jne .exit |
724 | jne .exit |
768 | 725 | ||
- | 726 | ; Calculate next sequencenumber |
|
- | 727 | test ecx, ecx |
|
- | 728 | jnz @f |
|
769 | ; Here we are expecting data, or a request to close |
729 | inc ecx |
- | 730 | @@: |
|
770 | ; OR both... |
- | |
771 | 731 | add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT) |
|
772 | ; Did we receive a FIN or RST? |
732 | |
773 | test [edx + TCP_Packet.Flags], TH_FIN |
- | |
774 | jz .check_ack |
- | |
775 | - | ||
776 | ; It was a fin or reset. |
- | |
777 | - | ||
778 | ;;; TODO: write following code: |
- | |
779 | ; Remove resend entries from the queue - I dont want to send any more data |
733 | test [edx + TCP_Packet.Flags], TH_FIN |
780 | ; Send an ACK to that fin, and enter closewait state |
- | |
781 | 734 | jnz .fin |
|
782 | .check_ack: |
735 | |
783 | ; Check that we received an ACK |
736 | .check_ack: |
784 | test [edx + TCP_Packet.Flags], TH_ACK |
737 | test [edx + TCP_Packet.Flags], TH_ACK |
785 | jz .exit |
738 | jz .exit |
786 | 739 | ||
787 | DEBUGF 1,"Received ACK\n" |
740 | DEBUGF 1,"Received ACK\n" |
788 | - | ||
789 | ; First, look at the incoming window. If this is less than or equal to 1024, |
741 | ; First, look at the incoming window. If this is less than or equal to 1024, |
790 | ; Set the socket window timer to 1. This will stop an additional Packets being queued. |
742 | ; Set the socket window timer to 1. This will stop an additional Packets being queued. |
791 | ; ** I may need to tweak this value, since I do not know how many Packets are already queued |
743 | ; ** I may need to tweak this value, since I do not know how many Packets are already queued |
792 | push ecx |
744 | push ecx |
793 | mov cx, [edx + TCP_Packet.Window] |
745 | mov cx, [edx + TCP_Packet.Window] |
794 | xchg cl, ch |
746 | xchg cl, ch |
795 | cmp cx, 1024 |
747 | cmp cx, 1024 |
796 | ja @f |
748 | ja @f |
797 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1 |
749 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1 |
798 | @@: |
750 | @@: |
799 | pop ecx |
751 | pop ecx |
- | 752 | ||
800 | 753 | ; Now, see if we received any data |
|
801 | test ecx, ecx |
- | |
802 | jnz .data ; Read data, if any |
- | |
803 | - | ||
804 | lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
754 | test ecx, ecx |
- | 755 | jz .ack |
|
805 | inc_INET esi |
756 | |
806 | 757 | DEBUGF 1,"Got %u bytes data!\n", ecx |
|
807 | ; If we had received a fin, we need to ACK it. |
758 | ; calculate header length |
808 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT |
759 | movzx eax, [edx + TCP_Packet.DataOffset] |
809 | je .ack |
- | |
- | 760 | and eax, 11110000b |
|
810 | jmp .exit |
761 | shr eax, 2 |
811 | 762 | DEBUGF 1,"TCP header size: %u\n", eax |
|
812 | .data: |
- | |
813 | ;;; |
763 | add edx, eax |
814 | lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
- | |
815 | add_INET esi |
- | |
816 | 764 | add esp, 4 |
|
817 | DEBUGF 1,"Got data!\n" |
765 | pop esi |
818 | mov esi, [esp + 4] |
766 | add esp, 4 |
819 | sub edx, esi |
767 | sub edx, esi |
820 | mov edi, edx |
768 | mov edi, edx |
821 | mov eax, ebx |
769 | mov eax, ebx |
822 | call socket_internal_receiver |
770 | jmp socket_internal_receiver ; Place the data from packet into socket |
823 | 771 | ||
824 | .ack: |
- | |
825 | mov [ebx + SOCKET_head.lock], 0 |
- | |
826 | ; Send an ACK |
772 | .ack: |
827 | mov eax, ebx |
773 | mov eax, ebx |
- | 774 | mov bl, TH_ACK |
|
- | 775 | push eax |
|
828 | mov bl, TH_ACK |
776 | xor ecx, ecx |
- | 777 | call TCP_send ; send the ack |
|
829 | call TCP_send_ack |
778 | pop ebx |
830 | .exit: |
- | |
831 | 779 | .exit: |
|
832 | mov [ebx + SOCKET_head.lock], 0 |
780 | mov [ebx + SOCKET_head.lock], 0 |
833 | ret |
781 | ret |
- | 782 | ||
- | 783 | .fin: |
|
- | 784 | ; Remove all resend entries from the queue |
|
- | 785 | mov ecx, TCP_QUEUE_SIZE |
|
- | 786 | mov esi, TCP_OUT_QUEUE+4 |
|
- | 787 | ||
- | 788 | .removeloop: |
|
- | 789 | cmp [esi + tcp_out_queue_entry.data_ptr], 0 |
|
- | 790 | je .maybe_next |
|
- | 791 | ||
- | 792 | ; TODO: check if the packets belong to the same tcp connection ! |
|
- | 793 | ||
- | 794 | DEBUGF 1,"Removing a queued packet\n" |
|
- | 795 | ||
- | 796 | push [esi + tcp_out_queue_entry.data_ptr] |
|
- | 797 | mov [esi + tcp_out_queue_entry.data_ptr], 0 |
|
- | 798 | dec [TCP_OUT_QUEUE] |
|
- | 799 | call kernel_free |
|
- | 800 | ||
- | 801 | .maybe_next: |
|
- | 802 | add esi, tcp_out_queue_entry.size |
|
- | 803 | loop .removeloop |
|
- | 804 | ||
- | 805 | ; Send an ACK to that fin, and enter closewait state |
|
- | 806 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT |
|
- | 807 | jmp .check_ack |
|
834 | 808 | ||
835 | 809 | ||
836 | 810 | ||
837 | align 4 |
811 | align 4 |
838 | stateTCB_FIN_WAIT_1: |
812 | stateTCB_FIN_WAIT_1: |
839 | 813 | ||
840 | DEBUGF 1,"TCBStateHandler: Fin_wait_1\n" |
814 | DEBUGF 1,"TCBStateHandler: Fin_wait_1\n" |
841 | 815 | ||
842 | ; We can either receive an ACK of a fin, or a fin |
816 | ; We can either receive an ACK of a fin, or a fin |
843 | mov al, [edx + TCP_Packet.Flags] |
817 | mov al, [edx + TCP_Packet.Flags] |
844 | and al, TH_FIN + TH_ACK |
818 | and al, TH_FIN + TH_ACK |
845 | 819 | ||
846 | cmp al, TH_ACK |
820 | cmp al, TH_ACK |
847 | jne @f |
821 | jne @f |
848 | 822 | ||
849 | ; It was an ACK |
823 | ; It was an ACK |
850 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_2 |
824 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_2 |
851 | jmp .exit |
825 | jmp .exit |
852 | 826 | ||
853 | @@: mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSING |
827 | @@: mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSING |
854 | cmp al, TH_FIN |
828 | cmp al, TH_FIN |
855 | je @f |
829 | je @f |
856 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT |
830 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT |
- | 831 | ||
- | 832 | @@: |
|
857 | 833 | ||
858 | @@: lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
834 | ; lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
859 | inc_INET esi |
- | |
860 | 835 | ; inc_INET esi |
|
861 | mov [ebx + SOCKET_head.lock], 0 |
836 | |
862 | ; Send an ACK |
837 | ; Send an ACK |
863 | mov eax, ebx |
838 | mov eax, ebx |
864 | mov bl, TH_ACK |
839 | mov bl, TH_ACK |
- | 840 | push eax |
|
- | 841 | xor ecx, ecx |
|
865 | call TCP_send_ack |
842 | call TCP_send |
- | 843 | pop ebx |
|
866 | 844 | ||
867 | .exit: |
845 | .exit: |
868 | mov [ebx + SOCKET_head.lock], 0 |
846 | mov [ebx + SOCKET_head.lock], 0 |
869 | ret |
847 | ret |
870 | 848 | ||
871 | 849 | ||
872 | 850 | ||
873 | align 4 |
851 | align 4 |
874 | stateTCB_FIN_WAIT_2: |
852 | stateTCB_FIN_WAIT_2: |
875 | 853 | ||
876 | DEBUGF 1,"TCBStateHandler: Fin_wait_2\n" |
854 | DEBUGF 1,"TCBStateHandler: Fin_wait_2\n" |
877 | 855 | ||
878 | test [edx + TCP_Packet.Flags], TH_FIN |
856 | test [edx + TCP_Packet.Flags], TH_FIN |
879 | jz .exit |
857 | jz .exit |
880 | 858 | ||
881 | ; Change state, as we have a fin |
859 | ; Change state, as we have a fin |
882 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT |
860 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT |
883 | 861 | ||
884 | lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
862 | lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
885 | inc_INET esi |
863 | inc_INET esi |
886 | 864 | ||
887 | mov [ebx + SOCKET_head.lock], 0 |
865 | mov [ebx + SOCKET_head.lock], 0 |
888 | 866 | ||
889 | ; Send an ACK |
867 | ; Send an ACK |
890 | mov eax, ebx |
868 | mov eax, ebx |
891 | mov bl, TH_ACK |
869 | mov bl, TH_ACK |
- | 870 | push eax |
|
- | 871 | xor ecx, ecx |
|
892 | call TCP_send_ack |
872 | call TCP_send |
- | 873 | pop ebx |
|
893 | 874 | ||
894 | .exit: |
875 | .exit: |
895 | mov [ebx + SOCKET_head.lock], 0 |
876 | mov [ebx + SOCKET_head.lock], 0 |
896 | ret |
877 | ret |
897 | 878 | ||
898 | 879 | ||
899 | 880 | ||
900 | align 4 |
881 | align 4 |
901 | stateTCB_CLOSE_WAIT: |
882 | stateTCB_CLOSE_WAIT: |
902 | 883 | ||
903 | DEBUGF 1,"TCBStateHandler: close_wait\n" |
884 | DEBUGF 1,"TCBStateHandler: close_wait\n" |
904 | ; Intentionally left empty |
885 | ; Intentionally left empty |
905 | ; socket_close_tcp handles this |
886 | ; socket_close_tcp handles this |
906 | 887 | ||
907 | mov [ebx + SOCKET_head.lock], 0 |
888 | mov [ebx + SOCKET_head.lock], 0 |
908 | ret |
889 | ret |
909 | 890 | ||
910 | 891 | ||
911 | 892 | ||
912 | align 4 |
893 | align 4 |
913 | stateTCB_CLOSING: |
894 | stateTCB_CLOSING: |
914 | 895 | ||
915 | DEBUGF 1,"TCBStateHandler: closingn\n" |
896 | DEBUGF 1,"TCBStateHandler: closingn\n" |
916 | 897 | ||
917 | ; We can either receive an ACK of a fin, or a fin |
898 | ; We can either receive an ACK of a fin, or a fin |
918 | test [edx + TCP_Packet.Flags], TH_ACK |
899 | test [edx + TCP_Packet.Flags], TH_ACK |
919 | jz .exit |
900 | jz .exit |
920 | 901 | ||
921 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT |
902 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT |
922 | 903 | ||
923 | .exit: |
904 | .exit: |
924 | 905 | ||
925 | mov [ebx + SOCKET_head.lock], 0 |
906 | mov [ebx + SOCKET_head.lock], 0 |
926 | ret |
907 | ret |
927 | 908 | ||
928 | 909 | ||
929 | align 4 |
910 | align 4 |
930 | stateTCB_LAST_ACK: |
911 | stateTCB_LAST_ACK: |
931 | 912 | ||
932 | DEBUGF 1,"TCBStateHandler: last_ackn\n" |
913 | DEBUGF 1,"TCBStateHandler: last_ackn\n" |
933 | 914 | ||
934 | ; Look at control flags - expecting an ACK |
915 | ; Look at control flags - expecting an ACK |
935 | test [edx + TCP_Packet.Flags], TH_ACK |
916 | test [edx + TCP_Packet.Flags], TH_ACK |
936 | jz .exit |
917 | jz .exit |
937 | 918 | ||
938 | mov [ebx + SOCKET_head.lock], 0 |
919 | mov [ebx + SOCKET_head.lock], 0 |
939 | 920 | ||
940 | ; delete the socket |
921 | ; delete the socket |
941 | stdcall net_socket_free, ebx |
922 | stdcall net_socket_free, ebx |
942 | 923 | ||
943 | .exit: |
924 | .exit: |
944 | ret |
925 | ret |
945 | 926 | ||
946 | 927 | ||
947 | align 4 |
928 | align 4 |
948 | stateTCB_TIME_WAIT: |
929 | stateTCB_TIME_WAIT: |
949 | 930 | ||
950 | DEBUGF 1,"TCBStateHandler: time_wait\n" |
931 | DEBUGF 1,"TCBStateHandler: time_wait\n" |
951 | 932 | ||
952 | mov [ebx + SOCKET_head.lock], 0 |
933 | mov [ebx + SOCKET_head.lock], 0 |
953 | 934 | ||
954 | ret |
935 | ret |
955 | 936 | ||
956 | 937 | ||
957 | align 4 |
938 | align 4 |
958 | stateTCB_CLOSED: |
939 | stateTCB_CLOSED: |
959 | 940 | ||
960 | DEBUGF 1,"TCBStateHandler: closed\n" |
941 | DEBUGF 1,"TCBStateHandler: closed\n" |
961 | 942 | ||
962 | mov [ebx + SOCKET_head.lock], 0 |
943 | mov [ebx + SOCKET_head.lock], 0 |
963 | 944 | ||
964 | ret |
945 | ret |
965 | 946 | ||
966 | 947 | ||
967 | 948 | ||
968 | ;--------------------------------------------------------------------------- |
949 | ;--------------------------------------------------------------------------- |
969 | ; |
950 | ; |
970 | ; TCP_API |
951 | ; TCP_API |
971 | ; |
952 | ; |
972 | ; This function is called by system function 75 |
953 | ; This function is called by system function 75 |
973 | ; |
954 | ; |
974 | ; IN: subfunction number in bl |
955 | ; IN: subfunction number in bl |
975 | ; device number in bh |
956 | ; device number in bh |
976 | ; ecx, edx, .. depends on subfunction |
957 | ; ecx, edx, .. depends on subfunction |
977 | ; |
958 | ; |
978 | ; OUT: |
959 | ; OUT: |
979 | ; |
960 | ; |
980 | ;--------------------------------------------------------------------------- |
961 | ;--------------------------------------------------------------------------- |
981 | align 4 |
962 | align 4 |
982 | TCP_API: |
963 | TCP_API: |
983 | 964 | ||
984 | movzx eax, bh |
965 | movzx eax, bh |
985 | shl eax, 2 |
966 | shl eax, 2 |
986 | 967 | ||
987 | test bl, bl |
968 | test bl, bl |
988 | jz .packets_tx ; 0 |
969 | jz .packets_tx ; 0 |
989 | dec bl |
970 | dec bl |
990 | jz .packets_rx ; 1 |
971 | jz .packets_rx ; 1 |
991 | 972 | ||
992 | .error: |
973 | .error: |
993 | mov eax, -1 |
974 | mov eax, -1 |
994 | ret |
975 | ret |
995 | 976 | ||
996 | .packets_tx: |
977 | .packets_tx: |
997 | add eax, TCP_PACKETS_TX |
978 | add eax, TCP_PACKETS_TX |
998 | mov eax, [eax] |
979 | mov eax, [eax] |
999 | ret |
980 | ret |
1000 | 981 | ||
1001 | .packets_rx: |
982 | .packets_rx: |
1002 | add eax, TCP_PACKETS_RX |
983 | add eax, TCP_PACKETS_RX |
1003 | mov eax, [eax] |
984 | mov eax, [eax] |
1004 | ret |
985 | ret |