Rev 1274 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1274 | Rev 1281 | ||
---|---|---|---|
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: 1274 $ |
18 | $Revision: 1281 $ |
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 39... | Line 39... | ||
39 | ends |
39 | ends |
Line 40... | Line 40... | ||
40 | 40 | ||
41 | struct tcp_in_queue_entry |
41 | struct tcp_in_queue_entry |
42 | .data_ptr dd ? |
42 | .data_ptr dd ? |
43 | .data_size dd ? |
43 | .data_size dd ? |
44 | .offset dd ? |
44 | .offset dd ? ; TODO: replace this in code by absolute address isntead of relative offset |
45 | .size: |
45 | .size: |
Line 46... | Line 46... | ||
46 | ends |
46 | ends |
47 | 47 | ||
Line 236... | Line 236... | ||
236 | 236 | ||
237 | .remove_it: |
237 | .remove_it: |
238 | push [esi + tcp_out_queue_entry.data_ptr] |
238 | push [esi + tcp_out_queue_entry.data_ptr] |
239 | mov [esi + tcp_out_queue_entry.data_ptr], 0 |
239 | mov [esi + tcp_out_queue_entry.data_ptr], 0 |
- | 240 | call kernel_free |
|
240 | call kernel_free |
241 | dec [TCP_OUT_QUEUE] |
Line 241... | Line 242... | ||
241 | jmp .find_next |
242 | jmp .find_next |
Line 389... | Line 390... | ||
389 | ; |
390 | ; |
390 | ; TCP_send (Assumes socket mutex set) |
391 | ; TCP_send (Assumes socket mutex set) |
391 | ; |
392 | ; |
392 | ; IN: eax = socket pointer |
393 | ; IN: eax = socket pointer |
393 | ; bl = flags |
394 | ; bl = flags |
394 | ; ecx = number of bytes to send, may be set to 0 |
395 | ; ecx = number of bytes to send, may be set to 0 (single ACK) |
395 | ; esi = pointer to data |
396 | ; esi = pointer to data |
396 | ; |
397 | ; |
397 | ;----------------------------------------------------------------- |
398 | ;----------------------------------------------------------------- |
398 | align 4 |
399 | align 4 |
399 | TCP_send: |
400 | TCP_send: |
Line 401... | Line 402... | ||
401 | DEBUGF 1,"Creating TCP packet, socket: %x, flags: %x\n",eax, bl |
402 | DEBUGF 1,"Creating TCP packet, socket: %x, flags: %x\n",eax, bl |
Line 402... | Line 403... | ||
402 | 403 | ||
403 | mov di , IP_PROTO_TCP |
404 | mov di , IP_PROTO_TCP |
Line 404... | Line 405... | ||
404 | add ecx, TCP_Packet.Data |
405 | add ecx, TCP_Packet.Data |
405 | 406 | ||
406 | push bx eax esi |
407 | push ecx bx eax esi |
407 | ; Create an IPv4 Packet of the correct size |
408 | ; Create an IPv4 Packet of the correct size |
Line 408... | Line 409... | ||
408 | mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
409 | mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
Line 434... | Line 435... | ||
434 | pop esi |
435 | pop esi |
Line 435... | Line 436... | ||
435 | 436 | ||
436 | ; fill in tcp sequence number |
437 | ; fill in tcp sequence number |
437 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
438 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
438 | pop [edi + TCP_Packet.SequenceNumber] |
- | |
Line 439... | Line 439... | ||
439 | inc_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT) ;;;;;;;; |
439 | pop [edi + TCP_Packet.SequenceNumber] |
440 | 440 | ||
441 | ; Fill in local and remote ports |
441 | ; Fill in local and remote ports |
Line 452... | Line 452... | ||
452 | mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes |
452 | mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes |
453 | mov [edi + TCP_Packet.UrgentPointer], 0 |
453 | mov [edi + TCP_Packet.UrgentPointer], 0 |
454 | mov [edi + TCP_Packet.DataOffset], 0x50 |
454 | mov [edi + TCP_Packet.DataOffset], 0x50 |
455 | mov [edi + TCP_Packet.Checksum], 0 |
455 | mov [edi + TCP_Packet.Checksum], 0 |
Line -... | Line 456... | ||
- | 456 | ||
- | 457 | ; Get size of total packet back in ecx |
|
456 | 458 | pop ecx |
|
457 | ; Push pointer to and size of total packet (needed for send procedure) |
459 | ; Push pointer to and size of total packet (needed for send procedure) |
458 | push edx eax |
- | |
459 | 460 | push edx eax |
|
460 | ; push socket number (for TCP_add_to_queue) |
461 | ; push socket number (for TCP_add_to_queue) |
Line 461... | Line 462... | ||
461 | push esi |
462 | push esi |
- | 463 | ||
- | 464 | ; Now, calculate the checksum |
|
- | 465 | xchg cl, ch |
|
462 | 466 | pushw cx |
|
463 | ; Now, calculate the checksum ; TODO: calculate correct checksum for packets with data |
467 | xchg cl, ch |
464 | pushw TCP_Packet.Data shl 8 |
468 | ;; pushw TCP_Packet.Data shl 8 |
465 | pushw IP_PROTO_TCP shl 8 |
469 | pushw IP_PROTO_TCP shl 8 |
Line 466... | Line 470... | ||
466 | pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. |
470 | pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. |
467 | pushd [edi-8] ; source address |
471 | pushd [edi-8] ; source address |
468 | 472 | ||
469 | xor edx, edx |
473 | xor edx, edx |
470 | mov ecx, TCP_Packet.Data |
474 | ; mov ecx, TCP_Packet.Data |
471 | mov esi, edi |
475 | mov esi, edi |
472 | call checksum_1 |
476 | call checksum_1 |
473 | mov ecx, 12 |
- | |
474 | mov esi, esp |
477 | mov ecx, 12 |
475 | call checksum_1 |
478 | mov esi, esp |
476 | add esp, 12 ; remove the pseudoheader from stack |
479 | call checksum_1 |
- | 480 | ; and store it in TCP header |
|
Line 477... | Line -... | ||
477 | ; and store it in TCP header |
- | |
478 | call checksum_2 |
481 | call checksum_2 |
479 | mov [edi + TCP_Packet.Checksum], dx |
482 | mov [edi + TCP_Packet.Checksum], dx |
480 | 483 | add esp, 10 ; remove the pseudoheader from stack |
|
481 | ; At last send the packet! |
484 | |
- | 485 | DEBUGF 1,"Sending TCP Packet to device %x\n", ebx |
|
- | 486 | mov edx, [edi + TCP_Packet.SequenceNumber] |
|
482 | DEBUGF 1,"Sending TCP Packet to device %x\n", ebx |
487 | bswap edx |
- | 488 | mov esi, [ebx + ETH_DEVICE.transmit] |
|
- | 489 | ||
- | 490 | pop cx ; get the length from packet, back from pseudoheader |
|
- | 491 | pop edi |
|
- | 492 | ||
- | 493 | cmp cx, TCP_Packet.Data shl 8 ; if the packet has no data |
|
- | 494 | je .only_one ; send it only once |
|
- | 495 | ||
- | 496 | and ecx, 0x0000ffff |
|
- | 497 | xchg cl, ch |
|
- | 498 | sub cx, TCP_Packet.Data |
|
483 | mov edx, [edi + TCP_Packet.SequenceNumber] |
499 | add_INET (edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT) |
- | 500 | ||
- | 501 | mov ecx, TCP_RETRIES |
|
- | 502 | ||
- | 503 | jmp .go_for_it |
|
- | 504 | ||
- | 505 | .only_one: |
|
- | 506 | ; inc_INET (edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT) |
|
- | 507 | mov ecx, 1 |
|
Line 484... | Line 508... | ||
484 | bswap edx |
508 | .go_for_it: |
485 | mov esi, [ebx + ETH_DEVICE.transmit] |
509 | |
486 | pop edi |
510 | mov [edi + SOCKET_head.lock], 0 |
487 | jmp TCP_queue |
511 | jmp TCP_queue ; At last send the packet! |
Line 500... | Line 524... | ||
500 | ; [esp + 4] size of buffer |
524 | ; [esp + 4] size of buffer |
501 | ; ebx = driver struct |
525 | ; ebx = driver struct |
502 | ; esi = sender proc |
526 | ; esi = sender proc |
503 | ; edx = sequence number of this packet in normal byte order |
527 | ; edx = sequence number of this packet in normal byte order |
504 | ; edi = socket number |
528 | ; edi = socket number |
- | 529 | ; ecx = retries |
|
505 | ; OUT: / |
530 | ; OUT: / |
506 | ; |
531 | ; |
507 | ;----------------------------------------------------------------- |
532 | ;----------------------------------------------------------------- |
508 | align 4 |
533 | align 4 |
509 | TCP_queue: |
534 | TCP_queue: |
Line 513... | Line 538... | ||
513 | bswap edx |
538 | bswap edx |
Line 514... | Line 539... | ||
514 | 539 | ||
515 | cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE |
540 | cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE |
Line -... | Line 541... | ||
- | 541 | jge .full |
|
516 | jge .full |
542 | |
517 | 543 | push ecx |
|
Line 518... | Line 544... | ||
518 | mov ecx, TCP_QUEUE_SIZE |
544 | mov ecx, TCP_QUEUE_SIZE |
519 | mov eax, TCP_OUT_QUEUE+4 |
545 | mov eax, TCP_OUT_QUEUE+4 |
Line 525... | Line 551... | ||
525 | loop .loop |
551 | loop .loop |
Line 526... | Line 552... | ||
526 | 552 | ||
527 | .full: ; silently discard the packet |
553 | .full: ; silently discard the packet |
Line -... | Line 554... | ||
- | 554 | DEBUGF 1,"TCP queue is full!\n" |
|
528 | DEBUGF 1,"TCP queue is full!\n" |
555 | |
529 | 556 | add esp, 4 |
|
Line 530... | Line 557... | ||
530 | call kernel_free |
557 | call kernel_free |
Line 531... | Line 558... | ||
531 | add esp, 4 |
558 | add esp, 4 |
Line -... | Line 559... | ||
- | 559 | ||
532 | 560 | ret |
|
533 | ret |
561 | |
534 | 562 | .found_it: ; eax points to empty queue entry |
|
535 | .found_it: ; eax points to empty queue entry |
- | |
536 | 563 | ||
537 | pop [eax + tcp_out_queue_entry.data_ptr] |
564 | pop [eax + tcp_out_queue_entry.retries] |
538 | pop [eax + tcp_out_queue_entry.data_size] |
565 | pop [eax + tcp_out_queue_entry.data_ptr] |
539 | mov [eax + tcp_out_queue_entry.ttl], 1 ; send immediately |
566 | pop [eax + tcp_out_queue_entry.data_size] |
Line 722... | Line 749... | ||
722 | bswap eax |
749 | bswap eax |
723 | cmp eax, [edx + TCP_Packet.SequenceNumber] |
750 | cmp eax, [edx + TCP_Packet.SequenceNumber] |
724 | jne .exit |
751 | jne .exit |
Line 725... | Line 752... | ||
725 | 752 | ||
726 | ; Calculate next sequencenumber |
753 | ; Calculate next sequencenumber |
727 | test ecx, ecx |
754 | ;; test ecx, ecx |
728 | jnz @f |
755 | ;; jnz @f |
729 | inc ecx |
756 | ;; inc ecx |
730 | @@: |
757 | ;; @@: |
Line 731... | Line 758... | ||
731 | add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT) |
758 | add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT) |
732 | 759 | ||
Line 733... | Line 760... | ||
733 | test [edx + TCP_Packet.Flags], TH_FIN |
760 | test [edx + TCP_Packet.Flags], TH_FIN + TH_RST ;;; |
734 | jnz .fin |
761 | jnz .fin |
735 | 762 | ||
Line 750... | Line 777... | ||
750 | @@: |
777 | @@: |
751 | pop ecx |
778 | pop ecx |
Line 752... | Line 779... | ||
752 | 779 | ||
753 | ; Now, see if we received any data |
780 | ; Now, see if we received any data |
754 | test ecx, ecx |
781 | test ecx, ecx |
Line 755... | Line 782... | ||
755 | jz .ack |
782 | jz .exit |
756 | 783 | ||
757 | DEBUGF 1,"Got %u bytes data!\n", ecx |
784 | DEBUGF 1,"Got %u bytes data!\n", ecx |
758 | ; calculate header length |
785 | ; calculate header length |
759 | movzx eax, [edx + TCP_Packet.DataOffset] |
786 | movzx eax, [edx + TCP_Packet.DataOffset] |
760 | and eax, 11110000b |
787 | and eax, 11110000b |
761 | shr eax, 2 |
788 | shr eax, 2 |
- | 789 | DEBUGF 1,"TCP header size: %u\n", eax |
|
762 | DEBUGF 1,"TCP header size: %u\n", eax |
790 | add edx, eax ; now edx points to data |
763 | add edx, eax |
791 | |
764 | add esp, 4 |
792 | add esp, 4 |
- | 793 | pop esi ; pointer to buffer |
|
765 | pop esi |
794 | add esp, 4 |
766 | add esp, 4 |
795 | |
767 | sub edx, esi |
796 | sub edx, esi |
- | 797 | mov edi, edx ; offset |
|
768 | mov edi, edx |
798 | mov eax, ebx ; socket ptr |
- | 799 | ||
- | 800 | call socket_internal_receiver ; Place the data from packet into socket |
|
- | 801 | ||
- | 802 | lea ebx, [eax + SOCKET_head.lock] ;;;;; |
|
Line 769... | Line 803... | ||
769 | mov eax, ebx |
803 | call wait_mutex ;;;;; |
770 | jmp socket_internal_receiver ; Place the data from packet into socket |
804 | mov ebx, eax ;;;; |
771 | 805 | ||
772 | .ack: |
806 | .ack: |