Subversion Repositories Kolibri OS

Rev

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

Rev 1257 Rev 1274
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...
17
 
17
 
18
$Revision: 1257 $
18
$Revision: 1274 $
19
 
19
 
20
TCP_RETRIES		equ 5		; Number of times to resend a Packet
20
TCP_RETRIES		equ 5		; Number of times to resend a Packet
Line 31... Line 31...
31
	.DataOffset		db ?	; DataOffset[0-3 bits] and Reserved[4-7]
31
	.DataOffset		db ?	; DataOffset[0-3 bits] and Reserved[4-7]
32
	.Flags			db ?	; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN
32
	.Flags			db ?	; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN
33
	.Window 		dw ?
33
	.Window 		dw ?
34
	.Checksum		dw ?
34
	.Checksum		dw ?
35
	.UrgentPointer		dw ?
35
	.UrgentPointer		dw ?
36
	.Options		rb 3
36
;        .Options                rb 3
37
	.Padding		db ?
37
;        .Padding                db ?
38
	.Data:
38
	.Data:
39
ends
39
ends
Line -... Line 40...
-
 
40
 
-
 
41
struct	tcp_in_queue_entry
-
 
42
	.data_ptr	dd ?
-
 
43
	.data_size	dd ?
-
 
44
	.offset 	dd ?
-
 
45
	.size:
-
 
46
ends
-
 
47
 
-
 
48
struct	tcp_out_queue_entry
-
 
49
	.data_ptr	dd ?
-
 
50
	.data_size	dd ?
-
 
51
	.ttl		dd ?
-
 
52
	.retries	dd ?
-
 
53
	.owner		dd ?
-
 
54
	.sendproc	dd ?
-
 
55
	.seq_num	dd ?
-
 
56
	.socket 	dd ?
-
 
57
	.size:
-
 
58
ends
40
 
59
 
41
align 4
60
align 4
42
uglobal
61
uglobal
43
	TCP_PACKETS_TX		rd  MAX_IP
62
	TCP_PACKETS_TX		rd  MAX_IP
Line 85... Line 104...
85
	mov	ecx, 2*MAX_IP
104
	mov	ecx, 2*MAX_IP
86
	rep	stosd
105
	rep	stosd
Line 87... Line 106...
87
 
106
 
Line 88... Line 107...
88
	init_queue TCP_IN_QUEUE
107
	init_queue TCP_IN_QUEUE
89
 
108
 
90
	; tcp_out_queue is a special type of queue:
109
; tcp_out_queue is a special type of queue:
91
	; The first dword is a counter of total packets queued.
110
; The first dword is a counter of total packets queued.
92
	; The remaining bytes are socket 'slots' wich use tcp_out_queue_entry data structure.
111
; The remaining bytes are socket 'slots' wich use tcp_out_queue_entry data structure.
Line 93... Line 112...
93
	; An empty slot is know by the fact that tcp_out_queue_entry.data_ptr (first dword of the slot) is set to 0
112
; An empty slot is know by the fact that tcp_out_queue_entry.data_ptr (first dword of the slot) is set to 0
94
	; There are TCP_OUT_QUEUE_SIZE number of slots
113
; There are TCP_OUT_QUEUE_SIZE number of slots
95
 
114
 
96
	xor	eax, eax
115
	xor	eax, eax
Line 109... Line 128...
109
;  OUT: /
128
;  OUT: /
110
;
129
;
111
;-----------------------------------------------------------------
130
;-----------------------------------------------------------------
112
align 4
131
align 4
113
TCP_decrease_socket_ttls:
132
TCP_decrease_socket_ttls:
114
	; scan through all the sockets, decrementing active timers
133
; scan through all the sockets, decrementing active timers
Line 115... Line 134...
115
 
134
 
Line 116... Line 135...
116
	mov	ebx, net_sockets
135
	mov	ebx, net_sockets
117
 
136
 
Line 133... Line 152...
133
	cmp	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0
152
	cmp	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0
134
	jne	.decrement_wnd
153
	jne	.decrement_wnd
135
	jmp	.next_socket
154
	jmp	.next_socket
Line 136... Line 155...
136
 
155
 
137
  .decrement_tcb:
156
  .decrement_tcb:
138
	; decrement it, delete socket if TCB timer = 0 & socket in timewait state
157
; decrement it, delete socket if TCB timer = 0 & socket in timewait state
139
	dec	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer]
158
	dec	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer]
Line 140... Line 159...
140
	jnz	.next_socket
159
	jnz	.next_socket
141
 
160
 
Line 146... Line 165...
146
	stdcall net_socket_free, ebx
165
	stdcall net_socket_free, ebx
147
	pop	ebx
166
	pop	ebx
148
	jmp	.next_socket
167
	jmp	.next_socket
Line 149... Line 168...
149
 
168
 
150
  .decrement_wnd:
-
 
151
	; TODO - prove it works!
169
  .decrement_wnd:
152
	dec	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer]
170
	dec	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer]
Line 153... Line 171...
153
	jmp	.next_socket
171
	jmp	.next_socket
154
 
172
 
Line 224... Line 242...
224
 
242
 
225
 
243
 
226
 
-
 
227
;-----------------------------------------------------------------
-
 
228
;
-
 
229
; TCP_add_to_queue:
-
 
230
;
-
 
231
;  Queue a TCP packet for sending
-
 
232
;
-
 
233
;  IN:  [esp] pointer to buffer
-
 
234
;       [esp + 4] size of buffer
-
 
