Release 0.3.4
This commit is contained in:
parent
2b6054a939
commit
1defd22a20
12
CHANGELOG
12
CHANGELOG
|
@ -7,9 +7,17 @@ iodine - IP over DNS is now easy
|
||||||
|
|
||||||
CHANGES:
|
CHANGES:
|
||||||
|
|
||||||
2006-11-06: 0.3.3
|
2006-11-08: 0.3.4
|
||||||
|
- Fixed handshake() buffer overflow
|
||||||
|
(Found by poplix, Secunia: SA22674 / FrSIRT/ADV-2006-4333)
|
||||||
|
- Added more tests
|
||||||
|
- More name parsing enhancements
|
||||||
|
- Now runs on Linux/AMD64
|
||||||
|
- Added setting to change server port
|
||||||
|
|
||||||
|
2006-11-05: 0.3.3
|
||||||
- Fixed possible buffer overflow
|
- Fixed possible buffer overflow
|
||||||
(Found by poplix)
|
(Found by poplix, Bugtraq ID: 20883)
|
||||||
- Reworked dns hostname encoding
|
- Reworked dns hostname encoding
|
||||||
|
|
||||||
2006-09-11: 0.3.2
|
2006-09-11: 0.3.2
|
||||||
|
|
17
README
17
README
|
@ -73,13 +73,22 @@ can be max 63 chars. So your domain name and subdomain should be as short as
|
||||||
possible to allow maximum throughput.
|
possible to allow maximum throughput.
|
||||||
|
|
||||||
|
|
||||||
|
TIPS & TRICKS:
|
||||||
|
|
||||||
|
If your port 53 is taken on a specific interface by an application that does
|
||||||
|
not use it, use -p on iodined to specify an alternate port (like -p 5353) and
|
||||||
|
use for instance iptables (on Linux) to forward the traffic:
|
||||||
|
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to :5353
|
||||||
|
(Sent in by Tom Schouten)
|
||||||
|
|
||||||
|
|
||||||
PORTABILITY:
|
PORTABILITY:
|
||||||
|
|
||||||
iodine has been tested on Linux (x86 and SPARC64), FreeBSD (x86), OpenBSD (x86),
|
iodine has been tested on Linux (x86, AMD64 and SPARC64), FreeBSD (x86),
|
||||||
NetBSD (x86) and MacOS X (10.3, ppc, with
|
OpenBSD (x86), NetBSD (x86) and MacOS X (10.3, ppc, with
|
||||||
http://www-user.rhrk.uni-kl.de/~nissler/tuntap/). It should work on other
|
http://www-user.rhrk.uni-kl.de/~nissler/tuntap/). It should work on other
|
||||||
unix-like systems as well that has TUN/TAP tunneling support. Let us know if you
|
unix-like systems as well that has TUN/TAP tunneling support (after some
|
||||||
get it to run on other platforms.
|
patching). Let us know if you get it to run on other platforms.
|
||||||
|
|
||||||
|
|
||||||
THE NAME:
|
THE NAME:
|
||||||
|
|
19
dns.c
19
dns.c
|
@ -26,6 +26,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -66,7 +67,7 @@ open_dns(const char *domain, int localport, in_addr_t listen_ip)
|
||||||
int flag;
|
int flag;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
bzero(&addr, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(localport);
|
addr.sin_port = htons(localport);
|
||||||
/* listen_ip already in network byte order from inet_addr, or 0 */
|
/* listen_ip already in network byte order from inet_addr, or 0 */
|
||||||
|
@ -110,7 +111,7 @@ dns_settarget(const char *host)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bzero(&peer, sizeof(peer));
|
memset(&peer, 0, sizeof(peer));
|
||||||
peer.sin_family = AF_INET;
|
peer.sin_family = AF_INET;
|
||||||
peer.sin_port = htons(53);
|
peer.sin_port = htons(53);
|
||||||
peer.sin_addr = *((struct in_addr *) h->h_addr);
|
peer.sin_addr = *((struct in_addr *) h->h_addr);
|
||||||
|
@ -235,7 +236,7 @@ dns_write(int fd, int id, char *buf, int len, char flag)
|
||||||
char *d;
|
char *d;
|
||||||
|
|
||||||
avail = 0xFF - strlen(topdomain) - 2;
|
avail = 0xFF - strlen(topdomain) - 2;
|
||||||
bzero(data, sizeof(data));
|
memset(data, 0, sizeof(data));
|
||||||
d = data;
|
d = data;
|
||||||
written = encode_data(buf, len, avail, d, flag);
|
written = encode_data(buf, len, avail, d, flag);
|
||||||
encoded = strlen(data);
|
encoded = strlen(data);
|
||||||
|
@ -286,7 +287,7 @@ int
|
||||||
dns_parse_reply(char *outbuf, int buflen, char *packet, int packetlen)
|
dns_parse_reply(char *outbuf, int buflen, char *packet, int packetlen)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
long ttl;
|
uint32_t ttl;
|
||||||
short rlen;
|
short rlen;
|
||||||
short type;
|
short type;
|
||||||
short class;
|
short class;
|
||||||
|
@ -309,12 +310,12 @@ dns_parse_reply(char *outbuf, int buflen, char *packet, int packetlen)
|
||||||
rlen = 0;
|
rlen = 0;
|
||||||
|
|
||||||
if(qdcount == 1) {
|
if(qdcount == 1) {
|
||||||
readname(packet, &data, name, sizeof(name));
|
readname(packet, packetlen, &data, name, sizeof(name));
|
||||||
readshort(packet, &data, &type);
|
readshort(packet, &data, &type);
|
||||||
readshort(packet, &data, &class);
|
readshort(packet, &data, &class);
|
||||||
}
|
}
|
||||||
if(ancount == 1) {
|
if(ancount == 1) {
|
||||||
readname(packet, &data, name, sizeof(name));
|
readname(packet, packetlen, &data, name, sizeof(name));
|
||||||
readshort(packet, &data, &type);
|
readshort(packet, &data, &type);
|
||||||
readshort(packet, &data, &class);
|
readshort(packet, &data, &class);
|
||||||
readlong(packet, &data, &ttl);
|
readlong(packet, &data, &ttl);
|
||||||
|
@ -455,7 +456,7 @@ dnsd_read(int fd, struct query *q, char *buf, int buflen)
|
||||||
qdcount = ntohs(header->qdcount);
|
qdcount = ntohs(header->qdcount);
|
||||||
|
|
||||||
if(qdcount == 1) {
|
if(qdcount == 1) {
|
||||||
readname(packet, &data, name, sizeof(name) -1);
|
readname(packet, r, &data, name, sizeof(name) -1);
|
||||||
name[256] = 0;
|
name[256] = 0;
|
||||||
readshort(packet, &data, &type);
|
readshort(packet, &data, &type);
|
||||||
readshort(packet, &data, &class);
|
readshort(packet, &data, &class);
|
||||||
|
@ -469,9 +470,11 @@ dnsd_read(int fd, struct query *q, char *buf, int buflen)
|
||||||
rv = decodepacket(name, buf, buflen);
|
rv = decodepacket(name, buf, buflen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (r < 0) { // Error
|
||||||
perror("recvfrom");
|
perror("recvfrom");
|
||||||
rv = 0;
|
rv = 0;
|
||||||
|
} else { // Packet too small to be dns protocol
|
||||||
|
rv = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -127,6 +127,7 @@ encode_data(char *buf, int len, int space, char *dest, char flag)
|
||||||
chunks = write / RAW_CHUNK;
|
chunks = write / RAW_CHUNK;
|
||||||
leftovers = write % RAW_CHUNK;
|
leftovers = write % RAW_CHUNK;
|
||||||
|
|
||||||
|
// flag is special character to be placed first in the encoded data
|
||||||
if (flag != 0) {
|
if (flag != 0) {
|
||||||
*dest = flag;
|
*dest = flag;
|
||||||
} else {
|
} else {
|
||||||
|
@ -135,7 +136,7 @@ encode_data(char *buf, int len, int space, char *dest, char flag)
|
||||||
}
|
}
|
||||||
dest++;
|
dest++;
|
||||||
|
|
||||||
bzero(encoded, sizeof(encoded));
|
memset(encoded, 0, sizeof(encoded));
|
||||||
ep = encoded;
|
ep = encoded;
|
||||||
dp = buf;
|
dp = buf;
|
||||||
for (i = 0; i < chunks; i++) {
|
for (i = 0; i < chunks; i++) {
|
||||||
|
@ -144,7 +145,7 @@ encode_data(char *buf, int len, int space, char *dest, char flag)
|
||||||
dp += RAW_CHUNK;
|
dp += RAW_CHUNK;
|
||||||
}
|
}
|
||||||
realwrite = ENC_CHUNK * chunks;
|
realwrite = ENC_CHUNK * chunks;
|
||||||
bzero(padding, sizeof(padding));
|
memset(padding, 0, sizeof(padding));
|
||||||
pp = padding;
|
pp = padding;
|
||||||
if (leftovers) {
|
if (leftovers) {
|
||||||
pp += RAW_CHUNK - leftovers;
|
pp += RAW_CHUNK - leftovers;
|
||||||
|
@ -187,7 +188,7 @@ decode_data(char *dest, int size, const char *src, char *srcend)
|
||||||
dest++;
|
dest++;
|
||||||
src++;
|
src++;
|
||||||
|
|
||||||
bzero(encoded, sizeof(encoded));
|
memset(encoded, 0, sizeof(encoded));
|
||||||
ep = encoded;
|
ep = encoded;
|
||||||
while(len < size && src < srcend) {
|
while(len < size && src < srcend) {
|
||||||
if(*src == '.') {
|
if(*src == '.') {
|
||||||
|
|
22
iodine.c
22
iodine.c
|
@ -112,8 +112,8 @@ static int
|
||||||
handshake(int dns_fd)
|
handshake(int dns_fd)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
char server[128];
|
char server[65];
|
||||||
char client[128];
|
char client[65];
|
||||||
char in[4096];
|
char in[4096];
|
||||||
int timeout;
|
int timeout;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
|
@ -144,12 +144,20 @@ handshake(int dns_fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
if (sscanf(in, "%[^-]-%[^-]-%d",
|
if (sscanf(in, "%64[^-]-%64[^-]-%d",
|
||||||
server, client, &mtu) == 3) {
|
server, client, &mtu) == 3) {
|
||||||
if (tun_setip(client) == 0 && tun_setmtu(mtu) == 0)
|
|
||||||
|
server[64] = 0;
|
||||||
|
client[64] = 0;
|
||||||
|
if (tun_setip(client) == 0 &&
|
||||||
|
tun_setmtu(mtu) == 0) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
else
|
} else {
|
||||||
warn("Received handshake but b0rk");
|
warn("Received handshake with bad data");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("Received bad handshake\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,7 +198,7 @@ help() {
|
||||||
static void
|
static void
|
||||||
version() {
|
version() {
|
||||||
printf("iodine IP over DNS tunneling client\n");
|
printf("iodine IP over DNS tunneling client\n");
|
||||||
printf("version: 0.3.3 from 2006-11-05\n");
|
printf("version: 0.3.4 from 2006-11-08\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
iodined.c
22
iodined.c
|
@ -111,7 +111,7 @@ tunnel(int tun_fd, int dns_fd)
|
||||||
}
|
}
|
||||||
if(FD_ISSET(dns_fd, &fds)) {
|
if(FD_ISSET(dns_fd, &fds)) {
|
||||||
read = dnsd_read(dns_fd, &q, in, sizeof(in));
|
read = dnsd_read(dns_fd, &q, in, sizeof(in));
|
||||||
if (read < 0)
|
if (read <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(in[0] == 'H' || in[0] == 'h') {
|
if(in[0] == 'H' || in[0] == 'h') {
|
||||||
|
@ -168,8 +168,8 @@ static void
|
||||||
usage() {
|
usage() {
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
|
|
||||||
printf("Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] [-m mtu] [-l ip address to listen on] "
|
printf("Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] [-m mtu] [-l ip address to listen on] [-p port]"
|
||||||
"tunnel_ip topdomain\n", __progname);
|
" tunnel_ip topdomain\n", __progname);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,8 +178,8 @@ help() {
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
|
|
||||||
printf("iodine IP over DNS tunneling server\n");
|
printf("iodine IP over DNS tunneling server\n");
|
||||||
printf("Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] [-m mtu] [-l ip address to listen on] "
|
printf("Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] [-m mtu] [-l ip address to listen on] [-p port]"
|
||||||
"tunnel_ip topdomain\n", __progname);
|
" tunnel_ip topdomain\n", __progname);
|
||||||
printf(" -v to print version info and exit\n");
|
printf(" -v to print version info and exit\n");
|
||||||
printf(" -h to print this help and exit\n");
|
printf(" -h to print this help and exit\n");
|
||||||
printf(" -f to keep running in foreground\n");
|
printf(" -f to keep running in foreground\n");
|
||||||
|
@ -188,6 +188,7 @@ help() {
|
||||||
printf(" -d device to set tunnel device name\n");
|
printf(" -d device to set tunnel device name\n");
|
||||||
printf(" -m mtu to set tunnel device mtu\n");
|
printf(" -m mtu to set tunnel device mtu\n");
|
||||||
printf(" -l ip address to listen on for incoming dns traffic (default 0.0.0.0)\n");
|
printf(" -l ip address to listen on for incoming dns traffic (default 0.0.0.0)\n");
|
||||||
|
printf(" -p port to listen on for incoming dns traffic (default 53)\n");
|
||||||
printf("tunnel_ip is the IP number of the local tunnel interface.\n");
|
printf("tunnel_ip is the IP number of the local tunnel interface.\n");
|
||||||
printf("topdomain is the FQDN that is delegated to this server.\n");
|
printf("topdomain is the FQDN that is delegated to this server.\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -196,7 +197,7 @@ help() {
|
||||||
static void
|
static void
|
||||||
version() {
|
version() {
|
||||||
printf("iodine IP over DNS tunneling server\n");
|
printf("iodine IP over DNS tunneling server\n");
|
||||||
printf("version: 0.3.3 from 2006-11-05\n");
|
printf("version: 0.3.4 from 2006-11-08\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +214,7 @@ main(int argc, char **argv)
|
||||||
int mtu;
|
int mtu;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
in_addr_t listen_ip;
|
in_addr_t listen_ip;
|
||||||
|
int port;
|
||||||
|
|
||||||
username = NULL;
|
username = NULL;
|
||||||
newroot = NULL;
|
newroot = NULL;
|
||||||
|
@ -220,13 +222,14 @@ main(int argc, char **argv)
|
||||||
foreground = 0;
|
foreground = 0;
|
||||||
mtu = 1024;
|
mtu = 1024;
|
||||||
listen_ip = INADDR_ANY;
|
listen_ip = INADDR_ANY;
|
||||||
|
port = 53;
|
||||||
|
|
||||||
packetbuf.len = 0;
|
packetbuf.len = 0;
|
||||||
packetbuf.offset = 0;
|
packetbuf.offset = 0;
|
||||||
outpacket.len = 0;
|
outpacket.len = 0;
|
||||||
q.id = 0;
|
q.id = 0;
|
||||||
|
|
||||||
while ((choice = getopt(argc, argv, "vfhu:t:d:m:l:")) != -1) {
|
while ((choice = getopt(argc, argv, "vfhu:t:d:m:l:p:")) != -1) {
|
||||||
switch(choice) {
|
switch(choice) {
|
||||||
case 'v':
|
case 'v':
|
||||||
version();
|
version();
|
||||||
|
@ -252,6 +255,9 @@ main(int argc, char **argv)
|
||||||
case 'l':
|
case 'l':
|
||||||
listen_ip = inet_addr(optarg);
|
listen_ip = inet_addr(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
|
port = atoi(optarg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
break;
|
break;
|
||||||
|
@ -291,7 +297,7 @@ main(int argc, char **argv)
|
||||||
goto cleanup0;
|
goto cleanup0;
|
||||||
if (tun_setip(argv[0]) != 0 || tun_setmtu(mtu) != 0)
|
if (tun_setip(argv[0]) != 0 || tun_setmtu(mtu) != 0)
|
||||||
goto cleanup1;
|
goto cleanup1;
|
||||||
if ((dnsd_fd = open_dns(argv[1], 53, listen_ip)) == -1)
|
if ((dnsd_fd = open_dns(argv[1], port, listen_ip)) == -1)
|
||||||
goto cleanup2;
|
goto cleanup2;
|
||||||
|
|
||||||
my_ip = inet_addr(argv[0]);
|
my_ip = inet_addr(argv[0]);
|
||||||
|
|
42
read.c
42
read.c
|
@ -15,14 +15,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
static int
|
static int
|
||||||
readname_loop(char *packet, char **src, char *dst, size_t length, size_t loop)
|
readname_loop(char *packet, int packetlen, char **src, char *dst, size_t length, size_t loop)
|
||||||
{
|
{
|
||||||
char *dummy;
|
char *dummy;
|
||||||
char *s;
|
char *s;
|
||||||
char *d;
|
char *d;
|
||||||
int len;
|
int len;
|
||||||
|
int offset;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
if (loop <= 0)
|
if (loop <= 0)
|
||||||
|
@ -36,8 +38,18 @@ readname_loop(char *packet, char **src, char *dst, size_t length, size_t loop)
|
||||||
|
|
||||||
/* is this a compressed label? */
|
/* is this a compressed label? */
|
||||||
if((c & 0xc0) == 0xc0) {
|
if((c & 0xc0) == 0xc0) {
|
||||||
dummy = packet + (((s[-1] & 0x3f) << 8) | s[0]);
|
offset = (((s[-1] & 0x3f) << 8) | (s[0] & 0xff));
|
||||||
len += readname_loop(packet, &dummy, d, length - len, loop - 1);
|
if (offset > packetlen) {
|
||||||
|
if (len == 0) {
|
||||||
|
// Bad jump first in packet
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
// Bad jump after some data
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dummy = packet + offset;
|
||||||
|
len += readname_loop(packet, packetlen, &dummy, d, length - len, loop - 1);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,9 +77,9 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
readname(char *packet, char **src, char *dst, size_t length)
|
readname(char *packet, int packetlen, char **src, char *dst, size_t length)
|
||||||
{
|
{
|
||||||
return readname_loop(packet, src, dst, length, 10);
|
return readname_loop(packet, packetlen, src, dst, length, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -83,19 +95,20 @@ readshort(char *packet, char **src, short *dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
readlong(char *packet, char **src, long *dst)
|
readlong(char *packet, char **src, uint32_t *dst)
|
||||||
{
|
{
|
||||||
|
// A long as described in dns protocol is always 32 bits
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
|
|
||||||
p = *src;
|
p = *src;
|
||||||
|
|
||||||
*dst = ((long)p[0] << 24)
|
*dst = ((uint32_t)p[0] << 24)
|
||||||
| ((long)p[1] << 16)
|
| ((uint32_t)p[1] << 16)
|
||||||
| ((long)p[2] << 8)
|
| ((uint32_t)p[2] << 8)
|
||||||
| ((long)p[3]);
|
| ((uint32_t)p[3]);
|
||||||
|
|
||||||
(*src) += sizeof(long);
|
(*src) += sizeof(uint32_t);
|
||||||
return sizeof(long);
|
return sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -135,8 +148,9 @@ putshort(char **dst, short value)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
putlong(char **dst, long value)
|
putlong(char **dst, uint32_t value)
|
||||||
{
|
{
|
||||||
|
// A long as described in dns protocol is always 32 bits
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
|
|
||||||
p = *dst;
|
p = *dst;
|
||||||
|
@ -147,7 +161,7 @@ putlong(char **dst, long value)
|
||||||
*p++ = (value);
|
*p++ = (value);
|
||||||
|
|
||||||
(*dst) = p;
|
(*dst) = p;
|
||||||
return sizeof(long);
|
return sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
6
read.h
6
read.h
|
@ -17,14 +17,14 @@
|
||||||
#ifndef _READ_H_
|
#ifndef _READ_H_
|
||||||
#define _READ_H_
|
#define _READ_H_
|
||||||
|
|
||||||
int readname(char *, char **, char *, size_t);
|
int readname(char *, int, char **, char *, size_t);
|
||||||
int readshort(char *, char **, short *);
|
int readshort(char *, char **, short *);
|
||||||
int readlong(char *, char **, long *);
|
int readlong(char *, char **, uint32_t *);
|
||||||
int readdata(char *, char **, char *, size_t);
|
int readdata(char *, char **, char *, size_t);
|
||||||
|
|
||||||
int putbyte(char **, char);
|
int putbyte(char **, char);
|
||||||
int putshort(char **, short);
|
int putshort(char **, short);
|
||||||
int putlong(char **, long);
|
int putlong(char **, uint32_t);
|
||||||
int putdata(char **, char *, size_t);
|
int putdata(char **, char *, size_t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
86
test.c
86
test.c
|
@ -23,11 +23,13 @@
|
||||||
#include <arpa/nameser8_compat.h>
|
#include <arpa/nameser8_compat.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
|
#include "encoding.h"
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
#include "read.h"
|
#include "read.h"
|
||||||
|
|
||||||
|
@ -73,10 +75,10 @@ static void
|
||||||
test_readputlong()
|
test_readputlong()
|
||||||
{
|
{
|
||||||
char buf[4];
|
char buf[4];
|
||||||
long putint;
|
uint32_t putint;
|
||||||
long tempi;
|
uint32_t tempi;
|
||||||
long tint;
|
uint32_t tint;
|
||||||
long *l;
|
uint32_t *l;
|
||||||
char* p;
|
char* p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -89,13 +91,13 @@ test_readputlong()
|
||||||
p = buf;
|
p = buf;
|
||||||
putlong(&p, tint);
|
putlong(&p, tint);
|
||||||
l = &putint;
|
l = &putint;
|
||||||
memcpy(l, buf, sizeof(int));
|
memcpy(l, buf, sizeof(uint32_t));
|
||||||
if (putint != tempi) {
|
if (putint != tempi) {
|
||||||
printf("Bad value on putlong for %d\n", i);
|
printf("Bad value on putlong for %d\n", i);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
l = &tempi;
|
l = &tempi;
|
||||||
memcpy(buf, l, sizeof(int));
|
memcpy(buf, l, sizeof(uint32_t));
|
||||||
p = buf;
|
p = buf;
|
||||||
readlong(NULL, &p, &tempi);
|
readlong(NULL, &p, &tempi);
|
||||||
if (tempi != tint) {
|
if (tempi != tint) {
|
||||||
|
@ -129,6 +131,13 @@ test_readname()
|
||||||
char onejump[] =
|
char onejump[] =
|
||||||
"AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
|
"AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
|
||||||
"\x02hh\xc0\x15\x00\x01\x00\x01\x05zBCDE\x00";
|
"\x02hh\xc0\x15\x00\x01\x00\x01\x05zBCDE\x00";
|
||||||
|
char badjump[] = {
|
||||||
|
'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
|
||||||
|
char badjump2[] = {
|
||||||
|
'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 'B', 'A', 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
|
||||||
|
char *jumper;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char *data;
|
char *data;
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -136,29 +145,51 @@ test_readname()
|
||||||
printf(" * Testing readname... ");
|
printf(" * Testing readname... ");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
bzero(buf, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
data = emptyloop + sizeof(HEADER);
|
data = emptyloop + sizeof(HEADER);
|
||||||
buf[1023] = 'A';
|
buf[1023] = 'A';
|
||||||
rv = readname(emptyloop, &data, buf, 1023);
|
rv = readname(emptyloop, sizeof(emptyloop), &data, buf, 1023);
|
||||||
assert(buf[1023] == 'A');
|
assert(buf[1023] == 'A');
|
||||||
|
|
||||||
bzero(buf, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
data = infloop + sizeof(HEADER);
|
data = infloop + sizeof(HEADER);
|
||||||
buf[4] = '\a';
|
buf[4] = '\a';
|
||||||
rv = readname(infloop, &data, buf, 4);
|
rv = readname(infloop, sizeof(infloop), &data, buf, 4);
|
||||||
assert(buf[4] == '\a');
|
assert(buf[4] == '\a');
|
||||||
|
|
||||||
bzero(buf, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
data = longname + sizeof(HEADER);
|
data = longname + sizeof(HEADER);
|
||||||
buf[256] = '\a';
|
buf[256] = '\a';
|
||||||
rv = readname(longname, &data, buf, 256);
|
rv = readname(longname, sizeof(longname), &data, buf, 256);
|
||||||
assert(buf[256] == '\a');
|
assert(buf[256] == '\a');
|
||||||
|
|
||||||
bzero(buf, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
data = onejump + sizeof(HEADER);
|
data = onejump + sizeof(HEADER);
|
||||||
rv = readname(onejump, &data, buf, 256);
|
rv = readname(onejump, sizeof(onejump), &data, buf, 256);
|
||||||
assert(rv == 9);
|
assert(rv == 9);
|
||||||
|
|
||||||
|
// These two tests use malloc to cause segfault if jump is executed
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
jumper = malloc(sizeof(badjump));
|
||||||
|
if (jumper) {
|
||||||
|
memcpy(jumper, badjump, sizeof(badjump));
|
||||||
|
data = jumper + sizeof(HEADER);
|
||||||
|
rv = readname(jumper, sizeof(badjump), &data, buf, 256);
|
||||||
|
assert(rv == 0);
|
||||||
|
}
|
||||||
|
free(jumper);
|
||||||
|
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
jumper = malloc(sizeof(badjump2));
|
||||||
|
if (jumper) {
|
||||||
|
memcpy(jumper, badjump2, sizeof(badjump2));
|
||||||
|
data = jumper + sizeof(HEADER);
|
||||||
|
rv = readname(jumper, sizeof(badjump2), &data, buf, 256);
|
||||||
|
assert(rv == 4);
|
||||||
|
assert(strcmp("BA.", buf) == 0);
|
||||||
|
}
|
||||||
|
free(jumper);
|
||||||
|
|
||||||
printf("OK\n");
|
printf("OK\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +201,7 @@ test_encode_hostname() {
|
||||||
|
|
||||||
len = 256;
|
len = 256;
|
||||||
printf(" * Testing hostname encoding... ");
|
printf(" * Testing hostname encoding... ");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
memset(buf, 0, 256);
|
memset(buf, 0, 256);
|
||||||
ret = dns_encode_hostname( // More than 63 chars between dots
|
ret = dns_encode_hostname( // More than 63 chars between dots
|
||||||
|
@ -189,6 +221,31 @@ test_encode_hostname() {
|
||||||
printf("OK\n");
|
printf("OK\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_base32() {
|
||||||
|
char temp[256];
|
||||||
|
char *start = "HELLOTEST";
|
||||||
|
char *out = "1HELLOTEST";
|
||||||
|
char *end;
|
||||||
|
char *tempend;
|
||||||
|
int codedlength;
|
||||||
|
|
||||||
|
printf(" * Testing base32 encoding... ");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
memset(temp, 0, sizeof(temp));
|
||||||
|
end = malloc(16);
|
||||||
|
memset(end, 0, 16);
|
||||||
|
|
||||||
|
codedlength = encode_data(start, 9, 256, temp, 0);
|
||||||
|
tempend = temp + strlen(temp);
|
||||||
|
decode_data(end, 16, temp, tempend);
|
||||||
|
assert(strcmp(out, end) == 0);
|
||||||
|
free(end);
|
||||||
|
|
||||||
|
printf("OK\n");
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
|
@ -198,6 +255,7 @@ main()
|
||||||
test_readputlong();
|
test_readputlong();
|
||||||
test_readname();
|
test_readname();
|
||||||
test_encode_hostname();
|
test_encode_hostname();
|
||||||
|
test_base32();
|
||||||
|
|
||||||
printf("** All went well :)\n");
|
printf("** All went well :)\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue