Subversion Repositories Kolibri OS

Rev

Rev 1281 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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