[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