/** @file
  Network library functions providing net buffer operation support.

Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/

#include <Uefi.h>

#include <Library/NetLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>


/**
  Allocate and build up the sketch for a NET_BUF.

  The net buffer allocated has the BlockOpNum's NET_BLOCK_OP, and its associated
  NET_VECTOR has the BlockNum's NET_BLOCK. But all the NET_BLOCK_OP and
  NET_BLOCK remain un-initialized.

  @param[in]  BlockNum       The number of NET_BLOCK in the vector of net buffer
  @param[in]  BlockOpNum     The number of NET_BLOCK_OP in the net buffer

  @return                    Pointer to the allocated NET_BUF, or NULL if the
                             allocation failed due to resource limit.

**/
NET_BUF *
NetbufAllocStruct (
  IN UINT32                 BlockNum,
  IN UINT32                 BlockOpNum
  )
{
  NET_BUF                   *Nbuf;
  NET_VECTOR                *Vector;

  ASSERT (BlockOpNum >= 1);

  //
  // Allocate three memory blocks.
  //
  Nbuf = AllocateZeroPool (NET_BUF_SIZE (BlockOpNum));

  if (Nbuf == NULL) {
    return NULL;
  }

  Nbuf->Signature           = NET_BUF_SIGNATURE;
  Nbuf->RefCnt              = 1;
  Nbuf->BlockOpNum          = BlockOpNum;
  InitializeListHead (&Nbuf->List);

  if (BlockNum != 0) {
    Vector = AllocateZeroPool (NET_VECTOR_SIZE (BlockNum));

    if (Vector == NULL) {
      goto FreeNbuf;
    }

    Vector->Signature = NET_VECTOR_SIGNATURE;
    Vector->RefCnt    = 1;
    Vector->BlockNum  = BlockNum;
    Nbuf->Vector      = Vector;
  }

  return Nbuf;

FreeNbuf:

  FreePool (Nbuf);
  return NULL;
}


/**
  Allocate a single block NET_BUF. Upon allocation, all the
  free space is in the tail room.

  @param[in]  Len              The length of the block.

  @return                      Pointer to the allocated NET_BUF, or NULL if the
                               allocation failed due to resource limit.

**/
NET_BUF  *
EFIAPI
NetbufAlloc (
  IN UINT32                 Len
  )
{
  NET_BUF                   *Nbuf;
  NET_VECTOR                *Vector;
  UINT8                     *Bulk;

  ASSERT (Len > 0);

  Nbuf = NetbufAllocStruct (1, 1);

  if (Nbuf == NULL) {
    return NULL;
  }

  Bulk = AllocatePool (Len);

  if (Bulk == NULL) {
    goto FreeNBuf;
  }

  Vector = Nbuf->Vector;
  Vector->Len                 = Len;

  Vector->Block[0].Bulk       = Bulk;
  Vector->Block[0].Len        = Len;

  Nbuf->BlockOp[0].BlockHead  = Bulk;
  Nbuf->BlockOp[0].BlockTail  = Bulk + Len;

  Nbuf->BlockOp[0].Head       = Bulk;
  Nbuf->BlockOp[0].Tail       = Bulk;
  Nbuf->BlockOp[0].Size       = 0;

  return Nbuf;

FreeNBuf:
  FreePool (Nbuf);
  return NULL;
}

/**
  Free the net vector.

  Decrease the reference count of the net vector by one. The real resource free
  operation isn't performed until the reference count of the net vector is
  decreased to 0.

  @param[in]  Vector                Pointer to the NET_VECTOR to be freed.

**/
VOID
NetbufFreeVector (
  IN NET_VECTOR             *Vector
  )
{
  UINT32                    Index;

  ASSERT (Vector != NULL);
  NET_CHECK_SIGNATURE (Vector, NET_VECTOR_SIGNATURE);
  ASSERT (Vector->RefCnt > 0);

  Vector->RefCnt--;

  if (Vector->RefCnt > 0) {
    return;
  }

  if (Vector->Free != NULL) {
    //
    // Call external free function to free the vector if it
    // isn't NULL. If NET_VECTOR_OWN_FIRST is set, release the
    // first block since it is allocated by us
    //
    if ((Vector->Flag & NET_VECTOR_OWN_FIRST) != 0) {
      gBS->FreePool (Vector->Block[0].Bulk);
    }

    Vector->Free (Vector->Arg);

  } else {
    //
    // Free each memory block associated with the Vector
    //
    for (Index = 0; Index < Vector->BlockNum; Index++) {
      gBS->FreePool (Vector->Block[Index].Bulk);
    }
  }

  FreePool (Vector);
}


/**
  Free the net buffer and its associated NET_VECTOR.

  Decrease the reference count of the net buffer by one. Free the associated net
  vector and itself if the reference count of the net buffer is decreased to 0.
  The net vector free operation just decrease the reference count of the net
  vector by one and do the real resource free operation when the reference count
  of the net vector is 0.

  @param[in]  Nbuf                  Pointer to the NET_BUF to be freed.

**/
VOID
EFIAPI
NetbufFree (
  IN NET_BUF                *Nbuf
  )
{
  ASSERT (Nbuf != NULL);
  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  ASSERT (Nbuf->RefCnt > 0);

  Nbuf->RefCnt--;

  if (Nbuf->RefCnt == 0) {
    //
    // Update Vector only when NBuf is to be released. That is,
    // all the sharing of Nbuf increse Vector's RefCnt by one
    //
    NetbufFreeVector (Nbuf->Vector);
    FreePool (Nbuf);
  }
}


/**
  Create a copy of the net buffer that shares the associated net vector.

  The reference count of the newly created net buffer is set to 1. The reference
  count of the associated net vector is increased by one.

  @param[in]  Nbuf              Pointer to the net buffer to be cloned.

  @return                       Pointer to the cloned net buffer, or NULL if the
                                allocation failed due to resource limit.

**/
NET_BUF *
EFIAPI
NetbufClone (
  IN NET_BUF                *Nbuf
  )
{
  NET_BUF                   *Clone;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  Clone = AllocatePool (NET_BUF_SIZE (Nbuf->BlockOpNum));

  if (Clone == NULL) {
    return NULL;
  }

  Clone->Signature  = NET_BUF_SIGNATURE;
  Clone->RefCnt     = 1;
  InitializeListHead (&Clone->List);

  Clone->Ip   = Nbuf->Ip;
  Clone->Tcp  = Nbuf->Tcp;

  CopyMem (Clone->ProtoData, Nbuf->ProtoData, NET_PROTO_DATA);

  NET_GET_REF (Nbuf->Vector);

  Clone->Vector     = Nbuf->Vector;
  Clone->BlockOpNum = Nbuf->BlockOpNum;
  Clone->TotalSize  = Nbuf->TotalSize;
  CopyMem (Clone->BlockOp, Nbuf->BlockOp, sizeof (NET_BLOCK_OP) * Nbuf->BlockOpNum);

  return Clone;
}


