Raw Socket TCP



  • Hallo,
    ich bin gerade dabei mir einen TCP/IP-Stack zu schreiben und bin auf ein interessantes Problem bei TCP gestoßen. Mit folgendem Code baue ich meinen Header zusammen.

    int TCP_Open(unsigned char *dstAddr, uint16_t srcPort, uint16_t dstPort){
        TCPEntry e;
        uCopy(dstAddr,e.dstIP,4);
        e.srcPort = srcPort;
        e.dstPort = dstPort;
        e.status = INIT1;
        e.seq = rand() & 0xFF;
        e.seq |= ((rand() << 8) & 0xFF00);
        e.ack = 0;
        unsigned int i=0;
        for(;i<sizeof(tcpTable) / sizeof(TCPEntry);i++){
            if(tcpTable[i].seq == 0){
                tcpTable[i] = e;
                break;
            }
        }
        TCP_Packet(i,0,0,TCP_SYN);	//Erstes SYN senden
        return i;
    }
    
    void TCP_Packet(int tcpID,unsigned char *data, int count, char controll){
        if(tcpID < 0)
            return;
        TCPEntry tcp = tcpTable[tcpID];
        unsigned char *bufOfAll = alloca(count + 20 + 12);
        //Pseudo-Header
        uCopy(myAddr,bufOfAll,4);
        uCopy(tcp.dstIP,bufOfAll+4,4);
        //Reserved
        bufOfAll[8] = 0;
        //Protocoll
        bufOfAll[9] = 0x06;
        //Length
        bufOfAll[10] = ((count + 20) >> 8) & 0xFF;
        bufOfAll[11] = (count + 20) & 0xFF;
        unsigned char *buf = bufOfAll + 12;
        //SrcPort
        buf[0] = (tcp.srcPort >> 8 ) & 0xFF;
        buf[1] = tcp.srcPort & 0xFF;
        //DstPort
        buf[2] = (tcp.dstPort >> 8 ) & 0xFF;
        buf[3] = tcp.dstPort & 0xFF;
        //Seq
        buf[4] = (tcp.seq >> 24) & 0xFF;
        buf[5] = (tcp.seq >> 16) & 0xFF;
        buf[6] = (tcp.seq >> 8) & 0xFF;
        buf[7] = tcp.seq & 0xFF;
        //Ack
        buf[8] = (tcp.ack >> 24) & 0xFF;
        buf[9] = (tcp.ack >> 16) & 0xFF;
        buf[10] = (tcp.ack >> 8) & 0xFF;
        buf[11] = tcp.ack & 0xFF;
        //data offset | reserved | controll
        uint16_t tmp = (5 << 12) | controll;
        buf[12] = (tmp >> 8) & 0xFF;
        buf[13] = tmp & 0xFF;
        //window
        buf[14] = 0;
        buf[15] = 0xFF;
        //Checksumme
        buf[16] = 0;
        buf[17] = 0;
        //Urgent Pointer
        buf[18] = 0;
        buf[19] = 0;
        uCopy(data,buf+20,count);
        uint16_t sum = calcChecksum(bufOfAll,count+20+12);
        buf[16] = (sum >> 8) & 0xFF;
        buf[17] = sum & 0xFF;
        IP_Packet(tcp.dstIP,buf,count+20,0x06);
    }
    

    Wenn ich mir den Verbindungsaufbau mit Wireshark anschaue wird im TCP-Packet kein Fehler angezeigt aber der Server-PC sendet keine SYN/ACK-Antwort und ich kann mir nicht erklären wieso.
    Das ganze ist übrigenz für einen Mikrocontroller.
    Schaut mal drauf und wenn ihr einen Fehler findet wäre ich dankbar.

    Mit freundlichen Grüßen
    BS++

    PS.: Das ganze Projekt gibts unter https://github.com/CodeOnSunday/AVR-Ethernet



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum C (C89 und C99) in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • vielleicht waere es schlau das gesendete paket mal zu zeigen. da findet sich der fehler bestimmt leichter.



  • ein problem was ich mit Raw IP packets hatte war am ende, dass mein PC die SYN/ACK packete abfing. vielleicht hast du dasselbe problem.



  • Hier der Hexdump von meinem SYN-Packet, aufgezeichnet mit Wireshark. Die IP-Schicht funktioniert da ich UDP schon ohne Probleme am laufen habe. Das Hauptproblem ist das ich nicht herrausfinde was am TCP-Header dazu führt das das Packet ignoriert wird.

    Ich verwende beim Verbindungsaufbau übrigenz keine Optionsfelder da diese laut meinen Recherchen optional sind.

    0000   1c af f7 01 35 a6 f8 36 17 3a 26 f0 08 00 45 00  ....5..6.:&...E.
    0010   00 28 d9 2a 40 00 ff 06 21 1b c0 a8 00 2a c0 a8  .(.*@...!....*..
    0020   00 0f 30 3a 00 50 00 00 f1 a7 00 00 00 00 50 02  ..0:.P........P.
    0030   00 ff bc 89 00 00 00 00 00 00 00 00              ............
    


  • Ich habe grade gefunden das wohl meine Checksumme nicht stimmt.
    Berechnet wird Sie wie folgt.

    uint16_t calcChecksum(unsigned char *data,int count){
    uint32_t sum = 0;
    for(unsigned int i=0;i<count/2;i++){
    sum += (((uint32_t)data[2*i] << 8) & 0xFF00) | ((uint32_t)data[2*i+1] & 0xFF);
    }
    if(count % 2 == 1)
    sum += (((uint32_t)data[count-1] << 8) & 0xFF00);
    sum += (sum >> 16) & 0xFF;
    return (~sum) & 0xFFFF;
    }
    

Anmelden zum Antworten