235
;       ebx = driver struct
-
 
236
;       esi = sender proc
-
 
237
;       edx = acknum
-
 
238
;  OUT: /
-
 
239
;
-
 
240
;-----------------------------------------------------------------
-
 
241
align 4
-
 
242
TCP_add_to_queue:
-
 
243
 
-
 
244
	DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %x\n", [esp], [esp+4], ebx, edx
-
 
245
 
-
 
246
	cmp	[TCP_OUT_QUEUE], TCP_QUEUE_SIZE
-
 
247
	jge	.full
-
 
248
 
-
 
249
	mov	ecx, TCP_QUEUE_SIZE
-
 
250
	mov	eax, TCP_OUT_QUEUE+4
-
 
251
 
-
 
252
  .loop:
-
 
253
	cmp	[eax + tcp_out_queue_entry.data_ptr], 0
-
 
254
	je	.found_it
-
 
255
	add	eax, tcp_out_queue_entry.size
-
 
256
	loop	.loop
-
 
257
 
-
 
258
  .full:			; silently discard the packet
-
 
259
 
-
 
260
	DEBUGF 1,"TCP queue is full!\n"
-
 
261
 
-
 
262
	call	kernel_free
-
 
263
	add	esp, 4
-
 
264
 
-
 
265
	ret
-
 
266
 
-
 
267
  .found_it:			; eax point to empty queue entry
-
 
268
 
-
 
269
	pop	[eax + tcp_out_queue_entry.data_ptr]
-
 
270
	pop	[eax + tcp_out_queue_entry.data_size]
-
 
271
	mov	[eax + tcp_out_queue_entry.ttl], 1			; send immediately
-
 
272
	mov	[eax + tcp_out_queue_entry.retries], TCP_RETRIES
-
 
273
	mov	[eax + tcp_out_queue_entry.owner], ebx
-
 
274
	mov	[eax + tcp_out_queue_entry.sendproc], esi
-
 
275
	mov	[eax + tcp_out_queue_entry.seq_num], edx
-
 
276
 
-
 
277
	inc	[TCP_OUT_QUEUE]
-
 
278
 
-
 
279
	sub	eax, TCP_OUT_QUEUE+4
-
 
280
	DEBUGF 1,"Added to queue in pos %u\n", eax
-
 
281
 
-
 
282
	ret
-
 
283
 
-
 
284
 
244
 
285
;-----------------------------------------------------------------
245
;-----------------------------------------------------------------
286
;
246
;
287
; TCP_handler:
247
; TCP_handler:
288
;
248
;
289
;  Called by IPv4_handler,
249
;  Called by IPv4_handler,
290
;  this procedure will inject the tcp data diagrams in the application sockets.
250
;  this procedure will inject the tcp data diagrams in the application sockets.
291
;
251
;
292
;  IN:  Pointer to buffer in [esp]
252
;  IN:  Pointer to buffer in [esp]
293
;       size of buffer in [esp+4]
253
;       size of buffer in [esp+4]
294
;       pointer to device struct in ebx
254
;       pointer to device struct in ebx
295
;       TCP Packet size in ecx
255
;       TCP Packet size in ecx
296
;       pointer to TCP Packet data in edx
256
;       pointer to TCP Packet in edx
297
;       SourceAddres in esi
257
;       SourceAddres (IPv4) in esi
298
;  OUT: /
258
;  OUT: /
299
;
259
;
Line 300... Line 260...
300
;-----------------------------------------------------------------
260
;-----------------------------------------------------------------
Line 301... Line 261...
301
align 4
261
align 4
Line 302... Line 262...
302
TCP_handler :
262
TCP_handler :
303
 
263
 
304
       DEBUGF 1,"TCP_Handler\n"
264
       DEBUGF 1,"TCP_Handler\n"
Line 305... Line 265...
305
 
265
 
Line 306... Line 266...
306
	; TODO: validate checksum
266
; TODO: validate checksum
307
 
267
 
Line 327... Line 287...
327
	jne	.socket_loop
287
	jne	.socket_loop
328
       @@:
288
       @@:
Line 329... Line 289...
329
 
289
 
330
	mov	ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort]
290
	mov	ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort]
331
	cmp	[edx + TCP_Packet.SourcePort] , ax
291
	cmp	[edx + TCP_Packet.SourcePort] , ax
332
	je	.change_state
292
	je	.found_socket
333
	test	ax, ax
293
	test	ax, ax
334
	jnz	.socket_loop
-
 
335
 
294
	jnz	.socket_loop
336
  .change_state:
-
 
337
 
295
  .found_socket:
Line 338... Line 296...
338
       DEBUGF 1,"Found valid socket for packet\n"
296
       DEBUGF 1,"Found valid socket for packet\n"
Line 339... Line -...
339
 
-
 
340
	inc	[TCP_PACKETS_RX]
297
 
341
 
298
	inc	[TCP_PACKETS_RX]
342
	push	ebx
299
 
Line 343... Line 300...
343
	lea	ebx, [ebx + SOCKET_head.lock]
300
	add	ebx, SOCKET_head.lock
344
	call	wait_mutex
301
	call	wait_mutex
345
	pop	ebx
302
	sub	ebx, SOCKET_head.lock
346
 
303
 
Line -... Line 304...
-
 
304
;-------------------------------
-
 
305
; ebx is pointer to socket
-
 
306
; ecx is size of tcp packet
-
 
307
; edx is pointer to tcp packet
-
 
308
 
-
 
309
; calculate header length
-
 
