svn commit: r329100 - in stable/11: lib/libstand share/mk sys/boot/common sys/boot/efi sys/boot/efi/boot1 sys/boot/efi/fdt sys/boot/efi/include sys/boot/efi/libefi sys/boot/efi/loader sys/boot/efi/...
Kyle Evans
kevans at FreeBSD.org
Sat Feb 10 04:56:09 UTC 2018
Author: kevans
Date: Sat Feb 10 04:56:07 2018
New Revision: 329100
URL: https://svnweb.freebsd.org/changeset/base/329100
Log:
MFC Loader Fixes 2017q2: r316437,r316577,r316578,r316585,r316590,r316612,
r316625,r316628,r316654,r316682,r316704,r316771,r317092,r317097,r317099,
r317652,r317785,r317886,r317887,r318142,r318320,r318356,r318678,r318754,
r318982,r318986,r318987,r318988,r318989,r318990,r318991,r318992,r318993,
r318994,r318999,r319083,r319084,r319085,r320011,r320234,r320288,r320304,
r320467,r320482
r316437: Small cleanup to make i386/loader match efi/loader boot environment
code
r316577: loader: part.c cstyle cleanup
r316578: loader: want mechanism to avoid RA with bcache
r316585: loader: zfs reader should check all labels
r316590: libstand/dosfs: cache FAT32 in 128 Kb blocks to save loader memory
r316612: In r298230 the value of HEAP_MIN was changed from 3MB to 64MB.
Correct a comment.
r316625: Do not use -msoft-float with intention of disabling FP on aarch64
r316628: Silence GCC warning by initializing the local variable.
r316654: loader: r316585 did miss userboot update
r316682: loader: r316585 did miss sparc/ofw
r316704: loader.efi: only fetch zfs pool guid for the actual boot device
r316771: loader: Avoid possible overflow via environment variable
r317092: loader: zfs reader vdev_probe should check for minimum device size
r317097: loader: F_READ/F_WRITE should be checked against masked flag
r317099: loader: uboot disk ioctl should call disk_ioctl
r317652: loader.efi: ResetSystem does not use data with EFI_SUCCESS
r317785: zfsboot: drvsize() may be unusable on some systems
r317886: distinguish NFS versus TFTP boot by rootpath
r317887: loader: network read rework
r318142: libstand: NULL pointer dereference in rarp
r318320: loader: add ip layer code into libstand
r318356: libstand: increase nfs max read size to 16k
r318678: Replacing iterating over rootpath by strsep(3).
r318754: Pass -N directly to ld via -Wl rather than passing it to the
compiler driver.
r318982: Pass a "FREEBSD" user-class in PXE dhcp request
r318986: add a comment on vendor index 19 and 20 to avoid confusion
r318987: Support URI scheme for root-path in netbooting
r318988: Always build tftpfs support along with nfs for pxeboot
r318989: Always issue the pxe request
r318990: Partially revert r314948
r318991: Document recent changes on pxeboot
r318992: Capitalize DHCP
r318993: Use the usual FreeBSD spelling for the DHCP user class
r318994: Catch with the change in the user class
r318999: Update the comments concerning net_parse_rootpath to reflect what
it is now
r319083: Followup on the user-class changes
r319084: Small cleanup in dev_net.c
r319085: use the same option list for dhcp discovery and request
r320011: Add chain loader support for loader
r320234: Make structure padding explicit in EFI_MEMORY_DESCRIPTOR
r320288: Allow Clang's integrated assembler to assemble boot0
r320304: loader.efi: Disable smbios for arm
r320467: loader: chain load relocate data declaration is bad
r320482: As with arm64 mark the EFI PE header as allocated on arm.
PR: 218473
Added:
stable/11/lib/libstand/ip.c
- copied unchanged from r318320, head/lib/libstand/ip.c
stable/11/sys/boot/i386/libi386/relocater_tramp.S
- copied unchanged from r320011, head/sys/boot/i386/libi386/relocater_tramp.S
stable/11/sys/boot/i386/loader/chain.c
- copied, changed from r320011, head/sys/boot/i386/loader/chain.c
Modified:
stable/11/lib/libstand/Makefile
stable/11/lib/libstand/arp.c
stable/11/lib/libstand/bootp.c
stable/11/lib/libstand/bootp.h
stable/11/lib/libstand/bootparam.c
stable/11/lib/libstand/dosfs.c
stable/11/lib/libstand/dosfs.h
stable/11/lib/libstand/ether.c
stable/11/lib/libstand/globals.c
stable/11/lib/libstand/net.c
stable/11/lib/libstand/net.h
stable/11/lib/libstand/netif.c
stable/11/lib/libstand/netif.h
stable/11/lib/libstand/nfs.c
stable/11/lib/libstand/rarp.c
stable/11/lib/libstand/rpc.c
stable/11/lib/libstand/rpc.h
stable/11/lib/libstand/stand.h
stable/11/lib/libstand/tftp.c
stable/11/lib/libstand/udp.c
stable/11/share/mk/bsd.stand.mk
stable/11/sys/boot/common/bcache.c
stable/11/sys/boot/common/commands.c
stable/11/sys/boot/common/dev_net.c
stable/11/sys/boot/common/disk.c
stable/11/sys/boot/common/md.c
stable/11/sys/boot/common/part.c
stable/11/sys/boot/efi/Makefile.inc
stable/11/sys/boot/efi/boot1/Makefile
stable/11/sys/boot/efi/boot1/boot1.c
stable/11/sys/boot/efi/boot1/zfs_module.c
stable/11/sys/boot/efi/fdt/Makefile
stable/11/sys/boot/efi/include/efidef.h
stable/11/sys/boot/efi/libefi/Makefile
stable/11/sys/boot/efi/libefi/efinet.c
stable/11/sys/boot/efi/libefi/efipart.c
stable/11/sys/boot/efi/libefi/time.c
stable/11/sys/boot/efi/loader/Makefile
stable/11/sys/boot/efi/loader/arch/arm/start.S
stable/11/sys/boot/efi/loader/arch/arm64/Makefile.inc
stable/11/sys/boot/efi/loader/main.c
stable/11/sys/boot/forth/menu.rc
stable/11/sys/boot/i386/boot0/Makefile
stable/11/sys/boot/i386/common/drv.h
stable/11/sys/boot/i386/libi386/Makefile
stable/11/sys/boot/i386/libi386/bioscd.c
stable/11/sys/boot/i386/libi386/biosdisk.c
stable/11/sys/boot/i386/libi386/biosmem.c
stable/11/sys/boot/i386/libi386/libi386.h
stable/11/sys/boot/i386/libi386/pxe.c
stable/11/sys/boot/i386/libi386/pxe.h
stable/11/sys/boot/i386/loader/Makefile
stable/11/sys/boot/i386/loader/help.i386
stable/11/sys/boot/i386/loader/main.c
stable/11/sys/boot/i386/pxeldr/pxeboot.8
stable/11/sys/boot/i386/zfsboot/zfsboot.c
stable/11/sys/boot/mips/beri/boot2/Makefile
stable/11/sys/boot/mips/beri/loader/beri_disk_cfi.c
stable/11/sys/boot/mips/beri/loader/beri_disk_sdcard.c
stable/11/sys/boot/ofw/libofw/ofw_disk.c
stable/11/sys/boot/ofw/libofw/ofw_net.c
stable/11/sys/boot/ofw/libofw/openfirm.c
stable/11/sys/boot/ofw/libofw/openfirm.h
stable/11/sys/boot/powerpc/ps3/ps3cdrom.c
stable/11/sys/boot/powerpc/ps3/ps3disk.c
stable/11/sys/boot/sparc64/loader/main.c
stable/11/sys/boot/uboot/lib/disk.c
stable/11/sys/boot/uboot/lib/net.c
stable/11/sys/boot/usb/storage/umass_loader.c
stable/11/sys/boot/userboot/userboot/main.c
stable/11/sys/boot/userboot/userboot/userboot_disk.c
stable/11/sys/boot/zfs/libzfs.h
stable/11/sys/boot/zfs/zfsimpl.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/lib/libstand/Makefile
==============================================================================
--- stable/11/lib/libstand/Makefile Sat Feb 10 04:37:44 2018 (r329099)
+++ stable/11/lib/libstand/Makefile Sat Feb 10 04:56:07 2018 (r329100)
@@ -141,7 +141,7 @@ SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \
fstat.c close.c lseek.c open.c read.c write.c readdir.c
# network routines
-SRCS+= arp.c ether.c inet_ntoa.c in_cksum.c net.c udp.c netif.c rpc.c
+SRCS+= arp.c ether.c ip.c inet_ntoa.c in_cksum.c net.c udp.c netif.c rpc.c
# network info services:
SRCS+= bootp.c rarp.c bootparam.c
Modified: stable/11/lib/libstand/arp.c
==============================================================================
--- stable/11/lib/libstand/arp.c Sat Feb 10 04:37:44 2018 (r329099)
+++ stable/11/lib/libstand/arp.c Sat Feb 10 04:56:07 2018 (r329100)
@@ -65,17 +65,16 @@ int arp_num = 1;
/* Local forwards */
static ssize_t arpsend(struct iodesc *, void *, size_t);
-static ssize_t arprecv(struct iodesc *, void *, size_t, time_t);
+static ssize_t arprecv(struct iodesc *, void **, void **, time_t);
/* Broadcast an ARP packet, asking who has addr on interface d */
u_char *
-arpwhohas(d, addr)
- struct iodesc *d;
- struct in_addr addr;
+arpwhohas(struct iodesc *d, struct in_addr addr)
{
int i;
struct ether_arp *ah;
struct arp_list *al;
+ void *pkt;
struct {
struct ether_header eh;
struct {
@@ -83,13 +82,6 @@ arpwhohas(d, addr)
u_char pad[18]; /* 60 - sizeof(...) */
} data;
} wbuf;
- struct {
- struct ether_header eh;
- struct {
- struct ether_arp arp;
- u_char pad[24]; /* extra space */
- } data;
- } rbuf;
/* Try for cached answer first */
for (i = 0, al = arp_list; i < arp_num; ++i, ++al)
@@ -122,20 +114,24 @@ arpwhohas(d, addr)
/* Store ip address in cache (incomplete entry). */
al->addr = addr;
+ pkt = NULL;
+ ah = NULL;
i = sendrecv(d,
arpsend, &wbuf.data, sizeof(wbuf.data),
- arprecv, &rbuf.data, sizeof(rbuf.data));
+ arprecv, &pkt, (void **)&ah);
if (i == -1) {
panic("arp: no response for %s\n",
inet_ntoa(addr));
}
/* Store ethernet address in cache */
- ah = &rbuf.data.arp;
#ifdef ARP_DEBUG
if (debug) {
+ struct ether_header *eh;
+
+ eh = (struct ether_header *)((uintptr_t)pkt + ETHER_ALIGN);
printf("arp: response from %s\n",
- ether_sprintf(rbuf.eh.ether_shost));
+ ether_sprintf(eh->ether_shost));
printf("arp: cacheing %s --> %s\n",
inet_ntoa(addr), ether_sprintf(ah->arp_sha));
}
@@ -143,14 +139,12 @@ arpwhohas(d, addr)
MACPY(ah->arp_sha, al->ea);
++arp_num;
+ free(pkt);
return (al->ea);
}
static ssize_t
-arpsend(d, pkt, len)
- struct iodesc *d;
- void *pkt;
- size_t len;
+arpsend(struct iodesc *d, void *pkt, size_t len)
{
#ifdef ARP_DEBUG
@@ -166,28 +160,27 @@ arpsend(d, pkt, len)
* else -1 (and errno == 0)
*/
static ssize_t
-arprecv(d, pkt, len, tleft)
- struct iodesc *d;
- void *pkt;
- size_t len;
- time_t tleft;
+arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft)
{
ssize_t n;
struct ether_arp *ah;
u_int16_t etype; /* host order */
+ void *ptr;
#ifdef ARP_DEBUG
if (debug)
printf("arprecv: ");
#endif
- n = readether(d, pkt, len, tleft, &etype);
+ ptr = NULL;
+ n = readether(d, &ptr, (void **)&ah, tleft, &etype);
errno = 0; /* XXX */
if (n == -1 || n < sizeof(struct ether_arp)) {
#ifdef ARP_DEBUG
if (debug)
printf("bad len=%d\n", n);
#endif
+ free(ptr);
return (-1);
}
@@ -196,12 +189,11 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("not arp type=%d\n", etype);
#endif
+ free(ptr);
return (-1);
}
/* Ethernet address now checked in readether() */
-
- ah = (struct ether_arp *)pkt;
if (ah->arp_hrd != htons(ARPHRD_ETHER) ||
ah->arp_pro != htons(ETHERTYPE_IP) ||
ah->arp_hln != sizeof(ah->arp_sha) ||
@@ -211,6 +203,7 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("bad hrd/pro/hln/pln\n");
#endif
+ free(ptr);
return (-1);
}
@@ -220,6 +213,7 @@ arprecv(d, pkt, len, tleft)
printf("is request\n");
#endif
arp_reply(d, ah);
+ free(ptr);
return (-1);
}
@@ -228,6 +222,7 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("not ARP reply\n");
#endif
+ free(ptr);
return (-1);
}
@@ -239,6 +234,7 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("unwanted address\n");
#endif
+ free(ptr);
return (-1);
}
/* We don't care who the reply was sent to. */
@@ -248,6 +244,8 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("got it\n");
#endif
+ *pkt = ptr;
+ *payload = ah;
return (n);
}
@@ -256,9 +254,7 @@ arprecv(d, pkt, len, tleft)
* Notes: Re-uses buffer. Pad to length = 46.
*/
void
-arp_reply(d, pkt)
- struct iodesc *d;
- void *pkt; /* the request */
+arp_reply(struct iodesc *d, void *pkt)
{
struct ether_arp *arp = pkt;
Modified: stable/11/lib/libstand/bootp.c
==============================================================================
--- stable/11/lib/libstand/bootp.c Sat Feb 10 04:37:44 2018 (r329099)
+++ stable/11/lib/libstand/bootp.c Sat Feb 10 04:56:07 2018 (r329100)
@@ -38,6 +38,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <stddef.h>
#include <sys/types.h>
#include <sys/limits.h>
#include <sys/endian.h>
@@ -72,7 +73,7 @@ static char vm_cmu[4] = VM_CMU;
/* Local forwards */
static ssize_t bootpsend(struct iodesc *, void *, size_t);
-static ssize_t bootprecv(struct iodesc *, void *, size_t, time_t);
+static ssize_t bootprecv(struct iodesc *, void **, void **, time_t);
static int vend_rfc1048(u_char *, u_int);
#ifdef BOOTP_VEND_CMU
static void vend_cmu(u_char *);
@@ -89,23 +90,50 @@ static void setenv_(u_char *cp, u_char *ep, struct dh
static char expected_dhcpmsgtype = -1, dhcp_ok;
struct in_addr dhcp_serverip;
#endif
+struct bootp *bootp_response;
+size_t bootp_response_size;
+static void
+bootp_fill_request(unsigned char *bp_vend)
+{
+ /*
+ * We are booting from PXE, we want to send the string
+ * 'PXEClient' to the DHCP server so you have the option of
+ * only responding to PXE aware dhcp requests.
+ */
+ bp_vend[0] = TAG_CLASSID;
+ bp_vend[1] = 9;
+ bcopy("PXEClient", &bp_vend[2], 9);
+ bp_vend[11] = TAG_USER_CLASS;
+ /* len of each user class + number of user class */
+ bp_vend[12] = 8;
+ /* len of the first user class */
+ bp_vend[13] = 7;
+ bcopy("FreeBSD", &bp_vend[14], 7);
+ bp_vend[21] = TAG_PARAM_REQ;
+ bp_vend[22] = 7;
+ bp_vend[23] = TAG_ROOTPATH;
+ bp_vend[24] = TAG_HOSTNAME;
+ bp_vend[25] = TAG_SWAPSERVER;
+ bp_vend[26] = TAG_GATEWAY;
+ bp_vend[27] = TAG_SUBNET_MASK;
+ bp_vend[28] = TAG_INTF_MTU;
+ bp_vend[29] = TAG_SERVERID;
+ bp_vend[30] = TAG_END;
+}
+
/* Fetch required bootp infomation */
void
-bootp(sock, flag)
- int sock;
- int flag;
+bootp(int sock)
{
+ void *pkt;
struct iodesc *d;
struct bootp *bp;
struct {
u_char header[HEADER_SIZE];
struct bootp wbootp;
} wbuf;
- struct {
- u_char header[HEADER_SIZE];
- struct bootp rbootp;
- } rbuf;
+ struct bootp *rbootp;
#ifdef BOOTP_DEBUG
if (debug)
@@ -137,29 +165,8 @@ bootp(sock, flag)
bp->bp_vend[4] = TAG_DHCP_MSGTYPE;
bp->bp_vend[5] = 1;
bp->bp_vend[6] = DHCPDISCOVER;
+ bootp_fill_request(&bp->bp_vend[7]);
- /*
- * If we are booting from PXE, we want to send the string
- * 'PXEClient' to the DHCP server so you have the option of
- * only responding to PXE aware dhcp requests.
- */
- if (flag & BOOTP_PXE) {
- bp->bp_vend[7] = TAG_CLASSID;
- bp->bp_vend[8] = 9;
- bcopy("PXEClient", &bp->bp_vend[9], 9);
- bp->bp_vend[18] = TAG_PARAM_REQ;
- bp->bp_vend[19] = 8;
- bp->bp_vend[20] = TAG_ROOTPATH;
- bp->bp_vend[21] = TAG_TFTP_SERVER;
- bp->bp_vend[22] = TAG_HOSTNAME;
- bp->bp_vend[23] = TAG_SWAPSERVER;
- bp->bp_vend[24] = TAG_GATEWAY;
- bp->bp_vend[25] = TAG_SUBNET_MASK;
- bp->bp_vend[26] = TAG_INTF_MTU;
- bp->bp_vend[27] = TAG_SERVERID;
- bp->bp_vend[28] = TAG_END;
- } else
- bp->bp_vend[7] = TAG_END;
#else
bp->bp_vend[4] = TAG_END;
#endif
@@ -176,8 +183,7 @@ bootp(sock, flag)
if(sendrecv(d,
bootpsend, bp, sizeof(*bp),
- bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
- == -1) {
+ bootprecv, &pkt, (void **)&rbootp) == -1) {
printf("bootp: no reply\n");
return;
}
@@ -188,7 +194,7 @@ bootp(sock, flag)
bp->bp_vend[6] = DHCPREQUEST;
bp->bp_vend[7] = TAG_REQ_ADDR;
bp->bp_vend[8] = 4;
- bcopy(&rbuf.rbootp.bp_yiaddr, &bp->bp_vend[9], 4);
+ bcopy(&rbootp->bp_yiaddr, &bp->bp_vend[9], 4);
bp->bp_vend[13] = TAG_SERVERID;
bp->bp_vend[14] = 4;
bcopy(&dhcp_serverip.s_addr, &bp->bp_vend[15], 4);
@@ -196,30 +202,25 @@ bootp(sock, flag)
bp->bp_vend[20] = 4;
leasetime = htonl(300);
bcopy(&leasetime, &bp->bp_vend[21], 4);
- if (flag & BOOTP_PXE) {
- bp->bp_vend[25] = TAG_CLASSID;
- bp->bp_vend[26] = 9;
- bcopy("PXEClient", &bp->bp_vend[27], 9);
- bp->bp_vend[36] = TAG_END;
- } else
- bp->bp_vend[25] = TAG_END;
+ bootp_fill_request(&bp->bp_vend[25]);
expected_dhcpmsgtype = DHCPACK;
+ free(pkt);
if(sendrecv(d,
bootpsend, bp, sizeof(*bp),
- bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
- == -1) {
+ bootprecv, &pkt, (void **)&rbootp) == -1) {
printf("DHCPREQUEST failed\n");
return;
}
}
#endif
- myip = d->myip = rbuf.rbootp.bp_yiaddr;
- servip = rbuf.rbootp.bp_siaddr;
- if(rootip.s_addr == INADDR_ANY) rootip = servip;
- bcopy(rbuf.rbootp.bp_file, bootfile, sizeof(bootfile));
+ myip = d->myip = rbootp->bp_yiaddr;
+ servip = rbootp->bp_siaddr;
+ if (rootip.s_addr == INADDR_ANY)
+ rootip = servip;
+ bcopy(rbootp->bp_file, bootfile, sizeof(bootfile));
bootfile[sizeof(bootfile) - 1] = '\0';
if (!netmask) {
@@ -259,14 +260,12 @@ bootp(sock, flag)
/* Bump xid so next request will be unique. */
++d->xid;
+ free(pkt);
}
/* Transmit a bootp request */
static ssize_t
-bootpsend(d, pkt, len)
- struct iodesc *d;
- void *pkt;
- size_t len;
+bootpsend(struct iodesc *d, void *pkt, size_t len)
{
struct bootp *bp;
@@ -287,30 +286,25 @@ bootpsend(d, pkt, len)
}
static ssize_t
-bootprecv(d, pkt, len, tleft)
-struct iodesc *d;
-void *pkt;
-size_t len;
-time_t tleft;
+bootprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft)
{
ssize_t n;
struct bootp *bp;
+ void *ptr;
-#ifdef BOOTP_DEBUGx
+#ifdef BOOTP_DEBUG
if (debug)
printf("bootp_recvoffer: called\n");
#endif
- n = readudp(d, pkt, len, tleft);
+ ptr = NULL;
+ n = readudp(d, &ptr, (void **)&bp, tleft);
if (n == -1 || n < sizeof(struct bootp) - BOOTP_VENDSIZE)
goto bad;
- bp = (struct bootp *)pkt;
-
#ifdef BOOTP_DEBUG
if (debug)
- printf("bootprecv: checked. bp = 0x%lx, n = %d\n",
- (long)bp, (int)n);
+ printf("bootprecv: checked. bp = %p, n = %zd\n", bp, n);
#endif
if (bp->bp_xid != htonl(d->xid)) {
#ifdef BOOTP_DEBUG
@@ -329,8 +323,21 @@ time_t tleft;
/* Suck out vendor info */
if (bcmp(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048)) == 0) {
- if(vend_rfc1048(bp->bp_vend, sizeof(bp->bp_vend)) != 0)
+ int vsize = n - offsetof(struct bootp, bp_vend);
+ if (vend_rfc1048(bp->bp_vend, vsize) != 0)
goto bad;
+
+ /* Save copy of bootp reply or DHCP ACK message */
+ if (bp->bp_op == BOOTREPLY &&
+ ((dhcp_ok == 1 && expected_dhcpmsgtype == DHCPACK) ||
+ dhcp_ok == 0)) {
+ free(bootp_response);
+ bootp_response = malloc(n);
+ if (bootp_response != NULL) {
+ bootp_response_size = n;
+ bcopy(bp, bootp_response, bootp_response_size);
+ }
+ }
}
#ifdef BOOTP_VEND_CMU
else if (bcmp(vm_cmu, bp->bp_vend, sizeof(vm_cmu)) == 0)
@@ -339,8 +346,11 @@ time_t tleft;
else
printf("bootprecv: unknown vendor 0x%lx\n", (long)bp->bp_vend);
- return(n);
+ *pkt = ptr;
+ *payload = bp;
+ return (n);
bad:
+ free(ptr);
errno = 0;
return (-1);
}
@@ -357,9 +367,7 @@ dhcp_try_rfc1048(u_char *cp, u_int len)
}
static int
-vend_rfc1048(cp, len)
- u_char *cp;
- u_int len;
+vend_rfc1048(u_char *cp, u_int len)
{
u_char *ep;
int size;
@@ -438,10 +446,6 @@ vend_rfc1048(cp, len)
bcopy(cp, &dhcp_serverip.s_addr,
sizeof(dhcp_serverip.s_addr));
}
- if (tag == TAG_TFTP_SERVER) {
- bcopy(cp, &tftpip.s_addr,
- sizeof(tftpip.s_addr));
- }
#endif
cp += size;
}
@@ -450,8 +454,7 @@ vend_rfc1048(cp, len)
#ifdef BOOTP_VEND_CMU
static void
-vend_cmu(cp)
- u_char *cp;
+vend_cmu(u_char *cp)
{
struct cmu_vend *vp;
Modified: stable/11/lib/libstand/bootp.h
==============================================================================
--- stable/11/lib/libstand/bootp.h Sat Feb 10 04:37:44 2018 (r329099)
+++ stable/11/lib/libstand/bootp.h Sat Feb 10 04:56:07 2018 (r329100)
@@ -108,7 +108,7 @@ struct bootp {
#define TAG_T2 ((unsigned char) 59)
#define TAG_CLASSID ((unsigned char) 60)
#define TAG_CLIENTID ((unsigned char) 61)
-#define TAG_TFTP_SERVER ((unsigned char) 150)
+#define TAG_USER_CLASS ((unsigned char) 77)
#endif
#define TAG_END ((unsigned char) 255)
@@ -124,12 +124,6 @@ struct bootp {
#endif
/*
- * bootp flags
- */
-#define BOOTP_NONE 0x0000 /* No flags */
-#define BOOTP_PXE 0x0001 /* Booting from PXE. */
-
-/*
* "vendor" data permitted for CMU bootp clients.
*/
@@ -147,6 +141,10 @@ struct cmu_vend {
/* v_flags values */
#define VF_SMASK 1 /* Subnet mask field contains valid data */
+
+/* cached bootp response/dhcp ack */
+extern struct bootp *bootp_response;
+extern size_t bootp_response_size;
int dhcp_try_rfc1048(u_char *cp, u_int len);
Modified: stable/11/lib/libstand/bootparam.c
==============================================================================
--- stable/11/lib/libstand/bootparam.c Sat Feb 10 04:37:44 2018 (r329099)
+++ stable/11/lib/libstand/bootparam.c Sat Feb 10 04:56:07 2018 (r329100)
@@ -104,8 +104,7 @@ int xdr_string_decode(char **p, char *str, int *len_p)
* know about us (don't want to broadcast a getport call).
*/
int
-bp_whoami(sockfd)
- int sockfd;
+bp_whoami(int sockfd)
{
/* RPC structures for PMAPPROC_CALLIT */
struct args {
@@ -126,22 +125,19 @@ bp_whoami(sockfd)
n_long h[RPC_HEADER_WORDS];
struct args d;
} sdata;
- struct {
- n_long h[RPC_HEADER_WORDS];
- struct repl d;
- } rdata;
char *send_tail, *recv_head;
struct iodesc *d;
- int len, x;
+ void *pkt;
+ int len, x, rc;
RPC_PRINTF(("bp_whoami: myip=%s\n", inet_ntoa(myip)));
+ rc = -1;
if (!(d = socktodesc(sockfd))) {
RPC_PRINTF(("bp_whoami: bad socket. %d\n", sockfd));
- return (-1);
+ return (rc);
}
args = &sdata.d;
- repl = &rdata.d;
/*
* Build request args for PMAPPROC_CALLIT.
@@ -156,19 +152,19 @@ bp_whoami(sockfd)
* append encapsulated data (client IP address)
*/
if (xdr_inaddr_encode(&send_tail, myip))
- return (-1);
+ return (rc);
/* RPC: portmap/callit */
d->myport = htons(--rpc_port);
d->destip.s_addr = INADDR_BROADCAST; /* XXX: subnet bcast? */
/* rpc_call will set d->destport */
+ pkt = NULL;
len = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT,
- args, send_tail - (char*)args,
- repl, sizeof(*repl));
+ args, send_tail - (char*)args, (void **)&repl, &pkt);
if (len < 8) {
printf("bootparamd: 'whoami' call failed\n");
- return (-1);
+ goto done;
}
/* Save bootparam server address (from IP header). */
@@ -196,7 +192,7 @@ bp_whoami(sockfd)
x = ntohl(repl->encap_len);
if (len < x) {
printf("bp_whoami: short reply, %d < %d\n", len, x);
- return (-1);
+ goto done;
}
recv_head = (char*) repl->capsule;
@@ -204,24 +200,27 @@ bp_whoami(sockfd)
hostnamelen = MAXHOSTNAMELEN-1;
if (xdr_string_decode(&recv_head, hostname, &hostnamelen)) {
RPC_PRINTF(("bp_whoami: bad hostname\n"));
- return (-1);
+ goto done;
}
/* domain name */
domainnamelen = MAXHOSTNAMELEN-1;
if (xdr_string_decode(&recv_head, domainname, &domainnamelen)) {
RPC_PRINTF(("bp_whoami: bad domainname\n"));
- return (-1);
+ goto done;
}
/* gateway address */
if (xdr_inaddr_decode(&recv_head, &gateip)) {
RPC_PRINTF(("bp_whoami: bad gateway\n"));
- return (-1);
+ goto done;
}
/* success */
- return(0);
+ rc = 0;
+done:
+ free(pkt);
+ return (rc);
}
@@ -233,25 +232,18 @@ bp_whoami(sockfd)
* server pathname
*/
int
-bp_getfile(sockfd, key, serv_addr, pathname)
- int sockfd;
- char *key;
- char *pathname;
- struct in_addr *serv_addr;
+bp_getfile(int sockfd, char *key, struct in_addr *serv_addr, char *pathname)
{
struct {
n_long h[RPC_HEADER_WORDS];
n_long d[64];
} sdata;
- struct {
- n_long h[RPC_HEADER_WORDS];
- n_long d[128];
- } rdata;
+ void *pkt;
char serv_name[FNAME_SIZE];
- char *send_tail, *recv_head;
+ char *rdata, *send_tail;
/* misc... */
struct iodesc *d;
- int sn_len, path_len, rlen;
+ int rc = -1, sn_len, path_len, rlen;
if (!(d = socktodesc(sockfd))) {
RPC_PRINTF(("bp_getfile: bad socket. %d\n", sockfd));
@@ -259,7 +251,6 @@ bp_getfile(sockfd, key, serv_addr, pathname)
}
send_tail = (char*) sdata.d;
- recv_head = (char*) rdata.d;
/*
* Build request message.
@@ -281,17 +272,16 @@ bp_getfile(sockfd, key, serv_addr, pathname)
d->myport = htons(--rpc_port);
d->destip = bp_server_addr;
/* rpc_call will set d->destport */
-
+ pkt = NULL;
rlen = rpc_call(d,
BOOTPARAM_PROG, BOOTPARAM_VERS, BOOTPARAM_GETFILE,
sdata.d, send_tail - (char*)sdata.d,
- rdata.d, sizeof(rdata.d));
+ (void **)&rdata, &pkt);
if (rlen < 4) {
RPC_PRINTF(("bp_getfile: short reply\n"));
errno = EBADRPC;
- return (-1);
+ goto done;
}
- recv_head = (char*) rdata.d;
/*
* Parse result message.
@@ -299,26 +289,29 @@ bp_getfile(sockfd, key, serv_addr, pathname)
/* server name */
sn_len = FNAME_SIZE-1;
- if (xdr_string_decode(&recv_head, serv_name, &sn_len)) {
+ if (xdr_string_decode(&rdata, serv_name, &sn_len)) {
RPC_PRINTF(("bp_getfile: bad server name\n"));
- return (-1);
+ goto done;
}
/* server IP address (mountd/NFS) */
- if (xdr_inaddr_decode(&recv_head, serv_addr)) {
+ if (xdr_inaddr_decode(&rdata, serv_addr)) {
RPC_PRINTF(("bp_getfile: bad server addr\n"));
- return (-1);
+ goto done;
}
/* server pathname */
path_len = MAXPATHLEN-1;
- if (xdr_string_decode(&recv_head, pathname, &path_len)) {
+ if (xdr_string_decode(&rdata, pathname, &path_len)) {
RPC_PRINTF(("bp_getfile: bad server path\n"));
- return (-1);
+ goto done;
}
/* success */
- return(0);
+ rc = 0;
+done:
+ free(pkt);
+ return (rc);
}
@@ -329,17 +322,14 @@ bp_getfile(sockfd, key, serv_addr, pathname)
int
-xdr_string_encode(pkt, str, len)
- char **pkt;
- char *str;
- int len;
+xdr_string_encode(char **pkt, char *str, int len)
{
- u_int32_t *lenp;
+ uint32_t *lenp;
char *datap;
int padlen = (len + 3) & ~3; /* padded length */
/* The data will be int aligned. */
- lenp = (u_int32_t*) *pkt;
+ lenp = (uint32_t *) *pkt;
*pkt += sizeof(*lenp);
*lenp = htonl(len);
@@ -351,18 +341,15 @@ xdr_string_encode(pkt, str, len)
}
int
-xdr_string_decode(pkt, str, len_p)
- char **pkt;
- char *str;
- int *len_p; /* bufsize - 1 */
+xdr_string_decode(char **pkt, char *str, int *len_p)
{
- u_int32_t *lenp;
+ uint32_t *lenp;
char *datap;
int slen; /* string length */
int plen; /* padded length */
/* The data will be int aligned. */
- lenp = (u_int32_t*) *pkt;
+ lenp = (uint32_t *) *pkt;
*pkt += sizeof(*lenp);
slen = ntohl(*lenp);
plen = (slen + 3) & ~3;
@@ -381,9 +368,7 @@ xdr_string_decode(pkt, str, len_p)
int
-xdr_inaddr_encode(pkt, ia)
- char **pkt;
- struct in_addr ia; /* network order */
+xdr_inaddr_encode(char **pkt, struct in_addr ia)
{
struct xdr_inaddr *xi;
u_char *cp;
@@ -414,9 +399,7 @@ xdr_inaddr_encode(pkt, ia)
}
int
-xdr_inaddr_decode(pkt, ia)
- char **pkt;
- struct in_addr *ia; /* network order */
+xdr_inaddr_decode(char **pkt, struct in_addr *ia)
{
struct xdr_inaddr *xi;
u_char *cp;
Modified: stable/11/lib/libstand/dosfs.c
==============================================================================
--- stable/11/lib/libstand/dosfs.c Sat Feb 10 04:37:44 2018 (r329099)
+++ stable/11/lib/libstand/dosfs.c Sat Feb 10 04:56:07 2018 (r329100)
@@ -65,6 +65,7 @@ struct fs_ops dosfs_fsops = {
#define DEPSEC 16 /* directory entries per sector */
#define DSHIFT 4 /* DEPSEC shift */
#define LOCLUS 2 /* lowest cluster number */
+#define FATBLKSZ 0x20000 /* size of block in the FAT cache buffer */
/* DOS "BIOS Parameter Block" */
typedef struct {
@@ -132,18 +133,6 @@ static DOS_DE dot[2] = {
((u_int)cv2((de)->dex.h_clus) << 16) | \
cv2((de)->clus))
-/*
- * fat cache metadata
- */
-struct fatcache {
- int unit; /* disk unit number */
- int size; /* buffer (and fat) size in sectors */
- u_char *buf;
-};
-
-static struct fatcache fat;
-
-static int dosunmount(DOS_FS *);
static int parsebs(DOS_FS *, DOS_BS *);
static int namede(DOS_FS *, const char *, DOS_DE **);
static int lookup(DOS_FS *, u_int, const char *, DOS_DE **);
@@ -153,36 +142,37 @@ static off_t fsize(DOS_FS *, DOS_DE *);
static int fatcnt(DOS_FS *, u_int);
static int fatget(DOS_FS *, u_int *);
static int fatend(u_int, u_int);
-static int ioread(DOS_FS *, u_int, void *, u_int);
-static int ioget(struct open_file *, daddr_t, void *, u_int);
+static int ioread(DOS_FS *, u_int, void *, size_t);
+static int ioget(struct open_file *, daddr_t, void *, size_t);
-static void
-dos_read_fat(DOS_FS *fs, struct open_file *fd)
+static int
+dos_read_fatblk(DOS_FS *fs, struct open_file *fd, u_int blknum)
{
- struct devdesc *dd = fd->f_devdata;
+ int err;
+ size_t io_size;
+ daddr_t offset_in_fat, max_offset_in_fat;
- if (fat.buf != NULL) { /* can we reuse old buffer? */
- if (fat.size != fs->spf) {
- free(fat.buf); /* no, free old buffer */
- fat.buf = NULL;
- }
- }
+ offset_in_fat = ((daddr_t)blknum) * FATBLKSZ;
+ max_offset_in_fat = secbyt(fs->spf);
+ io_size = FATBLKSZ;
+ if (offset_in_fat > max_offset_in_fat)
+ offset_in_fat = max_offset_in_fat;
+ if (offset_in_fat + io_size > max_offset_in_fat)
+ io_size = ((size_t)(max_offset_in_fat - offset_in_fat));
- if (fat.buf == NULL)
- fat.buf = malloc(secbyt(fs->spf));
-
- if (fat.buf != NULL) {
- if (ioget(fd, fs->lsnfat, fat.buf, secbyt(fs->spf)) == 0) {
- fat.size = fs->spf;
- fat.unit = dd->d_unit;
- return;
- }
+ if (io_size != 0) {
+ err = ioget(fd, fs->lsnfat + bytsec(offset_in_fat),
+ fs->fatbuf, io_size);
+ if (err != 0) {
+ fs->fatbuf_blknum = ((u_int)(-1));
+ return (err);
+ }
}
- if (fat.buf != NULL) /* got IO error */
- free(fat.buf);
- fat.buf = NULL;
- fat.unit = -1; /* impossible unit */
- fat.size = 0;
+ if (io_size < FATBLKSZ)
+ memset(fs->fatbuf + io_size, 0, FATBLKSZ - io_size);
+
+ fs->fatbuf_blknum = blknum;
+ return (0);
}
/*
@@ -192,24 +182,27 @@ static int
dos_mount(DOS_FS *fs, struct open_file *fd)
{
int err;
- struct devdesc *dd = fd->f_devdata;
u_char *buf;
bzero(fs, sizeof(DOS_FS));
fs->fd = fd;
- if ((err = !(buf = malloc(secbyt(1))) ? errno : 0) ||
- (err = ioget(fs->fd, 0, buf, secbyt(1))) ||
+ if ((buf = malloc(secbyt(1))) == NULL)
+ return (errno);
+ if ((err = ioget(fs->fd, 0, buf, secbyt(1))) ||
(err = parsebs(fs, (DOS_BS *)buf))) {
- if (buf != NULL)
- free(buf);
- (void)dosunmount(fs);
+ free(buf);
return (err);
}
free(buf);
- if (fat.buf == NULL || fat.unit != dd->d_unit)
- dos_read_fat(fs, fd);
+ if ((fs->fatbuf = malloc(FATBLKSZ)) == NULL)
+ return (errno);
+ err = dos_read_fatblk(fs, fd, 0);
+ if (err != 0) {
+ free(fs->fatbuf);
+ return (err);
+ }
fs->root = dot[0];
fs->root.name[0] = ' ';
@@ -228,21 +221,9 @@ dos_mount(DOS_FS *fs, struct open_file *fd)
static int
dos_unmount(DOS_FS *fs)
{
- int err;
-
if (fs->links)
return (EBUSY);
- if ((err = dosunmount(fs)))
- return (err);
- return (0);
-}
-
-/*
- * Common code shared by dos_mount() and dos_unmount()
- */
-static int
-dosunmount(DOS_FS *fs)
-{
+ free(fs->fatbuf);
free(fs);
return (0);
}
@@ -257,16 +238,20 @@ dos_open(const char *path, struct open_file *fd)
DOS_FILE *f;
DOS_FS *fs;
u_int size, clus;
- int err = 0;
+ int err;
/* Allocate mount structure, associate with open */
- fs = malloc(sizeof(DOS_FS));
-
- if ((err = dos_mount(fs, fd)))
- goto out;
+ if ((fs = malloc(sizeof(DOS_FS))) == NULL)
+ return (errno);
+ if ((err = dos_mount(fs, fd))) {
+ free(fs);
+ return (err);
+ }
- if ((err = namede(fs, path, &de)))
- goto out;
+ if ((err = namede(fs, path, &de))) {
+ dos_unmount(fs);
+ return (err);
+ }
clus = stclus(fs->fatsz, de);
size = cv4(de->size);
@@ -274,18 +259,20 @@ dos_open(const char *path, struct open_file *fd)
if ((!(de->attr & FA_DIR) && (!clus != !size)) ||
((de->attr & FA_DIR) && size) ||
(clus && !okclus(fs, clus))) {
- err = EINVAL;
- goto out;
+ dos_unmount(fs);
+ return (EINVAL);
}
- f = malloc(sizeof(DOS_FILE));
+ if ((f = malloc(sizeof(DOS_FILE))) == NULL) {
+ err = errno;
+ dos_unmount(fs);
+ return (err);
+ }
bzero(f, sizeof(DOS_FILE));
f->fs = fs;
fs->links++;
f->de = *de;
fd->f_fsdata = (void *)f;
-
- out:
- return (err);
+ return (0);
}
/*
@@ -761,34 +748,57 @@ fatcnt(DOS_FS *fs, u_int c)
}
/*
- * Get next cluster in cluster chain. Use in core fat cache unless another
- * device replaced it.
+ * Get next cluster in cluster chain. Use in core fat cache unless
+ * the number of current 128K block in FAT has changed.
*/
static int
fatget(DOS_FS *fs, u_int *c)
{
- u_char buf[4];
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list