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