예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
0
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;
}