Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 6 May 2017 20:32:27 +0000 (UTC)
From:      Toomas Soome <tsoome@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r317887 - in head: lib/libstand sys/boot/common sys/boot/efi/libefi sys/boot/efi/loader sys/boot/i386/libi386 sys/boot/i386/loader sys/boot/ofw/libofw sys/boot/uboot/lib
Message-ID:  <201705062032.v46KWRlF040330@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tsoome
Date: Sat May  6 20:32:27 2017
New Revision: 317887
URL: https://svnweb.freebsd.org/changeset/base/317887

Log:
  loader: network read rework
  
  The current read from network is working from up to down - we have some
  protocol needing the data from the network, so we build the buffer space
  for that protocol, add the extra space for headers and pass this buffer
  down to be filled by nif get call in hope, we have guessed the incoming
  packet size right. Amazingly enough this approach mostly does work, but
  not always...
  
  So, this update does work from down to up - we allocate buffer (based
  on MTU or frame size info), fill it up, and pass on for upper layers.
  The obvious problem is that when we should free the buffer - if at all.
  
  In the current implementation the upper layer will free the packet on error
  or when the packet is no longer needed.
  
  While working on the issue, the additional issue did pop up - the bios
  implementation does not have generic get/put interface but is using pxe
  udpsend/udpreceive instead. So the udp calls are gone and undi interface
  is implemented instead. Which in turn means slight other changes as we
  do not need to have duplicated pxe implementation and can just use dev_net.
  
  To align packet content, the actual read from nic is using shifted buffer by
  ETHER_ALIGN (2).
  
  Reviewed by:	bapt
  Differential Revision:	https://reviews.freebsd.org/D10232

Modified:
  head/lib/libstand/arp.c
  head/lib/libstand/bootp.c
  head/lib/libstand/bootp.h
  head/lib/libstand/bootparam.c
  head/lib/libstand/ether.c
  head/lib/libstand/net.c
  head/lib/libstand/net.h
  head/lib/libstand/netif.c
  head/lib/libstand/netif.h
  head/lib/libstand/nfs.c
  head/lib/libstand/rarp.c
  head/lib/libstand/rpc.c
  head/lib/libstand/rpc.h
  head/lib/libstand/tftp.c
  head/lib/libstand/udp.c
  head/sys/boot/common/dev_net.c
  head/sys/boot/efi/libefi/efinet.c
  head/sys/boot/efi/libefi/time.c
  head/sys/boot/efi/loader/Makefile
  head/sys/boot/i386/libi386/pxe.c
  head/sys/boot/i386/libi386/pxe.h
  head/sys/boot/i386/loader/Makefile
  head/sys/boot/ofw/libofw/ofw_net.c
  head/sys/boot/uboot/lib/net.c

Modified: head/lib/libstand/arp.c
==============================================================================
--- head/lib/libstand/arp.c	Sat May  6 19:23:58 2017	(r317886)
+++ head/lib/libstand/arp.c	Sat May  6 20:32:27 2017	(r317887)
@@ -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: head/lib/libstand/bootp.c
==============================================================================
--- head/lib/libstand/bootp.c	Sat May  6 19:23:58 2017	(r317886)
+++ head/lib/libstand/bootp.c	Sat May  6 20:32:27 2017	(r317887)
@@ -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,21 @@ static void setenv_(u_char *cp,  u_char 
 static char expected_dhcpmsgtype = -1, dhcp_ok;
 struct in_addr dhcp_serverip;
 #endif
+struct bootp *bootp_response;
+size_t bootp_response_size;
 
 /* Fetch required bootp infomation */
 void
-bootp(sock, flag)
-	int sock;
-	int flag;
+bootp(int sock, int flag)
 {
+	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)
@@ -175,8 +174,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;
 	}
@@ -187,7 +185,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);
@@ -205,20 +203,21 @@ bootp(sock, flag)
 
 		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) {
@@ -258,14 +257,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;
 
@@ -286,30 +283,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
@@ -328,8 +320,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)
@@ -338,8 +343,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);
 }
@@ -356,9 +364,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;
@@ -445,8 +451,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: head/lib/libstand/bootp.h
==============================================================================
--- head/lib/libstand/bootp.h	Sat May  6 19:23:58 2017	(r317886)
+++ head/lib/libstand/bootp.h	Sat May  6 20:32:27 2017	(r317887)
@@ -147,6 +147,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);
 
 #endif /* _BOOTP_H_ */

