* Parses NLRI info (IPv4) from the BGP message * * \details * Will get the NLRI and Withdrawn prefix entries from the data buffer. As per RFC, * this is only for v4. V6/mpls is via mpbgp attributes (RFC4760) * * \param [in] data Pointer to the start of the prefixes to be parsed * \param [in] len Length of the data in bytes to be read * \param [out] prefixes
| 171 | * \param [out] prefixes Reference to a list<prefix_tuple> to be updated with entries |
| 172 | */ |
| 173 | void UpdateMsg::parseNlriData_v4(u_char *data, uint16_t len, std::list<bgp::prefix_tuple> &prefixes) { |
| 174 | u_char ipv4_raw[4]; |
| 175 | char ipv4_char[16]; |
| 176 | u_char addr_bytes; |
| 177 | |
| 178 | bgp::prefix_tuple tuple; |
| 179 | |
| 180 | if (len <= 0 or data == NULL) |
| 181 | return; |
| 182 | |
| 183 | // TODO: Can extend this to support multicast, but right now we set it to unicast v4 |
| 184 | // Set the type for all to be unicast V4 |
| 185 | tuple.type = bgp::PREFIX_UNICAST_V4; |
| 186 | tuple.isIPv4 = true; |
| 187 | |
| 188 | // Loop through all prefixes |
| 189 | for (size_t read_size=0; read_size < len; read_size++) { |
| 190 | |
| 191 | bzero(ipv4_raw, sizeof(ipv4_raw)); |
| 192 | bzero(tuple.prefix_bin, sizeof(tuple.prefix_bin)); |
| 193 | |
| 194 | // Parse add-paths if enabled |
| 195 | if (peer_info->add_path_capability.isAddPathEnabled(bgp::BGP_AFI_IPV4, bgp::BGP_SAFI_UNICAST) |
| 196 | and (len - read_size) >= 4) { |
| 197 | memcpy(&tuple.path_id, data, 4); |
| 198 | bgp::SWAP_BYTES(&tuple.path_id); |
| 199 | data += 4; read_size += 4; |
| 200 | } else |
| 201 | tuple.path_id = 0; |
| 202 | |
| 203 | // set the address in bits length |
| 204 | tuple.len = *data++; |
| 205 | |
| 206 | // Figure out how many bytes the bits requires |
| 207 | addr_bytes = tuple.len / 8; |
| 208 | if (tuple.len % 8) |
| 209 | ++addr_bytes; |
| 210 | |
| 211 | SELF_DEBUG("%s: rtr=%s: Reading NLRI data prefix bits=%d bytes=%d", peer_addr.c_str(), |
| 212 | router_addr.c_str(), tuple.len, addr_bytes); |
| 213 | |
| 214 | if (addr_bytes <= 4) { |
| 215 | memcpy(ipv4_raw, data, addr_bytes); |
| 216 | read_size += addr_bytes; |
| 217 | data += addr_bytes; |
| 218 | |
| 219 | // Convert the IP to string printed format |
| 220 | inet_ntop(AF_INET, ipv4_raw, ipv4_char, sizeof(ipv4_char)); |
| 221 | tuple.prefix.assign(ipv4_char); |
| 222 | SELF_DEBUG("%s: rtr=%s: Adding prefix %s len %d", peer_addr.c_str(), |
| 223 | router_addr.c_str(), ipv4_char, tuple.len); |
| 224 | |
| 225 | // set the raw/binary address |
| 226 | memcpy(tuple.prefix_bin, ipv4_raw, sizeof(ipv4_raw)); |
| 227 | |
| 228 | // Add tuple to prefix list |
| 229 | prefixes.push_back(tuple); |
| 230 |
nothing calls this directly
no test coverage detected