xref: /netbsd-src/external/bsd/tcpdump/dist/print-dtp.c (revision 26ba0b503b498a5194a71ac319838b7f5497f3fe)
10f74e101Schristos /*
20f74e101Schristos  * Copyright (c) 1998-2007 The TCPDUMP project
30f74e101Schristos  *
40f74e101Schristos  * Redistribution and use in source and binary forms, with or without
50f74e101Schristos  * modification, are permitted provided that: (1) source code
60f74e101Schristos  * distributions retain the above copyright notice and this paragraph
70f74e101Schristos  * in its entirety, and (2) distributions including binary code include
80f74e101Schristos  * the above copyright notice and this paragraph in its entirety in
90f74e101Schristos  * the documentation or other materials provided with the distribution.
100f74e101Schristos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
110f74e101Schristos  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
120f74e101Schristos  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
130f74e101Schristos  * FOR A PARTICULAR PURPOSE.
140f74e101Schristos  *
150f74e101Schristos  * Original code by Carles Kishimoto <carles.kishimoto@gmail.com>
160f74e101Schristos  */
170f74e101Schristos 
18dc860a36Sspz /* \summary: Dynamic Trunking Protocol (DTP) printer */
19dc860a36Sspz 
20fdccd7e4Schristos #include <sys/cdefs.h>
21fdccd7e4Schristos #ifndef lint
22*26ba0b50Schristos __RCSID("$NetBSD: print-dtp.c,v 1.5 2024/09/02 16:15:31 christos Exp $");
23fdccd7e4Schristos #endif
24fdccd7e4Schristos 
25c74ad251Schristos #include <config.h>
260f74e101Schristos 
27c74ad251Schristos #include "netdissect-stdinc.h"
280f74e101Schristos 
29c74ad251Schristos #define ND_LONGJMP_FROM_TCHECK
30784088dfSchristos #include "netdissect.h"
310f74e101Schristos #include "addrtoname.h"
320f74e101Schristos #include "extract.h"
330f74e101Schristos 
34784088dfSchristos 
350f74e101Schristos #define DTP_HEADER_LEN			1
360f74e101Schristos #define DTP_DOMAIN_TLV			0x0001
370f74e101Schristos #define DTP_STATUS_TLV			0x0002
380f74e101Schristos #define DTP_DTP_TYPE_TLV		0x0003
390f74e101Schristos #define DTP_NEIGHBOR_TLV		0x0004
400f74e101Schristos 
41026d7285Schristos static const struct tok dtp_tlv_values[] = {
42c74ad251Schristos     { DTP_DOMAIN_TLV, "Domain" },
43c74ad251Schristos     { DTP_STATUS_TLV, "Status" },
44c74ad251Schristos     { DTP_DTP_TYPE_TLV, "DTP type" },
45c74ad251Schristos     { DTP_NEIGHBOR_TLV, "Neighbor" },
460f74e101Schristos     { 0, NULL}
470f74e101Schristos };
480f74e101Schristos 
490f74e101Schristos void
50c74ad251Schristos dtp_print(netdissect_options *ndo, const u_char *tptr, u_int length)
510f74e101Schristos {
52c74ad251Schristos     ndo->ndo_protocol = "dtp";
53c74ad251Schristos     if (length < DTP_HEADER_LEN) {
54c74ad251Schristos         ND_PRINT("[zero packet length]");
55c74ad251Schristos         goto invalid;
56c74ad251Schristos     }
570f74e101Schristos 
58c74ad251Schristos     ND_PRINT("DTPv%u, length %u",
59c74ad251Schristos            GET_U_1(tptr),
60c74ad251Schristos            length);
610f74e101Schristos 
620f74e101Schristos     /*
630f74e101Schristos      * In non-verbose mode, just print version.
640f74e101Schristos      */
65c47fd378Schristos     if (ndo->ndo_vflag < 1) {
660f74e101Schristos 	return;
670f74e101Schristos     }
680f74e101Schristos 
690f74e101Schristos     tptr += DTP_HEADER_LEN;
70c74ad251Schristos     length -= DTP_HEADER_LEN;
710f74e101Schristos 
72c74ad251Schristos     while (length) {
73c74ad251Schristos         uint16_t type, len;
740f74e101Schristos 
75c74ad251Schristos         if (length < 4) {
76c74ad251Schristos             ND_PRINT("[%u bytes remaining]", length);
77c74ad251Schristos             goto invalid;
78c74ad251Schristos         }
79c74ad251Schristos 	type = GET_BE_U_2(tptr);
80c74ad251Schristos         len  = GET_BE_U_2(tptr + 2);
81784088dfSchristos        /* XXX: should not be but sometimes it is, see the test captures */
82784088dfSchristos         if (type == 0)
830f74e101Schristos             return;
84c74ad251Schristos         ND_PRINT("\n\t%s (0x%04x) TLV, length %u",
850f74e101Schristos                tok2str(dtp_tlv_values, "Unknown", type),
86c74ad251Schristos                type, len);
870f74e101Schristos 
88784088dfSchristos         /* infinite loop check */
89c74ad251Schristos         if (len < 4 || len > length) {
90*26ba0b50Schristos             ND_PRINT("[TLV length %u]", len);
91784088dfSchristos             goto invalid;
92c74ad251Schristos         }
93784088dfSchristos 
940f74e101Schristos         switch (type) {
950f74e101Schristos 	case DTP_DOMAIN_TLV:
96c74ad251Schristos 		ND_PRINT(", ");
97c74ad251Schristos 		nd_printjnp(ndo, tptr+4, len-4);
980f74e101Schristos 		break;
990f74e101Schristos 
1000f74e101Schristos 	case DTP_STATUS_TLV:
1010f74e101Schristos 	case DTP_DTP_TYPE_TLV:
102c74ad251Schristos                 if (len != 5)
103784088dfSchristos                     goto invalid;
104c74ad251Schristos                 ND_PRINT(", 0x%x", GET_U_1(tptr + 4));
1050f74e101Schristos                 break;
1060f74e101Schristos 
1070f74e101Schristos 	case DTP_NEIGHBOR_TLV:
108c74ad251Schristos                 if (len != 10)
109784088dfSchristos                     goto invalid;
110c74ad251Schristos                 ND_PRINT(", %s", GET_ETHERADDR_STRING(tptr+4));
1110f74e101Schristos                 break;
1120f74e101Schristos 
1130f74e101Schristos         default:
114c74ad251Schristos             ND_TCHECK_LEN(tptr, len);
1150f74e101Schristos             break;
1160f74e101Schristos         }
1170f74e101Schristos         tptr += len;
118c74ad251Schristos         length -= len;
1190f74e101Schristos     }
1200f74e101Schristos     return;
1210f74e101Schristos 
122784088dfSchristos  invalid:
123c74ad251Schristos     nd_print_invalid(ndo);
124c74ad251Schristos     ND_TCHECK_LEN(tptr, length);
1250f74e101Schristos }
126