refactoring dns, ripped out dns packet generating code, removing dependency on io
This commit is contained in:
parent
c10fa59bbb
commit
e56074b42a
1
TODO
1
TODO
|
@ -19,3 +19,4 @@ STUFF TO DO:
|
||||||
|
|
||||||
- More/better documentation (as always)
|
- More/better documentation (as always)
|
||||||
|
|
||||||
|
- Modify readname to take the actual size of the buffer to fill, and make sure it adds a '\0' at the end. Then clean up dns.c to match the changes.
|
||||||
|
|
158
src/dns.c
158
src/dns.c
|
@ -38,6 +38,9 @@
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
#include "read.h"
|
#include "read.h"
|
||||||
|
|
||||||
|
#define QR_QUERY 0
|
||||||
|
#define QR_ANSWER 1
|
||||||
|
|
||||||
// For FreeBSD
|
// For FreeBSD
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||||
|
@ -195,48 +198,92 @@ dns_send_version(int dns_fd, int version)
|
||||||
dns_write(dns_fd, ++pingid, data, 6, 'V');
|
dns_write(dns_fd, ++pingid, data, 6, 'V');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dns_encode(char *buf, size_t buflen, struct query *q, int qr, char *data, size_t datalen)
|
||||||
|
{
|
||||||
|
HEADER *header;
|
||||||
|
short name;
|
||||||
|
char *p;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
memset(buf, 0, buflen);
|
||||||
|
|
||||||
|
header = (HEADER*)buf;
|
||||||
|
|
||||||
|
header->id = htons(q->id);
|
||||||
|
header->qr = qr;
|
||||||
|
header->opcode = 0;
|
||||||
|
header->aa = (qr == QR_ANSWER);
|
||||||
|
header->tc = 0;
|
||||||
|
header->rd = (qr == QR_QUERY);
|
||||||
|
header->ra = 0;
|
||||||
|
|
||||||
|
p = buf + sizeof(HEADER);
|
||||||
|
|
||||||
|
switch (qr) {
|
||||||
|
case QR_ANSWER:
|
||||||
|
header->ancount = htons(1);
|
||||||
|
header->qdcount = htons(1);
|
||||||
|
|
||||||
|
name = 0xc000 | ((p - buf) & 0x3fff);
|
||||||
|
p += dns_encode_hostname(q->name, p, strlen(q->name));
|
||||||
|
putshort(&p, q->type);
|
||||||
|
putshort(&p, C_IN);
|
||||||
|
|
||||||
|
putshort(&p, name);
|
||||||
|
putshort(&p, q->type);
|
||||||
|
putshort(&p, C_IN);
|
||||||
|
putlong(&p, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: This is jidder! This is used to detect if there's packets to be sent.
|
||||||
|
*/
|
||||||
|
q->id = 0;
|
||||||
|
|
||||||
|
putshort(&p, datalen);
|
||||||
|
putdata(&p, data, datalen);
|
||||||
|
break;
|
||||||
|
case QR_QUERY:
|
||||||
|
header->qdcount = htons(1);
|
||||||
|
header->arcount = htons(1);
|
||||||
|
|
||||||
|
p += dns_encode_hostname(data, p, datalen);
|
||||||
|
|
||||||
|
putshort(&p, q->type);
|
||||||
|
putshort(&p, C_IN);
|
||||||
|
|
||||||
|
// EDNS0
|
||||||
|
putbyte(&p, 0x00); //Root
|
||||||
|
putshort(&p, 0x0029); // OPT
|
||||||
|
putshort(&p, 0x1000); // Payload size: 4096
|
||||||
|
putshort(&p, 0x0000); // Higher bits/edns version
|
||||||
|
putshort(&p, 0x8000); // Z
|
||||||
|
putshort(&p, 0x0000); // Data length
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errx(1, "dns_encode: qr is wrong!!!");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
len = p - buf;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dns_query(int fd, int id, char *host, int type)
|
dns_query(int fd, int id, char *host, int type)
|
||||||
{
|
{
|
||||||
char *p;
|
|
||||||
int len;
|
|
||||||
int peerlen;
|
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
HEADER *header;
|
struct query q;
|
||||||
|
int peerlen;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
q.id = id;
|
||||||
|
q.type = type;
|
||||||
|
|
||||||
len = 0;
|
len = dns_encode(buf, sizeof(buf), &q, QR_QUERY, host, strlen(host));
|
||||||
memset(buf, 0, sizeof(buf));
|
|
||||||
|
|
||||||
header = (HEADER*)buf;
|
|
||||||
|
|
||||||
header->id = htons(id);
|
|
||||||
header->qr = 0;
|
|
||||||
header->opcode = 0;
|
|
||||||
header->aa = 0;
|
|
||||||
header->tc = 0;
|
|
||||||
header->rd = 1;
|
|
||||||
header->ra = 0;
|
|
||||||
|
|
||||||
header->qdcount = htons(1);
|
|
||||||
header->arcount = htons(1);
|
|
||||||
|
|
||||||
p = buf + sizeof(HEADER);
|
|
||||||
p += dns_encode_hostname(host, p, strlen(host));
|
|
||||||
|
|
||||||
putshort(&p, type);
|
|
||||||
putshort(&p, C_IN);
|
|
||||||
|
|
||||||
// EDNS0
|
|
||||||
putbyte(&p, 0x00); //Root
|
|
||||||
putshort(&p, 0x0029); // OPT
|
|
||||||
putshort(&p, 0x1000); // Payload size: 4096
|
|
||||||
putshort(&p, 0x0000); // Higher bits/edns version
|
|
||||||
putshort(&p, 0x8000); // Z
|
|
||||||
putshort(&p, 0x0000); // Data length
|
|
||||||
|
|
||||||
peerlen = sizeof(peer);
|
peerlen = sizeof(peer);
|
||||||
|
|
||||||
len = p - buf;
|
|
||||||
sendto(fd, buf, len, 0, (struct sockaddr*)&peer, peerlen);
|
sendto(fd, buf, len, 0, (struct sockaddr*)&peer, peerlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,49 +428,15 @@ dns_encode_hostname(const char *host, char *buffer, int size)
|
||||||
return p - buffer;
|
return p - buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
dnsd_send(int fd, struct query *q, char *data, int datalen)
|
dnsd_send(int fd, struct query *q, char *data, int datalen)
|
||||||
{
|
{
|
||||||
int len;
|
|
||||||
char *p;
|
|
||||||
char buf[64*1024];
|
char buf[64*1024];
|
||||||
short name;
|
int len;
|
||||||
HEADER *header;
|
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
len = dns_encode(buf, sizeof(buf), q, QR_ANSWER, data, datalen);
|
||||||
|
|
||||||
len = 0;
|
|
||||||
header = (HEADER*)buf;
|
|
||||||
|
|
||||||
header->id = htons(q->id);
|
|
||||||
header->qr = 1;
|
|
||||||
header->opcode = 0;
|
|
||||||
header->aa = 1;
|
|
||||||
header->tc = 0;
|
|
||||||
header->rd = 0;
|
|
||||||
header->ra = 0;
|
|
||||||
|
|
||||||
header->qdcount = htons(1);
|
|
||||||
header->ancount = htons(1);
|
|
||||||
|
|
||||||
p = buf + sizeof(HEADER);
|
|
||||||
|
|
||||||
name = 0xc000 | ((p - buf) & 0x3fff);
|
|
||||||
p += dns_encode_hostname(q->name, p, strlen(q->name));
|
|
||||||
putshort(&p, q->type);
|
|
||||||
putshort(&p, C_IN);
|
|
||||||
|
|
||||||
putshort(&p, name);
|
|
||||||
putshort(&p, q->type);
|
|
||||||
putshort(&p, C_IN);
|
|
||||||
putlong(&p, 0);
|
|
||||||
|
|
||||||
q->id = 0;
|
|
||||||
|
|
||||||
putshort(&p, datalen);
|
|
||||||
putdata(&p, data, datalen);
|
|
||||||
|
|
||||||
len = p - buf;
|
|
||||||
sendto(fd, buf, len, 0, (struct sockaddr*)&q->from, q->fromlen);
|
sendto(fd, buf, len, 0, (struct sockaddr*)&q->from, q->fromlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,3 +507,4 @@ dnsd_read(int fd, struct query *q, char *buf, int buflen)
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue