153f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Copyright (c) 1998-2006 The TCPDUMP project
353f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
453f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Redistribution and use in source and binary forms, with or without
553f17a9db278d33517d9888dd77848f554522a38JP Abgrall * modification, are permitted provided that: (1) source code
653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * distributions retain the above copyright notice and this paragraph
753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * in its entirety, and (2) distributions including binary code include
853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * the above copyright notice and this paragraph in its entirety in
953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * the documentation or other materials provided with the distribution.
1053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
1153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
1253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * FOR A PARTICULAR PURPOSE.
1453f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
1553f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Original code by Hannes Gredler (hannes@juniper.net)
1653f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
1753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
18e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes/* \summary: IEEE 802.1ag Connectivity Fault Management (CFM) protocols printer */
19e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
2053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#ifdef HAVE_CONFIG_H
2153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "config.h"
2253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
2353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
24e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include <netdissect-stdinc.h>
2553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
2653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include <stdio.h>
2753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
28e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include "netdissect.h"
2953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "extract.h"
3053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "ether.h"
3153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "addrtoname.h"
3253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "oui.h"
3353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "af.h"
3453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct cfm_common_header_t {
36892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t mdlevel_version;
37892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t opcode;
38892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t flags;
39892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t first_tlv_offset;
4053f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
4153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
4253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define	CFM_VERSION 0
4353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_EXTRACT_VERSION(x) (((x)&0x1f))
4453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_EXTRACT_MD_LEVEL(x) (((x)&0xe0)>>5)
4553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
4653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define	CFM_OPCODE_CCM 1
4753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define	CFM_OPCODE_LBR 2
4853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define	CFM_OPCODE_LBM 3
4953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define	CFM_OPCODE_LTR 4
5053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define	CFM_OPCODE_LTM 5
5153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
5253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok cfm_opcode_values[] = {
5353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_OPCODE_CCM, "Continouity Check Message"},
5453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_OPCODE_LBR, "Loopback Reply"},
5553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_OPCODE_LBM, "Loopback Message"},
5653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_OPCODE_LTR, "Linktrace Reply"},
5753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_OPCODE_LTM, "Linktrace Message"},
5853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
5953f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
6053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
6153f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
6253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Message Formats.
6353f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
6453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct cfm_ccm_t {
65892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t sequence[4];
66892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t ma_epi[2];
67e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    uint8_t names[48];
68e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    uint8_t itu_t_y_1731[16];
6953f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
7053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
7153f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
7253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Timer Bases for the CCM Interval field.
7353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Expressed in units of seconds.
7453f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
75e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughesstatic const float ccm_interval_base[8] = {0, 0.003333, 0.01, 0.1, 1, 10, 60, 600};
7653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CCM_INTERVAL_MIN_MULTIPLIER 3.25
7753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CCM_INTERVAL_MAX_MULTIPLIER 3.5
7853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
7953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CCM_RDI_FLAG 0x80
8053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_EXTRACT_CCM_INTERVAL(x) (((x)&0x07))
8153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
8253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CCM_MD_FORMAT_8021 0
8353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CCM_MD_FORMAT_NONE 1
8453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CCM_MD_FORMAT_DNS  2
8553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CCM_MD_FORMAT_MAC  3
8653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CCM_MD_FORMAT_CHAR 4
8753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
8853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok cfm_md_nameformat_values[] = {
8953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CCM_MD_FORMAT_8021, "IEEE 802.1"},
9053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CCM_MD_FORMAT_NONE, "No MD Name present"},
9153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CCM_MD_FORMAT_DNS, "DNS string"},
9253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CCM_MD_FORMAT_MAC, "MAC + 16Bit Integer"},
9353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CCM_MD_FORMAT_CHAR, "Character string"},
9453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
9553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
9653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
9753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CCM_MA_FORMAT_8021 0
9853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CCM_MA_FORMAT_VID  1
9953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CCM_MA_FORMAT_CHAR 2
10053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CCM_MA_FORMAT_INT  3
10153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CCM_MA_FORMAT_VPN  4
10253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
10353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok cfm_ma_nameformat_values[] = {
10453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CCM_MA_FORMAT_8021, "IEEE 802.1"},
10553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CCM_MA_FORMAT_VID, "Primary VID"},
10653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CCM_MA_FORMAT_CHAR, "Character string"},
10753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CCM_MA_FORMAT_INT, "16Bit Integer"},
10853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CCM_MA_FORMAT_VPN, "RFC2685 VPN-ID"},
10953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
11053f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
11153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
11253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct cfm_lbm_t {
113892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t transaction_id[4];
11453f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
11553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
11653f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct cfm_ltm_t {
117892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t transaction_id[4];
118892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t ttl;
119892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t original_mac[ETHER_ADDR_LEN];
120892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t target_mac[ETHER_ADDR_LEN];
12153f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
12253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
12353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok cfm_ltm_flag_values[] = {
12453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0x80, "Use Forwarding-DB only"},
12553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
12653f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
12753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
12853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct cfm_ltr_t {
129892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t transaction_id[4];
130892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t ttl;
131892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t replay_action;
13253f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
13353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
13453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok cfm_ltr_flag_values[] = {
135892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    { 0x80, "UseFDB Only"},
136892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    { 0x40, "FwdYes"},
137892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    { 0x20, "Terminal MEP"},
13853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
13953f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
14053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
14153f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok cfm_ltr_replay_action_values[] = {
14253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 1, "Exact Match"},
14353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 2, "Filtering DB"},
14453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 3, "MIP CCM DB"},
14553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
14653f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
14753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
14853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
14953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_TLV_END 0
15053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_TLV_SENDER_ID 1
15153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_TLV_PORT_STATUS 2
15253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_TLV_INTERFACE_STATUS 3
15353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_TLV_DATA 4
15453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_TLV_REPLY_INGRESS 5
15553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_TLV_REPLY_EGRESS 6
15653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_TLV_PRIVATE 31
15753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
15853f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok cfm_tlv_values[] = {
15953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_TLV_END, "End"},
16053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_TLV_SENDER_ID, "Sender ID"},
16153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_TLV_PORT_STATUS, "Port status"},
16253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_TLV_INTERFACE_STATUS, "Interface status"},
16353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_TLV_DATA, "Data"},
16453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_TLV_REPLY_INGRESS, "Reply Ingress"},
16553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_TLV_REPLY_EGRESS, "Reply Egress"},
16653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_TLV_PRIVATE, "Organization Specific"},
16753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
16853f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
16953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
17053f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
17153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * TLVs
17253f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
17353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
17453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct cfm_tlv_header_t {
175892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t type;
176892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t length[2];
17753f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
17853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
17953f17a9db278d33517d9888dd77848f554522a38JP Abgrall/* FIXME define TLV formats */
18053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
18153f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok cfm_tlv_port_status_values[] = {
18253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 1, "Blocked"},
18353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 2, "Up"},
18453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
18553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
18653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
18753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok cfm_tlv_interface_status_values[] = {
18853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 1, "Up"},
18953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 2, "Down"},
19053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 3, "Testing"},
19153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 5, "Dormant"},
19253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 6, "not present"},
19353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 7, "lower Layer down"},
19453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
19553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
19653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
19753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CHASSIS_ID_CHASSIS_COMPONENT 1
19853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CHASSIS_ID_INTERFACE_ALIAS 2
19953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CHASSIS_ID_PORT_COMPONENT 3
20053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CHASSIS_ID_MAC_ADDRESS 4
20153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CHASSIS_ID_NETWORK_ADDRESS 5
20253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CHASSIS_ID_INTERFACE_NAME 6
20353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define CFM_CHASSIS_ID_LOCAL 7
20453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
20553f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok cfm_tlv_senderid_chassisid_values[] = {
20653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, "Reserved"},
20753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CHASSIS_ID_CHASSIS_COMPONENT, "Chassis component"},
20853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CHASSIS_ID_INTERFACE_ALIAS, "Interface alias"},
20953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CHASSIS_ID_PORT_COMPONENT, "Port component"},
21053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CHASSIS_ID_MAC_ADDRESS, "MAC address"},
21153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CHASSIS_ID_NETWORK_ADDRESS, "Network address"},
21253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CHASSIS_ID_INTERFACE_NAME, "Interface name"},
21353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { CFM_CHASSIS_ID_LOCAL, "Locally assigned"},
21453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
21553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
21653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
21753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
218892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int
219e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughescfm_network_addr_print(netdissect_options *ndo,
220e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                       register const u_char *tptr)
221892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes{
222e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    u_int network_addr_type;
22353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int hexdump =  FALSE;
22453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
22553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /*
22653f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * Altough AFIs are tpically 2 octects wide,
22753f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * 802.1ab specifies that this field width
22853f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * is only once octet
22953f17a9db278d33517d9888dd77848f554522a38JP Abgrall     */
230e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    network_addr_type = *tptr;
231e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    ND_PRINT((ndo, "\n\t  Network Address Type %s (%u)",
232e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes           tok2str(af_values, "Unknown", network_addr_type),
233e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes           network_addr_type));
23453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
23553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /*
23653f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * Resolve the passed in Address.
23753f17a9db278d33517d9888dd77848f554522a38JP Abgrall     */
238e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    switch(network_addr_type) {
23953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case AFNUM_INET:
240892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr + 1)));
24153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
24253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
24353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case AFNUM_INET6:
244892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, ", %s", ip6addr_string(ndo, tptr + 1)));
24553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
24653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
24753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    default:
24853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        hexdump = TRUE;
24953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
25053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
25153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
25253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return hexdump;
25353f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
25453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
25553f17a9db278d33517d9888dd77848f554522a38JP Abgrallvoid
256892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughescfm_print(netdissect_options *ndo,
257892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes          register const u_char *pptr, register u_int length)
258892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes{
25953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    const struct cfm_common_header_t *cfm_common_header;
26053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    const struct cfm_tlv_header_t *cfm_tlv_header;
261e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const uint8_t *tptr, *tlv_ptr;
262e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const uint8_t *namesp;
263e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    u_int names_data_remaining;
264e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    uint8_t md_nameformat, md_namelength;
265e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const uint8_t *md_name;
266e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    uint8_t ma_nameformat, ma_namelength;
267e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    const uint8_t *ma_name;
26853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int hexdump, tlen, cfm_tlv_len, cfm_tlv_type, ccm_interval;
26953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
27053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
27153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    union {
27253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        const struct cfm_ccm_t *cfm_ccm;
27353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        const struct cfm_lbm_t *cfm_lbm;
27453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        const struct cfm_ltm_t *cfm_ltm;
27553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        const struct cfm_ltr_t *cfm_ltr;
27653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    } msg_ptr;
27753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
27853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    tptr=pptr;
27953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    cfm_common_header = (const struct cfm_common_header_t *)pptr;
280e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    if (length < sizeof(*cfm_common_header))
281e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        goto tooshort;
282892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_TCHECK(*cfm_common_header);
28353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
28453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /*
28553f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * Sanity checking of the header.
28653f17a9db278d33517d9888dd77848f554522a38JP Abgrall     */
28753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if (CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version) != CFM_VERSION) {
288892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "CFMv%u not supported, length %u",
289892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version), length));
29053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return;
29153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
29253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
293892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_PRINT((ndo, "CFMv%u %s, MD Level %u, length %u",
29453f17a9db278d33517d9888dd77848f554522a38JP Abgrall           CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version),
29553f17a9db278d33517d9888dd77848f554522a38JP Abgrall           tok2str(cfm_opcode_values, "unknown (%u)", cfm_common_header->opcode),
29653f17a9db278d33517d9888dd77848f554522a38JP Abgrall           CFM_EXTRACT_MD_LEVEL(cfm_common_header->mdlevel_version),
297892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes           length));
29853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
29953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /*
30053f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * In non-verbose mode just print the opcode and md-level.
30153f17a9db278d33517d9888dd77848f554522a38JP Abgrall     */
302892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    if (ndo->ndo_vflag < 1) {
30353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return;
30453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
30553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
306892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_PRINT((ndo, "\n\tFirst TLV offset %u", cfm_common_header->first_tlv_offset));
30753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
30853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    tptr += sizeof(const struct cfm_common_header_t);
30953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    tlen = length - sizeof(struct cfm_common_header_t);
31053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
311e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    /*
312e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes     * Sanity check the first TLV offset.
313e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes     */
314e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    if (cfm_common_header->first_tlv_offset > tlen) {
315e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ND_PRINT((ndo, " (too large, must be <= %u)", tlen));
316e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        return;
317e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    }
318e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
31953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    switch (cfm_common_header->opcode) {
32053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case CFM_OPCODE_CCM:
32153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        msg_ptr.cfm_ccm = (const struct cfm_ccm_t *)tptr;
322e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        if (cfm_common_header->first_tlv_offset < sizeof(*msg_ptr.cfm_ccm)) {
323e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            ND_PRINT((ndo, " (too small 1, must be >= %lu)",
324e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                     (unsigned long) sizeof(*msg_ptr.cfm_ccm)));
325e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            return;
326e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        }
327e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        if (tlen < sizeof(*msg_ptr.cfm_ccm))
328e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            goto tooshort;
329e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ND_TCHECK(*msg_ptr.cfm_ccm);
33053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
33153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ccm_interval = CFM_EXTRACT_CCM_INTERVAL(cfm_common_header->flags);
332892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, ", Flags [CCM Interval %u%s]",
33353f17a9db278d33517d9888dd77848f554522a38JP Abgrall               ccm_interval,
33453f17a9db278d33517d9888dd77848f554522a38JP Abgrall               cfm_common_header->flags & CFM_CCM_RDI_FLAG ?
335892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               ", RDI" : ""));
33653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
33753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        /*
33853f17a9db278d33517d9888dd77848f554522a38JP Abgrall         * Resolve the CCM interval field.
33953f17a9db278d33517d9888dd77848f554522a38JP Abgrall         */
34053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if (ccm_interval) {
341892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, "\n\t  CCM Interval %.3fs"
34253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                   ", min CCM Lifetime %.3fs, max CCM Lifetime %.3fs",
34353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                   ccm_interval_base[ccm_interval],
34453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                   ccm_interval_base[ccm_interval] * CCM_INTERVAL_MIN_MULTIPLIER,
345892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                   ccm_interval_base[ccm_interval] * CCM_INTERVAL_MAX_MULTIPLIER));
34653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
34753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
348892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "\n\t  Sequence Number 0x%08x, MA-End-Point-ID 0x%04x",
34953f17a9db278d33517d9888dd77848f554522a38JP Abgrall               EXTRACT_32BITS(msg_ptr.cfm_ccm->sequence),
350892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               EXTRACT_16BITS(msg_ptr.cfm_ccm->ma_epi)));
35153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
352e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        namesp = msg_ptr.cfm_ccm->names;
353e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        names_data_remaining = sizeof(msg_ptr.cfm_ccm->names);
35453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
35553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        /*
35653f17a9db278d33517d9888dd77848f554522a38JP Abgrall         * Resolve the MD fields.
35753f17a9db278d33517d9888dd77848f554522a38JP Abgrall         */
358e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        md_nameformat = *namesp;
359e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        namesp++;
360e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        names_data_remaining--;  /* We know this is != 0 */
361e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        if (md_nameformat != CFM_CCM_MD_FORMAT_NONE) {
362e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            md_namelength = *namesp;
363e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            namesp++;
364e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            names_data_remaining--; /* We know this is !=0 */
365e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            ND_PRINT((ndo, "\n\t  MD Name Format %s (%u), MD Name length %u",
366e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                   tok2str(cfm_md_nameformat_values, "Unknown",
367e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                           md_nameformat),
368e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                   md_nameformat,
369e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                   md_namelength));
370e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
371e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            /* -2 for the MA short name format and length */
372e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            if (md_namelength > names_data_remaining - 2) {
373e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                ND_PRINT((ndo, " (too large, must be <= %u)", names_data_remaining - 2));
374e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                return;
375e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            }
37653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
377e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            md_name = namesp;
378892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, "\n\t  MD Name: "));
379e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            switch (md_nameformat) {
38053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            case CFM_CCM_MD_FORMAT_DNS:
38153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            case CFM_CCM_MD_FORMAT_CHAR:
382e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                safeputs(ndo, md_name, md_namelength);
38353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                break;
38453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
38553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            case CFM_CCM_MD_FORMAT_MAC:
386e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                if (md_namelength == 6) {
387e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    ND_PRINT((ndo, "\n\t  MAC %s", etheraddr_string(ndo,
388e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                               md_name)));
389e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                } else {
390e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    ND_PRINT((ndo, "\n\t  MAC (length invalid)"));
391e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                }
39253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                break;
39353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
39453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                /* FIXME add printers for those MD formats - hexdump for now */
39553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            case CFM_CCM_MA_FORMAT_8021:
39653f17a9db278d33517d9888dd77848f554522a38JP Abgrall            default:
397e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                print_unknown_data(ndo, md_name, "\n\t    ",
398e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                                   md_namelength);
39953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
400e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            namesp += md_namelength;
401e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            names_data_remaining -= md_namelength;
402e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        } else {
403e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            ND_PRINT((ndo, "\n\t  MD Name Format %s (%u)",
404e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                   tok2str(cfm_md_nameformat_values, "Unknown",
405e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                           md_nameformat),
406e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                   md_nameformat));
40753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
40853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
40953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
41053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        /*
41153f17a9db278d33517d9888dd77848f554522a38JP Abgrall         * Resolve the MA fields.
41253f17a9db278d33517d9888dd77848f554522a38JP Abgrall         */
413e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ma_nameformat = *namesp;
414e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        namesp++;
415e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        names_data_remaining--; /* We know this is != 0 */
416e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ma_namelength = *namesp;
417e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        namesp++;
418e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        names_data_remaining--; /* We know this is != 0 */
419892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "\n\t  MA Name-Format %s (%u), MA name length %u",
42053f17a9db278d33517d9888dd77848f554522a38JP Abgrall               tok2str(cfm_ma_nameformat_values, "Unknown",
421e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                       ma_nameformat),
422e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes               ma_nameformat,
423e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes               ma_namelength));
42453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
425e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        if (ma_namelength > names_data_remaining) {
426e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            ND_PRINT((ndo, " (too large, must be <= %u)", names_data_remaining));
427e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            return;
428e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        }
429e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
430e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ma_name = namesp;
431892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "\n\t  MA Name: "));
432e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        switch (ma_nameformat) {
43353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_CCM_MA_FORMAT_CHAR:
434e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            safeputs(ndo, ma_name, ma_namelength);
43553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
43653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
43753f17a9db278d33517d9888dd77848f554522a38JP Abgrall            /* FIXME add printers for those MA formats - hexdump for now */
43853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_CCM_MA_FORMAT_8021:
43953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_CCM_MA_FORMAT_VID:
44053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_CCM_MA_FORMAT_INT:
44153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_CCM_MA_FORMAT_VPN:
44253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        default:
443e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            print_unknown_data(ndo, ma_name, "\n\t    ", ma_namelength);
44453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
44553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
44653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
44753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case CFM_OPCODE_LTM:
44853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        msg_ptr.cfm_ltm = (const struct cfm_ltm_t *)tptr;
449e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        if (cfm_common_header->first_tlv_offset < sizeof(*msg_ptr.cfm_ltm)) {
450e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            ND_PRINT((ndo, " (too small 4, must be >= %lu)",
451e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                     (unsigned long) sizeof(*msg_ptr.cfm_ltm)));
452e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            return;
453e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        }
454e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        if (tlen < sizeof(*msg_ptr.cfm_ltm))
455e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            goto tooshort;
456e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ND_TCHECK(*msg_ptr.cfm_ltm);
45753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
458892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, ", Flags [%s]",
459892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               bittok2str(cfm_ltm_flag_values, "none", cfm_common_header->flags)));
46053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
461e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ND_PRINT((ndo, "\n\t  Transaction-ID 0x%08x, ttl %u",
46253f17a9db278d33517d9888dd77848f554522a38JP Abgrall               EXTRACT_32BITS(msg_ptr.cfm_ltm->transaction_id),
463892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               msg_ptr.cfm_ltm->ttl));
46453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
465892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "\n\t  Original-MAC %s, Target-MAC %s",
466892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               etheraddr_string(ndo, msg_ptr.cfm_ltm->original_mac),
467892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               etheraddr_string(ndo, msg_ptr.cfm_ltm->target_mac)));
46853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
46953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
47053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case CFM_OPCODE_LTR:
47153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        msg_ptr.cfm_ltr = (const struct cfm_ltr_t *)tptr;
472e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        if (cfm_common_header->first_tlv_offset < sizeof(*msg_ptr.cfm_ltr)) {
473e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            ND_PRINT((ndo, " (too small 5, must be >= %lu)",
474e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                     (unsigned long) sizeof(*msg_ptr.cfm_ltr)));
475e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            return;
476e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        }
477e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        if (tlen < sizeof(*msg_ptr.cfm_ltr))
478e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            goto tooshort;
479e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ND_TCHECK(*msg_ptr.cfm_ltr);
48053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
481892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, ", Flags [%s]",
482892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               bittok2str(cfm_ltr_flag_values, "none", cfm_common_header->flags)));
48353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
484e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ND_PRINT((ndo, "\n\t  Transaction-ID 0x%08x, ttl %u",
48553f17a9db278d33517d9888dd77848f554522a38JP Abgrall               EXTRACT_32BITS(msg_ptr.cfm_ltr->transaction_id),
486892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               msg_ptr.cfm_ltr->ttl));
48753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
488892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "\n\t  Replay-Action %s (%u)",
48953f17a9db278d33517d9888dd77848f554522a38JP Abgrall               tok2str(cfm_ltr_replay_action_values,
49053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       "Unknown",
49153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       msg_ptr.cfm_ltr->replay_action),
492892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               msg_ptr.cfm_ltr->replay_action));
49353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
49453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
49553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        /*
49653f17a9db278d33517d9888dd77848f554522a38JP Abgrall         * No message decoder yet.
49753f17a9db278d33517d9888dd77848f554522a38JP Abgrall         * Hexdump everything up until the start of the TLVs
49853f17a9db278d33517d9888dd77848f554522a38JP Abgrall         */
49953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case CFM_OPCODE_LBR:
50053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case CFM_OPCODE_LBM:
50153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    default:
502e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        print_unknown_data(ndo, tptr, "\n\t  ",
503e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                           tlen -  cfm_common_header->first_tlv_offset);
50453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
50553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
50653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
50753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    tptr += cfm_common_header->first_tlv_offset;
50853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    tlen -= cfm_common_header->first_tlv_offset;
509892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
51053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    while (tlen > 0) {
51153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        cfm_tlv_header = (const struct cfm_tlv_header_t *)tptr;
51253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
51353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        /* Enough to read the tlv type ? */
514892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_TCHECK2(*tptr, 1);
51553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        cfm_tlv_type=cfm_tlv_header->type;
51653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
517e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ND_PRINT((ndo, "\n\t%s TLV (0x%02x)",
51853f17a9db278d33517d9888dd77848f554522a38JP Abgrall               tok2str(cfm_tlv_values, "Unknown", cfm_tlv_type),
519e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes               cfm_tlv_type));
520e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
521e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        if (cfm_tlv_type == CFM_TLV_END) {
522e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            /* Length is "Not present if the Type field is 0." */
52353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            return;
52453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
52553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
526e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        /* do we have the full tlv header ? */
527e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        if (tlen < sizeof(struct cfm_tlv_header_t))
528e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            goto tooshort;
529e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ND_TCHECK2(*tptr, sizeof(struct cfm_tlv_header_t));
530e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        cfm_tlv_len=EXTRACT_16BITS(&cfm_tlv_header->length);
531e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
532e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ND_PRINT((ndo, ", length %u", cfm_tlv_len));
533e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
53453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        tptr += sizeof(struct cfm_tlv_header_t);
53553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        tlen -= sizeof(struct cfm_tlv_header_t);
53653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        tlv_ptr = tptr;
53753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
538e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        /* do we have the full tlv ? */
539e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        if (tlen < cfm_tlv_len)
540e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            goto tooshort;
541e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes        ND_TCHECK2(*tptr, cfm_tlv_len);
54253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        hexdump = FALSE;
54353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
54453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        switch(cfm_tlv_type) {
54553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_TLV_PORT_STATUS:
546e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            if (cfm_tlv_len < 1) {
547e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                ND_PRINT((ndo, " (too short, must be >= 1)"));
548e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                return;
549e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            }
550892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, ", Status: %s (%u)",
55153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                   tok2str(cfm_tlv_port_status_values, "Unknown", *tptr),
552892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                   *tptr));
55353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
55453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
55553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_TLV_INTERFACE_STATUS:
556e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            if (cfm_tlv_len < 1) {
557e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                ND_PRINT((ndo, " (too short, must be >= 1)"));
558e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                return;
559e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            }
560892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, ", Status: %s (%u)",
56153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                   tok2str(cfm_tlv_interface_status_values, "Unknown", *tptr),
562892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                   *tptr));
56353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
56453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
56553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_TLV_PRIVATE:
566e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            if (cfm_tlv_len < 4) {
567e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                ND_PRINT((ndo, " (too short, must be >= 4)"));
568e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                return;
569e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            }
570892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, ", Vendor: %s (%u), Sub-Type %u",
57153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                   tok2str(oui_values,"Unknown", EXTRACT_24BITS(tptr)),
57253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                   EXTRACT_24BITS(tptr),
573892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                   *(tptr + 3)));
57453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            hexdump = TRUE;
57553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
57653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
57753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_TLV_SENDER_ID:
57853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        {
57953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            u_int chassis_id_type, chassis_id_length;
58053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            u_int mgmt_addr_length;
58153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
582e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            if (cfm_tlv_len < 1) {
583e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                ND_PRINT((ndo, " (too short, must be >= 1)"));
584e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                return;
585e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            }
586e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
58753f17a9db278d33517d9888dd77848f554522a38JP Abgrall            /*
588e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes             * Get the Chassis ID length and check it.
58953f17a9db278d33517d9888dd77848f554522a38JP Abgrall             */
59053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            chassis_id_length = *tptr;
59153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            tptr++;
59253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            tlen--;
593e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            cfm_tlv_len--;
59453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
59553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if (chassis_id_length) {
596e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                if (cfm_tlv_len < 1) {
597e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    ND_PRINT((ndo, "\n\t  (TLV too short)"));
598e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    return;
599e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                }
60053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                chassis_id_type = *tptr;
601e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                cfm_tlv_len--;
602892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, "\n\t  Chassis-ID Type %s (%u), Chassis-ID length %u",
60353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       tok2str(cfm_tlv_senderid_chassisid_values,
60453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                               "Unknown",
60553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                               chassis_id_type),
60653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       chassis_id_type,
607892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                       chassis_id_length));
60853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
609e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                if (cfm_tlv_len < chassis_id_length) {
610e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    ND_PRINT((ndo, "\n\t  (TLV too short)"));
611e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    return;
612e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                }
613e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
61453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                switch (chassis_id_type) {
61553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case CFM_CHASSIS_ID_MAC_ADDRESS:
616892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t  MAC %s", etheraddr_string(ndo, tptr + 1)));
61753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
61853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
61953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case CFM_CHASSIS_ID_NETWORK_ADDRESS:
620e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    hexdump |= cfm_network_addr_print(ndo, tptr);
62153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
62253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
62353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case CFM_CHASSIS_ID_INTERFACE_NAME: /* fall through */
62453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case CFM_CHASSIS_ID_INTERFACE_ALIAS:
62553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case CFM_CHASSIS_ID_LOCAL:
62653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case CFM_CHASSIS_ID_CHASSIS_COMPONENT:
62753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                case CFM_CHASSIS_ID_PORT_COMPONENT:
628892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    safeputs(ndo, tptr + 1, chassis_id_length);
62953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
63053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
63153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                default:
63253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    hexdump = TRUE;
63353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    break;
63453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                }
635e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                cfm_tlv_len -= chassis_id_length;
63653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
637e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                tptr += 1 + chassis_id_length;
638e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                tlen -= 1 + chassis_id_length;
639e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            }
64053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
64153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            /*
64253f17a9db278d33517d9888dd77848f554522a38JP Abgrall             * Check if there is a Management Address.
64353f17a9db278d33517d9888dd77848f554522a38JP Abgrall             */
644e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            if (cfm_tlv_len == 0) {
645e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                /* No, there isn't; we're done. */
646e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                return;
64753f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
64853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
649e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            mgmt_addr_length = *tptr;
65053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            tptr++;
65153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            tlen--;
652e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            cfm_tlv_len--;
65353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if (mgmt_addr_length) {
654e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                if (cfm_tlv_len < mgmt_addr_length) {
655e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    ND_PRINT((ndo, "\n\t  (TLV too short)"));
656e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    return;
657e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                }
658e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                cfm_tlv_len -= mgmt_addr_length;
659e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                /*
660e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                 * XXX - this is an OID; print it as such.
661e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                 */
662e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                tptr += mgmt_addr_length;
663e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                tlen -= mgmt_addr_length;
664e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
665e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                if (cfm_tlv_len < 1) {
666e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    ND_PRINT((ndo, "\n\t  (TLV too short)"));
667e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    return;
668e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                }
669e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
670e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                mgmt_addr_length = *tptr;
671e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                tptr++;
672e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                tlen--;
673e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                cfm_tlv_len--;
674e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                if (mgmt_addr_length) {
675e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    if (cfm_tlv_len < mgmt_addr_length) {
676e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                        ND_PRINT((ndo, "\n\t  (TLV too short)"));
677e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                        return;
678e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    }
679e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    cfm_tlv_len -= mgmt_addr_length;
680e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    /*
681e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                     * XXX - this is a TransportDomain; print it as such.
682e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                     */
683e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    tptr += mgmt_addr_length;
684e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                    tlen -= mgmt_addr_length;
685e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes                }
68653f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
687e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes            break;
68853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
68953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
69053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            /*
69153f17a9db278d33517d9888dd77848f554522a38JP Abgrall             * FIXME those are the defined TLVs that lack a decoder
69253f17a9db278d33517d9888dd77848f554522a38JP Abgrall             * you are welcome to contribute code ;-)
69353f17a9db278d33517d9888dd77848f554522a38JP Abgrall             */
69453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
69553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_TLV_DATA:
69653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_TLV_REPLY_INGRESS:
69753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case CFM_TLV_REPLY_EGRESS:
69853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        default:
69953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            hexdump = TRUE;
70053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
70153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
70253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        /* do we want to see an additional hexdump ? */
703892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if (hexdump || ndo->ndo_vflag > 1)
704892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            print_unknown_data(ndo, tlv_ptr, "\n\t  ", cfm_tlv_len);
70553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
70653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        tptr+=cfm_tlv_len;
70753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        tlen-=cfm_tlv_len;
70853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
70953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return;
710e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
711e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughestooshort:
712e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    ND_PRINT((ndo, "\n\t\t packet is too short"));
713e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes    return;
714e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes
71553f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
716892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
71753f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
718