/**
  Create a duplicated copy of the net buffer with data copied and HeadSpace
  bytes of head space reserved.

  The duplicated net buffer will allocate its own memory to hold the data of the
  source net buffer.

  @param[in]       Nbuf         Pointer to the net buffer to be duplicated from.
  @param[in, out]  Duplicate    Pointer to the net buffer to duplicate to, if
                                NULL a new net buffer is allocated.
  @param[in]      HeadSpace     Length of the head space to reserve.

  @return                       Pointer to the duplicated net buffer, or NULL if
                                the allocation failed due to resource limit.

**/
NET_BUF  *
EFIAPI
NetbufDuplicate (
  IN NET_BUF                *Nbuf,
  IN OUT NET_BUF            *Duplicate        OPTIONAL,
  IN UINT32                 HeadSpace
  )
{
  UINT8                     *Dst;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  if (Duplicate == NULL) {
    Duplicate = NetbufAlloc (Nbuf->TotalSize + HeadSpace);
  }

  if (Duplicate == NULL) {
    return NULL;
  }

  //
  // Don't set the IP and TCP head point, since it is most
  // like that they are pointing to the memory of Nbuf.
  //
  CopyMem (Duplicate->ProtoData, Nbuf->ProtoData, NET_PROTO_DATA);
  NetbufReserve (Duplicate, HeadSpace);

  Dst = NetbufAllocSpace (Duplicate, Nbuf->TotalSize, NET_BUF_TAIL);
  NetbufCopy (Nbuf, 0, Nbuf->TotalSize, Dst);

  return Duplicate;
}


/**
  Free a list of net buffers.

  @param[in, out]  Head              Pointer to the head of linked net buffers.

**/
VOID
EFIAPI
NetbufFreeList (
  IN OUT LIST_ENTRY         *Head
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  NET_BUF                   *Nbuf;

  Entry = Head->ForwardLink;

  NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
    NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

    RemoveEntryList (Entry);
    NetbufFree (Nbuf);
  }

  ASSERT (IsListEmpty (Head));
}


/**
  Get the index of NET_BLOCK_OP that contains the byte at Offset in the net
  buffer.

  This can be used to, for example, retrieve the IP header in the packet. It
  also can be used to get the fragment that contains the byte which is used
  mainly by the library implementation itself.

  @param[in]   Nbuf      Pointer to the net buffer.
  @param[in]   Offset    The offset of the byte.
  @param[out]  Index     Index of the NET_BLOCK_OP that contains the byte at
                         Offset.

  @return       Pointer to the Offset'th byte of data in the net buffer, or NULL
                if there is no such data in the net buffer.

**/
UINT8  *
EFIAPI
NetbufGetByte (
  IN  NET_BUF               *Nbuf,
  IN  UINT32                Offset,
  OUT UINT32                *Index  OPTIONAL
  )
{
  NET_BLOCK_OP              *BlockOp;
  UINT32                    Loop;
  UINT32                    Len;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  if (Offset >= Nbuf->TotalSize) {
    return NULL;
  }

  BlockOp = Nbuf->BlockOp;
  Len     = 0;

  for (Loop = 0; Loop < Nbuf->BlockOpNum; Loop++) {

    if (Len + BlockOp[Loop].Size <= Offset) {
      Len += BlockOp[Loop].Size;
      continue;
    }

    if (Index != NULL) {
      *Index = Loop;
    }

    return BlockOp[Loop].Head + (Offset - Len);
  }

  return NULL;
}



/**
  Set the NET_BLOCK and corresponding NET_BLOCK_OP in the net buffer and
  corresponding net vector according to the bulk pointer and bulk length.

  All the pointers in the Index'th NET_BLOCK and NET_BLOCK_OP are set to the
  bulk's head and tail respectively. So, this function alone can't be used by
  NetbufAlloc.

  @param[in, out]  Nbuf       Pointer to the net buffer.
  @param[in]       Bulk       Pointer to the data.
  @param[in]       Len        Length of the bulk data.
  @param[in]       Index      The data block index in the net buffer the bulk
                              data should belong to.

**/
VOID
NetbufSetBlock (
  IN OUT NET_BUF            *Nbuf,
  IN UINT8                  *Bulk,
  IN UINT32                 Len,
  IN UINT32                 Index
  )
{
  NET_BLOCK_OP              *BlockOp;
  NET_BLOCK                 *Block;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);
  ASSERT (Index < Nbuf->BlockOpNum);

  Block               = &(Nbuf->Vector->Block[Index]);
  BlockOp             = &(Nbuf->BlockOp[Index]);
  Block->Len          = Len;
  Block->Bulk         = Bulk;
  BlockOp->BlockHead  = Bulk;
  BlockOp->BlockTail  = Bulk + Len;
  BlockOp->Head       = Bulk;
  BlockOp->Tail       = Bulk + Len;
  BlockOp->Size       = Len;
}



/**
  Set the NET_BLOCK_OP in the net buffer. The corresponding NET_BLOCK
  structure is left untouched.

  Some times, there is no 1:1 relationship between NET_BLOCK and NET_BLOCK_OP.
  For example, that in NetbufGetFragment.

  @param[in, out]  Nbuf       Pointer to the net buffer.
  @param[in]       Bulk       Pointer to the data.
  @param[in]       Len        Length of the bulk data.
  @param[in]       Index      The data block index in the net buffer the bulk
                              data should belong to.

**/
VOID
NetbufSetBlockOp (
  IN OUT NET_BUF            *Nbuf,
  IN UINT8                  *Bulk,
  IN UINT32                 Len,
  IN UINT32                 Index
  )
{
  NET_BLOCK_OP              *BlockOp;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  ASSERT (Index < Nbuf->BlockOpNum);

  BlockOp             = &(Nbuf->BlockOp[Index]);
  BlockOp->BlockHead  = Bulk;
  BlockOp->BlockTail  = Bulk + Len;
  BlockOp->Head       = Bulk;
  BlockOp->Tail       = Bulk + Len;
  BlockOp->Size       = Len;
}


