svn commit: r246526 - in user/sbruno/pxe_http_head/sys/boot/i386: . libi386 loader pxe_http
Sean Bruno
sbruno at FreeBSD.org
Fri Feb 8 01:28:32 UTC 2013
Author: sbruno
Date: Fri Feb 8 01:28:30 2013
New Revision: 246526
URL: http://svnweb.freebsd.org/changeset/base/246526
Log:
Bring pxe_http all the way to the modern era in a functional state.
LOADER_HTTP_SUPPORT works in this branch at this time by compiling:
make -DLOADER_HTTP_SUPPOT -DLOADER_NO_GPT_SUPPORT. This will boot
and attempt to fetch a kernel/ramdisk from a web server.
Added:
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/Makefile
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/README
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/httpfs.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/httpfs.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_arp.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_arp.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_await.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_await.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_buffer.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_buffer.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_connection.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_connection.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_core.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_core.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_dhcp.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_dhcp.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_dns.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_dns.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_filter.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_filter.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_http.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_http.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_icmp.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_icmp.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_ip.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_ip.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_isr.S
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_isr.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_mem.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_mem.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_segment.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_segment.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_sock.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_sock.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_tcp.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_tcp.h
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_udp.c
user/sbruno/pxe_http_head/sys/boot/i386/pxe_http/pxe_udp.h
Modified:
user/sbruno/pxe_http_head/sys/boot/i386/Makefile
user/sbruno/pxe_http_head/sys/boot/i386/libi386/Makefile
user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.c
user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.h
user/sbruno/pxe_http_head/sys/boot/i386/loader/Makefile
user/sbruno/pxe_http_head/sys/boot/i386/loader/conf.c
user/sbruno/pxe_http_head/sys/boot/i386/loader/main.c
Modified: user/sbruno/pxe_http_head/sys/boot/i386/Makefile
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/Makefile Fri Feb 8 00:40:10 2013 (r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/Makefile Fri Feb 8 01:28:30 2013 (r246526)
@@ -3,7 +3,7 @@
.include <bsd.own.mk>
SUBDIR= mbr pmbr boot0 boot0sio btx boot2 cdboot gptboot kgzldr \
- libi386 libfirewire loader
+ libi386 libfirewire pxe_http loader
# special boot programs, 'self-extracting boot2+loader'
SUBDIR+= pxeldr
Modified: user/sbruno/pxe_http_head/sys/boot/i386/libi386/Makefile
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/libi386/Makefile Fri Feb 8 00:40:10 2013 (r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/libi386/Makefile Fri Feb 8 01:28:30 2013 (r246526)
@@ -7,17 +7,19 @@ SRCS= biosacpi.c bioscd.c biosdisk.c bio
biospci.c biossmap.c bootinfo.c bootinfo32.c bootinfo64.c \
comconsole.c devicename.c elf32_freebsd.c \
elf64_freebsd.c \
- i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.s \
+ i386_copy.c i386_module.c nullconsole.c pxe.c \
smbios.c time.c vidconsole.c amd64_tramp.S spinconsole.c
.PATH: ${.CURDIR}/../../zfs
SRCS+= devicename_stubs.c
-# Enable PXE TFTP or NFS support, not both.
+# Enable PXE to fetch things via HTTP, TFTP or NFS.
+.if !defined(LOADER_HTTP_SUPPORT)
.if defined(LOADER_TFTP_SUPPORT)
CFLAGS+= -DLOADER_TFTP_SUPPORT
.else
CFLAGS+= -DLOADER_NFS_SUPPORT
.endif
+.endif
BOOT_COMCONSOLE_PORT?= 0x3f8
CFLAGS+= -DCOMPORT=${BOOT_COMCONSOLE_PORT}
@@ -42,13 +44,19 @@ CFLAGS+= -DSMBIOS_LITTLE_ENDIAN_UUID
# Include simple terminal emulation (cons25-compatible)
CFLAGS+= -DTERM_EMU
+# allow pxe_http perform udpread/udpwrite
+CFLAGS+= -DPXEHTTP_UDP_FOR_LIBSTAND
+
+# enable debug of pxe_http
+CDLAGS+= -DPXE_DEBUG
+
# XXX: make alloca() useable
CFLAGS+= -Dalloca=__builtin_alloca
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../common \
-I${.CURDIR}/../btx/lib \
-I${.CURDIR}/../../../contrib/dev/acpica/include \
- -I${.CURDIR}/../../.. -I.
+ -I${.CURDIR}/../../.. -I. -I${.CURDIR}/../pxe_http
# the location of libstand
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
Modified: user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.c
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.c Fri Feb 8 00:40:10 2013 (r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.c Fri Feb 8 01:28:30 2013 (r246526)
@@ -39,7 +39,9 @@ __FBSDID("$FreeBSD$");
#include <net.h>
#include <netif.h>
+#ifdef LOADER_NFS_SUPPORT
#include <nfsv2.h>
+#endif
#include <iodesc.h>
#include <bootp.h>
@@ -47,37 +49,38 @@ __FBSDID("$FreeBSD$");
#include "btxv86.h"
#include "pxe.h"
-/*
- * Allocate the PXE buffers statically instead of sticking grimy fingers into
- * BTX's private data area. The scratch buffer is used to send information to
- * the PXE BIOS, and the data buffer is used to receive data from the PXE BIOS.
- */
-#define PXE_BUFFER_SIZE 0x2000
+#include "pxe_core.h"
+#include "pxe_dhcp.h"
+#include "pxe_isr.h"
+#include "pxe_ip.h"
+#include "pxe_udp.h"
+
+
#define PXE_TFTP_BUFFER_SIZE 512
-static char scratch_buffer[PXE_BUFFER_SIZE];
-static char data_buffer[PXE_BUFFER_SIZE];
+
+#ifndef PXEHTTP_UDP_FOR_LIBSTAND
+extern uint8_t *scratch_buffer;
+extern uint8_t *data_buffer;
+#endif
static pxenv_t *pxenv_p = NULL; /* PXENV+ */
static pxe_t *pxe_p = NULL; /* !PXE */
-static BOOTPLAYER bootplayer; /* PXE Cached information. */
-static int pxe_debug = 0;
static int pxe_sock = -1;
static int pxe_opens = 0;
void pxe_enable(void *pxeinfo);
-static void (*pxe_call)(int func);
-static void pxenv_call(int func);
-static void bangpxe_call(int func);
static int pxe_init(void);
static int pxe_strategy(void *devdata, int flag, daddr_t dblk,
size_t size, char *buf, size_t *rsize);
static int pxe_open(struct open_file *f, ...);
static int pxe_close(struct open_file *f);
-static void pxe_print(int verbose);
+static void pxe_print(int verbose);
static void pxe_cleanup(void);
+#ifdef LOADER_NFS_SUPPORT
static void pxe_setnfshandle(char *rootpath);
+#endif
static void pxe_perror(int error);
static int pxe_netif_match(struct netif *nif, void *machdep_hint);
@@ -88,19 +91,15 @@ static int pxe_netif_get(struct iodesc *
static int pxe_netif_put(struct iodesc *desc, void *pkt, size_t len);
static void pxe_netif_end(struct netif *nif);
+#ifdef LOADER_NFS_SUPPORT
#ifdef OLD_NFSV2
int nfs_getrootfh(struct iodesc*, char*, u_char*);
#else
int nfs_getrootfh(struct iodesc*, char*, uint32_t*, u_char*);
#endif
+#endif
extern struct netif_stats pxe_st[];
-extern u_int16_t __bangpxeseg;
-extern u_int16_t __bangpxeoff;
-extern void __bangpxeentry(void);
-extern u_int16_t __pxenvseg;
-extern u_int16_t __pxenvoff;
-extern void __pxenventry(void);
struct netif_dif pxe_ifs[] = {
/* dif_unit dif_nsel dif_stats dif_private */
@@ -149,7 +148,6 @@ pxe_enable(void *pxeinfo)
pxenv_p = (pxenv_t *)pxeinfo;
pxe_p = (pxe_t *)PTOV(pxenv_p->PXEPtr.segment * 16 +
pxenv_p->PXEPtr.offset);
- pxe_call = NULL;
}
/*
@@ -159,90 +157,9 @@ pxe_enable(void *pxeinfo)
static int
pxe_init(void)
{
- t_PXENV_GET_CACHED_INFO *gci_p;
- int counter;
- uint8_t checksum;
- uint8_t *checkptr;
-
- if(pxenv_p == NULL)
- return (0);
-
- /* look for "PXENV+" */
- if (bcmp((void *)pxenv_p->Signature, S_SIZE("PXENV+"))) {
- pxenv_p = NULL;
- return (0);
- }
-
- /* make sure the size is something we can handle */
- if (pxenv_p->Length > sizeof(*pxenv_p)) {
- printf("PXENV+ structure too large, ignoring\n");
- pxenv_p = NULL;
- return (0);
- }
-
- /*
- * do byte checksum:
- * add up each byte in the structure, the total should be 0
- */
- checksum = 0;
- checkptr = (uint8_t *) pxenv_p;
- for (counter = 0; counter < pxenv_p->Length; counter++)
- checksum += *checkptr++;
- if (checksum != 0) {
- printf("PXENV+ structure failed checksum, ignoring\n");
- pxenv_p = NULL;
- return (0);
- }
-
-
- /*
- * PXENV+ passed, so use that if !PXE is not available or
- * the checksum fails.
- */
- pxe_call = pxenv_call;
- if (pxenv_p->Version >= 0x0200) {
- for (;;) {
- if (bcmp((void *)pxe_p->Signature, S_SIZE("!PXE"))) {
- pxe_p = NULL;
- break;
- }
- checksum = 0;
- checkptr = (uint8_t *)pxe_p;
- for (counter = 0; counter < pxe_p->StructLength;
- counter++)
- checksum += *checkptr++;
- if (checksum != 0) {
- pxe_p = NULL;
- break;
- }
- pxe_call = bangpxe_call;
- break;
- }
- }
-
- printf("\nPXE version %d.%d, real mode entry point ",
- (uint8_t) (pxenv_p->Version >> 8),
- (uint8_t) (pxenv_p->Version & 0xFF));
- if (pxe_call == bangpxe_call)
- printf("@%04x:%04x\n",
- pxe_p->EntryPointSP.segment,
- pxe_p->EntryPointSP.offset);
- else
- printf("@%04x:%04x\n",
- pxenv_p->RMEntry.segment, pxenv_p->RMEntry.offset);
-
- gci_p = (t_PXENV_GET_CACHED_INFO *) scratch_buffer;
- bzero(gci_p, sizeof(*gci_p));
- gci_p->PacketType = PXENV_PACKET_TYPE_BINL_REPLY;
- pxe_call(PXENV_GET_CACHED_INFO);
- if (gci_p->Status != 0) {
- pxe_perror(gci_p->Status);
- pxe_p = NULL;
- return (0);
- }
- bcopy(PTOV((gci_p->Buffer.segment << 4) + gci_p->Buffer.offset),
- &bootplayer, gci_p->BufferSize);
- return (1);
+ if (__pxe_nic_irq != 0)
+ return (2);
+ return pxe_core_init(pxenv_p, pxe_p);
}
@@ -256,146 +173,94 @@ pxe_strategy(void *devdata, int flag, da
static int
pxe_open(struct open_file *f, ...)
{
- va_list args;
- char *devname; /* Device part of file name (or NULL). */
- char temp[FNAME_SIZE];
- int error = 0;
- int i;
-
- va_start(args, f);
- devname = va_arg(args, char*);
- va_end(args);
-
- /* On first open, do netif open, mount, etc. */
- if (pxe_opens == 0) {
- /* Find network interface. */
- if (pxe_sock < 0) {
- pxe_sock = netif_open(devname);
- if (pxe_sock < 0) {
- printf("pxe_open: netif_open() failed\n");
- return (ENXIO);
- }
- if (pxe_debug)
- printf("pxe_open: netif_open() succeeded\n");
- }
- if (rootip.s_addr == 0) {
- /*
- * Do a bootp/dhcp request to find out where our
- * NFS/TFTP server is. Even if we dont get back
- * the proper information, fall back to the server
- * which brought us to life and a default rootpath.
- */
- bootp(pxe_sock, BOOTP_PXE);
- if (rootip.s_addr == 0)
- rootip.s_addr = bootplayer.sip;
- if (!rootpath[0])
- strcpy(rootpath, PXENFSROOTPATH);
-
- for (i = 0; rootpath[i] != '\0' && i < FNAME_SIZE; i++)
- if (rootpath[i] == ':')
- break;
- if (i && i != FNAME_SIZE && rootpath[i] == ':') {
- rootpath[i++] = '\0';
- if (inet_addr(&rootpath[0]) != INADDR_NONE)
- rootip.s_addr = inet_addr(&rootpath[0]);
- bcopy(&rootpath[i], &temp[0], strlen(&rootpath[i])+1);
- bcopy(&temp[0], &rootpath[0], strlen(&rootpath[i])+1);
- }
- printf("pxe_open: server addr: %s\n", inet_ntoa(rootip));
- printf("pxe_open: server path: %s\n", rootpath);
- printf("pxe_open: gateway ip: %s\n", inet_ntoa(gateip));
-
- setenv("boot.netif.ip", inet_ntoa(myip), 1);
- setenv("boot.netif.netmask", intoa(netmask), 1);
- setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
- if (bootplayer.Hardware == ETHER_TYPE) {
- sprintf(temp, "%6D", bootplayer.CAddr, ":");
- setenv("boot.netif.hwaddr", temp, 1);
+ va_list args;
+ char *devname = NULL;
+ int i = 0;
+
+ va_start(args, f);
+ devname = va_arg(args, char*);
+ va_end(args);
+
+ if (pxe_opens == 0) {
+ /* Find network interface. */
+ if (pxe_sock < 0) {
+ pxe_sock = netif_open(devname);
+
+ if (pxe_sock < 0) {
+ printf("pxe_open: netif_open() failed\n");
+ return (ENXIO);
+ }
+
}
- setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
- setenv("boot.nfsroot.path", rootpath, 1);
- setenv("dhcp.host-name", hostname, 1);
+
+#ifdef PXE_BOOTP_USE_LIBSTAND
+ const PXE_IPADDR *addr = pxe_get_ip(PXE_IP_ROOT);
+
+ if ( (addr->ip == 0)) {
+ pxe_dhcp_query(0);
+ pxe_core_update_bootp();
+
+#ifdef PXEHTTP_UDP_FOR_LIBSTAND
+ gateip.s_addr = pxe_get_ip(PXE_IP_GATEWAY)->ip;
+ rootip.s_addr = pxe_get_ip(PXE_IP_ROOT)->ip;
+ netmask = pxe_get_ip(PXE_IP_NETMASK)->ip;
+ myip.s_addr = pxe_get_ip(PXE_IP_MY)->ip;
+ nameip.s_addr = pxe_get_ip(PXE_IP_NAMESERVER)->ip;
+#endif
+ }
+#endif /* PXE_BOOTP_USE_LIBSTAND */
}
- }
- pxe_opens++;
- f->f_devdata = &pxe_sock;
- return (error);
+ ++pxe_opens;
+ f->f_devdata = &pxe_sock;
+
+ return (0);
}
static int
pxe_close(struct open_file *f)
{
-#ifdef PXE_DEBUG
- if (pxe_debug)
- printf("pxe_close: opens=%d\n", pxe_opens);
-#endif
-
- /* On last close, do netif close, etc. */
- f->f_devdata = NULL;
- /* Extra close call? */
- if (pxe_opens <= 0)
- return (0);
- pxe_opens--;
- /* Not last close? */
- if (pxe_opens > 0)
- return(0);
+ /* On last close, do netif close, etc. */
+ f->f_devdata = NULL;
+
+ if (pxe_opens)
+ --pxe_opens;
+
+ /* Not last close? */
+ if (pxe_opens > 0)
+ return (0);
#ifdef LOADER_NFS_SUPPORT
/* get an NFS filehandle for our root filesystem */
pxe_setnfshandle(rootpath);
#endif
- if (pxe_sock >= 0) {
-
+ if (pxe_sock >= 0) {
#ifdef PXE_DEBUG
- if (pxe_debug)
- printf("pxe_close: calling netif_close()\n");
+ printf("pxe_close: calling netif_close()\n");
#endif
- netif_close(pxe_sock);
- pxe_sock = -1;
- }
- return (0);
+ netif_close(pxe_sock);
+ pxe_sock = -1;
+ }
+
+ return (0);
}
static void
pxe_print(int verbose)
{
+ printf(" pxenet0: MAC %6D\n", pxe_get_mymac(), ":");
+ printf(" ISR: at %x:%x (chained at: %x:%x)\n",
+ __pxe_entry_seg, __pxe_entry_off,
+ __chained_irq_seg, __chained_irq_off);
- if (pxe_call == NULL)
- return;
-
- printf(" pxe0: %s:%s\n", inet_ntoa(rootip), rootpath);
+ return;
}
static void
pxe_cleanup(void)
{
-#ifdef PXE_DEBUG
- t_PXENV_UNLOAD_STACK *unload_stack_p =
- (t_PXENV_UNLOAD_STACK *)scratch_buffer;
- t_PXENV_UNDI_SHUTDOWN *undi_shutdown_p =
- (t_PXENV_UNDI_SHUTDOWN *)scratch_buffer;
-#endif
-
- if (pxe_call == NULL)
- return;
-
- pxe_call(PXENV_UNDI_SHUTDOWN);
-
-#ifdef PXE_DEBUG
- if (pxe_debug && undi_shutdown_p->Status != 0)
- printf("pxe_cleanup: UNDI_SHUTDOWN failed %x\n",
- undi_shutdown_p->Status);
-#endif
-
- pxe_call(PXENV_UNLOAD_STACK);
-
-#ifdef PXE_DEBUG
- if (pxe_debug && unload_stack_p->Status != 0)
- printf("pxe_cleanup: UNLOAD_STACK failed %x\n",
- unload_stack_p->Status);
-#endif
+ pxe_core_shutdown();
}
void
@@ -517,61 +382,6 @@ pxe_setnfshandle(char *rootpath)
#endif /* OLD_NFSV2 */
#endif /* LOADER_NFS_SUPPORT */
-void
-pxenv_call(int func)
-{
-#ifdef PXE_DEBUG
- if (pxe_debug)
- printf("pxenv_call %x\n", func);
-#endif
-
- bzero(&v86, sizeof(v86));
- bzero(data_buffer, sizeof(data_buffer));
-
- __pxenvseg = pxenv_p->RMEntry.segment;
- __pxenvoff = pxenv_p->RMEntry.offset;
-
- v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
- v86.es = VTOPSEG(scratch_buffer);
- v86.edi = VTOPOFF(scratch_buffer);
- v86.addr = (VTOPSEG(__pxenventry) << 16) | VTOPOFF(__pxenventry);
- v86.ebx = func;
- v86int();
- v86.ctl = V86_FLAGS;
-}
-
-void
-bangpxe_call(int func)
-{
-#ifdef PXE_DEBUG
- if (pxe_debug)
- printf("bangpxe_call %x\n", func);
-#endif
-
- bzero(&v86, sizeof(v86));
- bzero(data_buffer, sizeof(data_buffer));
-
- __bangpxeseg = pxe_p->EntryPointSP.segment;
- __bangpxeoff = pxe_p->EntryPointSP.offset;
-
- v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
- v86.edx = VTOPSEG(scratch_buffer);
- v86.eax = VTOPOFF(scratch_buffer);
- v86.addr = (VTOPSEG(__bangpxeentry) << 16) | VTOPOFF(__bangpxeentry);
- v86.ebx = func;
- v86int();
- v86.ctl = V86_FLAGS;
-}
-
-
-time_t
-getsecs()
-{
- time_t n = 0;
- time(&n);
- return n;
-}
-
static int
pxe_netif_match(struct netif *nif, void *machdep_hint)
{
@@ -582,54 +392,128 @@ pxe_netif_match(struct netif *nif, void
static int
pxe_netif_probe(struct netif *nif, void *machdep_hint)
{
- t_PXENV_UDP_OPEN *udpopen_p = (t_PXENV_UDP_OPEN *)scratch_buffer;
+#ifdef PXE_DEBUG
+ printf("pxe_netif_probe() called.");
+#endif
- if (pxe_call == NULL)
- return -1;
+#ifdef PXEHTTP_UDP_FOR_LIBSTAND
+ if (__pxe_nic_irq == 0)
+ return (-1);
+#else
+ t_PXENV_UDP_OPEN *udpopen_p = (t_PXENV_UDP_OPEN *)scratch_buffer;
bzero(udpopen_p, sizeof(*udpopen_p));
- udpopen_p->src_ip = bootplayer.yip;
+
+ const PXE_IPADDR *my = pxe_get_ip(PXE_IP_MY);
+ udpopen_p->src_ip = my->ip;
pxe_call(PXENV_UDP_OPEN);
if (udpopen_p->status != 0) {
printf("pxe_netif_probe: failed %x\n", udpopen_p->status);
return -1;
}
+#endif
return 0;
}
static void
pxe_netif_end(struct netif *nif)
{
- t_PXENV_UDP_CLOSE *udpclose_p = (t_PXENV_UDP_CLOSE *)scratch_buffer;
- bzero(udpclose_p, sizeof(*udpclose_p));
+#ifdef PXE_DEBUG
+ printf("pxe_netif_end() called.");
+#endif
+#ifndef PXEHTTP_UDP_FOR_LIBSTAND
+ t_PXENV_UDP_CLOSE *udpclose_p = (t_PXENV_UDP_CLOSE *)scratch_buffer;
+
+ bzero(udpclose_p, sizeof(*udpclose_p));
- pxe_call(PXENV_UDP_CLOSE);
- if (udpclose_p->status != 0)
- printf("pxe_end failed %x\n", udpclose_p->status);
+ if (udpclose_p->status != 0)
+ printf("pxe_end failed %x\n", udpclose_p->status);
+#endif
}
static void
pxe_netif_init(struct iodesc *desc, void *machdep_hint)
{
+#ifdef PXE_DEBUG
+ printf("pxe_netif_init(): called.\n");
+#endif
+ uint8_t *mac = (uint8_t *)pxe_get_mymac();
+
int i;
for (i = 0; i < 6; ++i)
- desc->myea[i] = bootplayer.CAddr[i];
- desc->xid = bootplayer.ident;
+ desc->myea[i] = mac[i];
+
+ const PXE_IPADDR *my = pxe_get_ip(PXE_IP_MY);
+ desc->xid = my->ip;
}
static int
pxe_netif_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
{
+#ifdef PXE_DEBUG
+ printf("pxe_netif_put(): called.\n");
+#endif
return len;
}
static int
pxe_netif_put(struct iodesc *desc, void *pkt, size_t len)
{
+#ifdef PXE_DEBUG
+ printf("pxe_netif_put(): called.\n");
+#endif
return len;
}
+#ifdef PXEHTTP_UDP_FOR_LIBSTAND
+/* new versions of udp send/recv functions */
+ssize_t
+sendudp(struct iodesc *h, void *pkt, size_t len)
+{
+#ifdef PXE_DEBUG_HELL
+ printf("sendudp(): sending %u bytes from me:%u -> %s:%u\n",
+ len, ntohs(h->myport),
+ inet_ntoa(h->destip), ntohs(h->destport));
+#endif
+ void *ipdata = pkt - sizeof(PXE_UDP_PACKET);
+ PXE_IPADDR dst;
+ dst.ip = h->destip.s_addr;
+ if (!pxe_udp_send(ipdata, &dst, ntohs(h->destport),
+ ntohs(h->myport), len + sizeof(PXE_UDP_PACKET)))
+ {
+ printf("sendudp(): failed\n");
+ return (-1);
+ }
+ return (len);
+}
+
+ssize_t
+readudp(struct iodesc *h, void *pkt, size_t len, time_t timeout)
+{
+ PXE_UDP_DGRAM dgram;
+ struct udphdr *uh = (struct udphdr *) pkt - 1;
+
+ /* process any queued incoming packets */
+ pxe_core_recv_packets();
+
+ /* reading from default socket */
+ int recv = pxe_udp_read(NULL, pkt, len, &dgram);
+
+ if (recv == -1) {
+ printf("readudp(): failed\n");
+ return (-1);
+ }
+#ifdef PXE_DEBUG_HELL
+ printf("readudp(): received %d(%u/%u) bytes from %u port\n",
+ recv, len, dgram.size, dgram.src_port);
+#endif
+ uh->uh_sport = htons(dgram.src_port);
+ return (recv);
+}
+
+#else /* !defined(PXEHTTP_UDP_FOR_LIBSTAND) */
+/* old variants of udp send/recv functions */
ssize_t
sendudp(struct iodesc *h, void *pkt, size_t len)
{
@@ -648,7 +532,7 @@ sendudp(struct iodesc *h, void *pkt, siz
else
udpwrite_p->gw = gateip.s_addr;
- pxe_call(PXENV_UDP_WRITE);
+ pxe_core_call(PXENV_UDP_WRITE);
#if 0
/* XXX - I dont know why we need this. */
@@ -678,7 +562,7 @@ readudp(struct iodesc *h, void *pkt, siz
udpread_p->buffer.segment = VTOPSEG(data_buffer);
udpread_p->buffer.offset = VTOPOFF(data_buffer);
- pxe_call(PXENV_UDP_READ);
+ pxe_core_call(PXENV_UDP_READ);
#if 0
/* XXX - I dont know why we need this. */
@@ -694,3 +578,4 @@ readudp(struct iodesc *h, void *pkt, siz
uh->uh_sport = udpread_p->s_port;
return udpread_p->buffer_size;
}
+#endif /* PXEHTTP_UDP_FOR_LIBSTAND */
Modified: user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.h
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.h Fri Feb 8 00:40:10 2013 (r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/libi386/pxe.h Fri Feb 8 01:28:30 2013 (r246526)
@@ -48,6 +48,9 @@
* structures passed into PXE
* Question: does this really work for PXE's expected ABI?
*/
+#ifndef __PXE__H__
+#define __PXE__H__
+
#define PACKED __packed
#define S_SIZE(s) s, sizeof(s) - 1
@@ -147,7 +150,7 @@ typedef struct {
PXENV_STATUS_t Status;
ADDR32_t ProtocolIni; /* Phys addr of a copy of the driver module */
uint8_t reserved[8];
-} PACKED t_PXENV_UNDI_INITALIZE;
+} PACKED t_PXENV_UNDI_INITIALIZE;
#define MAXNUM_MCADDR 8
@@ -511,3 +514,5 @@ typedef struct {
typedef struct {
PXENV_STATUS_t Status;
} PACKED t_PXENV_STOP_BASE;
+
+#endif
Modified: user/sbruno/pxe_http_head/sys/boot/i386/loader/Makefile
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/loader/Makefile Fri Feb 8 00:40:10 2013 (r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/loader/Makefile Fri Feb 8 01:28:30 2013 (r246526)
@@ -23,12 +23,18 @@ CFLAGS+= -DLOADER_ZFS_SUPPORT
LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a
.endif
+# Enable HTTP support for PXE
+.if defined(LOADER_HTTP_SUPPORT)
+CFLAGS+= -DLOADER_HTTP_SUPPORT
+CFLAGS+= -DPXE_MORE
+.else
# Enable PXE TFTP or NFS support, not both.
.if defined(LOADER_TFTP_SUPPORT)
CFLAGS+= -DLOADER_TFTP_SUPPORT
.else
CFLAGS+= -DLOADER_NFS_SUPPORT
.endif
+.endif
# Include bcache code.
HAVE_BCACHE= yes
@@ -72,6 +78,10 @@ CFLAGS+= -I${.CURDIR}/..
# BTX components
CFLAGS+= -I${.CURDIR}/../btx/lib
+# pxe_http components
+LIBHTTP= ${.OBJDIR}/../pxe_http/libpxe_http.a
+CFLAGS+= -I$(.CURDIR)/../pxe_http
+
# Debug me!
#CFLAGS+= -g
#LDFLAGS+= -g
@@ -117,8 +127,8 @@ FILES+= menu.rc
# XXX crt0.o needs to be first for pxeboot(8) to work
OBJS= ${BTXCRT}
-DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND}
-LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND}
+DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBHTTP} ${LIBSTAND}
+LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBHTTP} ${LIBSTAND}
.include <bsd.prog.mk>
Modified: user/sbruno/pxe_http_head/sys/boot/i386/loader/conf.c
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/loader/conf.c Fri Feb 8 00:40:10 2013 (r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/loader/conf.c Fri Feb 8 01:28:30 2013 (r246526)
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#if defined(LOADER_ZFS_SUPPORT)
#include "../zfs/libzfs.h"
#endif
+#include "pxe_http/httpfs.h"
/*
* We could use linker sets for some or all of these, but
@@ -57,7 +58,8 @@ extern struct devsw fwohci;
struct devsw *devsw[] = {
&bioscd,
&biosdisk,
-#if defined(LOADER_NFS_SUPPORT) || defined(LOADER_TFTP_SUPPORT)
+#if defined(LOADER_NFS_SUPPORT) || defined(LOADER_TFTP_SUPPORT) || \
+ defined(LOADER_HTTP_SUPPORT)
&pxedisk,
#endif
#if defined(LOADER_FIREWIRE_SUPPORT)
@@ -73,10 +75,16 @@ struct fs_ops *file_system[] = {
#if defined(LOADER_ZFS_SUPPORT)
&zfs_fsops,
#endif
+/*
+ * Taking these out of HTTP support for now as this makes us too large
+ * to boot. sbruno 07FEB2013
+ */
+#if !defined(LOADER_HTTP_SUPPORT)
&ufs_fsops,
&ext2fs_fsops,
&dosfs_fsops,
&cd9660_fsops,
+#endif
#if defined(LOADER_NANDFS_SUPPORT)
&nandfs_fsops,
#endif
@@ -95,6 +103,9 @@ struct fs_ops *file_system[] = {
#ifdef LOADER_TFTP_SUPPORT
&tftp_fsops,
#endif
+#ifdef LOADER_HTTP_SUPPORT
+ &http_fsops,
+#endif
NULL
};
Modified: user/sbruno/pxe_http_head/sys/boot/i386/loader/main.c
==============================================================================
--- user/sbruno/pxe_http_head/sys/boot/i386/loader/main.c Fri Feb 8 00:40:10 2013 (r246525)
+++ user/sbruno/pxe_http_head/sys/boot/i386/loader/main.c Fri Feb 8 01:28:30 2013 (r246526)
@@ -45,6 +45,19 @@ __FBSDID("$FreeBSD$");
#include "libi386/libi386.h"
#include "btxv86.h"
+#ifdef PXE_MORE
+#include "pxe_arp.h"
+#include "pxe_connection.h"
+#include "pxe_dns.h"
+#include "pxe_filter.h"
+#include "pxe_http.h"
+#include "pxe_icmp.h"
+#include "pxe_ip.h"
+#include "pxe_sock.h"
+#include "pxe_tcp.h"
+#include "pxe_udp.h"
+#endif
+
#ifdef LOADER_ZFS_SUPPORT
#include "../zfs/libzfs.h"
#endif
@@ -353,6 +366,347 @@ command_lszfs(int argc, char *argv[])
}
#endif
+/* added for pxe_http */
+#ifdef PXE_MORE
+static int
+command_route(int argc, char *argv[])
+{
+ PXE_IPADDR net;
+ PXE_IPADDR gw;
+
+ if (argc < 2) {
+ printf("use: route add|del|print [default|net_addr gw_addr] \n");
+ return (CMD_OK);
+ }
+
+ if (!strcmp(argv[1], "print")) {
+ pxe_ip_route_stat();
+ return (CMD_OK);
+ }
+
+ if (argc < 4) {
+ printf("use: route add|del default|net_addr gw_addr\n");
+ return (CMD_OK);
+ }
+
+ if ( (strcmp(argv[1], "add") != 0) && (strcmp(argv[1], "del") != 0))
+ return (CMD_OK);
+
+ if (!strcmp(argv[2], "default")) {
+
+ if (!strcmp(argv[1], "del")) {
+ printf("Cannot delete default gateway.\n");
+ return (CMD_OK);
+ }
+
+ gw.ip = pxe_convert_ipstr(argv[3]);
+
+ pxe_ip_route_default(&gw);
+
+ return (CMD_OK);
+ }
+
+ gw.ip = pxe_convert_ipstr(argv[3]);
+ net.ip = pxe_convert_ipstr(argv[2]);
+
+ if (!strcmp(argv[1], "add")) {
+ pxe_ip_route_add(&net, pxe_ip_get_netmask(&net), &gw);
+ return (CMD_OK);
+ }
+
+ pxe_ip_route_del(&net, pxe_ip_get_netmask(&net), &gw);
+
+ return (CMD_OK);
+}
+
+static int
+command_arp(int argc, char *argv[])
+{
+ PXE_IPADDR *ip;
+
+ if (argc > 1) {
+
+ if (strcmp(argv[1], "stats") != 0)
+ ip = pxe_gethostbyname(argv[1]);
+ else {
+ pxe_arp_stats();
+ return (CMD_OK);
+ }
+
+ } else {
+ printf("use: arp ip4_address|stats\n");
+ return (CMD_OK);
+ }
+
+ printf("searching ip: %s\n", (ip != NULL) ? inet_ntoa(ip->ip) : "?");
+
+ const uint8_t* mac = (const uint8_t *)pxe_arp_ip4mac(ip);
+
+ if (mac != NULL)
+ printf("MAC: %6D\n", mac, ":");
+ else
+ printf("MAC search failed.\n");
+
+ return (CMD_OK);
+}
+
+static int
+command_ping(int argc, char *argv[])
+{
+ PXE_IPADDR* ip = NULL;
+
+ pxe_icmp_init();
+
+ if (argc > 1)
+ ip = pxe_gethostbyname(argv[1]);
+ else {
+ printf("use: ping ip4_address\n");
+ return (CMD_OK);
+ }
+
+ pxe_ping(ip, 5, 1);
+
+ return (CMD_OK);
+}
+
+static int
+command_await()
+{
+
+ while (1) {
+ if (!pxe_core_recv_packets()) {
+ twiddle();
+ delay(10000);
+ }
+ }
+
+ return (0);
+}
+
+#if 0
+static int
+command_sock(int argc, char *argv[])
+{
+ if (argc < 2) {
+ printf("use: socket stats|tcptest\n");
+ return (CMD_OK);
+ }
+
+ if (!strcmp(argv[1], "stats")) {
+ pxe_sock_stats();
+ return (CMD_OK);
+ }
+
+ if (argc < 3) {
+ printf("use: socket tcptest ip4.addr\n");
+ return (CMD_OK);
+ }
+
+ if (!strcmp(argv[1], "tcptest")) {
+ int socket = pxe_socket();
+ PXE_IPADDR ip;
+ uint32_t bps = 0;
+ uint32_t start_time = 0;
+ int index2 = 0;
+
+ ip.ip = pxe_convert_ipstr(argv[2]);
+
+ int res = pxe_connect(socket, &ip, 26, PXE_TCP_PROTOCOL);
+
+ if (res == -1)
+ printf("tcptest: failed to connect socket.\n");
+ else {
+ int index = 0;
+ int recvc = 0;
+ uint8_t data;
+ start_time = pxe_get_secs();
+
+ index = 0;
+ recvc = 0;
+
+ data = 1;
+
+ while ( data != 0) {
+ recvc = pxe_recv(socket, &data, 1);
+
+ if (recvc == -1) {
+ printf("tcptest: %d bytes recv, but next failed.\n", index);
+ pxe_close(socket);
+ return (CMD_OK);
+ }
+
+ if (recvc == 0) {
+ printf("!");
+ continue;
+ }
+
+ recvc = (index % 149) + 1;
+
+ if (data == 0) {
+ printf("tcptest: end of test.\n");
+ break;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-user
mailing list