Разбор ответа DNS - PullRequest
       24

Разбор ответа DNS

1 голос
/ 20 ноября 2010

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

Я довольно любитель, когда дело доходит до программирования на С, так что я не совсем уверен, где я ошибаюсь. Будем благодарны за любые подсказки / подсказки или ссылки на полезные ресурсы / учебники. Функция 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!!!!!

}

Спасибо, Чандер

1 Ответ

2 голосов
/ 20 ноября 2010

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

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

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

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

...