plat
[oweals/gnunet.git] / src / transport / wlan / loopback_helper.c
1
2
3 #include <sys/socket.h>
4 #include <sys/ioctl.h>
5 #include <sys/types.h>
6 #include <sys/wait.h>
7 #include <sys/time.h>
8 #include <sys/stat.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 #include <errno.h>
13 #include <resolv.h>
14 #include <string.h>
15 #include <utime.h>
16 #include <unistd.h>
17 #include <getopt.h>
18
19 #include "platform.h"
20 #include "gnunet_constants.h"
21 #include "gnunet_os_lib.h"
22 #include "gnunet_transport_plugin.h"
23 #include "transport.h"
24 #include "gnunet_util_lib.h"
25 #include "plugin_transport_wlan.h"
26 #include "gnunet_common.h"
27 #include "gnunet-transport-wlan-helper.h"
28 #include "gnunet_crypto_lib.h"
29 #include "loopback_helper.h"
30 #include "helper_common.h"
31
32 extern int first;
33
34 static void
35 sigfunc(int sig)
36 {
37   closeprog = 1;
38   unlink(FIFO_FILE1);
39   unlink(FIFO_FILE2);
40 }
41
42 static void
43 stdin_send(void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
44 {
45   struct sendbuf *write_pout = cls;
46   int sendsize;
47   struct GNUNET_MessageHeader newheader;
48   unsigned char * from;
49   unsigned char * to;
50
51   sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send);
52
53   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type))
54     {
55       fprintf(stderr, "Function stdin_send: wrong packet type\n");
56       exit(1);
57     }
58   if ((sendsize + write_pout->size) > MAXLINE * 2)
59     {
60       fprintf(stderr, "Function stdin_send: Packet too big for buffer\n");
61       exit(1);
62     }
63
64   newheader.size = htons(sendsize);
65   newheader.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
66
67   to = write_pout->buf + write_pout->size;
68   memcpy(to, &newheader, sizeof(struct GNUNET_MessageHeader));
69   write_pout->size += sizeof(struct GNUNET_MessageHeader);
70
71   from = ((unsigned char *) hdr) + sizeof(struct Radiotap_Send)
72       + sizeof(struct GNUNET_MessageHeader);
73   to = write_pout->buf + write_pout->size;
74   memcpy(to, from, sendsize - sizeof(struct GNUNET_MessageHeader));
75   write_pout->size += sendsize - sizeof(struct GNUNET_MessageHeader);
76 }
77
78 static void
79 file_in_send(void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
80 {
81   struct sendbuf * write_std = cls;
82   uint16_t sendsize;
83
84   sendsize = ntohs(hdr->size);
85
86   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type))
87     {
88       fprintf(stderr, "Function file_in_send: wrong packet type\n");
89       exit(1);
90     }
91   if ((sendsize + write_std->size) > MAXLINE * 2)
92     {
93       fprintf(stderr, "Function file_in_send: Packet too big for buffer\n");
94       exit(1);
95     }
96
97   memcpy(write_std->buf + write_std->size, hdr, sendsize);
98   write_std->size += sendsize;
99 }
100
101 int
102 testmode(int argc, char *argv[])
103 {
104   struct stat st;
105   int erg;
106
107   FILE *fpin;
108   FILE *fpout;
109
110   int fdpin;
111   int fdpout;
112
113   //make the fifos if needed
114   if (0 != stat(FIFO_FILE1, &st))
115     {
116       if (0 == stat(FIFO_FILE2, &st))
117         {
118           fprintf(stderr, "FIFO_FILE2 exists, but FIFO_FILE1 not\n");
119           exit(1);
120         }
121
122       umask(0);
123       erg = mknod(FIFO_FILE1, S_IFIFO | 0666, 0);
124       erg = mknod(FIFO_FILE2, S_IFIFO | 0666, 0);
125
126     }
127   else
128     {
129
130       if (0 != stat(FIFO_FILE2, &st))
131         {
132           fprintf(stderr, "FIFO_FILE1 exists, but FIFO_FILE2 not\n");
133           exit(1);
134         }
135
136     }
137
138   if (strstr(argv[2], "1"))
139     {
140       //fprintf(stderr, "First\n");
141       first = 1;
142       fpin = fopen(FIFO_FILE1, "r");
143       if (NULL == fpin)
144         {
145           fprintf(stderr, "fopen of read FIFO_FILE1\n");
146           exit(1);
147         }
148       if (NULL == (fpout = fopen(FIFO_FILE2, "w")))
149         {
150           fprintf(stderr, "fopen of write FIFO_FILE2\n");
151           exit(1);
152         }
153
154     }
155   else
156     {
157       first = 0;
158       //fprintf(stderr, "Second\n");
159       if (NULL == (fpout = fopen(FIFO_FILE1, "w")))
160         {
161           fprintf(stderr, "fopen of write FIFO_FILE1\n");
162           exit(1);
163         }
164       if (NULL == (fpin = fopen(FIFO_FILE2, "r")))
165         {
166           fprintf(stderr, "fopen of read FIFO_FILE2\n");
167           exit(1);
168         }
169
170     }
171
172   fdpin = fileno(fpin);
173   if (fdpin >= FD_SETSIZE)
174     {
175       fprintf(stderr, "File fdpin number too large (%d > %u)\n", fdpin,
176           (unsigned int) FD_SETSIZE);
177       close(fdpin);
178       return -1;
179     }
180
181   fdpout = fileno(fpout);
182   if (fdpout >= FD_SETSIZE)
183     {
184       fprintf(stderr, "File fdpout number too large (%d > %u)\n", fdpout,
185           (unsigned int) FD_SETSIZE);
186       close(fdpout);
187       return -1;
188
189     }
190
191   signal(SIGINT, &sigfunc);
192   signal(SIGTERM, &sigfunc);
193
194   char readbuf[MAXLINE];
195   int readsize = 0;
196   struct sendbuf write_std;
197   write_std.size = 0;
198   write_std.pos = 0;
199
200   struct sendbuf write_pout;
201   write_pout.size = 0;
202   write_pout.pos = 0;
203
204   int ret = 0;
205   int maxfd = 0;
206
207   fd_set rfds;
208   fd_set wfds;
209   struct timeval tv;
210   int retval;
211
212   struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst;
213   struct GNUNET_SERVER_MessageStreamTokenizer * file_in_mst;
214
215   stdin_mst = GNUNET_SERVER_mst_create(&stdin_send, &write_pout);
216   file_in_mst = GNUNET_SERVER_mst_create(&file_in_send, &write_std);
217
218   //send mac first
219
220   struct MacAddress macaddr;
221
222   //Send random mac address
223   macaddr.mac[0] = 0x13;
224   macaddr.mac[1] = 0x22;
225   macaddr.mac[2] = 0x33;
226   macaddr.mac[3] = 0x44;
227   macaddr.mac[4] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 256);
228   macaddr.mac[5] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, 256);
229
230   write_std.size = send_mac_to_plugin((char *) write_std.buf, macaddr.mac);
231
232   /*
233    //wait
234    tv.tv_sec = 2;
235    tv.tv_usec = 0;
236    retval = select(0, NULL, NULL, NULL, &tv);
237
238
239    tv.tv_sec = 3;
240    tv.tv_usec = 0;
241    // if there is something to write
242    FD_ZERO(&wfds);
243    FD_SET(STDOUT_FILENO, &wfds);
244
245    retval = select(STDOUT_FILENO + 1, NULL, &wfds, NULL, &tv);
246
247    if (FD_ISSET(STDOUT_FILENO, &wfds))
248    {
249    ret = write(STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size
250    - write_std.pos);
251
252    if (0 > ret)
253    {
254    closeprog = 1;
255    fprintf(stderr, "Write ERROR to STDOUT");
256    exit(1);
257    }
258    else
259    {
260    write_std.pos += ret;
261    // check if finished
262    if (write_std.pos == write_std.size)
263    {
264    write_std.pos = 0;
265    write_std.size = 0;
266    }
267    }
268    }
269
270    memcpy(&write_std.buf, &macmsg, sizeof(struct Wlan_Helper_Control_Message));
271    write_std.size = sizeof(struct Wlan_Helper_Control_Message);
272    */
273
274   //wait
275   tv.tv_sec = 2;
276   tv.tv_usec = 0;
277   retval = select(0, NULL, NULL, NULL, &tv);
278
279   while (0 == closeprog)
280     {
281
282       maxfd = 0;
283
284       //set timeout
285       tv.tv_sec = 5;
286       tv.tv_usec = 0;
287
288       FD_ZERO(&rfds);
289       // if output queue is empty
290       if (0 == write_pout.size)
291         {
292           FD_SET(STDIN_FILENO, &rfds);
293
294         }
295       if (0 == write_std.size)
296         {
297           FD_SET(fdpin, &rfds);
298           maxfd = fdpin;
299         }
300       FD_ZERO(&wfds);
301       // if there is something to write
302       if (0 < write_std.size)
303         {
304           FD_SET(STDOUT_FILENO, &wfds);
305           maxfd = MAX(maxfd, STDOUT_FILENO);
306         }
307
308       if (0 < write_pout.size)
309         {
310           FD_SET(fdpout, &wfds);
311           maxfd = MAX(maxfd, fdpout);
312         }
313
314       retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
315
316       if (-1 == retval && EINTR == errno)
317         {
318           continue;
319         }
320       if (0 > retval)
321         {
322           fprintf(stderr, "select failed: %s\n", strerror(errno));
323           exit(1);
324         }
325
326       if (FD_ISSET(STDOUT_FILENO, &wfds))
327         {
328           ret = write(STDOUT_FILENO, write_std.buf + write_std.pos,
329               write_std.size - write_std.pos);
330
331           if (0 > ret)
332             {
333               closeprog = 1;
334               fprintf(stderr, "Write ERROR to STDOUT\n");
335               exit(1);
336             }
337           else
338             {
339               write_std.pos += ret;
340               // check if finished
341               if (write_std.pos == write_std.size)
342                 {
343                   write_std.pos = 0;
344                   write_std.size = 0;
345                 }
346             }
347         }
348
349       if (FD_ISSET(fdpout, &wfds))
350         {
351           ret = write(fdpout, write_pout.buf + write_pout.pos, write_pout.size
352               - write_pout.pos);
353
354           if (0 > ret)
355             {
356               closeprog = 1;
357               fprintf(stderr, "Write ERROR to fdpout\n");
358             }
359           else
360             {
361               write_pout.pos += ret;
362               // check if finished
363               if (write_pout.pos == write_pout.size)
364                 {
365                   write_pout.pos = 0;
366                   write_pout.size = 0;
367                 }
368             }
369         }
370
371       if (FD_ISSET(STDIN_FILENO, &rfds))
372         {
373           readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
374
375           if (0 > readsize)
376             {
377               closeprog = 1;
378               fprintf(stderr, "Read ERROR to STDIN_FILENO\n");
379             }
380           else if (0 < readsize)
381             {
382               GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize,
383                   GNUNET_NO, GNUNET_NO);
384
385             }
386           else
387             {
388               //eof
389               closeprog = 1;
390             }
391         }
392
393       if (FD_ISSET(fdpin, &rfds))
394         {
395           readsize = read(fdpin, readbuf, sizeof(readbuf));
396
397           if (0 > readsize)
398             {
399               closeprog = 1;
400               fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno));
401               closeprog = 1;
402             }
403           else if (0 < readsize)
404             {
405               GNUNET_SERVER_mst_receive(file_in_mst, NULL, readbuf, readsize,
406                   GNUNET_NO, GNUNET_NO);
407
408             }
409           else
410             {
411               //eof
412               closeprog = 1;
413             }
414         }
415
416     }
417
418   //clean up
419   fclose(fpout);
420   fclose(fpin);
421
422   if (1 == first)
423     {
424       unlink(FIFO_FILE1);
425       unlink(FIFO_FILE2);
426     }
427
428   return (0);
429 }