1 /** @file
2   UEFI HTTP boot driver's private data structure and interfaces declaration.
3 
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 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 #ifndef __EFI_HTTP_BOOT_DXE_H__
16 #define __EFI_HTTP_BOOT_DXE_H__
17 
18 #include <Uefi.h>
19 
20 //
21 // Libraries
22 //
23 #include <Library/UefiBootServicesTableLib.h>
24 #include <Library/MemoryAllocationLib.h>
25 #include <Library/BaseLib.h>
26 #include <Library/UefiLib.h>
27 #include <Library/DevicePathLib.h>
28 #include <Library/DebugLib.h>
29 #include <Library/NetLib.h>
30 #include <Library/HttpLib.h>
31 
32 //
33 // UEFI Driver Model Protocols
34 //
35 #include <Protocol/DriverBinding.h>
36 #include <Protocol/ComponentName2.h>
37 #include <Protocol/ComponentName.h>
38 
39 //
40 // Consumed Protocols
41 //
42 #include <Protocol/NetworkInterfaceIdentifier.h>
43 #include <Protocol/Dhcp4.h>
44 #include <Protocol/Dhcp6.h>
45 #include <Protocol/Dns6.h>
46 #include <Protocol/Http.h>
47 #include <Protocol/Ip4Config2.h>
48 #include <Protocol/Ip6Config.h>
49 //
50 // Produced Protocols
51 //
52 #include <Protocol/LoadFile.h>
53 
54 //
55 // Driver Version
56 //
57 #define HTTP_BOOT_DXE_VERSION  0xa
58 
59 //
60 // Protocol instances
61 //
62 extern EFI_DRIVER_BINDING_PROTOCOL  gHttpBootDxeDriverBinding;
63 extern EFI_COMPONENT_NAME2_PROTOCOL gHttpBootDxeComponentName2;
64 extern EFI_COMPONENT_NAME_PROTOCOL  gHttpBootDxeComponentName;
65 
66 //
67 // Private data structure
68 //
69 typedef struct _HTTP_BOOT_PRIVATE_DATA      HTTP_BOOT_PRIVATE_DATA;
70 typedef struct _HTTP_BOOT_VIRTUAL_NIC       HTTP_BOOT_VIRTUAL_NIC;
71 
72 //
73 // Include files with internal function prototypes
74 //
75 #include "HttpBootComponentName.h"
76 #include "HttpBootDhcp4.h"
77 #include "HttpBootDhcp6.h"
78 #include "HttpBootImpl.h"
79 #include "HttpBootSupport.h"
80 #include "HttpBootClient.h"
81 
82 typedef union {
83   HTTP_BOOT_DHCP4_PACKET_CACHE              Dhcp4;
84   HTTP_BOOT_DHCP6_PACKET_CACHE              Dhcp6;
85 } HTTP_BOOT_DHCP_PACKET_CACHE;
86 
87 struct _HTTP_BOOT_VIRTUAL_NIC {
88   UINT32                                    Signature;
89   EFI_HANDLE                                Controller;
90   EFI_LOAD_FILE_PROTOCOL                    LoadFile;
91   EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
92   HTTP_BOOT_PRIVATE_DATA                    *Private;
93 };
94 
95 struct _HTTP_BOOT_PRIVATE_DATA {
96   UINT32                                    Signature;
97   EFI_HANDLE                                Controller;
98   EFI_HANDLE                                Image;
99 
100   HTTP_BOOT_VIRTUAL_NIC                     *Ip4Nic;
101   HTTP_BOOT_VIRTUAL_NIC                     *Ip6Nic;
102 
103   //
104   // Cousumed children
105   //
106   EFI_HANDLE                                Ip6Child;
107   EFI_HANDLE                                Dhcp4Child;
108   EFI_HANDLE                                Dhcp6Child;
109   HTTP_IO                                   HttpIo;
110   BOOLEAN                                   HttpCreated;
111 
112   //
113   // Consumed protocol
114   //
115   EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;
116   EFI_IP6_PROTOCOL                          *Ip6;
117   EFI_IP4_CONFIG2_PROTOCOL                  *Ip4Config2;
118   EFI_IP6_CONFIG_PROTOCOL                   *Ip6Config;
119   EFI_DHCP4_PROTOCOL                        *Dhcp4;
120   EFI_DHCP6_PROTOCOL                        *Dhcp6;
121   EFI_DEVICE_PATH_PROTOCOL                  *ParentDevicePath;
122 
123 
124   //
125   // Produced protocol
126   //
127   EFI_LOAD_FILE_PROTOCOL                    LoadFile;
128   EFI_DEVICE_PATH_PROTOCOL                  *DevicePath;
129   UINT32                                    Id;
130 
131   //
132   // Mode data
133   //
134   BOOLEAN                                   UsingIpv6;
135   BOOLEAN                                   Started;
136   EFI_IP_ADDRESS                            StationIp;
137   EFI_IP_ADDRESS                            SubnetMask;
138   EFI_IP_ADDRESS                            GatewayIp;
139   EFI_IP_ADDRESS                            ServerIp;
140   UINT16                                    Port;
141   CHAR8                                     *BootFileUri;
142   VOID                                      *BootFileUriParser;
143   UINTN                                     BootFileSize;
144   BOOLEAN                                   NoGateway;
145 
146   //
147   // Cached HTTP data
148   //
149   LIST_ENTRY                                CacheList;
150 
151   //
152   // Cached DHCP offer
153   //
154   // OfferIndex records the index of DhcpOffer[] buffer, and OfferCount records the num of each type of offer.
155   //
156   // It supposed that
157   //
158   //   OfferNum:    8
159   //   OfferBuffer: [ProxyNameUri, DhcpNameUri, DhcpIpUri, ProxyNameUri, ProxyIpUri, DhcpOnly, DhcpIpUri, DhcpNameUriDns]
160   //   (OfferBuffer is 0-based.)
161   //
162   // And assume that (DhcpIpUri is the first priority actually.)
163   //
164   //   SelectIndex:     5
165   //   SelectProxyType: HttpOfferTypeProxyIpUri
166   //   (SelectIndex is 1-based, and 0 means no one is selected.)
167   //
168   // So it should be
169   //
170   //                 DhcpIpUri  DhcpNameUriDns  DhcpDns  DhcpOnly  ProxyNameUri  ProxyIpUri  DhcpNameUri
171   //   OfferCount:  [       2,              1,       0,        1,            2,          1,            1]
172   //
173   //   OfferIndex: {[       2,              7,       0,        5,            0,         *4,            1]
174   //                [       6,              0,       0,        0,            3,          0,            0]
175   //                [       0,              0,       0,        0,            0,          0,            0]
176   //                ...                                                                                 ]}
177   //   (OfferIndex is 0-based.)
178   //
179   //
180   UINT32                                    SelectIndex;
181   UINT32                                    SelectProxyType;
182   HTTP_BOOT_DHCP_PACKET_CACHE               OfferBuffer[HTTP_BOOT_OFFER_MAX_NUM];
183   UINT32                                    OfferNum;
184   UINT32                                    OfferCount[HttpOfferTypeMax];
185   UINT32                                    OfferIndex[HttpOfferTypeMax][HTTP_BOOT_OFFER_MAX_NUM];
186 };
187 
188 #define HTTP_BOOT_PRIVATE_DATA_SIGNATURE          SIGNATURE_32 ('H', 'B', 'P', 'D')
189 #define HTTP_BOOT_VIRTUAL_NIC_SIGNATURE           SIGNATURE_32 ('H', 'B', 'V', 'N')
190 #define HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE(a)   CR (a, HTTP_BOOT_PRIVATE_DATA, LoadFile, HTTP_BOOT_PRIVATE_DATA_SIGNATURE)
191 #define HTTP_BOOT_PRIVATE_DATA_FROM_ID(a)         CR (a, HTTP_BOOT_PRIVATE_DATA, Id, HTTP_BOOT_PRIVATE_DATA_SIGNATURE)
192 #define HTTP_BOOT_VIRTUAL_NIC_FROM_LOADFILE(a)    CR (a, HTTP_BOOT_VIRTUAL_NIC, LoadFile, HTTP_BOOT_VIRTUAL_NIC_SIGNATURE)
193 extern EFI_LOAD_FILE_PROTOCOL               gHttpBootDxeLoadFile;
194 
195 /**
196   Tests to see if this driver supports a given controller. If a child device is provided,
197   it further tests to see if this driver supports creating a handle for the specified child device.
198 
199   This function checks to see if the driver specified by This supports the device specified by
200   ControllerHandle. Drivers will typically use the device path attached to
201   ControllerHandle and/or the services from the bus I/O abstraction attached to
202   ControllerHandle to determine if the driver supports ControllerHandle. This function
203   may be called many times during platform initialization. In order to reduce boot times, the tests
204   performed by this function must be very small, and take as little time as possible to execute. This
205   function must not change the state of any hardware devices, and this function must be aware that the
206   device specified by ControllerHandle may already be managed by the same driver or a
207   different driver. This function must match its calls to AllocatePages() with FreePages(),
208   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
209   Because ControllerHandle may have been previously started by the same driver, if a protocol is
210   already in the opened state, then it must not be closed with CloseProtocol(). This is required
211   to guarantee the state of ControllerHandle is not modified by this function.
212 
213   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
214   @param[in]  ControllerHandle     The handle of the controller to test. This handle
215                                    must support a protocol interface that supplies
216                                    an I/O abstraction to the driver.
217   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
218                                    parameter is ignored by device drivers, and is optional for bus
219                                    drivers. For bus drivers, if this parameter is not NULL, then
220                                    the bus driver must determine if the bus controller specified
221                                    by ControllerHandle and the child controller specified
222                                    by RemainingDevicePath are both supported by this
223                                    bus driver.
224 
225   @retval EFI_SUCCESS              The device specified by ControllerHandle and
226                                    RemainingDevicePath is supported by the driver specified by This.
227   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
228                                    RemainingDevicePath is already being managed by the driver
229                                    specified by This.
230   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
231                                    RemainingDevicePath is already being managed by a different
232                                    driver or an application that requires exclusive access.
233                                    Currently not implemented.
234   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
235                                    RemainingDevicePath is not supported by the driver specified by This.
236 **/
237 EFI_STATUS
238 EFIAPI
239 HttpBootIp4DxeDriverBindingSupported (
240   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
241   IN EFI_HANDLE                   ControllerHandle,
242   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
243   );
244 
245 /**
246   Starts a device controller or a bus controller.
247 
248   The Start() function is designed to be invoked from the EFI boot service ConnectController().
249   As a result, much of the error checking on the parameters to Start() has been moved into this
250   common boot service. It is legal to call Start() from other locations,
251   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
252   1. ControllerHandle must be a valid EFI_HANDLE.
253   2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
254      EFI_DEVICE_PATH_PROTOCOL.
255   3. Prior to calling Start(), the Supported() function for the driver specified by This must
256      have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
257 
258   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
259   @param[in]  ControllerHandle     The handle of the controller to start. This handle
260                                    must support a protocol interface that supplies
261                                    an I/O abstraction to the driver.
262   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
263                                    parameter is ignored by device drivers, and is optional for bus
264                                    drivers. For a bus driver, if this parameter is NULL, then handles
265                                    for all the children of Controller are created by this driver.
266                                    If this parameter is not NULL and the first Device Path Node is
267                                    not the End of Device Path Node, then only the handle for the
268                                    child device specified by the first Device Path Node of
269                                    RemainingDevicePath is created by this driver.
270                                    If the first Device Path Node of RemainingDevicePath is
271                                    the End of Device Path Node, no child handle is created by this
272                                    driver.
273 
274   @retval EFI_SUCCESS              The device was started.
275   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
276   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
277   @retval Others                   The driver failded to start the device.
278 
279 **/
280 EFI_STATUS
281 EFIAPI
282 HttpBootIp4DxeDriverBindingStart (
283   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
284   IN EFI_HANDLE                   ControllerHandle,
285   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
286   );
287 
288 /**
289   Stops a device controller or a bus controller.
290 
291   The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
292   As a result, much of the error checking on the parameters to Stop() has been moved
293   into this common boot service. It is legal to call Stop() from other locations,
294   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
295   1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
296      same driver's Start() function.
297   2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
298      EFI_HANDLE. In addition, all of these handles must have been created in this driver's
299      Start() function, and the Start() function must have called OpenProtocol() on
300      ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
301 
302   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
303   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
304                                 support a bus specific I/O protocol for the driver
305                                 to use to stop the device.
306   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
307   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
308                                 if NumberOfChildren is 0.
309 
310   @retval EFI_SUCCESS           The device was stopped.
311   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
312 
313 **/
314 EFI_STATUS
315 EFIAPI
316 HttpBootIp4DxeDriverBindingStop (
317   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
318   IN EFI_HANDLE                   ControllerHandle,
319   IN UINTN                        NumberOfChildren,
320   IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
321   );
322 
323 /**
324   Tests to see if this driver supports a given controller. If a child device is provided,
325   it further tests to see if this driver supports creating a handle for the specified child device.
326 
327   This function checks to see if the driver specified by This supports the device specified by
328   ControllerHandle. Drivers will typically use the device path attached to
329   ControllerHandle and/or the services from the bus I/O abstraction attached to
330   ControllerHandle to determine if the driver supports ControllerHandle. This function
331   may be called many times during platform initialization. In order to reduce boot times, the tests
332   performed by this function must be very small, and take as little time as possible to execute. This
333   function must not change the state of any hardware devices, and this function must be aware that the
334   device specified by ControllerHandle may already be managed by the same driver or a
335   different driver. This function must match its calls to AllocatePages() with FreePages(),
336   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
337   Because ControllerHandle may have been previously started by the same driver, if a protocol is
338   already in the opened state, then it must not be closed with CloseProtocol(). This is required
339   to guarantee the state of ControllerHandle is not modified by this function.
340 
341   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
342   @param[in]  ControllerHandle     The handle of the controller to test. This handle
343                                    must support a protocol interface that supplies
344                                    an I/O abstraction to the driver.
345   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
346                                    parameter is ignored by device drivers, and is optional for bus
347                                    drivers. For bus drivers, if this parameter is not NULL, then
348                                    the bus driver must determine if the bus controller specified
349                                    by ControllerHandle and the child controller specified
350                                    by RemainingDevicePath are both supported by this
351                                    bus driver.
352 
353   @retval EFI_SUCCESS              The device specified by ControllerHandle and
354                                    RemainingDevicePath is supported by the driver specified by This.
355   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
356                                    RemainingDevicePath is already being managed by the driver
357                                    specified by This.
358   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
359                                    RemainingDevicePath is already being managed by a different
360                                    driver or an application that requires exclusive access.
361                                    Currently not implemented.
362   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
363                                    RemainingDevicePath is not supported by the driver specified by This.
364 **/
365 EFI_STATUS
366 EFIAPI
367 HttpBootIp6DxeDriverBindingSupported (
368   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
369   IN EFI_HANDLE                   ControllerHandle,
370   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
371   );
372 
373 /**
374   Starts a device controller or a bus controller.
375 
376   The Start() function is designed to be invoked from the EFI boot service ConnectController().
377   As a result, much of the error checking on the parameters to Start() has been moved into this
378   common boot service. It is legal to call Start() from other locations,
379   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
380   1. ControllerHandle must be a valid EFI_HANDLE.
381   2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
382      EFI_DEVICE_PATH_PROTOCOL.
383   3. Prior to calling Start(), the Supported() function for the driver specified by This must
384      have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
385 
386   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
387   @param[in]  ControllerHandle     The handle of the controller to start. This handle
388                                    must support a protocol interface that supplies
389                                    an I/O abstraction to the driver.
390   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
391                                    parameter is ignored by device drivers, and is optional for bus
392                                    drivers. For a bus driver, if this parameter is NULL, then handles
393                                    for all the children of Controller are created by this driver.
394                                    If this parameter is not NULL and the first Device Path Node is
395                                    not the End of Device Path Node, then only the handle for the
396                                    child device specified by the first Device Path Node of
397                                    RemainingDevicePath is created by this driver.
398                                    If the first Device Path Node of RemainingDevicePath is
399                                    the End of Device Path Node, no child handle is created by this
400                                    driver.
401 
402   @retval EFI_SUCCESS              The device was started.
403   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
404   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
405   @retval Others                   The driver failded to start the device.
406 
407 **/
408 EFI_STATUS
409 EFIAPI
410 HttpBootIp6DxeDriverBindingStart (
411   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
412   IN EFI_HANDLE                   ControllerHandle,
413   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
414   );
415 
416 /**
417   Stops a device controller or a bus controller.
418 
419   The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
420   As a result, much of the error checking on the parameters to Stop() has been moved
421   into this common boot service. It is legal to call Stop() from other locations,
422   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
423   1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
424      same driver's Start() function.
425   2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
426      EFI_HANDLE. In addition, all of these handles must have been created in this driver's
427      Start() function, and the Start() function must have called OpenProtocol() on
428      ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
429 
430   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
431   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
432                                 support a bus specific I/O protocol for the driver
433                                 to use to stop the device.
434   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
435   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
436                                 if NumberOfChildren is 0.
437 
438   @retval EFI_SUCCESS           The device was stopped.
439   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
440 
441 **/
442 EFI_STATUS
443 EFIAPI
444 HttpBootIp6DxeDriverBindingStop (
445   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
446   IN EFI_HANDLE                   ControllerHandle,
447   IN UINTN                        NumberOfChildren,
448   IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
449   );
450 #endif
451