mirror of https://github.com/acidanthera/audk.git
302 lines
7.9 KiB
C
302 lines
7.9 KiB
C
/** @file
|
|
Implement the socket API.
|
|
|
|
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 <SocketInternals.h>
|
|
|
|
|
|
/**
|
|
File system interface for the socket layer.
|
|
|
|
This data structure defines the routines for the various
|
|
file system functions associated with the socket layer.
|
|
**/
|
|
const struct fileops SocketOperations = {
|
|
BslSocketClose, // close
|
|
BslSocketRead, // read
|
|
BslSocketWrite, // write
|
|
|
|
//
|
|
// Not supported
|
|
//
|
|
fnullop_fcntl, // fcntl
|
|
BslSocketPoll, // poll
|
|
fnullop_flush, // flush
|
|
|
|
fbadop_stat, // stat
|
|
fbadop_ioctl, // ioctl
|
|
fbadop_delete, // delete
|
|
fbadop_rmdir, // rmdir
|
|
fbadop_mkdir, // mkdir
|
|
fbadop_rename, // rename
|
|
|
|
NULL // lseek
|
|
};
|
|
|
|
|
|
/**
|
|
Translate from the socket file descriptor to the socket protocol.
|
|
|
|
@param [in] s Socket file descriptor returned from ::socket.
|
|
|
|
@param [in] ppDescriptor Address to receive the descriptor structure
|
|
address for the file
|
|
@param [in] pErrno Address of the errno variable
|
|
|
|
@return A pointer to the EFI_SOCKET_PROTOCOL structure or NULL if
|
|
an invalid file descriptor was passed in.
|
|
|
|
**/
|
|
EFI_SOCKET_PROTOCOL *
|
|
BslFdToSocketProtocol (
|
|
int s,
|
|
struct __filedes ** ppDescriptor,
|
|
int * pErrno
|
|
)
|
|
{
|
|
struct __filedes * pDescriptor;
|
|
EFI_SOCKET_PROTOCOL * pSocketProtocol;
|
|
|
|
//
|
|
// Assume failure
|
|
//
|
|
pSocketProtocol = NULL;
|
|
|
|
//
|
|
// Validate the file descriptor
|
|
//
|
|
if ( !ValidateFD ( s, TRUE )) {
|
|
//
|
|
// Bad file descriptor
|
|
//
|
|
*pErrno = EBADF;
|
|
}
|
|
else {
|
|
//
|
|
// Get the descriptor for the file
|
|
//
|
|
pDescriptor = &gMD->fdarray[ s ];
|
|
|
|
//
|
|
// Validate that the descriptor is associated with sockets
|
|
//
|
|
pSocketProtocol = BslValidateSocketFd ( pDescriptor, pErrno );
|
|
if (( NULL != ppDescriptor ) && ( NULL != pSocketProtocol )) {
|
|
*ppDescriptor = pDescriptor;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Return the socket protocol
|
|
//
|
|
return pSocketProtocol;
|
|
}
|
|
|
|
|
|
/**
|
|
Build a file descriptor for a socket.
|
|
|
|
@param [in] pSocketProtocol Socket protocol structure address
|
|
|
|
@param [in] pErrno Address of the errno variable
|
|
|
|
@return The file descriptor for the socket or -1 if an error occurs.
|
|
|
|
**/
|
|
int
|
|
BslSocketProtocolToFd (
|
|
IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
|
|
IN int * pErrno
|
|
)
|
|
{
|
|
int FileDescriptor;
|
|
struct __filedes * pDescriptor;
|
|
|
|
//
|
|
// Assume failure
|
|
//
|
|
FileDescriptor = -1;
|
|
|
|
//
|
|
// Locate a file descriptor
|
|
//
|
|
FileDescriptor = FindFreeFD ( VALID_CLOSED );
|
|
if ( FileDescriptor < 0 ) {
|
|
//
|
|
// All available FDs are in use
|
|
//
|
|
errno = EMFILE;
|
|
}
|
|
else {
|
|
//
|
|
// Initialize the file descriptor
|
|
//
|
|
pDescriptor = &gMD->fdarray[ FileDescriptor ];
|
|
pDescriptor->f_offset = 0;
|
|
pDescriptor->f_flag = 0;
|
|
pDescriptor->f_iflags = DTYPE_SOCKET;
|
|
pDescriptor->MyFD = (UINT16)FileDescriptor;
|
|
pDescriptor->Oflags = O_RDWR;
|
|
pDescriptor->Omode = S_ACC_READ | S_ACC_WRITE;
|
|
pDescriptor->RefCount = 1;
|
|
FILE_SET_MATURE ( pDescriptor );
|
|
|
|
//
|
|
// Socket specific file descriptor initialization
|
|
//
|
|
pDescriptor->devdata = pSocketProtocol;
|
|
pDescriptor->f_ops = &SocketOperations;
|
|
}
|
|
|
|
//
|
|
// Return the socket's file descriptor
|
|
//
|
|
return FileDescriptor;
|
|
}
|
|
|
|
|
|
/**
|
|
Creates an endpoint for network communication.
|
|
|
|
The socket routine initializes the communication endpoint and returns a
|
|
file descriptor.
|
|
|
|
The
|
|
<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html">POSIX</a>
|
|
documentation is available online.
|
|
|
|
@param [in] domain Select the family of protocols for the client or server
|
|
application. The supported values are:
|
|
<ul>
|
|
<li>AF_INET - Version 4 UEFI network stack</li>
|
|
</ul>
|
|
|
|
@param [in] type Specifies how to make the network connection. The following values
|
|
are supported:
|
|
<ul>
|
|
<li>
|
|
SOCK_DGRAM - Connect to UDP, provides a datagram service that is
|
|
manipulated by recvfrom and sendto.
|
|
</li>
|
|
<li>
|
|
SOCK_STREAM - Connect to TCP, provides a byte stream
|
|
that is manipluated by read, recv, send and write.
|
|
</li>
|
|
<li>
|
|
SOCK_RAW - Connect to IP, provides a datagram service that
|
|
is manipulated by recvfrom and sendto.
|
|
</li>
|
|
</ul>
|
|
|
|
@param [in] protocol Specifies the lower layer protocol to use. The following
|
|
values are supported:
|
|
<ul>
|
|
<li>IPPROTO_TCP</li> - This value must be combined with SOCK_STREAM.</li>
|
|
<li>IPPROTO_UDP</li> - This value must be combined with SOCK_DGRAM.</li>
|
|
<li>0 - 254</li> - An assigned
|
|
<a href="http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml">protocol number</a>
|
|
is combined with SOCK_RAW.
|
|
</li>
|
|
</ul>
|
|
|
|
@return This routine returns a file descriptor for the socket. If an error
|
|
occurs -1 is returned and ::errno contains more details.
|
|
|
|
**/
|
|
INT32
|
|
socket (
|
|
IN INT32 domain,
|
|
IN INT32 type,
|
|
IN INT32 protocol
|
|
)
|
|
{
|
|
INT32 FileDescriptor;
|
|
EFI_SOCKET_PROTOCOL * pSocketProtocol;
|
|
EFI_STATUS Status;
|
|
|
|
//
|
|
// Assume failure
|
|
//
|
|
FileDescriptor = -1;
|
|
|
|
//
|
|
// Locate the socket protocol
|
|
//
|
|
errno = EslServiceGetProtocol ( &pSocketProtocol );
|
|
if ( 0 == errno ) {
|
|
//
|
|
// Initialize the socket
|
|
//
|
|
Status = pSocketProtocol->pfnSocket ( pSocketProtocol,
|
|
domain,
|
|
type,
|
|
protocol,
|
|
&errno );
|
|
if ( !EFI_ERROR ( Status )) {
|
|
//
|
|
// Build the file descriptor for the socket
|
|
//
|
|
FileDescriptor = BslSocketProtocolToFd ( pSocketProtocol,
|
|
&errno );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Return the socket's file descriptor
|
|
//
|
|
return FileDescriptor;
|
|
}
|
|
|
|
|
|
/**
|
|
Validate the socket's file descriptor
|
|
|
|
@param [in] pDescriptor Descriptor for the file
|
|
|
|
@param [in] pErrno Address of the errno variable
|
|
|
|
@return A pointer to the EFI_SOCKET_PROTOCOL structure or NULL if
|
|
an invalid file descriptor was passed in.
|
|
|
|
**/
|
|
EFI_SOCKET_PROTOCOL *
|
|
BslValidateSocketFd (
|
|
struct __filedes * pDescriptor,
|
|
int * pErrno
|
|
)
|
|
{
|
|
EFI_SOCKET_PROTOCOL * pSocketProtocol;
|
|
|
|
//
|
|
// Assume failure
|
|
//
|
|
*pErrno = ENOTSOCK;
|
|
pSocketProtocol = NULL;
|
|
|
|
//
|
|
// Validate that the descriptor is associated with sockets
|
|
//
|
|
if ( DTYPE_SOCKET == ( pDescriptor->f_iflags & DTYPE_MASK )) {
|
|
//
|
|
// Locate the socket protocol
|
|
//
|
|
pSocketProtocol = pDescriptor->devdata;
|
|
*pErrno = 0;
|
|
}
|
|
|
|
//
|
|
// Return the socket protocol
|
|
//
|
|
return pSocketProtocol;
|
|
}
|