4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The ICMPv6 handle routines to process the ICMPv6 control messages.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.php.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "Ip6Impl.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_IP6_ICMP_TYPE mIp6SupportedIcmp[23] = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEST_UNREACHABLE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_NO_ROUTE_TO_DEST
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEST_UNREACHABLE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_COMM_PROHIBITED
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEST_UNREACHABLE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_BEYOND_SCOPE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEST_UNREACHABLE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_ADDR_UNREACHABLE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEST_UNREACHABLE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_PORT_UNREACHABLE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEST_UNREACHABLE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_SOURCE_ADDR_FAILED
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEST_UNREACHABLE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_ROUTE_REJECTED
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_PACKET_TOO_BIG,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEFAULT_CODE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_TIME_EXCEEDED,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_TIMEOUT_HOP_LIMIT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_TIME_EXCEEDED,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_TIMEOUT_REASSEMBLE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_PARAMETER_PROBLEM,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_ERRONEOUS_HEADER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_PARAMETER_PROBLEM,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_UNRECOGNIZE_NEXT_HDR
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_PARAMETER_PROBLEM,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_UNRECOGNIZE_OPTION
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_ECHO_REQUEST,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEFAULT_CODE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_ECHO_REPLY,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEFAULT_CODE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_LISTENER_QUERY,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEFAULT_CODE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_LISTENER_REPORT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEFAULT_CODE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_LISTENER_REPORT_2,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEFAULT_CODE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_LISTENER_DONE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEFAULT_CODE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_ROUTER_SOLICIT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEFAULT_CODE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_ROUTER_ADVERTISE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEFAULT_CODE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_NEIGHBOR_SOLICIT,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEFAULT_CODE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_NEIGHBOR_ADVERTISE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ICMP_V6_DEFAULT_CODE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Reply an ICMPv6 echo request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpSb The IP service that received the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Head The IP head of the ICMPv6 informational message.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The content of the ICMPv6 message with the IP head
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync removed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Successfully answered the ICMPv6 Echo request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to answer the ICMPv6 Echo request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6IcmpReplyEcho (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_SERVICE *IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_HEADER *Head,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_BUF *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_ICMP_INFORMATION_HEAD *Icmp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_BUF *Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_HEADER ReplyHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // make a copy the packet, it is really a bad idea to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // send the MNP's buffer back to MNP.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data = NetbufDuplicate (Packet, NULL, IP6_MAX_HEADLEN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Data == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Change the ICMP type to echo reply, exchange the source
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // and destination, then send it. The source is updated to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // use specific destination. See RFC1122. SRR/RR option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // update is omitted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Icmp = (IP6_ICMP_INFORMATION_HEAD *) NetbufGetByte (Data, 0, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Icmp == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Icmp->Head.Type = ICMP_V6_ECHO_REPLY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Icmp->Head.Checksum = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Generate the IPv6 basic header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If the Echo Reply is a response to a Echo Request sent to one of the node's unicast address,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the Source address of the Echo Reply must be the same address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&ReplyHead, sizeof (EFI_IP6_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ReplyHead.PayloadLength = HTONS ((UINT16) (Packet->TotalSize));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ReplyHead.NextHeader = IP6_ICMP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ReplyHead.HopLimit = IpSb->CurHopLimit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_COPY_ADDRESS (&ReplyHead.DestinationAddress, &Head->SourceAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6IsOneOfSetAddress (IpSb, &Head->DestinationAddress, NULL, NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_COPY_ADDRESS (&ReplyHead.SourceAddress, &Head->DestinationAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If source is unspecified, Ip6Output will select a source for us
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6Output (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &ReplyHead,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6SysPacketSent,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncExit:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process Packet Too Big message sent by a router in response to a packet that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync it cannot forward because the packet is larger than the MTU of outgoing link.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Since this driver already uses IPv6 minimum link MTU as the maximum packet size,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if Packet Too Big message is still received, do not reduce the packet size, but
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync rather include a Fragment header in the subsequent packets.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpSb The IP service that received the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Head The IP head of the ICMPv6 error packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The content of the ICMPv6 error with the IP head
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync removed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The ICMPv6 error processed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to finish the operation due to lack of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync resource.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The packet too big message is not sent to us.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6ProcessPacketTooBig (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_SERVICE *IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_HEADER *Head,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_BUF *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_ICMP_ERROR_HEAD Icmp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Mtu;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_ROUTE_ENTRY *RouteEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IPv6_ADDRESS *DestAddress;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtu = NTOHL (Icmp.Fourth);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DestAddress = &Icmp.IpHead.DestinationAddress;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Mtu < IP6_MIN_LINK_MTU) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Normally the multicast address is considered to be on-link and not recorded
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // in route table. Here it is added into the table since the MTU information
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // need be recorded.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IP6_IS_MULTICAST (DestAddress)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RouteEntry = Ip6CreateRouteEntry (DestAddress, 128, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (RouteEntry == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RouteEntry->Flag = IP6_DIRECT_ROUTE | IP6_PACKET_TOO_BIG;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InsertHeadList (&IpSb->RouteTable->RouteArea[128], &RouteEntry->Link);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->RouteTable->TotalNum++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RouteEntry = Ip6FindRouteEntry (IpSb->RouteTable, DestAddress, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (RouteEntry == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RouteEntry->Flag = RouteEntry->Flag | IP6_PACKET_TOO_BIG;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6FreeRouteEntry (RouteEntry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the ICMPv6 error packet, and deliver the packet to upper layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpSb The IP service that received the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Head The IP head of the ICMPv6 error packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The content of the ICMPv6 error with the IP head
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync removed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The ICMPv6 error processed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER The packet is invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to process the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6ProcessIcmpError (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_SERVICE *IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_HEADER *Head,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_BUF *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_ICMP_ERROR_HEAD Icmp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the validity of the packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet->TotalSize < sizeof (Icmp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto DROP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Icmp.Head.Type == ICMP_V6_PACKET_TOO_BIG) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Ip6ProcessPacketTooBig (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Notify the upper-layer process that an ICMPv6 eror message is received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_GET_CLIP_INFO (Packet)->Status = EFI_ICMP_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Ip6Demultiplex (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDROP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the ICMPv6 informational messages. If it is an ICMPv6 echo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync request, answer it. If it is a MLD message, trigger MLD routines to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync process it. If it is a ND message, trigger ND routines to process it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Otherwise, deliver it to upper layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpSb The IP service that receivd the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Head The IP head of the ICMPv6 informational packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The content of the ICMPv6 informational packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync with IP head removed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER The packet is invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The ICMPv6 informational message processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to process ICMPv6 informational message.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6ProcessIcmpInformation (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_SERVICE *IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_HEADER *Head,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_BUF *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_ICMP_INFORMATION_HEAD Icmp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_CHECK_SIGNATURE (Packet, NET_BUF_SIGNATURE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Head != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Icmp.Head.Type) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_ECHO_REQUEST:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If ICMPv6 echo, reply it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Icmp.Head.Code == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6IcmpReplyEcho (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_LISTENER_QUERY:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6ProcessMldQuery (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_LISTENER_REPORT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_LISTENER_REPORT_2:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6ProcessMldReport (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_NEIGHBOR_SOLICIT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6ProcessNeighborSolicit (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_NEIGHBOR_ADVERTISE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6ProcessNeighborAdvertise (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_ROUTER_ADVERTISE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6ProcessRouterAdvertise (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_REDIRECT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6ProcessRedirect (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_ECHO_REPLY:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6Demultiplex (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Handle the ICMPv6 packet. First validate the message format,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync then, according to the message types, process it as an informational packet or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync an error packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpSb The IP service that received the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Head The IP head of the ICMPv6 packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The content of the ICMPv6 packet with IP head
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync removed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER The packet is malformated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The ICMPv6 message successfully processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to handle the ICMPv6 packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6IcmpHandle (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_SERVICE *IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_HEADER *Head,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_BUF *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_ICMP_HEAD Icmp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 PseudoCheckSum;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 CheckSum;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the validity of the incoming packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet->TotalSize < sizeof (Icmp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto DROP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Make sure checksum is valid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PseudoCheckSum = NetIp6PseudoHeadChecksum (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Head->SourceAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Head->DestinationAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_ICMP,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->TotalSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CheckSum = (UINT16) ~NetAddChecksum (PseudoCheckSum, NetbufChecksum (Packet));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CheckSum != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto DROP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // According to the packet type, call corresponding process
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Icmp.Type <= ICMP_V6_ERROR_MAX) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Ip6ProcessIcmpError (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Ip6ProcessIcmpInformation (IpSb, Head, Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDROP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Retrieve the Prefix address according to the PrefixLength by clear the useless
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync bits.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PrefixLength The prefix length of the prefix.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Prefix On input, points to the original prefix address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync with dirty bits; on output, points to the updated
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address with useless bit clear.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6GetPrefix (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 PrefixLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_IPv6_ADDRESS *Prefix
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Byte;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Bit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Mask;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((Prefix != NULL) && (PrefixLength < IP6_PREFIX_NUM));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrefixLength == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (Prefix, sizeof (EFI_IPv6_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrefixLength == IP6_PREFIX_NUM - 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Byte = (UINT8) (PrefixLength / 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Bit = (UINT8) (PrefixLength % 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = Prefix->Addr[Byte];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Byte > 0) && (Byte < 16)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (Prefix->Addr + Byte, 16 - Byte);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Bit > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mask = (UINT8) (0xFF << (8 - Bit));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Prefix->Addr[Byte] = (UINT8) (Value & Mask);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check whether the DestinationAddress is an anycast address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpSb The IP service that received the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DestinationAddress Points to the Destination Address of the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE The DestinationAddress is anycast address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE The DestinationAddress is not anycast address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6IsAnycast (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_SERVICE *IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IPv6_ADDRESS *DestinationAddress
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PREFIX_LIST_ENTRY *PrefixEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IPv6_ADDRESS Prefix;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Flag;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&Prefix, sizeof (EFI_IPv6_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Flag = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If the address is known as on-link or autonomous prefix, record it as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // anycast address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrefixEntry = Ip6FindPrefixListEntry (IpSb, Flag, 255, DestinationAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PrefixEntry != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_COPY_ADDRESS (&Prefix, &PrefixEntry->Prefix);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6GetPrefix (PrefixEntry->PrefixLength, &Prefix);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_IP6_EQUAL (&Prefix, DestinationAddress)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Flag = (BOOLEAN) !Flag;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Flag);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Generate ICMPv6 error message and send it out to DestinationAddress. Currently
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Destination Unreachable message, Time Exceeded message and Parameter Problem
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync message are supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpSb The IP service that received the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The packet which invoking ICMPv6 error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SourceAddress If not NULL, points to the SourceAddress.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Otherwise, the IP layer will select a source address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync according to the DestinationAddress.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DestinationAddress Points to the Destination Address of the ICMPv6
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync error message.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Type The type of the ICMPv6 message.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Code The additional level of the ICMPv6 message.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Pointer If not NULL, identifies the octet offset within
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the invoking packet where the error was detected.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER The packet is malformated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES There is no sufficient resource to complete the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The ICMPv6 message was successfully sent out.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to generate the ICMPv6 packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6SendIcmpError (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_SERVICE *IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_BUF *Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IPv6_ADDRESS *DestinationAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 Type,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 Code,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 *Pointer OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 PacketLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_BUF *ErrorMsg;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 PayloadLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_HEADER Head;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_ICMP_INFORMATION_HEAD *IcmpHead;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *ErrorBody;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DestinationAddress == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // An ICMPv6 error message must not be originated as a result of receiving
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // a packet whose source address does not uniquely identify a single node --
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // e.g., the IPv6 Unspecified Address, an IPv6 multicast address, or an address
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // known by the ICMP message originator to be an IPv6 anycast address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NetIp6IsUnspecifiedAddr (DestinationAddress) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_IS_MULTICAST (DestinationAddress) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6IsAnycast (IpSb, DestinationAddress)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Type) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_DEST_UNREACHABLE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_TIME_EXCEEDED:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ICMP_V6_PARAMETER_PROBLEM:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Pointer == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PacketLen = sizeof (IP6_ICMP_ERROR_HEAD) + Packet->TotalSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PacketLen > IpSb->MaxPacketSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PacketLen = IpSb->MaxPacketSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrorMsg = NetbufAlloc (PacketLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ErrorMsg == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayloadLen = (UINT16) (PacketLen - sizeof (EFI_IP6_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create the basic IPv6 header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&Head, sizeof (EFI_IP6_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.PayloadLength = HTONS (PayloadLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.NextHeader = IP6_ICMP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.HopLimit = IpSb->CurHopLimit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SourceAddress != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_COPY_ADDRESS (&Head.SourceAddress, SourceAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&Head.SourceAddress, sizeof (EFI_IPv6_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_COPY_ADDRESS (&Head.DestinationAddress, DestinationAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufReserve (ErrorMsg, sizeof (EFI_IP6_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fill in the ICMP error message head
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpHead = (IP6_ICMP_INFORMATION_HEAD *) NetbufAllocSpace (ErrorMsg, sizeof (IP6_ICMP_INFORMATION_HEAD), FALSE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IcmpHead == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (ErrorMsg);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (IcmpHead, sizeof (IP6_ICMP_INFORMATION_HEAD));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpHead->Head.Type = Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpHead->Head.Code = Code;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Pointer != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IcmpHead->Fourth = HTONL (*Pointer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fill in the ICMP error message body
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PayloadLen -= sizeof (IP6_ICMP_INFORMATION_HEAD);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ErrorBody = NetbufAllocSpace (ErrorMsg, PayloadLen, FALSE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ErrorBody != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (ErrorBody, PayloadLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufCopy (Packet, 0, PayloadLen, ErrorBody);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Transmit the packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Ip6Output (IpSb, NULL, NULL, ErrorMsg, &Head, NULL, 0, Ip6SysPacketSent, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync