* handle the termination message, router entry will be updated * * \param [in] sock Socket to read the term message from * \param [in/out] r_entry Already defined router entry reference (will be updated) */
| 926 | * \param [in/out] r_entry Already defined router entry reference (will be updated) |
| 927 | */ |
| 928 | void parseBMP::handleTermMsg(int sock, MsgBusInterface::obj_router &r_entry) { |
| 929 | term_msg_v3 termMsg; |
| 930 | char infoBuf[sizeof(r_entry.term_data)]; |
| 931 | int infoLen; |
| 932 | |
| 933 | // Buffer the init message for parsing |
| 934 | bufferBMPMessage(sock); |
| 935 | |
| 936 | u_char *bufPtr = bmp_data; |
| 937 | |
| 938 | /* |
| 939 | * Loop through the term message (in buffer) to parse each TLV |
| 940 | */ |
| 941 | for (int i=0; i < bmp_data_len; i += BMP_TERM_MSG_LEN) { |
| 942 | memcpy(&termMsg, bufPtr, BMP_TERM_MSG_LEN); |
| 943 | termMsg.info = NULL; |
| 944 | bgp::SWAP_BYTES(&termMsg.len); |
| 945 | bgp::SWAP_BYTES(&termMsg.type); |
| 946 | |
| 947 | bufPtr += BMP_TERM_MSG_LEN; // Move pointer past the info header |
| 948 | |
| 949 | LOG_INFO("Term message type %hu and length %hu parsed", termMsg.type, termMsg.len); |
| 950 | |
| 951 | if (termMsg.len > 0) { |
| 952 | infoLen = sizeof(infoBuf) < termMsg.len ? sizeof(infoBuf) : termMsg.len; |
| 953 | bzero(infoBuf, sizeof(infoBuf)); |
| 954 | memcpy(infoBuf, bufPtr, infoLen); |
| 955 | bufPtr += infoLen; // Move pointer past the info data |
| 956 | i += infoLen; // Update the counter past the info data |
| 957 | |
| 958 | termMsg.info = infoBuf; |
| 959 | |
| 960 | LOG_INFO("Term message type %hu = %s", termMsg.type, termMsg.info); |
| 961 | } |
| 962 | |
| 963 | /* |
| 964 | * Save the data based on info type |
| 965 | */ |
| 966 | switch (termMsg.type) { |
| 967 | case TERM_TYPE_FREE_FORM_STRING : |
| 968 | memcpy(r_entry.term_data, termMsg.info, termMsg.len); |
| 969 | break; |
| 970 | |
| 971 | case TERM_TYPE_REASON : |
| 972 | { |
| 973 | // Get the term reason code from info data (first 2 bytes) |
| 974 | uint16_t term_reason; |
| 975 | memcpy(&term_reason, termMsg.info, 2); |
| 976 | bgp::SWAP_BYTES(&term_reason); |
| 977 | r_entry.term_reason_code = term_reason; |
| 978 | |
| 979 | switch (term_reason) { |
| 980 | case TERM_REASON_ADMIN_CLOSE : |
| 981 | LOG_INFO("%s BMP session closed by remote administratively", r_entry.ip_addr); |
| 982 | snprintf(r_entry.term_reason_text, sizeof(r_entry.term_reason_text), |
| 983 | "Remote session administratively closed"); |
| 984 | break; |
| 985 |
no test coverage detected