/* Handle the ICMPv6 packet. First validate the message format, then, according to the message types, process it as an informational packet or an error packet. */
EFI_STATUS Ip6IcmpHandle(IN IP6_SERVICE *IpSb, IN EFI_IP6_HEADER *Head, IN NET_BUF *Packet)
/* Handle the ICMPv6 packet. First validate the message format, then, according to the message types, process it as an informational packet or an error packet. */
EFI_STATUS Ip6IcmpHandle(IN IP6_SERVICE *IpSb, IN EFI_IP6_HEADER *Head, IN NET_BUF *Packet)
{
  IP6_ICMP_HEAD  Icmp;
  UINT16         PseudoCheckSum;
  UINT16         CheckSum;
  if (Packet->TotalSize < sizeof (Icmp)) {
    goto DROP;
  }
  NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *)&Icmp);
  PseudoCheckSum = NetIp6PseudoHeadChecksum (
                     &Head->SourceAddress,
                     &Head->DestinationAddress,
                     IP6_ICMP,
                     Packet->TotalSize
                     );
  CheckSum = (UINT16) ~NetAddChecksum (PseudoCheckSum, NetbufChecksum (Packet));
  if (CheckSum != 0) {
    goto DROP;
  }
  if (Icmp.Type <= ICMP_V6_ERROR_MAX) {
    return Ip6ProcessIcmpError (IpSb, Head, Packet);
  } else {
    return Ip6ProcessIcmpInformation (IpSb, Head, Packet);
  }
DROP:
  NetbufFree (Packet);
  return EFI_INVALID_PARAMETER;
}