]> git.proxmox.com Git - mirror_edk2.git/blob - StdLib/EfiSocketLib/UseEfiSocketLib.c
00396597b3bbee53ef5d3dd48f9eead13a5faa30
[mirror_edk2.git] / StdLib / EfiSocketLib / UseEfiSocketLib.c
1 /** @file
2 Implement the connection to the EFI socket library
3
4 Copyright (c) 2011, Intel Corporation. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "Socket.h"
10
11
12 /**
13 The following GUID values are only used when an application links
14 against EfiSocketLib. An alternative set of values exists in
15 SocketDxe\EntryUnload.c which the SocketDxe driver uses to coexist
16 with socket applications.
17
18 Tag GUID - IPv4 in use by an application using EfiSocketLib
19 **/
20 CONST EFI_GUID mEslIp4ServiceGuid __attribute__((weak)) = {
21 0x9c756011, 0x5d44, 0x4ee0, { 0xbc, 0xe7, 0xc3, 0x82, 0x18, 0xfe, 0x39, 0x8d }
22 };
23
24
25 /**
26 Tag GUID - IPv6 in use by an application using EfiSocketLib
27 **/
28 CONST EFI_GUID mEslIp6ServiceGuid __attribute__((weak)) = {
29 0xc51b2761, 0xc476, 0x45fe, { 0xbe, 0x61, 0xba, 0x4b, 0xcc, 0x32, 0xf2, 0x34 }
30 };
31
32
33 /**
34 Tag GUID - TCPv4 in use by an application using EfiSocketLib
35 **/
36 CONST EFI_GUID mEslTcp4ServiceGuid __attribute__((weak)) = {
37 0xffc659c2, 0x4ef2, 0x4532, { 0xb8, 0x75, 0xcd, 0x9a, 0xa4, 0x27, 0x4c, 0xde }
38 };
39
40
41 /**
42 Tag GUID - TCPv6 in use by an application using EfiSocketLib
43 **/
44 CONST EFI_GUID mEslTcp6ServiceGuid __attribute__((weak)) = {
45 0x279858a4, 0x4e9e, 0x4e53, { 0x93, 0x22, 0xf2, 0x54, 0xe0, 0x7e, 0xef, 0xd4 }
46 };
47
48
49 /**
50 Tag GUID - UDPv4 in use by an application using EfiSocketLib
51 **/
52 CONST EFI_GUID mEslUdp4ServiceGuid __attribute__((weak)) = {
53 0x44e03a55, 0x8d97, 0x4511, { 0xbf, 0xef, 0xa, 0x8b, 0xc6, 0x2c, 0x25, 0xae }
54 };
55
56
57 /**
58 Tag GUID - UDPv6 in use by an application using EfiSocketLib
59 **/
60 CONST EFI_GUID mEslUdp6ServiceGuid __attribute__((weak)) = {
61 0xaa4af677, 0x6efe, 0x477c, { 0x96, 0x68, 0xe8, 0x13, 0x9d, 0x2, 0xfd, 0x9b }
62 };
63
64
65 /**
66 Free the socket resources
67
68 This releases the socket resources allocated by calling
69 EslServiceGetProtocol.
70
71 This routine is called from the ::close routine in BsdSocketLib
72 to release the socket resources.
73
74 @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL
75 structure
76
77 @return Value for ::errno, zero (0) indicates success.
78
79 **/
80 int
81 EslServiceFreeProtocol (
82 IN EFI_SOCKET_PROTOCOL * pSocketProtocol
83 )
84 {
85 int RetVal;
86
87 //
88 // Release the socket resources
89 //
90 EslSocketFree ( pSocketProtocol, &RetVal );
91
92 //
93 // Return the operation status
94 //
95 return RetVal;
96 }
97
98
99 /**
100 Connect to the EFI socket library
101
102 This routine creates the ::ESL_SOCKET structure and returns
103 the API (::EFI_SOCKET_PROTOCOL address) to the socket file
104 system layer in BsdSocketLib.
105
106 This routine is called from the ::socket routine in BsdSocketLib
107 to create the data structure and initialize the API for a socket.
108 Note that this implementation is only used by socket applications
109 that link directly to EslSocketLib.
110
111 @param [in] ppSocketProtocol Address to receive the ::EFI_SOCKET_PROTOCOL
112 structure address
113
114 @return Value for ::errno, zero (0) indicates success.
115
116 **/
117 int
118 EslServiceGetProtocol (
119 IN EFI_SOCKET_PROTOCOL ** ppSocketProtocol
120 )
121 {
122 EFI_HANDLE ChildHandle;
123 ESL_SOCKET * pSocket;
124 int RetVal;
125 EFI_STATUS Status;
126
127 DBG_ENTER ( );
128
129 //
130 // Assume success
131 //
132 RetVal = 0;
133
134 //
135 // Locate the socket protocol
136 //
137 ChildHandle = NULL;
138 Status = EslSocketAllocate ( &ChildHandle,
139 DEBUG_SOCKET,
140 &pSocket );
141 if ( !EFI_ERROR ( Status )) {
142 *ppSocketProtocol = &pSocket->SocketProtocol;
143 }
144 else {
145 //
146 // No resources
147 //
148 RetVal = ENOMEM;
149 }
150
151 //
152 // Return the operation status
153 //
154 DBG_EXIT_DEC ( RetVal );
155 return RetVal;
156 }
157
158
159 /**
160 Connect to the network layer
161
162 This routine is the constructor for the EfiSocketLib when the
163 library is linked directly to an application. This routine
164 walks the ::cEslSocketBinding table to create ::ESL_SERVICE
165 structures, associated with the network adapters, which this
166 routine links to the ::ESL_LAYER structure.
167
168 This routine is called from ::EslConstructor as a result of the
169 constructor redirection in ::mpfnEslConstructor at the end of this
170 file.
171
172 @retval EFI_SUCCESS Successfully connected to the network layer
173
174 **/
175 EFI_STATUS
176 EslServiceNetworkConnect (
177 VOID
178 )
179 {
180 BOOLEAN bSomethingFound;
181 UINTN HandleCount;
182 UINTN Index;
183 CONST ESL_SOCKET_BINDING * pEnd;
184 EFI_HANDLE * pHandles;
185 CONST ESL_SOCKET_BINDING * pSocketBinding;
186 EFI_STATUS Status;
187
188 DBG_ENTER ( );
189
190 //
191 // Initialize the socket layer
192 //
193 Status = EFI_SUCCESS;
194 bSomethingFound = FALSE;
195 EslServiceLoad ( gImageHandle );
196
197 //
198 // Connect the network devices
199 //
200 pSocketBinding = &cEslSocketBinding[0];
201 pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
202 while ( pEnd > pSocketBinding ) {
203 //
204 // Attempt to locate the network adapters
205 //
206 HandleCount = 0;
207 pHandles = NULL;
208 Status = gBS->LocateHandleBuffer ( ByProtocol,
209 pSocketBinding->pNetworkBinding,
210 NULL,
211 &HandleCount,
212 &pHandles );
213 if ( EFI_ERROR ( Status )) {
214 DEBUG (( DEBUG_ERROR,
215 "ERROR with %s layer, Status: %r\r\n",
216 pSocketBinding->pName,
217 Status ));
218 }
219 else {
220 if ( NULL != pHandles ) {
221 //
222 // Attempt to connect to this network adapter
223 //
224 for ( Index = 0; HandleCount > Index; Index++ ) {
225 Status = EslServiceConnect ( gImageHandle,
226 pHandles[ Index ]);
227 if ( !EFI_ERROR ( Status )) {
228 bSomethingFound = TRUE;
229 }
230 else {
231 if ( EFI_OUT_OF_RESOURCES == Status ) {
232 //
233 // Pointless to continue without memory
234 //
235 break;
236 }
237 }
238 }
239
240 //
241 // Done with the handles
242 //
243 gBS->FreePool ( pHandles );
244 }
245 }
246
247 //
248 // Set the next network protocol
249 //
250 pSocketBinding += 1;
251 }
252
253 //
254 // Return the network connection status
255 //
256 if ( bSomethingFound ) {
257 Status = EFI_SUCCESS;
258 }
259 DBG_EXIT_STATUS ( Status );
260 return Status;
261 }
262
263
264 /**
265 Disconnect from the network layer
266
267 Destructor for the EfiSocketLib when the library is linked
268 directly to an application. This routine walks the
269 ::cEslSocketBinding table to remove the ::ESL_SERVICE
270 structures (network connections) from the ::ESL_LAYER structure.
271
272 This routine is called from ::EslDestructor as a result of the
273 destructor redirection in ::mpfnEslDestructor at the end of this
274 file.
275
276 @retval EFI_SUCCESS Successfully disconnected from the network layer
277
278 **/
279 EFI_STATUS
280 EslServiceNetworkDisconnect (
281 VOID
282 )
283 {
284 UINTN HandleCount;
285 UINTN Index;
286 CONST ESL_SOCKET_BINDING * pEnd;
287 EFI_HANDLE * pHandles;
288 CONST ESL_SOCKET_BINDING * pSocketBinding;
289 EFI_STATUS Status;
290
291 DBG_ENTER ( );
292
293 //
294 // Assume success
295 //
296 Status = EFI_SUCCESS;
297
298 //
299 // Disconnect the network devices
300 //
301 pSocketBinding = &cEslSocketBinding[0];
302 pEnd = &pSocketBinding[ cEslSocketBindingEntries ];
303 while ( pEnd > pSocketBinding ) {
304 //
305 // Attempt to locate the network adapters
306 //
307 HandleCount = 0;
308 pHandles = NULL;
309 Status = gBS->LocateHandleBuffer ( ByProtocol,
310 pSocketBinding->pNetworkBinding,
311 NULL,
312 &HandleCount,
313 &pHandles );
314 if (( !EFI_ERROR ( Status ))
315 && ( NULL != pHandles )) {
316 //
317 // Attempt to disconnect from this network adapter
318 //
319 for ( Index = 0; HandleCount > Index; Index++ ) {
320 Status = EslServiceDisconnect ( gImageHandle,
321 pHandles[ Index ]);
322 if ( EFI_ERROR ( Status )) {
323 break;
324 }
325 }
326
327 //
328 // Done with the handles
329 //
330 gBS->FreePool ( pHandles );
331 }
332
333 //
334 // Set the next network protocol
335 //
336 pSocketBinding += 1;
337 Status = EFI_SUCCESS;
338 }
339
340 //
341 // Finish the disconnect operation
342 //
343 if ( !EFI_ERROR ( Status )) {
344 EslServiceUnload ( );
345 }
346
347 //
348 // Return the network connection status
349 //
350 DBG_EXIT_STATUS ( Status );
351 return Status;
352 }
353
354
355 /**
356 Socket layer's service binding protocol delcaration.
357 **/
358 CONST EFI_SERVICE_BINDING_PROTOCOL mEfiServiceBinding __attribute__((weak)) = {
359 NULL,
360 NULL
361 };
362
363
364 /**
365 The following entries redirect the constructor and destructor
366 for any socket application that links against the EfiSocketLib.
367 Note that the SocketDxe driver uses different redirection.
368 **/
369 PFN_ESL_xSTRUCTOR mpfnEslConstructor __attribute__((weak)) = EslServiceNetworkConnect; ///< Constructor for EfiSocketLib
370 PFN_ESL_xSTRUCTOR mpfnEslDestructor __attribute__((weak)) = EslServiceNetworkDisconnect; ///< Destructor for EfiSocketLib