void start_plugin() { print_debug("%s : start_plugin\n", GGadu_PLUGIN_NAME); register_signal(update_handler, "update config"); register_signal(update_handler, "get current version"); print_debug("%s : create menu\n", GGadu_PLUGIN_NAME); menu_updatemenu = update_menu(); signal_emit(GGadu_PLUGIN_NAME, "gui register menu", menu_updatemenu, "main-gui"); if (timer != -1) g_source_remove(timer); /* initialize timers */ if ((gint) ggadu_config_var_get(update_handler, "check_automatically")) { timer = g_timeout_add(update_get_interval(), update_check, NULL); print_debug("%s : Timer ID set to %d\n", GGadu_PLUGIN_NAME, timer); } else { print_debug("%s : Resetting timer!\n", GGadu_PLUGIN_NAME); timer = -1; } if ((gint) ggadu_config_var_get(update_handler, "check_on_startup")) /* wait a while before looking for updates */ g_timeout_add(3000, update_check_on_startup, NULL); }
void signals_init() { register_signal(SIGUSR1, sigusr1); register_signal(SIGUSR2, sigusr2); register_signal(SIGALRM, sigalarm); register_signal(SIGHUP, sighup); }
/* PLUGIN INITIALISATION */ GGaduPlugin *initialize_plugin(gpointer conf_ptr) { gchar *this_configdir; print_debug("%s : initialize\n", GGadu_PLUGIN_NAME); GGadu_PLUGIN_ACTIVATE(conf_ptr); /* THIS IS IMPORTANT HERE */ handler = (GGaduPlugin *) register_plugin(GGadu_PLUGIN_NAME, _("External player sound driver")); SOUND_PLAY_FILE_SIG = register_signal(handler, "sound play file"); UPDATE_CONFIG_SIG = register_signal(handler, "update config"); if (g_getenv("HOME_ETC")) this_configdir = g_build_filename(g_getenv("HOME_ETC"), "gg2", NULL); else this_configdir = g_build_filename(g_get_home_dir(), ".gg2", NULL); ggadu_config_set_filename((GGaduPlugin *) handler, g_build_filename(this_configdir, "my-plugin", NULL)); ggadu_config_var_add(handler, "player", VAR_STR); if (!ggadu_config_read(handler)) g_warning(_("Unable to read configuration file for plugin %s"), ""); register_signal_receiver((GGaduPlugin *) handler, (signal_func_ptr) my_signal_receive); g_free(this_configdir); return handler; }
void read_incoming_tun (struct context *c) { /* * Setup for read() call on TUN/TAP device. */ /*ASSERT (!c->c2.to_link.len);*/ perf_push (PERF_READ_IN_TUN); c->c2.buf = c->c2.buffers->read_tun_buf; #ifdef TUN_PASS_BUFFER read_tun_buffered (c->c1.tuntap, &c->c2.buf, MAX_RW_SIZE_TUN (&c->c2.frame)); #else ASSERT (buf_init (&c->c2.buf, FRAME_HEADROOM (&c->c2.frame))); ASSERT (buf_safe (&c->c2.buf, MAX_RW_SIZE_TUN (&c->c2.frame))); c->c2.buf.len = read_tun (c->c1.tuntap, BPTR (&c->c2.buf), MAX_RW_SIZE_TUN (&c->c2.frame)); #endif #ifdef PACKET_TRUNCATION_CHECK ipv4_packet_size_verify (BPTR (&c->c2.buf), BLEN (&c->c2.buf), TUNNEL_TYPE (c->c1.tuntap), "READ_TUN", &c->c2.n_trunc_tun_read); #endif /* Was TUN/TAP interface stopped? */ if (tuntap_stop (c->c2.buf.len)) { register_signal (c, SIGTERM, "tun-stop"); msg (M_INFO, "TUN/TAP interface has been stopped, exiting"); perf_pop (); return; } /* Was TUN/TAP I/O operation aborted? */ if (tuntap_abort(c->c2.buf.len)) { register_signal(c, SIGHUP, "tun-abort"); c->persist.restart_sleep_seconds = 10; msg(M_INFO, "TUN/TAP I/O operation aborted, restarting"); perf_pop(); return; } /* Check the status return from read() */ check_status (c->c2.buf.len, "read from TUN/TAP", NULL, c->c1.tuntap); perf_pop (); }
int main (int argc, char *argv) { register_signal(SIGUSR1); register_signal(SIGUSR2); /* Busy wait for the child to send a signal. */ while (!usr_interrupt){ sleep(100000); } /* Now continue execution. */ puts ("That's all, folks!"); return 0; }
void check_add_routes_dowork (struct context *c) { if (test_routes (c->c1.route_list, c->c1.tuntap)) { check_add_routes_action (c, false); } else if (event_timeout_trigger (&c->c2.route_wakeup_expire, &c->c2.timeval, ETT_DEFAULT)) { check_add_routes_action (c, true); } else { msg (D_ROUTE, "Route: Waiting for TUN/TAP interface to come up..."); if (c->c1.tuntap) { if (!tun_standby (c->c1.tuntap)) { register_signal (c, SIGHUP, "ip-fail"); c->persist.restart_sleep_seconds = 10; #ifdef WIN32 show_routes (M_INFO|M_NOPREFIX); show_adapters (M_INFO|M_NOPREFIX); #endif } } update_time (); if (c->c2.route_wakeup.n != 1) event_timeout_init (&c->c2.route_wakeup, 1, now); event_timeout_reset (&c->c2.ping_rec_interval); } }
void check_tls_dowork (struct context *c) { interval_t wakeup = BIG_TIMEOUT; if (interval_test (&c->c2.tmp_int)) { const int tmp_status = tls_multi_process (c->c2.tls_multi, &c->c2.to_link, &c->c2.to_link_addr, get_link_socket_info (c), &wakeup); if (tmp_status == TLSMP_ACTIVE) { update_time (); interval_action (&c->c2.tmp_int); } else if (tmp_status == TLSMP_KILL) { register_signal (c, SIGTERM, "auth-control-exit"); } interval_future_trigger (&c->c2.tmp_int, wakeup); } interval_schedule_wakeup (&c->c2.tmp_int, &wakeup); if (wakeup) context_reschedule_sec (c, wakeup); }
int main(int argc, char *argv[]) { int fd = 0; struct aiocb aiocb = {0}; if (argc != 2) { fprintf(stderr, "Usage: ./a.out filename1 filename2 ...\n"); return EXIT_FAILURE; } register_signal(SIGIO); fd = open(argv[1], O_RDONLY); if (fd < 0) { fprintf(stderr, "open failure\n"); return EXIT_FAILURE; } aiocb.aio_fildes = fd; aiocb.aio_buf = (volatile void *)malloc(BUFSIZ+1); aiocb.aio_nbytes = BUFSIZ; aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; aiocb.aio_sigevent.sigev_signo = SIGIO; aiocb.aio_sigevent.sigev_value.sival_ptr = &aiocb; memset((void *)aiocb.aio_buf, 0, BUFSIZ+1); aiocb.aio_offset = offset; aio_read(&aiocb); sleep(1); return EXIT_SUCCESS; }
/** * If a restart signal is received during exit-notification, reset the * signal and return true. If its a soft restart signal from the event loop * which implies the loop cannot continue, remap to SIGTERM to exit promptly. */ static bool ignore_restart_signals(struct context *c) { bool ret = false; #ifdef ENABLE_OCC if ( (c->sig->signal_received == SIGUSR1 || c->sig->signal_received == SIGHUP) && event_timeout_defined(&c->c2.explicit_exit_notification_interval) ) { if (c->sig->source == SIG_SOURCE_HARD) { msg(M_INFO, "Ignoring %s received during exit notification", signal_name(c->sig->signal_received, true)); signal_reset(c->sig); ret = true; } else { msg(M_INFO, "Converting soft %s received during exit notification to SIGTERM", signal_name(c->sig->signal_received, true)); register_signal(c, SIGTERM, "exit-with-notification"); ret = false; } } #endif return ret; }
void incoming_push_message(struct context *c, const struct buffer *buffer) { struct gc_arena gc = gc_new(); unsigned int option_types_found = 0; int status; msg(D_PUSH, "PUSH: Received control message: '%s'", sanitize_control_message(BSTR(buffer), &gc)); status = process_incoming_push_msg(c, buffer, c->options.pull, pull_permission_mask(c), &option_types_found); if (status == PUSH_MSG_ERROR) { msg(D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", sanitize_control_message(BSTR(buffer), &gc)); } else if (status == PUSH_MSG_REPLY || status == PUSH_MSG_CONTINUATION) { c->options.push_option_types_found |= option_types_found; /* delay bringing tun/tap up until --push parms received from remote */ if (status == PUSH_MSG_REPLY) { if (!do_up(c, true, c->options.push_option_types_found)) { msg(D_PUSH_ERRORS, "Failed to open tun/tap interface"); goto error; } } event_timeout_clear(&c->c2.push_request_interval); } else if (status == PUSH_MSG_REQUEST) { if (c->options.mode == MODE_SERVER) { struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE]; /* Do not regenerate keys if client send a second push request */ if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized && !tls_session_update_crypto_params(session, &c->options, &c->c2.frame)) { msg(D_TLS_ERRORS, "TLS Error: initializing data channel failed"); goto error; } } } goto cleanup; error: register_signal(c, SIGUSR1, "process-push-msg-failed"); cleanup: gc_free(&gc); }
void check_server_poll_timeout_dowork (struct context *c) { event_timeout_reset (&c->c2.server_poll_interval); if (!tls_initial_packet_received (c->c2.tls_multi)) { msg (M_INFO, "Server poll timeout, restarting"); register_signal (c, SIGUSR1, "server_poll"); c->persist.restart_sleep_seconds = -1; } }
/* PLUGIN INITIALISATION */ GGaduPlugin *initialize_plugin(gpointer conf_ptr) { GGadu_PLUGIN_ACTIVATE(conf_ptr); ignore_handler = (GGaduPlugin *) register_plugin(GGadu_PLUGIN_NAME, _("Ignore option support")); IGNORE_ADD_CONTACT_SIG = register_signal(ignore_handler, "ignore add contact"); IGNORE_REMOVE_CONTACT_SIG = register_signal(ignore_handler, "ignore remove contact"); IGNORE_CHECK_CONTACT_SIG = register_signal(ignore_handler, "ignore check contact"); IGNORE_DIALOG_ADD_ID_SIG = register_signal(ignore_handler, "ignore dialog add id"); IGNORE_DIALOG_REMOVE_ID_SIG = register_signal(ignore_handler, "ignore dialog remove id"); ggadu_config_set_filename(ignore_handler, g_build_filename(config->configdir, "ignore-main", NULL)); ggadu_config_var_add(ignore_handler, "list", VAR_STR); if (!ggadu_config_read(ignore_handler)) g_warning(_("Unable to read configuration file for plugin %s"), ""); register_signal_receiver(ignore_handler, (signal_func_ptr) my_signal_receive); return ignore_handler; }
/* PLUGIN INITIALISATION */ GGaduPlugin *initialize_plugin(gpointer conf_ptr) { print_debug("%s : initialize\n", GGadu_PLUGIN_NAME); GGadu_PLUGIN_ACTIVATE(conf_ptr); handler = (GGaduPlugin *) register_plugin(GGadu_PLUGIN_NAME, _("External history viewer")); HISTORY_SHOW_FILE_SIG = register_signal(handler, "history show file"); UPDATE_CONFIG_SIG = register_signal(handler, "update config"); ggadu_config_set_filename((GGaduPlugin *) handler, g_build_filename(config->configdir, "history-external", NULL)); ggadu_config_var_add_with_default(handler, "viewer", VAR_STR, g_build_filename(BINDIR, "gghist %s", NULL)); if (!ggadu_config_read(handler)) g_warning(_("Unable to read configuration file for plugin %s"), ""); register_signal_receiver((GGaduPlugin *) handler, (signal_func_ptr) my_signal_receive); return handler; }
void start_plugin() { int e; if ((e = regcomp(®ex, "^([^ ]+)( ([^ ]+)( (.*))?)?$", REG_EXTENDED)) != 0) { char *err = get_regerror(e, ®ex); print_debug("%s: regcomp() failed: %s\n", GGadu_PLUGIN_NAME, err); print_debug("%s: plugin disabled\n", GGadu_PLUGIN_NAME); free(err); return; } if (remote_init() == -1) return; register_signal(handler, "update config"); /* perfidnie podpinamy siê pod sygna³ dockleta */ register_signal(handler, "docklet set icon"); register_signal(handler, "docklet set default icon"); menu_remotemenu = remote_menu(); signal_emit(GGadu_PLUGIN_NAME, "gui register menu", menu_remotemenu, "main-gui"); }
GGaduPlugin *initialize_plugin(gpointer conf_ptr) { print_debug("%s : initialize", GGadu_PLUGIN_NAME); GGadu_PLUGIN_ACTIVATE(conf_ptr); handler = (GGaduPlugin *) register_plugin(GGadu_PLUGIN_NAME, _("ESD sound driver")); SOUND_PLAY_FILE_SIG = register_signal(handler, "sound play file"); register_signal_receiver((GGaduPlugin *) handler, (signal_func_ptr) my_signal_receive); return handler; }
void alarm_handler(int signal){ if (signal != SIGALRM) { DBG("Caught wrong signal: %d", signal); exit(1); return; } //DBG("[SIGNAL] NACK LEN = %d", globals.nackl.num_members); if ((globals.nackl).num_members != 0) { // Read the nack list //print_list(&globals.datal); send_nack_packet(); // Register another alarm register_signal(); } }
int main(int argc, char **argv) { char *ptr; int c, i, j, cpu_tmp, opt_index, ops_touched = 0, vals[4] = {0}; bool prio_high = false, setsockmem = true; void (*main_loop)(struct ctx *ctx) = NULL; struct ctx ctx; init_ctx(&ctx); srand(time(NULL)); while ((c = getopt_long(argc, argv, short_options, long_options, &opt_index)) != EOF) { switch (c) { case 'd': case 'i': ctx.device_in = xstrdup(optarg); break; case 'o': ctx.device_out = xstrdup(optarg); break; case 'P': ctx.prefix = xstrdup(optarg); break; case 'R': ctx.rfraw = 1; break; case 'r': ctx.randomize = true; break; case 'J': ctx.jumbo = true; break; case 'T': ctx.magic = (uint32_t) strtoul(optarg, NULL, 0); pcap_check_magic(ctx.magic); break; case 'f': ctx.filter = xstrdup(optarg); break; case 'M': ctx.promiscuous = false; break; case 'N': ctx.hwtimestamp = false; break; case 'A': setsockmem = false; break; case 'u': ctx.uid = strtoul(optarg, NULL, 0); ctx.enforce = true; break; case 'g': ctx.gid = strtoul(optarg, NULL, 0); ctx.enforce = true; break; case 'C': ctx.fanout_group = strtoul(optarg, NULL, 0); if (ctx.fanout_group == 0) panic("Non-zero fanout group id required!\n"); break; case 'K': if (!strncmp(optarg, "hash", strlen("hash"))) ctx.fanout_type = PACKET_FANOUT_HASH; else if (!strncmp(optarg, "lb", strlen("lb")) || !strncmp(optarg, "rr", strlen("rr"))) ctx.fanout_type = PACKET_FANOUT_LB; else if (!strncmp(optarg, "cpu", strlen("cpu"))) ctx.fanout_type = PACKET_FANOUT_CPU; else if (!strncmp(optarg, "rnd", strlen("rnd"))) ctx.fanout_type = PACKET_FANOUT_RND; else if (!strncmp(optarg, "roll", strlen("roll"))) ctx.fanout_type = PACKET_FANOUT_ROLLOVER; else if (!strncmp(optarg, "qm", strlen("qm"))) ctx.fanout_type = PACKET_FANOUT_QM; else panic("Unknown fanout type!\n"); break; case 'L': if (!strncmp(optarg, "defrag", strlen("defrag"))) ctx.fanout_type |= PACKET_FANOUT_FLAG_DEFRAG; else if (!strncmp(optarg, "roll", strlen("roll"))) ctx.fanout_type |= PACKET_FANOUT_FLAG_ROLLOVER; else panic("Unknown fanout option!\n"); break; case 't': if (!strncmp(optarg, "host", strlen("host"))) ctx.packet_type = PACKET_HOST; else if (!strncmp(optarg, "broadcast", strlen("broadcast"))) ctx.packet_type = PACKET_BROADCAST; else if (!strncmp(optarg, "multicast", strlen("multicast"))) ctx.packet_type = PACKET_MULTICAST; else if (!strncmp(optarg, "others", strlen("others"))) ctx.packet_type = PACKET_OTHERHOST; else if (!strncmp(optarg, "outgoing", strlen("outgoing"))) ctx.packet_type = PACKET_OUTGOING; else ctx.packet_type = -1; break; case 'S': ptr = optarg; for (j = i = strlen(optarg); i > 0; --i) { if (!isdigit(optarg[j - i])) break; ptr++; } if (!strncmp(ptr, "KiB", strlen("KiB"))) ctx.reserve_size = 1 << 10; else if (!strncmp(ptr, "MiB", strlen("MiB"))) ctx.reserve_size = 1 << 20; else if (!strncmp(ptr, "GiB", strlen("GiB"))) ctx.reserve_size = 1 << 30; else panic("Syntax error in ring size param!\n"); ctx.reserve_size *= strtoul(optarg, NULL, 0); break; case 'b': cpu_tmp = strtol(optarg, NULL, 0); cpu_affinity(cpu_tmp); if (ctx.cpu != -2) ctx.cpu = cpu_tmp; break; case 'H': prio_high = true; break; case 'c': ctx.pcap = PCAP_OPS_RW; ops_touched = 1; break; case 'm': ctx.pcap = PCAP_OPS_MM; ops_touched = 1; break; case 'G': ctx.pcap = PCAP_OPS_SG; ops_touched = 1; break; case 'Q': ctx.cpu = -2; break; case 's': ctx.print_mode = PRINT_NONE; break; case 'q': ctx.print_mode = PRINT_LESS; break; case 'X': ctx.print_mode = (ctx.print_mode == PRINT_ASCII) ? PRINT_HEX_ASCII : PRINT_HEX; break; case 'l': ctx.print_mode = (ctx.print_mode == PRINT_HEX) ? PRINT_HEX_ASCII : PRINT_ASCII; break; case 'k': ctx.kpull = strtoul(optarg, NULL, 0); break; case 'n': frame_count_max = strtoul(optarg, NULL, 0); break; case 'F': ptr = optarg; for (j = i = strlen(optarg); i > 0; --i) { if (!isdigit(optarg[j - i])) break; ptr++; } if (!strncmp(ptr, "KiB", strlen("KiB"))) { ctx.dump_interval = 1 << 10; ctx.dump_mode = DUMP_INTERVAL_SIZE; } else if (!strncmp(ptr, "MiB", strlen("MiB"))) { ctx.dump_interval = 1 << 20; ctx.dump_mode = DUMP_INTERVAL_SIZE; } else if (!strncmp(ptr, "GiB", strlen("GiB"))) { ctx.dump_interval = 1 << 30; ctx.dump_mode = DUMP_INTERVAL_SIZE; } else if (!strncmp(ptr, "sec", strlen("sec"))) { ctx.dump_interval = 1; ctx.dump_mode = DUMP_INTERVAL_TIME; } else if (!strncmp(ptr, "min", strlen("min"))) { ctx.dump_interval = 60; ctx.dump_mode = DUMP_INTERVAL_TIME; } else if (!strncmp(ptr, "hrs", strlen("hrs"))) { ctx.dump_interval = 60 * 60; ctx.dump_mode = DUMP_INTERVAL_TIME; } else if (!strncmp(ptr, "s", strlen("s"))) { ctx.dump_interval = 1; ctx.dump_mode = DUMP_INTERVAL_TIME; } else { panic("Syntax error in time/size param!\n"); } ctx.dump_interval *= strtoul(optarg, NULL, 0); break; case 'V': ctx.verbose = true; break; case 'B': ctx.dump_bpf = true; break; case 'D': pcap_dump_type_features(); die(); break; case 'U': update_geoip(); die(); break; case 'w': ctx.link_type = LINKTYPE_LINUX_SLL; break; case 'v': version(); break; case 'h': help(); break; case '?': switch (optopt) { case 'd': case 'i': case 'o': case 'f': case 't': case 'P': case 'F': case 'n': case 'S': case 'b': case 'k': case 'T': case 'u': case 'g': case 'e': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) printf("Unknown option character `0x%X\'!\n", optopt); die(); } default: break; } } if (!ctx.filter && optind != argc) ctx.filter = argv2str(optind, argc, argv); if (!ctx.device_in) ctx.device_in = xstrdup("any"); register_signal(SIGINT, signal_handler); register_signal(SIGQUIT, signal_handler); register_signal(SIGTERM, signal_handler); register_signal(SIGHUP, signal_handler); tprintf_init(); if (prio_high) { set_proc_prio(-20); set_sched_status(SCHED_FIFO, sched_get_priority_max(SCHED_FIFO)); } if (device_mtu(ctx.device_in) || !strncmp("any", ctx.device_in, strlen(ctx.device_in))) { if (ctx.rfraw) setup_rfmon_mac80211_dev(&ctx, &ctx.device_in); if (!ctx.link_type) ctx.link_type = pcap_dev_to_linktype(ctx.device_in); if (link_has_sll_hdr(ctx.link_type)) { switch (ctx.magic) { case ORIGINAL_TCPDUMP_MAGIC: ctx.magic = ORIGINAL_TCPDUMP_MAGIC_LL; break; case NSEC_TCPDUMP_MAGIC: ctx.magic = NSEC_TCPDUMP_MAGIC_LL; break; case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC): ctx.magic = ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC_LL); break; case ___constant_swab32(NSEC_TCPDUMP_MAGIC): ctx.magic = ___constant_swab32(NSEC_TCPDUMP_MAGIC_LL); break; } } if (!ctx.device_out) { ctx.dump = 0; main_loop = recv_only_or_dump; } else if (device_mtu(ctx.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); main_loop = receive_to_xmit; } else { ctx.dump = 1; register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO); main_loop = recv_only_or_dump; if (!ops_touched) ctx.pcap = PCAP_OPS_SG; } } else { if (ctx.device_out && device_mtu(ctx.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); main_loop = pcap_to_xmit; if (!ops_touched) ctx.pcap = PCAP_OPS_MM; } else { setsockmem = false; main_loop = read_pcap; if (!ops_touched) ctx.pcap = PCAP_OPS_SG; } } bug_on(!main_loop); init_geoip(0); if (setsockmem) set_system_socket_memory(vals, array_size(vals)); if (!ctx.enforce) xlockme(); if (ctx.verbose) printf("pcap file I/O method: %s\n", pcap_ops_group_to_str[ctx.pcap]); main_loop(&ctx); if (!ctx.enforce) xunlockme(); if (setsockmem) reset_system_socket_memory(vals, array_size(vals)); destroy_geoip(); device_restore_irq_affinity_list(); tprintf_cleanup(); destroy_ctx(&ctx); return 0; }
void process_incoming_link (struct context *c) { struct gc_arena gc = gc_new (); bool decrypt_status; struct link_socket_info *lsi = get_link_socket_info (c); const uint8_t *orig_buf = c->c2.buf.data; perf_push (PERF_PROC_IN_LINK); if (c->c2.buf.len > 0) { c->c2.link_read_bytes += c->c2.buf.len; link_read_bytes_global += c->c2.buf.len; #ifdef ENABLE_MEMSTATS if (mmap_stats) mmap_stats->link_read_bytes = link_read_bytes_global; #endif c->c2.original_recv_size = c->c2.buf.len; #ifdef ENABLE_MANAGEMENT if (management) { management_bytes_in (management, c->c2.buf.len); #ifdef MANAGEMENT_DEF_AUTH management_bytes_server (management, &c->c2.link_read_bytes, &c->c2.link_write_bytes, &c->c2.mda_context); #endif } #endif } else c->c2.original_recv_size = 0; #ifdef ENABLE_DEBUG /* take action to corrupt packet if we are in gremlin test mode */ if (c->options.gremlin) { if (!ask_gremlin (c->options.gremlin)) c->c2.buf.len = 0; corrupt_gremlin (&c->c2.buf, c->options.gremlin); } #endif /* log incoming packet */ #ifdef LOG_RW if (c->c2.log_rw && c->c2.buf.len > 0) fprintf (stderr, "R"); #endif msg (D_LINK_RW, "%s READ [%d] from %s: %s", proto2ascii (lsi->proto, true), BLEN (&c->c2.buf), print_link_socket_actual (&c->c2.from, &gc), PROTO_DUMP (&c->c2.buf, &gc)); /* * Good, non-zero length packet received. * Commence multi-stage processing of packet, * such as authenticate, decrypt, decompress. * If any stage fails, it sets buf.len to 0 or -1, * telling downstream stages to ignore the packet. */ if (c->c2.buf.len > 0) { if (!link_socket_verify_incoming_addr (&c->c2.buf, lsi, &c->c2.from)) link_socket_bad_incoming_addr (&c->c2.buf, lsi, &c->c2.from); #ifdef ENABLE_CRYPTO #ifdef ENABLE_SSL if (c->c2.tls_multi) { /* * If tls_pre_decrypt returns true, it means the incoming * packet was a good TLS control channel packet. If so, TLS code * will deal with the packet and set buf.len to 0 so downstream * stages ignore it. * * If the packet is a data channel packet, tls_pre_decrypt * will load crypto_options with the correct encryption key * and return false. */ if (tls_pre_decrypt (c->c2.tls_multi, &c->c2.from, &c->c2.buf, &c->c2.crypto_options)) { interval_action (&c->c2.tmp_int); /* reset packet received timer if TLS packet */ if (c->options.ping_rec_timeout) event_timeout_reset (&c->c2.ping_rec_interval); } } #if P2MP_SERVER /* * Drop non-TLS packet if client-connect script/plugin has not * yet succeeded. */ if (c->c2.context_auth != CAS_SUCCEEDED) c->c2.buf.len = 0; #endif #endif /* ENABLE_SSL */ /* authenticate and decrypt the incoming packet */ decrypt_status = openvpn_decrypt (&c->c2.buf, c->c2.buffers->decrypt_buf, &c->c2.crypto_options, &c->c2.frame); if (!decrypt_status && link_socket_connection_oriented (c->c2.link_socket)) { /* decryption errors are fatal in TCP mode */ register_signal (c, SIGUSR1, "decryption-error"); /* SOFT-SIGUSR1 -- decryption error in TCP mode */ msg (D_STREAM_ERRORS, "Fatal decryption error (process_incoming_link), restarting"); goto done; } #endif /* ENABLE_CRYPTO */ #ifdef ENABLE_FRAGMENT if (c->c2.fragment) fragment_incoming (c->c2.fragment, &c->c2.buf, &c->c2.frame_fragment); #endif #ifdef ENABLE_LZO /* decompress the incoming packet */ if (lzo_defined (&c->c2.lzo_compwork)) lzo_decompress (&c->c2.buf, c->c2.buffers->lzo_decompress_buf, &c->c2.lzo_compwork, &c->c2.frame); #endif #ifdef PACKET_TRUNCATION_CHECK /* if (c->c2.buf.len > 1) --c->c2.buf.len; */ ipv4_packet_size_verify (BPTR (&c->c2.buf), BLEN (&c->c2.buf), TUNNEL_TYPE (c->c1.tuntap), "POST_DECRYPT", &c->c2.n_trunc_post_decrypt); #endif /* * Set our "official" outgoing address, since * if buf.len is non-zero, we know the packet * authenticated. In TLS mode we do nothing * because TLS mode takes care of source address * authentication. * * Also, update the persisted version of our packet-id. */ if (!TLS_MODE (c)) link_socket_set_outgoing_addr (&c->c2.buf, lsi, &c->c2.from, NULL, c->c2.es); /* reset packet received timer */ if (c->options.ping_rec_timeout && c->c2.buf.len > 0) event_timeout_reset (&c->c2.ping_rec_interval); /* increment authenticated receive byte count */ if (c->c2.buf.len > 0) { c->c2.link_read_bytes_auth += c->c2.buf.len; c->c2.max_recv_size_local = max_int (c->c2.original_recv_size, c->c2.max_recv_size_local); } /* Did we just receive an openvpn ping packet? */ if (is_ping_msg (&c->c2.buf)) { dmsg (D_PING, "RECEIVED PING PACKET"); c->c2.buf.len = 0; /* drop packet */ } #ifdef ENABLE_OCC /* Did we just receive an OCC packet? */ if (is_occ_msg (&c->c2.buf)) process_received_occ_msg (c); #endif buffer_turnover (orig_buf, &c->c2.to_tun, &c->c2.buf, &c->c2.buffers->read_link_buf); /* to_tun defined + unopened tuntap can cause deadlock */ if (!tuntap_defined (c->c1.tuntap)) c->c2.to_tun.len = 0; } else { buf_reset (&c->c2.to_tun); } done: perf_pop (); gc_free (&gc); }
void TrexWatchDog::init(bool enable){ m_enable = enable; if (m_enable) { register_signal(); } }
/* * Scheduled exit? */ void check_scheduled_exit_dowork (struct context *c) { register_signal (c, c->c2.scheduled_exit_signal, "delayed-exit"); }
void read_incoming_link (struct context *c) { /* * Set up for recvfrom call to read datagram * sent to our TCP/UDP port. */ int status; /*ASSERT (!c->c2.to_tun.len);*/ perf_push (PERF_READ_IN_LINK); c->c2.buf = c->c2.buffers->read_link_buf; ASSERT (buf_init (&c->c2.buf, FRAME_HEADROOM_ADJ (&c->c2.frame, FRAME_HEADROOM_MARKER_READ_LINK))); status = link_socket_read (c->c2.link_socket, &c->c2.buf, MAX_RW_SIZE_LINK (&c->c2.frame), &c->c2.from); if (socket_connection_reset (c->c2.link_socket, status)) { #if PORT_SHARE if (port_share && socket_foreign_protocol_detected (c->c2.link_socket)) { const struct buffer *fbuf = socket_foreign_protocol_head (c->c2.link_socket); const int sd = socket_foreign_protocol_sd (c->c2.link_socket); port_share_redirect (port_share, fbuf, sd); register_signal (c, SIGTERM, "port-share-redirect"); } else #endif { /* received a disconnect from a connection-oriented protocol */ if (c->options.inetd) { register_signal (c, SIGTERM, "connection-reset-inetd"); msg (D_STREAM_ERRORS, "Connection reset, inetd/xinetd exit [%d]", status); } else { #ifdef ENABLE_OCC if (event_timeout_defined(&c->c2.explicit_exit_notification_interval)) { msg (D_STREAM_ERRORS, "Connection reset during exit notification period, ignoring [%d]", status); openvpn_sleep(1); } else #endif { register_signal (c, SIGUSR1, "connection-reset"); /* SOFT-SIGUSR1 -- TCP connection reset */ msg (D_STREAM_ERRORS, "Connection reset, restarting [%d]", status); } } } perf_pop (); return; } /* check recvfrom status */ check_status (status, "read", c->c2.link_socket, NULL); #ifdef ENABLE_SOCKS /* Remove socks header if applicable */ socks_postprocess_incoming_link (c); #endif perf_pop (); }
/* * Should we exit due to inactivity timeout? */ void check_inactivity_timeout_dowork (struct context *c) { msg (M_INFO, "Inactivity timeout (--inactive), exiting"); register_signal (c, SIGTERM, "inactive"); }
void process_outgoing_link (struct context *c) { struct gc_arena gc = gc_new (); int error_code = 0; perf_push (PERF_PROC_OUT_LINK); if (c->c2.to_link.len > 0 && c->c2.to_link.len <= EXPANDED_SIZE (&c->c2.frame)) { /* * Setup for call to send/sendto which will send * packet to remote over the TCP/UDP port. */ int size = 0; ASSERT (link_socket_actual_defined (c->c2.to_link_addr)); #ifdef ENABLE_DEBUG /* In gremlin-test mode, we may choose to drop this packet */ if (!c->options.gremlin || ask_gremlin (c->options.gremlin)) #endif { /* * Let the traffic shaper know how many bytes * we wrote. */ #ifdef ENABLE_FEATURE_SHAPER if (c->options.shaper) shaper_wrote_bytes (&c->c2.shaper, BLEN (&c->c2.to_link) + datagram_overhead (c->options.ce.proto)); #endif /* * Let the pinger know that we sent a packet. */ if (c->options.ping_send_timeout) event_timeout_reset (&c->c2.ping_send_interval); #if PASSTOS_CAPABILITY /* Set TOS */ link_socket_set_tos (c->c2.link_socket); #endif /* Log packet send */ #ifdef LOG_RW if (c->c2.log_rw) fprintf (stderr, "W"); #endif msg (D_LINK_RW, "%s WRITE [%d] to %s: %s", proto2ascii (c->c2.link_socket->info.proto, c->c2.link_socket->info.af, true), BLEN (&c->c2.to_link), print_link_socket_actual (c->c2.to_link_addr, &gc), PROTO_DUMP (&c->c2.to_link, &gc)); /* Packet send complexified by possible Socks5 usage */ { struct link_socket_actual *to_addr = c->c2.to_link_addr; int size_delta = 0; /* If Socks5 over UDP, prepend header */ socks_preprocess_outgoing_link (c, &to_addr, &size_delta); /* Send packet */ size = link_socket_write (c->c2.link_socket, &c->c2.to_link, to_addr); /* Undo effect of prepend */ link_socket_write_post_size_adjust (&size, size_delta, &c->c2.to_link); } if (size > 0) { c->c2.max_send_size_local = max_int (size, c->c2.max_send_size_local); c->c2.link_write_bytes += size; link_write_bytes_global += size; #ifdef ENABLE_MEMSTATS if (mmap_stats) mmap_stats->link_write_bytes = link_write_bytes_global; #endif #ifdef ENABLE_MANAGEMENT if (management) { management_bytes_out (management, size); #ifdef MANAGEMENT_DEF_AUTH management_bytes_server (management, &c->c2.link_read_bytes, &c->c2.link_write_bytes, &c->c2.mda_context); #endif } #endif } } /* Check return status */ error_code = openvpn_errno(); check_status (size, "write", c->c2.link_socket, NULL); if (size > 0) { /* Did we write a different size packet than we intended? */ if (size != BLEN (&c->c2.to_link)) msg (D_LINK_ERRORS, "TCP/UDP packet was truncated/expanded on write to %s (tried=%d,actual=%d)", print_link_socket_actual (c->c2.to_link_addr, &gc), BLEN (&c->c2.to_link), size); } /* if not a ping/control message, indicate activity regarding --inactive parameter */ if (c->c2.buf.len > 0 ) register_activity (c, size); #ifdef ENABLE_CRYPTO /* for unreachable network and "connecting" state switch to the next host */ if (size < 0 && ENETUNREACH == error_code && c->c2.tls_multi && !tls_initial_packet_received (c->c2.tls_multi) && c->options.mode == MODE_POINT_TO_POINT) { msg (M_INFO, "Network unreachable, restarting"); register_signal (c, SIGUSR1, "network-unreachable"); } #endif } else { if (c->c2.to_link.len > 0) msg (D_LINK_ERRORS, "TCP/UDP packet too large on write to %s (tried=%d,max=%d)", print_link_socket_actual (c->c2.to_link_addr, &gc), c->c2.to_link.len, EXPANDED_SIZE (&c->c2.frame)); } buf_reset (&c->c2.to_link); perf_pop (); gc_free (&gc); }
bool process_incoming_link_part1 (struct context *c, struct link_socket_info *lsi, bool floated) { struct gc_arena gc = gc_new (); bool decrypt_status = false; if (c->c2.buf.len > 0) { c->c2.link_read_bytes += c->c2.buf.len; link_read_bytes_global += c->c2.buf.len; #ifdef ENABLE_MEMSTATS if (mmap_stats) mmap_stats->link_read_bytes = link_read_bytes_global; #endif c->c2.original_recv_size = c->c2.buf.len; #ifdef ENABLE_MANAGEMENT if (management) { management_bytes_in (management, c->c2.buf.len); #ifdef MANAGEMENT_DEF_AUTH management_bytes_server (management, &c->c2.link_read_bytes, &c->c2.link_write_bytes, &c->c2.mda_context); #endif } #endif } else c->c2.original_recv_size = 0; #ifdef ENABLE_DEBUG /* take action to corrupt packet if we are in gremlin test mode */ if (c->options.gremlin) { if (!ask_gremlin (c->options.gremlin)) c->c2.buf.len = 0; corrupt_gremlin (&c->c2.buf, c->options.gremlin); } #endif /* log incoming packet */ #ifdef LOG_RW if (c->c2.log_rw && c->c2.buf.len > 0) fprintf (stderr, "R"); #endif msg (D_LINK_RW, "%s READ [%d] from %s: %s", proto2ascii (lsi->proto, lsi->af, true), BLEN (&c->c2.buf), print_link_socket_actual (&c->c2.from, &gc), PROTO_DUMP (&c->c2.buf, &gc)); /* * Good, non-zero length packet received. * Commence multi-stage processing of packet, * such as authenticate, decrypt, decompress. * If any stage fails, it sets buf.len to 0 or -1, * telling downstream stages to ignore the packet. */ if (c->c2.buf.len > 0) { if (!link_socket_verify_incoming_addr (&c->c2.buf, lsi, &c->c2.from)) link_socket_bad_incoming_addr (&c->c2.buf, lsi, &c->c2.from); #ifdef ENABLE_CRYPTO #ifdef ENABLE_SSL if (c->c2.tls_multi) { /* * If tls_pre_decrypt returns true, it means the incoming * packet was a good TLS control channel packet. If so, TLS code * will deal with the packet and set buf.len to 0 so downstream * stages ignore it. * * If the packet is a data channel packet, tls_pre_decrypt * will load crypto_options with the correct encryption key * and return false. */ if (tls_pre_decrypt (c->c2.tls_multi, &c->c2.from, &c->c2.buf, &c->c2.crypto_options, floated)) { interval_action (&c->c2.tmp_int); /* reset packet received timer if TLS packet */ if (c->options.ping_rec_timeout) event_timeout_reset (&c->c2.ping_rec_interval); } } #if P2MP_SERVER /* * Drop non-TLS packet if client-connect script/plugin has not * yet succeeded. */ if (c->c2.context_auth != CAS_SUCCEEDED) c->c2.buf.len = 0; #endif #endif /* ENABLE_SSL */ /* authenticate and decrypt the incoming packet */ decrypt_status = openvpn_decrypt (&c->c2.buf, c->c2.buffers->decrypt_buf, &c->c2.crypto_options, &c->c2.frame); if (!decrypt_status && link_socket_connection_oriented (c->c2.link_socket)) { /* decryption errors are fatal in TCP mode */ register_signal (c, SIGUSR1, "decryption-error"); /* SOFT-SIGUSR1 -- decryption error in TCP mode */ msg (D_STREAM_ERRORS, "Fatal decryption error (process_incoming_link), restarting"); } #else /* ENABLE_CRYPTO */ decrypt_status = true; #endif /* ENABLE_CRYPTO */ } else { buf_reset (&c->c2.to_tun); } gc_free (&gc); return decrypt_status; }
void check_tls_errors_nco (struct context *c) { register_signal (c, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */ }
void check_tls_errors_co (struct context *c) { msg (D_STREAM_ERRORS, "Fatal TLS error (check_tls_errors_co), restarting"); register_signal (c, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */ }
int main(int argc, char **argv) { char *ptr; int c, i, j, cpu_tmp, opt_index, ops_touched = 0, vals[4] = {0}; bool prio_high = false, setsockmem = true; void (*main_loop)(struct ctx *ctx) = NULL; struct ctx ctx; init_ctx(&ctx); srand(time(NULL)); while ((c = getopt_long(argc, argv, short_options, long_options, &opt_index)) != EOF) { switch (c) { case 'd': case 'i': ctx.device_in = xstrdup(optarg); break; case 'o': ctx.device_out = xstrdup(optarg); break; case 'P': ctx.prefix = xstrdup(optarg); break; case 'R': ctx.link_type = LINKTYPE_IEEE802_11; ctx.rfraw = 1; break; case 'r': ctx.randomize = true; break; case 'J': ctx.jumbo = true; break; case 'T': ctx.magic = (uint32_t) strtoul(optarg, NULL, 0); pcap_check_magic(ctx.magic); break; case 'f': ctx.filter = xstrdup(optarg); break; case 'M': ctx.promiscuous = false; break; case 'A': setsockmem = false; break; case 'u': ctx.uid = strtoul(optarg, NULL, 0); ctx.enforce = true; break; case 'g': ctx.gid = strtoul(optarg, NULL, 0); ctx.enforce = true; break; case 't': if (!strncmp(optarg, "host", strlen("host"))) ctx.packet_type = PACKET_HOST; else if (!strncmp(optarg, "broadcast", strlen("broadcast"))) ctx.packet_type = PACKET_BROADCAST; else if (!strncmp(optarg, "multicast", strlen("multicast"))) ctx.packet_type = PACKET_MULTICAST; else if (!strncmp(optarg, "others", strlen("others"))) ctx.packet_type = PACKET_OTHERHOST; else if (!strncmp(optarg, "outgoing", strlen("outgoing"))) ctx.packet_type = PACKET_OUTGOING; else ctx.packet_type = -1; break; case 'S': ptr = optarg; ctx.reserve_size = 0; for (j = i = strlen(optarg); i > 0; --i) { if (!isdigit(optarg[j - i])) break; ptr++; } if (!strncmp(ptr, "KiB", strlen("KiB"))) ctx.reserve_size = 1 << 10; else if (!strncmp(ptr, "MiB", strlen("MiB"))) ctx.reserve_size = 1 << 20; else if (!strncmp(ptr, "GiB", strlen("GiB"))) ctx.reserve_size = 1 << 30; else panic("Syntax error in ring size param!\n"); *ptr = 0; ctx.reserve_size *= strtol(optarg, NULL, 0); break; case 'b': cpu_tmp = strtol(optarg, NULL, 0); cpu_affinity(cpu_tmp); if (ctx.cpu != -2) ctx.cpu = cpu_tmp; break; case 'H': prio_high = true; break; case 'c': ctx.pcap = PCAP_OPS_RW; ops_touched = 1; break; case 'm': ctx.pcap = PCAP_OPS_MM; ops_touched = 1; break; case 'G': ctx.pcap = PCAP_OPS_SG; ops_touched = 1; break; case 'Q': ctx.cpu = -2; break; case 's': ctx.print_mode = PRINT_NONE; break; case 'q': ctx.print_mode = PRINT_LESS; break; case 'X': ctx.print_mode = (ctx.print_mode == PRINT_ASCII) ? PRINT_HEX_ASCII : PRINT_HEX; break; case 'l': ctx.print_mode = (ctx.print_mode == PRINT_HEX) ? PRINT_HEX_ASCII : PRINT_ASCII; break; case 'k': ctx.kpull = strtol(optarg, NULL, 0); break; case 'n': frame_count_max = strtol(optarg, NULL, 0); break; case 'F': ptr = optarg; ctx.dump_interval = 0; for (j = i = strlen(optarg); i > 0; --i) { if (!isdigit(optarg[j - i])) break; ptr++; } if (!strncmp(ptr, "KiB", strlen("KiB"))) { ctx.dump_interval = 1 << 10; ctx.dump_mode = DUMP_INTERVAL_SIZE; } else if (!strncmp(ptr, "MiB", strlen("MiB"))) { ctx.dump_interval = 1 << 20; ctx.dump_mode = DUMP_INTERVAL_SIZE; } else if (!strncmp(ptr, "GiB", strlen("GiB"))) { ctx.dump_interval = 1 << 30; ctx.dump_mode = DUMP_INTERVAL_SIZE; } else if (!strncmp(ptr, "sec", strlen("sec"))) { ctx.dump_interval = 1; ctx.dump_mode = DUMP_INTERVAL_TIME; } else if (!strncmp(ptr, "min", strlen("min"))) { ctx.dump_interval = 60; ctx.dump_mode = DUMP_INTERVAL_TIME; } else if (!strncmp(ptr, "hrs", strlen("hrs"))) { ctx.dump_interval = 60 * 60; ctx.dump_mode = DUMP_INTERVAL_TIME; } else if (!strncmp(ptr, "s", strlen("s"))) { ctx.dump_interval = 1; ctx.dump_mode = DUMP_INTERVAL_TIME; } else { panic("Syntax error in time/size param!\n"); } *ptr = 0; ctx.dump_interval *= strtol(optarg, NULL, 0); break; case 'V': ctx.verbose = 1; break; case 'B': ctx.dump_bpf = true; break; case 'D': pcap_dump_type_features(); die(); break; case 'U': update_geoip(); die(); break; case 'v': version(); break; case 'h': help(); break; case '?': switch (optopt) { case 'd': case 'i': case 'o': case 'f': case 't': case 'P': case 'F': case 'n': case 'S': case 'b': case 'k': case 'T': case 'u': case 'g': case 'e': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) printf("Unknown option character `0x%X\'!\n", optopt); die(); } default: break; } } if (!ctx.filter && optind != argc) { int ret; off_t offset = 0; for (i = optind; i < argc; ++i) { size_t alen = strlen(argv[i]) + 2; size_t flen = ctx.filter ? strlen(ctx.filter) : 0; ctx.filter = xrealloc(ctx.filter, 1, flen + alen); ret = slprintf(ctx.filter + offset, strlen(argv[i]) + 2, "%s ", argv[i]); if (ret < 0) panic("Cannot concatenate filter string!\n"); else offset += ret; } } if (!ctx.device_in) ctx.device_in = xstrdup("any"); register_signal(SIGINT, signal_handler); register_signal(SIGHUP, signal_handler); tprintf_init(); if (prio_high) { set_proc_prio(-20); set_sched_status(SCHED_FIFO, sched_get_priority_max(SCHED_FIFO)); } if (ctx.device_in && (device_mtu(ctx.device_in) || !strncmp("any", ctx.device_in, strlen(ctx.device_in)))) { if (!ctx.rfraw) ctx.link_type = pcap_devtype_to_linktype(ctx.device_in); if (!ctx.device_out) { ctx.dump = 0; main_loop = recv_only_or_dump; } else if (device_mtu(ctx.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); main_loop = receive_to_xmit; } else { ctx.dump = 1; register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO); main_loop = recv_only_or_dump; if (!ops_touched) ctx.pcap = PCAP_OPS_SG; } } else { if (ctx.device_out && device_mtu(ctx.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); main_loop = pcap_to_xmit; if (!ops_touched) ctx.pcap = PCAP_OPS_MM; } else { main_loop = read_pcap; if (!ops_touched) ctx.pcap = PCAP_OPS_SG; } } bug_on(!main_loop); init_geoip(0); if (setsockmem) set_system_socket_memory(vals, array_size(vals)); if (!ctx.enforce) xlockme(); main_loop(&ctx); if (!ctx.enforce) xunlockme(); if (setsockmem) reset_system_socket_memory(vals, array_size(vals)); destroy_geoip(); device_restore_irq_affinity_list(); tprintf_cleanup(); destroy_ctx(&ctx); return 0; }
int main(int argc, char **argv) { int ret = 0, c, udp = 0, ipv4 = -1, daemon = 1, log = 1; char *port = NULL, *stun = NULL, *dev = NULL, *home = NULL, *alias = NULL; enum working_mode wmode = MODE_UNKNOW; setfsuid(getuid()); setfsgid(getgid()); home = fetch_home_dir(); while ((c = getopt_long(argc, argv, short_options, long_options, NULL)) != EOF) { switch (c) { case 'h': help(); break; case 'v': version(); break; case 'D': daemon = 0; break; case 'N': log = 0; break; case 'C': wmode = MODE_DUMPC; break; case 'S': wmode = MODE_DUMPS; break; case 'c': wmode = MODE_CLIENT; if (optarg) { if (*optarg == '=') optarg++; alias = xstrdup(optarg); } break; case 'd': dev = xstrdup(optarg); break; case 'k': wmode = MODE_KEYGEN; break; case '4': ipv4 = 1; break; case '6': ipv4 = 0; break; case 'x': wmode = MODE_EXPORT; break; case 's': wmode = MODE_SERVER; break; case 'u': udp = 1; break; case 't': stun = xstrdup(optarg); break; case 'p': port = xstrdup(optarg); break; case '?': switch (optopt) { case 't': case 'd': case 'u': case 'p': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) printf("Unknown option character `0x%X\'!\n", optopt); die(); } default: break; } } if (argc < 2) help(); register_signal(SIGINT, signal_handler); register_signal(SIGHUP, signal_handler); register_signal(SIGTERM, signal_handler); register_signal(SIGPIPE, signal_handler); curve25519_selftest(); switch (wmode) { case MODE_KEYGEN: ret = main_keygen(home); break; case MODE_EXPORT: ret = main_export(home); break; case MODE_DUMPC: ret = main_dumpc(home); break; case MODE_DUMPS: ret = main_dumps(home); break; case MODE_CLIENT: ret = main_client(home, dev, alias, daemon); break; case MODE_SERVER: if (!port) panic("No port specified!\n"); if (stun) print_stun_probe(stun, 3478, strtoul(port, NULL, 10)); ret = main_server(home, dev, port, udp, ipv4, daemon, log); break; default: die(); } free(dev); free(stun); free(port); free(alias); return ret; }
int main(int argc, char **argv) { int c, i, j, opt_index; char *ptr; bool prio_high = false; struct mode mode; void (*enter_mode)(struct mode *mode) = NULL; check_for_root_maybe_die(); memset(&mode, 0, sizeof(mode)); mode.link_type = LINKTYPE_EN10MB; mode.print_mode = FNTTYPE_PRINT_NORM; mode.cpu = CPU_UNKNOWN; mode.packet_type = PACKET_ALL; mode.promiscuous = true; mode.randomize = false; mode.pcap = PCAP_OPS_SG; mode.dump_interval = DUMP_INTERVAL; while ((c = getopt_long(argc, argv, short_options, long_options, &opt_index)) != EOF) { switch (c) { case 'd': case 'i': mode.device_in = xstrdup(optarg); break; case 'o': mode.device_out = xstrdup(optarg); break; case 'r': mode.randomize = true; break; case 'J': mode.jumbo_support = 1; break; case 'f': mode.filter = xstrdup(optarg); break; case 'M': mode.promiscuous = false; break; case 't': if (!strncmp(optarg, "host", strlen("host"))) mode.packet_type = PACKET_HOST; else if (!strncmp(optarg, "broadcast", strlen("broadcast"))) mode.packet_type = PACKET_BROADCAST; else if (!strncmp(optarg, "multicast", strlen("multicast"))) mode.packet_type = PACKET_MULTICAST; else if (!strncmp(optarg, "others", strlen("others"))) mode.packet_type = PACKET_OTHERHOST; else if (!strncmp(optarg, "outgoing", strlen("outgoing"))) mode.packet_type = PACKET_OUTGOING; else mode.packet_type = PACKET_ALL; break; case 'S': ptr = optarg; mode.reserve_size = 0; for (j = i = strlen(optarg); i > 0; --i) { if (!isdigit(optarg[j - i])) break; ptr++; } if (!strncmp(ptr, "KB", strlen("KB"))) mode.reserve_size = 1 << 10; else if (!strncmp(ptr, "MB", strlen("MB"))) mode.reserve_size = 1 << 20; else if (!strncmp(ptr, "GB", strlen("GB"))) mode.reserve_size = 1 << 30; else panic("Syntax error in ring size param!\n"); *ptr = 0; mode.reserve_size *= atoi(optarg); break; case 'b': set_cpu_affinity(optarg, 0); if (mode.cpu != CPU_NOTOUCH) mode.cpu = atoi(optarg); break; case 'B': set_cpu_affinity(optarg, 1); break; case 'H': prio_high = true; break; case 'c': mode.pcap = PCAP_OPS_RW; break; case 'm': mode.pcap = PCAP_OPS_MMAP; break; case 'Q': mode.cpu = CPU_NOTOUCH; break; case 's': mode.print_mode = FNTTYPE_PRINT_NONE; break; case 'q': mode.print_mode = FNTTYPE_PRINT_LESS; break; case 'l': mode.print_mode = FNTTYPE_PRINT_CHR1; break; case 'x': mode.print_mode = FNTTYPE_PRINT_HEX1; break; case 'C': mode.print_mode = FNTTYPE_PRINT_PAAC; break; case 'X': mode.print_mode = FNTTYPE_PRINT_HEX2; break; case 'N': mode.print_mode = FNTTYPE_PRINT_NOPA; break; case 'k': mode.kpull = (unsigned long) atol(optarg); break; case 'n': frame_cnt_max = (unsigned long) atol(optarg); break; case 'F': mode.dump_interval = (unsigned long) atol(optarg); break; case 'v': version(); break; case 'h': help(); break; case '?': switch (optopt) { case 'd': case 'i': case 'o': case 'f': case 't': case 'F': case 'n': case 'S': case 'b': case 'k': case 'B': case 'e': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) whine("Unknown option character " "`0x%X\'!\n", optopt); die(); } default: break; } } if (!mode.device_in) mode.device_in = xstrdup("any"); register_signal(SIGINT, signal_handler); register_signal(SIGHUP, signal_handler); init_pcap(mode.jumbo_support); tprintf_init(); header(); if (prio_high == true) { set_proc_prio(get_default_proc_prio()); set_sched_status(get_default_sched_policy(), get_default_sched_prio()); } if (mode.device_in && (device_mtu(mode.device_in) || !strncmp("any", mode.device_in, strlen(mode.device_in)))) { if (!mode.device_out) { mode.dump = 0; enter_mode = enter_mode_rx_only_or_dump; } else if (device_mtu(mode.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); enter_mode = enter_mode_rx_to_tx; } else { mode.dump = 1; register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO); enter_mode = enter_mode_rx_only_or_dump; } } else { if (mode.device_out && device_mtu(mode.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); enter_mode = enter_mode_pcap_to_tx; } else { enter_mode = enter_mode_read_pcap; } } if (!enter_mode) panic("Selection not supported!\n"); enter_mode(&mode); tprintf_cleanup(); cleanup_pcap(); if (mode.device_in) xfree(mode.device_in); if (mode.device_out) xfree(mode.device_out); return 0; }
int main(int argc, char **argv) { bool slow = false, invoke_cpp = false, reseed = true; int c, opt_index, i, j, vals[4] = {0}, irq; char *confname = NULL, *ptr; unsigned long cpus_tmp, orig_num = 0; unsigned long long tx_packets, tx_bytes; struct ctx ctx; fmemset(&ctx, 0, sizeof(ctx)); ctx.cpus = get_number_cpus_online(); ctx.uid = getuid(); ctx.gid = getgid(); while ((c = getopt_long(argc, argv, short_options, long_options, &opt_index)) != EOF) { switch (c) { case 'h': help(); break; case 'v': version(); break; case 'e': example(); break; case 'p': invoke_cpp = true; break; case 'V': ctx.verbose = true; break; case 'P': cpus_tmp = strtoul(optarg, NULL, 0); if (cpus_tmp > 0 && cpus_tmp < ctx.cpus) ctx.cpus = cpus_tmp; break; case 'd': case 'o': ctx.device = xstrndup(optarg, IFNAMSIZ); break; case 'r': ctx.rand = true; break; case 's': slow = true; ctx.cpus = 1; ctx.smoke_test = true; ctx.rhost = xstrdup(optarg); break; case 'R': ctx.rfraw = true; break; case 'J': ctx.jumbo_support = true; break; case 'c': case 'i': confname = xstrdup(optarg); if (!strncmp("-", confname, strlen("-"))) ctx.cpus = 1; break; case 'u': ctx.uid = strtoul(optarg, NULL, 0); ctx.enforce = true; break; case 'g': ctx.gid = strtoul(optarg, NULL, 0); ctx.enforce = true; break; case 'k': ctx.kpull = strtoul(optarg, NULL, 0); break; case 'E': seed = strtoul(optarg, NULL, 0); reseed = false; break; case 'n': orig_num = strtoul(optarg, NULL, 0); ctx.num = orig_num; break; case 't': slow = true; ctx.gap = strtoul(optarg, NULL, 0); if (ctx.gap > 0) /* Fall back to single core to not * mess up correct timing. We are slow * anyway! */ ctx.cpus = 1; break; case 'S': ptr = optarg; ctx.reserve_size = 0; for (j = i = strlen(optarg); i > 0; --i) { if (!isdigit(optarg[j - i])) break; ptr++; } if (!strncmp(ptr, "KiB", strlen("KiB"))) ctx.reserve_size = 1 << 10; else if (!strncmp(ptr, "MiB", strlen("MiB"))) ctx.reserve_size = 1 << 20; else if (!strncmp(ptr, "GiB", strlen("GiB"))) ctx.reserve_size = 1 << 30; else panic("Syntax error in ring size param!\n"); *ptr = 0; ctx.reserve_size *= strtol(optarg, NULL, 0); break; case '?': switch (optopt) { case 'd': case 'c': case 'n': case 'S': case 's': case 'P': case 'o': case 'E': case 'i': case 'k': case 'u': case 'g': case 't': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) printf("Unknown option character `0x%X\'!\n", optopt); die(); } default: break; } } if (argc < 5) help(); if (ctx.device == NULL) panic("No networking device given!\n"); if (confname == NULL) panic("No configuration file given!\n"); if (device_mtu(ctx.device) == 0) panic("This is no networking device!\n"); register_signal(SIGINT, signal_handler); register_signal(SIGHUP, signal_handler); register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); set_system_socket_memory(vals, array_size(vals)); xlockme(); if (ctx.rfraw) { ctx.device_trans = xstrdup(ctx.device); xfree(ctx.device); enter_rfmon_mac80211(ctx.device_trans, &ctx.device); sleep(0); } irq = device_irq_number(ctx.device); device_set_irq_affinity_list(irq, 0, ctx.cpus - 1); stats = setup_shared_var(ctx.cpus); for (i = 0; i < ctx.cpus; i++) { pid_t pid = fork(); switch (pid) { case 0: if (reseed) seed = generate_srand_seed(); srand(seed); cpu_affinity(i); main_loop(&ctx, confname, slow, i, invoke_cpp, orig_num); goto thread_out; case -1: panic("Cannot fork processes!\n"); } } for (i = 0; i < ctx.cpus; i++) { int status; wait(&status); if (WEXITSTATUS(status) == EXIT_FAILURE) die(); } if (ctx.rfraw) leave_rfmon_mac80211(ctx.device_trans, ctx.device); reset_system_socket_memory(vals, array_size(vals)); for (i = 0, tx_packets = tx_bytes = 0; i < ctx.cpus; i++) { while ((__get_state(i) & CPU_STATS_STATE_RES) == 0) sched_yield(); tx_packets += stats[i].tx_packets; tx_bytes += stats[i].tx_bytes; } fflush(stdout); printf("\n"); printf("\r%12llu packets outgoing\n", tx_packets); printf("\r%12llu bytes outgoing\n", tx_bytes); for (i = 0; i < ctx.cpus; i++) { printf("\r%12lu sec, %lu usec on CPU%d (%llu packets)\n", stats[i].tv_sec, stats[i].tv_usec, i, stats[i].tx_packets); } thread_out: xunlockme(); destroy_shared_var(stats, ctx.cpus); device_restore_irq_affinity_list(); free(ctx.device); free(ctx.device_trans); free(ctx.rhost); free(confname); return 0; }