]> git.proxmox.com Git - mirror_edk2.git/blob - StdLib/BsdSocketLib/socket.c
3754a29eb0fda35715fc9ba3da89a4070aced209
[mirror_edk2.git] / StdLib / BsdSocketLib / socket.c
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 const struct fileops SocketOperations = {
19 BslSocketClose, // close
20 BslSocketRead, // read
21 BslSocketWrite, // write
22
23 //
24 // Not supported
25 //
26 fnullop_fcntl, // fcntl
27 BslSocketPoll, // poll
28 fnullop_flush, // flush
29
30 fbadop_stat, // stat
31 fbadop_ioctl, // ioctl
32 fbadop_delete, // delete
33 fbadop_rmdir, // rmdir
34 fbadop_mkdir, // mkdir
35 fbadop_rename, // rename
36
37 NULL // lseek
38 };
39
40
41 /**
42 Translate from the socket file descriptor to the socket protocol.
43
44 @param [in] s Socket file descriptor returned from ::socket.
45
46 @param [in] ppDescriptor Address to receive the descriptor structure
47 address for the file
48 @param [in] pErrno Address of the errno variable
49
50 @returns A pointer to the socket protocol structure or NULL if
51 an invalid file descriptor was passed in.
52
53 **/
54 EFI_SOCKET_PROTOCOL *
55 BslFdToSocketProtocol (
56 int s,
57 struct __filedes ** ppDescriptor,
58 int * pErrno
59 )
60 {
61 struct __filedes * pDescriptor;
62 EFI_SOCKET_PROTOCOL * pSocketProtocol;
63
64 //
65 // Assume failure
66 //
67 pSocketProtocol = NULL;
68
69 //
70 // Validate the file descriptor
71 //
72 if ( !ValidateFD ( s, TRUE )) {
73 //
74 // Bad file descriptor
75 //
76 *pErrno = EBADF;
77 }
78 else {
79 //
80 // Get the descriptor for the file
81 //
82 pDescriptor = &gMD->fdarray [ s ];
83
84 //
85 // Validate that the descriptor is associated with sockets
86 //
87 pSocketProtocol = BslValidateSocketFd ( pDescriptor, pErrno );
88 if (( NULL != ppDescriptor ) && ( NULL != pSocketProtocol )) {
89 *ppDescriptor = pDescriptor;
90 }
91 }
92
93 //
94 // Return the socket protocol
95 //
96 return pSocketProtocol;
97 }
98
99
100 /**
101 Build a file descriptor for a socket.
102
103 @param [in] pSocketProtocol Socket protocol structure address
104
105 @param [in] pErrno Address of the errno variable
106
107 @returns The file descriptor for the socket or -1 if an error occurs.
108
109 **/
110 int
111 BslSocketProtocolToFd (
112 IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
113 IN int * pErrno
114 )
115 {
116 int FileDescriptor;
117 struct __filedes * pDescriptor;
118
119 //
120 // Assume failure
121 //
122 FileDescriptor = -1;
123
124 //
125 // Locate a file descriptor
126 //
127 FileDescriptor = FindFreeFD ( VALID_CLOSED );
128 if( FileDescriptor < 0 ) {
129 //
130 // All available FDs are in use
131 //
132 errno = EMFILE;
133 }
134 else {
135 //
136 // Initialize the file descriptor
137 //
138 pDescriptor = &gMD->fdarray [ FileDescriptor ];
139 pDescriptor->f_offset = 0;
140 pDescriptor->f_flag = 0;
141 pDescriptor->f_iflags = DTYPE_SOCKET;
142 pDescriptor->MyFD = (UINT16)FileDescriptor;
143 pDescriptor->Oflags = 0;
144 pDescriptor->Omode = S_ACC_READ | S_ACC_WRITE;
145 pDescriptor->RefCount = 1;
146 FILE_SET_MATURE ( pDescriptor );
147
148 //
149 // Socket specific file descriptor initialization
150 //
151 pDescriptor->devdata = pSocketProtocol;
152 pDescriptor->f_ops = &SocketOperations;
153 }
154
155 //
156 // Return the socket's file descriptor
157 //
158 return FileDescriptor;
159 }
160
161
162 /**
163 Creates an endpoint for network communication.
164
165 The ::Socket routine initializes the communication endpoint by providing
166 the support for the socket library function ::socket. The
167 <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html">POSIX</a>
168 documentation for the socket routine is available online for reference.
169
170 @param [in] domain Select the family of protocols for the client or server
171 application.
172
173 @param [in] type Specifies how to make the network connection. The following values
174 are supported:
175 <ul>
176 <li>
177 SOCK_STREAM - Connect to TCP, provides a byte stream
178 that is manipluated by read, recv, send and write.
179 </li>
180 <li>
181 SOCK_SEQPACKET - Connect to TCP, provides sequenced packet stream
182 that is manipulated by read, recv, send and write.
183 </li>
184 <li>
185 SOCK_DGRAM - Connect to UDP, provides a datagram service that is
186 manipulated by recvfrom and sendto.
187 </li>
188 </ul>
189
190 @param [in] protocol Specifies the lower layer protocol to use. The following
191 values are supported:
192 <ul>
193 <li>IPPROTO_TCP</li> - This value must be combined with SOCK_STREAM.</li>
194 <li>IPPROTO_UDP</li> - This value must be combined with SOCK_DGRAM.</li>
195 </ul>
196
197 @returns This routine returns a file descriptor for the socket.
198
199 **/
200 INT32
201 socket (
202 IN INT32 domain,
203 IN INT32 type,
204 IN INT32 protocol
205 )
206 {
207 INT32 FileDescriptor;
208 EFI_SOCKET_PROTOCOL * pSocketProtocol;
209 EFI_STATUS Status;
210
211 //
212 // Assume failure
213 //
214 FileDescriptor = -1;
215
216 //
217 // Locate the socket protocol
218 //
219 errno = EslServiceGetProtocol ( &pSocketProtocol );
220 if ( 0 == errno ) {
221 //
222 // Initialize the socket
223 //
224 Status = pSocketProtocol->pfnSocket ( pSocketProtocol,
225 domain,
226 type,
227 protocol,
228 &errno );
229 if ( !EFI_ERROR ( Status ))
230 {
231 //
232 // Build the file descriptor for the socket
233 //
234 FileDescriptor = BslSocketProtocolToFd ( pSocketProtocol,
235 &errno );
236 }
237 }
238
239 //
240 // Return the socket's file descriptor
241 //
242 return FileDescriptor;
243 }
244
245
246 /**
247 Validate the socket's file descriptor
248
249 @param [in] pDescriptor Descriptor for the file
250
251 @param [in] pErrno Address of the errno variable
252
253 @returns A pointer to the socket protocol structure or NULL if
254 an invalid file descriptor was passed in.
255
256 **/
257 EFI_SOCKET_PROTOCOL *
258 BslValidateSocketFd (
259 struct __filedes * pDescriptor,
260 int * pErrno
261 )
262 {
263 EFI_SOCKET_PROTOCOL * pSocketProtocol;
264
265 //
266 // Assume failure
267 //
268 *pErrno = ENOTSOCK;
269 pSocketProtocol = NULL;
270
271 //
272 // Validate that the descriptor is associated with sockets
273 //
274 if ( DTYPE_SOCKET == ( pDescriptor->f_iflags & DTYPE_MASK )) {
275 //
276 // Locate the socket protocol
277 //
278 pSocketProtocol = pDescriptor->devdata;
279 *pErrno = 0;
280 }
281
282 //
283 // Return the socket protocol
284 //
285 return pSocketProtocol;
286 }