10f74e101Schristos /* 20f74e101Schristos * Redistribution and use in source and binary forms, with or without 30f74e101Schristos * modification, are permitted provided that: (1) source code 40f74e101Schristos * distributions retain the above copyright notice and this paragraph 50f74e101Schristos * in its entirety, and (2) distributions including binary code include 60f74e101Schristos * the above copyright notice and this paragraph in its entirety in 70f74e101Schristos * the documentation or other materials provided with the distribution. 80f74e101Schristos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 90f74e101Schristos * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 100f74e101Schristos * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 110f74e101Schristos * FOR A PARTICULAR PURPOSE. 120f74e101Schristos * 1372c96ff3Schristos * Original code by Hannes Gredler (hannes@gredler.at) 140f74e101Schristos */ 150f74e101Schristos 1611b3aaa1Schristos #include <sys/cdefs.h> 170f74e101Schristos #ifndef lint 18*26ba0b50Schristos __RCSID("$NetBSD: print-bfd.c,v 1.10 2024/09/02 16:15:30 christos Exp $"); 190f74e101Schristos #endif 200f74e101Schristos 21dc860a36Sspz /* \summary: Bidirectional Forwarding Detection (BFD) printer */ 22dc860a36Sspz 23817e9a7eSchristos /* 24817e9a7eSchristos * specification: draft-ietf-bfd-base-01 for version 0, 25817e9a7eSchristos * RFC 5880 for version 1, and RFC 5881 26817e9a7eSchristos */ 27dc860a36Sspz 28c74ad251Schristos #include <config.h> 290f74e101Schristos 30c74ad251Schristos #include "netdissect-stdinc.h" 310f74e101Schristos 32c74ad251Schristos #define ND_LONGJMP_FROM_TCHECK 33fdccd7e4Schristos #include "netdissect.h" 340f74e101Schristos #include "extract.h" 350f74e101Schristos 360f74e101Schristos #include "udp.h" 370f74e101Schristos 380f74e101Schristos /* 39817e9a7eSchristos * Control packet, BFDv0, draft-ietf-bfd-base-01 400f74e101Schristos * 410f74e101Schristos * 0 1 2 3 420f74e101Schristos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 430f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 44817e9a7eSchristos * |Vers | Diag |H|D|P|F|C|A|Rsv| Detect Mult | Length | 450f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 460f74e101Schristos * | My Discriminator | 470f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 480f74e101Schristos * | Your Discriminator | 490f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 500f74e101Schristos * | Desired Min TX Interval | 510f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 520f74e101Schristos * | Required Min RX Interval | 530f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 540f74e101Schristos * | Required Min Echo RX Interval | 550f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 560f74e101Schristos */ 570f74e101Schristos 580f74e101Schristos /* 59dc860a36Sspz * Control packet, BFDv1, RFC 5880 600f74e101Schristos * 610f74e101Schristos * 0 1 2 3 620f74e101Schristos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 630f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 64dc860a36Sspz * |Vers | Diag |Sta|P|F|C|A|D|M| Detect Mult | Length | 650f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 660f74e101Schristos * | My Discriminator | 670f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 680f74e101Schristos * | Your Discriminator | 690f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 700f74e101Schristos * | Desired Min TX Interval | 710f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 720f74e101Schristos * | Required Min RX Interval | 730f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 740f74e101Schristos * | Required Min Echo RX Interval | 750f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 760f74e101Schristos */ 770f74e101Schristos 780f74e101Schristos struct bfd_header_t { 79c74ad251Schristos nd_uint8_t version_diag; 80c74ad251Schristos nd_uint8_t flags; 81c74ad251Schristos nd_uint8_t detect_time_multiplier; 82c74ad251Schristos nd_uint8_t length; 83c74ad251Schristos nd_uint32_t my_discriminator; 84c74ad251Schristos nd_uint32_t your_discriminator; 85c74ad251Schristos nd_uint32_t desired_min_tx_interval; 86c74ad251Schristos nd_uint32_t required_min_rx_interval; 87c74ad251Schristos nd_uint32_t required_min_echo_interval; 880f74e101Schristos }; 890f74e101Schristos 900f74e101Schristos /* 910f74e101Schristos * An optional Authentication Header may be present 920f74e101Schristos * 930f74e101Schristos * 0 1 2 3 940f74e101Schristos * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 950f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 960f74e101Schristos * | Auth Type | Auth Len | Authentication Data... | 970f74e101Schristos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 980f74e101Schristos */ 990f74e101Schristos 1000f74e101Schristos struct bfd_auth_header_t { 101c74ad251Schristos nd_uint8_t auth_type; 102c74ad251Schristos nd_uint8_t auth_len; 103c74ad251Schristos nd_uint8_t auth_data; 104c74ad251Schristos nd_uint8_t dummy; /* minimum 4 bytes */ 105dc860a36Sspz }; 106dc860a36Sspz 107dc860a36Sspz enum auth_type { 108dc860a36Sspz AUTH_PASSWORD = 1, 109dc860a36Sspz AUTH_MD5 = 2, 110dc860a36Sspz AUTH_MET_MD5 = 3, 111dc860a36Sspz AUTH_SHA1 = 4, 112dc860a36Sspz AUTH_MET_SHA1 = 5 1130f74e101Schristos }; 1140f74e101Schristos 1150f74e101Schristos static const struct tok bfd_v1_authentication_values[] = { 116dc860a36Sspz { AUTH_PASSWORD, "Simple Password" }, 117dc860a36Sspz { AUTH_MD5, "Keyed MD5" }, 118dc860a36Sspz { AUTH_MET_MD5, "Meticulous Keyed MD5" }, 119dc860a36Sspz { AUTH_SHA1, "Keyed SHA1" }, 120dc860a36Sspz { AUTH_MET_SHA1, "Meticulous Keyed SHA1" }, 1210f74e101Schristos { 0, NULL } 1220f74e101Schristos }; 1230f74e101Schristos 124dc860a36Sspz enum auth_length { 125dc860a36Sspz AUTH_PASSWORD_FIELD_MIN_LEN = 4, /* header + password min: 3 + 1 */ 126dc860a36Sspz AUTH_PASSWORD_FIELD_MAX_LEN = 19, /* header + password max: 3 + 16 */ 127dc860a36Sspz AUTH_MD5_FIELD_LEN = 24, 128dc860a36Sspz AUTH_MD5_HASH_LEN = 16, 129dc860a36Sspz AUTH_SHA1_FIELD_LEN = 28, 130dc860a36Sspz AUTH_SHA1_HASH_LEN = 20 131dc860a36Sspz }; 132dc860a36Sspz 1330f74e101Schristos #define BFD_EXTRACT_VERSION(x) (((x)&0xe0)>>5) 1340f74e101Schristos #define BFD_EXTRACT_DIAG(x) ((x)&0x1f) 1350f74e101Schristos 1360f74e101Schristos static const struct tok bfd_diag_values[] = { 1370f74e101Schristos { 0, "No Diagnostic" }, 1380f74e101Schristos { 1, "Control Detection Time Expired" }, 1390f74e101Schristos { 2, "Echo Function Failed" }, 1400f74e101Schristos { 3, "Neighbor Signaled Session Down" }, 1410f74e101Schristos { 4, "Forwarding Plane Reset" }, 1420f74e101Schristos { 5, "Path Down" }, 1430f74e101Schristos { 6, "Concatenated Path Down" }, 1440f74e101Schristos { 7, "Administratively Down" }, 1450f74e101Schristos { 8, "Reverse Concatenated Path Down" }, 1460f74e101Schristos { 0, NULL } 1470f74e101Schristos }; 1480f74e101Schristos 149c74ad251Schristos static const struct tok bfd_port_values[] = { 150c74ad251Schristos { BFD_CONTROL_PORT, "Control" }, 151c74ad251Schristos { BFD_MULTIHOP_PORT, "Multihop" }, 152c74ad251Schristos { BFD_LAG_PORT, "Lag" }, 153c74ad251Schristos { 0, NULL } 154c74ad251Schristos }; 155c74ad251Schristos 156817e9a7eSchristos #define BFD_FLAG_AUTH 0x04 157817e9a7eSchristos 1580f74e101Schristos static const struct tok bfd_v0_flag_values[] = { 1590f74e101Schristos { 0x80, "I Hear You" }, 1600f74e101Schristos { 0x40, "Demand" }, 1610f74e101Schristos { 0x20, "Poll" }, 1620f74e101Schristos { 0x10, "Final" }, 163817e9a7eSchristos { 0x08, "Control Plane Independent" }, 164817e9a7eSchristos { BFD_FLAG_AUTH, "Authentication Present" }, 1650f74e101Schristos { 0x02, "Reserved" }, 1660f74e101Schristos { 0x01, "Reserved" }, 1670f74e101Schristos { 0, NULL } 1680f74e101Schristos }; 1690f74e101Schristos 1700f74e101Schristos static const struct tok bfd_v1_flag_values[] = { 1710f74e101Schristos { 0x20, "Poll" }, 1720f74e101Schristos { 0x10, "Final" }, 1730f74e101Schristos { 0x08, "Control Plane Independent" }, 1740f74e101Schristos { BFD_FLAG_AUTH, "Authentication Present" }, 1750f74e101Schristos { 0x02, "Demand" }, 176dc860a36Sspz { 0x01, "Multipoint" }, 1770f74e101Schristos { 0, NULL } 1780f74e101Schristos }; 1790f74e101Schristos 1800f74e101Schristos static const struct tok bfd_v1_state_values[] = { 1810f74e101Schristos { 0, "AdminDown" }, 1820f74e101Schristos { 1, "Down" }, 1830f74e101Schristos { 2, "Init" }, 1840f74e101Schristos { 3, "Up" }, 1850f74e101Schristos { 0, NULL } 1860f74e101Schristos }; 1870f74e101Schristos 188c74ad251Schristos static void 189c74ad251Schristos auth_print(netdissect_options *ndo, const u_char *pptr) 190dc860a36Sspz { 191dc860a36Sspz const struct bfd_auth_header_t *bfd_auth_header; 192c74ad251Schristos uint8_t auth_type, auth_len; 193dc860a36Sspz int i; 194dc860a36Sspz 195c74ad251Schristos pptr += sizeof (struct bfd_header_t); 196dc860a36Sspz bfd_auth_header = (const struct bfd_auth_header_t *)pptr; 197c74ad251Schristos ND_TCHECK_SIZE(bfd_auth_header); 198c74ad251Schristos auth_type = GET_U_1(bfd_auth_header->auth_type); 199c74ad251Schristos auth_len = GET_U_1(bfd_auth_header->auth_len); 200c74ad251Schristos ND_PRINT("\n\tAuthentication: %s (%u), length: %u", 201c74ad251Schristos tok2str(bfd_v1_authentication_values,"Unknown",auth_type), 202c74ad251Schristos auth_type, auth_len); 203dc860a36Sspz pptr += 2; 204c74ad251Schristos ND_PRINT("\n\t Auth Key ID: %u", GET_U_1(pptr)); 205dc860a36Sspz 206c74ad251Schristos switch(auth_type) { 207dc860a36Sspz case AUTH_PASSWORD: 208dc860a36Sspz /* 209dc860a36Sspz * Simple Password Authentication Section Format 210dc860a36Sspz * 211dc860a36Sspz * 0 1 2 3 212dc860a36Sspz * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 213dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 214dc860a36Sspz * | Auth Type | Auth Len | Auth Key ID | Password... | 215dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 216dc860a36Sspz * | ... | 217dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 218dc860a36Sspz */ 219c74ad251Schristos if (auth_len < AUTH_PASSWORD_FIELD_MIN_LEN || 220c74ad251Schristos auth_len > AUTH_PASSWORD_FIELD_MAX_LEN) { 221c74ad251Schristos ND_PRINT("[invalid length %u]", 222c74ad251Schristos auth_len); 223dc860a36Sspz break; 224dc860a36Sspz } 225dc860a36Sspz pptr++; 226c74ad251Schristos ND_PRINT(", Password: "); 227dc860a36Sspz /* the length is equal to the password length plus three */ 228c74ad251Schristos (void)nd_printn(ndo, pptr, auth_len - 3, NULL); 229dc860a36Sspz break; 230dc860a36Sspz case AUTH_MD5: 231dc860a36Sspz case AUTH_MET_MD5: 232dc860a36Sspz /* 233dc860a36Sspz * Keyed MD5 and Meticulous Keyed MD5 Authentication Section Format 234dc860a36Sspz * 235dc860a36Sspz * 0 1 2 3 236dc860a36Sspz * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 237dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 238dc860a36Sspz * | Auth Type | Auth Len | Auth Key ID | Reserved | 239dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 240dc860a36Sspz * | Sequence Number | 241dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 242dc860a36Sspz * | Auth Key/Digest... | 243dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 244dc860a36Sspz * | ... | 245dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 246dc860a36Sspz */ 247c74ad251Schristos if (auth_len != AUTH_MD5_FIELD_LEN) { 248c74ad251Schristos ND_PRINT("[invalid length %u]", 249c74ad251Schristos auth_len); 250dc860a36Sspz break; 251dc860a36Sspz } 252dc860a36Sspz pptr += 2; 253c74ad251Schristos ND_PRINT(", Sequence Number: 0x%08x", GET_BE_U_4(pptr)); 254dc860a36Sspz pptr += 4; 255c74ad251Schristos ND_TCHECK_LEN(pptr, AUTH_MD5_HASH_LEN); 256c74ad251Schristos ND_PRINT("\n\t Digest: "); 257dc860a36Sspz for(i = 0; i < AUTH_MD5_HASH_LEN; i++) 258c74ad251Schristos ND_PRINT("%02x", GET_U_1(pptr + i)); 259dc860a36Sspz break; 260dc860a36Sspz case AUTH_SHA1: 261dc860a36Sspz case AUTH_MET_SHA1: 262dc860a36Sspz /* 263dc860a36Sspz * Keyed SHA1 and Meticulous Keyed SHA1 Authentication Section Format 264dc860a36Sspz * 265dc860a36Sspz * 0 1 2 3 266dc860a36Sspz * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 267dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 268dc860a36Sspz * | Auth Type | Auth Len | Auth Key ID | Reserved | 269dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 270dc860a36Sspz * | Sequence Number | 271dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 272dc860a36Sspz * | Auth Key/Hash... | 273dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 274dc860a36Sspz * | ... | 275dc860a36Sspz * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 276dc860a36Sspz */ 277c74ad251Schristos if (auth_len != AUTH_SHA1_FIELD_LEN) { 278c74ad251Schristos ND_PRINT("[invalid length %u]", 279c74ad251Schristos auth_len); 280dc860a36Sspz break; 281dc860a36Sspz } 282dc860a36Sspz pptr += 2; 283c74ad251Schristos ND_PRINT(", Sequence Number: 0x%08x", GET_BE_U_4(pptr)); 284dc860a36Sspz pptr += 4; 285c74ad251Schristos ND_TCHECK_LEN(pptr, AUTH_SHA1_HASH_LEN); 286c74ad251Schristos ND_PRINT("\n\t Hash: "); 287dc860a36Sspz for(i = 0; i < AUTH_SHA1_HASH_LEN; i++) 288c74ad251Schristos ND_PRINT("%02x", GET_U_1(pptr + i)); 289dc860a36Sspz break; 290dc860a36Sspz } 291dc860a36Sspz } 292dc860a36Sspz 2930f74e101Schristos void 294c74ad251Schristos bfd_print(netdissect_options *ndo, const u_char *pptr, 295c74ad251Schristos u_int len, u_int port) 2960f74e101Schristos { 297c74ad251Schristos ndo->ndo_protocol = "bfd"; 298c74ad251Schristos if (port == BFD_CONTROL_PORT || 299c74ad251Schristos port == BFD_MULTIHOP_PORT || 300c74ad251Schristos port == BFD_LAG_PORT) { 301817e9a7eSchristos /* 302817e9a7eSchristos * Control packet. 303817e9a7eSchristos */ 3040f74e101Schristos const struct bfd_header_t *bfd_header; 305817e9a7eSchristos uint8_t version_diag; 306b3a00663Schristos uint8_t version = 0; 307817e9a7eSchristos uint8_t flags; 3080f74e101Schristos 3090f74e101Schristos bfd_header = (const struct bfd_header_t *)pptr; 310c74ad251Schristos ND_TCHECK_SIZE(bfd_header); 311c74ad251Schristos version_diag = GET_U_1(bfd_header->version_diag); 312817e9a7eSchristos version = BFD_EXTRACT_VERSION(version_diag); 313c74ad251Schristos flags = GET_U_1(bfd_header->flags); 314817e9a7eSchristos 315817e9a7eSchristos switch (version) { 3160f74e101Schristos 3170f74e101Schristos /* BFDv0 */ 318817e9a7eSchristos case 0: 319*26ba0b50Schristos if (ndo->ndo_vflag < 1) { 320c74ad251Schristos ND_PRINT("BFDv0, Control, Flags: [%s], length: %u", 321817e9a7eSchristos bittok2str(bfd_v0_flag_values, "none", flags), 322c74ad251Schristos len); 3230f74e101Schristos return; 3240f74e101Schristos } 3250f74e101Schristos 326c74ad251Schristos ND_PRINT("BFDv0, length: %u\n\tControl, Flags: [%s], Diagnostic: %s (0x%02x)", 3270f74e101Schristos len, 328817e9a7eSchristos bittok2str(bfd_v0_flag_values, "none", flags), 329817e9a7eSchristos tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(version_diag)), 330c74ad251Schristos BFD_EXTRACT_DIAG(version_diag)); 3310f74e101Schristos 332c74ad251Schristos ND_PRINT("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", 333c74ad251Schristos GET_U_1(bfd_header->detect_time_multiplier), 334c74ad251Schristos GET_U_1(bfd_header->detect_time_multiplier) * GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000, 335c74ad251Schristos GET_U_1(bfd_header->length)); 3360f74e101Schristos 3370f74e101Schristos 338c74ad251Schristos ND_PRINT("\n\tMy Discriminator: 0x%08x", 339c74ad251Schristos GET_BE_U_4(bfd_header->my_discriminator)); 340c74ad251Schristos ND_PRINT(", Your Discriminator: 0x%08x", 341c74ad251Schristos GET_BE_U_4(bfd_header->your_discriminator)); 342c74ad251Schristos ND_PRINT("\n\t Desired min Tx Interval: %4u ms", 343c74ad251Schristos GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000); 344c74ad251Schristos ND_PRINT("\n\t Required min Rx Interval: %4u ms", 345c74ad251Schristos GET_BE_U_4(bfd_header->required_min_rx_interval)/1000); 346c74ad251Schristos ND_PRINT("\n\t Required min Echo Interval: %4u ms", 347c74ad251Schristos GET_BE_U_4(bfd_header->required_min_echo_interval)/1000); 3480f74e101Schristos 349817e9a7eSchristos if (flags & BFD_FLAG_AUTH) { 350c74ad251Schristos auth_print(ndo, pptr); 3510f74e101Schristos } 3520f74e101Schristos break; 3530f74e101Schristos 3540f74e101Schristos /* BFDv1 */ 355817e9a7eSchristos case 1: 356*26ba0b50Schristos if (ndo->ndo_vflag < 1) { 357c74ad251Schristos ND_PRINT("BFDv1, %s, State %s, Flags: [%s], length: %u", 358c74ad251Schristos tok2str(bfd_port_values, "unknown (%u)", port), 359817e9a7eSchristos tok2str(bfd_v1_state_values, "unknown (%u)", (flags & 0xc0) >> 6), 360817e9a7eSchristos bittok2str(bfd_v1_flag_values, "none", flags & 0x3f), 361c74ad251Schristos len); 362817e9a7eSchristos return; 363817e9a7eSchristos } 364817e9a7eSchristos 365c74ad251Schristos ND_PRINT("BFDv1, length: %u\n\t%s, State %s, Flags: [%s], Diagnostic: %s (0x%02x)", 366817e9a7eSchristos len, 367c74ad251Schristos tok2str(bfd_port_values, "unknown (%u)", port), 368817e9a7eSchristos tok2str(bfd_v1_state_values, "unknown (%u)", (flags & 0xc0) >> 6), 369817e9a7eSchristos bittok2str(bfd_v1_flag_values, "none", flags & 0x3f), 370817e9a7eSchristos tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(version_diag)), 371c74ad251Schristos BFD_EXTRACT_DIAG(version_diag)); 372817e9a7eSchristos 373c74ad251Schristos ND_PRINT("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", 374c74ad251Schristos GET_U_1(bfd_header->detect_time_multiplier), 375c74ad251Schristos GET_U_1(bfd_header->detect_time_multiplier) * GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000, 376c74ad251Schristos GET_U_1(bfd_header->length)); 377817e9a7eSchristos 378817e9a7eSchristos 379c74ad251Schristos ND_PRINT("\n\tMy Discriminator: 0x%08x", 380c74ad251Schristos GET_BE_U_4(bfd_header->my_discriminator)); 381c74ad251Schristos ND_PRINT(", Your Discriminator: 0x%08x", 382c74ad251Schristos GET_BE_U_4(bfd_header->your_discriminator)); 383c74ad251Schristos ND_PRINT("\n\t Desired min Tx Interval: %4u ms", 384c74ad251Schristos GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000); 385c74ad251Schristos ND_PRINT("\n\t Required min Rx Interval: %4u ms", 386c74ad251Schristos GET_BE_U_4(bfd_header->required_min_rx_interval)/1000); 387c74ad251Schristos ND_PRINT("\n\t Required min Echo Interval: %4u ms", 388c74ad251Schristos GET_BE_U_4(bfd_header->required_min_echo_interval)/1000); 389817e9a7eSchristos 390817e9a7eSchristos if (flags & BFD_FLAG_AUTH) { 391c74ad251Schristos auth_print(ndo, pptr); 392817e9a7eSchristos } 393817e9a7eSchristos break; 3940f74e101Schristos 3950f74e101Schristos default: 396c74ad251Schristos ND_PRINT("BFDv%u, Control, length: %u", 397817e9a7eSchristos version, 398c74ad251Schristos len); 399b3a00663Schristos if (ndo->ndo_vflag >= 1) { 400b3a00663Schristos if(!print_unknown_data(ndo, pptr,"\n\t",len)) 4010f74e101Schristos return; 4020f74e101Schristos } 4030f74e101Schristos break; 4040f74e101Schristos } 405817e9a7eSchristos } else if (port == BFD_ECHO_PORT) { 406817e9a7eSchristos /* 407817e9a7eSchristos * Echo packet. 408817e9a7eSchristos */ 409c74ad251Schristos ND_PRINT("BFD, Echo, length: %u", 410c74ad251Schristos len); 411817e9a7eSchristos if (ndo->ndo_vflag >= 1) { 412817e9a7eSchristos if(!print_unknown_data(ndo, pptr,"\n\t",len)) 413817e9a7eSchristos return; 414817e9a7eSchristos } 415817e9a7eSchristos } else { 416817e9a7eSchristos /* 417817e9a7eSchristos * Unknown packet type. 418817e9a7eSchristos */ 419c74ad251Schristos ND_PRINT("BFD, unknown (%u), length: %u", 420817e9a7eSchristos port, 421c74ad251Schristos len); 422817e9a7eSchristos if (ndo->ndo_vflag >= 1) { 423817e9a7eSchristos if(!print_unknown_data(ndo, pptr,"\n\t",len)) 424817e9a7eSchristos return; 425817e9a7eSchristos } 426817e9a7eSchristos } 4270f74e101Schristos } 428