From 7a2378763af1b240ac943a3d499f792bde48d02a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Philipp=20T=C3=B6lke?= Date: Mon, 28 Jun 2010 12:37:43 +0000 Subject: [PATCH] vpn: tcp-natting in one direction untested and most likly unworking code --- src/vpn/Makefile | 14 ++++- src/vpn/packet.c | 14 ++--- src/vpn/packet.h | 2 +- src/vpn/tcp.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++ src/vpn/tcp.h | 8 +++ src/vpn/test.c | 3 + 6 files changed, 176 insertions(+), 11 deletions(-) create mode 100644 src/vpn/tcp.c create mode 100644 src/vpn/tcp.h diff --git a/src/vpn/Makefile b/src/vpn/Makefile index 783c66d92..d2d4342bb 100644 --- a/src/vpn/Makefile +++ b/src/vpn/Makefile @@ -3,11 +3,19 @@ CXXFLAGS = ${CFLAGS} LDFLAGS = -all:default +.PHONY: .dependencies -default: test +all: default -test: test.o tun.o packet.o debug.o pretty-print.o +default: .dependencies test + +test: test.o tun.o packet.o debug.o pretty-print.o tcp.o + +.dependencies: + echo > .dependencies + gcc -M *.c >> .dependencies + +-include .dependencies clean: rm -f *.o diff --git a/src/vpn/packet.c b/src/vpn/packet.c index 37ce44863..2d52dbc81 100644 --- a/src/vpn/packet.c +++ b/src/vpn/packet.c @@ -9,12 +9,12 @@ #include "debug.h" #include "packet.h" -long payload(struct ip6_pkt* pkt) {{{ - return (pkt->hdr.paylgth[0] << 8) + pkt->hdr.paylgth[1]; +long payload(struct ip6_hdr* hdr) {{{ + return (hdr->paylgth[0] << 8) + hdr->paylgth[1]; }}} void send_pkt(int fd, struct ip6_pkt* pkt) {{{ - int sz = payload(pkt); + int sz = payload(&(pkt->hdr)); int w = 0; char* buf = (char*)malloc(sz+40); @@ -120,8 +120,8 @@ struct ip6_pkt* parse_ip6(struct pkt_tun* pkt) {{{ pkt6->hdr.dadr[w] = pkt->data[24+w]; } - pkt6->data = (unsigned char*)malloc(payload(pkt6)); - memcpy(pkt6->data, pkt->data+40, payload(pkt6)); + pkt6->data = (unsigned char*)malloc(payload(&(pkt6->hdr))); + memcpy(pkt6->data, pkt->data+40, payload(&(pkt6->hdr))); return pkt6; }}} @@ -150,8 +150,8 @@ struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt* pkt) {{{ res->data.opt = (unsigned char*) malloc((res->data.off - 5)*4); memcpy(res->data.opt, pkt->data+20, (res->data.off - 5)*4); - res->data.data = (unsigned char*) malloc(payload(pkt) - 4*(res->data.off)); - memcpy(res->data.data, pkt->data+4*(res->data.off), payload(pkt) - 4*(res->data.off)); + res->data.data = (unsigned char*) malloc(payload(&(pkt->hdr)) - 4*(res->data.off)); + memcpy(res->data.data, pkt->data+4*(res->data.off), payload(&(pkt->hdr)) - 4*(res->data.off)); return res; }}} diff --git a/src/vpn/packet.h b/src/vpn/packet.h index 504690936..4044eecb0 100644 --- a/src/vpn/packet.h +++ b/src/vpn/packet.h @@ -45,6 +45,6 @@ extern struct ip6_pkt* parse_ip6(struct pkt_tun* pkt); struct ip6_tcp* parse_ip6_tcp(struct ip6_pkt*); -extern long payload(struct ip6_pkt* pkt); +extern long payload(struct ip6_hdr* pkt); #endif diff --git a/src/vpn/tcp.c b/src/vpn/tcp.c new file mode 100644 index 000000000..cd40f280a --- /dev/null +++ b/src/vpn/tcp.c @@ -0,0 +1,146 @@ +#include "debug.h" +#include "packet.h" +#include "tcp.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct le { + int spt, dpt; + + unsigned char sadr[16]; + unsigned char dadr[16]; + + int socket; + + struct le* next; +}; + +static struct le* le_head = 0; + +static int look_for_child(struct ip6_tcp* pkt) { + struct le* cur; + + for(cur = le_head; cur != 0; cur = cur->next) { + if (cur->spt == pkt->data.spt &&/*{{{*/ + cur->dpt == pkt->data.spt && + cur->sadr[0] == pkt->hdr.sadr[0] && + cur->sadr[1] == pkt->hdr.sadr[1] && + cur->sadr[2] == pkt->hdr.sadr[2] && + cur->sadr[3] == pkt->hdr.sadr[3] && + cur->sadr[4] == pkt->hdr.sadr[4] && + cur->sadr[5] == pkt->hdr.sadr[5] && + cur->sadr[6] == pkt->hdr.sadr[6] && + cur->sadr[7] == pkt->hdr.sadr[7] && + cur->sadr[8] == pkt->hdr.sadr[8] && + cur->sadr[9] == pkt->hdr.sadr[9] && + cur->sadr[10] == pkt->hdr.sadr[10] && + cur->sadr[11] == pkt->hdr.sadr[11] && + cur->sadr[12] == pkt->hdr.sadr[12] && + cur->sadr[13] == pkt->hdr.sadr[13] && + cur->sadr[14] == pkt->hdr.sadr[14] && + cur->sadr[15] == pkt->hdr.sadr[15] && + + cur->dadr[0] == pkt->hdr.dadr[0] && + cur->dadr[1] == pkt->hdr.dadr[1] && + cur->dadr[2] == pkt->hdr.dadr[2] && + cur->dadr[3] == pkt->hdr.dadr[3] && + cur->dadr[4] == pkt->hdr.dadr[4] && + cur->dadr[5] == pkt->hdr.dadr[5] && + cur->dadr[6] == pkt->hdr.dadr[6] && + cur->dadr[7] == pkt->hdr.dadr[7] && + cur->dadr[8] == pkt->hdr.dadr[8] && + cur->dadr[9] == pkt->hdr.dadr[9] && + cur->dadr[10] == pkt->hdr.dadr[10] && + cur->dadr[11] == pkt->hdr.dadr[11] && + cur->dadr[12] == pkt->hdr.dadr[12] && + cur->dadr[13] == pkt->hdr.dadr[13] && + cur->dadr[14] == pkt->hdr.dadr[14] && + cur->dadr[15] == pkt->hdr.dadr[15])/*}}}*/ + return cur->socket; + } + return -1; +} + +static struct le* new_le() {{{ + struct le* res = (struct le*) malloc(sizeof(struct le)); + + struct le** cur; + + for(cur = &le_head; *cur != 0; cur = &((*cur)->next)) {} + + *cur = res; + + return res; +}}} + +static int nat(struct ip6_tcp* pkt) {{{ + unsigned char adr1[] = { 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; + unsigned char adr2[] = { 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}; + + if (strncmp((char*)adr1, (char*)pkt->hdr.dadr, 16)) { + int sock = socket(AF_INET, SOCK_STREAM, 0); + struct sockaddr_in info; + memset(&info, 0, sizeof(info)); + + info.sin_family = AF_INET; + info.sin_port = pkt->data.dpt; + inet_pton(AF_INET, "94.142.241.111", &info.sin_addr.s_addr); + + connect(sock, (const struct sockaddr*)&info, sizeof(info)); + return sock; + } else if (strncmp((char*)adr2, (char*)pkt->hdr.dadr, 16)) { + int sock = socket(AF_INET6, SOCK_STREAM, 0); + + struct sockaddr_in6 info; + memset(&info, 0, sizeof(info)); + + info.sin6_family = AF_INET6; + info.sin6_port = pkt->data.dpt; + + inet_pton(AF_INET6, "2a02:898:17:8000::42", info.sin6_addr.s6_addr); + + connect(sock, (const struct sockaddr*)&info, sizeof(info)); + + return sock; + } + return -1; +}}} + +void handle_tcp(struct ip6_tcp* pkt) { + signal(SIGCHLD, SIG_IGN); + + int fd = look_for_child(pkt); + + if (fd == -1) { + struct le* le = new_le(); + le->spt = pkt->data.spt; + le->dpt = pkt->data.dpt; + + memcpy(le->sadr, pkt->hdr.sadr, 16); + memcpy(le->dadr, pkt->hdr.dadr, 16); + + le->socket = nat(pkt); + fd = le->socket; + } + + int size = payload((&pkt->hdr)) - pkt->data.off; + + int w = 0; + while (size > 0) { + w = write(fd, pkt->data.data, size - w); + if (w < 0) { + debug(1, 0, "writing: %s\n", strerror(errno)); + } else { + size -= w; + } + } +} diff --git a/src/vpn/tcp.h b/src/vpn/tcp.h new file mode 100644 index 000000000..c933b1b4c --- /dev/null +++ b/src/vpn/tcp.h @@ -0,0 +1,8 @@ +#ifndef _GNTUN_TCP_H_ +#define _GNTUN_TCP_H_ + +#include "packet.h" + +extern void handle_tcp(struct ip6_tcp*); + +#endif diff --git a/src/vpn/test.c b/src/vpn/test.c index acdf4249a..3672b9df2 100644 --- a/src/vpn/test.c +++ b/src/vpn/test.c @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -8,6 +9,7 @@ #include "tun.h" #include "debug.h" #include "pretty-print.h" +#include "tcp.h" int main(int c, char** v) { char dev[IFNAMSIZ]; @@ -32,6 +34,7 @@ int main(int c, char** v) { pkt_printf(pkt6); struct ip6_tcp* pkt6_tcp = parse_ip6_tcp(pkt6); pkt_printf_ip6tcp(pkt6_tcp); + handle_tcp(pkt6_tcp); break; } break; -- 2.25.1