unsigned int getRRs(char *q, dns_rr *rRecord){ uint32_t ipAddr; rRecord->ttl = ntohl(*(uint32_t*)(q)); //这里是ntohl,32bit数字的转化 char str[INET_ADDRSTRLEN]; struct in_addr addr; q+=sizeof(rRecord->ttl); rRecord->data_len = ntohs(*(uint16_t*)(q)); q+=sizeof(rRecord->data_len); if(rRecord->type == MX_TYPE){ q += 2; //将Preferencre的长度空出去 } if(rRecord->type == A_TYPE){ ipAddr = *(uint32_t*)(q); memcpy(&addr, &ipAddr, 4); char *ptr = inet_ntop(AF_INET, &addr, str, sizeof(str)); //转化为十进制点分值的IP地址 rRecord->rdata = (char*)malloc((strlen(ptr)+1)*sizeof(char)); strcpy(rRecord->rdata,ptr); return 4 + 2 + rRecord->data_len; } else if(rRecord->type == CNAME_TYPE){ char domainName[100]; memset(domainName, 0, 100); char *d = domainName; uint8_t count = 0; int i = 0; //完成报文中数字加域名形式至点分值的转换 while(1){ if(*q!='\0'){ count = *(uint8_t*)(q); q++; while(count){ memcpy(&(domainName[i]), q, sizeof(char)); count--; q++; i++; } domainName[i] = '.'; //加点 i++; } else{ domainName[i-1] = '\0'; //标注结束 q++; break; } } rRecord->rdata = (char*)malloc(i*sizeof(char)); memcpy(rRecord->rdata, domainName, i); //此时的i便为转换后变长字符串的长度了,经过了循环遍历 return 4 + 2 + rRecord->data_len +1; } else if(rRecord->type == MX_TYPE){ int firstlen = rRecord->data_len - 5; char domainName[100]; memset(domainName, 0, 100); char *d = domainName; //printf("d: %s\n", d); uint8_t count = 0; int i = 0; //count = ntohs(*(uint8_t*)(q)); //完成报文中数字加域名形式至点分值的转换 while(1){ if(*q!='\0'){ count = *(uint8_t*)(q); //printf("count:%d\n", count); q++; while(count){ //printf("i: %d\n", i); //printf("char1:%c\n", *q); memcpy(&(domainName[i]), q, sizeof(char)); //printf("domain name i: %c\n", domainName[i]); count--; q++; i++; } domainName[i] = '.'; //加点 i++; domainName[i] = '\0'; i++; break; } } strcpy(domainName, strcat(domainName, rRecord->name)); //由于压缩了指针,对两字符串进行拼接 //printf("Converted domain name: %s\n", domainName); int totalen = strlen(rRecord->name) + i; //拼接后总长度 rRecord->rdata = (char*)malloc(totalen*sizeof(char)); memcpy(rRecord->rdata, domainName, totalen); return 12+rRecord->data_len; } }
时间: 2024-04-26 16:21:03 浏览: 13
这段代码是一个函数,目的是从 DNS 报文中获取资源记录信息。输入参数 q 是一个指向 DNS 报文中资源记录段的指针,rRecord 是一个结构体,用于存储获取到的资源记录信息。该函数首先通过指针 q 获取资源记录的 TTL 字段,并使用 ntohl 函数将其转换为主机字节序,然后再获取数据长度字段,并使用 ntohs 函数将其转换为主机字节序。接下来,根据资源记录类型不同,分别进行不同的处理。如果是 A 记录类型,则将 IP 地址转换成十进制点分值的 IP 地址,并存储在 rRecord 结构体中,然后返回占用的字节数。如果是 CNAME 记录类型,则将域名进行数字加域名形式至点分值的转换,并存储在 rRecord 结构体中,然后返回占用的字节数。如果是 MX 记录类型,则先获取 Preference 字段的长度,然后再将域名进行转换,并将其与记录中的名称拼接起来,存储在 rRecord 结构体中,最后返回占用的字节数。
相关问题
unsigned int getHeader(char *q, dns_header *header){ header->id = ntohs(*(uint16_t*) (q)); header->tag = ntohs(*(uint16_t*) (q+2)); header->queryNum = ntohs(*(uint16_t*) (q+4)); //printf("queryName: %d\n", header->id); header->answerNum = ntohs(*(uint16_t*) (q+6)); header->authorNum = ntohs(*(uint16_t*) (q+8)); header->addNum = ntohs(*(uint16_t*) (q+10)); return sizeof(dns_header); }帮我解释这段代码
这段代码的作用是从一个DNS查询消息中提取出消息头部分的字段,并将这些字段存入一个dns_header结构中。函数的参数是一个指向字符数组的指针q,指向要被解析的DNS消息的起始位置,以及一个指向dns_header结构的指针header,用于存储解析结果。函数的返回值是一个unsigned int类型的值,表示消息头部分的长度。
函数中首先使用ntohs()函数将消息中的16位字节序转换为主机字节序,然后使用指针偏移的方式,将转换后的结果存入dns_header结构中对应的字段中。其中,id字段存储消息的标识符,tag字段存储消息的标志,queryNum字段存储查询的数量,answerNum字段存储回答的数量,authorNum字段存储授权回答的数量,addNum字段存储附加回答的数量。
最后,函数返回dns_header结构的大小,以便后续进行解析。需要注意的是,函数中没有对指针q指向的内存进行边界检查,如果消息格式不正确或者消息长度不足可能会导致程序出错。
简化这段代码unsigned int rr2buf(char *o, dns_rr* rr) { int i = 0; uint16_t temp; uint32_t temp32; temp = htons(49164); memcpy(o, &temp, sizeof(short)); o+=2; temp=htons(rr->type); memcpy(o, &temp, sizeof(short)); o+=2; temp=htons(rr->rclass); memcpy(o, &temp, sizeof(short)); o+=2; temp32=htonl(rr->ttl); memcpy(o, &temp32, (2*sizeof(short))); o+=4; temp=htons(rr->data_len); memcpy(o, &temp, sizeof(short)); o+=2; if(rr->type == MX_TYPE){ temp=htons(1); memcpy(o, &temp, sizeof(short)); o+=2; } if(rr->type == A_TYPE){ uint32_t ipAddr = inet_addr(rr->rdata); memcpy(o, &ipAddr,rr->data_len); o+=rr->data_len; return 16; } else if(rr->type == CNAME_TYPE){ char* ini = o; uint8_t count = 0; int i = 0; int j = 1; int tempts = 0; o++; while(1){ if(rr->rdata[i] == '.'){ memcpy(o-count-1, &count, sizeof(char)); count = 0; o++; i++; tempts = 1; } else if(rr->rdata[i] == '\0'){ memcpy(o, &(rr->rdata[i]), sizeof(char)); memcpy(o-count-1, &count, sizeof(char)); count = 0; break; } else{ memcpy(o, &(rr->rdata[i]), sizeof(char)); o++; i++; count++; } } return 12 + rr->data_len + 1; } else if(rr->type == MX_TYPE){ char* ini = o; uint8_t count = 0; int i = 0; int j = 1; int tempts = 0; o++; while(1){ if(rr->rdata[i] == '.'){ memcpy(o-count-1, &count, sizeof(char)); count = 0; o++; i++; tempts = 1; break; } else if(rr->rdata[i] == '\0'){ memcpy(o, &(rr->rdata[i]), sizeof(char)); memcpy(o-count-1, &count, sizeof(char)); count = 0; break; } else{ memcpy(o, &(rr->rdata[i]), sizeof(char)); o++; i++; count++; } } o--; temp = htons(49164); //这里指代1100000000001100,DNS报文中压缩指针的操作 memcpy(o, &temp, sizeof(short)); return 16+i; } }
以下是我简化后的代码,主要是将重复的代码提出来作为函数,并将一些重复操作合并在一起。
```
unsigned int rr2buf(char *o, dns_rr* rr) {
uint16_t temp = htons(49164);
memcpy(o, &temp, sizeof(short));
o += 2;
temp = htons(rr->type);
memcpy(o, &temp, sizeof(short));
o += 2;
temp = htons(rr->rclass);
memcpy(o, &temp, sizeof(short));
o += 2;
uint32_t temp32 = htonl(rr->ttl);
memcpy(o, &temp32, (2*sizeof(short)));
o += 4;
temp = htons(rr->data_len);
memcpy(o, &temp, sizeof(short));
o += 2;
if (rr->type == A_TYPE) {
return writeARecord(o, rr);
} else if (rr->type == CNAME_TYPE) {
return writeCNAMERecord(o, rr);
} else if (rr->type == MX_TYPE) {
return writeMXRecord(o, rr);
}
return 0;
}
unsigned int writeARecord(char* o, dns_rr* rr) {
uint32_t ipAddr = inet_addr(rr->rdata);
memcpy(o, &ipAddr, rr->data_len);
return 16;
}
unsigned int writeCNAMERecord(char* o, dns_rr* rr) {
char* ini = o;
uint8_t count = 0;
int i = 0;
int j = 1;
int tempts = 0;
o++;
while(1) {
if (rr->rdata[i] == '.') {
memcpy(o-count-1, &count, sizeof(char));
count = 0;
o++;
i++;
tempts = 1;
} else if (rr->rdata[i] == '\0') {
memcpy(o, &(rr->rdata[i]), sizeof(char));
memcpy(o-count-1, &count, sizeof(char));
count = 0;
break;
} else {
memcpy(o, &(rr->rdata[i]), sizeof(char));
o++;
i++;
count++;
}
}
return 12 + rr->data_len + 1;
}
unsigned int writeMXRecord(char* o, dns_rr* rr) {
char* ini = o;
uint8_t count = 0;
int i = 0;
int j = 1;
int tempts = 0;
o++;
while(1) {
if (rr->rdata[i] == '.') {
memcpy(o-count-1, &count, sizeof(char));
count = 0;
o++;
i++;
tempts = 1;
break;
} else if (rr->rdata[i] == '\0') {
memcpy(o, &(rr->rdata[i]), sizeof(char));
memcpy(o-count-1, &count, sizeof(char));
count = 0;
break;
} else {
memcpy(o, &(rr->rdata[i]), sizeof(char));
o++;
i++;
count++;
}
}
o--;
uint16_t temp = htons(49164);
memcpy(o, &temp, sizeof(short));
return 16 + i;
}
```