开发者

Parsing DNS Response

I am having some trouble with parsing DNS Response. Following is my code. The following are the structures. I'm getting a segmentation fault in the printf(), where im trying to print QNAME.

I'm pretty amateur when it comes to C programming, so im not really sure where im going wrong. Any helps/hints or link to useful resources/tutorials, will be appreciated. The function verfify_header() works correctly. I'm not sure why HEADER is properly extracted using memcpy(). and other fields are not.

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

The following is the function that parses the dns response.

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)开发者_Go百科 + 1);

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

}

Thanks, Chander


The problem is that you're trying to use C structures to parse data from over the network. If your machine is big endian and your compiler happens to order bitfields the way you want them ordered, this might work okay (until you get to the pointer fields...), but it's very fragile. You should be parsing packets as an array of unsigned char.

Now, look at this:

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

This is a structure that's 8 or 16 bytes (depending on your platform), nothing like the variable-length field in the actual DNS packet. And there's certainly no way you're going to get a valid pointer (which would be local to your own machine and process's address space) out of the data off the network.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