8fa2e58431
- Add shim-httpboot-support.patch to support HTTPBoot - Add shim-update-openssl-1.0.2g.patch to update openssl to 1.0.2g and Cryptlib to 5e2318dd37a51948aaf845c7d920b11f47cdcfe6 - Drop patches since they are merged into shim-update-openssl-1.0.2g.patch + shim-update-openssl-1.0.2d.patch + shim-gcc5.patch + shim-bsc950569-fix-cryptlib-va-functions.patch + shim-fix-aarch64.patch - Refresh shim-change-debug-file-path.patch - Add shim-bsc973496-mokmanager-no-append-write.patch to work around the firmware that doesn't support APPEND_WRITE (bsc973496) - shim-install : remove '\n' from the help message (bsc#991188) - shim-install : print a message if there is no valid EFI partition (bsc#991187) OBS-URL: https://build.opensuse.org/request/show/416362 OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory/shim?expand=0&rev=115
2220 lines
76 KiB
Diff
2220 lines
76 KiB
Diff
From fa1e44d19d6a622241b5411039421976c674bd0f Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Tue, 13 Oct 2015 18:18:25 +0800
|
|
Subject: [PATCH 1/3] Make translate_slashes() public
|
|
|
|
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
|
|
---
|
|
include/str.h | 20 ++++++++++++++++++++
|
|
netboot.c | 18 ------------------
|
|
2 files changed, 20 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/include/str.h b/include/str.h
|
|
index 0f3e003..9a74836 100644
|
|
--- a/include/str.h
|
|
+++ b/include/str.h
|
|
@@ -42,4 +42,24 @@ strcata(CHAR8 *dest, const CHAR8 *src)
|
|
return dest;
|
|
}
|
|
|
|
+static inline
|
|
+__attribute__((unused))
|
|
+CHAR8 *
|
|
+translate_slashes(char *str)
|
|
+{
|
|
+ int i;
|
|
+ int j;
|
|
+ if (str == NULL)
|
|
+ return (CHAR8 *)str;
|
|
+
|
|
+ for (i = 0, j = 0; str[i] != '\0'; i++, j++) {
|
|
+ if (str[i] == '\\') {
|
|
+ str[j] = '/';
|
|
+ if (str[i+1] == '\\')
|
|
+ i++;
|
|
+ }
|
|
+ }
|
|
+ return (CHAR8 *)str;
|
|
+}
|
|
+
|
|
#endif /* SHIM_STR_H */
|
|
diff --git a/netboot.c b/netboot.c
|
|
index ad5d37e..1cc1a2b 100644
|
|
--- a/netboot.c
|
|
+++ b/netboot.c
|
|
@@ -54,24 +54,6 @@ typedef struct {
|
|
UINT8 Data[1];
|
|
} EFI_DHCP6_PACKET_OPTION;
|
|
|
|
-static CHAR8 *
|
|
-translate_slashes(char *str)
|
|
-{
|
|
- int i;
|
|
- int j;
|
|
- if (str == NULL)
|
|
- return (CHAR8 *)str;
|
|
-
|
|
- for (i = 0, j = 0; str[i] != '\0'; i++, j++) {
|
|
- if (str[i] == '\\') {
|
|
- str[j] = '/';
|
|
- if (str[i+1] == '\\')
|
|
- i++;
|
|
- }
|
|
- }
|
|
- return (CHAR8 *)str;
|
|
-}
|
|
-
|
|
/*
|
|
* usingNetboot
|
|
* Returns TRUE if we identify a protocol that is enabled and Providing us with
|
|
--
|
|
2.7.1
|
|
|
|
|
|
From 6d6091c59660435e76a922daa76891928c878ae6 Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Wed, 14 Oct 2015 16:59:22 +0800
|
|
Subject: [PATCH 2/3] Add HTTP and IpConfig headers
|
|
|
|
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
|
|
---
|
|
include/Http.h | 517 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
include/Ip4Config2.h | 315 +++++++++++++++++++++++++++++++
|
|
include/Ip6Config.h | 366 ++++++++++++++++++++++++++++++++++++
|
|
3 files changed, 1198 insertions(+)
|
|
create mode 100644 include/Http.h
|
|
create mode 100644 include/Ip4Config2.h
|
|
create mode 100644 include/Ip6Config.h
|
|
|
|
diff --git a/include/Http.h b/include/Http.h
|
|
new file mode 100644
|
|
index 0000000..cd77703
|
|
--- /dev/null
|
|
+++ b/include/Http.h
|
|
@@ -0,0 +1,517 @@
|
|
+/** @file
|
|
+ This file defines the EFI HTTP Protocol interface. It is split into
|
|
+ the following two main sections:
|
|
+ HTTP Service Binding Protocol (HTTPSB)
|
|
+ HTTP Protocol (HTTP)
|
|
+
|
|
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
|
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
|
|
+ This program and the accompanying materials
|
|
+ are licensed and made available under the terms and conditions of the BSD License
|
|
+ which accompanies this distribution. The full text of the license may be found at
|
|
+ http://opensource.org/licenses/bsd-license.php
|
|
+
|
|
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
+
|
|
+ @par Revision Reference:
|
|
+ This Protocol is introduced in UEFI Specification 2.5
|
|
+
|
|
+**/
|
|
+
|
|
+#ifndef __EFI_HTTP_PROTOCOL_H__
|
|
+#define __EFI_HTTP_PROTOCOL_H__
|
|
+
|
|
+#define EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID \
|
|
+ { \
|
|
+ 0xbdc8e6af, 0xd9bc, 0x4379, {0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c } \
|
|
+ }
|
|
+
|
|
+#define EFI_HTTP_PROTOCOL_GUID \
|
|
+ { \
|
|
+ 0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b } \
|
|
+ }
|
|
+
|
|
+typedef struct _EFI_HTTP_PROTOCOL EFI_HTTP_PROTOCOL;
|
|
+
|
|
+///
|
|
+/// EFI_HTTP_VERSION
|
|
+///
|
|
+typedef enum {
|
|
+ HttpVersion10,
|
|
+ HttpVersion11,
|
|
+ HttpVersionUnsupported
|
|
+} EFI_HTTP_VERSION;
|
|
+
|
|
+///
|
|
+/// EFI_HTTP_METHOD
|
|
+///
|
|
+typedef enum {
|
|
+ HttpMethodGet,
|
|
+ HttpMethodPost,
|
|
+ HttpMethodPatch,
|
|
+ HttpMethodOptions,
|
|
+ HttpMethodConnect,
|
|
+ HttpMethodHead,
|
|
+ HttpMethodPut,
|
|
+ HttpMethodDelete,
|
|
+ HttpMethodTrace,
|
|
+ HttpMethodMax
|
|
+} EFI_HTTP_METHOD;
|
|
+
|
|
+///
|
|
+/// EFI_HTTP_STATUS_CODE
|
|
+///
|
|
+typedef enum {
|
|
+ HTTP_STATUS_UNSUPPORTED_STATUS = 0,
|
|
+ HTTP_STATUS_100_CONTINUE,
|
|
+ HTTP_STATUS_101_SWITCHING_PROTOCOLS,
|
|
+ HTTP_STATUS_200_OK,
|
|
+ HTTP_STATUS_201_CREATED,
|
|
+ HTTP_STATUS_202_ACCEPTED,
|
|
+ HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION,
|
|
+ HTTP_STATUS_204_NO_CONTENT,
|
|
+ HTTP_STATUS_205_RESET_CONTENT,
|
|
+ HTTP_STATUS_206_PARTIAL_CONTENT,
|
|
+ HTTP_STATUS_300_MULTIPLE_CHIOCES,
|
|
+ HTTP_STATUS_301_MOVED_PERMANENTLY,
|
|
+ HTTP_STATUS_302_FOUND,
|
|
+ HTTP_STATUS_303_SEE_OTHER,
|
|
+ HTTP_STATUS_304_NOT_MODIFIED,
|
|
+ HTTP_STATUS_305_USE_PROXY,
|
|
+ HTTP_STATUS_307_TEMPORARY_REDIRECT,
|
|
+ HTTP_STATUS_400_BAD_REQUEST,
|
|
+ HTTP_STATUS_401_UNAUTHORIZED,
|
|
+ HTTP_STATUS_402_PAYMENT_REQUIRED,
|
|
+ HTTP_STATUS_403_FORBIDDEN,
|
|
+ HTTP_STATUS_404_NOT_FOUND,
|
|
+ HTTP_STATUS_405_METHOD_NOT_ALLOWED,
|
|
+ HTTP_STATUS_406_NOT_ACCEPTABLE,
|
|
+ HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED,
|
|
+ HTTP_STATUS_408_REQUEST_TIME_OUT,
|
|
+ HTTP_STATUS_409_CONFLICT,
|
|
+ HTTP_STATUS_410_GONE,
|
|
+ HTTP_STATUS_411_LENGTH_REQUIRED,
|
|
+ HTTP_STATUS_412_PRECONDITION_FAILED,
|
|
+ HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE,
|
|
+ HTTP_STATUS_414_REQUEST_URI_TOO_LARGE,
|
|
+ HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE,
|
|
+ HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED,
|
|
+ HTTP_STATUS_417_EXPECTATION_FAILED,
|
|
+ HTTP_STATUS_500_INTERNAL_SERVER_ERROR,
|
|
+ HTTP_STATUS_501_NOT_IMPLEMENTED,
|
|
+ HTTP_STATUS_502_BAD_GATEWAY,
|
|
+ HTTP_STATUS_503_SERVICE_UNAVAILABLE,
|
|
+ HTTP_STATUS_504_GATEWAY_TIME_OUT,
|
|
+ HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED
|
|
+} EFI_HTTP_STATUS_CODE;
|
|
+
|
|
+///
|
|
+/// EFI_HTTPv4_ACCESS_POINT
|
|
+///
|
|
+typedef struct {
|
|
+ ///
|
|
+ /// Set to TRUE to instruct the EFI HTTP instance to use the default address
|
|
+ /// information in every TCP connection made by this instance. In addition, when set
|
|
+ /// to TRUE, LocalAddress and LocalSubnet are ignored.
|
|
+ ///
|
|
+ BOOLEAN UseDefaultAddress;
|
|
+ ///
|
|
+ /// If UseDefaultAddress is set to FALSE, this defines the local IP address to be
|
|
+ /// used in every TCP connection opened by this instance.
|
|
+ ///
|
|
+ EFI_IPv4_ADDRESS LocalAddress;
|
|
+ ///
|
|
+ /// If UseDefaultAddress is set to FALSE, this defines the local subnet to be used
|
|
+ /// in every TCP connection opened by this instance.
|
|
+ ///
|
|
+ EFI_IPv4_ADDRESS LocalSubnet;
|
|
+ ///
|
|
+ /// This defines the local port to be used in
|
|
+ /// every TCP connection opened by this instance.
|
|
+ ///
|
|
+ UINT16 LocalPort;
|
|
+} EFI_HTTPv4_ACCESS_POINT;
|
|
+
|
|
+///
|
|
+/// EFI_HTTPv6_ACCESS_POINT
|
|
+///
|
|
+typedef struct {
|
|
+ ///
|
|
+ /// Local IP address to be used in every TCP connection opened by this instance.
|
|
+ ///
|
|
+ EFI_IPv6_ADDRESS LocalAddress;
|
|
+ ///
|
|
+ /// Local port to be used in every TCP connection opened by this instance.
|
|
+ ///
|
|
+ UINT16 LocalPort;
|
|
+} EFI_HTTPv6_ACCESS_POINT;
|
|
+
|
|
+///
|
|
+/// EFI_HTTP_CONFIG_DATA_ACCESS_POINT
|
|
+///
|
|
+
|
|
+
|
|
+typedef struct {
|
|
+ ///
|
|
+ /// HTTP version that this instance will support.
|
|
+ ///
|
|
+ EFI_HTTP_VERSION HttpVersion;
|
|
+ ///
|
|
+ /// Time out (in milliseconds) when blocking for requests.
|
|
+ ///
|
|
+ UINT32 TimeOutMillisec;
|
|
+ ///
|
|
+ /// Defines behavior of EFI DNS and TCP protocols consumed by this instance. If
|
|
+ /// FALSE, this instance will use EFI_DNS4_PROTOCOL and EFI_TCP4_PROTOCOL. If TRUE,
|
|
+ /// this instance will use EFI_DNS6_PROTOCOL and EFI_TCP6_PROTOCOL.
|
|
+ ///
|
|
+ BOOLEAN LocalAddressIsIPv6;
|
|
+
|
|
+ union {
|
|
+ ///
|
|
+ /// When LocalAddressIsIPv6 is FALSE, this points to the local address, subnet, and
|
|
+ /// port used by the underlying TCP protocol.
|
|
+ ///
|
|
+ EFI_HTTPv4_ACCESS_POINT *IPv4Node;
|
|
+ ///
|
|
+ /// When LocalAddressIsIPv6 is TRUE, this points to the local IPv6 address and port
|
|
+ /// used by the underlying TCP protocol.
|
|
+ ///
|
|
+ EFI_HTTPv6_ACCESS_POINT *IPv6Node;
|
|
+ } AccessPoint;
|
|
+} EFI_HTTP_CONFIG_DATA;
|
|
+
|
|
+///
|
|
+/// EFI_HTTP_REQUEST_DATA
|
|
+///
|
|
+typedef struct {
|
|
+ ///
|
|
+ /// The HTTP method (e.g. GET, POST) for this HTTP Request.
|
|
+ ///
|
|
+ EFI_HTTP_METHOD Method;
|
|
+ ///
|
|
+ /// The URI of a remote host. From the information in this field, the HTTP instance
|
|
+ /// will be able to determine whether to use HTTP or HTTPS and will also be able to
|
|
+ /// determine the port number to use. If no port number is specified, port 80 (HTTP)
|
|
+ /// is assumed. See RFC 3986 for more details on URI syntax.
|
|
+ ///
|
|
+ CHAR16 *Url;
|
|
+} EFI_HTTP_REQUEST_DATA;
|
|
+
|
|
+///
|
|
+/// EFI_HTTP_RESPONSE_DATA
|
|
+///
|
|
+typedef struct {
|
|
+ ///
|
|
+ /// Response status code returned by the remote host.
|
|
+ ///
|
|
+ EFI_HTTP_STATUS_CODE StatusCode;
|
|
+} EFI_HTTP_RESPONSE_DATA;
|
|
+
|
|
+///
|
|
+/// EFI_HTTP_HEADER
|
|
+///
|
|
+typedef struct {
|
|
+ ///
|
|
+ /// Null terminated string which describes a field name. See RFC 2616 Section 14 for
|
|
+ /// detailed information about field names.
|
|
+ ///
|
|
+ CHAR8 *FieldName;
|
|
+ ///
|
|
+ /// Null terminated string which describes the corresponding field value. See RFC 2616
|
|
+ /// Section 14 for detailed information about field values.
|
|
+ ///
|
|
+ CHAR8 *FieldValue;
|
|
+} EFI_HTTP_HEADER;
|
|
+
|
|
+///
|
|
+/// EFI_HTTP_MESSAGE
|
|
+///
|
|
+typedef struct {
|
|
+ ///
|
|
+ /// HTTP message data.
|
|
+ ///
|
|
+ union {
|
|
+ ///
|
|
+ /// When the token is used to send a HTTP request, Request is a pointer to storage that
|
|
+ /// contains such data as URL and HTTP method.
|
|
+ ///
|
|
+ EFI_HTTP_REQUEST_DATA *Request;
|
|
+ ///
|
|
+ /// When used to await a response, Response points to storage containing HTTP response
|
|
+ /// status code.
|
|
+ ///
|
|
+ EFI_HTTP_RESPONSE_DATA *Response;
|
|
+ } Data;
|
|
+ ///
|
|
+ /// Number of HTTP header structures in Headers list. On request, this count is
|
|
+ /// provided by the caller. On response, this count is provided by the HTTP driver.
|
|
+ ///
|
|
+ UINTN HeaderCount;
|
|
+ ///
|
|
+ /// Array containing list of HTTP headers. On request, this array is populated by the
|
|
+ /// caller. On response, this array is allocated and populated by the HTTP driver. It
|
|
+ /// is the responsibility of the caller to free this memory on both request and
|
|
+ /// response.
|
|
+ ///
|
|
+ EFI_HTTP_HEADER *Headers;
|
|
+ ///
|
|
+ /// Length in bytes of the HTTP body. This can be zero depending on the HttpMethod type.
|
|
+ ///
|
|
+ UINTN BodyLength;
|
|
+ ///
|
|
+ /// Body associated with the HTTP request or response. This can be NULL depending on
|
|
+ /// the HttpMethod type.
|
|
+ ///
|
|
+ VOID *Body;
|
|
+} EFI_HTTP_MESSAGE;
|
|
+
|
|
+
|
|
+///
|
|
+/// EFI_HTTP_TOKEN
|
|
+///
|
|
+typedef struct {
|
|
+ ///
|
|
+ /// This Event will be signaled after the Status field is updated by the EFI HTTP
|
|
+ /// Protocol driver. The type of Event must be EFI_NOTIFY_SIGNAL. The Task Priority
|
|
+ /// Level (TPL) of Event must be lower than or equal to TPL_CALLBACK.
|
|
+ ///
|
|
+ EFI_EVENT Event;
|
|
+ ///
|
|
+ /// Status will be set to one of the following value if the HTTP request is
|
|
+ /// successfully sent or if an unexpected error occurs:
|
|
+ /// EFI_SUCCESS: The HTTP request was successfully sent to the remote host.
|
|
+ /// EFI_HTTP_ERROR: The response message was successfully received but contains a
|
|
+ /// HTTP error. The response status code is returned in token.
|
|
+ /// EFI_ABORTED: The HTTP request was cancelled by the caller and removed from
|
|
+ /// the transmit queue.
|
|
+ /// EFI_TIMEOUT: The HTTP request timed out before reaching the remote host.
|
|
+ /// EFI_DEVICE_ERROR: An unexpected system or network error occurred.
|
|
+ ///
|
|
+ EFI_STATUS Status;
|
|
+ ///
|
|
+ /// Pointer to storage containing HTTP message data.
|
|
+ ///
|
|
+ EFI_HTTP_MESSAGE *Message;
|
|
+} EFI_HTTP_TOKEN;
|
|
+
|
|
+/**
|
|
+ Returns the operational parameters for the current HTTP child instance.
|
|
+
|
|
+ The GetModeData() function is used to read the current mode data (operational
|
|
+ parameters) for this HTTP protocol instance.
|
|
+
|
|
+ @param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
|
+ @param[out] HttpConfigData Point to buffer for operational parameters of this
|
|
+ HTTP instance.
|
|
+
|
|
+ @retval EFI_SUCCESS Operation succeeded.
|
|
+ @retval EFI_INVALID_PARAMETER This is NULL.
|
|
+ HttpConfigData is NULL.
|
|
+ HttpInstance->LocalAddressIsIPv6 is FALSE and
|
|
+ HttpConfigData->IPv4Node is NULL.
|
|
+ HttpInstance->LocalAddressIsIPv6 is TRUE and
|
|
+ HttpConfigData->IPv6Node is NULL.
|
|
+ @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started.
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI * EFI_HTTP_GET_MODE_DATA)(
|
|
+ IN EFI_HTTP_PROTOCOL *This,
|
|
+ OUT EFI_HTTP_CONFIG_DATA *HttpConfigData
|
|
+ );
|
|
+
|
|
+/**
|
|
+ Initialize or brutally reset the operational parameters for this EFI HTTP instance.
|
|
+
|
|
+ The Configure() function does the following:
|
|
+ When HttpConfigData is not NULL Initialize this EFI HTTP instance by configuring
|
|
+ timeout, local address, port, etc.
|
|
+ When HttpConfigData is NULL, reset this EFI HTTP instance by closing all active
|
|
+ connections with remote hosts, canceling all asynchronous tokens, and flush request
|
|
+ and response buffers without informing the appropriate hosts.
|
|
+
|
|
+ No other EFI HTTP function can be executed by this instance until the Configure()
|
|
+ function is executed and returns successfully.
|
|
+
|
|
+ @param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
|
+ @param[in] HttpConfigData Pointer to the configure data to configure the instance.
|
|
+
|
|
+ @retval EFI_SUCCESS Operation succeeded.
|
|
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
|
+ This is NULL.
|
|
+ HttpConfigData is NULL.
|
|
+ HttpConfigData->LocalAddressIsIPv6 is FALSE and
|
|
+ HttpConfigData->IPv4Node is NULL.
|
|
+ HttpConfigData->LocalAddressIsIPv6 is TRUE and
|
|
+ HttpConfigData->IPv6Node is NULL.
|
|
+ @retval EFI_ALREADY_STARTED Reinitialize this HTTP instance without calling
|
|
+ Configure() with NULL to reset it.
|
|
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
|
+ @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources when
|
|
+ executing Configure().
|
|
+ @retval EFI_UNSUPPORTED One or more options in ConfigData are not supported
|
|
+ in the implementation.
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI * EFI_HTTP_CONFIGURE)(
|
|
+ IN EFI_HTTP_PROTOCOL *This,
|
|
+ IN EFI_HTTP_CONFIG_DATA *HttpConfigData
|
|
+ );
|
|
+
|
|
+/**
|
|
+ The Request() function queues an HTTP request to this HTTP instance,
|
|
+ similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent
|
|
+ successfully, or if there is an error, Status in token will be updated and Event will
|
|
+ be signaled.
|
|
+
|
|
+ @param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
|
+ @param[in] Token Pointer to storage containing HTTP request token.
|
|
+
|
|
+ @retval EFI_SUCCESS Outgoing data was processed.
|
|
+ @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started.
|
|
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
|
+ @retval EFI_TIMEOUT Data was dropped out of the transmit or receive queue.
|
|
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
|
+ This is NULL.
|
|
+ Token is NULL.
|
|
+ Token->Message is NULL.
|
|
+ Token->Message->Body is not NULL,
|
|
+ Token->Message->BodyLength is non-zero, and
|
|
+ Token->Message->Data is NULL, but a previous call to
|
|
+ Request()has not been completed successfully.
|
|
+ @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources.
|
|
+ @retval EFI_UNSUPPORTED The HTTP method is not supported in current implementation.
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_HTTP_REQUEST) (
|
|
+ IN EFI_HTTP_PROTOCOL *This,
|
|
+ IN EFI_HTTP_TOKEN *Token
|
|
+ );
|
|
+
|
|
+/**
|
|
+ Abort an asynchronous HTTP request or response token.
|
|
+
|
|
+ The Cancel() function aborts a pending HTTP request or response transaction. If
|
|
+ Token is not NULL and the token is in transmit or receive queues when it is being
|
|
+ cancelled, its Token->Status will be set to EFI_ABORTED and then Token->Event will
|
|
+ be signaled. If the token is not in one of the queues, which usually means that the
|
|
+ asynchronous operation has completed, EFI_NOT_FOUND is returned. If Token is NULL,
|
|
+ all asynchronous tokens issued by Request() or Response() will be aborted.
|
|
+
|
|
+ @param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
|
+ @param[in] Token Point to storage containing HTTP request or response
|
|
+ token.
|
|
+
|
|
+ @retval EFI_SUCCESS Request and Response queues are successfully flushed.
|
|
+ @retval EFI_INVALID_PARAMETER This is NULL.
|
|
+ @retval EFI_NOT_STARTED This instance hasn't been configured.
|
|
+ @retval EFI_NOT_FOUND The asynchronous request or response token is not
|
|
+ found.
|
|
+ @retval EFI_UNSUPPORTED The implementation does not support this function.
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_HTTP_CANCEL)(
|
|
+ IN EFI_HTTP_PROTOCOL *This,
|
|
+ IN EFI_HTTP_TOKEN *Token
|
|
+ );
|
|
+
|
|
+/**
|
|
+ The Response() function queues an HTTP response to this HTTP instance, similar to
|
|
+ Receive() function in the EFI TCP driver. When the HTTP Response is received successfully,
|
|
+ or if there is an error, Status in token will be updated and Event will be signaled.
|
|
+
|
|
+ The HTTP driver will queue a receive token to the underlying TCP instance. When data
|
|
+ is received in the underlying TCP instance, the data will be parsed and Token will
|
|
+ be populated with the response data. If the data received from the remote host
|
|
+ contains an incomplete or invalid HTTP header, the HTTP driver will continue waiting
|
|
+ (asynchronously) for more data to be sent from the remote host before signaling
|
|
+ Event in Token.
|
|
+
|
|
+ It is the responsibility of the caller to allocate a buffer for Body and specify the
|
|
+ size in BodyLength. If the remote host provides a response that contains a content
|
|
+ body, up to BodyLength bytes will be copied from the receive buffer into Body and
|
|
+ BodyLength will be updated with the amount of bytes received and copied to Body. This
|
|
+ allows the client to download a large file in chunks instead of into one contiguous
|
|
+ block of memory. Similar to HTTP request, if Body is not NULL and BodyLength is
|
|
+ non-zero and all other fields are NULL or 0, the HTTP driver will queue a receive
|
|
+ token to underlying TCP instance. If data arrives in the receive buffer, up to
|
|
+ BodyLength bytes of data will be copied to Body. The HTTP driver will then update
|
|
+ BodyLength with the amount of bytes received and copied to Body.
|
|
+
|
|
+ If the HTTP driver does not have an open underlying TCP connection with the host
|
|
+ specified in the response URL, Request() will return EFI_ACCESS_DENIED. This is
|
|
+ consistent with RFC 2616 recommendation that HTTP clients should attempt to maintain
|
|
+ an open TCP connection between client and host.
|
|
+
|
|
+ @param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
|
+ @param[in] Token Pointer to storage containing HTTP response token.
|
|
+
|
|
+ @retval EFI_SUCCESS Allocation succeeded.
|
|
+ @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been
|
|
+ initialized.
|
|
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
|
+ This is NULL.
|
|
+ Token is NULL.
|
|
+ Token->Message->Headers is NULL.
|
|
+ Token->Message is NULL.
|
|
+ Token->Message->Body is not NULL,
|
|
+ Token->Message->BodyLength is non-zero, and
|
|
+ Token->Message->Data is NULL, but a previous call to
|
|
+ Response() has not been completed successfully.
|
|
+ @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources.
|
|
+ @retval EFI_ACCESS_DENIED An open TCP connection is not present with the host
|
|
+ specified by response URL.
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_HTTP_RESPONSE) (
|
|
+ IN EFI_HTTP_PROTOCOL *This,
|
|
+ IN EFI_HTTP_TOKEN *Token
|
|
+ );
|
|
+
|
|
+/**
|
|
+ The Poll() function can be used by network drivers and applications to increase the
|
|
+ rate that data packets are moved between the communication devices and the transmit
|
|
+ and receive queues.
|
|
+
|
|
+ In some systems, the periodic timer event in the managed network driver may not poll
|
|
+ the underlying communications device fast enough to transmit and/or receive all data
|
|
+ packets without missing incoming packets or dropping outgoing packets. Drivers and
|
|
+ applications that are experiencing packet loss should try calling the Poll() function
|
|
+ more often.
|
|
+
|
|
+ @param[in] This Pointer to EFI_HTTP_PROTOCOL instance.
|
|
+
|
|
+ @retval EFI_SUCCESS Incoming or outgoing data was processed..
|
|
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred
|
|
+ @retval EFI_INVALID_PARAMETER This is NULL.
|
|
+ @retval EFI_NOT_READY No incoming or outgoing data is processed.
|
|
+ @retval EFI_NOT_STARTED This EFI HTTP Protocol instance has not been started.
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_HTTP_POLL) (
|
|
+ IN EFI_HTTP_PROTOCOL *This
|
|
+ );
|
|
+
|
|
+///
|
|
+/// The EFI HTTP protocol is designed to be used by EFI drivers and applications to
|
|
+/// create and transmit HTTP Requests, as well as handle HTTP responses that are
|
|
+/// returned by a remote host. This EFI protocol uses and relies on an underlying EFI
|
|
+/// TCP protocol.
|
|
+///
|
|
+struct _EFI_HTTP_PROTOCOL {
|
|
+ EFI_HTTP_GET_MODE_DATA GetModeData;
|
|
+ EFI_HTTP_CONFIGURE Configure;
|
|
+ EFI_HTTP_REQUEST Request;
|
|
+ EFI_HTTP_CANCEL Cancel;
|
|
+ EFI_HTTP_RESPONSE Response;
|
|
+ EFI_HTTP_POLL Poll;
|
|
+};
|
|
+
|
|
+#endif
|
|
diff --git a/include/Ip4Config2.h b/include/Ip4Config2.h
|
|
new file mode 100644
|
|
index 0000000..b4f1d84
|
|
--- /dev/null
|
|
+++ b/include/Ip4Config2.h
|
|
@@ -0,0 +1,315 @@
|
|
+/** @file
|
|
+ This file provides a definition of the EFI IPv4 Configuration II
|
|
+ Protocol.
|
|
+
|
|
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
|
|
+This program and the accompanying materials
|
|
+are licensed and made available under the terms and conditions of the BSD License
|
|
+which accompanies this distribution. The full text of the license may be found at<BR>
|
|
+http://opensource.org/licenses/bsd-license.php
|
|
+
|
|
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
+
|
|
+@par Revision Reference:
|
|
+This Protocol is introduced in UEFI Specification 2.5
|
|
+
|
|
+**/
|
|
+#ifndef __EFI_IP4CONFIG2_PROTOCOL_H__
|
|
+#define __EFI_IP4CONFIG2_PROTOCOL_H__
|
|
+
|
|
+#include <efiip.h>
|
|
+
|
|
+#define EFI_IP4_CONFIG2_PROTOCOL_GUID \
|
|
+ { \
|
|
+ 0x5b446ed1, 0xe30b, 0x4faa, {0x87, 0x1a, 0x36, 0x54, 0xec, 0xa3, 0x60, 0x80 } \
|
|
+ }
|
|
+
|
|
+typedef struct _EFI_IP4_CONFIG2_PROTOCOL EFI_IP4_CONFIG2_PROTOCOL;
|
|
+
|
|
+
|
|
+///
|
|
+/// EFI_IP4_CONFIG2_DATA_TYPE
|
|
+///
|
|
+typedef enum {
|
|
+ ///
|
|
+ /// The interface information of the communication device this EFI
|
|
+ /// IPv4 Configuration II Protocol instance manages. This type of
|
|
+ /// data is read only. The corresponding Data is of type
|
|
+ /// EFI_IP4_CONFIG2_INTERFACE_INFO.
|
|
+ ///
|
|
+ Ip4Config2DataTypeInterfaceInfo,
|
|
+ ///
|
|
+ /// The general configuration policy for the EFI IPv4 network stack
|
|
+ /// running on the communication device this EFI IPv4
|
|
+ /// Configuration II Protocol instance manages. The policy will
|
|
+ /// affect other configuration settings. The corresponding Data is of
|
|
+ /// type EFI_IP4_CONFIG2_POLICY.
|
|
+ ///
|
|
+ Ip4Config2DataTypePolicy,
|
|
+ ///
|
|
+ /// The station addresses set manually for the EFI IPv4 network
|
|
+ /// stack. It is only configurable when the policy is
|
|
+ /// Ip4Config2PolicyStatic. The corresponding Data is of
|
|
+ /// type EFI_IP4_CONFIG2_MANUAL_ADDRESS.
|
|
+ ///
|
|
+ Ip4Config2DataTypeManualAddress,
|
|
+ ///
|
|
+ /// The gateway addresses set manually for the EFI IPv4 network
|
|
+ /// stack running on the communication device this EFI IPv4
|
|
+ /// Configuration II Protocol manages. It is not configurable when
|
|
+ /// the policy is Ip4Config2PolicyDhcp. The gateway
|
|
+ /// addresses must be unicast IPv4 addresses. The corresponding
|
|
+ /// Data is a pointer to an array of EFI_IPv4_ADDRESS instances.
|
|
+ ///
|
|
+ Ip4Config2DataTypeGateway,
|
|
+ ///
|
|
+ /// The DNS server list for the EFI IPv4 network stack running on
|
|
+ /// the communication device this EFI IPv4 Configuration II
|
|
+ /// Protocol manages. It is not configurable when the policy is
|
|
+ /// Ip4Config2PolicyDhcp. The DNS server addresses must be
|
|
+ /// unicast IPv4 addresses. The corresponding Data is a pointer to
|
|
+ /// an array of EFI_IPv4_ADDRESS instances.
|
|
+ ///
|
|
+ Ip4Config2DataTypeDnsServer,
|
|
+ Ip4Config2DataTypeMaximum
|
|
+} EFI_IP4_CONFIG2_DATA_TYPE;
|
|
+
|
|
+///
|
|
+/// EFI_IP4_CONFIG2_INTERFACE_INFO related definitions
|
|
+///
|
|
+#define EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE 32
|
|
+
|
|
+///
|
|
+/// EFI_IP4_CONFIG2_INTERFACE_INFO
|
|
+///
|
|
+typedef struct {
|
|
+ ///
|
|
+ /// The name of the interface. It is a NULL-terminated Unicode string.
|
|
+ ///
|
|
+ CHAR16 Name[EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE];
|
|
+ ///
|
|
+ /// The interface type of the network interface. See RFC 1700,
|
|
+ /// section "Number Hardware Type".
|
|
+ ///
|
|
+ UINT8 IfType;
|
|
+ ///
|
|
+ /// The size, in bytes, of the network interface's hardware address.
|
|
+ ///
|
|
+ UINT32 HwAddressSize;
|
|
+ ///
|
|
+ /// The hardware address for the network interface.
|
|
+ ///
|
|
+ EFI_MAC_ADDRESS HwAddress;
|
|
+ ///
|
|
+ /// The station IPv4 address of this EFI IPv4 network stack.
|
|
+ ///
|
|
+ EFI_IPv4_ADDRESS StationAddress;
|
|
+ ///
|
|
+ /// The subnet address mask that is associated with the station address.
|
|
+ ///
|
|
+ EFI_IPv4_ADDRESS SubnetMask;
|
|
+ ///
|
|
+ /// Size of the following RouteTable, in bytes. May be zero.
|
|
+ ///
|
|
+ UINT32 RouteTableSize;
|
|
+ ///
|
|
+ /// The route table of the IPv4 network stack runs on this interface.
|
|
+ /// Set to NULL if RouteTableSize is zero. Type EFI_IP4_ROUTE_TABLE is defined in
|
|
+ /// EFI_IP4_PROTOCOL.GetModeData().
|
|
+ ///
|
|
+ EFI_IP4_ROUTE_TABLE *RouteTable OPTIONAL;
|
|
+} EFI_IP4_CONFIG2_INTERFACE_INFO;
|
|
+
|
|
+///
|
|
+/// EFI_IP4_CONFIG2_POLICY
|
|
+///
|
|
+typedef enum {
|
|
+ ///
|
|
+ /// Under this policy, the Ip4Config2DataTypeManualAddress,
|
|
+ /// Ip4Config2DataTypeGateway and Ip4Config2DataTypeDnsServer configuration
|
|
+ /// data are required to be set manually. The EFI IPv4 Protocol will get all
|
|
+ /// required configuration such as IPv4 address, subnet mask and
|
|
+ /// gateway settings from the EFI IPv4 Configuration II protocol.
|
|
+ ///
|
|
+ Ip4Config2PolicyStatic,
|
|
+ ///
|
|
+ /// Under this policy, the Ip4Config2DataTypeManualAddress,
|
|
+ /// Ip4Config2DataTypeGateway and Ip4Config2DataTypeDnsServer configuration data are
|
|
+ /// not allowed to set via SetData(). All of these configurations are retrieved from DHCP
|
|
+ /// server or other auto-configuration mechanism.
|
|
+ ///
|
|
+ Ip4Config2PolicyDhcp,
|
|
+ Ip4Config2PolicyMax
|
|
+} EFI_IP4_CONFIG2_POLICY;
|
|
+
|
|
+///
|
|
+/// EFI_IP4_CONFIG2_MANUAL_ADDRESS
|
|
+///
|
|
+typedef struct {
|
|
+ ///
|
|
+ /// The IPv4 unicast address.
|
|
+ ///
|
|
+ EFI_IPv4_ADDRESS Address;
|
|
+ ///
|
|
+ /// The subnet mask.
|
|
+ ///
|
|
+ EFI_IPv4_ADDRESS SubnetMask;
|
|
+} EFI_IP4_CONFIG2_MANUAL_ADDRESS;
|
|
+
|
|
+/**
|
|
+ Set the configuration for the EFI IPv4 network stack running on the communication device this EFI
|
|
+ IPv4 Configuration II Protocol instance manages.
|
|
+
|
|
+ This function is used to set the configuration data of type DataType for the EFI IPv4 network stack
|
|
+ running on the communication device this EFI IPv4 Configuration II Protocol instance manages.
|
|
+ The successfully configured data is valid after system reset or power-off.
|
|
+ The DataSize is used to calculate the count of structure instances in the Data for some
|
|
+ DataType that multiple structure instances are allowed.
|
|
+ This function is always non-blocking. When setting some typeof configuration data, an
|
|
+ asynchronous process is invoked to check the correctness of the data, such as doing address conflict
|
|
+ detection on the manually set local IPv4 address. EFI_NOT_READY is returned immediately to
|
|
+ indicate that such an asynchronous process is invoked and the process is not finished yet. The caller
|
|
+ willing to get the result of the asynchronous process is required to call RegisterDataNotify()
|
|
+ to register an event on the specified configuration data. Once the event is signaled, the caller can call
|
|
+ GetData()to get back the configuration data in order to know the result. For other types of
|
|
+ configuration data that do not require an asynchronous configuration process, the result of the
|
|
+ operation is immediately returned.
|
|
+
|
|
+ @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
|
|
+ @param[in] DataType The type of data to set.
|
|
+ @param[in] DataSize Size of the buffer pointed to by Data in bytes.
|
|
+ @param[in] Data The data buffer to set. The type ofthe data buffer is associated
|
|
+ with the DataType.
|
|
+
|
|
+ @retval EFI_SUCCESS The specified configuration data for the EFI IPv4 network stack is set
|
|
+ successfully.
|
|
+ @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
|
|
+ This is NULL.
|
|
+ Data is NULL.
|
|
+ One or more fields in Data do not match the requirement of the data type
|
|
+ indicated by DataType.
|
|
+ @retval EFI_WRITE_PROTECTED The specified configuration data is read-only or the specified configuration
|
|
+ data can not be set under the current policy.
|
|
+ @retval EFI_ACCESS_DENIED Another set operation on the specified configuration data is already in process.
|
|
+ @retval EFI_NOT_READY An asynchronous process is invoked to set the specified configuration data and
|
|
+ the process is not finished yet.
|
|
+ @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type indicated by DataType.
|
|
+ @retval EFI_UNSUPPORTED This DataType is not supported.
|
|
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
|
+ @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred.
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_IP4_CONFIG2_SET_DATA) (
|
|
+ IN EFI_IP4_CONFIG2_PROTOCOL *This,
|
|
+ IN EFI_IP4_CONFIG2_DATA_TYPE DataType,
|
|
+ IN UINTN DataSize,
|
|
+ IN VOID *Data
|
|
+ );
|
|
+
|
|
+/**
|
|
+ Get the configuration data for the EFI IPv4 network stack running on the communication device this
|
|
+ EFI IPv4 Configuration II Protocol instance manages.
|
|
+
|
|
+ This function returns the configuration data of type DataType for the EFI IPv4 network stack
|
|
+ running on the communication device this EFI IPv4 Configuration II Protocol instance manages.
|
|
+ The caller is responsible for allocating the buffer usedto return the specified configuration data and
|
|
+ the required size will be returned to the caller if the size of the buffer is too small.
|
|
+ EFI_NOT_READY is returned if the specified configuration data is not ready due to an already in
|
|
+ progress asynchronous configuration process. The caller can call RegisterDataNotify() to
|
|
+ register an event on the specified configuration data. Once the asynchronous configuration process is
|
|
+ finished, the event will be signaled and a subsequent GetData() call will return the specified
|
|
+ configuration data.
|
|
+
|
|
+ @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
|
|
+ @param[in] DataType The type of data to get.
|
|
+ @param[out] DataSize On input, in bytes, the size of Data. On output, in bytes, the size
|
|
+ of buffer required to store the specified configuration data.
|
|
+ @param[in] Data The data buffer in which the configuration data is returned. The
|
|
+ type of the data buffer is associated with the DataType. Ignored
|
|
+ if DataSize is 0.
|
|
+
|
|
+ @retval EFI_SUCCESS The specified configuration data is got successfully.
|
|
+ @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
|
|
+ This is NULL.
|
|
+ DataSize is NULL.
|
|
+ Data is NULL if *DataSizeis not zero.
|
|
+ @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified configuration data
|
|
+ and the required size is returned in DataSize.
|
|
+ @retval EFI_NOT_READY The specified configuration data is not ready due to an already in
|
|
+ progress asynchronous configuration process.
|
|
+ @retval EFI_NOT_FOUND The specified configuration data is not found.
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_IP4_CONFIG2_GET_DATA) (
|
|
+ IN EFI_IP4_CONFIG2_PROTOCOL *This,
|
|
+ IN EFI_IP4_CONFIG2_DATA_TYPE DataType,
|
|
+ IN OUT UINTN *DataSize,
|
|
+ IN VOID *Data OPTIONAL
|
|
+ );
|
|
+
|
|
+/**
|
|
+ Register an event that is to be signaled whenever a configuration process on the specified
|
|
+ configuration data is done.
|
|
+
|
|
+ This function registers an event that is to be signaled whenever a configuration process on the
|
|
+ specified configuration data is done. An event can be registered for different DataType
|
|
+ simultaneously and the caller is responsible for determining which type of configuration data causes
|
|
+ the signaling of the event in such case.
|
|
+
|
|
+ @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
|
|
+ @param[in] DataType The type of data to unregister the event for.
|
|
+ @param[in] Event The event to register.
|
|
+
|
|
+ @retval EFI_SUCCESS The notification event for the specified configuration data is
|
|
+ registered.
|
|
+ @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
|
|
+ @retval EFI_UNSUPPORTED The configuration data type specified by DataType is not supported.
|
|
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
|
+ @retval EFI_ACCESS_DENIED The Event is already registered for the DataType.
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_IP4_CONFIG2_REGISTER_NOTIFY) (
|
|
+ IN EFI_IP4_CONFIG2_PROTOCOL *This,
|
|
+ IN EFI_IP4_CONFIG2_DATA_TYPE DataType,
|
|
+ IN EFI_EVENT Event
|
|
+ );
|
|
+
|
|
+/**
|
|
+ Remove a previously registered event for the specified configuration data.
|
|
+
|
|
+ This function removes a previously registeredevent for the specified configuration data.
|
|
+
|
|
+ @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
|
|
+ @param[in] DataType The type of data to remove the previously registered event for.
|
|
+ @param[in] Event The event to unregister.
|
|
+
|
|
+ @retval EFI_SUCCESS The event registered for the specified configuration data is removed.
|
|
+ @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
|
|
+ @retval EFI_NOT_FOUND The Eventhas not been registered for the specified DataType.
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_IP4_CONFIG2_UNREGISTER_NOTIFY) (
|
|
+ IN EFI_IP4_CONFIG2_PROTOCOL *This,
|
|
+ IN EFI_IP4_CONFIG2_DATA_TYPE DataType,
|
|
+ IN EFI_EVENT Event
|
|
+ );
|
|
+
|
|
+///
|
|
+/// The EFI_IP4_CONFIG2_PROTOCOL is designed to be the central repository for the common
|
|
+/// configurations and the administrator configurable settings for the EFI IPv4 network stack.
|
|
+/// An EFI IPv4 Configuration II Protocol instance will be installed on each communication device that
|
|
+/// the EFI IPv4 network stack runs on.
|
|
+///
|
|
+struct _EFI_IP4_CONFIG2_PROTOCOL {
|
|
+ EFI_IP4_CONFIG2_SET_DATA SetData;
|
|
+ EFI_IP4_CONFIG2_GET_DATA GetData;
|
|
+ EFI_IP4_CONFIG2_REGISTER_NOTIFY RegisterDataNotify;
|
|
+ EFI_IP4_CONFIG2_UNREGISTER_NOTIFY UnregisterDataNotify;
|
|
+};
|
|
+
|
|
+#endif
|
|
diff --git a/include/Ip6Config.h b/include/Ip6Config.h
|
|
new file mode 100644
|
|
index 0000000..003e50e
|
|
--- /dev/null
|
|
+++ b/include/Ip6Config.h
|
|
@@ -0,0 +1,366 @@
|
|
+/** @file
|
|
+ This file provides a definition of the EFI IPv6 Configuration
|
|
+ Protocol.
|
|
+
|
|
+Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
|
|
+This program and the accompanying materials
|
|
+are licensed and made available under the terms and conditions of the BSD License
|
|
+which accompanies this distribution. The full text of the license may be found at<BR>
|
|
+http://opensource.org/licenses/bsd-license.php
|
|
+
|
|
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
+
|
|
+**/
|
|
+#ifndef __EFI_IP6CONFIG_PROTOCOL_H__
|
|
+#define __EFI_IP6CONFIG_PROTOCOL_H__
|
|
+
|
|
+#include <efiip.h>
|
|
+
|
|
+#define EFI_IP6_CONFIG_PROTOCOL_GUID \
|
|
+ { \
|
|
+ 0x937fe521, 0x95ae, 0x4d1a, {0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \
|
|
+ }
|
|
+
|
|
+typedef struct _EFI_IP6_CONFIG_PROTOCOL EFI_IP6_CONFIG_PROTOCOL;
|
|
+
|
|
+///
|
|
+/// EFI_IP6_CONFIG_DATA_TYPE
|
|
+///
|
|
+typedef enum {
|
|
+ ///
|
|
+ /// The interface information of the communication
|
|
+ /// device this EFI IPv6 Configuration Protocol instance manages.
|
|
+ /// This type of data is read only.The corresponding Data is of type
|
|
+ /// EFI_IP6_CONFIG_INTERFACE_INFO.
|
|
+ ///
|
|
+ Ip6ConfigDataTypeInterfaceInfo,
|
|
+ ///
|
|
+ /// The alternative interface ID for the
|
|
+ /// communication device this EFI IPv6 Configuration Protocol
|
|
+ /// instance manages if the link local IPv6 address generated from
|
|
+ /// the interfaced ID based on the default source the EFI IPv6
|
|
+ /// Protocol uses is a duplicate address. The length of the interface
|
|
+ /// ID is 64 bit. The corresponding Data is of type
|
|
+ /// EFI_IP6_CONFIG_INTERFACE_ID.
|
|
+ ///
|
|
+ Ip6ConfigDataTypeAltInterfaceId,
|
|
+ ///
|
|
+ /// The general configuration policy for the EFI IPv6 network
|
|
+ /// stack running on the communication device this EFI IPv6
|
|
+ /// Configuration Protocol instance manages. The policy will affect
|
|
+ /// other configuration settings. The corresponding Data is of type
|
|
+ /// EFI_IP6_CONFIG_POLICY.
|
|
+ ///
|
|
+ Ip6ConfigDataTypePolicy,
|
|
+ ///
|
|
+ /// The number of consecutive
|
|
+ /// Neighbor Solicitation messages sent while performing Duplicate
|
|
+ /// Address Detection on a tentative address. A value of zero
|
|
+ /// indicates that Duplicate Address Detection will not be performed
|
|
+ /// on tentative addresses. The corresponding Data is of type
|
|
+ /// EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS.
|
|
+ ///
|
|
+ Ip6ConfigDataTypeDupAddrDetectTransmits,
|
|
+ ///
|
|
+ /// The station addresses set manually for the EFI
|
|
+ /// IPv6 network stack. It is only configurable when the policy is
|
|
+ /// Ip6ConfigPolicyManual. The corresponding Data is a
|
|
+ /// pointer to an array of EFI_IPv6_ADDRESS instances.
|
|
+ ///
|
|
+ Ip6ConfigDataTypeManualAddress,
|
|
+ ///
|
|
+ /// The gateway addresses set manually for the EFI IPv6
|
|
+ /// network stack running on the communication device this EFI
|
|
+ /// IPv6 Configuration Protocol manages. It is not configurable when
|
|
+ /// the policy is Ip6ConfigPolicyAutomatic. The gateway
|
|
+ /// addresses must be unicast IPv6 addresses. The corresponding
|
|
+ /// Data is a pointer to an array of EFI_IPv6_ADDRESS instances.
|
|
+ ///
|
|
+ Ip6ConfigDataTypeGateway,
|
|
+ ///
|
|
+ /// The DNS server list for the EFI IPv6 network stack
|
|
+ /// running on the communication device this EFI IPv6
|
|
+ /// Configuration Protocol manages. It is not configurable when the
|
|
+ /// policy is Ip6ConfigPolicyAutomatic.The DNS server
|
|
+ /// addresses must be unicast IPv6 addresses. The corresponding
|
|
+ /// Data is a pointer to an array of EFI_IPv6_ADDRESS instances.
|
|
+ ///
|
|
+ Ip6ConfigDataTypeDnsServer,
|
|
+ ///
|
|
+ /// The number of this enumeration memebers.
|
|
+ ///
|
|
+ Ip6ConfigDataTypeMaximum
|
|
+} EFI_IP6_CONFIG_DATA_TYPE;
|
|
+
|
|
+///
|
|
+/// EFI_IP6_CONFIG_INTERFACE_INFO
|
|
+/// describes the operational state of the interface this
|
|
+/// EFI IPv6 Configuration Protocol instance manages.
|
|
+///
|
|
+typedef struct {
|
|
+ ///
|
|
+ /// The name of the interface. It is a NULL-terminated string.
|
|
+ ///
|
|
+ CHAR16 Name[32];
|
|
+ ///
|
|
+ /// The interface type of the network interface.
|
|
+ ///
|
|
+ UINT8 IfType;
|
|
+ ///
|
|
+ /// The size, in bytes, of the network interface's hardware address.
|
|
+ ///
|
|
+ UINT32 HwAddressSize;
|
|
+ ///
|
|
+ /// The hardware address for the network interface.
|
|
+ ///
|
|
+ EFI_MAC_ADDRESS HwAddress;
|
|
+ ///
|
|
+ /// Number of EFI_IP6_ADDRESS_INFO structures pointed to by AddressInfo.
|
|
+ ///
|
|
+ UINT32 AddressInfoCount;
|
|
+ ///
|
|
+ /// Pointer to an array of EFI_IP6_ADDRESS_INFO instances
|
|
+ /// which contain the local IPv6 addresses and the corresponding
|
|
+ /// prefix length information. Set to NULL if AddressInfoCount
|
|
+ /// is zero.
|
|
+ ///
|
|
+ EFI_IP6_ADDRESS_INFO *AddressInfo;
|
|
+ ///
|
|
+ /// Number of route table entries in the following RouteTable.
|
|
+ ///
|
|
+ UINT32 RouteCount;
|
|
+ ///
|
|
+ /// The route table of the IPv6 network stack runs on this interface.
|
|
+ /// Set to NULL if RouteCount is zero.
|
|
+ ///
|
|
+ EFI_IP6_ROUTE_TABLE *RouteTable;
|
|
+} EFI_IP6_CONFIG_INTERFACE_INFO;
|
|
+
|
|
+///
|
|
+/// EFI_IP6_CONFIG_INTERFACE_ID
|
|
+/// describes the 64-bit interface ID.
|
|
+///
|
|
+typedef struct {
|
|
+ UINT8 Id[8];
|
|
+} EFI_IP6_CONFIG_INTERFACE_ID;
|
|
+
|
|
+///
|
|
+/// EFI_IP6_CONFIG_POLICY
|
|
+/// defines the general configuration policy the EFI IPv6
|
|
+/// Configuration Protocol supports.
|
|
+///
|
|
+typedef enum {
|
|
+ ///
|
|
+ /// Under this policy, the IpI6ConfigDataTypeManualAddress,
|
|
+ /// Ip6ConfigDataTypeGateway and Ip6ConfigDataTypeDnsServer
|
|
+ /// configuration data are required to be set manually.
|
|
+ /// The EFI IPv6 Protocol will get all required configuration
|
|
+ /// such as address, prefix and gateway settings from the EFI
|
|
+ /// IPv6 Configuration protocol.
|
|
+ ///
|
|
+ Ip6ConfigPolicyManual,
|
|
+ ///
|
|
+ /// Under this policy, the IpI6ConfigDataTypeManualAddress,
|
|
+ /// Ip6ConfigDataTypeGateway and Ip6ConfigDataTypeDnsServer
|
|
+ /// configuration data are not allowed to set via SetData().
|
|
+ /// All of these configurations are retrieved from some auto
|
|
+ /// configuration mechanism.
|
|
+ /// The EFI IPv6 Protocol will use the IPv6 stateless address
|
|
+ /// autoconfiguration mechanism and/or the IPv6 stateful address
|
|
+ /// autoconfiguration mechanism described in the related RFCs to
|
|
+ /// get address and other configuration information
|
|
+ ///
|
|
+ Ip6ConfigPolicyAutomatic
|
|
+} EFI_IP6_CONFIG_POLICY;
|
|
+
|
|
+///
|
|
+/// EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
|
|
+/// describes the number of consecutive Neighbor Solicitation messages sent
|
|
+/// while performing Duplicate Address Detection on a tentative address.
|
|
+/// The default value for a newly detected communication device is 1.
|
|
+///
|
|
+typedef struct {
|
|
+ UINT32 DupAddrDetectTransmits; ///< The number of consecutive Neighbor Solicitation messages sent.
|
|
+} EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS;
|
|
+
|
|
+///
|
|
+/// EFI_IP6_CONFIG_MANUAL_ADDRESS
|
|
+/// is used to set the station address information for the EFI IPv6 network
|
|
+/// stack manually when the policy is Ip6ConfigPolicyManual.
|
|
+///
|
|
+typedef struct {
|
|
+ EFI_IPv6_ADDRESS Address; ///< The IPv6 unicast address.
|
|
+ BOOLEAN IsAnycast; ///< Set to TRUE if Address is anycast.
|
|
+ UINT8 PrefixLength; ///< The length, in bits, of the prefix associated with this Address.
|
|
+} EFI_IP6_CONFIG_MANUAL_ADDRESS;
|
|
+
|
|
+
|
|
+/**
|
|
+ Set the configuration for the EFI IPv6 network stack running on the communication
|
|
+ device this EFI IPv6 Configuration Protocol instance manages.
|
|
+
|
|
+ This function is used to set the configuration data of type DataType for the EFI
|
|
+ IPv6 network stack running on the communication device this EFI IPv6 Configuration
|
|
+ Protocol instance manages.
|
|
+
|
|
+ The DataSize is used to calculate the count of structure instances in the Data for
|
|
+ some DataType that multiple structure instances are allowed.
|
|
+
|
|
+ This function is always non-blocking. When setting some type of configuration data,
|
|
+ an asynchronous process is invoked to check the correctness of the data, such as
|
|
+ doing Duplicate Address Detection on the manually set local IPv6 addresses.
|
|
+ EFI_NOT_READY is returned immediately to indicate that such an asynchronous process
|
|
+ is invoked and the process is not finished yet. The caller willing to get the result
|
|
+ of the asynchronous process is required to call RegisterDataNotify() to register an
|
|
+ event on the specified configuration data. Once the event is signaled, the caller
|
|
+ can call GetData() to get back the configuration data in order to know the result.
|
|
+ For other types of configuration data that do not require an asynchronous configuration
|
|
+ process, the result of the operation is immediately returned.
|
|
+
|
|
+ @param[in] This Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
|
|
+ @param[in] DataType The type of data to set.
|
|
+ @param[in] DataSize Size of the buffer pointed to by Data in bytes.
|
|
+ @param[in] Data The data buffer to set. The type of the data buffer is
|
|
+ associated with the DataType.
|
|
+
|
|
+ @retval EFI_SUCCESS The specified configuration data for the EFI IPv6
|
|
+ network stack is set successfully.
|
|
+ @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
|
|
+ - This is NULL.
|
|
+ - Data is NULL.
|
|
+ - One or more fields in Data do not match the requirement of the
|
|
+ data type indicated by DataType.
|
|
+ @retval EFI_WRITE_PROTECTED The specified configuration data is read-only or the specified
|
|
+ configuration data can not be set under the current policy
|
|
+ @retval EFI_ACCESS_DENIED Another set operation on the specified configuration
|
|
+ data is already in process.
|
|
+ @retval EFI_NOT_READY An asynchronous process is invoked to set the specified
|
|
+ configuration data and the process is not finished yet.
|
|
+ @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type
|
|
+ indicated by DataType.
|
|
+ @retval EFI_UNSUPPORTED This DataType is not supported.
|
|
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
|
+ @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred.
|
|
+
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_IP6_CONFIG_SET_DATA)(
|
|
+ IN EFI_IP6_CONFIG_PROTOCOL *This,
|
|
+ IN EFI_IP6_CONFIG_DATA_TYPE DataType,
|
|
+ IN UINTN DataSize,
|
|
+ IN VOID *Data
|
|
+ );
|
|
+
|
|
+/**
|
|
+ Get the configuration data for the EFI IPv6 network stack running on the communication
|
|
+ device this EFI IPv6 Configuration Protocol instance manages.
|
|
+
|
|
+ This function returns the configuration data of type DataType for the EFI IPv6 network
|
|
+ stack running on the communication device this EFI IPv6 Configuration Protocol instance
|
|
+ manages.
|
|
+
|
|
+ The caller is responsible for allocating the buffer used to return the specified
|
|
+ configuration data and the required size will be returned to the caller if the size of
|
|
+ the buffer is too small.
|
|
+
|
|
+ EFI_NOT_READY is returned if the specified configuration data is not ready due to an
|
|
+ already in progress asynchronous configuration process. The caller can call RegisterDataNotify()
|
|
+ to register an event on the specified configuration data. Once the asynchronous configuration
|
|
+ process is finished, the event will be signaled and a subsequent GetData() call will return
|
|
+ the specified configuration data.
|
|
+
|
|
+ @param[in] This Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
|
|
+ @param[in] DataType The type of data to get.
|
|
+ @param[in,out] DataSize On input, in bytes, the size of Data. On output, in bytes, the
|
|
+ size of buffer required to store the specified configuration data.
|
|
+ @param[in] Data The data buffer in which the configuration data is returned. The
|
|
+ type of the data buffer is associated with the DataType.
|
|
+
|
|
+ @retval EFI_SUCCESS The specified configuration data is got successfully.
|
|
+ @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
|
|
+ - This is NULL.
|
|
+ - DataSize is NULL.
|
|
+ - Data is NULL if *DataSize is not zero.
|
|
+ @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified configuration data
|
|
+ and the required size is returned in DataSize.
|
|
+ @retval EFI_NOT_READY The specified configuration data is not ready due to an already in
|
|
+ progress asynchronous configuration process.
|
|
+ @retval EFI_NOT_FOUND The specified configuration data is not found.
|
|
+
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_IP6_CONFIG_GET_DATA)(
|
|
+ IN EFI_IP6_CONFIG_PROTOCOL *This,
|
|
+ IN EFI_IP6_CONFIG_DATA_TYPE DataType,
|
|
+ IN OUT UINTN *DataSize,
|
|
+ IN VOID *Data OPTIONAL
|
|
+ );
|
|
+
|
|
+/**
|
|
+ Register an event that is to be signaled whenever a configuration process on the specified
|
|
+ configuration data is done.
|
|
+
|
|
+ This function registers an event that is to be signaled whenever a configuration process
|
|
+ on the specified configuration data is done. An event can be registered for different DataType
|
|
+ simultaneously and the caller is responsible for determining which type of configuration data
|
|
+ causes the signaling of the event in such case.
|
|
+
|
|
+ @param[in] This Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
|
|
+ @param[in] DataType The type of data to unregister the event for.
|
|
+ @param[in] Event The event to register.
|
|
+
|
|
+ @retval EFI_SUCCESS The notification event for the specified configuration data is
|
|
+ registered.
|
|
+ @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
|
|
+ @retval EFI_UNSUPPORTED The configuration data type specified by DataType is not
|
|
+ supported.
|
|
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
|
+ @retval EFI_ACCESS_DENIED The Event is already registered for the DataType.
|
|
+
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_IP6_CONFIG_REGISTER_NOTIFY)(
|
|
+ IN EFI_IP6_CONFIG_PROTOCOL *This,
|
|
+ IN EFI_IP6_CONFIG_DATA_TYPE DataType,
|
|
+ IN EFI_EVENT Event
|
|
+ );
|
|
+
|
|
+/**
|
|
+ Remove a previously registered event for the specified configuration data.
|
|
+
|
|
+ This function removes a previously registered event for the specified configuration data.
|
|
+
|
|
+ @param[in] This Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
|
|
+ @param[in] DataType The type of data to remove the previously registered event for.
|
|
+ @param[in] Event The event to unregister.
|
|
+
|
|
+ @retval EFI_SUCCESS The event registered for the specified configuration data is removed.
|
|
+ @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
|
|
+ @retval EFI_NOT_FOUND The Event has not been registered for the specified
|
|
+ DataType.
|
|
+
|
|
+**/
|
|
+typedef
|
|
+EFI_STATUS
|
|
+(EFIAPI *EFI_IP6_CONFIG_UNREGISTER_NOTIFY)(
|
|
+ IN EFI_IP6_CONFIG_PROTOCOL *This,
|
|
+ IN EFI_IP6_CONFIG_DATA_TYPE DataType,
|
|
+ IN EFI_EVENT Event
|
|
+ );
|
|
+
|
|
+///
|
|
+/// The EFI_IP6_CONFIG_PROTOCOL provides the mechanism to set and get various
|
|
+/// types of configurations for the EFI IPv6 network stack.
|
|
+///
|
|
+struct _EFI_IP6_CONFIG_PROTOCOL {
|
|
+ EFI_IP6_CONFIG_SET_DATA SetData;
|
|
+ EFI_IP6_CONFIG_GET_DATA GetData;
|
|
+ EFI_IP6_CONFIG_REGISTER_NOTIFY RegisterDataNotify;
|
|
+ EFI_IP6_CONFIG_UNREGISTER_NOTIFY UnregisterDataNotify;
|
|
+};
|
|
+
|
|
+#endif
|
|
--
|
|
2.7.1
|
|
|
|
|
|
From 06e5348c1de053a0a07583a83629b21561ec2caa Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Wed, 14 Oct 2015 17:04:10 +0800
|
|
Subject: [PATCH 3/3] Add the optional HTTPBoot support
|
|
|
|
This commit adds the basic support for HTTPBoot, i.e. to fetch
|
|
the next stage loader with the HTTP protocol.
|
|
|
|
It requires gnu-efi >= 3.0.3 to support the URI device path and
|
|
Ip4Config2 or Ip6Config protocol support in the UEFI implementation.
|
|
|
|
To build shim.efi with HTTPBoot support:
|
|
make ENABLE_HTTPBOOT=1 shim.efi
|
|
|
|
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
|
|
---
|
|
Makefile | 9 +
|
|
httpboot.c | 774 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
httpboot.h | 41 ++++
|
|
shim.c | 12 +
|
|
4 files changed, 836 insertions(+)
|
|
create mode 100644 httpboot.c
|
|
create mode 100644 httpboot.h
|
|
|
|
diff --git a/Makefile b/Makefile
|
|
index 2c3d554..f636500 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -38,6 +38,10 @@ ifneq ($(origin OVERRIDE_SECURITY_POLICY), undefined)
|
|
CFLAGS += -DOVERRIDE_SECURITY_POLICY
|
|
endif
|
|
|
|
+ifneq ($(origin ENABLE_HTTPBOOT), undefined)
|
|
+ CFLAGS += -DENABLE_HTTPBOOT
|
|
+endif
|
|
+
|
|
ifeq ($(ARCH),x86_64)
|
|
CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc \
|
|
-maccumulate-outgoing-args \
|
|
@@ -75,6 +79,11 @@ MOK_SOURCES = MokManager.c shim.h include/console.h PasswordCrypt.c PasswordCryp
|
|
FALLBACK_OBJS = fallback.o
|
|
FALLBACK_SRCS = fallback.c
|
|
|
|
+ifneq ($(origin ENABLE_HTTPBOOT), undefined)
|
|
+ OBJS += httpboot.o
|
|
+ SOURCES += httpboot.c httpboot.h
|
|
+endif
|
|
+
|
|
all: $(TARGET)
|
|
|
|
shim.crt:
|
|
diff --git a/httpboot.c b/httpboot.c
|
|
new file mode 100644
|
|
index 0000000..ad01b8d
|
|
--- /dev/null
|
|
+++ b/httpboot.c
|
|
@@ -0,0 +1,774 @@
|
|
+/*
|
|
+ * Copyright 2015 SUSE LINUX GmbH <glin@suse.com>
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ *
|
|
+ * Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ *
|
|
+ * Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the
|
|
+ * distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
+ *
|
|
+ * Significant portions of this code are derived from Tianocore
|
|
+ * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel
|
|
+ * Corporation.
|
|
+ */
|
|
+
|
|
+#include <efi.h>
|
|
+#include <efilib.h>
|
|
+#include "str.h"
|
|
+#include "Http.h"
|
|
+#include "Ip4Config2.h"
|
|
+#include "Ip6Config.h"
|
|
+
|
|
+extern UINT8 in_protocol;
|
|
+
|
|
+#define perror(fmt, ...) ({ \
|
|
+ UINTN __perror_ret = 0; \
|
|
+ if (!in_protocol) \
|
|
+ __perror_ret = Print((fmt), ##__VA_ARGS__); \
|
|
+ __perror_ret; \
|
|
+ })
|
|
+
|
|
+static UINTN
|
|
+ascii_to_int (CONST CHAR8 *str)
|
|
+{
|
|
+ UINTN u;
|
|
+ CHAR8 c;
|
|
+
|
|
+ // skip preceeding white space
|
|
+ while (*str && *str == ' ') {
|
|
+ str += 1;
|
|
+ }
|
|
+
|
|
+ // convert digits
|
|
+ u = 0;
|
|
+ while ((c = *(str++))) {
|
|
+ if (c >= '0' && c <= '9') {
|
|
+ u = (u * 10) + c - '0';
|
|
+ } else {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return u;
|
|
+}
|
|
+
|
|
+static UINTN
|
|
+convert_http_status_code (EFI_HTTP_STATUS_CODE status_code)
|
|
+{
|
|
+ if (status_code >= HTTP_STATUS_100_CONTINUE &&
|
|
+ status_code < HTTP_STATUS_200_OK) {
|
|
+ return (status_code - HTTP_STATUS_100_CONTINUE + 100);
|
|
+ } else if (status_code >= HTTP_STATUS_200_OK &&
|
|
+ status_code < HTTP_STATUS_300_MULTIPLE_CHIOCES) {
|
|
+ return (status_code - HTTP_STATUS_200_OK + 200);
|
|
+ } else if (status_code >= HTTP_STATUS_300_MULTIPLE_CHIOCES &&
|
|
+ status_code < HTTP_STATUS_400_BAD_REQUEST) {
|
|
+ return (status_code - HTTP_STATUS_300_MULTIPLE_CHIOCES + 300);
|
|
+ } else if (status_code >= HTTP_STATUS_400_BAD_REQUEST &&
|
|
+ status_code < HTTP_STATUS_500_INTERNAL_SERVER_ERROR) {
|
|
+ return (status_code - HTTP_STATUS_400_BAD_REQUEST + 400);
|
|
+ } else if (status_code >= HTTP_STATUS_500_INTERNAL_SERVER_ERROR) {
|
|
+ return (status_code - HTTP_STATUS_500_INTERNAL_SERVER_ERROR + 500);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static EFI_DEVICE_PATH *devpath;
|
|
+static EFI_MAC_ADDRESS mac_addr;
|
|
+static IPv4_DEVICE_PATH ip4_node;
|
|
+static IPv6_DEVICE_PATH ip6_node;
|
|
+static BOOLEAN is_ip6;
|
|
+static CHAR8 *uri;
|
|
+
|
|
+BOOLEAN
|
|
+find_httpboot (EFI_HANDLE device)
|
|
+{
|
|
+ EFI_DEVICE_PATH *unpacked;
|
|
+ EFI_DEVICE_PATH *Node;
|
|
+ EFI_DEVICE_PATH *NextNode;
|
|
+ MAC_ADDR_DEVICE_PATH *MacNode;
|
|
+ URI_DEVICE_PATH *UriNode;
|
|
+ UINTN uri_size;
|
|
+
|
|
+ if (!uri)
|
|
+ FreePool(uri);
|
|
+
|
|
+ devpath = DevicePathFromHandle(device);
|
|
+ if (!devpath) {
|
|
+ perror(L"Failed to get device path\n");
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ unpacked = UnpackDevicePath(devpath);
|
|
+ if (!unpacked) {
|
|
+ perror(L"Failed to unpack device path\n");
|
|
+ return FALSE;
|
|
+ }
|
|
+ Node = unpacked;
|
|
+
|
|
+ /* Traverse the device path to find IPv4()/Uri() or IPv6()/Uri() */
|
|
+ while (!IsDevicePathEnd(Node)) {
|
|
+ /* Save the MAC node so we can match the net card later */
|
|
+ if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
|
|
+ DevicePathSubType(Node) == MSG_MAC_ADDR_DP) {
|
|
+ MacNode = (MAC_ADDR_DEVICE_PATH *)Node;
|
|
+ CopyMem(&mac_addr, &MacNode->MacAddress, sizeof(EFI_MAC_ADDRESS));
|
|
+ }
|
|
+
|
|
+ if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
|
|
+ (DevicePathSubType(Node) == MSG_IPv4_DP ||
|
|
+ DevicePathSubType(Node) == MSG_IPv6_DP)) {
|
|
+ /* Save the IP node so we can set up the connection later */
|
|
+ if (DevicePathSubType(Node) == MSG_IPv6_DP) {
|
|
+ CopyMem(&ip6_node, Node, sizeof(IPv6_DEVICE_PATH));
|
|
+ is_ip6 = TRUE;
|
|
+ } else {
|
|
+ CopyMem(&ip4_node, Node, sizeof(IPv4_DEVICE_PATH));
|
|
+ is_ip6 = FALSE;
|
|
+ }
|
|
+
|
|
+ Node = NextDevicePathNode(Node);
|
|
+ NextNode = NextDevicePathNode(Node);
|
|
+ if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
|
|
+ DevicePathSubType(Node) == MSG_URI_DP &&
|
|
+ IsDevicePathEnd(NextNode)) {
|
|
+ /* Save the current URI */
|
|
+ UriNode = (URI_DEVICE_PATH *)Node;
|
|
+ uri_size = strlena(UriNode->Uri);
|
|
+ uri = AllocatePool(uri_size + 1);
|
|
+ if (!uri) {
|
|
+ perror(L"Failed to allocate uri\n");
|
|
+ return FALSE;
|
|
+ }
|
|
+ CopyMem(uri, UriNode->Uri, uri_size + 1);
|
|
+ FreePool(unpacked);
|
|
+ return TRUE;
|
|
+ }
|
|
+ }
|
|
+ Node = NextDevicePathNode(Node);
|
|
+ }
|
|
+
|
|
+ FreePool(unpacked);
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static EFI_STATUS
|
|
+generate_next_uri (CONST CHAR8 *current_uri, CONST CHAR8 *next_loader,
|
|
+ CHAR8 **uri)
|
|
+{
|
|
+ CONST CHAR8 *ptr;
|
|
+ UINTN next_len;
|
|
+ UINTN path_len = 0;
|
|
+ UINTN count = 0;
|
|
+
|
|
+ if (strncmpa(current_uri, (CHAR8 *)"http://", 7) == 0) {
|
|
+ ptr = current_uri + 7;
|
|
+ count += 7;
|
|
+ } else {
|
|
+ return EFI_INVALID_PARAMETER;
|
|
+ }
|
|
+
|
|
+ /* Extract the path */
|
|
+ next_len = strlena(next_loader);
|
|
+ while (*ptr != '\0') {
|
|
+ count++;
|
|
+ if (*ptr == '/')
|
|
+ path_len = count;
|
|
+ ptr++;
|
|
+ }
|
|
+
|
|
+ *uri = AllocatePool(sizeof(CHAR8) * (path_len + next_len + 1));
|
|
+ if (!*uri)
|
|
+ return EFI_OUT_OF_RESOURCES;
|
|
+
|
|
+ CopyMem(*uri, current_uri, path_len);
|
|
+ CopyMem(*uri + path_len, next_loader, next_len);
|
|
+ (*uri)[path_len + next_len] = '\0';
|
|
+
|
|
+ return EFI_SUCCESS;
|
|
+}
|
|
+
|
|
+static EFI_STATUS
|
|
+extract_hostname (CONST CHAR8 *url, CHAR8 **hostname)
|
|
+{
|
|
+ CONST CHAR8 *ptr, *start;
|
|
+ UINTN host_len = 0;
|
|
+
|
|
+ if (strncmpa(url, (CHAR8 *)"http://", 7) == 0)
|
|
+ start = url + 7;
|
|
+ else
|
|
+ return EFI_INVALID_PARAMETER;
|
|
+
|
|
+ ptr = start;
|
|
+ while (*ptr != '/' && *ptr != '\0') {
|
|
+ host_len++;
|
|
+ ptr++;
|
|
+ }
|
|
+
|
|
+ *hostname = AllocatePool(sizeof(CHAR8) * (host_len + 1));
|
|
+ if (!*hostname)
|
|
+ return EFI_OUT_OF_RESOURCES;
|
|
+
|
|
+ CopyMem(*hostname, start, host_len);
|
|
+ (*hostname)[host_len] = '\0';
|
|
+
|
|
+ return EFI_SUCCESS;
|
|
+}
|
|
+
|
|
+#define SAME_MAC_ADDR(a, b) (!CompareMem(a, b, sizeof(EFI_MAC_ADDRESS)))
|
|
+
|
|
+static EFI_HANDLE
|
|
+get_nic_handle (EFI_MAC_ADDRESS *mac)
|
|
+{
|
|
+ EFI_GUID http_binding_guid = EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID;
|
|
+ EFI_DEVICE_PATH *unpacked = NULL;
|
|
+ EFI_DEVICE_PATH *Node;
|
|
+ EFI_DEVICE_PATH *temp_path = NULL;
|
|
+ MAC_ADDR_DEVICE_PATH *MacNode;
|
|
+ EFI_HANDLE handle = NULL;
|
|
+ EFI_HANDLE *buffer;
|
|
+ UINTN NoHandles;
|
|
+ UINTN i;
|
|
+ EFI_STATUS status;
|
|
+
|
|
+ /* Get the list of handles that support the HTTP service binding
|
|
+ protocol */
|
|
+ status = uefi_call_wrapper(BS->LocateHandleBuffer, 5,
|
|
+ ByProtocol,
|
|
+ &http_binding_guid,
|
|
+ NULL,
|
|
+ &NoHandles,
|
|
+ &buffer);
|
|
+ if (EFI_ERROR(status))
|
|
+ return NULL;
|
|
+
|
|
+ for (i = 0; i < NoHandles; i++) {
|
|
+ temp_path = DevicePathFromHandle(buffer[i]);
|
|
+
|
|
+ /* Match the MAC address */
|
|
+ unpacked = UnpackDevicePath(temp_path);
|
|
+ if (!unpacked) {
|
|
+ perror(L"Failed to unpack device path\n");
|
|
+ continue;
|
|
+ }
|
|
+ Node = unpacked;
|
|
+ while (!IsDevicePathEnd(Node)) {
|
|
+ if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
|
|
+ DevicePathSubType(Node) == MSG_MAC_ADDR_DP) {
|
|
+ MacNode = (MAC_ADDR_DEVICE_PATH *)Node;
|
|
+ if (SAME_MAC_ADDR(mac, &MacNode->MacAddress)) {
|
|
+ handle = buffer[i];
|
|
+ goto out;
|
|
+ }
|
|
+ }
|
|
+ Node = NextDevicePathNode(Node);
|
|
+ }
|
|
+ FreePool(unpacked);
|
|
+ unpacked = NULL;
|
|
+ }
|
|
+
|
|
+out:
|
|
+ if (unpacked)
|
|
+ FreePool(unpacked);
|
|
+ FreePool(buffer);
|
|
+
|
|
+ return handle;
|
|
+}
|
|
+
|
|
+static BOOLEAN
|
|
+is_unspecified_addr (EFI_IPv6_ADDRESS ip6)
|
|
+{
|
|
+ UINT8 i;
|
|
+
|
|
+ for (i = 0; i<16; i++) {
|
|
+ if (ip6.Addr[i] != 0)
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static EFI_STATUS
|
|
+set_ip6(EFI_HANDLE *nic, IPv6_DEVICE_PATH *ip6node)
|
|
+{
|
|
+ EFI_GUID ip6_config_guid = EFI_IP6_CONFIG_PROTOCOL_GUID;
|
|
+ EFI_IP6_CONFIG_PROTOCOL *ip6cfg;
|
|
+ EFI_IP6_CONFIG_MANUAL_ADDRESS ip6;
|
|
+ EFI_IPv6_ADDRESS gateway;
|
|
+ EFI_STATUS status;
|
|
+
|
|
+ status = uefi_call_wrapper(BS->HandleProtocol, 3,
|
|
+ nic,
|
|
+ &ip6_config_guid,
|
|
+ (VOID **)&ip6cfg);
|
|
+ if (EFI_ERROR (status))
|
|
+ return status;
|
|
+
|
|
+ ip6.Address = ip6node->LocalIpAddress;
|
|
+ ip6.PrefixLength = ip6node->PrefixLength;
|
|
+ ip6.IsAnycast = FALSE;
|
|
+ status = uefi_call_wrapper(ip6cfg->SetData, 4,
|
|
+ ip6cfg,
|
|
+ Ip6ConfigDataTypeManualAddress,
|
|
+ sizeof(ip6),
|
|
+ &ip6);
|
|
+ if (EFI_ERROR (status))
|
|
+ return status;
|
|
+
|
|
+ gateway = ip6node->GatewayIpAddress;
|
|
+ if (is_unspecified_addr(gateway))
|
|
+ return EFI_SUCCESS;
|
|
+
|
|
+ status = uefi_call_wrapper(ip6cfg->SetData, 4,
|
|
+ ip6cfg,
|
|
+ Ip6ConfigDataTypeGateway,
|
|
+ sizeof(gateway),
|
|
+ &gateway);
|
|
+ if (EFI_ERROR (status))
|
|
+ return status;
|
|
+
|
|
+ return EFI_SUCCESS;
|
|
+}
|
|
+
|
|
+static EFI_STATUS
|
|
+set_ip4(EFI_HANDLE *nic, IPv4_DEVICE_PATH *ip4node)
|
|
+{
|
|
+ EFI_GUID ip4_config2_guid = EFI_IP4_CONFIG2_PROTOCOL_GUID;
|
|
+ EFI_IP4_CONFIG2_PROTOCOL *ip4cfg2;
|
|
+ EFI_IP4_CONFIG2_MANUAL_ADDRESS ip4;
|
|
+ EFI_IPv4_ADDRESS gateway;
|
|
+ EFI_STATUS status;
|
|
+
|
|
+ status = uefi_call_wrapper(BS->HandleProtocol, 3,
|
|
+ nic,
|
|
+ &ip4_config2_guid,
|
|
+ (VOID **)&ip4cfg2);
|
|
+ if (EFI_ERROR (status))
|
|
+ return status;
|
|
+
|
|
+ ip4.Address = ip4node->LocalIpAddress;
|
|
+ ip4.SubnetMask = ip4node->SubnetMask;
|
|
+ status = uefi_call_wrapper(ip4cfg2->SetData, 4,
|
|
+ ip4cfg2,
|
|
+ Ip4Config2DataTypeManualAddress,
|
|
+ sizeof(ip4),
|
|
+ &ip4);
|
|
+ if (EFI_ERROR (status))
|
|
+ return status;
|
|
+
|
|
+ gateway = ip4node->GatewayIpAddress;
|
|
+ status = uefi_call_wrapper(ip4cfg2->SetData, 4,
|
|
+ ip4cfg2,
|
|
+ Ip4Config2DataTypeGateway,
|
|
+ sizeof(gateway),
|
|
+ &gateway);
|
|
+ if (EFI_ERROR (status))
|
|
+ return status;
|
|
+
|
|
+ return EFI_SUCCESS;
|
|
+}
|
|
+
|
|
+static VOID EFIAPI
|
|
+httpnotify (EFI_EVENT Event, VOID *Context)
|
|
+{
|
|
+ *((BOOLEAN *) Context) = TRUE;
|
|
+}
|
|
+
|
|
+static EFI_STATUS
|
|
+configure_http (EFI_HTTP_PROTOCOL *http, BOOLEAN is_ip6)
|
|
+{
|
|
+ EFI_HTTP_CONFIG_DATA http_mode;
|
|
+ EFI_HTTPv4_ACCESS_POINT ip4node;
|
|
+ EFI_HTTPv6_ACCESS_POINT ip6node;
|
|
+
|
|
+ /* Configure HTTP */
|
|
+ ZeroMem(&http_mode, sizeof(http_mode));
|
|
+ http_mode.HttpVersion = HttpVersion11;
|
|
+ /* use the default time out */
|
|
+ http_mode.TimeOutMillisec = 0;
|
|
+
|
|
+ if (!is_ip6) {
|
|
+ http_mode.LocalAddressIsIPv6 = FALSE;
|
|
+ ZeroMem(&ip4node, sizeof(ip4node));
|
|
+ ip4node.UseDefaultAddress = TRUE;
|
|
+ http_mode.AccessPoint.IPv4Node = &ip4node;
|
|
+ } else {
|
|
+ http_mode.LocalAddressIsIPv6 = TRUE;
|
|
+ ZeroMem(&ip6node, sizeof(ip6node));
|
|
+ http_mode.AccessPoint.IPv6Node = &ip6node;
|
|
+ }
|
|
+
|
|
+ return uefi_call_wrapper(http->Configure, 2, http, &http_mode);
|
|
+}
|
|
+
|
|
+static EFI_STATUS
|
|
+send_http_request (EFI_HTTP_PROTOCOL *http, CHAR8 *hostname, CHAR8 *uri)
|
|
+{
|
|
+ EFI_HTTP_TOKEN tx_token;
|
|
+ EFI_HTTP_MESSAGE tx_message;
|
|
+ EFI_HTTP_REQUEST_DATA request;
|
|
+ EFI_HTTP_HEADER headers[3];
|
|
+ BOOLEAN request_done;
|
|
+ CHAR16 *Url = NULL;
|
|
+ EFI_STATUS status;
|
|
+ EFI_STATUS event_status;
|
|
+
|
|
+ /* Convert the ascii string to the UCS2 string */
|
|
+ Url = PoolPrint(L"%a", uri);
|
|
+ if (!Url)
|
|
+ return EFI_OUT_OF_RESOURCES;
|
|
+
|
|
+ request.Method = HttpMethodGet;
|
|
+ request.Url = Url;
|
|
+
|
|
+ /* Prepare the HTTP headers */
|
|
+ headers[0].FieldName = (CHAR8 *)"Host";
|
|
+ headers[0].FieldValue = hostname;
|
|
+ headers[1].FieldName = (CHAR8 *)"Accept";
|
|
+ headers[1].FieldValue = (CHAR8 *)"*/*";
|
|
+ headers[2].FieldName = (CHAR8 *)"User-Agent";
|
|
+ headers[2].FieldValue = (CHAR8 *)"UefiHttpBoot/1.0";
|
|
+
|
|
+ tx_message.Data.Request = &request;
|
|
+ tx_message.HeaderCount = 3;
|
|
+ tx_message.Headers = headers;
|
|
+ tx_message.BodyLength = 0;
|
|
+ tx_message.Body = NULL;
|
|
+
|
|
+ tx_token.Status = EFI_NOT_READY;
|
|
+ tx_token.Message = &tx_message;
|
|
+ tx_token.Event = NULL;
|
|
+ request_done = FALSE;
|
|
+ status = uefi_call_wrapper(BS->CreateEvent, 5,
|
|
+ EVT_NOTIFY_SIGNAL,
|
|
+ TPL_NOTIFY,
|
|
+ httpnotify,
|
|
+ &request_done,
|
|
+ &tx_token.Event);
|
|
+ if (EFI_ERROR(status)) {
|
|
+ perror(L"Failed to Create Event for HTTP request: %r\n", status);
|
|
+ goto no_event;
|
|
+ }
|
|
+
|
|
+ /* Send out the request */
|
|
+ status = uefi_call_wrapper(http->Request, 2, http, &tx_token);
|
|
+ if (EFI_ERROR(status)) {
|
|
+ perror(L"HTTP request failed: %r\n", status);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ /* Wait for the response */
|
|
+ while (!request_done)
|
|
+ uefi_call_wrapper(http->Poll, 1, http);
|
|
+
|
|
+ if (EFI_ERROR(tx_token.Status)) {
|
|
+ perror(L"HTTP request: %r\n", tx_token.Status);
|
|
+ status = tx_token.Status;
|
|
+ }
|
|
+
|
|
+error:
|
|
+ event_status = uefi_call_wrapper(BS->CloseEvent, 1, tx_token.Event);
|
|
+ if (EFI_ERROR(event_status)) {
|
|
+ perror(L"Failed to close Event for HTTP request: %r\n",
|
|
+ event_status);
|
|
+ }
|
|
+
|
|
+no_event:
|
|
+ if (Url)
|
|
+ FreePool(Url);
|
|
+
|
|
+ return status;
|
|
+}
|
|
+
|
|
+static EFI_STATUS
|
|
+receive_http_response(EFI_HTTP_PROTOCOL *http, VOID **buffer, UINTN *buf_size)
|
|
+{
|
|
+ EFI_HTTP_TOKEN rx_token;
|
|
+ EFI_HTTP_MESSAGE rx_message;
|
|
+ EFI_HTTP_RESPONSE_DATA response;
|
|
+ EFI_HTTP_STATUS_CODE http_status;
|
|
+ BOOLEAN response_done;
|
|
+ UINTN i, downloaded;
|
|
+ CHAR8 rx_buffer[9216];
|
|
+ EFI_STATUS status;
|
|
+ EFI_STATUS event_status;
|
|
+
|
|
+ /* Initialize the rx message and buffer */
|
|
+ response.StatusCode = HTTP_STATUS_UNSUPPORTED_STATUS;
|
|
+ rx_message.Data.Response = &response;
|
|
+ rx_message.HeaderCount = 0;
|
|
+ rx_message.Headers = 0;
|
|
+ rx_message.BodyLength = sizeof(rx_buffer);
|
|
+ rx_message.Body = rx_buffer;
|
|
+
|
|
+ rx_token.Status = EFI_NOT_READY;
|
|
+ rx_token.Message = &rx_message;
|
|
+ rx_token.Event = NULL;
|
|
+ response_done = FALSE;
|
|
+ status = uefi_call_wrapper(BS->CreateEvent, 5,
|
|
+ EVT_NOTIFY_SIGNAL,
|
|
+ TPL_NOTIFY,
|
|
+ httpnotify,
|
|
+ &response_done,
|
|
+ &rx_token.Event);
|
|
+ if (EFI_ERROR(status)) {
|
|
+ perror(L"Failed to Create Event for HTTP response: %r\n", status);
|
|
+ goto no_event;
|
|
+ }
|
|
+
|
|
+ /* Notify the firmware to receive the HTTP messages */
|
|
+ status = uefi_call_wrapper(http->Response, 2, http, &rx_token);
|
|
+ if (EFI_ERROR(status)) {
|
|
+ perror(L"HTTP response failed: %r\n", status);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ /* Wait for the response */
|
|
+ while (!response_done)
|
|
+ uefi_call_wrapper(http->Poll, 1, http);
|
|
+
|
|
+ if (EFI_ERROR(rx_token.Status)) {
|
|
+ perror(L"HTTP response: %r\n", rx_token.Status);
|
|
+ status = rx_token.Status;
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ /* Check the HTTP status code */
|
|
+ http_status = rx_token.Message->Data.Response->StatusCode;
|
|
+ if (http_status != HTTP_STATUS_200_OK) {
|
|
+ perror(L"HTTP Status Code: %d\n",
|
|
+ convert_http_status_code(http_status));
|
|
+ status = EFI_ABORTED;
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ /* Check the length of the file */
|
|
+ for (i = 0; i < rx_message.HeaderCount; i++) {
|
|
+ if (!strcmpa(rx_message.Headers[i].FieldName, (CHAR8 *)"Content-Length")) {
|
|
+ *buf_size = ascii_to_int(rx_message.Headers[i].FieldValue);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (*buf_size == 0) {
|
|
+ perror(L"Failed to get Content-Lenght\n");
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ *buffer = AllocatePool(*buf_size);
|
|
+ if (!*buffer) {
|
|
+ perror(L"Failed to allocate new rx buffer\n");
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ downloaded = rx_message.BodyLength;
|
|
+
|
|
+ CopyMem(*buffer, rx_buffer, downloaded);
|
|
+
|
|
+ /* Retreive the rest of the message */
|
|
+ while (downloaded < *buf_size) {
|
|
+ if (rx_message.Headers) {
|
|
+ FreePool(rx_message.Headers);
|
|
+ }
|
|
+ rx_message.Headers = NULL;
|
|
+ rx_message.HeaderCount = 0;
|
|
+ rx_message.Data.Response = NULL;
|
|
+ rx_message.BodyLength = sizeof(rx_buffer);
|
|
+ rx_message.Body = rx_buffer;
|
|
+
|
|
+ rx_token.Status = EFI_NOT_READY;
|
|
+ response_done = FALSE;
|
|
+
|
|
+ status = uefi_call_wrapper(http->Response, 2, http, &rx_token);
|
|
+ if (EFI_ERROR(status)) {
|
|
+ perror(L"HTTP response failed: %r\n", status);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ while (!response_done)
|
|
+ uefi_call_wrapper(http->Poll, 1, http);
|
|
+
|
|
+ if (EFI_ERROR(rx_token.Status)) {
|
|
+ perror(L"HTTP response: %r\n", rx_token.Status);
|
|
+ status = rx_token.Status;
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ if (rx_message.BodyLength + downloaded > *buf_size) {
|
|
+ status = EFI_BAD_BUFFER_SIZE;
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ CopyMem(*buffer + downloaded, rx_buffer, rx_message.BodyLength);
|
|
+
|
|
+ downloaded += rx_message.BodyLength;
|
|
+ }
|
|
+
|
|
+error:
|
|
+ event_status = uefi_call_wrapper(BS->CloseEvent, 1, rx_token.Event);
|
|
+ if (EFI_ERROR(event_status)) {
|
|
+ perror(L"Failed to close Event for HTTP response: %r\n",
|
|
+ event_status);
|
|
+ }
|
|
+
|
|
+no_event:
|
|
+ if (EFI_ERROR(status) && *buffer)
|
|
+ FreePool(*buffer);
|
|
+
|
|
+ return status;
|
|
+}
|
|
+
|
|
+static EFI_STATUS
|
|
+http_fetch (EFI_HANDLE image, EFI_HANDLE device,
|
|
+ CHAR8 *hostname, CHAR8 *uri, BOOLEAN is_ip6,
|
|
+ VOID **buffer, UINTN *buf_size)
|
|
+{
|
|
+ EFI_GUID http_binding_guid = EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID;
|
|
+ EFI_GUID http_protocol_guid = EFI_HTTP_PROTOCOL_GUID;
|
|
+ EFI_SERVICE_BINDING *service;
|
|
+ EFI_HANDLE http_handle;
|
|
+ EFI_HTTP_PROTOCOL *http;
|
|
+ EFI_STATUS status;
|
|
+ EFI_STATUS child_status;
|
|
+
|
|
+ *buffer = NULL;
|
|
+ *buf_size = 0;
|
|
+
|
|
+ /* Open HTTP Service Binding Protocol */
|
|
+ status = uefi_call_wrapper(BS->OpenProtocol, 6, device,
|
|
+ &http_binding_guid, (VOID **)&service,
|
|
+ image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
+ if (EFI_ERROR (status))
|
|
+ return status;
|
|
+
|
|
+ /* Create the ChildHandle from the Service Binding */
|
|
+ /* Set the handle to NULL to request a new handle */
|
|
+ http_handle = NULL;
|
|
+ status = uefi_call_wrapper(service->CreateChild, 2, service,
|
|
+ &http_handle);
|
|
+ if (EFI_ERROR (status))
|
|
+ return status;
|
|
+
|
|
+ /* Get the http protocol */
|
|
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, http_handle,
|
|
+ &http_protocol_guid, (VOID **)&http);
|
|
+ if (EFI_ERROR (status)) {
|
|
+ perror(L"Failed to get http\n");
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ status = configure_http(http, is_ip6);
|
|
+ if (EFI_ERROR (status)) {
|
|
+ perror(L"Failed to configure http: %r\n", status);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ status = send_http_request(http, hostname, uri);
|
|
+ if (EFI_ERROR(status)) {
|
|
+ perror(L"Failed to send HTTP request: %r\n", status);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ status = receive_http_response(http, buffer, buf_size);
|
|
+ if (EFI_ERROR(status)) {
|
|
+ perror(L"Failed to receive HTTP response: %r\n", status);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+error:
|
|
+ child_status = uefi_call_wrapper(service->DestroyChild, 2, service,
|
|
+ http_handle);
|
|
+
|
|
+ if (EFI_ERROR(status)) {
|
|
+ return status;
|
|
+ } else if (EFI_ERROR(child_status)) {
|
|
+ return child_status;
|
|
+ }
|
|
+
|
|
+ return EFI_SUCCESS;
|
|
+}
|
|
+
|
|
+EFI_STATUS
|
|
+httpboot_fetch_buffer (EFI_HANDLE image, VOID **buffer, UINTN *buf_size)
|
|
+{
|
|
+ EFI_STATUS status;
|
|
+ EFI_HANDLE nic;
|
|
+ CHAR8 *next_loader = NULL;
|
|
+ CHAR8 *next_uri = NULL;
|
|
+ CHAR8 *hostname = NULL;
|
|
+
|
|
+ if (!uri)
|
|
+ return EFI_NOT_READY;
|
|
+
|
|
+ next_loader = translate_slashes(DEFAULT_LOADER_CHAR);
|
|
+
|
|
+ /* Create the URI for the next loader based on the original URI */
|
|
+ status = generate_next_uri(uri, next_loader, &next_uri);
|
|
+ if (EFI_ERROR (status)) {
|
|
+ perror(L"Next URI: %a, %r\n", next_uri, status);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ /* Extract the hostname (or IP) from URI */
|
|
+ status = extract_hostname(uri, &hostname);
|
|
+ if (EFI_ERROR (status)) {
|
|
+ perror(L"hostname: %a, %r\n", hostname, status);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ /* Get the handle that associates with the NIC we are using and
|
|
+ also supports the HTTP service binding protocol */
|
|
+ nic = get_nic_handle(&mac_addr);
|
|
+ if (!nic) {
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ /* UEFI stops DHCP after fetching the image and stores the related
|
|
+ information in the device path node. We have to set up the
|
|
+ connection on our own for the further operations. */
|
|
+ if (!is_ip6)
|
|
+ status = set_ip4(nic, &ip4_node);
|
|
+ else
|
|
+ status = set_ip6(nic, &ip6_node);
|
|
+ if (EFI_ERROR (status)) {
|
|
+ perror(L"Failed to set IP for HTTPBoot: %r\n", status);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ /* Use HTTP protocl to fetch the remote file */
|
|
+ status = http_fetch (image, nic, hostname, next_uri, is_ip6,
|
|
+ buffer, buf_size);
|
|
+ if (EFI_ERROR (status)) {
|
|
+ perror(L"Failed to fetch image: %r\n", status);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+error:
|
|
+ FreePool(uri);
|
|
+ uri = NULL;
|
|
+ if (next_uri)
|
|
+ FreePool(next_uri);
|
|
+ if (hostname)
|
|
+ FreePool(hostname);
|
|
+
|
|
+ return status;
|
|
+}
|
|
diff --git a/httpboot.h b/httpboot.h
|
|
new file mode 100644
|
|
index 0000000..79ee465
|
|
--- /dev/null
|
|
+++ b/httpboot.h
|
|
@@ -0,0 +1,41 @@
|
|
+/*
|
|
+ * Copyright 2015 SUSE LINUX GmbH <glin@suse.com>
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ *
|
|
+ * Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ *
|
|
+ * Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the
|
|
+ * distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
+ *
|
|
+ * Significant portions of this code are derived from Tianocore
|
|
+ * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel
|
|
+ * Corporation.
|
|
+ */
|
|
+
|
|
+#ifndef _HTTPBOOT_H_
|
|
+#define _HTTPBOOT_H_
|
|
+
|
|
+BOOLEAN find_httpboot (EFI_DEVICE_PATH *devpath);
|
|
+
|
|
+EFI_STATUS httpboot_fetch_buffer (EFI_HANDLE image, VOID **buffer, UINTN *buf_size);
|
|
+
|
|
+#endif
|
|
diff --git a/shim.c b/shim.c
|
|
index c93d96d..0e42a7b 100644
|
|
--- a/shim.c
|
|
+++ b/shim.c
|
|
@@ -39,6 +39,7 @@
|
|
#include "PeImage.h"
|
|
#include "shim.h"
|
|
#include "netboot.h"
|
|
+#include "httpboot.h"
|
|
#include "shim_cert.h"
|
|
#include "replacements.h"
|
|
#include "ucs2.h"
|
|
@@ -1651,6 +1652,17 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
|
|
}
|
|
data = sourcebuffer;
|
|
datasize = sourcesize;
|
|
+#if defined(ENABLE_HTTPBOOT)
|
|
+ } else if (find_httpboot(li->DeviceHandle)) {
|
|
+ efi_status = httpboot_fetch_buffer (image_handle, &sourcebuffer,
|
|
+ &sourcesize);
|
|
+ if (efi_status != EFI_SUCCESS) {
|
|
+ perror(L"Unable to fetch HTTP image: %r\n", efi_status);
|
|
+ return efi_status;
|
|
+ }
|
|
+ data = sourcebuffer;
|
|
+ datasize = sourcesize;
|
|
+#endif
|
|
} else {
|
|
/*
|
|
* Read the new executable off disk
|
|
--
|
|
2.7.1
|
|
|