310
	movzx	eax, [edx + TCP_Packet.DataOffset]
-
 
311
	and	eax, 11110000b
-
 
312
	shr	eax, 2
-
 
313
       DEBUGF 1,"TCP header size: %u\n", eax
347
;----------------------------------
314
	sub	ecx, eax
348
; ebx is pointer to socket
315
 
Line 349... Line 316...
349
; ecx is size of tcp packet
316
;-------------------------------
350
; edx is pointer to tcp packet
317
; ecx is size of tcp data
351
 
318
 
Line -... Line 319...
-
 
319
; as a Packet has been received, update the TCB timer
352
	; as a Packet has been received, update the TCB timer
320
	mov	[ebx +	SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], TCP_SOCKET_TTL
-
 
321
 
353
	mov	[ebx +	SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], TCP_SOCKET_TTL
322
; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges
354
 
323
	test	[edx + TCP_Packet.Flags], TH_ACK
-
 
324
	jz	.no_ack 				 ; No ACK, so no data yet
355
	; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges
325
 
356
	test	[edx + TCP_Packet.Flags], TH_ACK
326
; Calculate ACK number
357
	jz	.call_handler					; No ACK, so no data yet
327
	mov	edi, [edx + TCP_Packet.AckNumber]
358
 
328
	bswap	edi
Line 359... Line -...
359
;        mov     eax, [edx + TCP_Packet.SequenceNumber]          ; Calculate sequencenumber in eax
-
 
360
;        bswap   eax                                             ;
-
 
361
;        add     eax, ecx                                        ;
329
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], edi
362
 
-
 
363
	mov	eax, [edx + TCP_Packet.AckNumber]
330
       DEBUGF 1,"Setting last_ack_number to %u\n", edi
364
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], eax
-
 
365
	;---------
331
	bswap	edi
366
 
332
 
367
	cmp	[TCP_OUT_QUEUE], 0
-
 
368
	je	.call_handler
333
; Dequeue all acknowledged packets
369
	push	ecx
334
	cmp	[TCP_OUT_QUEUE], 0		; first, check if any packets are queued at all
370
 
335
	je	.no_ack
-
 
336
 
-
 
337
	push	ecx
-
 
338
       DEBUGF 1,"Removing all queued packets with smaller ACK\n"
-
 
339
	mov	ecx, TCP_QUEUE_SIZE
371
       DEBUGF 1,"Removing all queued packets with smaller ACK\n"
340
	mov	esi, TCP_OUT_QUEUE+4
372
 
341
  .loop:
373
	mov	ecx, TCP_QUEUE_SIZE
-
 
Line 374... Line 342...
374
	mov	esi, TCP_OUT_QUEUE+4
342
	cmp	[esi + tcp_out_queue_entry.data_ptr], 0
Line 375... Line 343...
375
 
343
	je	.maybe_next
376
  .loop:
344
 
Line 388... Line 356...
388
	call	kernel_free
356
	call	kernel_free
Line 389... Line 357...
389
 
357
 
390
  .maybe_next:
358
  .maybe_next:
391
	add	esi, tcp_out_queue_entry.size
359
	add	esi, tcp_out_queue_entry.size
392
	loop	.loop
-
 
393
 
360
	loop	.loop
-
 
361
	pop	ecx
-
 
362
 
-
 
363
 
394
	pop	ecx
364
; Now call the correct handler, depending on the socket state
395
  .call_handler:
-
 
396
	; Call handler for given TCB state
365
  .no_ack:
397
	mov	eax, [ebx +  SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state]
-
 
Line 398... Line 366...
398
	DEBUGF 1,"Socket state: %u\n", eax
366
	mov	eax, [ebx +  SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state]
399
 
367
 
400
	cmp	eax, TCB_LISTEN
368
	cmp	eax, TCB_LISTEN
401
	jb	.dump
369
	jb	.dump
Line 417... Line 385...
417
 
385
 
418
 
386
 
419
 
387
 
420
;-----------------------------------------------------------------
388
;-----------------------------------------------------------------
421
;
389
;
-
 
390
; TCP_send  (Assumes socket mutex set)
422
; TCP_socket_send
391
;
423
;
392
; IN: eax = socket pointer
424
; IN: eax = socket pointer
393
;      bl = flags
425
;     ecx = number of bytes to send
394
;      ecx = number of bytes to send, may be set to 0
426
;     esi = pointer to data
395
;      esi = pointer to data
427
;
396
;
Line 428... Line 397...
428
;-----------------------------------------------------------------
397
;-----------------------------------------------------------------
Line 429... Line 398...
429
align 4
398
align 4
-
 
399
TCP_send:
Line -... Line 400...
-
 
400
 
430
TCP_socket_send:
401
	DEBUGF 1,"Creating TCP packet, socket: %x, flags: %x\n",eax, bl
431
 
-
 
432
	DEBUGF 1,"Creating TCP Packet\n"
402
 
433
 
403
	mov	di , IP_PROTO_TCP
Line 434... Line -...
434
	mov	di , IP_PROTO_TCP
-
 
435
 
-
 
436
; Create an IPv4 Packet of the correct size
-
 
437
	push	eax
-
 
438
	mov	ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
-
 
439
	mov	eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
-
 
440
 
-
 
441
; meanwhile, create the pseudoheader in stack,
-
 
442
; (now that we still have all the variables that are needed.)
-
 
443
	push	cx
-
 
444
	push	di
404
	add	ecx, TCP_Packet.Data
445
	push	eax
405
 
446
	push	ebx
