|
30 | 30 |
|
31 | 31 | #include "bgpdump_lib.h" |
32 | 32 | #include "utils.h" |
| 33 | +#include "khash.h" |
33 | 34 |
|
| 35 | +#include "bgpstream.h" |
34 | 36 | #include "bgpstream_utils.h" |
35 | 37 |
|
36 | 38 | #include "bgpstream_debug.h" |
37 | 39 | #include "bgpstream_record.h" |
38 | 40 |
|
| 41 | +#include "bgpstream_constants.h" |
39 | 42 | #include "bgpstream_elem_int.h" |
| 43 | +#include "bgpstream_utils_rtr.h" |
40 | 44 |
|
41 | 45 | /* ==================== PROTECTED FUNCTIONS ==================== */ |
42 | 46 |
|
@@ -81,12 +85,25 @@ void bgpstream_elem_destroy(bgpstream_elem_t *elem) { |
81 | 85 | bgpstream_community_set_destroy(elem->communities); |
82 | 86 | elem->communities = NULL; |
83 | 87 |
|
| 88 | +#ifdef WITH_RTR |
| 89 | + if(elem->annotations.active){ |
| 90 | + kh_destroy(rpki_result, elem->annotations.rpki_kh); |
| 91 | + elem->annotations.rpki_kh = NULL; |
| 92 | + } |
| 93 | +#endif |
| 94 | + |
84 | 95 | free(elem); |
85 | 96 | } |
86 | 97 |
|
87 | 98 | void bgpstream_elem_clear(bgpstream_elem_t *elem) { |
88 | 99 | bgpstream_as_path_clear(elem->aspath); |
89 | 100 | bgpstream_community_set_clear(elem->communities); |
| 101 | +#ifdef WITH_RTR |
| 102 | + if(elem->annotations.active && |
| 103 | + (elem->annotations.rpki_validation_status != BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTVALIDATED)){ |
| 104 | + kh_clear(rpki_result, elem->annotations.rpki_kh); |
| 105 | + } |
| 106 | +#endif |
90 | 107 | } |
91 | 108 |
|
92 | 109 | bgpstream_elem_t *bgpstream_elem_copy(bgpstream_elem_t *dst, |
@@ -346,6 +363,17 @@ char *bgpstream_elem_custom_snprintf(char *buf, size_t len, |
346 | 363 | if(B_FULL) |
347 | 364 | return NULL; |
348 | 365 |
|
| 366 | +#ifdef WITH_RTR |
| 367 | + /* RPKI Validation */ |
| 368 | + if(elem->annotations.active) { |
| 369 | + char buf_rpki[BGPSTREAM_RPKI_RST_MAX_LEN]; |
| 370 | + c = bgpstream_elem_get_rpki_validation_result_snprintf( |
| 371 | + buf_rpki, sizeof(buf_rpki), elem); |
| 372 | + strcat(buf, buf_rpki); |
| 373 | + written += c; |
| 374 | + buf_p += c; |
| 375 | + } |
| 376 | +#endif |
349 | 377 | /* END OF LINE */ |
350 | 378 | break; |
351 | 379 |
|
@@ -422,3 +450,99 @@ char *bgpstream_elem_snprintf(char *buf, size_t len, |
422 | 450 | { |
423 | 451 | return bgpstream_elem_custom_snprintf(buf, len, elem, 1); |
424 | 452 | } |
| 453 | + |
| 454 | +#ifdef WITH_RTR |
| 455 | +int bgpstream_elem_get_rpki_validation_result_snprintf( |
| 456 | + char *buf, size_t len, bgpstream_elem_t const *elem) |
| 457 | +{ |
| 458 | + int key; |
| 459 | + char *val; |
| 460 | + char result_output[BGPSTREAM_RPKI_RST_MAX_LEN]; |
| 461 | + char valid_prefixes[BGPSTREAM_RPKI_RST_MAX_LEN]; |
| 462 | + if (elem->annotations.rpki_validation_status != |
| 463 | + BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND) { |
| 464 | + snprintf(result_output, sizeof(result_output), "%s%s", result_output, |
| 465 | + elem->annotations.rpki_validation_status == |
| 466 | + BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_INVALID |
| 467 | + ? "invalid;" : "valid;"); |
| 468 | + |
| 469 | + kh_foreach(elem->annotations.rpki_kh, key, val, |
| 470 | + snprintf(valid_prefixes, sizeof(valid_prefixes), "%i,%s;", key, val); |
| 471 | + strcat(result_output, valid_prefixes); |
| 472 | + ); |
| 473 | + result_output[strlen(result_output) - 1] = 0; |
| 474 | + } else { |
| 475 | + snprintf(result_output, sizeof(result_output), "%s%s", result_output, |
| 476 | + "notfound"); |
| 477 | + } |
| 478 | + |
| 479 | + return snprintf(buf, len, "%s", result_output); |
| 480 | +} |
| 481 | + |
| 482 | +void bgpstream_elem_get_rpki_validation_result(struct rtr_mgr_config *cfg, bgpstream_elem_t *elem, |
| 483 | + char *prefix, |
| 484 | + uint32_t origin_asn, |
| 485 | + uint8_t mask_len) |
| 486 | +{ |
| 487 | + if (elem->annotations.rpki_validation_status == |
| 488 | + BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTVALIDATED) { |
| 489 | + |
| 490 | + struct reasoned_result res_reasoned = |
| 491 | + bgpstream_rtr_validate_reason(cfg, origin_asn, prefix, mask_len); |
| 492 | + |
| 493 | + if (res_reasoned.result == BGP_PFXV_STATE_VALID) { |
| 494 | + elem->annotations.rpki_validation_status = |
| 495 | + BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_VALID; |
| 496 | + } |
| 497 | + if (res_reasoned.result == BGP_PFXV_STATE_NOT_FOUND) { |
| 498 | + elem->annotations.rpki_validation_status = |
| 499 | + BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND; |
| 500 | + } |
| 501 | + if (res_reasoned.result == BGP_PFXV_STATE_INVALID) { |
| 502 | + elem->annotations.rpki_validation_status = |
| 503 | + BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_INVALID; |
| 504 | + } |
| 505 | + |
| 506 | + if (elem->annotations.rpki_validation_status != |
| 507 | + BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND) { |
| 508 | + |
| 509 | + char reason_prefix[INET6_ADDRSTRLEN]; |
| 510 | + char buf_p[BGPSTREAM_RPKI_RST_MAX_LEN]; |
| 511 | + |
| 512 | + int ret; |
| 513 | + khiter_t k; |
| 514 | + |
| 515 | + if(elem->annotations.khash_init != 1) { |
| 516 | + elem->annotations.rpki_kh = kh_init(rpki_result); |
| 517 | + elem->annotations.khash_init = 1; |
| 518 | + } |
| 519 | + |
| 520 | + for (int i = 0; i < res_reasoned.reason_len; i++) { |
| 521 | + if(kh_get(rpki_result, elem->annotations.rpki_kh, res_reasoned.reason[i].asn) == |
| 522 | + kh_end(elem->annotations.rpki_kh)){ |
| 523 | + k = kh_put(rpki_result, elem->annotations.rpki_kh, (int) res_reasoned.reason[i].asn, &ret); |
| 524 | + kh_val(elem->annotations.rpki_kh, k) = '\0'; |
| 525 | + } |
| 526 | + else { |
| 527 | + k = kh_get(rpki_result, elem->annotations.rpki_kh, (int) res_reasoned.reason[i].asn); |
| 528 | + } |
| 529 | + |
| 530 | + lrtr_ip_addr_to_str(&(res_reasoned.reason[i].prefix), reason_prefix, sizeof(reason_prefix)); |
| 531 | + snprintf(elem->annotations.valid_prefix[k], BGPSTREAM_RPKI_RST_MAX_LEN, "%s/%" PRIu8 "-%"PRIu8, |
| 532 | + reason_prefix, res_reasoned.reason[i].min_len, res_reasoned.reason[i].max_len); |
| 533 | + |
| 534 | + if(!kh_val(elem->annotations.rpki_kh, k)){ |
| 535 | + kh_val(elem->annotations.rpki_kh, k) = elem->annotations.valid_prefix[k]; |
| 536 | + } |
| 537 | + else if(!strstr(kh_val(elem->annotations.rpki_kh, k), elem->annotations.valid_prefix[k])) { |
| 538 | + snprintf(buf_p, sizeof(buf_p), "%s %s", kh_val(elem->annotations.rpki_kh, k), |
| 539 | + elem->annotations.valid_prefix[k]); |
| 540 | + kh_val(elem->annotations.rpki_kh, k) = buf_p; |
| 541 | + } |
| 542 | + } |
| 543 | + } |
| 544 | + |
| 545 | + free(res_reasoned.reason); |
| 546 | + } |
| 547 | +} |
| 548 | +#endif |
0 commit comments