read the output of the helper
[oweals/gnunet.git] / src / vpn / tcp.c
1 #include "debug.h"
2 #include "packet.h"
3 #include "tcp.h"
4
5 #include <errno.h>
6 #include <netinet/in.h>
7 #include <netinet/ip.h>
8 #include <signal.h>
9 #include <stdlib.h>
10 #include <arpa/inet.h>
11 #include <string.h>
12 #include <sys/socket.h>
13 #include <sys/types.h>
14 #include <unistd.h>
15
16 struct le {
17         int spt, dpt;
18
19         unsigned char sadr[16];
20         unsigned char dadr[16];
21
22         int socket;
23
24         struct le* next;
25 };
26
27 static struct le* le_head = 0;
28
29 static int look_for_child(struct ip6_tcp* pkt) {
30         struct le* cur;
31
32         for(cur = le_head; cur != 0; cur = cur->next) {
33                 if (cur->spt == pkt->data.spt &&/*{{{*/
34                                 cur->dpt == pkt->data.spt &&
35                                 cur->sadr[0] == pkt->hdr.sadr[0] &&
36                                 cur->sadr[1] == pkt->hdr.sadr[1] &&
37                                 cur->sadr[2] == pkt->hdr.sadr[2] &&
38                                 cur->sadr[3] == pkt->hdr.sadr[3] &&
39                                 cur->sadr[4] == pkt->hdr.sadr[4] &&
40                                 cur->sadr[5] == pkt->hdr.sadr[5] &&
41                                 cur->sadr[6] == pkt->hdr.sadr[6] &&
42                                 cur->sadr[7] == pkt->hdr.sadr[7] &&
43                                 cur->sadr[8] == pkt->hdr.sadr[8] &&
44                                 cur->sadr[9] == pkt->hdr.sadr[9] &&
45                                 cur->sadr[10] == pkt->hdr.sadr[10] &&
46                                 cur->sadr[11] == pkt->hdr.sadr[11] &&
47                                 cur->sadr[12] == pkt->hdr.sadr[12] &&
48                                 cur->sadr[13] == pkt->hdr.sadr[13] &&
49                                 cur->sadr[14] == pkt->hdr.sadr[14] &&
50                                 cur->sadr[15] == pkt->hdr.sadr[15] &&
51
52                                 cur->dadr[0] == pkt->hdr.dadr[0] &&
53                                 cur->dadr[1] == pkt->hdr.dadr[1] &&
54                                 cur->dadr[2] == pkt->hdr.dadr[2] &&
55                                 cur->dadr[3] == pkt->hdr.dadr[3] &&
56                                 cur->dadr[4] == pkt->hdr.dadr[4] &&
57                                 cur->dadr[5] == pkt->hdr.dadr[5] &&
58                                 cur->dadr[6] == pkt->hdr.dadr[6] &&
59                                 cur->dadr[7] == pkt->hdr.dadr[7] &&
60                                 cur->dadr[8] == pkt->hdr.dadr[8] &&
61                                 cur->dadr[9] == pkt->hdr.dadr[9] &&
62                                 cur->dadr[10] == pkt->hdr.dadr[10] &&
63                                 cur->dadr[11] == pkt->hdr.dadr[11] &&
64                                 cur->dadr[12] == pkt->hdr.dadr[12] &&
65                                 cur->dadr[13] == pkt->hdr.dadr[13] &&
66                                 cur->dadr[14] == pkt->hdr.dadr[14] &&
67                                 cur->dadr[15] == pkt->hdr.dadr[15])/*}}}*/
68                         return cur->socket;
69         }
70         return -1;
71 }
72
73 static struct le* new_le() {{{
74         struct le* res = (struct le*) malloc(sizeof(struct le));
75
76         struct le** cur;
77
78         for(cur = &le_head; *cur != 0; cur = &((*cur)->next)) {}
79
80         *cur = res;
81
82         return res;
83 }}}
84
85 static int nat(struct ip6_tcp* pkt) {{{
86         unsigned char adr1[] = { 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
87         unsigned char adr2[] = { 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
88
89         if (strncmp((char*)adr1, (char*)pkt->hdr.dadr, 16)) {
90                 int sock = socket(AF_INET, SOCK_STREAM, 0);
91                 struct sockaddr_in info;
92                 memset(&info, 0, sizeof(info));
93
94                 info.sin_family = AF_INET;
95                 info.sin_port = pkt->data.dpt;
96                 inet_pton(AF_INET, "94.142.241.111", &info.sin_addr.s_addr);
97
98                 connect(sock, (const struct sockaddr*)&info, sizeof(info));
99                 return sock;
100         } else if (strncmp((char*)adr2, (char*)pkt->hdr.dadr, 16)) {
101                 int sock = socket(AF_INET6, SOCK_STREAM, 0);
102
103                 struct sockaddr_in6 info;
104                 memset(&info, 0, sizeof(info));
105
106                 info.sin6_family = AF_INET6;
107                 info.sin6_port = pkt->data.dpt;
108
109                 inet_pton(AF_INET6, "2a02:898:17:8000::42", info.sin6_addr.s6_addr);
110
111                 connect(sock, (const struct sockaddr*)&info, sizeof(info));
112
113                 return sock;
114         }
115         return -1;
116 }}}
117
118 void handle_tcp(struct ip6_tcp* pkt) {
119         signal(SIGCHLD, SIG_IGN);
120
121         int fd = look_for_child(pkt);
122
123         if (fd == -1) {
124                 struct le* le = new_le();
125                 le->spt = pkt->data.spt;
126                 le->dpt = pkt->data.dpt;
127
128                 memcpy(le->sadr, pkt->hdr.sadr, 16);
129                 memcpy(le->dadr, pkt->hdr.dadr, 16);
130
131                 le->socket = nat(pkt);
132                 fd = le->socket;
133         }
134
135         int size = payload((&pkt->hdr)) - pkt->data.off;
136
137         int w = 0;
138         while (size > 0) {
139                 w = write(fd, pkt->data.data, size - w);
140                 if (w < 0) {
141                         debug(1, 0, "writing: %s\n", strerror(errno));
142                 } else {
143                         size -= w;
144                 }
145         }
146 }