u_int32_t bmp_process_packet(char *bmp_packet, u_int32_t len, struct bmp_peer *bmpp) { struct bgp_misc_structs *bms; struct bgp_peer *peer; char *bmp_packet_ptr = bmp_packet; u_int32_t pkt_remaining_len, msg_len, msg_start_len; struct bmp_common_hdr *bch = NULL; if (!bmpp) return FALSE; peer = &bmpp->self; bms = bgp_select_misc_db(peer->type); if (!bms) return FALSE; if (len < sizeof(struct bmp_common_hdr)) { Log(LOG_INFO, "INFO ( %s/%s ): [%s] packet discarded: failed bmp_get_and_check_length() BMP common hdr\n", config.name, bms->log_str, peer->addr_str); return FALSE; } for (msg_start_len = pkt_remaining_len = len; pkt_remaining_len; msg_start_len = pkt_remaining_len) { if (!(bch = (struct bmp_common_hdr *) bmp_get_and_check_length(&bmp_packet_ptr, &pkt_remaining_len, sizeof(struct bmp_common_hdr)))) return msg_start_len; if (bch->version != BMP_V3) { Log(LOG_INFO, "INFO ( %s/%s ): [%s] packet discarded: BMP version != %u\n", config.name, bms->log_str, peer->addr_str, BMP_V3); return FALSE; } bmp_common_hdr_get_len(bch, &msg_len); if (pkt_remaining_len < msg_len) return msg_start_len; if (bch->type <= BMP_MSG_TYPE_MAX) { Log(LOG_DEBUG, "DEBUG ( %s/%s ): [%s] [common] type: %s (%u)\n", config.name, bms->log_str, peer->addr_str, bmp_msg_types[bch->type], bch->type); } switch (bch->type) { case BMP_MSG_ROUTE_MONITOR: bmp_process_msg_route_monitor(&bmp_packet_ptr, &pkt_remaining_len, bmpp); break; case BMP_MSG_STATS: bmp_process_msg_stats(&bmp_packet_ptr, &pkt_remaining_len, bmpp); break; case BMP_MSG_PEER_DOWN: bmp_process_msg_peer_down(&bmp_packet_ptr, &pkt_remaining_len, bmpp); break; case BMP_MSG_PEER_UP: bmp_process_msg_peer_up(&bmp_packet_ptr, &pkt_remaining_len, bmpp); break; case BMP_MSG_INIT: bmp_process_msg_init(&bmp_packet_ptr, &pkt_remaining_len, msg_len, bmpp); break; case BMP_MSG_TERM: bmp_process_msg_term(&bmp_packet_ptr, &pkt_remaining_len, msg_len, bmpp); break; case BMP_MSG_ROUTE_MIRROR: bmp_process_msg_route_mirror(&bmp_packet_ptr, &pkt_remaining_len, bmpp); break; default: Log(LOG_INFO, "INFO ( %s/%s ): [%s] packet discarded: unknown message type (%u)\n", config.name, bms->log_str, peer->addr_str, bch->type); break; } if ((msg_start_len - pkt_remaining_len) < msg_len) { /* let's jump forward: we may have been unable to parse some (sub-)element */ bmp_jump_offset(&bmp_packet_ptr, &pkt_remaining_len, (msg_len - (msg_start_len - pkt_remaining_len))); } } return FALSE; }
void bmp_process_packet(char *bmp_packet, u_int32_t len, struct bgp_peer *peer) { char *bmp_packet_ptr = bmp_packet; u_int32_t remaining_len, bmp_len; struct bmp_common_hdr *bch = NULL; remaining_len = len; if (!(bch = (struct bmp_common_hdr *) bmp_get_and_check_length(&bmp_packet_ptr, &remaining_len, sizeof(struct bmp_common_hdr)))) { Log(LOG_INFO, "INFO ( %s/core/BMP ): [Id: %s] packet discarded: failed bmp_get_and_check_length() BMP common hdr\n", config.name, peer->addr_str); return; } if (bch->version != BMP_V3) { Log(LOG_INFO, "INFO ( %s/core/BMP ): [Id: %s] packet discarded: BMP version != %u\n", config.name, peer->addr_str, BMP_V3); return; } bmp_common_hdr_get_len(bch, &bmp_len); /* if (bmp_len != len) { // Option 1: log only Log(LOG_DEBUG, "DEBUG ( %s/core/BMP ): [Id: %s] BMP common hdr len (%u) != recv() len (%u)\n", config.name, peer->addr_str, bmp_len, len); // Option 2: log and return Log(LOG_INFO, "INFO ( %s/core/BMP ): [Id: %s] packet discarded: BMP len (%u) != recv() len (%u)\n", config.name, peer->addr_str, bmp_len, len); return; } */ if (bch->type <= BMP_MSG_TYPE_MAX) { Log(LOG_DEBUG, "DEBUG ( %s/core/BMP ): [Id: %s] [common] type: %s (%u)\n", config.name, peer->addr_str, bmp_msg_types[bch->type], bch->type); } switch (bch->type) { case BMP_MSG_ROUTE: bmp_process_msg_route(&bmp_packet_ptr, &remaining_len, peer); break; case BMP_MSG_STATS: bmp_process_msg_stats(&bmp_packet_ptr, &remaining_len, peer); break; case BMP_MSG_PEER_DOWN: bmp_process_msg_peer_down(&bmp_packet_ptr, &remaining_len, peer); break; case BMP_MSG_PEER_UP: bmp_process_msg_peer_up(&bmp_packet_ptr, &remaining_len, peer); break; case BMP_MSG_INIT: bmp_process_msg_init(&bmp_packet_ptr, &remaining_len, peer); break; case BMP_MSG_TERM: bmp_process_msg_term(&bmp_packet_ptr, &remaining_len, peer); break; default: Log(LOG_INFO, "INFO ( %s/core/BMP ): [Id: %s] packet discarded: unknown message type (%u)\n", config.name, peer->addr_str, bch->type); return; } }