Esempio n. 1
0
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);
}
Esempio n. 2
0
void signals_init()
{
	register_signal(SIGUSR1, sigusr1);
	register_signal(SIGUSR2, sigusr2);
	register_signal(SIGALRM, sigalarm);
	register_signal(SIGHUP, sighup);
}
Esempio n. 3
0
/* 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;
}
Esempio n. 4
0
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 ();
}
Esempio n. 5
0
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;
}
Esempio n. 6
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);
    }
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
/**
 * 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;
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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;
    }
}
Esempio n. 12
0
/* 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;
}
Esempio n. 13
0
/* 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;
}
Esempio n. 14
0
void start_plugin()
{
	int e;
	if ((e = regcomp(&regex, "^([^ ]+)( ([^ ]+)( (.*))?)?$", REG_EXTENDED)) != 0)
	{
		char *err = get_regerror(e, &regex);
		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");
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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();
    }
}
Esempio n. 17
0
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;
}
Esempio n. 18
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();
    } 
}
Esempio n. 20
0
/*
 * Scheduled exit?
 */
void
check_scheduled_exit_dowork (struct context *c)
{
  register_signal (c, c->c2.scheduled_exit_signal, "delayed-exit");
}
Esempio n. 21
0
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 ();
}
Esempio n. 22
0
/*
 * 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");
}
Esempio n. 23
0
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);
}
Esempio n. 24
0
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;
}
Esempio n. 25
0
void
check_tls_errors_nco (struct context *c)
{
  register_signal (c, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */
}
Esempio n. 26
0
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 */
}
Esempio n. 27
0
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;
}
Esempio n. 28
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;
}
Esempio n. 29
0
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;
}
Esempio n. 30
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;
}