* Parses an open message * * \details * Reads the open message from buffer. The parsed data will be * returned via the out params. * * \param [in] data Pointer to raw bgp payload data, starting at the notification message * \param [in] size Size of the data available to read; prevent overrun when reading * \param [in] openMessageIsSent If open
| 56 | * \return ZERO is error, otherwise a positive value indicating the number of bytes read for the open message |
| 57 | */ |
| 58 | size_t OpenMsg::parseOpenMsg(u_char *data, size_t size, bool openMessageIsSent, uint32_t &asn, uint16_t &holdTime, |
| 59 | std::string &bgp_id, std::list<std::string> &capabilities) { |
| 60 | char bgp_id_char[16]; |
| 61 | size_t read_size = 0; |
| 62 | u_char *bufPtr = data; |
| 63 | open_bgp_hdr open_hdr = {0}; |
| 64 | capabilities.clear(); |
| 65 | |
| 66 | /* |
| 67 | * Make sure available size is large enough for an open message |
| 68 | */ |
| 69 | if (size < sizeof(open_hdr)) { |
| 70 | LOG_WARN("%s: Cloud not read open message due to buffer having less bytes than open message size", peer_addr.c_str()); |
| 71 | return 0; |
| 72 | } |
| 73 | |
| 74 | memcpy(&open_hdr, bufPtr, sizeof(open_hdr)); |
| 75 | read_size = sizeof(open_hdr); |
| 76 | bufPtr += read_size; // Move pointer past the open header |
| 77 | |
| 78 | // Change to host order |
| 79 | bgp::SWAP_BYTES(&open_hdr.hold); |
| 80 | bgp::SWAP_BYTES(&open_hdr.asn); |
| 81 | |
| 82 | // Update the output params |
| 83 | holdTime = open_hdr.hold; |
| 84 | asn = open_hdr.asn; |
| 85 | |
| 86 | inet_ntop(AF_INET, &open_hdr.bgp_id, bgp_id_char, sizeof(bgp_id_char)); |
| 87 | bgp_id.assign(bgp_id_char); |
| 88 | |
| 89 | SELF_DEBUG("%s: Open message:ver=%d hold=%u asn=%hu bgp_id=%s params_len=%d", peer_addr.c_str(), |
| 90 | open_hdr.ver, open_hdr.hold, open_hdr.asn, bgp_id.c_str(), open_hdr.param_len); |
| 91 | |
| 92 | /* |
| 93 | * Make sure the buffer contains the rest of the open message, but allow a zero length in case the |
| 94 | * data is missing on purpose (router implementation) |
| 95 | */ |
| 96 | if (open_hdr.param_len == 0) { |
| 97 | LOG_WARN("%s: Capabilities in open message is ZERO/empty, this is abnormal and likely a router implementation issue.", peer_addr.c_str()); |
| 98 | return read_size; |
| 99 | } |
| 100 | |
| 101 | else if (open_hdr.param_len > (size - read_size)) { |
| 102 | LOG_WARN("%s: Capabilities in open message are truncated, attempting parse what's there; param_len %d > bgp msg bytes remaining of %d", |
| 103 | peer_addr.c_str(), open_hdr.param_len, (size - read_size)); |
| 104 | |
| 105 | // Parse as many capabilities as possible |
| 106 | parseCapabilities(bufPtr, (size - read_size), openMessageIsSent, asn, capabilities); |
| 107 | |
| 108 | read_size += (size - read_size); |
| 109 | |
| 110 | } else { |
| 111 | |
| 112 | if (!parseCapabilities(bufPtr, open_hdr.param_len, openMessageIsSent, asn, capabilities)) { |
| 113 | LOG_WARN("%s: Could not read capabilities correctly in buffer, message is invalid.", peer_addr.c_str()); |
| 114 | return 0; |
| 115 | } |
no test coverage detected