406
	push	bx eax esi
Line -... Line 407...
-
 
407
; Create an IPv4 Packet of the correct size
447
 
408
	mov	ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
448
 
-
 
449
	push	ecx esi eax		; save some variables for later
-
 
450
	add	ecx, TCP_Packet.Options
-
 
451
	call	IPv4_create_packet
-
 
452
	cmp	edi, -1
-
 
453
	je	.fail
-
 
454
 
-
 
455
	pop	esi
-
 
456
 
-
 
457
; Now add the TCP header to the IPv4 packet
-
 
458
 
-
 
459
	push	[esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
409
	mov	eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
460
	pop	[edi + TCP_Packet.SequenceNumber]
-
 
461
 
-
 
462
	push	dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort]
410
 
463
	pop	dword [edi + TCP_Packet.SourcePort]
-
 
464
 
-
 
465
 
-
 
466
	push	[esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
-
 
467
	pop	[edi + TCP_Packet.AckNumber]
-
 
468
 
-
 
469
	mov	al, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.flags]
-
 
470
	mov	[edi + TCP_Packet.Flags], al
-
 
471
 
-
 
472
	mov	[edi + TCP_Packet.Window], 0x0005	   ; 1280 bytes
411
	call	IPv4_create_packet
Line 473... Line 412...
473
	mov	[edi + TCP_Packet.UrgentPointer], 0
412
	cmp	edi, -1
474
	mov	[edi + TCP_Packet.DataOffset], 0x50
413
	je	.fail
475
	mov	[edi + TCP_Packet.Checksum], 0
414
 
476
 
415
; If there is any data, copy it first
477
; Copy the data
416
	pop	esi
478
	mov	esi, [esp]
417
	push	edi
479
	mov	ecx, [esp+4]
-
 
480
	add	edi, TCP_Packet.Options
-
 
481
 
-
 
482
	shr	ecx, 1
418
	add	edi, TCP_Packet.Data
483
	jnc	.nb
-
 
484
	movsb
-
 
485
.nb:	shr	ecx, 1
-
 
486
	jnc	.nw
-
 
487
	movsw
-
 
488
.nw:	rep movsd
419
	sub	ecx, TCP_Packet.Data
489
 
420
 
490
; Now, calculate the checksum for pseudoheader
-
 
491
	xor	edx, edx
-
 
492
	mov	ecx, 12
-
 
493
	mov	esi, esp
-
 
494
	call	checksum_1
-
 
495
	add	esp, 12 				   ; remove the pseudoheader from stack
-
 
496
; And that of the data
-
 
497
	pop	esi
-
 
498
	pop	ecx
-
 
499
	call	checksum_1
-
 
500
; Now create the final checksum and store it in TCP header
-
 
501
	call	checksum_2
-
 
502
	mov	[edi + TCP_Packet.Checksum], dx
-
 
503
 
421
	shr	ecx, 1
504
; And now, send it!
-
 
505
	DEBUGF 1,"Sending TCP Packet to device %x\n", ebx
-
 
506
	lea	esi, [ebx+ETH_DEVICE.transmit]
-
 
507
	mov	edx, [edi + TCP_Packet.AckNumber]
-
 
508
	jmp	TCP_add_to_queue
-
 
509
 
-
 
510
  .fail:
-
 
511
	add	esp, 12+12+4
-
 
512
	ret
-
 
513
 
-
 
514
 
-
 
515
 
-
 
516
 
-
 
517
 
-
 
518
;-----------------------------------------------------------------
-
 
519
;
-
 
520
; TCP_send_ack
-
 
521
;
-
 
522
; IN: eax = socket pointer
-
 
523
;      bl = flags
-
 
524
;
-
 
525
;-----------------------------------------------------------------
-
 
526
align 4
-
 
527
TCP_send_ack:
-
 
528
 
-
 
529
	DEBUGF 1,"Creating TCP ACK, socket: %x, flags: %x\n",eax, bl
-
 
530
 
-
 
531
	mov	di , IP_PROTO_TCP
-
 
532
	mov	ecx, TCP_Packet.Options
-
 
533
 
422
	jnc	.nb
534
	push	bx eax
-
 
Line 535... Line 423...
535
 
423
	movsb
536
; Create an IPv4 Packet of the correct size
424
.nb:	shr	ecx, 1
Line -... Line 425...
-
 
425
	jnc	.nw
537
 
426
	movsw
538
	mov	ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
427
.nw:	test	ecx, ecx
-
 
428
	jz	.nd
Line -... Line 429...
-
 
429
	rep	movsd
539
	mov	eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
430
.nd:
540
 
431
	pop	edi
Line -... Line 432...
-
 
432
 
541
	call	IPv4_create_packet
433
; Fill in the TCP header
542
	cmp	edi, -1
434
	pop	esi
Line -... Line 435...
-
 
435
 
543
	je	.fail
436
; fill in tcp sequence number
544
 
437
	push	[esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
545
; Fill in the TCP header
438
	pop	[edi + TCP_Packet.SequenceNumber]
546
	pop	esi
439
	inc_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT) ;;;;;;;;
547
 
440
 
548
	push	[esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
441
; Fill in local and remote ports
Line -... Line 442...
-
 
442
	push	dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort]
549
	pop	[edi + TCP_Packet.SequenceNumber]
443
	pop	dword [edi + TCP_Packet.SourcePort]
Line 550... Line 444...
550
 
444
 
551
	push	dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] ; both ports at once
445
; Acknumber
Line 552... Line 446...
552
	pop	dword [edi + TCP_Packet.SourcePort]
