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