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