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; }
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; }