* Parses the update message * * \details * Reads the update message from socket and parses it. The parsed output will * be added to the DB. * * \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 [out] parsed_data Reference t
| 66 | * \return ZERO is error, otherwise a positive value indicating the number of bytes read from update message |
| 67 | */ |
| 68 | size_t UpdateMsg::parseUpdateMsg(u_char *data, size_t size, parsed_update_data &parsed_data) { |
| 69 | size_t read_size = 0; |
| 70 | u_char *bufPtr = data; |
| 71 | |
| 72 | // Clear the parsed_data |
| 73 | parsed_data.advertised.clear(); |
| 74 | parsed_data.attrs.clear(); |
| 75 | parsed_data.withdrawn.clear(); |
| 76 | |
| 77 | |
| 78 | /* --------------------------------------------------------- |
| 79 | * Parse and setup the update header struct |
| 80 | */ |
| 81 | update_bgp_hdr uHdr; |
| 82 | |
| 83 | SELF_DEBUG("%s: rtr=%s: Parsing update message of size %d", peer_addr.c_str(), router_addr.c_str(), size); |
| 84 | |
| 85 | if (size < 2) { |
| 86 | LOG_WARN("%s: rtr=%s: Update message is too short to parse header", peer_addr.c_str(), router_addr.c_str()); |
| 87 | return 0; |
| 88 | } |
| 89 | |
| 90 | // Get the withdrawn length |
| 91 | memcpy(&uHdr.withdrawn_len, bufPtr, sizeof(uHdr.withdrawn_len)); |
| 92 | bufPtr += sizeof(uHdr.withdrawn_len); read_size += sizeof(uHdr.withdrawn_len); |
| 93 | bgp::SWAP_BYTES(&uHdr.withdrawn_len); |
| 94 | |
| 95 | // Set the withdrawn data pointer |
| 96 | if ((size - read_size) < uHdr.withdrawn_len) { |
| 97 | LOG_WARN("%s: rtr=%s: Update message is too short to parse withdrawn data", peer_addr.c_str(), router_addr.c_str()); |
| 98 | return 0; |
| 99 | } |
| 100 | |
| 101 | uHdr.withdrawnPtr = bufPtr; |
| 102 | bufPtr += uHdr.withdrawn_len; read_size += uHdr.withdrawn_len; |
| 103 | |
| 104 | SELF_DEBUG("%s: rtr=%s: Withdrawn len = %hu", peer_addr.c_str(), router_addr.c_str(), uHdr.withdrawn_len ); |
| 105 | |
| 106 | // Get the attributes length |
| 107 | memcpy(&uHdr.attr_len, bufPtr, sizeof(uHdr.attr_len)); |
| 108 | bufPtr += sizeof(uHdr.attr_len); read_size += sizeof(uHdr.attr_len); |
| 109 | bgp::SWAP_BYTES(&uHdr.attr_len); |
| 110 | SELF_DEBUG("%s: rtr=%s: Attribute len = %hu", peer_addr.c_str(), router_addr.c_str(), uHdr.attr_len); |
| 111 | |
| 112 | // Set the attributes data pointer |
| 113 | if ((size - read_size) < uHdr.attr_len) { |
| 114 | LOG_WARN("%s: rtr=%s: Update message is too short to parse attr data", peer_addr.c_str(), router_addr.c_str()); |
| 115 | return 0; |
| 116 | } |
| 117 | uHdr.attrPtr = bufPtr; |
| 118 | bufPtr += uHdr.attr_len; read_size += uHdr.attr_len; |
| 119 | |
| 120 | // Set the NLRI data pointer |
| 121 | uHdr.nlriPtr = bufPtr; |
| 122 | |
| 123 | /* |
| 124 | * Check if End-Of-RIB |
| 125 | */ |
no test coverage detected