* Passes conformance and functional tests. * Builds with GCC 4.4 compiler. Signed-off by: lpleahy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12497 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			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 = 0;
 | 
						|
    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;
 | 
						|
}
 |