/* Handle the ICMP packet. First validate the message format, then according to the message types, process it as query or error packet. */
EFI_STATUS Ip4IcmpHandle(IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet)
/* Handle the ICMP packet. First validate the message format, then according to the message types, process it as query or error packet. */
EFI_STATUS Ip4IcmpHandle(IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet)
{
  IP4_ICMP_HEAD  Icmp;
  UINT16         Checksum;
  if (Packet->TotalSize < sizeof (Icmp)) {
    goto DROP;
  }
  NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *)&Icmp);
  if (Icmp.Type > ICMP_TYPE_MAX) {
    goto DROP;
  }
  Checksum = (UINT16)(~NetbufChecksum (Packet));
  if ((Icmp.Checksum != 0) && (Checksum != 0)) {
    goto DROP;
  }
  if (mIcmpClass[Icmp.Type].IcmpClass == ICMP_ERROR_MESSAGE) {
    return Ip4ProcessIcmpError (IpSb, Head, Packet);
  } else if (mIcmpClass[Icmp.Type].IcmpClass == ICMP_QUERY_MESSAGE) {
    return Ip4ProcessIcmpQuery (IpSb, Head, Packet);
  }
DROP:
  NetbufFree (Packet);
  return EFI_INVALID_PARAMETER;
}