2010-11-19 10 views
1

Ich habe einige Probleme mit der Analyse der DNS-Antwort. Folgendes ist mein Code. Das Folgende sind die Strukturen. Ich erhalte einen Segmentierungsfehler in printf(), wo ich versuche, QNAME zu drucken.DNS-Antwort analysieren

Ich bin ziemlich amateur, wenn es um C-Programmierung geht, also bin ich nicht wirklich sicher, wo es falsch geht. Jede Hilfe/Hinweise oder Link zu nützlichen Ressourcen/Tutorials, wird geschätzt. Die Funktion verfify_header() funktioniert korrekt. Ich bin mir nicht sicher, warum HEADER mit memcpy() richtig extrahiert wird. und andere Felder sind nicht.

struct HEADER{  
    unsigned short ID;  
    unsigned char RD:1;  
    unsigned char TC:1;  
    unsigned char AA:1;  
    unsigned char Opcode:4;  
    unsigned char QR:1;  
    unsigned char RCODE:4;  
    unsigned char Z:3;  
    unsigned char RA:1;  
    unsigned short QDCOUNT;  
    unsigned short ANCOUNT;  
    unsigned short NSCOUNT;  
    unsigned short ARCOUNT;  
}; 

struct REQ_DATA{ 
unsigned short qtype; 
unsigned short qclass; 
}; 

struct QUESTION{ 
    char* qname; 
    struct REQ_DATA field; 
}; 

struct RES_DATA{  
    unsigned short type;  
    unsigned short class;  
    unsigned int ttl;  
    unsigned short rdlength;  
}; 

struct RESPONSE{ 
    char* name;  
    struct RES_DATA field;  
    char* rdata;  
}; 

Das folgende ist die Funktion, die die DNS-Antwort analysiert.

void parse_response(char *recvbuf, struct result *res)  
{ 
    struct HEADER *rechd = (struct HEADER*) malloc(sizeof(struct HEADER));  
    struct QUESTION qst;  
    struct RESPONSE *rp = (struct RESPONSE*) malloc(sizeof(struct RESPONSE));  
    struct RES_DATA fld; 

    char* rname = (char*)malloc(sizeof(char));  
    int hlen,qlen,rlen; 
    hlen = sizeof(struct HEADER); 

    memcpy(rechd,recvbuf,hlen); 

    verify_header(rechd); //This function works correctly 
    qlen = sizeof(struct QUESTION); 

    //RESPONSE is after QUESTION and HEADER 
    rlen = sizeof(struct RESPONSE); 

    int length = hlen + qlen; 
    rp = (struct RESPONSE*)(recvbuf + length); 
//memcpy(rp, recbbuf + length, sizeof(struct RESPONSE)); 

    memcpy(rname, rp, strlen(rname) + 1); 

    printf("QNAME: %s\n", *rname); //Segmentation Fault occurs over here!!!!! 

} 

Danke, Chander

+1

Sie brauchen nicht die * on * rname –

+0

Ich bekomme einen NULL-Wert. Auch habe ich versucht, mit memove(), wo immer ich mit memcpy, aber immer noch das gleiche Ergebnis –

Antwort

2

Das Problem ist, dass Sie versuchen, C-Strukturen zu verwenden, um Daten zu analysieren, aus über das Netzwerk. Wenn Ihre Maschine Big Endian ist und Ihr Compiler Bitfelder so sortiert, wie Sie es wollen, funktioniert das vielleicht in Ordnung (bis Sie zu den Zeigerfeldern kommen ...), aber es ist sehr fragil. Sie sollten Pakete als Array von unsigned char analysieren.

Nun sieh dir das an:

struct QUESTION{ 
    char* qname; 
    struct REQ_DATA field; 
}; 

Dies ist eine Struktur, die 8 ist oder 16 Bytes (je nach Plattform), nichts wie das Feld mit variabler Länge in der aktuellen DNS-Paket. Und es gibt keine Möglichkeit, einen gültigen Zeiger (der lokal für den Adressraum Ihrer eigenen Maschine und Ihres Prozesses wäre) aus den Daten aus dem Netzwerk zu bekommen.