Subversion Repositories Kolibri OS

Rev

Rev 1257 | Go to most recent revision | Show entire file | Regard 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 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 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
Line 796... Line 748...
796
	ja	@f
748
	ja	@f
797
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1
749
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1
798
      @@:
750
      @@:
799
	pop	ecx
751
	pop	ecx
Line -... Line 752...
-
 
752
 
800
 
753
; Now, see if we received any data
801
	test	ecx, ecx
-
 
802
	jnz	.data			   ; Read data, if any
-
 
803
 
-
 
804
	lea	esi, [ebx +  SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
754
	test	ecx, ecx
Line -... Line 755...
-
 
755
	jz	.ack
805
	inc_INET esi
756
 
806
 
757
	DEBUGF	1,"Got %u bytes data!\n", ecx
807
	; If we had received a fin, we need to ACK it.
758
; calculate header length
808
	cmp	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT
759
	movzx	eax, [edx + TCP_Packet.DataOffset]
809
	je	.ack
-
 
-
 
760
	and	eax, 11110000b
810
	jmp	.exit
761
	shr	eax, 2
811
 
762
       DEBUGF 1,"TCP header size: %u\n", eax
812
  .data:
-
 
813
	     ;;;
763
	add	edx, eax
814
	lea	esi, [ebx +  SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
-
 
815
	add_INET esi
-
 
816
 
764
	add	esp, 4
817
	DEBUGF	1,"Got data!\n"
765
	pop	esi
818
	mov	esi, [esp + 4]
766
	add	esp, 4
819
	sub	edx, esi
767
	sub	edx, esi
820
	mov	edi, edx
768
	mov	edi, edx
Line 821... Line 769...
821
	mov	eax, ebx
769
	mov	eax, ebx
822
	call	socket_internal_receiver
-
 
823
 
-
 
824
  .ack:
770
	jmp	socket_internal_receiver	; Place the data from packet into socket
825
	mov	[ebx + SOCKET_head.lock], 0
771
 
-
 
772
  .ack:
-
 
773
	mov	eax, ebx
826
	; Send an ACK
774
	mov	bl, TH_ACK
-
 
775
	push	eax
827
	mov	eax, ebx
776
	xor	ecx, ecx
828
	mov	bl, TH_ACK
-
 
829
	call	TCP_send_ack
777
	call	TCP_send		    ; send the ack
830
  .exit:
778
	pop	ebx
Line -... Line 779...
-
 
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]
-
 
797
	mov	[esi + tcp_out_queue_entry.data_ptr], 0
-
 
798
	dec	[TCP_OUT_QUEUE]
-
 
799
	call	kernel_free
-
 
800
 
-
 
801
  .maybe_next:
-
 
802
	add	esi, tcp_out_queue_entry.size
-
 
803
	loop	.removeloop
-
 
804
 
Line 831... Line 805...
831
 
805
; Send an ACK to that fin, and enter closewait state
832
	mov	[ebx + SOCKET_head.lock], 0
806
	mov	[ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT
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: