Example #1
0
iow_t *bgpcorsaro_io_prepare_file_full(bgpcorsaro_t *bgpcorsaro,
                                       const char *plugin_name,
                                       bgpcorsaro_interval_t *interval,
                                       int compress_type, int compress_level,
                                       int flags)
{
  iow_t *f = NULL;
  char *outfileuri;

  /* generate a file name based on the plugin name */
  if ((outfileuri = generate_file_name(bgpcorsaro, plugin_name, interval,
                                       compress_type)) == NULL) {
    bgpcorsaro_log(__func__, bgpcorsaro, "could not generate file name for %s",
                   plugin_name);
    return NULL;
  }

  if ((f = wandio_wcreate(outfileuri, compress_type, compress_level, flags)) ==
      NULL) {
    bgpcorsaro_log(__func__, bgpcorsaro, "could not open %s for writing",
                   outfileuri);
    return NULL;
  }

  free(outfileuri);
  return f;
}
/** Implements the init_output function of the plugin API */
int bgpcorsaro_pfxmonitor_init_output(bgpcorsaro_t *bgpcorsaro)
{
  struct bgpcorsaro_pfxmonitor_state_t *state;
  bgpcorsaro_plugin_t *plugin = PLUGIN(bgpcorsaro);
  assert(plugin != NULL);

  if ((state = malloc_zero(sizeof(struct bgpcorsaro_pfxmonitor_state_t))) ==
      NULL) {
    bgpcorsaro_log(__func__, bgpcorsaro,
                   "could not malloc bgpcorsaro_pfxmonitor_state_t");
    goto err;
  }
  bgpcorsaro_plugin_register_state(bgpcorsaro->plugin_manager, plugin, state);

  /* initialize state with default values */
  state = STATE(bgpcorsaro);
  strncpy(state->metric_prefix, PFXMONITOR_DEFAULT_METRIC_PFX,
          PFXMONITOR_METRIC_PFX_LEN);
  strncpy(state->ip_space_name, PFXMONITOR_DEFAULT_IPSPACE_NAME,
          PFXMONITOR_METRIC_PFX_LEN);

  if ((state->poi = bgpstream_ip_counter_create()) == NULL) {
    goto err;
  }
  state->peer_asns_th = PFXMONITOR_DEFAULT_PEER_ASNS_THRESHOLD;
  state->more_specific = 0;

  /* parse the arguments */
  if (parse_args(bgpcorsaro) != 0) {
    goto err;
  }

  graphite_safe(state->metric_prefix);
  graphite_safe(state->ip_space_name);

  /* create all the sets and maps we need */
  if ((state->overlapping_pfx_cache = bgpstream_pfx_storage_set_create()) ==
        NULL ||
      (state->non_overlapping_pfx_cache = bgpstream_pfx_storage_set_create()) ==
        NULL ||
      (state->pfx_info = kh_init(pfx_info_map)) == NULL ||
      (state->unique_origins = bgpstream_id_set_create()) == NULL ||
      (state->peer_asns = bgpstream_id_set_create()) == NULL) {
    goto err;
  }

  /* defer opening the output file until we start the first interval */

  return 0;

err:
  bgpcorsaro_pfxmonitor_close_output(bgpcorsaro);
  return -1;
}
Example #3
0
/** Implements the start_interval function of the plugin API */
int bgpcorsaro_pacifier_start_interval(bgpcorsaro_t *bgpcorsaro,
				       bgpcorsaro_interval_t *int_start)
{
  struct bgpcorsaro_pacifier_state_t *state = STATE(bgpcorsaro);

  if(state->outfile == NULL)
    {
      if((
	  state->outfile_p[state->outfile_n] =
	  bgpcorsaro_io_prepare_file(bgpcorsaro,
				     PLUGIN(bgpcorsaro)->name,
				     int_start)) == NULL)
	{
	  bgpcorsaro_log(__func__, bgpcorsaro, "could not open %s output file",
			 PLUGIN(bgpcorsaro)->name);
	  return -1;
	}
      state->outfile = state->
	outfile_p[state->outfile_n];
    }

  bgpcorsaro_io_write_interval_start(bgpcorsaro, state->outfile, int_start);

  struct timeval tv;

  if(state->tv_start == 0)
    {
      gettimeofday_wrap(&tv);
      state->tv_start = tv.tv_sec;
      state->tv_first_time = state->tv_start;
    }

  // a new interval is starting
  state->intervals++;
  
  // fprintf(stderr, "START INTERVAL TIME: %d \n", state->tv_start);

  return 0;
}
/** Implements the start_interval function of the plugin API */
int bgpcorsaro_pfxmonitor_start_interval(bgpcorsaro_t *bgpcorsaro,
                                         bgpcorsaro_interval_t *int_start)
{
  struct bgpcorsaro_pfxmonitor_state_t *state = STATE(bgpcorsaro);

  /* open an output file */
  if (state->outfile == NULL) {
    if ((state->outfile_p[state->outfile_n] = bgpcorsaro_io_prepare_file(
           bgpcorsaro, PLUGIN(bgpcorsaro)->name, int_start)) == NULL) {
      bgpcorsaro_log(__func__, bgpcorsaro, "could not open %s output file",
                     PLUGIN(bgpcorsaro)->name);
      return -1;
    }
    state->outfile = state->outfile_p[state->outfile_n];
  }

  bgpcorsaro_io_write_interval_start(bgpcorsaro, state->outfile, int_start);

  /* save the interval start to correctly output the time series values */
  state->interval_start = int_start->time;

  return 0;
}
Example #5
0
/** Implements the init_output function of the plugin API */
int bgpcorsaro_pacifier_init_output(bgpcorsaro_t *bgpcorsaro)
{
  struct bgpcorsaro_pacifier_state_t *state;
  bgpcorsaro_plugin_t *plugin = PLUGIN(bgpcorsaro);
  assert(plugin != NULL);

  if((state = malloc_zero(sizeof(struct bgpcorsaro_pacifier_state_t))) == NULL)
    {
      bgpcorsaro_log(__func__, bgpcorsaro,
		     "could not malloc bgpcorsaro_pacifier_state_t");
      goto err;
    }
  bgpcorsaro_plugin_register_state(bgpcorsaro->plugin_manager, plugin, state);


  // initializing state
  state = STATE(bgpcorsaro);
  state->tv_start = 0;      // 0 means it is the first interval, so the time has to be initialized at interval start
  state->wait = 30;         // 30 seconds is the default wait time, between start and end
  state->tv_first_time = 0; // 0 means it is the first interval, so the time has to be initialized at interval start
  state->intervals = 0;     // number of intervals processed
  state->adaptive = 0;      // default behavior is not adaptive
  
  /* parse the arguments */
  if(parse_args(bgpcorsaro) != 0)
    {
      return -1;
    }

  /* defer opening the output file until we start the first interval */

  return 0;

 err:
  bgpcorsaro_pacifier_close_output(bgpcorsaro);
  return -1;
}
Example #6
0
/** Entry point for the Bgpcorsaro tool */
int main(int argc, char *argv[])
{
  /* we MUST not use any of the getopt global vars outside of arg parsing */
  /* this is because the plugins can use get opt to parse their config */
  int opt;
  int prevoptind;
  char *tmpl = NULL;
  char *name = NULL;
  int i = 0;
  int interval = -1000;
  double this_time = 0;
  double last_time = 0;
  char *plugins[BGPCORSARO_PLUGIN_ID_MAX];
  int plugin_cnt = 0;
  char *plugin_arg_ptr = NULL;
  int align = 0;
  int rotate = 0;
  int meta_rotate = -1;
  int logfile_disable = 0;

  bgpstream_data_interface_option_t *option;

  char *projects[PROJECT_CMD_CNT];
  int projects_cnt = 0;

  char *types[TYPE_CMD_CNT];
  int types_cnt = 0;

  char *collectors[COLLECTOR_CMD_CNT];
  int collectors_cnt = 0;

  char *endp;
  struct window windows[WINDOW_CMD_CNT];
  int windows_cnt = 0;

  char *peerasns[PEERASN_CMD_CNT];
  int peerasns_cnt = 0;

  char *prefixes[PREFIX_CMD_CNT];
  int prefixes_cnt = 0;

  char *communities[COMMUNITY_CMD_CNT];
  int communities_cnt = 0;

  char *interface_options[OPTION_CMD_CNT];
  int interface_options_cnt = 0;

  int rib_period = 0;
  int live = 0;

  int rc = 0;

  signal(SIGINT, catch_sigint);


  if((stream = bgpstream_create()) == NULL)
    {
      fprintf(stderr, "ERROR: Could not create BGPStream instance\n");
      return -1;
    }
  datasource_id_default = datasource_id =
    bgpstream_get_data_interface_id(stream);
  datasource_info =
    bgpstream_get_data_interface_info(stream, datasource_id);
  assert(datasource_id != 0);

  while(prevoptind = optind,
        (opt = getopt(argc, argv, ":d:o:p:c:t:w:j:k:y:P:i:ag:lLx:n:O:r:R:hv?")) >= 0)
    {
      if (optind == prevoptind + 2 && (optarg == NULL || *optarg == '-') ) {
        opt = ':';
        -- optind;
      }
      switch(opt)
	{
	case 'd':
          if((datasource_id =
              bgpstream_get_data_interface_id_by_name(stream, optarg)) == 0)
            {
              fprintf(stderr, "ERROR: Invalid data interface name '%s'\n",
                      optarg);
              usage();
              exit(-1);
            }
          datasource_info =
            bgpstream_get_data_interface_info(stream, datasource_id);
	  break;

	case 'p':
	  if(projects_cnt == PROJECT_CMD_CNT)
	    {
	      fprintf(stderr,
		      "ERROR: A maximum of %d projects can be specified on "
		      "the command line\n",
		      PROJECT_CMD_CNT);
	      usage();
	      exit(-1);
	    }
	  projects[projects_cnt++] = strdup(optarg);
	  break;

	case 'c':
	  if(collectors_cnt == COLLECTOR_CMD_CNT)
	    {
	      fprintf(stderr,
		      "ERROR: A maximum of %d collectors can be specified on "
		      "the command line\n",
		      COLLECTOR_CMD_CNT);
	      usage();
	      exit(-1);
	    }
	  collectors[collectors_cnt++] = strdup(optarg);
	  break;

	case 't':
	  if(types_cnt == TYPE_CMD_CNT)
	    {
	      fprintf(stderr,
		      "ERROR: A maximum of %d types can be specified on "
		      "the command line\n",
		      TYPE_CMD_CNT);
	      usage();
	      exit(-1);
	    }
	  types[types_cnt++] = strdup(optarg);
	  break;

	case 'w':
	  if(windows_cnt == WINDOW_CMD_CNT)
	    {
	      fprintf(stderr,
		      "ERROR: A maximum of %d windows can be specified on "
		      "the command line\n",
		      WINDOW_CMD_CNT);
	      usage();
	      exit(-1);
	    }
	  /* split the window into a start and end */
	  if((endp = strchr(optarg, ',')) == NULL)
	    {
              windows[windows_cnt].end = BGPSTREAM_FOREVER;
	    }
          else
            {
              *endp = '\0';
              endp++;
              windows[windows_cnt].end =  atoi(endp);
            }
	  windows[windows_cnt].start = atoi(optarg);
	  windows_cnt++;
	  break;

        case 'j':
	  if(peerasns_cnt == PEERASN_CMD_CNT)
	    {
	      fprintf(stderr,
		      "ERROR: A maximum of %d peer asns can be specified on "
		      "the command line\n",
		      PEERASN_CMD_CNT);
	      usage();
	      exit(-1);
	    }
	  peerasns[peerasns_cnt++] = strdup(optarg);
	  break;

        case 'k':
	  if(prefixes_cnt == PREFIX_CMD_CNT)
	    {
	      fprintf(stderr,
		      "ERROR: A maximum of %d peer asns can be specified on "
		      "the command line\n",
		      PREFIX_CMD_CNT);
	      usage();
	      exit(-1);
	    }
	  prefixes[prefixes_cnt++] = strdup(optarg);
	  break;

        case 'y':
	  if(communities_cnt == COMMUNITY_CMD_CNT)
	    {
	      fprintf(stderr,
		      "ERROR: A maximum of %d communities can be specified on "
		      "the command line\n",
		      PREFIX_CMD_CNT);
	      usage();
	      exit(-1);
	    }
	  communities[communities_cnt++] = strdup(optarg);
	  break;

        case 'o':
          if(interface_options_cnt == OPTION_CMD_CNT)
	    {
	      fprintf(stderr,
		      "ERROR: A maximum of %d interface options can be specified\n",
		      OPTION_CMD_CNT);
	      usage();
	      exit(-1);
	    }
	  interface_options[interface_options_cnt++] = strdup(optarg);
          break;

	case 'P':
	  rib_period = atoi(optarg);
	  break;

	case 'l':
	  live = 1;
	  break;

        case 'g':
          gap_limit = atoi(optarg);
          break;


	case 'a':
	  align = 1;
	  break;


	case 'i':
	  interval = atoi(optarg);
	  break;

	case 'L':
	  logfile_disable = 1;
	  break;

	case 'n':
	  name = strdup(optarg);
	  break;

	case 'O':
	  tmpl = strdup(optarg);
	  break;

	case 'x':
	  plugins[plugin_cnt++] = strdup(optarg);
	  break;

	case 'r':
	  rotate = atoi(optarg);
	  break;

	case 'R':
	  meta_rotate = atoi(optarg);
	  break;

	case ':':
	  fprintf(stderr, "ERROR: Missing option argument for -%c\n", optopt);
	  usage();
	  exit(-1);
	  break;

	case '?':
	case 'v':
	  fprintf(stderr, "bgpcorsaro version %d.%d.%d\n",
		  BGPSTREAM_MAJOR_VERSION,
		  BGPSTREAM_MID_VERSION,
		  BGPSTREAM_MINOR_VERSION);
	  usage();
	  exit(0);
	  break;

	default:
	  usage();
	  exit(-1);
	}
    }

  /* store the value of the last index*/
  /*lastopt = optind;*/

  /* reset getopt for others */
  optind = 1;

  /* -- call NO library functions which may use getopt before here -- */
  /* this ESPECIALLY means bgpcorsaro_enable_plugin */

  for(i=0; i<interface_options_cnt; i++)
    {
      if(*interface_options[i] == '?')
        {
          dump_if_options();
          usage();
          exit(0);
        }
      else
        {
          /* actually set this option */
          if((endp = strchr(interface_options[i], ',')) == NULL)
            {
              fprintf(stderr,
                      "ERROR: Malformed data interface option (%s)\n",
                      interface_options[i]);
              fprintf(stderr,
                      "ERROR: Expecting <option-name>,<option-value>\n");
              usage();
              exit(-1);
            }
          *endp = '\0';
          endp++;
          if((option =
              bgpstream_get_data_interface_option_by_name(stream, datasource_id,
                                                          interface_options[i])) == NULL)
            {
              fprintf(stderr,
                      "ERROR: Invalid option '%s' for data interface '%s'\n",
                      interface_options[i], datasource_info->name);
              usage();
              exit(-1);
            }
          bgpstream_set_data_interface_option(stream, option, endp);
        }
      free(interface_options[i]);
      interface_options[i] = NULL;
    }
  interface_options_cnt = 0;

  if(windows_cnt == 0)
    {
      fprintf(stderr,
              "ERROR: At least one time window must be specified using -w\n");
      usage();
      goto err;
    }

  if(tmpl == NULL)
    {
      fprintf(stderr,
	      "ERROR: An output file template must be specified using -O\n");
      usage();
      goto err;
    }

  /* alloc bgpcorsaro */
  if((bgpcorsaro = bgpcorsaro_alloc_output(tmpl)) == NULL)
    {
      usage();
      goto err;
    }

  if(name != NULL && bgpcorsaro_set_monitorname(bgpcorsaro, name) != 0)
    {
      bgpcorsaro_log(__func__, bgpcorsaro, "failed to set monitor name");
      goto err;
    }

  if(interval > -1000)
    {
      bgpcorsaro_set_interval(bgpcorsaro, interval);
    }

  if(align == 1)
    {
      bgpcorsaro_set_interval_alignment(bgpcorsaro, BGPCORSARO_INTERVAL_ALIGN_YES);
    }

  if(rotate > 0)
    {
      bgpcorsaro_set_output_rotation(bgpcorsaro, rotate);
    }

  if(meta_rotate >= 0)
    {
      bgpcorsaro_set_meta_output_rotation(bgpcorsaro, meta_rotate);
    }

  for(i=0;i<plugin_cnt;i++)
    {
      /* the string at plugins[i] will contain the name of the plugin,
	 optionally followed by a space and then the arguments to pass
	 to the plugin */
      if((plugin_arg_ptr = strchr(plugins[i], ' ')) != NULL)
	{
	  /* set the space to a nul, which allows plugins[i] to be used
	     for the plugin name, and then increment plugin_arg_ptr to
	     point to the next character, which will be the start of the
	     arg string (or at worst case, the terminating \0 */
	  *plugin_arg_ptr = '\0';
	  plugin_arg_ptr++;
	}

      if(bgpcorsaro_enable_plugin(bgpcorsaro, plugins[i], plugin_arg_ptr) != 0)
	{
	  fprintf(stderr, "ERROR: Could not enable plugin %s\n",
		  plugins[i]);
	  usage();
	  goto err;
	}
    }

  if(logfile_disable != 0)
    {
      bgpcorsaro_disable_logfile(bgpcorsaro);
    }

  if(bgpcorsaro_start_output(bgpcorsaro) != 0)
    {
      usage();
      goto err;
    }

  /* create a record buffer */
  if (record == NULL &&
      (record = bgpstream_record_create()) == NULL) {
    fprintf(stderr, "ERROR: Could not create BGPStream record\n");
    return -1;
  }

  /* pass along the user's filter requests to bgpstream */

  /* types */
  for(i=0; i<types_cnt; i++)
    {
      bgpstream_add_filter(stream, BGPSTREAM_FILTER_TYPE_RECORD_TYPE, types[i]);
      free(types[i]);
    }

  /* projects */
  for(i=0; i<projects_cnt; i++)
    {
      bgpstream_add_filter(stream, BGPSTREAM_FILTER_TYPE_PROJECT, projects[i]);
      free(projects[i]);
    }

  /* collectors */
  for(i=0; i<collectors_cnt; i++)
    {
      bgpstream_add_filter(stream, BGPSTREAM_FILTER_TYPE_COLLECTOR, collectors[i]);
      free(collectors[i]);
    }

  /* windows */
  int minimum_time = 0;
  int current_time = 0;
  for(i=0; i<windows_cnt; i++)
    {
      bgpstream_add_interval_filter(stream, windows[i].start, windows[i].end);
      current_time =  windows[i].start;
      if(minimum_time == 0 || current_time < minimum_time)
	{
	  minimum_time = current_time;
	}
    }

    /* peer asns */
  for(i=0; i<peerasns_cnt; i++)
    {
      bgpstream_add_filter(stream, BGPSTREAM_FILTER_TYPE_ELEM_PEER_ASN, peerasns[i]);
      free(peerasns[i]);
    }

  /* prefixes */
  for(i=0; i<prefixes_cnt; i++)
    {
      bgpstream_add_filter(stream, BGPSTREAM_FILTER_TYPE_ELEM_PREFIX, prefixes[i]);
      free(prefixes[i]);
    }

  /* communities */
  for(i=0; i<communities_cnt; i++)
    {
      bgpstream_add_filter(stream, BGPSTREAM_FILTER_TYPE_ELEM_COMMUNITY, communities[i]);
      free(communities[i]);
    }

  /* frequencies */
  if(rib_period > 0)
    {
      bgpstream_add_rib_period_filter(stream, rib_period);
    }

  /* live mode */
  if(live != 0)
    {
      bgpstream_set_live_mode(stream);
    }

  bgpstream_set_data_interface(stream, datasource_id);

  if(bgpstream_start(stream) < 0) {
    fprintf(stderr, "ERROR: Could not init BGPStream\n");
    return -1;
  }

  /* let bgpcorsaro have the trace pointer */
  bgpcorsaro_set_stream(bgpcorsaro, stream);

  while (bgpcorsaro_shutdown == 0 &&
	 (rc = bgpstream_get_next_record(stream, record)) > 0 ) {

    /* remove records that preceed the beginning of the stream */
    if(record->attributes.record_time < minimum_time)
      {
	continue;
      }

    /* check the gap limit is not exceeded */
    this_time = record->attributes.record_time;
    if(gap_limit > 0 && /* gap limit is enabled */
       last_time > 0 && /* this is not the first packet */
       ((this_time-last_time) > 0) && /* packet doesn't go backward */
       (this_time - last_time) > gap_limit) /* packet exceeds gap */
      {
        bgpcorsaro_log(__func__, bgpcorsaro,
                       "gap limit exceeded (prev: %f this: %f diff: %f)",
                       last_time, this_time, (this_time - last_time));
        return -1;
      }
    last_time = this_time;

    /*bgpcorsaro_log(__func__, bgpcorsaro, "got a record!");*/
    if(bgpcorsaro_per_record(bgpcorsaro, record) != 0)
      {
	bgpcorsaro_log(__func__, bgpcorsaro, "bgpcorsaro_per_record failed");
	return -1;
      }
  }

  if (rc < 0) {
    bgpcorsaro_log(__func__, bgpcorsaro,
		   "bgpstream encountered an error processing records");
    return 1;
  }

  /* free the plugin strings */
  for(i=0;i<plugin_cnt;i++)
    {
      if(plugins[i] != NULL)
	free(plugins[i]);
    }

  /* free the template string */
  if(tmpl != NULL)
    free(tmpl);

  bgpcorsaro_finalize_output(bgpcorsaro);
  bgpcorsaro = NULL;
  if(stream != NULL)
    {
      bgpstream_destroy(stream);
      stream = NULL;
    }

  clean();
  return 0;

 err:
  /* if we bail early, let us be responsible and up the memory we alloc'd */
  for(i=0;i<plugin_cnt;i++)
    {
      if(plugins[i] != NULL)
	free(plugins[i]);
    }

  if(tmpl != NULL)
    free(tmpl);

  clean();

  return -1;
}