Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107163491
D10232.id26988.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
76 KB
Referenced Files
None
Subscribers
None
D10232.id26988.diff
View Options
Index: lib/libstand/arp.c
===================================================================
--- lib/libstand/arp.c
+++ lib/libstand/arp.c
@@ -65,17 +65,16 @@
/* 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 @@
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 @@
/* 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 + 2);
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 @@
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 @@
* 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 @@
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 @@
if (debug)
printf("bad hrd/pro/hln/pln\n");
#endif
+ free(ptr);
return (-1);
}
@@ -220,6 +213,7 @@
printf("is request\n");
#endif
arp_reply(d, ah);
+ free(ptr);
return (-1);
}
@@ -228,6 +222,7 @@
if (debug)
printf("not ARP reply\n");
#endif
+ free(ptr);
return (-1);
}
@@ -239,6 +234,7 @@
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 @@
if (debug)
printf("got it\n");
#endif
+ *pkt = ptr;
+ *payload = ah;
return (n);
}
@@ -256,9 +254,7 @@
* 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;
Index: lib/libstand/bootp.h
===================================================================
--- lib/libstand/bootp.h
+++ lib/libstand/bootp.h
@@ -148,6 +148,10 @@
/* 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_ */
Index: lib/libstand/bootp.c
===================================================================
--- lib/libstand/bootp.c
+++ lib/libstand/bootp.c
@@ -38,6 +38,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <stddef.h>
#include <sys/types.h>
#include <sys/limits.h>
#include <sys/endian.h>
@@ -72,7 +73,7 @@
/* 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 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)
@@ -176,8 +175,7 @@
if(sendrecv(d,
bootpsend, bp, sizeof(*bp),
- bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
- == -1) {
+ bootprecv, &pkt, (void **)&rbootp) == -1) {
printf("bootp: no reply\n");
return;
}
@@ -188,7 +186,7 @@
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);
@@ -206,20 +204,21 @@
expected_dhcpmsgtype = DHCPACK;
+ free(pkt);
if(sendrecv(d,
bootpsend, bp, sizeof(*bp),
- bootprecv, &rbuf.rbootp, sizeof(rbuf.rbootp))
- == -1) {
+ bootprecv, &pkt, (void **)&rbootp) == -1) {
printf("DHCPREQUEST failed\n");
return;
}
}
#endif
- myip = d->myip = rbuf.rbootp.bp_yiaddr;
- servip = rbuf.rbootp.bp_siaddr;
- if(rootip.s_addr == INADDR_ANY) rootip = servip;
- bcopy(rbuf.rbootp.bp_file, bootfile, sizeof(bootfile));
+ myip = d->myip = rbootp->bp_yiaddr;
+ servip = rbootp->bp_siaddr;
+ if (rootip.s_addr == INADDR_ANY)
+ rootip = servip;
+ bcopy(rbootp->bp_file, bootfile, sizeof(bootfile));
bootfile[sizeof(bootfile) - 1] = '\0';
if (!netmask) {
@@ -259,14 +258,12 @@
/* Bump xid so next request will be unique. */
++d->xid;
+ free(pkt);
}
/* Transmit a bootp request */
static ssize_t
-bootpsend(d, pkt, len)
- struct iodesc *d;
- void *pkt;
- size_t len;
+bootpsend(struct iodesc *d, void *pkt, size_t len)
{
struct bootp *bp;
@@ -287,30 +284,26 @@
}
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 = 0x%p, n = %d\n",
+ (void *)bp, (int)n);
#endif
if (bp->bp_xid != htonl(d->xid)) {
#ifdef BOOTP_DEBUG
@@ -329,8 +322,21 @@
/* Suck out vendor info */
if (bcmp(vm_rfc1048, bp->bp_vend, sizeof(vm_rfc1048)) == 0) {
- if(vend_rfc1048(bp->bp_vend, sizeof(bp->bp_vend)) != 0)
+ int vsize = n - offsetof(struct bootp, bp_vend);
+ if (vend_rfc1048(bp->bp_vend, vsize) != 0)
goto bad;
+
+ /* Save copy of bootp reply or DHCP ACK message */
+ if (bp->bp_op == BOOTREPLY &&
+ ((dhcp_ok == 1 && expected_dhcpmsgtype == DHCPACK) ||
+ dhcp_ok == 0)) {
+ free(bootp_response);
+ bootp_response = malloc(n);
+ if (bootp_response != NULL) {
+ bootp_response_size = n;
+ bcopy(bp, bootp_response, bootp_response_size);
+ }
+ }
}
#ifdef BOOTP_VEND_CMU
else if (bcmp(vm_cmu, bp->bp_vend, sizeof(vm_cmu)) == 0)
@@ -339,8 +345,11 @@
else
printf("bootprecv: unknown vendor 0x%lx\n", (long)bp->bp_vend);
- return(n);
+ *pkt = ptr;
+ *payload = bp;
+ return (n);
bad:
+ free(ptr);
errno = 0;
return (-1);
}
@@ -357,9 +366,7 @@
}
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;
@@ -450,8 +457,7 @@
#ifdef BOOTP_VEND_CMU
static void
-vend_cmu(cp)
- u_char *cp;
+vend_cmu(u_char *cp)
{
struct cmu_vend *vp;
Index: lib/libstand/bootparam.c
===================================================================
--- lib/libstand/bootparam.c
+++ lib/libstand/bootparam.c
@@ -104,8 +104,7 @@
* 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,13 +125,10 @@
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 = -1;
RPC_PRINTF(("bp_whoami: myip=%s\n", inet_ntoa(myip)));
@@ -141,7 +137,6 @@
return (-1);
}
args = &sdata.d;
- repl = &rdata.d;
/*
* Build request args for PMAPPROC_CALLIT.
@@ -163,12 +158,12 @@
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 @@
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 @@
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 @@
* 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 @@
}
send_tail = (char*) sdata.d;
- recv_head = (char*) rdata.d;
/*
* Build request message.
@@ -281,17 +271,16 @@
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 @@
/* 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 @@
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;
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,10 +340,7 @@
}
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;
char *datap;
@@ -362,7 +348,7 @@
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 @@
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 @@
}
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;
Index: lib/libstand/ether.c
===================================================================
--- lib/libstand/ether.c
+++ lib/libstand/ether.c
@@ -54,12 +54,7 @@
/* 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 @@
/*
* 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 + 2);
/* Validate Ethernet address. */
if (bcmp(d->myea, eh->ether_dhost, 6) != 0 &&
bcmp(bcea, eh->ether_dhost, 6) != 0) {
@@ -120,8 +114,12 @@
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 @@
*/
static char digits[] = "0123456789abcdef";
char *
-ether_sprintf(ap)
- u_char *ap;
+ether_sprintf(u_char *ap)
{
int i;
static char etherbuf[18];
Index: lib/libstand/net.h
===================================================================
--- lib/libstand/net.h
+++ lib/libstand/net.h
@@ -107,16 +107,15 @@
/* 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);
Index: lib/libstand/net.c
===================================================================
--- lib/libstand/net.c
+++ lib/libstand/net.c
@@ -70,10 +70,10 @@
*/
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 @@
}
/* 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);
Index: lib/libstand/netif.h
===================================================================
--- lib/libstand/netif.h
+++ 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 @@
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 *);
Index: lib/libstand/netif.c
===================================================================
--- lib/libstand/netif.c
+++ lib/libstand/netif.c
@@ -59,7 +59,7 @@
*/
void
-netif_init()
+netif_init(void)
{
struct netif_driver *drv;
int d, i;
@@ -76,13 +76,11 @@
}
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 @@
}
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 @@
}
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 @@
}
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 @@
}
void
-netif_detach(nif)
- struct netif *nif;
+netif_detach(struct netif *nif)
{
struct netif_driver *drv = nif->nif_driver;
@@ -217,11 +208,7 @@
}
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 @@
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 @@
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 @@
}
int
-netif_open(machdep_hint)
- void *machdep_hint;
+netif_open(void *machdep_hint)
{
int fd;
struct iodesc *s;
@@ -313,23 +295,22 @@
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);
}
Index: lib/libstand/nfs.c
===================================================================
--- lib/libstand/nfs.c
+++ lib/libstand/nfs.c
@@ -185,6 +185,7 @@
int
nfs_getrootfh(struct iodesc *d, char *path, uint32_t *fhlenp, u_char *fhp)
{
+ void *pkt = NULL;
int len;
struct args {
uint32_t len;
@@ -201,10 +202,6 @@
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
@@ -213,7 +210,6 @@
#endif
args = &sdata.d;
- repl = &rdata.d;
bzero(args, sizeof(*args));
len = strlen(path);
@@ -224,18 +220,25 @@
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);
}
@@ -246,6 +249,7 @@
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;
@@ -263,10 +267,6 @@
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
@@ -275,7 +275,6 @@
#endif
args = &sdata.d;
- repl = &rdata.d;
bzero(args, sizeof(*args));
args->fhsize = htonl(d->fhsize);
@@ -289,23 +288,30 @@
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);
}
@@ -316,6 +322,7 @@
int
nfs_readlink(struct nfs_iodesc *d, char *buf)
{
+ void *pkt = NULL;
struct args {
uint32_t fhsize;
u_char fh[NFS_V3MAXFHSIZE];
@@ -331,11 +338,8 @@
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)
@@ -343,32 +347,41 @@
#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;
+done:
+ free(pkt);
return (0);
}
#endif
@@ -380,6 +393,7 @@
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];
@@ -397,16 +411,11 @@
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);
@@ -421,16 +430,19 @@
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;
@@ -438,9 +450,11 @@
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);
}
@@ -481,17 +495,8 @@
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)
+ if (f->f_dev->dv_type != DEVT_NET)
return (EINVAL);
-#else
- if (strcmp(f->f_dev->dv_name, "pxe") != 0)
- return (EINVAL);
-#endif
if (!(desc = socktodesc(*(int *)(f->f_devdata))))
return (EINVAL);
@@ -660,9 +665,8 @@
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);
}
@@ -773,6 +777,7 @@
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;
@@ -787,14 +792,12 @@
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));
@@ -810,11 +813,23 @@
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) {
+ free(pkt);
+ pkt = NULL;
+ pfp = NULL;
+ cookie = 0;
+ return (errno);
+ }
repl = (struct nfsv3_readdir_repl *)buf;
- if (repl->errno != 0)
- return (ntohl(repl->errno));
+ if (repl->errno != 0) {
+ int rc = ntohl(repl->errno);
+ free(pkt);
+ pkt = NULL;
+ pfp = NULL;
+ cookie = 0;
+ return (rc);
+ }
pfp = fp;
cookie = fp->off;
fp->cookie = ((uint64_t)ntohl(repl->cookiev0) << 32) |
@@ -826,6 +841,9 @@
if (rent->follows == 0) {
/* fid0 is actually eof */
if (rent->fid0 != 0) {
+ free(pkt);
+ pkt = NULL;
+ pfp = NULL;
cookie = 0;
return (ENOENT);
}
Index: lib/libstand/rarp.c
===================================================================
--- lib/libstand/rarp.c
+++ lib/libstand/rarp.c
@@ -54,17 +54,17 @@
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 +72,6 @@
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 +95,21 @@
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 +127,7 @@
* 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 +143,26 @@
* 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 +171,10 @@
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 +184,7 @@
if (debug)
printf("bad hrd/pro/hln/pln\n");
#endif
+ free(ptr);
return (-1);
}
@@ -204,6 +193,7 @@
if (debug)
printf("bad op=0x%x\n", ntohs(ap->arp_op));
#endif
+ free(ptr);
return (-1);
}
@@ -213,6 +203,7 @@
if (debug)
printf("unwanted address\n");
#endif
+ free(ptr);
return (-1);
}
@@ -221,5 +212,7 @@
if (debug)
printf("got it\n");
#endif
+ *pkt = ptr;
+ *payload = ap;
return (n);
}
Index: lib/libstand/rpc.h
===================================================================
--- lib/libstand/rpc.h
+++ 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);
Index: lib/libstand/rpc.c
===================================================================
--- lib/libstand/rpc.c
+++ lib/libstand/rpc.c
@@ -97,7 +97,7 @@
};
/* 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 +109,14 @@
*/
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 +145,6 @@
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 +152,6 @@
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 +164,28 @@
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 +194,21 @@
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 +217,9 @@
* 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 +227,15 @@
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 +243,8 @@
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 +253,20 @@
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 +384,7 @@
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 +409,18 @@
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);
Index: lib/libstand/tftp.c
===================================================================
--- lib/libstand/tftp.c
+++ lib/libstand/tftp.c
@@ -73,8 +73,8 @@
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 +114,8 @@
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 +178,23 @@
}
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 +204,7 @@
/*
* Expected block?
*/
+ free(ptr);
return (-1);
}
if (d->xid == 1) {
@@ -211,11 +212,13 @@
* 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 +230,7 @@
#endif
errno = tftperrors[ntohs(t->th_code)];
}
+ free(ptr);
return (-1);
case OACK: {
struct udphdr *uh;
@@ -237,6 +241,7 @@
* Drop the pkt.
*/
if (d->xid != 1) {
+ free(ptr);
return (-1);
}
@@ -244,7 +249,7 @@
* 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 +257,18 @@
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 +285,7 @@
char *wtail;
int l;
ssize_t res;
+ void *pkt;
struct tftphdr *t;
char *tftp_blksize = NULL;
int blksize_l;
@@ -314,8 +324,6 @@
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 +333,17 @@
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 +379,7 @@
} __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 +387,20 @@
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 +427,8 @@
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);
@@ -507,7 +523,7 @@
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 @@
if (tftpfile) {
free(tftpfile->path);
+ free(tftpfile->pkt);
free(tftpfile);
}
is_open = 0;
@@ -591,8 +608,9 @@
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 @@
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);
Index: lib/libstand/udp.c
===================================================================
--- lib/libstand/udp.c
+++ lib/libstand/udp.c
@@ -59,10 +59,7 @@
/* 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 +128,29 @@
/*
* 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 +161,8 @@
/* Send ARP reply */
arp_reply(d, ah);
}
- return -1;
+ free(ptr);
+ return (-1);
}
if (etype != ETHERTYPE_IP) {
@@ -175,7 +170,8 @@
if (debug)
printf("readudp: not IP. ether_type=%x\n", etype);
#endif
- return -1;
+ free(ptr);
+ return (-1);
}
/* Check ip header */
@@ -185,7 +181,8 @@
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 +192,8 @@
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 +201,8 @@
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 +211,14 @@
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 +228,8 @@
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 +240,8 @@
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) */
@@ -252,7 +255,8 @@
printf("readudp: bad cksum\n");
#endif
*ip = tip;
- return -1;
+ free(ptr);
+ return (-1);
}
*ip = tip;
}
@@ -263,10 +267,13 @@
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);
}
Index: sys/boot/common/dev_net.c
===================================================================
--- sys/boot/common/dev_net.c
+++ sys/boot/common/dev_net.c
@@ -58,6 +58,7 @@
#include <netinet/in_systm.h>
#include <stand.h>
+#include <stddef.h>
#include <string.h>
#include <net.h>
#include <netif.h>
@@ -79,7 +80,7 @@
static int net_open(struct open_file *, ...);
static int net_close(struct open_file *);
static void net_cleanup(void);
-static int net_strategy();
+static int net_strategy(void *, int, daddr_t, size_t, char *, size_t *);
static int net_print(int);
static int net_getparams(int sock);
@@ -216,7 +217,8 @@
}
static int
-net_strategy()
+net_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf,
+ size_t *rsize)
{
return (EIO);
@@ -246,6 +248,8 @@
{
char buf[MAXHOSTNAMELEN];
n_long rootaddr, smask;
+ struct iodesc *d = socktodesc(sock);
+ extern struct in_addr servip;
#ifdef SUPPORT_BOOTP
/*
@@ -254,8 +258,26 @@
* 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
Index: sys/boot/efi/libefi/efinet.c
===================================================================
--- sys/boot/efi/libefi/efinet.c
+++ sys/boot/efi/libefi/efinet.c
@@ -36,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",
@@ -113,7 +111,7 @@
return (0);
}
-static int
+static ssize_t
efinet_put(struct iodesc *desc, void *pkt, size_t len)
{
struct netif *nif = desc->io_netif;
@@ -125,14 +123,14 @@
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 = NULL; /* XXX Is this needed? */
- status = net->GetStatus(net, 0, &buf);
+ status = net->GetStatus(net, NULL, &buf);
/*
* XXX EFI1.1 and the E1000 card returns a different
* address than we gave. Sigh.
@@ -143,41 +141,42 @@
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 = roundup2(net->Mode->MaxPacketSize, 64) + 256;
+ buf = malloc(bufsz + 2);
+ if (buf == NULL)
+ return (ret);
+ ptr = buf + 2;
- 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, 0, &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
@@ -205,8 +204,8 @@
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;
}
}
@@ -214,8 +213,8 @@
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;
}
}
@@ -224,10 +223,10 @@
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;
}
}
@@ -258,9 +257,9 @@
.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
@@ -277,13 +276,14 @@
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);
@@ -313,10 +313,11 @@
* 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];
@@ -351,6 +352,11 @@
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);
Index: sys/boot/efi/libefi/time.c
===================================================================
--- sys/boot/efi/libefi/time.c
+++ sys/boot/efi/libefi/time.c
@@ -230,5 +230,5 @@
time_t
getsecs(void)
{
- return time(0);
+ return time(NULL);
}
Index: sys/boot/efi/loader/Makefile
===================================================================
--- sys/boot/efi/loader/Makefile
+++ sys/boot/efi/loader/Makefile
@@ -9,6 +9,7 @@
PROG= loader.sym
INTERNALPROG=
WARNS?= 3
+LOADER_NET_SUPPORT?= yes
# architecture-specific loader code
SRCS= autoload.c \
@@ -35,6 +36,10 @@
CWARNFLAGS.zfs.c+= -Wno-missing-prototypes
.endif
+.if defined(LOADER_NET_SUPPORT)
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
+.endif
+
.if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} > 40201
CWARNFLAGS.self_reloc.c+= -Wno-error=maybe-uninitialized
.endif
Index: sys/boot/i386/libi386/pxe.h
===================================================================
--- sys/boot/i386/libi386/pxe.h
+++ sys/boot/i386/libi386/pxe.h
@@ -349,7 +349,7 @@
*/
# 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;
Index: sys/boot/i386/libi386/pxe.c
===================================================================
--- sys/boot/i386/libi386/pxe.c
+++ sys/boot/i386/libi386/pxe.c
@@ -30,11 +30,14 @@
__FBSDID("$FreeBSD$");
#include <stand.h>
+#include <stddef.h>
#include <string.h>
#include <stdarg.h>
+#include <sys/param.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
+#include <netinet/ip.h>
#include <netinet/udp.h>
#include <net.h>
@@ -53,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; /* 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);
@@ -71,25 +72,17 @@
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;
@@ -97,25 +90,24 @@
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[] = {
@@ -124,15 +116,15 @@
};
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
};
/*
@@ -160,6 +152,7 @@
int counter;
uint8_t checksum;
uint8_t *checkptr;
+ extern struct devsw netdev;
if (pxenv_p == NULL)
return (0);
@@ -215,7 +208,11 @@
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));
@@ -236,192 +233,29 @@
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);
- }
-
- }
- if (rootip.s_addr == 0) {
- /*
- * Try to extract the RFC1048 data from PXE.
- * If fail 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");
- }
-
-#ifdef LOADER_TFTP_SUPPORT
- bootp(pxe_sock, BOOTP_PXE);
-#endif
- 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_NFS;
- if (tftpip.s_addr != 0) {
- netproto = NET_TFTP;
- rootip.s_addr = tftpip.s_addr;
- }
-
- if (netproto == NET_NFS && !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)
- 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(sizeof(mtu), 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;
+ 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);
}
- 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);
+ printf(" %s0:", pxedisk.dv_name);
if (verbose) {
- snprintf(line, sizeof(line), " pxe0: %s:%s\n",
- inet_ntoa(rootip), rootpath);
- } else {
- snprintf(line, sizeof(line), " pxe0:\n");
+ printf(" %s:%s", inet_ntoa(rootip), rootpath);
}
- return (pager_output(line));
+ return (pager_output("\n"));
}
static void
@@ -460,66 +294,6 @@
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)
{
@@ -570,121 +344,196 @@
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;
-
- bzero(udpopen_p, sizeof(*udpopen_p));
- udpopen_p->src_ip = bootplayer.yip;
- pxe_call(PXENV_UDP_OPEN);
+ return (-1);
- 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;
-static int
-pxe_netif_put(struct iodesc *desc, void *pkt, size_t len)
-{
- return len;
+ 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);
}
-ssize_t
-sendudp(struct iodesc *h, void *pkt, size_t len)
+static int
+pxe_netif_receive(void **pkt)
{
- t_PXENV_UDP_WRITE *udpwrite_p = (t_PXENV_UDP_WRITE *)scratch_buffer;
- bzero(udpwrite_p, sizeof(*udpwrite_p));
+ 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);
+ }
+
+ 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);
+ }
+
+ size = isr->FrameLength;
+ buf = malloc(size + 2);
+ if (buf == NULL)
+ return (-1);
+ ptr = buf + 2;
+ 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);
+ }
- 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);
+ /* Did we got another update? */
+ if (isr->FuncFlag == PXENV_UNDI_ISR_OUT_RECEIVE)
+ continue;
+ break;
+ }
- if (netmask == 0 || SAMENET(myip, h->destip, netmask))
- udpwrite_p->gw = 0;
- else
- udpwrite_p->gw = gateip.s_addr;
+ *pkt = buf;
+ return (rsize);
+}
- pxe_call(PXENV_UDP_WRITE);
+static ssize_t
+pxe_netif_get(struct iodesc *desc, void **pkt, time_t timeout)
+{
+ time_t t;
+ void *ptr;
+ int ret = -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;
+ 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;
- }
- bcopy(data_buffer, pkt, udpread_p->buffer_size);
- uh->uh_sport = udpread_p->s_port;
- return udpread_p->buffer_size;
+ 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);
+ }
+
+ return (len);
}
Index: sys/boot/i386/loader/Makefile
===================================================================
--- sys/boot/i386/loader/Makefile
+++ sys/boot/i386/loader/Makefile
@@ -9,6 +9,7 @@
INTERNALPROG=
NEWVERSWHAT?= "bootstrap loader" x86
VERSION_FILE= ${.CURDIR}/../loader/version
+LOADER_NET_SUPPORT?= yes
# architecture-specific loader code
SRCS= main.c conf.c vers.c
@@ -25,6 +26,10 @@
LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a
.endif
+.if defined(LOADER_NET_SUPPORT)
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
+.endif
+
# Enable PXE TFTP or NFS support, not both.
.if defined(LOADER_TFTP_SUPPORT)
CFLAGS+= -DLOADER_TFTP_SUPPORT
Index: sys/boot/ofw/libofw/ofw_net.c
===================================================================
--- sys/boot/ofw/libofw/ofw_net.c
+++ sys/boot/ofw/libofw/ofw_net.c
@@ -57,7 +57,7 @@
{ 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 +68,7 @@
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;
Index: sys/boot/uboot/lib/net.c
===================================================================
--- sys/boot/uboot/lib/net.c
+++ sys/boot/uboot/lib/net.c
@@ -61,7 +61,7 @@
{ 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 +72,7 @@
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 {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 12, 2:38 AM (11 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15760153
Default Alt Text
D10232.id26988.diff (76 KB)
Attached To
Mode
D10232: loader: network read rework
Attached
Detach File
Event Timeline
Log In to Comment