/** @file
  IP4 input process.

Copyright (c) 2005 - 2020, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Ip4Impl.h"

/**
  Create an empty assemble entry for the packet identified by
  (Dst, Src, Id, Protocol). The default life for the packet is
  120 seconds.

  @param[in]  Dst                    The destination address
  @param[in]  Src                    The source address
  @param[in]  Id                     The ID field in IP header
  @param[in]  Protocol               The protocol field in IP header

  @return NULL if failed to allocate memory for the entry, otherwise
          the point to just created reassemble entry.

**/
IP4_ASSEMBLE_ENTRY *
Ip4CreateAssembleEntry (
  IN IP4_ADDR  Dst,
  IN IP4_ADDR  Src,
  IN UINT16    Id,
  IN UINT8     Protocol
  )
{
  IP4_ASSEMBLE_ENTRY  *Assemble;

  Assemble = AllocatePool (sizeof (IP4_ASSEMBLE_ENTRY));

  if (Assemble == NULL) {
    return NULL;
  }

  InitializeListHead (&Assemble->Link);
  InitializeListHead (&Assemble->Fragments);

  Assemble->Dst      = Dst;
  Assemble->Src      = Src;
  Assemble->Id       = Id;
  Assemble->Protocol = Protocol;
  Assemble->TotalLen = 0;
  Assemble->CurLen   = 0;
  Assemble->Head     = NULL;
  Assemble->Info     = NULL;
  Assemble->Life     = IP4_FRAGMENT_LIFE;

  return Assemble;
}

/**
  Release all the fragments of a packet, then free the assemble entry.

  @param[in]  Assemble               The assemble entry to free

**/
VOID
Ip4FreeAssembleEntry (
  IN IP4_ASSEMBLE_ENTRY  *Assemble
  )
{
  LIST_ENTRY  *Entry;
  LIST_ENTRY  *Next;
  NET_BUF     *Fragment;

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Assemble->Fragments) {
    Fragment = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);

    RemoveEntryList (Entry);
    NetbufFree (Fragment);
  }

  FreePool (Assemble);
}

/**
  Initialize an already allocated assemble table. This is generally
  the assemble table embedded in the IP4 service instance.

  @param[in, out]  Table                  The assemble table to initialize.

**/
VOID
Ip4InitAssembleTable (
  IN OUT IP4_ASSEMBLE_TABLE  *Table
  )
{
  UINT32  Index;

  for (Index = 0; Index < IP4_ASSEMLE_HASH_SIZE; Index++) {
    InitializeListHead (&Table->Bucket[Index]);
  }
}

/**
  Clean up the assemble table: remove all the fragments
  and assemble entries.

  @param[in]  Table                  The assemble table to clean up

**/
VOID
Ip4CleanAssembleTable (
  IN IP4_ASSEMBLE_TABLE  *Table
  )
{
  LIST_ENTRY          *Entry;
  LIST_ENTRY          *Next;
  IP4_ASSEMBLE_ENTRY  *Assemble;
  UINT32              Index;

  for (Index = 0; Index < IP4_ASSEMLE_HASH_SIZE; Index++) {
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &Table->Bucket[Index]) {
      Assemble = NET_LIST_USER_STRUCT (Entry, IP4_ASSEMBLE_ENTRY, Link);

      RemoveEntryList (Entry);
      Ip4FreeAssembleEntry (Assemble);
    }
  }
}

/**
  Trim the packet to fit in [Start, End), and update the per
  packet information.

  @param  Packet                 Packet to trim
  @param  Start                  The sequence of the first byte to fit in
  @param  End                    One beyond the sequence of last byte to fit in.

**/
VOID
Ip4TrimPacket (
  IN OUT NET_BUF  *Packet,
  IN     INTN     Start,
  IN     INTN     End
  )
{
  IP4_CLIP_INFO  *Info;
  INTN           Len;

  Info = IP4_GET_CLIP_INFO (Packet);

  ASSERT (Info->Start + Info->Length == Info->End);
  ASSERT ((Info->Start < End) && (Start < Info->End));

  if (Info->Start < Start) {
    Len = Start - Info->Start;

    NetbufTrim (Packet, (UINT32)Len, NET_BUF_HEAD);
    Info->Start   = Start;
    Info->Length -= Len;
  }

  if (End < Info->End) {
    Len = End - Info->End;

    NetbufTrim (Packet, (UINT32)Len, NET_BUF_TAIL);
    Info->End     = End;
    Info->Length -= Len;
  }
}

/**
  Release all the fragments of the packet. This is the callback for
  the assembled packet's OnFree. It will free the assemble entry,
  which in turn will free all the fragments of the packet.

  @param[in]  Arg                    The assemble entry to free

**/
VOID
EFIAPI
Ip4OnFreeFragments (
  IN VOID  *Arg
  )
{
  Ip4FreeAssembleEntry ((IP4_ASSEMBLE_ENTRY *)Arg);
}

