Beispiel #1
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;

  initialize_bismark_id();

  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
#ifdef ENABLE_FREQUENT_UPDATES
  if (anonymize_mac(bismark_mac, bismark_mac)) {
    fprintf(stderr, "Error anonymizing router MAC address\n");
  }
#endif
  packet_series_init(&packet_data);
  flow_table_init(&flow_table);
  dns_table_init(&dns_table, &domain_whitelist);
#ifdef ENABLE_HTTP_URL
  http_table_init(&http_table);
#endif
  address_table_init(&address_table);
  drop_statistics_init(&drop_statistics);
#ifdef ENABLE_FREQUENT_UPDATES
  device_throughput_table_init(&device_throughput_table);
#endif
  upload_failures_init(&upload_failures, UPLOAD_FAILURES_FILENAME);

  initialize_signal_handler();
  set_next_alarm();

  /* 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);
}
Beispiel #2
0
static void write_frequent_update() {
  FILE* handle = fopen (PENDING_FREQUENT_UPDATE_FILENAME, "w");
  if (!handle) {
#ifndef NDEBUG
    perror("Could not open update file for writing");
#endif
    exit(1);
  }
  if (!fprintf(handle,
               "%d\n%s\n",
               FREQUENT_FILE_FORMAT_VERSION,
               BUILD_ID) < 0) {
#ifndef NDEBUG
    perror("Error writing update");
#endif
    exit(1);
  }
  time_t current_timestamp = time(NULL);
  if (!fprintf(handle,
               "%s %" PRId64 " %d %" PRId64 "\n\n",
               bismark_id,
               start_timestamp_microseconds,
               frequent_sequence_number,
               (int64_t)current_timestamp) < 0) {
#ifndef NDEBUG
    perror("Error writing update");
#endif
    exit(1);
  }
  if (device_throughput_table_write_update(&device_throughput_table, handle)) {
    exit(1);
  }
  fclose(handle);

  char update_filename[FILENAME_MAX];
  snprintf(update_filename,
           FILENAME_MAX,
           FREQUENT_UPDATE_FILENAME,
           bismark_id,
           start_timestamp_microseconds,
           frequent_sequence_number);
  if (rename(PENDING_FREQUENT_UPDATE_FILENAME, update_filename)) {
#ifndef NDEBUG
    perror("Could not stage update");
#endif
    exit(1);
  }

  ++frequent_sequence_number;

  device_throughput_table_init(&device_throughput_table);
}
Beispiel #3
0
static void write_frequent_update() {
  printf("Writing frequent log to %s\n", PENDING_FREQUENT_UPDATE_FILENAME);
  FILE* handle = fopen(PENDING_FREQUENT_UPDATE_FILENAME, "w");
  if (!handle) {
    perror("Could not open update file for writing");
    exit(1);
  }
  if (fprintf(handle, "%d\n", FREQUENT_FILE_FORMAT_VERSION) < 0) {
    perror("Error writing update");
    exit(1);
  }
  time_t current_timestamp = time(NULL);
  if (fprintf(handle, "%" PRId64 "\n", (int64_t)current_timestamp) < 0) {
    perror("Error writing update");
    exit(1);
  }
  if (fprintf(handle, "%s\n\n", buffer_to_hex(bismark_mac, ETH_ALEN)) < 0) {
    perror("Error writing update");
    exit(1);
  }
  if (device_throughput_table_write_update(&device_throughput_table, handle)) {
    exit(1);
  }
  fclose(handle);

  char update_filename[FILENAME_MAX];
  snprintf(update_filename,
           FILENAME_MAX,
           FREQUENT_UPDATE_FILENAME,
           bismark_id,
           start_timestamp_microseconds,
           frequent_sequence_number);
  if (rename(PENDING_FREQUENT_UPDATE_FILENAME, update_filename)) {
    perror("Could not stage update");
    exit(1);
  }

  ++frequent_sequence_number;

  device_throughput_table_init(&device_throughput_table);
}
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);
}