From owner-svn-src-head@freebsd.org Sat May 6 20:32:29 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B64AAD614C8; Sat, 6 May 2017 20:32:29 +0000 (UTC) (envelope-from tsoome@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 463C677A; Sat, 6 May 2017 20:32:29 +0000 (UTC) (envelope-from tsoome@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v46KWSfd040341; Sat, 6 May 2017 20:32:28 GMT (envelope-from tsoome@FreeBSD.org) Received: (from tsoome@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v46KWRlF040330; Sat, 6 May 2017 20:32:27 GMT (envelope-from tsoome@FreeBSD.org) Message-Id: <201705062032.v46KWRlF040330@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tsoome set sender to tsoome@FreeBSD.org using -f From: Toomas Soome Date: Sat, 6 May 2017 20:32:27 +0000 (UTC) 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 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 May 2017 20:32:29 -0000 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 __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -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 ***