Update code
This commit is contained in:
796
dns.c
796
dns.c
@@ -51,25 +51,25 @@ unsigned int dns_read_int(unsigned char **buffer)
|
|||||||
return ntohs(value);
|
return ntohs(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dns_rrs *dns_rr_get_start(struct dns_packet *packet, int type, int *count)
|
struct dns_rrs *dns_get_rrs_start(struct dns_packet *packet, int type, int *count)
|
||||||
{
|
{
|
||||||
unsigned short start;
|
unsigned short start;
|
||||||
struct dns_head *head = &packet->head;
|
struct dns_head *head = &packet->head;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DNS_RR_QD:
|
case DNS_RRS_QD:
|
||||||
*count = head->qdcount;
|
*count = head->qdcount;
|
||||||
start = packet->questions;
|
start = packet->questions;
|
||||||
break;
|
break;
|
||||||
case DNS_RR_AN:
|
case DNS_RRS_AN:
|
||||||
*count = head->ancount;
|
*count = head->ancount;
|
||||||
start = packet->answers;
|
start = packet->answers;
|
||||||
break;
|
break;
|
||||||
case DNS_RR_NS:
|
case DNS_RRS_NS:
|
||||||
*count = head->nscount;
|
*count = head->nscount;
|
||||||
start = packet->nameservers;
|
start = packet->nameservers;
|
||||||
break;
|
break;
|
||||||
case DNS_RR_NR:
|
case DNS_RRS_NR:
|
||||||
*count = head->nrcount;
|
*count = head->nrcount;
|
||||||
start = packet->additional;
|
start = packet->additional;
|
||||||
break;
|
break;
|
||||||
@@ -81,16 +81,16 @@ struct dns_rrs *dns_rr_get_start(struct dns_packet *packet, int type, int *count
|
|||||||
return (struct dns_rrs *)(packet->data + start);
|
return (struct dns_rrs *)(packet->data + start);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dns_rrs *dns_rr_get_next(struct dns_packet *packet, struct dns_rrs *rrs)
|
struct dns_rrs *dns_get_rrs_next(struct dns_packet *packet, struct dns_rrs *rrs)
|
||||||
{
|
{
|
||||||
if (rrs->next == 0) {
|
if (rrs->next == DNS_RR_END) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (struct dns_rrs *)(packet->data + rrs->next);
|
return (struct dns_rrs *)(packet->data + rrs->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *dns_rr_add_start(struct dns_packet *packet, int *maxlen)
|
unsigned char *_dns_add_rrs_start(struct dns_packet *packet, int *maxlen)
|
||||||
{
|
{
|
||||||
struct dns_rrs *rrs;
|
struct dns_rrs *rrs;
|
||||||
unsigned char *end = packet->data + packet->len;
|
unsigned char *end = packet->data + packet->len;
|
||||||
@@ -111,24 +111,25 @@ int dns_rr_add_end(struct dns_packet *packet, int type, dns_type_t rrtype, int l
|
|||||||
unsigned short *count;
|
unsigned short *count;
|
||||||
unsigned short *start;
|
unsigned short *start;
|
||||||
|
|
||||||
|
len += sizeof(*rrs);
|
||||||
if (packet->len + len > packet->size - sizeof(*packet)) {
|
if (packet->len + len > packet->size - sizeof(*packet)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DNS_RR_QD:
|
case DNS_RRS_QD:
|
||||||
count = &head->qdcount;
|
count = &head->qdcount;
|
||||||
start = &packet->questions;
|
start = &packet->questions;
|
||||||
break;
|
break;
|
||||||
case DNS_RR_AN:
|
case DNS_RRS_AN:
|
||||||
count = &head->ancount;
|
count = &head->ancount;
|
||||||
start = &packet->answers;
|
start = &packet->answers;
|
||||||
break;
|
break;
|
||||||
case DNS_RR_NS:
|
case DNS_RRS_NS:
|
||||||
count = &head->nscount;
|
count = &head->nscount;
|
||||||
start = &packet->nameservers;
|
start = &packet->nameservers;
|
||||||
break;
|
break;
|
||||||
case DNS_RR_NR:
|
case DNS_RRS_NR:
|
||||||
count = &head->nrcount;
|
count = &head->nrcount;
|
||||||
start = &packet->additional;
|
start = &packet->additional;
|
||||||
break;
|
break;
|
||||||
@@ -143,17 +144,262 @@ int dns_rr_add_end(struct dns_packet *packet, int type, dns_type_t rrtype, int l
|
|||||||
rrs->type = rrtype;
|
rrs->type = rrtype;
|
||||||
*start = packet->len;
|
*start = packet->len;
|
||||||
packet->len += len;
|
packet->len += len;
|
||||||
return 0;
|
return sizeof(*rrs) + len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_decode_head(struct dns_head *head, unsigned char **data)
|
int _dns_add_qr_head(unsigned char *data, int maxlen, char *domain, int qtype, int qclass)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < maxlen; i++) {
|
||||||
|
*data = *domain;
|
||||||
|
if (*domain == '\0') {
|
||||||
|
data++;
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data++;
|
||||||
|
domain++;
|
||||||
|
}
|
||||||
|
len += i;
|
||||||
|
|
||||||
|
if (maxlen - len < 4) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*((unsigned short *)(data)) = qtype;
|
||||||
|
data += 2;
|
||||||
|
len += 2;
|
||||||
|
|
||||||
|
*((unsigned short *)(data)) = qclass;
|
||||||
|
data += 2;
|
||||||
|
len += 2;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _dns_get_qr_head(unsigned char *data, char *domain, int maxsize, int *qtype, int *qclass)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int len = 0;
|
||||||
|
for (i = 0; i < maxsize; i++) {
|
||||||
|
*domain = *data;
|
||||||
|
if (*data == '\0') {
|
||||||
|
domain++;
|
||||||
|
data++;
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*domain = *data;
|
||||||
|
domain++;
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
len += i;
|
||||||
|
if (len >= maxsize) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*qtype = *((unsigned short *)(data));
|
||||||
|
data += 2;
|
||||||
|
len += 2;
|
||||||
|
|
||||||
|
*qclass = *((unsigned short *)(data));
|
||||||
|
data += 2;
|
||||||
|
len += 2;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _dns_add_rr_head(unsigned char *data, int maxlen, char *domain, int qtype, int qclass, int ttl, int rr_len)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
len = _dns_add_qr_head(data, maxlen, domain, qtype, qclass);
|
||||||
|
if (len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data += len;
|
||||||
|
if (maxlen - len < 6) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*((unsigned int *)(data)) = ttl;
|
||||||
|
data += 4;
|
||||||
|
len += 4;
|
||||||
|
|
||||||
|
*((unsigned short *)(data)) = rr_len;
|
||||||
|
data += 2;
|
||||||
|
len += 2;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _dns_get_rr_head(unsigned char *data, char *domain, int maxsize, int *qtype, int *qclass, int *ttl, int *rr_len)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
len = _dns_get_qr_head(data, domain, maxsize, qtype, qclass);
|
||||||
|
data += len;
|
||||||
|
|
||||||
|
*ttl = *((unsigned int *)(data));
|
||||||
|
data += 4;
|
||||||
|
len += 4;
|
||||||
|
|
||||||
|
*rr_len = *((unsigned short *)(data));
|
||||||
|
data += 2;
|
||||||
|
len += 2;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dns_add_A(struct dns_packet *packet, char *domain, int ttl, unsigned char addr[4])
|
||||||
|
{
|
||||||
|
int maxlen = 0;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
unsigned char *data = _dns_add_rrs_start(packet, &maxlen);
|
||||||
|
if (data == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = _dns_add_rr_head(data, maxlen, domain, DNS_T_A, DNS_C_IN, ttl, DNS_RR_A_LEN);
|
||||||
|
if (len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data += len;
|
||||||
|
|
||||||
|
memcpy(data, addr, DNS_RR_A_LEN);
|
||||||
|
data += DNS_RR_A_LEN;
|
||||||
|
len += DNS_RR_A_LEN;
|
||||||
|
|
||||||
|
return dns_rr_add_end(packet, DNS_RRS_AN, DNS_T_A, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dns_get_A(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[4])
|
||||||
|
{
|
||||||
|
int qtype = 0;
|
||||||
|
int qclass = 0;
|
||||||
|
int rr_len = 0;
|
||||||
|
int len = 0;
|
||||||
|
int total_len = 0;
|
||||||
|
|
||||||
|
unsigned char *data = rrs->data;
|
||||||
|
|
||||||
|
if (rrs->type != DNS_T_A) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = _dns_get_rr_head(data, domain, maxsize, &qtype, &qclass, ttl, &rr_len);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data += len;
|
||||||
|
total_len += len;
|
||||||
|
|
||||||
|
if (qtype != DNS_T_A || rr_len != DNS_RR_A_LEN) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(addr, data, DNS_RR_A_LEN);
|
||||||
|
total_len += rr_len;
|
||||||
|
data += rr_len;
|
||||||
|
|
||||||
|
return total_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dns_add_AAAA(struct dns_packet *packet, char *domain, int ttl, unsigned char addr[16])
|
||||||
|
{
|
||||||
|
int maxlen = 0;
|
||||||
|
int len = 0;
|
||||||
|
unsigned char *data = _dns_add_rrs_start(packet, &maxlen);
|
||||||
|
if (data == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = _dns_add_rr_head(data, maxlen, domain, DNS_T_AAAA, DNS_C_IN, ttl, DNS_RR_AAAA_LEN);
|
||||||
|
if (len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data += len;
|
||||||
|
|
||||||
|
memcpy(data, addr, DNS_RR_AAAA_LEN);
|
||||||
|
data += DNS_RR_AAAA_LEN;
|
||||||
|
len += DNS_RR_AAAA_LEN;
|
||||||
|
|
||||||
|
return dns_rr_add_end(packet, DNS_RRS_AN, DNS_T_AAAA, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dns_get_AAAA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[16])
|
||||||
|
{
|
||||||
|
int qtype = 0;
|
||||||
|
int qclass = 0;
|
||||||
|
int rr_len = 0;
|
||||||
|
int len = 0;
|
||||||
|
int total_len = 0;
|
||||||
|
|
||||||
|
if (rrs->type != DNS_T_AAAA) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *data = rrs->data;
|
||||||
|
|
||||||
|
len = _dns_get_rr_head(data, domain, maxsize, &qtype, &qclass, ttl, &rr_len);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data += len;
|
||||||
|
total_len += len;
|
||||||
|
|
||||||
|
if (qtype != DNS_T_AAAA || rr_len != DNS_RR_AAAA_LEN) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(addr, rrs->data, DNS_RR_AAAA_LEN);
|
||||||
|
total_len += DNS_RR_AAAA_LEN;
|
||||||
|
|
||||||
|
return total_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Format:
|
||||||
|
* |DNS_NAME\0(string)|qtype(short)|qclass(short)|
|
||||||
|
*/
|
||||||
|
int dns_add_domain(struct dns_packet *packet, char *domain, int qtype, int qclass)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int maxlen = 0;
|
||||||
|
unsigned char *data = _dns_add_rrs_start(packet, &maxlen);
|
||||||
|
|
||||||
|
if (data == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = _dns_add_qr_head(data, maxlen, domain, qtype, qclass);
|
||||||
|
if (len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dns_rr_add_end(packet, DNS_RRS_QD, DNS_T_CNAME, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dns_get_domain(struct dns_rrs *rrs, char *domain, int maxsize, int *qtype, int *qclass)
|
||||||
|
{
|
||||||
|
if (rrs->type != DNS_T_CNAME) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _dns_get_qr_head(rrs->data, domain, maxsize, qtype, qclass);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _dns_decode_head(struct dns_head *head, unsigned char *data)
|
||||||
{
|
{
|
||||||
unsigned int fields;
|
unsigned int fields;
|
||||||
unsigned char *start = *data;
|
unsigned char *start = data;
|
||||||
unsigned char *end = start;
|
unsigned char *end = data;
|
||||||
|
|
||||||
head->id = dns_read_short(data);
|
head->id = dns_read_short(&data);
|
||||||
fields = dns_read_short(data);
|
fields = dns_read_short(&data);
|
||||||
head->qr = (fields & QR_MASK) >> 15;
|
head->qr = (fields & QR_MASK) >> 15;
|
||||||
head->opcode = (fields & OPCODE_MASK) >> 11;
|
head->opcode = (fields & OPCODE_MASK) >> 11;
|
||||||
head->aa = (fields & AA_MASK) >> 10;
|
head->aa = (fields & AA_MASK) >> 10;
|
||||||
@@ -161,32 +407,38 @@ int dns_decode_head(struct dns_head *head, unsigned char **data)
|
|||||||
head->rd = (fields & RD_MASK) >> 8;
|
head->rd = (fields & RD_MASK) >> 8;
|
||||||
head->ra = (fields & RA_MASK) >> 7;
|
head->ra = (fields & RA_MASK) >> 7;
|
||||||
head->rcode = (fields & RCODE_MASK) >> 0;
|
head->rcode = (fields & RCODE_MASK) >> 0;
|
||||||
head->qdcount = dns_read_short(data);
|
head->qdcount = dns_read_short(&data);
|
||||||
head->ancount = dns_read_short(data);
|
head->ancount = dns_read_short(&data);
|
||||||
head->nscount = dns_read_short(data);
|
head->nscount = dns_read_short(&data);
|
||||||
head->nrcount = dns_read_short(data);
|
head->nrcount = dns_read_short(&data);
|
||||||
|
|
||||||
end = *data;
|
end = data;
|
||||||
return start - end;
|
return end - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_encode_head(unsigned char **data, struct dns_head *head)
|
int _dns_encode_head(unsigned char *data, int size, struct dns_head *head)
|
||||||
{
|
{
|
||||||
dns_write_short(data, head->id);
|
int len = 12;
|
||||||
|
|
||||||
|
if (size < len) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_write_short(&data, head->id);
|
||||||
|
|
||||||
int fields = 0;
|
int fields = 0;
|
||||||
fields |= (head->qr << 15) & QR_MASK;
|
fields |= (head->qr << 15) & QR_MASK;
|
||||||
fields |= (head->rcode << 0) & RCODE_MASK;
|
fields |= (head->rcode << 0) & RCODE_MASK;
|
||||||
dns_write_short(data, fields);
|
dns_write_short(&data, fields);
|
||||||
|
|
||||||
dns_write_short(data, head->qdcount);
|
dns_write_short(&data, head->qdcount);
|
||||||
dns_write_short(data, head->ancount);
|
dns_write_short(&data, head->ancount);
|
||||||
dns_write_short(data, head->nscount);
|
dns_write_short(&data, head->nscount);
|
||||||
dns_write_short(data, head->nrcount);
|
dns_write_short(&data, head->nrcount);
|
||||||
return 0;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_decode_domain(char *output, int size, unsigned char *data)
|
int _dns_decode_domain(char *output, int size, unsigned char *data)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int output_len = 0;
|
int output_len = 0;
|
||||||
@@ -218,7 +470,7 @@ int dns_decode_domain(char *output, int size, unsigned char *data)
|
|||||||
return total_len;
|
return total_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_encode_domain(unsigned char *output, int size, char *domain)
|
int _dns_encode_domain(unsigned char *output, int size, char *domain)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int num = 0;
|
int num = 0;
|
||||||
@@ -247,129 +499,325 @@ int dns_encode_domain(unsigned char *output, int size, char *domain)
|
|||||||
return total_len;
|
return total_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_decode_qd(unsigned char *data, int size, char *domain, int domain_size, int *qtype, int *qclass)
|
int _dns_decode_qr_head(unsigned char *data, int size, char *domain, int domain_size, int *qtype, int *qclass)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
len = dns_decode_domain(domain, domain_size, data);
|
len = _dns_decode_domain(domain, domain_size, data);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
data += len;
|
data += len;
|
||||||
*qtype = dns_read_short(&data);
|
*qtype = dns_read_short(&data);
|
||||||
|
len += 2;
|
||||||
*qclass = dns_read_short(&data);
|
*qclass = dns_read_short(&data);
|
||||||
|
len += 2;
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int _dns_encode_qr_head(unsigned char *data, int size, char *domain, int qtype, int qclass)
|
||||||
* Format:
|
|
||||||
* |DNS_NAME\0(string)|qtype(short)|qclass(short)|
|
|
||||||
*/
|
|
||||||
int dns_add_domain(struct dns_packet *packet, char *domain, int qtype, int qclass)
|
|
||||||
{
|
{
|
||||||
int maxlen = 0;
|
|
||||||
int i;
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
unsigned char *data = dns_rr_add_start(packet, &maxlen);
|
len = _dns_encode_domain(data, size, domain);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data += len;
|
||||||
|
|
||||||
if (data == NULL) {
|
if (size - len < 4) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < maxlen - 4; i++) {
|
dns_write_short(&data, qtype);
|
||||||
*data = *domain;
|
len += 2;
|
||||||
if (*domain == '\0') {
|
dns_write_short(&data, qclass);
|
||||||
data++;
|
|
||||||
i++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
data++;
|
|
||||||
domain++;
|
|
||||||
}
|
|
||||||
len += i;
|
|
||||||
*((unsigned short *)(data)) = qtype;
|
|
||||||
data += 2;
|
|
||||||
len += 2;
|
len += 2;
|
||||||
|
|
||||||
*((unsigned short *)(data)) = qclass;
|
return len;
|
||||||
data += 2;
|
}
|
||||||
|
|
||||||
|
int _dns_decode_rr_head(unsigned char *data, int size, char *domain, int domain_size, int *qtype, int *qclass, int *ttl, int *rr_len)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int total_len = 0;
|
||||||
|
|
||||||
|
len = _dns_decode_qr_head(data, size, domain, domain_size, qtype, qclass);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
data += len;
|
||||||
|
total_len += len;
|
||||||
|
|
||||||
|
*ttl = dns_read_int(&data);
|
||||||
|
len += 4;
|
||||||
|
total_len += 4;
|
||||||
|
|
||||||
|
*rr_len = dns_read_short(&data);
|
||||||
len += 2;
|
len += 2;
|
||||||
|
total_len += 2;
|
||||||
|
|
||||||
return dns_rr_add_end(packet, DNS_RR_QD, DNS_T_CNAME, len);
|
return total_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_add_A(struct dns_packet *packet, unsigned char addr[4])
|
int _dns_encode_rr_head(unsigned char *data, int size, char *domain, int qtype, int qclass, int ttl, int rr_len)
|
||||||
{
|
{
|
||||||
int maxlen = 0;
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
unsigned char *data = dns_rr_add_start(packet, &maxlen);
|
int total_len = 0;
|
||||||
unsigned char *data_ptr = data;
|
len = _dns_encode_qr_head(data, size, domain, qtype, qclass);
|
||||||
if (data == NULL) {
|
if (len <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data, addr, 4);
|
data += len;
|
||||||
data += 4;
|
total_len += len;
|
||||||
len += 4;
|
|
||||||
|
|
||||||
return dns_rr_add_end(packet, DNS_RR_AN, DNS_T_A, len);
|
if (size - len < 6) {
|
||||||
}
|
|
||||||
|
|
||||||
int dns_add_AAAA(struct dns_packet *packet, unsigned char addr[16])
|
|
||||||
{
|
|
||||||
int maxlen = 0;
|
|
||||||
int len = 0;
|
|
||||||
unsigned char *data = dns_rr_add_start(packet, &maxlen);
|
|
||||||
if (data == NULL) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data, addr, 4);
|
dns_write_int(&data, ttl);
|
||||||
data += 4;
|
|
||||||
len += 4;
|
len += 4;
|
||||||
|
total_len += 4;
|
||||||
|
|
||||||
return dns_rr_add_end(packet, DNS_RR_AN, DNS_T_AAAA, len);
|
dns_write_short(&data, rr_len);
|
||||||
|
len += 2;
|
||||||
|
total_len += 2;
|
||||||
|
|
||||||
|
return total_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_get_domain(struct dns_rrs *rrs, char *domain, int maxsize, int *qtype, int *qclass)
|
int _dns_decode_A(unsigned char addr[4], unsigned char *data)
|
||||||
{
|
{
|
||||||
int i = 0;
|
memcpy(addr, data, DNS_RR_A_LEN);
|
||||||
unsigned char *data = rrs->data;
|
return DNS_RR_A_LEN;
|
||||||
for (i = 0; i < maxsize; i++) {
|
}
|
||||||
*domain = *data;
|
|
||||||
if (*data == '\0') {
|
int _dns_encode_A(unsigned char *output, int size, struct dns_rrs *rrs)
|
||||||
domain++;
|
{
|
||||||
data++;
|
int len;
|
||||||
|
int len_rrs;
|
||||||
|
int total_len = 0;
|
||||||
|
int qtype = 0;
|
||||||
|
int qclass = 0;
|
||||||
|
int ttl = 0;
|
||||||
|
char domain[DNS_MAX_CNAME_LEN];
|
||||||
|
unsigned char *data_rrs;
|
||||||
|
int rr_len;
|
||||||
|
|
||||||
|
data_rrs = rrs->data;
|
||||||
|
len_rrs = _dns_get_rr_head(data_rrs, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
|
||||||
|
if (len_rrs <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data_rrs += len_rrs;
|
||||||
|
|
||||||
|
if (rr_len != DNS_RR_A_LEN) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = _dns_encode_rr_head(output, size, domain, qtype, qclass, ttl, DNS_RR_A_LEN);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
output += len;
|
||||||
|
total_len += len;
|
||||||
|
|
||||||
|
if (size - total_len < rr_len + DNS_RR_A_LEN) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(output, data_rrs, DNS_RR_A_LEN);
|
||||||
|
output += DNS_RR_A_LEN;
|
||||||
|
data_rrs += DNS_RR_A_LEN;
|
||||||
|
total_len += DNS_RR_A_LEN;
|
||||||
|
|
||||||
|
return total_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _dns_decode_AAAA(unsigned char addr[DNS_RR_AAAA_LEN], unsigned char *data)
|
||||||
|
{
|
||||||
|
memcpy(addr, data, DNS_RR_AAAA_LEN);
|
||||||
|
return DNS_RR_AAAA_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _dns_encode_AAAA(unsigned char *output, int size, struct dns_rrs *rrs)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
int len_rrs;
|
||||||
|
int total_len = 0;
|
||||||
|
int qtype = 0;
|
||||||
|
int qclass = 0;
|
||||||
|
int ttl = 0;
|
||||||
|
char domain[DNS_MAX_CNAME_LEN];
|
||||||
|
unsigned char *data_rrs;
|
||||||
|
int rr_len;
|
||||||
|
|
||||||
|
data_rrs = rrs->data;
|
||||||
|
len_rrs = _dns_get_rr_head(data_rrs, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
|
||||||
|
if (len_rrs <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data_rrs += len_rrs;
|
||||||
|
|
||||||
|
if (rr_len != DNS_RR_AAAA_LEN) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = _dns_encode_rr_head(output, size, domain, qtype, qclass, ttl, DNS_RR_AAAA_LEN);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
output += len;
|
||||||
|
total_len += len;
|
||||||
|
|
||||||
|
if (size - total_len < rr_len + DNS_RR_AAAA_LEN) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(output, data_rrs, DNS_RR_AAAA_LEN);
|
||||||
|
output += DNS_RR_AAAA_LEN;
|
||||||
|
data_rrs += DNS_RR_AAAA_LEN;
|
||||||
|
total_len += DNS_RR_AAAA_LEN;
|
||||||
|
|
||||||
|
return total_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _dns_decode_qd(struct dns_packet *packet, unsigned char *data, int size)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
int decode_len = 0;
|
||||||
|
int qtype = 0;
|
||||||
|
int qclass = 0;
|
||||||
|
char domain[DNS_MAX_CNAME_LEN];
|
||||||
|
|
||||||
|
int ttl;
|
||||||
|
int rr_len;
|
||||||
|
len = _dns_decode_qr_head(data, size, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
decode_len += len;
|
||||||
|
|
||||||
|
len = dns_add_domain(packet, domain, qtype, qclass);
|
||||||
|
if ( len <= 0 ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return decode_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _dns_decode_an(struct dns_packet *packet, unsigned char *data, int size)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
int qtype = 0;
|
||||||
|
int qclass = 0;
|
||||||
|
int ttl;
|
||||||
|
int rr_len = 0;
|
||||||
|
char domain[DNS_MAX_CNAME_LEN];
|
||||||
|
int decode_len = 0;
|
||||||
|
|
||||||
|
len = _dns_decode_rr_head(data, size, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass, &ttl, &rr_len);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
data += len;
|
||||||
|
decode_len += len;
|
||||||
|
switch (qtype) {
|
||||||
|
case DNS_T_A: {
|
||||||
|
unsigned char addr[DNS_RR_A_LEN];
|
||||||
|
len = _dns_decode_A(addr, data);
|
||||||
|
if (len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data += len;
|
||||||
|
decode_len += len;
|
||||||
|
len = dns_add_A(packet, domain, ttl, addr);
|
||||||
|
if (len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case DNS_T_AAAA: {
|
||||||
|
unsigned char addr[DNS_RR_AAAA_LEN];
|
||||||
|
len = _dns_decode_AAAA(addr, data);
|
||||||
|
if (len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data += len;
|
||||||
|
decode_len += len;
|
||||||
|
len = dns_add_AAAA(packet, domain, ttl, addr);
|
||||||
|
if (len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*domain = *data;
|
|
||||||
domain++;
|
return decode_len;
|
||||||
data++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*qtype = *((unsigned short *)(data));
|
int _dns_encode_qd(unsigned char *data, int size, struct dns_rrs *rrs)
|
||||||
data += 2;
|
{
|
||||||
|
int len;
|
||||||
*qclass = *((unsigned short *)(data));
|
int len_rrs;
|
||||||
data += 2;
|
int qtype = 0;
|
||||||
|
int qclass = 0;
|
||||||
return 0;
|
int total_len = 0;
|
||||||
|
char domain[DNS_MAX_CNAME_LEN];
|
||||||
|
unsigned char *data_rrs = rrs->data;
|
||||||
|
len_rrs = _dns_get_qr_head(data_rrs, domain, DNS_MAX_CNAME_LEN, &qtype, &qclass);
|
||||||
|
if (len_rrs <= 0) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_decode_body(struct dns_packet *packet, unsigned char *data, int size)
|
len = _dns_encode_qr_head(data, size, domain, qtype, qclass);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
total_len += len;
|
||||||
|
|
||||||
|
return total_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _dns_encode_an(unsigned char *data, int size, struct dns_rrs *rrs)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
int total_len = 0;
|
||||||
|
switch (rrs->type) {
|
||||||
|
case DNS_T_A: {
|
||||||
|
len = _dns_encode_A(data, size, rrs);
|
||||||
|
if (len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
total_len += len;
|
||||||
|
} break;
|
||||||
|
case DNS_T_AAAA:
|
||||||
|
len = _dns_encode_AAAA(data, size, rrs);
|
||||||
|
if (len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
total_len += len;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _dns_decode_body(struct dns_packet *packet, unsigned char *data, int size)
|
||||||
{
|
{
|
||||||
struct dns_head *head = &packet->head;
|
struct dns_head *head = &packet->head;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int decode_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++) {
|
for (i = 0; i < head->qdcount; i++) {
|
||||||
len = dns_decode_qd(data, size - decode_len, name, DNS_MAX_CNAME_LEN, &qtype, &qclass);
|
len = _dns_decode_qd(packet, data, size - decode_len);
|
||||||
if (dns_add_domain(packet, name, qtype, qclass) != 0) {
|
if (len <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
head->qdcount--;
|
head->qdcount--;
|
||||||
@@ -377,62 +825,114 @@ int dns_decode_body(struct dns_packet *packet, unsigned char *data, int size)
|
|||||||
data += len;
|
data += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < head->ancount; i++) {
|
||||||
|
len = _dns_decode_an(packet, data, size - decode_len);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
head->ancount--;
|
||||||
|
decode_len += len;
|
||||||
|
data += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return decode_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _dns_encode_body(unsigned char *data, int size, struct dns_packet *packet)
|
||||||
|
{
|
||||||
|
struct dns_head *head = &packet->head;
|
||||||
|
int i = 0;
|
||||||
|
int len = 0;
|
||||||
|
int encode_len = 0;
|
||||||
|
struct dns_rrs *rrs;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
rrs = dns_get_rrs_start(packet, DNS_RRS_QD, &count);
|
||||||
|
head->qdcount = count;
|
||||||
|
for (i = 0; i < count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
||||||
|
len = _dns_encode_qd(data, size - encode_len, rrs);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
encode_len += len;
|
||||||
|
data += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
rrs = dns_get_rrs_start(packet, DNS_RRS_AN, &count);
|
||||||
|
head->ancount = count;
|
||||||
|
for (i = 0; i < count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
||||||
|
len = _dns_encode_an(data, size - encode_len, rrs);
|
||||||
|
if (len <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
encode_len += len;
|
||||||
|
data += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return encode_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dns_packet_init(struct dns_packet *packet, int size, struct dns_head *head)
|
||||||
|
{
|
||||||
|
struct dns_head *init_head = &packet->head;
|
||||||
|
memset(packet, 0, size);
|
||||||
|
packet->size = size;
|
||||||
|
init_head->id = head->id;
|
||||||
|
init_head->qr = head->qr;
|
||||||
|
init_head->opcode = head->opcode;
|
||||||
|
init_head->aa = head->aa;
|
||||||
|
init_head->tc = 0;
|
||||||
|
init_head->rd = head->rd;
|
||||||
|
init_head->ra = head->ra;
|
||||||
|
init_head->rcode = head->rcode;
|
||||||
|
packet->questions = DNS_RR_END;
|
||||||
|
packet->answers = DNS_RR_END;
|
||||||
|
packet->nameservers = DNS_RR_END;
|
||||||
|
packet->additional = DNS_RR_END;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_decode(struct dns_packet *packet, unsigned char *data, int size)
|
int dns_decode(struct dns_packet *packet, int maxsize, unsigned char *data, int size)
|
||||||
{
|
{
|
||||||
struct dns_head *head = &packet->head;
|
struct dns_head *head = &packet->head;
|
||||||
int decode_len = 0;
|
int decode_len = 0;
|
||||||
int ret = 0;
|
int len = 0;
|
||||||
|
|
||||||
decode_len = dns_decode_head(head, &data);
|
memset(packet, 0, sizeof(*packet));
|
||||||
ret = dns_decode_body(packet, data, size - decode_len);
|
dns_packet_init(packet, maxsize, head);
|
||||||
|
len = _dns_decode_head(head, data);
|
||||||
struct dns_rrs *rrs;
|
if (len < 0) {
|
||||||
int count = 0;
|
return -1;
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
rrs = dns_rr_get_start(packet, DNS_RR_QD, &count);
|
|
||||||
for (i = 0; i < count && rrs; i++, rrs = dns_rr_get_next(packet, rrs)) {
|
|
||||||
char name[128];
|
|
||||||
int qclass = 0;
|
|
||||||
int qtype = 0;
|
|
||||||
|
|
||||||
dns_get_domain(rrs, name, 128, &qtype, &qclass);
|
|
||||||
|
|
||||||
printf("QR: %d, domain: %s, qtype = %d, qclass = %d\n", head->qr, name, qtype, qclass);
|
|
||||||
}
|
}
|
||||||
|
data += len;
|
||||||
|
decode_len += len;
|
||||||
|
|
||||||
return ret;
|
len = _dns_decode_body(packet, data, size - decode_len);
|
||||||
|
if (len < 0) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
decode_len += len;
|
||||||
|
|
||||||
int dns_packet_init(struct dns_packet *packet, int size)
|
return decode_len;
|
||||||
{
|
|
||||||
memset(packet, 0, size);
|
|
||||||
packet->size = size;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_encode(unsigned char *data, int size, struct dns_packet *packet)
|
int dns_encode(unsigned char *data, int size, struct dns_packet *packet)
|
||||||
{
|
{
|
||||||
int rc;
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
int total_len = 0;
|
||||||
|
|
||||||
len = dns_encode_head(&data, &packet->head);
|
len = _dns_encode_head(data, size, &packet->head);
|
||||||
|
if (len <= 0) {
|
||||||
while (1) {
|
return -1;
|
||||||
len = dns_encode_domain(data, size, "www.baidu.com");
|
}
|
||||||
data += len;
|
data += len;
|
||||||
dns_write_short(&data, /*qType*/ 12);
|
total_len += len;
|
||||||
dns_write_short(&data, /*qClass*/ 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
len = _dns_encode_body(data, size - len, packet);
|
||||||
rc |= dns_encode_resource_records(packet->answers, data);
|
if (len <= 0) {
|
||||||
rc |= dns_encode_resource_records(packet->nameservers, data);
|
return -1;
|
||||||
rc |= dns_encode_resource_records(packet->additional, data);
|
}
|
||||||
*/
|
total_len += len;
|
||||||
return rc;
|
return total_len;
|
||||||
}
|
}
|
||||||
107
dns.h
107
dns.h
@@ -14,7 +14,15 @@
|
|||||||
#define RA_MASK 0x8000
|
#define RA_MASK 0x8000
|
||||||
#define RCODE_MASK 0x000F
|
#define RCODE_MASK 0x000F
|
||||||
|
|
||||||
typedef enum dns_section { DNS_S_QD = 0x01, DNS_S_AN = 0x02, DNS_S_NS = 0x04, DNS_S_AR = 0x08, DNS_S_ALL = 0x0f } dns_section_t;
|
#define DNS_RR_A_LEN 4
|
||||||
|
#define DNS_RR_AAAA_LEN 16
|
||||||
|
|
||||||
|
#define DNS_RRS_QD 0
|
||||||
|
#define DNS_RRS_AN 1
|
||||||
|
#define DNS_RRS_NS 2
|
||||||
|
#define DNS_RRS_NR 3
|
||||||
|
|
||||||
|
#define DNS_RR_END (-1)
|
||||||
|
|
||||||
typedef enum dns_class { DNS_C_IN = 1, DNS_C_ANY = 255 } dns_class_t;
|
typedef enum dns_class { DNS_C_IN = 1, DNS_C_ANY = 255 } dns_class_t;
|
||||||
|
|
||||||
@@ -63,10 +71,10 @@ struct dns_head {
|
|||||||
unsigned short id; // identification number
|
unsigned short id; // identification number
|
||||||
unsigned short qr; /* Query/Response Flag */
|
unsigned short qr; /* Query/Response Flag */
|
||||||
unsigned short opcode; /* Operation Code */
|
unsigned short opcode; /* Operation Code */
|
||||||
unsigned short aa; /* Authoritative Answer Flag */
|
unsigned char aa; /* Authoritative Answer Flag */
|
||||||
unsigned short tc; /* Truncation Flag */
|
unsigned char tc; /* Truncation Flag */
|
||||||
unsigned short rd; /* Recursion Desired */
|
unsigned char rd; /* Recursion Desired */
|
||||||
unsigned short ra; /* Recursion Available */
|
unsigned char ra; /* Recursion Available */
|
||||||
unsigned short rcode; /* Response Code */
|
unsigned short rcode; /* Response Code */
|
||||||
unsigned short qdcount; // number of question entries
|
unsigned short qdcount; // number of question entries
|
||||||
unsigned short ancount; // number of answer entries
|
unsigned short ancount; // number of answer entries
|
||||||
@@ -74,77 +82,6 @@ struct dns_head {
|
|||||||
unsigned short nrcount; // number of addititional resource entries
|
unsigned short nrcount; // number of addititional resource entries
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct dns_qds {
|
|
||||||
unsigned short type;
|
|
||||||
unsigned short classes;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef uint32_t TTL;
|
|
||||||
|
|
||||||
typedef struct dns_question_t /* RFC-1035 */
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
dns_type_t type;
|
|
||||||
dns_class_t class;
|
|
||||||
} dns_question_t;
|
|
||||||
|
|
||||||
typedef struct dns_generic_t /* RFC-1035 */
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
dns_type_t type;
|
|
||||||
dns_class_t class;
|
|
||||||
TTL ttl;
|
|
||||||
} dns_generic_t;
|
|
||||||
|
|
||||||
typedef struct dns_a_t /* RFC-1035 */
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
dns_type_t type;
|
|
||||||
dns_class_t class;
|
|
||||||
TTL ttl;
|
|
||||||
in_addr_t address;
|
|
||||||
} dns_a_t;
|
|
||||||
|
|
||||||
typedef struct dns_aaaa_t /* RFC-1886 */
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
dns_type_t type;
|
|
||||||
dns_class_t class;
|
|
||||||
TTL ttl;
|
|
||||||
struct in6_addr address;
|
|
||||||
} dns_aaaa_t;
|
|
||||||
|
|
||||||
typedef struct dns_cname_t /* RFC-1035 */
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
dns_type_t type;
|
|
||||||
dns_class_t class;
|
|
||||||
TTL ttl;
|
|
||||||
const char *cname;
|
|
||||||
} dns_cname_t;
|
|
||||||
|
|
||||||
typedef struct dns_ptr_t /* RFC-1035 */
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
dns_type_t type;
|
|
||||||
dns_class_t class;
|
|
||||||
TTL ttl;
|
|
||||||
const char *ptr;
|
|
||||||
} dns_ptr_t;
|
|
||||||
|
|
||||||
typedef union dns_answer_t {
|
|
||||||
dns_generic_t generic;
|
|
||||||
dns_a_t a;
|
|
||||||
dns_cname_t cname;
|
|
||||||
dns_ptr_t ptr;
|
|
||||||
dns_aaaa_t aaaa;
|
|
||||||
} dns_answer_t;
|
|
||||||
|
|
||||||
#define DNS_RR_QD 0
|
|
||||||
#define DNS_RR_AN 1
|
|
||||||
#define DNS_RR_NS 2
|
|
||||||
#define DNS_RR_NR 3
|
|
||||||
|
|
||||||
struct dns_rrs {
|
struct dns_rrs {
|
||||||
unsigned short next;
|
unsigned short next;
|
||||||
unsigned short len;
|
unsigned short len;
|
||||||
@@ -163,18 +100,26 @@ struct dns_packet {
|
|||||||
unsigned char data[0];
|
unsigned char data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
int dns_decode(struct dns_packet *packet, unsigned char *data, int size);
|
struct dns_rrs *dns_get_rrs_next(struct dns_packet *packet, struct dns_rrs *rrs);
|
||||||
|
|
||||||
int dns_encode(unsigned char *data, int size, struct dns_packet *packet);
|
struct dns_rrs *dns_get_rrs_start(struct dns_packet *packet, int type, int *count);
|
||||||
|
|
||||||
int dns_packet_init(struct dns_packet *packet, int size);
|
int dns_add_A(struct dns_packet *packet, char *domain, int ttl, unsigned char addr[4]);
|
||||||
|
|
||||||
|
int dns_get_A(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[4]);
|
||||||
|
|
||||||
|
int dns_add_AAAA(struct dns_packet *packet, char *domain, int ttl, unsigned char addr[16]);
|
||||||
|
|
||||||
|
int dns_get_AAAA(struct dns_rrs *rrs, char *domain, int maxsize, int *ttl, unsigned char addr[16]);
|
||||||
|
|
||||||
int dns_get_domain(struct dns_rrs *rrs, char *domain, int maxsize, int *qtype, int *qclass);
|
int dns_get_domain(struct dns_rrs *rrs, char *domain, int maxsize, int *qtype, int *qclass);
|
||||||
|
|
||||||
int dns_add_domain(struct dns_packet *packet, char *domain, int qtype, int qclass);
|
int dns_add_domain(struct dns_packet *packet, char *domain, int qtype, int qclass);
|
||||||
|
|
||||||
struct dns_rrs *dns_rr_get_next(struct dns_packet *packet, struct dns_rrs *rrs);
|
int dns_decode(struct dns_packet *packet, int maxsize, unsigned char *data, int size);
|
||||||
|
|
||||||
struct dns_rrs *dns_rr_get_start(struct dns_packet *packet, int type, int *count);
|
int dns_encode(unsigned char *data, int size, struct dns_packet *packet);
|
||||||
|
|
||||||
|
int dns_packet_init(struct dns_packet *packet, int size, struct dns_head *head);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
56
dns_server.c
56
dns_server.c
@@ -1,6 +1,6 @@
|
|||||||
#include "dns_server.h"
|
#include "dns_server.h"
|
||||||
#include "hashtable.h"
|
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
|
#include "hashtable.h"
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <linux/filter.h>
|
#include <linux/filter.h>
|
||||||
@@ -46,6 +46,36 @@ static void tv_sub(struct timeval *out, struct timeval *in)
|
|||||||
|
|
||||||
void _dns_server_period_run()
|
void _dns_server_period_run()
|
||||||
{
|
{
|
||||||
|
unsigned char packet_data[DNS_INPACKET_SIZE];
|
||||||
|
unsigned char data[DNS_INPACKET_SIZE];
|
||||||
|
|
||||||
|
struct dns_packet *packet = (struct dns_packet *)packet_data;
|
||||||
|
|
||||||
|
struct dns_head head;
|
||||||
|
memset(&head, 0, sizeof(head));
|
||||||
|
head.rcode = 0;
|
||||||
|
head.qr = 0;
|
||||||
|
head.ra = 1;
|
||||||
|
head.id = 1;
|
||||||
|
|
||||||
|
int len;
|
||||||
|
struct sockaddr_in to;
|
||||||
|
socklen_t to_len = sizeof(to);
|
||||||
|
|
||||||
|
dns_packet_init(packet, DNS_INPACKET_SIZE, &head);
|
||||||
|
dns_add_domain(packet, "www.baidu.com", 1, 1);
|
||||||
|
len = dns_encode(data, DNS_INPACKET_SIZE, packet);
|
||||||
|
|
||||||
|
memset(&to, 0, sizeof(to));
|
||||||
|
to.sin_addr.s_addr = inet_addr("192.168.1.1");
|
||||||
|
to.sin_port = htons(53);
|
||||||
|
|
||||||
|
len = sendto(server.fd, data, len, 0, (struct sockaddr *)&to, to_len);
|
||||||
|
if (len < 0) {
|
||||||
|
printf("send failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("send %d\n", len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _dns_server_process(struct timeval *now)
|
static int _dns_server_process(struct timeval *now)
|
||||||
@@ -63,12 +93,26 @@ static int _dns_server_process(struct timeval *now)
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_packet_init(packet, sizeof(rsppacket));
|
dns_decode(packet, DNS_INPACKET_SIZE, inpacket, len);
|
||||||
dns_decode(packet, inpacket, len);
|
|
||||||
|
|
||||||
printf("head.id = %d\n", packet->head.id);
|
int count;
|
||||||
printf("head.an_count = %d\n", packet->head.ancount);
|
struct dns_rrs *rrs;
|
||||||
printf("head.qd_count = %d\n", packet->head.qdcount);
|
char name[128];
|
||||||
|
int i = 0;
|
||||||
|
int ttl;
|
||||||
|
|
||||||
|
rrs = dns_get_rrs_start(packet, DNS_RRS_AN, &count);
|
||||||
|
for (i = 0; i < count && rrs; i++, rrs = dns_get_rrs_next(packet, rrs)) {
|
||||||
|
switch (rrs->type) {
|
||||||
|
case DNS_T_A: {
|
||||||
|
unsigned char addr[4];
|
||||||
|
dns_get_A(rrs, name, 128, &ttl, addr);
|
||||||
|
printf("%s %d : %d.%d.%d.%d\n", name, ttl, addr[0], addr[1], addr[2], addr[3]);
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
errout:
|
errout:
|
||||||
|
|||||||
Reference in New Issue
Block a user