static int add_prefixes_from_file(bgpstream_ip_counter_t *poi, char *pfx_file_string) { char pfx_line[MAX_LOG_BUFFER_LEN]; io_t *file = NULL; bgpstream_pfx_storage_t pfx_st; if (pfx_file_string == NULL) { return -1; } if ((file = wandio_create(pfx_file_string)) == NULL) { fprintf(stderr, "ERROR: Could not open prefix file (%s)\n", pfx_file_string); return -1; } while (wandio_fgets(file, &pfx_line, MAX_LOG_BUFFER_LEN, 1) > 0) { /* treat # as comment line, and ignore empty lines */ if (pfx_line[0] == '#' || pfx_line[0] == '\0') { continue; } if (bgpstream_str2pfx(pfx_line, &pfx_st) == NULL || bgpstream_ip_counter_add(poi, (bgpstream_pfx_t *)&pfx_st) != 0) { /* failed to parse/insert the prefix */ return -1; } } wandio_destroy(file); return 0; }
/** Parse the arguments given to the plugin */ static int parse_args(bgpcorsaro_t *bgpcorsaro) { bgpcorsaro_plugin_t *plugin = PLUGIN(bgpcorsaro); struct bgpcorsaro_pfxmonitor_state_t *state = STATE(bgpcorsaro); int opt; bgpstream_pfx_storage_t pfx_st; if (plugin->argc <= 0) { return 0; } /* NB: remember to reset optind to 1 before using getopt! */ optind = 1; while ((opt = getopt(plugin->argc, plugin->argv, ":l:L:m:n:i:M?")) >= 0) { switch (opt) { case 'm': if (optarg != NULL && strlen(optarg) - 1 <= PFXMONITOR_METRIC_PFX_LEN) { strncpy(state->metric_prefix, optarg, PFXMONITOR_METRIC_PFX_LEN); } else { fprintf(stderr, "Error: could not set metric prefix\n"); usage(plugin); return -1; } break; case 'i': if (optarg != NULL && strlen(optarg) - 1 <= PFXMONITOR_METRIC_PFX_LEN) { strncpy(state->ip_space_name, optarg, PFXMONITOR_METRIC_PFX_LEN); } else { fprintf(stderr, "Error: could not set IP space name\n"); usage(plugin); return -1; } break; case 'l': if (bgpstream_str2pfx(optarg, &pfx_st) == NULL) { fprintf(stderr, "Error: Could not parse prefix (%s)\n", optarg); usage(plugin); return -1; } bgpstream_ip_counter_add(state->poi, (bgpstream_pfx_t *)&pfx_st); break; case 'L': if (add_prefixes_from_file(state->poi, optarg) != 0) { return -1; } break; case 'M': state->more_specific = 1; break; case 'n': state->peer_asns_th = atoi(optarg); break; case '?': case ':': default: usage(plugin); return -1; } } /* if no prefixes were provided, */ if (bgpstream_ip_counter_get_ipcount(state->poi, BGPSTREAM_ADDR_VERSION_IPV4) == 0 && bgpstream_ip_counter_get_ipcount(state->poi, BGPSTREAM_ADDR_VERSION_IPV6) == 0) { fprintf(stderr, "Error: no valid prefixes provided\n"); usage(plugin); return -1; } return 0; }
void bgpstream_filter_mgr_filter_add(bgpstream_filter_mgr_t *bs_filter_mgr, bgpstream_filter_type_t filter_type, const char *filter_value) { bgpstream_str_set_t **v = NULL; bgpstream_debug("\tBSF_MGR:: add_filter start"); if (bs_filter_mgr == NULL) { return; // nothing to customize } switch (filter_type) { case BGPSTREAM_FILTER_TYPE_ELEM_PEER_ASN: if (bs_filter_mgr->peer_asns == NULL) { if ((bs_filter_mgr->peer_asns = bgpstream_id_set_create()) == NULL) { bgpstream_debug("\tBSF_MGR:: add_filter malloc failed"); bgpstream_log_warn("\tBSF_MGR: can't allocate memory"); return; } } bgpstream_id_set_insert(bs_filter_mgr->peer_asns, (uint32_t)strtoul(filter_value, NULL, 10)); return; case BGPSTREAM_FILTER_TYPE_ELEM_TYPE: if (strcmp(filter_value, "ribs") == 0) { bs_filter_mgr->elemtype_mask |= (BGPSTREAM_FILTER_ELEM_TYPE_RIB); } else if (strcmp(filter_value, "announcements") == 0) { bs_filter_mgr->elemtype_mask |= (BGPSTREAM_FILTER_ELEM_TYPE_ANNOUNCEMENT); } else if (strcmp(filter_value, "withdrawals") == 0) { bs_filter_mgr->elemtype_mask |= (BGPSTREAM_FILTER_ELEM_TYPE_WITHDRAWAL); } else if (strcmp(filter_value, "peerstates") == 0) { bs_filter_mgr->elemtype_mask |= (BGPSTREAM_FILTER_ELEM_TYPE_PEERSTATE); } else { bgpstream_log_warn("\tBSF_MGR: %s is not a known element type", filter_value); } return; case BGPSTREAM_FILTER_TYPE_ELEM_ASPATH: if (bs_filter_mgr->aspath_exprs == NULL) { if ((bs_filter_mgr->aspath_exprs = bgpstream_str_set_create()) == NULL) { bgpstream_debug("\tBSF_MGR:: add_filter malloc failed"); bgpstream_log_warn("\tBSF_MGR: can't allocate memory"); return; } } bgpstream_str_set_insert(bs_filter_mgr->aspath_exprs, filter_value); return; case BGPSTREAM_FILTER_TYPE_ELEM_PREFIX: case BGPSTREAM_FILTER_TYPE_ELEM_PREFIX_MORE: case BGPSTREAM_FILTER_TYPE_ELEM_PREFIX_LESS: case BGPSTREAM_FILTER_TYPE_ELEM_PREFIX_EXACT: case BGPSTREAM_FILTER_TYPE_ELEM_PREFIX_ANY: { bgpstream_pfx_storage_t pfx; uint8_t matchtype; if (bs_filter_mgr->prefixes == NULL) { if ((bs_filter_mgr->prefixes = bgpstream_patricia_tree_create(NULL)) == NULL) { bgpstream_debug("\tBSF_MGR:: add_filter malloc failed"); bgpstream_log_warn("\tBSF_MGR: can't allocate memory"); return; } } bgpstream_str2pfx(filter_value, &pfx); if (filter_type == BGPSTREAM_FILTER_TYPE_ELEM_PREFIX_MORE || filter_type == BGPSTREAM_FILTER_TYPE_ELEM_PREFIX) { matchtype = BGPSTREAM_PREFIX_MATCH_MORE; } else if (filter_type == BGPSTREAM_FILTER_TYPE_ELEM_PREFIX_LESS) { matchtype = BGPSTREAM_PREFIX_MATCH_LESS; } else if (filter_type == BGPSTREAM_FILTER_TYPE_ELEM_PREFIX_EXACT) { matchtype = BGPSTREAM_PREFIX_MATCH_EXACT; } else { matchtype = BGPSTREAM_PREFIX_MATCH_ANY; } pfx.allowed_matches = matchtype; if (bgpstream_patricia_tree_insert(bs_filter_mgr->prefixes, (bgpstream_pfx_t *)&pfx) == NULL) { bgpstream_debug("\tBSF_MGR:: add_filter malloc failed"); bgpstream_log_warn("\tBSF_MGR: can't add prefix"); return; } return; } case BGPSTREAM_FILTER_TYPE_ELEM_COMMUNITY: { int mask = 0; khiter_t k; int khret; bgpstream_community_t comm; if (bs_filter_mgr->communities == NULL) { if ((bs_filter_mgr->communities = kh_init(bgpstream_community_filter)) == NULL) { bgpstream_debug("\tBSF_MGR:: add_filter malloc failed"); bgpstream_log_warn("\tBSF_MGR: can't allocate memory"); return; } } if ((mask = bgpstream_str2community(filter_value, &comm)) < 0) { bgpstream_debug("\tBSF_MGR:: can't convert community"); return; } if ((k = kh_get(bgpstream_community_filter, bs_filter_mgr->communities, comm)) == kh_end(bs_filter_mgr->communities)) { k = kh_put(bgpstream_community_filter, bs_filter_mgr->communities, comm, &khret); kh_value(bs_filter_mgr->communities, k) = mask; } /* we use the AND because the less restrictive filter wins over the more * restrictive: * e.g. 10:0, 10:* is equivalent to 10:* */ kh_value(bs_filter_mgr->communities, k) = kh_value(bs_filter_mgr->communities, k) & mask; /* DEBUG: fprintf(stderr, "%s - %d\n", * filter_value, kh_value(bs_filter_mgr->communities, k) ); */ return; } case BGPSTREAM_FILTER_TYPE_ELEM_IP_VERSION: if (strcmp(filter_value, "4") == 0) { bs_filter_mgr->ipversion = BGPSTREAM_ADDR_VERSION_IPV4; } else if (strcmp(filter_value, "6") == 0) { bs_filter_mgr->ipversion = BGPSTREAM_ADDR_VERSION_IPV6; } else { bgpstream_log_warn("\tBSF_MGR: Unknown IP version %s, ignoring", filter_value); } return; case BGPSTREAM_FILTER_TYPE_PROJECT: v = &bs_filter_mgr->projects; break; case BGPSTREAM_FILTER_TYPE_COLLECTOR: v = &bs_filter_mgr->collectors; break; case BGPSTREAM_FILTER_TYPE_RECORD_TYPE: v = &bs_filter_mgr->bgp_types; break; default: bgpstream_log_warn("\tBSF_MGR: unknown filter - ignoring"); return; } if (*v == NULL) { if ((*v = bgpstream_str_set_create()) == NULL) { bgpstream_debug("\tBSF_MGR:: add_filter malloc failed"); bgpstream_log_warn("\tBSF_MGR: can't allocate memory"); return; } } bgpstream_str_set_insert(*v, filter_value); bgpstream_debug("\tBSF_MGR:: add_filter stop"); return; }
int test_val_res_struct() { uint32_t asn = TEST_PFX_ASN; uint8_t max_pfx_len = TEST_PFX_MAX_LEN; bgpstream_ipv4_addr_t pfxv4; bgpstream_str2pfx(IPV4_TEST_PFX_A, (bgpstream_pfx_storage_t *)&pfxv4); bgpstream_rpki_validation_result_t val_table; bgpstream_rpki_validation_result_init(&val_table, 2); CHECK("RTR: Compare max size after init", val_table.asn_size == 2); CHECK("RTR: Compare used asn size after init", val_table.asn_used == 0); CHECK("RTR: Compare asn_pfx pointer address after init", val_table.asn_pfx != NULL); /* the sequence to calculate the memory size is: max(2, 2**(ceil(log(X + 1) / log(2)))) where X is the number of added elements */ size_t memory_test_sizes[10] = {2, 2, 4, 4, 8, 8, 8, 8, 16, 16}; int x; for (x = 0; x < 10; x++) { bgpstream_rpki_validation_result_insert_asn(&val_table, asn + x); CHECK("RTR: Compare used asn size after adding asn", val_table.asn_used == (x + 1)); CHECK("RTR: Compare max asn size after adding asn", val_table.asn_size == memory_test_sizes[x]); CHECK("RTR: Compare asn in prefix array after adding asn", val_table.asn_pfx[x].asn == (asn + x)); CHECK("RTR: Compare number of used prefix after adding asn", val_table.asn_pfx[x].pfx_used == 0); CHECK("RTR: Compare max number of prefix after adding asn", val_table.asn_pfx[x].pfx_size == 2); bgpstream_rpki_validation_result_insert_asn(&val_table, asn + x); CHECK("RTR: Compare used asn size after adding duplicate asn", val_table.asn_used == (x + 1)); CHECK("RTR: Compare max asn size after adding duplicate asn", val_table.asn_size == memory_test_sizes[x]); CHECK("RTR: Compare number of used prefix after adding asn", val_table.asn_pfx[x].pfx_used == 0); CHECK("RTR: Compare max number of prefix after adding asn", val_table.asn_pfx[x].pfx_size == 2); int y; for (y = 0; y < 10; y++) { bgpstream_rpki_validation_result_insert_pfx( &val_table, asn + x, (bgpstream_pfx_t *)&pfxv4, max_pfx_len - y); CHECK("RTR: Compare used asn size after adding prefix", val_table.asn_used == (x + 1)); CHECK("RTR: Compare max asn size after adding prefix", val_table.asn_size == memory_test_sizes[x]); CHECK("RTR: Compare asn after adding prefix", val_table.asn_pfx[x].asn == (asn + x)); CHECK("RTR: Compare number of used prefix of asn after adding prefix", val_table.asn_pfx[x].pfx_used == (y + 1)); CHECK("RTR: Compare max number of prefix of asn after adding prefix", val_table.asn_pfx[x].pfx_size == memory_test_sizes[y]); CHECK("RTR: Compare prefix in prefix array of asn after adding prefix", inet_ntoa(val_table.asn_pfx[x].pfxs[y].pfx.address.ipv4) == inet_ntoa(pfxv4.ipv4)); CHECK("RTR: Compare max len of prefix of asn after adding prefix", val_table.asn_pfx[x].pfxs[y].max_pfx_len == (max_pfx_len - y)); bgpstream_rpki_validation_result_insert_pfx( &val_table, asn + x, (bgpstream_pfx_t *)&pfxv4, max_pfx_len - y); CHECK("RTR: Compare used asn size after adding duplicate prefix", val_table.asn_used == (x + 1)); CHECK("RTR: Compare max asn size after adding duplicate prefix", val_table.asn_size == memory_test_sizes[x]); CHECK("RTR: Compare asn after adding duplicate prefix", val_table.asn_pfx[x].asn == (asn + x)); CHECK("RTR: Compare number of used prefix of asn after adding duplicate " "prefix", val_table.asn_pfx[x].pfx_used == (y + 1)); CHECK("RTR: Compare max number of prefix of asn after adding duplicate " "prefix", val_table.asn_pfx[x].pfx_size == memory_test_sizes[y]); CHECK("RTR: Compare prefix in prefix array of asn after adding duplicate " "prefix", inet_ntoa(val_table.asn_pfx[x].pfxs[y].pfx.address.ipv4) == inet_ntoa(pfxv4.ipv4)); CHECK( "RTR: Compare max len of prefix of asn after adding duplicate prefix", val_table.asn_pfx[x].pfxs[y].max_pfx_len == (max_pfx_len - y)); } } bgpstream_rpki_validation_result_free(&val_table); return 0; }