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