]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c
NetworkPkg: Move Network library and drivers from MdeModulePkg to NetworkPkg
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Udp4Dxe / Udp4Impl.c
diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c
deleted file mode 100644 (file)
index fb1951f..0000000
+++ /dev/null
@@ -1,1908 +0,0 @@
-/** @file\r
-  The implementation of the Udp4 protocol.\r
-\r
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-\r
-#include "Udp4Impl.h"\r
-\r
-UINT16  mUdp4RandomPort;\r
-\r
-/**\r
-  This function checks and timeouts the I/O datagrams holding by the corresponding\r
-  service context.\r
-\r
-  @param[in]  Event                  The event this function registered to.\r
-  @param[in]  Context                The context data registered during the creation of\r
-                                     the Event.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Udp4CheckTimeout (\r
-  IN EFI_EVENT  Event,\r
-  IN VOID       *Context\r
-  );\r
-\r
-/**\r
-  This function finds the udp instance by the specified <Address, Port> pair.\r
-\r
-  @param[in]  InstanceList           Pointer to the head of the list linking the udp\r
-                                     instances.\r
-  @param[in]  Address                Pointer to the specified IPv4 address.\r
-  @param[in]  Port                   The udp port number.\r
-\r
-  @retval TRUE     The specified <Address, Port> pair is found.\r
-  @retval FALSE    Otherwise.\r
-\r
-**/\r
-BOOLEAN\r
-Udp4FindInstanceByPort (\r
-  IN LIST_ENTRY        *InstanceList,\r
-  IN EFI_IPv4_ADDRESS  *Address,\r
-  IN UINT16            Port\r
-  );\r
-\r
-/**\r
-  This function is the packet transmitting notify function registered to the IpIo\r
-  interface. It's called to signal the udp TxToken when IpIo layer completes the\r
-  transmitting of the udp datagram.\r
-\r
-  @param[in]  Status                 The completion status of the output udp datagram.\r
-  @param[in]  Context                Pointer to the context data.\r
-  @param[in]  Sender                 Specify a pointer of EFI_IP4_PROTOCOL for sending.\r
-  @param[in]  NotifyData             Pointer to the notify data.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Udp4DgramSent (\r
-  IN EFI_STATUS        Status,\r
-  IN VOID              *Context,\r
-  IN IP_IO_IP_PROTOCOL Sender,\r
-  IN VOID              *NotifyData\r
-  );\r
-\r
-/**\r
-  This function processes the received datagram passed up by the IpIo layer.\r
-\r
-  @param[in]  Status             The status of this udp datagram.\r
-  @param[in]  IcmpError          The IcmpError code, only available when Status is\r
-                                 EFI_ICMP_ERROR.\r
-  @param[in]  NetSession         Pointer to the EFI_NET_SESSION_DATA.\r
-  @param[in]  Packet             Pointer to the NET_BUF containing the received udp\r
-                                 datagram.\r
-  @param[in]  Context            Pointer to the context data.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Udp4DgramRcvd (\r
-  IN EFI_STATUS            Status,\r
-  IN UINT8                 IcmpError,\r
-  IN EFI_NET_SESSION_DATA  *NetSession,\r
-  IN NET_BUF               *Packet,\r
-  IN VOID                  *Context\r
-  );\r
-\r
-/**\r
-  This function cancels the token specified by Arg in the Map. This is a callback\r
-  used by Udp4InstanceCancelToken().\r
-\r
-  @param[in]  Map                Pointer to the NET_MAP.\r
-  @param[in]  Item               Pointer to the NET_MAP_ITEM.\r
-  @param[in]  Arg                Pointer to the token to be cancelled, if NULL,\r
-                                 the token specified by Item is cancelled.\r
-\r
-  @retval EFI_SUCCESS            The token is cancelled if Arg is NULL or the token\r
-                                 is not the same as that in the Item if Arg is not\r
-                                 NULL.\r
-  @retval EFI_ABORTED            Arg is not NULL, and the token specified by Arg is\r
-                                 cancelled.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Udp4CancelTokens (\r
-  IN NET_MAP       *Map,\r
-  IN NET_MAP_ITEM  *Item,\r
-  IN VOID          *Arg OPTIONAL\r
-  );\r
-\r
-/**\r
-  This function matches the received udp datagram with the Instance.\r
-\r
-  @param[in]  Instance           Pointer to the udp instance context data.\r
-  @param[in]  Udp4Session        Pointer to the EFI_UDP4_SESSION_DATA abstracted\r
-                                 from the received udp datagram.\r
-\r
-  @retval TRUE       The udp datagram matches the receiving requirments of the\r
-                     udp Instance.\r
-  @retval FALSE      Otherwise.\r
-\r
-**/\r
-BOOLEAN\r
-Udp4MatchDgram (\r
-  IN UDP4_INSTANCE_DATA     *Instance,\r
-  IN EFI_UDP4_SESSION_DATA  *Udp4Session\r
-  );\r
-\r
-/**\r
-  This function removes the Wrap specified by Context and release relevant resources.\r
-\r
-  @param[in]  Event              The Event this notify function registered to.\r
-  @param[in]  Context            Pointer to the context data.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Udp4RecycleRxDataWrap (\r
-  IN EFI_EVENT  Event,\r
-  IN VOID       *Context\r
-  );\r
-\r
-/**\r
-  This function wraps the Packet and the RxData.\r
-\r
-  @param[in]  Instance               Pointer to the instance context data.\r
-  @param[in]  Packet                 Pointer to the buffer containing the received\r
-                                     datagram.\r
-  @param[in]  RxData                 Pointer to the EFI_UDP4_RECEIVE_DATA of this\r
-                                     datagram.\r
-\r
-  @return Pointer to the structure wrapping the RxData and the Packet.\r
-\r
-**/\r
-UDP4_RXDATA_WRAP *\r
-Udp4WrapRxData (\r
-  IN UDP4_INSTANCE_DATA     *Instance,\r
-  IN NET_BUF                *Packet,\r
-  IN EFI_UDP4_RECEIVE_DATA  *RxData\r
-  );\r
-\r
-/**\r
-  This function enqueues the received datagram into the instances' receiving queues.\r
-\r
-  @param[in]  Udp4Service            Pointer to the udp service context data.\r
-  @param[in]  Packet                 Pointer to the buffer containing the received\r
-                                     datagram.\r
-  @param[in]  RxData                 Pointer to the EFI_UDP4_RECEIVE_DATA of this\r
-                                     datagram.\r
-\r
-  @return The times this datagram is enqueued.\r
-\r
-**/\r
-UINTN\r
-Udp4EnqueueDgram (\r
-  IN UDP4_SERVICE_DATA      *Udp4Service,\r
-  IN NET_BUF                *Packet,\r
-  IN EFI_UDP4_RECEIVE_DATA  *RxData\r
-  );\r
-\r
-/**\r
-  This function delivers the datagrams enqueued in the instances.\r
-\r
-  @param[in]  Udp4Service            Pointer to the udp service context data.\r
-\r
-**/\r
-VOID\r
-Udp4DeliverDgram (\r
-  IN UDP4_SERVICE_DATA  *Udp4Service\r
-  );\r
-\r
-/**\r
-  This function demultiplexes the received udp datagram to the appropriate instances.\r
-\r
-  @param[in]  Udp4Service            Pointer to the udp service context data.\r
-  @param[in]  NetSession             Pointer to the EFI_NET_SESSION_DATA abstracted from\r
-                                     the received datagram.\r
-  @param[in]  Packet                 Pointer to the buffer containing the received udp\r
-                                     datagram.\r
-\r
-**/\r
-VOID\r
-Udp4Demultiplex (\r
-  IN UDP4_SERVICE_DATA     *Udp4Service,\r
-  IN EFI_NET_SESSION_DATA  *NetSession,\r
-  IN NET_BUF               *Packet\r
-  );\r
-\r
-/**\r
-  This function handles the received Icmp Error message and demultiplexes it to the\r
-  instance.\r
-\r
-  @param[in]  Udp4Service            Pointer to the udp service context data.\r
-  @param[in]  IcmpError              The icmp error code.\r
-  @param[in]  NetSession             Pointer to the EFI_NET_SESSION_DATA abstracted\r
-                                 from the received Icmp Error packet.\r
-  @param[in]  Packet                 Pointer to the Icmp Error packet.\r
-\r
-**/\r
-VOID\r
-Udp4IcmpHandler (\r
-  IN UDP4_SERVICE_DATA     *Udp4Service,\r
-  IN UINT8                 IcmpError,\r
-  IN EFI_NET_SESSION_DATA  *NetSession,\r
-  IN NET_BUF               *Packet\r
-  );\r
-\r
-/**\r
-  This function builds and sends out a icmp port unreachable message.\r
-\r
-  @param[in]  IpIo                   Pointer to the IP_IO instance.\r
-  @param[in]  NetSession             Pointer to the EFI_NET_SESSION_DATA of the packet\r
-                                     causes this icmp error message.\r
-  @param[in]  Udp4Header             Pointer to the udp header of the datagram causes\r
-                                     this icmp error message.\r
-\r
-**/\r
-VOID\r
-Udp4SendPortUnreach (\r
-  IN IP_IO                 *IpIo,\r
-  IN EFI_NET_SESSION_DATA  *NetSession,\r
-  IN VOID                  *Udp4Header\r
-  );\r
-\r
-\r
-/**\r
-  Create the Udp service context data.\r
-\r
-  @param[in, out] Udp4Service      Pointer to the UDP4_SERVICE_DATA.\r
-  @param[in]      ImageHandle      The image handle of this udp4 driver.\r
-  @param[in]      ControllerHandle The controller handle this udp4 driver binds on.\r
-\r
-  @retval EFI_SUCCESS              The udp4 service context data is created and\r
-                                   initialized.\r
-  @retval EFI_OUT_OF_RESOURCES     Cannot allocate memory.\r
-  @retval other                    Other error occurs.\r
-\r
-**/\r
-EFI_STATUS\r
-Udp4CreateService (\r
-  IN OUT UDP4_SERVICE_DATA  *Udp4Service,\r
-  IN     EFI_HANDLE         ImageHandle,\r
-  IN     EFI_HANDLE         ControllerHandle\r
-  )\r
-{\r
-  EFI_STATUS          Status;\r
-  IP_IO_OPEN_DATA     OpenData;\r
-  EFI_IP4_CONFIG_DATA *Ip4ConfigData;\r
-\r
-  ZeroMem (Udp4Service, sizeof (UDP4_SERVICE_DATA));\r
-\r
-  Udp4Service->Signature        = UDP4_SERVICE_DATA_SIGNATURE;\r
-  Udp4Service->ServiceBinding   = mUdp4ServiceBinding;\r
-  Udp4Service->ImageHandle      = ImageHandle;\r
-  Udp4Service->ControllerHandle = ControllerHandle;\r
-  Udp4Service->ChildrenNumber   = 0;\r
-\r
-  InitializeListHead (&Udp4Service->ChildrenList);\r
-\r
-  //\r
-  // Create the IpIo for this service context.\r
-  //\r
-  Udp4Service->IpIo = IpIoCreate (ImageHandle, ControllerHandle, IP_VERSION_4);\r
-  if (Udp4Service->IpIo == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  //\r
-  // Set the OpenData used to open the IpIo.\r
-  //\r
-  Ip4ConfigData = &OpenData.IpConfigData.Ip4CfgData;\r
-  CopyMem (Ip4ConfigData, &mIp4IoDefaultIpConfigData, sizeof (EFI_IP4_CONFIG_DATA));\r
-  Ip4ConfigData->AcceptBroadcast = TRUE;\r
-  OpenData.RcvdContext           = (VOID *) Udp4Service;\r
-  OpenData.SndContext            = NULL;\r
-  OpenData.PktRcvdNotify         = Udp4DgramRcvd;\r
-  OpenData.PktSentNotify         = Udp4DgramSent;\r
-\r
-  //\r
-  // Configure and start the IpIo.\r
-  //\r
-  Status = IpIoOpen (Udp4Service->IpIo, &OpenData);\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
-  }\r
-\r
-  //\r
-  // Create the event for Udp timeout checking.\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
-                  Udp4CheckTimeout,\r
-                  Udp4Service,\r
-                  &Udp4Service->TimeoutEvent\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
-  }\r
-\r
-  //\r
-  // Start the timeout timer event.\r
-  //\r
-  Status = gBS->SetTimer (\r
-                  Udp4Service->TimeoutEvent,\r
-                  TimerPeriodic,\r
-                  UDP4_TIMEOUT_INTERVAL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-\r
-ON_ERROR:\r
-\r
-  if (Udp4Service->TimeoutEvent != NULL) {\r
-    gBS->CloseEvent (Udp4Service->TimeoutEvent);\r
-  }\r
-\r
-  IpIoDestroy (Udp4Service->IpIo);\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Clean the Udp service context data.\r
-\r
-  @param[in]  Udp4Service            Pointer to the UDP4_SERVICE_DATA.\r
-\r
-**/\r
-VOID\r
-Udp4CleanService (\r
-  IN UDP4_SERVICE_DATA  *Udp4Service\r
-  )\r
-{\r
-  //\r
-  // Cancel the TimeoutEvent timer.\r
-  //\r
-  gBS->SetTimer (Udp4Service->TimeoutEvent, TimerCancel, 0);\r
-\r
-  //\r
-  // Close the TimeoutEvent timer.\r
-  //\r
-  gBS->CloseEvent (Udp4Service->TimeoutEvent);\r
-\r
-  //\r
-  // Destroy the IpIo.\r
-  //\r
-  IpIoDestroy (Udp4Service->IpIo);\r
-}\r
-\r
-\r
-/**\r
-  This function checks and timeouts the I/O datagrams holding by the corresponding\r
-  service context.\r
-\r
-  @param[in]  Event                  The event this function registered to.\r
-  @param[in]  Context                The context data registered during the creation of\r
-                                     the Event.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Udp4CheckTimeout (\r
-  IN EFI_EVENT  Event,\r
-  IN VOID       *Context\r
-  )\r
-{\r
-  UDP4_SERVICE_DATA   *Udp4Service;\r
-  LIST_ENTRY          *Entry;\r
-  UDP4_INSTANCE_DATA  *Instance;\r
-  LIST_ENTRY          *WrapEntry;\r
-  LIST_ENTRY          *NextEntry;\r
-  UDP4_RXDATA_WRAP    *Wrap;\r
-\r
-  Udp4Service = (UDP4_SERVICE_DATA *) Context;\r
-  NET_CHECK_SIGNATURE (Udp4Service, UDP4_SERVICE_DATA_SIGNATURE);\r
-\r
-  NET_LIST_FOR_EACH (Entry, &Udp4Service->ChildrenList) {\r
-    //\r
-    // Iterate all the instances belonging to this service context.\r
-    //\r
-    Instance = NET_LIST_USER_STRUCT (Entry, UDP4_INSTANCE_DATA, Link);\r
-    NET_CHECK_SIGNATURE (Instance, UDP4_INSTANCE_DATA_SIGNATURE);\r
-\r
-    if (!Instance->Configured || (Instance->ConfigData.ReceiveTimeout == 0)) {\r
-      //\r
-      // Skip this instance if it's not configured or no receive timeout.\r
-      //\r
-      continue;\r
-    }\r
-\r
-    NET_LIST_FOR_EACH_SAFE (WrapEntry, NextEntry, &Instance->RcvdDgramQue) {\r
-      //\r
-      // Iterate all the rxdatas belonging to this udp instance.\r
-      //\r
-      Wrap = NET_LIST_USER_STRUCT (WrapEntry, UDP4_RXDATA_WRAP, Link);\r
-\r
-      //\r
-      // TimeoutTick unit is microsecond, MNP_TIMEOUT_CHECK_INTERVAL unit is 100ns.\r
-      //\r
-      if (Wrap->TimeoutTick < (UDP4_TIMEOUT_INTERVAL / 10)) {\r
-        //\r
-        // Remove this RxData if it timeouts.\r
-        //\r
-        Udp4RecycleRxDataWrap (NULL, (VOID *) Wrap);\r
-      } else {\r
-        Wrap->TimeoutTick -= (UDP4_TIMEOUT_INTERVAL / 10);\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  This function intializes the new created udp instance.\r
-\r
-  @param[in]      Udp4Service       Pointer to the UDP4_SERVICE_DATA.\r
-  @param[in, out] Instance          Pointer to the un-initialized UDP4_INSTANCE_DATA.\r
-\r
-**/\r
-VOID\r
-Udp4InitInstance (\r
-  IN     UDP4_SERVICE_DATA   *Udp4Service,\r
-  IN OUT UDP4_INSTANCE_DATA  *Instance\r
-  )\r
-{\r
-  //\r
-  // Set the signature.\r
-  //\r
-  Instance->Signature = UDP4_INSTANCE_DATA_SIGNATURE;\r
-\r
-  //\r
-  // Init the lists.\r
-  //\r
-  InitializeListHead (&Instance->Link);\r
-  InitializeListHead (&Instance->RcvdDgramQue);\r
-  InitializeListHead (&Instance->DeliveredDgramQue);\r
-\r
-  //\r
-  // Init the NET_MAPs.\r
-  //\r
-  NetMapInit (&Instance->TxTokens);\r
-  NetMapInit (&Instance->RxTokens);\r
-  NetMapInit (&Instance->McastIps);\r
-\r
-  //\r
-  // Save the pointer to the UDP4_SERVICE_DATA, and initialize other members.\r
-  //\r
-  Instance->Udp4Service = Udp4Service;\r
-  CopyMem (&Instance->Udp4Proto, &mUdp4Protocol, sizeof (Instance->Udp4Proto));\r
-  Instance->IcmpError   = EFI_SUCCESS;\r
-  Instance->Configured  = FALSE;\r
-  Instance->IsNoMapping = FALSE;\r
-  Instance->InDestroy   = FALSE;\r
-}\r
-\r
-\r
-/**\r
-  This function cleans the udp instance.\r
-\r
-  @param[in]  Instance               Pointer to the UDP4_INSTANCE_DATA to clean.\r
-\r
-**/\r
-VOID\r
-Udp4CleanInstance (\r
-  IN UDP4_INSTANCE_DATA  *Instance\r
-  )\r
-{\r
-  NetMapClean (&Instance->McastIps);\r
-  NetMapClean (&Instance->RxTokens);\r
-  NetMapClean (&Instance->TxTokens);\r
-}\r
-\r
-\r
-/**\r
-  This function finds the udp instance by the specified <Address, Port> pair.\r
-\r
-  @param[in]  InstanceList           Pointer to the head of the list linking the udp\r
-                                     instances.\r
-  @param[in]  Address                Pointer to the specified IPv4 address.\r
-  @param[in]  Port                   The udp port number.\r
-\r
-  @retval TRUE     The specified <Address, Port> pair is found.\r
-  @retval FALSE    Otherwise.\r
-\r
-**/\r
-BOOLEAN\r
-Udp4FindInstanceByPort (\r
-  IN LIST_ENTRY        *InstanceList,\r
-  IN EFI_IPv4_ADDRESS  *Address,\r
-  IN UINT16            Port\r
-  )\r
-{\r
-  LIST_ENTRY            *Entry;\r
-  UDP4_INSTANCE_DATA    *Instance;\r
-  EFI_UDP4_CONFIG_DATA  *ConfigData;\r
-\r
-  NET_LIST_FOR_EACH (Entry, InstanceList) {\r
-    //\r
-    // Iterate all the udp instances.\r
-    //\r
-    Instance   = NET_LIST_USER_STRUCT (Entry, UDP4_INSTANCE_DATA, Link);\r
-    ConfigData = &Instance->ConfigData;\r
-\r
-    if (!Instance->Configured || ConfigData->AcceptAnyPort) {\r
-      //\r
-      // If the instance is not configured or the configdata of the instance indicates\r
-      // this instance accepts any port, skip it.\r
-      //\r
-      continue;\r
-    }\r
-\r
-    if (EFI_IP4_EQUAL (&ConfigData->StationAddress, Address) &&\r
-      (ConfigData->StationPort == Port)) {\r
-      //\r
-      // if both the address and the port are the same, return TRUE.\r
-      //\r
-      return TRUE;\r
-    }\r
-  }\r
-\r
-  //\r
-  // return FALSE when matching fails.\r
-  //\r
-  return FALSE;\r
-}\r
-\r
-\r
-/**\r
-  This function tries to bind the udp instance according to the configured port\r
-  allocation strategy.\r
-\r
-  @param[in]      InstanceList   Pointer to the head of the list linking the udp\r
-                                 instances.\r
-  @param[in, out] ConfigData     Pointer to the ConfigData of the instance to be\r
-                                 bound. ConfigData->StationPort will be assigned\r
-                                 with an available port value on success.\r
-\r
-  @retval EFI_SUCCESS            The bound operation is completed successfully.\r
-  @retval EFI_ACCESS_DENIED      The <Address, Port> specified by the ConfigData is\r
-                                 already used by other instance.\r
-  @retval EFI_OUT_OF_RESOURCES   No available port resources.\r
-\r
-**/\r
-EFI_STATUS\r
-Udp4Bind (\r
-  IN     LIST_ENTRY            *InstanceList,\r
-  IN OUT EFI_UDP4_CONFIG_DATA  *ConfigData\r
-  )\r
-{\r
-  EFI_IPv4_ADDRESS  *StationAddress;\r
-  UINT16            StartPort;\r
-\r
-  if (ConfigData->AcceptAnyPort) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  StationAddress = &ConfigData->StationAddress;\r
-\r
-  if (ConfigData->StationPort != 0) {\r
-\r
-    if (!ConfigData->AllowDuplicatePort &&\r
-      Udp4FindInstanceByPort (InstanceList, StationAddress, ConfigData->StationPort)) {\r
-      //\r
-      // Do not allow duplicate port and the port is already used by other instance.\r
-      //\r
-      return EFI_ACCESS_DENIED;\r
-    }\r
-  } else {\r
-    //\r
-    // select a random port for this instance;\r
-    //\r
-\r
-    if (ConfigData->AllowDuplicatePort) {\r
-      //\r
-      // Just pick up the random port if the instance allows duplicate port.\r
-      //\r
-      ConfigData->StationPort = mUdp4RandomPort;\r
-    } else {\r
-\r
-      StartPort = mUdp4RandomPort;\r
-\r
-      while (Udp4FindInstanceByPort(InstanceList, StationAddress, mUdp4RandomPort)) {\r
-\r
-        mUdp4RandomPort++;\r
-        if (mUdp4RandomPort == 0) {\r
-          mUdp4RandomPort = UDP4_PORT_KNOWN;\r
-        }\r
-\r
-        if (mUdp4RandomPort == StartPort) {\r
-          //\r
-          // No available port.\r
-          //\r
-          return EFI_OUT_OF_RESOURCES;\r
-        }\r
-      }\r
-\r
-      ConfigData->StationPort = mUdp4RandomPort;\r
-    }\r
-\r
-    mUdp4RandomPort++;\r
-    if (mUdp4RandomPort == 0) {\r
-      mUdp4RandomPort = UDP4_PORT_KNOWN;\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  This function is used to check whether the NewConfigData has any un-reconfigurable\r
-  parameters changed compared to the OldConfigData.\r
-\r
-  @param[in]  OldConfigData      Pointer to the current ConfigData the udp instance\r
-                                 uses.\r
-  @param[in]  NewConfigData      Pointer to the new ConfigData.\r
-\r
-  @retval TRUE     The instance is reconfigurable.\r
-  @retval FALSE    Otherwise.\r
-\r
-**/\r
-BOOLEAN\r
-Udp4IsReconfigurable (\r
-  IN EFI_UDP4_CONFIG_DATA  *OldConfigData,\r
-  IN EFI_UDP4_CONFIG_DATA  *NewConfigData\r
-  )\r
-{\r
-  if ((NewConfigData->AcceptAnyPort      != OldConfigData->AcceptAnyPort)     ||\r
-      (NewConfigData->AcceptBroadcast    != OldConfigData->AcceptBroadcast)   ||\r
-      (NewConfigData->AcceptPromiscuous  != OldConfigData->AcceptPromiscuous) ||\r
-      (NewConfigData->AllowDuplicatePort != OldConfigData->AllowDuplicatePort)\r
-      ) {\r
-    //\r
-    // The receiving filter parameters cannot be changed.\r
-    //\r
-    return FALSE;\r
-  }\r
-\r
-  if ((!NewConfigData->AcceptAnyPort) &&\r
-      (NewConfigData->StationPort != OldConfigData->StationPort)\r
-      ) {\r
-    //\r
-    // The port is not changeable.\r
-    //\r
-    return FALSE;\r
-  }\r
-\r
-  if (!NewConfigData->AcceptPromiscuous) {\r
-\r
-    if (NewConfigData->UseDefaultAddress != OldConfigData->UseDefaultAddress) {\r
-      //\r
-      // The NewConfigData differs to the old one on the UseDefaultAddress.\r
-      //\r
-      return FALSE;\r
-    }\r
-\r
-    if (!NewConfigData->UseDefaultAddress &&\r
-        (!EFI_IP4_EQUAL (&NewConfigData->StationAddress, &OldConfigData->StationAddress) ||\r
-         !EFI_IP4_EQUAL (&NewConfigData->SubnetMask, &OldConfigData->SubnetMask))\r
-        ) {\r
-      //\r
-      // If the instance doesn't use the default address, and the new address or\r
-      // new subnet mask is different from the old values.\r
-      //\r
-      return FALSE;\r
-    }\r
-  }\r
-\r
-  if (!EFI_IP4_EQUAL (&NewConfigData->RemoteAddress, &OldConfigData->RemoteAddress)) {\r
-    //\r
-    // The remoteaddress is not the same.\r
-    //\r
-    return FALSE;\r
-  }\r
-\r
-  if (!EFI_IP4_EQUAL (&NewConfigData->RemoteAddress, &mZeroIp4Addr) &&\r
-      NewConfigData->RemotePort != OldConfigData->RemotePort\r
-      ) {\r
-    //\r
-    // The RemotePort differs if it's designated in the configdata.\r
-    //\r
-    return FALSE;\r
-  }\r
-\r
-  //\r
-  // All checks pass, return TRUE.\r
-  //\r
-  return TRUE;\r
-}\r
-\r
-\r
-/**\r
-  This function builds the Ip4 configdata from the Udp4ConfigData.\r
-\r
-  @param[in]       Udp4ConfigData    Pointer to the EFI_UDP4_CONFIG_DATA.\r
-  @param[in, out]  Ip4ConfigData     Pointer to the EFI_IP4_CONFIG_DATA.\r
-\r
-**/\r
-VOID\r
-Udp4BuildIp4ConfigData (\r
-  IN     EFI_UDP4_CONFIG_DATA  *Udp4ConfigData,\r
-  IN OUT EFI_IP4_CONFIG_DATA   *Ip4ConfigData\r
-  )\r
-{\r
-  CopyMem (Ip4ConfigData, &mIp4IoDefaultIpConfigData, sizeof (*Ip4ConfigData));\r
-\r
-  Ip4ConfigData->DefaultProtocol   = EFI_IP_PROTO_UDP;\r
-  Ip4ConfigData->AcceptBroadcast   = Udp4ConfigData->AcceptBroadcast;\r
-  Ip4ConfigData->AcceptPromiscuous = Udp4ConfigData->AcceptPromiscuous;\r
-  Ip4ConfigData->UseDefaultAddress = Udp4ConfigData->UseDefaultAddress;\r
-  CopyMem (&Ip4ConfigData->StationAddress, &Udp4ConfigData->StationAddress, sizeof (EFI_IPv4_ADDRESS));\r
-  CopyMem (&Ip4ConfigData->SubnetMask, &Udp4ConfigData->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
-\r
-  //\r
-  // use the -1 magic number to disable the receiving process of the ip instance.\r
-  //\r
-  Ip4ConfigData->ReceiveTimeout    = (UINT32) (-1);\r
-}\r
-\r
-\r
-/**\r
-  This function validates the TxToken, it returns the error code according to the spec.\r
-\r
-  @param[in]  Instance           Pointer to the udp instance context data.\r
-  @param[in]  TxToken            Pointer to the token to be checked.\r
-\r
-  @retval EFI_SUCCESS            The TxToken is valid.\r
-  @retval EFI_INVALID_PARAMETER  One or more of the following are TRUE: This is\r
-                                 NULL. Token is NULL. Token.Event is NULL.\r
-                                 Token.Packet.TxData is NULL.\r
-                                 Token.Packet.TxData.FragmentCount is zero.\r
-                                 Token.Packet.TxData.DataLength is not equal to the\r
-                                 sum of fragment lengths. One or more of the\r
-                                 Token.Packet.TxData.FragmentTable[].\r
-                                 FragmentLength fields is zero. One or more of the\r
-                                 Token.Packet.TxData.FragmentTable[].\r
-                                 FragmentBuffer fields is NULL.\r
-                                 Token.Packet.TxData. GatewayAddress is not a\r
-                                 unicast IPv4 address if it is not NULL. One or\r
-                                 more IPv4 addresses in Token.Packet.TxData.\r
-                                 UdpSessionData are not valid unicast IPv4\r
-                                 addresses if the UdpSessionData is not NULL.\r
-  @retval EFI_BAD_BUFFER_SIZE    The data length is greater than the maximum UDP\r
-                                 packet size.\r
-\r
-**/\r
-EFI_STATUS\r
-Udp4ValidateTxToken (\r
-  IN UDP4_INSTANCE_DATA         *Instance,\r
-  IN EFI_UDP4_COMPLETION_TOKEN  *TxToken\r
-  )\r
-{\r
-  EFI_UDP4_TRANSMIT_DATA  *TxData;\r
-  UINT32                  Index;\r
-  UINT32                  TotalLen;\r
-  EFI_UDP4_CONFIG_DATA    *ConfigData;\r
-  EFI_UDP4_SESSION_DATA   *UdpSessionData;\r
-  IP4_ADDR                SourceAddress;\r
-  IP4_ADDR                GatewayAddress;\r
-\r
-  if (TxToken->Event == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  TxData = TxToken->Packet.TxData;\r
-\r
-  if ((TxData == NULL) || (TxData->FragmentCount == 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  TotalLen = 0;\r
-  for (Index = 0; Index < TxData->FragmentCount; Index++) {\r
-\r
-    if ((TxData->FragmentTable[Index].FragmentBuffer == NULL) ||\r
-      (TxData->FragmentTable[Index].FragmentLength == 0)) {\r
-      //\r
-      // if the FragmentBuffer is NULL or the FragmentLeng is zero.\r
-      //\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    TotalLen += TxData->FragmentTable[Index].FragmentLength;\r
-  }\r
-\r
-  if (TotalLen != TxData->DataLength) {\r
-    //\r
-    // The TotalLen calculated by adding all the FragmentLeng doesn't equal to the\r
-    // DataLength.\r
-    //\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (TxData->GatewayAddress != NULL) {\r
-    CopyMem (&GatewayAddress, TxData->GatewayAddress, sizeof (IP4_ADDR));\r
-\r
-    if (!Instance->ConfigData.UseDefaultAddress &&\r
-        (EFI_NTOHL(Instance->ConfigData.SubnetMask) != 0) &&\r
-        !NetIp4IsUnicast (NTOHL (GatewayAddress), EFI_NTOHL(Instance->ConfigData.SubnetMask))) {\r
-      //\r
-      // The specified GatewayAddress is not a unicast IPv4 address while it's not 0.\r
-      //\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-  }\r
-\r
-  ConfigData     = &Instance->ConfigData;\r
-  UdpSessionData = TxData->UdpSessionData;\r
-\r
-  if (UdpSessionData != NULL) {\r
-\r
-    CopyMem (&SourceAddress, &UdpSessionData->SourceAddress, sizeof (IP4_ADDR));\r
-\r
-    if ((SourceAddress != 0) &&\r
-        !Instance->ConfigData.UseDefaultAddress &&\r
-        (EFI_NTOHL(Instance->ConfigData.SubnetMask) != 0) &&\r
-        !NetIp4IsUnicast (HTONL (SourceAddress), EFI_NTOHL(Instance->ConfigData.SubnetMask))) {\r
-      //\r
-      // Check whether SourceAddress is a valid IPv4 address in case it's not zero.\r
-      // The configured station address is used if SourceAddress is zero.\r
-      //\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    if ((UdpSessionData->DestinationPort == 0) && (ConfigData->RemotePort == 0)) {\r
-      //\r
-      // Ambiguous, no avalaible DestinationPort for this token.\r
-      //\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    if (EFI_IP4_EQUAL (&UdpSessionData->DestinationAddress, &mZeroIp4Addr)) {\r
-      //\r
-      // The DestinationAddress specified in the UdpSessionData is 0.\r
-      //\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-  } else if (EFI_IP4_EQUAL (&ConfigData->RemoteAddress, &mZeroIp4Addr)) {\r
-    //\r
-    // the configured RemoteAddress is all zero, and the user doens't override the\r
-    // destination address.\r
-    //\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (TxData->DataLength > UDP4_MAX_DATA_SIZE) {\r
-    return EFI_BAD_BUFFER_SIZE;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  This function checks whether the specified Token duplicates with the one in the Map.\r
-\r
-  @param[in]  Map                Pointer to the NET_MAP.\r
-  @param[in]  Item               Pointer to the NET_MAP_ITEM contain the pointer to\r
-                                 the Token.\r
-  @param[in]  Context            Pointer to the Token to be checked.\r
-\r
-  @retval EFI_SUCCESS            The Token specified by Context differs from the\r
-                                 one in the Item.\r
-  @retval EFI_ACCESS_DENIED      The Token duplicates with the one in the Item.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Udp4TokenExist (\r
-  IN NET_MAP       *Map,\r
-  IN NET_MAP_ITEM  *Item,\r
-  IN VOID          *Context\r
-  )\r
-{\r
-  EFI_UDP4_COMPLETION_TOKEN  *Token;\r
-  EFI_UDP4_COMPLETION_TOKEN  *TokenInItem;\r
-\r
-  Token       = (EFI_UDP4_COMPLETION_TOKEN*) Context;\r
-  TokenInItem = (EFI_UDP4_COMPLETION_TOKEN*) Item->Key;\r
-\r
-  if ((Token == TokenInItem) || (Token->Event == TokenInItem->Event)) {\r
-    //\r
-    // The Token duplicates with the TokenInItem in case either the two pointers are the\r
-    // same or the Events of these two tokens are the same.\r
-    //\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  This function calculates the checksum for the Packet, utilizing the pre-calculated\r
-  pseudo HeadSum to reduce some overhead.\r
-\r
-  @param[in]  Packet             Pointer to the NET_BUF contains the udp datagram.\r
-  @param[in]  HeadSum            Checksum of the pseudo header execpt the length\r
-                                 field.\r
-\r
-  @retval The 16-bit checksum of this udp datagram.\r
-\r
-**/\r
-UINT16\r
-Udp4Checksum (\r
-  IN NET_BUF *Packet,\r
-  IN UINT16  HeadSum\r
-  )\r
-{\r
-  UINT16  Checksum;\r
-\r
-  Checksum  = NetbufChecksum (Packet);\r
-  Checksum  = NetAddChecksum (Checksum, HeadSum);\r
-\r
-  Checksum  = NetAddChecksum (Checksum, HTONS ((UINT16) Packet->TotalSize));\r
-\r
-  return (UINT16) ~Checksum;\r
-}\r
-\r
-\r
-/**\r
-  This function removes the specified Token from the TokenMap.\r
-\r
-  @param[in, out] TokenMap       Pointer to the NET_MAP containing the tokens.\r
-  @param[in]      Token          Pointer to the Token to be removed.\r
-\r
-  @retval EFI_SUCCESS            The specified Token is removed from the TokenMap.\r
-  @retval EFI_NOT_FOUND          The specified Token is not found in the TokenMap.\r
-\r
-**/\r
-EFI_STATUS\r
-Udp4RemoveToken (\r
-  IN OUT NET_MAP                    *TokenMap,\r
-  IN     EFI_UDP4_COMPLETION_TOKEN  *Token\r
-  )\r
-{\r
-  NET_MAP_ITEM  *Item;\r
-\r
-  //\r
-  // Find the Token first.\r
-  //\r
-  Item = NetMapFindKey (TokenMap, (VOID *) Token);\r
-\r
-  if (Item != NULL) {\r
-    //\r
-    // Remove the token if it's found in the map.\r
-    //\r
-    NetMapRemoveItem (TokenMap, Item, NULL);\r
-\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
-  This function is the packet transmitting notify function registered to the IpIo\r
-  interface. It's called to signal the udp TxToken when IpIo layer completes the\r
-  transmitting of the udp datagram.\r
-\r
-  @param[in]  Status                 The completion status of the output udp datagram.\r
-  @param[in]  Context                Pointer to the context data.\r
-  @param[in]  Sender                 Specify a pointer of EFI_IP4_PROTOCOL for sending.\r
-  @param[in]  NotifyData             Pointer to the notify data.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Udp4DgramSent (\r
-  IN EFI_STATUS        Status,\r
-  IN VOID              *Context,\r
-  IN IP_IO_IP_PROTOCOL Sender,\r
-  IN VOID              *NotifyData\r
-  )\r
-{\r
-  UDP4_INSTANCE_DATA         *Instance;\r
-  EFI_UDP4_COMPLETION_TOKEN  *Token;\r
-\r
-  Instance = (UDP4_INSTANCE_DATA *) Context;\r
-  Token    = (EFI_UDP4_COMPLETION_TOKEN *) NotifyData;\r
-\r
-  if (Udp4RemoveToken (&Instance->TxTokens, Token) == EFI_SUCCESS) {\r
-    //\r
-    // The token may be cancelled. Only signal it if the remove operation succeeds.\r
-    //\r
-    Token->Status = Status;\r
-    gBS->SignalEvent (Token->Event);\r
-    DispatchDpc ();\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  This function processes the received datagram passed up by the IpIo layer.\r
-\r
-  @param[in]  Status             The status of this udp datagram.\r
-  @param[in]  IcmpError          The IcmpError code, only available when Status is\r
-                                 EFI_ICMP_ERROR.\r
-  @param[in]  NetSession         Pointer to the EFI_NET_SESSION_DATA.\r
-  @param[in]  Packet             Pointer to the NET_BUF containing the received udp\r
-                                 datagram.\r
-  @param[in]  Context            Pointer to the context data.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Udp4DgramRcvd (\r
-  IN EFI_STATUS            Status,\r
-  IN UINT8                 IcmpError,\r
-  IN EFI_NET_SESSION_DATA  *NetSession,\r
-  IN NET_BUF               *Packet,\r
-  IN VOID                  *Context\r
-  )\r
-{\r
-  NET_CHECK_SIGNATURE (Packet, NET_BUF_SIGNATURE);\r
-\r
-  //\r
-  // IpIo only passes received packets with Status EFI_SUCCESS or EFI_ICMP_ERROR.\r
-  //\r
-  if (Status == EFI_SUCCESS) {\r
-    //\r
-    // Demultiplex the received datagram.\r
-    //\r
-    Udp4Demultiplex ((UDP4_SERVICE_DATA *) Context, NetSession, Packet);\r
-  } else {\r
-    //\r
-    // Handle the ICMP_ERROR packet.\r
-    //\r
-    Udp4IcmpHandler ((UDP4_SERVICE_DATA *) Context, IcmpError, NetSession, Packet);\r
-  }\r
-\r
-  //\r
-  // Dispatch the DPC queued by the NotifyFunction of the rx token's events\r
-  // which are signaled with received data.\r
-  //\r
-  DispatchDpc ();\r
-}\r
-\r
-\r
-/**\r
-  This function removes the multicast group specified by Arg from the Map.\r
-\r
-  @param[in, out] Map            Pointer to the NET_MAP.\r
-  @param[in]      Item           Pointer to the NET_MAP_ITEM.\r
-  @param[in]      Arg            Pointer to the Arg, it's the pointer to a\r
-                                 multicast IPv4 Address.\r
-\r
-  @retval EFI_SUCCESS            The multicast address is removed.\r
-  @retval EFI_ABORTED            The specified multicast address is removed and the\r
-                                 Arg is not NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Udp4LeaveGroup (\r
-  IN OUT NET_MAP       *Map,\r
-  IN     NET_MAP_ITEM  *Item,\r
-  IN     VOID          *Arg OPTIONAL\r
-  )\r
-{\r
-  EFI_IPv4_ADDRESS  *McastIp;\r
-\r
-  McastIp = Arg;\r
-\r
-  if ((McastIp != NULL) && (!EFI_IP4_EQUAL (McastIp, &(Item->Key)))) {\r
-    //\r
-    // McastIp is not NULL and the multicast address contained in the Item\r
-    // is not the same as McastIp.\r
-    //\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Remove this Item.\r
-  //\r
-  NetMapRemoveItem (Map, Item, NULL);\r
-\r
-  if (McastIp != NULL) {\r
-    //\r
-    // Return EFI_ABORTED in case McastIp is not NULL to terminate the iteration.\r
-    //\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  This function cancels the token specified by Arg in the Map. This is a callback\r
-  used by Udp4InstanceCancelToken().\r
-\r
-  @param[in]  Map                Pointer to the NET_MAP.\r
-  @param[in]  Item               Pointer to the NET_MAP_ITEM.\r
-  @param[in]  Arg                Pointer to the token to be cancelled, if NULL,\r
-                                 the token specified by Item is cancelled.\r
-\r
-  @retval EFI_SUCCESS            The token is cancelled if Arg is NULL or the token\r
-                                 is not the same as that in the Item if Arg is not\r
-                                 NULL.\r
-  @retval EFI_ABORTED            Arg is not NULL, and the token specified by Arg is\r
-                                 cancelled.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Udp4CancelTokens (\r
-  IN NET_MAP       *Map,\r
-  IN NET_MAP_ITEM  *Item,\r
-  IN VOID          *Arg OPTIONAL\r
-  )\r
-{\r
-  EFI_UDP4_COMPLETION_TOKEN  *TokenToCancel;\r
-  NET_BUF                    *Packet;\r
-  IP_IO                      *IpIo;\r
-\r
-  if ((Arg != NULL) && (Item->Key != Arg)) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (Item->Value != NULL) {\r
-    //\r
-    // If the token is a transmit token, the corresponding Packet is recorded in\r
-    // Item->Value, invoke IpIo to cancel this packet first. The IpIoCancelTxToken\r
-    // will invoke Udp4DgramSent, the token will be signaled and this Item will\r
-    // be removed from the Map there.\r
-    //\r
-    Packet = (NET_BUF *) (Item->Value);\r
-    IpIo   = (IP_IO *) (*((UINTN *) &Packet->ProtoData[0]));\r
-\r
-    IpIoCancelTxToken (IpIo, Packet);\r
-  } else {\r
-    //\r
-    // The token is a receive token. Abort it and remove it from the Map.\r
-    //\r
-    TokenToCancel = (EFI_UDP4_COMPLETION_TOKEN *) Item->Key;\r
-    NetMapRemoveItem (Map, Item, NULL);\r
-\r
-    TokenToCancel->Status = EFI_ABORTED;\r
-    gBS->SignalEvent (TokenToCancel->Event);\r
-  }\r
-\r
-  if (Arg != NULL) {\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  This function removes all the Wrap datas in the RcvdDgramQue.\r
-\r
-  @param[in]  Instance           Pointer to the udp instance context data.\r
-\r
-**/\r
-VOID\r
-Udp4FlushRcvdDgram (\r
-  IN UDP4_INSTANCE_DATA  *Instance\r
-  )\r
-{\r
-  UDP4_RXDATA_WRAP  *Wrap;\r
-\r
-  while (!IsListEmpty (&Instance->RcvdDgramQue)) {\r
-    //\r
-    // Iterate all the Wraps in the RcvdDgramQue.\r
-    //\r
-    Wrap = NET_LIST_HEAD (&Instance->RcvdDgramQue, UDP4_RXDATA_WRAP, Link);\r
-\r
-    //\r
-    // The Wrap will be removed from the RcvdDgramQue by this function call.\r
-    //\r
-    Udp4RecycleRxDataWrap (NULL, (VOID *) Wrap);\r
-  }\r
-}\r
-\r
-\r
-\r
-/**\r
-  Cancel Udp4 tokens from the Udp4 instance.\r
-\r
-  @param[in]  Instance           Pointer to the udp instance context data.\r
-  @param[in]  Token              Pointer to the token to be canceled, if NULL, all\r
-                                 tokens in this instance will be cancelled.\r
-\r
-  @retval EFI_SUCCESS            The Token is cancelled.\r
-  @retval EFI_NOT_FOUND          The Token is not found.\r
-\r
-**/\r
-EFI_STATUS\r
-Udp4InstanceCancelToken (\r
-  IN UDP4_INSTANCE_DATA         *Instance,\r
-  IN EFI_UDP4_COMPLETION_TOKEN  *Token OPTIONAL\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  //\r
-  // Cancel this token from the TxTokens map.\r
-  //\r
-  Status = NetMapIterate (&Instance->TxTokens, Udp4CancelTokens, Token);\r
-\r
-  if ((Token != NULL) && (Status == EFI_ABORTED)) {\r
-    //\r
-    // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from\r
-    // the TxTokens, just return success.\r
-    //\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Try to cancel this token from the RxTokens map in condition either the Token\r
-  // is NULL or the specified Token is not in TxTokens.\r
-  //\r
-  Status = NetMapIterate (&Instance->RxTokens, Udp4CancelTokens, Token);\r
-\r
-  if ((Token != NULL) && (Status == EFI_SUCCESS)) {\r
-    //\r
-    // If Token isn't NULL and Status is EFI_SUCCESS, the token is neither in the\r
-    // TxTokens nor the RxTokens, or say, it's not found.\r
-    //\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  ASSERT ((Token != NULL) || ((0 == NetMapGetCount (&Instance->TxTokens))\r
-    && (0 == NetMapGetCount (&Instance->RxTokens))));\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  This function matches the received udp datagram with the Instance.\r
-\r
-  @param[in]  Instance           Pointer to the udp instance context data.\r
-  @param[in]  Udp4Session        Pointer to the EFI_UDP4_SESSION_DATA abstracted\r
-                                 from the received udp datagram.\r
-\r
-  @retval TRUE       The udp datagram matches the receiving requirments of the\r
-                     udp Instance.\r
-  @retval FALSE      Otherwise.\r
-\r
-**/\r
-BOOLEAN\r
-Udp4MatchDgram (\r
-  IN UDP4_INSTANCE_DATA     *Instance,\r
-  IN EFI_UDP4_SESSION_DATA  *Udp4Session\r
-  )\r
-{\r
-  EFI_UDP4_CONFIG_DATA  *ConfigData;\r
-  IP4_ADDR              Destination;\r
-\r
-  ConfigData = &Instance->ConfigData;\r
-\r
-  if (ConfigData->AcceptPromiscuous) {\r
-    //\r
-    // Always matches if this instance is in the promiscuous state.\r
-    //\r
-    return TRUE;\r
-  }\r
-\r
-  if ((!ConfigData->AcceptAnyPort && (Udp4Session->DestinationPort != ConfigData->StationPort)) ||\r
-      ((ConfigData->RemotePort != 0) && (Udp4Session->SourcePort != ConfigData->RemotePort))\r
-      ) {\r
-    //\r
-    // The local port or the remote port doesn't match.\r
-    //\r
-    return FALSE;\r
-  }\r
-\r
-  if (!EFI_IP4_EQUAL (&ConfigData->RemoteAddress, &mZeroIp4Addr) &&\r
-      !EFI_IP4_EQUAL (&ConfigData->RemoteAddress, &Udp4Session->SourceAddress)\r
-      ) {\r
-    //\r
-    // This datagram doesn't come from the instance's specified sender.\r
-    //\r
-    return FALSE;\r
-  }\r
-\r
-  if (EFI_IP4_EQUAL (&ConfigData->StationAddress, &mZeroIp4Addr) ||\r
-      EFI_IP4_EQUAL (&Udp4Session->DestinationAddress, &ConfigData->StationAddress)\r
-      ) {\r
-    //\r
-    // The instance is configured to receive datagrams destined to any station IP or\r
-    // the destination address of this datagram matches the configured station IP.\r
-    //\r
-    return TRUE;\r
-  }\r
-\r
-  CopyMem (&Destination, &Udp4Session->DestinationAddress, sizeof (IP4_ADDR));\r
-\r
-  if (IP4_IS_LOCAL_BROADCAST (Destination) && ConfigData->AcceptBroadcast) {\r
-    //\r
-    // The instance is configured to receive broadcast and this is a broadcast packet.\r
-    //\r
-    return TRUE;\r
-  }\r
-\r
-  if (IP4_IS_MULTICAST (NTOHL (Destination)) &&\r
-      NetMapFindKey (&Instance->McastIps, (VOID *) (UINTN) Destination) != NULL\r
-      ) {\r
-    //\r
-    // It's a multicast packet and the multicast address is accepted by this instance.\r
-    //\r
-    return TRUE;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-\r
-/**\r
-  This function removes the Wrap specified by Context and release relevant resources.\r
-\r
-  @param[in]  Event              The Event this notify function registered to.\r
-  @param[in]  Context            Pointer to the context data.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Udp4RecycleRxDataWrap (\r
-  IN EFI_EVENT  Event,\r
-  IN VOID       *Context\r
-  )\r
-{\r
-  UDP4_RXDATA_WRAP  *Wrap;\r
-\r
-  Wrap = (UDP4_RXDATA_WRAP *) Context;\r
-\r
-  //\r
-  // Remove the Wrap from the list it belongs to.\r
-  //\r
-  RemoveEntryList (&Wrap->Link);\r
-\r
-  //\r
-  // Free the Packet associated with this Wrap.\r
-  //\r
-  NetbufFree (Wrap->Packet);\r
-\r
-  //\r
-  // Close the event.\r
-  //\r
-  gBS->CloseEvent (Wrap->RxData.RecycleSignal);\r
-\r
-  FreePool (Wrap);\r
-}\r
-\r
-\r
-/**\r
-  This function wraps the Packet and the RxData.\r
-\r
-  @param[in]  Instance               Pointer to the instance context data.\r
-  @param[in]  Packet                 Pointer to the buffer containing the received\r
-                                     datagram.\r
-  @param[in]  RxData                 Pointer to the EFI_UDP4_RECEIVE_DATA of this\r
-                                     datagram.\r
-\r
-  @return Pointer to the structure wrapping the RxData and the Packet.\r
-\r
-**/\r
-UDP4_RXDATA_WRAP *\r
-Udp4WrapRxData (\r
-  IN UDP4_INSTANCE_DATA     *Instance,\r
-  IN NET_BUF                *Packet,\r
-  IN EFI_UDP4_RECEIVE_DATA  *RxData\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  UDP4_RXDATA_WRAP      *Wrap;\r
-\r
-  //\r
-  // Allocate buffer for the Wrap.\r
-  //\r
-  Wrap = AllocatePool (sizeof (UDP4_RXDATA_WRAP) +\r
-         (Packet->BlockOpNum - 1) * sizeof (EFI_UDP4_FRAGMENT_DATA));\r
-  if (Wrap == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  InitializeListHead (&Wrap->Link);\r
-\r
-  CopyMem (&Wrap->RxData, RxData, sizeof (Wrap->RxData));\r
-\r
-  //\r
-  // Create the Recycle event.\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  Udp4RecycleRxDataWrap,\r
-                  Wrap,\r
-                  &Wrap->RxData.RecycleSignal\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (Wrap);\r
-    return NULL;\r
-  }\r
-\r
-  Wrap->Packet      = Packet;\r
-  Wrap->TimeoutTick = Instance->ConfigData.ReceiveTimeout;\r
-\r
-  return Wrap;\r
-}\r
-\r
-\r
-/**\r
-  This function enqueues the received datagram into the instances' receiving queues.\r
-\r
-  @param[in]  Udp4Service            Pointer to the udp service context data.\r
-  @param[in]  Packet                 Pointer to the buffer containing the received\r
-                                     datagram.\r
-  @param[in]  RxData                 Pointer to the EFI_UDP4_RECEIVE_DATA of this\r
-                                     datagram.\r
-\r
-  @return The times this datagram is enqueued.\r
-\r
-**/\r
-UINTN\r
-Udp4EnqueueDgram (\r
-  IN UDP4_SERVICE_DATA      *Udp4Service,\r
-  IN NET_BUF                *Packet,\r
-  IN EFI_UDP4_RECEIVE_DATA  *RxData\r
-  )\r
-{\r
-  LIST_ENTRY          *Entry;\r
-  UDP4_INSTANCE_DATA  *Instance;\r
-  UDP4_RXDATA_WRAP    *Wrap;\r
-  UINTN               Enqueued;\r
-\r
-  Enqueued = 0;\r
-\r
-  NET_LIST_FOR_EACH (Entry, &Udp4Service->ChildrenList) {\r
-    //\r
-    // Iterate the instances.\r
-    //\r
-    Instance = NET_LIST_USER_STRUCT (Entry, UDP4_INSTANCE_DATA, Link);\r
-\r
-    if (!Instance->Configured) {\r
-      continue;\r
-    }\r
-\r
-    if (Udp4MatchDgram (Instance, &RxData->UdpSession)) {\r
-      //\r
-      // Wrap the RxData and put this Wrap into the instances RcvdDgramQue.\r
-      //\r
-      Wrap = Udp4WrapRxData (Instance, Packet, RxData);\r
-      if (Wrap == NULL) {\r
-        continue;\r
-      }\r
-\r
-      NET_GET_REF (Packet);\r
-\r
-      InsertTailList (&Instance->RcvdDgramQue, &Wrap->Link);\r
-\r
-      Enqueued++;\r
-    }\r
-  }\r
-\r
-  return Enqueued;\r
-}\r
-\r
-\r
-/**\r
-  This function delivers the received datagrams for the specified instance.\r
-\r
-  @param[in]  Instance               Pointer to the instance context data.\r
-\r
-**/\r
-VOID\r
-Udp4InstanceDeliverDgram (\r
-  IN UDP4_INSTANCE_DATA  *Instance\r
-  )\r
-{\r
-  UDP4_RXDATA_WRAP           *Wrap;\r
-  EFI_UDP4_COMPLETION_TOKEN  *Token;\r
-  NET_BUF                    *Dup;\r
-  EFI_UDP4_RECEIVE_DATA      *RxData;\r
-  EFI_TPL                    OldTpl;\r
-\r
-  if (!IsListEmpty (&Instance->RcvdDgramQue) &&\r
-      !NetMapIsEmpty (&Instance->RxTokens)) {\r
-\r
-    Wrap = NET_LIST_HEAD (&Instance->RcvdDgramQue, UDP4_RXDATA_WRAP, Link);\r
-\r
-    if (NET_BUF_SHARED (Wrap->Packet)) {\r
-      //\r
-      // Duplicate the Packet if it is shared between instances.\r
-      //\r
-      Dup = NetbufDuplicate (Wrap->Packet, NULL, 0);\r
-      if (Dup == NULL) {\r
-        return;\r
-      }\r
-\r
-      NetbufFree (Wrap->Packet);\r
-\r
-      Wrap->Packet = Dup;\r
-    }\r
-\r
-    NetListRemoveHead (&Instance->RcvdDgramQue);\r
-\r
-    Token = (EFI_UDP4_COMPLETION_TOKEN *) NetMapRemoveHead (&Instance->RxTokens, NULL);\r
-\r
-    //\r
-    // Build the FragmentTable and set the FragmentCount in RxData.\r
-    //\r
-    RxData                = &Wrap->RxData;\r
-    RxData->FragmentCount = Wrap->Packet->BlockOpNum;\r
-\r
-    NetbufBuildExt (\r
-      Wrap->Packet,\r
-      (NET_FRAGMENT *) RxData->FragmentTable,\r
-      &RxData->FragmentCount\r
-      );\r
-\r
-    Token->Status        = EFI_SUCCESS;\r
-    Token->Packet.RxData = &Wrap->RxData;\r
-\r
-    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-    InsertTailList (&Instance->DeliveredDgramQue, &Wrap->Link);\r
-    gBS->RestoreTPL (OldTpl);\r
-\r
-    gBS->SignalEvent (Token->Event);\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  This function delivers the datagrams enqueued in the instances.\r
-\r
-  @param[in]  Udp4Service            Pointer to the udp service context data.\r
-\r
-**/\r
-VOID\r
-Udp4DeliverDgram (\r
-  IN UDP4_SERVICE_DATA  *Udp4Service\r
-  )\r
-{\r
-  LIST_ENTRY          *Entry;\r
-  UDP4_INSTANCE_DATA  *Instance;\r
-\r
-  NET_LIST_FOR_EACH (Entry, &Udp4Service->ChildrenList) {\r
-    //\r
-    // Iterate the instances.\r
-    //\r
-    Instance = NET_LIST_USER_STRUCT (Entry, UDP4_INSTANCE_DATA, Link);\r
-\r
-    if (!Instance->Configured) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Deliver the datagrams of this instance.\r
-    //\r
-    Udp4InstanceDeliverDgram (Instance);\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  This function demultiplexes the received udp datagram to the appropriate instances.\r
-\r
-  @param[in]  Udp4Service            Pointer to the udp service context data.\r
-  @param[in]  NetSession             Pointer to the EFI_NET_SESSION_DATA abstracted from\r
-                                     the received datagram.\r
-  @param[in]  Packet                 Pointer to the buffer containing the received udp\r
-                                     datagram.\r
-\r
-**/\r
-VOID\r
-Udp4Demultiplex (\r
-  IN UDP4_SERVICE_DATA     *Udp4Service,\r
-  IN EFI_NET_SESSION_DATA  *NetSession,\r
-  IN NET_BUF               *Packet\r
-  )\r
-{\r
-  EFI_UDP_HEADER        *Udp4Header;\r
-  UINT16                 HeadSum;\r
-  EFI_UDP4_RECEIVE_DATA  RxData;\r
-  EFI_UDP4_SESSION_DATA  *Udp4Session;\r
-  UINTN                  Enqueued;\r
-\r
-  if (Packet->TotalSize < sizeof (EFI_UDP_HEADER)) {\r
-    NetbufFree (Packet);\r
-    return;\r
-  }\r
-\r
-  //\r
-  // Get the datagram header from the packet buffer.\r
-  //\r
-  Udp4Header = (EFI_UDP_HEADER *) NetbufGetByte (Packet, 0, NULL);\r
-  ASSERT (Udp4Header != NULL);\r
-\r
-  if (Udp4Header->Checksum != 0) {\r
-    //\r
-    // check the checksum.\r
-    //\r
-    HeadSum = NetPseudoHeadChecksum (\r
-                NetSession->Source.Addr[0],\r
-                NetSession->Dest.Addr[0],\r
-                EFI_IP_PROTO_UDP,\r
-                0\r
-                );\r
-\r
-    if (Udp4Checksum (Packet, HeadSum) != 0) {\r
-      //\r
-      // Wrong checksum.\r
-      //\r
-      NetbufFree (Packet);\r
-      return;\r
-    }\r
-  }\r
-\r
-  Udp4Session                  = &RxData.UdpSession;\r
-  Udp4Session->SourcePort      = NTOHS (Udp4Header->SrcPort);\r
-  Udp4Session->DestinationPort = NTOHS (Udp4Header->DstPort);\r
-\r
-  CopyMem (&Udp4Session->SourceAddress, &NetSession->Source, sizeof (EFI_IPv4_ADDRESS));\r
-  CopyMem (&Udp4Session->DestinationAddress, &NetSession->Dest, sizeof (EFI_IPv4_ADDRESS));\r
-\r
-  //\r
-  // Trim the UDP header.\r
-  //\r
-  NetbufTrim (Packet, UDP4_HEADER_SIZE, TRUE);\r
-\r
-  RxData.DataLength = (UINT32) Packet->TotalSize;\r
-\r
-  //\r
-  // Try to enqueue this datagram into the instances.\r
-  //\r
-  Enqueued = Udp4EnqueueDgram (Udp4Service, Packet, &RxData);\r
-\r
-  if (Enqueued == 0) {\r
-    //\r
-    // Send the port unreachable ICMP packet before we free this NET_BUF\r
-    //\r
-    Udp4SendPortUnreach (Udp4Service->IpIo, NetSession, Udp4Header);\r
-  }\r
-\r
-  //\r
-  // Try to free the packet before deliver it.\r
-  //\r
-  NetbufFree (Packet);\r
-\r
-  if (Enqueued > 0) {\r
-    //\r
-    // Deliver the datagram.\r
-    //\r
-    Udp4DeliverDgram (Udp4Service);\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  This function builds and sends out a icmp port unreachable message.\r
-\r
-  @param[in]  IpIo                   Pointer to the IP_IO instance.\r
-  @param[in]  NetSession             Pointer to the EFI_NET_SESSION_DATA of the packet\r
-                                     causes this icmp error message.\r
-  @param[in]  Udp4Header             Pointer to the udp header of the datagram causes\r
-                                     this icmp error message.\r
-\r
-**/\r
-VOID\r
-Udp4SendPortUnreach (\r
-  IN IP_IO                 *IpIo,\r
-  IN EFI_NET_SESSION_DATA  *NetSession,\r
-  IN VOID                  *Udp4Header\r
-  )\r
-{\r
-  NET_BUF              *Packet;\r
-  UINT32               Len;\r
-  IP4_ICMP_ERROR_HEAD  *IcmpErrHdr;\r
-  EFI_IP4_HEADER       *IpHdr;\r
-  UINT8                *Ptr;\r
-  IP_IO_OVERRIDE       Override;\r
-  IP_IO_IP_INFO        *IpSender;\r
-\r
-  IpSender = IpIoFindSender (&IpIo, NetSession->IpVersion, &NetSession->Dest);\r
-  if (IpSender == NULL) {\r
-    //\r
-    // No appropriate sender, since we cannot send out the ICMP message through\r
-    // the default zero station address IP instance, abort.\r
-    //\r
-    return;\r
-  }\r
-\r
-  IpHdr = NetSession->IpHdr.Ip4Hdr;\r
-\r
-  //\r
-  // Calculate the required length of the icmp error message.\r
-  //\r
-  Len = sizeof (IP4_ICMP_ERROR_HEAD) + (EFI_IP4_HEADER_LEN (IpHdr) -\r
-        sizeof (IP4_HEAD)) + ICMP_ERROR_PACKET_LENGTH;\r
-\r
-  //\r
-  // Allocate buffer for the icmp error message.\r
-  //\r
-  Packet = NetbufAlloc (Len);\r
-  if (Packet == NULL) {\r
-    return;\r
-  }\r
-\r
-  //\r
-  // Allocate space for the IP4_ICMP_ERROR_HEAD.\r
-  //\r
-  IcmpErrHdr = (IP4_ICMP_ERROR_HEAD *) NetbufAllocSpace (Packet, Len, FALSE);\r
-  ASSERT (IcmpErrHdr != NULL);\r
-\r
-  //\r
-  // Set the required fields for the icmp port unreachable message.\r
-  //\r
-  IcmpErrHdr->Head.Type     = ICMP_TYPE_UNREACH;\r
-  IcmpErrHdr->Head.Code     = ICMP_CODE_UNREACH_PORT;\r
-  IcmpErrHdr->Head.Checksum = 0;\r
-  IcmpErrHdr->Fourth        = 0;\r
-\r
-  //\r
-  // Copy the IP header of the datagram tragged the error.\r
-  //\r
-  CopyMem (&IcmpErrHdr->IpHead, IpHdr, EFI_IP4_HEADER_LEN (IpHdr));\r
-\r
-  //\r
-  // Copy the UDP header.\r
-  //\r
-  Ptr = (UINT8 *) &IcmpErrHdr->IpHead + EFI_IP4_HEADER_LEN (IpHdr);\r
-  CopyMem (Ptr, Udp4Header, ICMP_ERROR_PACKET_LENGTH);\r
-\r
-  //\r
-  // Calculate the checksum.\r
-  //\r
-  IcmpErrHdr->Head.Checksum = (UINT16) ~(NetbufChecksum (Packet));\r
-\r
-  //\r
-  // Fill the override data.\r
-  //\r
-  Override.Ip4OverrideData.DoNotFragment = FALSE;\r
-  Override.Ip4OverrideData.TypeOfService = 0;\r
-  Override.Ip4OverrideData.TimeToLive    = 255;\r
-  Override.Ip4OverrideData.Protocol      = EFI_IP_PROTO_ICMP;\r
-\r
-  CopyMem (&Override.Ip4OverrideData.SourceAddress, &NetSession->Dest, sizeof (EFI_IPv4_ADDRESS));\r
-  ZeroMem (&Override.Ip4OverrideData.GatewayAddress, sizeof (EFI_IPv4_ADDRESS));\r
-\r
-  //\r
-  // Send out this icmp packet.\r
-  //\r
-  IpIoSend (IpIo, Packet, IpSender, NULL, NULL, &NetSession->Source, &Override);\r
-\r
-  NetbufFree (Packet);\r
-}\r
-\r
-\r
-/**\r
-  This function handles the received Icmp Error message and demultiplexes it to the\r
-  instance.\r
-\r
-  @param[in]  Udp4Service            Pointer to the udp service context data.\r
-  @param[in]  IcmpError              The icmp error code.\r
-  @param[in]  NetSession             Pointer to the EFI_NET_SESSION_DATA abstracted\r
-                                 from the received Icmp Error packet.\r
-  @param[in]  Packet                 Pointer to the Icmp Error packet.\r
-\r
-**/\r
-VOID\r
-Udp4IcmpHandler (\r
-  IN UDP4_SERVICE_DATA     *Udp4Service,\r
-  IN UINT8                 IcmpError,\r
-  IN EFI_NET_SESSION_DATA  *NetSession,\r
-  IN NET_BUF               *Packet\r
-  )\r
-{\r
-  EFI_UDP_HEADER        *Udp4Header;\r
-  EFI_UDP4_SESSION_DATA  Udp4Session;\r
-  LIST_ENTRY             *Entry;\r
-  UDP4_INSTANCE_DATA     *Instance;\r
-\r
-  if (Packet->TotalSize < sizeof (EFI_UDP_HEADER)) {\r
-    NetbufFree (Packet);\r
-    return;\r
-  }\r
-\r
-  Udp4Header = (EFI_UDP_HEADER *) NetbufGetByte (Packet, 0, NULL);\r
-  ASSERT (Udp4Header != NULL);\r
-\r
-  CopyMem (&Udp4Session.SourceAddress, &NetSession->Source, sizeof (EFI_IPv4_ADDRESS));\r
-  CopyMem (&Udp4Session.DestinationAddress, &NetSession->Dest, sizeof (EFI_IPv4_ADDRESS));\r
-\r
-  Udp4Session.SourcePort      = NTOHS (Udp4Header->DstPort);\r
-  Udp4Session.DestinationPort = NTOHS (Udp4Header->SrcPort);\r
-\r
-  NET_LIST_FOR_EACH (Entry, &Udp4Service->ChildrenList) {\r
-    //\r
-    // Iterate all the instances.\r
-    //\r
-    Instance = NET_LIST_USER_STRUCT (Entry, UDP4_INSTANCE_DATA, Link);\r
-\r
-    if (!Instance->Configured) {\r
-      continue;\r
-    }\r
-\r
-    if (Udp4MatchDgram (Instance, &Udp4Session)) {\r
-      //\r
-      // Translate the Icmp Error code according to the udp spec.\r
-      //\r
-      Instance->IcmpError = IpIoGetIcmpErrStatus (IcmpError, IP_VERSION_4, NULL, NULL);\r
-\r
-      if (IcmpError > ICMP_ERR_UNREACH_PORT) {\r
-        Instance->IcmpError = EFI_ICMP_ERROR;\r
-      }\r
-\r
-      //\r
-      // Notify the instance with the received Icmp Error.\r
-      //\r
-      Udp4ReportIcmpError (Instance);\r
-\r
-      break;\r
-    }\r
-  }\r
-\r
-  NetbufFree (Packet);\r
-}\r
-\r
-\r
-/**\r
-  This function reports the received ICMP error.\r
-\r
-  @param[in]  Instance               Pointer to the udp instance context data.\r
-\r
-**/\r
-VOID\r
-Udp4ReportIcmpError (\r
-  IN UDP4_INSTANCE_DATA  *Instance\r
-  )\r
-{\r
-  EFI_UDP4_COMPLETION_TOKEN  *Token;\r
-\r
-  if (NetMapIsEmpty (&Instance->RxTokens)) {\r
-    //\r
-    // There are no receive tokens to deliver the ICMP error.\r
-    //\r
-    return;\r
-  }\r
-\r
-  if (EFI_ERROR (Instance->IcmpError)) {\r
-    //\r
-    // Try to get a RxToken from the RxTokens map.\r
-    //\r
-    Token = (EFI_UDP4_COMPLETION_TOKEN *) NetMapRemoveHead (&Instance->RxTokens, NULL);\r
-\r
-    if (Token != NULL) {\r
-      //\r
-      // Report the error through the Token.\r
-      //\r
-      Token->Status = Instance->IcmpError;\r
-      gBS->SignalEvent (Token->Event);\r
-\r
-      //\r
-      // Clear the IcmpError.\r
-      //\r
-      Instance->IcmpError = EFI_SUCCESS;\r
-    }\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  This function is a dummy ext-free function for the NET_BUF created for the output\r
-  udp datagram.\r
-\r
-  @param[in]  Context                Pointer to the context data.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Udp4NetVectorExtFree (\r
-  VOID  *Context\r
-  )\r
-{\r
-}\r
-\r