summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/boot/lib/libstand/arp.c56
-rw-r--r--usr/src/boot/lib/libstand/bootp.c54
-rw-r--r--usr/src/boot/lib/libstand/bootp.h1
-rw-r--r--usr/src/boot/lib/libstand/bootparam.c102
-rw-r--r--usr/src/boot/lib/libstand/ether.c37
-rw-r--r--usr/src/boot/lib/libstand/net.c11
-rw-r--r--usr/src/boot/lib/libstand/net.h9
-rw-r--r--usr/src/boot/lib/libstand/netif.c58
-rw-r--r--usr/src/boot/lib/libstand/netif.h8
-rw-r--r--usr/src/boot/lib/libstand/nfs.c159
-rw-r--r--usr/src/boot/lib/libstand/rarp.c44
-rw-r--r--usr/src/boot/lib/libstand/rpc.c82
-rw-r--r--usr/src/boot/lib/libstand/rpc.h2
-rw-r--r--usr/src/boot/lib/libstand/tftp.c86
-rw-r--r--usr/src/boot/lib/libstand/udp.c65
-rw-r--r--usr/src/boot/sys/boot/common/dev_net.c25
-rw-r--r--usr/src/boot/sys/boot/common/multiboot2.c10
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/efinet.c93
-rw-r--r--usr/src/boot/sys/boot/efi/loader/Makefile.common4
-rw-r--r--usr/src/boot/sys/boot/forth/support.4th6
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/multiboot.c8
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/pxe.c548
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/pxe.h2
-rw-r--r--usr/src/boot/sys/boot/ofw/libofw/ofw_net.c48
-rw-r--r--usr/src/boot/sys/boot/uboot/lib/net.c33
25 files changed, 710 insertions, 841 deletions
diff --git a/usr/src/boot/lib/libstand/arp.c b/usr/src/boot/lib/libstand/arp.c
index e6175325f3..22bd028df1 100644
--- a/usr/src/boot/lib/libstand/arp.c
+++ b/usr/src/boot/lib/libstand/arp.c
@@ -36,7 +36,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/socket.h>
@@ -65,17 +64,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 +81,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,35 +113,36 @@ 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));
}
#endif
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 +158,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 +187,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 +201,7 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("bad hrd/pro/hln/pln\n");
#endif
+ free(ptr);
return (-1);
}
@@ -220,6 +211,7 @@ arprecv(d, pkt, len, tleft)
printf("is request\n");
#endif
arp_reply(d, ah);
+ free(ptr);
return (-1);
}
@@ -228,6 +220,7 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("not ARP reply\n");
#endif
+ free(ptr);
return (-1);
}
@@ -239,6 +232,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 +242,8 @@ arprecv(d, pkt, len, tleft)
if (debug)
printf("got it\n");
#endif
+ *pkt = ptr;
+ *payload = ah;
return (n);
}
@@ -256,9 +252,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;
diff --git a/usr/src/boot/lib/libstand/bootp.c b/usr/src/boot/lib/libstand/bootp.c
index 117229753c..e4bbccfcaf 100644
--- a/usr/src/boot/lib/libstand/bootp.c
+++ b/usr/src/boot/lib/libstand/bootp.c
@@ -37,6 +37,7 @@
#include <sys/cdefs.h>
+#include <stddef.h>
#include <sys/types.h>
#include <sys/limits.h>
#include <sys/endian.h>
@@ -71,7 +72,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,21 +90,20 @@ 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(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)
@@ -173,8 +173,7 @@ bootp(int sock, int 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;
}
@@ -185,7 +184,7 @@ bootp(int sock, int 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);
@@ -203,20 +202,21 @@ bootp(int sock, int 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) {
@@ -256,6 +256,7 @@ bootp(int sock, int flag)
/* Bump xid so next request will be unique. */
++d->xid;
+ free(pkt);
}
/* Transmit a bootp request */
@@ -281,26 +282,25 @@ bootpsend(struct iodesc *d, void *pkt, size_t len)
}
static ssize_t
-bootprecv(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
@@ -319,7 +319,8 @@ bootprecv(struct iodesc *d, void *pkt, size_t len, 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 */
@@ -327,10 +328,10 @@ bootprecv(struct iodesc *d, void *pkt, size_t len, time_t tleft)
((dhcp_ok == 1 && expected_dhcpmsgtype == DHCPACK) ||
dhcp_ok == 0)) {
free(bootp_response);
- bootp_response = malloc(sizeof (*bootp_response));
+ bootp_response = malloc(n);
if (bootp_response != NULL) {
- bcopy(bp, bootp_response,
- sizeof (*bootp_response));
+ bootp_response_size = n;
+ bcopy(bp, bootp_response, bootp_response_size);
}
}
}
@@ -341,8 +342,11 @@ bootprecv(struct iodesc *d, void *pkt, size_t len, time_t tleft)
else
printf("bootprecv: unknown vendor 0x%lx\n", (long)bp->bp_vend);
+ *pkt = ptr;
+ *payload = bp;
return(n);
bad:
+ free(ptr);
errno = 0;
return (-1);
}
diff --git a/usr/src/boot/lib/libstand/bootp.h b/usr/src/boot/lib/libstand/bootp.h
index 72c781994b..89fd978aab 100644
--- a/usr/src/boot/lib/libstand/bootp.h
+++ b/usr/src/boot/lib/libstand/bootp.h
@@ -149,6 +149,7 @@ struct cmu_vend {
/* cached bootp response/dhcp ack */
extern struct bootp *bootp_response;
+extern size_t bootp_response_size;
int dhcp_try_rfc1048(uint8_t *cp, size_t len);
diff --git a/usr/src/boot/lib/libstand/bootparam.c b/usr/src/boot/lib/libstand/bootparam.c
index e4d2f1022c..2f86f52257 100644
--- a/usr/src/boot/lib/libstand/bootparam.c
+++ b/usr/src/boot/lib/libstand/bootparam.c
@@ -31,7 +31,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
/*
* RPC/bootparams
@@ -104,8 +103,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 +124,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 +151,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 +191,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 +199,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 +231,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 +250,6 @@ bp_getfile(sockfd, key, serv_addr, pathname)
}
send_tail = (char*) sdata.d;
- recv_head = (char*) rdata.d;
/*
* Build request message.
@@ -281,17 +271,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 +288,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 +321,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 +340,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 +367,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 +398,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;
diff --git a/usr/src/boot/lib/libstand/ether.c b/usr/src/boot/lib/libstand/ether.c
index 50a8934ca1..71d7f72876 100644
--- a/usr/src/boot/lib/libstand/ether.c
+++ b/usr/src/boot/lib/libstand/ether.c
@@ -36,7 +36,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/socket.h>
@@ -54,12 +53,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 +80,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 +113,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);
diff --git a/usr/src/boot/lib/libstand/net.c b/usr/src/boot/lib/libstand/net.c
index 24593e6d2e..740696a5a2 100644
--- a/usr/src/boot/lib/libstand/net.c
+++ b/usr/src/boot/lib/libstand/net.c
@@ -36,7 +36,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/socket.h>
@@ -70,10 +69,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 +115,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);
diff --git a/usr/src/boot/lib/libstand/net.h b/usr/src/boot/lib/libstand/net.h
index b7fc912eca..e1d0877c5c 100644
--- a/usr/src/boot/lib/libstand/net.h
+++ b/usr/src/boot/lib/libstand/net.h
@@ -107,16 +107,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, u_int16_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),
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);
diff --git a/usr/src/boot/lib/libstand/netif.c b/usr/src/boot/lib/libstand/netif.c
index c260690c50..e5eb603e5e 100644
--- a/usr/src/boot/lib/libstand/netif.c
+++ b/usr/src/boot/lib/libstand/netif.c
@@ -32,7 +32,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/types.h>
@@ -59,7 +58,7 @@ int netif_debug = 0;
*/
void
-netif_init()
+netif_init(void)
{
struct netif_driver *drv;
int d, i;
@@ -76,13 +75,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 +88,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 +158,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 +170,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 +190,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 +207,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 +224,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 +257,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 +271,7 @@ socktodesc(sock)
}
int
-netif_open(machdep_hint)
- void *machdep_hint;
+netif_open(void *machdep_hint)
{
int fd;
struct iodesc *s;
@@ -313,23 +294,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);
}
diff --git a/usr/src/boot/lib/libstand/netif.h b/usr/src/boot/lib/libstand/netif.h
index dac285107a..44165ab0d8 100644
--- a/usr/src/boot/lib/libstand/netif.h
+++ b/usr/src/boot/lib/libstand/netif.h
@@ -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 *);
diff --git a/usr/src/boot/lib/libstand/nfs.c b/usr/src/boot/lib/libstand/nfs.c
index e97449183c..29d08c7cf4 100644
--- a/usr/src/boot/lib/libstand/nfs.c
+++ b/usr/src/boot/lib/libstand/nfs.c
@@ -184,6 +184,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;
@@ -200,10 +201,6 @@ nfs_getrootfh(struct iodesc *d, char *path, uint32_t *fhlenp, u_char *fhp)
uint32_t h[RPC_HEADER_WORDS];
struct args d;
} sdata;
- struct {
- uint32_t h[RPC_HEADER_WORDS];
- struct repl d;
- } rdata;
size_t cc;
#ifdef NFS_DEBUG
@@ -212,7 +209,6 @@ nfs_getrootfh(struct iodesc *d, char *path, uint32_t *fhlenp, u_char *fhp)
#endif
args = &sdata.d;
- repl = &rdata.d;
bzero(args, sizeof(*args));
len = strlen(path);
@@ -223,18 +219,25 @@ nfs_getrootfh(struct iodesc *d, char *path, uint32_t *fhlenp, u_char *fhp)
len = sizeof(uint32_t) + roundup(len, sizeof(uint32_t));
cc = rpc_call(d, RPCPROG_MNT, RPCMNT_VER3, RPCMNT_MOUNT,
- args, len, repl, sizeof(*repl));
- if (cc == -1)
+ args, len, (void **)&repl, &pkt);
+ if (cc == -1) {
+ free(pkt);
/* errno was set by rpc_call */
return (errno);
- if (cc < 2 * sizeof (uint32_t))
+ }
+ if (cc < 2 * sizeof (uint32_t)) {
+ free(pkt);
return (EBADRPC);
- if (repl->errno != 0)
+ }
+ if (repl->errno != 0) {
+ free(pkt);
return (ntohl(repl->errno));
+ }
*fhlenp = ntohl(repl->fhsize);
bcopy(repl->fh, fhp, *fhlenp);
set_nfs_read_size();
+ free(pkt);
return (0);
}
@@ -245,6 +248,7 @@ nfs_getrootfh(struct iodesc *d, char *path, uint32_t *fhlenp, u_char *fhp)
int
nfs_lookupfh(struct nfs_iodesc *d, const char *name, struct nfs_iodesc *newfd)
{
+ void *pkt = NULL;
int len, rlen, pos;
struct args {
uint32_t fhsize;
@@ -262,10 +266,6 @@ nfs_lookupfh(struct nfs_iodesc *d, const char *name, struct nfs_iodesc *newfd)
uint32_t h[RPC_HEADER_WORDS];
struct args d;
} sdata;
- struct {
- uint32_t h[RPC_HEADER_WORDS];
- struct repl d;
- } rdata;
ssize_t cc;
#ifdef NFS_DEBUG
@@ -274,7 +274,6 @@ nfs_lookupfh(struct nfs_iodesc *d, const char *name, struct nfs_iodesc *newfd)
#endif
args = &sdata.d;
- repl = &rdata.d;
bzero(args, sizeof(*args));
args->fhsize = htonl(d->fhsize);
@@ -288,33 +287,40 @@ nfs_lookupfh(struct nfs_iodesc *d, const char *name, struct nfs_iodesc *newfd)
len = sizeof(uint32_t) + pos * sizeof(uint32_t) +
roundup(len, sizeof(uint32_t));
- rlen = sizeof(*repl);
-
cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_LOOKUP,
- args, len, repl, rlen);
- if (cc == -1)
+ args, len, (void **)&repl, &pkt);
+ if (cc == -1) {
+ free(pkt);
return (errno); /* XXX - from rpc_call */
- if (cc < 2 * sizeof(uint32_t))
+ }
+ if (cc < 2 * sizeof(uint32_t)) {
+ free(pkt);
return (EIO);
- if (repl->errno != 0)
+ }
+ if (repl->errno != 0) {
+ free(pkt);
/* saerrno.h now matches NFS error numbers. */
return (ntohl(repl->errno));
+ }
newfd->fhsize = ntohl(repl->fhsize);
bcopy(repl->fhplusattr, &newfd->fh, newfd->fhsize);
pos = roundup(newfd->fhsize, sizeof(uint32_t)) / sizeof(uint32_t);
- if (repl->fhplusattr[pos++] == 0)
+ if (repl->fhplusattr[pos++] == 0) {
+ free(pkt);
return (EIO);
+ }
bcopy(&repl->fhplusattr[pos], &newfd->fa, sizeof(newfd->fa));
+ free(pkt);
return (0);
}
-#ifndef NFS_NOSYMLINK
/*
* Get the destination of a symbolic link.
*/
int
nfs_readlink(struct nfs_iodesc *d, char *buf)
{
+ void *pkt = NULL;
struct args {
uint32_t fhsize;
u_char fh[NFS_V3MAXFHSIZE];
@@ -330,11 +336,8 @@ nfs_readlink(struct nfs_iodesc *d, char *buf)
uint32_t h[RPC_HEADER_WORDS];
struct args d;
} sdata;
- struct {
- uint32_t h[RPC_HEADER_WORDS];
- struct repl d;
- } rdata;
ssize_t cc;
+ int rc = 0;
#ifdef NFS_DEBUG
if (debug)
@@ -342,35 +345,43 @@ nfs_readlink(struct nfs_iodesc *d, char *buf)
#endif
args = &sdata.d;
- repl = &rdata.d;
bzero(args, sizeof(*args));
args->fhsize = htonl(d->fhsize);
bcopy(d->fh, args->fh, d->fhsize);
cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READLINK,
args, sizeof(uint32_t) + roundup(d->fhsize, sizeof(uint32_t)),
- repl, sizeof(*repl));
+ (void **)&repl, &pkt);
if (cc == -1)
return (errno);
- if (cc < 2 * sizeof(uint32_t))
- return (EIO);
+ if (cc < 2 * sizeof(uint32_t)) {
+ rc = EIO;
+ goto done;
+ }
- if (repl->errno != 0)
- return (ntohl(repl->errno));
+ if (repl->errno != 0) {
+ rc = ntohl(repl->errno);
+ goto done;
+ }
- if (repl->ok == 0)
- return (EIO);
+ if (repl->ok == 0) {
+ rc = EIO;
+ goto done;
+ }
repl->len = ntohl(repl->len);
- if (repl->len > NFS_MAXPATHLEN)
- return (ENAMETOOLONG);
+ if (repl->len > NFS_MAXPATHLEN) {
+ rc = ENAMETOOLONG;
+ goto done;
+ }
bcopy(repl->path, buf, repl->len);
buf[repl->len] = 0;
- return (0);
+done:
+ free(pkt);
+ return (rc);
}
-#endif
/*
* Read data from a file.
@@ -379,6 +390,7 @@ nfs_readlink(struct nfs_iodesc *d, char *buf)
ssize_t
nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len)
{
+ void *pkt = NULL;
struct args {
uint32_t fhsize;
uint32_t fhoffcnt[NFS_V3MAXFHSIZE / sizeof(uint32_t) + 3];
@@ -396,16 +408,11 @@ nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len)
uint32_t h[RPC_HEADER_WORDS];
struct args d;
} sdata;
- struct {
- uint32_t h[RPC_HEADER_WORDS];
- struct repl d;
- } rdata;
size_t cc;
long x;
int hlen, rlen, pos;
args = &sdata.d;
- repl = &rdata.d;
bzero(args, sizeof(*args));
args->fhsize = htonl(d->fhsize);
@@ -420,16 +427,19 @@ nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len)
cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READ,
args, 4 * sizeof(uint32_t) + roundup(d->fhsize, sizeof(uint32_t)),
- repl, sizeof(*repl));
- if (cc == -1)
+ (void **)&repl, &pkt);
+ if (cc == -1) {
/* errno was already set by rpc_call */
return (-1);
+ }
if (cc < hlen) {
errno = EBADRPC;
+ free(pkt);
return (-1);
}
if (repl->errno != 0) {
errno = ntohl(repl->errno);
+ free(pkt);
return (-1);
}
rlen = cc - hlen;
@@ -437,9 +447,11 @@ nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len)
if (rlen < x) {
printf("nfsread: short packet, %d < %ld\n", rlen, x);
errno = EBADRPC;
+ free(pkt);
return (-1);
}
bcopy(repl->data, addr, x);
+ free(pkt);
return (x);
}
@@ -456,7 +468,6 @@ nfs_open(const char *upath, struct open_file *f)
u_char *fh;
char *cp;
int i;
-#ifndef NFS_NOSYMLINK
struct nfs_iodesc *newfd;
struct nfsv3_fattrs *fa;
char *ncp;
@@ -464,7 +475,6 @@ nfs_open(const char *upath, struct open_file *f)
char namebuf[NFS_MAXPATHLEN + 1];
char linkbuf[NFS_MAXPATHLEN + 1];
int nlinks = 0;
-#endif
int error;
char *path;
@@ -480,17 +490,8 @@ nfs_open(const char *upath, struct open_file *f)
return (ENXIO);
}
- /*
- * This is silly - we should look at dv_type but that value is
- * arch dependant and we can't use it here.
- */
-#ifndef __i386__
- if (strcmp(f->f_dev->dv_name, "net") != 0)
- return (EINVAL);
-#else
- if (strcmp(f->f_dev->dv_name, "pxe") != 0)
+ if (f->f_dev->dv_type != DEVT_NET)
return (EINVAL);
-#endif
if (!(desc = socktodesc(*(int *)(f->f_devdata))))
return (EINVAL);
@@ -524,7 +525,6 @@ nfs_open(const char *upath, struct open_file *f)
error = ENOMEM;
goto out;
}
-#ifndef NFS_NOSYMLINK
bcopy(&nfs_root_node, currfd, sizeof(*currfd));
newfd = NULL;
@@ -627,11 +627,6 @@ nfs_open(const char *upath, struct open_file *f)
out:
free(newfd);
free(path);
-#else
- currfd->iodesc = desc;
-
- error = nfs_lookupfh(&nfs_root_node, upath, currfd);
-#endif
if (!error) {
currfd->off = 0;
currfd->cookie = 0;
@@ -659,9 +654,8 @@ nfs_close(struct open_file *f)
printf("nfs_close: fp=0x%lx\n", (u_long)fp);
#endif
- if (fp)
- free(fp);
- f->f_fsdata = (void *)0;
+ free(fp);
+ f->f_fsdata = NULL;
return (0);
}
@@ -772,11 +766,12 @@ nfs_readdir(struct open_file *f, struct dirent *d)
struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata;
struct nfsv3_readdir_repl *repl;
struct nfsv3_readdir_entry *rent;
+ static void *pkt = NULL;
static char *buf;
static struct nfs_iodesc *pfp = NULL;
static uint64_t cookie = 0;
size_t cc;
- int pos;
+ int pos, rc;
struct args {
uint32_t fhsize;
@@ -786,14 +781,12 @@ nfs_readdir(struct open_file *f, struct dirent *d)
uint32_t h[RPC_HEADER_WORDS];
struct args d;
} sdata;
- static struct {
- uint32_t h[RPC_HEADER_WORDS];
- u_char d[NFS_READDIRSIZE];
- } rdata;
if (fp != pfp || fp->off != cookie) {
pfp = NULL;
refill:
+ free(pkt);
+ pkt = NULL;
args = &sdata.d;
bzero(args, sizeof(*args));
@@ -809,11 +802,16 @@ nfs_readdir(struct open_file *f, struct dirent *d)
cc = rpc_call(fp->iodesc, NFS_PROG, NFS_VER3, NFSPROCV3_READDIR,
args, 6 * sizeof(uint32_t) +
roundup(fp->fhsize, sizeof(uint32_t)),
- rdata.d, sizeof(rdata.d));
- buf = rdata.d;
+ (void **)&buf, &pkt);
+ if (cc == -1) {
+ rc = errno;
+ goto err;
+ }
repl = (struct nfsv3_readdir_repl *)buf;
- if (repl->errno != 0)
- return (ntohl(repl->errno));
+ if (repl->errno != 0) {
+ rc = ntohl(repl->errno);
+ goto err;
+ }
pfp = fp;
cookie = fp->off;
fp->cookie = ((uint64_t)ntohl(repl->cookiev0) << 32) |
@@ -825,8 +823,8 @@ nfs_readdir(struct open_file *f, struct dirent *d)
if (rent->follows == 0) {
/* fid0 is actually eof */
if (rent->fid0 != 0) {
- cookie = 0;
- return (ENOENT);
+ rc = ENOENT;
+ goto err;
}
goto refill;
}
@@ -841,4 +839,11 @@ nfs_readdir(struct open_file *f, struct dirent *d)
pos += 2;
buf = (u_char *)&rent->nameplus[pos];
return (0);
+
+err:
+ free(pkt);
+ pkt = NULL;
+ pfp = NULL;
+ cookie = 0;
+ return (rc);
}
diff --git a/usr/src/boot/lib/libstand/rarp.c b/usr/src/boot/lib/libstand/rarp.c
index 07ec1ccd4c..120b2c377f 100644
--- a/usr/src/boot/lib/libstand/rarp.c
+++ b/usr/src/boot/lib/libstand/rarp.c
@@ -36,7 +36,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/socket.h>
@@ -54,17 +53,17 @@ __FBSDID("$FreeBSD$");
static ssize_t rarpsend(struct iodesc *, void *, size_t);
-static ssize_t rarprecv(struct iodesc *, void *, size_t, time_t);
+static ssize_t rarprecv(struct iodesc *, void **, void **, time_t);
/*
* Ethernet (Reverse) Address Resolution Protocol (see RFC 903, and 826).
*/
int
-rarp_getipaddress(sock)
- int sock;
+rarp_getipaddress(int sock)
{
struct iodesc *d;
struct ether_arp *ap;
+ void *pkt;
struct {
u_char header[ETHER_SIZE];
struct {
@@ -72,13 +71,6 @@ rarp_getipaddress(sock)
u_char pad[18]; /* 60 - sizeof(arp) */
} data;
} wbuf;
- struct {
- u_char header[ETHER_SIZE];
- struct {
- struct ether_arp arp;
- u_char pad[24]; /* extra space */
- } data;
- } rbuf;
#ifdef RARP_DEBUG
if (debug)
@@ -102,21 +94,21 @@ rarp_getipaddress(sock)
ap->arp_op = htons(ARPOP_REVREQUEST);
bcopy(d->myea, ap->arp_sha, 6);
bcopy(d->myea, ap->arp_tha, 6);
+ pkt = NULL;
if (sendrecv(d,
rarpsend, &wbuf.data, sizeof(wbuf.data),
- rarprecv, &rbuf.data, sizeof(rbuf.data)) < 0)
- {
+ rarprecv, &pkt, (void *)&ap) < 0) {
printf("No response for RARP request\n");
return (-1);
}
- ap = &rbuf.data.arp;
bcopy(ap->arp_tpa, (char *)&myip, sizeof(myip));
#if 0
/* XXX - Can NOT assume this is our root server! */
bcopy(ap->arp_spa, (char *)&rootip, sizeof(rootip));
#endif
+ free(pkt);
/* Compute our "natural" netmask. */
if (IN_CLASSA(myip.s_addr))
@@ -134,10 +126,7 @@ rarp_getipaddress(sock)
* Broadcast a RARP request (i.e. who knows who I am)
*/
static ssize_t
-rarpsend(d, pkt, len)
- struct iodesc *d;
- void *pkt;
- size_t len;
+rarpsend(struct iodesc *d, void *pkt, size_t len)
{
#ifdef RARP_DEBUG
@@ -153,28 +142,26 @@ rarpsend(d, pkt, len)
* else -1 (and errno == 0)
*/
static ssize_t
-rarprecv(d, pkt, len, tleft)
- struct iodesc *d;
- void *pkt;
- size_t len;
- time_t tleft;
+rarprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft)
{
ssize_t n;
struct ether_arp *ap;
- u_int16_t etype; /* host order */
+ void *ptr = NULL;
+ uint16_t etype; /* host order */
#ifdef RARP_DEBUG
if (debug)
printf("rarprecv: ");
#endif
- n = readether(d, pkt, len, tleft, &etype);
+ n = readether(d, &ptr, (void **)&ap, tleft, &etype);
errno = 0; /* XXX */
if (n == -1 || n < sizeof(struct ether_arp)) {
#ifdef RARP_DEBUG
if (debug)
printf("bad len=%d\n", n);
#endif
+ free(ptr);
return (-1);
}
@@ -183,10 +170,10 @@ rarprecv(d, pkt, len, tleft)
if (debug)
printf("bad type=0x%x\n", etype);
#endif
+ free(ptr);
return (-1);
}
- ap = (struct ether_arp *)pkt;
if (ap->arp_hrd != htons(ARPHRD_ETHER) ||
ap->arp_pro != htons(ETHERTYPE_IP) ||
ap->arp_hln != sizeof(ap->arp_sha) ||
@@ -196,6 +183,7 @@ rarprecv(d, pkt, len, tleft)
if (debug)
printf("bad hrd/pro/hln/pln\n");
#endif
+ free(ptr);
return (-1);
}
@@ -204,6 +192,7 @@ rarprecv(d, pkt, len, tleft)
if (debug)
printf("bad op=0x%x\n", ntohs(ap->arp_op));
#endif
+ free(ptr);
return (-1);
}
@@ -213,6 +202,7 @@ rarprecv(d, pkt, len, tleft)
if (debug)
printf("unwanted address\n");
#endif
+ free(ptr);
return (-1);
}
@@ -221,5 +211,7 @@ rarprecv(d, pkt, len, tleft)
if (debug)
printf("got it\n");
#endif
+ *pkt = ptr;
+ *payload = ap;
return (n);
}
diff --git a/usr/src/boot/lib/libstand/rpc.c b/usr/src/boot/lib/libstand/rpc.c
index ee155f6ee0..0923739441 100644
--- a/usr/src/boot/lib/libstand/rpc.c
+++ b/usr/src/boot/lib/libstand/rpc.c
@@ -36,7 +36,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
/*
* RPC functions used by NFS and bootparams.
@@ -97,7 +96,7 @@ struct rpc_reply {
};
/* Local forwards */
-static ssize_t recvrpc(struct iodesc *, void *, size_t, time_t);
+static ssize_t recvrpc(struct iodesc *, void **, void **, time_t);
static int rpc_getport(struct iodesc *, n_long, n_long);
int rpc_xid;
@@ -109,14 +108,14 @@ int rpc_port = 0x400; /* predecrement */
*/
ssize_t
rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc,
- void *sdata, size_t slen, void *rdata, size_t rlen)
+ void *sdata, size_t slen, void **rdata, void **pkt)
{
- ssize_t cc;
+ ssize_t cc, rsize;
struct auth_info *auth;
struct rpc_call *call;
struct rpc_reply *reply;
char *send_head, *send_tail;
- char *recv_head, *recv_tail;
+ void *ptr;
n_long x;
int port; /* host order */
@@ -145,7 +144,6 @@ rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc,
auth->authtype = htonl(RPCAUTH_NULL);
auth->authlen = 0;
-#if 1
/* Auth credentials: always auth unix (as root) */
send_head -= sizeof(struct auth_unix);
bzero(send_head, sizeof(struct auth_unix));
@@ -153,13 +151,6 @@ rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc,
auth = (struct auth_info *)send_head;
auth->authtype = htonl(RPCAUTH_UNIX);
auth->authlen = htonl(sizeof(struct auth_unix));
-#else
- /* Auth credentials: always auth_null (XXX OK?) */
- send_head -= sizeof(*auth);
- auth = send_head;
- auth->authtype = htonl(RPCAUTH_NULL);
- auth->authlen = 0;
-#endif
/* RPC call structure. */
send_head -= sizeof(*call);
@@ -172,34 +163,28 @@ rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc,
call->rp_vers = htonl(vers);
call->rp_proc = htonl(proc);
- /* Make room for the rpc_reply header. */
- recv_head = rdata;
- recv_tail = (char *)rdata + rlen;
- recv_head -= sizeof(*reply);
-
+ ptr = NULL;
cc = sendrecv(d,
sendudp, send_head, send_tail - send_head,
- recvrpc, recv_head, recv_tail - recv_head);
+ recvrpc, &ptr, (void **)&reply);
#ifdef RPC_DEBUG
if (debug)
- printf("callrpc: cc=%ld rlen=%lu\n", (long)cc, (u_long)rlen);
+ printf("callrpc: cc=%zd\n", cc);
#endif
if (cc == -1)
return (-1);
if (cc <= sizeof(*reply)) {
errno = EBADRPC;
+ free(ptr);
return (-1);
}
- recv_tail = recv_head + cc;
-
/*
* Check the RPC reply status.
* The xid, dir, astatus were already checked.
*/
- reply = (struct rpc_reply *)recv_head;
auth = &reply->rp_u.rpu_rok.rok_auth;
x = ntohl(auth->authlen);
if (x != 0) {
@@ -208,17 +193,21 @@ rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc,
printf("callrpc: reply auth != NULL\n");
#endif
errno = EBADRPC;
- return(-1);
+ free(ptr);
+ return (-1);
}
x = ntohl(reply->rp_u.rpu_rok.rok_status);
if (x != 0) {
printf("callrpc: error = %ld\n", (long)x);
errno = EBADRPC;
- return(-1);
+ free(ptr);
+ return (-1);
}
- recv_head += sizeof(*reply);
- return (ssize_t)(recv_tail - recv_head);
+ rsize = cc - sizeof(*reply);
+ *rdata = (void *)((uintptr_t)reply + sizeof(*reply));
+ *pkt = ptr;
+ return (rsize);
}
/*
@@ -227,8 +216,9 @@ rpc_call(struct iodesc *d, n_long prog, n_long vers, n_long proc,
* Remaining checks are done by callrpc
*/
static ssize_t
-recvrpc(struct iodesc *d, void *pkt, size_t len, time_t tleft)
+recvrpc(struct iodesc *d, void **pkt, void **payload, time_t tleft)
{
+ void *ptr;
struct rpc_reply *reply;
ssize_t n;
int x;
@@ -236,14 +226,15 @@ recvrpc(struct iodesc *d, void *pkt, size_t len, time_t tleft)
errno = 0;
#ifdef RPC_DEBUG
if (debug)
- printf("recvrpc: called len=%lu\n", (u_long)len);
+ printf("recvrpc: called\n");
#endif
- n = readudp(d, pkt, len, tleft);
- if (n <= (4 * 4))
- return -1;
-
- reply = (struct rpc_reply *)pkt;
+ ptr = NULL;
+ n = readudp(d, &ptr, (void **)&reply, tleft);
+ if (n <= (4 * 4)) {
+ free(ptr);
+ return (-1);
+ }
x = ntohl(reply->rp_xid);
if (x != rpc_xid) {
@@ -251,7 +242,8 @@ recvrpc(struct iodesc *d, void *pkt, size_t len, time_t tleft)
if (debug)
printf("recvrpc: rp_xid %d != xid %d\n", x, rpc_xid);
#endif
- return -1;
+ free(ptr);
+ return (-1);
}
x = ntohl(reply->rp_direction);
@@ -260,16 +252,20 @@ recvrpc(struct iodesc *d, void *pkt, size_t len, time_t tleft)
if (debug)
printf("recvrpc: rp_direction %d != REPLY\n", x);
#endif
- return -1;
+ free(ptr);
+ return (-1);
}
x = ntohl(reply->rp_astatus);
if (x != RPC_MSGACCEPTED) {
errno = ntohl(reply->rp_u.rpu_errno);
printf("recvrpc: reject, astat=%d, errno=%d\n", x, errno);
- return -1;
+ free(ptr);
+ return (-1);
}
+ *pkt = ptr;
+ *payload = reply;
/* Return data count (thus indicating success) */
return (n);
}
@@ -387,11 +383,7 @@ rpc_getport(struct iodesc *d, n_long prog, n_long vers)
n_long h[RPC_HEADER_WORDS];
struct args d;
} sdata;
- struct {
- n_long h[RPC_HEADER_WORDS];
- struct res d;
- n_long pad;
- } rdata;
+ void *pkt;
ssize_t cc;
int port;
@@ -416,16 +408,18 @@ rpc_getport(struct iodesc *d, n_long prog, n_long vers)
args->vers = htonl(vers);
args->proto = htonl(IPPROTO_UDP);
args->port = 0;
- res = &rdata.d;
+ pkt = NULL;
cc = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_GETPORT,
- args, sizeof(*args), res, sizeof(*res));
+ args, sizeof(*args), (void **)&res, &pkt);
if (cc < sizeof(*res)) {
printf("getport: %s", strerror(errno));
errno = EBADRPC;
+ free(pkt);
return (-1);
}
port = (int)ntohl(res->port);
+ free(pkt);
rpc_pmap_putcache(d->destip, prog, vers, port);
diff --git a/usr/src/boot/lib/libstand/rpc.h b/usr/src/boot/lib/libstand/rpc.h
index e06ce41692..6dda060482 100644
--- a/usr/src/boot/lib/libstand/rpc.h
+++ b/usr/src/boot/lib/libstand/rpc.h
@@ -48,7 +48,7 @@
/* RPC functions: */
ssize_t rpc_call(struct iodesc *, n_long, n_long, n_long,
- void *, size_t, void *, size_t);
+ void *, size_t, void **, void **);
void rpc_fromaddr(void *, struct in_addr *, u_short *);
int rpc_pmap_getcache(struct in_addr, u_int, u_int);
void rpc_pmap_putcache(struct in_addr, u_int, u_int, int);
diff --git a/usr/src/boot/lib/libstand/tftp.c b/usr/src/boot/lib/libstand/tftp.c
index b3d2da7b0e..36ced27a20 100644
--- a/usr/src/boot/lib/libstand/tftp.c
+++ b/usr/src/boot/lib/libstand/tftp.c
@@ -32,7 +32,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
/*
* Simple TFTP implementation for libsa.
@@ -73,8 +72,8 @@ static int tftp_stat(struct open_file *f, struct stat *sb);
static ssize_t sendrecv_tftp(struct tftp_handle *h,
ssize_t (*sproc)(struct iodesc *, void *, size_t),
void *sbuf, size_t ssize,
- ssize_t (*rproc)(struct tftp_handle *h, void *, ssize_t, time_t, unsigned short *),
- void *rbuf, size_t rsize, unsigned short *rtype);
+ ssize_t (*rproc)(struct tftp_handle *h, void **, void **, time_t, unsigned short *),
+ void **, void **, unsigned short *rtype);
struct fs_ops tftp_fsops = {
"tftp",
@@ -114,11 +113,8 @@ struct tftp_handle {
char *path; /* saved for re-requests */
unsigned int tftp_blksize;
unsigned long tftp_tsize;
- struct {
- u_char header[HEADER_SIZE];
- struct tftphdr t;
- u_char space[TFTP_MAX_BLKSIZE];
- } __packed __aligned(4) lastdata;
+ void *pkt;
+ struct tftphdr *tftp_hdr;
};
#define TFTP_MAX_ERRCODE EOPTNEG
@@ -181,20 +177,23 @@ tftp_sendack(struct tftp_handle *h)
}
static ssize_t
-recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft,
+recvtftp(struct tftp_handle *h, void **pkt, void **payload, time_t tleft,
unsigned short *rtype)
{
struct iodesc *d = h->iodesc;
struct tftphdr *t;
+ void *ptr = NULL;
+ ssize_t len;
errno = 0;
- len = readudp(d, pkt, len, tleft);
+ len = readudp(d, &ptr, (void **)&t, tleft);
- if (len < 4)
+ if (len < 4) {
+ free(ptr);
return (-1);
+ }
- t = (struct tftphdr *) pkt;
*rtype = ntohs(t->th_opcode);
switch (ntohs(t->th_opcode)) {
case DATA: {
@@ -204,6 +203,7 @@ recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft,
/*
* Expected block?
*/
+ free(ptr);
return (-1);
}
if (d->xid == 1) {
@@ -211,11 +211,13 @@ recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft,
* First data packet from new port.
*/
struct udphdr *uh;
- uh = (struct udphdr *) pkt - 1;
+ uh = (struct udphdr *) t - 1;
d->destport = uh->uh_sport;
} /* else check uh_sport has not changed??? */
- got = len - (t->th_data - (char *) t);
- return got;
+ got = len - (t->th_data - (char *)t);
+ *pkt = ptr;
+ *payload = t;
+ return (got);
}
case ERROR:
if ((unsigned) ntohs(t->th_code) > TFTP_MAX_ERRCODE) {
@@ -227,6 +229,7 @@ recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft,
#endif
errno = tftperrors[ntohs(t->th_code)];
}
+ free(ptr);
return (-1);
case OACK: {
struct udphdr *uh;
@@ -237,6 +240,7 @@ recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft,
* Drop the pkt.
*/
if (d->xid != 1) {
+ free(ptr);
return (-1);
}
@@ -244,7 +248,7 @@ recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft,
* Remember which port this OACK came from, because we need
* to send the ACK or errors back to it.
*/
- uh = (struct udphdr *) pkt - 1;
+ uh = (struct udphdr *) t - 1;
d->destport = uh->uh_sport;
/* Parse options ACK-ed by the server. */
@@ -252,14 +256,18 @@ recvtftp(struct tftp_handle *h, void *pkt, ssize_t len, time_t tleft,
if (tftp_parse_oack(h, t->th_u.tu_stuff, tftp_oack_len) != 0) {
tftp_senderr(h, EOPTNEG, "Malformed OACK");
errno = EIO;
+ free(ptr);
return (-1);
}
+ *pkt = ptr;
+ *payload = t;
return (0);
}
default:
#ifdef TFTP_DEBUG
printf("tftp type %d not handled\n", ntohs(t->th_opcode));
#endif
+ free(ptr);
return (-1);
}
}
@@ -276,6 +284,7 @@ tftp_makereq(struct tftp_handle *h)
char *wtail;
int l;
ssize_t res;
+ void *pkt;
struct tftphdr *t;
char *tftp_blksize = NULL;
int blksize_l;
@@ -314,8 +323,6 @@ tftp_makereq(struct tftp_handle *h)
bcopy("0", wtail, 2);
wtail += 2;
- t = &h->lastdata.t;
-
/* h->iodesc->myport = htons(--tftpport); */
h->iodesc->myport = htons(tftpport + (getsecs() & 0x3ff));
h->iodesc->destport = htons(IPPORT_TFTP);
@@ -325,8 +332,17 @@ tftp_makereq(struct tftp_handle *h)
h->islastblock = 0;
h->validsize = 0;
+ pkt = NULL;
res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
- &recvtftp, t, sizeof(*t) + h->tftp_blksize, &rtype);
+ &recvtftp, &pkt, (void **)&t, &rtype);
+ if (res == -1) {
+ free(pkt);
+ return (errno);
+ }
+
+ free(h->pkt);
+ h->pkt = pkt;
+ h->tftp_hdr = t;
if (rtype == OACK)
return (tftp_getnextblock(h));
@@ -362,6 +378,7 @@ tftp_getnextblock(struct tftp_handle *h)
} __packed __aligned(4) wbuf;
char *wtail;
int res;
+ void *pkt;
struct tftphdr *t;
unsigned short rtype = 0;
wbuf.t.th_opcode = htons((u_short) ACK);
@@ -369,16 +386,20 @@ tftp_getnextblock(struct tftp_handle *h)
wbuf.t.th_block = htons((u_short) h->currblock);
wtail += 2;
- t = &h->lastdata.t;
-
h->iodesc->xid = h->currblock + 1; /* expected block */
+ pkt = NULL;
res = sendrecv_tftp(h, &sendudp, &wbuf.t, wtail - (char *) &wbuf.t,
- &recvtftp, t, sizeof(*t) + h->tftp_blksize, &rtype);
+ &recvtftp, &pkt, (void **)&t, &rtype);
- if (res == -1) /* 0 is OK! */
+ if (res == -1) { /* 0 is OK! */
+ free(pkt);
return (errno);
+ }
+ free(h->pkt);
+ h->pkt = pkt;
+ h->tftp_hdr = t;
h->currblock++;
h->validsize = res;
if (res < h->tftp_blksize)
@@ -405,14 +426,8 @@ tftp_open(const char *path, struct open_file *f)
if (netproto != NET_TFTP)
return (EINVAL);
- if (strcmp(f->f_dev->dv_name, "net") != 0) {
-#ifdef __i386__
- if (strcmp(f->f_dev->dv_name, "pxe") != 0)
- return (EINVAL);
-#else
+ if (f->f_dev->dv_type != DEVT_NET)
return (EINVAL);
-#endif
- }
if (is_open)
return (EBUSY);
@@ -451,6 +466,7 @@ tftp_open(const char *path, struct open_file *f)
if (res) {
free(tftpfile->path);
+ free(tftpfile->pkt);
free(tftpfile);
return (res);
}
@@ -507,7 +523,7 @@ tftp_read(struct open_file *f, void *addr, size_t size,
return (EINVAL);
}
count = (size < inbuffer ? size : inbuffer);
- bcopy(tftpfile->lastdata.t.th_data + offinblock,
+ bcopy(tftpfile->tftp_hdr->th_data + offinblock,
addr, count);
addr = (char *)addr + count;
@@ -540,6 +556,7 @@ tftp_close(struct open_file *f)
if (tftpfile) {
free(tftpfile->path);
+ free(tftpfile->pkt);
free(tftpfile);
}
is_open = 0;
@@ -591,8 +608,9 @@ static ssize_t
sendrecv_tftp(struct tftp_handle *h,
ssize_t (*sproc)(struct iodesc *, void *, size_t),
void *sbuf, size_t ssize,
- ssize_t (*rproc)(struct tftp_handle *, void *, ssize_t, time_t, unsigned short *),
- void *rbuf, size_t rsize, unsigned short *rtype)
+ ssize_t (*rproc)(struct tftp_handle *, void **, void **, time_t,
+ unsigned short *),
+ void **pkt, void **payload, unsigned short *rtype)
{
struct iodesc *d = h->iodesc;
ssize_t cc;
@@ -624,7 +642,7 @@ sendrecv_tftp(struct tftp_handle *h,
recvnext:
/* Try to get a packet and process it. */
- cc = (*rproc)(h, rbuf, rsize, tleft, rtype);
+ cc = (*rproc)(h, pkt, payload, tleft, rtype);
/* Return on data, EOF or real error. */
if (cc != -1 || errno != 0)
return (cc);
diff --git a/usr/src/boot/lib/libstand/udp.c b/usr/src/boot/lib/libstand/udp.c
index d41be902a3..2883a1751e 100644
--- a/usr/src/boot/lib/libstand/udp.c
+++ b/usr/src/boot/lib/libstand/udp.c
@@ -36,7 +36,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/socket.h>
@@ -59,10 +58,7 @@ __FBSDID("$FreeBSD$");
/* Caller must leave room for ethernet, ip and udp headers in front!! */
ssize_t
-sendudp(d, pkt, len)
- struct iodesc *d;
- void *pkt;
- size_t len;
+sendudp(struct iodesc *d, void *pkt, size_t len)
{
ssize_t cc;
struct ip *ip;
@@ -131,32 +127,29 @@ sendudp(d, pkt, len)
/*
* Receive a UDP packet and validate it is for us.
- * Caller leaves room for the headers (Ether, IP, UDP)
*/
ssize_t
-readudp(d, pkt, len, tleft)
- struct iodesc *d;
- void *pkt;
- size_t len;
- time_t tleft;
+readudp(struct iodesc *d, void **pkt, void **payload, time_t tleft)
{
ssize_t n;
size_t hlen;
struct ip *ip;
struct udphdr *uh;
- u_int16_t etype; /* host order */
+ uint16_t etype; /* host order */
+ void *ptr;
#ifdef NET_DEBUG
if (debug)
printf("readudp: called\n");
#endif
- uh = (struct udphdr *)pkt - 1;
- ip = (struct ip *)uh - 1;
-
- n = readether(d, ip, len + sizeof(*ip) + sizeof(*uh), tleft, &etype);
- if (n == -1 || n < sizeof(*ip) + sizeof(*uh))
- return -1;
+ ip = NULL;
+ ptr = NULL;
+ n = readether(d, &ptr, (void **)&ip, tleft, &etype);
+ if (n == -1 || n < sizeof(*ip) + sizeof(*uh)) {
+ free(ptr);
+ return (-1);
+ }
/* Ethernet address checks now in readether() */
@@ -167,7 +160,8 @@ readudp(d, pkt, len, tleft)
/* Send ARP reply */
arp_reply(d, ah);
}
- return -1;
+ free(ptr);
+ return (-1);
}
if (etype != ETHERTYPE_IP) {
@@ -175,7 +169,8 @@ readudp(d, pkt, len, tleft)
if (debug)
printf("readudp: not IP. ether_type=%x\n", etype);
#endif
- return -1;
+ free(ptr);
+ return (-1);
}
/* Check ip header */
@@ -185,7 +180,8 @@ readudp(d, pkt, len, tleft)
if (debug)
printf("readudp: IP version or not UDP. ip_v=%d ip_p=%d\n", ip->ip_v, ip->ip_p);
#endif
- return -1;
+ free(ptr);
+ return (-1);
}
hlen = ip->ip_hl << 2;
@@ -195,7 +191,8 @@ readudp(d, pkt, len, tleft)
if (debug)
printf("readudp: short hdr or bad cksum.\n");
#endif
- return -1;
+ free(ptr);
+ return (-1);
}
if (n < ntohs(ip->ip_len)) {
#ifdef NET_DEBUG
@@ -203,7 +200,8 @@ readudp(d, pkt, len, tleft)
printf("readudp: bad length %d < %d.\n",
(int)n, ntohs(ip->ip_len));
#endif
- return -1;
+ free(ptr);
+ return (-1);
}
if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) {
#ifdef NET_DEBUG
@@ -212,12 +210,14 @@ readudp(d, pkt, len, tleft)
printf("%s\n", inet_ntoa(ip->ip_dst));
}
#endif
- return -1;
+ free(ptr);
+ return (-1);
}
+ uh = (struct udphdr *)((uintptr_t)ip + sizeof (*ip));
/* If there were ip options, make them go away */
if (hlen != sizeof(*ip)) {
- bcopy(((u_char *)ip) + hlen, uh, len - hlen);
+ bcopy(((u_char *)ip) + hlen, uh, uh->uh_ulen - hlen);
ip->ip_len = htons(sizeof(*ip));
n -= hlen - sizeof(*ip);
}
@@ -227,7 +227,8 @@ readudp(d, pkt, len, tleft)
printf("readudp: bad dport %d != %d\n",
d->myport, ntohs(uh->uh_dport));
#endif
- return -1;
+ free(ptr);
+ return (-1);
}
#ifndef UDP_NO_CKSUM
@@ -238,7 +239,8 @@ readudp(d, pkt, len, tleft)
n = ntohs(uh->uh_ulen) + sizeof(*ip);
if (n > RECV_SIZE - ETHER_SIZE) {
printf("readudp: huge packet, udp len %d\n", (int)n);
- return -1;
+ free(ptr);
+ return (-1);
}
/* Check checksum (must save and restore ip header) */
@@ -251,8 +253,8 @@ readudp(d, pkt, len, tleft)
if (debug)
printf("readudp: bad cksum\n");
#endif
- *ip = tip;
- return -1;
+ free(ptr);
+ return (-1);
}
*ip = tip;
}
@@ -263,10 +265,13 @@ readudp(d, pkt, len, tleft)
printf("readudp: bad udp len %d < %d\n",
ntohs(uh->uh_ulen), (int)sizeof(*uh));
#endif
- return -1;
+ free(ptr);
+ return (-1);
}
n = (n > (ntohs(uh->uh_ulen) - sizeof(*uh))) ?
ntohs(uh->uh_ulen) - sizeof(*uh) : n;
+ *pkt = ptr;
+ *payload = (void *)((uintptr_t)uh + sizeof(*uh));
return (n);
}
diff --git a/usr/src/boot/sys/boot/common/dev_net.c b/usr/src/boot/sys/boot/common/dev_net.c
index 6321db7c5b..bf8b0f3d96 100644
--- a/usr/src/boot/sys/boot/common/dev_net.c
+++ b/usr/src/boot/sys/boot/common/dev_net.c
@@ -57,6 +57,7 @@
#include <netinet/in_systm.h>
#include <stand.h>
+#include <stddef.h>
#include <string.h>
#include <net.h>
#include <netif.h>
@@ -244,6 +245,8 @@ net_getparams(int sock)
{
char buf[MAXHOSTNAMELEN];
n_long rootaddr, smask;
+ struct iodesc *d = socktodesc(sock);
+ extern struct in_addr servip;
#ifdef SUPPORT_BOOTP
/*
@@ -252,8 +255,26 @@ net_getparams(int sock)
* be initialized. If any remain uninitialized, we will
* use RARP and RPC/bootparam (the Sun way) to get them.
*/
- if (try_bootp)
- bootp(sock, BOOTP_NONE);
+ if (try_bootp) {
+ int rc = -1;
+ if (bootp_response != NULL) {
+ rc = dhcp_try_rfc1048(bootp_response->bp_vend,
+ bootp_response_size -
+ offsetof(struct bootp, bp_vend));
+
+ if (servip.s_addr == 0)
+ servip = bootp_response->bp_siaddr;
+ if (rootip.s_addr == 0)
+ rootip = bootp_response->bp_siaddr;
+ if (gateip.s_addr == 0)
+ gateip = bootp_response->bp_giaddr;
+ if (myip.s_addr == 0)
+ myip = bootp_response->bp_yiaddr;
+ d->myip = myip;
+ }
+ if (rc < 0)
+ bootp(sock, BOOTP_NONE);
+ }
if (myip.s_addr != 0)
goto exit;
#ifdef NETIF_DEBUG
diff --git a/usr/src/boot/sys/boot/common/multiboot2.c b/usr/src/boot/sys/boot/common/multiboot2.c
index 1808d09c89..6ea8480e9f 100644
--- a/usr/src/boot/sys/boot/common/multiboot2.c
+++ b/usr/src/boot/sys/boot/common/multiboot2.c
@@ -759,8 +759,7 @@ mbi_size(struct preloaded_file *fp, char *cmdline)
size = roundup2(size, MULTIBOOT_TAG_ALIGN);
if (bootp_response != NULL) {
- size += sizeof(multiboot_tag_network_t) +
- sizeof (*bootp_response);
+ size += sizeof(multiboot_tag_network_t) + bootp_response_size;
size = roundup2(size, MULTIBOOT_TAG_ALIGN);
}
@@ -1002,12 +1001,11 @@ multiboot2_exec(struct preloaded_file *fp)
if (bootp_response != NULL) {
multiboot_tag_network_t *tag;
tag = (multiboot_tag_network_t *)
- mb_malloc(sizeof (*tag) + sizeof (*bootp_response));
+ mb_malloc(sizeof(*tag) + bootp_response_size);
tag->mb_type = MULTIBOOT_TAG_TYPE_NETWORK;
- tag->mb_size = sizeof (*tag) + sizeof (*bootp_response);
- memcpy(tag->mb_dhcpack, bootp_response,
- sizeof (*bootp_response));
+ tag->mb_size = sizeof(*tag) + bootp_response_size;
+ memcpy(tag->mb_dhcpack, bootp_response, bootp_response_size);
}
if (rsdp != NULL) {
diff --git a/usr/src/boot/sys/boot/efi/libefi/efinet.c b/usr/src/boot/sys/boot/efi/libefi/efinet.c
index 973acfe217..b62e6c787d 100644
--- a/usr/src/boot/sys/boot/efi/libefi/efinet.c
+++ b/usr/src/boot/sys/boot/efi/libefi/efinet.c
@@ -28,6 +28,7 @@
#include <sys/cdefs.h>
#include <sys/param.h>
+#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -35,19 +36,17 @@
#include <net.h>
#include <netif.h>
-#include <dev_net.c>
-
#include <efi.h>
#include <efilib.h>
static EFI_GUID sn_guid = EFI_SIMPLE_NETWORK_PROTOCOL;
static void efinet_end(struct netif *);
-static int efinet_get(struct iodesc *, void *, size_t, time_t);
+static ssize_t efinet_get(struct iodesc *, void **, time_t);
static void efinet_init(struct iodesc *, void *);
static int efinet_match(struct netif *, void *);
static int efinet_probe(struct netif *, void *);
-static int efinet_put(struct iodesc *, void *, size_t);
+static ssize_t efinet_put(struct iodesc *, void *, size_t);
struct netif_driver efinetif = {
.netif_bname = "efinet",
@@ -112,7 +111,7 @@ efinet_probe(struct netif *nif, void *machdep_hint)
return (0);
}
-static int
+static ssize_t
efinet_put(struct iodesc *desc, void *pkt, size_t len)
{
struct netif *nif = desc->io_netif;
@@ -124,59 +123,60 @@ efinet_put(struct iodesc *desc, void *pkt, size_t len)
if (net == NULL)
return (-1);
- status = net->Transmit(net, 0, len, pkt, 0, 0, 0);
+ status = net->Transmit(net, 0, len, pkt, NULL, NULL, NULL);
if (status != EFI_SUCCESS)
return (-1);
/* Wait for the buffer to be transmitted */
do {
- buf = 0; /* XXX Is this needed? */
- status = net->GetStatus(net, 0, &buf);
+ buf = NULL; /* XXX Is this needed? */
+ status = net->GetStatus(net, NULL, &buf);
/*
* XXX EFI1.1 and the E1000 card returns a different
* address than we gave. Sigh.
*/
- } while (status == EFI_SUCCESS && buf == 0);
+ } while (status == EFI_SUCCESS && buf == NULL);
/* XXX How do we deal with status != EFI_SUCCESS now? */
return ((status == EFI_SUCCESS) ? len : -1);
}
-static int
-efinet_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
+static ssize_t
+efinet_get(struct iodesc *desc, void **pkt, time_t timeout)
{
struct netif *nif = desc->io_netif;
EFI_SIMPLE_NETWORK *net;
EFI_STATUS status;
UINTN bufsz;
time_t t;
- char buf[2048];
+ char *buf, *ptr;
+ ssize_t ret = -1;
net = nif->nif_devdata;
if (net == NULL)
- return (0);
+ return (ret);
+
+ bufsz = net->Mode->MaxPacketSize + ETHER_HDR_LEN + ETHER_CRC_LEN;
+ buf = malloc(bufsz + ETHER_ALIGN);
+ if (buf == NULL)
+ return (ret);
+ ptr = buf + ETHER_ALIGN;
- t = time(0);
- while ((time(0) - t) < timeout) {
- bufsz = sizeof(buf);
- status = net->Receive(net, 0, &bufsz, buf, 0, 0, 0);
+ t = getsecs();
+ while ((getsecs() - t) < timeout) {
+ status = net->Receive(net, NULL, &bufsz, ptr, NULL, NULL, NULL);
if (status == EFI_SUCCESS) {
- /*
- * XXX EFI1.1 and the E1000 card trash our
- * workspace if we do not do this silly copy.
- * Either they are not respecting the len
- * value or do not like the alignment.
- */
- if (bufsz > len)
- bufsz = len;
- bcopy(buf, pkt, bufsz);
- return (bufsz);
+ *pkt = buf;
+ ret = (ssize_t)bufsz;
+ break;
}
if (status != EFI_NOT_READY)
- return (0);
+ break;
}
- return (0);
+ if (ret == -1)
+ free(buf);
+ return (ret);
}
static void
@@ -204,8 +204,8 @@ efinet_init(struct iodesc *desc, void *machdep_hint)
if (net->Mode->State == EfiSimpleNetworkStopped) {
status = net->Start(net);
if (status != EFI_SUCCESS) {
- printf("net%d: cannot start interface (status=%ld)\n",
- nif->nif_unit, (long)status);
+ printf("net%d: cannot start interface (status=%lu)\n",
+ nif->nif_unit, EFI_ERROR_CODE(status));
return;
}
}
@@ -213,8 +213,8 @@ efinet_init(struct iodesc *desc, void *machdep_hint)
if (net->Mode->State != EfiSimpleNetworkInitialized) {
status = net->Initialize(net, 0, 0);
if (status != EFI_SUCCESS) {
- printf("net%d: cannot init. interface (status=%ld)\n",
- nif->nif_unit, (long)status);
+ printf("net%d: cannot init. interface (status=%lu)\n",
+ nif->nif_unit, EFI_ERROR_CODE(status));
return;
}
}
@@ -223,10 +223,10 @@ efinet_init(struct iodesc *desc, void *machdep_hint)
UINT32 mask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
- status = net->ReceiveFilters(net, mask, 0, FALSE, 0, 0);
+ status = net->ReceiveFilters(net, mask, 0, FALSE, 0, NULL);
if (status != EFI_SUCCESS) {
- printf("net%d: cannot set rx. filters (status=%ld)\n",
- nif->nif_unit, (long)status);
+ printf("net%d: cannot set rx. filters (status=%lu)\n",
+ nif->nif_unit, EFI_ERROR_CODE(status));
return;
}
}
@@ -257,9 +257,9 @@ struct devsw efinet_dev = {
.dv_name = "net",
.dv_type = DEVT_NET,
.dv_init = efinet_dev_init,
- .dv_strategy = net_strategy,
- .dv_open = net_open,
- .dv_close = net_close,
+ .dv_strategy = NULL, /* Will be set in efinet_dev_init */
+ .dv_open = NULL, /* Will be set in efinet_dev_init */
+ .dv_close = NULL, /* Will be set in efinet_dev_init */
.dv_ioctl = noioctl,
.dv_print = efinet_dev_print,
.dv_cleanup = NULL
@@ -276,13 +276,14 @@ efinet_dev_init()
EFI_STATUS status;
UINTN sz;
int err, i, nifs;
+ extern struct devsw netdev;
sz = 0;
handles = NULL;
- status = BS->LocateHandle(ByProtocol, &sn_guid, 0, &sz, 0);
+ status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz, NULL);
if (status == EFI_BUFFER_TOO_SMALL) {
handles = (EFI_HANDLE *)malloc(sz);
- status = BS->LocateHandle(ByProtocol, &sn_guid, 0, &sz,
+ status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz,
handles);
if (EFI_ERROR(status))
free(handles);
@@ -312,10 +313,11 @@ efinet_dev_init()
* pull packets off the network leading to lost packets.
*/
status = BS->OpenProtocol(handles[i], &sn_guid, (void **)&net,
- IH, 0, EFI_OPEN_PROTOCOL_EXCLUSIVE);
+ IH, NULL, EFI_OPEN_PROTOCOL_EXCLUSIVE);
if (status != EFI_SUCCESS) {
printf("Unable to open network interface %d for "
- "exclusive access: %d\n", i, EFI_ERROR(status));
+ "exclusive access: %lu\n", i,
+ EFI_ERROR_CODE(status));
}
handles2[nifs] = handles[i];
@@ -350,6 +352,11 @@ efinet_dev_init()
dif->dif_stats = &stats[i];
dif->dif_private = handles2[i];
}
+
+ efinet_dev.dv_open = netdev.dv_open;
+ efinet_dev.dv_close = netdev.dv_close;
+ efinet_dev.dv_strategy = netdev.dv_strategy;
+
done:
free(handles2);
return (err);
diff --git a/usr/src/boot/sys/boot/efi/loader/Makefile.common b/usr/src/boot/sys/boot/efi/loader/Makefile.common
index fbddfeab8a..5b4a47efda 100644
--- a/usr/src/boot/sys/boot/efi/loader/Makefile.common
+++ b/usr/src/boot/sys/boot/efi/loader/Makefile.common
@@ -14,8 +14,8 @@ SRCS += load_elf64.c load_elf64_obj.c reloc_elf64.c
OBJS += load_elf32.o load_elf32_obj.o reloc_elf32.o \
load_elf64.o load_elf64_obj.o reloc_elf64.o
-SRCS += disk.c part.c
-OBJS += disk.o part.o
+SRCS += disk.c part.c dev_net.c
+OBJS += disk.o part.o dev_net.o
CFLAGS += -DLOADER_DISK_SUPPORT
SRCS += crc32.c
OBJS += crc32.o
diff --git a/usr/src/boot/sys/boot/forth/support.4th b/usr/src/boot/sys/boot/forth/support.4th
index 7707102deb..8b30502724 100644
--- a/usr/src/boot/sys/boot/forth/support.4th
+++ b/usr/src/boot/sys/boot/forth/support.4th
@@ -1151,10 +1151,8 @@ string current_file_name_ref \ used to print the file name
: scan_conf_dir ( -- addr len -1 | 0 )
s" currdev" getenv -1 <> if
- dup 3 \ we only need first 3 chars
- s" pxe" compare 0=
- swap 3
- s" net" compare 0= or if
+ 3 \ we only need first 3 chars
+ s" net" compare 0= if
s" boot.tftproot.server" getenv? if
0 exit \ readdir does not work on tftp
then
diff --git a/usr/src/boot/sys/boot/i386/libi386/multiboot.c b/usr/src/boot/sys/boot/i386/libi386/multiboot.c
index e6329240b6..f169f73902 100644
--- a/usr/src/boot/sys/boot/i386/libi386/multiboot.c
+++ b/usr/src/boot/sys/boot/i386/libi386/multiboot.c
@@ -384,12 +384,12 @@ multiboot_exec(struct preloaded_file *fp)
mb_info->mmap_addr = VTOP(mmap);
mb_info->flags |= MULTIBOOT_INFO_MEM_MAP;
- if (strstr(getenv("loaddev"), "pxe") != NULL &&
+ if (strstr(getenv("loaddev"), "net") != NULL &&
bootp_response != NULL) {
- mb_info->drives_length = sizeof (*bootp_response);
- mb_info->drives_addr = mb_malloc(mb_info->drives_length);
+ mb_info->drives_length = bootp_response_size;
+ mb_info->drives_addr = mb_malloc(bootp_response_size);
i386_copyin(bootp_response, mb_info->drives_addr,
- mb_info->drives_length);
+ bootp_response_size);
mb_info->flags &= ~MULTIBOOT_INFO_DRIVE_INFO;
}
/*
diff --git a/usr/src/boot/sys/boot/i386/libi386/pxe.c b/usr/src/boot/sys/boot/i386/libi386/pxe.c
index 2feb4d0f69..b947fbe7a7 100644
--- a/usr/src/boot/sys/boot/i386/libi386/pxe.c
+++ b/usr/src/boot/sys/boot/i386/libi386/pxe.c
@@ -29,11 +29,15 @@
#include <sys/cdefs.h>
#include <stand.h>
+#include <stddef.h>
#include <string.h>
#include <stdarg.h>
+#include <sys/param.h>
+#include <net/ethernet.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
+#include <netinet/ip.h>
#include <netinet/udp.h>
#include <net.h>
@@ -52,17 +56,15 @@
* 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];
static pxenv_t *pxenv_p = NULL; /* PXENV+ */
static pxe_t *pxe_p = NULL; /* !PXE */
-static BOOTPLAYER bootplayer = {0}; /* PXE Cached information. */
+#ifdef PXE_DEBUG
static int pxe_debug = 0;
-static int pxe_sock = -1;
-static int pxe_opens = 0;
+#endif
void pxe_enable(void *pxeinfo);
static void (*pxe_call)(int func);
@@ -70,25 +72,17 @@ 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 int pxe_print(int verbose);
static void pxe_cleanup(void);
-static void pxe_setnfshandle(char *rootpath);
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 ssize_t pxe_netif_get(struct iodesc *, void **, time_t);
+static ssize_t pxe_netif_put(struct iodesc *desc, void *pkt, size_t len);
static void pxe_netif_end(struct netif *nif);
-int nfs_getrootfh(struct iodesc*, char*, uint32_t*, u_char*);
-
extern struct netif_stats pxe_st[];
extern u_int16_t __bangpxeseg;
extern u_int16_t __bangpxeoff;
@@ -96,25 +90,24 @@ extern void __bangpxeentry(void);
extern u_int16_t __pxenvseg;
extern u_int16_t __pxenvoff;
extern void __pxenventry(void);
-extern struct in_addr servip;
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)];
+struct netif_stats pxe_st[nitems(pxe_ifs)];
struct netif_driver pxenetif = {
- "pxenet",
- pxe_netif_match,
- pxe_netif_probe,
- pxe_netif_init,
- pxe_netif_get,
- pxe_netif_put,
- pxe_netif_end,
- pxe_ifs,
- NENTS(pxe_ifs)
+ .netif_bname = "pxenet",
+ .netif_match = pxe_netif_match,
+ .netif_probe = pxe_netif_probe,
+ .netif_init = pxe_netif_init,
+ .netif_get = pxe_netif_get,
+ .netif_put = pxe_netif_put,
+ .netif_end = pxe_netif_end,
+ .netif_ifs = pxe_ifs,
+ .netif_nifs = nitems(pxe_ifs)
};
struct netif_driver *netif_drivers[] = {
@@ -123,15 +116,15 @@ struct netif_driver *netif_drivers[] = {
};
struct devsw pxedisk = {
- "pxe",
- DEVT_NET,
- pxe_init,
- pxe_strategy,
- pxe_open,
- pxe_close,
- noioctl,
- pxe_print,
- pxe_cleanup
+ .dv_name = "net",
+ .dv_type = DEVT_NET,
+ .dv_init = pxe_init,
+ .dv_strategy = NULL, /* Will be set in pxe_init */
+ .dv_open = NULL, /* Will be set in pxe_init */
+ .dv_close = NULL, /* Will be set in pxe_init */
+ .dv_ioctl = noioctl,
+ .dv_print = pxe_print,
+ .dv_cleanup = pxe_cleanup
};
/*
@@ -159,7 +152,8 @@ pxe_init(void)
int counter;
uint8_t checksum;
uint8_t *checkptr;
-
+ extern struct devsw netdev;
+
if(pxenv_p == NULL)
return (0);
@@ -175,7 +169,7 @@ pxe_init(void)
pxenv_p = NULL;
return (0);
}
-
+
/*
* do byte checksum:
* add up each byte in the structure, the total should be 0
@@ -190,7 +184,6 @@ pxe_init(void)
return (0);
}
-
/*
* PXENV+ passed, so use that if !PXE is not available or
* the checksum fails.
@@ -215,7 +208,11 @@ pxe_init(void)
break;
}
}
-
+
+ pxedisk.dv_open = netdev.dv_open;
+ pxedisk.dv_close = netdev.dv_close;
+ pxedisk.dv_strategy = netdev.dv_strategy;
+
printf("\nPXE version %d.%d, real mode entry point ",
(uint8_t) (pxenv_p->Version >> 8),
(uint8_t) (pxenv_p->Version & 0xFF));
@@ -229,188 +226,38 @@ pxe_init(void)
gci_p = (t_PXENV_GET_CACHED_INFO *) scratch_buffer;
bzero(gci_p, sizeof(*gci_p));
- gci_p->PacketType = PXENV_PACKET_TYPE_BINL_REPLY;
+ 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);
-}
-
-static int
-pxe_strategy(void *devdata, int flag, daddr_t dblk, size_t size,
- char *buf, size_t *rsize)
-{
- return (EIO);
-}
-
-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 (socktodesc(pxe_sock) == NULL) {
- printf("pxe_open: bad socket %d\n", pxe_sock);
- return (ENXIO);
- }
+ free(bootp_response);
+ if ((bootp_response = malloc(gci_p->BufferSize)) != NULL) {
+ bootp_response_size = gci_p->BufferSize;
+ bcopy(PTOV((gci_p->Buffer.segment << 4) + gci_p->Buffer.offset),
+ bootp_response, bootp_response_size);
}
- if (rootip.s_addr == 0) {
- /*
- * Try to extract the RFC1048 data from PXE.
- * Otherwise 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.
- */
- if (dhcp_try_rfc1048(bootplayer.vendor.d, BOOTP_DHCPVEND) < 0) {
- if (pxe_debug)
- printf("pxe_open: no RFC1048 data in PXE Cache\n");
- bootp(pxe_sock, BOOTP_PXE);
- } else if (pxe_debug) {
- printf("pxe_open: loaded RFC1048 data from PXE Cache\n");
- }
- if (rootip.s_addr == 0)
- rootip.s_addr = bootplayer.sip;
- if (gateip.s_addr == 0)
- gateip.s_addr = bootplayer.gip;
- if (myip.s_addr == 0)
- myip.s_addr = bootplayer.yip;
- if (servip.s_addr == 0)
- servip = rootip;
-
- netproto = NET_TFTP;
-
- if (!rootpath[0])
- strcpy(rootpath, PXENFSROOTPATH);
-
- for (i = 0; rootpath[i] != '\0' && i < FNAME_SIZE; i++)
- if (rootpath[i] == ':')
- break;
- if (i && i != FNAME_SIZE && rootpath[i] == ':') {
- rootpath[i++] = '\0';
- if (inet_addr(&rootpath[0]) != INADDR_NONE) {
- netproto = NET_NFS;
- 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);
- }
- setenv("boot.netif.ip", inet_ntoa(myip), 1);
- setenv("boot.netif.netmask", intoa(netmask), 1);
- setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
- setenv("boot.netif.server", inet_ntoa(rootip), 1);
- if (bootplayer.Hardware == ETHER_TYPE) {
- sprintf(temp, "%6D", bootplayer.CAddr, ":");
- setenv("boot.netif.hwaddr", temp, 1);
- }
- if (intf_mtu != 0) {
- char mtu[16];
- snprintf(mtu, sizeof(mtu), "%u", intf_mtu);
- setenv("boot.netif.mtu", mtu, 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));
- printf("pxe_open: my ip: %s\n", inet_ntoa(myip));
- printf("pxe_open: netmask: %s\n", intoa(netmask));
- printf("pxe_open: servip: %s\n", inet_ntoa(servip));
-
- if (netproto == NET_TFTP) {
- setenv("boot.tftproot.server", inet_ntoa(rootip), 1);
- setenv("boot.tftproot.path", rootpath, 1);
- } else if (netproto == NET_NFS) {
- setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
- setenv("boot.nfsroot.path", rootpath, 1);
- }
- setenv("dhcp.host-name", hostname, 1);
-
- setenv("pxeboot.ip", inet_ntoa(myip), 1);
- if (bootplayer.Hardware == ETHER_TYPE) {
- sprintf(temp, "%6D", bootplayer.CAddr, ":");
- setenv("pxeboot.hwaddr", temp, 1);
- }
- }
- }
- pxe_opens++;
- f->f_devdata = &pxe_sock;
- return (error);
-}
-
-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);
-
- if (netproto == NET_NFS) {
- /* get an NFS filehandle for our root filesystem */
- pxe_setnfshandle(rootpath);
- }
-
- if (pxe_sock >= 0) {
-
-#ifdef PXE_DEBUG
- if (pxe_debug)
- printf("pxe_close: calling netif_close()\n");
-#endif
- netif_close(pxe_sock);
- pxe_sock = -1;
- }
- return (0);
+ return (1);
}
static int
pxe_print(int verbose)
{
- char line[255];
if (pxe_call == NULL)
return (0);
printf("%s devices:", pxedisk.dv_name);
if (pager_output("\n") != 0)
return (1);
- snprintf(line, sizeof (line), " pxe0: %s:%s\n", inet_ntoa(rootip),
- rootpath);
- return (pager_output(line));
+ printf(" %s0:", pxedisk.dv_name);
+ if (verbose) {
+ printf(" %s:%s", inet_ntoa(rootip), rootpath);
+ }
+ return (pager_output("\n"));
}
static void
@@ -449,67 +296,6 @@ pxe_perror(int err)
return;
}
-/*
- * Reach inside the libstand NFS code and dig out an NFS handle
- * for the root filesystem.
- */
-
-#define NFS_V3MAXFHSIZE 64
-
-struct nfs_iodesc {
- struct iodesc *iodesc;
- off_t off;
- uint32_t fhsize;
- u_char fh[NFS_V3MAXFHSIZE];
- /* structure truncated */
-};
-extern struct nfs_iodesc nfs_root_node;
-extern int rpc_port;
-
-static void
-pxe_rpcmountcall()
-{
- struct iodesc *d;
- int error;
-
- if (!(d = socktodesc(pxe_sock)))
- return;
- d->myport = htons(--rpc_port);
- d->destip = rootip;
- if ((error = nfs_getrootfh(d, rootpath, &nfs_root_node.fhsize,
- nfs_root_node.fh)) != 0) {
- printf("NFS MOUNT RPC error: %d\n", error);
- nfs_root_node.fhsize = 0;
- }
- nfs_root_node.iodesc = d;
-}
-
-static void
-pxe_setnfshandle(char *rootpath)
-{
- int i;
- u_char *fh;
- char buf[2 * NFS_V3MAXFHSIZE + 3], *cp;
-
- /*
- * If NFS files were never opened, we need to do mount call
- * ourselves. Use nfs_root_node.iodesc as flag indicating
- * previous NFS usage.
- */
- if (nfs_root_node.iodesc == NULL)
- pxe_rpcmountcall();
-
- fh = &nfs_root_node.fh[0];
- buf[0] = 'X';
- cp = &buf[1];
- for (i = 0; i < nfs_root_node.fhsize; i++, cp += 2)
- sprintf(cp, "%02x", fh[i]);
- sprintf(cp, "X");
- setenv("boot.nfsroot.nfshandle", buf, 1);
- sprintf(buf, "%d", nfs_root_node.fhsize);
- setenv("boot.nfsroot.nfshandlelen", buf, 1);
-}
-
void
pxenv_call(int func)
{
@@ -560,122 +346,198 @@ bangpxe_call(int func)
static int
pxe_netif_match(struct netif *nif, void *machdep_hint)
{
- return 1;
+ 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;
+ return (-1);
- bzero(udpopen_p, sizeof(*udpopen_p));
- udpopen_p->src_ip = bootplayer.yip;
- pxe_call(PXENV_UDP_OPEN);
-
- if (udpopen_p->status != 0) {
- printf("pxe_netif_probe: failed %x\n", udpopen_p->status);
- return -1;
- }
- return 0;
+ 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));
+ t_PXENV_UNDI_CLOSE *undi_close_p;
- pxe_call(PXENV_UDP_CLOSE);
- if (udpclose_p->status != 0)
- printf("pxe_end failed %x\n", udpclose_p->status);
+ undi_close_p = (t_PXENV_UNDI_CLOSE *)scratch_buffer;
+ bzero(undi_close_p, sizeof(*undi_close_p));
+ pxe_call(PXENV_UNDI_CLOSE);
+ if (undi_close_p->Status != 0)
+ printf("undi close failed: %x\n", undi_close_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;
-}
+ t_PXENV_UNDI_GET_INFORMATION *undi_info_p;
+ t_PXENV_UNDI_OPEN *undi_open_p;
+ uint8_t *mac;
+ int i, len;
+
+ undi_info_p = (t_PXENV_UNDI_GET_INFORMATION *)scratch_buffer;
+ bzero(undi_info_p, sizeof(*undi_info_p));
+ pxe_call(PXENV_UNDI_GET_INFORMATION);
+ if (undi_info_p->Status != 0) {
+ printf("undi get info failed: %x\n", undi_info_p->Status);
+ return;
+ }
-static int
-pxe_netif_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
-{
- return len;
+ /* Make sure the CurrentNodeAddress is valid. */
+ for (i = 0; i < undi_info_p->HwAddrLen; ++i) {
+ if (undi_info_p->CurrentNodeAddress[i] != 0)
+ break;
+ }
+ if (i < undi_info_p->HwAddrLen) {
+ for (i = 0; i < undi_info_p->HwAddrLen; ++i) {
+ if (undi_info_p->CurrentNodeAddress[i] != 0xff)
+ break;
+ }
+ }
+ if (i < undi_info_p->HwAddrLen)
+ mac = undi_info_p->CurrentNodeAddress;
+ else
+ mac = undi_info_p->PermNodeAddress;
+
+ len = min(sizeof (desc->myea), undi_info_p->HwAddrLen);
+ for (i = 0; i < len; ++i) {
+ desc->myea[i] = mac[i];
+ }
+
+ if (bootp_response != NULL)
+ desc->xid = bootp_response->bp_xid;
+ else
+ desc->xid = 0;
+
+ undi_open_p = (t_PXENV_UNDI_OPEN *)scratch_buffer;
+ bzero(undi_open_p, sizeof(*undi_open_p));
+ undi_open_p->PktFilter = FLTR_DIRECTED | FLTR_BRDCST;
+ pxe_call(PXENV_UNDI_OPEN);
+ if (undi_open_p->Status != 0)
+ printf("undi open failed: %x\n", undi_open_p->Status);
}
static int
-pxe_netif_put(struct iodesc *desc, void *pkt, size_t len)
+pxe_netif_receive(void **pkt)
{
- return len;
-}
+ t_PXENV_UNDI_ISR *isr = (t_PXENV_UNDI_ISR *)scratch_buffer;
+ char *buf, *ptr, *frame;
+ size_t size, rsize;
+
+ bzero(isr, sizeof(*isr));
+ isr->FuncFlag = PXENV_UNDI_ISR_IN_START;
+ pxe_call(PXENV_UNDI_ISR);
+ if (isr->Status != 0)
+ return (-1);
+
+ bzero(isr, sizeof(*isr));
+ isr->FuncFlag = PXENV_UNDI_ISR_IN_PROCESS;
+ pxe_call(PXENV_UNDI_ISR);
+ if (isr->Status != 0)
+ return (-1);
+
+ while (isr->FuncFlag == PXENV_UNDI_ISR_OUT_TRANSMIT) {
+ /*
+ * Wait till transmit is done.
+ */
+ bzero(isr, sizeof(*isr));
+ isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
+ pxe_call(PXENV_UNDI_ISR);
+ if (isr->Status != 0 ||
+ isr->FuncFlag == PXENV_UNDI_ISR_OUT_DONE)
+ return (-1);
+ }
-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;
+ while (isr->FuncFlag != PXENV_UNDI_ISR_OUT_RECEIVE) {
+ if (isr->Status != 0 ||
+ isr->FuncFlag == PXENV_UNDI_ISR_OUT_DONE) {
+ return (-1);
+ }
+ bzero(isr, sizeof(*isr));
+ isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
+ pxe_call(PXENV_UNDI_ISR);
+ }
- pxe_call(PXENV_UDP_WRITE);
+ size = isr->FrameLength;
+ buf = malloc(size + ETHER_ALIGN);
+ if (buf == NULL)
+ return (-1);
+ ptr = buf + ETHER_ALIGN;
+ rsize = 0;
+
+ while (rsize < size) {
+ frame = (char *)((uintptr_t)isr->Frame.segment << 4);
+ frame += isr->Frame.offset;
+ bcopy(PTOV(frame), ptr, isr->BufferLength);
+ ptr += isr->BufferLength;
+ rsize += isr->BufferLength;
+
+ bzero(isr, sizeof(*isr));
+ isr->FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
+ pxe_call(PXENV_UNDI_ISR);
+ if (isr->Status != 0) {
+ free(buf);
+ return (-1);
+ }
-#if 0
- /* 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;
+ /* Did we got another update? */
+ if (isr->FuncFlag == PXENV_UNDI_ISR_OUT_RECEIVE)
+ continue;
+ break;
+ }
+
+ *pkt = buf;
+ return (rsize);
+}
+
+static ssize_t
+pxe_netif_get(struct iodesc *desc, void **pkt, time_t timeout)
+{
+ time_t t;
+ void *ptr;
+ ssize_t ret = -1;
+
+ t = getsecs();
+ while ((getsecs() - t) < timeout) {
+ ret = pxe_netif_receive(&ptr);
+ if (ret != -1) {
+ *pkt = ptr;
+ break;
+ }
}
- return len;
+ return (ret);
}
-ssize_t
-readudp(struct iodesc *h, void *pkt, size_t len, time_t timeout)
+static ssize_t
+pxe_netif_put(struct iodesc *desc, void *pkt, size_t len)
{
- t_PXENV_UDP_READ *udpread_p = (t_PXENV_UDP_READ *)scratch_buffer;
- struct udphdr *uh = NULL;
+ t_PXENV_UNDI_TRANSMIT *trans_p;
+ t_PXENV_UNDI_TBD *tbd_p;
+ char *data;
- uh = (struct udphdr *) pkt - 1;
- bzero(udpread_p, sizeof(*udpread_p));
+ trans_p = (t_PXENV_UNDI_TRANSMIT *)scratch_buffer;
+ bzero(trans_p, sizeof(*trans_p));
+ tbd_p = (t_PXENV_UNDI_TBD *)(scratch_buffer + sizeof(*trans_p));
+ bzero(tbd_p, sizeof(*tbd_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);
+ data = scratch_buffer + sizeof(*trans_p) + sizeof(*tbd_p);
- pxe_call(PXENV_UDP_READ);
+ trans_p->TBD.segment = VTOPSEG(tbd_p);
+ trans_p->TBD.offset = VTOPOFF(tbd_p);
-#if 0
- /* 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;
+ tbd_p->ImmedLength = len;
+ tbd_p->Xmit.segment = VTOPSEG(data);
+ tbd_p->Xmit.offset = VTOPOFF(data);
+ bcopy(pkt, data, len);
+
+ pxe_call(PXENV_UNDI_TRANSMIT);
+ if (trans_p->Status != 0) {
+ return (-1);
}
- bcopy(data_buffer, pkt, udpread_p->buffer_size);
- uh->uh_sport = udpread_p->s_port;
- return udpread_p->buffer_size;
+
+ return (len);
}
diff --git a/usr/src/boot/sys/boot/i386/libi386/pxe.h b/usr/src/boot/sys/boot/i386/libi386/pxe.h
index e58d8d538d..1afc23bf4b 100644
--- a/usr/src/boot/sys/boot/i386/libi386/pxe.h
+++ b/usr/src/boot/sys/boot/i386/libi386/pxe.h
@@ -347,7 +347,7 @@ typedef struct {
*/
# define PXENV_UNDI_ISR_OUT_DONE 0
# define PXENV_UNDI_ISR_OUT_TRANSMIT 2
-# define PXENV_UNDI_ISR_OUT_RECIEVE 3
+# define PXENV_UNDI_ISR_OUT_RECEIVE 3
# define PXENV_UNDI_ISR_OUT_BUSY 4
} PACKED t_PXENV_UNDI_ISR;
diff --git a/usr/src/boot/sys/boot/ofw/libofw/ofw_net.c b/usr/src/boot/sys/boot/ofw/libofw/ofw_net.c
index 691dedab05..977467f753 100644
--- a/usr/src/boot/sys/boot/ofw/libofw/ofw_net.c
+++ b/usr/src/boot/sys/boot/ofw/libofw/ofw_net.c
@@ -25,7 +25,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/types.h>
@@ -46,8 +45,8 @@ __FBSDID("$FreeBSD$");
static int ofwn_probe(struct netif *, void *);
static int ofwn_match(struct netif *, void *);
static void ofwn_init(struct iodesc *, void *);
-static int ofwn_get(struct iodesc *, void *, size_t, time_t);
-static int ofwn_put(struct iodesc *, void *, size_t);
+static ssize_t ofwn_get(struct iodesc *, void **, time_t);
+static ssize_t ofwn_put(struct iodesc *, void *, size_t);
static void ofwn_end(struct netif *);
extern struct netif_stats ofwn_stats[];
@@ -57,7 +56,7 @@ struct netif_dif ofwn_ifs[] = {
{ 0, 1, &ofwn_stats[0], 0, },
};
-struct netif_stats ofwn_stats[NENTS(ofwn_ifs)];
+struct netif_stats ofwn_stats[nitems(ofwn_ifs)];
struct netif_driver ofwnet = {
"net", /* netif_bname */
@@ -68,7 +67,7 @@ struct netif_driver ofwnet = {
ofwn_put, /* netif_put */
ofwn_end, /* netif_end */
ofwn_ifs, /* netif_ifs */
- NENTS(ofwn_ifs) /* netif_nifs */
+ nitems(ofwn_ifs) /* netif_nifs */
};
static ihandle_t netinstance;
@@ -87,7 +86,7 @@ ofwn_probe(struct netif *nif, void *machdep_hint)
return 0;
}
-static int
+static ssize_t
ofwn_put(struct iodesc *desc, void *pkt, size_t len)
{
size_t sendlen;
@@ -124,20 +123,32 @@ ofwn_put(struct iodesc *desc, void *pkt, size_t len)
return rv;
}
-static int
-ofwn_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
+static ssize_t
+ofwn_get(struct iodesc *desc, void **pkt, time_t timeout)
{
time_t t;
- int length;
+ ssize_t length;
+ size_t len;
+ char *buf, *ptr;
#if defined(NETIF_DEBUG)
- printf("netif_get: pkt=%p, maxlen=%d, timeout=%d\n", pkt, len,
- timeout);
+ printf("netif_get: pkt=%p, timeout=%d\n", pkt, timeout);
#endif
+ /*
+ * We should read the "max-frame-size" int property instead,
+ * but at this time the iodesc does not have mtu, so we will take
+ * a small shortcut here.
+ */
+ len = ETHER_MAX_LEN;
+ buf = malloc(len + ETHER_ALIGN);
+ if (buf == NULL)
+ return (-1);
+ ptr = buf + ETHER_ALIGN;
+
t = getsecs();
do {
- length = OF_read(netinstance, pkt, len);
+ length = OF_read(netinstance, ptr, len);
} while ((length == -2 || length == 0) &&
(getsecs() - t < timeout));
@@ -145,12 +156,14 @@ ofwn_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
printf("netif_get: received length=%d (%x)\n", length, length);
#endif
- if (length < 12)
- return -1;
+ if (length < 12) {
+ free(buf);
+ return (-1);
+ }
#if defined(NETIF_VERBOSE_DEBUG)
{
- char *ch = pkt;
+ char *ch = ptr;
int i;
for(i = 0; i < 96; i += 4) {
@@ -163,7 +176,7 @@ ofwn_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
#if defined(NETIF_DEBUG)
{
- struct ether_header *eh = pkt;
+ struct ether_header *eh = ptr;
printf("dst: %s ", ether_sprintf(eh->ether_dhost));
printf("src: %s ", ether_sprintf(eh->ether_shost));
@@ -171,7 +184,8 @@ ofwn_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
}
#endif
- return length;
+ *pkt = buf;
+ return (length);
}
extern char *strchr();
diff --git a/usr/src/boot/sys/boot/uboot/lib/net.c b/usr/src/boot/sys/boot/uboot/lib/net.c
index 9bc0c07543..1f15f3ce0e 100644
--- a/usr/src/boot/sys/boot/uboot/lib/net.c
+++ b/usr/src/boot/sys/boot/uboot/lib/net.c
@@ -26,7 +26,6 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/types.h>
@@ -50,8 +49,8 @@ __FBSDID("$FreeBSD$");
static int net_probe(struct netif *, void *);
static int net_match(struct netif *, void *);
static void net_init(struct iodesc *, void *);
-static int net_get(struct iodesc *, void *, size_t, time_t);
-static int net_put(struct iodesc *, void *, size_t);
+static ssize_t net_get(struct iodesc *, void **, time_t);
+static ssize_t net_put(struct iodesc *, void *, size_t);
static void net_end(struct netif *);
extern struct netif_stats net_stats[];
@@ -61,7 +60,7 @@ struct netif_dif net_ifs[] = {
{ 0, 1, &net_stats[0], 0, },
};
-struct netif_stats net_stats[NENTS(net_ifs)];
+struct netif_stats net_stats[nitems(net_ifs)];
struct netif_driver uboot_net = {
"uboot_eth", /* netif_bname */
@@ -72,7 +71,7 @@ struct netif_driver uboot_net = {
net_put, /* netif_put */
net_end, /* netif_end */
net_ifs, /* netif_ifs */
- NENTS(net_ifs) /* netif_nifs */
+ nitems(net_ifs) /* netif_nifs */
};
struct uboot_softc {
@@ -232,7 +231,7 @@ net_probe(struct netif *nif, void *machdep_hint)
return (0);
}
-static int
+static ssize_t
net_put(struct iodesc *desc, void *pkt, size_t len)
{
struct netif *nif = desc->io_netif;
@@ -271,18 +270,21 @@ net_put(struct iodesc *desc, void *pkt, size_t len)
return (rv);
}
-static int
-net_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
+static ssize_t
+net_get(struct iodesc *desc, void **pkt, time_t timeout)
{
struct netif *nif = desc->io_netif;
struct uboot_softc *sc = nif->nif_devdata;
time_t t;
int err, rlen;
+ size_t len;
+ char *buf;
#if defined(NETIF_DEBUG)
- printf("net_get: pkt %p, len %d, timeout %d\n", pkt, len, timeout);
+ printf("net_get: pkt %p, timeout %d\n", pkt, timeout);
#endif
t = getsecs();
+ len = sizeof (sc->sc_rxbuf);
do {
err = ub_dev_recv(sc->sc_handle, sc->sc_rxbuf, len, &rlen);
@@ -299,13 +301,12 @@ net_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
#endif
if (rlen > 0) {
- memcpy(pkt, sc->sc_rxbuf, MIN(len, rlen));
- if (rlen != len) {
-#if defined(NETIF_DEBUG)
- printf("net_get: len %x, rlen %x\n", len, rlen);
-#endif
- }
- return (rlen);
+ buf = malloc(rlen + ETHER_ALIGN);
+ if (buf == NULL)
+ return (-1);
+ memcpy(buf + ETHER_ALIGN, sc->sc_rxbuf, rlen);
+ *pkt = buf;
+ return ((ssize_t)rlen);
}
return (-1);