2010-11-19 10 views
1

Je rencontre des problèmes avec l'analyse de la réponse DNS. Voici mon code. Ce qui suit sont les structures. Je reçois une erreur de segmentation dans printf(), où j'essaie d'imprimer QNAME. Je suis assez amateur quand il s'agit de programmation en C, donc je ne sais pas vraiment où je vais mal. Toute aide/astuces ou lien vers des ressources/tutoriels utiles, sera appréciée. La fonction verfify_header() fonctionne correctement. Je ne suis pas sûr pourquoi HEADER est correctement extrait en utilisant memcpy(). et d'autres champs ne sont pas.Analyse de la réponse DNS

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;  
}; 

Voici la fonction qui analyse la réponse DNS.

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!!!!! 

} 

Merci, Chander

+1

Vous n'avez pas besoin du * on * rname –

+0

Je reçois une valeur NULL. Aussi, j'ai essayé d'utiliser memmove() partout où j'utilise memcpy, mais toujours le même résultat –

Répondre

2

Le problème est que vous essayez d'utiliser des structures C pour analyser les données à partir du réseau. Si votre machine est big endian et que votre compilateur arrive à ordonner des bitfields comme vous le souhaitez, cela pourrait bien marcher (jusqu'à ce que vous arriviez aux champs de pointeurs ...), mais c'est très fragile. Vous devriez analyser les paquets comme un tableau de unsigned char.

Maintenant, regardez ceci:

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

C'est une structure c'est 8 ou 16 octets (en fonction de votre plate-forme), rien comme le champ de longueur variable dans le paquet DNS réel. Et il n'y a certainement aucun moyen d'obtenir un pointeur valide (qui serait local à votre propre machine et l'espace d'adressage du processus) sur les données hors du réseau.