Subversion Repositories Kolibri OS

Rev

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

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