TunnelIPv6Interface::TunnelIPv6Interface(const std::string& interface_name, int mtu): UnixSocket(tunnel_open(interface_name.c_str()), true), mInterfaceName(interface_name), mLastError(0), mNetlinkFD(-1), mHardwareAddress(), mRealmLocalAddress(), mRealmLocalPrefixSize(64) { if (0 > mFDRead) { throw std::invalid_argument("Unable to open tunnel interface"); } { char ActualInterfaceName[TUNNEL_MAX_INTERFACE_NAME_LEN] = ""; int ret = 0; ret = tunnel_get_name(mFDRead, ActualInterfaceName, sizeof(ActualInterfaceName)); if (ret) { syslog(LOG_WARNING, "TunnelIPv6Interface: Couldn't get tunnel name! errno=%d, %s", errno, strerror(errno)); } else if (mInterfaceName != ActualInterfaceName) { syslog(LOG_WARNING, "TunnelIPv6Interface: Couldn't create tunnel named \"%s\", got \"%s\" instead!", mInterfaceName.c_str(), ActualInterfaceName); mInterfaceName = ActualInterfaceName; } } tunnel_set_mtu(mFDRead, mtu); setup_signals(); }
/* * Main entry point: */ int MAIN(int argc, char **argv) { // First print GPL information: printf("%s %s [%s] Copyright (C) 2017 basil\n", PROGRAM_NAME_LONG, PROGRAM_VERSION, PLATFORM); puts("License GPLv3+: GNU GPL version 3 or later " "<http://gnu.org/licenses/gpl.html>."); puts("This is free software: you are free to change and redistribute it."); puts("There is NO WARRANTY, to the extent permitted by law."); putchar('\n'); // Process options: options_init(argc, argv); // Initialise various components (order is important!). log_init(); trace("changing to home directory %s", PROGRAM_DIR); chdir_home(); trace("installing files (if required)"); install_files(); trace("initialising user configuration"); config_init(); trace("initialising tunnel management"); tunnel_init(); // Initialise the sockets library (if required on this platform). trace("initialising sockets"); init_sockets(); // Get number of threads. int num_threads = (options_get()->seen_num_threads? options_get()->val_num_threads: NUM_THREADS_DEFAULT); if (num_threads < 1 || num_threads > NUM_THREADS_MAX) { error("unable to spawn %d threads; expected a number within the " "range 1..%u", num_threads, NUM_THREADS_MAX); } // Create configuration server thread. trace("launching configuration server thread"); if (thread_lock_init(&config_lock)) { error("unable to initialise global configuration lock"); } thread_t config_thread; if (!options_get()->seen_no_ui && thread_create(&config_thread, configuration_thread, NULL) != 0) { error("unable to create configuration server thread"); } // Open the packet capture/injection device driver. trace("initialising packet capture"); if (!options_get()->seen_no_capture) { init_capture(); } // Open the tunnels. trace("initialising tunnels"); tunnel_file_read(); tunnel_open(); // Go to sleep if we are not capturing packets. while (options_get()->seen_no_capture) { sleeptime(UINT64_MAX); } // Start worker threads. for (int i = 1; i < num_threads; i++) { thread_t work_thread; if (thread_create(&work_thread, worker_thread, NULL) != 0) { error("unable to create worker thread"); } } worker_thread((void *)0); return EXIT_SUCCESS; }