[syslinux:pathbased] pxe: handle tftp:// URLs natively

syslinux-bot for H. Peter Anvin hpa at zytor.com
Sun Feb 28 23:12:05 PST 2010


Commit-ID:  9ccd44b8acbd3664d5ab25cfec7c6f8c239dd428
Gitweb:     http://syslinux.zytor.com/commit/9ccd44b8acbd3664d5ab25cfec7c6f8c239dd428
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Sun, 28 Feb 2010 23:08:52 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Sun, 28 Feb 2010 23:08:52 -0800

pxe: handle tftp:// URLs natively

Handle tftp:// URLs natively, instead of relying on gPXE.  This also
allows for specifying a nonstandard TFTP port.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>


---
 core/fs/pxe/pxe.c |   39 ++++++++++++++++++++++++++++++++++++++-
 core/fs/pxe/pxe.h |   12 ++++++++++++
 2 files changed, 50 insertions(+), 1 deletions(-)

diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index ac4485c..292e27d 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -12,7 +12,6 @@
 uint32_t server_ip = 0;            /* IP address of boot server */
 uint32_t net_mask = 0;             /* net_mask of this subnet */
 uint32_t gate_way = 0;             /* Default router */
-uint16_t server_port = TFTP_PORT;  /* TFTP server port */
 uint16_t real_base_mem;            /* Amount of DOS memory after freeing */
 
 uint8_t MAC[MAC_MAX];		   /* Actual MAC address */
@@ -365,6 +364,7 @@ enum pxe_path_type {
     PXE_RELATIVE,		/* No :: or URL */
     PXE_HOMESERVER,		/* Starting with :: */
     PXE_TFTP,			/* host:: */
+    PXE_URL_TFTP,		/* tftp:// */
     PXE_URL,			/* Absolute URL syntax */
 };
 
@@ -372,7 +372,11 @@ static enum pxe_path_type pxe_path_type(const char *str)
 {
     const char *p;
     
+    if (strncasecmp(str, "tftp://", 7))
+	return PXE_URL_TFTP;
+
     p = str;
+
     while (1) {
 	switch (*p) {
 	case ':':
@@ -654,6 +658,7 @@ static void pxe_searchdir(const char *filename, struct file *file)
     uint32_t opdata, *opdata_ptr;
     enum pxe_path_type path_type;
     char fullpath[2*FILENAME_MAX];
+    uint16_t server_port = TFTP_PORT;  /* TFTP server port */
 
     file->file_len = 0;
     file->open_file = NULL;
@@ -686,6 +691,38 @@ static void pxe_searchdir(const char *filename, struct file *file)
 	if (parse_dotquad(filename, &ip) != np)
 	    ip = dns_resolv(filename);
 	break;
+
+    case PXE_URL_TFTP:
+	np = filename + 7;
+	while (*np && *np != '/' && *np != ':')
+	    np++;
+	if (np > filename + 7) {
+	    if (parse_dotquad(filename, &ip) != np)
+		ip = dns_resolv(filename);
+	}
+	if (*np == ':') {
+	    np++;
+	    server_port = 0;
+	    while (*np >= '0' && *np <= '9')
+		server_port = server_port * 10 + *np++ - '0';
+	    server_port = server_port ? htons(server_port) : TFTP_PORT;
+	}
+	if (*np == '/')
+	    np++;		/* Do *NOT* eat more than one slash here... */
+	/*
+	 * The ; is because of a quirk in the TFTP URI spec (RFC
+	 * 3617); it is to be followed by TFTP modes, which we just ignore.
+	 */
+	while (*np && *np != ';') {
+	    if (*np == '%') {
+		if (is_hex(np[1]) && is_hex(np[2]))
+		    *buf++ = (hexval(np[1]) << 4) + hexval(np[2]);
+		np += 3;
+	    } else {
+		*buf++ = *np++;
+	    }
+	}
+	break;
     }
 
     if (!ip)
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index 5e6aded..3cec753 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -34,6 +34,18 @@
 #define is_digit(c)     (((c) >= '0') && ((c) <= '9'))
 #define major_ver(v)    (((v) >> 8) && 0xff)
 
+static inline bool is_hex(char c)
+{
+    return (c >= '0' && c <= '9') ||
+	(c >= 'A' && c <= 'F') ||
+	(c >= 'a' && c <= 'f');
+}
+
+static inline int hexval(char c)
+{
+    return (c >= 'A') ? (c & ~0x20) - 'A' + 10 : (c - '0');
+}
+
 /*
  * TFTP operation codes
  */



More information about the Syslinux-commits mailing list