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
- // 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
break;\r
\r
default:\r
- Ip4Demultiplex (IpSb, Head, Packet);\r
+ Ip4Demultiplex (IpSb, Head, Packet, Option, OptionLen);\r
}\r
\r
Packet = NULL;\r
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
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
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
\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
-\r
- RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN;\r
- RxData->Options = NULL;\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
- 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
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
//\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
- ASSERT (Head != NULL);\r
- \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
+ 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
+ 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
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
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
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
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
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
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