update code
This commit is contained in:
234
dns.c
234
dns.c
@@ -1,102 +1,222 @@
|
||||
#include "dns.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DNS_MAX_CNAME_LEN 128
|
||||
|
||||
int dns_decode_head(struct dns_head *head, struct idns_head *ihead)
|
||||
short dns_read_short(unsigned char **buffer)
|
||||
{
|
||||
head->id = ntohs(ihead->id);
|
||||
head->opcode = (ihead->opcode >> 3) & 0x0F;
|
||||
head->query = (ihead->opcode & 0x80) != 0x80;
|
||||
head->aa = (ihead->opcode & 0x04) == 0x04;
|
||||
head->tc = (ihead->opcode & 0x02) == 0x02;
|
||||
head->rd = (ihead->opcode & 0x01) == 0x01;
|
||||
head->ra = (ihead->rcode & 0x80) == 0x80;
|
||||
head->z = (ihead->rcode & 0x40) == 0x40;
|
||||
head->ad = (ihead->rcode & 0x20) == 0x20;
|
||||
head->cd = (ihead->rcode & 0x10) == 0x10;
|
||||
head->rcode = (ihead->rcode & 0x0F);
|
||||
head->qdcount = ntohs(ihead->qdcount);
|
||||
head->ancount = ntohs(ihead->ancount);
|
||||
head->nscount = ntohs(ihead->nscount);
|
||||
head->nrcount = ntohs(ihead->arcount);
|
||||
unsigned short value;
|
||||
|
||||
value = *((unsigned short *)(*buffer));
|
||||
*buffer += 2;
|
||||
|
||||
return ntohs(value);
|
||||
}
|
||||
|
||||
void dns_write_char(unsigned char **buffer, unsigned char value)
|
||||
{
|
||||
**buffer = value;
|
||||
*buffer += 1;
|
||||
}
|
||||
|
||||
unsigned char dns_read_char(unsigned char **buffer)
|
||||
{
|
||||
unsigned char value = **buffer;
|
||||
*buffer += 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
void dns_write_short(unsigned char **buffer, unsigned short value)
|
||||
{
|
||||
value = htons(value);
|
||||
*((unsigned short *)(*buffer)) = value;
|
||||
*buffer += 2;
|
||||
}
|
||||
|
||||
void dns_write_int(unsigned char **buffer, unsigned int value)
|
||||
{
|
||||
value = htons(value);
|
||||
*((unsigned int *)(*buffer)) = value;
|
||||
*buffer += 4;
|
||||
}
|
||||
|
||||
unsigned int dns_read_int(unsigned char **buffer)
|
||||
{
|
||||
unsigned int value;
|
||||
|
||||
value = *((unsigned int *)(*buffer));
|
||||
*buffer += 4;
|
||||
|
||||
return ntohs(value);
|
||||
}
|
||||
|
||||
int dns_decode_head(struct dns_head *head, unsigned char **data)
|
||||
{
|
||||
unsigned int fields;
|
||||
unsigned char *start = *data;
|
||||
unsigned char *end = start;
|
||||
|
||||
head->id = dns_read_short(data);
|
||||
fields = dns_read_short(data);
|
||||
head->qr = (fields & QR_MASK) >> 15;
|
||||
head->opcode = (fields & OPCODE_MASK) >> 11;
|
||||
head->aa = (fields & AA_MASK) >> 10;
|
||||
head->tc = (fields & TC_MASK) >> 9;
|
||||
head->rd = (fields & RD_MASK) >> 8;
|
||||
head->ra = (fields & RA_MASK) >> 7;
|
||||
head->rcode = (fields & RCODE_MASK) >> 0;
|
||||
head->qdcount = dns_read_short(data);
|
||||
head->ancount = dns_read_short(data);
|
||||
head->nscount = dns_read_short(data);
|
||||
head->nrcount = dns_read_short(data);
|
||||
|
||||
end = *data;
|
||||
return start - end;
|
||||
}
|
||||
|
||||
int dns_encode_head(unsigned char **data, struct dns_head *head)
|
||||
{
|
||||
dns_write_short(data, head->id);
|
||||
|
||||
int fields = 0;
|
||||
fields |= (head->qr << 15) & QR_MASK;
|
||||
fields |= (head->rcode << 0) & RCODE_MASK;
|
||||
dns_write_short(data, fields);
|
||||
|
||||
dns_write_short(data, head->qdcount);
|
||||
dns_write_short(data, head->ancount);
|
||||
dns_write_short(data, head->nscount);
|
||||
dns_write_short(data, head->nrcount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_decode_rr(char *data, int size)
|
||||
int dns_get_domain(char *output, int size, unsigned char *data)
|
||||
{
|
||||
int ret;
|
||||
int len = 0;
|
||||
int i = 0;
|
||||
int output_len = 0;
|
||||
int copy_len = 0;
|
||||
int total_len = 0;
|
||||
|
||||
return len;
|
||||
}
|
||||
while (data[i]) {
|
||||
int len = data[i];
|
||||
|
||||
int dns_get_domain(char *data, int size, char *output)
|
||||
{
|
||||
int i = 0;
|
||||
if (i != 0) {
|
||||
*output = '.';
|
||||
output++;
|
||||
}
|
||||
|
||||
while (data[i]) {
|
||||
int len = data[i];
|
||||
*output = '.';
|
||||
output++;
|
||||
i++;
|
||||
memcpy(output, data + i, len);
|
||||
total_len++;
|
||||
if (output_len < size - 1) {
|
||||
copy_len = (len < size - output_len) ? len : size - 1 - output_len;
|
||||
memcpy(output, data + i, copy_len);
|
||||
}
|
||||
i += len;
|
||||
output += len;
|
||||
output_len += len;
|
||||
total_len += len;
|
||||
}
|
||||
|
||||
int qtype = (unsigned short) data[i+1];
|
||||
int qclass = (unsigned short) data[i+3];
|
||||
|
||||
return 0;
|
||||
*output = 0;
|
||||
total_len++;
|
||||
return total_len;
|
||||
}
|
||||
|
||||
int dns_decode_qd(char *data, int size)
|
||||
int dns_encode_domain(unsigned char *output, int size, char *domain)
|
||||
{
|
||||
int i = 0;
|
||||
int num = 0;
|
||||
int total_len = 0;
|
||||
unsigned char *ptr_num = output++;
|
||||
total_len++;
|
||||
while (i < size && *domain != 0) {
|
||||
if (*domain == '.') {
|
||||
*ptr_num = num;
|
||||
num = 0;
|
||||
ptr_num = output;
|
||||
domain++;
|
||||
output++;
|
||||
total_len++;
|
||||
continue;
|
||||
}
|
||||
*output = *domain;
|
||||
num++;
|
||||
output++;
|
||||
domain++;
|
||||
total_len++;
|
||||
}
|
||||
*ptr_num = num;
|
||||
*output = 0;
|
||||
total_len++;
|
||||
return total_len;
|
||||
}
|
||||
|
||||
int dns_decode_qd(unsigned char *data, int size, char *domain, int domain_size, int *qtype, int *qclass)
|
||||
{
|
||||
int ret;
|
||||
int len = 0;
|
||||
char name[DNS_MAX_CNAME_LEN];
|
||||
len = dns_get_domain(data, size, name);
|
||||
printf("%s\n", name);
|
||||
len = dns_get_domain(domain, domain_size, data);
|
||||
data += len;
|
||||
*qtype = dns_read_short(&data);
|
||||
*qclass = dns_read_short(&data);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int dns_decode_body(struct dns_packet *packet, char *data, int size)
|
||||
int dns_decode_body(struct dns_packet *packet, unsigned char *data, int size)
|
||||
{
|
||||
struct dns_head *head = &packet->head;
|
||||
int i = 0;
|
||||
int len = 0;
|
||||
int decode_len = 0;
|
||||
int qtype = 0;
|
||||
int qclass = 0;
|
||||
char name[DNS_MAX_CNAME_LEN];
|
||||
|
||||
if (head->nrcount || head->nscount || head->ancount) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < head->qdcount; i++) {
|
||||
len = dns_decode_qd(data, size - decode_len);
|
||||
|
||||
len = dns_decode_qd(data, size - decode_len, name, DNS_MAX_CNAME_LEN, &qtype, &qclass);
|
||||
printf("QR: %d, domain: %s, qtype = %d, qclass = %d\n", head->qr, name, qtype, qclass);
|
||||
decode_len += len;
|
||||
data += len;
|
||||
}
|
||||
|
||||
for (i = 0; i < head->qdcount; i++) {
|
||||
}
|
||||
|
||||
for (i = 0; i < head->qdcount; i++) {
|
||||
}
|
||||
|
||||
for (i = 0; i < head->qdcount; i++) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_decode(struct dns_packet *packet, char *data, int size)
|
||||
int dns_decode(struct dns_packet *packet, unsigned char *data, int size)
|
||||
{
|
||||
struct idns_head *ihead = (struct idns_head *)data;
|
||||
struct dns_head *head = &packet->head;
|
||||
int decode_len = 0;
|
||||
int ret = 0;
|
||||
|
||||
dns_decode_head(head, ihead);
|
||||
decode_len += sizeof(struct idns_head);
|
||||
data += sizeof(struct idns_head);
|
||||
dns_decode_body(packet, data, size - decode_len);
|
||||
return -1;
|
||||
decode_len = dns_decode_head(head, &data);
|
||||
ret = dns_decode_body(packet, data, size - decode_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int dns_encode(unsigned char *data, int size, struct dns_packet *packet)
|
||||
{
|
||||
int rc;
|
||||
int len = 0;
|
||||
|
||||
len = dns_encode_head(&data, &packet->head);
|
||||
|
||||
while (1) {
|
||||
len = dns_encode_domain(data, size, "www.baidu.com");
|
||||
data += len;
|
||||
dns_write_short(&data, /*qType*/12);
|
||||
dns_write_short(&data, /*qClass*/ 1);
|
||||
}
|
||||
|
||||
/*
|
||||
rc |= dns_encode_resource_records(packet->answers, data);
|
||||
rc |= dns_encode_resource_records(packet->nameservers, data);
|
||||
rc |= dns_encode_resource_records(packet->additional, data);
|
||||
*/
|
||||
return rc;
|
||||
}
|
||||
Reference in New Issue
Block a user