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
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -230,6 +232,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)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
|
||||
///
|
||||
|
@@ -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
|
||||
);
|
||||
|
||||
|
||||
if (gIp4ControllerNameTable != NULL) {
|
||||
FreeUnicodeStringTable (gIp4ControllerNameTable);
|
||||
gIp4ControllerNameTable = NULL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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)) {
|
||||
@@ -1688,6 +1695,27 @@ Ip4TxTokenValid (
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
Head.Src = NTOHL (Head.Src);
|
||||
GateWay = NTOHL (GateWay);
|
||||
RawHdrLen = (UINT8) (RawHdrLen << 2);
|
||||
|
||||
CopyMem (&Head, FirstFragment, IP4_MIN_HEADLEN);
|
||||
|
||||
Ip4NtohHead (&Head);
|
||||
HeadLen = 0;
|
||||
DontFragment = IP4_DO_NOT_FRAGMENT (Head.Fragment);
|
||||
|
||||
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;
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
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;
|
||||
|
||||
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;
|
||||
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);
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
);
|
||||
|
||||
|
@@ -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.
|
||||
@@ -323,6 +335,13 @@ Ip4Output (
|
||||
Mtu = IpSb->MaxPacketSize + sizeof (IP4_HEAD);
|
||||
|
||||
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
|
||||
|
Reference in New Issue
Block a user