コード例 #1
0
static int
same_header(char *mrt_filename, unsigned char *previous_header)
{
  off_t read_bytes;
  io_t *io_h = wandio_create(mrt_filename);
  if(io_h == NULL)
    {
      bgpstream_log_err("\t\tBSDS_SINGLEFILE: can't open file!");    
      return -1;
    }
  
  read_bytes = wandio_read(io_h, (void *) &(buffer[0]),  MAX_HEADER_READ_BYTES);
  if(read_bytes < 0)
    {
      bgpstream_log_err("\t\tBSDS_SINGLEFILE: can't read file!");
      wandio_destroy(io_h);
      return -1;
    }

  int ret = memcmp(buffer, previous_header, sizeof(unsigned char) * read_bytes);
  wandio_destroy(io_h);
  /* if there is no difference, then they have the same header */
  if(ret == 0)
    {
      /* fprintf(stderr, "same header\n"); */
      return 1;
    }
  memcpy(previous_header, buffer, sizeof(unsigned char) * read_bytes);
  return 0;
}
コード例 #2
0
int
bgpstream_csvfile_datasource_update_input_queue(bgpstream_csvfile_datasource_t* csvfile_ds,
                                                bgpstream_input_mgr_t *input_mgr) {
  bgpstream_debug("\t\tBSDS_CSVFILE: csvfile_ds update input queue start");
  
  io_t *file_io = NULL;
  char buffer[BUFFER_LEN];
  int read = 0;

  struct timeval tv;
  gettimeofday(&tv, NULL);
  
  /* we accept all timestamp earlier than now() - 1 second */
  csvfile_ds->max_accepted_ts = tv.tv_sec - 1;

  csvfile_ds->num_results = 0;
  csvfile_ds->max_ts_infile = 0;
  csvfile_ds->input_mgr = input_mgr;
  
  if((file_io = wandio_create(csvfile_ds->csvfile_file)) == NULL)
    {
      bgpstream_log_err("\t\tBSDS_CSVFILE: create csvfile_ds can't open file %s", csvfile_ds->csvfile_file);    
      return -1;
    }

    while((read = wandio_read(file_io, &buffer, BUFFER_LEN)) > 0)
    {
      if(csv_parse(&(csvfile_ds->parser), buffer, read,
		   parse_csvfile_field,
		   parse_csvfile_rowend,
		   csvfile_ds) != read)
	{
          bgpstream_log_err("\t\tBSDS_CSVFILE: CSV error %s", csv_strerror(csv_error(&(csvfile_ds->parser))));         
	  return -1;
	}
    }

  if(csv_fini(&(csvfile_ds->parser),
	      parse_csvfile_field,
	      parse_csvfile_rowend,
	      csvfile_ds) != 0)
    {
      bgpstream_log_err("\t\tBSDS_CSVFILE: CSV error %s", csv_strerror(csv_error(&(csvfile_ds->parser))));         
      return -1;
    }
  
  wandio_destroy(file_io);
  csvfile_ds->input_mgr = NULL;
  csvfile_ds->last_processed_ts = csvfile_ds->max_ts_infile;
  
  bgpstream_debug("\t\tBSDS_CSVFILE: csvfile_ds update input queue end");
  return csvfile_ds->num_results;
}
コード例 #3
0
bgpstream_csvfile_datasource_t *
bgpstream_csvfile_datasource_create(bgpstream_filter_mgr_t *filter_mgr, 
                                    char *csvfile_file)
{
  bgpstream_debug("\t\tBSDS_CSVFILE: create csvfile_ds start");  
  bgpstream_csvfile_datasource_t *csvfile_ds = (bgpstream_csvfile_datasource_t*) malloc_zero(sizeof(bgpstream_csvfile_datasource_t));
  if(csvfile_ds == NULL) {
    bgpstream_log_err("\t\tBSDS_CSVFILE: create csvfile_ds can't allocate memory");    
    goto err;
  }  
  if(csvfile_file == NULL)
    {
      bgpstream_log_err("\t\tBSDS_CSVFILE: create csvfile_ds no file provided");    
      goto err;
    }
  if((csvfile_ds->csvfile_file = strdup(csvfile_file)) == NULL)
    {
      bgpstream_log_err("\t\tBSDS_CSVFILE: can't allocate memory for filename");    
      goto err;
    }
  
  /* cvs file parser options */
  unsigned char options = CSV_STRICT | CSV_REPALL_NL | CSV_STRICT_FINI |
                CSV_APPEND_NULL | CSV_EMPTY_IS_NULL;

  if(csv_init(&(csvfile_ds->parser), options) !=0)
    {
      bgpstream_log_err("\t\tBSDS_CSVFILE: can't initialize csv parser");    
      goto err;
    }

  csvfile_ds->current_field = CSVFILE_PATH;
  
  csvfile_ds->filter_mgr = filter_mgr;
  csvfile_ds->input_mgr = NULL;

  csvfile_ds->num_results = 0;

  csvfile_ds->max_ts_infile = 0;
  csvfile_ds->last_processed_ts = 0;
  csvfile_ds->max_accepted_ts = 0;

  bgpstream_debug("\t\tBSDS_CSVFILE: create csvfile_ds end");
  return csvfile_ds;
  
 err:
  bgpstream_csvfile_datasource_destroy(csvfile_ds);
  return NULL;
}
コード例 #4
0
bgpstream_singlefile_datasource_t *
bgpstream_singlefile_datasource_create(bgpstream_filter_mgr_t *filter_mgr,
                                       char *singlefile_rib_mrtfile,
                                       char *singlefile_upd_mrtfile)
{
  bgpstream_debug("\t\tBSDS_CLIST: create singlefile_ds start");  
  bgpstream_singlefile_datasource_t *singlefile_ds = (bgpstream_singlefile_datasource_t*) malloc(sizeof(bgpstream_singlefile_datasource_t));
  if(singlefile_ds == NULL) {
    bgpstream_log_err("\t\tBSDS_CLIST: create singlefile_ds can't allocate memory");    
    return NULL; // can't allocate memory
  }
  singlefile_ds->filter_mgr = filter_mgr;
  singlefile_ds->rib_filename[0] = '\0';
  singlefile_ds->rib_header[0] = '\0';
  singlefile_ds->last_rib_filetime = 0;
  if(singlefile_rib_mrtfile != NULL)
    {
      strcpy(singlefile_ds->rib_filename, singlefile_rib_mrtfile);
    }
  singlefile_ds->update_filename[0] = '\0';
  singlefile_ds->update_header[0] = '\0';
  singlefile_ds->last_update_filetime = 0;
  if(singlefile_upd_mrtfile != NULL)
    {
      strcpy(singlefile_ds->update_filename, singlefile_upd_mrtfile);
    }
  bgpstream_debug("\t\tBSDS_CLIST: create customlist_ds end");
  return singlefile_ds;
}
コード例 #5
0
static int bgpstream_parse_endvalue(char *conj, fp_state_t *state,
                                    bgpstream_filter_item_t **curr)
{

  if (*curr) {
    free((*curr)->value);
    free(*curr);
    *curr = NULL;
  }

  /* Check for a valid conjunction */
  if (strcmp(conj, "and") == 0) {
    *state = TERM;
  }

  /* TODO allow 'or', anything else? */

  if (*state != TERM) {
    bgpstream_log_err("Bad conjunction in bgpstream filter string: %s", conj);
    *state = FAIL;
    return FAIL;
  }

  *curr = (bgpstream_filter_item_t *)calloc(1, sizeof(bgpstream_filter_item_t));

  return *state;
}
コード例 #6
0
static int bgpstream_parse_filter_term(char *term, fp_state_t *state,
                                       bgpstream_filter_item_t *curr)
{

  /* Painful list of strcmps... */
  /* TODO, can we save some time by checking the first character to rule
   * out most of the terms quickly?? */

  if (strcmp(term, "project") == 0 || strcmp(term, "proj") == 0) {
    /* Project */
    bgpstream_debug("Got a project term");
    curr->termtype = BGPSTREAM_FILTER_TYPE_PROJECT;
    *state = VALUE;
    return *state;
  }

  if (strcmp(term, "collector") == 0 || strcmp(term, "coll") == 0) {
    /* Collector */
    bgpstream_debug("Got a collector term");
    curr->termtype = BGPSTREAM_FILTER_TYPE_COLLECTOR;
    *state = VALUE;
    return *state;
  }

  if (strcmp(term, "type") == 0) {
    /* Type */
    bgpstream_debug("Got a type term");
    curr->termtype = BGPSTREAM_FILTER_TYPE_RECORD_TYPE;
    *state = VALUE;
    return *state;
  }

  if (strcmp(term, "peer") == 0) {
    /* Peer */
    bgpstream_debug("Got a peer term");
    curr->termtype = BGPSTREAM_FILTER_TYPE_ELEM_PEER_ASN;
    *state = VALUE;
    return *state;
  }

  if (strcmp(term, "prefix") == 0 || strcmp(term, "pref") == 0) {
    /* prefix */
    bgpstream_debug("Got a prefix term");
    /* XXX is this the best default? */
    curr->termtype = BGPSTREAM_FILTER_TYPE_ELEM_PREFIX_MORE;
    *state = PREFIXEXT;
    return *state;
  }

  if (strcmp(term, "community") == 0 || strcmp(term, "comm") == 0) {
    /* Community */
    bgpstream_debug("Got a community term");
    curr->termtype = BGPSTREAM_FILTER_TYPE_ELEM_COMMUNITY;
    *state = VALUE;
    return *state;
  }

  if (strcmp(term, "aspath") == 0 || strcmp(term, "path") == 0) {
    /* AS Path */
    bgpstream_debug("Got an aspath term");
    curr->termtype = BGPSTREAM_FILTER_TYPE_ELEM_ASPATH;
    *state = VALUE;
    return *state;
  }

  if (strcmp(term, "extcommunity") == 0 || strcmp(term, "extc") == 0) {
    /* Extended Community */
    bgpstream_debug("Got a extended community term");
    curr->termtype = BGPSTREAM_FILTER_TYPE_ELEM_EXTENDED_COMMUNITY;
    *state = VALUE;
    return *state;
  }

  if (strcmp(term, "ipversion") == 0 || strcmp(term, "ipv") == 0) {
    /* IP version */
    bgpstream_debug("Got a ip version term");
    curr->termtype = BGPSTREAM_FILTER_TYPE_ELEM_IP_VERSION;
    *state = VALUE;
    return *state;
  }

  if (strcmp(term, "elemtype") == 0) {
    /* Element type */
    bgpstream_debug("Got an element type term");
    curr->termtype = BGPSTREAM_FILTER_TYPE_ELEM_TYPE;
    *state = VALUE;
    return *state;
  }

  bgpstream_log_err("Expected a valid term, got %s", term);
  *state = FAIL;
  return FAIL;
}
コード例 #7
0
int bgpstream_parse_filter_string(bgpstream_t *bs, const char *fstring)
{

  char *tok;
  char *sptr = NULL;
  int ret = 1;

  bgpstream_debug("Parsing filter string - %s", fstring);
  bgpstream_filter_item_t *filteritem;
  fp_state_t state = TERM;

  tok = strtok_r((char *)fstring, (char *)" ", &sptr);

  filteritem =
    (bgpstream_filter_item_t *)calloc(1, sizeof(bgpstream_filter_item_t));

  while (tok != NULL) {

    switch (state) {
    case TERM:
      if (bgpstream_parse_filter_term(tok, &state, filteritem) == FAIL) {
        ret = 0;
        goto endparsing;
      }
      break;

    case PREFIXEXT:
      if (bgpstream_parse_prefixext(tok, &state, filteritem) == FAIL) {
        ret = 0;
        goto endparsing;
      }
      if (state == ENDVALUE) {
        instantiate_filter(bs, filteritem);
      }
      break;

    case VALUE:
      if (bgpstream_parse_value(tok, &state, filteritem) == FAIL) {
        ret = 0;
        goto endparsing;
      }
      instantiate_filter(bs, filteritem);
      break;

    case QUOTEDVALUE:
      if (bgpstream_parse_quotedvalue(tok, &state, filteritem) == FAIL) {
        ret = 0;
        goto endparsing;
      }
      if (state == ENDVALUE) {
        instantiate_filter(bs, filteritem);
      }
      break;

    case ENDVALUE:
      if (bgpstream_parse_endvalue(tok, &state, &filteritem) == FAIL) {
        ret = 0;
        goto endparsing;
      }
      break;

    default:
      bgpstream_log_err("Unexpected BGPStream filter string state: %d", state);
      ret = 0;
      goto endparsing;
    }
    tok = strtok_r(NULL, " ", &sptr);
  }

endparsing:

  if (filteritem) {
    if (filteritem->value) {
      free(filteritem->value);
    }
    free(filteritem);
  }

  bgpstream_debug("Finished parsing filter string");
  return ret;
}
コード例 #8
0
bgpstream_broker_datasource_t *
bgpstream_broker_datasource_create(bgpstream_filter_mgr_t *filter_mgr,
                                   char *broker_url, char **params,
                                   int params_cnt)
{
  int i;
  bgpstream_debug("\t\tBSDS_BROKER: create broker_ds start");
  bgpstream_broker_datasource_t *broker_ds;

  if ((broker_ds = malloc_zero(sizeof(bgpstream_broker_datasource_t))) ==
      NULL) {
    bgpstream_log_err(
      "\t\tBSDS_BROKER: create broker_ds can't allocate memory");
    goto err;
  }
  if (broker_url == NULL) {
    bgpstream_log_err("\t\tBSDS_BROKER: create broker_ds no file provided");
    goto err;
  }
  broker_ds->filter_mgr = filter_mgr;
  broker_ds->first_param = 1;
  broker_ds->query_url_remaining = URL_BUFLEN;
  broker_ds->query_url_buf[0] = '\0';

  // http://bgpstream.caida.org/broker (e.g.)
  APPEND_STR(broker_url);

  // http://bgpstream.caida.org/broker/data?
  APPEND_STR("/data");

  // projects, collectors, bgp_types, and time_intervals are used as filters
  // only if they are provided by the user
  bgpstream_interval_filter_t *tif;

  // projects
  char *f;
  if (filter_mgr->projects != NULL) {
    bgpstream_str_set_rewind(filter_mgr->projects);
    while ((f = bgpstream_str_set_next(filter_mgr->projects)) != NULL) {
      AMPORQ;
      APPEND_STR("projects[]=");
      APPEND_STR(f);
    }
  }
  // collectors
  if (filter_mgr->collectors != NULL) {
    bgpstream_str_set_rewind(filter_mgr->collectors);
    while ((f = bgpstream_str_set_next(filter_mgr->collectors)) != NULL) {
      AMPORQ;
      APPEND_STR("collectors[]=");
      APPEND_STR(f);
    }
  }
  // bgp_types
  if (filter_mgr->bgp_types != NULL) {
    bgpstream_str_set_rewind(filter_mgr->bgp_types);
    while ((f = bgpstream_str_set_next(filter_mgr->bgp_types)) != NULL) {
      AMPORQ;
      APPEND_STR("types[]=");
      APPEND_STR(f);
    }
  }

  // user-provided params
  for (i = 0; i < params_cnt; i++) {
    assert(params[i] != NULL);
    AMPORQ;
    APPEND_STR(params[i]);
  }

// time_intervals
#define BUFLEN 20
  char int_buf[BUFLEN];
  if (filter_mgr->time_intervals != NULL) {
    tif = filter_mgr->time_intervals;

    while (tif != NULL) {
      AMPORQ;
      APPEND_STR("intervals[]=");

      // BEGIN TIME
      if (snprintf(int_buf, BUFLEN, "%" PRIu32, tif->begin_time) >= BUFLEN) {
        goto err;
      }
      APPEND_STR(int_buf);
      APPEND_STR(",");

      // END TIME
      if (snprintf(int_buf, BUFLEN, "%" PRIu32, tif->end_time) >= BUFLEN) {
        goto err;
      }
      APPEND_STR(int_buf);

      tif = tif->next;
    }
  }

  // grab pointer to the end of the current string to simplify modifying the
  // query later
  broker_ds->query_url_end =
    broker_ds->query_url_buf + strlen(broker_ds->query_url_buf);
  assert((*broker_ds->query_url_end) == '\0');

  bgpstream_debug("\t\tBSDS_BROKER: create broker_ds end");

  return broker_ds;
err:
  bgpstream_broker_datasource_destroy(broker_ds);
  return NULL;
}
コード例 #9
0
ファイル: bgpstream_record.c プロジェクト: digizeph/bgpstream
static int bgpstream_elem_check_filters(bgpstream_filter_mgr_t *filter_mgr,
                                        bgpstream_elem_t *elem)
{
  int pass = 0;

  /* First up, check if this element is the right type */
  if (filter_mgr->elemtype_mask) {

    if (elem->type == BGPSTREAM_ELEM_TYPE_PEERSTATE &&
        !(filter_mgr->elemtype_mask & BGPSTREAM_FILTER_ELEM_TYPE_PEERSTATE)) {
      return 0;
    }

    if (elem->type == BGPSTREAM_ELEM_TYPE_RIB &&
        !(filter_mgr->elemtype_mask & BGPSTREAM_FILTER_ELEM_TYPE_RIB)) {
      return 0;
    }

    if (elem->type == BGPSTREAM_ELEM_TYPE_ANNOUNCEMENT &&
        !(filter_mgr->elemtype_mask &
          BGPSTREAM_FILTER_ELEM_TYPE_ANNOUNCEMENT)) {
      return 0;
    }

    if (elem->type == BGPSTREAM_ELEM_TYPE_WITHDRAWAL &&
        !(filter_mgr->elemtype_mask & BGPSTREAM_FILTER_ELEM_TYPE_WITHDRAWAL)) {
      return 0;
    }
  }

  /* Checking peer ASNs: if the filter is on and the peer asn is not in the
   * set, return 0 */
  if (filter_mgr->peer_asns &&
      bgpstream_id_set_exists(filter_mgr->peer_asns, elem->peer_asnumber) ==
        0) {
    return 0;
  }

  if (filter_mgr->ipversion) {
    /* Determine address version for the element prefix */

    if (elem->type == BGPSTREAM_ELEM_TYPE_PEERSTATE) {
      return 0;
    }

    bgpstream_ip_addr_t *addr = &(((bgpstream_pfx_t *)&elem->prefix)->address);
    if (addr->version != filter_mgr->ipversion)
      return 0;
  }

  if (filter_mgr->prefixes) {
    if (elem->type == BGPSTREAM_ELEM_TYPE_PEERSTATE) {
      return 0;
    }
    return bgpstream_elem_prefix_match(filter_mgr->prefixes,
                                       (bgpstream_pfx_t *)&elem->prefix);
  }

  /* Checking AS Path expressions */
  if (filter_mgr->aspath_exprs) {
    char aspath[65536];
    char *regexstr;
    int pathlen;
    regex_t re;
    int result;
    int negatives = 0;
    int positives = 0;
    int totalpositives = 0;

    if (elem->type == BGPSTREAM_ELEM_TYPE_WITHDRAWAL ||
        elem->type == BGPSTREAM_ELEM_TYPE_PEERSTATE) {
      return 0;
    }

    pathlen = bgpstream_as_path_get_filterable(aspath, 65535, elem->aspath);

    if (pathlen == 65535) {
      bgpstream_log_warn("AS Path is too long? Filter may not work well.");
    }

    if (pathlen == 0) {
      return 0;
    }

    bgpstream_str_set_rewind(filter_mgr->aspath_exprs);
    while ((regexstr = bgpstream_str_set_next(filter_mgr->aspath_exprs)) !=
           NULL) {
      int negate = 0;

      if (strlen(regexstr) == 0)
        continue;

      if (*regexstr == '!') {
        negate = 1;
        regexstr++;
      } else {
        totalpositives += 1;
      }

      if (regcomp(&re, regexstr, 0) < 0) {
        /* XXX should really use regerror here for proper error reporting */
        bgpstream_log_err("Failed to compile AS path regex");
        break;
      }

      result = regexec(&re, aspath, 0, NULL, 0);
      if (result == 0) {
        if (!negate) {
          positives++;
        }
        if (negate) {
          negatives++;
        }
      }

      regfree(&re);
      if (result != REG_NOMATCH && result != 0) {
        bgpstream_log_err("Error while matching AS path regex");
        break;
      }
    }
    if (positives == totalpositives && negatives == 0) {
      return 1;
    } else {
      return 0;
    }
  }
  /* Checking communities (unless it is a withdrawal message) */
  pass = (filter_mgr->communities != NULL) ? 0 : 1;
  if (filter_mgr->communities) {
    if (elem->type == BGPSTREAM_ELEM_TYPE_WITHDRAWAL ||
        elem->type == BGPSTREAM_ELEM_TYPE_PEERSTATE) {
      return 0;
    }

    bgpstream_community_t *c;
    khiter_t k;
    for (k = kh_begin(filter_mgr->communities);
         k != kh_end(filter_mgr->communities); ++k) {
      if (kh_exist(filter_mgr->communities, k)) {
        c = &(kh_key(filter_mgr->communities, k));
        if (bgpstream_community_set_match(
              elem->communities, c, kh_value(filter_mgr->communities, k))) {
          pass = 1;
          break;
        }
      }
    }
    if (pass == 0) {
      return 0;
    }
  }

  return 1;
}