xref: /freebsd-src/contrib/tcpdump/print-dtp.c (revision 0a7e5f1f02aad2ff5fff1c60f44c6975fd07e1d9)
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