446
	push	[esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
553
 
447
	pop	[edi + TCP_Packet.AckNumber]
554
	push	[esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
448
 
555
	pop	[edi + TCP_Packet.AckNumber]
449
; Fill  in other tcp options
556
 
450
	pop	cx
Line 557... Line 451...
557
	pop	cx
451
	mov	[edi + TCP_Packet.Flags], cl
558
	mov	[edi + TCP_Packet.Flags], cl
452
	mov	[edi + TCP_Packet.Window], 0x0005	   ; 1280 bytes
559
	mov	[edi + TCP_Packet.Window], 0x0005	   ; 1280 bytes
453
	mov	[edi + TCP_Packet.UrgentPointer], 0
560
	mov	[edi + TCP_Packet.UrgentPointer], 0
454
	mov	[edi + TCP_Packet.DataOffset], 0x50
561
	mov	[edi + TCP_Packet.DataOffset], 0x50
455
	mov	[edi + TCP_Packet.Checksum], 0
562
	mov	[edi + TCP_Packet.Checksum], 0
456
 
563
 
457
; Push pointer to and size of total packet (needed for send procedure)
564
	push	edx eax
458
	push	edx eax
565
 
459
 
566
;        lea     esi, [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
460
; push socket number (for TCP_add_to_queue)
567
;        inc_INET esi
461
	push	esi
Line 568... Line 462...
568
 
462
 
569
; Now, calculate the checksum
463
; Now, calculate the checksum                  ; TODO: calculate correct checksum for packets with data
570
	pushw	TCP_Packet.Options shl 8
-
 
571
	pushw	IP_PROTO_TCP shl 8
464
	pushw	TCP_Packet.Data shl 8
-
 
465
	pushw	IP_PROTO_TCP shl 8
-
 
466
	pushd	[edi-4] ; destination address  ; TODO: fix this, IPv4 packet could have options..
-
 
467
	pushd	[edi-8] ; source address
572
	pushd	[edi-4] ; destination address  ; TODO: fix this, IPv4 packet could have options..
468
 
Line 573... Line 469...
573
	pushd	[edi-8] ; source address
469
	xor	edx, edx
574
 
470
	mov	ecx, TCP_Packet.Data
-
 
471
	mov	esi, edi
-
 
472
	call	checksum_1
-
 
473
	mov	ecx, 12
-
 
474
	mov	esi, esp
-
 
475
	call	checksum_1
-
 
476
	add	esp, 12 				   ; remove the pseudoheader from stack
-
 
477
; and store it in TCP header
-
 
478
	call	checksum_2
-
 
479
	mov	[edi + TCP_Packet.Checksum], dx
-
 
480
 
-
 
481
; At last send the packet!
-
 
482
	DEBUGF 1,"Sending TCP Packet to device %x\n", ebx
-
 
483
	mov	edx, [edi + TCP_Packet.SequenceNumber]
-
 
484
	bswap	edx
-
 
485
	mov	esi, [ebx + ETH_DEVICE.transmit]
-
 
486
	pop	edi
-
 
487
	jmp	TCP_queue
-
 
488
 
-
 
489
  .fail:
-
 
490
	add	esp, 2+4
-
 
491
	or	eax, -1
-
 
492
	ret
-
 
493
 
-
 
494
 
-
 
495
;-----------------------------------------------------------------
-
 
496
;
-
 
497
;  Queue a TCP packet for sending
-
 
498
;
-
 
499
;  IN:  [esp] pointer to buffer
-
 
500
;       [esp + 4] size of buffer
-
 
501
;       ebx = driver struct
-
 
502
;       esi = sender proc
-
 
503
;       edx = sequence number of this packet in normal byte order
-
 
504
;       edi = socket number
-
 
505
;  OUT: /
-
 
506
;
-
 
507
;-----------------------------------------------------------------
-
 
508
align 4
-
 
509
TCP_queue:
-
 
510
 
-
 
511
	bswap	edx
-
 
512
	DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %u\n", [esp], [esp+4], ebx, edx
-
 
513
	bswap	edx
-
 
514
 
-
 
515
	cmp	[TCP_OUT_QUEUE], TCP_QUEUE_SIZE
-
 
516
	jge	.full
-
 
517
 
-
 
518
	mov	ecx, TCP_QUEUE_SIZE
-
 
519
	mov	eax, TCP_OUT_QUEUE+4
-
 
520
 
-
 
521
  .loop:
-
 
522
	cmp	[eax + tcp_out_queue_entry.data_ptr], 0
-
 
523
	je	.found_it
-
 
524
	add	eax, tcp_out_queue_entry.size
-
 
525
	loop	.loop
-
 
526
 
-
 
527
  .full:			; silently discard the packet
-
 
528
	DEBUGF 1,"TCP queue is full!\n"
-
 
529
 
-
 
530
	call	kernel_free
575
	xor	edx, edx
531
	add	esp, 4
Line 606... Line 562...
606
align 4
562
align 4
607
stateTCB_LISTEN:
563
stateTCB_LISTEN:
Line 608... Line 564...
608
 
564
 
Line 609... Line -...
609
	DEBUGF	1,"TCBStateHandler: Listen\n"
-
 
610
 
565
	DEBUGF	1,"TCBStateHandler: Listen\n"
611
	; In this case, we are expecting a SYN Packet
-
 
612
	; For now, if the Packet is a SYN, process it, and send a response
-
 
613
	; If not, ignore it
-
 
614
 
-
 
615
	; Look at control flags
566
 
616
	test	[edx + TCP_Packet.Flags], TH_SYN
567
	test	[edx + TCP_Packet.Flags], TH_SYN	; SYN packet? => send syn+ack, open new socket and set connection to established
617
	jz	.exit
568
	jz	.exit
618
	; Exit if backlog queue is full
569
; Exit if backlog queue is full
619
	mov	ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
570
	mov	ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
620
	cmp	ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog]
571
	cmp	ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog]
621
	jae	.exit
572
	jae	.exit
622
	; Allocate new socket
573
; Allocate new socket
623
	push	esi
-
 
624
	call	net_socket_alloc
574
	push	esi edi
625
	pop	esi
575
	call	net_socket_alloc
626
	test	eax, eax
576
	test	eax, eax
627
	jz	.exit
-
 
628
	; Copy structure from current socket to new, including lock
577
	jz	.fail
629
	push	esi edi
578
; Copy structure from current socket to new, including lock
630
	lea	esi, [ebx + SOCKET_head.PID]	; yes, PID must also be copied
579
	lea	esi, [ebx + SOCKET_head.PID]		; yes, PID must also be copied
631
	lea	edi, [eax + SOCKET_head.PID]
580
	lea	edi, [eax + SOCKET_head.PID]
632
	mov	ecx, ((SOCKET_head.end - SOCKET_head.PID) + IPv4_SOCKET.end + TCP_SOCKET.end + 3)/4
581
	mov	ecx, ((SOCKET_head.end - SOCKET_head.PID) + IPv4_SOCKET.end + TCP_SOCKET.end + 3)/4
633
	rep	movsd
582
	rep	movsd
634
	pop	edi esi
583
	pop	edi esi
635
	; Push pointer to new socket to queue
584
; Push pointer to new socket to queue
636
	movzx	ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
585
	movzx	ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
Line 637... Line -...
637
	inc	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
-
 
638
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + ecx*4], eax
-
 
