]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4Dxe / Ip4Input.c
index be87ec5d9835496eaf3fe364d43ed43794a13cbf..24c5846588031b0e0a43f7d13708973e98a63632 100644 (file)
@@ -1,14 +1,10 @@
 /** @file\r
   IP4 input process.\r
-  \r
-Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
 \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -292,7 +288,7 @@ Ip4Reassemble (
   // check whether THIS.Start < PREV.End for overlap. If two fragments\r
   // overlaps, trim the overlapped part off THIS fragment.\r
   //\r
-  if ((Cur != Head) && ((Prev = Cur->BackLink) != Head)) {\r
+  if ((Prev = Cur->BackLink) != Head) {\r
     Fragment  = NET_LIST_USER_STRUCT (Prev, NET_BUF, List);\r
     Node      = IP4_GET_CLIP_INFO (Fragment);\r
 \r
@@ -419,7 +415,15 @@ Ip4Reassemble (
     }\r
 \r
     NewPacket->Ip.Ip4 = Assemble->Head;\r
-    CopyMem (IP4_GET_CLIP_INFO (NewPacket), Assemble->Info, sizeof (*IP4_GET_CLIP_INFO (NewPacket)));\r
+\r
+    ASSERT (Assemble->Info != NULL);\r
+\r
+    CopyMem (\r
+      IP4_GET_CLIP_INFO (NewPacket),\r
+      Assemble->Info,\r
+      sizeof (*IP4_GET_CLIP_INFO (NewPacket))\r
+      );\r
+\r
     return NewPacket;\r
   }\r
 \r
@@ -431,8 +435,8 @@ DROP:
 }\r
 \r
 /**\r
-  The callback function for the net buffer which wraps the packet processed by \r
-  IPsec. It releases the wrap packet and also signals IPsec to free the resources. \r
+  The callback function for the net buffer which wraps the packet processed by\r
+  IPsec. It releases the wrap packet and also signals IPsec to free the resources.\r
 \r
   @param[in]  Arg       The wrap context\r
 \r
@@ -459,25 +463,25 @@ Ip4IpSecFree (
 }\r
 \r
 /**\r
-  The work function to locate IPsec protocol to process the inbound or \r
+  The work function to locate IPsec protocol to process the inbound or\r
   outbound IP packets. The process routine handls the packet with following\r
-  actions: bypass the packet, discard the packet, or protect the packet.       \r
+  actions: bypass the packet, discard the packet, or protect the packet.\r
 \r
   @param[in]       IpSb          The IP4 service instance.\r
   @param[in, out]  Head          The The caller supplied IP4 header.\r
   @param[in, out]  Netbuf        The IP4 packet to be processed by IPsec.\r
   @param[in, out]  Options       The caller supplied options.\r
   @param[in, out]  OptionsLen    The length of the option.\r
-  @param[in]       Direction     The directionality in an SPD entry, \r
+  @param[in]       Direction     The directionality in an SPD entry,\r
                                  EfiIPsecInBound or EfiIPsecOutBound.\r
   @param[in]       Context       The token's wrap.\r
 \r
   @retval EFI_SUCCESS            The IPsec protocol is not available or disabled.\r
   @retval EFI_SUCCESS            The packet was bypassed and all buffers remain the same.\r
   @retval EFI_SUCCESS            The packet was protected.\r
-  @retval EFI_ACCESS_DENIED      The packet was discarded.  \r
+  @retval EFI_ACCESS_DENIED      The packet was discarded.\r
   @retval EFI_OUT_OF_RESOURCES   There is no suffcient resource to complete the operation.\r
-  @retval EFI_BUFFER_TOO_SMALL   The number of non-empty block is bigger than the \r
+  @retval EFI_BUFFER_TOO_SMALL   The number of non-empty block is bigger than the\r
                                  number of input data blocks when build a fragment table.\r
 \r
 **/\r
