note
[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       // FIXME: use mkfifo!
140      erg = mknod(FIFO_FILE1, S_IFIFO | 0666, 0);
141       if (0 != erg)
142         {
143           fprintf(stderr, "Error at mknode1 \n");
144           //exit(1);
145         }
146       erg = mknod(FIFO_FILE2, S_IFIFO | 0666, 0);
147       if (0 != erg)
148         {
149           fprintf(stderr, "Error at mknode2 \n");
150           //exit(1);
151         }
152
153     }
154   else
155     {
156
157       if (0 != stat(FIFO_FILE2, &st))
158         {
159           fprintf(stderr, "FIFO_FILE1 exists, but FIFO_FILE2 not\n");
160           exit(1);
161         }
162
163     }
164
165   if (strstr(argv[2], "1"))
166     {
167       //fprintf(stderr, "First\n");
168       first = 1;
169       fpin = fopen(FIFO_FILE1, "r");
170       if (NULL == fpin)
171         {
172           fprintf(stderr, "fopen of read FIFO_FILE1\n");
173           goto end;
174         }
175       fpout = fopen(FIFO_FILE2, "w");
176       if (NULL == fpout)
177         {
178           fprintf(stderr, "fopen of write FIFO_FILE2\n");
179           goto end;
180         }
181
182     }
183   else
184     {
185       first = 0;
186       //fprintf(stderr, "Second\n");
187       fpout = fopen(FIFO_FILE1, "w");
188       if (NULL == fpout)
189         {
190           fprintf(stderr, "fopen of write FIFO_FILE1\n");
191           goto end;
192         }
193       fpin = fopen(FIFO_FILE2, "r");
194       if (NULL == fpin)
195         {
196           fprintf(stderr, "fopen of read FIFO_FILE2\n");
197           goto end;
198         }
199
200     }
201
202   fdpin = fileno(fpin);
203   GNUNET_assert(fpin >= 0);
204
205   if (fdpin >= FD_SETSIZE)
206     {
207       fprintf(stderr, "File fdpin number too large (%d > %u)\n", fdpin,
208           (unsigned int) FD_SETSIZE);
209       goto end;
210     }
211
212   fdpout = fileno(fpout);
213   GNUNET_assert(fdpout >= 0 );
214
215   if (fdpout >= FD_SETSIZE)
216     {
217       fprintf(stderr, "File fdpout number too large (%d > %u)\n", fdpout,
218           (unsigned int) FD_SETSIZE);
219       goto end;
220
221     }
222
223   signal(SIGINT, &sigfunc);
224   signal(SIGTERM, &sigfunc);
225
226   char readbuf[MAXLINE];
227   int readsize = 0;
228   struct sendbuf write_std;
229   write_std.size = 0;
230   write_std.pos = 0;
231
232   struct sendbuf write_pout;
233   write_pout.size = 0;
234   write_pout.pos = 0;
235
236   int ret = 0;
237   int maxfd = 0;
238
239   fd_set rfds;
240   fd_set wfds;
241   struct timeval tv;
242   int retval;
243
244   struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst;
245   struct GNUNET_SERVER_MessageStreamTokenizer * file_in_mst;
246
247   stdin_mst = GNUNET_SERVER_mst_create(&stdin_send, &write_pout);
248   file_in_mst = GNUNET_SERVER_mst_create(&file_in_send, &write_std);
249
250   //send mac first
251
252   struct MacAddress macaddr;
253
254   //Send random mac address
255   macaddr.mac[0] = 0x13;
256   macaddr.mac[1] = 0x22;
257   macaddr.mac[2] = 0x33;
258   macaddr.mac[3] = 0x44;
259   macaddr.mac[4] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 256);
260   macaddr.mac[5] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, 256);
261
262   write_std.size = send_mac_to_plugin((char *) write_std.buf, macaddr.mac);
263
264   /*
265    //wait
266    tv.tv_sec = 2;
267    tv.tv_usec = 0;
268    retval = select(0, NULL, NULL, NULL, &tv);
269
270
271    tv.tv_sec = 3;
272    tv.tv_usec = 0;
273    // if there is something to write
274    FD_ZERO(&wfds);
275    FD_SET(STDOUT_FILENO, &wfds);
276
277    retval = select(STDOUT_FILENO + 1, NULL, &wfds, NULL, &tv);
278
279    if (FD_ISSET(STDOUT_FILENO, &wfds))
280    {
281    ret = write(STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size
282    - write_std.pos);
283
284    if (0 > ret)
285    {
286    closeprog = 1;
287    fprintf(stderr, "Write ERROR to STDOUT");
288    exit(1);
289    }
290    else
291    {
292    write_std.pos += ret;
293    // check if finished
294    if (write_std.pos == write_std.size)
295    {
296    write_std.pos = 0;
297    write_std.size = 0;
298    }
299    }
300    }
301
302    memcpy(&write_std.buf, &macmsg, sizeof(struct Wlan_Helper_Control_Message));
303    write_std.size = sizeof(struct Wlan_Helper_Control_Message);
304    */
305
306   //wait
307   tv.tv_sec = 2;
308   tv.tv_usec = 0;
309   select(0, NULL, NULL, NULL, &tv);
310
311   while (0 == closeprog)
312     {
313
314       maxfd = 0;
315
316       //set timeout
317       tv.tv_sec = 5;
318       tv.tv_usec = 0;
319
320       FD_ZERO(&rfds);
321       // if output queue is empty
322       if (0 == write_pout.size)
323         {
324           FD_SET(STDIN_FILENO, &rfds);
325
326         }
327       if (0 == write_std.size)
328         {
329           FD_SET(fdpin, &rfds);
330           maxfd = fdpin;
331         }
332       FD_ZERO(&wfds);
333       // if there is something to write
334       if (0 < write_std.size)
335         {
336           FD_SET(STDOUT_FILENO, &wfds);
337           maxfd = MAX(maxfd, STDOUT_FILENO);
338         }
339
340       if (0 < write_pout.size)
341         {
342           FD_SET(fdpout, &wfds);
343           maxfd = MAX(maxfd, fdpout);
344         }
345
346       retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
347
348       if (-1 == retval && EINTR == errno)
349         {
350           continue;
351         }
352       if (0 > retval)
353         {
354           fprintf(stderr, "select failed: %s\n", strerror(errno));
355           closeprog = 1;
356           break;
357         }
358
359       if (FD_ISSET(STDOUT_FILENO, &wfds))
360         {
361           ret = write(STDOUT_FILENO, write_std.buf + write_std.pos,
362               write_std.size - write_std.pos);
363
364           if (0 > ret)
365             {
366               closeprog = 1;
367               fprintf(stderr, "Write ERROR to STDOUT\n");
368               break;
369             }
370           else
371             {
372               write_std.pos += ret;
373               // check if finished
374               if (write_std.pos == write_std.size)
375                 {
376                   write_std.pos = 0;
377                   write_std.size = 0;
378                 }
379             }
380         }
381
382       if (FD_ISSET(fdpout, &wfds))
383         {
384           ret = write(fdpout, write_pout.buf + write_pout.pos, write_pout.size
385               - write_pout.pos);
386
387           if (0 > ret)
388             {
389               closeprog = 1;
390               fprintf(stderr, "Write ERROR to fdpout\n");
391             }
392           else
393             {
394               write_pout.pos += ret;
395               // check if finished
396               if (write_pout.pos == write_pout.size)
397                 {
398                   write_pout.pos = 0;
399                   write_pout.size = 0;
400                 }
401             }
402         }
403
404       if (FD_ISSET(STDIN_FILENO, &rfds))
405         {
406           readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
407
408           if (0 > readsize)
409             {
410               closeprog = 1;
411               fprintf(stderr, "Read ERROR to STDIN_FILENO\n");
412             }
413           else if (0 < readsize)
414             {
415               GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize,
416                   GNUNET_NO, GNUNET_NO);
417
418             }
419           else
420             {
421               //eof
422               closeprog = 1;
423             }
424         }
425
426       if (FD_ISSET(fdpin, &rfds))
427         {
428           readsize = read(fdpin, readbuf, sizeof(readbuf));
429
430           if (0 > readsize)
431             {
432               closeprog = 1;
433               fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno));
434               break;
435             }
436           else if (0 < readsize)
437             {
438               GNUNET_SERVER_mst_receive(file_in_mst, NULL, readbuf, readsize,
439                   GNUNET_NO, GNUNET_NO);
440
441             }
442           else
443             {
444               //eof
445               closeprog = 1;
446             }
447         }
448
449     }
450
451   //clean up
452
453   GNUNET_SERVER_mst_destroy(stdin_mst);
454   GNUNET_SERVER_mst_destroy(file_in_mst);
455
456   end: if (fpout != NULL)
457     fclose(fpout);
458   if (fpin != NULL)
459     fclose(fpin);
460
461   if (1 == first)
462     {
463       unlink(FIFO_FILE1);
464       unlink(FIFO_FILE2);
465     }
466
467   return (0);
468 }