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