639
 
-
 
640
	; We have a SYN. update the socket with this IP Packets details,
586
	inc	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
641
	; And send a response
587
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + ecx*4], eax
642
 
588
 
643
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], esi ; IP source address
589
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], esi ; IP source address
644
	mov	cx, [edx + TCP_Packet.SourcePort]
590
	mov	cx, [edx + TCP_Packet.SourcePort]
Line 649... Line 595...
649
	lea	esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
595
	lea	esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
650
	inc_INET esi ; RCV.NXT
596
	inc_INET esi ; RCV.NXT
651
	mov	ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS]
597
	mov	ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS]
652
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], ecx
598
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], ecx
Line 653... Line -...
653
 
-
 
654
	mov	[eax + SOCKET_head.lock], 0
599
 
Line 655... Line 600...
655
	mov	[ebx + SOCKET_head.lock], 0
600
	mov	[ebx + SOCKET_head.lock], 0
656
 
601
 
657
	push	eax
602
	push	eax
-
 
603
; Now construct the response
658
	; Now construct the response
604
	mov	bl, TH_SYN + TH_ACK
659
	mov	bl, TH_SYN + TH_ACK
605
	xor	ecx, ecx
Line -... Line 606...
-
 
606
	call	TCP_send
660
	call	TCP_send_ack
607
	pop	eax
661
	pop	eax
608
 
662
 
-
 
