2014-12-04 24 views
5

Ich versuche, ein TCP-Paket zu analysieren und dann einen Zeiger auf den Start der Nutzlast zuweisen.Parsen eines TCP-Pakets Daten

Ich bin mit C und das ist mein Code so weit:

void dump(const unsigned char *data, int length) { //*data contains the raw packet data 
    unsigned int i; 
    static unsigned long pcount = 0; 

    // Decode Packet Header 
    struct ether_header *eth_header = (struct ether_header *) data; 

    printf("\n\n === PACKET %ld HEADER ===\n", pcount); 

    printf("\nSource MAC: "); 
    for (i = 0; i < 6; ++i) { 
     printf("%02x", eth_header->ether_shost[i]); //? Why don't i use nthos here? 
     if (i < 5) printf(":"); 
    } 

    unsigned short ethernet_type = ntohs(eth_header->ether_type); 
    printf("\nType: %hu\n", ethernet_type); 

    if (ethernet_type == ETHERTYPE_IP) { //IP Header 
     printf("\n == IP HEADER ==\n"); 
     struct ip *ip_hdr = (struct ip*) data + sizeof(struct ether_header); 
     unsigned int size_ip = ip_hdr->ip_hl * 4; 
     printf("\nIP Version: %u", ip_hdr->ip_v); //? Nthos or no nthos 
     printf("\nHeader Length: %u", ip_hdr->ip_hl); //? Nthos or no nthos 
     printf("\nTotal Length: %hu", ntohs(ip_hdr->ip_len)); //? Nthos or no nthos 

     // TCP Header 
     printf("\n== TCP HEADER ==\n"); 
     struct tcphdr *tcp_hdr = (struct tcphdr*) data + sizeof(struct ether_header) + size_ip; 
     printf("\n Source Port: %" PRIu16, nthos(tcp_hdr->th_sport)); 
     printf("\n Destination Port: %" PRIu16, nthos(tcp_hdr->th_dport)); 
     printf("\n fin: %" PRIu16, tcp_hdr->fin); 
     printf("\n urg: %" PRIu16, tcp_hdr->urg); 
     printf("\n ack_seq: %" PRIu32, ntohl(tcp_hdr->ack_seq)); 

     //Transport payload! i.e. rest of the data 
     const unsigned char *payload = data + ETH_HLEN + size_ip + sizeof(struct tcphdr) + tcp_hdr->doff; 

    } 

Ich bin sicher, dass es Fehler in diesem Code ist, weil die Port-Nummern all komisch sind. Nicht eine einzige weist 80 zu. Die ausgegebene Ip-Version kann auch wirklich komisch sein (wie Version 11). Was mache ich falsch? Vielen Dank!

Auch ich bin unsicher wann nthos zu verwenden und wann nicht. Ich weiß nthos ist für 16 Bit unsigned Integer und ich weiß nthol ist für 32 Bit vorzeichenlose Integer, aber ich weiß, dass Sie nicht gemeint sind, sie für alles in diesen Paketen zu verwenden (wie: tcp_hdr-> fin). Warum bestimmte Dinge und nicht sie?

VIELEN DANK!

EDIT:

Dank Art für die meisten f die Probleme zu beheben. Ich habe meine tcp_hdr und ip_hdr bearbeitet, damit die Klammern jetzt korrekt sind!

Ich habe noch zwei Probleme:

  • Die ersten 10 Bytes der Nutzlast seltsame Symbole hat (so denke ich, ich habe nicht die Nutzlast korrekt zugeordnet).
  • Ich bin immer noch unsicher, wann nthos/nthol zu verwenden. Ich weiß, dass u_int16_t ntohs ist und u_int32_t ist ntohl. Aber was ist mit Dingen, die int oder unisgned short int signiert sind. Zum Beispiel habe ich ntohs oder nthol für die ip_v nicht verwendet, damit es funktioniert. Warum nicht? Ist "ip_hdr-> ip_hl" nthol? etc ...

EDIT2

Ich reparierte haben, warum meine Nutzlast nicht korrekt war die Ausgabe (es ist, weil ich die TCP_header Größe falsch berechnet).

Obwohl ich immer noch verwirrt bin, wann nthos zu verwenden, werde ich dies als eine separate Frage stellen, wie ich denke, ich habe zu viele Fragen zu diesem 1 Beitrag gestellt!

When to use ntohs and ntohl in C?

+0

Sie wissen, dass Dinge wie Port-Nummern sind in * Netzwerk * ​​Byte-Reihenfolge? Verwenden Sie 'ntohs', um einen kurzen (16-Bit-) Wert von der Netzwerk-Byte-Reihenfolge in die Host-Byte-Reihenfolge zu konvertieren. –

+0

Ich habe beides versucht aber seltsame Nummern für eiehr bekommen. Code wird jetzt aktualisiert! –

+0

Gibt es andere Felder, die korrekt aussehen? Wie die Quell-/Zieladressen? Der Ethernet-Header? Wie sieht es im Vergleich zu demselben Paket in z.B. Wireshark? Und Sie * erhalten * dies auf einem rohen Sockel? Und erhalten * alle * des Pakets? –

Antwort

5

höchstwahrscheinlich Ihr Problem hier ist:

struct ip *ip_hdr = (struct ip*) data + sizeof(struct ether_header); 
struct tcphdr *tcp_hdr = (struct tcphdr*) data + sizeof(struct ether_header) + size_ip; 

Doing (struct ip*) data + sizeof(struct ether_header) ersten Abgüsse Daten struct ip *, fügt dann sizeof(struct ether_header) es, die wir von Zeiger arithmetics wissen nicht, was Sie es erwarten machen.

Wenn das Problem nach wie vor unklar ist, hier ist ein einfaches Programm, das Sie in der richtigen Richtung zeigen soll:

#include <stdio.h> 

struct foo { 
    int a, b; 
}; 

int 
main(int argc, char **argv) 
{ 
    char *x = NULL; 

    printf("%p\n", x); 
    printf("%p\n", (struct foo *)x + 4); 
    printf("%p\n", (struct foo *)(x + 4)); 

    return 0; 
} 
+0

Das ist behoben wie fast alle meine Probleme. Stört es dich, wenn du auch den zweiten Teil meiner Frage beantwortest, wenn du ntohs benutzen willst. Meine aktuelle Regel, die ich erfunden habe, ist für alles vom Typ u_int16_t ist ntohs und u_int32_t ist ntohl. Aber was ist mit Dingen, die int oder unisgned short int signiert sind. Zum Beispiel habe ich ntohs nicht für die ip_v verwendet, damit es funktioniert. Warum nicht? Danke –

+0

Schauen Sie sich die IP-Header und eine Definition an. Grundregel ist: Sie konvertieren keine Werte, die 1B oder kürzer sind (ip_v, ip_hl). Sie verwenden ntohs für 2B-Werte (ip_len, ip_p). Sie verwenden ntohl für 4B-Werte. "Aber was ist mit Dingen, die int oder unisgned short int signiert sind: Es spielt keine Rolle, ob es signiert ist oder nicht (und ich glaube nicht, dass es signierte Werte in ip hdr gibt), also ist int int nur 4B wert und vorzeichenlose Abkürzung ist 2B-Wert. Sie können den ip-Header hier sehen: http://en.wikipedia.org/wiki/IPv4#Header – davak

+0

so warten Sie "ip_hdr-> ip_hl" verwenden Sie htol dann wie es ist vom Typ "unsigned int ip_hl: 4;" Wenn ich htol hinzugefügt habe, wird das Programm beendet, bevor sogar der TCP-Header gelesen wird (wahrscheinlich bedeutet es das Lesen eines Teils des Speichers, den es nicht tun soll). Aber als ich es ohne Ntohl oder Ntohs verließ, es hat gut funktioniert! –