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