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