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