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