/**
  Helper function for NetbufGetFragment. NetbufGetFragment may allocate the
  first block to reserve HeadSpace bytes header space. So it needs to create a
  new net vector for the first block and can avoid copy for the remaining data
  by sharing the old net vector.

  @param[in]  Arg                   Point to the old NET_VECTOR.

**/
VOID
EFIAPI
NetbufGetFragmentFree (
  IN VOID                   *Arg
  )
{
  NET_VECTOR                *Vector;

  Vector = (NET_VECTOR *)Arg;
  NetbufFreeVector (Vector);
}


/**
  Create a NET_BUF structure which contains Len byte data of Nbuf starting from
  Offset.

  A new NET_BUF structure will be created but the associated data in NET_VECTOR
  is shared. This function exists to do IP packet fragmentation.

  @param[in]  Nbuf         Pointer to the net buffer to be extracted.
  @param[in]  Offset       Starting point of the data to be included in the new
                           net buffer.
  @param[in]  Len          Bytes of data to be included in the new net buffer.
  @param[in]  HeadSpace    Bytes of head space to reserve for protocol header.

  @return                  Pointer to the cloned net buffer, or NULL if the
                           allocation failed due to resource limit.

**/
NET_BUF  *
EFIAPI
NetbufGetFragment (
  IN NET_BUF                *Nbuf,
  IN UINT32                 Offset,
  IN UINT32                 Len,
  IN UINT32                 HeadSpace
  )
{
  NET_BUF                   *Child;
  NET_VECTOR                *Vector;
  NET_BLOCK_OP              *BlockOp;
  UINT32                    CurBlockOp;
  UINT32                    BlockOpNum;
  UINT8                     *FirstBulk;
  UINT32                    Index;
  UINT32                    First;
  UINT32                    Last;
  UINT32                    FirstSkip;
  UINT32                    FirstLen;
  UINT32                    LastLen;
  UINT32                    Cur;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  if ((Len == 0) || (Offset + Len > Nbuf->TotalSize)) {
    return NULL;
  }

  //
  // First find the first and last BlockOp that contains
  // the valid data, and compute the offset of the first
  // BlockOp and length of the last BlockOp
  //
  BlockOp = Nbuf->BlockOp;
  Cur     = 0;

  for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
    if (Offset < Cur + BlockOp[Index].Size) {
      break;
    }

    Cur += BlockOp[Index].Size;
  }

  //
  // First is the index of the first BlockOp, FirstSkip is
  // the offset of the first byte in the first BlockOp.
  //
  First     = Index;
  FirstSkip = Offset - Cur;
  FirstLen  = BlockOp[Index].Size - FirstSkip;

  Last      = 0;
  LastLen   = 0;

  if (Len > FirstLen) {
    Cur += BlockOp[Index].Size;
    Index++;

    for (; Index < Nbuf->BlockOpNum; Index++) {
      if (Offset + Len <= Cur + BlockOp[Index].Size) {
        Last    = Index;
        LastLen = Offset + Len - Cur;
        break;
      }

      Cur += BlockOp[Index].Size;
    }

  } else {
    Last     = First;
    LastLen  = Len;
    FirstLen = Len;
  }

  ASSERT (Last >= First);
  BlockOpNum = Last - First + 1;
  CurBlockOp = 0;

  if (HeadSpace != 0) {
    //
    // Allocate an extra block to accomdate the head space.
    //
    BlockOpNum++;

    Child = NetbufAllocStruct (1, BlockOpNum);

    if (Child == NULL) {
      return NULL;
    }

    FirstBulk = AllocatePool (HeadSpace);

    if (FirstBulk == NULL) {
      goto FreeChild;
    }

    Vector        = Child->Vector;
    Vector->Free  = NetbufGetFragmentFree;
    Vector->Arg   = Nbuf->Vector;
    Vector->Flag  = NET_VECTOR_OWN_FIRST;
    Vector->Len   = HeadSpace;

    //
    // Reserve the head space in the first block
    //
    NetbufSetBlock (Child, FirstBulk, HeadSpace, 0);
    Child->BlockOp[0].Head += HeadSpace;
    Child->BlockOp[0].Size =  0;
    CurBlockOp++;

  } else {
    Child = NetbufAllocStruct (0, BlockOpNum);

    if (Child == NULL) {
      return NULL;
    }

    Child->Vector = Nbuf->Vector;
  }

  NET_GET_REF (Nbuf->Vector);
  Child->TotalSize = Len;

  //
  // Set all the BlockOp up, the first and last one are special
  // and need special process.
  //
  NetbufSetBlockOp (
    Child,
    Nbuf->BlockOp[First].Head + FirstSkip,
    FirstLen,
    CurBlockOp++
    );

  for (Index = First + 1; Index < Last; Index++) {
    NetbufSetBlockOp (
      Child,
      BlockOp[Index].Head,
      BlockOp[Index].Size,
      CurBlockOp++
      );
  }

  if (First != Last) {
    NetbufSetBlockOp (
      Child,
      BlockOp[Last].Head,
      LastLen,
      CurBlockOp
      );
  }

  CopyMem (Child->ProtoData, Nbuf->ProtoData, NET_PROTO_DATA);
  return Child;

FreeChild:

  FreePool (Child);
  return NULL;
}



