efi_loader: device_path: add support for HTTP device path

Add efi_dp_from_http to form a device path from HTTP. The
device path is the concatenation of the device path returned
by efi_dp_from_ipv4 together with an URI node and an END node.

Signed-off-by: Adriano Cordova <adrianox@gmail.com>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
Adriano Cordova 2024-12-04 00:05:22 -03:00 committed by Heinrich Schuchardt
parent b20f497f22
commit 4b0723004b
2 changed files with 65 additions and 0 deletions

View file

@ -1021,6 +1021,70 @@ static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip,
return dp2;
}
/**
* efi_dp_from_http() - set device path from http
*
* Set the device path to an IPv4 path as provided by efi_dp_from_ipv4
* concatenated with a device path of subtype DEVICE_PATH_SUB_TYPE_MSG_URI,
* and an END node.
*
* @server: URI of remote server
* Return: pointer to HTTP device path, NULL on error
*/
struct efi_device_path *efi_dp_from_http(const char *server)
{
struct efi_device_path *dp1, *dp2;
struct efi_device_path_uri *uridp;
efi_uintn_t uridp_len;
char *pos;
char tmp[128];
struct efi_ipv4_address ip;
struct efi_ipv4_address mask;
if ((server && strlen("http://") + strlen(server) + 1 > sizeof(tmp)) ||
(!server && IS_ENABLED(CONFIG_NET_LWIP)))
return NULL;
efi_net_get_addr(&ip, &mask, NULL);
dp1 = efi_dp_from_ipv4(&ip, &mask, NULL);
if (!dp1)
return NULL;
strcpy(tmp, "http://");
if (server) {
strlcat(tmp, server, sizeof(tmp));
#if !IS_ENABLED(CONFIG_NET_LWIP)
}
else {
ip_to_string(net_server_ip, tmp + strlen("http://"));
#endif
}
uridp_len = sizeof(struct efi_device_path) + strlen(tmp) + 1;
uridp = efi_alloc(uridp_len + sizeof(END));
if (!uridp) {
log_err("Out of memory\n");
return NULL;
}
uridp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
uridp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_URI;
uridp->dp.length = uridp_len;
debug("device path: setting uri device path to %s\n", tmp);
memcpy(uridp->uri, tmp, strlen(tmp) + 1);
pos = (char *)uridp + uridp_len;
memcpy(pos, &END, sizeof(END));
dp2 = efi_dp_concat(dp1, (const struct efi_device_path *)uridp, 0);
efi_free_pool(uridp);
efi_free_pool(dp1);
return dp2;
}
/* Construct a device-path for memory-mapped image */
struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
uint64_t start_address,