[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v5 02/20] net: read bracketed ipv6 addrs and port numbers
From: |
Robbie Harwood |
Subject: |
[PATCH v5 02/20] net: read bracketed ipv6 addrs and port numbers |
Date: |
Tue, 25 Apr 2023 11:05:13 -0400 |
Allow specifying port numbers for http and tftp paths and allow ipv6
addresses to be recognized with brackets around them, which is required
to specify a port number.
Co-authored-by: Aaron Miller <aaronmiller@fb.com>
Signed-off-by: Aaron Miller <aaronmiller@fb.com>
Co-authored-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
---
docs/grub.texi | 12 +++++++
grub-core/net/http.c | 18 ++++++++---
grub-core/net/net.c | 77 +++++++++++++++++++++++++++++++++++++++++---
grub-core/net/tftp.c | 6 +++-
include/grub/net.h | 1 +
5 files changed, 104 insertions(+), 10 deletions(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index 73f4d8c017..bca1407bf3 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -3057,6 +3057,18 @@ environment variable @samp{net_default_server} is used.
Before using the network drive, you must initialize the network.
@xref{Network}, for more information.
+When using @samp{http} or @samp{tftp}, ports other than @samp{80} can be
+specified using a colon (@samp{:}) after the address. To avoid parsing
+conflicts, when using IPv6 addresses with custom ports, the addresses
+must be enclosed with square brackets (@samp{[]}), as is standard
+practice.
+
+@example
+(http,example.com:31337)
+(http,127.0.0.1:339)
+(http,[::1]:11235)
+@end example
+
If you boot GRUB from a CD-ROM, @samp{(cd)} is available. @xref{Making
a GRUB bootable CD-ROM}, for details.
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index d67cad4829..df690acf67 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -318,12 +318,14 @@ http_establish (struct grub_file *file, grub_off_t
offset, int initial)
int i;
struct grub_net_buff *nb;
grub_err_t err;
+ char *server = file->device->net->server;
+ int port = file->device->net->port;
nb = grub_netbuff_alloc (GRUB_NET_TCP_RESERVE_SIZE
+ sizeof ("GET ") - 1
+ grub_strlen (data->filename)
+ sizeof (" HTTP/1.1\r\nHost: ") - 1
- + grub_strlen (file->device->net->server)
+ + grub_strlen (server) + sizeof (":XXXXXXXXXX")
+ sizeof ("\r\nUser-Agent: " PACKAGE_STRING
"\r\n") - 1
+ sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX"
@@ -362,7 +364,7 @@ http_establish (struct grub_file *file, grub_off_t offset,
int initial)
sizeof (" HTTP/1.1\r\nHost: ") - 1);
ptr = nb->tail;
- err = grub_netbuff_put (nb, grub_strlen (file->device->net->server));
+ err = grub_netbuff_put (nb, grub_strlen (server));
if (err)
{
grub_netbuff_free (nb);
@@ -371,6 +373,12 @@ http_establish (struct grub_file *file, grub_off_t offset,
int initial)
grub_memcpy (ptr, file->device->net->server,
grub_strlen (file->device->net->server));
+ if (port)
+ {
+ ptr = nb->tail;
+ grub_snprintf ((char *) ptr, sizeof (":XXXXXXXXXX"), ":%d", port);
+ }
+
ptr = nb->tail;
err = grub_netbuff_put (nb,
sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n")
@@ -396,8 +404,10 @@ http_establish (struct grub_file *file, grub_off_t offset,
int initial)
grub_netbuff_put (nb, 2);
grub_memcpy (ptr, "\r\n", 2);
- data->sock = grub_net_tcp_open (file->device->net->server,
- HTTP_PORT, http_receive,
+ grub_dprintf ("http", "opening path %s on host %s TCP port %d\n",
+ data->filename, server, port ? port : HTTP_PORT);
+ data->sock = grub_net_tcp_open (server,
+ port ? port : HTTP_PORT, http_receive,
http_err, NULL,
file);
if (!data->sock)
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
index 7046dc5789..03a3063ca2 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -443,6 +443,13 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char
**rest)
grub_uint16_t newip[8];
const char *ptr = val;
int word, quaddot = -1;
+ bool bracketed = false;
+
+ if (ptr[0] == '[')
+ {
+ bracketed = true;
+ ptr++;
+ }
if (ptr[0] == ':' && ptr[1] != ':')
return 0;
@@ -481,6 +488,8 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char
**rest)
grub_memset (&newip[quaddot], 0, (7 - word) * sizeof (newip[0]));
}
grub_memcpy (ip, newip, 16);
+ if (bracketed && *ptr == ']')
+ ptr++;
if (rest)
*rest = ptr;
return 1;
@@ -1319,8 +1328,10 @@ grub_net_open_real (const char *name)
{
grub_net_app_level_t proto;
const char *protname, *server;
+ char *host, *port_start;
grub_size_t protnamelen;
int try;
+ int port = 0;
if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0)
{
@@ -1358,6 +1369,62 @@ grub_net_open_real (const char *name)
return NULL;
}
+ /* ipv6 or port specified? */
+ if ((port_start = grub_strchr (server, ':')))
+ {
+ char *ipv6_begin;
+ if ((ipv6_begin = grub_strchr (server, '[')))
+ {
+ char *ipv6_end = grub_strchr (server, ']');
+ if (!ipv6_end)
+ {
+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("mismatched [ in
address"));
+ return NULL;
+ }
+ /* port number after bracketed ipv6 addr */
+ if (ipv6_end[1] == ':')
+ {
+ port = grub_strtoul (ipv6_end + 2, NULL, 10);
+ if (port == 0 || port > 65535)
+ {
+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("bad port number"));
+ return NULL;
+ }
+ }
+ host = grub_strndup (ipv6_begin, (ipv6_end - ipv6_begin) + 1);
+ }
+ else
+ {
+ if (grub_strchr (port_start + 1, ':'))
+ {
+ int iplen = grub_strlen (server);
+ /* bracket bare ipv6 addrs */
+ host = grub_malloc (iplen + 3);
+ if (!host)
+ return NULL;
+ host[0] = '[';
+ grub_memcpy (host + 1, server, iplen);
+ host[iplen + 1] = ']';
+ host[iplen + 2] = '\0';
+ }
+ else
+ {
+ /* hostname:port or ipv4:port */
+ port = grub_strtol (port_start + 1, NULL, 10);
+ if (port == 0 || port > 65535)
+ {
+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("bad port number"));
+ return NULL;
+ }
+ host = grub_strndup (server, port_start - server);
+ }
+ }
+ }
+ else
+ host = grub_strdup (server);
+ if (!host)
+ return NULL;
+
for (try = 0; try < 2; try++)
{
FOR_NET_APP_LEVEL (proto)
@@ -1367,14 +1434,13 @@ grub_net_open_real (const char *name)
{
grub_net_t ret = grub_zalloc (sizeof (*ret));
if (!ret)
- return NULL;
- ret->protocol = proto;
- ret->server = grub_strdup (server);
- if (!ret->server)
{
- grub_free (ret);
+ grub_free (host);
return NULL;
}
+ ret->protocol = proto;
+ ret->port = port;
+ ret->server = host;
ret->fs = &grub_net_fs;
return ret;
}
@@ -1449,6 +1515,7 @@ grub_net_open_real (const char *name)
grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' not found"),
name);
+ grub_free (host);
return NULL;
}
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
index 7dbd3056d6..409b1d09bc 100644
--- a/grub-core/net/tftp.c
+++ b/grub-core/net/tftp.c
@@ -295,6 +295,7 @@ tftp_open (struct grub_file *file, const char *filename)
grub_err_t err;
grub_uint8_t *nbd;
grub_net_network_level_address_t addr;
+ int port = file->device->net->port;
data = grub_zalloc (sizeof (*data));
if (!data)
@@ -361,12 +362,15 @@ tftp_open (struct grub_file *file, const char *filename)
err = grub_net_resolve_address (file->device->net->server, &addr);
if (err)
{
+ grub_dprintf ("tftp", "Address resolution failed: %d\n", err);
+ grub_dprintf ("tftp", "file_size is %" PRIuGRUB_UINT64_T ", block_size
is %" PRIuGRUB_UINT32_T "\n",
+ data->file_size, data->block_size);
grub_free (data);
return err;
}
data->sock = grub_net_udp_open (addr,
- TFTP_SERVER_PORT, tftp_receive,
+ port ? port : TFTP_SERVER_PORT, tftp_receive,
file);
if (!data->sock)
{
diff --git a/include/grub/net.h b/include/grub/net.h
index 79cba357ae..844e501c12 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -271,6 +271,7 @@ typedef struct grub_net
{
char *server;
char *name;
+ grub_uint16_t port;
grub_net_app_level_t protocol;
grub_net_packets_t packs;
grub_off_t offset;
--
2.40.0
- [PATCH v5 16/20] Prepend prefix when HTTP path is relative, (continued)
- [PATCH v5 16/20] Prepend prefix when HTTP path is relative, Robbie Harwood, 2023/04/25
- [PATCH v5 11/20] efinet: also use the firmware acceleration for http, Robbie Harwood, 2023/04/25
- [PATCH v5 08/20] efinet Configure network from UEFI device path, Robbie Harwood, 2023/04/25
- [PATCH v5 06/20] grub.texi: Add net_bootp6 doumentation, Robbie Harwood, 2023/04/25
- [PATCH v5 15/20] Try mac/guid/etc before grub.cfg on tftp config files, Robbie Harwood, 2023/04/25
- [PATCH v5 20/20] efinet: Add DHCP proxy support, Robbie Harwood, 2023/04/25
- [PATCH v5 05/20] efinet: add structures for PXE messages, Robbie Harwood, 2023/04/25
- [PATCH v5 18/20] http: Prepend prefix when the HTTP path is relative, Robbie Harwood, 2023/04/25
- [PATCH v5 07/20] bootp: Process DHCPACK packet during HTTP Boot, Robbie Harwood, 2023/04/25
- [PATCH v5 09/20] efinet: set DNS server from UEFI protocol, Robbie Harwood, 2023/04/25
- [PATCH v5 02/20] net: read bracketed ipv6 addrs and port numbers,
Robbie Harwood <=
- [PATCH v5 17/20] efi/http: Enclose literal IPv6 addresses in square brackets, Robbie Harwood, 2023/04/25
- [PATCH v5 12/20] efi/http: match protocol+hostname of boot url in root_url, Robbie Harwood, 2023/04/25
- [PATCH v5 14/20] use fw_path prefix when fallback searching for grub config, Robbie Harwood, 2023/04/25