From owner-svn-src-user@FreeBSD.ORG Fri Feb 8 01:28:32 2013 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 074A7DF1; Fri, 8 Feb 2013 01:28:32 +0000 (UTC) (envelope-from sbruno@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id DFF93CC5; Fri, 8 Feb 2013 01:28:31 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r181SV82083600; Fri, 8 Feb 2013 01:28:31 GMT (envelope-from sbruno@svn.freebsd.org) Received: (from sbruno@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r181SUQH083588; Fri, 8 Feb 2013 01:28:30 GMT (envelope-from sbruno@svn.freebsd.org) Message-Id: <201302080128.r181SUQH083588@svn.freebsd.org> From: Sean Bruno Date: Fri, 8 Feb 2013 01:28:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r246526 - in user/sbruno/pxe_http_head/sys/boot/i386: . libi386 loader pxe_http X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Feb 2013 01:28:32 -0000 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 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 #include +#ifdef LOADER_NFS_SUPPORT #include +#endif #include #include @@ -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 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 ***