/**
  Build a NET_BUF from external blocks.

  A new NET_BUF structure will be created from external blocks. Additional block
  of memory will be allocated to hold reserved HeadSpace bytes of header room
  and existing HeadLen bytes of header but the external blocks are shared by the
  net buffer to avoid data copying.

  @param[in]  ExtFragment           Pointer to the data block.
  @param[in]  ExtNum                The number of the data blocks.
  @param[in]  HeadSpace             The head space to be reserved.
  @param[in]  HeadLen               The length of the protocol header, This function
                                    will pull that number of data into a linear block.
  @param[in]  ExtFree               Pointer to the caller provided free function.
  @param[in]  Arg                   The argument passed to ExtFree when ExtFree is
                                    called.

  @return                  Pointer to the net buffer built from the data blocks,
                           or NULL if the allocation failed due to resource
                           limit.

**/
NET_BUF  *
EFIAPI
NetbufFromExt (
  IN NET_FRAGMENT           *ExtFragment,
  IN UINT32                 ExtNum,
  IN UINT32                 HeadSpace,
  IN UINT32                 HeadLen,
  IN NET_VECTOR_EXT_FREE    ExtFree,
  IN VOID                   *Arg          OPTIONAL
  )
{
  NET_BUF                   *Nbuf;
  NET_VECTOR                *Vector;
  NET_FRAGMENT              SavedFragment;
  UINT32                    SavedIndex;
  UINT32                    TotalLen;
  UINT32                    BlockNum;
  UINT8                     *FirstBlock;
  UINT32                    FirstBlockLen;
  UINT8                     *Header;
  UINT32                    CurBlock;
  UINT32                    Index;
  UINT32                    Len;
  UINT32                    Copied;

  ASSERT ((ExtFragment != NULL) && (ExtNum > 0) && (ExtFree != NULL));

  SavedFragment.Bulk = NULL;
  SavedFragment.Len  = 0;

  FirstBlockLen  = 0;
  FirstBlock     = NULL;
  BlockNum       = ExtNum;
  Index          = 0;
  TotalLen       = 0;
  SavedIndex     = 0;
  Len            = 0;
  Copied         = 0;

  //
  // No need to consolidate the header if the first block is
  // longer than the header length or there is only one block.
  //
  if ((ExtFragment[0].Len >= HeadLen) || (ExtNum == 1)) {
    HeadLen = 0;
  }

  //
  // Allocate an extra block if we need to:
  //  1. Allocate some header space
  //  2. aggreate the packet header
  //
  if ((HeadSpace != 0) || (HeadLen != 0)) {
    FirstBlockLen = HeadLen + HeadSpace;
    FirstBlock    = AllocatePool (FirstBlockLen);

    if (FirstBlock == NULL) {
      return NULL;
    }

    BlockNum++;
  }

  //
  // Copy the header to the first block, reduce the NET_BLOCK
  // to allocate by one for each block that is completely covered
  // by the first bulk.
  //
  if (HeadLen != 0) {
    Len    = HeadLen;
    Header = FirstBlock + HeadSpace;

    for (Index = 0; Index < ExtNum; Index++) {
      if (Len >= ExtFragment[Index].Len) {
        CopyMem (Header, ExtFragment[Index].Bulk, ExtFragment[Index].Len);

        Copied    += ExtFragment[Index].Len;
        Len       -= ExtFragment[Index].Len;
        Header    += ExtFragment[Index].Len;
        TotalLen  += ExtFragment[Index].Len;
        BlockNum--;

        if (Len == 0) {
          //
          // Increament the index number to point to the next
          // non-empty fragment.
          //
          Index++;
          break;
        }

      } else {
        CopyMem (Header, ExtFragment[Index].Bulk, Len);

        Copied    += Len;
        TotalLen  += Len;

        //
        // Adjust the block structure to exclude the data copied,
        // So, the left-over block can be processed as other blocks.
        // But it must be recovered later. (SavedIndex > 0) always
        // holds since we don't aggreate the header if the first block
        // is bigger enough that the header is continuous
        //
        SavedIndex    = Index;
        SavedFragment = ExtFragment[Index];
        ExtFragment[Index].Bulk += Len;
        ExtFragment[Index].Len  -= Len;
        break;
      }
    }
  }

  Nbuf = NetbufAllocStruct (BlockNum, BlockNum);

  if (Nbuf == NULL) {
    goto FreeFirstBlock;
  }

  Vector       = Nbuf->Vector;
  Vector->Free = ExtFree;
  Vector->Arg  = Arg;
  Vector->Flag = ((FirstBlockLen != 0) ? NET_VECTOR_OWN_FIRST : 0);

  //
  // Set the first block up which may contain
  // some head space and aggregated header
  //
  CurBlock = 0;

  if (FirstBlockLen != 0) {
    NetbufSetBlock (Nbuf, FirstBlock, HeadSpace + Copied, 0);
    Nbuf->BlockOp[0].Head += HeadSpace;
    Nbuf->BlockOp[0].Size =  Copied;

    CurBlock++;
  }

  for (; Index < ExtNum; Index++) {
    NetbufSetBlock (Nbuf, ExtFragment[Index].Bulk, ExtFragment[Index].Len, CurBlock);
    TotalLen += ExtFragment[Index].Len;
    CurBlock++;
  }

  Vector->Len     = TotalLen + HeadSpace;
  Nbuf->TotalSize = TotalLen;

  if (SavedIndex != 0) {
    ExtFragment[SavedIndex] = SavedFragment;
  }

  return Nbuf;

FreeFirstBlock:
  if (FirstBlock != NULL) {
    FreePool (FirstBlock);
  }
  return NULL;
}


/**
  Build a fragment table to contain the fragments in the net buffer. This is the
  opposite operation of the NetbufFromExt.

  @param[in]       Nbuf                  Point to the net buffer.
  @param[in, out]  ExtFragment           Pointer to the data block.
  @param[in, out]  ExtNum                The number of the data blocks.

  @retval EFI_BUFFER_TOO_SMALL  The number of non-empty block is bigger than
                                ExtNum.
  @retval EFI_SUCCESS           Fragment table is built successfully.

**/
EFI_STATUS
EFIAPI
NetbufBuildExt (
  IN NET_BUF                *Nbuf,
  IN OUT NET_FRAGMENT       *ExtFragment,
  IN OUT UINT32             *ExtNum
  )
{
  UINT32                    Index;
  UINT32                    Current;

  Current = 0;

  for (Index = 0; (Index < Nbuf->BlockOpNum); Index++) {
    if (Nbuf->BlockOp[Index].Size == 0) {
      continue;
    }

    if (Current < *ExtNum) {
      ExtFragment[Current].Bulk = Nbuf->BlockOp[Index].Head;
      ExtFragment[Current].Len  = Nbuf->BlockOp[Index].Size;
      Current++;
    } else {
      return EFI_BUFFER_TOO_SMALL;
    }
  }

  *ExtNum = Current;
  return EFI_SUCCESS;
}


