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;
char topdomain[256];
// Current IP packet
char activepacket[4096];
int lastlen;
int packetpos;
int packetlen;
uint16_t chunkid;
static int
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);
topdomain[sizeof(topdomain) - 1] = 0;
// Init chunk id
chunkid = 0;
return fd;
}
@ -137,12 +147,77 @@ close_dns(int 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
dns_ping(int dns_fd)
{
dns_write(dns_fd, dns_fd,
"AAAAAAAAAAAKRYOAAAAAAAAAAAKRYOAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAAAAAAB",
119);
if (dns_sending()) {
// Resend latest chunk
printf("No reply on chunk, resending\n");
dns_send_chunk(dns_fd);
} else {
dns_write(dns_fd, dns_fd, "\0", 1);
}
}
void
@ -178,7 +253,7 @@ dns_query(int fd, int id, char *host, int type)
peerlen = sizeof(peer);
len = p - buf;
sendto(fd, buf, len+1, 0, (struct sockaddr*)&peer, peerlen);
sendto(fd, buf, len, 0, (struct sockaddr*)&peer, peerlen);
}
int
@ -248,7 +323,7 @@ dns_read(int fd, char *buf, int buflen)
printf("Read %d bytes DNS reply\n", r);
if(r == -1) {
perror("recvfrom");
perror("recv");
} else {
header = (HEADER*)packet;
@ -277,8 +352,10 @@ dns_read(int fd, char *buf, int buflen)
READSHORT(port, 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_
#define _DNS_H_
extern struct sockaddr_in peer;
int open_dns(const char *, const char *);
void close_dns(int);
int dns_sending();
void dns_handle_tun(int, char *, int);
void dns_ping(int);
void dns_query(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
dnsd_respond(int fd, struct sockaddr_in from)
dnsd_respond(int fd, short id, struct sockaddr_in from)
{
int len;
int size;
@ -163,7 +163,7 @@ dnsd_respond(int fd, struct sockaddr_in from)
len = 0;
header = (HEADER*)buf;
header->id = 0;
header->id = id;
header->qr = 1;
header->opcode = 0;
header->aa = 1;
@ -194,6 +194,7 @@ dnsd_read(int fd, char *buf, int buflen)
{
int i;
int r;
short id;
short type;
short class;
short qdcount;
@ -214,6 +215,8 @@ dnsd_read(int fd, char *buf, int buflen)
} else {
header = (HEADER*)packet;
id = ntohs(header->id);
data = packet + sizeof(HEADER);
if(!header->qr) {
@ -227,7 +230,7 @@ dnsd_read(int fd, char *buf, int buflen)
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 read;
fd_set fds;
char buf[1024];
char buf[4096];
struct timeval tv;
while (running) {
@ -49,7 +49,9 @@ tunnel(int tun_fd, int dns_fd)
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(tun_fd, &fds);
if (!dns_sending()) {
FD_SET(tun_fd, &fds);
}
FD_SET(dns_fd, &fds);
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);
} else {
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)) {
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);
}
}
}
}