From owner-svn-src-user@FreeBSD.ORG Thu Feb 7 15:49:07 2013 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 3406DA46; Thu, 7 Feb 2013 15:49:07 +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 0EE3E962; Thu, 7 Feb 2013 15:49:07 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r17Fn758008190; Thu, 7 Feb 2013 15:49:07 GMT (envelope-from sbruno@svn.freebsd.org) Received: (from sbruno@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r17Fn6Mh008182; Thu, 7 Feb 2013 15:49:06 GMT (envelope-from sbruno@svn.freebsd.org) Message-Id: <201302071549.r17Fn6Mh008182@svn.freebsd.org> From: Sean Bruno Date: Thu, 7 Feb 2013 15:49:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r246488 - in user/sbruno/head_189017: lib/libstand sys/boot/i386 sys/boot/i386/libi386 sys/boot/i386/loader sys/boot/i386/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: Thu, 07 Feb 2013 15:49:07 -0000 Author: sbruno Date: Thu Feb 7 15:49:05 2013 New Revision: 246488 URL: http://svnweb.freebsd.org/changeset/base/246488 Log: Bring pxe_http into head@189017 in a functional state Added: user/sbruno/head_189017/sys/boot/i386/pxe_http/ user/sbruno/head_189017/sys/boot/i386/pxe_http/Makefile user/sbruno/head_189017/sys/boot/i386/pxe_http/README user/sbruno/head_189017/sys/boot/i386/pxe_http/httpfs.c user/sbruno/head_189017/sys/boot/i386/pxe_http/httpfs.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_arp.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_arp.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_await.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_await.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_buffer.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_buffer.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_connection.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_connection.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_core.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_core.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_dhcp.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_dhcp.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_dns.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_dns.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_filter.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_filter.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_http.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_http.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_icmp.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_icmp.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_ip.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_ip.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_isr.S user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_isr.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_mem.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_mem.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_segment.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_segment.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_sock.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_sock.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_tcp.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_tcp.h user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_udp.c user/sbruno/head_189017/sys/boot/i386/pxe_http/pxe_udp.h Modified: user/sbruno/head_189017/lib/libstand/printf.c user/sbruno/head_189017/lib/libstand/stand.h user/sbruno/head_189017/sys/boot/i386/Makefile user/sbruno/head_189017/sys/boot/i386/libi386/Makefile user/sbruno/head_189017/sys/boot/i386/libi386/pxe.c user/sbruno/head_189017/sys/boot/i386/libi386/pxe.h user/sbruno/head_189017/sys/boot/i386/loader/Makefile user/sbruno/head_189017/sys/boot/i386/loader/conf.c user/sbruno/head_189017/sys/boot/i386/loader/main.c Modified: user/sbruno/head_189017/lib/libstand/printf.c ============================================================================== --- user/sbruno/head_189017/lib/libstand/printf.c Thu Feb 7 15:45:28 2013 (r246487) +++ user/sbruno/head_189017/lib/libstand/printf.c Thu Feb 7 15:49:05 2013 (r246488) @@ -57,7 +57,7 @@ __FBSDID("$FreeBSD$"); #define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1) static char *ksprintn (char *buf, uintmax_t num, int base, int *len, int upper); -static int kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap); +static int kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, size_t size, va_list ap); int printf(const char *fmt, ...) @@ -66,7 +66,7 @@ printf(const char *fmt, ...) int retval; va_start(ap, fmt); - retval = kvprintf(fmt, putchar, NULL, 10, ap); + retval = kvprintf(fmt, putchar, NULL, 10, 0, ap); va_end(ap); return retval; } @@ -75,7 +75,7 @@ void vprintf(const char *fmt, va_list ap) { - kvprintf(fmt, putchar, NULL, 10, ap); + kvprintf(fmt, putchar, NULL, 10, 0, ap); } int @@ -85,18 +85,42 @@ sprintf(char *buf, const char *cfmt, ... va_list ap; va_start(ap, cfmt); - retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap); + retval = kvprintf(cfmt, NULL, (void *)buf, 10, 0, ap); buf[retval] = '\0'; va_end(ap); return retval; } +int +snprintf(char *buf, size_t size, const char *cfmt, ...) +{ + int retval; + va_list ap; + size_t maxsize = (size > 1) ? size - 1 : 0; + + if (maxsize == 0) { + buf[0] = '\0'; + return (0); + } + + va_start(ap, cfmt); + retval = kvprintf(cfmt, NULL, (void *)buf, 10, maxsize, ap); + + if (retval < maxsize) + buf[retval] = '\0'; + else + buf[maxsize] = '\0'; + + va_end(ap); + return retval; +} + void vsprintf(char *buf, const char *cfmt, va_list ap) { int retval; - retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap); + retval = kvprintf(cfmt, NULL, (void *)buf, 10, 0, ap); buf[retval] = '\0'; } @@ -149,9 +173,11 @@ ksprintn(char *nbuf, uintmax_t num, int * ("%*D", len, ptr, " " -> XX XX XX XX ... */ static int -kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap) +kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, size_t maxsize, va_list ap) { -#define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; } +#define PCHAR(c) { int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; \ + if (maxsize && (retval == maxsize)) return (retval); \ + } char nbuf[MAXNBUF]; char *d; const char *p, *percent, *q; Modified: user/sbruno/head_189017/lib/libstand/stand.h ============================================================================== --- user/sbruno/head_189017/lib/libstand/stand.h Thu Feb 7 15:45:28 2013 (r246487) +++ user/sbruno/head_189017/lib/libstand/stand.h Thu Feb 7 15:49:05 2013 (r246488) @@ -239,6 +239,7 @@ extern void mallocstats(void); extern int printf(const char *fmt, ...) __printflike(1, 2); extern void vprintf(const char *fmt, __va_list); extern int sprintf(char *buf, const char *cfmt, ...) __printflike(2, 3); +extern int snprintf(char *buf, size_t size, const char *cfmt, ...) __printflike(3, 4); extern void vsprintf(char *buf, const char *cfmt, __va_list); extern void twiddle(void); Modified: user/sbruno/head_189017/sys/boot/i386/Makefile ============================================================================== --- user/sbruno/head_189017/sys/boot/i386/Makefile Thu Feb 7 15:45:28 2013 (r246487) +++ user/sbruno/head_189017/sys/boot/i386/Makefile Thu Feb 7 15:49:05 2013 (r246488) @@ -1,7 +1,7 @@ # $FreeBSD$ SUBDIR= mbr pmbr boot0 boot0sio btx boot2 cdboot gptboot zfsboot \ - gptzfsboot kgzldr libi386 libfirewire loader + gptzfsboot kgzldr libi386 libfirewire pxe_http loader # special boot programs, 'self-extracting boot2+loader' SUBDIR+= pxeldr Modified: user/sbruno/head_189017/sys/boot/i386/libi386/Makefile ============================================================================== --- user/sbruno/head_189017/sys/boot/i386/libi386/Makefile Thu Feb 7 15:45:28 2013 (r246487) +++ user/sbruno/head_189017/sys/boot/i386/libi386/Makefile Thu Feb 7 15:49:05 2013 (r246488) @@ -7,15 +7,17 @@ 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 -# 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} @@ -35,13 +37,17 @@ CFLAGS+= -DSMBIOS_SERIAL_NUMBERS # Include simple terminal emulation (cons25-compatible) CFLAGS+= -DTERM_EMU +CDLAGS+= -DPXE_DEBUG + +# allow pxe_http perform udpread/udpwrite +CFLAGS+= -DPXEHTTP_UDP_FOR_LIBSTAND # XXX: make alloca() useable CFLAGS+= -Dalloca=__builtin_alloca CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../btx/lib \ -I${.CURDIR}/../../../contrib/dev/acpica \ - -I${.CURDIR}/../../.. -I. + -I${.CURDIR}/../../.. -I. -I${.CURDIR}/../pxe_http/ # the location of libstand CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ Modified: user/sbruno/head_189017/sys/boot/i386/libi386/pxe.c ============================================================================== --- user/sbruno/head_189017/sys/boot/i386/libi386/pxe.c Thu Feb 7 15:45:28 2013 (r246487) +++ user/sbruno/head_189017/sys/boot/i386/libi386/pxe.c Thu Feb 7 15:49:05 2013 (r246488) @@ -39,67 +39,65 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef LOADER_NFS_SUPPORT #include +#endif #include #include #include #include "btxv86.h" #include "pxe.h" +#include "pxe_core.h" +#include "pxe_dhcp.h" +#include "pxe_isr.h" +#include "pxe_ip.h" +#include "pxe_udp.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 #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 + +extern char servername[256]; 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; +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_cleanup(void); -static void pxe_setnfshandle(char *rootpath); +static void pxe_print(int verbose); -static void pxe_perror(int error); static int pxe_netif_match(struct netif *nif, void *machdep_hint); static int pxe_netif_probe(struct netif *nif, void *machdep_hint); static void pxe_netif_init(struct iodesc *desc, void *machdep_hint); static int pxe_netif_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout); + static int pxe_netif_put(struct iodesc *desc, void *pkt, size_t len); static void pxe_netif_end(struct netif *nif); -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 */ - {0, 1, &pxe_st[0], 0} -}; +#ifdef LOADER_NFS_SUPPORT +static void pxe_setnfshandle(char *rootpath); +#endif + +extern struct netif_stats pxe_st[]; + +struct netif_dif pxe_ifs[] = { + /* dif_unit dif_nsel dif_stats dif_private */ + {0, 1, &pxe_st[0], 0} + }; struct netif_stats pxe_st[NENTS(pxe_ifs)]; @@ -132,279 +130,234 @@ struct devsw pxedisk = { pxe_cleanup }; -/* - * This function is called by the loader to enable PXE support if we - * are booted by PXE. The passed in pointer is a pointer to the - * PXENV+ structure. +/* pxe_enable() - This function is called by the loader to enable PXE support + * if we are booted by PXE. + * in: + * pxeinfo - pointer is a pointer to the PXENV+ structure. + * out: + * none */ void 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; } -/* - * return true if pxe structures are found/initialized, - * also figures out our IP information via the pxe cached info struct +/* pxe_init() - inits pxe_core structs + * in: + * none + * out: + * 2 - already initialized + * 1 - if pxe structures are found & initialized + * 0 - failed */ 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); } - +/* block device strategy function */ static int pxe_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf, size_t *rsize) { + return (EIO); } +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); + + return; +} + 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[1]) - 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) +pxe_cleanup(void) { - if (pxe_call != NULL) { - if (*bootplayer.Sname == '\0') { - printf(" "IP_STR":%s\n", - IP_ARGS(htonl(bootplayer.sip)), - bootplayer.bootfile); - } else { - printf(" %s:%s\n", bootplayer.Sname, - bootplayer.bootfile); - } - } + pxe_core_shutdown(); +} - return; +static int +pxe_netif_match(struct netif *nif, void *machdep_hint) +{ +#ifdef PXE_DEBUG + printf("pxe_netif_match() called."); +#endif + return (1); +} + + +static int +pxe_netif_probe(struct netif *nif, void *machdep_hint) +{ +#ifdef PXE_DEBUG + printf("pxe_netif_probe() called."); +#endif + +#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)); + + const PXE_IPADDR *my = pxe_get_ip(PXE_IP_MY); + udpopen_p->src_ip = my->ip; + + pxe_core_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_cleanup(void) +pxe_netif_end(struct netif *nif) { #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; + printf("pxe_netif_end() called."); #endif - if (pxe_call == NULL) - return; +#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_UNDI_SHUTDOWN); + pxe_core_call(PXENV_UDP_CLOSE); + + 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 - if (pxe_debug && undi_shutdown_p->Status != 0) - printf("pxe_cleanup: UNDI_SHUTDOWN failed %x\n", - undi_shutdown_p->Status); + 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] = mac[i]; - pxe_call(PXENV_UNLOAD_STACK); + const PXE_IPADDR *my = pxe_get_ip(PXE_IP_MY); + desc->xid = my->ip; +} -#ifdef PXE_DEBUG - if (pxe_debug && unload_stack_p->Status != 0) - printf("pxe_cleanup: UNLOAD_STACK failed %x\n", - unload_stack_p->Status); +static int +pxe_netif_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout) +{ +#ifdef PXE_DEBUG + printf("pxe_netif_get(): called.\n"); #endif + return (len); } -void -pxe_perror(int err) +static int +pxe_netif_put(struct iodesc *desc, void *pkt, size_t len) { - return; +#ifdef PXE_DEBUG + printf("pxe_netif_put(): called.\n"); +#endif + return (len); } +#ifdef LOADER_NFS_SUPPORT /* * Reach inside the libstand NFS code and dig out an NFS handle * for the root filesystem. @@ -415,6 +368,7 @@ struct nfs_iodesc { u_char fh[NFS_FHSIZE]; /* structure truncated here */ }; + extern struct nfs_iodesc nfs_root_node; extern int rpc_port; @@ -456,181 +410,127 @@ pxe_setnfshandle(char *rootpath) sprintf(cp, "X"); setenv("boot.nfsroot.nfshandle", buf, 1); } - -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 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 - if (pxe_debug) - printf("bangpxe_call %x\n", func); +#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); - 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) -{ - return 1; -} - - -static int -pxe_netif_probe(struct netif *nif, void *machdep_hint) -{ - t_PXENV_UDP_OPEN *udpopen_p = (t_PXENV_UDP_OPEN *)scratch_buffer; - - if (pxe_call == NULL) - return -1; - - bzero(udpopen_p, sizeof(*udpopen_p)); - udpopen_p->src_ip = bootplayer.yip; - pxe_call(PXENV_UDP_OPEN); + PXE_IPADDR dst; + dst.ip = h->destip.s_addr; - if (udpopen_p->status != 0) { - printf("pxe_netif_probe: failed %x\n", udpopen_p->status); - return -1; + if (!pxe_udp_send(ipdata, &dst, ntohs(h->destport), + ntohs(h->myport), len + sizeof(PXE_UDP_PACKET))) + { + printf("sendudp(): failed\n"); + return (-1); } - 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)); - - pxe_call(PXENV_UDP_CLOSE); - if (udpclose_p->status != 0) - printf("pxe_end failed %x\n", udpclose_p->status); -} - -static void -pxe_netif_init(struct iodesc *desc, void *machdep_hint) -{ - int i; - for (i = 0; i < 6; ++i) - desc->myea[i] = bootplayer.CAddr[i]; - desc->xid = bootplayer.ident; + + return (len); } -static int -pxe_netif_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout) +ssize_t +readudp(struct iodesc *h, void *pkt, size_t len, time_t timeout) { - return len; -} + PXE_UDP_DGRAM dgram; + struct udphdr *uh = (struct udphdr *) pkt - 1; + + /* process any queued incoming packets */ + pxe_core_recv_packets(); -static int -pxe_netif_put(struct iodesc *desc, void *pkt, size_t len) -{ - return len; + /* 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) { - t_PXENV_UDP_WRITE *udpwrite_p = (t_PXENV_UDP_WRITE *)scratch_buffer; - bzero(udpwrite_p, sizeof(*udpwrite_p)); - - udpwrite_p->ip = h->destip.s_addr; - udpwrite_p->dst_port = h->destport; - udpwrite_p->src_port = h->myport; - udpwrite_p->buffer_size = len; - udpwrite_p->buffer.segment = VTOPSEG(pkt); - udpwrite_p->buffer.offset = VTOPOFF(pkt); - - if (netmask == 0 || SAMENET(myip, h->destip, netmask)) - udpwrite_p->gw = 0; - else - udpwrite_p->gw = gateip.s_addr; - - pxe_call(PXENV_UDP_WRITE); + t_PXENV_UDP_WRITE *udpwrite_p = (t_PXENV_UDP_WRITE *)scratch_buffer; + bzero(udpwrite_p, sizeof(*udpwrite_p)); + + udpwrite_p->ip = h->destip.s_addr; + udpwrite_p->dst_port = h->destport; + udpwrite_p->src_port = h->myport; + udpwrite_p->buffer_size = len; + udpwrite_p->buffer.segment = VTOPSEG(pkt); + udpwrite_p->buffer.offset = VTOPOFF(pkt); + + if (netmask == 0 || SAMENET(myip, h->destip, netmask)) + udpwrite_p->gw = 0; + else + udpwrite_p->gw = gateip.s_addr; + pxe_core_call(PXENV_UDP_WRITE); #if 0 - /* XXX - I dont know why we need this. */ - delay(1000); + /* XXX - I dont know why we need this. */ + delay(1000); #endif - if (udpwrite_p->status != 0) { - /* XXX: This happens a lot. It shouldn't. */ - if (udpwrite_p->status != 1) - printf("sendudp failed %x\n", udpwrite_p->status); - return -1; + if (udpwrite_p->status != 0) { + /* XXX: This happens a lot. It shouldn't. */ + if (udpwrite_p->status != 1) + printf("sendudp failed %x\n", udpwrite_p->status); + + return (-1); } - return len; + + return (len); } ssize_t readudp(struct iodesc *h, void *pkt, size_t len, time_t timeout) { - t_PXENV_UDP_READ *udpread_p = (t_PXENV_UDP_READ *)scratch_buffer; - struct udphdr *uh = NULL; - - uh = (struct udphdr *) pkt - 1; - bzero(udpread_p, sizeof(*udpread_p)); - - udpread_p->dest_ip = h->myip.s_addr; - udpread_p->d_port = h->myport; - udpread_p->buffer_size = len; - udpread_p->buffer.segment = VTOPSEG(data_buffer); - udpread_p->buffer.offset = VTOPOFF(data_buffer); - - pxe_call(PXENV_UDP_READ); - + t_PXENV_UDP_READ *udpread_p = (t_PXENV_UDP_READ *)scratch_buffer; + struct udphdr *uh = NULL; + + uh = (struct udphdr *) pkt - 1; + bzero(udpread_p, sizeof(*udpread_p)); + + udpread_p->dest_ip = h->myip.s_addr; + udpread_p->d_port = h->myport; + udpread_p->buffer_size = len; + udpread_p->buffer.segment = VTOPSEG(data_buffer); + udpread_p->buffer.offset = VTOPOFF(data_buffer); + + pxe_core_call(PXENV_UDP_READ); + #if 0 - /* XXX - I dont know why we need this. */ - delay(1000); + /* XXX - I dont know why we need this. */ + delay(1000); #endif - if (udpread_p->status != 0) { - /* XXX: This happens a lot. It shouldn't. */ - if (udpread_p->status != 1) - printf("readudp failed %x\n", udpread_p->status); - return -1; + if (udpread_p->status != 0) { + /* XXX: This happens a lot. It shouldn't. */ + if (udpread_p->status != 1) + printf("readudp failed %x\n", udpread_p->status); + + return (-1); } - bcopy(data_buffer, pkt, udpread_p->buffer_size); - uh->uh_sport = udpread_p->s_port; - return udpread_p->buffer_size; + + bcopy(data_buffer, pkt, udpread_p->buffer_size); + uh->uh_sport = udpread_p->s_port; + + return (udpread_p->buffer_size); } + +#endif /* PXEHTTP_UDP_FOR_LIBSTAND */ Modified: user/sbruno/head_189017/sys/boot/i386/libi386/pxe.h ============================================================================== --- user/sbruno/head_189017/sys/boot/i386/libi386/pxe.h Thu Feb 7 15:45:28 2013 (r246487) +++ user/sbruno/head_189017/sys/boot/i386/libi386/pxe.h Thu Feb 7 15:49:05 2013 (r246488) @@ -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 @@ -156,7 +159,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 @@ -334,6 +337,15 @@ typedef struct { uint32_t Reserved[4]; /* must be 0 */ } PACKED t_PXENV_UNDI_GET_NDIS_INFO; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***