aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2011-04-11 04:16:03 -0700
committerEric W. Biederman <ebiederm@xmission.com>2011-04-12 14:41:13 -0700
commitf7af71ef607670b22ce52d314bc38e1f39d32431 (patch)
tree1a752a2b0a73fac15dbbacee4619252ac767b92d /core
parent530e69d1cb52479b290a738c3b9b56de2e4e623d (diff)
downloadsyslinux-f7af71ef607670b22ce52d314bc38e1f39d32431.tar.gz
syslinux-f7af71ef607670b22ce52d314bc38e1f39d32431.tar.xz
syslinux-f7af71ef607670b22ce52d314bc38e1f39d32431.zip
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 <ebiederm@xmission.com>
Diffstat (limited to 'core')
-rw-r--r--core/fs/pxe/pxe.c54
-rw-r--r--core/fs/pxe/pxe.h4
2 files changed, 53 insertions, 5 deletions
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index af580c63..c173cd0a 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -6,10 +6,8 @@
#include <minmax.h>
#include <sys/cpu.h>
#include "pxe.h"
-#if 1
-#include "lwip/api.h"
-#include "lwip/dns.h"
-#endif
+#include <lwip/api.h>
+#include <lwip/dns.h>
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 dd1d31f0..59661bcb 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);