@@ -504,21 +508,20 @@ Ip4IpSecProcessPacket (
   IP4_HEAD                  ZeroHead;\r
 \r
   Status        = EFI_SUCCESS;\r
+\r
+  if (!mIpSec2Installed) {\r
+    goto ON_EXIT;\r
+  }\r
+  ASSERT (mIpSec != NULL);\r
+\r
   Packet        = *Netbuf;\r
   RecycleEvent  = NULL;\r
   IpSecWrap     = NULL;\r
   FragmentTable = NULL;\r
-  TxWrap        = (IP4_TXTOKEN_WRAP *) Context; \r
+  TxWrap        = (IP4_TXTOKEN_WRAP *) Context;\r
   FragmentCount = Packet->BlockOpNum;\r
 \r
   ZeroMem (&ZeroHead, sizeof (IP4_HEAD));\r
-  \r
-  if (mIpSec == NULL) {\r
-    gBS->LocateProtocol (&gEfiIpSecProtocolGuid, NULL, (VOID **) &mIpSec);\r
-    if (mIpSec == NULL) {\r
-      goto ON_EXIT;\r
-    }\r
-  }\r
 \r
   //\r
   // Check whether the IPsec enable variable is set.\r
@@ -526,14 +529,14 @@ Ip4IpSecProcessPacket (
   if (mIpSec->DisabledFlag) {\r
     //\r
     // If IPsec is disabled, restore the original MTU\r
-    //   \r
+    //\r
     IpSb->MaxPacketSize = IpSb->OldMaxPacketSize;\r
     goto ON_EXIT;\r
   } else {\r
     //\r
-    // If IPsec is enabled, use the MTU which reduce the IPsec header length.  \r
+    // If IPsec is enabled, use the MTU which reduce the IPsec header length.\r
     //\r
-    IpSb->MaxPacketSize = IpSb->OldMaxPacketSize - IP4_MAX_IPSEC_HEADLEN;   \r
+    IpSb->MaxPacketSize = IpSb->OldMaxPacketSize - IP4_MAX_IPSEC_HEADLEN;\r
   }\r
 \r
   //\r
@@ -545,9 +548,9 @@ Ip4IpSecProcessPacket (
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ON_EXIT;\r
   }\r
\r
+\r
   Status = NetbufBuildExt (Packet, FragmentTable, &FragmentCount);\r
-  \r
+\r
   //\r
   // Record the original FragmentTable and count.\r
   //\r
@@ -563,14 +566,14 @@ Ip4IpSecProcessPacket (
   // Convert host byte order to network byte order\r
   //\r
   Ip4NtohHead (*Head);\r
-  \r
+\r
   Status = mIpSec->ProcessExt (\r
                      mIpSec,\r
                      IpSb->Controller,\r
                      IP_VERSION_4,\r
                      (VOID *) (*Head),\r
                      &(*Head)->Protocol,\r
-                     (VOID **)Options,\r
+                     (VOID **) Options,\r
                      OptionsLen,\r
                      (EFI_IPSEC_FRAGMENT_DATA **) (&FragmentTable),\r
                      &FragmentCount,\r
@@ -581,17 +584,27 @@ Ip4IpSecProcessPacket (
   // Convert back to host byte order\r
   //\r
   Ip4NtohHead (*Head);\r
-  \r
+\r
   if (EFI_ERROR (Status)) {\r
+    FreePool (OriginalFragmentTable);\r
     goto ON_EXIT;\r
   }\r
 \r
   if (OriginalFragmentTable == FragmentTable && OriginalFragmentCount == FragmentCount) {\r
+    //\r
+    // For ByPass Packet\r
+    //\r
+    FreePool (FragmentTable);\r
     goto ON_EXIT;\r
+  } else {\r
+    //\r
+    // Free the FragmentTable which allocated before calling the IPsec.\r
+    //\r
+    FreePool (OriginalFragmentTable);\r
   }\r
 \r
   if (Direction == EfiIPsecOutBound && TxWrap != NULL) {\r
-  \r
+\r
     TxWrap->IpSecRecycleSignal = RecycleEvent;\r
     TxWrap->Packet             = NetbufFromExt (\r
                                    FragmentTable,\r
@@ -602,6 +615,11 @@ Ip4IpSecProcessPacket (
                                    TxWrap\r
                                    );\r
     if (TxWrap->Packet == NULL) {\r
+      //\r
+      // Recover the TxWrap->Packet, if meet a error, and the caller will free\r
+      // the TxWrap.\r
+      //\r
+      TxWrap->Packet = *Netbuf;\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto ON_EXIT;\r
     }\r
@@ -611,27 +629,32 @@ Ip4IpSecProcessPacket (
     //\r
     NetIpSecNetbufFree (*Netbuf);\r
     *Netbuf = TxWrap->Packet;\r
-    \r
+\r
   } else {\r
-  \r
+\r
     IpSecWrap = AllocateZeroPool (sizeof (IP4_IPSEC_WRAP));\r
-  \r
+\r
     if (IpSecWrap == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      gBS->SignalEvent (RecycleEvent);\r
       goto ON_EXIT;\r
     }\r
-    \r
+\r
     IpSecWrap->IpSecRecycleSignal = RecycleEvent;\r
     IpSecWrap->Packet             = Packet;\r
     Packet                        = NetbufFromExt (\r
-                                      FragmentTable, \r
-                                      FragmentCount, \r
-                                      IP4_MAX_HEADLEN, \r
-                                      0, \r
-                                      Ip4IpSecFree, \r
+                                      FragmentTable,\r
+                                      FragmentCount,\r
+                                      IP4_MAX_HEADLEN,\r
+                                      0,\r
+                                      Ip4IpSecFree,\r
                                       IpSecWrap\r
                                       );\r
-  \r
+\r
     if (Packet == NULL) {\r
+      Packet = IpSecWrap->Packet;\r
+      gBS->SignalEvent (RecycleEvent);\r
+      FreePool (IpSecWrap);\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto ON_EXIT;\r
     }\r
@@ -657,7 +680,7 @@ ON_EXIT:
 /**\r
   Pre-process the IPv4 packet. First validates the IPv4 packet, and\r
   then reassembles packet if it is necessary.\r
-  \r
+\r
   @param[in]       IpSb            Pointer to IP4_SERVICE.\r
   @param[in, out]  Packet          Pointer to the Packet to be processed.\r
   @param[in]       Head            Pointer to the IP4_HEAD.\r
@@ -667,7 +690,7 @@ ON_EXIT:
                                    as multicast.\r
 \r
   @retval     EFI_SEUCCESS               The recieved packet is in well form.\r
-  @retval     EFI_INVAILD_PARAMETER      The recieved packet is malformed.  \r
+  @retval     EFI_INVAILD_PARAMETER      The recieved packet is malformed.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -676,9 +699,9 @@ Ip4PreProcessPacket (
   IN OUT NET_BUF        **Packet,\r
   IN     IP4_HEAD       *Head,\r
   IN     UINT8          *Option,\r
-  IN     UINT32         OptionLen, \r
+  IN     UINT32         OptionLen,\r
   IN     UINT32         Flag\r
-  ) \r
+  )\r
 {\r
   IP4_CLIP_INFO             *Info;\r
   UINT32                    HeadLen;\r
@@ -686,12 +709,12 @@ Ip4PreProcessPacket (
   UINT16                    Checksum;\r
 \r
   //\r
-  // Check that the IP4 header is correctly formatted\r
+  // Check if the IP4 header is correctly formatted.\r
   //\r
   if ((*Packet)->TotalSize < IP4_MIN_HEADLEN) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   HeadLen  = (Head->HeadLen << 2);\r
   TotalLen = NTOHS (Head->TotalLen);\r
 \r
@@ -740,13 +763,13 @@ Ip4PreProcessPacket (
   // Validate the options. Don't call the Ip4OptionIsValid if\r
   // there is no option to save some CPU process.\r
   //\r
-  \r
+\r
   if ((OptionLen > 0) && !Ip4OptionIsValid (Option, OptionLen, TRUE)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
-  // Trim the head off, after this point, the packet is headless.\r
+  // Trim the head off, after this point, the packet is headless,\r
   // and Packet->TotalLen == Info->Length.\r
   //\r
   NetbufTrim (*Packet, HeadLen, TRUE);\r
@@ -781,7 +804,7 @@ Ip4PreProcessPacket (
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -813,15 +836,16 @@ Ip4AccpetFrame (
   IP4_HEAD                  ZeroHead;\r
   UINT8                     *Option;\r
   UINT32                    OptionLen;\r
-  \r
+\r
   IpSb   = (IP4_SERVICE *) Context;\r
   Option = NULL;\r
 \r
-  if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTORY)) {\r
+  if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTROY)) {\r
     goto DROP;\r
   }\r
 \r
-  Head      = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL); \r
+  Head      = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL);\r
+  ASSERT (Head != NULL);\r
   OptionLen = (Head->HeadLen << 2) - IP4_MIN_HEADLEN;\r
   if (OptionLen > 0) {\r
     Option = (UINT8 *) (Head + 1);\r
@@ -831,11 +855,11 @@ Ip4AccpetFrame (
   // Validate packet format and reassemble packet if it is necessary.\r
   //\r
   Status = Ip4PreProcessPacket (\r
-             IpSb, \r
-             &Packet, \r
-             Head, \r
+             IpSb,\r
+             &Packet,\r
+             Head,\r
              Option,\r
-             OptionLen,  \r
+             OptionLen,\r
              Flag\r
              );\r
 \r
@@ -848,11 +872,11 @@ Ip4AccpetFrame (
   // and no need consider any other ahead ext headers.\r
   //\r
   Status = Ip4IpSecProcessPacket (\r
-             IpSb, \r
-             &Head, \r
-             &Packet, \r
+             IpSb,\r
+             &Head,\r
+             &Packet,\r
              &Option,\r
-             &OptionLen, \r
+             &OptionLen,\r
              EfiIPsecInBound,\r
              NULL\r
              );\r
@@ -860,7 +884,7 @@ Ip4AccpetFrame (
   if (EFI_ERROR (Status)) {\r
     goto RESTART;\r
   }\r
-  \r
+\r
   //\r
   // If the packet is protected by tunnel mode, parse the inner Ip Packet.\r
   //\r
@@ -871,18 +895,21 @@ Ip4AccpetFrame (
   // is transfered to the packet process logic.\r
   //\r
     Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL);\r
+    ASSERT (Head != NULL);\r
     Status = Ip4PreProcessPacket (\r
-               IpSb, \r
-               &Packet, \r
-               Head, \r
+               IpSb,\r
+               &Packet,\r
+               Head,\r
                Option,\r
-               OptionLen,  \r
+               OptionLen,\r
                Flag\r
                );\r
     if (EFI_ERROR (Status)) {\r
       goto RESTART;\r
     }\r
   }\r
+\r
+  ASSERT (Packet != NULL);\r
   Head  = Packet->Ip.Ip4;\r
   IP4_GET_CLIP_INFO (Packet)->Status = EFI_SUCCESS;\r
 \r
@@ -896,7 +923,7 @@ Ip4AccpetFrame (
     break;\r
 \r
   default:\r
-    Ip4Demultiplex (IpSb, Head, Packet);\r
+    Ip4Demultiplex (IpSb, Head, Packet, Option, OptionLen);\r
   }\r
 \r
   Packet = NULL;\r
@@ -1119,8 +1146,8 @@ Ip4OnRecyclePacket (
   to the upper layer. Upper layer will signal the recycle event in\r
   it when it is done with the packet.\r
 \r
-  @param[in]  IpInstance             The IP4 child to receive the packet\r
-  @param[in]  Packet                 The packet to deliver up.\r
+  @param[in]  IpInstance    The IP4 child to receive the packet.\r
+  @param[in]  Packet        The packet to deliver up.\r
 \r
   @retval Wrap              if warp the packet succeed.\r
   @retval NULL              failed to wrap the packet .\r
@@ -1135,6 +1162,7 @@ Ip4WrapRxData (
   IP4_RXDATA_WRAP           *Wrap;\r
   EFI_IP4_RECEIVE_DATA      *RxData;\r
   EFI_STATUS                Status;\r
+  BOOLEAN                   RawData;\r
 \r
   Wrap = AllocatePool (IP4_RXDATA_WRAP_SIZE (Packet->BlockOpNum));\r
 \r
@@ -1148,7 +1176,7 @@ Ip4WrapRxData (
   Wrap->Packet      = Packet;\r
   RxData            = &Wrap->RxData;\r
 \r
-  ZeroMem (&RxData->TimeStamp, sizeof (EFI_TIME));\r
+  ZeroMem (RxData, sizeof (EFI_IP4_RECEIVE_DATA));\r
 \r
   Status = gBS->CreateEvent (\r
                   EVT_NOTIFY_SIGNAL,\r
@@ -1165,17 +1193,21 @@ Ip4WrapRxData (
 \r
   ASSERT (Packet->Ip.Ip4 != NULL);\r
 \r
+  ASSERT (IpInstance != NULL);\r
+  RawData = IpInstance->ConfigData.RawData;\r
+\r
   //\r
   // The application expects a network byte order header.\r
   //\r
-  RxData->HeaderLength  = (Packet->Ip.Ip4->HeadLen << 2);\r
-  RxData->Header        = (EFI_IP4_HEADER *) Ip4NtohHead (Packet->Ip.Ip4);\r
+  if (!RawData) {\r
+    RxData->HeaderLength  = (Packet->Ip.Ip4->HeadLen << 2);\r
+    RxData->Header        = (EFI_IP4_HEADER *) Ip4NtohHead (Packet->Ip.Ip4);\r
+    RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN;\r
+    RxData->Options       = NULL;\r
 \r
-  RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN;\r
-  RxData->Options       = NULL;\r
-\r
-  if (RxData->OptionsLength != 0) {\r
-    RxData->Options = (VOID *) (RxData->Header + 1);\r
+    if (RxData->OptionsLength != 0) {\r
+      RxData->Options = (VOID *) (RxData->Header + 1);\r
+    }\r
   }\r
 \r
   RxData->DataLength  = Packet->TotalSize;\r
@@ -1214,6 +1246,7 @@ Ip4InstanceDeliverPacket (
   NET_BUF                   *Packet;\r
   NET_BUF                   *Dup;\r
   UINT8                     *Head;\r
+  UINT32                    HeadLen;\r
 \r
   //\r
   // Deliver a packet if there are both a packet and a receive token.\r
@@ -1239,22 +1272,32 @@ Ip4InstanceDeliverPacket (
       //\r
       // Create a duplicated packet if this packet is shared\r
       //\r
-      Dup = NetbufDuplicate (Packet, NULL, IP4_MAX_HEADLEN);\r
+      if (IpInstance->ConfigData.RawData) {\r
+        HeadLen = 0;\r
+      } else {\r
+        HeadLen = IP4_MAX_HEADLEN;\r
+      }\r
+\r
+      Dup = NetbufDuplicate (Packet, NULL, HeadLen);\r
 \r
       if (Dup == NULL) {\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
 \r
-      //\r
-      // Copy the IP head over. The packet to deliver up is\r
-      // headless. Trim the head off after copy. The IP head\r
-      // may be not continuous before the data.\r
-      //\r
-      Head    = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD);\r
-      Dup->Ip.Ip4 = (IP4_HEAD *) Head;\r
+      if (!IpInstance->ConfigData.RawData) {\r
+        //\r
+        // Copy the IP head over. The packet to deliver up is\r
+        // headless. Trim the head off after copy. The IP head\r
+        // may be not continuous before the data.\r
+        //\r
+        Head = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD);\r
+        ASSERT (Head != NULL);\r
 \r
-      CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2);\r
-      NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE);\r
+        Dup->Ip.Ip4 = (IP4_HEAD *) Head;\r
+\r
+        CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2);\r
+        NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE);\r
+      }\r
 \r
       Wrap = Ip4WrapRxData (IpInstance, Dup);\r
 \r
@@ -1292,10 +1335,12 @@ Ip4InstanceDeliverPacket (
   Enqueue a received packet to all the IP children that share\r
   the same interface.\r
 \r
-  @param[in]  IpSb                   The IP4 service instance that receive the packet\r
-  @param[in]  Head                   The header of the received packet\r
-  @param[in]  Packet                 The data of the received packet\r
-  @param[in]  IpIf                   The interface to enqueue the packet to\r
+  @param[in]  IpSb               The IP4 service instance that receive the packet.\r
+  @param[in]  Head               The header of the received packet.\r
+  @param[in]  Packet             The data of the received packet.\r
+  @param[in]  Option             Point to the IP4 packet header options.\r
+  @param[in]  OptionLen          Length of the IP4 packet header options.\r
+  @param[in]  IpIf               The interface to enqueue the packet to.\r
 \r
   @return The number of the IP4 children that accepts the packet\r
 \r
@@ -1305,6 +1350,8 @@ Ip4InterfaceEnquePacket (
   IN IP4_SERVICE            *IpSb,\r
   IN IP4_HEAD               *Head,\r
   IN NET_BUF                *Packet,\r
+  IN UINT8                  *Option,\r
+  IN UINT32                 OptionLen,\r
   IN IP4_INTERFACE          *IpIf\r
   )\r
 {\r
@@ -1370,6 +1417,13 @@ Ip4InterfaceEnquePacket (
     IpInstance = NET_LIST_USER_STRUCT (Entry, IP4_PROTOCOL, AddrLink);\r
     NET_CHECK_SIGNATURE (IpInstance, IP4_PROTOCOL_SIGNATURE);\r
 \r
+    //\r
+    // In RawData mode, add IPv4 headers and options back to packet.\r
+    //\r
+    if ((IpInstance->ConfigData.RawData) && (Option != NULL) && (OptionLen != 0)){\r
+      Ip4PrependHead (Packet, Head, Option, OptionLen);\r
+    }\r
+\r
     if (Ip4InstanceEnquePacket (IpInstance, Head, Packet) == EFI_SUCCESS) {\r
       Enqueued++;\r
     }\r
@@ -1416,11 +1470,13 @@ Ip4InterfaceDeliverPacket (
   child wants to consume the packet because each IP child needs\r
   its own copy of the packet to make changes.\r
 \r
-  @param[in]  IpSb                   The IP4 service instance that received the packet\r
-  @param[in]  Head                   The header of the received packet\r
-  @param[in]  Packet                 The data of the received packet\r
+  @param[in]  IpSb               The IP4 service instance that received the packet.\r
+  @param[in]  Head               The header of the received packet.\r
+  @param[in]  Packet             The data of the received packet.\r
+  @param[in]  Option             Point to the IP4 packet header options.\r
+  @param[in]  OptionLen          Length of the IP4 packet header options.\r
 \r
-  @retval EFI_NOT_FOUND          No IP child accepts the packet\r
+  @retval EFI_NOT_FOUND          No IP child accepts the packet.\r
   @retval EFI_SUCCESS            The packet is enqueued or delivered to some IP\r
                                  children.\r
 \r
@@ -1429,7 +1485,9 @@ EFI_STATUS
 Ip4Demultiplex (\r
   IN IP4_SERVICE            *IpSb,\r
   IN IP4_HEAD               *Head,\r
-  IN NET_BUF                *Packet\r
+  IN NET_BUF                *Packet,\r
+  IN UINT8                  *Option,\r
+  IN UINT32                 OptionLen\r
   )\r
 {\r
   LIST_ENTRY                *Entry;\r
@@ -1446,7 +1504,14 @@ Ip4Demultiplex (
     IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);\r
 \r
     if (IpIf->Configured) {\r
-      Enqueued += Ip4InterfaceEnquePacket (IpSb, Head, Packet, IpIf);\r
+      Enqueued += Ip4InterfaceEnquePacket (\r
+                    IpSb,\r
+                    Head,\r
+                    Packet,\r
+                    Option,\r
+                    OptionLen,\r
+                    IpIf\r
+                    );\r
     }\r
   }\r
 \r