**/\r
BOOLEAN\r
Ip6IsOptionValid (\r
- IN IP6_SERVICE *IpSb,\r
- IN NET_BUF *Packet,\r
- IN UINT8 *Option,\r
- IN UINT8 OptionLen,\r
- IN UINT32 Pointer\r
+ IN IP6_SERVICE *IpSb,\r
+ IN NET_BUF *Packet,\r
+ IN UINT8 *Option,\r
+ IN UINT8 OptionLen,\r
+ IN UINT32 Pointer\r
)\r
{\r
- UINT8 Offset;\r
- UINT8 OptionType;\r
+ UINT8 Offset;\r
+ UINT8 OptionType;\r
\r
Offset = 0;\r
\r
OptionType = *(Option + Offset);\r
\r
switch (OptionType) {\r
- case Ip6OptionPad1:\r
- //\r
- // It is a Pad1 option\r
- //\r
- Offset++;\r
- break;\r
- case Ip6OptionPadN:\r
- //\r
- // It is a PadN option\r
- //\r
- Offset = (UINT8) (Offset + *(Option + Offset + 1) + 2);\r
- break;\r
- case Ip6OptionRouterAlert:\r
- //\r
- // It is a Router Alert Option\r
- //\r
- Offset += 4;\r
- break;\r
- default:\r
- //\r
- // The highest-order two bits specify the action must be taken if\r
- // the processing IPv6 node does not recognize the option type.\r
- //\r
- switch (OptionType & Ip6OptionMask) {\r
- case Ip6OptionSkip:\r
- Offset = (UINT8) (Offset + *(Option + Offset + 1));\r
+ case Ip6OptionPad1:\r
+ //\r
+ // It is a Pad1 option\r
+ //\r
+ Offset++;\r
break;\r
- case Ip6OptionDiscard:\r
- return FALSE;\r
- case Ip6OptionParameterProblem:\r
- Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER);\r
- Ip6SendIcmpError (\r
- IpSb,\r
- Packet,\r
- NULL,\r
- &Packet->Ip.Ip6->SourceAddress,\r
- ICMP_V6_PARAMETER_PROBLEM,\r
- 2,\r
- &Pointer\r
- );\r
- return FALSE;\r
- case Ip6OptionMask:\r
- if (!IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) {\r
- Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER);\r
- Ip6SendIcmpError (\r
- IpSb,\r
- Packet,\r
- NULL,\r
- &Packet->Ip.Ip6->SourceAddress,\r
- ICMP_V6_PARAMETER_PROBLEM,\r
- 2,\r
- &Pointer\r
- );\r
+ case Ip6OptionPadN:\r
+ //\r
+ // It is a PadN option\r
+ //\r
+ Offset = (UINT8)(Offset + *(Option + Offset + 1) + 2);\r
+ break;\r
+ case Ip6OptionRouterAlert:\r
+ //\r
+ // It is a Router Alert Option\r
+ //\r
+ Offset += 4;\r
+ break;\r
+ default:\r
+ //\r
+ // The highest-order two bits specify the action must be taken if\r
+ // the processing IPv6 node does not recognize the option type.\r
+ //\r
+ switch (OptionType & Ip6OptionMask) {\r
+ case Ip6OptionSkip:\r
+ Offset = (UINT8)(Offset + *(Option + Offset + 1));\r
+ break;\r
+ case Ip6OptionDiscard:\r
+ return FALSE;\r
+ case Ip6OptionParameterProblem:\r
+ Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER);\r
+ Ip6SendIcmpError (\r
+ IpSb,\r
+ Packet,\r
+ NULL,\r
+ &Packet->Ip.Ip6->SourceAddress,\r
+ ICMP_V6_PARAMETER_PROBLEM,\r
+ 2,\r
+ &Pointer\r
+ );\r
+ return FALSE;\r
+ case Ip6OptionMask:\r
+ if (!IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) {\r
+ Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER);\r
+ Ip6SendIcmpError (\r
+ IpSb,\r
+ Packet,\r
+ NULL,\r
+ &Packet->Ip.Ip6->SourceAddress,\r
+ ICMP_V6_PARAMETER_PROBLEM,\r
+ 2,\r
+ &Pointer\r
+ );\r
+ }\r
+\r
+ return FALSE;\r
+ break;\r
}\r
\r
- return FALSE;\r
break;\r
- }\r
-\r
- break;\r
}\r
-\r
}\r
\r
return TRUE;\r
**/\r
BOOLEAN\r
Ip6IsNDOptionValid (\r
- IN UINT8 *Option,\r
- IN UINT16 OptionLen\r
+ IN UINT8 *Option,\r
+ IN UINT16 OptionLen\r
)\r
{\r
- UINT32 Offset;\r
- UINT16 Length;\r
- IP6_OPTION_HEADER *OptionHeader;\r
+ UINT32 Offset;\r
+ UINT16 Length;\r
+ IP6_OPTION_HEADER *OptionHeader;\r
\r
if (Option == NULL) {\r
ASSERT (Option != NULL);\r
// fit within the input buffer.\r
//\r
while (Offset + sizeof (IP6_OPTION_HEADER) - 1 < OptionLen) {\r
- OptionHeader = (IP6_OPTION_HEADER*) (Option + Offset);\r
- Length = (UINT16) OptionHeader->Length * 8;\r
+ OptionHeader = (IP6_OPTION_HEADER *)(Option + Offset);\r
+ Length = (UINT16)OptionHeader->Length * 8;\r
\r
switch (OptionHeader->Type) {\r
- case Ip6OptionPrefixInfo:\r
- if (Length != 32) {\r
- return FALSE;\r
- }\r
- break;\r
+ case Ip6OptionPrefixInfo:\r
+ if (Length != 32) {\r
+ return FALSE;\r
+ }\r
\r
- case Ip6OptionMtu:\r
- if (Length != 8) {\r
- return FALSE;\r
- }\r
- break;\r
+ break;\r
\r
- default:\r
- // RFC 4861 states that Length field cannot be 0.\r
- if (Length == 0) {\r
- return FALSE;\r
- }\r
- break;\r
+ case Ip6OptionMtu:\r
+ if (Length != 8) {\r
+ return FALSE;\r
+ }\r
+\r
+ break;\r
+\r
+ default:\r
+ // RFC 4861 states that Length field cannot be 0.\r
+ if (Length == 0) {\r
+ return FALSE;\r
+ }\r
+\r
+ break;\r
}\r
\r
//\r
// Check whether recognized options are within the input buffer's scope.\r
//\r
switch (OptionHeader->Type) {\r
- case Ip6OptionEtherSource:\r
- case Ip6OptionEtherTarget:\r
- case Ip6OptionPrefixInfo:\r
- case Ip6OptionRedirected:\r
- case Ip6OptionMtu:\r
- if (Offset + Length > (UINT32) OptionLen) {\r
- return FALSE;\r
- }\r
- break;\r
+ case Ip6OptionEtherSource:\r
+ case Ip6OptionEtherTarget:\r
+ case Ip6OptionPrefixInfo:\r
+ case Ip6OptionRedirected:\r
+ case Ip6OptionMtu:\r
+ if (Offset + Length > (UINT32)OptionLen) {\r
+ return FALSE;\r
+ }\r
\r
- default:\r
- //\r
- // Unrecognized options can be either valid (but unused) or invalid\r
- // (garbage in between or right after valid options). Silently ignore.\r
- //\r
- break;\r
+ break;\r
+\r
+ default:\r
+ //\r
+ // Unrecognized options can be either valid (but unused) or invalid\r
+ // (garbage in between or right after valid options). Silently ignore.\r
+ //\r
+ break;\r
}\r
\r
//\r
return TRUE;\r
}\r
\r
-\r
/**\r
Validate whether the NextHeader is a known valid protocol or one of the user configured\r
protocols from the upper layer.\r
**/\r
BOOLEAN\r
Ip6IsValidProtocol (\r
- IN IP6_SERVICE *IpSb,\r
- IN UINT8 NextHeader\r
+ IN IP6_SERVICE *IpSb,\r
+ IN UINT8 NextHeader\r
)\r
{\r
- LIST_ENTRY *Entry;\r
- IP6_PROTOCOL *IpInstance;\r
-\r
- if (NextHeader == EFI_IP_PROTO_TCP ||\r
- NextHeader == EFI_IP_PROTO_UDP ||\r
- NextHeader == IP6_ICMP ||\r
- NextHeader == IP6_ESP\r
- ) {\r
+ LIST_ENTRY *Entry;\r
+ IP6_PROTOCOL *IpInstance;\r
+\r
+ if ((NextHeader == EFI_IP_PROTO_TCP) ||\r
+ (NextHeader == EFI_IP_PROTO_UDP) ||\r
+ (NextHeader == IP6_ICMP) ||\r
+ (NextHeader == IP6_ESP)\r
+ )\r
+ {\r
return TRUE;\r
}\r
\r
**/\r
BOOLEAN\r
Ip6IsExtsValid (\r
- IN IP6_SERVICE *IpSb OPTIONAL,\r
- IN NET_BUF *Packet OPTIONAL,\r
- IN UINT8 *NextHeader,\r
- IN UINT8 *ExtHdrs,\r
- IN UINT32 ExtHdrsLen,\r
- IN BOOLEAN Rcvd,\r
- OUT UINT32 *FormerHeader OPTIONAL,\r
- OUT UINT8 **LastHeader,\r
- OUT UINT32 *RealExtsLen OPTIONAL,\r
- OUT UINT32 *UnFragmentLen OPTIONAL,\r
- OUT BOOLEAN *Fragmented OPTIONAL\r
+ IN IP6_SERVICE *IpSb OPTIONAL,\r
+ IN NET_BUF *Packet OPTIONAL,\r
+ IN UINT8 *NextHeader,\r
+ IN UINT8 *ExtHdrs,\r
+ IN UINT32 ExtHdrsLen,\r
+ IN BOOLEAN Rcvd,\r
+ OUT UINT32 *FormerHeader OPTIONAL,\r
+ OUT UINT8 **LastHeader,\r
+ OUT UINT32 *RealExtsLen OPTIONAL,\r
+ OUT UINT32 *UnFragmentLen OPTIONAL,\r
+ OUT BOOLEAN *Fragmented OPTIONAL\r
)\r
{\r
- UINT32 Pointer;\r
- UINT32 Offset;\r
- UINT8 *Option;\r
- UINT8 OptionLen;\r
- BOOLEAN Flag;\r
- UINT8 CountD;\r
- UINT8 CountA;\r
- IP6_FRAGMENT_HEADER *FragmentHead;\r
- UINT16 FragmentOffset;\r
- IP6_ROUTING_HEADER *RoutingHead;\r
+ UINT32 Pointer;\r
+ UINT32 Offset;\r
+ UINT8 *Option;\r
+ UINT8 OptionLen;\r
+ BOOLEAN Flag;\r
+ UINT8 CountD;\r
+ UINT8 CountA;\r
+ IP6_FRAGMENT_HEADER *FragmentHead;\r
+ UINT16 FragmentOffset;\r
+ IP6_ROUTING_HEADER *RoutingHead;\r
\r
if (RealExtsLen != NULL) {\r
*RealExtsLen = 0;\r
\r
*LastHeader = NextHeader;\r
\r
- if (ExtHdrs == NULL && ExtHdrsLen == 0) {\r
+ if ((ExtHdrs == NULL) && (ExtHdrsLen == 0)) {\r
return TRUE;\r
}\r
\r
- if ((ExtHdrs == NULL && ExtHdrsLen != 0) || (ExtHdrs != NULL && ExtHdrsLen == 0)) {\r
+ if (((ExtHdrs == NULL) && (ExtHdrsLen != 0)) || ((ExtHdrs != NULL) && (ExtHdrsLen == 0))) {\r
return FALSE;\r
}\r
\r
CountA = 0;\r
\r
while (Offset <= ExtHdrsLen) {\r
-\r
switch (*NextHeader) {\r
- case IP6_HOP_BY_HOP:\r
- if (Offset != 0) {\r
- if (!Rcvd) {\r
+ case IP6_HOP_BY_HOP:\r
+ if (Offset != 0) {\r
+ if (!Rcvd) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Hop-by-Hop Options header is restricted to appear immediately after an IPv6 header only.\r
+ // If not, generate a ICMP parameter problem message with code value of 1.\r
+ //\r
+ if (Pointer == 0) {\r
+ Pointer = sizeof (EFI_IP6_HEADER);\r
+ } else {\r
+ Pointer = Offset + sizeof (EFI_IP6_HEADER);\r
+ }\r
+\r
+ if ((IpSb != NULL) && (Packet != NULL) &&\r
+ !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress))\r
+ {\r
+ Ip6SendIcmpError (\r
+ IpSb,\r
+ Packet,\r
+ NULL,\r
+ &Packet->Ip.Ip6->SourceAddress,\r
+ ICMP_V6_PARAMETER_PROBLEM,\r
+ 1,\r
+ &Pointer\r
+ );\r
+ }\r
+\r
return FALSE;\r
}\r
- //\r
- // Hop-by-Hop Options header is restricted to appear immediately after an IPv6 header only.\r
- // If not, generate a ICMP parameter problem message with code value of 1.\r
- //\r
- if (Pointer == 0) {\r
- Pointer = sizeof (EFI_IP6_HEADER);\r
- } else {\r
- Pointer = Offset + sizeof (EFI_IP6_HEADER);\r
+\r
+ Flag = TRUE;\r
+\r
+ //\r
+ // Fall through\r
+ //\r
+ case IP6_DESTINATION:\r
+ if (*NextHeader == IP6_DESTINATION) {\r
+ CountD++;\r
}\r
\r
- if ((IpSb != NULL) && (Packet != NULL) &&\r
- !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) {\r
- Ip6SendIcmpError (\r
- IpSb,\r
- Packet,\r
- NULL,\r
- &Packet->Ip.Ip6->SourceAddress,\r
- ICMP_V6_PARAMETER_PROBLEM,\r
- 1,\r
- &Pointer\r
- );\r
+ if (CountD > 2) {\r
+ return FALSE;\r
}\r
- return FALSE;\r
- }\r
\r
- Flag = TRUE;\r
+ NextHeader = ExtHdrs + Offset;\r
+ Pointer = Offset;\r
\r
- //\r
- // Fall through\r
- //\r
- case IP6_DESTINATION:\r
- if (*NextHeader == IP6_DESTINATION) {\r
- CountD++;\r
- }\r
+ Offset++;\r
+ Option = ExtHdrs + Offset;\r
+ OptionLen = (UINT8)((*Option + 1) * 8 - 2);\r
+ Option++;\r
+ Offset++;\r
\r
- if (CountD > 2) {\r
- return FALSE;\r
- }\r
+ if ((IpSb != NULL) && (Packet != NULL) && !Ip6IsOptionValid (IpSb, Packet, Option, OptionLen, Offset)) {\r
+ return FALSE;\r
+ }\r
\r
- NextHeader = ExtHdrs + Offset;\r
- Pointer = Offset;\r
+ Offset = Offset + OptionLen;\r
\r
- Offset++;\r
- Option = ExtHdrs + Offset;\r
- OptionLen = (UINT8) ((*Option + 1) * 8 - 2);\r
- Option++;\r
- Offset++;\r
+ if (Flag) {\r
+ if (UnFragmentLen != NULL) {\r
+ *UnFragmentLen = Offset;\r
+ }\r
\r
- if (IpSb != NULL && Packet != NULL && !Ip6IsOptionValid (IpSb, Packet, Option, OptionLen, Offset)) {\r
- return FALSE;\r
- }\r
+ Flag = FALSE;\r
+ }\r
+\r
+ break;\r
\r
- Offset = Offset + OptionLen;\r
+ case IP6_ROUTING:\r
+ NextHeader = ExtHdrs + Offset;\r
+ RoutingHead = (IP6_ROUTING_HEADER *)NextHeader;\r
\r
- if (Flag) {\r
- if (UnFragmentLen != NULL) {\r
- *UnFragmentLen = Offset;\r
+ //\r
+ // Type 0 routing header is defined in RFC2460 and deprecated in RFC5095.\r
+ // Thus all routing types are processed as unrecognized.\r
+ //\r
+ if (RoutingHead->SegmentsLeft == 0) {\r
+ //\r
+ // Ignore the routing header and proceed to process the next header.\r
+ //\r
+ Offset = Offset + (RoutingHead->HeaderLen + 1) * 8;\r
+\r
+ if (UnFragmentLen != NULL) {\r
+ *UnFragmentLen = Offset;\r
+ }\r
+ } else {\r
+ //\r
+ // Discard the packet and send an ICMP Parameter Problem, Code 0, message\r
+ // to the packet's source address, pointing to the unrecognized routing\r
+ // type.\r
+ //\r
+ Pointer = Offset + 2 + sizeof (EFI_IP6_HEADER);\r
+ if ((IpSb != NULL) && (Packet != NULL) &&\r
+ !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress))\r
+ {\r
+ Ip6SendIcmpError (\r
+ IpSb,\r
+ Packet,\r
+ NULL,\r
+ &Packet->Ip.Ip6->SourceAddress,\r
+ ICMP_V6_PARAMETER_PROBLEM,\r
+ 0,\r
+ &Pointer\r
+ );\r
+ }\r
+\r
+ return FALSE;\r
}\r
\r
- Flag = FALSE;\r
- }\r
+ break;\r
\r
- break;\r
+ case IP6_FRAGMENT:\r
\r
- case IP6_ROUTING:\r
- NextHeader = ExtHdrs + Offset;\r
- RoutingHead = (IP6_ROUTING_HEADER *) NextHeader;\r
+ //\r
+ // RFC2402, AH header should after fragment header.\r
+ //\r
+ if (CountA > 1) {\r
+ return FALSE;\r
+ }\r
\r
- //\r
- // Type 0 routing header is defined in RFC2460 and deprecated in RFC5095.\r
- // Thus all routing types are processed as unrecognized.\r
- //\r
- if (RoutingHead->SegmentsLeft == 0) {\r
//\r
- // Ignore the routing header and proceed to process the next header.\r
+ // RFC2460, ICMP Parameter Problem message with code 0 should be sent\r
+ // if the length of a fragment is not a multiple of 8 octets and the M\r
+ // flag of that fragment is 1, pointing to the Payload length field of the\r
+ // fragment packet.\r
//\r
- Offset = Offset + (RoutingHead->HeaderLen + 1) * 8;\r
+ if ((IpSb != NULL) && (Packet != NULL) && ((ExtHdrsLen % 8) != 0)) {\r
+ //\r
+ // Check whether it is the last fragment.\r
+ //\r
+ FragmentHead = (IP6_FRAGMENT_HEADER *)(ExtHdrs + Offset);\r
+ if (FragmentHead == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ FragmentOffset = NTOHS (FragmentHead->FragmentOffset);\r
+\r
+ if (((FragmentOffset & 0x1) == 0x1) &&\r
+ !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress))\r
+ {\r
+ Pointer = sizeof (UINT32);\r
+ Ip6SendIcmpError (\r
+ IpSb,\r
+ Packet,\r
+ NULL,\r
+ &Packet->Ip.Ip6->SourceAddress,\r
+ ICMP_V6_PARAMETER_PROBLEM,\r
+ 0,\r
+ &Pointer\r
+ );\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ if (Fragmented != NULL) {\r
+ *Fragmented = TRUE;\r
+ }\r
+\r
+ if (Rcvd && (FormerHeader != NULL)) {\r
+ *FormerHeader = (UINT32)(NextHeader - ExtHdrs);\r
+ }\r
+\r
+ NextHeader = ExtHdrs + Offset;\r
+ Offset = Offset + 8;\r
+ break;\r
\r
- if (UnFragmentLen != NULL) {\r
- *UnFragmentLen = Offset;\r
+ case IP6_AH:\r
+ if (++CountA > 1) {\r
+ return FALSE;\r
}\r
\r
- } else {\r
+ Option = ExtHdrs + Offset;\r
+ NextHeader = Option;\r
+ Option++;\r
//\r
- // Discard the packet and send an ICMP Parameter Problem, Code 0, message\r
- // to the packet's source address, pointing to the unrecognized routing\r
- // type.\r
+ // RFC2402, Payload length is specified in 32-bit words, minus "2".\r
//\r
- Pointer = Offset + 2 + sizeof (EFI_IP6_HEADER);\r
- if ((IpSb != NULL) && (Packet != NULL) &&\r
- !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) {\r
- Ip6SendIcmpError (\r
- IpSb,\r
- Packet,\r
- NULL,\r
- &Packet->Ip.Ip6->SourceAddress,\r
- ICMP_V6_PARAMETER_PROBLEM,\r
- 0,\r
- &Pointer\r
- );\r
- }\r
+ OptionLen = (UINT8)((*Option + 2) * 4);\r
+ Offset = Offset + OptionLen;\r
+ break;\r
\r
+ case IP6_NO_NEXT_HEADER:\r
+ *LastHeader = NextHeader;\r
return FALSE;\r
- }\r
+ break;\r
\r
- break;\r
+ default:\r
+ if (Ip6IsValidProtocol (IpSb, *NextHeader)) {\r
+ *LastHeader = NextHeader;\r
\r
- case IP6_FRAGMENT:\r
+ if (RealExtsLen != NULL) {\r
+ *RealExtsLen = Offset;\r
+ }\r
\r
- //\r
- // RFC2402, AH header should after fragment header.\r
- //\r
- if (CountA > 1) {\r
- return FALSE;\r
- }\r
+ return TRUE;\r
+ }\r
\r
- //\r
- // RFC2460, ICMP Parameter Problem message with code 0 should be sent\r
- // if the length of a fragment is not a multiple of 8 octets and the M\r
- // flag of that fragment is 1, pointing to the Payload length field of the\r
- // fragment packet.\r
- //\r
- if (IpSb != NULL && Packet != NULL && (ExtHdrsLen % 8) != 0) {\r
//\r
- // Check whether it is the last fragment.\r
+ // The Next Header value is unrecognized by the node, discard the packet and\r
+ // send an ICMP parameter problem message with code value of 1.\r
//\r
- FragmentHead = (IP6_FRAGMENT_HEADER *) (ExtHdrs + Offset);\r
- if (FragmentHead == NULL) {\r
- return FALSE;\r
+ if (Offset == 0) {\r
+ //\r
+ // The Next Header directly follows IPv6 basic header.\r
+ //\r
+ Pointer = 6;\r
+ } else {\r
+ if (Pointer == 0) {\r
+ Pointer = sizeof (EFI_IP6_HEADER);\r
+ } else {\r
+ Pointer = Offset + sizeof (EFI_IP6_HEADER);\r
+ }\r
}\r
\r
- FragmentOffset = NTOHS (FragmentHead->FragmentOffset);\r
-\r
- if (((FragmentOffset & 0x1) == 0x1) &&\r
- !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) {\r
- Pointer = sizeof (UINT32);\r
+ if ((IpSb != NULL) && (Packet != NULL) &&\r
+ !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress))\r
+ {\r
Ip6SendIcmpError (\r
IpSb,\r
Packet,\r
NULL,\r
&Packet->Ip.Ip6->SourceAddress,\r
ICMP_V6_PARAMETER_PROBLEM,\r
- 0,\r
+ 1,\r
&Pointer\r
);\r
- return FALSE;\r
}\r
- }\r
-\r
- if (Fragmented != NULL) {\r
- *Fragmented = TRUE;\r
- }\r
\r
- if (Rcvd && FormerHeader != NULL) {\r
- *FormerHeader = (UINT32) (NextHeader - ExtHdrs);\r
- }\r
-\r
- NextHeader = ExtHdrs + Offset;\r
- Offset = Offset + 8;\r
- break;\r
-\r
- case IP6_AH:\r
- if (++CountA > 1) {\r
return FALSE;\r
- }\r
-\r
- Option = ExtHdrs + Offset;\r
- NextHeader = Option;\r
- Option++;\r
- //\r
- // RFC2402, Payload length is specified in 32-bit words, minus "2".\r
- //\r
- OptionLen = (UINT8) ((*Option + 2) * 4);\r
- Offset = Offset + OptionLen;\r
- break;\r
-\r
- case IP6_NO_NEXT_HEADER:\r
- *LastHeader = NextHeader;\r
- return FALSE;\r
- break;\r
-\r
- default:\r
- if (Ip6IsValidProtocol (IpSb, *NextHeader)) {\r
-\r
- *LastHeader = NextHeader;\r
-\r
- if (RealExtsLen != NULL) {\r
- *RealExtsLen = Offset;\r
- }\r
-\r
- return TRUE;\r
- }\r
-\r
- //\r
- // The Next Header value is unrecognized by the node, discard the packet and\r
- // send an ICMP parameter problem message with code value of 1.\r
- //\r
- if (Offset == 0) {\r
- //\r
- // The Next Header directly follows IPv6 basic header.\r
- //\r
- Pointer = 6;\r
- } else {\r
- if (Pointer == 0) {\r
- Pointer = sizeof (EFI_IP6_HEADER);\r
- } else {\r
- Pointer = Offset + sizeof (EFI_IP6_HEADER);\r
- }\r
- }\r
-\r
- if ((IpSb != NULL) && (Packet != NULL) &&\r
- !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) {\r
- Ip6SendIcmpError (\r
- IpSb,\r
- Packet,\r
- NULL,\r
- &Packet->Ip.Ip6->SourceAddress,\r
- ICMP_V6_PARAMETER_PROBLEM,\r
- 1,\r
- &Pointer\r
- );\r
- }\r
- return FALSE;\r
}\r
}\r
\r
**/\r
EFI_STATUS\r
Ip6FillHopByHop (\r
- OUT UINT8 *Buffer,\r
- IN OUT UINTN *BufferLen,\r
- IN UINT8 NextHeader\r
+ OUT UINT8 *Buffer,\r
+ IN OUT UINTN *BufferLen,\r
+ IN UINT8 NextHeader\r
)\r
{\r
- UINT8 BufferArray[8];\r
+ UINT8 BufferArray[8];\r
\r
if (*BufferLen < 8) {\r
*BufferLen = 8;\r
**/\r
EFI_STATUS\r
Ip6FillFragmentHeader (\r
- IN IP6_SERVICE *IpSb,\r
- IN UINT8 NextHeader,\r
- IN UINT8 LastHeader,\r
- IN UINT8 *ExtHdrs,\r
- IN UINT32 ExtHdrsLen,\r
- IN UINT16 FragmentOffset,\r
- OUT UINT8 **UpdatedExtHdrs\r
+ IN IP6_SERVICE *IpSb,\r
+ IN UINT8 NextHeader,\r
+ IN UINT8 LastHeader,\r
+ IN UINT8 *ExtHdrs,\r
+ IN UINT32 ExtHdrsLen,\r
+ IN UINT16 FragmentOffset,\r
+ OUT UINT8 **UpdatedExtHdrs\r
)\r
{\r
- UINT32 Length;\r
- UINT8 *Buffer;\r
- UINT32 FormerHeader;\r
- UINT32 Offset;\r
- UINT32 Part1Len;\r
- UINT32 HeaderLen;\r
- UINT8 Current;\r
- IP6_FRAGMENT_HEADER FragmentHead;\r
+ UINT32 Length;\r
+ UINT8 *Buffer;\r
+ UINT32 FormerHeader;\r
+ UINT32 Offset;\r
+ UINT32 Part1Len;\r
+ UINT32 HeaderLen;\r
+ UINT8 Current;\r
+ IP6_FRAGMENT_HEADER FragmentHead;\r
\r
if (UpdatedExtHdrs == NULL) {\r
return EFI_INVALID_PARAMETER;\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- Offset = 0;\r
- Part1Len = 0;\r
- FormerHeader = 0;\r
- Current = NextHeader;\r
+ Offset = 0;\r
+ Part1Len = 0;\r
+ FormerHeader = 0;\r
+ Current = NextHeader;\r
\r
while ((ExtHdrs != NULL) && (Offset <= ExtHdrsLen)) {\r
switch (NextHeader) {\r
- case IP6_ROUTING:\r
- case IP6_HOP_BY_HOP:\r
- case IP6_DESTINATION:\r
- Current = NextHeader;\r
- NextHeader = *(ExtHdrs + Offset);\r
+ case IP6_ROUTING:\r
+ case IP6_HOP_BY_HOP:\r
+ case IP6_DESTINATION:\r
+ Current = NextHeader;\r
+ NextHeader = *(ExtHdrs + Offset);\r
+\r
+ if ((Current == IP6_DESTINATION) && (NextHeader != IP6_ROUTING)) {\r
+ //\r
+ // Destination Options header should occur at most twice, once before\r
+ // a Routing header and once before the upper-layer header. Here we\r
+ // find the one before the upper-layer header. Insert the Fragment\r
+ // Header before it.\r
+ //\r
+ CopyMem (Buffer, ExtHdrs, Part1Len);\r
+ *(Buffer + FormerHeader) = IP6_FRAGMENT;\r
+ //\r
+ // Exit the loop.\r
+ //\r
+ Offset = ExtHdrsLen + 1;\r
+ break;\r
+ }\r
\r
- if ((Current == IP6_DESTINATION) && (NextHeader != IP6_ROUTING)) {\r
- //\r
- // Destination Options header should occur at most twice, once before\r
- // a Routing header and once before the upper-layer header. Here we\r
- // find the one before the upper-layer header. Insert the Fragment\r
- // Header before it.\r
- //\r
- CopyMem (Buffer, ExtHdrs, Part1Len);\r
- *(Buffer + FormerHeader) = IP6_FRAGMENT;\r
- //\r
- // Exit the loop.\r
- //\r
- Offset = ExtHdrsLen + 1;\r
+ FormerHeader = Offset;\r
+ HeaderLen = (*(ExtHdrs + Offset + 1) + 1) * 8;\r
+ Part1Len = Part1Len + HeaderLen;\r
+ Offset = Offset + HeaderLen;\r
break;\r
- }\r
-\r
\r
- FormerHeader = Offset;\r
- HeaderLen = (*(ExtHdrs + Offset + 1) + 1) * 8;\r
- Part1Len = Part1Len + HeaderLen;\r
- Offset = Offset + HeaderLen;\r
- break;\r
-\r
- case IP6_FRAGMENT:\r
- Current = NextHeader;\r
-\r
- if (Part1Len != 0) {\r
- CopyMem (Buffer, ExtHdrs, Part1Len);\r
- }\r
-\r
- *(Buffer + FormerHeader) = IP6_FRAGMENT;\r
-\r
- //\r
- // Exit the loop.\r
- //\r
- Offset = ExtHdrsLen + 1;\r
- break;\r
+ case IP6_FRAGMENT:\r
+ Current = NextHeader;\r
\r
- case IP6_AH:\r
- Current = NextHeader;\r
- NextHeader = *(ExtHdrs + Offset);\r
- //\r
- // RFC2402, Payload length is specified in 32-bit words, minus "2".\r
- //\r
- HeaderLen = (*(ExtHdrs + Offset + 1) + 2) * 4;\r
- Part1Len = Part1Len + HeaderLen;\r
- Offset = Offset + HeaderLen;\r
- break;\r
+ if (Part1Len != 0) {\r
+ CopyMem (Buffer, ExtHdrs, Part1Len);\r
+ }\r
\r
- default:\r
- if (Ip6IsValidProtocol (IpSb, NextHeader)) {\r
- Current = NextHeader;\r
- CopyMem (Buffer, ExtHdrs, Part1Len);\r
*(Buffer + FormerHeader) = IP6_FRAGMENT;\r
+\r
//\r
// Exit the loop.\r
//\r
Offset = ExtHdrsLen + 1;\r
break;\r
- }\r
\r
- FreePool (Buffer);\r
- return EFI_UNSUPPORTED;\r
+ case IP6_AH:\r
+ Current = NextHeader;\r
+ NextHeader = *(ExtHdrs + Offset);\r
+ //\r
+ // RFC2402, Payload length is specified in 32-bit words, minus "2".\r
+ //\r
+ HeaderLen = (*(ExtHdrs + Offset + 1) + 2) * 4;\r
+ Part1Len = Part1Len + HeaderLen;\r
+ Offset = Offset + HeaderLen;\r
+ break;\r
+\r
+ default:\r
+ if (Ip6IsValidProtocol (IpSb, NextHeader)) {\r
+ Current = NextHeader;\r
+ CopyMem (Buffer, ExtHdrs, Part1Len);\r
+ *(Buffer + FormerHeader) = IP6_FRAGMENT;\r
+ //\r
+ // Exit the loop.\r
+ //\r
+ Offset = ExtHdrsLen + 1;\r
+ break;\r
+ }\r
+\r
+ FreePool (Buffer);\r
+ return EFI_UNSUPPORTED;\r
}\r
}\r
\r
\r
return EFI_SUCCESS;\r
}\r
-\r