/**
  Build a net buffer from a list of net buffers.

  All the fragments will be collected from the list of NEW_BUF and then a new
  net buffer will be created through NetbufFromExt.

  @param[in]   BufList    A List of the net buffer.
  @param[in]   HeadSpace  The head space to be reserved.
  @param[in]   HeaderLen  The length of the protocol header, This function
                          will pull that number of data into a linear block.
  @param[in]   ExtFree    Pointer to the caller provided free function.
  @param[in]   Arg        The argument passed to ExtFree when ExtFree is called.

  @return                 Pointer to the net buffer built from the list of net
                          buffers.

**/
NET_BUF  *
EFIAPI
NetbufFromBufList (
  IN LIST_ENTRY             *BufList,
  IN UINT32                 HeadSpace,
  IN UINT32                 HeaderLen,
  IN NET_VECTOR_EXT_FREE    ExtFree,
  IN VOID                   *Arg              OPTIONAL
  )
{
  NET_FRAGMENT              *Fragment;
  UINT32                    FragmentNum;
  LIST_ENTRY                *Entry;
  NET_BUF                   *Nbuf;
  UINT32                    Index;
  UINT32                    Current;

  //
  //Compute how many blocks are there
  //
  FragmentNum = 0;

  NET_LIST_FOR_EACH (Entry, BufList) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
    NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
    FragmentNum += Nbuf->BlockOpNum;
  }

  //
  //Allocate and copy block points
  //
  Fragment = AllocatePool (sizeof (NET_FRAGMENT) * FragmentNum);

  if (Fragment == NULL) {
    return NULL;
  }

  Current = 0;

  NET_LIST_FOR_EACH (Entry, BufList) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
    NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

    for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
      if (Nbuf->BlockOp[Index].Size != 0) {
        Fragment[Current].Bulk = Nbuf->BlockOp[Index].Head;
        Fragment[Current].Len  = Nbuf->BlockOp[Index].Size;
        Current++;
      }
    }
  }

  Nbuf = NetbufFromExt (Fragment, Current, HeadSpace, HeaderLen, ExtFree, Arg);
  FreePool (Fragment);

  return Nbuf;
}


/**
  Reserve some space in the header room of the net buffer.

  Upon allocation, all the space are in the tail room of the buffer. Call this
  function to move some space to the header room. This function is quite limited
  in that it can only reserve space from the first block of an empty NET_BUF not
  built from the external. But it should be enough for the network stack.

  @param[in, out]  Nbuf     Pointer to the net buffer.
  @param[in]       Len      The length of buffer to be reserved from the header.

**/
VOID
EFIAPI
NetbufReserve (
  IN OUT NET_BUF            *Nbuf,
  IN UINT32                 Len
  )
{
  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);

  ASSERT ((Nbuf->BlockOpNum == 1) && (Nbuf->TotalSize == 0));
  ASSERT ((Nbuf->Vector->Free == NULL) && (Nbuf->Vector->Len >= Len));

  Nbuf->BlockOp[0].Head += Len;
  Nbuf->BlockOp[0].Tail += Len;

  ASSERT (Nbuf->BlockOp[0].Tail <= Nbuf->BlockOp[0].BlockTail);
}


/**
  Allocate Len bytes of space from the header or tail of the buffer.

  @param[in, out]  Nbuf       Pointer to the net buffer.
  @param[in]       Len        The length of the buffer to be allocated.
  @param[in]       FromHead   The flag to indicate whether reserve the data
                              from head (TRUE) or tail (FALSE).

  @return                     Pointer to the first byte of the allocated buffer,
                              or NULL if there is no sufficient space.

**/
UINT8*
EFIAPI
NetbufAllocSpace (
  IN OUT NET_BUF            *Nbuf,
  IN UINT32                 Len,
  IN BOOLEAN                FromHead
  )
{
  NET_BLOCK_OP              *BlockOp;
  UINT32                    Index;
  UINT8                     *SavedTail;

  Index = 0;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);

  ASSERT (Len > 0);

  if (FromHead) {
    //
    // Allocate some space from head. If the buffer is empty,
    // allocate from the first block. If it isn't, allocate
    // from the first non-empty block, or the block before that.
    //
    if (Nbuf->TotalSize == 0) {
      Index = 0;
    } else {
      NetbufGetByte (Nbuf, 0, &Index);

      if ((NET_HEADSPACE(&(Nbuf->BlockOp[Index])) < Len) && (Index > 0)) {
        Index--;
      }
    }

    BlockOp = &(Nbuf->BlockOp[Index]);

    if (NET_HEADSPACE (BlockOp) < Len) {
      return NULL;
    }

    BlockOp->Head   -= Len;
    BlockOp->Size   += Len;
    Nbuf->TotalSize += Len;

    return BlockOp->Head;

  } else {
    //
    // Allocate some space from the tail. If the buffer is empty,
    // allocate from the first block. If it isn't, allocate
    // from the last non-empty block, or the block after that.
    //
    if (Nbuf->TotalSize == 0) {
      Index = 0;
    } else {
      NetbufGetByte (Nbuf, Nbuf->TotalSize - 1, &Index);

      if ((NET_TAILSPACE(&(Nbuf->BlockOp[Index])) < Len) &&
          (Index < Nbuf->BlockOpNum - 1)) {

        Index++;
      }
    }

    BlockOp = &(Nbuf->BlockOp[Index]);

    if (NET_TAILSPACE (BlockOp) < Len) {
      return NULL;
    }

    SavedTail       = BlockOp->Tail;

    BlockOp->Tail   += Len;
    BlockOp->Size   += Len;
    Nbuf->TotalSize += Len;

    return SavedTail;
  }
}


/**
  Trim a single NET_BLOCK by Len bytes from the header or tail.

  @param[in, out]  BlockOp      Pointer to the NET_BLOCK.
  @param[in]       Len          The length of the data to be trimmed.
  @param[in]       FromHead     The flag to indicate whether trim data from head
                                (TRUE) or tail (FALSE).

**/
VOID
NetblockTrim (
  IN OUT NET_BLOCK_OP       *BlockOp,
  IN UINT32                 Len,
  IN BOOLEAN                FromHead
  )
{
  ASSERT ((BlockOp != NULL) && (BlockOp->Size >= Len));

  BlockOp->Size -= Len;

  if (FromHead) {
    BlockOp->Head += Len;
  } else {
    BlockOp->Tail -= Len;
  }
}


