1d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/** @file
2d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  Implement the socket API.
3d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
4d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  Copyright (c) 2011, Intel Corporation
5d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  All rights reserved. This program and the accompanying materials
6d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  are licensed and made available under the terms and conditions of the BSD License
7d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  which accompanies this distribution.  The full text of the license may be found at
8d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  http://opensource.org/licenses/bsd-license.php
9d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
10d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
13d7ce700605e1af0e455e31ec11f19ff21d26b525darylm**/
14d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
15d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <SocketInternals.h>
16d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
17d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
18a88c31639bb24c73383a4528a5b77066e805148blpleahy/**
19a88c31639bb24c73383a4528a5b77066e805148blpleahy  File system interface for the socket layer.
20a88c31639bb24c73383a4528a5b77066e805148blpleahy
21a88c31639bb24c73383a4528a5b77066e805148blpleahy  This data structure defines the routines for the various
22a88c31639bb24c73383a4528a5b77066e805148blpleahy  file system functions associated with the socket layer.
23a88c31639bb24c73383a4528a5b77066e805148blpleahy**/
24d7ce700605e1af0e455e31ec11f19ff21d26b525darylmconst struct fileops SocketOperations = {
25d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  BslSocketClose,     //  close
26d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  BslSocketRead,      //  read
27d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  BslSocketWrite,     //  write
28d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
29d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
30d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Not supported
31d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
32d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  fnullop_fcntl,      //  fcntl
33d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  BslSocketPoll,      //  poll
34d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  fnullop_flush,      //  flush
35d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
36d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  fbadop_stat,        //  stat
37d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  fbadop_ioctl,       //  ioctl
38d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  fbadop_delete,      //  delete
39d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  fbadop_rmdir,       //  rmdir
40d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  fbadop_mkdir,       //  mkdir
41d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  fbadop_rename,      //  rename
42d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
43d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  NULL                //  lseek
44d7ce700605e1af0e455e31ec11f19ff21d26b525darylm};
45d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
46d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
47d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/**
48d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  Translate from the socket file descriptor to the socket protocol.
49d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
50d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  @param [in] s             Socket file descriptor returned from ::socket.
51d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
52d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  @param [in] ppDescriptor  Address to receive the descriptor structure
53d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                            address for the file
54d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  @param [in] pErrno        Address of the errno variable
55d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
56a88c31639bb24c73383a4528a5b77066e805148blpleahy  @return   A pointer to the EFI_SOCKET_PROTOCOL structure or NULL if
57d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            an invalid file descriptor was passed in.
58d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
59d7ce700605e1af0e455e31ec11f19ff21d26b525darylm **/
60d7ce700605e1af0e455e31ec11f19ff21d26b525darylmEFI_SOCKET_PROTOCOL *
61d7ce700605e1af0e455e31ec11f19ff21d26b525darylmBslFdToSocketProtocol (
62d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int s,
63d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  struct __filedes ** ppDescriptor,
64d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int * pErrno
65d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  )
66d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
67d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  struct __filedes * pDescriptor;
68d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  EFI_SOCKET_PROTOCOL * pSocketProtocol;
69d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
70d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
71d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Assume failure
72d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
73d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  pSocketProtocol = NULL;
74d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
75d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
76d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Validate the file descriptor
77d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
78d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if ( !ValidateFD ( s, TRUE )) {
79d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
80d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //  Bad file descriptor
81d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
82d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    *pErrno = EBADF;
83d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
84d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  else {
85d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
86d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //  Get the descriptor for the file
87d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
88a88c31639bb24c73383a4528a5b77066e805148blpleahy    pDescriptor = &gMD->fdarray[ s ];
89d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
90d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
91d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //  Validate that the descriptor is associated with sockets
92d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
93d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    pSocketProtocol = BslValidateSocketFd ( pDescriptor, pErrno );
94d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (( NULL != ppDescriptor ) && ( NULL != pSocketProtocol )) {
95d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      *ppDescriptor = pDescriptor;
96d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
97d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
98d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
99d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
100d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Return the socket protocol
101d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
102d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  return pSocketProtocol;
103d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
104d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
105d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
106d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/**
107d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  Build a file descriptor for a socket.
108d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
109d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  @param [in] pSocketProtocol   Socket protocol structure address
1107dc1329100c370992cdd430359512443bd1ee9f2darylm
111d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  @param [in] pErrno            Address of the errno variable
112d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
1137dc1329100c370992cdd430359512443bd1ee9f2darylm  @return  The file descriptor for the socket or -1 if an error occurs.
114d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
115d7ce700605e1af0e455e31ec11f19ff21d26b525darylm **/
116d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint
117d7ce700605e1af0e455e31ec11f19ff21d26b525darylmBslSocketProtocolToFd (
118d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
119d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  IN int * pErrno
120d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  )
121d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
122d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int FileDescriptor;
123d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  struct __filedes * pDescriptor;
124d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
125d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
126d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Assume failure
127d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
128d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  FileDescriptor = -1;
129d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
130d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
131d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Locate a file descriptor
132d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
133d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  FileDescriptor = FindFreeFD ( VALID_CLOSED );
134a88c31639bb24c73383a4528a5b77066e805148blpleahy  if ( FileDescriptor < 0 ) {
135d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
136d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    // All available FDs are in use
137d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
138d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    errno = EMFILE;
139d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
140d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  else {
141d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
142d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //  Initialize the file descriptor
143d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
144a88c31639bb24c73383a4528a5b77066e805148blpleahy    pDescriptor = &gMD->fdarray[ FileDescriptor ];
145d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    pDescriptor->f_offset = 0;
146d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    pDescriptor->f_flag = 0;
147d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    pDescriptor->f_iflags = DTYPE_SOCKET;
148d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    pDescriptor->MyFD = (UINT16)FileDescriptor;
1493cdb02f964241fe8f2f1c8d286108606ef54e4ddlpleahy    pDescriptor->Oflags = O_RDWR;
150d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    pDescriptor->Omode = S_ACC_READ | S_ACC_WRITE;
151d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    pDescriptor->RefCount = 1;
152d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    FILE_SET_MATURE ( pDescriptor );
153d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
154d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
155d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //  Socket specific file descriptor initialization
156d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
157d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    pDescriptor->devdata = pSocketProtocol;
158d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    pDescriptor->f_ops = &SocketOperations;
159d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
160d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
161d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
162d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Return the socket's file descriptor
163d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
164d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  return FileDescriptor;
165d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
166d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
167d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
168d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/**
169d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  Creates an endpoint for network communication.
170d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
171a88c31639bb24c73383a4528a5b77066e805148blpleahy  The socket routine initializes the communication endpoint and returns a
172a88c31639bb24c73383a4528a5b77066e805148blpleahy  file descriptor.
173a88c31639bb24c73383a4528a5b77066e805148blpleahy
174a88c31639bb24c73383a4528a5b77066e805148blpleahy  The
175d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html">POSIX</a>
176a88c31639bb24c73383a4528a5b77066e805148blpleahy  documentation is available online.
177d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
178d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  @param [in] domain    Select the family of protocols for the client or server
179a88c31639bb24c73383a4528a5b77066e805148blpleahy                        application.  The supported values are:
180a88c31639bb24c73383a4528a5b77066e805148blpleahy                        <ul>
181a88c31639bb24c73383a4528a5b77066e805148blpleahy                          <li>AF_INET - Version 4 UEFI network stack</li>
182a88c31639bb24c73383a4528a5b77066e805148blpleahy                        </ul>
183d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
184d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  @param [in] type      Specifies how to make the network connection.  The following values
185d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                        are supported:
186d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                        <ul>
187d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                          <li>
188a88c31639bb24c73383a4528a5b77066e805148blpleahy                            SOCK_DGRAM - Connect to UDP, provides a datagram service that is
189a88c31639bb24c73383a4528a5b77066e805148blpleahy                            manipulated by recvfrom and sendto.
190d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                          </li>
191d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                          <li>
192a88c31639bb24c73383a4528a5b77066e805148blpleahy                            SOCK_STREAM - Connect to TCP, provides a byte stream
193a88c31639bb24c73383a4528a5b77066e805148blpleahy                            that is manipluated by read, recv, send and write.
194d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                          </li>
195d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                          <li>
196a88c31639bb24c73383a4528a5b77066e805148blpleahy                            SOCK_RAW - Connect to IP, provides a datagram service that
197a88c31639bb24c73383a4528a5b77066e805148blpleahy                            is manipulated by recvfrom and sendto.
198d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                          </li>
199d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                        </ul>
200d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
201d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  @param [in] protocol  Specifies the lower layer protocol to use.  The following
202d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                        values are supported:
203d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                        <ul>
204d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                          <li>IPPROTO_TCP</li> - This value must be combined with SOCK_STREAM.</li>
205d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                          <li>IPPROTO_UDP</li> - This value must be combined with SOCK_DGRAM.</li>
206a88c31639bb24c73383a4528a5b77066e805148blpleahy                          <li>0 - 254</li> - An assigned
207a88c31639bb24c73383a4528a5b77066e805148blpleahy                            <a href="http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml">protocol number</a>
208a88c31639bb24c73383a4528a5b77066e805148blpleahy                            is combined with SOCK_RAW.
209a88c31639bb24c73383a4528a5b77066e805148blpleahy                          </li>
210d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                        </ul>
211d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
212a88c31639bb24c73383a4528a5b77066e805148blpleahy  @return  This routine returns a file descriptor for the socket.  If an error
213a88c31639bb24c73383a4528a5b77066e805148blpleahy           occurs -1 is returned and ::errno contains more details.
214d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
215d7ce700605e1af0e455e31ec11f19ff21d26b525darylm **/
216d7ce700605e1af0e455e31ec11f19ff21d26b525darylmINT32
217d7ce700605e1af0e455e31ec11f19ff21d26b525darylmsocket (
218d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  IN INT32 domain,
219d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  IN INT32 type,
220d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  IN INT32 protocol
221d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  )
222d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
223d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  INT32 FileDescriptor;
224d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  EFI_SOCKET_PROTOCOL * pSocketProtocol;
225d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  EFI_STATUS Status;
226d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
227d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
228d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Assume failure
229d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
230d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  FileDescriptor = -1;
231d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
232d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
233d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Locate the socket protocol
234d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
235d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  errno = EslServiceGetProtocol ( &pSocketProtocol );
236d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if ( 0 == errno ) {
237d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
238d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //  Initialize the socket
239d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
240d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    Status = pSocketProtocol->pfnSocket ( pSocketProtocol,
241d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                          domain,
242d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                          type,
243d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                          protocol,
244d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                          &errno );
245a88c31639bb24c73383a4528a5b77066e805148blpleahy    if ( !EFI_ERROR ( Status )) {
246d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      //
247d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      //  Build the file descriptor for the socket
248d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      //
249d7ce700605e1af0e455e31ec11f19ff21d26b525darylm      FileDescriptor = BslSocketProtocolToFd ( pSocketProtocol,
250d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                                               &errno );
251d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
252d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
253d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
254d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
255d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Return the socket's file descriptor
256d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
257d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  return FileDescriptor;
258d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
259d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
260d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
261d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/**
262d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  Validate the socket's file descriptor
263d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
264d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  @param [in] pDescriptor Descriptor for the file
265d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
266d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  @param [in] pErrno      Address of the errno variable
267d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
268a88c31639bb24c73383a4528a5b77066e805148blpleahy  @return   A pointer to the EFI_SOCKET_PROTOCOL structure or NULL if
269d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            an invalid file descriptor was passed in.
270d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
271d7ce700605e1af0e455e31ec11f19ff21d26b525darylm **/
272d7ce700605e1af0e455e31ec11f19ff21d26b525darylmEFI_SOCKET_PROTOCOL *
273d7ce700605e1af0e455e31ec11f19ff21d26b525darylmBslValidateSocketFd (
274d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  struct __filedes * pDescriptor,
275d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  int * pErrno
276d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  )
277d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
278d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  EFI_SOCKET_PROTOCOL * pSocketProtocol;
279d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
280d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
281d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Assume failure
282d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
283d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  *pErrno = ENOTSOCK;
284d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  pSocketProtocol = NULL;
285d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
286d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
287d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Validate that the descriptor is associated with sockets
288d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
289d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  if ( DTYPE_SOCKET == ( pDescriptor->f_iflags & DTYPE_MASK )) {
290d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
291d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //  Locate the socket protocol
292d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    //
293d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    pSocketProtocol = pDescriptor->devdata;
294d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    *pErrno = 0;
295d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  }
296d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
297d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
298d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //  Return the socket protocol
299d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  //
300d7ce700605e1af0e455e31ec11f19ff21d26b525darylm  return pSocketProtocol;
301d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
302