1 /* 2 * Copyright (c) 1998-2007 The TCPDUMP project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that: (1) source code 6 * distributions retain the above copyright notice and this paragraph 7 * in its entirety, and (2) distributions including binary code include 8 * the above copyright notice and this paragraph in its entirety in 9 * the documentation or other materials provided with the distribution. 10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 11 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 12 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 * FOR A PARTICULAR PURPOSE. 14 * 15 * Original code by Carles Kishimoto <carles.kishimoto@gmail.com> 16 */ 17 18 /* \summary: Dynamic Trunking Protocol (DTP) printer */ 19 20 #include <sys/cdefs.h> 21 #ifndef lint 22 __RCSID("$NetBSD: print-dtp.c,v 1.5 2024/09/02 16:15:31 christos Exp $"); 23 #endif 24 25 #include <config.h> 26 27 #include "netdissect-stdinc.h" 28 29 #define ND_LONGJMP_FROM_TCHECK 30 #include "netdissect.h" 31 #include "addrtoname.h" 32 #include "extract.h" 33 34 35 #define DTP_HEADER_LEN 1 36 #define DTP_DOMAIN_TLV 0x0001 37 #define DTP_STATUS_TLV 0x0002 38 #define DTP_DTP_TYPE_TLV 0x0003 39 #define DTP_NEIGHBOR_TLV 0x0004 40 41 static const struct tok dtp_tlv_values[] = { 42 { DTP_DOMAIN_TLV, "Domain" }, 43 { DTP_STATUS_TLV, "Status" }, 44 { DTP_DTP_TYPE_TLV, "DTP type" }, 45 { DTP_NEIGHBOR_TLV, "Neighbor" }, 46 { 0, NULL} 47 }; 48 49 void 50 dtp_print(netdissect_options *ndo, const u_char *tptr, u_int length) 51 { 52 ndo->ndo_protocol = "dtp"; 53 if (length < DTP_HEADER_LEN) { 54 ND_PRINT("[zero packet length]"); 55 goto invalid; 56 } 57 58 ND_PRINT("DTPv%u, length %u", 59 GET_U_1(tptr), 60 length); 61 62 /* 63 * In non-verbose mode, just print version. 64 */ 65 if (ndo->ndo_vflag < 1) { 66 return; 67 } 68 69 tptr += DTP_HEADER_LEN; 70 length -= DTP_HEADER_LEN; 71 72 while (length) { 73 uint16_t type, len; 74 75 if (length < 4) { 76 ND_PRINT("[%u bytes remaining]", length); 77 goto invalid; 78 } 79 type = GET_BE_U_2(tptr); 80 len = GET_BE_U_2(tptr + 2); 81 /* XXX: should not be but sometimes it is, see the test captures */ 82 if (type == 0) 83 return; 84 ND_PRINT("\n\t%s (0x%04x) TLV, length %u", 85 tok2str(dtp_tlv_values, "Unknown", type), 86 type, len); 87 88 /* infinite loop check */ 89 if (len < 4 || len > length) { 90 ND_PRINT("[TLV length %u]", len); 91 goto invalid; 92 } 93 94 switch (type) { 95 case DTP_DOMAIN_TLV: 96 ND_PRINT(", "); 97 nd_printjnp(ndo, tptr+4, len-4); 98 break; 99 100 case DTP_STATUS_TLV: 101 case DTP_DTP_TYPE_TLV: 102 if (len != 5) 103 goto invalid; 104 ND_PRINT(", 0x%x", GET_U_1(tptr + 4)); 105 break; 106 107 case DTP_NEIGHBOR_TLV: 108 if (len != 10) 109 goto invalid; 110 ND_PRINT(", %s", GET_ETHERADDR_STRING(tptr+4)); 111 break; 112 113 default: 114 ND_TCHECK_LEN(tptr, len); 115 break; 116 } 117 tptr += len; 118 length -= len; 119 } 120 return; 121 122 invalid: 123 nd_print_invalid(ndo); 124 ND_TCHECK_LEN(tptr, length); 125 } 126