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