xref: /netbsd-src/external/bsd/tcpdump/dist/print-loopback.c (revision 26ba0b503b498a5194a71ac319838b7f5497f3fe)
1c47fd378Schristos /*
2c47fd378Schristos  * Copyright (c) 2014 The TCPDUMP project
3c47fd378Schristos  * All rights reserved.
4c47fd378Schristos  *
5c47fd378Schristos  * Redistribution and use in source and binary forms, with or without
6c47fd378Schristos  * modification, are permitted provided that the following conditions
7c47fd378Schristos  * are met:
8c47fd378Schristos  * 1. Redistributions of source code must retain the above copyright
9c47fd378Schristos  *    notice, this list of conditions and the following disclaimer.
10c47fd378Schristos  * 2. Redistributions in binary form must reproduce the above copyright
11c47fd378Schristos  *    notice, this list of conditions and the following disclaimer in the
12c47fd378Schristos  *    documentation and/or other materials provided with the distribution.
13c47fd378Schristos  *
14c47fd378Schristos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15c47fd378Schristos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16c47fd378Schristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17c47fd378Schristos  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
18c47fd378Schristos  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19c47fd378Schristos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20c47fd378Schristos  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21c47fd378Schristos  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22c47fd378Schristos  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23c47fd378Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24c47fd378Schristos  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25c47fd378Schristos  * POSSIBILITY OF SUCH DAMAGE.
26c47fd378Schristos  */
27c47fd378Schristos 
28b3a00663Schristos #include <sys/cdefs.h>
29b3a00663Schristos #ifndef lint
30*26ba0b50Schristos __RCSID("$NetBSD: print-loopback.c,v 1.6 2024/09/02 16:15:32 christos Exp $");
31b3a00663Schristos #endif
32b3a00663Schristos 
33dc860a36Sspz /* \summary: Loopback Protocol printer */
34dc860a36Sspz 
35dc860a36Sspz /*
36dc860a36Sspz  * originally defined as the Ethernet Configuration Testing Protocol.
37*26ba0b50Schristos  * specification:
38*26ba0b50Schristos  * https://web.archive.org/web/20060919181108/http://www.mit.edu/people/jhawk/ctp.pdf
39dc860a36Sspz  */
40dc860a36Sspz 
41c74ad251Schristos #include <config.h>
42c47fd378Schristos 
43c74ad251Schristos #include "netdissect-stdinc.h"
44c47fd378Schristos 
45c74ad251Schristos #define ND_LONGJMP_FROM_TCHECK
46fdccd7e4Schristos #include "netdissect.h"
47c47fd378Schristos #include "extract.h"
48c47fd378Schristos #include "addrtoname.h"
49c47fd378Schristos 
50c47fd378Schristos 
51c47fd378Schristos #define LOOPBACK_REPLY   1
52c47fd378Schristos #define LOOPBACK_FWDDATA 2
53c47fd378Schristos 
54c47fd378Schristos static const struct tok fcode_str[] = {
55c47fd378Schristos 	{ LOOPBACK_REPLY,   "Reply"        },
56c47fd378Schristos 	{ LOOPBACK_FWDDATA, "Forward Data" },
57c47fd378Schristos 	{ 0, NULL }
58c47fd378Schristos };
59c47fd378Schristos 
60c47fd378Schristos static void
61c74ad251Schristos loopback_message_print(netdissect_options *ndo,
62c74ad251Schristos                        const u_char *cp, u_int len)
63c47fd378Schristos {
64c47fd378Schristos 	uint16_t function;
65c47fd378Schristos 
66c47fd378Schristos 	if (len < 2)
67fdccd7e4Schristos 		goto invalid;
68c47fd378Schristos 	/* function */
69c74ad251Schristos 	function = GET_LE_U_2(cp);
70c47fd378Schristos 	cp += 2;
71c74ad251Schristos 	len -= 2;
72c74ad251Schristos 	ND_PRINT(", %s", tok2str(fcode_str, " invalid (%u)", function));
73c47fd378Schristos 
74c47fd378Schristos 	switch (function) {
75c47fd378Schristos 		case LOOPBACK_REPLY:
76c74ad251Schristos 			if (len < 2)
77fdccd7e4Schristos 				goto invalid;
78c47fd378Schristos 			/* receipt number */
79c74ad251Schristos 			ND_PRINT(", receipt number %u", GET_LE_U_2(cp));
80c47fd378Schristos 			cp += 2;
81c74ad251Schristos 			len -= 2;
82c47fd378Schristos 			/* data */
83c74ad251Schristos 			ND_PRINT(", data (%u octets)", len);
84c74ad251Schristos 			ND_TCHECK_LEN(cp, len);
85c47fd378Schristos 			break;
86c47fd378Schristos 		case LOOPBACK_FWDDATA:
87c74ad251Schristos 			if (len < MAC_ADDR_LEN)
88fdccd7e4Schristos 				goto invalid;
89c47fd378Schristos 			/* forwarding address */
90c74ad251Schristos 			ND_PRINT(", forwarding address %s", GET_ETHERADDR_STRING(cp));
91c74ad251Schristos 			cp += MAC_ADDR_LEN;
92c74ad251Schristos 			len -= MAC_ADDR_LEN;
93c47fd378Schristos 			/* data */
94c74ad251Schristos 			ND_PRINT(", data (%u octets)", len);
95c74ad251Schristos 			ND_TCHECK_LEN(cp, len);
96c47fd378Schristos 			break;
97c47fd378Schristos 		default:
98c74ad251Schristos 			ND_TCHECK_LEN(cp, len);
99c47fd378Schristos 			break;
100c47fd378Schristos 	}
101c47fd378Schristos 	return;
102c47fd378Schristos 
103fdccd7e4Schristos invalid:
104c74ad251Schristos 	nd_print_invalid(ndo);
105c74ad251Schristos 	ND_TCHECK_LEN(cp, len);
106c47fd378Schristos }
107c47fd378Schristos 
108c47fd378Schristos void
109c74ad251Schristos loopback_print(netdissect_options *ndo,
110c74ad251Schristos                const u_char *cp, u_int len)
111c47fd378Schristos {
112c47fd378Schristos 	uint16_t skipCount;
113c47fd378Schristos 
114c74ad251Schristos 	ndo->ndo_protocol = "loopback";
115c74ad251Schristos 	ND_PRINT("Loopback");
116c47fd378Schristos 	if (len < 2)
117fdccd7e4Schristos 		goto invalid;
118c47fd378Schristos 	/* skipCount */
119c74ad251Schristos 	skipCount = GET_LE_U_2(cp);
120c47fd378Schristos 	cp += 2;
121c74ad251Schristos 	len -= 2;
122c74ad251Schristos 	ND_PRINT(", skipCount %u", skipCount);
123c47fd378Schristos 	if (skipCount % 8)
124c74ad251Schristos 		ND_PRINT(" (bogus)");
125c74ad251Schristos 	if (skipCount > len)
126fdccd7e4Schristos 		goto invalid;
127c74ad251Schristos 	/* the octets to skip */
128c74ad251Schristos 	ND_TCHECK_LEN(cp, skipCount);
129c74ad251Schristos 	cp += skipCount;
130c74ad251Schristos 	len -= skipCount;
131c74ad251Schristos 	/* the first message to decode */
132c74ad251Schristos 	loopback_message_print(ndo, cp, len);
133c47fd378Schristos 	return;
134c47fd378Schristos 
135fdccd7e4Schristos invalid:
136c74ad251Schristos 	nd_print_invalid(ndo);
137c74ad251Schristos 	ND_TCHECK_LEN(cp, len);
138c47fd378Schristos }
139c47fd378Schristos 
140