Sourcecode Fortschritt



  • Version 0.0.2.93:

    - Initialisierungsreihenfolge verbessert: U.a. wird Video früher installiert (-> je eher, desto besser. Ermöglicht frühere Debugausgaben).
    - printf unterstützt nun %M und %I für die Ausgabe von IP und MAC Adressen. Angewendet im Netzwerkcode
    - Strg+A resultiert nicht mehr in #PF, wenn keine Netzwerkkarte vorhanden ist
    - Code aufgeräumt



  • Version 0.0.2.94:

    - Analyse der DHCP-Option-Bytes vereinfacht
    - c/s/vs/v/printf geben nun Anzahl geschriebener Zeichen zurück
    - i2Hex (und damit auch c/s/vs/v/printf) gibt kein h mehr am Ende hexadezimaler Zahlen aus
    - Ausgabe der ARP-Tabelle verbessert


  • Mod

    version = "0.0.2.95 - Rev: 934"

    SIP ersatzlos gestrichen

    Problem: Zusammenhang netzwork adapter und IP geht verloren


  • Mod

    version = "0.0.2.96 - Rev: 935"

    Fehler bei ACK auf DHCP_Inform korrigiert. Your IP (dhcp->yiaddr) wird nur übernommen, wenn ungleich 0.0.0.0:

    static void useDHCP_IP(network_adapter_t* adapter, dhcp_t* dhcp)
    {
        if (dhcp->yiaddr[0] || dhcp->yiaddr[1] || dhcp->yiaddr[2] || dhcp->yiaddr[3])
        {
            for(uint8_t i = 0; i < 4; i++)
                adapter->IP_address[i] = dhcp->yiaddr[i];
        }
    }
    

  • Mod

    version = "0.0.2.97 - Rev: 936"

    Endlich habe ich einen Trick gefunden, wie man auch die Antworten des DHCP-Servers in wireshark von einem anderen PC im LAN beobachten kann. Man muss bei den Anfragen die Forderung stellen, dass die Antwort an alle (BROADCAST) gesendet wird.

    Beweis-Foto: http://www.henkessoft.de/OS_Dev/Bilder/rev936.PNG 👍

    Nachdem dieser Ablauf nun eindeutig demonstriert werden konnte, bitte ich um Reproduktion auch an anderer Stelle. 😉



  • Version 0.0.2.98:

    - Unterstützung von Parametern beim Programmstart
    - Hello-Userprogramm zeigt übergebene Parameter an
    - Verbessertes makefile für other_userprogs


  • Mod

    Tests von Cuervo mit der vorhergehenden Vesrion:

    - DHCP_Release funktioniert. Wenn der DHCP-Server will, wird es als abgelaufen angezeigt
    - Wir müssen das Angebot aus OFFER verwenden für REQUEST anstelle der konstanten RIP (das kann der Server anders sehen ^^) aus network.h
    - HOST NAME angeben bei den options

    Fotos (Cuervo): http://prettyos.fanofblitzbasic.de/PrettyNWPics.zip

    MrX: deine Version produziert einen #PF F000EF6F eip: 115391

    ckernel.c: shell auskommentiert, "executeFile("1:/ttt.ELF", 0, 0); // TEST" eingefügt, klappt bestens. Bitte in Ordnung bringen.


  • Mod

    version = "0.0.2.99 - Rev: 938"

    shell auskommentiert, ttt wird testweise ausgeführt.

    Netzwerk: Hostname "PrettyOS" eingeführt bei DHCP, DHCP_Request übernimmt IP aus DHCP_Offer.



  • Version 0.0.2.100:

    - cpu.c: Es wird überprüft, ob cpuid unterstützt wird; Funktionen zum Lesen und Schreiben des MSR implementiert
    - memory.txt geupdated und erweitert
    - Bugfix/Hack: Shell nimmt nun argv/argc-Parameter beim Start
    - Projektmappen: Verbesserte Intellisense-Kompatibilität durch Dummy-Header VCcompatibility.h und verbesserte Includepfad-Einstellungen



  • Version 0.0.2.101:

    - Neuer Bugfix-Versuch. argc/argv nun via user stack übergeben.


  • Mod

    Bitte darauf achten, dass bei den cross-tools die enthaltenen binutils, darunter auch ld.exe nicht mehr zu einem lauffähigen produkt führen (#PF).

    MrX wird demnächst ein neues bundle für die crosstools hochladen. ⚠

    http://kloke-witten.dyndns.org/~philipp/bin.zip <--- wenn es eilt



  • Version 0.0.2.102:

    - Parameterübergabe wieder über eax/ecx
    - Fehlerbehandlung im Floppytreiber verbessert
    - Konsolen überarbeitet (Stabilität, Code vereinfacht)


  • Mod

    version = "0.0.2.103 - Rev: 942"

    TCP weiter ausgebaut:
    - Senden klappt
    - Checksum (UDP, TCP) bewirkt #PF
    - 3-way-handshake: SYN kann bereits mit SYN ACK beantwortet werden


  • Mod

    version = "0.0.2.105 - Rev: 944" (beim nächsten Mal bitte stehen lassen, wurde offenbar eine übersprungen)

    checksum für UDP: 0 (wegen DHCP)
    checksum für TCP: aktiviert, wireshark validiert diese aber als "incorrect" ⚠

    Checksum: 0x7754 [incorrect, should be 0xba47 (maybe caused by "TCP checksum offload"?)]
    

  • Mod

    version = "0.0.2.105 - Rev: 944"

    Parameter "protocol" ergänzt:
    uint16_t udptcpCalculateChecksum(void* p, size_t length, uint8_t sourceIp[4], uint8_t destinationIp[4], uint16_t protocol)

    Checksum falsch.


  • Mod

    version = "0.0.2.106 - Rev: 945"

    - TCP-Checksum noch nicht korrekt
    - internetChecksum (Fkt. wird bereits bei ip und icmp eingesetzt) mit verwendet


  • Mod

    version = "0.0.2.107 - Rev: 946"

    - tcp checksum noch nicht korrekt, aber schon nahe dran ^^


  • Mod

    version = "0.0.2.108 - Rev: 947"

    - tcp checksum noch falsch
    - pseudoheader byteweise aufgebaut für besseren Überblick

    uint16_t udptcpCalculateChecksum(void* p, uint16_t length, uint8_t srcIP[4], uint8_t destIP[4], uint16_t protocol)
    {
        uint32_t pseudoHeaderChecksum = 0;
        uint8_t  header[12]; // Pseudo header
        uint8_t* data = header;
        uint8_t  count = 12; // pseudo header contains 12 byte
    
        for (uint8_t i=0; i<4; i++)
        {
            header[i] = srcIP[i];
        }
        for (uint8_t i=4; i<8; i++)
        {
            header[i] = destIP[i-4];
        }
    
        header[8]  = 0;
        header[9]  = protocol;
        header[10] = length & 0xFF;
        header[11] = (length >> 8) & 0xFF;
    
        while (count > 1)
        {
            // pseudo header contains 6 WORD
            pseudoHeaderChecksum += (data[0] << 8) | data[1]; // Big Endian
            data   += 2;
            count  -= 2;
        }
    
        return internetChecksum(p, length, pseudoHeaderChecksum); // util.c
    }
    
    // compute internet checksum for "count" bytes beginning at location "addr"
    uint16_t internetChecksum(void* addr, size_t count, uint32_t pseudoHeaderChecksum)
    {
        uint32_t sum  = pseudoHeaderChecksum;
        uint8_t* data = addr;
    
        while (count > 1) // inner loop
        {
            sum   += (data[0] << 8) | data[1]; // Big Endian
            data  += 2;
            count -= 2;
        }
    
        if (count > 0) // add left-over byte, if any
        {
            sum += data[0] << 8;
        }
    
        while (sum >> 16) // fold 32-bit sum to 16 bits
        {
            sum = (sum & 0xFFFF) + (sum >> 16);
        }
    
        return ~sum & 0xFFFF;
    }
    
    void tcpSend(network_adapter_t* adapter, void* data, uint32_t length, uint16_t srcPort, uint8_t srcIP[4], uint16_t destPort, uint8_t destIP[4], tcpFlags flags, uint32_t seqNumber, uint32_t ackNumber)
    {
    //...
        packet->checksum = 0; // for checksum calculation
        packet->checksum = htons(udptcpCalculateChecksum((void*)packet, length + sizeof(tcpPacket_t), srcIP, destIP, 6));
    
        ipv4_send(adapter, packet, length + sizeof(tcpPacket_t), destIP, 6);
    //...
    }
    

    Wenn man header[8] ... [11] dreht, wird die differenz kleiner.

    Hier ein Hexpaket:

    0013d41127a50010a70f0a0c0800450000280000400080067707c0a80161c0a8011700170607000000001cb30fc95012fffff3750000000000000000
    Checksum: 0xf375 [incorrect, should be 0xf96f (maybe caused by "TCP checksum offload"?)]

    Hex-Code:
    IP-Paket: 450000280000400080067707c0a80161c0a80117
    TCP-Paket: 00170607000000001cb30fc95012fffff3750000

    Internet Protocol Version 4, Src: 192.168.1.97 (192.168.1.97), Dst: 192.168.1.23 (192.168.1.23)

    Transmission Control Protocol, Src Port: telnet (23), Dst Port: simba-cs (1543), Seq: 0, Ack: 1, Len: 0
    (Len ist hier die Datenlänge)

    chat:
    <ehenkes>TCP-Paket: 00170607000000001cb30fc95012fffff3750000
    <ehenkes>Src: 192.168.1.97 (192.168.1.97), Dst: 192.168.1.23 (192.168.1.23)
    <ehenkes>raus kommen muss: 0xf96f
    <ehenkes>daten gibts keine, reiner header
    <ehenkes>udptcpCalculateChecksum(void* p, uint16_t length, uint8_t srcIP[4], uint8_t destIP[4], uint16_t protocol)
    <ehenkes>p zeigt auf den tcp-header
    <ehenkes>length = sizeof(tcp_header)
    <ehenkes>IPs sind klar
    <ehenkes>MrX: gut so?
    <MrX>ja
    <ehenkes>Header length: 20 bytes
    <ehenkes>des TCP headers
    

    Weitere Pakete: (IPs gleich)

    <ehenkes>0017062800000000c56a32495012ffff007827a5    Checksum: 0x0078 [incorrect, should be 0x0672 (maybe caused by "TCP checksum offload"?)]
    
    <ehenkes>0017062900000000591dc44a5012fffffc630604  Checksum: 0xfc63 [incorrect, should be 0x025e (maybe caused by "TCP checksum offload"?)]
    

    erzeugt mit:

    header[11]  = 0;
        header[10]  = protocol;
        header[9]   = length & 0xFF;
        header[8]   = (length >> 8) & 0xFF;
    

    Nach Simulation:
    <MrX>Übrigens weiß ich, wie Du deine Variante lauffähig kriegst.

    header[8]  = 0;
    header[9]  = protocol;
    header[11] = length & 0xFF;
    header[10] = (length >> 8) & 0xFF;
    

  • Mod

    version = "0.0.2.109 - Rev: 948"

    MEILENSTEIN: http://www.c-plusplus.net/forum/p2078201#2078201
    Erfolg! (thx to Mrx for simulating TCP checksum) 🙂 👍

    tcp.h:

    typedef struct 
    {
            uint8_t src[4];
            uint8_t dest[4];
            uint8_t res;
            uint8_t prot;
            uint16_t length;
    } __attribute__((packed)) tcpPseudoHeader_t;
    

    network.c:

    uint16_t udptcpCalculateChecksum(void* p, uint16_t length, uint8_t srcIP[4], uint8_t destIP[4], uint16_t protocol)
    {
        tcpPseudoHeader_t pseudo;
        for (uint8_t i=0; i<4; i++)
        {
            pseudo.src[i] = srcIP[i];
            pseudo.dest[i] = destIP[i];
        }
        pseudo.length = htons(length);
        pseudo.prot = protocol;
        pseudo.res = 0;
    
        uint32_t pseudoHeaderChecksum = 0;
        uint8_t  count = 12; // pseudo header contains 12 byte
    
        uint8_t* data = (uint8_t*)&pseudo;   
    
        while (count > 1)
        {
            // pseudo header contains 6 WORD
            pseudoHeaderChecksum += (data[0] << 8) | data[1]; // Big Endian
            data   += 2;
            count  -= 2;
        }
    
        return internetChecksum(p, length, pseudoHeaderChecksum); // util.c
    }
    

    ... und schon geht der Weg zum ESTABLISHED:

    12 14.042894 192.168.1.23 192.168.1.97 TCP 62 shockwave > telnet [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1
    13 14.052667 192.168.1.97 192.168.1.23 TCP 60 telnet > shockwave [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0
    14 14.052691 192.168.1.23 192.168.1.97 TCP 54 shockwave > telnet [ACK] Seq=1 Ack=1 Win=65535 Len=0

    ➡ syn - syn ack - ack (TCP 3-way-handshake) 👍

    Mit dieser Version kann man erste versuche bei TCP/IP unternehmen, z.B. TELNET nutzen: http://www.henkessoft.de/OS_Dev/Bilder/rev.948_TCP_TELNET.PNG

    http://www.manpagez.com/man/1/telnet/ <--- Kommandos


  • Mod

    rev. 949:

    TCP weiter ausgebaut, vor allem werden nun die Transition States angezeigt:
    (CLOSED -->) LISTEN --> SYN_RECEIVED --> ESTABLISHED

    Length: 66 Rcv: 00-10-A7-0F-0A-0C  Transm.: 00-13-D4-11-27-A5                   
    Ethernet 2. Prot. type: IP.  IP version: 4, IP Header Length: 20 byte           
    TCP: src port: 1232  dest port: 23 URG: 0 ACK: 0 PSH: 0 RST: 0 SYN: 1 FIN: 0    
    TCP prev. state: CLOSED                                                         
    TCP set from CLOSED to LISTEN.                                                  
    TCP curr. state: LISTEN                                                         
    
    Length: 66 Rcv: 00-10-A7-0F-0A-0C  Transm.: 00-13-D4-11-27-A5                   
    Ethernet 2. Prot. type: IP.  IP version: 4, IP Header Length: 20 byte           
    TCP: src port: 1232  dest port: 23 URG: 0 ACK: 0 PSH: 0 RST: 0 SYN: 1 FIN: 0    
    TCP prev. state: LISTEN                                                         
    
    EthernetSend: length: 54.                                                       
    
    >>> Transmission starts <<<                                                     
    Physical Address of Tx Buffer = 014051D8h                                       
    packet sent.                                                                    
    TCP curr. state: SYN_RECEIVED                                                   
    
    Length: 64 Rcv: 00-10-A7-0F-0A-0C  Transm.: 00-13-D4-11-27-A5                   
    Ethernet 2. Prot. type: IP.  IP version: 4, IP Header Length: 20 byte           
    TCP: src port: 1232  dest port: 23 URG: 0 ACK: 1 PSH: 0 RST: 0 SYN: 0 FIN: 0    
    TCP prev. state: SYN_RECEIVED                                                   
    TCP curr. state: ESTABLISHED
    

    Da wir mit CLOSED starten und noch keine sockets bauen, müssen wir den Übergang zu LISTEN noch etwas künstlich durchführen:

    void tcpListen(network_adapter_t* adapter)
    {
        adapter->TCP_PrevState = adapter->TCP_CurrState;
        adapter->TCP_CurrState = LISTEN;
    
        // TODO: more action needed?
    }
    
    Erst ab dort geht es geregelt weiter:
    
    [cpp]if (tcp->SYN && !tcp->ACK) // SYN
        {
            adapter->TCP_PrevState = adapter->TCP_CurrState;
            if (adapter->TCP_CurrState == CLOSED)
            {   
                printf("TCP set from CLOSED to LISTEN.\n");
                tcpListen(adapter);
            }
            else if (adapter->TCP_CurrState == LISTEN)
            {
                tcpSend(adapter, 0, 0, htons(tcp->destPort), adapter->IP_address, htons(tcp->sourcePort), transmittingIP, SYN_ACK_FLAG, 0 /*seqNumber*/ , tcp->sequenceNumber+htonl(1) /*ackNumber*/);
                adapter->TCP_CurrState = SYN_RECEIVED;
            }
    //...
    

    telnet baut zumindest einen "Kontakt" zu uns auf, erwartet aber wohl mehr von seinem "Server" als nur einen 3-way-handshake:

    Microsoft Telnet> open 192.168.1.97
    Verbindungsaufbau zu 192.168.1.97...
    

Anmelden zum Antworten