From f7af71ef607670b22ce52d314bc38e1f39d32431 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 11 Apr 2011 04:16:03 -0700 Subject: [PATCH] core: pxe: Add general support for pluggable url handlers. In preparation for adding http support (and possibly others) add support for looking up a url scheme by name in a table and calling the appropriate open function. This also adds a struct netbuf pointer to the pxe inode allowing for some easy to implement and nice to use streaming abstractions like pxe_getc. Cleanup the includes of lwip headers. We want <> brackets (no point in searching in the current directory first) and the ifdefs around them can go. Signed-off-by: Eric W. Biederman --- core/fs/pxe/pxe.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- core/fs/pxe/pxe.h | 4 ++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c index af580c6..c173cd0 100644 --- a/core/fs/pxe/pxe.c +++ b/core/fs/pxe/pxe.c @@ -6,10 +6,8 @@ #include #include #include "pxe.h" -#if 1 -#include "lwip/api.h" -#include "lwip/dns.h" -#endif +#include +#include static uint16_t real_base_mem; /* Amount of DOS memory after freeing */ @@ -33,6 +31,13 @@ bool have_uuid = false; /* Common receive buffer */ __lowmem char packet_buf[PKTBUF_SIZE] __aligned(16); +static struct url_open { + const char *scheme; + void (*open)(struct inode *inode, const char *url); +} url_table[] = { + { NULL, NULL }, +}; + /* * Allocate a local UDP port structure and assign it a local port number. * Return the inode pointer if success, or null if failure @@ -184,7 +189,7 @@ static int gendotquad(char *dst, uint32_t ip) * return the the string address after the ip string * */ -static const char *parse_dotquad(const char *ip_str, uint32_t *res) +const char *parse_dotquad(const char *ip_str, uint32_t *res) { const char *p = ip_str; uint8_t part = 0; @@ -322,6 +327,30 @@ static void pxe_mangle_name(char *dst, const char *src) } /* + * Read a single character from the specified pxe inode. + * Very useful for stepping through http streams and + * parsing their headers. + */ +int pxe_getc(struct inode *inode) +{ + struct pxe_pvt_inode *socket = PVT(inode); + unsigned char byte; + + while (!socket->tftp_bytesleft) { + if (socket->tftp_goteof) + return -1; + + socket->fill_buffer(inode); + } + + byte = *socket->tftp_dataptr; + socket->tftp_bytesleft -= 1; + socket->tftp_dataptr += 1; + + return byte; +} + +/* * Get a fresh packet if the buffer is drained, and we haven't hit * EOF yet. The buffer should be filled immediately after draining! */ @@ -487,6 +516,21 @@ static void __pxe_searchdir(const char *filename, struct file *file) if (!inode) return; /* Allocation failure */ + if (path_type == PXE_URL) { + struct url_open *entry; + np = strchr(filename, ':'); + + for (entry = url_table; entry->scheme; entry++) { + int scheme_len = strlen(entry->scheme); + if (scheme_len != (np - filename)) + continue; + if (memcmp(entry->scheme, filename, scheme_len) != 0) + continue; + entry->open(inode, filename); + goto done; + } + } + #if GPXE if (path_type == PXE_URL) { if (has_gpxe) { diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h index dd1d31f..59661bc 100644 --- a/core/fs/pxe/pxe.h +++ b/core/fs/pxe/pxe.h @@ -150,11 +150,13 @@ struct bootp_t { } __attribute__ ((packed)); struct netconn; +struct netbuf; /* * Our inode private information -- this includes the packet buffer! */ struct pxe_pvt_inode { struct netconn *conn; /* lwip network connection */ + struct netbuf *buf; /* lwip cached buffer */ uint16_t tftp_localport; /* Local port number (0=not in us)*/ uint16_t tftp_remoteport; /* Remote port number */ uint32_t tftp_remoteip; /* Remote IP address */ @@ -242,6 +244,8 @@ void pxe_poll(void); bool ip_ok(uint32_t); int pxe_call(int, void *); extern __lowmem char packet_buf[PKTBUF_SIZE] __aligned(16); +const char *parse_dotquad(const char *ip_str, uint32_t *res); +int pxe_getc(struct inode *inode); /* dhcp_options.c */ void parse_dhcp(int); -- 2.7.4