2010-11-19 2 views
1

У меня возникли проблемы с разбором DNS-ответа. Следующий мой код. Ниже представлены структуры. Я получаю ошибку сегментации в printf(), где im пытается распечатать QNAME.Анализ DNS-ответа

Я довольно любитель, когда речь заходит о программировании на С, поэтому я не уверен, где я ошибаюсь. Любые советы/подсказки или ссылки на полезные ресурсы/учебные пособия будут оценены. Функция verfify_header() работает правильно. Я не уверен, почему HEADER правильно извлечен с помощью memcpy(). и другие поля - нет.

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

Следующая функция, которая анализирует реакцию 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!!!!! 

} 

Спасибо, Chander

+1

Вам не нужно * on * rname –

+0

Я получаю значение NULL. Кроме того, я попытался использовать memmove(), где бы я не использовал memcpy, но все тот же результат –

ответ

2

Проблема заключается в том, что вы пытаетесь использовать C структуру для анализа данных по сети. Если ваша машина большая, и ваш компилятор работает, чтобы упорядочить битовые поля так, как вы их заказывали, это может работать нормально (пока вы не дойдете до полей указателя ...), но это очень хрупко. Вы должны разбирать пакеты как массив из unsigned char.

Теперь, посмотрите на это:

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

Это структура, это 8 или 16 байт (в зависимости от платформы), ничего подобного в поле переменной длины, в самом пакете DNS. И, конечно же, вы не сможете получить действительный указатель (который будет локальным для вашего собственного пространства машины и процесса) вне данных из сети.

Смежные вопросы