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 #ifdef HAVE_CONFIG_H 21 #include <config.h> 22 #endif 23 24 #include "netdissect-stdinc.h" 25 26 #define ND_LONGJMP_FROM_TCHECK 27 #include "netdissect.h" 28 #include "addrtoname.h" 29 #include "extract.h" 30 31 32 #define DTP_HEADER_LEN 1 33 #define DTP_DOMAIN_TLV 0x0001 34 #define DTP_STATUS_TLV 0x0002 35 #define DTP_DTP_TYPE_TLV 0x0003 36 #define DTP_NEIGHBOR_TLV 0x0004 37 38 static const struct tok dtp_tlv_values[] = { 39 { DTP_DOMAIN_TLV, "Domain" }, 40 { DTP_STATUS_TLV, "Status" }, 41 { DTP_DTP_TYPE_TLV, "DTP type" }, 42 { DTP_NEIGHBOR_TLV, "Neighbor" }, 43 { 0, NULL} 44 }; 45 46 void 47 dtp_print(netdissect_options *ndo, const u_char *tptr, u_int length) 48 { 49 ndo->ndo_protocol = "dtp"; 50 if (length < DTP_HEADER_LEN) { 51 ND_PRINT("[zero packet length]"); 52 goto invalid; 53 } 54 55 ND_PRINT("DTPv%u, length %u", 56 GET_U_1(tptr), 57 length); 58 59 /* 60 * In non-verbose mode, just print version. 61 */ 62 if (ndo->ndo_vflag < 1) { 63 return; 64 } 65 66 tptr += DTP_HEADER_LEN; 67 length -= DTP_HEADER_LEN; 68 69 while (length) { 70 uint16_t type, len; 71 72 if (length < 4) { 73 ND_PRINT("[%u bytes remaining]", length); 74 goto invalid; 75 } 76 type = GET_BE_U_2(tptr); 77 len = GET_BE_U_2(tptr + 2); 78 /* XXX: should not be but sometimes it is, see the test captures */ 79 if (type == 0) 80 return; 81 ND_PRINT("\n\t%s (0x%04x) TLV, length %u", 82 tok2str(dtp_tlv_values, "Unknown", type), 83 type, len); 84 85 /* infinite loop check */ 86 if (len < 4 || len > length) { 87 ND_PRINT("[invalid TLV length %u]", len); 88 goto invalid; 89 } 90 91 switch (type) { 92 case DTP_DOMAIN_TLV: 93 ND_PRINT(", "); 94 nd_printjnp(ndo, tptr+4, len-4); 95 break; 96 97 case DTP_STATUS_TLV: 98 case DTP_DTP_TYPE_TLV: 99 if (len != 5) 100 goto invalid; 101 ND_PRINT(", 0x%x", GET_U_1(tptr + 4)); 102 break; 103 104 case DTP_NEIGHBOR_TLV: 105 if (len != 10) 106 goto invalid; 107 ND_PRINT(", %s", GET_ETHERADDR_STRING(tptr+4)); 108 break; 109 110 default: 111 ND_TCHECK_LEN(tptr, len); 112 break; 113 } 114 tptr += len; 115 length -= len; 116 } 117 return; 118 119 invalid: 120 nd_print_invalid(ndo); 121 ND_TCHECK_LEN(tptr, length); 122 } 123