00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00035
00036
00037 #include <errno.h>
00038 #include <pthread.h>
00039 #include <signal.h>
00040 #include <stdarg.h>
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <syslog.h>
00045 #include <unistd.h>
00046 #include "netdevice.h"
00047 #include "message.h"
00048 #include "iwconnect.h"
00049 #include "iwc_print.h"
00050
00051
00052
00053
00054
00055 extern int iwc_init_host();
00056 extern int iwc_init_model(const char *);
00057 extern int iwc_init_net();
00058 extern int iwc_init_check_pidfile(const char *);
00059 extern int iwc_init_create_pidfile(const char *);
00060 extern int iwc_init_remove_pidfile(const char *);
00061
00062 extern int iwc_model_register();
00063 extern int iwc_model_deregister();
00064 extern void iwc_model_update(int, const char*);
00065
00066 extern void iwc_notify_poll(void *);
00067
00068
00069
00070
00071 char *exec_name = NULL;
00072 const char iwc_version[] = "0.3.0beta\0";
00073 const char iwc_pidfile[] = "/var/run/iwconnect.pid";
00075
00076 iwc_client_info client_info;
00077 iwc_model_info model_info;
00080 int num_vif;
00081
00082
00083 int tap_sockets[MAX_NUM_VIF];
00084 int net_socket;
00087 int direct;
00088
00090 int iwc_dbg;
00091
00093 int is_registered;
00094
00096 int ip_family;
00097
00098
00099
00100
00102 void
00103 iwc_usage()
00104 {
00105 printf("\nUsage: %s MODELIP:MODELPORT LOCALPORT\n", exec_name);
00106 printf("\t\t [-i INTERFACE][-6][-n][-d]\n");
00107 printf("Try `%s -h' for more details\n", exec_name);
00108
00109 exit(EXIT_FAILURE);
00110 }
00111
00113 void
00114 iwc_help()
00115 {
00116 printf("\nUsage: %s MODELIP:MODELPORT LOCALPORT\n", exec_name);
00117 printf("\t\t\t[-i INTERFACE][-6][-n][-d][-h]\n");
00118 printf("\nTunnels traffic from a virtual wireless interface to a\n");
00119 printf("wireless emulation model. First you have to create a virtual\n");
00120 printf("interface with `vifctl -c INTERFACE`. The virtual interfaces are \n");
00121 printf("then detected automatically.\n");
00122 printf("\nParameters:\n");
00123 printf("MODELIP:PORT\tIP Address/Hostname and port number of wireless model\n");
00124 printf("LOCALPORT\tLocal port to listen for model replies\n");
00125 printf("-6\t\tUse IPv6 protocol\n");
00126 printf("-d\t\tEnable debug output\n");
00127 printf("-h\t\tShow this help message\n");
00128 printf("-i INTERFACE\tTunnel interface (default: %s)\n", client_info.host_if);
00129 printf("-n\t\tEnable node-to-node communication (only for testing!)\n");
00130
00131 exit(EXIT_SUCCESS);
00132 }
00133
00135 int
00136 ignore_debug(const char* text, ...)
00137 {
00138 return 0;
00139 }
00140
00142 int
00143 print_debug(const char *format, ...)
00144 {
00145 va_list arg;
00146
00147 va_start(arg, format);
00148 iwc_debug_args(format, arg);
00149 va_end(arg);
00150
00151 return 0;
00152 }
00153
00155 void
00156 ignore_debug_args(const char *format, va_list arg)
00157 {
00158 }
00159
00161 void
00162 print_debug_args(const char *format, va_list arg)
00163 {
00164 FILE *stdout = fopen("/dev/stdout", "a");
00165 fprintf(stdout, "DEBUG: ");
00166 vfprintf(stdout, format, arg);
00167 fclose(stdout);
00168 }
00169
00171 int
00172 iwc_error(const char *format, ...)
00173 {
00174 int chars_printed = 0;
00175 va_list arg;
00176
00177 FILE *stderr = fopen("/dev/stderr", "a");
00178 if (stderr == NULL)
00179 return -1;
00180 chars_printed = fprintf(stderr, "Error: ");
00181 va_start(arg, format);
00182 chars_printed += vfprintf(stderr, format, arg);
00183 va_end(arg);
00184 fclose(stderr);
00185
00186 return chars_printed;
00187 }
00188
00190 void
00191 iwc_log(const char *format, ...)
00192 {
00193 va_list arg;
00194
00195
00196 openlog(exec_name, LOG_PID, LOG_SYSLOG);
00197 va_start(arg, format);
00198 vsyslog(LOG_INFO, format, arg);
00199 va_end(arg);
00200 closelog();
00201
00202
00203 FILE *stdout = fopen("/dev/stdout", "a");
00204 if (stdout == NULL)
00205 return;
00206 va_start(arg, format);
00207 vfprintf(stdout, format, arg);
00208 va_end(arg);
00209 fclose(stdout);
00210 }
00211
00213 void
00214 iwc_shutdown(int signal)
00215 {
00216 int i;
00217 int rtrn = 0;
00218
00219 iwc_log("iwconnect: Shutdown\n");
00220
00221
00222 if (is_registered == 1)
00223 {
00224 if (iwc_model_deregister() < 0)
00225 signal = rtrn;
00226 else
00227 is_registered = 0;
00228 }
00229
00230
00231 close(net_socket);
00232 for (i = 0; i < num_vif; i++)
00233 close(tap_sockets[i]);
00234
00235
00236 iwc_init_remove_pidfile(iwc_pidfile);
00237
00238 if (((signal == SIGINT) ||
00239 (signal == SIGABRT) ||
00240 (signal == SIGTERM)) &&
00241 (rtrn == 0))
00242 {
00243 exit(EXIT_SUCCESS);
00244 } else {
00245 exit(signal);
00246 }
00247 }
00248
00249
00251 void
00252 iwc_daemon()
00253 {
00254 fd_set fds;
00255 int i, recv_bytes, sent_bytes;
00256 register int ret;
00257 char buffer[DATA_MSG_SIZE];
00258 struct data_msg *message = (struct data_msg *) buffer;
00259 raw_packet *ether_frame = (raw_packet *) message->wlan_pkt;
00260
00261 iwc_debug("iwc_daemon(): Running main loop with %i vif(s)\n", num_vif);
00262 iwc_debug("\n");
00263 iwc_init_create_pidfile(iwc_pidfile);
00264
00265
00266 int max_fd = 0;
00267 for (i = 0; i < num_vif; i++)
00268 max_fd = max(max_fd, tap_sockets[i]);
00269 max_fd = max(max_fd, net_socket) + 1;
00270
00271
00272
00273
00274
00275
00276 for (;;)
00277 {
00278 FD_ZERO(&fds);
00279 for (i = 0; i < num_vif; i++)
00280 FD_SET(tap_sockets[i], &fds);
00281 FD_SET(net_socket, &fds);
00282
00283
00284 if ((ret = select(max_fd, &fds, NULL, NULL, NULL)) < 0)
00285 {
00286 iwc_error("iwc_daemon(): select() (%s)\n",
00287 strerror(errno));
00288 return;
00289 } else {
00290
00291 for (i = 0; i < num_vif; i++)
00292 {
00293 if (FD_ISSET(tap_sockets[i], &fds))
00294 {
00295
00296 recv_bytes = read(tap_sockets[i], ether_frame,
00297 MAX_FRAME_SIZE);
00298 iwc_debug(">>tap_fd<< %i Bytes read\n", recv_bytes);
00299 if (recv_bytes > 0)
00300 {
00301 message->header.type = DATA_MSG;
00302 memmove(&message->header.id, client_info.host_id,
00303 sizeof(client_info.host_id));
00304 message->pkt_length = recv_bytes;
00305 message->vif_index = i;
00306 debug_msg((char *) message);
00307
00308
00309 if ((sent_bytes = sendto(net_socket, message,
00310 DATA_PREAMBLE_SIZE + recv_bytes, 0,
00311 model_info.host_info.addr_info.ai_addr,
00312 model_info.host_info.addr_info.ai_addrlen)) < 0)
00313 {
00314 iwc_error("iwc_daemon(): net:sendto (%s)\n",
00315 strerror(errno));
00316 }
00317 iwc_debug(">>net_socket<< %i Bytes sent\n", sent_bytes);
00318 iwc_debug("\n");
00319 } else
00320 iwc_error("iwc_daemon(): tap:read (%s)\n", strerror(errno));
00321 }
00322 }
00323
00324 if (FD_ISSET(net_socket, &fds))
00325 {
00326 recv_bytes = recvfrom(net_socket, buffer, DATA_MSG_SIZE, 0,
00327 NULL, NULL);
00328 iwc_debug(">>net_socket<< %i Bytes read\n", recv_bytes);
00329 if (recv_bytes > 0)
00330 {
00331 if (is_data_msg((struct msg_header *) buffer))
00332 {
00333 debug_msg(buffer);
00334
00335
00336 iwc_debug("iwc_daemon(): sendto fd = %i, pkt_length = %i\n",
00337 tap_sockets[message->vif_index],
00338 message->pkt_length);
00339 if ((sent_bytes = write(
00340 tap_sockets[message->vif_index],
00341 ether_frame, message->pkt_length)) < 1)
00342 {
00343 iwc_error("iwc_daemon(): write() (%s)\n",
00344 strerror(errno));
00345 } else {
00346 iwc_debug(">>tap_fd<< %i Bytes sent\n", sent_bytes);
00347 iwc_debug("\n");
00348 }
00349 } else {
00350 if (is_ack_msg((struct msg_header *) buffer))
00351 {
00352 iwc_debug("iwc_daemon(): Discard straying Ack message\n");
00353 iwc_debug("\n");
00354 } else {
00355 iwc_debug("iwc_daemon(): Unknown message received\n");
00356 iwc_debug("\n");
00357 }
00358 }
00359 } else {
00360 if (errno == ECONNREFUSED)
00361 iwc_log("No connection to WlanModel (%s)\n", strerror(errno));
00362 else
00363 iwc_error("iwc_daemon(): recvfrom() (%s)\n", strerror(errno));
00364 return;
00365 }
00366 }
00367 }
00368 }
00369 }
00370
00371
00373 int
00374 iwc_pars_opts(int argc, char *argv[])
00375 {
00376 int opt = -1;
00377 int debug = 0;
00378 int req_args = 3;
00379 int add_args = 0;
00380 int port_conv = -1;
00381
00382
00383 iwc_debug = ignore_debug;
00384 iwc_debug_args = ignore_debug_args;
00385
00386 while ((opt = getopt(argc, argv, "6dnhi:")) != -1)
00387 {
00388 switch (opt)
00389 {
00390 case 'h':
00391 iwc_help();
00392 break;
00393 case 'i':
00394 add_args += 2;
00395 break;
00396 case 'd':
00397 add_args++;
00398 debug = 1;
00399 break;
00400 case 'n':
00401 add_args++;
00402 break;
00403 case '6':
00404 add_args++;
00405 ip_family = PF_INET6;
00406 break;
00407 }
00408 }
00409 optind = 0;
00410
00411 if (argc < (req_args + add_args))
00412 {
00413 iwc_error("Missing arguments\n");
00414 return -1;
00415 }
00416
00417
00418 if (debug == 1)
00419 {
00420 iwc_dbg = 1;
00421 iwc_debug = print_debug;
00422 iwc_debug_args = print_debug_args;
00423 vif_set_debug_function(iwc_debug);
00424 }
00425 vif_set_error_function(iwc_error);
00426
00427 iwc_log("Starting iwconnect %s\n", &iwc_version);
00428 if (debug == 1)
00429 iwc_debug("Debugging enabled!\n");
00430 if (ip_family == AF_INET6)
00431 iwc_log("Using IPv6 protocol\n");
00432
00433
00434 if (init_udp_socket() < 0)
00435 return (EXIT_FAILURE);
00436
00437
00438 if (iwc_init_model(argv[1 + add_args]) == -1)
00439 {
00440 iwc_error("Model initialization failed!\n");
00441 return -1;
00442 }
00443
00444
00445 port_conv = atoi(argv[2 + add_args]);
00446 if ((port_conv > 65536) || (port_conv < 1))
00447 {
00448 iwc_error("Invalid local port number\n");
00449 return -1;
00450 } else {
00451 memmove(client_info.host_port, argv[2 + add_args], 5);
00452 }
00453
00454 while ((opt = getopt(argc, argv, "6dni:")) != -1)
00455 {
00456 switch (opt)
00457 {
00458 case 'n':
00459 direct = 1;
00460 break;
00461 case 'i':
00462 if (get_ip_by_dev(NULL, optarg))
00463 return -1;
00464 else
00465 {
00466 strncpy(client_info.host_if, optarg, IFNAMSIZ);
00467 client_info.host_if[IFNAMSIZ] = '\0';
00468 }
00469 break;
00470 }
00471 }
00472 iwc_debug("Using local interface %s\n", client_info.host_if);
00473
00474 return 0;
00475 }
00476
00478 int
00479 main(int argc, char *argv[])
00480 {
00481 pthread_t tid;
00482 pid_t pid = 0;
00483 int is_running = -1;
00484
00485
00486 if (strrchr(argv[0], '/') == NULL)
00487 {
00488 exec_name = argv[0];
00489 } else {
00490 exec_name = strrchr(argv[0], '/') + 1;
00491 }
00492
00493
00494 num_vif = 0;
00495 ip_family = AF_INET;
00496 direct = 0;
00497 iwc_dbg = 0;
00498 is_registered = 0;
00499 memset(&model_info, 0, sizeof(iwc_model_info));
00500 memset(&client_info, 0, sizeof(iwc_client_info));
00501 strcpy(client_info.host_if, "eth0\0");
00502
00503
00504 if (iwc_pars_opts(argc, argv) < 0)
00505 iwc_usage();
00506
00507
00508 is_running = iwc_init_check_pidfile(iwc_pidfile);
00509 if (is_running != 0)
00510 return EXIT_FAILURE;
00511
00512
00513 if (iwc_init_host() < 0)
00514 {
00515 iwc_error("Host initialization failed!\n");
00516 return EXIT_FAILURE;
00517 }
00518
00519
00520 signal(SIGINT, iwc_shutdown);
00521 signal(SIGABRT, iwc_shutdown);
00522 signal(SIGTERM, iwc_shutdown);
00523
00524
00525 if (iwc_init_net() < 0)
00526 {
00527 iwc_error("Network initialization failed!\n");
00528 return EXIT_FAILURE;
00529 }
00530
00531 iwc_debug("Successfully finished host initialization!\n");
00532 iwc_debug("\n");
00533
00534
00535 if (direct != 1)
00536 {
00537 if ((is_registered = iwc_model_register()) != 1)
00538 return EXIT_FAILURE;
00539 } else {
00540 iwc_log("Not registering host!\n");
00541 }
00542
00543
00544 if (pthread_create(&tid, NULL, iwc_notify_poll,
00545 (void *) &iwc_model_update) < 0)
00546 {
00547 iwc_error("Couldn't create new thread (%s)\n", strerror(errno));
00548 iwc_shutdown(EXIT_FAILURE);
00549 }
00550
00551 if (iwc_dbg == 0)
00552 {
00553 pid = fork();
00554 if (pid < 0)
00555 {
00556 iwc_error("Couldn't fork process to background\n");
00557 iwc_shutdown(EXIT_FAILURE);
00558 }
00559 if (pid > 0)
00560 return EXIT_SUCCESS;
00561 }
00562
00563
00564 iwc_daemon();
00565
00566 exit(EXIT_FAILURE);
00567 }