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;
}
static bool
bgpstream_csvfile_datasource_filter_ok(bgpstream_csvfile_datasource_t* csvfile_ds) {
  bgpstream_debug("\t\tBSDS_CSVFILE: csvfile_ds apply filter start");

  /* fprintf(stderr, "%s %s %s %s\n", */
  /*         csvfile_ds->filename, csvfile_ds->project, csvfile_ds->collector, csvfile_ds->bgp_type); */

  bgpstream_interval_filter_t * tif;
  bool all_false;
  
  char *f;  
  
  // projects
  all_false = true;
  if(csvfile_ds->filter_mgr->projects != NULL) {
    bgpstream_str_set_rewind(csvfile_ds->filter_mgr->projects);    
    while((f = bgpstream_str_set_next(csvfile_ds->filter_mgr->projects)) != NULL)
      {
        if(strcmp(f, csvfile_ds->project) == 0) {
          all_false = false;
          break;
        }
      }    
    if(all_false) {
      return false; 
    }
  }
  // collectors
  all_false = true;
  if(csvfile_ds->filter_mgr->collectors != NULL) {
    bgpstream_str_set_rewind(csvfile_ds->filter_mgr->collectors);    
    while((f = bgpstream_str_set_next(csvfile_ds->filter_mgr->collectors)) != NULL)
      {
        if(strcmp(f, csvfile_ds->collector) == 0) {
          all_false = false;
          break;
        }
      }    
    if(all_false) {
      return false; 
    }
  }

  // bgp_types
  all_false = true;
  if(csvfile_ds->filter_mgr->bgp_types != NULL) {
    bgpstream_str_set_rewind(csvfile_ds->filter_mgr->bgp_types);    
    while((f = bgpstream_str_set_next(csvfile_ds->filter_mgr->bgp_types)) != NULL)
      {
        if(strcmp(f, csvfile_ds->bgp_type) == 0) {
          all_false = false;
          break;
        }
      }    
    if(all_false) {
      return false; 
    }
  }

  // time_intervals
  all_false = true;
  if(csvfile_ds->filter_mgr->time_intervals != NULL) {
    tif = csvfile_ds->filter_mgr->time_intervals;
    while(tif != NULL) {      
      // filetime (we consider 15 mins before to consider routeviews updates
      // and 120 seconds to have some margins)
      if(csvfile_ds->filetime >= (tif->begin_time - 15*60 - 120) &&
         (tif->end_time == BGPSTREAM_FOREVER ||
          csvfile_ds->filetime <= tif->end_time)) {
	all_false = false;
	break;
      }
      tif = tif->next;
    }
    if(all_false) {
      return false; 
    }
  }
  // if all the filters are passed
  return true;
}
Ejemplo n.º 3
0
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;
}