Subversion Repositories Kolibri OS

Rev

Rev 1206 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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