first try on send functionality

This commit is contained in:
Erik Ekman 2006-06-05 20:05:11 +00:00
parent f701f3c6ca
commit 9bb84fe05d
4 changed files with 104 additions and 14 deletions

89
dns.c
View File

@ -35,6 +35,13 @@ static int host2dns(const char *, char *, int);
struct sockaddr_in peer; struct sockaddr_in peer;
char topdomain[256]; char topdomain[256];
// Current IP packet
char activepacket[4096];
int lastlen;
int packetpos;
int packetlen;
uint16_t chunkid;
static int static int
readname(char *packet, char *dst, char *src) readname(char *packet, char *dst, char *src)
{ {
@ -128,6 +135,9 @@ open_dns(const char *host, const char *domain)
strncpy(topdomain, domain, sizeof(topdomain) - 2); strncpy(topdomain, domain, sizeof(topdomain) - 2);
topdomain[sizeof(topdomain) - 1] = 0; topdomain[sizeof(topdomain) - 1] = 0;
// Init chunk id
chunkid = 0;
return fd; return fd;
} }
@ -137,12 +147,77 @@ close_dns(int fd)
close(fd); close(fd);
} }
int
dns_sending()
{
return (packetlen != 0);
}
static void
dns_send_chunk(int fd)
{
int avail;
char *p;
p = activepacket;
p += packetpos;
avail = packetlen - packetpos;
lastlen = dns_write(fd, ++chunkid, p, avail);
printf("Sent %d bytes of %d remaining\n", lastlen, avail);
}
void
dns_handle_tun(int fd, char *data, int len)
{
memcpy(activepacket, data, MIN(len, sizeof(activepacket)));
lastlen = 0;
packetpos = 0;
packetlen = len;
dns_send_chunk(fd);
}
static int
dns_handle_reply(int fd, char *data, int len)
{
uint16_t id;
char *p;
p = data;
READSHORT(id, p);
// Handle ACKing
if (dns_sending() && id == chunkid) {
// Got ACK on sent packet
packetpos += lastlen;
if (packetpos == packetlen) {
// Packet completed
printf("IP packet size %d sent successfully!\n", packetlen);
packetpos = 0;
packetlen = 0;
lastlen = 0;
} else {
// More to send
dns_send_chunk(fd);
}
}
// Detect if any data is attached
// TODO
return 0;
}
void void
dns_ping(int dns_fd) dns_ping(int dns_fd)
{ {
dns_write(dns_fd, dns_fd, if (dns_sending()) {
"AAAAAAAAAAAKRYOAAAAAAAAAAAKRYOAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAAAAAAB", // Resend latest chunk
119); printf("No reply on chunk, resending\n");
dns_send_chunk(dns_fd);
} else {
dns_write(dns_fd, dns_fd, "\0", 1);
}
} }
void void
@ -178,7 +253,7 @@ dns_query(int fd, int id, char *host, int type)
peerlen = sizeof(peer); peerlen = sizeof(peer);
len = p - buf; len = p - buf;
sendto(fd, buf, len+1, 0, (struct sockaddr*)&peer, peerlen); sendto(fd, buf, len, 0, (struct sockaddr*)&peer, peerlen);
} }
int int
@ -248,7 +323,7 @@ dns_read(int fd, char *buf, int buflen)
printf("Read %d bytes DNS reply\n", r); printf("Read %d bytes DNS reply\n", r);
if(r == -1) { if(r == -1) {
perror("recvfrom"); perror("recv");
} else { } else {
header = (HEADER*)packet; header = (HEADER*)packet;
@ -277,8 +352,10 @@ dns_read(int fd, char *buf, int buflen)
READSHORT(port, r); READSHORT(port, r);
READNAME(packet, host, r); READNAME(packet, host, r);
} }
printf("%s\n", name); // printf("%s\n", name);
} }
// Is any data attached?
return dns_handle_reply(fd, packet, r);
} }
} }

4
dns.h
View File

@ -17,11 +17,11 @@
#ifndef _DNS_H_ #ifndef _DNS_H_
#define _DNS_H_ #define _DNS_H_
extern struct sockaddr_in peer;
int open_dns(const char *, const char *); int open_dns(const char *, const char *);
void close_dns(int); void close_dns(int);
int dns_sending();
void dns_handle_tun(int, char *, int);
void dns_ping(int); void dns_ping(int);
void dns_query(int, int, char *, int); void dns_query(int, int, char *, int);
int dns_write(int, int, char *, int); int dns_write(int, int, char *, int);

9
dnsd.c
View File

@ -150,7 +150,7 @@ host2dns(const char *host, char *buffer, int size)
} }
static void static void
dnsd_respond(int fd, struct sockaddr_in from) dnsd_respond(int fd, short id, struct sockaddr_in from)
{ {
int len; int len;
int size; int size;
@ -163,7 +163,7 @@ dnsd_respond(int fd, struct sockaddr_in from)
len = 0; len = 0;
header = (HEADER*)buf; header = (HEADER*)buf;
header->id = 0; header->id = id;
header->qr = 1; header->qr = 1;
header->opcode = 0; header->opcode = 0;
header->aa = 1; header->aa = 1;
@ -194,6 +194,7 @@ dnsd_read(int fd, char *buf, int buflen)
{ {
int i; int i;
int r; int r;
short id;
short type; short type;
short class; short class;
short qdcount; short qdcount;
@ -214,6 +215,8 @@ dnsd_read(int fd, char *buf, int buflen)
} else { } else {
header = (HEADER*)packet; header = (HEADER*)packet;
id = ntohs(header->id);
data = packet + sizeof(HEADER); data = packet + sizeof(HEADER);
if(!header->qr) { if(!header->qr) {
@ -227,7 +230,7 @@ dnsd_read(int fd, char *buf, int buflen)
printf("%s %d %d\n", name, type, class); printf("%s %d %d\n", name, type, class);
dnsd_respond(fd, from); dnsd_respond(fd, id, from);
} }
} }
} }

View File

@ -41,7 +41,7 @@ tunnel(int tun_fd, int dns_fd)
int i; int i;
int read; int read;
fd_set fds; fd_set fds;
char buf[1024]; char buf[4096];
struct timeval tv; struct timeval tv;
while (running) { while (running) {
@ -49,7 +49,9 @@ tunnel(int tun_fd, int dns_fd)
tv.tv_usec = 0; tv.tv_usec = 0;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(tun_fd, &fds); if (!dns_sending()) {
FD_SET(tun_fd, &fds);
}
FD_SET(dns_fd, &fds); FD_SET(dns_fd, &fds);
i = select(MAX(tun_fd, dns_fd) + 1, &fds, NULL, NULL, &tv); i = select(MAX(tun_fd, dns_fd) + 1, &fds, NULL, NULL, &tv);
@ -65,10 +67,18 @@ tunnel(int tun_fd, int dns_fd)
dns_ping(dns_fd); dns_ping(dns_fd);
} else { } else {
if(FD_ISSET(tun_fd, &fds)) { if(FD_ISSET(tun_fd, &fds)) {
read = read_tun(tun_fd, buf, sizeof(buf));
if (read > 0) {
printf("Got data on tun! %d bytes\n", read);
dns_handle_tun(dns_fd, buf, read);
}
} }
if(FD_ISSET(dns_fd, &fds)) { if(FD_ISSET(dns_fd, &fds)) {
read = dns_read(dns_fd, buf, sizeof(buf)); read = dns_read(dns_fd, buf, sizeof(buf));
if (read > 0) {
printf("Got data on dns! %d bytes\n", read);
write_tun(tun_fd, buf, read);
}
} }
} }
} }