Rev 1206 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1206 | Rev 1249 | ||
---|---|---|---|
Line 13... | Line 13... | ||
13 | ;; Version 2, June 1991 ;; |
13 | ;; Version 2, June 1991 ;; |
14 | ;; ;; |
14 | ;; ;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 16... | Line 16... | ||
16 | 16 | ||
Line 17... | Line -... | ||
17 | - | ||
18 | $Revision: 1206 $ |
17 | |
19 | 18 | $Revision: 1249 $ |
|
20 | 19 | ||
21 | ; TCP TCB states |
20 | |
22 | TCB_LISTEN equ 1 |
21 | TCB_LISTEN equ 1 |
Line 29... | Line 28... | ||
29 | TCB_CLOSING equ 8 |
28 | TCB_CLOSING equ 8 |
30 | TCB_LAST_ACK equ 9 |
29 | TCB_LAST_ACK equ 9 |
31 | TCB_TIMED_WAIT equ 10 |
30 | TCB_TIMED_WAIT equ 10 |
32 | TCB_CLOSED equ 11 |
31 | TCB_CLOSED equ 11 |
Line 33... | Line 32... | ||
33 | 32 | ||
34 | TH_FIN equ 0x01 |
33 | TH_FIN equ 1 shl 0 |
35 | TH_SYN equ 0x02 |
34 | TH_SYN equ 1 shl 1 |
36 | TH_RST equ 0x04 |
35 | TH_RST equ 1 shl 2 |
37 | TH_PUSH equ 0x08 |
36 | TH_PUSH equ 1 shl 3 |
38 | TH_ACK equ 0x10 |
37 | TH_ACK equ 1 shl 4 |
Line 39... | Line 38... | ||
39 | TH_URG equ 0x20 |
38 | TH_URG equ 1 shl 5 |
Line 40... | Line 39... | ||
40 | 39 | ||
41 | TWOMSL equ 10 ; # of secs to wait before closing socket |
40 | TWOMSL equ 10 ; # of secs to wait before closing socket |
Line 42... | Line 41... | ||
42 | 41 | ||
Line -... | Line 42... | ||
- | 42 | TCP_RETRIES equ 5 ; Number of times to resend a Packet |
|
43 | TCP_RETRIES equ 5 ; Number of times to resend a Packet |
43 | TCP_TIMEOUT equ 10 ; resend if not replied to in 1/100 s |
44 | TCP_TIMEOUT equ 10 ; resend if not replied to in x hs |
44 | |
45 | 45 | TCP_QUEUE_SIZE equ 16 |
|
46 | TCP_QUEUE_SIZE equ 16 |
46 | |
47 | 47 | ||
Line 63... | Line 63... | ||
63 | align 4 |
63 | align 4 |
64 | uglobal |
64 | uglobal |
65 | TCP_PACKETS_TX rd MAX_IP |
65 | TCP_PACKETS_TX rd MAX_IP |
66 | TCP_PACKETS_RX rd MAX_IP |
66 | TCP_PACKETS_RX rd MAX_IP |
Line 67... | Line 67... | ||
67 | 67 | ||
68 | TCP_IN_QUEUE rd 3*TCP_QUEUE_SIZE+3 |
68 | TCP_IN_QUEUE rd (tcp_in_queue_entry.size*TCP_QUEUE_SIZE+queue.data)/4 |
- | 69 | TCP_OUT_QUEUE dd ? |
|
69 | TCP_OUT_QUEUE rd 3*TCP_QUEUE_SIZE+3 |
70 | rd (tcp_out_queue_entry.size*TCP_QUEUE_SIZE)/4 |
Line -... | Line 71... | ||
- | 71 | endg |
|
- | 72 | ||
- | 73 | align 4 |
|
- | 74 | iglobal |
|
- | 75 | ||
- | 76 | TCBStateHandler: |
|
- | 77 | ||
- | 78 | dd stateTCB_LISTEN |
|
- | 79 | dd stateTCB_SYN_SENT |
|
- | 80 | dd stateTCB_SYN_RECEIVED |
|
- | 81 | dd stateTCB_ESTABLISHED |
|
- | 82 | dd stateTCB_FIN_WAIT_1 |
|
- | 83 | dd stateTCB_FIN_WAIT_2 |
|
- | 84 | dd stateTCB_CLOSE_WAIT |
|
- | 85 | dd stateTCB_CLOSING |
|
- | 86 | dd stateTCB_LAST_ACK |
|
- | 87 | dd stateTCB_TIME_WAIT |
|
- | 88 | dd stateTCB_CLOSED |
|
- | 89 | ||
- | 90 | endg |
|
- | 91 | ||
- | 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 |
|
Line 70... | Line 111... | ||
70 | endg |
111 | |
Line 90... | Line 131... | ||
90 | xor eax, eax |
131 | xor eax, eax |
91 | mov edi, TCP_PACKETS_TX |
132 | mov edi, TCP_PACKETS_TX |
92 | mov ecx, 2*MAX_IP |
133 | mov ecx, 2*MAX_IP |
93 | rep stosd |
134 | rep stosd |
Line 94... | Line 135... | ||
94 | 135 | ||
95 | mov dword [TCP_IN_QUEUE], TCP_QUEUE_SIZE |
- | |
96 | mov dword [TCP_IN_QUEUE+4], TCP_IN_QUEUE + queue.data |
- | |
97 | mov dword [TCP_IN_QUEUE+8], TCP_IN_QUEUE + queue.data |
- | |
98 | 136 | init_queue TCP_IN_QUEUE |
|
99 | mov dword [TCP_OUT_QUEUE], TCP_QUEUE_SIZE |
- | |
100 | mov dword [TCP_OUT_QUEUE+4], TCP_OUT_QUEUE + queue.data |
- | |
Line 101... | Line 137... | ||
101 | mov dword [TCP_OUT_QUEUE+8], TCP_OUT_QUEUE + queue.data |
137 | init_queue TCP_OUT_QUEUE |
Line 102... | Line 138... | ||
102 | 138 | ||
103 | ret |
139 | ret |
104 | 140 | ||
105 | 141 | ||
106 | ;----------------------------------------------------------------- |
142 | ;----------------------------------------------------------------- |
107 | ; |
143 | ; |
108 | ; tcp_tcb_handler |
144 | ; TCP_decrease_socket_ttls |
109 | ; |
145 | ; |
Line 110... | Line 146... | ||
110 | ; Handles sockets in the timewait state, closing them |
146 | ; IN: / |
111 | ; when the TCB timer expires |
147 | ; OUT: / |
112 | ; |
148 | ; |
Line 113... | Line 149... | ||
113 | ;----------------------------------------------------------------- |
149 | ;----------------------------------------------------------------- |
Line 114... | Line 150... | ||
114 | 150 | ||
115 | align 4 |
151 | align 4 |
116 | tcp_tcb_handler: |
- | |
Line 117... | Line 152... | ||
117 | ; scan through all the sockets, decrementing active timers |
152 | TCP_decrease_socket_ttls: |
118 | 153 | ; scan through all the sockets, decrementing active timers |
|
119 | mov ebx, net_sockets |
154 | |
120 | 155 | mov ebx, net_sockets |
|
Line -... | Line 156... | ||
- | 156 | ||
- | 157 | cmp [ebx + SOCKET_head.NextPtr], 0 |
|
- | 158 | je .exit |
|
121 | cmp [ebx + SOCKET.NextPtr], 0 |
159 | |
Line 122... | Line 160... | ||
122 | je .exit |
160 | .next_socket: |
123 | DEBUGF 1, "K : sockets:\n" |
161 | mov ebx, [ebx + SOCKET_head.NextPtr] |
124 | 162 | or ebx, ebx |
|
125 | .next_socket: |
163 | jz .exit |
126 | mov ebx, [ebx + SOCKET.NextPtr] |
164 | |
Line 127... | Line 165... | ||
127 | or ebx, ebx |
165 | cmp [ebx + SOCKET_head.Type], IP_PROTO_TCP |
128 | jz .exit |
166 | jne .next_socket |
129 | 167 | ||
130 | ; 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] |
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] |
Line 131... | Line 169... | ||
131 | 169 | ||
132 | cmp [ebx + SOCKET.TCBTimer], 0 |
170 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBTimer], 0 |
Line 133... | Line 171... | ||
133 | jne .decrement_tcb |
171 | jne .decrement_tcb |
134 | cmp [ebx + SOCKET.wndsizeTimer], 0 |
172 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0 |
135 | jne .decrement_wnd |
173 | jne .decrement_wnd |
136 | jmp .next_socket |
174 | jmp .next_socket |
Line 137... | Line 175... | ||
137 | 175 | ||
138 | .decrement_tcb: |
176 | .decrement_tcb: |
139 | ; decrement it, delete socket if TCB timer = 0 & socket in timewait state |
177 | ; decrement it, delete socket if TCB timer = 0 & socket in timewait state |
140 | dec [ebx + SOCKET.TCBTimer] |
178 | dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBTimer] |
Line 141... | Line 179... | ||
141 | jnz .next_socket |
179 | jnz .next_socket |
142 | 180 | ||
Line -... | Line 181... | ||
- | 181 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_TIMED_WAIT |
|
143 | cmp [ebx + SOCKET.TCBState], TCB_TIMED_WAIT |
182 | jne .next_socket |
144 | jne .next_socket |
183 | |
145 | 184 | push [ebx + SOCKET_head.PrevPtr] |
|
146 | push [ebx + SOCKET.PrevPtr] |
185 | stdcall net_socket_free, ebx |
147 | stdcall net_socket_free, ebx |
186 | pop ebx |
148 | pop ebx |
187 | jmp .next_socket |
149 | jmp .next_socket |
188 | |
- | 189 | .decrement_wnd: |
|
- | 190 | ; TODO - prove it works! |
|
- | 191 | dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer] |
|
150 | 192 | jmp .next_socket |
|
151 | .decrement_wnd: |
193 | |
Line 152... | Line 194... | ||
152 | ; TODO - prove it works! |
194 | .exit: |
153 | dec [ebx + SOCKET.wndsizeTimer] |
- | |
154 | jmp .next_socket |
- | |
155 | - | ||
156 | .exit: |
- | |
157 | ret |
- | |
158 | - | ||
159 | - | ||
160 | ;*************************************************************************** |
- | |
161 | ; Function |
195 | ret |
162 | ; tcp_tx_handler |
- | |
163 | ; |
- | |
164 | ; Description |
- | |
165 | ; Handles queued TCP data |
- | |
166 | ; This is a kernel function, called by stack_handler |
- | |
167 | ; |
- | |
168 | ;*************************************************************************** |
- | |
169 | - | ||
170 | align 4 |
- | |
171 | tcp_tx_handler: |
- | |
172 | ; decrement all resend buffers timers. If they |
- | |
173 | ; expire, queue them for sending, and restart the timer. |
- | |
174 | ; If the retries counter reach 0, delete the entry |
- | |
175 | - | ||
Line 176... | Line -... | ||
176 | mov esi, resendQ |
- | |
177 | mov ecx, 0 |
- | |
178 | - | ||
179 | .next_resendq: |
- | |
180 | ; cmp ecx, NUMRESENDENTRIES |
- | |
181 | je .exit ; None left |
- | |
182 | cmp dword[esi + 4], 0 |
- | |
183 | jne @f ; found one |
- | |
184 | inc ecx |
- | |
185 | add esi, 8 |
- | |
186 | jmp .next_resendq |
- | |
187 | - | ||
188 | @@: ; we have one. decrement it's timer by 1 |
- | |
189 | dec word[esi + 2] |
- | |
190 | jz @f |
- | |
191 | inc ecx |
- | |
192 | add esi, 8 |
- | |
193 | jmp .next_resendq ; Timer not zero, so move on |
- | |
194 | - | ||
195 | @@: |
- | |
196 | xor ebx, ebx |
- | |
197 | ; restart timer, and decrement retries |
- | |
198 | ; After the first resend, back of on next, by a factor of 5 |
- | |
199 | mov [esi + 2], word TCP_TIMEOUT * 5 |
- | |
200 | dec byte[esi + 1] |
- | |
201 | jnz @f |
- | |
202 | 196 | ||
203 | ; retries now 0, so delete from queue |
197 | |
204 | xchg [esi + 4], ebx |
- | |
205 | - | ||
206 | @@: ; resend Packet |
- | |
207 | pushad |
- | |
208 | - | ||
209 | ; mov eax, EMPTY_QUEUE |
- | |
210 | ; call dequeue |
- | |
Line 211... | Line -... | ||
211 | ; cmp ax, NO_BUFFER |
- | |
212 | jne .tth004z |
198 | |
213 | - | ||
214 | ; TODO - try again in 10ms. |
- | |
215 | test ebx, ebx |
199 | ;----------------------------------------------------------------- |
216 | jnz @f |
200 | ; |
217 | mov [esi + 4], ebx |
- | |
218 | 201 | ; TCP_send_queued: |
|
219 | @@: ; Mark it to expire in 10ms - 1 tick |
202 | ; |
220 | mov byte[esi + 1], 1 |
203 | ; Decreases 'ttl' of tcp packets queued. |
221 | mov word[esi + 2], 1 |
- | |
222 | jmp .tth005 |
204 | ; if 'ttl' reaches 0, resend the packet and decrease 'retries' |
223 | 205 | ; if 'retries' reaches zero, remove the queued packet |
|
224 | .tth004z: |
- | |
225 | ; we have a buffer # in ax |
206 | ; |
226 | ; push eax ecx |
207 | ; IN: / |
227 | ; mov ecx, IPBUFFSIZE |
208 | ; OUT: / |
228 | ; mul ecx |
- | |
229 | ; add eax, IPbuffs |
- | |
230 | - | ||
231 | ; we have the buffer address in eax |
- | |
232 | mov edi, eax |
- | |
233 | pop ecx |
- | |
Line 234... | Line 209... | ||
234 | ; Now get buffer location, and copy buffer across. argh! more copying,, |
209 | ; |
- | 210 | ;----------------------------------------------------------------- |
|
- | 211 | ||
- | 212 | align 4 |
|
235 | ; mov esi, resendBuffer |
213 | TCP_send_queued: |
- | 214 | ||
236 | ; @@: add esi, IPBUFFSIZE |
215 | cmp [TCP_OUT_QUEUE], 0 |
Line 237... | Line 216... | ||
237 | loop @b |
216 | je .exit |
238 | 217 | ||
Line 239... | Line 218... | ||
239 | ; we have resend buffer location in esi |
218 | mov eax, TCP_QUEUE_SIZE |
240 | ; mov ecx, IPBUFFSIZE |
219 | mov ecx, [TCP_OUT_QUEUE] |
241 | 220 | mov esi, TCP_OUT_QUEUE+4 |
|
Line -... | Line 221... | ||
- | 221 | ||
- | 222 | .loop: |
|
- | 223 | cmp [esi + tcp_out_queue_entry.data_ptr], 0 |
|
- | 224 | jnz .found_one |
|
- | 225 | add esi, tcp_out_queue_entry.size |
|
- | 226 | loop .loop |
|
- | 227 | .exit: |
|
- | 228 | ret |
|
- | 229 | ||
242 | ; copy data across |
230 | .found_one: |
- | 231 | dec [esi + tcp_out_queue_entry.ttl] |
|
- | 232 | jz .send_it |
|
- | 233 | .find_next: |
|
- | 234 | dec eax |
|
243 | push edi |
235 | jz .exit |
Line 244... | Line 236... | ||
244 | cld |
236 | jmp .loop |
245 | rep movsb |
237 | |
246 | pop edi |
238 | .send_it: |
247 | 239 | push eax ecx esi |
|
248 | ; queue Packet |
240 | |
249 | ; mov eax, NET1OUT_QUEUE |
- | |
250 | ; mov edx, [IP_LIST] |
241 | push [esi + tcp_out_queue_entry.data_size] |
251 | ; cmp edx, [edi + IP_Packet.DestinationAddress] |
242 | push [esi + tcp_out_queue_entry.data_ptr] |
252 | ; jne .not_local |
243 | mov ebx, [esi + tcp_out_queue_entry.owner] |
253 | ; mov eax, IPIN_QUEUE |
244 | |
254 | 245 | call [esi + tcp_out_queue_entry.sendproc] |
|
255 | .not_local: |
- | |
256 | pop ebx |
246 | |
257 | ; call queue |
247 | pop esi ecx eax |
258 | 248 | ||
259 | .tth005: |
249 | dec [esi + tcp_out_queue_entry.retries] |
Line -... | Line 250... | ||
- | 250 | jz .remove_it |
|
260 | popad |
251 | mov [esi + tcp_out_queue_entry.ttl], TCP_TIMEOUT |
261 | - | ||
Line 262... | Line 252... | ||
262 | inc ecx |
252 | jmp .find_next |
- | 253 | ||
Line 263... | Line 254... | ||
263 | add esi, 8 |
254 | .remove_it: |
- | 255 | push [esi + tcp_out_queue_entry.data_ptr] |
|
Line 264... | Line 256... | ||
264 | jmp .next_resendq |
256 | mov [esi + tcp_out_queue_entry.data_ptr], 0 |
265 | 257 | dec [TCP_OUT_QUEUE] |
|
266 | .exit: |
258 | call kernel_free |
267 | ret |
259 | jmp .find_next |
- | 260 | ||
Line -... | Line 261... | ||
- | 261 | ||
268 | 262 | ||
- | 263 | ;----------------------------------------------------------------- |
|
Line 269... | Line -... | ||
269 | - | ||
270 | - | ||
271 | ;----------------------------------------------------------------- |
264 | ; |
272 | ; |
- | |
Line 273... | Line 265... | ||
273 | ; TCP_Handler: |
265 | ; TCP_add_to_queue: |
Line -... | Line 266... | ||
- | 266 | ; |
|
- | 267 | ; Queue a TCP packet for sending |
|
274 | ; |
268 | ; |
275 | ; Called by IPv4_handler, |
269 | ; IN: [esp] pointer to buffer |
- | 270 | ; [esp + 4] size of buffer |
|
276 | ; this procedure will inject the tcp data diagrams in the application sockets. |
271 | ; ebx = driver struct |
- | 272 | ; esi = sender proc |
|
Line 277... | Line -... | ||
277 | ; |
- | |
Line 278... | Line -... | ||
278 | ; IN: Pointer to buffer in [esp] |
- | |
279 | ; size of buffer in [esp+4] |
- | |
280 | ; pointer to device struct in ebx |
- | |
- | 273 | ; edx = acknum |
|
Line 281... | Line -... | ||
281 | ; TCP Packet size in ecx |
- | |
Line -... | Line 274... | ||
- | 274 | ; OUT: / |
|
- | 275 | ; |
|
- | 276 | ;----------------------------------------------------------------- |
|
- | 277 | ||
- | 278 | align 4 |
|
282 | ; pointer to TCP Packet data in edx |
279 | TCP_add_to_queue: |
- | 280 | ||
- | 281 | cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE |
|
- | 282 | jge .full |
|
283 | ; SourceAddres in esi |
283 | |
- | 284 | mov ecx, TCP_QUEUE_SIZE |
|
284 | ; OUT: / |
285 | mov eax, TCP_OUT_QUEUE+4 |
- | 286 | ||
- | 287 | .loop: |
|
- | 288 | cmp [eax + tcp_out_queue_entry.data_ptr], 0 |
|
- | 289 | je .found_it |
|
Line 285... | Line 290... | ||
285 | ; |
290 | add eax, tcp_out_queue_entry.size |
286 | ;----------------------------------------------------------------- |
291 | loop .loop |
Line 287... | Line 292... | ||
287 | 292 | ||
Line 288... | Line -... | ||
288 | TCP_Handler : |
- | |
289 | - | ||
290 | 293 | .full: ; silently discard the packet |
|
291 | DEBUGF 1,"TCP_Handler\n" |
294 | call kernel_free |
292 | 295 | add esp, 4 |
|
Line 293... | Line 296... | ||
293 | jmp .exit ;;;; |
296 | |
Line 294... | Line 297... | ||
294 | 297 | ret |
|
295 | ; Look for a socket where |
298 | |
296 | ; IP Packet TCP Destination Port = local Port |
299 | .found_it: ; eax point to empty queue entry |
297 | ; IP Packet SA = Remote IP |
300 | |
298 | ; IP Packet TCP Source Port = remote Port |
- | |
299 | - | ||
300 | mov ebx, net_sockets |
- | |
301 | - | ||
302 | .next_socket.1: |
- | |
303 | mov ebx, [ebx + SOCKET.NextPtr] |
- | |
304 | or ebx, ebx |
- | |
305 | jz .next_socket.1.exit |
- | |
Line 306... | Line -... | ||
306 | - | ||
307 | ; DEBUGF 1, "K : tcp_rx - 1.dport: %x - %x\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4 |
- | |
308 | 301 | pop [eax + tcp_out_queue_entry.data_ptr] |
|
309 | mov ax, [edx + TCP_Packet.DestinationPort] ; get the dest. port from the TCP hdr |
- | |
310 | cmp [ebx + SOCKET.LocalPort], ax ; get the dest. port from the TCP hdr |
- | |
311 | jne .next_socket.1 ; different - try next socket |
- | |
312 | 302 | pop [eax + tcp_out_queue_entry.data_size] |
|
313 | ; DEBUGF 1, "K : tcp_rx - 1.addr: %x - %x\n", [edx + IP_Packet.SourceAddress], [ebx + SOCKET.RemoteIP] |
- | |
314 | - | ||
315 | mov eax, esi ;[edx + IP_Packet.SourceAddress] ; get the source IP Addr from the IP hdr |
- | |
316 | cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP |
- | |
317 | jne .next_socket.1 ; different - try next socket |
- | |
318 | 303 | mov [eax + tcp_out_queue_entry.ttl], 1 ; send immediately |
|
319 | ; DEBUGF 1, "K : tcp_rx - 1.sport: %x - %x\n", [edx + 20 + TCP_Packet.SourcePort]:4, [ebx + SOCKET.RemotePort]:4 |
- | |
320 | - | ||
321 | mov ax, [edx + TCP_Packet.SourcePort] ; get the source port from the TCP hdr |
- | |
322 | cmp [ebx + SOCKET.RemotePort], ax ; compare with socket's remote port |
- | |
323 | jne .next_socket.1 ; different - try next socket |
- | |
324 | - | ||
325 | ; We have a complete match - use this socket |
- | |
326 | jmp .change_state |
- | |
Line 327... | Line -... | ||
327 | - | ||
328 | .next_socket.1.exit: |
304 | mov [eax + tcp_out_queue_entry.retries], TCP_RETRIES |
- | 305 | mov [eax + tcp_out_queue_entry.owner], ebx |
|
- | 306 | mov [eax + tcp_out_queue_entry.sendproc], esi |
|
329 | 307 | mov [eax + tcp_out_queue_entry.ack_num], edx |
|
330 | ; If we got here, there was no match |
308 | |
- | 309 | ||
Line 331... | Line 310... | ||
331 | ; Look for a socket where |
310 | ret |
- | 311 | ||
- | 312 | ||
- | 313 | ;----------------------------------------------------------------- |
|
- | 314 | ; |
|
Line 332... | Line -... | ||
332 | ; IP Packet TCP Destination Port = local Port |
- | |
333 | ; IP Packet SA = Remote IP |
- | |
334 | ; socket remote Port = 0 |
315 | ; TCP_handler: |
Line -... | Line 316... | ||
- | 316 | ; |
|
335 | 317 | ; Called by IPv4_handler, |
|
- | 318 | ; this procedure will inject the tcp data diagrams in the application sockets. |
|
- | 319 | ; |
|
Line -... | Line 320... | ||
- | 320 | ; IN: Pointer to buffer in [esp] |
|
336 | mov ebx, net_sockets |
321 | ; size of buffer in [esp+4] |
- | 322 | ; pointer to device struct in ebx |
|
337 | 323 | ; TCP Packet size in ecx |
|
Line -... | Line 324... | ||
- | 324 | ; pointer to TCP Packet data in edx |
|
338 | .next_socket.2: |
325 | ; SourceAddres in esi |
Line 339... | Line 326... | ||
339 | mov ebx, [ebx + SOCKET.NextPtr] |
326 | ; OUT: / |
- | 327 | ; |
|
340 | or ebx, ebx |
328 | ;----------------------------------------------------------------- |
Line 341... | Line 329... | ||
341 | jz .next_socket.2.exit |
329 | |
342 | 330 | align 4 |
|
- | 331 | TCP_handler : |
|
Line -... | Line 332... | ||
- | 332 | ||
343 | ; DEBUGF 1, "K : tcp_rx - 2.dport: %x - %x\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4 |
333 | DEBUGF 1,"TCP_Handler\n" |
Line -... | Line 334... | ||
- | 334 | ||
- | 335 | ; IP Packet TCP Destination Port = local Port |
|
344 | 336 | ; IP Packet SA = Remote IP OR = 0 |
|
Line -... | Line 337... | ||
- | 337 | ; IP Packet TCP Source Port = remote Port OR = 0 |
|
- | 338 | ||
- | 339 | mov ebx, net_sockets |
|
- | 340 | ||
- | 341 | .socket_loop: |
|
- | 342 | mov ebx, [ebx + SOCKET_head.NextPtr] |
|
345 | mov ax, [edx + TCP_Packet.DestinationPort] ; get the dest. port from the TCP hdr |
343 | or ebx, ebx |
346 | cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port |
344 | jz .dump |
- | 345 | ||
- | 346 | mov ax, [edx + TCP_Packet.DestinationPort] |
|
Line -... | Line 347... | ||
- | 347 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], ax |
|
347 | jne .next_socket.2 ; different - try next socket |
348 | jne .socket_loop |
- | 349 | ||
348 | 350 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
|
Line 349... | Line 351... | ||
349 | ; DEBUGF 1, "K : tcp_rx - 2.addr: %x - %x\n", [edx + IP_Packet.SourceAddress], [ebx + SOCKET.RemoteIP] |
351 | cmp eax, esi |
- | 352 | je @f |
|
- | 353 | test eax, eax |
|
- | 354 | jne .socket_loop |
|
- | 355 | @@: |
|
- | 356 | ||
- | 357 | mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort] |
|
Line 350... | Line -... | ||
350 | - | ||
351 | ; mov eax, esi ;[edx + IP_Packet.SourceAddress] ; get the source IP Addr from the IP hdr |
358 | cmp [edx + TCP_Packet.SourcePort] , ax |
352 | cmp [ebx + SOCKET.RemoteIP], esi ; compare with socket's remote IP |
359 | je .change_state |
353 | jne .next_socket.2 ; different - try next socket |
- | |
Line 354... | Line 360... | ||
354 | 360 | test ax, ax |
|
- | 361 | jne .socket_loop |
|
Line 355... | Line 362... | ||
355 | ; DEBUGF 1, "K : tcp_rx - 2.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4 |
362 | |
- | 363 | .change_state: |
|
Line -... | Line 364... | ||
- | 364 | ||
- | 365 | push ebx |
|
356 | 366 | lea ebx, [ebx + SOCKET_head.lock] |
|
357 | cmp [ebx + SOCKET.RemotePort], 0 ; only match a remote socket of 0 |
367 | call wait_mutex |
Line 358... | Line 368... | ||
358 | jne .next_socket.2 ; different - try next socket |
368 | pop ebx |
Line 359... | Line 369... | ||
359 | 369 | ||
360 | ; We have a complete match - use this socket |
370 | ;---------------------------------- |
361 | jmp .change_state |
371 | ; ebx is pointer to socket |
362 | 372 | ; ecx is size of tcp packet |
|
363 | .next_socket.2.exit: |
373 | ; edx is pointer to tcp packet |
364 | 374 | ||
365 | ; If we got here, there was no match |
375 | ; as a Packet has been received, update the TCB timer |
366 | ; Look for a socket where |
376 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBTimer], TWOMSL |
367 | ; IP Packet TCP Destination Port = local Port |
377 | |
Line 368... | Line -... | ||
368 | ; socket Remote IP = 0 |
- | |
369 | ; socket remote Port = 0 |
- | |
370 | - | ||
371 | mov ebx, net_sockets |
- | |
372 | 378 | ; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges |
|
373 | .next_socket.3: |
- | |
374 | mov ebx, [ebx + SOCKET.NextPtr] |
- | |
375 | or ebx, ebx |
379 | test [edx + TCP_Packet.Flags], TH_ACK |
376 | jz .next_socket.3.exit |
- | |
377 | - | ||
378 | ; DEBUGF 1, "K : tcp_rx - 3.dport: %x - %x\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4 |
- | |
379 | - | ||
380 | mov ax, [edx + TCP_Packet.DestinationPort] ; get destination port from the TCP hdr |
- | |
381 | cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port |
- | |
382 | jne .next_socket.3 ; different - try next socket |
- | |
383 | - | ||
384 | ; DEBUGF 1, "K : tcp_rx - 3.addr: 00000000 - %x\n", [ebx + SOCKET.RemoteIP] |
- | |
Line 385... | Line 380... | ||
385 | 380 | jz .call_handler ; No ACK, so no data yet |
|
Line 386... | Line -... | ||
386 | cmp [ebx + SOCKET.RemoteIP], 0 ; only match a socket remote IP of 0 |
- | |
387 | jne .next_socket.3 ; different - try next socket |
381 | |
Line 388... | Line 382... | ||
388 | 382 | mov eax, [edx + TCP_Packet.SequenceNumber] ; Calculate sequencenumber in eax |
|
- | 383 | bswap eax ; |
|
- | 384 | add eax, ecx ; |
|
- | 385 | ||
Line -... | Line 386... | ||
- | 386 | cmp [TCP_OUT_QUEUE], 0 |
|
389 | ; DEBUGF 1, "K : tcp_rx - 3.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4 |
387 | je .call_handler |
- | 388 | ||
390 | 389 | push ecx |
|
- | 390 | mov ecx, TCP_QUEUE_SIZE |
|
391 | cmp [ebx + SOCKET.RemotePort], 0 ; only match a remote socket of 0 |
391 | mov esi, TCP_OUT_QUEUE+4 |
Line 392... | Line -... | ||
392 | jne .next_socket.3 ; different - try next socket |
- | |
Line 393... | Line 392... | ||
393 | 392 | ||
- | 393 | .loop: |
|
- | 394 | cmp [esi + tcp_out_queue_entry.data_ptr], 0 |
|
- | 395 | jne .maybe_next |
|
- | 396 | cmp [esi + tcp_out_queue_entry.ack_num], eax |
|
Line 394... | Line 397... | ||
394 | ; We have a complete match - use this socket |
397 | jg .maybe_next |
Line 395... | Line 398... | ||
395 | jmp .change_state |
398 | |
396 | - | ||
397 | .next_socket.3.exit: |
- | |
398 | - | ||
399 | ; If we got here, we need to reject the Packet |
- | |
Line 400... | Line 399... | ||
400 | 399 | push [esi + tcp_out_queue_entry.data_ptr] |
|
401 | DEBUGF 1, "K : tcp_rx - dumped\n" |
400 | mov [esi + tcp_out_queue_entry.data_ptr], 0 |
Line -... | Line 401... | ||
- | 401 | dec [TCP_OUT_QUEUE] |
|
402 | ; DEBUGF 1, "K : --------: %x-%x-%x (flags: %x)\n", [edx + 20 + TCP_Packet.DestinationPort]:4, [edx + IP_Packet.SourceAddress], [edx + 20 + TCP_Packet.SourcePort]:4, [edx + 20 + TCP_Packet.Flags]:2 |
402 | call kernel_free |
403 | - | ||
Line 404... | Line -... | ||
404 | ; inc [dumped_rx_count] |
- | |
405 | jmp .exit |
- | |
406 | - | ||
407 | .change_state: |
- | |
408 | - | ||
409 | ; We have a valid socket/TCB, so call the TCB State Machine for that skt. |
- | |
410 | ; socket is pointed to by ebx |
- | |
411 | ; IP Packet is pointed to by edx |
- | |
412 | ; IP buffer number is on stack ( it will be popped at the end) |
- | |
413 | - | ||
414 | stdcall tcpStateMachine, ebx |
- | |
415 | - | ||
416 | .exit: |
- | |
417 | - | ||
418 | call kernel_free |
- | |
419 | add esp, 4 ; pop (balance stack) |
- | |
420 | - | ||
421 | ret |
- | |
422 | - | ||
423 | - | ||
424 | - | ||
425 | ;----------------------------------------------------------------- |
- | |
426 | ; |
- | |
427 | ; IN: eax = dest ip |
- | |
428 | ; ebx = source ip |
- | |
429 | ; ecx = data length |
- | |
430 | ; edx = remote port shl 16 + local port |
- | |
431 | ; esi = data offset |
- | |
432 | ; |
- | |
433 | ;----------------------------------------------------------------- |
- | |
434 | - | ||
435 | TCP_create_Packet: |
- | |
436 | - | ||
437 | DEBUGF 1,"Create TCP Packet\n" |
- | |
438 | ;*************************************************************************** |
- | |
Line 439... | Line 403... | ||
439 | ; Function |
403 | |
440 | ; buildTCPPacket |
404 | .maybe_next: |
Line 441... | Line 405... | ||
441 | ; |
405 | add esi, tcp_out_queue_entry.size |
442 | ; Description |
406 | loop .loop |
Line -... | Line 407... | ||
- | 407 | pop ecx |
|
- | 408 | ||
443 | ; builds an IP Packet with TCP data fully populated for transmission |
409 | .call_handler: |
444 | ; You may destroy any and all registers |
410 | ; Call handler for given TCB state |
Line 445... | Line 411... | ||
445 | ; TCP control flags specified in bl |
411 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState] |
446 | ; This TCB is in [sktAddr] |
412 | cmp eax, TCB_LISTEN |
447 | ; User data pointed to by esi |
- | |
448 | ; Data length in ecx |
- | |
449 | ; Transmit buffer number in eax |
- | |
450 | ; |
- | |
451 | ;*************************************************************************** |
- | |
452 | - | ||
453 | push ecx ; Save data length |
- | |
454 | - | ||
455 | add ecx, UDP_Packet.Data |
- | |
456 | mov di , IP_PROTO_UDP |
- | |
457 | - | ||
458 | ; dx = fragment id |
- | |
459 | - | ||
460 | call IPv4_create_Packet ; TODO: figure out a way to choose between IPv4 and IPv6 |
- | |
461 | cmp edi, -1 |
- | |
462 | je .exit |
- | |
463 | - | ||
464 | mov [edi + TCP_Packet.Flags], bl ; TCP flags |
- | |
465 | - | ||
466 | ; mov ebx, [sockAddr];---------------------------------------------------------- eof |
- | |
467 | - | ||
468 | ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr |
- | |
469 | - | ||
470 | ; Fill in the IP header ( some data is in the socket descriptor) |
- | |
471 | mov eax, [ebx + SOCKET.LocalIP] |
- | |
472 | ; mov [edx + IP_Packet.SourceAddress], eax |
- | |
473 | mov eax, [ebx + SOCKET.RemoteIP] |
- | |
474 | ; mov [edx + IP_Packet.DestinationAddress], eax |
- | |
475 | - | ||
476 | ; mov [edx + IP_Packet.VersionAndIHL], 0x45 |
- | |
477 | ; mov [edx + IP_Packet.TypeOfService], 0 |
- | |
478 | - | ||
479 | pop eax ; Get the TCP data length |
- | |
480 | push eax |
- | |
481 | - | ||
482 | add eax, 20 + 20 ; add IP header and TCP header lengths |
- | |
483 | rol ax, 8 |
- | |
484 | ; mov [edx + IP_Packet.TotalLength], ax |
413 | jb .exit |
485 | ; mov [edx + IP_Packet.Identification], 0 |
414 | cmp eax, TCB_CLOSED |
Line -... | Line 415... | ||
- | 415 | ja .exit |
|
- | 416 | ||
- | 417 | shl eax, 2 |
|
- | 418 | add eax, TCBStateHandler - 4 |
|
- | 419 | ||
- | 420 | push .exit |
|
- | 421 | jmp eax |
|
Line -... | Line 422... | ||
- | 422 | ||
- | 423 | .exit: |
|
- | 424 | mov [ebx + SOCKET_head.lock], 0 |
|
- | 425 | ||
- | 426 | .dump: |
|
- | 427 | DEBUGF 1,"Dumping TCP packet\n" |
|
486 | ; mov [edx + IP_Packet.FlagsAndFragmentOffset], 0x0040 |
428 | call kernel_free |
- | 429 | add esp, 4 ; pop (balance stack) |
|
- | 430 | ||
- | 431 | ret |
|
- | 432 | ||
- | 433 | ||
- | 434 | ||
487 | ; mov [edx + IP_Packet.TimeToLive], 0x20 |
435 | ;----------------------------------------------------------------- |
- | 436 | ; |
|
- | 437 | ; TCP_socket_send |
|
488 | ; mov [edx + IP_Packet.Protocol], PROTOCOL_TCP |
438 | ; |
489 | 439 | ; IN: eax = socket pointer |
|
- | 440 | ; ecx = number of bytes to send |
|
Line -... | Line 441... | ||
- | 441 | ; esi = pointer to data |
|
- | 442 | ; |
|
490 | ; Checksum left unfilled |
443 | ;----------------------------------------------------------------- |
491 | ; mov [edx + IP_Packet.HeaderChecksum], 0 |
- | |
492 | - | ||
Line 493... | Line -... | ||
493 | ; Fill in the TCP header (some data is in the socket descriptor) |
- | |
494 | mov ax, [ebx + SOCKET.LocalPort] |
- | |
495 | mov [edx + 20 + TCP_Packet.SourcePort], ax ; Local Port |
- | |
496 | - | ||
497 | mov ax, [ebx + SOCKET.RemotePort] |
- | |
498 | mov [edx + 20 + TCP_Packet.DestinationPort], ax ; desitination Port |
- | |
499 | - | ||
500 | ; Checksum left unfilled |
- | |
501 | mov [edx + 20 + TCP_Packet.Checksum], 0 |
- | |
502 | - | ||
503 | ; sequence number |
- | |
504 | mov eax, [ebx + SOCKET.SND_NXT] |
- | |
505 | mov [edx + 20 + TCP_Packet.SequenceNumber], eax |
- | |
506 | - | ||
507 | ; ack number |
- | |
508 | mov eax, [ebx + SOCKET.RCV_NXT] |
- | |
509 | mov [edx + 20 + TCP_Packet.AckNumber], eax |
- | |
510 | - | ||
511 | ; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size) |
- | |
512 | ; 768 bytes seems better |
- | |
513 | mov [edx + 20 + TCP_Packet.Window], 0x0003 |
- | |
514 | - | ||
515 | ; Urgent pointer (0) |
- | |
516 | mov [edx + 20 + TCP_Packet.UrgentPointer], 0 |
- | |
517 | - | ||
518 | ; data offset ( 0x50 ) |
- | |
519 | mov [edx + 20 + TCP_Packet.DataOffset], 0x50 |
- | |
520 | - | ||
521 | pop ecx ; count of bytes to send |
- | |
Line 522... | Line -... | ||
522 | mov ebx, ecx ; need the length later |
- | |
523 | - | ||
524 | cmp ebx, 0 |
- | |
525 | jz @f |
- | |
526 | - | ||
527 | mov edi, edx |
- | |
528 | add edi, 40 |
- | |
529 | cld |
- | |
530 | rep movsb ; copy the data across |
- | |
531 | - | ||
532 | @@: ; we have edx as IPbuffer ptr. |
- | |
533 | ; Fill in the TCP checksum |
- | |
534 | ; First, fill in pseudoheader |
- | |
535 | ; mov eax, [edx + IP_Packet.SourceAddress] |
- | |
Line 536... | Line 444... | ||
536 | ; mov [pseudoHeader], eax |
444 | |
537 | ; mov eax, [edx + IP_Packet.DestinationAddress] |
- | |
538 | ; mov [pseudoHeader + 4], eax |
- | |
539 | ; mov word[pseudoHeader + 8], PROTOCOL_TCP shl 8 + 0 |
445 | align 4 |
540 | ; add ebx, 20 |
446 | TCP_socket_send: |
541 | ; mov [pseudoHeader + 10], bh |
- | |
542 | ; mov [pseudoHeader + 11], bl |
- | |
543 | ; |
447 | |
544 | ; mov eax, pseudoHeader |
448 | DEBUGF 1,"Creating TCP Packet\n" |
545 | ; mov [checkAdd1], eax |
449 | |
546 | ; mov word[checkSize1], 12 |
450 | mov di , IP_PROTO_TCP |
547 | ; mov eax, edx |
- | |
548 | ; add eax, 20 |
451 | |
Line 549... | Line 452... | ||
549 | ; mov [checkAdd2], eax |
452 | ; Create an IPv4 Packet of the correct size |
550 | ; mov eax, ebx |
- | |
551 | ; mov [checkSize2], ax |
453 | push eax |
Line 552... | Line -... | ||
552 | ; |
- | |
553 | ; call checksum |
- | |
554 | 454 | mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
|
555 | ; store it in the TCP checksum ( in the correct order! ) |
- | |
556 | ; mov ax, [checkResult] |
- | |
557 | ; rol ax, 8 |
- | |
Line 558... | Line 455... | ||
558 | ; mov [edx + 20 + TCP_Packet.Checksum], ax |
455 | mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
559 | 456 | ||
Line 560... | Line -... | ||
560 | ; Fill in the IP header checksum |
- | |
561 | ; movzx eax, byte [edx + IP_Packet.VersionAndIHL] ; Calculate Header length by using IHL field |
457 | ; meanwhile, create the pseudoheader in stack, |
Line -... | Line 458... | ||
- | 458 | ; (now that we still have all the variables that are needed.) |
|
562 | ; and eax, 0x0000000F ; |
459 | push cx |
563 | ; shl eax, 2 ; |
460 | push di |
Line 564... | Line -... | ||
564 | ; |
- | |
565 | stdcall checksum_jb, edx, eax ; buf_ptr, buf_size |
- | |
566 | rol ax, 8 |
461 | push eax |
567 | ; mov [edx + IP_Packet.HeaderChecksum], ax |
462 | push ebx |
568 | - | ||
569 | - | ||
570 | .exit: |
463 | |
571 | - | ||
Line 572... | Line 464... | ||
572 | call kernel_free |
464 | |
- | 465 | push ecx esi eax ; save some variables for later |
|
Line 573... | Line 466... | ||
573 | add esp, 4 ; pop (balance stack) |
466 | add ecx, TCP_Packet.Data |
574 | 467 | call IPv4_create_packet |
|
Line 575... | Line -... | ||
575 | ret |
- | |
576 | ;endp |
468 | cmp edi, -1 |
577 | - | ||
578 | - | ||
579 | ; Increments the 32 bit value pointed to by esi in internet order |
- | |
580 | proc inc_inet_esi stdcall |
- | |
581 | ; push eax |
- | |
582 | ; mov eax, [esi] |
- | |
583 | ; bswap eax |
469 | je .fail |
584 | ; inc eax |
- | |
585 | ; bswap eax |
- | |
586 | ; mov [esi], eax |
- | |
587 | ; pop eax |
- | |
588 | ; ret |
- | |
589 | inc byte[esi+0] |
- | |
590 | adc byte[esi+1],0 |
- | |
591 | adc byte[esi+2],0 |
- | |
592 | adc byte[esi+3],0 |
- | |
593 | endp |
- | |
594 | - | ||
595 | - | ||
596 | ; Increments the 32 bit value pointed to by esi in internet order |
- | |
597 | ; by the value in ecx |
- | |
598 | proc add_inet_esi stdcall |
- | |
Line 599... | Line -... | ||
599 | push eax |
- | |
600 | mov eax, [esi] |
- | |
601 | bswap eax |
- | |
602 | add eax, ecx |
- | |
603 | bswap eax |
470 | |
604 | mov [esi], eax |
- | |
605 | pop eax |
- | |
606 | ret |
471 | pop esi |
Line 607... | Line -... | ||
607 | endp |
- | |
608 | 472 | ||
- | 473 | ; Now add the TCP header to the IPv4 packet |
|
- | 474 | ||
- | 475 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
|
- | 476 | pop [edi + TCP_Packet.SequenceNumber] |
|
Line 609... | Line 477... | ||
609 | 477 | ||
Line 610... | Line 478... | ||
610 | iglobal |
478 | push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] |
611 | TCBStateHandler dd \ |
479 | pop dword [edi + TCP_Packet.SourcePort] |
612 | stateTCB_LISTEN, \ |
480 | |
613 | stateTCB_SYN_SENT, \ |
481 | |
614 | stateTCB_SYN_RECEIVED, \ |
- | |
Line 615... | Line 482... | ||
615 | stateTCB_ESTABLISHED, \ |
482 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
- | 483 | pop [edi + TCP_Packet.AckNumber] |
|
- | 484 | ||
- | 485 | mov al, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.flags] |
|
- | 486 | mov [edi + TCP_Packet.Flags], al |
|
- | 487 | ||
- | 488 | mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes ;;; TODO: read RFC ! |
|
- | 489 | mov [edi + TCP_Packet.UrgentPointer], 0 |
|
- | 490 | mov [edi + TCP_Packet.DataOffset], 0x50 |
|
- | 491 | mov [edi + TCP_Packet.Checksum], 0 |
|
- | 492 | ||
- | 493 | ; Copy the data |
|
- | 494 | mov esi, [esp] |
|
- | 495 | mov ecx, [esp+4] |
|
- | 496 | add edi, TCP_Packet.Data |
|
Line 616... | Line 497... | ||
616 | stateTCB_FIN_WAIT_1, \ |
497 | |
- | 498 | shr ecx, 1 |
|
617 | stateTCB_FIN_WAIT_2, \ |
499 | jnc .nb |
618 | stateTCB_CLOSE_WAIT, \ |
- | |
Line -... | Line 500... | ||
- | 500 | movsb |
|
- | 501 | .nb: shr ecx, 1 |
|
- | 502 | jnc .nw |
|
- | 503 | movsw |
|
619 | stateTCB_CLOSING, \ |
504 | .nw: rep movsd |
620 | stateTCB_LAST_ACK, \ |
505 | |
621 | stateTCB_TIME_WAIT, \ |
506 | ; Now, calculate the checksum for pseudoheader |
622 | stateTCB_CLOSED |
507 | xor edx, edx |
Line 623... | Line 508... | ||
623 | endg |
508 | mov ecx, 12 |
624 | 509 | mov esi, esp |
|
625 | 510 | call checksum_1 |
|
Line 626... | Line 511... | ||
626 | ;*************************************************************************** |
511 | add esp, 12 ; remove the pseudoheader from stack |
627 | ; Function |
512 | ; And that of the data |
Line 628... | Line -... | ||
628 | ; tcpStateMachine |
- | |
629 | ; |
513 | pop esi |
630 | ; Description |
514 | pop ecx |
631 | ; TCP state machine |
515 | call checksum_1 |
632 | ; This is a kernel function, called by tcp_rx |
516 | ; Now create the final checksum and store it in TCP header |
633 | ; |
517 | call checksum_2 |
634 | ; IP buffer address given in edx |
518 | mov [edi + TCP_Packet.Checksum], dx |
635 | ; Socket/TCB address in ebx |
519 | |
636 | ; |
520 | ; And now, send it! |
637 | ; The IP buffer will be released by the caller |
521 | DEBUGF 1,"Sending TCP Packet to device %x\n", ebx |
638 | ;*************************************************************************** |
522 | mov esi, ETH_sender |
639 | - | ||
640 | proc tcpStateMachine stdcall, sockAddr:DWORD |
- | |
641 | ; as a Packet has been received, update the TCB timer |
- | |
642 | mov [ebx + SOCKET.TCBTimer], TWOMSL |
- | |
643 | - | ||
644 | ; If the received Packet has an ACK bit set, |
- | |
Line 645... | Line 523... | ||
645 | ; remove any Packets in the resend queue that this |
523 | mov edx, [edi + TCP_Packet.AckNumber] |
646 | ; received Packet acknowledges |
524 | jmp TCP_add_to_queue |
647 | pushad |
525 | |
648 | test [edx + 20 + TCP_Packet.Flags], TH_ACK |
- | |
649 | jz .call_handler ; No ACK, so no data yet |
- | |
650 | - | ||
651 | ; get skt number in eax |
- | |
652 | stdcall net_socket_addr_to_num, ebx |
- | |
653 | - | ||
654 | ; The ack number is in [edx + 28], inet format |
- | |
655 | ; skt in eax |
- | |
656 | - | ||
657 | mov esi, resendQ |
- | |
658 | xor ecx, ecx |
- | |
659 | - | ||
660 | .next_resendq: |
- | |
661 | ; cmp ecx, NUMRESENDENTRIES |
- | |
Line 662... | Line -... | ||
662 | je .call_handler ; None left |
- | |
663 | cmp [esi + 4], eax |
526 | .fail: |
Line 664... | Line 527... | ||
664 | je @f ; found one |
527 | add esp, 12+4 |
665 | inc ecx |
528 | ret |
666 | add esi, 8 |
529 | |
Line 667... | Line 530... | ||
667 | jmp .next_resendq |
530 | |
668 | 531 | ||
669 | @@: ; Can we delete this buffer? |
- | |
Line -... | Line 532... | ||
- | 532 | ||
670 | 533 | ||
671 | ; If yes, goto @@. No, goto .next_resendq |
534 | ;----------------------------------------------------------------- |
672 | ; Get Packet data address |
535 | ; |
Line 673... | Line 536... | ||
673 | 536 | ; TCP_send_ack |
|
674 | push ecx |
537 | ; |
675 | ; Now get buffer location, and copy buffer across. argh! more copying,, |
538 | ; IN: eax = socket pointer |
676 | ; imul edi, ecx, IPBUFFSIZE |
539 | ; bl = flags |
Line 677... | Line 540... | ||
677 | ; add edi, resendBuffer |
540 | ; |
678 | 541 | ;----------------------------------------------------------------- |
|
Line 679... | Line 542... | ||
679 | ; we have dest buffer location in edi. incoming Packet in edx. |
542 | |
680 | ; Get this Packets sequence number |
543 | align 4 |
681 | ; preserve al, ecx, esi, edx |
544 | TCP_send_ack: |
Line 682... | Line 545... | ||
682 | mov ecx, [edi + 20 + TCP_Packet.SequenceNumber] |
545 | |
683 | bswap ecx |
546 | DEBUGF 1,"Creating TCP ACK\n" |
684 | movzx ebx, word[edi + 2] |
547 | |
Line 685... | Line 548... | ||
685 | xchg bl, bh |
548 | mov di , IP_PROTO_TCP |
686 | sub ebx, 40 |
549 | mov cx , TCP_Packet.Data |
687 | add ecx, ebx ; ecx is now seq# of last byte +1, intel format |
550 | |
Line 688... | Line 551... | ||
688 | 551 | push bx eax |
|
689 | ; get recievd ack #, in intel format |
552 | |
690 | mov ebx, [edx + 20 + TCP_Packet.AckNumber] |
553 | ; Create an IPv4 Packet of the correct size |
691 | bswap ebx |
554 | mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
Line 692... | Line 555... | ||
692 | 555 | mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
|
693 | cmp ebx, ecx ; Finally. ecx = rx'ed ack. ebx = last byte in que |
- | |
694 | ; DANGER! need to handle case that we have just |
- | |
695 | ; passed the 2**32, and wrapped round! |
- | |
696 | pop ecx |
- | |
697 | jae @f ; if rx > old, delete old |
556 | |
698 | - | ||
699 | inc ecx |
- | |
700 | add esi, 8 |
- | |
701 | jmp .next_resendq |
- | |
702 | 557 | call IPv4_create_packet |
|
703 | @@: mov dword[esi + 4], 0 |
- | |
704 | inc ecx |
- | |
705 | add esi, 8 |
- | |
706 | jmp .next_resendq |
- | |
707 | - | ||
708 | .call_handler: |
- | |
709 | popad |
- | |
710 | - | ||
711 | ; Call handler for given TCB state |
- | |
712 | - | ||
713 | mov eax, [ebx + SOCKET.TCBState] |
- | |
714 | cmp eax, TCB_LISTEN |
- | |
715 | jb .exit |
- | |
716 | cmp eax, TCB_CLOSED |
- | |
Line 717... | Line 558... | ||
717 | ja .exit |
558 | cmp edi, -1 |
718 | 559 | je .fail |
|
719 | stdcall [TCBStateHandler + (eax - 1) * 4], [sockAddr] |
- | |
Line -... | Line 560... | ||
- | 560 | ||
- | 561 | ; Fill in the TCP header |
|
720 | 562 | pop esi |
|
721 | .exit: |
563 | |
722 | ret |
564 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
723 | endp |
565 | pop [edi + TCP_Packet.SequenceNumber] |
Line 724... | Line 566... | ||
724 | 566 | ||
725 | 567 | push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] |
|
Line -... | Line 568... | ||
- | 568 | pop dword [edi + TCP_Packet.SourcePort] |
|
- | 569 | ||
726 | proc stateTCB_LISTEN stdcall, sockAddr:DWORD |
570 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
727 | ; In this case, we are expecting a SYN Packet |
571 | pop [edi + TCP_Packet.AckNumber] |
Line 728... | Line 572... | ||
728 | ; For now, if the Packet is a SYN, process it, and send a response |
572 | |
729 | ; If not, ignore it |
573 | pop cx |
Line 730... | Line 574... | ||
730 | 574 | mov [edi + TCP_Packet.Flags], cl |
|
731 | ; Look at control flags |
575 | mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes |
732 | test [edx + 20 + TCP_Packet.Flags], TH_SYN |
576 | mov [edi + TCP_Packet.UrgentPointer], 0 |
733 | jz .exit |
577 | mov [edi + TCP_Packet.DataOffset], 0x50 |
Line 734... | Line 578... | ||
734 | 578 | ||
Line 735... | Line 579... | ||
735 | ; We have a SYN. update the socket with this IP Packets details, |
579 | push eax edx |
736 | ; And send a response |
580 | |
737 | - | ||
Line -... | Line 581... | ||
- | 581 | push word TCP_Packet.Data shl 8 |
|
- | 582 | push IP_PROTO_TCP |
|
738 | ; mov eax, [edx + IP_Packet.SourceAddress] |
583 | push [esi + SOCKET_head.end + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
739 | ; mov [ebx + SOCKET.RemoteIP], eax |
584 | push [esi + SOCKET_head.end + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
740 | ; mov ax, [edx + 20 + TCP_Packet.SourcePort] |
585 | |
Line 741... | Line 586... | ||
741 | ; mov [ebx + SOCKET.RemotePort], ax |
586 | ; Now, calculate the checksum for pseudoheader |
742 | ; mov eax, [edx + 20 + TCP_Packet.SequenceNumber] |
587 | xor edx, edx |
743 | ; mov [ebx + SOCKET.IRS], eax |
588 | mov ecx, 12 |
Line 744... | Line 589... | ||
744 | ; mov [ebx + SOCKET.RCV_NXT], eax |
589 | mov esi, esp |
Line 745... | Line 590... | ||
745 | ; lea esi, [ebx + SOCKET.RCV_NXT] |
590 | call checksum_1 |
746 | ; call inc_inet_esi ; RCV.NXT |
- | |
747 | ; mov eax, [ebx + SOCKET.ISS] |
- | |
748 | ; mov [ebx + SOCKET.SND_NXT], eax |
- | |
749 | ; |
- | |
750 | ; Now construct the response, and queue for sending by IP |
- | |
751 | ; mov eax, EMPTY_QUEUE |
- | |
752 | ; call dequeue |
- | |
753 | ; cmp ax, NO_BUFFER |
- | |
754 | ; je .exit |
- | |
755 | - | ||
756 | push eax |
- | |
757 | mov bl, TH_SYN + TH_ACK |
- | |
758 | xor ecx, ecx |
- | |
759 | xor esi, esi |
- | |
760 | ; stdcall build_tcp_Packet, [sockAddr] |
- | |
761 | - | ||
762 | ; mov eax, NET1OUT_QUEUE |
- | |
763 | ;;; mov edx, [stack_ip] |
- | |
764 | mov ecx, [sockAddr] |
- | |
765 | cmp edx, [ecx + SOCKET.RemoteIP] |
- | |
766 | jne .not_local |
- | |
767 | ; mov eax, IPIN_QUEUE |
- | |
768 | - | ||
769 | .not_local: |
- | |
770 | ; Send it. |
- | |
771 | pop ebx |
591 | add esp, 12 ; remove the pseudoheader from stack |
772 | ;;; call queue |
- | |
773 | - | ||
774 | mov esi, [sockAddr] |
- | |
775 | mov [esi + SOCKET.TCBState], TCB_SYN_RECEIVED |
- | |
776 | - | ||
777 | ; increment SND.NXT in socket |
- | |
Line 778... | Line 592... | ||
778 | add esi, SOCKET.SND_NXT |
592 | ; Now create the final checksum and store it in TCP header |
779 | call inc_inet_esi |
593 | call checksum_2 |
780 | 594 | mov [edi + TCP_Packet.Checksum], dx |
|
781 | .exit: |
595 | |
Line 782... | Line -... | ||
782 | ret |
- | |
783 | endp |
596 | ; And now, send it! |
784 | 597 | DEBUGF 1,"Sending TCP Packet to device %x\n", ebx |
|
785 | 598 | mov esi, ETH_sender |
|
786 | proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD |
599 | mov edx, [edi + TCP_Packet.AckNumber] |
787 | ; We are awaiting an ACK to our SYN, with a SYM |
600 | jmp TCP_add_to_queue |
788 | ; Look at control flags - expecting an ACK |
601 | |
789 | 602 | .fail: |
|
Line 790... | Line 603... | ||
790 | mov al, [edx + 20 + TCP_Packet.Flags] |
603 | add esp, 12+4 |
Line 791... | Line 604... | ||
791 | and al, TH_SYN + TH_ACK |
604 | ret |
792 | cmp al, TH_SYN + TH_ACK |
605 | |
793 | je .syn_ack |
606 | |
794 | 607 | ||
795 | test al, TH_SYN |
608 | |
Line 796... | Line 609... | ||
796 | jz .exit |
609 | |
797 | 610 | align 4 |
|
798 | mov [ebx + SOCKET.TCBState], TCB_SYN_RECEIVED |
611 | stateTCB_LISTEN: |
799 | push TH_SYN + TH_ACK |
612 | ; In this case, we are expecting a SYN Packet |
800 | jmp .send |
613 | ; For now, if the Packet is a SYN, process it, and send a response |
801 | 614 | ; If not, ignore it |
|
802 | .syn_ack: |
615 | |
Line 803... | Line 616... | ||
803 | mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED |
616 | ; Look at control flags |
804 | push TH_ACK |
617 | test [edx + TCP_Packet.Flags], TH_SYN |
Line 805... | Line -... | ||
805 | - | ||
806 | .send: |
- | |
807 | ; Store the recv.nxt field |
- | |
808 | mov eax, [edx + 20 + TCP_Packet.SequenceNumber] |
618 | jz .exit |
809 | - | ||
810 | ; Update our recv.nxt field |
619 | |
Line 811... | Line 620... | ||
811 | mov [ebx + SOCKET.RCV_NXT], eax |
620 | ; We have a SYN. update the socket with this IP Packets details, |
812 | lea esi, [ebx + SOCKET.RCV_NXT] |
621 | ; And send a response |
813 | call inc_inet_esi |
622 | |
814 | 623 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP], esi ; IP source address |
|
Line 815... | Line 624... | ||
815 | ; Send an ACK |
624 | mov ax, [edx + TCP_Packet.SourcePort] |
816 | ; Now construct the response, and queue for sending by IP |
- | |
817 | ; mov eax, EMPTY_QUEUE |
- | |
818 | ; call dequeue |
- | |
819 | ; cmp ax, NO_BUFFER |
- | |
820 | pop ebx |
- | |
821 | je .exit |
- | |
822 | - | ||
823 | push eax |
- | |
824 | 625 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], ax |
|
825 | xor ecx, ecx |
- | |
826 | xor esi, esi |
- | |
827 | ; stdcall build_tcp_Packet, [sockAddr] |
- | |
828 | - | ||
829 | ; mov eax, NET1OUT_QUEUE |
- | |
830 | ;;; mov edx, [stack_ip] |
- | |
831 | ; mov ecx, [sockAddr] |
- | |
832 | ; cmp edx, [ecx + SOCKET.RemoteIP] |
626 | mov eax, [edx + TCP_Packet.SequenceNumber] |
833 | ; jne .not_local |
- | |
834 | ; mov eax, IPIN_QUEUE |
- | |
835 | 627 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.IRS], eax |
|
836 | .not_local: |
- | |
837 | ; Send it. |
- | |
838 | pop ebx |
- | |
839 | ;;; call queue |
- | |
840 | - | ||
841 | .exit: |
- | |
842 | ret |
- | |
843 | endp |
- | |
844 | - | ||
845 | - | ||
846 | proc stateTCB_SYN_RECEIVED stdcall, sockAddr:DWORD |
- | |
847 | ; In this case, we are expecting an ACK Packet |
- | |
848 | ; For now, if the Packet is an ACK, process it, |
- | |
849 | ; If not, ignore it |
- | |
850 | - | ||
851 | test [edx + 20 + TCP_Packet.Flags], TH_RST |
- | |
852 | jz .check_ack |
- | |
853 | - | ||
854 | push [ebx + SOCKET.OrigRemotePort] [ebx + SOCKET.OrigRemoteIP] |
- | |
855 | pop [ebx + SOCKET.RemoteIP] [ebx + SOCKET.RemotePort] |
- | |
856 | - | ||
857 | mov [ebx + SOCKET.TCBState], TCB_LISTEN |
- | |
858 | jmp .exit |
- | |
859 | - | ||
860 | .check_ack: |
- | |
861 | ; Look at control flags - expecting an ACK |
- | |
862 | test [edx + 20 + TCP_Packet.Flags], TH_ACK |
628 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], eax |
Line 863... | Line 629... | ||
863 | jz .exit |
629 | lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
864 | 630 | inc_INET esi ; RCV.NXT |
|
865 | mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED |
- | |
866 | - | ||
867 | .exit: |
- | |
868 | ret |
- | |
869 | endp |
- | |
870 | - | ||
871 | - | ||
872 | proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD |
- | |
873 | ; Here we are expecting data, or a request to close |
631 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS] |
874 | ; OR both... |
632 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], eax |
875 | - | ||
876 | ; Did we receive a FIN or RST? |
- | |
877 | test [edx + 20 + TCP_Packet.Flags], TH_FIN |
- | |
878 | jz .check_ack |
- | |
879 | - | ||
880 | ; It was a fin or reset. |
- | |
881 | - | ||
882 | ; Remove resend entries from the queue - I dont want to send any more data |
- | |
883 | pushad |
- | |
884 | - | ||
885 | ; get skt # |
- | |
886 | stdcall net_socket_addr_to_num, ebx |
- | |
887 | - | ||
888 | mov esi, resendQ |
- | |
889 | mov ecx, 0 |
- | |
890 | - | ||
891 | .next_resendq: |
633 | |
892 | ; cmp ecx, NUMRESENDENTRIES |
634 | ; Now construct the response |
893 | ; je .last_resendq ; None left |
- | |
894 | ; cmp [esi + 4], eax |
- | |
895 | ; je @f ; found one |
- | |
896 | ; inc ecx |
- | |
897 | ; add esi, 8 |
- | |
898 | ; jmp .next_resendq |
- | |
899 | - | ||
Line -... | Line 635... | ||
- | 635 | mov bl, TH_SYN + TH_ACK |
|
- | 636 | call TCP_send_ack |
|
900 | @@: mov dword[esi + 4], 0 |
637 | |
901 | inc ecx |
638 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_SYN_RECEIVED |
902 | add esi, 8 |
639 | |
903 | jmp .next_resendq |
640 | ; increment SND.NXT in socket |
Line 904... | Line 641... | ||
904 | 641 | lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
|
905 | .last_resendq: |
642 | inc_INET esi |
Line 906... | Line 643... | ||
906 | popad |
643 | |
907 | 644 | .exit: |
|
908 | @@: ; Send an ACK to that fin, and enter closewait state |
645 | ret |
Line 909... | Line 646... | ||
909 | 646 | ||
910 | mov [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT |
647 | |
911 | lea esi, [ebx + SOCKET.RCV_NXT] |
648 | align 4 |
912 | mov eax, [esi] ; save original |
649 | stateTCB_SYN_SENT: |
913 | call inc_inet_esi |
- | |
914 | ;; jmp ste_ack - NO, there may be data |
- | |
915 | - | ||
Line -... | Line 650... | ||
- | 650 | ; We are awaiting an ACK to our SYN, with a SYM |
|
- | 651 | ; Look at control flags - expecting an ACK |
|
916 | .check_ack: |
652 | |
917 | ; Check that we received an ACK |
- | |
918 | test [edx + 20 + TCP_Packet.Flags], TH_ACK |
- | |
919 | jz .exit |
- | |
920 | - | ||
921 | ; TODO - done, I think! |
- | |
922 | ; First, look at the incoming window. If this is less than or equal to 1024, |
- | |
923 | ; Set the socket window timer to 1. This will stop an additional Packets being queued. |
- | |
924 | ; ** I may need to tweak this value, since I do not know how many Packets are already queued |
653 | mov al, [edx + TCP_Packet.Flags] |
925 | mov cx, [edx + 20 + TCP_Packet.Window] |
654 | and al, TH_SYN + TH_ACK |
926 | xchg cl, ch |
- | |
927 | cmp cx, 1024 |
- | |
928 | ja @f |
- | |
929 | - | ||
930 | mov [ebx + SOCKET.wndsizeTimer], 1 |
- | |
931 | - | ||
932 | @@: ; OK, here is the deal |
- | |
933 | ; My recv.nct field holds the seq of the expected next rec byte |
- | |
934 | ; if the recevied sequence number is not equal to this, do not |
- | |
935 | ; increment the recv.nxt field, do not copy data - just send a |
- | |
936 | ; repeat ack. |
- | |
937 | - | ||
938 | ; recv.nxt is in dword [edx+24], in inet format |
- | |
939 | ; recv seq is in [sktAddr]+56, in inet format |
- | |
Line 940... | Line 655... | ||
940 | ; just do a comparision |
655 | cmp al, TH_SYN + TH_ACK |
941 | mov ecx, [ebx + SOCKET.RCV_NXT] |
656 | je .syn_ack |
942 | cmp [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT |
- | |
Line -... | Line 657... | ||
- | 657 | ||
- | 658 | test al, TH_SYN |
|
943 | jne @f |
659 | jz .exit |
944 | mov ecx, eax |
660 | |
945 | 661 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_SYN_RECEIVED |
|
Line 946... | Line 662... | ||
946 | @@: cmp ecx, [edx + 20 + TCP_Packet.SequenceNumber] |
662 | push TH_SYN + TH_ACK |
947 | jne .ack |
663 | jmp .send |
Line 948... | Line 664... | ||
948 | 664 | ||
949 | 665 | .syn_ack: |
|
Line 950... | Line 666... | ||
950 | ; Read the data bytes, store in socket buffer |
666 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.TCBState], TCB_ESTABLISHED |
951 | ; movzx ecx, [edx + IP_Packet.TotalLength] |
- | |
952 | xchg cl, ch |
- | |
953 | sub ecx, 40 ; Discard 40 bytes of header |
- | |
954 | ja .data ; Read data, if any |
- | |
955 | - | ||
956 | ; If we had received a fin, we need to ACK it. |
- | |
957 | cmp [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT |
- | |
958 | je .ack |
667 | push TH_ACK |
959 | jmp .exit |
668 | |
960 | - | ||
961 | .data: |
- | |
962 | push ebx |
- | |
963 | add ebx, SOCKET.lock |
- | |
964 | call wait_mutex |
- | |
965 | pop ebx |
- | |
966 | - | ||
967 | push ecx |
- | |
968 | push [ebx + SOCKET.PID] ; get socket owner PID |
- | |
969 | mov eax, [ebx + SOCKET.rxDataCount] |
- | |
970 | add eax, ecx |
- | |
971 | cmp eax, SOCKETBUFFSIZE - SOCKETHEADERSIZE |
- | |
972 | ja .overflow |
- | |
973 | - | ||
Line 974... | Line 669... | ||
974 | mov [ebx + SOCKET.rxDataCount], eax ; increment the count of bytes in buffer |
669 | .send: |
975 | 670 | ; Store the recv.nxt field |
|
976 | ; point to the location to store the data |
- | |
Line -... | Line 671... | ||
- | 671 | mov eax, [edx + TCP_Packet.SequenceNumber] |
|
- | 672 | ||
977 | lea edi, [ebx + eax + SOCKETHEADERSIZE] |
673 | ; Update our recv.nxt field |
978 | sub edi, ecx |
674 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], eax |
979 | 675 | lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
|
980 | add edx, 40 ; edx now points to the data |
676 | inc_INET esi |
981 | mov esi, edx |
- | |
Line -... | Line 677... | ||
- | 677 | ||
- | 678 | ; Send an ACK |
|
982 | 679 | pop ebx |
|
983 | cld |
680 | call TCP_send_ack |
984 | rep movsb ; copy the data across |
681 | |
985 | mov [ebx + SOCKET.lock], 0 ; release mutex |
682 | .exit: |
Line 986... | Line 683... | ||
986 | 683 | ret |
|
Line 987... | Line 684... | ||
987 | ; flag an event to the application |
684 | |
988 | pop eax |
685 | |
989 | mov ecx, 1 |
- | |
Line -... | Line 686... | ||
- | 686 | ||
990 | mov esi, TASK_DATA + TASKDATA.pid |
687 | align 4 |
991 | 688 | stateTCB_SYN_RECEIVED: |
|
992 | .next_pid: |
689 | ; In this case, we are expecting an ACK Packet |
993 | cmp [esi], eax |
690 | ; For now, if the Packet is an ACK, process it, |
Line 994... | Line 691... | ||
994 | je .found_pid |
691 | ; If not, ignore it |
995 | inc ecx |
692 | |
Line 996... | Line 693... | ||
996 | add esi, 0x20 |
693 | test [edx + TCP_Packet.Flags], TH_RST |
997 | cmp ecx, [TASK_COUNT] |
694 | jz .check_ack |
998 | jbe .next_pid |
- | |
Line 999... | Line -... | ||
999 | - | ||
1000 | .found_pid: |
- | |
1001 | shl ecx, 8 |
695 | |
1002 | or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event |
- | |
1003 | - | ||
1004 | pop ecx |
696 | push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemotePort] |
1005 | 697 | pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort] |
|
1006 | ; Update our recv.nxt field |
- | |
1007 | lea esi, [ebx + SOCKET.RCV_NXT] |
- | |
1008 | call add_inet_esi |
- | |
1009 | - | ||
1010 | .ack: |
- | |
1011 | ; Send an ACK |
- | |
1012 | ; Now construct the response, and queue for sending by IP |
- | |
1013 | ; mov eax, EMPTY_QUEUE |
- | |
1014 | ; call dequeue |
- | |
1015 | ; cmp ax, NO_BUFFER |
- | |
1016 | je .exit |
- | |
1017 | - | ||
1018 | push eax |
- | |
1019 | - | ||
1020 | mov bl, TH_ACK |
- | |
1021 | xor ecx, ecx |
- | |
1022 | xor esi, esi |
- | |
1023 | ; stdcall build_tcp_Packet, [sockAddr] |
- | |
1024 | - | ||
1025 | ; mov eax, NET1OUT_QUEUE |
- | |
1026 | - | ||
1027 | ;;; mov edx, [stack_ip] |
- | |
1028 | ; mov ecx, [sockAddr] |
- | |
1029 | ; cmp edx, [ecx + SOCKET.RemoteIP] |
- | |
1030 | ; jne .not_local |
- | |
1031 | ; mov eax, IPIN_QUEUE |
- | |
1032 | - | ||
1033 | .not_local: |
- | |
1034 | ; Send it. |
- | |
1035 | pop ebx |
- | |
1036 | ;;; call queue |
- | |
1037 | - | ||
1038 | .exit: |
- | |
1039 | ret |
- | |
1040 | .overflow: |
- | |
1041 | ; no place in buffer |
- | |
1042 | ; so simply restore stack and exit |
- | |
1043 | pop eax ecx |
- | |
1044 | mov [ebx + SOCKET.lock], 0 |
- | |
1045 | ret |
- | |
1046 | endp |
- | |
1047 | - | ||
1048 | - | ||
1049 | proc stateTCB_FIN_WAIT_1 stdcall, sockAddr:DWORD |
- | |
1050 | ; We can either receive an ACK of a fin, or a fin |
- | |
1051 | mov al, [edx + 20 + TCP_Packet.Flags] |
- | |
1052 | and al, TH_FIN + TH_ACK |
- | |
1053 | - | ||
1054 | cmp al, TH_ACK |
- | |
1055 | jne @f |
- | |
1056 | - | ||
1057 | ; It was an ACK |
- | |
1058 | mov [ebx + SOCKET.TCBState], TCB_FIN_WAIT_2 |
- | |
1059 | jmp .exit |
- | |
1060 | - | ||
1061 | @@: mov [ebx + SOCKET.TCBState], TCB_CLOSING |
- | |
1062 | cmp al, TH_FIN |
- | |
1063 | je @f |
- | |
1064 | mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT |
- | |
1065 | - | ||
1066 | @@: lea esi, [ebx + SOCKET.RCV_NXT] |
- | |
1067 | call inc_inet_esi |
- | |
1068 | - | ||
1069 | ; Send an ACK |
- | |
1070 | ; mov eax, EMPTY_QUEUE |
- | |
1071 | ; call dequeue |
- | |
1072 | ; cmp ax, NO_BUFFER |
- | |
Line 1073... | Line -... | ||
1073 | je .exit |
- | |
Line 1074... | Line -... | ||
1074 | - | ||
1075 | push eax |
- | |
1076 | - | ||
1077 | mov bl, TH_ACK |
- | |
1078 | xor ecx, ecx |
- | |
1079 | xor esi, esi |
- | |
1080 | ; stdcall build_tcp_Packet, [sockAddr] |
- | |
1081 | 698 | push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemoteIP] |
|
1082 | ; mov eax, NET1OUT_QUEUE |
- | |
1083 | ;;; mov edx, [stack_ip] |
- | |
1084 | ; mov ecx, [sockAddr] |
- | |
1085 | ; cmp edx, [ecx + SOCKET.RemoteIP] |
- | |
1086 | ; jne .not_local |
- | |
1087 | ; mov eax, IPIN_QUEUE |
- | |
1088 | 699 | pop [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
|
1089 | .not_local: |
- | |
1090 | ; Send it. |
- | |
1091 | pop ebx |
- | |
1092 | ;;; call queue |
- | |
1093 | - | ||
1094 | .exit: |
- | |
1095 | ret |
- | |
1096 | endp |
- | |
1097 | - | ||
1098 | - | ||
1099 | proc stateTCB_FIN_WAIT_2 stdcall, sockAddr:DWORD |
- | |
1100 | test [edx + 20 + TCP_Packet.Flags], TH_FIN |
- | |
1101 | jz .exit |
- | |
1102 | - | ||
1103 | ; Change state, as we have a fin |
- | |
1104 | mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT |
- | |
1105 | - | ||
1106 | lea esi, [ebx + SOCKET.RCV_NXT] |
- | |
1107 | call inc_inet_esi |
- | |
1108 | - | ||
1109 | ; Send an ACK |
- | |
1110 | ; mov eax, EMPTY_QUEUE |
- | |
1111 | ; call dequeue |
- | |
1112 | ;; cmp ax, NO_BUFFER |
- | |
1113 | ; je .exit |
- | |
1114 | - | ||
1115 | push eax |
- | |
1116 | - | ||
1117 | mov bl, TH_ACK |
- | |
1118 | xor ecx, ecx |
- | |
1119 | xor esi, esi |
- | |
1120 | ; stdcall build_tcp_Packet, [sockAddr] |
- | |
1121 | - | ||
1122 | ; mov eax, NET1OUT_QUEUE |
- | |
1123 | ;;; mov edx, [stack_ip] |
- | |
1124 | mov ecx, [sockAddr] |
- | |
1125 | cmp edx, [ecx + SOCKET.RemoteIP] |
- | |
1126 | jne .not_local |
- | |
1127 | ; mov eax, IPIN_QUEUE |
- | |
1128 | - | ||
1129 | .not_local: |
- | |
1130 | ; Send it. |
- | |
1131 | pop ebx |
- | |
1132 | ;;; call queue |
- | |
1133 | - | ||
1134 | .exit: |
- | |
1135 | ret |
- | |
1136 | endp |
- | |
1137 | - | ||
1138 | 700 | ||
1139 | proc stateTCB_CLOSE_WAIT stdcall, sockAddr:DWORD |
- | |
1140 | ; Intentionally left empty |
- | |
1141 | ; socket_close_tcp handles this |
- | |
1142 | ret |
- | |
1143 | endp |
- | |
1144 | - | ||
1145 | - | ||
1146 | proc stateTCB_CLOSING stdcall, sockAddr:DWORD |
- | |
1147 | ; We can either receive an ACK of a fin, or a fin |
- | |
1148 | test [edx + 20 + TCP_Packet.Flags], TH_ACK |
- | |
1149 | jz .exit |
- | |
1150 | - | ||
1151 | mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT |
- | |
1152 | - | ||
1153 | .exit: |
- | |
1154 | ret |
- | |
1155 | endp |
- | |
1156 | - | ||
1157 | - | ||
1158 | proc stateTCB_LAST_ACK stdcall, sockAddr:DWORD |
- | |
1159 | ; Look at control flags - expecting an ACK |
- | |
1160 | test [edx + 20 + TCP_Packet.Flags], TH_ACK |
- | |
1161 | jz .exit |
- | |
1162 | - | ||
1163 | ; delete the socket |
- | |
Line 1164... | Line -... | ||
1164 | stdcall net_socket_free, ebx |
- | |
1165 | - | ||
1166 | .exit: |
- | |
Line 1167... | Line -... | ||
1167 | ret |
- | |
1168 | endp |
- | |
Line 1169... | Line -... | ||
1169 | - | ||
1170 | - | ||
1171 | proc stateTCB_TIME_WAIT stdcall, sockAddr:DWORD |
- | |
1172 | ret |
- | |
1173 | endp |
- | |
1174 | - | ||
1175 | - | ||
1176 | proc stateTCB_CLOSED stdcall, sockAddr:DWORD |
- | |
1177 | ret |
- | |
1178 | endp |
- | |
1179 | - | ||
1180 | - | ||
1181 | - | ||
1182 | ;; [53.7] Send data through STREAM socket |
- | |
1183 | ; |
- | |
1184 | ; @param EBX is socket number |
- | |
1185 | ; @param ECX is application data size (number of bytes to send) |
- | |
1186 | ; @param EDX is pointer to application data buffer |
- | |
1187 | ; @return 0 (sent successfully) or -1 (error) in EAX |
- | |
1188 | ;; |
- | |
1189 | ;proc socket_write_tcp stdcall |
- | |
1190 | ;local sockAddr dd ? |
- | |
1191 | - | ||
1192 | ; DEBUGF 1, "socket_write_tcp(0x%x)\n", ebx |
- | |
1193 | stdcall net_socket_num_to_addr, ebx |
- | |
1194 | or eax, eax |
- | |
1195 | jz .error |
- | |
1196 | - | ||
1197 | mov ebx, eax |
- | |
1198 | ; mov [sockAddr], ebx |
- | |
1199 | - | ||
1200 | ; If the sockets window timer is nonzero, do not queue Packet |
- | |
1201 | cmp [ebx + SOCKET.wndsizeTimer], 0 |
- | |
1202 | jne .error |
- | |
1203 | - | ||
1204 | ; mov eax, EMPTY_QUEUE |
- | |
1205 | ; call dequeue |
- | |
1206 | ; cmp ax, NO_BUFFER |
- | |
1207 | ; je .error |
- | |
1208 | - | ||
1209 | push eax |
- | |
1210 | - | ||
1211 | ; Get the address of the callers data |
- | |
1212 | mov edi, [TASK_BASE] |
- | |
1213 | add edi, TASKDATA.mem_start |
- | |
1214 | add edx, [edi] |
- | |
1215 | mov esi, edx |
- | |
1216 | - | ||
1217 | pop eax |
- | |
1218 | push eax |
- | |
1219 | - | ||
1220 | push ecx |
- | |
1221 | mov bl, TH_ACK |
- |