/** @file | |
Definition of IP6 option process routines. | |
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#ifndef __EFI_IP6_OPTION_H__ | |
#define __EFI_IP6_OPTION_H__ | |
#define IP6_FRAGMENT_OFFSET_MASK (~0x3) | |
// | |
// For more information see RFC 8200, Section 4.3, 4.4, and 4.6 | |
// | |
// This example format is from section 4.6 | |
// This does not apply to fragment headers | |
// | |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
// | Next Header | Hdr Ext Len | | | |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | |
// | | | |
// . . | |
// . Header-Specific Data . | |
// . . | |
// | | | |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
// | |
// Next Header 8-bit selector. Identifies the type of | |
// header immediately following the extension | |
// header. Uses the same values as the IPv4 | |
// Protocol field [IANA-PN]. | |
// | |
// Hdr Ext Len 8-bit unsigned integer. Length of the | |
// Destination Options header in 8-octet units, | |
// not including the first 8 octets. | |
// | |
// These defines apply to the following: | |
// 1. Hop by Hop | |
// 2. Routing | |
// 3. Destination | |
// | |
typedef struct _IP6_EXT_HDR { | |
/// | |
/// The Next Header field identifies the type of header immediately | |
/// | |
UINT8 NextHeader; | |
/// | |
/// The Hdr Ext Len field specifies the length of the Hop-by-Hop Options | |
/// | |
UINT8 HdrExtLen; | |
/// | |
/// Header-Specific Data | |
/// | |
} IP6_EXT_HDR; | |
STATIC_ASSERT ( | |
sizeof (IP6_EXT_HDR) == 2, | |
"The combined size of Next Header and Len is two 8 bit fields" | |
); | |
// | |
// IPv6 extension headers contain an 8-bit length field which describes the size of | |
// the header. However, the length field only includes the size of the extension | |
// header options, not the size of the first 8 bytes of the header. Therefore, in | |
// order to calculate the full size of the extension header, we add 1 (to account | |
// for the first 8 bytes omitted by the length field reporting) and then multiply | |
// by 8 (since the size is represented in 8-byte units). | |
// | |
// a is the length field of the extension header (UINT8) | |
// The result may be up to 2046 octets (UINT16) | |
// | |
#define IP6_HDR_EXT_LEN(a) (((UINT16)((UINT8)(a)) + 1) * 8) | |
// This is the maxmimum length permissible by a extension header | |
// Length is UINT8 of 8 octets not including the first 8 octets | |
#define IP6_MAX_EXT_DATA_LENGTH (IP6_HDR_EXT_LEN (MAX_UINT8) - sizeof(IP6_EXT_HDR)) | |
STATIC_ASSERT ( | |
IP6_MAX_EXT_DATA_LENGTH == 2046, | |
"Maximum data length is ((MAX_UINT8 + 1) * 8) - 2" | |
); | |
typedef struct _IP6_FRAGMENT_HEADER { | |
UINT8 NextHeader; | |
UINT8 Reserved; | |
UINT16 FragmentOffset; | |
UINT32 Identification; | |
} IP6_FRAGMENT_HEADER; | |
typedef struct _IP6_ROUTING_HEADER { | |
UINT8 NextHeader; | |
UINT8 HeaderLen; | |
UINT8 RoutingType; | |
UINT8 SegmentsLeft; | |
} IP6_ROUTING_HEADER; | |
typedef enum { | |
Ip6OptionPad1 = 0, | |
Ip6OptionPadN = 1, | |
Ip6OptionRouterAlert = 5, | |
Ip6OptionSkip = 0, | |
Ip6OptionDiscard = 0x40, | |
Ip6OptionParameterProblem = 0x80, | |
Ip6OptionMask = 0xc0, | |
Ip6OptionEtherSource = 1, | |
Ip6OptionEtherTarget = 2, | |
Ip6OptionPrefixInfo = 3, | |
Ip6OptionRedirected = 4, | |
Ip6OptionMtu = 5 | |
} IP6_OPTION_TYPE; | |
/** | |
Validate the IP6 extension header format for both the packets we received | |
and that we will transmit. It will compute the ICMPv6 error message fields | |
if the option is mal-formatted. | |
@param[in] IpSb The IP6 service instance. This is an optional parameter. | |
@param[in] Packet The data of the packet. Ignored if NULL. | |
@param[in] NextHeader The next header field in IPv6 basic header. | |
@param[in] ExtHdrs The first byte of the option. | |
@param[in] ExtHdrsLen The length of the whole option. | |
@param[in] Rcvd The option is from the packet we received if TRUE, | |
otherwise, the option we want to transmit. | |
@param[out] FormerHeader The offset of NextHeader which points to Fragment | |
Header when we received, of the ExtHdrs. | |
Ignored if we transmit. | |
@param[out] LastHeader The pointer of NextHeader of the last extension | |
header processed by IP6. | |
@param[out] RealExtsLen The length of extension headers processed by IP6 layer. | |
This is an optional parameter that may be NULL. | |
@param[out] UnFragmentLen The length of unfragmented length of extension headers. | |
This is an optional parameter that may be NULL. | |
@param[out] Fragmented Indicate whether the packet is fragmented. | |
This is an optional parameter that may be NULL. | |
@retval TRUE The option is properly formatted. | |
@retval FALSE The option is malformatted. | |
**/ | |
BOOLEAN | |
Ip6IsExtsValid ( | |
IN IP6_SERVICE *IpSb OPTIONAL, | |
IN NET_BUF *Packet OPTIONAL, | |
IN UINT8 *NextHeader, | |
IN UINT8 *ExtHdrs, | |
IN UINT32 ExtHdrsLen, | |
IN BOOLEAN Rcvd, | |
OUT UINT32 *FormerHeader OPTIONAL, | |
OUT UINT8 **LastHeader, | |
OUT UINT32 *RealExtsLen OPTIONAL, | |
OUT UINT32 *UnFragmentLen OPTIONAL, | |
OUT BOOLEAN *Fragmented OPTIONAL | |
); | |
/** | |
Generate an IPv6 router alert option in network order and output it through Buffer. | |
@param[out] Buffer Points to a buffer to record the generated option. | |
@param[in, out] BufferLen The length of Buffer, in bytes. | |
@param[in] NextHeader The 8-bit selector indicates the type of header | |
immediately following the Hop-by-Hop Options header. | |
@retval EFI_BUFFER_TOO_SMALL The Buffer is too small to contain the generated | |
option. BufferLen is updated for the required size. | |
@retval EFI_SUCCESS The option is generated and filled in to Buffer. | |
**/ | |
EFI_STATUS | |
Ip6FillHopByHop ( | |
OUT UINT8 *Buffer, | |
IN OUT UINTN *BufferLen, | |
IN UINT8 NextHeader | |
); | |
/** | |
Insert a Fragment Header to the Extension headers and output it in UpdatedExtHdrs. | |
@param[in] IpSb The IP6 service instance to transmit the packet. | |
@param[in] NextHeader The extension header type of first extension header. | |
@param[in] LastHeader The extension header type of last extension header. | |
@param[in] ExtHdrs The length of the original extension header. | |
@param[in] ExtHdrsLen The length of the extension headers. | |
@param[in] FragmentOffset The fragment offset of the data following the header. | |
@param[out] UpdatedExtHdrs The updated ExtHdrs with Fragment header inserted. | |
It's caller's responsibility to free this buffer. | |
@retval EFI_OUT_OF_RESOURCES Failed to finish the operation due to lake of | |
resource. | |
@retval EFI_UNSUPPORTED The extension header specified in ExtHdrs is not | |
supported currently. | |
@retval EFI_SUCCESS The operation performed successfully. | |
**/ | |
EFI_STATUS | |
Ip6FillFragmentHeader ( | |
IN IP6_SERVICE *IpSb, | |
IN UINT8 NextHeader, | |
IN UINT8 LastHeader, | |
IN UINT8 *ExtHdrs, | |
IN UINT32 ExtHdrsLen, | |
IN UINT16 FragmentOffset, | |
OUT UINT8 **UpdatedExtHdrs | |
); | |
/** | |
Copy the extension headers from the original to buffer. A Fragment header is | |
appended to the end. | |
@param[in] NextHeader The 8-bit selector indicates the type of | |
the fragment header's next header. | |
@param[in] ExtHdrs The length of the original extension header. | |
@param[in] LastHeader The pointer of next header of last extension header. | |
@param[in] FragmentOffset The fragment offset of the data following the header. | |
@param[in] UnFragmentHdrLen The length of unfragmented length of extension headers. | |
@param[in, out] Buf The buffer to copy options to. | |
@param[in, out] BufLen The length of the buffer. | |
@retval EFI_SUCCESS The options are copied over. | |
@retval EFI_BUFFER_TOO_SMALL The buffer caller provided is too small. | |
**/ | |
EFI_STATUS | |
Ip6CopyExts ( | |
IN UINT8 NextHeader, | |
IN UINT8 *ExtHdrs, | |
IN UINT8 *LastHeader, | |
IN UINT16 FragmentOffset, | |
IN UINT32 UnFragmentHdrLen, | |
IN OUT UINT8 *Buf, | |
IN OUT UINT32 *BufLen | |
); | |
/** | |
Validate the IP6 option format for both the packets we received | |
and that we will transmit. It supports the defined options in Neighbor | |
Discovery messages. | |
@param[in] Option The first byte of the option. | |
@param[in] OptionLen The length of the whole option. | |
@retval TRUE The option is properly formatted. | |
@retval FALSE The option is malformatted. | |
**/ | |
BOOLEAN | |
Ip6IsNDOptionValid ( | |
IN UINT8 *Option, | |
IN UINT16 OptionLen | |
); | |
#endif |