15b0fe478SBruce M Simpson /* 25b0fe478SBruce M Simpson * Redistribution and use in source and binary forms, with or without 35b0fe478SBruce M Simpson * modification, are permitted provided that: (1) source code 45b0fe478SBruce M Simpson * distributions retain the above copyright notice and this paragraph 55b0fe478SBruce M Simpson * in its entirety, and (2) distributions including binary code include 65b0fe478SBruce M Simpson * the above copyright notice and this paragraph in its entirety in 75b0fe478SBruce M Simpson * the documentation or other materials provided with the distribution. 85b0fe478SBruce M Simpson * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 95b0fe478SBruce M Simpson * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 105b0fe478SBruce M Simpson * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 115b0fe478SBruce M Simpson * FOR A PARTICULAR PURPOSE. 125b0fe478SBruce M Simpson * 130bff6a5aSEd Maste * Original code by Hannes Gredler (hannes@gredler.at) 145b0fe478SBruce M Simpson */ 155b0fe478SBruce M Simpson 163340d773SGleb Smirnoff /* \summary: Bidirectional Forwarding Detection (BFD) printer */ 173340d773SGleb Smirnoff 1839e421e8SCy Schubert /* 1939e421e8SCy Schubert * specification: draft-ietf-bfd-base-01 for version 0, 2039e421e8SCy Schubert * RFC 5880 for version 1, and RFC 5881 2139e421e8SCy Schubert */ 223340d773SGleb Smirnoff 23ee67461eSJoseph Mingrone #include <config.h> 245b0fe478SBruce M Simpson 25ee67461eSJoseph Mingrone #include "netdissect-stdinc.h" 265b0fe478SBruce M Simpson 27ee67461eSJoseph Mingrone #define ND_LONGJMP_FROM_TCHECK 283340d773SGleb Smirnoff #include "netdissect.h" 295b0fe478SBruce M Simpson #include "extract.h" 305b0fe478SBruce M Simpson 315b0fe478SBruce M Simpson #include "udp.h" 325b0fe478SBruce M Simpson 335b0fe478SBruce M Simpson /* 3439e421e8SCy Schubert * Control packet, BFDv0, draft-ietf-bfd-base-01 355b0fe478SBruce M Simpson * 365b0fe478SBruce M Simpson * 0 1 2 3 375b0fe478SBruce M Simpson * 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 385b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3939e421e8SCy Schubert * |Vers | Diag |H|D|P|F|C|A|Rsv| Detect Mult | Length | 405b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 415b0fe478SBruce M Simpson * | My Discriminator | 425b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 435b0fe478SBruce M Simpson * | Your Discriminator | 445b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 455b0fe478SBruce M Simpson * | Desired Min TX Interval | 465b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 475b0fe478SBruce M Simpson * | Required Min RX Interval | 485b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 495b0fe478SBruce M Simpson * | Required Min Echo RX Interval | 505b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 515b0fe478SBruce M Simpson */ 525b0fe478SBruce M Simpson 53f4d0c64aSSam Leffler /* 543340d773SGleb Smirnoff * Control packet, BFDv1, RFC 5880 55f4d0c64aSSam Leffler * 56f4d0c64aSSam Leffler * 0 1 2 3 57f4d0c64aSSam Leffler * 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 58f4d0c64aSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 593340d773SGleb Smirnoff * |Vers | Diag |Sta|P|F|C|A|D|M| Detect Mult | Length | 60f4d0c64aSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 61f4d0c64aSSam Leffler * | My Discriminator | 62f4d0c64aSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 63f4d0c64aSSam Leffler * | Your Discriminator | 64f4d0c64aSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 65f4d0c64aSSam Leffler * | Desired Min TX Interval | 66f4d0c64aSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 67f4d0c64aSSam Leffler * | Required Min RX Interval | 68f4d0c64aSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 69f4d0c64aSSam Leffler * | Required Min Echo RX Interval | 70f4d0c64aSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 71f4d0c64aSSam Leffler */ 72f4d0c64aSSam Leffler 735b0fe478SBruce M Simpson struct bfd_header_t { 74ee67461eSJoseph Mingrone nd_uint8_t version_diag; 75ee67461eSJoseph Mingrone nd_uint8_t flags; 76ee67461eSJoseph Mingrone nd_uint8_t detect_time_multiplier; 77ee67461eSJoseph Mingrone nd_uint8_t length; 78ee67461eSJoseph Mingrone nd_uint32_t my_discriminator; 79ee67461eSJoseph Mingrone nd_uint32_t your_discriminator; 80ee67461eSJoseph Mingrone nd_uint32_t desired_min_tx_interval; 81ee67461eSJoseph Mingrone nd_uint32_t required_min_rx_interval; 82ee67461eSJoseph Mingrone nd_uint32_t required_min_echo_interval; 835b0fe478SBruce M Simpson }; 845b0fe478SBruce M Simpson 85f4d0c64aSSam Leffler /* 86f4d0c64aSSam Leffler * An optional Authentication Header may be present 87f4d0c64aSSam Leffler * 88f4d0c64aSSam Leffler * 0 1 2 3 89f4d0c64aSSam Leffler * 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 90f4d0c64aSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 91f4d0c64aSSam Leffler * | Auth Type | Auth Len | Authentication Data... | 92f4d0c64aSSam Leffler * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 93f4d0c64aSSam Leffler */ 94f4d0c64aSSam Leffler 95f4d0c64aSSam Leffler struct bfd_auth_header_t { 96ee67461eSJoseph Mingrone nd_uint8_t auth_type; 97ee67461eSJoseph Mingrone nd_uint8_t auth_len; 98ee67461eSJoseph Mingrone nd_uint8_t auth_data; 99ee67461eSJoseph Mingrone nd_uint8_t dummy; /* minimum 4 bytes */ 1003340d773SGleb Smirnoff }; 1013340d773SGleb Smirnoff 1023340d773SGleb Smirnoff enum auth_type { 1033340d773SGleb Smirnoff AUTH_PASSWORD = 1, 1043340d773SGleb Smirnoff AUTH_MD5 = 2, 1053340d773SGleb Smirnoff AUTH_MET_MD5 = 3, 1063340d773SGleb Smirnoff AUTH_SHA1 = 4, 1073340d773SGleb Smirnoff AUTH_MET_SHA1 = 5 108f4d0c64aSSam Leffler }; 109f4d0c64aSSam Leffler 110f4d0c64aSSam Leffler static const struct tok bfd_v1_authentication_values[] = { 1113340d773SGleb Smirnoff { AUTH_PASSWORD, "Simple Password" }, 1123340d773SGleb Smirnoff { AUTH_MD5, "Keyed MD5" }, 1133340d773SGleb Smirnoff { AUTH_MET_MD5, "Meticulous Keyed MD5" }, 1143340d773SGleb Smirnoff { AUTH_SHA1, "Keyed SHA1" }, 1153340d773SGleb Smirnoff { AUTH_MET_SHA1, "Meticulous Keyed SHA1" }, 116f4d0c64aSSam Leffler { 0, NULL } 117f4d0c64aSSam Leffler }; 118f4d0c64aSSam Leffler 1193340d773SGleb Smirnoff enum auth_length { 1203340d773SGleb Smirnoff AUTH_PASSWORD_FIELD_MIN_LEN = 4, /* header + password min: 3 + 1 */ 1213340d773SGleb Smirnoff AUTH_PASSWORD_FIELD_MAX_LEN = 19, /* header + password max: 3 + 16 */ 1223340d773SGleb Smirnoff AUTH_MD5_FIELD_LEN = 24, 1233340d773SGleb Smirnoff AUTH_MD5_HASH_LEN = 16, 1243340d773SGleb Smirnoff AUTH_SHA1_FIELD_LEN = 28, 1253340d773SGleb Smirnoff AUTH_SHA1_HASH_LEN = 20 1263340d773SGleb Smirnoff }; 1273340d773SGleb Smirnoff 1285b0fe478SBruce M Simpson #define BFD_EXTRACT_VERSION(x) (((x)&0xe0)>>5) 1295b0fe478SBruce M Simpson #define BFD_EXTRACT_DIAG(x) ((x)&0x1f) 1305b0fe478SBruce M Simpson 1315b0fe478SBruce M Simpson static const struct tok bfd_diag_values[] = { 1325b0fe478SBruce M Simpson { 0, "No Diagnostic" }, 1335b0fe478SBruce M Simpson { 1, "Control Detection Time Expired" }, 1345b0fe478SBruce M Simpson { 2, "Echo Function Failed" }, 1355b0fe478SBruce M Simpson { 3, "Neighbor Signaled Session Down" }, 1365b0fe478SBruce M Simpson { 4, "Forwarding Plane Reset" }, 1375b0fe478SBruce M Simpson { 5, "Path Down" }, 1385b0fe478SBruce M Simpson { 6, "Concatenated Path Down" }, 1395b0fe478SBruce M Simpson { 7, "Administratively Down" }, 140f4d0c64aSSam Leffler { 8, "Reverse Concatenated Path Down" }, 1415b0fe478SBruce M Simpson { 0, NULL } 1425b0fe478SBruce M Simpson }; 1435b0fe478SBruce M Simpson 144ee67461eSJoseph Mingrone static const struct tok bfd_port_values[] = { 145ee67461eSJoseph Mingrone { BFD_CONTROL_PORT, "Control" }, 146ee67461eSJoseph Mingrone { BFD_MULTIHOP_PORT, "Multihop" }, 147ee67461eSJoseph Mingrone { BFD_LAG_PORT, "Lag" }, 148ee67461eSJoseph Mingrone { 0, NULL } 149ee67461eSJoseph Mingrone }; 150ee67461eSJoseph Mingrone 15139e421e8SCy Schubert #define BFD_FLAG_AUTH 0x04 15239e421e8SCy Schubert 153f4d0c64aSSam Leffler static const struct tok bfd_v0_flag_values[] = { 1545b0fe478SBruce M Simpson { 0x80, "I Hear You" }, 1555b0fe478SBruce M Simpson { 0x40, "Demand" }, 1565b0fe478SBruce M Simpson { 0x20, "Poll" }, 1575b0fe478SBruce M Simpson { 0x10, "Final" }, 15839e421e8SCy Schubert { 0x08, "Control Plane Independent" }, 15939e421e8SCy Schubert { BFD_FLAG_AUTH, "Authentication Present" }, 1605b0fe478SBruce M Simpson { 0x02, "Reserved" }, 1615b0fe478SBruce M Simpson { 0x01, "Reserved" }, 1625b0fe478SBruce M Simpson { 0, NULL } 1635b0fe478SBruce M Simpson }; 1645b0fe478SBruce M Simpson 165f4d0c64aSSam Leffler static const struct tok bfd_v1_flag_values[] = { 166f4d0c64aSSam Leffler { 0x20, "Poll" }, 167f4d0c64aSSam Leffler { 0x10, "Final" }, 168f4d0c64aSSam Leffler { 0x08, "Control Plane Independent" }, 169f4d0c64aSSam Leffler { BFD_FLAG_AUTH, "Authentication Present" }, 170f4d0c64aSSam Leffler { 0x02, "Demand" }, 1713340d773SGleb Smirnoff { 0x01, "Multipoint" }, 172f4d0c64aSSam Leffler { 0, NULL } 173f4d0c64aSSam Leffler }; 174f4d0c64aSSam Leffler 175f4d0c64aSSam Leffler static const struct tok bfd_v1_state_values[] = { 176f4d0c64aSSam Leffler { 0, "AdminDown" }, 177f4d0c64aSSam Leffler { 1, "Down" }, 178f4d0c64aSSam Leffler { 2, "Init" }, 179f4d0c64aSSam Leffler { 3, "Up" }, 180f4d0c64aSSam Leffler { 0, NULL } 181f4d0c64aSSam Leffler }; 182f4d0c64aSSam Leffler 183ee67461eSJoseph Mingrone static void 184ee67461eSJoseph Mingrone auth_print(netdissect_options *ndo, const u_char *pptr) 1853340d773SGleb Smirnoff { 1863340d773SGleb Smirnoff const struct bfd_auth_header_t *bfd_auth_header; 187ee67461eSJoseph Mingrone uint8_t auth_type, auth_len; 1883340d773SGleb Smirnoff int i; 1893340d773SGleb Smirnoff 190ee67461eSJoseph Mingrone pptr += sizeof (struct bfd_header_t); 1913340d773SGleb Smirnoff bfd_auth_header = (const struct bfd_auth_header_t *)pptr; 192ee67461eSJoseph Mingrone ND_TCHECK_SIZE(bfd_auth_header); 193ee67461eSJoseph Mingrone auth_type = GET_U_1(bfd_auth_header->auth_type); 194ee67461eSJoseph Mingrone auth_len = GET_U_1(bfd_auth_header->auth_len); 195ee67461eSJoseph Mingrone ND_PRINT("\n\tAuthentication: %s (%u), length: %u", 196ee67461eSJoseph Mingrone tok2str(bfd_v1_authentication_values,"Unknown",auth_type), 197ee67461eSJoseph Mingrone auth_type, auth_len); 1983340d773SGleb Smirnoff pptr += 2; 199ee67461eSJoseph Mingrone ND_PRINT("\n\t Auth Key ID: %u", GET_U_1(pptr)); 2003340d773SGleb Smirnoff 201ee67461eSJoseph Mingrone switch(auth_type) { 2023340d773SGleb Smirnoff case AUTH_PASSWORD: 2033340d773SGleb Smirnoff /* 2043340d773SGleb Smirnoff * Simple Password Authentication Section Format 2053340d773SGleb Smirnoff * 2063340d773SGleb Smirnoff * 0 1 2 3 2073340d773SGleb Smirnoff * 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 2083340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2093340d773SGleb Smirnoff * | Auth Type | Auth Len | Auth Key ID | Password... | 2103340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2113340d773SGleb Smirnoff * | ... | 2123340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2133340d773SGleb Smirnoff */ 214ee67461eSJoseph Mingrone if (auth_len < AUTH_PASSWORD_FIELD_MIN_LEN || 215ee67461eSJoseph Mingrone auth_len > AUTH_PASSWORD_FIELD_MAX_LEN) { 216ee67461eSJoseph Mingrone ND_PRINT("[invalid length %u]", 217ee67461eSJoseph Mingrone auth_len); 2183340d773SGleb Smirnoff break; 2193340d773SGleb Smirnoff } 2203340d773SGleb Smirnoff pptr++; 221ee67461eSJoseph Mingrone ND_PRINT(", Password: "); 2223340d773SGleb Smirnoff /* the length is equal to the password length plus three */ 223ee67461eSJoseph Mingrone (void)nd_printn(ndo, pptr, auth_len - 3, NULL); 2243340d773SGleb Smirnoff break; 2253340d773SGleb Smirnoff case AUTH_MD5: 2263340d773SGleb Smirnoff case AUTH_MET_MD5: 2273340d773SGleb Smirnoff /* 2283340d773SGleb Smirnoff * Keyed MD5 and Meticulous Keyed MD5 Authentication Section Format 2293340d773SGleb Smirnoff * 2303340d773SGleb Smirnoff * 0 1 2 3 2313340d773SGleb Smirnoff * 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 2323340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2333340d773SGleb Smirnoff * | Auth Type | Auth Len | Auth Key ID | Reserved | 2343340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2353340d773SGleb Smirnoff * | Sequence Number | 2363340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2373340d773SGleb Smirnoff * | Auth Key/Digest... | 2383340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2393340d773SGleb Smirnoff * | ... | 2403340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2413340d773SGleb Smirnoff */ 242ee67461eSJoseph Mingrone if (auth_len != AUTH_MD5_FIELD_LEN) { 243ee67461eSJoseph Mingrone ND_PRINT("[invalid length %u]", 244ee67461eSJoseph Mingrone auth_len); 2453340d773SGleb Smirnoff break; 2463340d773SGleb Smirnoff } 2473340d773SGleb Smirnoff pptr += 2; 248ee67461eSJoseph Mingrone ND_PRINT(", Sequence Number: 0x%08x", GET_BE_U_4(pptr)); 2493340d773SGleb Smirnoff pptr += 4; 250ee67461eSJoseph Mingrone ND_TCHECK_LEN(pptr, AUTH_MD5_HASH_LEN); 251ee67461eSJoseph Mingrone ND_PRINT("\n\t Digest: "); 2523340d773SGleb Smirnoff for(i = 0; i < AUTH_MD5_HASH_LEN; i++) 253ee67461eSJoseph Mingrone ND_PRINT("%02x", GET_U_1(pptr + i)); 2543340d773SGleb Smirnoff break; 2553340d773SGleb Smirnoff case AUTH_SHA1: 2563340d773SGleb Smirnoff case AUTH_MET_SHA1: 2573340d773SGleb Smirnoff /* 2583340d773SGleb Smirnoff * Keyed SHA1 and Meticulous Keyed SHA1 Authentication Section Format 2593340d773SGleb Smirnoff * 2603340d773SGleb Smirnoff * 0 1 2 3 2613340d773SGleb Smirnoff * 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 2623340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2633340d773SGleb Smirnoff * | Auth Type | Auth Len | Auth Key ID | Reserved | 2643340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2653340d773SGleb Smirnoff * | Sequence Number | 2663340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2673340d773SGleb Smirnoff * | Auth Key/Hash... | 2683340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2693340d773SGleb Smirnoff * | ... | 2703340d773SGleb Smirnoff * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2713340d773SGleb Smirnoff */ 272ee67461eSJoseph Mingrone if (auth_len != AUTH_SHA1_FIELD_LEN) { 273ee67461eSJoseph Mingrone ND_PRINT("[invalid length %u]", 274ee67461eSJoseph Mingrone auth_len); 2753340d773SGleb Smirnoff break; 2763340d773SGleb Smirnoff } 2773340d773SGleb Smirnoff pptr += 2; 278ee67461eSJoseph Mingrone ND_PRINT(", Sequence Number: 0x%08x", GET_BE_U_4(pptr)); 2793340d773SGleb Smirnoff pptr += 4; 280ee67461eSJoseph Mingrone ND_TCHECK_LEN(pptr, AUTH_SHA1_HASH_LEN); 281ee67461eSJoseph Mingrone ND_PRINT("\n\t Hash: "); 2823340d773SGleb Smirnoff for(i = 0; i < AUTH_SHA1_HASH_LEN; i++) 283ee67461eSJoseph Mingrone ND_PRINT("%02x", GET_U_1(pptr + i)); 2843340d773SGleb Smirnoff break; 2853340d773SGleb Smirnoff } 2863340d773SGleb Smirnoff } 2873340d773SGleb Smirnoff 2885b0fe478SBruce M Simpson void 289ee67461eSJoseph Mingrone bfd_print(netdissect_options *ndo, const u_char *pptr, 290ee67461eSJoseph Mingrone u_int len, u_int port) 2915b0fe478SBruce M Simpson { 292ee67461eSJoseph Mingrone ndo->ndo_protocol = "bfd"; 293ee67461eSJoseph Mingrone if (port == BFD_CONTROL_PORT || 294ee67461eSJoseph Mingrone port == BFD_MULTIHOP_PORT || 295ee67461eSJoseph Mingrone port == BFD_LAG_PORT) { 29639e421e8SCy Schubert /* 29739e421e8SCy Schubert * Control packet. 29839e421e8SCy Schubert */ 2995b0fe478SBruce M Simpson const struct bfd_header_t *bfd_header; 30039e421e8SCy Schubert uint8_t version_diag; 3013c602fabSXin LI uint8_t version = 0; 30239e421e8SCy Schubert uint8_t flags; 3035b0fe478SBruce M Simpson 3045b0fe478SBruce M Simpson bfd_header = (const struct bfd_header_t *)pptr; 305ee67461eSJoseph Mingrone ND_TCHECK_SIZE(bfd_header); 306ee67461eSJoseph Mingrone version_diag = GET_U_1(bfd_header->version_diag); 30739e421e8SCy Schubert version = BFD_EXTRACT_VERSION(version_diag); 308ee67461eSJoseph Mingrone flags = GET_U_1(bfd_header->flags); 30939e421e8SCy Schubert 31039e421e8SCy Schubert switch (version) { 3115b0fe478SBruce M Simpson 312f4d0c64aSSam Leffler /* BFDv0 */ 31339e421e8SCy Schubert case 0: 314*0a7e5f1fSJoseph Mingrone if (ndo->ndo_vflag < 1) { 315ee67461eSJoseph Mingrone ND_PRINT("BFDv0, Control, Flags: [%s], length: %u", 31639e421e8SCy Schubert bittok2str(bfd_v0_flag_values, "none", flags), 317ee67461eSJoseph Mingrone len); 3185b0fe478SBruce M Simpson return; 3195b0fe478SBruce M Simpson } 3205b0fe478SBruce M Simpson 321ee67461eSJoseph Mingrone ND_PRINT("BFDv0, length: %u\n\tControl, Flags: [%s], Diagnostic: %s (0x%02x)", 3225b0fe478SBruce M Simpson len, 32339e421e8SCy Schubert bittok2str(bfd_v0_flag_values, "none", flags), 32439e421e8SCy Schubert tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(version_diag)), 325ee67461eSJoseph Mingrone BFD_EXTRACT_DIAG(version_diag)); 326f4d0c64aSSam Leffler 327ee67461eSJoseph Mingrone ND_PRINT("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", 328ee67461eSJoseph Mingrone GET_U_1(bfd_header->detect_time_multiplier), 329ee67461eSJoseph Mingrone GET_U_1(bfd_header->detect_time_multiplier) * GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000, 330ee67461eSJoseph Mingrone GET_U_1(bfd_header->length)); 331f4d0c64aSSam Leffler 332f4d0c64aSSam Leffler 333ee67461eSJoseph Mingrone ND_PRINT("\n\tMy Discriminator: 0x%08x", 334ee67461eSJoseph Mingrone GET_BE_U_4(bfd_header->my_discriminator)); 335ee67461eSJoseph Mingrone ND_PRINT(", Your Discriminator: 0x%08x", 336ee67461eSJoseph Mingrone GET_BE_U_4(bfd_header->your_discriminator)); 337ee67461eSJoseph Mingrone ND_PRINT("\n\t Desired min Tx Interval: %4u ms", 338ee67461eSJoseph Mingrone GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000); 339ee67461eSJoseph Mingrone ND_PRINT("\n\t Required min Rx Interval: %4u ms", 340ee67461eSJoseph Mingrone GET_BE_U_4(bfd_header->required_min_rx_interval)/1000); 341ee67461eSJoseph Mingrone ND_PRINT("\n\t Required min Echo Interval: %4u ms", 342ee67461eSJoseph Mingrone GET_BE_U_4(bfd_header->required_min_echo_interval)/1000); 343f4d0c64aSSam Leffler 34439e421e8SCy Schubert if (flags & BFD_FLAG_AUTH) { 345ee67461eSJoseph Mingrone auth_print(ndo, pptr); 346f4d0c64aSSam Leffler } 347f4d0c64aSSam Leffler break; 348f4d0c64aSSam Leffler 349f4d0c64aSSam Leffler /* BFDv1 */ 35039e421e8SCy Schubert case 1: 351*0a7e5f1fSJoseph Mingrone if (ndo->ndo_vflag < 1) { 352ee67461eSJoseph Mingrone ND_PRINT("BFDv1, %s, State %s, Flags: [%s], length: %u", 353ee67461eSJoseph Mingrone tok2str(bfd_port_values, "unknown (%u)", port), 35439e421e8SCy Schubert tok2str(bfd_v1_state_values, "unknown (%u)", (flags & 0xc0) >> 6), 35539e421e8SCy Schubert bittok2str(bfd_v1_flag_values, "none", flags & 0x3f), 356ee67461eSJoseph Mingrone len); 35739e421e8SCy Schubert return; 35839e421e8SCy Schubert } 35939e421e8SCy Schubert 360ee67461eSJoseph Mingrone ND_PRINT("BFDv1, length: %u\n\t%s, State %s, Flags: [%s], Diagnostic: %s (0x%02x)", 36139e421e8SCy Schubert len, 362ee67461eSJoseph Mingrone tok2str(bfd_port_values, "unknown (%u)", port), 36339e421e8SCy Schubert tok2str(bfd_v1_state_values, "unknown (%u)", (flags & 0xc0) >> 6), 36439e421e8SCy Schubert bittok2str(bfd_v1_flag_values, "none", flags & 0x3f), 36539e421e8SCy Schubert tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(version_diag)), 366ee67461eSJoseph Mingrone BFD_EXTRACT_DIAG(version_diag)); 36739e421e8SCy Schubert 368ee67461eSJoseph Mingrone ND_PRINT("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", 369ee67461eSJoseph Mingrone GET_U_1(bfd_header->detect_time_multiplier), 370ee67461eSJoseph Mingrone GET_U_1(bfd_header->detect_time_multiplier) * GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000, 371ee67461eSJoseph Mingrone GET_U_1(bfd_header->length)); 37239e421e8SCy Schubert 37339e421e8SCy Schubert 374ee67461eSJoseph Mingrone ND_PRINT("\n\tMy Discriminator: 0x%08x", 375ee67461eSJoseph Mingrone GET_BE_U_4(bfd_header->my_discriminator)); 376ee67461eSJoseph Mingrone ND_PRINT(", Your Discriminator: 0x%08x", 377ee67461eSJoseph Mingrone GET_BE_U_4(bfd_header->your_discriminator)); 378ee67461eSJoseph Mingrone ND_PRINT("\n\t Desired min Tx Interval: %4u ms", 379ee67461eSJoseph Mingrone GET_BE_U_4(bfd_header->desired_min_tx_interval)/1000); 380ee67461eSJoseph Mingrone ND_PRINT("\n\t Required min Rx Interval: %4u ms", 381ee67461eSJoseph Mingrone GET_BE_U_4(bfd_header->required_min_rx_interval)/1000); 382ee67461eSJoseph Mingrone ND_PRINT("\n\t Required min Echo Interval: %4u ms", 383ee67461eSJoseph Mingrone GET_BE_U_4(bfd_header->required_min_echo_interval)/1000); 38439e421e8SCy Schubert 38539e421e8SCy Schubert if (flags & BFD_FLAG_AUTH) { 386ee67461eSJoseph Mingrone auth_print(ndo, pptr); 38739e421e8SCy Schubert } 38839e421e8SCy Schubert break; 3895b0fe478SBruce M Simpson 3905b0fe478SBruce M Simpson default: 391ee67461eSJoseph Mingrone ND_PRINT("BFDv%u, Control, length: %u", 39239e421e8SCy Schubert version, 393ee67461eSJoseph Mingrone len); 3943c602fabSXin LI if (ndo->ndo_vflag >= 1) { 3953c602fabSXin LI if(!print_unknown_data(ndo, pptr,"\n\t",len)) 3965b0fe478SBruce M Simpson return; 3975b0fe478SBruce M Simpson } 3985b0fe478SBruce M Simpson break; 3995b0fe478SBruce M Simpson } 40039e421e8SCy Schubert } else if (port == BFD_ECHO_PORT) { 40139e421e8SCy Schubert /* 40239e421e8SCy Schubert * Echo packet. 40339e421e8SCy Schubert */ 404ee67461eSJoseph Mingrone ND_PRINT("BFD, Echo, length: %u", 405ee67461eSJoseph Mingrone len); 40639e421e8SCy Schubert if (ndo->ndo_vflag >= 1) { 40739e421e8SCy Schubert if(!print_unknown_data(ndo, pptr,"\n\t",len)) 40839e421e8SCy Schubert return; 40939e421e8SCy Schubert } 41039e421e8SCy Schubert } else { 41139e421e8SCy Schubert /* 41239e421e8SCy Schubert * Unknown packet type. 41339e421e8SCy Schubert */ 414ee67461eSJoseph Mingrone ND_PRINT("BFD, unknown (%u), length: %u", 41539e421e8SCy Schubert port, 416ee67461eSJoseph Mingrone len); 41739e421e8SCy Schubert if (ndo->ndo_vflag >= 1) { 41839e421e8SCy Schubert if(!print_unknown_data(ndo, pptr,"\n\t",len)) 41939e421e8SCy Schubert return; 42039e421e8SCy Schubert } 42139e421e8SCy Schubert } 4225b0fe478SBruce M Simpson } 423