/**
  Trim Len bytes from the header or tail of the net buffer.

  @param[in, out]  Nbuf         Pointer to the net buffer.
  @param[in]       Len          The length of the data to be trimmed.
  @param[in]      FromHead      The flag to indicate whether trim data from head
                                (TRUE) or tail (FALSE).

  @return    Length of the actually trimmed data, which is possible to be less
             than Len because the TotalSize of Nbuf is less than Len.

**/
UINT32
EFIAPI
NetbufTrim (
  IN OUT NET_BUF            *Nbuf,
  IN UINT32                 Len,
  IN BOOLEAN                FromHead
  )
{
  NET_BLOCK_OP              *BlockOp;
  UINT32                    Index;
  UINT32                    Trimmed;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  if (Len > Nbuf->TotalSize) {
    Len = Nbuf->TotalSize;
  }

  //
  // If FromTail is true, iterate backward. That
  // is, init Index to NBuf->BlockNum - 1, and
  // decrease it by 1 during each loop. Otherwise,
  // iterate forward. That is, init Index to 0, and
  // increase it by 1 during each loop.
  //
  Trimmed          = 0;
  Nbuf->TotalSize -= Len;

  Index   = (FromHead ? 0 : Nbuf->BlockOpNum - 1);
  BlockOp = Nbuf->BlockOp;

  for (;;) {
    if (BlockOp[Index].Size == 0) {
      Index += (FromHead ? 1 : -1);
      continue;
    }

    if (Len > BlockOp[Index].Size) {
      Len     -= BlockOp[Index].Size;
      Trimmed += BlockOp[Index].Size;
      NetblockTrim (&BlockOp[Index], BlockOp[Index].Size, FromHead);
    } else {
      Trimmed += Len;
      NetblockTrim (&BlockOp[Index], Len, FromHead);
      break;
    }

    Index += (FromHead ? 1 : -1);
  }

  return Trimmed;
}


/**
  Copy Len bytes of data from the specific offset of the net buffer to the
  destination memory.

  The Len bytes of data may cross the several fragments of the net buffer.

  @param[in]   Nbuf         Pointer to the net buffer.
  @param[in]   Offset       The sequence number of the first byte to copy.
  @param[in]   Len          Length of the data to copy.
  @param[in]   Dest         The destination of the data to copy to.

  @return           The length of the actual copied data, or 0 if the offset
                    specified exceeds the total size of net buffer.

**/
UINT32
EFIAPI
NetbufCopy (
  IN NET_BUF                *Nbuf,
  IN UINT32                 Offset,
  IN UINT32                 Len,
  IN UINT8                  *Dest
  )
{
  NET_BLOCK_OP              *BlockOp;
  UINT32                    Skip;
  UINT32                    Left;
  UINT32                    Copied;
  UINT32                    Index;
  UINT32                    Cur;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  ASSERT (Dest);

  if ((Len == 0) || (Nbuf->TotalSize <= Offset)) {
    return 0;
  }

  if (Nbuf->TotalSize - Offset < Len) {
    Len = Nbuf->TotalSize - Offset;
  }

  BlockOp = Nbuf->BlockOp;

  //
  // Skip to the offset. Don't make "Offset-By-One" error here.
  // Cur + BLOCK.SIZE is the first sequence number of next block.
  // So, (Offset < Cur + BLOCK.SIZE) means that the  first byte
  // is in the current block. if (Offset == Cur + BLOCK.SIZE), the
  // first byte is the next block's first byte.
  //
  Cur = 0;

  for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
    if (BlockOp[Index].Size == 0) {
      continue;
    }

    if (Offset < Cur + BlockOp[Index].Size) {
      break;
    }

    Cur += BlockOp[Index].Size;
  }

  //
  // Cur is the sequence number of the first byte in the block
  // Offset - Cur is the number of bytes before first byte to
  // to copy in the current block.
  //
  Skip  = Offset - Cur;
  Left  = BlockOp[Index].Size - Skip;

  if (Len <= Left) {
    CopyMem (Dest, BlockOp[Index].Head + Skip, Len);
    return Len;
  }

  CopyMem (Dest, BlockOp[Index].Head + Skip, Left);

  Dest  += Left;
  Len   -= Left;
  Copied = Left;

  Index++;

  for (; Index < Nbuf->BlockOpNum; Index++) {
    if (Len > BlockOp[Index].Size) {
      Len    -= BlockOp[Index].Size;
      Copied += BlockOp[Index].Size;

      CopyMem (Dest, BlockOp[Index].Head, BlockOp[Index].Size);
      Dest   += BlockOp[Index].Size;
    } else {
      Copied += Len;
      CopyMem (Dest, BlockOp[Index].Head, Len);
      break;
    }
  }

  return Copied;
}


/**
  Initiate the net buffer queue.

  @param[in, out]  NbufQue   Pointer to the net buffer queue to be initialized.

**/
VOID
EFIAPI
NetbufQueInit (
  IN OUT NET_BUF_QUEUE          *NbufQue
  )
{
  NbufQue->Signature  = NET_QUE_SIGNATURE;
  NbufQue->RefCnt     = 1;
  InitializeListHead (&NbufQue->List);

  InitializeListHead (&NbufQue->BufList);
  NbufQue->BufSize  = 0;
  NbufQue->BufNum   = 0;
}


/**
  Allocate and initialize a net buffer queue.

  @return         Pointer to the allocated net buffer queue, or NULL if the
                  allocation failed due to resource limit.

**/
NET_BUF_QUEUE  *
EFIAPI
NetbufQueAlloc (
  VOID
  )
{
  NET_BUF_QUEUE             *NbufQue;

  NbufQue = AllocatePool (sizeof (NET_BUF_QUEUE));
  if (NbufQue == NULL) {
    return NULL;
  }

  NetbufQueInit (NbufQue);

  return NbufQue;
}


