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: https://www.mit.edu/people/jhawk/ctp.pdf 33 */ 34 35 #ifdef HAVE_CONFIG_H 36 #include <config.h> 37 #endif 38 39 #include "netdissect-stdinc.h" 40 41 #define ND_LONGJMP_FROM_TCHECK 42 #include "netdissect.h" 43 #include "extract.h" 44 #include "addrtoname.h" 45 46 47 #define LOOPBACK_REPLY 1 48 #define LOOPBACK_FWDDATA 2 49 50 static const struct tok fcode_str[] = { 51 { LOOPBACK_REPLY, "Reply" }, 52 { LOOPBACK_FWDDATA, "Forward Data" }, 53 { 0, NULL } 54 }; 55 56 static void 57 loopback_message_print(netdissect_options *ndo, 58 const u_char *cp, u_int len) 59 { 60 uint16_t function; 61 62 if (len < 2) 63 goto invalid; 64 /* function */ 65 function = GET_LE_U_2(cp); 66 cp += 2; 67 len -= 2; 68 ND_PRINT(", %s", tok2str(fcode_str, " invalid (%u)", function)); 69 70 switch (function) { 71 case LOOPBACK_REPLY: 72 if (len < 2) 73 goto invalid; 74 /* receipt number */ 75 ND_PRINT(", receipt number %u", GET_LE_U_2(cp)); 76 cp += 2; 77 len -= 2; 78 /* data */ 79 ND_PRINT(", data (%u octets)", len); 80 ND_TCHECK_LEN(cp, len); 81 break; 82 case LOOPBACK_FWDDATA: 83 if (len < MAC_ADDR_LEN) 84 goto invalid; 85 /* forwarding address */ 86 ND_PRINT(", forwarding address %s", GET_ETHERADDR_STRING(cp)); 87 cp += MAC_ADDR_LEN; 88 len -= MAC_ADDR_LEN; 89 /* data */ 90 ND_PRINT(", data (%u octets)", len); 91 ND_TCHECK_LEN(cp, len); 92 break; 93 default: 94 ND_TCHECK_LEN(cp, len); 95 break; 96 } 97 return; 98 99 invalid: 100 nd_print_invalid(ndo); 101 ND_TCHECK_LEN(cp, len); 102 } 103 104 void 105 loopback_print(netdissect_options *ndo, 106 const u_char *cp, u_int len) 107 { 108 uint16_t skipCount; 109 110 ndo->ndo_protocol = "loopback"; 111 ND_PRINT("Loopback"); 112 if (len < 2) 113 goto invalid; 114 /* skipCount */ 115 skipCount = GET_LE_U_2(cp); 116 cp += 2; 117 len -= 2; 118 ND_PRINT(", skipCount %u", skipCount); 119 if (skipCount % 8) 120 ND_PRINT(" (bogus)"); 121 if (skipCount > len) 122 goto invalid; 123 /* the octets to skip */ 124 ND_TCHECK_LEN(cp, skipCount); 125 cp += skipCount; 126 len -= skipCount; 127 /* the first message to decode */ 128 loopback_message_print(ndo, cp, len); 129 return; 130 131 invalid: 132 nd_print_invalid(ndo); 133 ND_TCHECK_LEN(cp, len); 134 } 135 136