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