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