summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/Network/Ip4Dxe
diff options
context:
space:
mode:
authorsfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>2012-12-13 06:47:06 +0000
committersfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>2012-12-13 06:47:06 +0000
commit216f79703b8cb8dc65abdd768bedb2bcdbc1a1f8 (patch)
tree847cafec4185c79f082ccb9a5e895062a06980c1 /MdeModulePkg/Universal/Network/Ip4Dxe
parent906e1cb7f7f178f5cb2a3bebbac59f6aa8c273a4 (diff)
1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support.
2. Fix the driver binding Stop() hang issue in the network stack. 3. Add Ip4 raw data support. 4. Add iSCSI Dhcp option 60 support. Signed-off-by: Fu Siyuan <siyuan.fu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> Reviewed-by: Ouyang Qian <qian.ouyang@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13995 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal/Network/Ip4Dxe')
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c126
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h5
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c163
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h9
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c6
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c208
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h2
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c108
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h28
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c29
10 files changed, 483 insertions, 201 deletions
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c b/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c
index d3fcf048f..2ccfb3cc1 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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<BR>
@@ -173,6 +173,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIp4DriverNameTable[] = {
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gIp4ControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -231,6 +233,74 @@ Ip4ComponentNameGetDriverName (
}
/**
+ Update the component name for the IP4 child handle.
+
+ @param Ip4[in] A pointer to the EFI_IP4_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_IP4_PROTOCOL *Ip4
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[80];
+ EFI_IP4_MODE_DATA Ip4ModeData;
+
+ if (Ip4 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer as:
+ // IPv4 (SrcIP=127.0.0.1, DestIP=127.0.0.1)
+ //
+ Status = Ip4->GetModeData (Ip4, &Ip4ModeData, NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (!Ip4ModeData.IsStarted || !Ip4ModeData.IsConfigured) {
+ UnicodeSPrint (HandleName, sizeof (HandleName), L"IPv4 (Not started)");
+ } else {
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"IPv4 (SrcIP=%d.%d.%d.%d)",
+ Ip4ModeData.ConfigData.StationAddress.Addr[0],
+ Ip4ModeData.ConfigData.StationAddress.Addr[1],
+ Ip4ModeData.ConfigData.StationAddress.Addr[2],
+ Ip4ModeData.ConfigData.StationAddress.Addr[3]
+ );
+ }
+
+ if (gIp4ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gIp4ControllerNameTable);
+ gIp4ControllerNameTable = NULL;
+ }
+ Status = AddUnicodeString2 (
+ "eng",
+ gIp4ComponentName.SupportedLanguages,
+ &gIp4ControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gIp4ComponentName2.SupportedLanguages,
+ &gIp4ControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@@ -308,5 +378,57 @@ Ip4ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_IP4_PROTOCOL *Ip4;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiManagedNetworkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiIp4ProtocolGuid,
+ (VOID **)&Ip4,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Ip4);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gIp4ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gIp4ComponentName)
+ );
}
+
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h
index 295f82297..64049303e 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h
@@ -1,7 +1,7 @@
/** @file
Common definition for IP4.
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -63,6 +63,9 @@ typedef struct _IP4_SERVICE IP4_SERVICE;
#define IP4_FIRST_FRAGMENT(FragmentField) \
((BOOLEAN)(((FragmentField) & IP4_HEAD_OFFSET_MASK) == 0))
+#define IP4_DO_NOT_FRAGMENT(FragmentField) \
+ ((BOOLEAN)(((FragmentField) & IP4_HEAD_DF_MASK) == IP4_HEAD_DF_MASK))
+
#define IP4_IS_BROADCAST(CastType) ((CastType) >= IP4_LOCAL_BROADCAST)
///
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
index 4ce85a3f5..5a84837a4 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
@@ -176,7 +176,6 @@ Ip4CreateService (
IpSb->ServiceBinding.CreateChild = Ip4ServiceBindingCreateChild;
IpSb->ServiceBinding.DestroyChild = Ip4ServiceBindingDestroyChild;
IpSb->State = IP4_SERVICE_UNSTARTED;
- IpSb->InDestroy = FALSE;
IpSb->NumChildren = 0;
InitializeListHead (&IpSb->Children);
@@ -396,6 +395,42 @@ Ip4CleanService (
return EFI_SUCCESS;
}
+/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+Ip4DestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+)
+{
+ IP4_PROTOCOL *IpInstance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP4_PROTOCOL, Link, IP4_PROTOCOL_SIGNATURE);
+ ServiceBinding = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (IpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
+}
/**
Start this driver on ControllerHandle. This service is called by the
@@ -529,14 +564,13 @@ Ip4DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
{
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- IP4_SERVICE *IpSb;
- IP4_PROTOCOL *IpInstance;
- EFI_HANDLE NicHandle;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
- INTN State;
- BOOLEAN IsArp;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ IP4_SERVICE *IpSb;
+ EFI_HANDLE NicHandle;
+ EFI_STATUS Status;
+ INTN State;
+ LIST_ENTRY *List;
+ IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
//
// IP4 driver opens the MNP child, ARP children or the IP4_CONFIG protocol
@@ -557,7 +591,6 @@ Ip4DriverBindingStop (
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
-
if (Status == EFI_SUCCESS) {
//
// Retrieve the IP4 service binding protocol. If failed, it is
@@ -572,15 +605,11 @@ Ip4DriverBindingStop (
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
-
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding);
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
if (IpSb->Ip4Config != NULL && (IpSb->State != IP4_SERVICE_DESTROY)) {
IpSb->Ip4Config->Stop (IpSb->Ip4Config);
@@ -591,9 +620,7 @@ Ip4DriverBindingStop (
IpSb->Image,
ControllerHandle
);
-
if (EFI_ERROR (Status)) {
- gBS->RestoreTPL (OldTpl);
return Status;
}
@@ -609,7 +636,6 @@ Ip4DriverBindingStop (
gBS->CloseEvent (IpSb->ReconfigEvent);
}
- gBS->RestoreTPL (OldTpl);
return EFI_SUCCESS;
}
@@ -619,16 +645,12 @@ Ip4DriverBindingStop (
// service binding is installed on the NIC handle. So, need to open
// the protocol info to find the NIC handle.
//
- IsArp = FALSE;
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
-
if (NicHandle == NULL) {
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);
- IsArp = TRUE;
- }
-
- if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ if (NicHandle == NULL) {
+ return EFI_SUCCESS;
+ }
}
//
@@ -642,34 +664,23 @@ Ip4DriverBindingStop (
NicHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
-
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding);
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- if (IpSb->InDestroy) {
- gBS->RestoreTPL (OldTpl);
- return EFI_SUCCESS;
- }
-
- if (IsArp) {
- while (!IsListEmpty (&IpSb->Children)) {
- IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link);
-
- ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
- }
-
- if (IpSb->NumChildren != 0) {
- Status = EFI_DEVICE_ERROR;
- goto ON_ERROR;
- }
-
- IpSb->InDestroy = TRUE;
-
+ if (NumberOfChildren != 0) {
+ List = &IpSb->Children;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ Ip4DestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
+ } else if (IsListEmpty (&IpSb->Children)) {
State = IpSb->State;
IpSb->State = IP4_SERVICE_DESTROY;
@@ -682,7 +693,6 @@ Ip4DriverBindingStop (
// OK, clean other resources then uninstall the service binding protocol.
//
Status = Ip4CleanService (IpSb);
-
if (EFI_ERROR (Status)) {
IpSb->State = State;
goto ON_ERROR;
@@ -693,52 +703,15 @@ Ip4DriverBindingStop (
&gEfiIp4ServiceBindingProtocolGuid,
ServiceBinding
);
-
- FreePool (IpSb);
- } else if (NumberOfChildren == 0) {
- IpSb->InDestroy = TRUE;
-
- State = IpSb->State;
- IpSb->State = IP4_SERVICE_DESTROY;
-
- //
- // Clear the variable data.
- //
- Ip4ClearVariableData (IpSb);
-
- //
- // OK, clean other resources then uninstall the service binding protocol.
- //
- Status = Ip4CleanService (IpSb);
-
- if (EFI_ERROR (Status)) {
- IpSb->State = State;
- goto ON_ERROR;
+
+ if (gIp4ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gIp4ControllerNameTable);
+ gIp4ControllerNameTable = NULL;
}
-
- gBS->UninstallProtocolInterface (
- NicHandle,
- &gEfiIp4ServiceBindingProtocolGuid,
- ServiceBinding
- );
-
FreePool (IpSb);
- } else {
-
- while (!IsListEmpty (&IpSb->Children)) {
- IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link);
-
- ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
- }
-
- if (IpSb->NumChildren != 0) {
- Status = EFI_DEVICE_ERROR;
- }
}
ON_ERROR:
-
- gBS->RestoreTPL (OldTpl);
return Status;
}
@@ -935,6 +908,15 @@ Ip4ServiceBindingDestroyChild (
ChildHandle
);
+ if (IpInstance->Interface != NULL && IpInstance->Interface->Arp != NULL) {
+ gBS->CloseProtocol (
+ IpInstance->Interface->ArpHandle,
+ &gEfiArpProtocolGuid,
+ gIp4DriverBinding.DriverBindingHandle,
+ ChildHandle
+ );
+ }
+
//
// Uninstall the IP4 protocol first. Many thing happens during
// this:
@@ -949,12 +931,13 @@ Ip4ServiceBindingDestroyChild (
// will be called back before preceeding. If any packets not recycled,
// that means there is a resource leak.
//
+ gBS->RestoreTPL (OldTpl);
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiIp4ProtocolGuid,
&IpInstance->Ip4Proto
);
-
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h
index 96044fd0c..32984bad6 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -19,6 +19,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
extern EFI_DRIVER_BINDING_PROTOCOL gIp4DriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gIp4ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gIp4ComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gIp4ControllerNameTable;
+
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+} IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
//
// Function prototype for the driver's entry point
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c
index 18cb9ff36..e5e2b984e 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -193,7 +193,7 @@ Ip4ProcessIcmpError (
}
IP4_GET_CLIP_INFO (Packet)->Status = EFI_ICMP_ERROR;
- return Ip4Demultiplex (IpSb, Head, Packet);
+ return Ip4Demultiplex (IpSb, Head, Packet, NULL, 0);
}
@@ -308,7 +308,7 @@ Ip4ProcessIcmpQuery (
return Ip4IcmpReplyEcho (IpSb, Head, Packet);
}
- return Ip4Demultiplex (IpSb, Head, Packet);
+ return Ip4Demultiplex (IpSb, Head, Packet, NULL, 0);
}
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
index f4ce3ea02..74bf7f76e 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
@@ -868,6 +868,7 @@ Ip4ConfigProtocol (
EFI_STATUS Status;
IP4_ADDR Ip;
IP4_ADDR Netmask;
+ EFI_ARP_PROTOCOL *Arp;
IpSb = IpInstance->Service;
@@ -972,6 +973,20 @@ Ip4ConfigProtocol (
}
IpInstance->Interface = IpIf;
+ if (IpIf->Arp != NULL) {
+ Arp = NULL;
+ Status = gBS->OpenProtocol (
+ IpIf->ArpHandle,
+ &gEfiArpProtocolGuid,
+ (VOID **) &Arp,
+ gIp4DriverBinding.DriverBindingHandle,
+ IpInstance->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+ }
InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);
CopyMem (&IpInstance->ConfigData, Config, sizeof (IpInstance->ConfigData));
@@ -1028,6 +1043,14 @@ Ip4CleanProtocol (
if (IpInstance->Interface != NULL) {
RemoveEntryList (&IpInstance->AddrLink);
+ if (IpInstance->Interface->Arp != NULL) {
+ gBS->CloseProtocol (
+ IpInstance->Interface->ArpHandle,
+ &gEfiArpProtocolGuid,
+ gIp4DriverBinding.DriverBindingHandle,
+ IpInstance->Handle
+ );
+ }
Ip4FreeInterface (IpInstance->Interface, IpInstance);
IpInstance->Interface = NULL;
}
@@ -1193,14 +1216,6 @@ EfiIp4Configure (
// Validate the configuration first.
//
if (IpConfigData != NULL) {
- //
- // This implementation doesn't support RawData
- //
- if (IpConfigData->RawData) {
- Status = EFI_UNSUPPORTED;
- goto ON_EXIT;
- }
-
CopyMem (&IpAddress, &IpConfigData->StationAddress, sizeof (IP4_ADDR));
CopyMem (&SubnetMask, &IpConfigData->SubnetMask, sizeof (IP4_ADDR));
@@ -1620,22 +1635,23 @@ Ip4TokenExist (
return EFI_SUCCESS;
}
-
/**
Validate the user's token against current station address.
- @param[in] Token User's token to validate
- @param[in] IpIf The IP4 child's interface.
+ @param[in] Token User's token to validate.
+ @param[in] IpIf The IP4 child's interface.
+ @param[in] RawData Set to TRUE to send unformatted packets.
- @retval EFI_INVALID_PARAMETER Some parameters are invalid
+ @retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_BAD_BUFFER_SIZE The user's option/data is too long.
- @retval EFI_SUCCESS The token is OK
+ @retval EFI_SUCCESS The token is valid.
**/
EFI_STATUS
Ip4TxTokenValid (
IN EFI_IP4_COMPLETION_TOKEN *Token,
- IN IP4_INTERFACE *IpIf
+ IN IP4_INTERFACE *IpIf,
+ IN BOOLEAN RawData
)
{
EFI_IP4_TRANSMIT_DATA *TxData;
@@ -1653,20 +1669,7 @@ Ip4TxTokenValid (
TxData = Token->Packet.TxData;
//
- // Check the IP options: no more than 40 bytes and format is OK
- //
- if (TxData->OptionsLength != 0) {
- if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) {
- return EFI_INVALID_PARAMETER;
- }
- }
-
- //
- // Check the fragment table: no empty fragment, and length isn't bogus
+ // Check the fragment table: no empty fragment, and length isn't bogus.
//
if ((TxData->TotalDataLength == 0) || (TxData->FragmentCount == 0)) {
return EFI_INVALID_PARAMETER;
@@ -1674,6 +1677,10 @@ Ip4TxTokenValid (
Offset = TxData->TotalDataLength;
+ if (Offset > IP4_MAX_PACKET_SIZE) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
for (Index = 0; Index < TxData->FragmentCount; Index++) {
if ((TxData->FragmentTable[Index].FragmentBuffer == NULL) ||
(TxData->FragmentTable[Index].FragmentLength == 0)) {
@@ -1689,6 +1696,27 @@ Ip4TxTokenValid (
}
//
+ // NOTE that OptionsLength/OptionsBuffer/OverrideData are ignored if RawData
+ // is TRUE.
+ //
+ if (RawData) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Check the IP options: no more than 40 bytes and format is OK
+ //
+ if (TxData->OptionsLength != 0) {
+ if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
// Check the source and gateway: they must be a valid unicast.
// Gateway must also be on the connected network.
//
@@ -1888,6 +1916,10 @@ EfiIp4Transmit (
EFI_TPL OldTpl;
BOOLEAN DontFragment;
UINT32 HeadLen;
+ UINT8 RawHdrLen;
+ UINT32 OptionsLength;
+ UINT8 *OptionsBuffer;
+ VOID *FirstFragment;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
@@ -1913,7 +1945,7 @@ EfiIp4Transmit (
//
// make sure that token is properly formated
//
- Status = Ip4TxTokenValid (Token, IpIf);
+ Status = Ip4TxTokenValid (Token, IpIf, Config->RawData);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
@@ -1933,32 +1965,82 @@ EfiIp4Transmit (
//
TxData = Token->Packet.TxData;
- CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR));
- Head.Dst = NTOHL (Head.Dst);
+ FirstFragment = NULL;
- if (TxData->OverrideData != NULL) {
- Override = TxData->OverrideData;
- Head.Protocol = Override->Protocol;
- Head.Tos = Override->TypeOfService;
- Head.Ttl = Override->TimeToLive;
- DontFragment = Override->DoNotFragment;
+ if (Config->RawData) {
+ //
+ // When RawData is TRUE, first buffer in FragmentTable points to a raw
+ // IPv4 fragment including IPv4 header and options.
+ //
+ FirstFragment = TxData->FragmentTable[0].FragmentBuffer;
+ CopyMem (&RawHdrLen, FirstFragment, sizeof (UINT8));
- CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR));
- CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR));
+ RawHdrLen = (UINT8) (RawHdrLen & 0x0f);
+ if (RawHdrLen < 5) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RawHdrLen = (UINT8) (RawHdrLen << 2);
+
+ CopyMem (&Head, FirstFragment, IP4_MIN_HEADLEN);
+
+ Ip4NtohHead (&Head);
+ HeadLen = 0;
+ DontFragment = IP4_DO_NOT_FRAGMENT (Head.Fragment);
- Head.Src = NTOHL (Head.Src);
- GateWay = NTOHL (GateWay);
+ if (!DontFragment) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ GateWay = IP4_ALLZERO_ADDRESS;
+
+ //
+ // Get IPv4 options from first fragment.
+ //
+ if (RawHdrLen == IP4_MIN_HEADLEN) {
+ OptionsLength = 0;
+ OptionsBuffer = NULL;
+ } else {
+ OptionsLength = RawHdrLen - IP4_MIN_HEADLEN;
+ OptionsBuffer = (UINT8 *) FirstFragment + IP4_MIN_HEADLEN;
+ }
+
+ //
+ // Trim off IPv4 header and options from first fragment.
+ //
+ TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment + RawHdrLen;
+ TxData->FragmentTable[0].FragmentLength = TxData->FragmentTable[0].FragmentLength - RawHdrLen;
} else {
- Head.Src = IpIf->Ip;
- GateWay = IP4_ALLZERO_ADDRESS;
- Head.Protocol = Config->DefaultProtocol;
- Head.Tos = Config->TypeOfService;
- Head.Ttl = Config->TimeToLive;
- DontFragment = Config->DoNotFragment;
- }
+ CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR));
+ Head.Dst = NTOHL (Head.Dst);
- Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0);
- HeadLen = (TxData->OptionsLength + 3) & (~0x03);
+ if (TxData->OverrideData != NULL) {
+ Override = TxData->OverrideData;
+ Head.Protocol = Override->Protocol;
+ Head.Tos = Override->TypeOfService;
+ Head.Ttl = Override->TimeToLive;
+ DontFragment = Override->DoNotFragment;
+
+ CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR));
+ CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR));
+
+ Head.Src = NTOHL (Head.Src);
+ GateWay = NTOHL (GateWay);
+ } else {
+ Head.Src = IpIf->Ip;
+ GateWay = IP4_ALLZERO_ADDRESS;
+ Head.Protocol = Config->DefaultProtocol;
+ Head.Tos = Config->TypeOfService;
+ Head.Ttl = Config->TimeToLive;
+ DontFragment = Config->DoNotFragment;
+ }
+
+ Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0);
+ HeadLen = (TxData->OptionsLength + 3) & (~0x03);
+
+ OptionsLength = TxData->OptionsLength;
+ OptionsBuffer = (UINT8 *) (TxData->OptionsBuffer);
+ }
//
// If don't fragment and fragment needed, return error
@@ -2004,6 +2086,13 @@ EfiIp4Transmit (
// free the IP4_TXTOKEN_WRAP. Now, the token wrap hasn't been
// enqueued.
//
+ if (Config->RawData) {
+ //
+ // Restore pointer of first fragment in RawData mode.
+ //
+ TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;
+ }
+
NetbufFree (Wrap->Packet);
goto ON_EXIT;
}
@@ -2019,8 +2108,8 @@ EfiIp4Transmit (
IpInstance,
Wrap->Packet,
&Head,
- TxData->OptionsBuffer,
- TxData->OptionsLength,
+ OptionsBuffer,
+ OptionsLength,
GateWay,
Ip4OnPacketSent,
Wrap
@@ -2028,9 +2117,24 @@ EfiIp4Transmit (
if (EFI_ERROR (Status)) {
Wrap->Sent = FALSE;
+
+ if (Config->RawData) {
+ //
+ // Restore pointer of first fragment in RawData mode.
+ //
+ TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;
+ }
+
NetbufFree (Wrap->Packet);
}
+ if (Config->RawData) {
+ //
+ // Restore pointer of first fragment in RawData mode.
+ //
+ TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;
+ }
+
ON_EXIT:
gBS->RestoreTPL (OldTpl);
return Status;
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
index 563cf7f91..ad8a9276b 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
@@ -33,6 +33,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DpcLib.h>
+#include <Library/PrintLib.h>
#include "Ip4Common.h"
#include "Ip4Driver.h"
@@ -160,7 +161,6 @@ struct _IP4_SERVICE {
UINT32 Signature;
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
INTN State;
- BOOLEAN InDestroy;
//
// List of all the IP instances and interfaces, and default
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
index d985b1aeb..62163f4c5 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
@@ -714,7 +714,7 @@ Ip4PreProcessPacket (
UINT16 Checksum;
//
- // Check that the IP4 header is correctly formatted
+ // Check if the IP4 header is correctly formatted.
//
if ((*Packet)->TotalSize < IP4_MIN_HEADLEN) {
return EFI_INVALID_PARAMETER;
@@ -774,7 +774,7 @@ Ip4PreProcessPacket (
}
//
- // Trim the head off, after this point, the packet is headless.
+ // Trim the head off, after this point, the packet is headless,
// and Packet->TotalLen == Info->Length.
//
NetbufTrim (*Packet, HeadLen, TRUE);
@@ -928,7 +928,7 @@ Ip4AccpetFrame (
break;
default:
- Ip4Demultiplex (IpSb, Head, Packet);
+ Ip4Demultiplex (IpSb, Head, Packet, Option, OptionLen);
}
Packet = NULL;
@@ -1151,8 +1151,8 @@ Ip4OnRecyclePacket (
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.
+ @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 .
@@ -1167,6 +1167,7 @@ Ip4WrapRxData (
IP4_RXDATA_WRAP *Wrap;
EFI_IP4_RECEIVE_DATA *RxData;
EFI_STATUS Status;
+ BOOLEAN RawData;
Wrap = AllocatePool (IP4_RXDATA_WRAP_SIZE (Packet->BlockOpNum));
@@ -1180,7 +1181,7 @@ Ip4WrapRxData (
Wrap->Packet = Packet;
RxData = &Wrap->RxData;
- ZeroMem (&RxData->TimeStamp, sizeof (EFI_TIME));
+ ZeroMem (RxData, sizeof (EFI_IP4_RECEIVE_DATA));
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
@@ -1197,17 +1198,21 @@ Ip4WrapRxData (
ASSERT (Packet->Ip.Ip4 != NULL);
+ ASSERT (IpInstance != NULL);
+ RawData = IpInstance->ConfigData.RawData;
+
//
// The application expects a network byte order header.
//
- 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 (!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);
+ if (RxData->OptionsLength != 0) {
+ RxData->Options = (VOID *) (RxData->Header + 1);
+ }
}
RxData->DataLength = Packet->TotalSize;
@@ -1246,6 +1251,7 @@ Ip4InstanceDeliverPacket (
NET_BUF *Packet;
NET_BUF *Dup;
UINT8 *Head;
+ UINT32 HeadLen;
//
// Deliver a packet if there are both a packet and a receive token.
@@ -1271,24 +1277,32 @@ Ip4InstanceDeliverPacket (
//
// Create a duplicated packet if this packet is shared
//
- Dup = NetbufDuplicate (Packet, NULL, IP4_MAX_HEADLEN);
+ if (IpInstance->ConfigData.RawData) {
+ HeadLen = 0;
+ } else {
+ HeadLen = IP4_MAX_HEADLEN;
+ }
+
+ Dup = NetbufDuplicate (Packet, NULL, HeadLen);
if (Dup == NULL) {
return EFI_OUT_OF_RESOURCES;
}
- //
- // 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);
+ 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);
@@ -1326,10 +1340,12 @@ Ip4InstanceDeliverPacket (
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] IpIf The interface to enqueue the packet to
+ @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
@@ -1339,6 +1355,8 @@ Ip4InterfaceEnquePacket (
IN IP4_SERVICE *IpSb,
IN IP4_HEAD *Head,
IN NET_BUF *Packet,
+ IN UINT8 *Option,
+ IN UINT32 OptionLen,
IN IP4_INTERFACE *IpIf
)
{
@@ -1404,6 +1422,13 @@ Ip4InterfaceEnquePacket (
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++;
}
@@ -1450,11 +1475,13 @@ Ip4InterfaceDeliverPacket (
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] 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_NOT_FOUND No IP child accepts the packet.
@retval EFI_SUCCESS The packet is enqueued or delivered to some IP
children.
@@ -1463,7 +1490,9 @@ EFI_STATUS
Ip4Demultiplex (
IN IP4_SERVICE *IpSb,
IN IP4_HEAD *Head,
- IN NET_BUF *Packet
+ IN NET_BUF *Packet,
+ IN UINT8 *Option,
+ IN UINT32 OptionLen
)
{
LIST_ENTRY *Entry;
@@ -1480,7 +1509,14 @@ Ip4Demultiplex (
IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);
if (IpIf->Configured) {
- Enqueued += Ip4InterfaceEnquePacket (IpSb, Head, Packet, IpIf);
+ Enqueued += Ip4InterfaceEnquePacket (
+ IpSb,
+ Head,
+ Packet,
+ Option,
+ OptionLen,
+ IpIf
+ );
}
}
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h
index fda4d18c9..1c8e8b2a1 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -141,11 +141,13 @@ Ip4AccpetFrame (
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] 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_NOT_FOUND No IP child accepts the packet.
@retval EFI_SUCCESS The packet is enqueued or delivered to some IP
children.
@@ -154,17 +156,21 @@ EFI_STATUS
Ip4Demultiplex (
IN IP4_SERVICE *IpSb,
IN IP4_HEAD *Head,
- IN NET_BUF *Packet
+ IN NET_BUF *Packet,
+ IN UINT8 *Option,
+ IN UINT32 OptionLen
);
/**
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] IpIf The interface to enqueue the packet to
+ @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
@@ -174,6 +180,8 @@ Ip4InterfaceEnquePacket (
IN IP4_SERVICE *IpSb,
IN IP4_HEAD *Head,
IN NET_BUF *Packet,
+ IN UINT8 *Option,
+ IN UINT32 OptionLen,
IN IP4_INTERFACE *IpIf
);
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
index 85dffe064..7ff17b663 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
@@ -1,7 +1,7 @@
/** @file
Transmit the IP4 packet.
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -204,6 +204,10 @@ Ip4SysPacketSent (
@retval EFI_NO_MAPPING There is no interface to the destination.
@retval EFI_NOT_FOUND There is no route to the destination
@retval EFI_SUCCESS The packet is successfully transmitted.
+ @retval EFI_BAD_BUFFER_SIZE The length of the IPv4 header + option length +
+ total data length is greater than MTU (or greater
+ than the maximum packet size if Token.Packet.TxData.
+ OverrideData.DoNotFragment is TRUE.)
@retval Others Failed to transmit the packet.
**/
@@ -231,6 +235,7 @@ Ip4Output (
UINT32 Offset;
UINT32 Mtu;
UINT32 Num;
+ BOOLEAN RawData;
//
// Select an interface/source for system packet, application
@@ -252,11 +257,18 @@ Ip4Output (
//
// Before IPsec process, prepared the IP head.
+ // If Ip4Output is transmitting RawData, don't update IPv4 header.
//
- HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));
- Head->HeadLen = (UINT8) (HeadLen >> 2);
- Head->Id = mIp4Id++;
- Head->Ver = 4;
+ HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));
+
+ if ((IpInstance != NULL) && IpInstance->ConfigData.RawData) {
+ RawData = TRUE;
+ } else {
+ Head->HeadLen = (UINT8) (HeadLen >> 2);
+ Head->Id = mIp4Id++;
+ Head->Ver = 4;
+ RawData = FALSE;
+ }
//
// Call IPsec process.
@@ -324,6 +336,13 @@ Ip4Output (
if (Packet->TotalSize + HeadLen > Mtu) {
//
+ // Fragmentation is diabled for RawData mode.
+ //
+ if (RawData) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ //
// Packet is fragmented from the tail to the head, that is, the
// first frame sent is the last fragment of the packet. The first
// fragment is NOT sent in this loop. First compute how many