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 = 0;
|
---|
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 | }
|
---|