* Decode label from NLRI data * * \details * Decodes the labels from the NLRI data into labels string * * \param [in] data Pointer to the start of the label + prefixes to be parsed * \param [in] len Length of the data in bytes to be read * \param [out] labels Reference to string that will be updated with labels delimited by comm
| 409 | * |
| 410 | */ |
| 411 | inline uint16_t MPReachAttr::decodeLabel(u_char *data, uint16_t len, std::string &labels) { |
| 412 | int read_size = 0; |
| 413 | typedef union { |
| 414 | struct { |
| 415 | uint8_t ttl : 8; // TTL - not present since only 3 octets are used |
| 416 | uint8_t bos : 1; // Bottom of stack |
| 417 | uint8_t exp : 3; // EXP - not really used |
| 418 | uint32_t value : 20; // Label value |
| 419 | } decode; |
| 420 | uint32_t data; // Raw label - 3 octets only per RFC3107 |
| 421 | } mpls_label; |
| 422 | |
| 423 | mpls_label label; |
| 424 | |
| 425 | labels.clear(); |
| 426 | |
| 427 | u_char *data_ptr = data; |
| 428 | |
| 429 | // the label is 3 octets long |
| 430 | while (read_size <= len) |
| 431 | { |
| 432 | bzero(&label, sizeof(label)); |
| 433 | |
| 434 | memcpy(&label.data, data_ptr, 3); |
| 435 | bgp::SWAP_BYTES(&label.data); // change to host order |
| 436 | |
| 437 | data_ptr += 3; |
| 438 | read_size += 3; |
| 439 | |
| 440 | ostringstream convert; |
| 441 | convert << label.decode.value; |
| 442 | labels.append(convert.str()); |
| 443 | |
| 444 | //printf("label data = %x\n", label.data); |
| 445 | if (label.decode.bos == 1 or label.data == 0x80000000 /* withdrawn label as 32bits instead of 24 */ |
| 446 | or label.data == 0 /* l3vpn seems to use zero instead of rfc3107 suggested value */) { |
| 447 | break; // Reached EoS |
| 448 | |
| 449 | } else { |
| 450 | labels.append(","); |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | return read_size; |
| 455 | } |
| 456 | |
| 457 | } /* namespace bgp_msg */ |
nothing calls this directly
no test coverage detected