00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00017
00018
00019 #include <arpa/inet.h>
00020
00021 #include <errno.h>
00022 #include <fcntl.h>
00023 #include <netdb.h>
00024 #include <signal.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <time.h>
00028 #include <unistd.h>
00029 #include <vif.h>
00030 #include "iwconnect.h"
00031 #include "iwc_print.h"
00032 #include "message.h"
00033 #include "netdevice.h"
00034
00035
00036
00037
00038 extern char *exec_name;
00039 extern iwc_client_info client_info;
00040 extern iwc_model_info model_info;
00041 extern int num_vif;
00042 extern int tap_sockets[MAX_NUM_VIF];
00043 extern int net_socket;
00044 extern int ip_family;
00045
00046
00047
00048
00052 void
00053 iwc_print_addrinfo(struct addrinfo *addr)
00054 {
00055 char str[INET6_ADDRSTRLEN];
00056 uint16_t port;
00057 memset(&str, 0, INET6_ADDRSTRLEN);
00058
00059 iwc_debug("[AI_FLAGS] AI_PASSIVE = %li, AI_CANONNAME = %li, AI_NUMERICHOST = %li\n",
00060 AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST);
00061 iwc_debug("[AF_FAMILY] AF_UNSPEC = %li, AF_INET = %li, AF_INET6 = %li\n",
00062 AF_UNSPEC, AF_INET, AF_INET6);
00063 iwc_debug("[SOCKETS] SOCK_STREAM = %li, SOCK_DGRAM = %li\n",
00064 SOCK_STREAM, SOCK_DGRAM);
00065 iwc_debug("[PROTOCOL] IPPROTO_TCP = %li, IPPROTO_UDP = %li\n",
00066 IPPROTO_TCP, IPPROTO_UDP);
00067 iwc_debug("ai_flags = %li\n", addr->ai_flags);
00068 iwc_debug("ai_family = %li\n", addr->ai_family);
00069 iwc_debug("ai_socktype = %li\n", addr->ai_socktype);
00070 iwc_debug("ai_protocol = %li\n", addr->ai_protocol);
00071 iwc_debug("ai_addrlen = %i\n", addr->ai_addrlen);
00072 if (addr->ai_family == AF_INET)
00073 {
00074 inet_ntop(addr->ai_family,
00075 &((struct sockaddr_in *) addr->ai_addr)->sin_addr,
00076 str, addr->ai_addrlen);
00077 port = ntohs(((struct sockaddr_in *) addr->ai_addr)->sin_port);
00078 }
00079 if (addr->ai_family == AF_INET6)
00080 {
00081 inet_ntop(addr->ai_family,
00082 &((struct sockaddr_in6 *) addr->ai_addr)->sin6_addr,
00083 str, addr->ai_addrlen);
00084 port = ntohs(((struct sockaddr_in6 *) addr->ai_addr)->sin6_port);
00085 }
00086 iwc_debug("ai_addr = %p (addr = %s, port = %i)\n",
00087 addr->ai_addr, str, port);
00088 iwc_debug("ai_canonname = %p (%s)\n", addr->ai_canonname, addr->ai_canonname);
00089 iwc_debug("ai_next = %p\n", addr->ai_next);
00090 }
00091
00095 void
00096 iwc_print_model_info(iwc_model_info *minfo)
00097 {
00098 char addr[INET6_ADDRSTRLEN];
00099 iwc_host_info *info = &minfo->host_info;
00100 iwc_debug(",-- Model Information -----------------\n");
00101 iwc_debug("| Name:\t\t\t%s\n", info->hostname);
00102 if (ip_family == AF_INET)
00103 {
00104 iwc_debug("| IPv4 Address:\t\t%s\n",
00105 inet_ntoa(((struct sockaddr_in *) &info->addr)->sin_addr));
00106 iwc_debug("| Port:\t\t\t%u\n",
00107 ntohs(((struct sockaddr_in *) &info->addr)->sin_port));
00108 }
00109 if (ip_family == AF_INET6)
00110 {
00111 iwc_debug("| IPv6 Address:\t\t%s\n",
00112 inet_ntop(info->addr_info.ai_family,
00113 &((struct sockaddr_in6 *) &info->addr)->sin6_addr,
00114 addr, info->addr_info.ai_addrlen));
00115 iwc_debug("| Port:\t\t\t%u\n",
00116 ntohs(((struct sockaddr_in6 *) &info->addr)->sin6_port));
00117 }
00118 iwc_debug("`--------------------------------------\n");
00119 }
00120
00124 void
00125 iwc_print_client_info(iwc_client_info *cinfo)
00126 {
00127 char addr[INET6_ADDRSTRLEN];
00128 iwc_host_info *info = &cinfo->host_info;
00129 iwc_debug(",-- Host Information ------------------\n");
00130 iwc_debug("| Name:\t\t\t%s\n", info->hostname);
00131 iwc_debug("| Interface:\t\t%s\n", cinfo->host_if);
00132 iwc_debug("| ID/MAC Address:\t%s\n", cinfo->host_id);
00133 if (ip_family == AF_INET)
00134 {
00135 iwc_debug("| IPv4 Address:\t\t%s\n",
00136 inet_ntoa(((struct sockaddr_in *) &info->addr)->sin_addr));
00137 iwc_debug("| Port:\t\t\t%u\n",
00138 ntohs(((struct sockaddr_in *) &info->addr)->sin_port));
00139 }
00140 if (ip_family == AF_INET6)
00141 {
00142 iwc_debug("| IPv6 Address:\t\t%s\n",
00143 inet_ntop(info->addr_info.ai_family,
00144 &((struct sockaddr_in6 *) &info->addr)->sin6_addr,
00145 addr, info->addr_info.ai_addrlen));
00146 iwc_debug("| Port:\t\t\t%u\n",
00147 ntohs(((struct sockaddr_in6 *) &info->addr)->sin6_port));
00148 }
00149 iwc_debug("`--------------------------------------\n");
00150 }
00151
00152
00153
00154
00159 int
00160 iwc_init_model(const char *arg)
00161 {
00162 struct addrinfo request, *result;
00163 iwc_host_info *info = &model_info.host_info;
00164 char model[HOST_NAME_MAX + 1];
00165 char cport[5 + 1];
00166 int iport = -1;
00167 int del_index = -1;
00168 const char delimiter = ':';
00169
00170
00171 if (strlen(arg) > (HOST_NAME_MAX + 1 + 5))
00172 {
00173 iwc_error("Destination address to long!\n");
00174 return -1;
00175 }
00176
00177
00178 for (del_index = 0; del_index < HOST_NAME_MAX + 1; del_index++)
00179 {
00180 if (*(arg + del_index) == delimiter)
00181 {
00182 memmove(model, arg, del_index);
00183 model[del_index] = '\0';
00184 memmove(cport, arg + del_index + 1, 5);
00185 cport[5] = '\0';
00186 break;
00187 }
00188 }
00189
00190
00191 iport = atoi(cport);
00192 if ((iport > 65536) || (iport < 1))
00193 {
00194 iwc_error("Invalid destination port number\n");
00195 return -1;
00196 }
00197
00198
00199 memset(&request, 0, sizeof(struct addrinfo));
00200 request.ai_flags = 0;
00201 request.ai_family = ip_family;
00202 request.ai_socktype = SOCK_DGRAM;
00203 request.ai_protocol = 0;
00204 request.ai_canonname = NULL;
00205 request.ai_addr = NULL;
00206 request.ai_next = NULL;
00207
00208
00209
00210 if (getaddrinfo(model, cport, &request, &result) < 0)
00211 {
00212 iwc_error("Cannot resolve destination address (%s)\n", gai_strerror(errno));
00213 return -1;
00214 }
00215 while (1)
00216 {
00217 if (ip_family == result->ai_family)
00218 {
00219 memmove(&info->addr_info, result, sizeof(struct addrinfo));
00220 memmove(&info->addr, result->ai_addr, sizeof(struct sockaddr_storage));
00221 info->addr_info.ai_addr = (struct sockaddr *) &info->addr;
00222 info->addr_info.ai_canonname = info->hostname;
00223 }
00224 if ((result = result->ai_next) == NULL)
00225 break;
00226 }
00227 freeaddrinfo(result);
00228 if (info->addr_info.ai_addr == NULL)
00229 {
00230 iwc_error("Couldn't find valid address for destination\n");
00231 return -1;
00232 }
00233
00234 if (getnameinfo(info->addr_info.ai_addr,
00235 info->addr_info.ai_addrlen, info->hostname,
00236 HOST_NAME_MAX, NULL, 0, NI_NAMEREQD) < 0)
00237
00238 iwc_debug("Failed to lookup hostname of destination IP (%s)\n",
00239 gai_strerror(errno));
00240
00241 iwc_print_model_info(&model_info);
00242 return 0;
00243 }
00244
00248 int
00249 iwc_init_host()
00250 {
00251 int i = -1;
00252 char addr_string[INET6_ADDRSTRLEN];
00253 addr_storage addr;
00254 struct addrinfo request, *result;
00255 uint32_t random_int = 0;
00256 unsigned char id_source[ETH_ALEN];
00257 iwc_host_info *info = &client_info.host_info;
00258
00259
00260 if (gethostname(info->hostname, HOST_NAME_MAX) != 0)
00261 {
00262 iwc_error("Unable to retrieve hostname (%s)\n", strerror(errno));
00263 return -1;
00264 }
00265 info->hostname[HOST_NAME_MAX] = '\0';
00266
00267
00268 memset(&addr, 0, sizeof(addr));
00269 if (get_ip_by_dev(&addr, client_info.host_if) != 0)
00270 return -1;
00271
00272 memset(addr_string, 0, INET6_ADDRSTRLEN);
00273 inet_ntop(ip_family, &addr, addr_string, INET6_ADDRSTRLEN);
00274
00275
00276 memset(&request, 0, sizeof(struct addrinfo));
00277 request.ai_flags = 0;
00278 request.ai_family = ip_family;
00279 request.ai_socktype = SOCK_DGRAM;
00280 request.ai_protocol = 0;
00281 request.ai_canonname = NULL;
00282 request.ai_addr = NULL;
00283 request.ai_next = NULL;
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 if (getaddrinfo(addr_string, client_info.host_port, &request, &result) < 0)
00295 {
00296 iwc_error("Cannot find listen address (%s)\n", gai_strerror(errno));
00297 iwc_error("%s\n", strerror(errno));
00298 return -1;
00299 }
00300 while (1)
00301 {
00302 if (ip_family == result->ai_family)
00303 {
00304 memmove(&info->addr_info, result, sizeof(struct addrinfo));
00305 memmove(&info->addr, result->ai_addr, sizeof(struct sockaddr_storage));
00306 info->addr_info.ai_addr = (struct sockaddr *) &info->addr;
00307 info->addr_info.ai_canonname = info->hostname;
00308 if (ip_family == AF_INET6)
00309 ((struct sockaddr_in6 *) &info->addr)->sin6_scope_id =
00310 if_nametoindex(client_info.host_if);
00311 }
00312 if ((result = result->ai_next) == NULL)
00313 break;
00314 }
00315 freeaddrinfo(result);
00316
00317
00318 get_mac_by_dev(client_info.host_mac, client_info.host_if);
00319
00320
00321 if ((client_info.host_mac[0] == 0) && (client_info.host_mac[1] == 0) &&
00322 (client_info.host_mac[2] == 0) && (client_info.host_mac[3] == 0) &&
00323 (client_info.host_mac[4] == 0) && (client_info.host_mac[5] == 0))
00324 {
00325 iwc_debug("No valid MAC address found for interface %s\n", client_info.host_if);
00326 iwc_debug("-> Generating random ID\n");
00327 srand(time(NULL));
00328 random_int = random();
00329 id_source[0] = 0x0A;
00330 id_source[1] = 0xAA;
00331 id_source[2] = (random_int>>24) & 0xFF;
00332 id_source[3] = (random_int>>16) & 0xFF;
00333 id_source[4] = (random_int>>8) & 0xFF;
00334 id_source[5] = random_int & 0xFF;
00335 } else {
00336 memmove(id_source, client_info.host_mac, ETH_ALEN);
00337 }
00338 for (i = 0; i < ETH_ALEN; i++)
00339 sprintf(client_info.host_id + (2 * i), "%02x", id_source[i]);
00340 client_info.host_id[2 * ETH_ALEN] = '\0';
00341
00342 iwc_print_client_info(&client_info);
00343 return 0;
00344 }
00345
00349 int
00350 iwc_init_net()
00351 {
00352 int i = 0;
00353 int phy_mtu = 0;
00354 int vif_mtu = 0;
00355 char vif_names[MAX_NUM_VIF][IFNAMSIZ + 1];
00356
00357
00358 net_socket = -1;
00359 for (i = 0; i < MAX_NUM_VIF; i++)
00360 {
00361 tap_sockets[i] = -1;
00362 *vif_names[i] = '\0';
00363 }
00364
00365
00366
00367 if ((num_vif = vif_get_names(vif_names)) < 1)
00368 return -1;
00369
00370 iwc_log("Capturing %i virtual interface(s):\n", num_vif);
00371 for (i = 0; i < num_vif; i++)
00372 iwc_log(" %s\n", vif_names[i]);
00373
00374
00375 phy_mtu = get_mtu_by_dev(client_info.host_if);
00376 for (i = 0; i < num_vif; i++)
00377 {
00378 vif_mtu = get_mtu_by_dev(vif_names[i]);
00379 if (phy_mtu < vif_mtu + sizeof(struct ether_header) + DATA_PREAMBLE_SIZE)
00380 {
00381 iwc_error("MTU %i on interface '%s' is too small!\n",
00382 phy_mtu, client_info.host_if);
00383 iwc_error("At least %i (%s) + %i required\n", vif_mtu, vif_names[i],
00384 sizeof(struct ether_header) + DATA_PREAMBLE_SIZE);
00385 return -1;
00386 }
00387 }
00388
00389
00390 for (i = 0; i < num_vif; i++)
00391 {
00392 if ((tap_sockets[i] = open_tap_socket(vif_names[i])) < 0)
00393 return -1;
00394 }
00395
00396
00397 if ((net_socket = bind_net_socket(&(client_info.host_info.addr_info))) < 0)
00398 return -1;
00399
00400 return 0;
00401 }
00402
00406 int
00407 iwc_init_create_pidfile(const char *path)
00408 {
00409 char buf[32];
00410
00411 int fd = open(path, O_WRONLY | O_CREAT, 0640);
00412 if (fd < 0)
00413 {
00414 iwc_error("iwc_init_create_pidfile(): open(%s) failed (%s)",
00415 path, strerror(errno));
00416 return 1;
00417 } else {
00418 snprintf(buf, sizeof(buf), "%d\n", getpid());
00419 if (write(fd, buf, strlen(buf)) < 0)
00420 {
00421 iwc_error("iwc_init_create_pidfile(): write failed (%s)",
00422 path, strerror(errno));
00423 close(fd);
00424 return 1;
00425 }
00426 close(fd);
00427 }
00428 return 0;
00429 }
00430
00434 int
00435 iwc_init_remove_pidfile(const char *path)
00436 {
00437 if (unlink(path) < 0)
00438 {
00439 iwc_debug("iwc_model_init_remove_pidfile(): unlink(%s) failed (%s)\n",
00440 path, strerror(errno));
00441 return 1;
00442 }
00443 return 0;
00444 }
00445
00450 int
00451 iwc_init_check_pidfile(const char *path)
00452 {
00453 char buf[32];
00454 ssize_t rtrn;
00455
00456 int fd = open(path, O_RDONLY);
00457 if (fd < 0)
00458 {
00459 if (errno == ENOENT)
00460 return 0;
00461
00462 iwc_error("iwc_init_check_pidfile(): open(%s) failed (%s)",
00463 path, strerror(errno));
00464 return -1;
00465 }
00466 rtrn = read(fd, buf, sizeof(buf));
00467 close(fd);
00468
00469 if (rtrn <= 0)
00470 {
00471 if (rtrn == 0)
00472 {
00473 iwc_debug("Empty PID file in %s, overriding", path);
00474 return 0;
00475 }
00476
00477 iwc_error("iwc_init_check_pidfile(): read(%s) failed (%s)",
00478 path, strerror(errno));
00479 return -1;
00480
00481 } else {
00482
00483 pid_t pid;
00484
00485 if (buf[rtrn-1] == '\n')
00486 rtrn--;
00487 buf[rtrn] = '\0';
00488 pid = atoi(buf);
00489 if (pid == getpid() ||
00490 (kill(pid, 0) < 0 && errno == ESRCH))
00491 {
00492
00493 iwc_debug("iwc_init_check_pidfile(): found PID file (%i) but no such process, ignoring\n",
00494 pid);
00495 iwc_init_remove_pidfile(path);
00496 return 0;
00497 } else {
00498 iwc_error("Traffic redirection already running with PID %i\n", pid);
00499 printf("Notice: Shutdown %s with 'kill -15 %i'\n", exec_name, pid);
00500 return pid;
00501 }
00502 }
00503 }