Removed the 2 seconds wait
[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   while (0 == closeprog)
265     {
266
267       maxfd = 0;
268
269       //set timeout
270       tv.tv_sec = 5;
271       tv.tv_usec = 0;
272
273       FD_ZERO(&rfds);
274       // if output queue is empty
275       if (0 == write_pout.size)
276         {
277           FD_SET(STDIN_FILENO, &rfds);
278
279         }
280       if (0 == write_std.size)
281         {
282           FD_SET(fdpin, &rfds);
283           maxfd = fdpin;
284         }
285       FD_ZERO(&wfds);
286       // if there is something to write
287       if (0 < write_std.size)
288         {
289           FD_SET(STDOUT_FILENO, &wfds);
290           maxfd = MAX(maxfd, STDOUT_FILENO);
291         }
292
293       if (0 < write_pout.size)
294         {
295           FD_SET(fdpout, &wfds);
296           maxfd = MAX(maxfd, fdpout);
297         }
298
299       retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
300
301       if (-1 == retval && EINTR == errno)
302         {
303           continue;
304         }
305       if (0 > retval)
306         {
307           fprintf(stderr, "select failed: %s\n", strerror(errno));
308           closeprog = 1;
309           break;
310         }
311
312       if (FD_ISSET(STDOUT_FILENO, &wfds))
313         {
314           ret = write(STDOUT_FILENO, write_std.buf + write_std.pos,
315               write_std.size - write_std.pos);
316
317           if (0 > ret)
318             {
319               closeprog = 1;
320               fprintf(stderr, "Write ERROR to STDOUT\n");
321               break;
322             }
323           else
324             {
325               write_std.pos += ret;
326               // check if finished
327               if (write_std.pos == write_std.size)
328                 {
329                   write_std.pos = 0;
330                   write_std.size = 0;
331                 }
332             }
333         }
334
335       if (FD_ISSET(fdpout, &wfds))
336         {
337           ret = write(fdpout, write_pout.buf + write_pout.pos, write_pout.size
338               - write_pout.pos);
339
340           if (0 > ret)
341             {
342               closeprog = 1;
343               fprintf(stderr, "Write ERROR to fdpout\n");
344             }
345           else
346             {
347               write_pout.pos += ret;
348               // check if finished
349               if (write_pout.pos == write_pout.size)
350                 {
351                   write_pout.pos = 0;
352                   write_pout.size = 0;
353                 }
354             }
355         }
356
357       if (FD_ISSET(STDIN_FILENO, &rfds))
358         {
359           readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
360
361           if (0 > readsize)
362             {
363               closeprog = 1;
364               fprintf(stderr, "Read ERROR to STDIN_FILENO\n");
365             }
366           else if (0 < readsize)
367             {
368               GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize,
369                   GNUNET_NO, GNUNET_NO);
370
371             }
372           else
373             {
374               //eof
375               closeprog = 1;
376             }
377         }
378
379       if (FD_ISSET(fdpin, &rfds))
380         {
381           readsize = read(fdpin, readbuf, sizeof(readbuf));
382
383           if (0 > readsize)
384             {
385               closeprog = 1;
386               fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno));
387               break;
388             }
389           else if (0 < readsize)
390             {
391               GNUNET_SERVER_mst_receive(file_in_mst, NULL, readbuf, readsize,
392                   GNUNET_NO, GNUNET_NO);
393
394             }
395           else
396             {
397               //eof
398               closeprog = 1;
399             }
400         }
401
402     }
403
404   //clean up
405
406   GNUNET_SERVER_mst_destroy(stdin_mst);
407   GNUNET_SERVER_mst_destroy(file_in_mst);
408
409   end: if (fpout != NULL)
410     fclose(fpout);
411   if (fpin != NULL)
412     fclose(fpin);
413
414   if (1 == first)
415     {
416       unlink(FIFO_FILE1);
417       unlink(FIFO_FILE2);
418     }
419
420   return (0);
421 }