Modified: head/lib/libstand/bootparam.c
==============================================================================
--- head/lib/libstand/bootparam.c	Sat May  6 19:23:58 2017	(r317886)
+++ head/lib/libstand/bootparam.c	Sat May  6 20:32:27 2017	(r317887)
@@ -104,8 +104,7 @@ int xdr_string_decode(char **p, char *st
  * 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, pathn
 	}
 
 	send_tail = (char*) sdata.d;
-	recv_head = (char*) rdata.d;
 
 	/*
 	 * Build request message.
@@ -281,17 +272,16 @@ bp_getfile(sockfd, key, serv_addr, pathn
 	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, pathn
 
 	/* 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, pathn
 
 
 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: head/lib/libstand/ether.c
==============================================================================
--- head/lib/libstand/ether.c	Sat May  6 19:23:58 2017	(r317886)
+++ head/lib/libstand/ether.c	Sat May  6 20:32:27 2017	(r317887)
@@ -54,12 +54,7 @@ __FBSDID("$FreeBSD$");
 
 /* Caller must leave room for ethernet header in front!! */
 ssize_t
-sendether(d, pkt, len, dea, etype)
-	struct iodesc *d;
-	void *pkt;
-	size_t len;
-	u_char *dea;
-	int etype;
+sendether(struct iodesc *d, void *pkt, size_t len, uint8_t *dea, int etype)
 {
 	ssize_t n;
 	struct ether_header *eh;
@@ -86,32 +81,31 @@ sendether(d, pkt, len, dea, etype)
 
 /*
  * Get a packet of any Ethernet type, with our address or
- * the broadcast address.  Save the Ether type in arg 5.
- * NOTE: Caller must leave room for the Ether header.
+ * the broadcast address.  Save the Ether type in etype.
+ * Unless there is an error, we pass the whole packet and the unencapsulated
+ * data.
  */
 ssize_t
-readether(d, pkt, len, tleft, etype)
-	struct iodesc *d;
-	void *pkt;
-	size_t len;
-	time_t tleft;
-	u_int16_t *etype;
+readether(struct iodesc *d, void **pkt, void **payload, time_t tleft,
+    uint16_t *etype)
 {
 	ssize_t n;
 	struct ether_header *eh;
+	void *ptr;
 
 #ifdef ETHER_DEBUG
  	if (debug)
 		printf("readether: called\n");
 #endif
 
-	eh = (struct ether_header *)pkt - 1;
-	len += sizeof(*eh);
-
-	n = netif_get(d, eh, len, tleft);
-	if (n == -1 || n < sizeof(*eh))
+	ptr = NULL;
+	n = netif_get(d, &ptr, tleft);
+	if (n == -1 || n < sizeof(*eh)) {
+		free(ptr);
 		return (-1);
+	}
 
+	eh = (struct ether_header *)((uintptr_t)ptr + ETHER_ALIGN);
 	/* Validate Ethernet address. */
 	if (bcmp(d->myea, eh->ether_dhost, 6) != 0 &&
 	    bcmp(bcea, eh->ether_dhost, 6) != 0) {
@@ -120,8 +114,12 @@ readether(d, pkt, len, tleft, etype)
 			printf("readether: not ours (ea=%s)\n",
 			    ether_sprintf(eh->ether_dhost));
 #endif
+		free(ptr);
 		return (-1);
 	}
+
+	*pkt = ptr;
+	*payload = (void *)((uintptr_t)eh + sizeof(*eh));
 	*etype = ntohs(eh->ether_type);
 
 	n -= sizeof(*eh);
@@ -133,8 +131,7 @@ readether(d, pkt, len, tleft, etype)
  */
 static char digits[] = "0123456789abcdef";
 char *
-ether_sprintf(ap)
-        u_char *ap;
+ether_sprintf(u_char *ap)
 {
 	int i;
 	static char etherbuf[18];

Modified: head/lib/libstand/net.c
==============================================================================
--- head/lib/libstand/net.c	Sat May  6 19:23:58 2017	(r317886)
+++ head/lib/libstand/net.c	Sat May  6 20:32:27 2017	(r317887)
@@ -70,10 +70,10 @@ __FBSDID("$FreeBSD$");
  */
 ssize_t
 sendrecv(struct iodesc *d,
-	ssize_t (*sproc)(struct iodesc *, void *, size_t),
-	void *sbuf, size_t ssize,
-	ssize_t (*rproc)(struct iodesc *, void *, size_t, time_t),
-	void *rbuf, size_t rsize)
+    ssize_t (*sproc)(struct iodesc *, void *, size_t),
+    void *sbuf, size_t ssize,
+    ssize_t (*rproc)(struct iodesc *, void **, void **, time_t),
+    void **pkt, void **payload)
 {
 	ssize_t cc;
 	time_t t, tmo, tlast;
@@ -116,7 +116,7 @@ sendrecv(struct iodesc *d,
 		}
 
 		/* Try to get a packet and process it. */
-		cc = (*rproc)(d, rbuf, rsize, tleft);
+		cc = (*rproc)(d, pkt, payload, tleft);
 		/* Return on data, EOF or real error. */
 		if (cc != -1 || errno != 0)
 			return (cc);

Modified: head/lib/libstand/net.h
==============================================================================
--- head/lib/libstand/net.h	Sat May  6 19:23:58 2017	(r317886)
+++ head/lib/libstand/net.h	Sat May  6 20:32:27 2017	(r317887)
@@ -106,16 +106,15 @@ int	rarp_getipaddress(int);
 /* Link functions: */
 ssize_t sendether(struct iodesc *d, void *pkt, size_t len,
 			u_char *dea, int etype);
-ssize_t readether(struct iodesc *d, void *pkt, size_t len,
-			time_t tleft, u_int16_t *etype);
+ssize_t readether(struct iodesc *, void **, void **, time_t, uint16_t *);
 
 ssize_t	sendudp(struct iodesc *, void *, size_t);
-ssize_t	readudp(struct iodesc *, void *, size_t, time_t);
+ssize_t	readudp(struct iodesc *, void **, void **, time_t);
 ssize_t	sendrecv(struct iodesc *,
-		      ssize_t (*)(struct iodesc *, void *, size_t),
+			ssize_t (*)(struct iodesc *, void *, size_t),
 			void *, size_t,
-		        ssize_t (*)(struct iodesc *, void *, size_t, time_t),
-			void *, size_t);
+			ssize_t (*)(struct iodesc *, void **, void **, time_t),
+			void **, void **);
 
 /* bootp/DHCP */
 void	bootp(int, int);

Modified: head/lib/libstand/netif.c
==============================================================================
--- head/lib/libstand/netif.c	Sat May  6 19:23:58 2017	(r317886)
+++ head/lib/libstand/netif.c	Sat May  6 20:32:27 2017	(r317887)
@@ -59,7 +59,7 @@ int netif_debug = 0;
  */
 
 void
-netif_init()
+netif_init(void)
 {
 	struct netif_driver *drv;
 	int d, i;
@@ -76,13 +76,11 @@ netif_init()
 }
 
 int
-netif_match(nif, machdep_hint)
-	struct netif *nif;
-	void *machdep_hint;
+netif_match(struct netif *nif, void *machdep_hint)
 {
 	struct netif_driver *drv = nif->nif_driver;
 
-#if 0
+#if NETIF_DEBUG
 	if (netif_debug)
 		printf("%s%d: netif_match (%d)\n", drv->netif_bname,
 		    nif->nif_unit, nif->nif_sel);
@@ -91,8 +89,7 @@ netif_match(nif, machdep_hint)
 }
 
 struct netif *
-netif_select(machdep_hint)
-	void *machdep_hint;
+netif_select(void *machdep_hint)
 {
 	int d, u, unit_done, s;
 	struct netif_driver *drv;
@@ -162,9 +159,7 @@ netif_select(machdep_hint)
 }
 
 int
-netif_probe(nif, machdep_hint)
-	struct netif *nif;
-	void *machdep_hint;
+netif_probe(struct netif *nif, void *machdep_hint)
 {
 	struct netif_driver *drv = nif->nif_driver;
 
@@ -176,10 +171,7 @@ netif_probe(nif, machdep_hint)
 }
 
 void
-netif_attach(nif, desc, machdep_hint)
-	struct netif *nif;
-	struct iodesc *desc;
-	void *machdep_hint;
+netif_attach(struct netif *nif, struct iodesc *desc, void *machdep_hint)
 {
 	struct netif_driver *drv = nif->nif_driver;
 
@@ -199,8 +191,7 @@ netif_attach(nif, desc, machdep_hint)
 }
 
 void
-netif_detach(nif)
-	struct netif *nif;
+netif_detach(struct netif *nif)
 {
 	struct netif_driver *drv = nif->nif_driver;
 
@@ -217,11 +208,7 @@ netif_detach(nif)
 }
 
 ssize_t
-netif_get(desc, pkt, len, timo)
-	struct iodesc *desc;
-	void *pkt;
-	size_t len;
-	time_t timo;
+netif_get(struct iodesc *desc, void **pkt, time_t timo)
 {
 #ifdef NETIF_DEBUG
 	struct netif *nif = desc->io_netif;
@@ -238,20 +225,17 @@ netif_get(desc, pkt, len, timo)
 		panic("%s%d: no netif_get support\n", drv->netif_bname,
 		    nif->nif_unit);
 #endif
-	rv = drv->netif_get(desc, pkt, len, timo);
+	rv = drv->netif_get(desc, pkt, timo);
 #ifdef NETIF_DEBUG
 	if (netif_debug)
 		printf("%s%d: netif_get returning %d\n", drv->netif_bname,
 		    nif->nif_unit, (int)rv);
 #endif
-	return rv;
+	return (rv);
 }
 
 ssize_t
-netif_put(desc, pkt, len)
-	struct iodesc *desc;
-	void *pkt;
-	size_t len;
+netif_put(struct iodesc *desc, void *pkt, size_t len)
 {
 #ifdef NETIF_DEBUG
 	struct netif *nif = desc->io_netif;
@@ -274,12 +258,11 @@ netif_put(desc, pkt, len)
 		printf("%s%d: netif_put returning %d\n", drv->netif_bname,
 		    nif->nif_unit, (int)rv);
 #endif
-	return rv;
+	return (rv);
 }
 
 struct iodesc *
-socktodesc(sock)
-	int sock;
+socktodesc(int sock)
 {
 	if (sock >= SOPEN_MAX) {
 		errno = EBADF;
@@ -289,8 +272,7 @@ socktodesc(sock)
 }
 
 int
-netif_open(machdep_hint)
-	void *machdep_hint;
+netif_open(void *machdep_hint)
 {
 	int fd;
 	struct iodesc *s;
@@ -313,23 +295,22 @@ fnd:
 		printf("netboot: couldn't probe %s%d\n",
 		    nif->nif_driver->netif_bname, nif->nif_unit);
 		errno = EINVAL;
-		return(-1);
+		return (-1);
 	}
 	netif_attach(nif, s, machdep_hint);
 
-	return(fd);
+	return (fd);
 }
 
 int
-netif_close(sock)
-	int sock;
+netif_close(int sock)
 {
 	if (sock >= SOPEN_MAX) {
 		errno = EBADF;
-		return(-1);
+		return (-1);
 	}
 	netif_detach(sockets[sock].io_netif);
 	sockets[sock].io_netif = (struct netif *)0;
 
-	return(0);
+	return (0);
 }

Modified: head/lib/libstand/netif.h
==============================================================================
--- head/lib/libstand/netif.h	Sat May  6 19:23:58 2017	(r317886)
+++ head/lib/libstand/netif.h	Sat May  6 20:32:27 2017	(r317887)
@@ -6,15 +6,13 @@
 #define __SYS_LIBNETBOOT_NETIF_H
 #include "iodesc.h"
 
-#define NENTS(x)	sizeof(x)/sizeof(x[0])
-
 struct netif_driver {
 	const	char *netif_bname;
 	int	(*netif_match)(struct netif *, void *);
 	int	(*netif_probe)(struct netif *, void *);
 	void	(*netif_init)(struct iodesc *, void *);
-	int	(*netif_get)(struct iodesc *, void *, size_t, time_t);
-	int	(*netif_put)(struct iodesc *, void *, size_t);
+	ssize_t	(*netif_get)(struct iodesc *, void **, time_t);
+	ssize_t	(*netif_put)(struct iodesc *, void *, size_t);
 	void	(*netif_end)(struct netif *);
 	struct	netif_dif *netif_ifs;
 	int	netif_nifs;
@@ -56,7 +54,7 @@ struct netif	*netif_select(void *);
 int		netif_probe(struct netif *, void *);
 void		netif_attach(struct netif *, struct iodesc *, void *);
 void		netif_detach(struct netif *);
-ssize_t		netif_get(struct iodesc *, void *, size_t, time_t);
+ssize_t		netif_get(struct iodesc *, void **, time_t);
 ssize_t		netif_put(struct iodesc *, void *, size_t);
 
 int		netif_open(void *);

Modified: head/lib/libstand/nfs.c
==============================================================================
--- head/lib/libstand/nfs.c	Sat May  6 19:23:58 2017	(r317886)
+++ head/lib/libstand/nfs.c	Sat May  6 20:32:27 2017	(r317887)
@@ -185,6 +185,7 @@ set_nfs_read_size(void)
 int
 nfs_getrootfh(struct iodesc *d, char *path, uint32_t *fhlenp, u_char *fhp)
 {
+	void *pkt = NULL;
 	int len;
 	struct args {
 		uint32_t len;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201705062032.v46KWRlF040330>