?? print-cfm.c
字號:
CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version), tok2str(cfm_opcode_values, "unknown (%u)", cfm_common_header->opcode), CFM_EXTRACT_MD_LEVEL(cfm_common_header->mdlevel_version), length); /* * In non-verbose mode just print the opcode and md-level. */ if (vflag < 1) { return; } printf("\n\tFirst TLV offset %u", cfm_common_header->first_tlv_offset); tptr += sizeof(const struct cfm_common_header_t); tlen = length - sizeof(struct cfm_common_header_t); switch (cfm_common_header->opcode) { case CFM_OPCODE_CCM: msg_ptr.cfm_ccm = (const struct cfm_ccm_t *)tptr; ccm_interval = CFM_EXTRACT_CCM_INTERVAL(cfm_common_header->flags); printf(", Flags [CCM Interval %u%s]", ccm_interval, cfm_common_header->flags & CFM_CCM_RDI_FLAG ? ", RDI" : ""); /* * Resolve the CCM interval field. */ if (ccm_interval) { printf("\n\t CCM Interval %.3fs" ", min CCM Lifetime %.3fs, max CCM Lifetime %.3fs", ccm_interval_base[ccm_interval], ccm_interval_base[ccm_interval] * CCM_INTERVAL_MIN_MULTIPLIER, ccm_interval_base[ccm_interval] * CCM_INTERVAL_MAX_MULTIPLIER); } printf("\n\t Sequence Number 0x%08x, MA-End-Point-ID 0x%04x", EXTRACT_32BITS(msg_ptr.cfm_ccm->sequence), EXTRACT_16BITS(msg_ptr.cfm_ccm->ma_epi)); /* * Resolve the MD fields. */ printf("\n\t MD Name Format %s (%u), MD Name length %u", tok2str(cfm_md_nameformat_values, "Unknown", msg_ptr.cfm_ccm->md_nameformat), msg_ptr.cfm_ccm->md_nameformat, msg_ptr.cfm_ccm->md_namelength); if (msg_ptr.cfm_ccm->md_nameformat != CFM_CCM_MD_FORMAT_NONE) { printf("\n\t MD Name: "); switch (msg_ptr.cfm_ccm->md_nameformat) { case CFM_CCM_MD_FORMAT_DNS: case CFM_CCM_MD_FORMAT_CHAR: safeputs((const char *)msg_ptr.cfm_ccm->md_name, msg_ptr.cfm_ccm->md_namelength); break; case CFM_CCM_MD_FORMAT_MAC: printf("\n\t MAC %s", etheraddr_string( msg_ptr.cfm_ccm->md_name)); break; /* FIXME add printers for those MD formats - hexdump for now */ case CFM_CCM_MA_FORMAT_8021: default: print_unknown_data(msg_ptr.cfm_ccm->md_name, "\n\t ", msg_ptr.cfm_ccm->md_namelength); } } /* * Resolve the MA fields. */ ma_nameformat = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength; ma_namelength = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength + 1; ma_name = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength + 2; printf("\n\t MA Name-Format %s (%u), MA name length %u", tok2str(cfm_ma_nameformat_values, "Unknown", *ma_nameformat), *ma_nameformat, *ma_namelength); printf("\n\t MA Name: "); switch (*ma_nameformat) { case CFM_CCM_MA_FORMAT_CHAR: safeputs((const char *)ma_name, *ma_namelength); break; /* FIXME add printers for those MA formats - hexdump for now */ case CFM_CCM_MA_FORMAT_8021: case CFM_CCM_MA_FORMAT_VID: case CFM_CCM_MA_FORMAT_INT: case CFM_CCM_MA_FORMAT_VPN: default: print_unknown_data(ma_name, "\n\t ", *ma_namelength); } break; case CFM_OPCODE_LTM: printf(", Flags [%s]", bittok2str(cfm_ltm_flag_values, "none", cfm_common_header->flags)); printf("\n\t Transaction-ID 0x%08x, Egress-ID %s, ttl %u", EXTRACT_32BITS(msg_ptr.cfm_ltm->transaction_id), cfm_egress_id_string(msg_ptr.cfm_ltm->egress_id), msg_ptr.cfm_ltm->ttl); printf("\n\t Original-MAC %s, Target-MAC %s", etheraddr_string(msg_ptr.cfm_ltm->original_mac), etheraddr_string(msg_ptr.cfm_ltm->target_mac)); break; case CFM_OPCODE_LTR: printf(", Flags [%s]", bittok2str(cfm_ltr_flag_values, "none", cfm_common_header->flags)); printf("\n\t Transaction-ID 0x%08x, Last-Egress-ID %s", EXTRACT_32BITS(msg_ptr.cfm_ltr->transaction_id), cfm_egress_id_string(msg_ptr.cfm_ltr->last_egress_id)); printf("\n\t Next-Egress-ID %s, ttl %u", cfm_egress_id_string(msg_ptr.cfm_ltr->next_egress_id), msg_ptr.cfm_ltr->ttl); printf("\n\t Replay-Action %s (%u)", tok2str(cfm_ltr_replay_action_values, "Unknown", msg_ptr.cfm_ltr->replay_action), msg_ptr.cfm_ltr->replay_action); break; /* * No message decoder yet. * Hexdump everything up until the start of the TLVs */ case CFM_OPCODE_LBR: case CFM_OPCODE_LBM: default: if (tlen > cfm_common_header->first_tlv_offset) { print_unknown_data(tptr, "\n\t ", tlen - cfm_common_header->first_tlv_offset); } break; } /* * Sanity check for not walking off. */ if (tlen <= cfm_common_header->first_tlv_offset) { return; } tptr += cfm_common_header->first_tlv_offset; tlen -= cfm_common_header->first_tlv_offset; while (tlen > 0) { cfm_tlv_header = (const struct cfm_tlv_header_t *)tptr; /* Enough to read the tlv type ? */ TCHECK2(*tptr, 1); cfm_tlv_type=cfm_tlv_header->type; if (cfm_tlv_type != CFM_TLV_END) { /* did we capture enough for fully decoding the object header ? */ TCHECK2(*tptr, sizeof(struct cfm_tlv_header_t)); cfm_tlv_len=EXTRACT_16BITS(&cfm_tlv_header->length); } else { cfm_tlv_len = 0; } printf("\n\t%s TLV (0x%02x), length %u", tok2str(cfm_tlv_values, "Unknown", cfm_tlv_type), cfm_tlv_type, cfm_tlv_len); /* sanity check for not walking off and infinite loop check. */ if ((cfm_tlv_type != CFM_TLV_END) && ((cfm_tlv_len + sizeof(struct cfm_tlv_header_t) > tlen) || (!cfm_tlv_len))) { print_unknown_data(tptr,"\n\t ",tlen); return; } tptr += sizeof(struct cfm_tlv_header_t); tlen -= sizeof(struct cfm_tlv_header_t); tlv_ptr = tptr; /* did we capture enough for fully decoding the object ? */ if (cfm_tlv_type != CFM_TLV_END) { TCHECK2(*tptr, cfm_tlv_len); } hexdump = FALSE; switch(cfm_tlv_type) { case CFM_TLV_END: /* we are done - bail out */ return; case CFM_TLV_PORT_STATUS: printf(", Status: %s (%u)", tok2str(cfm_tlv_port_status_values, "Unknown", *tptr), *tptr); break; case CFM_TLV_INTERFACE_STATUS: printf(", Status: %s (%u)", tok2str(cfm_tlv_interface_status_values, "Unknown", *tptr), *tptr); break; case CFM_TLV_PRIVATE: printf(", Vendor: %s (%u), Sub-Type %u", tok2str(oui_values,"Unknown", EXTRACT_24BITS(tptr)), EXTRACT_24BITS(tptr), *(tptr+3)); hexdump = TRUE; break; case CFM_TLV_SENDER_ID: { u_int chassis_id_type, chassis_id_length; u_int mgmt_addr_length; /* * Check if there is a Chassis-ID. */ chassis_id_length = *tptr; if (chassis_id_length > tlen) { hexdump = TRUE; break; } tptr++; tlen--; if (chassis_id_length) { chassis_id_type = *tptr; printf("\n\t Chassis-ID Type %s (%u), Chassis-ID length %u", tok2str(cfm_tlv_senderid_chassisid_values, "Unknown", chassis_id_type), chassis_id_type, chassis_id_length); switch (chassis_id_type) { case CFM_CHASSIS_ID_MAC_ADDRESS: printf("\n\t MAC %s", etheraddr_string(tptr+1)); break; case CFM_CHASSIS_ID_NETWORK_ADDRESS: hexdump |= cfm_mgmt_addr_print(tptr); break; case CFM_CHASSIS_ID_INTERFACE_NAME: /* fall through */ case CFM_CHASSIS_ID_INTERFACE_ALIAS: case CFM_CHASSIS_ID_LOCAL: case CFM_CHASSIS_ID_CHASSIS_COMPONENT: case CFM_CHASSIS_ID_PORT_COMPONENT: safeputs((const char *)tptr+1, chassis_id_length); break; default: hexdump = TRUE; break; } } tptr += chassis_id_length; tlen -= chassis_id_length; /* * Check if there is a Management Address. */ mgmt_addr_length = *tptr; if (mgmt_addr_length > tlen) { hexdump = TRUE; break; } tptr++; tlen--; if (mgmt_addr_length) { hexdump |= cfm_mgmt_addr_print(tptr); } tptr += mgmt_addr_length; tlen -= mgmt_addr_length; } break; /* * FIXME those are the defined TLVs that lack a decoder * you are welcome to contribute code ;-) */ case CFM_TLV_DATA: case CFM_TLV_REPLY_INGRESS: case CFM_TLV_REPLY_EGRESS: default: hexdump = TRUE; break; } /* do we want to see an additional hexdump ? */ if (hexdump || vflag > 1) print_unknown_data(tlv_ptr, "\n\t ", cfm_tlv_len); tptr+=cfm_tlv_len; tlen-=cfm_tlv_len; } return;trunc: printf("\n\t\t packet exceeded snapshot");}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -