[63704] | 1 | /* $Id: VBoxPktDmp.h 98103 2023-01-17 14:15:46Z vboxsync $ */
|
---|
| 2 | /** @file
|
---|
| 3 | * VBoxPktDmp.h - Dump Ethernet frame into debug log.
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2016-2023 Oracle and/or its affiliates.
|
---|
[63704] | 8 | *
|
---|
[96407] | 9 | * This file is part of VirtualBox base platform packages, as
|
---|
| 10 | * available from https://www.virtualbox.org.
|
---|
[63704] | 11 | *
|
---|
[96407] | 12 | * This program is free software; you can redistribute it and/or
|
---|
| 13 | * modify it under the terms of the GNU General Public License
|
---|
| 14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
| 15 | * License.
|
---|
| 16 | *
|
---|
| 17 | * This program is distributed in the hope that it will be useful, but
|
---|
| 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 20 | * General Public License for more details.
|
---|
| 21 | *
|
---|
| 22 | * You should have received a copy of the GNU General Public License
|
---|
| 23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
| 24 | *
|
---|
[63704] | 25 | * The contents of this file may alternatively be used under the terms
|
---|
| 26 | * of the Common Development and Distribution License Version 1.0
|
---|
[96407] | 27 | * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
|
---|
| 28 | * in the VirtualBox distribution, in which case the provisions of the
|
---|
[63704] | 29 | * CDDL are applicable instead of those of the GPL.
|
---|
| 30 | *
|
---|
| 31 | * You may elect to license modified versions of this file under the
|
---|
| 32 | * terms and conditions of either the GPL or the CDDL or both.
|
---|
[96407] | 33 | *
|
---|
| 34 | * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
|
---|
[63704] | 35 | */
|
---|
| 36 |
|
---|
[76558] | 37 | #ifndef VBOX_INCLUDED_VBoxPktDmp_h
|
---|
| 38 | #define VBOX_INCLUDED_VBoxPktDmp_h
|
---|
[76507] | 39 | #ifndef RT_WITHOUT_PRAGMA_ONCE
|
---|
| 40 | # pragma once
|
---|
| 41 | #endif
|
---|
[63704] | 42 |
|
---|
[68670] | 43 | #include <iprt/net.h>
|
---|
| 44 | #include <iprt/log.h>
|
---|
| 45 | #if defined(LOG_ENABLED) && !defined(VBOX_DEVICE_STRUCT_TESTCASE)
|
---|
| 46 | # include <iprt/asm.h>
|
---|
| 47 | #endif
|
---|
| 48 |
|
---|
| 49 |
|
---|
[63704] | 50 | DECLINLINE(const char *) vboxEthTypeStr(uint16_t uType)
|
---|
| 51 | {
|
---|
| 52 | switch (uType)
|
---|
| 53 | {
|
---|
| 54 | case RTNET_ETHERTYPE_IPV4: return "IP";
|
---|
| 55 | case RTNET_ETHERTYPE_IPV6: return "IPv6";
|
---|
| 56 | case RTNET_ETHERTYPE_ARP: return "ARP";
|
---|
| 57 | }
|
---|
| 58 | return "unknown";
|
---|
| 59 | }
|
---|
| 60 |
|
---|
| 61 |
|
---|
[82681] | 62 | DECLINLINE(void) vboxEthPacketDump(const char *pcszInstance, const char *pcszText, const uint8_t *pcPacket, uint32_t cb)
|
---|
[63704] | 63 | {
|
---|
| 64 | #if defined(LOG_ENABLED) && !defined(VBOX_DEVICE_STRUCT_TESTCASE)
|
---|
| 65 | AssertReturnVoid(cb >= 14);
|
---|
| 66 |
|
---|
| 67 | const uint8_t *pHdr = pcPacket;
|
---|
| 68 | const uint8_t *pEnd = pcPacket + cb;
|
---|
| 69 | AssertReturnVoid(pEnd - pHdr >= 14);
|
---|
| 70 | uint16_t uEthType = RT_N2H_U16(*(uint16_t*)(pHdr+12));
|
---|
| 71 | Log2(("%s: %s (%d bytes), %RTmac => %RTmac, EthType=%s(0x%x)\n", pcszInstance,
|
---|
| 72 | pcszText, cb, pHdr+6, pHdr, vboxEthTypeStr(uEthType), uEthType));
|
---|
| 73 | pHdr += sizeof(RTNETETHERHDR);
|
---|
| 74 | if (uEthType == RTNET_ETHERTYPE_VLAN)
|
---|
| 75 | {
|
---|
| 76 | AssertReturnVoid(pEnd - pHdr >= 4);
|
---|
| 77 | uEthType = RT_N2H_U16(*(uint16_t*)(pHdr+2));
|
---|
| 78 | Log2((" + VLAN: id=%d EthType=%s(0x%x)\n", RT_N2H_U16(*(uint16_t*)(pHdr)) & 0xFFF,
|
---|
| 79 | vboxEthTypeStr(uEthType), uEthType));
|
---|
| 80 | pHdr += 2 * sizeof(uint16_t);
|
---|
| 81 | }
|
---|
| 82 | uint8_t uProto = 0xFF;
|
---|
| 83 | switch (uEthType)
|
---|
| 84 | {
|
---|
| 85 | case RTNET_ETHERTYPE_IPV6:
|
---|
| 86 | AssertReturnVoid(pEnd - pHdr >= 40);
|
---|
| 87 | uProto = pHdr[6];
|
---|
| 88 | Log2((" + IPv6: %RTnaipv6 => %RTnaipv6\n", pHdr+8, pHdr+24));
|
---|
| 89 | pHdr += 40;
|
---|
| 90 | break;
|
---|
| 91 | case RTNET_ETHERTYPE_IPV4:
|
---|
| 92 | AssertReturnVoid(pEnd - pHdr >= 20);
|
---|
| 93 | uProto = pHdr[9];
|
---|
| 94 | Log2((" + IP: %RTnaipv4 => %RTnaipv4\n", *(uint32_t*)(pHdr+12), *(uint32_t*)(pHdr+16)));
|
---|
| 95 | pHdr += (pHdr[0] & 0xF) * 4;
|
---|
| 96 | break;
|
---|
| 97 | case RTNET_ETHERTYPE_ARP:
|
---|
| 98 | AssertReturnVoid(pEnd - pHdr >= 28);
|
---|
| 99 | AssertReturnVoid(RT_N2H_U16(*(uint16_t*)(pHdr+2)) == RTNET_ETHERTYPE_IPV4);
|
---|
| 100 | switch (RT_N2H_U16(*(uint16_t*)(pHdr+6)))
|
---|
| 101 | {
|
---|
| 102 | case 1: /* ARP request */
|
---|
| 103 | Log2((" + ARP-REQ: who-has %RTnaipv4 tell %RTnaipv4\n",
|
---|
| 104 | *(uint32_t*)(pHdr+24), *(uint32_t*)(pHdr+14)));
|
---|
| 105 | break;
|
---|
| 106 | case 2: /* ARP reply */
|
---|
| 107 | Log2((" + ARP-RPL: %RTnaipv4 is-at %RTmac\n",
|
---|
| 108 | *(uint32_t*)(pHdr+14), pHdr+8));
|
---|
| 109 | break;
|
---|
| 110 | default:
|
---|
| 111 | Log2((" + ARP: unknown op %d\n", RT_N2H_U16(*(uint16_t*)(pHdr+6))));
|
---|
| 112 | break;
|
---|
| 113 | }
|
---|
| 114 | break;
|
---|
| 115 | /* There is no default case as uProto is initialized with 0xFF */
|
---|
| 116 | }
|
---|
| 117 | while (uProto != 0xFF)
|
---|
| 118 | {
|
---|
| 119 | switch (uProto)
|
---|
| 120 | {
|
---|
| 121 | case 0: /* IPv6 Hop-by-Hop option*/
|
---|
| 122 | case 60: /* IPv6 Destination option*/
|
---|
| 123 | case 43: /* IPv6 Routing option */
|
---|
| 124 | case 44: /* IPv6 Fragment option */
|
---|
| 125 | Log2((" + IPv6 option (%d): <not implemented>\n", uProto));
|
---|
| 126 | uProto = pHdr[0];
|
---|
| 127 | pHdr += pHdr[1] * 8 + 8; /* Skip to the next extension/protocol */
|
---|
| 128 | break;
|
---|
| 129 | case 51: /* IPv6 IPsec AH */
|
---|
| 130 | Log2((" + IPv6 IPsec AH: <not implemented>\n"));
|
---|
| 131 | uProto = pHdr[0];
|
---|
| 132 | pHdr += (pHdr[1] + 2) * 4; /* Skip to the next extension/protocol */
|
---|
| 133 | break;
|
---|
| 134 | case 50: /* IPv6 IPsec ESP */
|
---|
| 135 | /* Cannot decode IPsec, fall through */
|
---|
| 136 | Log2((" + IPv6 IPsec ESP: <not implemented>\n"));
|
---|
| 137 | uProto = 0xFF;
|
---|
| 138 | break;
|
---|
| 139 | case 59: /* No Next Header */
|
---|
| 140 | Log2((" + IPv6 No Next Header\n"));
|
---|
| 141 | uProto = 0xFF;
|
---|
| 142 | break;
|
---|
| 143 | case 58: /* IPv6-ICMP */
|
---|
| 144 | switch (pHdr[0])
|
---|
| 145 | {
|
---|
| 146 | case 1: Log2((" + IPv6-ICMP: destination unreachable, code %d\n", pHdr[1])); break;
|
---|
| 147 | case 128: Log2((" + IPv6-ICMP: echo request\n")); break;
|
---|
| 148 | case 129: Log2((" + IPv6-ICMP: echo reply\n")); break;
|
---|
| 149 | default: Log2((" + IPv6-ICMP: unknown type %d, code %d\n", pHdr[0], pHdr[1])); break;
|
---|
| 150 | }
|
---|
| 151 | uProto = 0xFF;
|
---|
| 152 | break;
|
---|
| 153 | case 1: /* ICMP */
|
---|
| 154 | switch (pHdr[0])
|
---|
| 155 | {
|
---|
| 156 | case 0: Log2((" + ICMP: echo reply\n")); break;
|
---|
| 157 | case 8: Log2((" + ICMP: echo request\n")); break;
|
---|
| 158 | case 3: Log2((" + ICMP: destination unreachable, code %d\n", pHdr[1])); break;
|
---|
| 159 | default: Log2((" + ICMP: unknown type %d, code %d\n", pHdr[0], pHdr[1])); break;
|
---|
| 160 | }
|
---|
| 161 | uProto = 0xFF;
|
---|
| 162 | break;
|
---|
| 163 | case 6: /* TCP */
|
---|
| 164 | Log2((" + TCP: src=%d dst=%d seq=%x ack=%x\n",
|
---|
| 165 | RT_N2H_U16(*(uint16_t*)(pHdr)), RT_N2H_U16(*(uint16_t*)(pHdr+2)),
|
---|
| 166 | RT_N2H_U32(*(uint32_t*)(pHdr+4)), RT_N2H_U32(*(uint32_t*)(pHdr+8))));
|
---|
| 167 | uProto = 0xFF;
|
---|
| 168 | break;
|
---|
| 169 | case 17: /* UDP */
|
---|
| 170 | Log2((" + UDP: src=%d dst=%d\n",
|
---|
| 171 | RT_N2H_U16(*(uint16_t*)(pHdr)), RT_N2H_U16(*(uint16_t*)(pHdr+2))));
|
---|
| 172 | uProto = 0xFF;
|
---|
| 173 | break;
|
---|
| 174 | default:
|
---|
| 175 | Log2((" + Unknown: proto=0x%x\n", uProto));
|
---|
| 176 | uProto = 0xFF;
|
---|
| 177 | break;
|
---|
| 178 | }
|
---|
| 179 | }
|
---|
| 180 | Log3(("%.*Rhxd\n", cb, pcPacket));
|
---|
| 181 | #else
|
---|
| 182 | RT_NOREF4(pcszInstance, pcszText, pcPacket, cb);
|
---|
| 183 | #endif
|
---|
| 184 | }
|
---|
| 185 |
|
---|
[76585] | 186 | #endif /* !VBOX_INCLUDED_VBoxPktDmp_h */
|
---|