/**
  Reassemble the IP fragments. If all the fragments of the packet
  have been received, it will wrap the packet in a net buffer then
  return it to caller. If the packet can't be assembled, NULL is
  return.

  @param  Table     The assemble table used. New assemble entry will be created
                    if the Packet is from a new chain of fragments.
  @param  Packet    The fragment to assemble. It might be freed if the fragment
                    can't be re-assembled.

  @return NULL if the packet can't be reassemble. The point to just assembled
          packet if all the fragments of the packet have arrived.

**/
NET_BUF *
Ip4Reassemble (
  IN OUT IP4_ASSEMBLE_TABLE  *Table,
  IN OUT NET_BUF             *Packet
  )
{
  IP4_HEAD            *IpHead;
  IP4_CLIP_INFO       *This;
  IP4_CLIP_INFO       *Node;
  IP4_ASSEMBLE_ENTRY  *Assemble;
  LIST_ENTRY          *Head;
  LIST_ENTRY          *Prev;
  LIST_ENTRY          *Cur;
  NET_BUF             *Fragment;
  NET_BUF             *NewPacket;
  INTN                Index;

  IpHead = Packet->Ip.Ip4;
  This   = IP4_GET_CLIP_INFO (Packet);

  ASSERT (IpHead != NULL);

  //
  // First: find the related assemble entry
  //
  Assemble = NULL;
  Index    = IP4_ASSEMBLE_HASH (IpHead->Dst, IpHead->Src, IpHead->Id, IpHead->Protocol);

  NET_LIST_FOR_EACH (Cur, &Table->Bucket[Index]) {
    Assemble = NET_LIST_USER_STRUCT (Cur, IP4_ASSEMBLE_ENTRY, Link);

    if ((Assemble->Dst == IpHead->Dst) && (Assemble->Src == IpHead->Src) &&
        (Assemble->Id == IpHead->Id)   && (Assemble->Protocol == IpHead->Protocol))
    {
      break;
    }
  }

  //
  // Create a new assemble entry if no assemble entry is related to this packet
  //
  if (Cur == &Table->Bucket[Index]) {
    Assemble = Ip4CreateAssembleEntry (
                 IpHead->Dst,
                 IpHead->Src,
                 IpHead->Id,
                 IpHead->Protocol
                 );

    if (Assemble == NULL) {
      goto DROP;
    }

    InsertHeadList (&Table->Bucket[Index], &Assemble->Link);
  }

  //
  // Assemble shouldn't be NULL here
  //
  ASSERT (Assemble != NULL);

  //
  // Find the point to insert the packet: before the first
  // fragment with THIS.Start < CUR.Start. the previous one
  // has PREV.Start <= THIS.Start < CUR.Start.
  //
  Head = &Assemble->Fragments;

  NET_LIST_FOR_EACH (Cur, Head) {
    Fragment = NET_LIST_USER_STRUCT (Cur, NET_BUF, List);

    if (This->Start < IP4_GET_CLIP_INFO (Fragment)->Start) {
      break;
    }
  }

  //
  // Check whether the current fragment overlaps with the previous one.
  // It holds that: PREV.Start <= THIS.Start < THIS.End. Only need to
  // check whether THIS.Start < PREV.End for overlap. If two fragments
  // overlaps, trim the overlapped part off THIS fragment.
  //
  if ((Prev = Cur->BackLink) != Head) {
    Fragment = NET_LIST_USER_STRUCT (Prev, NET_BUF, List);
    Node     = IP4_GET_CLIP_INFO (Fragment);

    if (This->Start < Node->End) {
      if (This->End <= Node->End) {
        NetbufFree (Packet);
        return NULL;
      }

      Ip4TrimPacket (Packet, Node->End, This->End);
    }
  }

  //
  // Insert the fragment into the packet. The fragment may be removed
  // from the list by the following checks.
  //
  NetListInsertBefore (Cur, &Packet->List);

  //
  // Check the packets after the insert point. It holds that:
  // THIS.Start <= NODE.Start < NODE.End. The equality holds
  // if PREV and NEXT are continuous. THIS fragment may fill
  // several holes. Remove the completely overlapped fragments
  //
  while (Cur != Head) {
    Fragment = NET_LIST_USER_STRUCT (Cur, NET_BUF, List);
    Node     = IP4_GET_CLIP_INFO (Fragment);

    //
    // Remove fragments completely overlapped by this fragment
    //
    if (Node->End <= This->End) {
      Cur = Cur->ForwardLink;

      RemoveEntryList (&Fragment->List);
      Assemble->CurLen -= Node->Length;

      NetbufFree (Fragment);
      continue;
    }

    //
    // The conditions are: THIS.Start <= NODE.Start, and THIS.End <
    // NODE.End. Two fragments overlaps if NODE.Start < THIS.End.
    // If two fragments start at the same offset, remove THIS fragment
    // because ((THIS.Start == NODE.Start) && (THIS.End < NODE.End)).
    //
    if (Node->Start < This->End) {
      if (This->Start == Node->Start) {
        RemoveEntryList (&Packet->List);
        goto DROP;
      }

      Ip4TrimPacket (Packet, This->Start, Node->Start);
    }

    break;
  }

  //
  // Update the assemble info: increase the current length. If it is
  // the frist fragment, update the packet's IP head and per packet
  // info. If it is the last fragment, update the total length.
  //
  Assemble->CurLen += This->Length;

  if (This->Start == 0) {
    //
    // Once the first fragment is enqueued, it can't be removed
    // from the fragment list. So, Assemble->Head always point
    // to valid memory area.
    //
    ASSERT (Assemble->Head == NULL);

    Assemble->Head = IpHead;
    Assemble->Info = IP4_GET_CLIP_INFO (Packet);
  }

  //
  // Don't update the length more than once.
  //
  if (IP4_LAST_FRAGMENT (IpHead->Fragment) && (Assemble->TotalLen == 0)) {
    Assemble->TotalLen = This->End;
  }

  //
  // Deliver the whole packet if all the fragments received.
  // All fragments received if:
  //  1. received the last one, so, the total length is know
  //  2. received all the data. If the last fragment on the
  //     queue ends at the total length, all data is received.
  //
  if ((Assemble->TotalLen != 0) && (Assemble->CurLen >= Assemble->TotalLen)) {
    RemoveEntryList (&Assemble->Link);

    //
    // If the packet is properly formatted, the last fragment's End
    // equals to the packet's total length. Otherwise, the packet
    // is a fake, drop it now.
    //
    Fragment = NET_LIST_USER_STRUCT (Head->BackLink, NET_BUF, List);

    if (IP4_GET_CLIP_INFO (Fragment)->End != Assemble->TotalLen) {
      Ip4FreeAssembleEntry (Assemble);
      return NULL;
    }

    //
    // Wrap the packet in a net buffer then deliver it up
    //
    NewPacket = NetbufFromBufList (
                  &Assemble->Fragments,
                  0,
                  0,
                  Ip4OnFreeFragments,
                  Assemble
                  );

    if (NewPacket == NULL) {
      Ip4FreeAssembleEntry (Assemble);
      return NULL;
    }

    NewPacket->Ip.Ip4 = Assemble->Head;

    ASSERT (Assemble->Info != NULL);

    CopyMem (
      IP4_GET_CLIP_INFO (NewPacket),
      Assemble->Info,
      sizeof (*IP4_GET_CLIP_INFO (NewPacket))
      );

    return NewPacket;
  }

  return NULL;

DROP:
  NetbufFree (Packet);
  return NULL;
}

