Eigenes OS - Networking


  • Mod

    Im übrigen verfügt PrettyOS inzwischen über ein rudimentäres Networking Modul.


  • Mod

    DHCP wäre ein möglicher nächster Schritt. 🙂


  • Mod

    Source     Dest        Source     Dest              Packet
       MAC addr   MAC addr    IP addr    IP addr           Description
       -----------------------------------------------------------------
       Client     Broadcast   0.0.0.0    255.255.255.255   DHCP Discover
       DHCPsrvr   Broadcast   DHCPsrvr   255.255.255.255   DHCP Offer
       Client     Broadcast   0.0.0.0    255.255.255.255   DHCP Request
       DHCPsrvr   Broadcast   DHCPsrvr   255.255.255.255   DHCP ACK
    

    So kann DHCP rudimentär ablaufen.


  • Mod

    Ich denke wir sollten diesen Thread nutzen für die Diskussion bezüglich Netzwerk-Code. DHCP Discover gelingt bereits problemlos. Uns fehlt bisher eine Testumgebung, in der ein Server daraufhin DHCP Offer ausführt. Es ist bisher nicht verständlich, warum der LAN-Router bzw. der Qemu-Server das noch nicht leisten, obwohl wir - gemäß wireshark analysiert - sauber anfragen. Uns fehlen Werkzeuge, um den Gesamtvorgang zu analysieren. Wir sehen nur via wireshark die (nicht) gesendeten Pakete aber nicht die Ursachen dafür, z.B. am Server/Router.


  • Mod

    Eine Frage tauchte in einer Diskussion auf: Gehört Netzwerk zu OSDev? Erster Blick in den Tanenbaum zeigt, dass dieses Thema dort (oberflächlich, d.h. weitgehend theoretisch) behandelt wird. Es gibt allerdings eine Menge Bücher über verteilte Betriebssysteme. Netzwerke und Internet als verlängerte Netzwerke spielen heute eine so wesentliche Rolle, dass Treiber für verschiedene Netzwerkkomponenten und für die Netzwerkprotokolle m.E. zu einem user-orientierten OS moderner Ausrichtung dazu gehören. Daher werden wir diese Thematik weiter verfolgen, auch wenn man in OSDev Communities und Foren hierzu wenig Unterstützung erfährt.


  • Mod

    Der klassische DHCP-Ablauf: http://www.henkessoft.de/OS_Dev/Bilder/rev936.PNG

    Dies sind die Momente, die für das "Spec" Lesen und viele Fehlversuche entschädigen. DHCP ist nun weitgehend eingetütet.

    Nun ist das nächste Ziel TCP.


  • Mod

    Hier die Software-Simulation von MrX für die korrekte TCP checksum:
    (Das TCP-Paket stammte aus wireshark)

    Version für MSVC++:

    #include <fstream>
    #include <iostream>
    #include <cstdint>
    
    uint16_t internetChecksum(void* addr, size_t count, uint32_t pseudoHeaderChecksum)
    {
        uint32_t sum  = pseudoHeaderChecksum;
        uint8_t* data = (uint8_t*)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;
    }
    #pragma pack(1)
    typedef struct {
    	uint8_t src[4];
    	uint8_t dest[4];
    	uint8_t res;
    	uint8_t prot;
    	uint16_t length;
    } pseudo_t;
    
    #define htons(v) ((((v) >> 8) & 0xFF) | (((v) & 0xFF) << 8))
    
    uint16_t udptcpCalculateChecksum(void* p, uint16_t length, uint8_t srcIP[4], uint8_t destIP[4], uint16_t protocol)
    {
    	pseudo_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
    }
    
    // Should: 0xf96f
    uint8_t src[4] = {192,168,1,97};
    uint8_t dest[4] = {192,168,1,23};
    int main() 
    {
    	uint8_t packet[] = {00, 0x17, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xb3, 0x0f, 0xc9, 0x50, 0x12, 0xff, 0xff, 0, 0, 0x00, 0x00};
    	uint16_t checksum = udptcpCalculateChecksum(packet, 20, src, dest, 6);
    	printf("%X\n", checksum);
    	system("PAUSE");
    }
    

    Eine übertragene version für code::blocks findet man im Repo.


  • Mod


  • Mod

    Mit dieser Version kann man bereits sehr schön bezüglich TCP experimentieren:
    http://www.c-plusplus.net/forum/p2082954#2082954


  • Mod

    Das erste user-program mit TCP: starwars.elf (thx to MrX) 🙂 👍
    http://www.c-plusplus.net/forum/p2084431?sid=e87c6e3575b25c6a7266509a9b3b2cf8#2084431 🙂

    userlib.h:

    uint32_t tcp_connect(IP_t IP, uint16_t port); 
    void     tcp_send(uint32_t ID, void* data, size_t length);
    void     tcp_close(uint32_t ID);
    

  • Mod

    http://www.henkessoft.de/OS_Dev/OS_Dev4.htm#mozTocId358796

    Eine Zusammenfassung zum Thema Netzwerk im Tutorial, Teil 4.


  • Mod

    Der IRC Client entwickelt sich schon ganz nett. Man müsste die eingehenden "Umlaute und Sonderzeichen" noch für die Bildschirmausgabe übersetzen und alle Eingaben wahlfrei machen.


  • Mod

    Das tcp-Modul schafft ganz schön Aufwand. Momentan fehlt noch der dup-ack Mechanismus und der timer für das Vernichten der Connection aus dem Zustand TIME_WAIT heraus. Wir versuchen, hierfür die todo_list in erweiterter Form einzusetzen.

    Rückblende:
    Wenn man bedenkt, dass das gesamte Internet weitgehend auf dieser Norm rfc 793 aus 1981 basiert, da staunt man schon. Diejenigen, die diese "arpanet" rfc geschrieben haben, wussten das damals nicht, was sie da Wichtiges machen.Alles basiert auf dem engen Ethernet frame von insgesamt 1500 byte, damals ziemlich viel, heute eher wenig. 1981 gab es gerade mal den IBM PC, der noch keine Festplatte sein eigen nannte, sondern lediglich ein oder zwei Floppys kannte. Er wurde ab 1981 fast 6 Jahre lang unverändert gebaut und war der Quasi-Standard schlechthin. Ab 1983 kam der IBM PC XT, 1984 der IBM PC AT (mit Festplatte und 6 MHz CPU). Der "AT" kostete damals über 20000 DM, daran kann ich mich erinnern, selbst für Großfirmen ein stolzer Betrag. 😉

    Auf der anderen Seite werden heute immer noch PCs gebaut mit diesem Prozessortyp x86 und den damit verbundenen lästigen Mechanismen, die noch jeder Pentium-PC (und kompatible) mit sich herum schleppt.


  • Mod

    tcp: dup-ack und Timer für das Vernichten der Connection sind implementiert. Nun gehts bei den Out-of-Order Paketen weiter. 😉


  • Mod

    Code zum Umwandeln von IP-String nach IP_t (von MrX):

    IP_t stringToIP(char* str)
    {
    	IP_t IP;
        for(uint8_t i_start = 0, i_end = 0, byte = 0; byte < 4; i_end++)
        {
            if(str[i_end] == 0)
            {
                IP.IP[byte] = atoi(str+i_start);
                break;
            }
            if(str[i_end] == '.')
            {
                str[i_end] = 0;
                IP.IP[byte] = atoi(str+i_start);
                i_start = i_end+1;
                byte++;
            }
        }
    	return(IP);
    }
    


  • Genau, Fehlerbehandlung wird sowieso überbewertet. Vor allem in einem Kernel. 🙂



  • Ist ja nicht im Kernel 😉



  • Ach so, dann ist das natürlich in Ordnung. 😉


  • Mod

    taljeth: kannst du auch einen konstruktiven Beitrag leisten?



  • Wenn es dir nicht konstruktiv genug ist, auf Schwachpunkt in gepostetem Code hinzuweisen, dann tut es mir leid. Vermutlich kann ich es dann nicht.


Anmelden zum Antworten