/**
  Free a net buffer queue.

  Decrease the reference count of the net buffer queue by one. The real resource
  free operation isn't performed until the reference count of the net buffer
  queue is decreased to 0.

  @param[in]  NbufQue               Pointer to the net buffer queue to be freed.

**/
VOID
EFIAPI
NetbufQueFree (
  IN NET_BUF_QUEUE          *NbufQue
  )
{
  ASSERT (NbufQue != NULL);
  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);

  NbufQue->RefCnt--;

  if (NbufQue->RefCnt == 0) {
    NetbufQueFlush (NbufQue);
    FreePool (NbufQue);
  }
}


/**
  Append a net buffer to the net buffer queue.

  @param[in, out]  NbufQue            Pointer to the net buffer queue.
  @param[in, out]  Nbuf               Pointer to the net buffer to be appended.

**/
VOID
EFIAPI
NetbufQueAppend (
  IN OUT NET_BUF_QUEUE          *NbufQue,
  IN OUT NET_BUF                *Nbuf
  )
{
  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);
  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  InsertTailList (&NbufQue->BufList, &Nbuf->List);

  NbufQue->BufSize += Nbuf->TotalSize;
  NbufQue->BufNum++;
}


/**
  Remove a net buffer from the head in the specific queue and return it.

  @param[in, out]  NbufQue               Pointer to the net buffer queue.

  @return           Pointer to the net buffer removed from the specific queue,
                    or NULL if there is no net buffer in the specific queue.

**/
NET_BUF  *
EFIAPI
NetbufQueRemove (
  IN OUT NET_BUF_QUEUE          *NbufQue
  )
{
  NET_BUF                   *First;

  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);

  if (NbufQue->BufNum == 0) {
    return NULL;
  }

  First = NET_LIST_USER_STRUCT (NbufQue->BufList.ForwardLink, NET_BUF, List);

  NetListRemoveHead (&NbufQue->BufList);

  NbufQue->BufSize -= First->TotalSize;
  NbufQue->BufNum--;
  return First;
}


/**
  Copy Len bytes of data from the net buffer queue at the specific offset to the
  destination memory.

  The copying operation is the same as NetbufCopy but applies to the net buffer
  queue instead of the net buffer.

  @param[in]   NbufQue         Pointer to the net buffer queue.
  @param[in]   Offset          The sequence number of the first byte to copy.
  @param[in]   Len             Length of the data to copy.
  @param[out]  Dest            The destination of the data to copy to.

  @return       The length of the actual copied data, or 0 if the offset
                specified exceeds the total size of net buffer queue.

**/
UINT32
EFIAPI
NetbufQueCopy (
  IN NET_BUF_QUEUE          *NbufQue,
  IN UINT32                 Offset,
  IN UINT32                 Len,
  OUT UINT8                 *Dest
  )
{
  LIST_ENTRY                *Entry;
  NET_BUF                   *Nbuf;
  UINT32                    Skip;
  UINT32                    Left;
  UINT32                    Cur;
  UINT32                    Copied;

  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);
  ASSERT (Dest != NULL);

  if ((Len == 0) || (NbufQue->BufSize <= Offset)) {
    return 0;
  }

  if (NbufQue->BufSize - Offset < Len) {
    Len = NbufQue->BufSize - Offset;
  }

  //
  // skip to the Offset
  //
  Cur   = 0;
  Nbuf  = NULL;

  NET_LIST_FOR_EACH (Entry, &NbufQue->BufList) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);

    if (Offset < Cur + Nbuf->TotalSize) {
      break;
    }

    Cur += Nbuf->TotalSize;
  }

  ASSERT (Nbuf != NULL);

  //
  // Copy the data in the first buffer.
  //
  Skip  = Offset - Cur;
  Left  = Nbuf->TotalSize - Skip;

  if (Len < Left) {
    return NetbufCopy (Nbuf, Skip, Len, Dest);
  }

  NetbufCopy (Nbuf, Skip, Left, Dest);
  Dest  += Left;
  Len   -= Left;
  Copied = Left;

  //
  // Iterate over the others
  //
  Entry = Entry->ForwardLink;

  while ((Len > 0) && (Entry != &NbufQue->BufList)) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);

    if (Len > Nbuf->TotalSize) {
      Len -= Nbuf->TotalSize;
      Copied += Nbuf->TotalSize;

      NetbufCopy (Nbuf, 0, Nbuf->TotalSize, Dest);
      Dest += Nbuf->TotalSize;

    } else {
      NetbufCopy (Nbuf, 0, Len, Dest);
      Copied += Len;
      break;
    }

    Entry = Entry->ForwardLink;
  }

  return Copied;
}


/**
  Trim Len bytes of data from the buffer queue and free any net buffer
  that is completely trimmed.

  The trimming operation is the same as NetbufTrim but applies to the net buffer
  queue instead of the net buffer.

  @param[in, out]  NbufQue               Pointer to the net buffer queue.
  @param[in]       Len                   Length of the data to trim.

  @return   The actual length of the data trimmed.

**/
UINT32
EFIAPI
NetbufQueTrim (
  IN OUT NET_BUF_QUEUE      *NbufQue,
  IN UINT32                 Len
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  NET_BUF                   *Nbuf;
  UINT32                    Trimmed;

  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);

  if (Len == 0) {
    return 0;
  }

  if (Len > NbufQue->BufSize) {
    Len = NbufQue->BufSize;
  }

  NbufQue->BufSize -= Len;
  Trimmed = 0;

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &NbufQue->BufList) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);

    if (Len >= Nbuf->TotalSize) {
      Trimmed += Nbuf->TotalSize;
      Len -= Nbuf->TotalSize;

      RemoveEntryList (Entry);
      NetbufFree (Nbuf);

      NbufQue->BufNum--;

      if (Len == 0) {
        break;
      }

    } else {
      Trimmed += NetbufTrim (Nbuf, Len, NET_BUF_HEAD);
      break;
    }
  }

  return Trimmed;
}


/**
  Flush the net buffer queue.

  @param[in, out]  NbufQue               Pointer to the queue to be flushed.

**/
VOID
EFIAPI
NetbufQueFlush (
  IN OUT NET_BUF_QUEUE          *NbufQue
  )
{
  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);

  NetbufFreeList (&NbufQue->BufList);

  NbufQue->BufNum   = 0;
  NbufQue->BufSize  = 0;
}


