Subversion Repositories Kolibri OS

Rev

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

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