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