377 lines
9.6 KiB
C
377 lines
9.6 KiB
C
/** @file
|
|
Implement the connection to the EFI socket library
|
|
|
|
Copyright (c) 2011, Intel Corporation
|
|
All rights reserved. This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include "Socket.h"
|
|
|
|
|
|
/**
|
|
The following GUID values are only used when an application links
|
|
against EfiSocketLib. An alternative set of values exists in
|
|
SocketDxe\EntryUnload.c which the SocketDxe driver uses to coexist
|
|
with socket applications.
|
|
|
|
Tag GUID - IPv4 in use by an application using EfiSocketLib
|
|
**/
|
|
CONST EFI_GUID mEslIp4ServiceGuid __attribute__((weak)) = {
|
|
0x9c756011, 0x5d44, 0x4ee0, { 0xbc, 0xe7, 0xc3, 0x82, 0x18, 0xfe, 0x39, 0x8d }
|
|
};
|
|
|
|
|
|
/**
|
|
Tag GUID - IPv6 in use by an application using EfiSocketLib
|
|
**/
|
|
CONST EFI_GUID mEslIp6ServiceGuid __attribute__((weak)) = {
|
|
0xc51b2761, 0xc476, 0x45fe, { 0xbe, 0x61, 0xba, 0x4b, 0xcc, 0x32, 0xf2, 0x34 }
|
|
};
|
|
|
|
|
|
/**
|
|
Tag GUID - TCPv4 in use by an application using EfiSocketLib
|
|
**/
|
|
CONST EFI_GUID mEslTcp4ServiceGuid __attribute__((weak)) = {
|
|
0xffc659c2, 0x4ef2, 0x4532, { 0xb8, 0x75, 0xcd, 0x9a, 0xa4, 0x27, 0x4c, 0xde }
|
|
};
|
|
|
|
|
|
/**
|
|
Tag GUID - TCPv6 in use by an application using EfiSocketLib
|
|
**/
|
|
CONST EFI_GUID mEslTcp6ServiceGuid __attribute__((weak)) = {
|
|
0x279858a4, 0x4e9e, 0x4e53, { 0x93, 0x22, 0xf2, 0x54, 0xe0, 0x7e, 0xef, 0xd4 }
|
|
};
|
|
|
|
|
|
/**
|
|
Tag GUID - UDPv4 in use by an application using EfiSocketLib
|
|
**/
|
|
CONST EFI_GUID mEslUdp4ServiceGuid __attribute__((weak)) = {
|
|
0x44e03a55, 0x8d97, 0x4511, { 0xbf, 0xef, 0xa, 0x8b, 0xc6, 0x2c, 0x25, 0xae }
|
|
};
|
|
|
|
|
|
/**
|
|
Tag GUID - UDPv6 in use by an application using EfiSocketLib
|
|
**/
|
|
CONST EFI_GUID mEslUdp6ServiceGuid __attribute__((weak)) = {
|
|
0xaa4af677, 0x6efe, 0x477c, { 0x96, 0x68, 0xe8, 0x13, 0x9d, 0x2, 0xfd, 0x9b }
|
|
};
|
|
|
|
|
|
/**
|
|
Free the socket resources
|
|
|
|
This releases the socket resources allocated by calling
|
|
EslServiceGetProtocol.
|
|
|
|
This routine is called from the ::close routine in BsdSocketLib
|
|
to release the socket resources.
|
|
|
|
@param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL
|
|
structure
|
|
|
|
@return Value for ::errno, zero (0) indicates success.
|
|
|
|
**/
|
|
int
|
|
EslServiceFreeProtocol (
|
|
IN EFI_SOCKET_PROTOCOL * pSocketProtocol
|
|
)
|
|
{
|
|
int RetVal;
|
|
|
|
//
|
|
// Release the socket resources
|
|
//
|
|
EslSocketFree ( pSocketProtocol, &RetVal );
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
return RetVal;
|
|
}
|
|
|
|
|
|
/**
|
|
Connect to the EFI socket library
|
|
|
|
This routine creates the ::ESL_SOCKET structure and returns
|
|
the API (::EFI_SOCKET_PROTOCOL address) to the socket file
|
|
system layer in BsdSocketLib.
|
|
|
|
This routine is called from the ::socket routine in BsdSocketLib
|
|
to create the data structure and initialize the API for a socket.
|
|
Note that this implementation is only used by socket applications
|
|
that link directly to EslSocketLib.
|
|
|
|
@param [in] ppSocketProtocol Address to receive the ::EFI_SOCKET_PROTOCOL
|
|
structure address
|
|
|
|
@return Value for ::errno, zero (0) indicates success.
|
|
|
|
**/
|
|
int
|
|
EslServiceGetProtocol (
|
|
IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol
|
|
)
|
|
{
|
|
EFI_HANDLE ChildHandle;
|
|
ESL_SOCKET * pSocket;
|
|
int RetVal;
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Assume success
|
|
//
|
|
RetVal = 0;
|
|
|
|
//
|
|
// Locate the socket protocol
|
|
//
|
|
ChildHandle = NULL;
|
|
Status = EslSocketAllocate ( &ChildHandle,
|
|
DEBUG_SOCKET,
|
|
&pSocket );
|
|
if ( !EFI_ERROR ( Status )) {
|
|
*ppSocketProtocol = &pSocket->SocketProtocol;
|
|
}
|
|
else {
|
|
//
|
|
// No resources
|
|
//
|
|
RetVal = ENOMEM;
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_DEC ( RetVal );
|
|
return RetVal;
|
|
}
|
|
|
|
|
|
/**
|
|
Connect to the network layer
|
|
|
|
This routine is the constructor for the EfiSocketLib when the
|
|
library is linked directly to an application. This routine
|
|
walks the ::cEslSocketBinding table to create ::ESL_SERVICE
|
|
structures, associated with the network adapters, which this
|
|
routine links to the ::ESL_LAYER structure.
|
|
|
|
This routine is called from ::EslConstructor as a result of the
|
|
constructor redirection in ::mpfnEslConstructor at the end of this
|
|
file.
|
|
|
|
@retval EFI_SUCCESS Successfully connected to the network layer
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EslServiceNetworkConnect (
|
|
VOID
|
|
)
|
|
{
|
|
BOOLEAN bSomethingFound;
|
|
UINTN HandleCount;
|
|
UINTN Index;
|
|
CONST ESL_SOCKET_BINDING * pEnd;
|
|
EFI_HANDLE * pHandles;
|
|
CONST ESL_SOCKET_BINDING * pSocketBinding;
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Initialize the socket layer
|
|
//
|
|
Status = EFI_SUCCESS;
|
|
bSomethingFound = FALSE;
|
|
EslServiceLoad ( gImageHandle );
|
|
|
|
//
|
|
// Connect the network devices
|
|
//
|
|
pSocketBinding = &cEslSocketBinding[0];
|
|
pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
|
|
while ( pEnd > pSocketBinding ) {
|
|
//
|
|
// Attempt to locate the network adapters
|
|
//
|
|
HandleCount = 0;
|
|
pHandles = NULL;
|
|
Status = gBS->LocateHandleBuffer ( ByProtocol,
|
|
pSocketBinding->pNetworkBinding,
|
|
NULL,
|
|
&HandleCount,
|
|
&pHandles );
|
|
if ( EFI_ERROR ( Status )) {
|
|
DEBUG (( DEBUG_ERROR,
|
|
"ERROR with %s layer, Status: %r\r\n",
|
|
pSocketBinding->pName,
|
|
Status ));
|
|
}
|
|
else {
|
|
if ( NULL != pHandles ) {
|
|
//
|
|
// Attempt to connect to this network adapter
|
|
//
|
|
for ( Index = 0; HandleCount > Index; Index++ ) {
|
|
Status = EslServiceConnect ( gImageHandle,
|
|
pHandles[ Index ]);
|
|
if ( !EFI_ERROR ( Status )) {
|
|
bSomethingFound = TRUE;
|
|
}
|
|
else {
|
|
if ( EFI_OUT_OF_RESOURCES == Status ) {
|
|
//
|
|
// Pointless to continue without memory
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Done with the handles
|
|
//
|
|
gBS->FreePool ( pHandles );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the next network protocol
|
|
//
|
|
pSocketBinding += 1;
|
|
}
|
|
|
|
//
|
|
// Return the network connection status
|
|
//
|
|
if ( bSomethingFound ) {
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
Disconnect from the network layer
|
|
|
|
Destructor for the EfiSocketLib when the library is linked
|
|
directly to an application. This routine walks the
|
|
::cEslSocketBinding table to remove the ::ESL_SERVICE
|
|
structures (network connections) from the ::ESL_LAYER structure.
|
|
|
|
This routine is called from ::EslDestructor as a result of the
|
|
destructor redirection in ::mpfnEslDestructor at the end of this
|
|
file.
|
|
|
|
@retval EFI_SUCCESS Successfully disconnected from the network layer
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EslServiceNetworkDisconnect (
|
|
VOID
|
|
)
|
|
{
|
|
UINTN HandleCount;
|
|
UINTN Index;
|
|
CONST ESL_SOCKET_BINDING * pEnd;
|
|
EFI_HANDLE * pHandles;
|
|
CONST ESL_SOCKET_BINDING * pSocketBinding;
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Assume success
|
|
//
|
|
Status = EFI_SUCCESS;
|
|
|
|
//
|
|
// Disconnect the network devices
|
|
//
|
|
pSocketBinding = &cEslSocketBinding[0];
|
|
pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
|
|
while ( pEnd > pSocketBinding ) {
|
|
//
|
|
// Attempt to locate the network adapters
|
|
//
|
|
HandleCount = 0;
|
|
pHandles = NULL;
|
|
Status = gBS->LocateHandleBuffer ( ByProtocol,
|
|
pSocketBinding->pNetworkBinding,
|
|
NULL,
|
|
&HandleCount,
|
|
&pHandles );
|
|
if (( !EFI_ERROR ( Status ))
|
|
&& ( NULL != pHandles )) {
|
|
//
|
|
// Attempt to disconnect from this network adapter
|
|
//
|
|
for ( Index = 0; HandleCount > Index; Index++ ) {
|
|
Status = EslServiceDisconnect ( gImageHandle,
|
|
pHandles[ Index ]);
|
|
if ( EFI_ERROR ( Status )) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Done with the handles
|
|
//
|
|
gBS->FreePool ( pHandles );
|
|
}
|
|
|
|
//
|
|
// Set the next network protocol
|
|
//
|
|
pSocketBinding += 1;
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// Finish the disconnect operation
|
|
//
|
|
if ( !EFI_ERROR ( Status )) {
|
|
EslServiceUnload ( );
|
|
}
|
|
|
|
//
|
|
// Return the network connection status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
Socket layer's service binding protocol delcaration.
|
|
**/
|
|
CONST EFI_SERVICE_BINDING_PROTOCOL mEfiServiceBinding __attribute__((weak)) = {
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
|
|
/**
|
|
The following entries redirect the constructor and destructor
|
|
for any socket application that links against the EfiSocketLib.
|
|
Note that the SocketDxe driver uses different redirection.
|
|
**/
|
|
PFN_ESL_xSTRUCTOR mpfnEslConstructor __attribute__((weak)) = EslServiceNetworkConnect; ///< Constructor for EfiSocketLib
|
|
PFN_ESL_xSTRUCTOR mpfnEslDestructor __attribute__((weak)) = EslServiceNetworkDisconnect; ///< Destructor for EfiSocketLib
|