/**
  Compute the checksum for a bulk of data.

  @param[in]   Bulk                  Pointer to the data.
  @param[in]   Len                   Length of the data, in bytes.

  @return    The computed checksum.

**/
UINT16
EFIAPI
NetblockChecksum (
  IN UINT8                  *Bulk,
  IN UINT32                 Len
  )
{
  register UINT32           Sum;

  Sum = 0;

  //
  // Add left-over byte, if any
  //
  if (Len % 2 != 0) {
    Sum += *(Bulk + Len - 1);
  }

  while (Len > 1) {
    Sum += *(UINT16 *) Bulk;
    Bulk += 2;
    Len -= 2;
  }

  //
  // Fold 32-bit sum to 16 bits
  //
  while ((Sum >> 16) != 0) {
    Sum = (Sum & 0xffff) + (Sum >> 16);

  }

  return (UINT16) Sum;
}


/**
  Add two checksums.

  @param[in]   Checksum1             The first checksum to be added.
  @param[in]   Checksum2             The second checksum to be added.

  @return         The new checksum.

**/
UINT16
EFIAPI
NetAddChecksum (
  IN UINT16                 Checksum1,
  IN UINT16                 Checksum2
  )
{
  UINT32                    Sum;

  Sum = Checksum1 + Checksum2;

  //
  // two UINT16 can only add up to a carry of 1.
  //
  if ((Sum >> 16) != 0) {
    Sum = (Sum & 0xffff) + 1;

  }

  return (UINT16) Sum;
}


/**
  Compute the checksum for a NET_BUF.

  @param[in]   Nbuf                  Pointer to the net buffer.

  @return    The computed checksum.

**/
UINT16
EFIAPI
NetbufChecksum (
  IN NET_BUF                *Nbuf
  )
{
  NET_BLOCK_OP              *BlockOp;
  UINT32                    Offset;
  UINT16                    TotalSum;
  UINT16                    BlockSum;
  UINT32                    Index;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  TotalSum  = 0;
  Offset    = 0;
  BlockOp   = Nbuf->BlockOp;

  for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
    if (BlockOp[Index].Size == 0) {
      continue;
    }

    BlockSum = NetblockChecksum (BlockOp[Index].Head, BlockOp[Index].Size);

    if ((Offset & 0x01) != 0) {
      //
      // The checksum starts with an odd byte, swap
      // the checksum before added to total checksum
      //
      BlockSum = SwapBytes16 (BlockSum);
    }

    TotalSum = NetAddChecksum (BlockSum, TotalSum);
    Offset  += BlockOp[Index].Size;
  }

  return TotalSum;
}


/**
  Compute the checksum for TCP/UDP pseudo header.

  Src and Dst are in network byte order, and Len is in host byte order.

  @param[in]   Src                   The source address of the packet.
  @param[in]   Dst                   The destination address of the packet.
  @param[in]   Proto                 The protocol type of the packet.
  @param[in]   Len                   The length of the packet.

  @return   The computed checksum.

**/
UINT16
EFIAPI
NetPseudoHeadChecksum (
  IN IP4_ADDR               Src,
  IN IP4_ADDR               Dst,
  IN UINT8                  Proto,
  IN UINT16                 Len
  )
{
  NET_PSEUDO_HDR            Hdr;

  //
  // Zero the memory to relieve align problems
  //
  ZeroMem (&Hdr, sizeof (Hdr));

  Hdr.SrcIp     = Src;
  Hdr.DstIp     = Dst;
  Hdr.Protocol  = Proto;
  Hdr.Len       = HTONS (Len);

  return NetblockChecksum ((UINT8 *) &Hdr, sizeof (Hdr));
}

/**
  Compute the checksum for TCP6/UDP6 pseudo header.

  Src and Dst are in network byte order, and Len is in host byte order.

  @param[in]   Src                   The source address of the packet.
  @param[in]   Dst                   The destination address of the packet.
  @param[in]   NextHeader            The protocol type of the packet.
  @param[in]   Len                   The length of the packet.

  @return   The computed checksum.

**/
UINT16
EFIAPI
NetIp6PseudoHeadChecksum (
  IN EFI_IPv6_ADDRESS       *Src,
  IN EFI_IPv6_ADDRESS       *Dst,
  IN UINT8                  NextHeader,
  IN UINT32                 Len
  )
{
  NET_IP6_PSEUDO_HDR        Hdr;

  //
  // Zero the memory to relieve align problems
  //
  ZeroMem (&Hdr, sizeof (Hdr));

  IP6_COPY_ADDRESS (&Hdr.SrcIp, Src);
  IP6_COPY_ADDRESS (&Hdr.DstIp, Dst);

  Hdr.NextHeader = NextHeader;
  Hdr.Len        = HTONL (Len);

  return NetblockChecksum ((UINT8 *) &Hdr, sizeof (Hdr));
}

/**
  The function frees the net buffer which allocated by the IP protocol. It releases 
  only the net buffer and doesn't call the external free function. 

  This function should be called after finishing the process of mIpSec->ProcessExt() 
  for outbound traffic. The (EFI_IPSEC2_PROTOCOL)->ProcessExt() allocates a new 
  buffer for the ESP, so there needs a function to free the old net buffer.

  @param[in]  Nbuf       The network buffer to be freed.

**/
VOID
NetIpSecNetbufFree (
  NET_BUF   *Nbuf
  )
{
  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  ASSERT (Nbuf->RefCnt > 0);

  Nbuf->RefCnt--;

  if (Nbuf->RefCnt == 0) {
    
    //
    // Update Vector only when NBuf is to be released. That is,
    // all the sharing of Nbuf increse Vector's RefCnt by one
    //
    NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);
    ASSERT (Nbuf->Vector->RefCnt > 0);

    Nbuf->Vector->RefCnt--;

    if (Nbuf->Vector->RefCnt > 0) {
      return;
    }

    //
    // If NET_VECTOR_OWN_FIRST is set, release the first block since it is 
    // allocated by us
    //
    if ((Nbuf->Vector->Flag & NET_VECTOR_OWN_FIRST) != 0) {
      FreePool (Nbuf->Vector->Block[0].Bulk);
    }
    FreePool (Nbuf->Vector);
    FreePool (Nbuf); 
  } 
}

