net.h revision 7f9a335e8fb0442971f42e4ac695f6f8832095b7
/** @file
* IPRT - Network Protocols.
*/
/*
* Copyright (C) 2008-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE 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.
*/
#ifndef ___iprt_net_h
#define ___iprt_net_h
/** @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 pszValue The value to convert.
* @param pAddr Where to store the result.
*/
/**
* IPv4 address.
*/
typedef RTUINT32U RTNETADDRIPV4;
/** 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.
*/
/**
* 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.
*/
/**
* 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.
*/
/**
* IPv6 address.
*/
typedef RTUINT128U RTNETADDRIPV6;
/** 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.
*/
/**
* IPX address.
*/
#pragma pack(1)
typedef struct RTNETADDRIPX
{
/** The network ID. */
/** The node ID. (Defaults to the MAC address apparently.) */
} RTNETADDRIPX;
#pragma pack()
/** 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. */
/** 32-bit view. */
/** 16-bit view. */
/** 8-bit view. */
/** IPv4 view. */
#ifndef IPv6 /* Work around X11 and RDP defining IPv6 to 1. */
/** IPv6 view. */
#endif
/** IPX view. */
/** MAC address view. */
} RTNETADDRU;
/** 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. */
/** IP version 4. */
/** IP version 6. */
/** IPX. */
/** MAC address. */
/** The end of the valid values. */
/** The usual 32-bit hack. */
RTNETADDRTYPE_32_BIT_HACK = 0x7fffffff
/** 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. */
/** Indicates which view of @a u that is valid. */
/** The port number for IPv4 and IPv6 addresses. This is set to
* RTNETADDR_NA_PORT if not applicable. */
} 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
{
/** Ethernet frame type or frame size, depending on the kind of ethernet.
* This is big endian on the wire. */
#pragma pack()
/** Pointer to an ethernet header. */
typedef RTNETETHERHDR *PRTNETETHERHDR;
/** Pointer to a const ethernet header. */
typedef RTNETETHERHDR const *PCRTNETETHERHDR;
/** @name EtherType (RTNETETHERHDR::EtherType)
* @{ */
/** @} */
/**
* 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. */
/** 06 - Offset if fragmented. */
/** 08 - Time to live. */
/** 09 - Protocol. */
/** 0a - Header check sum. */
/** 0c - Source address. */
/** 10 - Destination address. */
/** 14 - Options (optional). */
} RTNETIPV4;
#pragma pack()
/** 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(bool) RTNetIPv4IsHdrValid(PCRTNETIPV4 pIpHdr, size_t cbHdrMax, size_t cbPktMax, bool fChecksum);
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);
/**
* 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. */
/** 04 - Payload length, including extension headers. */
/** 06 - Next header type (RTNETIPV4_PROT_XXX). */
/** 07 - Hop limit. */
/** xx - Source address. */
/** xx - Destination address. */
} RTNETIPV6;
#pragma pack()
/** 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)
/**
* UDP header.
*/
#pragma pack(1)
typedef struct RTNETUDP
{
/** The source port. */
/** The destination port. */
/** The length of the UDP header and associated data. */
/** The checksum of the pseudo header, the UDP header and the data. */
} RTNETUDP;
#pragma pack()
/** Pointer to an UDP header. */
/** 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(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_*). */
/** 01 - Hardware address type. Same as RTNETARPHDR::ar_htype. */
/** 02 - Hardware address length. */
/** 03 - Gateway hops. */
/** 04 - Transaction ID. */
/** 08 - Seconds since boot started. */
/** 0a - Unused (BOOTP) / Flags (DHCP) (RTNET_DHCP_FLAGS_*). */
/** 0c - Client IPv4 address. */
/** 10 - Your IPv4 address. */
/** 14 - Server IPv4 address. */
/** 18 - Gateway IPv4 address. */
/** 1c - Client hardware address. */
union
{
} bp_chaddr;
/** 2c - Server name. */
/** 6c - File name / more DHCP options. */
/** ec - Vendor specific area (BOOTP) / Options (DHCP).
* @remark This is really 312 bytes in the DHCP version. */
union
{
struct DHCP
{
/** ec - The DHCP cookie (RTNET_DHCP_COOKIE). */
/** f0 - The DHCP options. */
} Dhcp;
} bp_vend;
} RTNETBOOTP;
#pragma pack()
/** 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. */
/** The normal size of RTNETBOOTP::bp_vend::Dhcp::dhcp_opts. */
/** @name BOOTP packet opcode values
* @{ */
#define RTNETBOOTP_OP_REQUEST 1
#define RTNETBOOTP_OP_REPLY 2
/** @} */
/** @name DHCP flags (RTNETBOOTP::bp_flags)
* @{ */
/** @} */
/** The DHCP cookie (network endian). */
/**
* An IPv4 DHCP option header.
*/
typedef struct RTNETDHCPOPT
{
/** 00 - The DHCP option. */
/** 01 - The data length (excluding this header). */
/* 02 - The option data follows here, optional and of variable length. */
} RTNETDHCPOPT;
/** 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.
#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 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. */
/** Hardware address type. */
/** Hardware address length. */
/** Client IPv4 address. */
/** Your IPv4 address. */
/** Server IPv4 address. */
/** Gateway IPv4 address. */
/** Client hardware address. */
/** Server name. */
} 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. */
/** 02 - The destination port. */
/** 04 - The sequence number. */
/** 08 - The acknowledgement number. */
#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. */
/** 12 - The urgent pointer. */
/* (options follows here and then the data (aka text).) */
} RTNETTCP;
#pragma pack()
/** Pointer to a TCP packet. */
/** 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(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,
/**
* IPv4 ICMP packet header.
*/
#pragma pack(1)
typedef struct RTNETICMPV4HDR
{
/** 00 - The ICMP message type. */
/** 01 - Type specific code that further qualifies the message. */
/** 02 - Checksum of the ICMP message. */
#pragma pack()
/** 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. */
/** 04 - The identifier to help the requestor match up the reply.
* Can be 0. Typically fixed value. */
/** 06 - The sequence number to help the requestor match up the reply.
* Can be 0. Typically incrementing between requests. */
/** 08 - Variable length data that is to be returned unmodified in the reply. */
#pragma pack()
/** 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. */
/** 04 - Identifier copied from the traceroute option's ID number. */
/** 06 - Unused. (Possibly an icmp_seq?) */
/** 08 - Outbound hop count. From the IP packet causing this message. */
/** 0a - Return hop count. From the IP packet causing this message. */
/** 0c - Output link speed, 0 if not known. */
/** 10 - Output link MTU, 0 if not known. */
#pragma pack()
/** 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
{
} RTNETICMPV4;
/** Pointer to an ICMP union packet. */
typedef RTNETICMPV4 *PRTNETICMPV4;
/** Pointer to a const ICMP union packet. */
typedef RTNETICMPV4 const *PCRTNETICMPV4;
/** @todo add ICMPv6 when needed. */
#define RTNETIPV6_PROT_ICMPV6 (58)
#define RTNETIPV6_ICMPV6_CODE_0 (0)
#define RTNETIPV6_ICMP_NS_TYPE (135)
#define RTNETIPV6_ICMP_NA_TYPE (136)
#define RTNETIPV6_ICMP_ND_SLLA_OPT (1)
#define RTNETIPV6_ICMP_ND_TLLA_OPT (2)
#define RTNETIPV6_ICMP_ND_LLA_LEN (1)
/** ICMPv6 ND Source Link Layer Address option */
#pragma pack(1)
typedef struct RTNETNDP_SLLA_OPT
{
#pragma pack()
typedef RTNETNDP_SLLA_OPT *PRTNETNDP_SLLA_OPT;
typedef RTNETNDP_SLLA_OPT const *PCRTNETNDP_SLLA_OPT;
/** ICMPv6 ND Neighbor Sollicitation */
#pragma pack(1)
typedef struct RTNETNDP
{
/** ICMPv6 type. */
/** ICMPv6 code. */
/** ICMPv6 checksum */
/** reserved */
/** target address */
} RTNETNDP;
#pragma pack()
/** Pointer to a NDP ND packet. */
/** Pointer to a const NDP NS packet. */
typedef RTNETNDP const *PCRTNETNDP;
/**
* Ethernet ARP header.
*/
#pragma pack(1)
typedef struct RTNETARPHDR
{
/** The hardware type. */
/** The protocol type (ethertype). */
/** The hardware address length. */
/** The protocol address length. */
/** The operation. */
} RTNETARPHDR;
#pragma pack()
/** Pointer to an ethernet ARP header. */
typedef RTNETARPHDR *PRTNETARPHDR;
/** Pointer to a const ethernet ARP header. */
typedef RTNETARPHDR const *PCRTNETARPHDR;
/** ARP hardware type - ethernet. */
/** @name ARP operations
* @{ */
#define RTNET_ARPOP_REQUEST UINT16_C(1) /**< Request hardware address given a protocol address (ARP). */
#define RTNET_ARPOP_REVREQUEST UINT16_C(3) /**< Request protocol address given a hardware address (RARP). */
/** Check if an ARP operation is a request or not. */
/** Check if an ARP operation is a reply or not. */
/** @} */
/**
* Ethernet IPv4 + 6-byte MAC ARP request packet.
*/
#pragma pack(1)
typedef struct RTNETARPIPV4
{
/** ARP header. */
/** The sender hardware address. */
/** The sender protocol address. */
/** The target hardware address. */
/** The arget protocol address. */
} RTNETARPIPV4;
#pragma pack()
/** 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;
/** @} */
#endif