/**
  The callback function for the net buffer which wraps the packet processed by
  IPsec. It releases the wrap packet and also signals IPsec to free the resources.

  @param[in]  Arg       The wrap context

**/
VOID
EFIAPI
Ip4IpSecFree (
  IN VOID  *Arg
  )
{
  IP4_IPSEC_WRAP  *Wrap;

  Wrap = (IP4_IPSEC_WRAP *)Arg;

  if (Wrap->IpSecRecycleSignal != NULL) {
    gBS->SignalEvent (Wrap->IpSecRecycleSignal);
  }

  NetbufFree (Wrap->Packet);

  FreePool (Wrap);

  return;
}

/**
  The work function to locate IPsec protocol to process the inbound or
  outbound IP packets. The process routine handls the packet with following
  actions: bypass the packet, discard the packet, or protect the packet.

  @param[in]       IpSb          The IP4 service instance.
  @param[in, out]  Head          The caller supplied IP4 header.
  @param[in, out]  Netbuf        The IP4 packet to be processed by IPsec.
  @param[in, out]  Options       The caller supplied options.
  @param[in, out]  OptionsLen    The length of the option.
  @param[in]       Direction     The directionality in an SPD entry,
                                 EfiIPsecInBound or EfiIPsecOutBound.
  @param[in]       Context       The token's wrap.

  @retval EFI_SUCCESS            The IPsec protocol is not available or disabled.
  @retval EFI_SUCCESS            The packet was bypassed and all buffers remain the same.
  @retval EFI_SUCCESS            The packet was protected.
  @retval EFI_ACCESS_DENIED      The packet was discarded.
  @retval EFI_OUT_OF_RESOURCES   There is no sufficient resource to complete the operation.
  @retval EFI_BUFFER_TOO_SMALL   The number of non-empty block is bigger than the
                                 number of input data blocks when build a fragment table.

**/
EFI_STATUS
Ip4IpSecProcessPacket (
  IN     IP4_SERVICE            *IpSb,
  IN OUT IP4_HEAD               **Head,
  IN OUT NET_BUF                **Netbuf,
  IN OUT UINT8                  **Options,
  IN OUT UINT32                 *OptionsLen,
  IN     EFI_IPSEC_TRAFFIC_DIR  Direction,
  IN     VOID                   *Context
  )
{
  NET_FRAGMENT      *FragmentTable;
  NET_FRAGMENT      *OriginalFragmentTable;
  UINT32            FragmentCount;
  UINT32            OriginalFragmentCount;
  EFI_EVENT         RecycleEvent;
  NET_BUF           *Packet;
  IP4_TXTOKEN_WRAP  *TxWrap;
  IP4_IPSEC_WRAP    *IpSecWrap;
  EFI_STATUS        Status;
  IP4_HEAD          ZeroHead;

  Status = EFI_SUCCESS;

  if (!mIpSec2Installed) {
    goto ON_EXIT;
  }

  ASSERT (mIpSec != NULL);

  Packet        = *Netbuf;
  RecycleEvent  = NULL;
  IpSecWrap     = NULL;
  FragmentTable = NULL;
  TxWrap        = (IP4_TXTOKEN_WRAP *)Context;
  FragmentCount = Packet->BlockOpNum;

  ZeroMem (&ZeroHead, sizeof (IP4_HEAD));

  //
  // Check whether the IPsec enable variable is set.
  //
  if (mIpSec->DisabledFlag) {
    //
    // If IPsec is disabled, restore the original MTU
    //
    IpSb->MaxPacketSize = IpSb->OldMaxPacketSize;
    goto ON_EXIT;
  } else {
    //
    // If IPsec is enabled, use the MTU which reduce the IPsec header length.
    //
    IpSb->MaxPacketSize = IpSb->OldMaxPacketSize - IP4_MAX_IPSEC_HEADLEN;
  }

  //
  // Rebuild fragment table from netbuf to ease IPsec process.
  //
  FragmentTable = AllocateZeroPool (FragmentCount * sizeof (NET_FRAGMENT));

  if (FragmentTable == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  Status = NetbufBuildExt (Packet, FragmentTable, &FragmentCount);

  //
  // Record the original FragmentTable and count.
  //
  OriginalFragmentTable = FragmentTable;
  OriginalFragmentCount = FragmentCount;

  if (EFI_ERROR (Status)) {
    FreePool (FragmentTable);
    goto ON_EXIT;
  }

  //
  // Convert host byte order to network byte order
  //
  Ip4NtohHead (*Head);

  Status = mIpSec->ProcessExt (
                     mIpSec,
                     IpSb->Controller,
                     IP_VERSION_4,
                     (VOID *)(*Head),
                     &(*Head)->Protocol,
                     (VOID **)Options,
                     OptionsLen,
                     (EFI_IPSEC_FRAGMENT_DATA **)(&FragmentTable),
                     &FragmentCount,
                     Direction,
                     &RecycleEvent
                     );
  //
  // Convert back to host byte order
  //
  Ip4NtohHead (*Head);

  if (EFI_ERROR (Status)) {
    FreePool (OriginalFragmentTable);
    goto ON_EXIT;
  }

  if ((OriginalFragmentTable == FragmentTable) && (OriginalFragmentCount == FragmentCount)) {
    //
    // For ByPass Packet
    //
    FreePool (FragmentTable);
    goto ON_EXIT;
  } else {
    //
    // Free the FragmentTable which allocated before calling the IPsec.
    //
    FreePool (OriginalFragmentTable);
  }

  if ((Direction == EfiIPsecOutBound) && (TxWrap != NULL)) {
    TxWrap->IpSecRecycleSignal = RecycleEvent;
    TxWrap->Packet             = NetbufFromExt (
                                   FragmentTable,
                                   FragmentCount,
                                   IP4_MAX_HEADLEN,
                                   0,
                                   Ip4FreeTxToken,
                                   TxWrap
                                   );
    if (TxWrap->Packet == NULL) {
      //
      // Recover the TxWrap->Packet, if meet a error, and the caller will free
      // the TxWrap.
      //
      TxWrap->Packet = *Netbuf;
      Status         = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

    //
    // Free original Netbuf.
    //
    NetIpSecNetbufFree (*Netbuf);
    *Netbuf = TxWrap->Packet;
  } else {
    IpSecWrap = AllocateZeroPool (sizeof (IP4_IPSEC_WRAP));

    if (IpSecWrap == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      gBS->SignalEvent (RecycleEvent);
      goto ON_EXIT;
    }

    IpSecWrap->IpSecRecycleSignal = RecycleEvent;
    IpSecWrap->Packet             = Packet;
    Packet                        = NetbufFromExt (
                                      FragmentTable,
                                      FragmentCount,
                                      IP4_MAX_HEADLEN,
                                      0,
                                      Ip4IpSecFree,
                                      IpSecWrap
                                      );

    if (Packet == NULL) {
      Packet = IpSecWrap->Packet;
      gBS->SignalEvent (RecycleEvent);
      FreePool (IpSecWrap);
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

    if ((Direction == EfiIPsecInBound) && (0 != CompareMem (*Head, &ZeroHead, sizeof (IP4_HEAD)))) {
      Ip4PrependHead (Packet, *Head, *Options, *OptionsLen);
      Ip4NtohHead (Packet->Ip.Ip4);
      NetbufTrim (Packet, ((*Head)->HeadLen << 2), TRUE);

      CopyMem (
        IP4_GET_CLIP_INFO (Packet),
        IP4_GET_CLIP_INFO (IpSecWrap->Packet),
        sizeof (IP4_CLIP_INFO)
        );
    }

    *Netbuf = Packet;
  }

ON_EXIT:
  return Status;
}

/**
  Pre-process the IPv4 packet. First validates the IPv4 packet, and
  then reassembles packet if it is necessary.

  @param[in]       IpSb            Pointer to IP4_SERVICE.
  @param[in, out]  Packet          Pointer to the Packet to be processed.
  @param[in]       Head            Pointer to the IP4_HEAD.
  @param[in]       Option          Pointer to a buffer which contains the IPv4 option.
  @param[in]       OptionLen       The length of Option in bytes.
  @param[in]       Flag            The link layer flag for the packet received, such
                                   as multicast.

  @retval     EFI_SUCCESS                The received packet is in well form.
  @retval     EFI_INVALID_PARAMETER      The received packet is malformed.

**/
EFI_STATUS
Ip4PreProcessPacket (
  IN     IP4_SERVICE  *IpSb,
  IN OUT NET_BUF      **Packet,
  IN     IP4_HEAD     *Head,
  IN     UINT8        *Option,
  IN     UINT32       OptionLen,
  IN     UINT32       Flag
  )
{
  IP4_CLIP_INFO  *Info;
  UINT32         HeadLen;
  UINT32         TotalLen;
  UINT16         Checksum;

  //
  // Check if the IP4 header is correctly formatted.
  //
  HeadLen  = (Head->HeadLen << 2);
  TotalLen = NTOHS (Head->TotalLen);

  //
  // Mnp may deliver frame trailer sequence up, trim it off.
  //
  if (TotalLen < (*Packet)->TotalSize) {
    NetbufTrim (*Packet, (*Packet)->TotalSize - TotalLen, FALSE);
  }

  if ((Head->Ver != 4) || (HeadLen < IP4_MIN_HEADLEN) ||
      (TotalLen < HeadLen) || (TotalLen != (*Packet)->TotalSize))
  {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Some OS may send IP packets without checksum.
  //
  Checksum = (UINT16)(~NetblockChecksum ((UINT8 *)Head, HeadLen));

  if ((Head->Checksum != 0) && (Checksum != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Convert the IP header to host byte order, then get the per packet info.
  //
  (*Packet)->Ip.Ip4 = Ip4NtohHead (Head);

  Info           = IP4_GET_CLIP_INFO (*Packet);
  Info->LinkFlag = Flag;
  Info->CastType = Ip4GetHostCast (IpSb, Head->Dst, Head->Src);
  Info->Start    = (Head->Fragment & IP4_HEAD_OFFSET_MASK) << 3;
  Info->Length   = Head->TotalLen - HeadLen;
  Info->End      = Info->Start + Info->Length;
  Info->Status   = EFI_SUCCESS;

  //
  // The packet is destinated to us if the CastType is non-zero.
  //
  if ((Info->CastType == 0) || (Info->End > IP4_MAX_PACKET_SIZE)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Validate the options. Don't call the Ip4OptionIsValid if
  // there is no option to save some CPU process.
  //

  if ((OptionLen > 0) && !Ip4OptionIsValid (Option, OptionLen, TRUE)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Trim the head off, after this point, the packet is headless,
  // and Packet->TotalLen == Info->Length.
  //
  NetbufTrim (*Packet, HeadLen, TRUE);

  //
  // Reassemble the packet if this is a fragment. The packet is a
  // fragment if its head has MF (more fragment) set, or it starts
  // at non-zero byte.
  //
  if (((Head->Fragment & IP4_HEAD_MF_MASK) != 0) || (Info->Start != 0)) {
    //
    // Drop the fragment if DF is set but it is fragmented. Gateway
    // need to send a type 4 destination unreache ICMP message here.
    //
    if ((Head->Fragment & IP4_HEAD_DF_MASK) != 0) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // The length of all but the last fragments is in the unit of 8 bytes.
    //
    if (((Head->Fragment & IP4_HEAD_MF_MASK) != 0) && (Info->Length % 8 != 0)) {
      return EFI_INVALID_PARAMETER;
    }

    *Packet = Ip4Reassemble (&IpSb->Assemble, *Packet);

    //
    // Packet assembly isn't complete, start receive more packet.
    //
    if (*Packet == NULL) {
      return EFI_INVALID_PARAMETER;
    }
  }

  return EFI_SUCCESS;
}

/**
  This function checks the IPv4 packet length.

  @param[in]       Packet          Pointer to the IPv4 Packet to be checked.

  @retval TRUE                   The input IPv4 packet length is valid.
  @retval FALSE                  The input IPv4 packet length is invalid.

**/
BOOLEAN
Ip4IsValidPacketLength (
  IN NET_BUF  *Packet
  )
{
  //
  // Check the IP4 packet length.
  //
  if (Packet->TotalSize < IP4_MIN_HEADLEN) {
    return FALSE;
  }

  return TRUE;
}

/**
  The IP4 input routine. It is called by the IP4_INTERFACE when a
  IP4 fragment is received from MNP.

  @param[in]  Ip4Instance        The IP4 child that request the receive, most like
                                 it is NULL.
  @param[in]  Packet             The IP4 packet received.
  @param[in]  IoStatus           The return status of receive request.
  @param[in]  Flag               The link layer flag for the packet received, such
                                 as multicast.
  @param[in]  Context            The IP4 service instance that own the MNP.

**/
VOID
Ip4AccpetFrame (
  IN IP4_PROTOCOL  *Ip4Instance,
  IN NET_BUF       *Packet,
  IN EFI_STATUS    IoStatus,
  IN UINT32        Flag,
  IN VOID          *Context
  )
{
  IP4_SERVICE  *IpSb;
  IP4_HEAD     *Head;
  EFI_STATUS   Status;
  IP4_HEAD     ZeroHead;
  UINT8        *Option;
  UINT32       OptionLen;

  IpSb   = (IP4_SERVICE *)Context;
  Option = NULL;

  if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTROY)) {
    goto DROP;
  }

  if (!Ip4IsValidPacketLength (Packet)) {
    goto RESTART;
  }

  Head = (IP4_HEAD *)NetbufGetByte (Packet, 0, NULL);
  ASSERT (Head != NULL);
  OptionLen = (Head->HeadLen << 2) - IP4_MIN_HEADLEN;
  if (OptionLen > 0) {
    Option = (UINT8 *)(Head + 1);
  }

  //
  // Validate packet format and reassemble packet if it is necessary.
  //
  Status = Ip4PreProcessPacket (
             IpSb,
             &Packet,
             Head,
             Option,
             OptionLen,
             Flag
             );

  if (EFI_ERROR (Status)) {
    goto RESTART;
  }

  //
  // After trim off, the packet is a esp/ah/udp/tcp/icmp6 net buffer,
  // and no need consider any other ahead ext headers.
  //
  Status = Ip4IpSecProcessPacket (
             IpSb,
             &Head,
             &Packet,
             &Option,
             &OptionLen,
             EfiIPsecInBound,
             NULL
             );

  if (EFI_ERROR (Status)) {
    goto RESTART;
  }

  //
  // If the packet is protected by tunnel mode, parse the inner Ip Packet.
  //
  ZeroMem (&ZeroHead, sizeof (IP4_HEAD));
  if (0 == CompareMem (Head, &ZeroHead, sizeof (IP4_HEAD))) {
    // Packet may have been changed. Head, HeadLen, TotalLen, and
    // info must be reloaded before use. The ownership of the packet
    // is transferred to the packet process logic.
    //
    if (!Ip4IsValidPacketLength (Packet)) {
      goto RESTART;
    }

    Head = (IP4_HEAD *)NetbufGetByte (Packet, 0, NULL);
    ASSERT (Head != NULL);
    Status = Ip4PreProcessPacket (
               IpSb,
               &Packet,
               Head,
               Option,
               OptionLen,
               Flag
               );
    if (EFI_ERROR (Status)) {
      goto RESTART;
    }
  }

  ASSERT (Packet != NULL);
  Head                               = Packet->Ip.Ip4;
  IP4_GET_CLIP_INFO (Packet)->Status = EFI_SUCCESS;

  switch (Head->Protocol) {
    case EFI_IP_PROTO_ICMP:
      Ip4IcmpHandle (IpSb, Head, Packet);
      break;

    case IP4_PROTO_IGMP:
      Ip4IgmpHandle (IpSb, Head, Packet);
      break;

    default:
      Ip4Demultiplex (IpSb, Head, Packet, Option, OptionLen);
  }

  Packet = NULL;

  //
  // Dispatch the DPCs queued by the NotifyFunction of the rx token's events
  // which are signaled with received data.
  //
  DispatchDpc ();

RESTART:
  Ip4ReceiveFrame (IpSb->DefaultInterface, NULL, Ip4AccpetFrame, IpSb);

DROP:
  if (Packet != NULL) {
    NetbufFree (Packet);
  }

  return;
}

/**
  Check whether this IP child accepts the packet.

  @param[in]  IpInstance             The IP child to check
  @param[in]  Head                   The IP header of the packet
  @param[in]  Packet                 The data of the packet

  @retval TRUE   If the child wants to receive the packet.
  @retval FALSE  Otherwise.

**/
BOOLEAN
Ip4InstanceFrameAcceptable (
  IN IP4_PROTOCOL  *IpInstance,
  IN IP4_HEAD      *Head,
  IN NET_BUF       *Packet
  )
{
  IP4_ICMP_ERROR_HEAD  Icmp;
  EFI_IP4_CONFIG_DATA  *Config;
  IP4_CLIP_INFO        *Info;
  UINT16               Proto;
  UINT32               Index;

  Config = &IpInstance->ConfigData;

  //
  // Dirty trick for the Tiano UEFI network stack implementation. If
  // ReceiveTimeout == -1, the receive of the packet for this instance
  // is disabled. The UEFI spec don't have such capability. We add
  // this to improve the performance because IP will make a copy of
  // the received packet for each accepting instance. Some IP instances
  // used by UDP/TCP only send packets, they don't wants to receive.
  //
  if (Config->ReceiveTimeout == (UINT32)(-1)) {
    return FALSE;
  }

  if (Config->AcceptPromiscuous) {
    return TRUE;
  }

  //
  // Use protocol from the IP header embedded in the ICMP error
  // message to filter, instead of ICMP itself. ICMP handle will
  // call Ip4Demultiplex to deliver ICMP errors.
  //
  Proto = Head->Protocol;

  if ((Proto == EFI_IP_PROTO_ICMP) && (!Config->AcceptAnyProtocol) && (Proto != Config->DefaultProtocol)) {
    NetbufCopy (Packet, 0, sizeof (Icmp.Head), (UINT8 *)&Icmp.Head);

    if (mIcmpClass[Icmp.Head.Type].IcmpClass == ICMP_ERROR_MESSAGE) {
      if (!Config->AcceptIcmpErrors) {
        return FALSE;
      }

      NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *)&Icmp);
      Proto = Icmp.IpHead.Protocol;
    }
  }

  //
  // Match the protocol
  //
  if (!Config->AcceptAnyProtocol && (Proto != Config->DefaultProtocol)) {
    return FALSE;
  }

  //
  // Check for broadcast, the caller has computed the packet's
  // cast type for this child's interface.
  //
  Info = IP4_GET_CLIP_INFO (Packet);

  if (IP4_IS_BROADCAST (Info->CastType)) {
    return Config->AcceptBroadcast;
  }

  //
  // If it is a multicast packet, check whether we are in the group.
  //
  if (Info->CastType == IP4_MULTICAST) {
    //
    // Receive the multicast if the instance wants to receive all packets.
    //
    if (!IpInstance->ConfigData.UseDefaultAddress && (IpInstance->Interface->Ip == 0)) {
      return TRUE;
    }

    for (Index = 0; Index < IpInstance->GroupCount; Index++) {
      if (IpInstance->Groups[Index] == HTONL (Head->Dst)) {
        break;
      }
    }

    return (BOOLEAN)(Index < IpInstance->GroupCount);
  }

  return TRUE;
}

/**
  Enqueue a shared copy of the packet to the IP4 child if the
  packet is acceptable to it. Here the data of the packet is
  shared, but the net buffer isn't.

  @param[in]  IpInstance             The IP4 child to enqueue the packet to
  @param[in]  Head                   The IP header of the received packet
  @param[in]  Packet                 The data of the received packet

  @retval EFI_NOT_STARTED        The IP child hasn't been configured.
  @retval EFI_INVALID_PARAMETER  The child doesn't want to receive the packet
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate some resource
  @retval EFI_SUCCESS            A shared copy the packet is enqueued to the child.

**/
EFI_STATUS
Ip4InstanceEnquePacket (
  IN IP4_PROTOCOL  *IpInstance,
  IN IP4_HEAD      *Head,
  IN NET_BUF       *Packet
  )
{
  IP4_CLIP_INFO  *Info;
  NET_BUF        *Clone;

  //
  // Check whether the packet is acceptable to this instance.
  //
  if (IpInstance->State != IP4_STATE_CONFIGED) {
    return EFI_NOT_STARTED;
  }

  if (!Ip4InstanceFrameAcceptable (IpInstance, Head, Packet)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Enqueue a shared copy of the packet.
  //
  Clone = NetbufClone (Packet);

  if (Clone == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Set the receive time out for the assembled packet. If it expires,
  // packet will be removed from the queue.
  //
  Info       = IP4_GET_CLIP_INFO (Clone);
  Info->Life = IP4_US_TO_SEC (IpInstance->ConfigData.ReceiveTimeout);

  InsertTailList (&IpInstance->Received, &Clone->List);
  return EFI_SUCCESS;
}

/**
  The signal handle of IP4's recycle event. It is called back
  when the upper layer release the packet.

  @param  Event              The IP4's recycle event.
  @param  Context            The context of the handle, which is a
                             IP4_RXDATA_WRAP

**/
VOID
EFIAPI
Ip4OnRecyclePacket (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  IP4_RXDATA_WRAP  *Wrap;

  Wrap = (IP4_RXDATA_WRAP *)Context;

  EfiAcquireLockOrFail (&Wrap->IpInstance->RecycleLock);
  RemoveEntryList (&Wrap->Link);
  EfiReleaseLock (&Wrap->IpInstance->RecycleLock);

  ASSERT (!NET_BUF_SHARED (Wrap->Packet));
  NetbufFree (Wrap->Packet);

  gBS->CloseEvent (Wrap->RxData.RecycleSignal);
  FreePool (Wrap);
}

/**
  Wrap the received packet to a IP4_RXDATA_WRAP, which will be
  delivered to the upper layer. Each IP4 child that accepts the
  packet will get a not-shared copy of the packet which is wrapped
  in the IP4_RXDATA_WRAP. The IP4_RXDATA_WRAP->RxData is passed
  to the upper layer. Upper layer will signal the recycle event in
  it when it is done with the packet.

  @param[in]  IpInstance    The IP4 child to receive the packet.
  @param[in]  Packet        The packet to deliver up.

  @retval Wrap              if warp the packet succeed.
  @retval NULL              failed to wrap the packet .

**/
IP4_RXDATA_WRAP *
Ip4WrapRxData (
  IN IP4_PROTOCOL  *IpInstance,
  IN NET_BUF       *Packet
  )
{
  IP4_RXDATA_WRAP       *Wrap;
  EFI_IP4_RECEIVE_DATA  *RxData;
  EFI_STATUS            Status;
  BOOLEAN               RawData;

  Wrap = AllocatePool (IP4_RXDATA_WRAP_SIZE (Packet->BlockOpNum));

  if (Wrap == NULL) {
    return NULL;
  }

  InitializeListHead (&Wrap->Link);

  Wrap->IpInstance = IpInstance;
  Wrap->Packet     = Packet;
  RxData           = &Wrap->RxData;

  ZeroMem (RxData, sizeof (EFI_IP4_RECEIVE_DATA));

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  Ip4OnRecyclePacket,
                  Wrap,
                  &RxData->RecycleSignal
                  );

  if (EFI_ERROR (Status)) {
    FreePool (Wrap);
    return NULL;
  }

  ASSERT (Packet->Ip.Ip4 != NULL);

  ASSERT (IpInstance != NULL);
  RawData = IpInstance->ConfigData.RawData;

  //
  // The application expects a network byte order header.
  //
  if (!RawData) {
    RxData->HeaderLength  = (Packet->Ip.Ip4->HeadLen << 2);
    RxData->Header        = (EFI_IP4_HEADER *)Ip4NtohHead (Packet->Ip.Ip4);
    RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN;
    RxData->Options       = NULL;

    if (RxData->OptionsLength != 0) {
      RxData->Options = (VOID *)(RxData->Header + 1);
    }
  }

  RxData->DataLength = Packet->TotalSize;

  //
  // Build the fragment table to be delivered up.
  //
  RxData->FragmentCount = Packet->BlockOpNum;
  NetbufBuildExt (Packet, (NET_FRAGMENT *)RxData->FragmentTable, &RxData->FragmentCount);

  return Wrap;
}

/**
  Deliver the received packets to upper layer if there are both received
  requests and enqueued packets. If the enqueued packet is shared, it will
  duplicate it to a non-shared packet, release the shared packet, then
  deliver the non-shared packet up.

  @param[in]  IpInstance         The IP child to deliver the packet up.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources to deliver the
                                 packets.
  @retval EFI_SUCCESS            All the enqueued packets that can be delivered
                                 are delivered up.

**/
EFI_STATUS
Ip4InstanceDeliverPacket (
  IN IP4_PROTOCOL  *IpInstance
  )
{
  EFI_IP4_COMPLETION_TOKEN  *Token;
  IP4_RXDATA_WRAP           *Wrap;
  NET_BUF                   *Packet;
  NET_BUF                   *Dup;
  UINT8                     *Head;
  UINT32                    HeadLen;

  //
  // Deliver a packet if there are both a packet and a receive token.
  //
  while (!IsListEmpty (&IpInstance->Received) &&
         !NetMapIsEmpty (&IpInstance->RxTokens))
  {
    Packet = NET_LIST_HEAD (&IpInstance->Received, NET_BUF, List);

    if (!NET_BUF_SHARED (Packet)) {
      //
      // If this is the only instance that wants the packet, wrap it up.
      //
      Wrap = Ip4WrapRxData (IpInstance, Packet);

      if (Wrap == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      RemoveEntryList (&Packet->List);
    } else {
      //
      // Create a duplicated packet if this packet is shared
      //
      if (IpInstance->ConfigData.RawData) {
        HeadLen = 0;
      } else {
        HeadLen = IP4_MAX_HEADLEN;
      }

      Dup = NetbufDuplicate (Packet, NULL, HeadLen);

      if (Dup == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      if (!IpInstance->ConfigData.RawData) {
        //
        // Copy the IP head over. The packet to deliver up is
        // headless. Trim the head off after copy. The IP head
        // may be not continuous before the data.
        //
        Head = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD);
        ASSERT (Head != NULL);

        Dup->Ip.Ip4 = (IP4_HEAD *)Head;

        CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2);
        NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE);
      }

      Wrap = Ip4WrapRxData (IpInstance, Dup);

      if (Wrap == NULL) {
        NetbufFree (Dup);
        return EFI_OUT_OF_RESOURCES;
      }

      RemoveEntryList (&Packet->List);
      NetbufFree (Packet);

      Packet = Dup;
    }

    //
    // Insert it into the delivered packet, then get a user's
    // receive token, pass the wrapped packet up.
    //
    EfiAcquireLockOrFail (&IpInstance->RecycleLock);
    InsertHeadList (&IpInstance->Delivered, &Wrap->Link);
    EfiReleaseLock (&IpInstance->RecycleLock);

    Token                = NetMapRemoveHead (&IpInstance->RxTokens, NULL);
    Token->Status        = IP4_GET_CLIP_INFO (Packet)->Status;
    Token->Packet.RxData = &Wrap->RxData;

    gBS->SignalEvent (Token->Event);
  }

  return EFI_SUCCESS;
}

/**
  Enqueue a received packet to all the IP children that share
  the same interface.

  @param[in]  IpSb               The IP4 service instance that receive the packet.
  @param[in]  Head               The header of the received packet.
  @param[in]  Packet             The data of the received packet.
  @param[in]  Option             Point to the IP4 packet header options.
  @param[in]  OptionLen          Length of the IP4 packet header options.
  @param[in]  IpIf               The interface to enqueue the packet to.

  @return The number of the IP4 children that accepts the packet

**/
INTN
Ip4InterfaceEnquePacket (
  IN IP4_SERVICE    *IpSb,
  IN IP4_HEAD       *Head,
  IN NET_BUF        *Packet,
  IN UINT8          *Option,
  IN UINT32         OptionLen,
  IN IP4_INTERFACE  *IpIf
  )
{
  IP4_PROTOCOL   *IpInstance;
  IP4_CLIP_INFO  *Info;
  LIST_ENTRY     *Entry;
  INTN           Enqueued;
  INTN           LocalType;
  INTN           SavedType;

  //
  // First, check that the packet is acceptable to this interface
  // and find the local cast type for the interface. A packet sent
  // to say 192.168.1.1 should NOT be deliver to 10.0.0.1 unless
  // promiscuous receiving.
  //
  LocalType = 0;
  Info      = IP4_GET_CLIP_INFO (Packet);

  if ((Info->CastType == IP4_MULTICAST) || (Info->CastType == IP4_LOCAL_BROADCAST)) {
    //
    // If the CastType is multicast, don't need to filter against
    // the group address here, Ip4InstanceFrameAcceptable will do
    // that later.
    //
    LocalType = Info->CastType;
  } else {
    //
    // Check the destination against local IP. If the station
    // address is 0.0.0.0, it means receiving all the IP destined
    // to local non-zero IP. Otherwise, it is necessary to compare
    // the destination to the interface's IP address.
    //
    if (IpIf->Ip == IP4_ALLZERO_ADDRESS) {
      LocalType = IP4_LOCAL_HOST;
    } else {
      LocalType = Ip4GetNetCast (Head->Dst, IpIf);

      if ((LocalType == 0) && IpIf->PromiscRecv) {
        LocalType = IP4_PROMISCUOUS;
      }
    }
  }

  if (LocalType == 0) {
    return 0;
  }

  //
  // Iterate through the ip instances on the interface, enqueue
  // the packet if filter passed. Save the original cast type,
  // and pass the local cast type to the IP children on the
  // interface. The global cast type will be restored later.
  //
  SavedType      = Info->CastType;
  Info->CastType = LocalType;

  Enqueued = 0;

  NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) {
    IpInstance = NET_LIST_USER_STRUCT (Entry, IP4_PROTOCOL, AddrLink);
    NET_CHECK_SIGNATURE (IpInstance, IP4_PROTOCOL_SIGNATURE);

    //
    // In RawData mode, add IPv4 headers and options back to packet.
    //
    if ((IpInstance->ConfigData.RawData) && (Option != NULL) && (OptionLen != 0)) {
      Ip4PrependHead (Packet, Head, Option, OptionLen);
    }

    if (Ip4InstanceEnquePacket (IpInstance, Head, Packet) == EFI_SUCCESS) {
      Enqueued++;
    }
  }

  Info->CastType = SavedType;
  return Enqueued;
}

/**
  Deliver the packet for each IP4 child on the interface.

  @param[in]  IpSb               The IP4 service instance that received the packet
  @param[in]  IpIf               The IP4 interface to deliver the packet.

  @retval EFI_SUCCESS            It always returns EFI_SUCCESS now

**/
EFI_STATUS
Ip4InterfaceDeliverPacket (
  IN IP4_SERVICE    *IpSb,
  IN IP4_INTERFACE  *IpIf
  )
{
  IP4_PROTOCOL  *Ip4Instance;
  LIST_ENTRY    *Entry;

  NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) {
    Ip4Instance = NET_LIST_USER_STRUCT (Entry, IP4_PROTOCOL, AddrLink);
    Ip4InstanceDeliverPacket (Ip4Instance);
  }

  return EFI_SUCCESS;
}

/**
  Demultiple the packet. the packet delivery is processed in two
  passes. The first pass will enqueue a shared copy of the packet
  to each IP4 child that accepts the packet. The second pass will
  deliver a non-shared copy of the packet to each IP4 child that
  has pending receive requests. Data is copied if more than one
  child wants to consume the packet because each IP child needs
  its own copy of the packet to make changes.

  @param[in]  IpSb               The IP4 service instance that received the packet.
  @param[in]  Head               The header of the received packet.
  @param[in]  Packet             The data of the received packet.
  @param[in]  Option             Point to the IP4 packet header options.
  @param[in]  OptionLen          Length of the IP4 packet header options.

  @retval EFI_NOT_FOUND          No IP child accepts the packet.
  @retval EFI_SUCCESS            The packet is enqueued or delivered to some IP
                                 children.

**/
EFI_STATUS
Ip4Demultiplex (
  IN IP4_SERVICE  *IpSb,
  IN IP4_HEAD     *Head,
  IN NET_BUF      *Packet,
  IN UINT8        *Option,
  IN UINT32       OptionLen
  )
{
  LIST_ENTRY     *Entry;
  IP4_INTERFACE  *IpIf;
  INTN           Enqueued;

  //
  // Two pass delivery: first, enqueue a shared copy of the packet
  // to each instance that accept the packet.
  //
  Enqueued = 0;

  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);

    if (IpIf->Configured) {
      Enqueued += Ip4InterfaceEnquePacket (
                    IpSb,
                    Head,
                    Packet,
                    Option,
                    OptionLen,
                    IpIf
                    );
    }
  }

  //
  // Second: deliver a duplicate of the packet to each instance.
  // Release the local reference first, so that the last instance
  // getting the packet will not copy the data.
  //
  NetbufFree (Packet);

  if (Enqueued == 0) {
    return EFI_NOT_FOUND;
  }

  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);

    if (IpIf->Configured) {
      Ip4InterfaceDeliverPacket (IpSb, IpIf);
    }
  }

  return EFI_SUCCESS;
}

