1411677aeSAaron LI /*
2411677aeSAaron LI * Copyright (c) 2014 The TCPDUMP project
3411677aeSAaron LI * All rights reserved.
4411677aeSAaron LI *
5411677aeSAaron LI * Redistribution and use in source and binary forms, with or without
6411677aeSAaron LI * modification, are permitted provided that the following conditions
7411677aeSAaron LI * are met:
8411677aeSAaron LI * 1. Redistributions of source code must retain the above copyright
9411677aeSAaron LI * notice, this list of conditions and the following disclaimer.
10411677aeSAaron LI * 2. Redistributions in binary form must reproduce the above copyright
11411677aeSAaron LI * notice, this list of conditions and the following disclaimer in the
12411677aeSAaron LI * documentation and/or other materials provided with the distribution.
13411677aeSAaron LI *
14411677aeSAaron LI * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15411677aeSAaron LI * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16411677aeSAaron LI * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17411677aeSAaron LI * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
18411677aeSAaron LI * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19411677aeSAaron LI * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20411677aeSAaron LI * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21411677aeSAaron LI * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22411677aeSAaron LI * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23411677aeSAaron LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24411677aeSAaron LI * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25411677aeSAaron LI * POSSIBILITY OF SUCH DAMAGE.
26411677aeSAaron LI */
27411677aeSAaron LI
28411677aeSAaron LI /* \summary: Loopback Protocol printer */
29411677aeSAaron LI
30411677aeSAaron LI /*
31411677aeSAaron LI * originally defined as the Ethernet Configuration Testing Protocol.
32*ed775ee7SAntonio Huete Jimenez * specification: https://www.mit.edu/people/jhawk/ctp.pdf
33411677aeSAaron LI */
34411677aeSAaron LI
35411677aeSAaron LI #ifdef HAVE_CONFIG_H
36*ed775ee7SAntonio Huete Jimenez #include <config.h>
37411677aeSAaron LI #endif
38411677aeSAaron LI
39*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
40411677aeSAaron LI
41*ed775ee7SAntonio Huete Jimenez #define ND_LONGJMP_FROM_TCHECK
42411677aeSAaron LI #include "netdissect.h"
43411677aeSAaron LI #include "extract.h"
44411677aeSAaron LI #include "addrtoname.h"
45411677aeSAaron LI
46411677aeSAaron LI
47411677aeSAaron LI #define LOOPBACK_REPLY 1
48411677aeSAaron LI #define LOOPBACK_FWDDATA 2
49411677aeSAaron LI
50411677aeSAaron LI static const struct tok fcode_str[] = {
51411677aeSAaron LI { LOOPBACK_REPLY, "Reply" },
52411677aeSAaron LI { LOOPBACK_FWDDATA, "Forward Data" },
53411677aeSAaron LI { 0, NULL }
54411677aeSAaron LI };
55411677aeSAaron LI
56411677aeSAaron LI static void
loopback_message_print(netdissect_options * ndo,const u_char * cp,u_int len)57*ed775ee7SAntonio Huete Jimenez loopback_message_print(netdissect_options *ndo,
58*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
59411677aeSAaron LI {
60411677aeSAaron LI uint16_t function;
61411677aeSAaron LI
62411677aeSAaron LI if (len < 2)
63411677aeSAaron LI goto invalid;
64411677aeSAaron LI /* function */
65*ed775ee7SAntonio Huete Jimenez function = GET_LE_U_2(cp);
66411677aeSAaron LI cp += 2;
67*ed775ee7SAntonio Huete Jimenez len -= 2;
68*ed775ee7SAntonio Huete Jimenez ND_PRINT(", %s", tok2str(fcode_str, " invalid (%u)", function));
69411677aeSAaron LI
70411677aeSAaron LI switch (function) {
71411677aeSAaron LI case LOOPBACK_REPLY:
72*ed775ee7SAntonio Huete Jimenez if (len < 2)
73411677aeSAaron LI goto invalid;
74411677aeSAaron LI /* receipt number */
75*ed775ee7SAntonio Huete Jimenez ND_PRINT(", receipt number %u", GET_LE_U_2(cp));
76411677aeSAaron LI cp += 2;
77*ed775ee7SAntonio Huete Jimenez len -= 2;
78411677aeSAaron LI /* data */
79*ed775ee7SAntonio Huete Jimenez ND_PRINT(", data (%u octets)", len);
80*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
81411677aeSAaron LI break;
82411677aeSAaron LI case LOOPBACK_FWDDATA:
83*ed775ee7SAntonio Huete Jimenez if (len < MAC_ADDR_LEN)
84411677aeSAaron LI goto invalid;
85411677aeSAaron LI /* forwarding address */
86*ed775ee7SAntonio Huete Jimenez ND_PRINT(", forwarding address %s", GET_ETHERADDR_STRING(cp));
87*ed775ee7SAntonio Huete Jimenez cp += MAC_ADDR_LEN;
88*ed775ee7SAntonio Huete Jimenez len -= MAC_ADDR_LEN;
89411677aeSAaron LI /* data */
90*ed775ee7SAntonio Huete Jimenez ND_PRINT(", data (%u octets)", len);
91*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
92411677aeSAaron LI break;
93411677aeSAaron LI default:
94*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
95411677aeSAaron LI break;
96411677aeSAaron LI }
97411677aeSAaron LI return;
98411677aeSAaron LI
99411677aeSAaron LI invalid:
100*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
101*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
102411677aeSAaron LI }
103411677aeSAaron LI
104411677aeSAaron LI void
loopback_print(netdissect_options * ndo,const u_char * cp,u_int len)105*ed775ee7SAntonio Huete Jimenez loopback_print(netdissect_options *ndo,
106*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
107411677aeSAaron LI {
108411677aeSAaron LI uint16_t skipCount;
109411677aeSAaron LI
110*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "loopback";
111*ed775ee7SAntonio Huete Jimenez ND_PRINT("Loopback");
112411677aeSAaron LI if (len < 2)
113411677aeSAaron LI goto invalid;
114411677aeSAaron LI /* skipCount */
115*ed775ee7SAntonio Huete Jimenez skipCount = GET_LE_U_2(cp);
116411677aeSAaron LI cp += 2;
117*ed775ee7SAntonio Huete Jimenez len -= 2;
118*ed775ee7SAntonio Huete Jimenez ND_PRINT(", skipCount %u", skipCount);
119411677aeSAaron LI if (skipCount % 8)
120*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (bogus)");
121*ed775ee7SAntonio Huete Jimenez if (skipCount > len)
122411677aeSAaron LI goto invalid;
123*ed775ee7SAntonio Huete Jimenez /* the octets to skip */
124*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, skipCount);
125*ed775ee7SAntonio Huete Jimenez cp += skipCount;
126*ed775ee7SAntonio Huete Jimenez len -= skipCount;
127*ed775ee7SAntonio Huete Jimenez /* the first message to decode */
128*ed775ee7SAntonio Huete Jimenez loopback_message_print(ndo, cp, len);
129411677aeSAaron LI return;
130411677aeSAaron LI
131411677aeSAaron LI invalid:
132*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
133*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
134411677aeSAaron LI }
135411677aeSAaron LI
136