There are usecases for running TFTP and HTTP on nonstandard ports. This patch allows you to specify nonstandard ports with the following syntax:
set root=(http,$net_default_server,portno) or set root=(http,,portno) It also allows an initial : where a , should be for pxe: backwards compatibility --- ChangeLog | 11 ++++ grub-core/net/http.c | 3 +- grub-core/net/net.c | 152 +++++++++++++++++++++++++-------------------------- grub-core/net/tftp.c | 3 +- include/grub/net.h | 2 + 5 files changed, 90 insertions(+), 81 deletions(-) diff --git a/ChangeLog b/ChangeLog index c38917b..4f08e29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2014-12-11 Victor Lowther <victor.lowt...@gmail.com> + + * grub-core/net/net.c: Allow grub_net_open_real to handle parsing + an optional port number for tftp and http network protocols. + * grub-core/net/http.c: Expose default port for HTTP in the + grub_http_protocol struct. + * grub-core/net/tftp.c: Expose default port for TFTP in the + grub_tftp_protocol struct. + * includegrub/net.h: Extend grub_net_app_protocol and grub_net_t + to include the port number. + 2014-12-09 Andrei Borzenkov <arvidj...@gmail.com> * grub-core/term/serial.c (grub_cmd_serial): Fix --rtscts diff --git a/grub-core/net/http.c b/grub-core/net/http.c index 4684f8b..2562d5e 100644 --- a/grub-core/net/http.c +++ b/grub-core/net/http.c @@ -392,7 +392,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) grub_memcpy (ptr, "\r\n", 2); data->sock = grub_net_tcp_open (file->device->net->server, - HTTP_PORT, http_receive, + file->device->net->port, http_receive, http_err, http_err, file); if (!data->sock) @@ -545,6 +545,7 @@ http_packets_pulled (struct grub_file *file) static struct grub_net_app_protocol grub_http_protocol = { .name = "http", + .port = HTTP_PORT, .open = http_open, .close = http_close, .seek = http_seek, diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 21a4e94..5dfad02 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -1271,98 +1271,92 @@ static grub_net_t grub_net_open_real (const char *name) { grub_net_app_level_t proto; - const char *protname, *server; + char *server; + const char *protname, *work, *comma; grub_size_t protnamelen; - int try; - - if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0) + grub_uint16_t port; + grub_net_t ret; + port = 0; + server = NULL; + work = name; + protname = NULL; + + if (grub_strncmp (work, "pxe", sizeof ("pxe") - 1) == 0) { protname = "tftp"; - protnamelen = sizeof ("tftp") - 1; - server = name + sizeof ("pxe:") - 1; + work += (sizeof ("pxe") - 1); } - else if (grub_strcmp (name, "pxe") == 0) + else if (grub_strncmp (work, "tftp", sizeof("tftp") - 1) == 0) { protname = "tftp"; - protnamelen = sizeof ("tftp") - 1; - server = grub_net_default_server; + work += (sizeof ("tftp") - 1); } - else + else if (grub_strncmp (work, "http", sizeof("http") - 1) == 0) { - const char *comma; - comma = grub_strchr (name, ','); - if (comma) - { - protnamelen = comma - name; - server = comma + 1; - protname = name; - } - else - { - protnamelen = grub_strlen (name); - server = grub_net_default_server; - protname = name; - } + protname = "http"; + work += (sizeof ("http") - 1); } - if (!server) + + if (grub_strlen(work) != 0 && !(*work == ',' || *work == ':')) { - grub_error (GRUB_ERR_NET_BAD_ADDRESS, - N_("no server is specified")); + grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' not found"), + name); return NULL; - } - - for (try = 0; try < 2; try++) + } + if (grub_strlen(work)) { - FOR_NET_APP_LEVEL (proto) - { - if (grub_memcmp (proto->name, protname, protnamelen) == 0 - && proto->name[protnamelen] == 0) - { - grub_net_t ret = grub_zalloc (sizeof (*ret)); - if (!ret) - return NULL; - ret->protocol = proto; - if (server) - { - ret->server = grub_strdup (server); - if (!ret->server) - { - grub_free (ret); - return NULL; - } - } - else - ret->server = NULL; - ret->fs = &grub_net_fs; - ret->offset = 0; - ret->eof = 0; - return ret; - } - } - if (try == 0) - { - if (sizeof ("http") - 1 == protnamelen - && grub_memcmp ("http", protname, protnamelen) == 0) - { - grub_dl_load ("http"); - grub_errno = GRUB_ERR_NONE; - continue; - } - if (sizeof ("tftp") - 1 == protnamelen - && grub_memcmp ("tftp", protname, protnamelen) == 0) - { - grub_dl_load ("tftp"); - grub_errno = GRUB_ERR_NONE; - continue; - } - } - break; + /* Get past the seperator */ + work += 1; + if (!grub_strlen(work)) + { + grub_error(GRUB_ERR_NET_BAD_ADDRESS,N_("no server is specified")); + return NULL; + } + comma = grub_strchr (work, ','); + if (comma) + { + /* Extract our port and real server */ + port = grub_strtoul(comma + 1,0,10); + if (comma != work) + server = grub_strndup (work,comma - work); + else + server = grub_strdup(grub_net_default_server); + } + else if (grub_strlen(work)) + { + server = grub_strdup(work); + } } - - /* Restore original error. */ - grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' not found"), - name); - + else + server = grub_strdup(grub_net_default_server); + /* Now we have the protocol, the server, and a port if one was specified. */ + protnamelen = grub_strlen(protname); + if (!server) + goto out1; + grub_dl_load(protname); + grub_errno = GRUB_ERR_NONE; + ret = grub_zalloc (sizeof (*ret)); + if (!ret) + goto out2; + ret->server = server; + ret->fs = &grub_net_fs; + ret->offset = 0; + ret->eof = 0; + FOR_NET_APP_LEVEL (proto) + { + if (grub_strncmp (proto->name, protname, protnamelen) != 0) + continue; + ret->protocol = proto; + if (!port) + ret->port = proto->port; + else + ret->port = port; + return ret; + } + out2: + grub_free(ret); + out1: + grub_free(server); return NULL; } diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 1319671..d047a86 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -378,7 +378,7 @@ tftp_open (struct grub_file *file, const char *filename) } data->sock = grub_net_udp_open (addr, - TFTP_SERVER_PORT, tftp_receive, + file->device->net->port, tftp_receive, file); if (!data->sock) { { @@ -475,6 +475,7 @@ tftp_packets_pulled (struct grub_file *file) static struct grub_net_app_protocol grub_tftp_protocol = { .name = "tftp", + .port = TFTP_SERVER_PORT, .open = tftp_open, .close = tftp_close, .packets_pulled = tftp_packets_pulled diff --git a/include/grub/net.h b/include/grub/net.h index 538baa3..2249b10 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -245,6 +245,7 @@ struct grub_net_app_protocol struct grub_net_app_protocol *next; struct grub_net_app_protocol **prev; const char *name; + grub_uint16_t port; grub_err_t (*dir) (grub_device_t device, const char *path, int (*hook) (const char *filename, const struct grub_dirhook_info *info)); @@ -264,6 +265,7 @@ typedef struct grub_net grub_fs_t fs; int eof; int stall; + grub_uint16_t port; } *grub_net_t; extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); -- 2.1.3 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel