summaryrefslogtreecommitdiffstats
path: root/include/iprt/net.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/iprt/net.h')
-rw-r--r--include/iprt/net.h1064
1 files changed, 1064 insertions, 0 deletions
diff --git a/include/iprt/net.h b/include/iprt/net.h
new file mode 100644
index 00000000..8396fc60
--- /dev/null
+++ b/include/iprt/net.h
@@ -0,0 +1,1064 @@
+/** @file
+ * IPRT - Network Protocols.
+ */
+
+/*
+ * Copyright (C) 2008-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
+ * in the VirtualBox distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
+ */
+
+#ifndef IPRT_INCLUDED_net_h
+#define IPRT_INCLUDED_net_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/assert.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_net RTNet - Network Protocols
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Converts an stringified Ethernet MAC address into the RTMAC representation.
+ *
+ * @todo This should be move to some generic part of the runtime.
+ *
+ * @returns VINF_SUCCESS on success, VERR_GETOPT_INVALID_ARGUMENT_FORMAT on
+ * failure.
+ *
+ * @param pszAddr The address string to convert.
+ * @param pMacAddr Where to store the result.
+ */
+RTDECL(int) RTNetStrToMacAddr(const char *pszAddr, PRTMAC pMacAddr);
+
+/**
+ * IPv4 address.
+ */
+typedef RTUINT32U RTNETADDRIPV4;
+AssertCompileSize(RTNETADDRIPV4, 4);
+/** Pointer to a IPv4 address. */
+typedef RTNETADDRIPV4 *PRTNETADDRIPV4;
+/** Pointer to a const IPv4 address. */
+typedef RTNETADDRIPV4 const *PCRTNETADDRIPV4;
+
+/**
+ * Tests if the given string is an IPv4 address.
+ *
+ * @returns boolean.
+ * @param pcszAddr String which may be an IPv4 address.
+ */
+RTDECL(bool) RTNetIsIPv4AddrStr(const char *pcszAddr);
+
+/**
+ * Tests if the given string is a wildcard IPv4 address.
+ *
+ * @returns boolean.
+ * @param pcszAddr String which may be an IPv4 address.
+ */
+RTDECL(bool) RTNetStrIsIPv4AddrAny(const char *pcszAddr);
+
+/**
+ * Parses dotted-decimal IPv4 address into RTNETADDRIPV4 representation.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ * failure.
+ *
+ * @param pcszAddr The value to convert.
+ * @param ppszNext Where to store the pointer to the first char
+ * following the address. (Optional)
+ * @param pAddr Where to store the result.
+ */
+RTDECL(int) RTNetStrToIPv4AddrEx(const char *pcszAddr, PRTNETADDRIPV4 pAddr, char **ppszNext);
+
+/**
+ * Parses dotted-decimal IPv4 address into RTNETADDRIPV4 representation.
+ * Leading and trailing whitespace is ignored.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ * failure.
+ *
+ * @param pcszAddr The value to convert.
+ * @param pAddr Where to store the result.
+ */
+RTDECL(int) RTNetStrToIPv4Addr(const char *pcszAddr, PRTNETADDRIPV4 pAddr);
+
+/**
+ * Parses dotted-decimal IPv4 CIDR notation into RTNETADDRIPV4
+ * representation and prefix length. Missing prefix specification is
+ * treated as exact address specification (prefix length 32). Leading
+ * and trailing whitespace is ignored.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ * failure.
+ *
+ * @param pcszAddr The value to convert.
+ * @param pAddr Where to store the address.
+ * @param piPrefix Where to store the prefix length;
+ */
+RTDECL(int) RTNetStrToIPv4Cidr(const char *pcszAddr, PRTNETADDRIPV4 pAddr, int *piPrefix);
+
+/**
+ * Verifies that RTNETADDRIPV4 is a valid contiguous netmask and
+ * computes its prefix length.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ * failure.
+ *
+ * @param pMask The netmask to verify and convert.
+ * @param piPrefix Where to store the prefix length. (Optional)
+ */
+RTDECL(int) RTNetMaskToPrefixIPv4(PCRTNETADDRIPV4 pMask, int *piPrefix);
+
+/**
+ * Computes netmask corresponding to the prefix length.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ * failure.
+ *
+ * @param iPrefix The prefix to convert.
+ * @param pMask Where to store the netmask.
+ */
+RTDECL(int) RTNetPrefixToMaskIPv4(int iPrefix, PRTNETADDRIPV4 pMask);
+
+
+/**
+ * IPv6 address.
+ */
+typedef RTUINT128U RTNETADDRIPV6;
+AssertCompileSize(RTNETADDRIPV6, 16);
+/** Pointer to a IPv6 address. */
+typedef RTNETADDRIPV6 *PRTNETADDRIPV6;
+/** Pointer to a const IPv6 address. */
+typedef RTNETADDRIPV6 const *PCRTNETADDRIPV6;
+
+/**
+ * Tests if the given string is a valid IPv6 address.
+ *
+ * @returns @c true if it is, @c false if not.
+ * @param pszAddress String which may be an IPv6 address.
+ */
+RTDECL(bool) RTNetIsIPv6AddrStr(const char *pszAddress);
+
+/**
+ * Tests if the given string is a wildcard IPv6 address.
+ *
+ * @returns @c true if it is, @c false if not.
+ * @param pszAddress String which may be an IPv6 address.
+ */
+RTDECL(bool) RTNetStrIsIPv6AddrAny(const char *pszAddress);
+
+/**
+ * Parses IPv6 address into RTNETADDRIPV6 representation.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ * failure.
+ *
+ * @param pcszAddr The value to convert.
+ * @param ppszNext Where to store the pointer to the first char
+ * following the address. (Optional)
+ * @param pAddr Where to store the result.
+ */
+RTDECL(int) RTNetStrToIPv6AddrEx(const char *pcszAddr, PRTNETADDRIPV6 pAddr, char **ppszNext);
+
+/**
+ * Parses IPv6 address into RTNETADDRIPV6 representation.
+ * Leading and trailing whitespace is ignored.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ * failure.
+ *
+ * @param pcszAddr The value to convert.
+ * @param ppszZone Where to store the pointer to the first char
+ * of the zone id. NULL is stored if there is
+ * no zone id.
+ * @param pAddr Where to store the result.
+ */
+RTDECL(int) RTNetStrToIPv6Addr(const char *pcszAddr, PRTNETADDRIPV6 pAddr, char **ppszZone);
+
+/**
+ * Verifies that RTNETADDRIPV6 is a valid contiguous netmask and
+ * computes its prefix length.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ * failure.
+ *
+ * @param pMask The netmask to verify and convert.
+ * @param piPrefix Where to store the prefix length. (Optional)
+ */
+RTDECL(int) RTNetMaskToPrefixIPv6(PCRTNETADDRIPV6 pMask, int *piPrefix);
+
+/**
+ * Computes netmask corresponding to the prefix length.
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ * failure.
+ *
+ * @param iPrefix The prefix to convert.
+ * @param pMask Where to store the netmask.
+ */
+RTDECL(int) RTNetPrefixToMaskIPv6(int iPrefix, PRTNETADDRIPV6 pMask);
+
+/**
+ * Parses IPv6 prefix notation into RTNETADDRIPV6 representation and
+ * prefix length. Missing prefix specification is treated as exact
+ * address specification (prefix length 128). Leading and trailing
+ * whitespace is ignored.
+ *
+ * "CIDR" in the name is a misnomer as IPv6 doesn't have network
+ * classes, but is parallel to the IPv4 name (and naming things is
+ * hard).
+ *
+ * @returns VINF_SUCCESS on success, VERR_INVALID_PARAMETER on
+ * failure.
+ *
+ * @param pcszAddr The value to convert.
+ * @param pAddr Where to store the address.
+ * @param piPrefix Where to store the prefix length;
+ */
+RTDECL(int) RTNetStrToIPv6Cidr(const char *pcszAddr, PRTNETADDRIPV6 pAddr, int *piPrefix);
+
+
+/**
+ * IPX address.
+ */
+#pragma pack(1)
+typedef struct RTNETADDRIPX
+{
+ /** The network ID. */
+ uint32_t Network;
+ /** The node ID. (Defaults to the MAC address apparently.) */
+ RTMAC Node;
+} RTNETADDRIPX;
+#pragma pack()
+AssertCompileSize(RTNETADDRIPX, 4+6);
+/** Pointer to an IPX address. */
+typedef RTNETADDRIPX *PRTNETADDRIPX;
+/** Pointer to a const IPX address. */
+typedef RTNETADDRIPX const *PCRTNETADDRIPX;
+
+/**
+ * Network address union.
+ *
+ * @remarks The size of this structure may change in the future.
+ */
+typedef union RTNETADDRU
+{
+ /** 64-bit view. */
+ uint64_t au64[2];
+ /** 32-bit view. */
+ uint32_t au32[4];
+ /** 16-bit view. */
+ uint16_t au16[8];
+ /** 8-bit view. */
+ uint8_t au8[16];
+ /** IPv4 view. */
+ RTNETADDRIPV4 IPv4;
+#ifndef IPv6 /* Work around X11 and RDP defining IPv6 to 1. */
+ /** IPv6 view. */
+ RTNETADDRIPV6 IPv6;
+#endif
+ /** IPX view. */
+ RTNETADDRIPX Ipx;
+ /** MAC address view. */
+ RTMAC Mac;
+} RTNETADDRU;
+AssertCompileSize(RTNETADDRU, 16);
+/** Pointer to an address union. */
+typedef RTNETADDRU *PRTNETADDRU;
+/** Pointer to a const address union. */
+typedef RTNETADDRU const *PCRTNETADDRU;
+
+/**
+ * Network address type.
+ *
+ * @remarks The value assignments may change in the future.
+ */
+typedef enum RTNETADDRTYPE
+{
+ /** The invalid 0 entry. */
+ RTNETADDRTYPE_INVALID = 0,
+ /** IP version 4. */
+ RTNETADDRTYPE_IPV4,
+ /** IP version 6. */
+ RTNETADDRTYPE_IPV6,
+ /** IPX. */
+ RTNETADDRTYPE_IPX,
+ /** MAC address. */
+ RTNETADDRTYPE_MAC,
+ /** The end of the valid values. */
+ RTNETADDRTYPE_END,
+ /** The usual 32-bit hack. */
+ RTNETADDRTYPE_32_BIT_HACK = 0x7fffffff
+} RTNETADDRTYPE;
+/** Pointer to a network address type. */
+typedef RTNETADDRTYPE *PRTNETADDRTYPE;
+/** Pointer to a const network address type. */
+typedef RTNETADDRTYPE const *PCRTNETADDRTYPE;
+
+/**
+ * Network address.
+ *
+ * @remarks The size and type values may change.
+ */
+typedef struct RTNETADDR
+{
+ /** The address union. */
+ RTNETADDRU uAddr;
+ /** Indicates which view of @a u that is valid. */
+ RTNETADDRTYPE enmType;
+ /** The port number for IPv4 and IPv6 addresses. This is set to
+ * RTNETADDR_NA_PORT if not applicable. */
+ uint32_t uPort;
+} RTNETADDR;
+/** Pointer to a network address. */
+typedef RTNETADDR *PRTNETADDR;
+/** Pointer to a const network address. */
+typedef RTNETADDR const *PCRTNETADDR;
+
+/** The not applicable value of RTNETADDR::uPort value use to inid. */
+#define RTNETADDR_PORT_NA UINT32_MAX
+
+/**
+ * Ethernet header.
+ */
+#pragma pack(1)
+typedef struct RTNETETHERHDR
+{
+ RTMAC DstMac;
+ RTMAC SrcMac;
+ /** Ethernet frame type or frame size, depending on the kind of ethernet.
+ * This is big endian on the wire. */
+ uint16_t EtherType;
+} RTNETETHERHDR;
+#pragma pack()
+AssertCompileSize(RTNETETHERHDR, 14);
+/** Pointer to an ethernet header. */
+typedef RTNETETHERHDR *PRTNETETHERHDR;
+/** Pointer to a const ethernet header. */
+typedef RTNETETHERHDR const *PCRTNETETHERHDR;
+
+/** @name EtherType (RTNETETHERHDR::EtherType)
+ * @{ */
+#define RTNET_ETHERTYPE_IPV4 UINT16_C(0x0800)
+#define RTNET_ETHERTYPE_ARP UINT16_C(0x0806)
+#define RTNET_ETHERTYPE_IPV6 UINT16_C(0x86dd)
+#define RTNET_ETHERTYPE_VLAN UINT16_C(0x8100)
+#define RTNET_ETHERTYPE_IPX_1 UINT16_C(0x8037)
+#define RTNET_ETHERTYPE_IPX_2 UINT16_C(0x8137)
+#define RTNET_ETHERTYPE_IPX_3 UINT16_C(0x8138)
+/** @} */
+
+
+/**
+ * IPv4 header.
+ * All is bigendian on the wire.
+ */
+#pragma pack(1)
+typedef struct RTNETIPV4
+{
+#ifdef RT_BIG_ENDIAN
+ unsigned int ip_v : 4;
+ unsigned int ip_hl : 4;
+ unsigned int ip_tos : 8;
+ unsigned int ip_len : 16;
+#else
+ /** 00:0 - Header length given as a 32-bit word count. */
+ unsigned int ip_hl : 4;
+ /** 00:4 - Header version. */
+ unsigned int ip_v : 4;
+ /** 01 - Type of service. */
+ unsigned int ip_tos : 8;
+ /** 02 - Total length (header + data). */
+ unsigned int ip_len : 16;
+#endif
+ /** 04 - Packet idenficiation. */
+ uint16_t ip_id;
+ /** 06 - Offset if fragmented. */
+ uint16_t ip_off;
+ /** 08 - Time to live. */
+ uint8_t ip_ttl;
+ /** 09 - Protocol. */
+ uint8_t ip_p;
+ /** 0a - Header check sum. */
+ uint16_t ip_sum;
+ /** 0c - Source address. */
+ RTNETADDRIPV4 ip_src;
+ /** 10 - Destination address. */
+ RTNETADDRIPV4 ip_dst;
+ /** 14 - Options (optional). */
+ uint32_t ip_options[1];
+} RTNETIPV4;
+#pragma pack()
+AssertCompileSize(RTNETIPV4, 6 * 4);
+/** Pointer to a IPv4 header. */
+typedef RTNETIPV4 *PRTNETIPV4;
+/** Pointer to a const IPv4 header. */
+typedef RTNETIPV4 const *PCRTNETIPV4;
+
+/** The minimum IPv4 header length (in bytes).
+ * Up to and including RTNETIPV4::ip_dst. */
+#define RTNETIPV4_MIN_LEN (20)
+
+
+/** @name IPv4 Protocol Numbers
+ * @{ */
+/** IPv4: ICMP */
+#define RTNETIPV4_PROT_ICMP (1)
+/** IPv4: TCP */
+#define RTNETIPV4_PROT_TCP (6)
+/** IPv4: UDP */
+#define RTNETIPV4_PROT_UDP (17)
+/** @} */
+
+/** @name Common IPv4 Port Assignments
+ * @{
+ */
+/** Boostrap Protocol / DHCP) Server. */
+#define RTNETIPV4_PORT_BOOTPS (67)
+/** Boostrap Protocol / DHCP) Client. */
+#define RTNETIPV4_PORT_BOOTPC (68)
+/** @} */
+
+/** @name IPv4 Flags
+ * @{ */
+/** IPv4: Don't fragment */
+#define RTNETIPV4_FLAGS_DF (0x4000)
+/** IPv4: More fragments */
+#define RTNETIPV4_FLAGS_MF (0x2000)
+/** @} */
+
+RTDECL(uint16_t) RTNetIPv4HdrChecksum(PCRTNETIPV4 pIpHdr);
+RTDECL(bool) RTNetIPv4IsHdrValid(PCRTNETIPV4 pIpHdr, size_t cbHdrMax, size_t cbPktMax, bool fChecksum);
+RTDECL(uint32_t) RTNetIPv4PseudoChecksum(PCRTNETIPV4 pIpHdr);
+RTDECL(uint32_t) RTNetIPv4PseudoChecksumBits(RTNETADDRIPV4 SrcAddr, RTNETADDRIPV4 DstAddr, uint8_t bProtocol, uint16_t cbPkt);
+RTDECL(uint32_t) RTNetIPv4AddDataChecksum(void const *pvData, size_t cbData, uint32_t u32Sum, bool *pfOdd);
+RTDECL(uint16_t) RTNetIPv4FinalizeChecksum(uint32_t u32Sum);
+
+
+/**
+ * IPv6 header.
+ * All is bigendian on the wire.
+ */
+#pragma pack(1)
+typedef struct RTNETIPV6
+{
+ /** Version (4 bits), Traffic Class (8 bits) and Flow Lable (20 bits).
+ * @todo this is probably mislabeled - ip6_flow vs. ip6_vfc, fix later. */
+ uint32_t ip6_vfc;
+ /** 04 - Payload length, including extension headers. */
+ uint16_t ip6_plen;
+ /** 06 - Next header type (RTNETIPV4_PROT_XXX). */
+ uint8_t ip6_nxt;
+ /** 07 - Hop limit. */
+ uint8_t ip6_hlim;
+ /** xx - Source address. */
+ RTNETADDRIPV6 ip6_src;
+ /** xx - Destination address. */
+ RTNETADDRIPV6 ip6_dst;
+} RTNETIPV6;
+#pragma pack()
+AssertCompileSize(RTNETIPV6, 8 + 16 + 16);
+/** Pointer to a IPv6 header. */
+typedef RTNETIPV6 *PRTNETIPV6;
+/** Pointer to a const IPv6 header. */
+typedef RTNETIPV6 const *PCRTNETIPV6;
+
+/** The minimum IPv6 header length (in bytes).
+ * Up to and including RTNETIPV6::ip6_dst. */
+#define RTNETIPV6_MIN_LEN (40)
+#define RTNETIPV6_ICMPV6_ND_WITH_LLA_OPT_MIN_LEN (32)
+
+RTDECL(uint32_t) RTNetIPv6PseudoChecksum(PCRTNETIPV6 pIpHdr);
+RTDECL(uint32_t) RTNetIPv6PseudoChecksumEx(PCRTNETIPV6 pIpHdr, uint8_t bProtocol, uint16_t cbPkt);
+RTDECL(uint32_t) RTNetIPv6PseudoChecksumBits(PCRTNETADDRIPV6 pSrcAddr, PCRTNETADDRIPV6 pDstAddr,
+ uint8_t bProtocol, uint16_t cbPkt);
+
+
+/**
+ * UDP header.
+ */
+#pragma pack(1)
+typedef struct RTNETUDP
+{
+ /** The source port. */
+ uint16_t uh_sport;
+ /** The destination port. */
+ uint16_t uh_dport;
+ /** The length of the UDP header and associated data. */
+ uint16_t uh_ulen;
+ /** The checksum of the pseudo header, the UDP header and the data. */
+ uint16_t uh_sum;
+} RTNETUDP;
+#pragma pack()
+AssertCompileSize(RTNETUDP, 8);
+/** Pointer to an UDP header. */
+typedef RTNETUDP *PRTNETUDP;
+/** Pointer to a const UDP header. */
+typedef RTNETUDP const *PCRTNETUDP;
+
+/** The minimum UDP packet length (in bytes). (RTNETUDP::uh_ulen) */
+#define RTNETUDP_MIN_LEN (8)
+
+RTDECL(uint16_t) RTNetUDPChecksum(uint32_t u32Sum, PCRTNETUDP pUdpHdr);
+RTDECL(uint32_t) RTNetIPv4AddUDPChecksum(PCRTNETUDP pUdpHdr, uint32_t u32Sum);
+RTDECL(uint16_t) RTNetIPv4UDPChecksum(PCRTNETIPV4 pIpHdr, PCRTNETUDP pUdpHdr, void const *pvData);
+RTDECL(bool) RTNetIPv4IsUDPSizeValid(PCRTNETIPV4 pIpHdr, PCRTNETUDP pUdpHdr, size_t cbPktMax);
+RTDECL(bool) RTNetIPv4IsUDPValid(PCRTNETIPV4 pIpHdr, PCRTNETUDP pUdpHdr, void const *pvData, size_t cbPktMax, bool fChecksum);
+
+
+/**
+ * IPv4 BOOTP / DHCP packet.
+ */
+#pragma pack(1)
+typedef struct RTNETBOOTP
+{
+ /** 00 - The packet opcode (RTNETBOOTP_OP_*). */
+ uint8_t bp_op;
+ /** 01 - Hardware address type. Same as RTNETARPHDR::ar_htype. */
+ uint8_t bp_htype;
+ /** 02 - Hardware address length. */
+ uint8_t bp_hlen;
+ /** 03 - Gateway hops. */
+ uint8_t bp_hops;
+ /** 04 - Transaction ID. */
+ uint32_t bp_xid;
+ /** 08 - Seconds since boot started. */
+ uint16_t bp_secs;
+ /** 0a - Unused (BOOTP) / Flags (DHCP) (RTNET_DHCP_FLAGS_*). */
+ uint16_t bp_flags;
+ /** 0c - Client IPv4 address. */
+ RTNETADDRIPV4 bp_ciaddr;
+ /** 10 - Your IPv4 address. */
+ RTNETADDRIPV4 bp_yiaddr;
+ /** 14 - Server IPv4 address. */
+ RTNETADDRIPV4 bp_siaddr;
+ /** 18 - Gateway IPv4 address. */
+ RTNETADDRIPV4 bp_giaddr;
+ /** 1c - Client hardware address. */
+ union
+ {
+ uint8_t au8[16];
+ RTMAC Mac;
+ } bp_chaddr;
+ /** 2c - Server name. */
+ uint8_t bp_sname[64];
+ /** 6c - File name / more DHCP options. */
+ uint8_t bp_file[128];
+ /** ec - Vendor specific area (BOOTP) / Options (DHCP).
+ * @remark This is really 312 bytes in the DHCP version. */
+ union
+ {
+ uint8_t au8[128];
+ struct DHCP
+ {
+ /** ec - The DHCP cookie (RTNET_DHCP_COOKIE). */
+ uint32_t dhcp_cookie;
+ /** f0 - The DHCP options. */
+ uint8_t dhcp_opts[124];
+ } Dhcp;
+ } bp_vend;
+
+} RTNETBOOTP;
+#pragma pack()
+AssertCompileSize(RTNETBOOTP, 0xec + 128);
+/** Pointer to a BOOTP / DHCP packet. */
+typedef RTNETBOOTP *PRTNETBOOTP;
+/** Pointer to a const BOOTP / DHCP packet. */
+typedef RTNETBOOTP const *PCRTNETBOOTP;
+
+/** Minimum BOOTP packet length. For quick validation, no standard thing really. */
+#define RTNETBOOTP_MIN_LEN 0xec
+/** Minimum DHCP packet length. For quick validation, no standard thing really. */
+#define RTNETBOOTP_DHCP_MIN_LEN 0xf1
+
+/** The normal size of the a DHCP packet (i.e. a RTNETBOOTP).
+ * Same as RTNET_DHCP_OPT_SIZE, just expressed differently. */
+#define RTNET_DHCP_NORMAL_SIZE (0xec + 4 + RTNET_DHCP_OPT_SIZE)
+/** The normal size of RTNETBOOTP::bp_vend::Dhcp::dhcp_opts. */
+#define RTNET_DHCP_OPT_SIZE (312 - 4)
+
+/** @name BOOTP packet opcode values
+ * @{ */
+#define RTNETBOOTP_OP_REQUEST 1
+#define RTNETBOOTP_OP_REPLY 2
+/** @} */
+
+/** @name DHCP flags (RTNETBOOTP::bp_flags)
+ * @{ */
+#define RTNET_DHCP_FLAGS_NO_BROADCAST UINT16_C(0x8000) /** @todo check test!!! */
+/** @} */
+
+/** The DHCP cookie (network endian). */
+#define RTNET_DHCP_COOKIE UINT32_C(0x63825363)
+
+/**
+ * An IPv4 DHCP option header.
+ */
+typedef struct RTNETDHCPOPT
+{
+ /** 00 - The DHCP option. */
+ uint8_t dhcp_opt;
+ /** 01 - The data length (excluding this header). */
+ uint8_t dhcp_len;
+ /* 02 - The option data follows here, optional and of variable length. */
+} RTNETDHCPOPT;
+AssertCompileSize(RTNETDHCPOPT, 2);
+/** Pointer to a DHCP option header. */
+typedef RTNETDHCPOPT *PRTNETDHCPOPT;
+/** Pointer to a const DHCP option header. */
+typedef RTNETDHCPOPT const *PCRTNETDHCPOPT;
+
+/** @name DHCP options
+ * @{ */
+/** 1 byte padding, this has no dhcp_len field. */
+#define RTNET_DHCP_OPT_PAD 0
+
+/** The subnet mask. */
+#define RTNET_DHCP_OPT_SUBNET_MASK 1
+/** The time offset. */
+#define RTNET_DHCP_OPT_TIME_OFFSET 2
+/** The routers for the subnet. */
+#define RTNET_DHCP_OPT_ROUTERS 3
+/** Domain Name Server. */
+#define RTNET_DHCP_OPT_DNS 6
+/** Host name. */
+#define RTNET_DHCP_OPT_HOST_NAME 12
+/** Domain name. */
+#define RTNET_DHCP_OPT_DOMAIN_NAME 15
+
+/** The requested address. */
+#define RTNET_DHCP_OPT_REQ_ADDR 50
+/** The lease time in seconds. */
+#define RTNET_DHCP_OPT_LEASE_TIME 51
+/** Option overload.
+ * Indicates that the bp_file and/or bp_sname holds contains DHCP options. */
+#define RTNET_DHCP_OPT_OPTION_OVERLOAD 52
+/** Have a 8-bit message type value as data, see RTNET_DHCP_MT_*. */
+#define RTNET_DHCP_OPT_MSG_TYPE 53
+/** Server ID. */
+#define RTNET_DHCP_OPT_SERVER_ID 54
+/** Parameter request list. */
+#define RTNET_DHCP_OPT_PARAM_REQ_LIST 55
+/** The maximum DHCP message size a client is willing to accept. */
+#define RTNET_DHCP_OPT_MAX_DHCP_MSG_SIZE 57
+/** Client ID. */
+#define RTNET_DHCP_OPT_CLIENT_ID 61
+/** TFTP server name. */
+#define RTNET_DHCP_OPT_TFTP_SERVER_NAME 66
+/** Bootfile name. */
+#define RTNET_DHCP_OPT_BOOTFILE_NAME 67
+
+/** Marks the end of the DHCP options, this has no dhcp_len field. */
+#define RTNET_DHCP_OPT_END 255
+/** @} */
+
+/** @name DHCP Option overload flags (option 52)
+ * @{ */
+#define RTNET_DHCP_OPTION_OVERLOAD_FILE 1
+#define RTNET_DHCP_OPTION_OVERLOAD_SNAME 2
+#define RTNET_DHCP_OPTION_OVERLOAD_MASK 3
+/** @} */
+
+/** @name DHCP Message Types (option 53)
+ * @{ */
+#define RTNET_DHCP_MT_DISCOVER 1
+#define RTNET_DHCP_MT_OFFER 2
+#define RTNET_DHCP_MT_REQUEST 3
+#define RTNET_DHCP_MT_DECLINE 4
+#define RTNET_DHCP_MT_ACK 5
+#define RTNET_DHCP_MT_NAC 6
+#define RTNET_DHCP_MT_RELEASE 7
+#define RTNET_DHCP_MT_INFORM 8
+/** @} */
+
+/** @name DHCP Flags
+ * @{ */
+#define RTNET_DHCP_FLAG_BROADCAST 0x8000
+/** @} */
+
+RTDECL(bool) RTNetIPv4IsDHCPValid(PCRTNETUDP pUdpHdr, PCRTNETBOOTP pDhcp, size_t cbDhcp, uint8_t *pMsgType);
+
+
+/**
+ * IPv4 DHCP packet.
+ * @deprecated Use RTNETBOOTP.
+ */
+#pragma pack(1)
+typedef struct RTNETDHCP
+{
+ /** 00 - The packet opcode. */
+ uint8_t Op;
+ /** Hardware address type. */
+ uint8_t HType;
+ /** Hardware address length. */
+ uint8_t HLen;
+ uint8_t Hops;
+ uint32_t XID;
+ uint16_t Secs;
+ uint16_t Flags;
+ /** Client IPv4 address. */
+ RTNETADDRIPV4 CIAddr;
+ /** Your IPv4 address. */
+ RTNETADDRIPV4 YIAddr;
+ /** Server IPv4 address. */
+ RTNETADDRIPV4 SIAddr;
+ /** Gateway IPv4 address. */
+ RTNETADDRIPV4 GIAddr;
+ /** Client hardware address. */
+ uint8_t CHAddr[16];
+ /** Server name. */
+ uint8_t SName[64];
+ uint8_t File[128];
+ uint8_t abMagic[4];
+ uint8_t DhcpOpt;
+ uint8_t DhcpLen; /* 1 */
+ uint8_t DhcpReq;
+ uint8_t abOptions[57];
+} RTNETDHCP;
+#pragma pack()
+/** @todo AssertCompileSize(RTNETDHCP, ); */
+/** Pointer to a DHCP packet. */
+typedef RTNETDHCP *PRTNETDHCP;
+/** Pointer to a const DHCP packet. */
+typedef RTNETDHCP const *PCRTNETDHCP;
+
+
+/**
+ * TCP packet.
+ */
+#pragma pack(1)
+typedef struct RTNETTCP
+{
+ /** 00 - The source port. */
+ uint16_t th_sport;
+ /** 02 - The destination port. */
+ uint16_t th_dport;
+ /** 04 - The sequence number. */
+ uint32_t th_seq;
+ /** 08 - The acknowledgement number. */
+ uint32_t th_ack;
+#ifdef RT_BIG_ENDIAN
+ unsigned int th_win : 16;
+ unsigned int th_flags : 8;
+ unsigned int th_off : 4;
+ unsigned int th_x2 : 4;
+#else
+ /** 0c:0 - Reserved. */
+ unsigned int th_x2 : 4;
+ /** 0c:4 - The data offset given as a dword count from the start of this header. */
+ unsigned int th_off : 4;
+ /** 0d - flags. */
+ unsigned int th_flags : 8;
+ /** 0e - The window. */
+ unsigned int th_win : 16;
+#endif
+ /** 10 - The checksum of the pseudo header, the TCP header and the data. */
+ uint16_t th_sum;
+ /** 12 - The urgent pointer. */
+ uint16_t th_urp;
+ /* (options follows here and then the data (aka text).) */
+} RTNETTCP;
+#pragma pack()
+AssertCompileSize(RTNETTCP, 20);
+/** Pointer to a TCP packet. */
+typedef RTNETTCP *PRTNETTCP;
+/** Pointer to a const TCP packet. */
+typedef RTNETTCP const *PCRTNETTCP;
+
+/** The minimum TCP header length (in bytes). (RTNETTCP::th_off * 4) */
+#define RTNETTCP_MIN_LEN (20)
+
+/** @name TCP flags (RTNETTCP::th_flags)
+ * @{ */
+#define RTNETTCP_F_FIN 0x01
+#define RTNETTCP_F_SYN 0x02
+#define RTNETTCP_F_RST 0x04
+#define RTNETTCP_F_PSH 0x08
+#define RTNETTCP_F_ACK 0x10
+#define RTNETTCP_F_URG 0x20
+#define RTNETTCP_F_ECE 0x40
+#define RTNETTCP_F_CWR 0x80
+/** @} */
+
+RTDECL(uint16_t) RTNetTCPChecksum(uint32_t u32Sum, PCRTNETTCP pTcpHdr, void const *pvData, size_t cbData);
+RTDECL(uint32_t) RTNetIPv4AddTCPChecksum(PCRTNETTCP pTcpHdr, uint32_t u32Sum);
+RTDECL(uint16_t) RTNetIPv4TCPChecksum(PCRTNETIPV4 pIpHdr, PCRTNETTCP pTcpHdr, void const *pvData);
+RTDECL(bool) RTNetIPv4IsTCPSizeValid(PCRTNETIPV4 pIpHdr, PCRTNETTCP pTcpHdr, size_t cbHdrMax, size_t cbPktMax);
+RTDECL(bool) RTNetIPv4IsTCPValid(PCRTNETIPV4 pIpHdr, PCRTNETTCP pTcpHdr, size_t cbHdrMax, void const *pvData,
+ size_t cbPktMax, bool fChecksum);
+
+
+/**
+ * IPv4 ICMP packet header.
+ */
+#pragma pack(1)
+typedef struct RTNETICMPV4HDR
+{
+ /** 00 - The ICMP message type. */
+ uint8_t icmp_type;
+ /** 01 - Type specific code that further qualifies the message. */
+ uint8_t icmp_code;
+ /** 02 - Checksum of the ICMP message. */
+ uint16_t icmp_cksum;
+} RTNETICMPV4HDR;
+#pragma pack()
+AssertCompileSize(RTNETICMPV4HDR, 4);
+/** Pointer to an ICMP packet header. */
+typedef RTNETICMPV4HDR *PRTNETICMPV4HDR;
+/** Pointer to a const ICMP packet header. */
+typedef RTNETICMPV4HDR const *PCRTNETICMPV4HDR;
+
+/** @name ICMP (v4) message types.
+ * @{ */
+#define RTNETICMPV4_TYPE_ECHO_REPLY 0
+#define RTNETICMPV4_TYPE_ECHO_REQUEST 8
+#define RTNETICMPV4_TYPE_TRACEROUTE 30
+/** @} */
+
+/**
+ * IPv4 ICMP ECHO Reply & Request packet.
+ */
+#pragma pack(1)
+typedef struct RTNETICMPV4ECHO
+{
+ /** 00 - The ICMP header. */
+ RTNETICMPV4HDR Hdr;
+ /** 04 - The identifier to help the requestor match up the reply.
+ * Can be 0. Typically fixed value. */
+ uint16_t icmp_id;
+ /** 06 - The sequence number to help the requestor match up the reply.
+ * Can be 0. Typically incrementing between requests. */
+ uint16_t icmp_seq;
+ /** 08 - Variable length data that is to be returned unmodified in the reply. */
+ uint8_t icmp_data[1];
+} RTNETICMPV4ECHO;
+#pragma pack()
+AssertCompileSize(RTNETICMPV4ECHO, 9);
+/** Pointer to an ICMP ECHO packet. */
+typedef RTNETICMPV4ECHO *PRTNETICMPV4ECHO;
+/** Pointer to a const ICMP ECHO packet. */
+typedef RTNETICMPV4ECHO const *PCRTNETICMPV4ECHO;
+
+/**
+ * IPv4 ICMP TRACEROUTE packet.
+ * This is an reply to an IP packet with the traceroute option set.
+ */
+#pragma pack(1)
+typedef struct RTNETICMPV4TRACEROUTE
+{
+ /** 00 - The ICMP header. */
+ RTNETICMPV4HDR Hdr;
+ /** 04 - Identifier copied from the traceroute option's ID number. */
+ uint16_t icmp_id;
+ /** 06 - Unused. (Possibly an icmp_seq?) */
+ uint16_t icmp_void;
+ /** 08 - Outbound hop count. From the IP packet causing this message. */
+ uint16_t icmp_ohc;
+ /** 0a - Return hop count. From the IP packet causing this message. */
+ uint16_t icmp_rhc;
+ /** 0c - Output link speed, 0 if not known. */
+ uint32_t icmp_speed;
+ /** 10 - Output link MTU, 0 if not known. */
+ uint32_t icmp_mtu;
+} RTNETICMPV4TRACEROUTE;
+#pragma pack()
+AssertCompileSize(RTNETICMPV4TRACEROUTE, 20);
+/** Pointer to an ICMP TRACEROUTE packet. */
+typedef RTNETICMPV4TRACEROUTE *PRTNETICMPV4TRACEROUTE;
+/** Pointer to a const ICMP TRACEROUTE packet. */
+typedef RTNETICMPV4TRACEROUTE const *PCRTNETICMPV4TRACEROUTE;
+
+/** @todo add more ICMPv4 as needed. */
+
+/**
+ * IPv4 ICMP union packet.
+ */
+typedef union RTNETICMPV4
+{
+ RTNETICMPV4HDR Hdr;
+ RTNETICMPV4ECHO Echo;
+ RTNETICMPV4TRACEROUTE Traceroute;
+} RTNETICMPV4;
+/** Pointer to an ICMP union packet. */
+typedef RTNETICMPV4 *PRTNETICMPV4;
+/** Pointer to a const ICMP union packet. */
+typedef RTNETICMPV4 const *PCRTNETICMPV4;
+
+
+/**
+ * IPv6 ICMP packet header.
+ */
+#pragma pack(1)
+typedef struct RTNETICMPV6HDR
+{
+ /** 00 - The ICMPv6 message type. */
+ uint8_t icmp6_type;
+ /** 01 - Type specific code that further qualifies the message. */
+ uint8_t icmp6_code;
+ /** 02 - Checksum of the ICMPv6 message. */
+ uint16_t icmp6_cksum;
+} RTNETICMPV6HDR;
+#pragma pack()
+AssertCompileSize(RTNETICMPV6HDR, 4);
+/** Pointer to an ICMPv6 packet header. */
+typedef RTNETICMPV6HDR *PRTNETICMPV6HDR;
+/** Pointer to a const ICMP packet header. */
+typedef RTNETICMPV6HDR const *PCRTNETICMPV6HDR;
+
+#define RTNETIPV6_PROT_ICMPV6 (58)
+
+/** @name Internet Control Message Protocol version 6 (ICMPv6) message types.
+ * @{ */
+#define RTNETIPV6_ICMP_TYPE_RS 133
+#define RTNETIPV6_ICMP_TYPE_RA 134
+#define RTNETIPV6_ICMP_TYPE_NS 135
+#define RTNETIPV6_ICMP_TYPE_NA 136
+#define RTNETIPV6_ICMP_TYPE_RDR 137
+/** @} */
+
+/** @name Neighbor Discovery option types
+ * @{ */
+#define RTNETIPV6_ICMP_ND_SLLA_OPT (1)
+#define RTNETIPV6_ICMP_ND_TLLA_OPT (2)
+/** @} */
+
+/** ICMPv6 ND Source/Target Link Layer Address option */
+#pragma pack(1)
+typedef struct RTNETNDP_LLA_OPT
+{
+ uint8_t type;
+ uint8_t len;
+ RTMAC lla;
+} RTNETNDP_LLA_OPT;
+#pragma pack()
+
+AssertCompileSize(RTNETNDP_LLA_OPT, 1+1+6);
+
+typedef RTNETNDP_LLA_OPT *PRTNETNDP_LLA_OPT;
+typedef RTNETNDP_LLA_OPT const *PCRTNETNDP_LLA_OPT;
+
+/** ICMPv6 ND Neighbor Sollicitation */
+#pragma pack(1)
+typedef struct RTNETNDP
+{
+ /** 00 - The ICMPv6 header. */
+ RTNETICMPV6HDR Hdr;
+ /** 04 - reserved */
+ uint32_t reserved;
+ /** 08 - target address */
+ RTNETADDRIPV6 target_address;
+} RTNETNDP;
+#pragma pack()
+AssertCompileSize(RTNETNDP, 4+4+16);
+/** Pointer to a NDP ND packet. */
+typedef RTNETNDP *PRTNETNDP;
+/** Pointer to a const NDP NS packet. */
+typedef RTNETNDP const *PCRTNETNDP;
+
+
+/**
+ * Ethernet ARP header.
+ */
+#pragma pack(1)
+typedef struct RTNETARPHDR
+{
+ /** The hardware type. */
+ uint16_t ar_htype;
+ /** The protocol type (ethertype). */
+ uint16_t ar_ptype;
+ /** The hardware address length. */
+ uint8_t ar_hlen;
+ /** The protocol address length. */
+ uint8_t ar_plen;
+ /** The operation. */
+ uint16_t ar_oper;
+} RTNETARPHDR;
+#pragma pack()
+AssertCompileSize(RTNETARPHDR, 8);
+/** Pointer to an ethernet ARP header. */
+typedef RTNETARPHDR *PRTNETARPHDR;
+/** Pointer to a const ethernet ARP header. */
+typedef RTNETARPHDR const *PCRTNETARPHDR;
+
+/** ARP hardware type - ethernet. */
+#define RTNET_ARP_ETHER UINT16_C(1)
+
+/** @name ARP operations
+ * @{ */
+#define RTNET_ARPOP_REQUEST UINT16_C(1) /**< Request hardware address given a protocol address (ARP). */
+#define RTNET_ARPOP_REPLY UINT16_C(2)
+#define RTNET_ARPOP_REVREQUEST UINT16_C(3) /**< Request protocol address given a hardware address (RARP). */
+#define RTNET_ARPOP_REVREPLY UINT16_C(4)
+#define RTNET_ARPOP_INVREQUEST UINT16_C(8) /**< Inverse ARP. */
+#define RTNET_ARPOP_INVREPLY UINT16_C(9)
+/** Check if an ARP operation is a request or not. */
+#define RTNET_ARPOP_IS_REQUEST(Op) ((Op) & 1)
+/** Check if an ARP operation is a reply or not. */
+#define RTNET_ARPOP_IS_REPLY(Op) (!RTNET_ARPOP_IS_REQUEST(Op))
+/** @} */
+
+
+/**
+ * Ethernet IPv4 + 6-byte MAC ARP request packet.
+ */
+#pragma pack(1)
+typedef struct RTNETARPIPV4
+{
+ /** ARP header. */
+ RTNETARPHDR Hdr;
+ /** The sender hardware address. */
+ RTMAC ar_sha;
+ /** The sender protocol address. */
+ RTNETADDRIPV4 ar_spa;
+ /** The target hardware address. */
+ RTMAC ar_tha;
+ /** The target protocol address. */
+ RTNETADDRIPV4 ar_tpa;
+} RTNETARPIPV4;
+#pragma pack()
+AssertCompileSize(RTNETARPIPV4, 8+6+4+6+4);
+/** Pointer to an ethernet IPv4+MAC ARP request packet. */
+typedef RTNETARPIPV4 *PRTNETARPIPV4;
+/** Pointer to a const ethernet IPv4+MAC ARP request packet. */
+typedef RTNETARPIPV4 const *PCRTNETARPIPV4;
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* !IPRT_INCLUDED_net_h */
+