/**
  Timeout the fragment and enqueued packets.

  @param[in]  IpSb                   The IP4 service instance to timeout

**/
VOID
Ip4PacketTimerTicking (
  IN IP4_SERVICE  *IpSb
  )
{
  LIST_ENTRY          *InstanceEntry;
  LIST_ENTRY          *Entry;
  LIST_ENTRY          *Next;
  IP4_PROTOCOL        *IpInstance;
  IP4_ASSEMBLE_ENTRY  *Assemble;
  NET_BUF             *Packet;
  IP4_CLIP_INFO       *Info;
  UINT32              Index;

  //
  // First, time out the fragments. The packet's life is counting down
  // once the first-arrived fragment was received.
  //
  for (Index = 0; Index < IP4_ASSEMLE_HASH_SIZE; Index++) {
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->Assemble.Bucket[Index]) {
      Assemble = NET_LIST_USER_STRUCT (Entry, IP4_ASSEMBLE_ENTRY, Link);

      if ((Assemble->Life > 0) && (--Assemble->Life == 0)) {
        RemoveEntryList (Entry);
        Ip4FreeAssembleEntry (Assemble);
      }
    }
  }

  NET_LIST_FOR_EACH (InstanceEntry, &IpSb->Children) {
    IpInstance = NET_LIST_USER_STRUCT (InstanceEntry, IP4_PROTOCOL, Link);

    //
    // Second, time out the assembled packets enqueued on each IP child.
    //
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpInstance->Received) {
      Packet = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
      Info   = IP4_GET_CLIP_INFO (Packet);

      if ((Info->Life > 0) && (--Info->Life == 0)) {
        RemoveEntryList (Entry);
        NetbufFree (Packet);
      }
    }

    //
    // Third: time out the transmitted packets.
    //
    NetMapIterate (&IpInstance->TxTokens, Ip4SentPacketTicking, NULL);
  }
}