663
	mov	[eax +	SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
-
 
664
	call	notify_network_event
-
 
665
 
-
 
666
	; increment SND.NXT in socket
609
	mov	[eax + SOCKET_head.lock], 0
Line 667... Line 610...
667
	lea	esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
610
	mov	[eax +	SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
668
	inc_INET esi
611
	call	notify_network_event
669
	ret
612
	ret
Line -... Line 613...
-
 
613
 
-
 
614
  .exit:
-
 
615
	mov	[ebx + SOCKET_head.lock], 0
-
 
616
	ret
-
 
617
 
Line 670... Line 618...
670
 
618
  .fail:
671
  .exit:
619
	add	esp, 8
Line 672... Line 620...
672
	mov	[ebx + SOCKET_head.lock], 0
620
	mov	[ebx + SOCKET_head.lock], 0
Line 673... Line 621...
673
	ret
621
	ret
674
 
622
 
Line 675... Line 623...
675
 
623
 
676
align 4
-
 
677
stateTCB_SYN_SENT:
-
 
678
 
-
 
Line 679... Line 624...
679
	DEBUGF	1,"TCBStateHandler: Syn_Sent\n"
624
align 4
680
 
625
stateTCB_SYN_SENT:
Line -... Line 626...
-
 
626
 
681
	; We are awaiting an ACK to our SYN, with a SYM
627
	DEBUGF	1,"TCBStateHandler: Syn_Sent\n"
682
	; Look at control flags - expecting an ACK
628
 
683
 
-
 
Line 684... Line -...
684
	mov	al, [edx + TCP_Packet.Flags]
-
 
685
	and	al, TH_SYN + TH_ACK
-
 
686
	cmp	al, TH_SYN + TH_ACK
-
 
Line 687... Line -...
687
	je	.syn_ack
-
 
688
 
-
 
689
	test	al, TH_SYN
629
	; We are awaiting an ACK to our SYN, with a SYM
690
	jz	.exit
630
	; Look at control flags - expecting an ACK
691
 
-
 
692
	mov	[ebx +	SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
-
 
693
	pushd	TH_SYN + TH_ACK
-
 
694
	jmp	.send
-
 
695
 
-
 
Line -... Line 631...
-
 
631
 
696
  .syn_ack:
632
	mov	al, [edx + TCP_Packet.Flags]
697
	mov	[ebx +	SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED
-
 
Line -... Line 633...
-
 
633
 
-
 
634
	test	al, TH_RST
-
 
635
	jnz	.reset			; jump if RST bit set
-
 
636
 
-
 
637
	push	[edx + TCP_Packet.SequenceNumber]				     ;;
-
 
638
	pop	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]	     ;;
-
 
639
	inc_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT)      ;;
-
 
640
 
698
	pushd	TH_ACK
641
 
699
 
642
	push	[edx + TCP_Packet.AckNumber]					    ;;;;;;
-
 
643
	pop	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]	    ;;;;;;
-
 
644
 
-
 
645
	and	al, TH_SYN + TH_ACK
-
 
646
	jz	.exit			; jump if none of the following is set: RST, SYN, ACK
700
  .send:
647
 
701
	; Store the recv.nxt field
-
 
Line 702... Line 648...
702
	mov	eax, [edx + TCP_Packet.SequenceNumber]
648
	test	al, TH_ACK
703
	mov	[ebx +	SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.IRS], eax
649
	jz     .onlysyn 		; jump if only SYN bit is set
704
	bswap	eax
650
 
Line -... Line 651...
-
 
651
	; If we arrived here, SYN and ACK are set
-
 
652
 
-
 
653
	mov	[ebx +	SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED
-
 
654
	pushw	TH_ACK
-
 
655
 
-
 
656
  .send:	; Send an ACK
-
 
657
	mov	eax, ebx
-
 
658
	pop	bx
-
 
659
	push	eax
-
 
660
	xor	ecx, ecx
-
 
661
	call	TCP_send
-
 
662
	pop	ebx
-
 
663
 
-
 
664
  .exit:
Line 705... Line 665...
705
	inc	eax
665
	mov	[ebx + SOCKET_head.lock], 0
706
	bswap	eax
666
	ret
Line 707... Line 667...
707
	mov	[ebx +	SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], eax	      ; Update our recv.nxt field
667
 
Line 708... Line -...
708
	mov	[ebx + SOCKET_head.lock], 0
-
 
709
 
-
 
710
	lea	esi, [ebx +  SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
-
 
711
	inc_INET esi
-
 
712
 
668
  .reset:
713
	; Send an ACK
669
	; TODO: ....
Line 714... Line 670...
714
	mov	eax, ebx
670
 
715
	pop	ebx
671
	; remove all queued TCP packets for this connection !
716
	call	TCP_send_ack
672
 
717
 
673
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSED
Line 718... Line 674...
718
  .exit:
674
	mov	[ebx + SOCKET_head.lock], 0
719
	mov	[ebx + SOCKET_head.lock], 0
675
	ret
Line 720... Line 676...
720
	ret
676
 
721
 
-
 
722
 
677
  .onlysyn:
723
 
678
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
Line 724... Line 679...
724
align 4
679
	pushw	TH_SYN + TH_ACK
725
stateTCB_SYN_RECEIVED:
680
	jmp	.send
726
 
681
 
Line 757... Line 712...
757
 
712
 
758
 
713
 
Line 759... Line -...
759
align 4
-
 
760
stateTCB_ESTABLISHED:
714
align 4
Line 761... Line 715...
761
 
715
stateTCB_ESTABLISHED:
-
 
716
 
-
 
717
	DEBUGF	1,"TCBStateHandler: Established\n"
-
 
718
 
762
 
719
	mov	eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
763
	DEBUGF	1,"TCBStateHandler: Established\n"
720
	bswap	eax
Line 764... Line 721...
764
 
721
	DEBUGF	1,"RCV_NXT is set to:%u\n", eax
-
 
722
	bswap	eax
-
 
723
	cmp	eax, [edx + TCP_Packet.SequenceNumber]
-
 
724
	jne	.exit
765
	mov	eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
725
 
-
 
726
; Calculate next sequencenumber
Line 766... Line -...
766
	cmp	eax, [edx + TCP_Packet.SequenceNumber]
-
 
767
	jne	.exit
727
	test	ecx, ecx
768
 
728
	jnz	@f
769
	; Here we are expecting data, or a request to close
-
 
770
	; OR both...
-
 
771
 
-
 
772
	; Did we receive a FIN or RST?
-
 
773
	test	[edx + TCP_Packet.Flags], TH_FIN
-
 
774
	jz	.check_ack
-
 
Line 775... Line 729...
775
 
729
	inc	ecx
776
	; It was a fin or reset.
-
 
777
 
730
       @@:
778
;;; TODO: write following code:
731
	add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT)
Line 779... Line 732...
779
	; Remove resend entries from the queue  - I dont want to send any more data
732
 
780
	; Send an ACK to that fin, and enter closewait state
-
 
781
 
733
	test	[edx + TCP_Packet.Flags], TH_FIN
782
  .check_ack:
734
	jnz	.fin
783
	; Check that we received an ACK
735
 
784
	test	[edx + TCP_Packet.Flags], TH_ACK
736
  .check_ack:
785
	jz	.exit
737
	test	[edx + TCP_Packet.Flags], TH_ACK
786
 
738
	jz	.exit
787
	DEBUGF	1,"Received ACK\n"
739
 
788
 
740
	DEBUGF	1,"Received ACK\n"
789
	; First, look at the incoming window. If this is less than or equal to 1024,
741
; First, look at the incoming window. If this is less than or equal to 1024,
790
	; Set the socket window timer to 1. This will stop an additional Packets being queued.
742
; Set the socket window timer to 1. This will stop an additional Packets being queued.
791
	; ** I may need to tweak this value, since I do not know how many Packets are already queued
743
; ** I may need to tweak this value, since I do not know how many Packets are already queued
Line -... Line 744...
-
 
744
	push	ecx
792
	push	ecx
745
	mov	cx, [edx + TCP_Packet.Window]
793
	mov	cx, [edx + TCP_Packet.Window]
-
 
794
	xchg	cl, ch
-
 
795
	cmp	cx, 1024
-
 
796
	ja	@f
-
 
797
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1
-
 
798
      @@:
-
 
799
	pop	ecx
-
 
800
 
746
	xchg	cl, ch
801
	test	ecx, ecx
-
 
802
	jnz	.data			   ; Read data, if any
-
 
803
 
-
 
804
	lea	esi, [ebx +  SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
-
 
805
	inc_INET esi
-
 
806
 
-
 
Line 807... Line 747...
807
	; If we had received a fin, we need to ACK it.
747
	cmp	cx, 1024
-
 
748
	ja	@f
-
 
749
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1
808
	cmp	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT
750
      @@:
-
 
751
	pop	ecx
-
 
752
 
-
 
753
; Now, see if we received any data
-
 
754
	test	ecx, ecx
-
 
755
	jz	.ack
-
 
756
 
809
	je	.ack
757
	DEBUGF	1,"Got %u bytes data!\n", ecx
810
	jmp	.exit
758
; calculate header length
811
 
759
	movzx	eax, [edx + TCP_Packet.DataOffset]
812
  .data:
760
	and	eax, 11110000b
Line 813... Line 761...
813
	     ;;;
761
	shr	eax, 2
814
	lea	esi, [ebx +  SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
-
 
815
	add_INET esi
-
 
816
 
762
       DEBUGF 1,"TCP header size: %u\n", eax
817
	DEBUGF	1,"Got data!\n"
763
	add	edx, eax
-
 
764
	add	esp, 4
-
 
765
	pop	esi
818
	mov	esi, [esp + 4]
766
	add	esp, 4
-
 
767
	sub	edx, esi
819
	sub	edx, esi
768
	mov	edi, edx
820
	mov	edi, edx
-
 
821
	mov	eax, ebx
769
	mov	eax, ebx
822
	call	socket_internal_receiver
770
	jmp	socket_internal_receiver	; Place the data from packet into socket
Line -... Line 771...
-
 
771
 
-
 
772
  .ack:
-
 
773
	mov	eax, ebx
-
 
774
	mov	bl, TH_ACK
-
 
775
	push	eax
-
 
776
	xor	ecx, ecx
-
 
777
	call	TCP_send		    ; send the ack
-
 
778
	pop	ebx
-
 
779
  .exit:
-
 
780
	mov	[ebx + SOCKET_head.lock], 0
-
 
781
	ret
-
 
782
 
-
 
783
  .fin:
-
 
784
; Remove all resend entries from the queue
-
 
785
	mov	ecx, TCP_QUEUE_SIZE
-
 
786
	mov	esi, TCP_OUT_QUEUE+4
-
 
787
 
-
 
788
  .removeloop:
-
 
789
	cmp	[esi + tcp_out_queue_entry.data_ptr], 0
-
 
790
	je	.maybe_next
-
 
791
 
-
 
792
	; TODO: check if the packets belong to the same tcp connection !
-
 
793
 
-
 
794
       DEBUGF 1,"Removing a queued packet\n"
-
 
795
 
-
 
796
	push	[esi + tcp_out_queue_entry.data_ptr]
Line 823... Line 797...
823
 
797
	mov	[esi + tcp_out_queue_entry.data_ptr], 0
824
  .ack:
798
	dec	[TCP_OUT_QUEUE]
Line 853... Line 827...
853
    @@: mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSING
827
    @@: mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSING
854
	cmp	al, TH_FIN
828
	cmp	al, TH_FIN
855
	je	@f
829
	je	@f
856
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
830
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT
Line -... Line 831...
-
 
831
 
-
 
832
    @@:
857
 
833
 
858
    @@: lea	esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
834
;        lea     esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
Line 859... Line -...
859
	inc_INET esi
-
 
860
 
835
;        inc_INET esi
861
	mov	[ebx + SOCKET_head.lock], 0
836
 
862
	; Send an ACK
837
	; Send an ACK
-
 
838
	mov	eax, ebx
-
 
839
	mov	bl, TH_ACK
863
	mov	eax, ebx
840
	push	eax
-
 
841
	xor	ecx, ecx
Line 864... Line 842...
864
	mov	bl, TH_ACK
842
	call	TCP_send
865
	call	TCP_send_ack
843
	pop	ebx
866
 
844
 
Line 887... Line 865...
887
	mov	[ebx + SOCKET_head.lock], 0
865
	mov	[ebx + SOCKET_head.lock], 0
Line 888... Line 866...
888
 
866
 
889
	; Send an ACK
867
	; Send an ACK
890
	mov	eax, ebx
868
	mov	eax, ebx
-
 
869
	mov	bl, TH_ACK
-
 
870
	push	eax
891
	mov	bl, TH_ACK
871
	xor	ecx, ecx
-
 
872
	call	TCP_send
Line 892... Line 873...
892
	call	TCP_send_ack
873
	pop	ebx
893
 
874
 
894
  .exit:
875
  .exit: