grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Allow nonstandard ports when specifying network protocols.


From: Victor Lowther
Subject: [PATCH] Allow nonstandard ports when specifying network protocols.
Date: Thu, 11 Dec 2014 13:58:04 -0600

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  <address@hidden>
+
+       * 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  <address@hidden>

        * 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]