/* Try to get next flow, which should succeed */
static void
test_flow_table_get_next_flow(int argc, char *argv[])
{
	struct flow_key key1 = {1};
	struct flow_key key2 = {2};
	struct flow_key key_check = {0};
	struct action action_multiple[MAX_ACTIONS] = {0};
	struct action action_check[MAX_ACTIONS] = {0};
	struct flow_stats stats_zero = {0};
	struct flow_stats stats_check = {0};
	int ret = 0;

	flow_table_init();

	flow_table_del_all();
	action_output_build(&action_multiple[0], 1);
	action_null_build(&action_multiple[1]);
	ret = flow_table_add_flow(&key1, action_multiple);
	assert(ret >= 0);
	ret = flow_table_add_flow(&key2, action_multiple);
	assert(ret >= 0);

	ret = flow_table_get_first_flow(&key_check, action_check, &stats_check);
	assert(ret >= 0);
	if (memcmp(&key1, &key_check, sizeof(struct flow_key)) == 0 ) {
		ret = flow_table_get_next_flow(&key_check, &key_check, action_check, &stats_check);
		assert(ret >= 0);
		assert(memcmp(action_multiple, action_check, sizeof(struct action)) == 0);
		assert(memcmp(&stats_zero, &stats_check, sizeof(struct flow_stats)) == 0 );
		assert(memcmp(&key2, &key_check, sizeof(struct flow_key)) == 0 );
	} else if (memcmp(&key2, &key_check, sizeof(struct flow_key) == 0)) {
		ret = flow_table_get_next_flow(&key_check, &key_check, action_check, &stats_check);
		assert(ret >= 0);
		assert(memcmp(action_multiple, action_check, sizeof(struct action)) == 0);
		assert(memcmp(&stats_zero, &stats_check, sizeof(struct flow_stats)) == 0 );
		assert(memcmp(&key1, &key_check, sizeof(struct flow_key)) == 0 );
	} else {
		assert(1==0);
	}

}
/* Try to delete a normal flow and a non-existent flow, which should succeed
 * and fail with -1 respectively */
static void
test_flow_table_del_flow(int argc, char *argv[])
{
	struct flow_key key1 = {1};
	struct action action_multiple[MAX_ACTIONS] = {0};
	int ret = 0;

	flow_table_init();

	/* TODO: Break this into multiple tests? */
	action_output_build(&action_multiple[0], 1);
	action_output_build(&action_multiple[1], 2);
	action_null_build(&action_multiple[2]);
	flow_table_add_flow(&key1, action_multiple);
	ret = flow_table_del_flow(&key1);
	assert(ret >= 0);
	/* check no flow match */
	ret = flow_table_get_flow(&key1, NULL, NULL);
	assert(ret < 0);
	ret = flow_table_del_flow(&key1);
	assert(ret < 0);
}
/* Try to get a flow, which should succeed */
static void
test_flow_table_get_flow(int argc, char *argv[])
{
	struct flow_key key1 = {1};
	struct action action_multiple[MAX_ACTIONS] = {0};
	struct action action_check[MAX_ACTIONS] = {0};
	struct flow_stats stats_zero = {0};
	struct flow_stats stats_check = {0};
	int ret = 0;

	flow_table_init();

	action_output_build(&action_multiple[0], 1);
	action_output_build(&action_multiple[1], 2);
	action_null_build(&action_multiple[2]);
	flow_table_add_flow(&key1, action_multiple);
	ret = flow_table_get_flow(&key1, action_check, &stats_check);
	assert(ret >= 0);
	assert(memcmp(&action_multiple[0], action_check, sizeof(struct action)) == 0);
	assert(memcmp(&action_multiple[1], &action_check[1], sizeof(struct action)) == 0);
	assert(memcmp(&stats_zero, &stats_check , sizeof(struct flow_stats)) == 0 );
}
Beispiel #4
0
int main(int argc, char *argv[]) {
  if (argc < 2) {
    fprintf(stderr, "Usage: %s <interface> [whitelist]\n", argv[0]);
    return 1;
  }

  struct timeval start_timeval;
  gettimeofday(&start_timeval, NULL);
  start_timestamp_microseconds
      = start_timeval.tv_sec * NUM_MICROS_PER_SECOND + start_timeval.tv_usec;

  if (initialize_bismark_id()) {
    return 1;
  }

  if (argc < 3 || initialize_domain_whitelist(argv[2])) {
    fprintf(stderr, "Error loading domain whitelist; whitelisting disabled.\n");
  }

#ifndef DISABLE_ANONYMIZATION
  if (anonymization_init()) {
    fprintf(stderr, "Error initializing anonymizer\n");
    return 1;
  }
#endif
  packet_series_init(&packet_data);
  flow_table_init(&flow_table);
  dns_table_init(&dns_table, &domain_whitelist);
  address_table_init(&address_table);
  drop_statistics_init(&drop_statistics);
#ifdef ENABLE_FREQUENT_UPDATES
  device_throughput_table_init(&device_throughput_table);
#endif

  if (pthread_mutex_init(&update_lock, NULL)) {
    perror("Error initializing mutex");
    return 1;
  }
  sigset_t signal_set;
  sigemptyset(&signal_set);
  sigaddset(&signal_set, SIGINT);
  sigaddset(&signal_set, SIGTERM);
  if (pthread_sigmask(SIG_BLOCK, &signal_set, NULL)) {
    perror("Error calling pthread_sigmask");
    return 1;
  }
  if (pthread_create(&signal_thread, NULL, handle_signals, &signal_set)) {
    perror("Error creating signal handling thread");
    return 1;
  }
  if (pthread_create(&update_thread, NULL, updater, NULL)) {
    perror("Error creating updates thread");
    return 1;
  }
#ifdef ENABLE_FREQUENT_UPDATES
  if (pthread_create(&frequent_update_thread, NULL, frequent_updater, NULL)) {
    perror("Error creating frequent updates thread");
    return 1;
  }
#endif

  /* By default, pcap uses an internal buffer of 500 KB. Any packets that
   * overflow this buffer will be dropped. pcap_stats tells the number of
   * dropped packets.
   *
   * Because pcap does its own buffering, we don't need to run packet
   * processing in a separate thread. (It would be easier to just increase
   * the buffer size if we experience performance problems.) */
  pcap_handle = initialize_pcap(argv[1]);
  if (!pcap_handle) {
    return 1;
  }
  return pcap_loop(pcap_handle, -1, process_packet, NULL);
}