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