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