mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-26 10:09:19 +02:00
rewrote READ* and PUT*; in read.c, handeling malformed compression of names
This commit is contained in:
parent
eb9f38f2e0
commit
4a9887c9df
86
dns.c
86
dns.c
|
@ -32,18 +32,20 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "read.h"
|
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
|
#include "read.h"
|
||||||
|
|
||||||
// For FreeBSD
|
// For FreeBSD
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int host2dns(const char *, char *, int);
|
static int host2dns(const char *, char *, int);
|
||||||
static int dns_write(int, int, char *, int, char);
|
static int dns_write(int, int, char *, int, char);
|
||||||
|
static void dns_query(int, int, char *, int);
|
||||||
|
|
||||||
struct sockaddr_in peer;
|
struct sockaddr_in peer;
|
||||||
char topdomain[256];
|
char topdomain[256];
|
||||||
|
@ -68,7 +70,8 @@ open_dns(const char *domain, int localport, in_addr_t listen_ip)
|
||||||
bzero(&addr, sizeof(addr));
|
bzero(&addr, sizeof(addr));
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(localport);
|
addr.sin_port = htons(localport);
|
||||||
addr.sin_addr.s_addr = listen_ip; // This is already network byte order, inet_addr() or constant INADDR_ANY (==0)
|
/* listen_ip already in network byte order from inet_addr, or 0 */
|
||||||
|
addr.sin_addr.s_addr = listen_ip;
|
||||||
|
|
||||||
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if(fd < 0) {
|
if(fd < 0) {
|
||||||
|
@ -88,10 +91,11 @@ open_dns(const char *domain, int localport, in_addr_t listen_ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save top domain used
|
// Save top domain used
|
||||||
strncpy(topdomain, domain, sizeof(topdomain) - 2);
|
strncpy(topdomain, domain, sizeof(topdomain) - 1);
|
||||||
topdomain[sizeof(topdomain) - 1] = 0;
|
topdomain[sizeof(topdomain) - 1] = '\0';
|
||||||
|
|
||||||
printf("Opened UDP socket\n");
|
printf("Opened UDP socket\n");
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +181,7 @@ dns_handshake(int dns_fd)
|
||||||
dns_write(dns_fd, ++pingid, data, 2, 'H');
|
dns_write(dns_fd, ++pingid, data, 2, 'H');
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
char *p;
|
||||||
|
@ -205,16 +209,16 @@ dns_query(int fd, int id, char *host, int type)
|
||||||
p = buf + sizeof(HEADER);
|
p = buf + sizeof(HEADER);
|
||||||
p += host2dns(host, p, strlen(host));
|
p += host2dns(host, p, strlen(host));
|
||||||
|
|
||||||
PUTSHORT(type, p);
|
putshort(&p, type);
|
||||||
PUTSHORT(C_IN, p);
|
putshort(&p, C_IN);
|
||||||
|
|
||||||
// EDNS0
|
// EDNS0
|
||||||
*p++ = 0x00; //Root
|
putbyte(&p, 0x00); //Root
|
||||||
PUTSHORT(0x0029, p); // OPT
|
putshort(&p, 0x0029); // OPT
|
||||||
PUTSHORT(0x1000, p); // Payload size: 4096
|
putshort(&p, 0x1000); // Payload size: 4096
|
||||||
PUTSHORT(0x0000, p); // Higher bits/ edns version
|
putshort(&p, 0x0000); // Higher bits/edns version
|
||||||
PUTSHORT(0x8000, p); // Z
|
putshort(&p, 0x8000); // Z
|
||||||
PUTSHORT(0x0000, p); // Data length
|
putshort(&p, 0x0000); // Data length
|
||||||
|
|
||||||
peerlen = sizeof(peer);
|
peerlen = sizeof(peer);
|
||||||
|
|
||||||
|
@ -250,6 +254,7 @@ int
|
||||||
dns_read(int fd, char *buf, int buflen)
|
dns_read(int fd, char *buf, int buflen)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
int rv;
|
||||||
long ttl;
|
long ttl;
|
||||||
short rlen;
|
short rlen;
|
||||||
short type;
|
short type;
|
||||||
|
@ -267,6 +272,7 @@ dns_read(int fd, char *buf, int buflen)
|
||||||
addrlen = sizeof(struct sockaddr);
|
addrlen = sizeof(struct sockaddr);
|
||||||
r = recvfrom(fd, packet, sizeof(packet), 0, (struct sockaddr*)&from, &addrlen);
|
r = recvfrom(fd, packet, sizeof(packet), 0, (struct sockaddr*)&from, &addrlen);
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
perror("recvfrom");
|
perror("recvfrom");
|
||||||
} else {
|
} else {
|
||||||
|
@ -281,17 +287,17 @@ dns_read(int fd, char *buf, int buflen)
|
||||||
rlen = 0;
|
rlen = 0;
|
||||||
|
|
||||||
if(qdcount == 1) {
|
if(qdcount == 1) {
|
||||||
READNAME(packet, name, data);
|
readname(packet, &data, name, sizeof(name));
|
||||||
READSHORT(type, data);
|
readshort(packet, &data, &type);
|
||||||
READSHORT(class, data);
|
readshort(packet, &data, &class);
|
||||||
}
|
}
|
||||||
if(ancount == 1) {
|
if(ancount == 1) {
|
||||||
READNAME(packet, name, data);
|
readname(packet, &data, name, sizeof(name));
|
||||||
READSHORT(type, data);
|
readshort(packet, &data, &type);
|
||||||
READSHORT(class, data);
|
readshort(packet, &data, &class);
|
||||||
READLONG(ttl, data);
|
readlong(packet, &data, &ttl);
|
||||||
READSHORT(rlen, data);
|
readshort(packet, &data, &rlen);
|
||||||
READDATA(rdata, data, rlen);
|
readdata(packet, &data, rdata, rlen);
|
||||||
}
|
}
|
||||||
if (dns_sending() && chunkid == ntohs(header->id)) {
|
if (dns_sending() && chunkid == ntohs(header->id)) {
|
||||||
// Got ACK on sent packet
|
// Got ACK on sent packet
|
||||||
|
@ -309,14 +315,12 @@ dns_read(int fd, char *buf, int buflen)
|
||||||
|
|
||||||
if(type == T_NULL && rlen > 2) {
|
if(type == T_NULL && rlen > 2) {
|
||||||
memcpy(buf, rdata, rlen);
|
memcpy(buf, rdata, rlen);
|
||||||
return rlen;
|
rv = rlen;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -375,19 +379,18 @@ dnsd_send(int fd, struct query *q, char *data, int datalen)
|
||||||
|
|
||||||
name = 0xc000 | ((p - buf) & 0x3fff);
|
name = 0xc000 | ((p - buf) & 0x3fff);
|
||||||
p += host2dns(q->name, p, strlen(q->name));
|
p += host2dns(q->name, p, strlen(q->name));
|
||||||
PUTSHORT(q->type, p);
|
putshort(&p, q->type);
|
||||||
PUTSHORT(C_IN, p);
|
putshort(&p, C_IN);
|
||||||
|
|
||||||
PUTSHORT(name, p);
|
putshort(&p, name);
|
||||||
PUTSHORT(q->type, p);
|
putshort(&p, q->type);
|
||||||
PUTSHORT(C_IN, p);
|
putshort(&p, C_IN);
|
||||||
PUTLONG(0, p);
|
putlong(&p, 0);
|
||||||
|
|
||||||
q->id = 0;
|
q->id = 0;
|
||||||
|
|
||||||
PUTSHORT(datalen, p);
|
putshort(&p, datalen);
|
||||||
memcpy(p, data, datalen);
|
putdata(&p, data, datalen);
|
||||||
p += datalen;
|
|
||||||
|
|
||||||
len = p - buf;
|
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);
|
||||||
|
@ -411,6 +414,7 @@ int
|
||||||
dnsd_read(int fd, struct query *q, char *buf, int buflen)
|
dnsd_read(int fd, struct query *q, char *buf, int buflen)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
int rv;
|
||||||
short id;
|
short id;
|
||||||
short type;
|
short type;
|
||||||
short class;
|
short class;
|
||||||
|
@ -436,10 +440,9 @@ 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) {
|
||||||
bzero(name, sizeof(name));
|
readname(packet, &data, name, sizeof(name));
|
||||||
READNAME(packet, name, data);
|
readshort(packet, &data, &type);
|
||||||
READSHORT(type, data);
|
readshort(packet, &data, &class);
|
||||||
READSHORT(class, data);
|
|
||||||
|
|
||||||
strncpy(q->name, name, 256);
|
strncpy(q->name, name, 256);
|
||||||
q->type = type;
|
q->type = type;
|
||||||
|
@ -447,12 +450,13 @@ dnsd_read(int fd, struct query *q, char *buf, int buflen)
|
||||||
q->fromlen = addrlen;
|
q->fromlen = addrlen;
|
||||||
memcpy((struct sockaddr*)&q->from, (struct sockaddr*)&from, addrlen);
|
memcpy((struct sockaddr*)&q->from, (struct sockaddr*)&from, addrlen);
|
||||||
|
|
||||||
return decodepacket(name, buf, buflen);
|
rv = decodepacket(name, buf, buflen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
perror("recvfrom");
|
perror("recvfrom");
|
||||||
|
rv = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
1
dns.h
1
dns.h
|
@ -25,7 +25,6 @@ int dns_sending();
|
||||||
void dns_handle_tun(int, char *, int);
|
void dns_handle_tun(int, char *, int);
|
||||||
void dns_ping(int);
|
void dns_ping(int);
|
||||||
void dns_handshake(int);
|
void dns_handshake(int);
|
||||||
void dns_query(int, int, char *, int);
|
|
||||||
int dns_read(int, char *, int);
|
int dns_read(int, char *, int);
|
||||||
|
|
||||||
extern struct sockaddr_in peer;
|
extern struct sockaddr_in peer;
|
||||||
|
|
125
read.c
125
read.c
|
@ -17,38 +17,129 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
readname(char *packet, char *dst, char *src)
|
readname(char *packet, char **src, char *dst, size_t length)
|
||||||
{
|
{
|
||||||
char l;
|
char *dummy;
|
||||||
int len;
|
int len;
|
||||||
int offset;
|
char *p;
|
||||||
|
char c;
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
|
|
||||||
while(*src) {
|
p = *src;
|
||||||
l = *src++;
|
|
||||||
len++;
|
|
||||||
|
|
||||||
if(l & 0x80 && l & 0x40) {
|
p = *src;
|
||||||
offset = ((src[-1] & 0x3f) << 8) | src[0];
|
while(*p && len < length) {
|
||||||
readname(packet, dst, packet + offset);
|
c = *p++;
|
||||||
dst += strlen(dst);
|
|
||||||
|
/* is this a compressed label? */
|
||||||
|
if((c & 0xc0) == 0xc0) {
|
||||||
|
dummy = packet + (((p[-1] & 0x3f) << 8) | p[0]);
|
||||||
|
readname(packet, &dummy, dst, length - len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(l) {
|
while(c && len < length) {
|
||||||
*dst++ = *src++;
|
*dst++ = *p++;
|
||||||
l--;
|
|
||||||
len++;
|
len++;
|
||||||
|
|
||||||
|
c--;
|
||||||
}
|
}
|
||||||
|
|
||||||
*dst++ = '.';
|
if (*p != 0)
|
||||||
|
*dst = '.';
|
||||||
|
else
|
||||||
|
*dst = '\0';
|
||||||
}
|
}
|
||||||
|
(*src) = p+1;
|
||||||
|
|
||||||
*dst = '\0';
|
return strlen(dst);
|
||||||
src++;
|
}
|
||||||
len++;
|
|
||||||
|
int
|
||||||
|
readshort(char *packet, char **src, short *dst)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = *src;
|
||||||
|
*dst = ((short)p[0] << 8)
|
||||||
|
| ((short)p[1]);
|
||||||
|
|
||||||
|
(*src) += sizeof(short);
|
||||||
|
return sizeof(short);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
readlong(char *packet, char **src, long *dst)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = *src;
|
||||||
|
|
||||||
|
*dst = ((long)p[0] << 24)
|
||||||
|
| ((long)p[1] << 16)
|
||||||
|
| ((long)p[2] << 8)
|
||||||
|
| ((long)p[3]);
|
||||||
|
|
||||||
|
(*src) += sizeof(long);
|
||||||
|
return sizeof(long);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
readdata(char *packet, char **src, char *dst, size_t len)
|
||||||
|
{
|
||||||
|
memcpy(dst, *src, len);
|
||||||
|
|
||||||
|
(*src) += len;
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
putbyte(char **dst, char value)
|
||||||
|
{
|
||||||
|
**dst = value;
|
||||||
|
(*dst)++;
|
||||||
|
|
||||||
|
return sizeof(char);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
putshort(char **dst, short value)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = *dst;
|
||||||
|
|
||||||
|
*p++ = (value >> 8);
|
||||||
|
*p++ = value;
|
||||||
|
|
||||||
|
(*dst) = p;
|
||||||
|
return sizeof(short);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
putlong(char **dst, long value)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = *dst;
|
||||||
|
|
||||||
|
*p++ = (value >> 24);
|
||||||
|
*p++ = (value >> 16);
|
||||||
|
*p++ = (value >> 8);
|
||||||
|
*p++ = (value);
|
||||||
|
|
||||||
|
(*dst) = p;
|
||||||
|
return sizeof(long);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
putdata(char **dst, char *data, size_t len)
|
||||||
|
{
|
||||||
|
memcpy(*dst, data, len);
|
||||||
|
|
||||||
|
(*dst) += len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
21
read.h
21
read.h
|
@ -17,19 +17,14 @@
|
||||||
#ifndef _READ_H_
|
#ifndef _READ_H_
|
||||||
#define _READ_H_
|
#define _READ_H_
|
||||||
|
|
||||||
int readname(char *, char *, char *);
|
int readname(char *, char **, char *, size_t);
|
||||||
|
int readshort(char *, char **, short *);
|
||||||
|
int readlong(char *, char **, long *);
|
||||||
|
int readdata(char *, char **, char *, size_t);
|
||||||
|
|
||||||
#define READNAME(packet, dst, src) (src) += readname((packet), (dst), (src));
|
int putbyte(char **, char);
|
||||||
|
int putshort(char **, short);
|
||||||
#define READSHORT(dst, src) \
|
int putlong(char **, long);
|
||||||
memcpy(&dst, src, 2); \
|
int putdata(char **, char *, size_t);
|
||||||
(dst) = ntohs(dst); (src)+=2;
|
|
||||||
|
|
||||||
#define READLONG(dst, src) \
|
|
||||||
memcpy(&dst, src, 2); \
|
|
||||||
(dst) = ntohl(dst); (src)+=4;
|
|
||||||
|
|
||||||
#define READDATA(dst, src, len) \
|
|
||||||
memcpy((dst), (src), (len)); (src)+=(len);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue