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