netboot is now in the tree. the argument that finally resulted in it being here
will also keep netboot from compiling until fixes are made.
This commit is contained in:
parent
b9e5a43208
commit
428bb7f594
|
@ -0,0 +1,5 @@
|
|||
CFLAGS = -g -I../../../ -I../../../../include
|
||||
PROG = netboot
|
||||
SRCS = arp.c bootp.c conf.c exec.c in_cksum.c netif.c net.c nfsboot.c rpc.c ut
|
||||
.PATH: ../../common/netboot
|
||||
+
|
|
@ -0,0 +1,12 @@
|
|||
Necessary:
|
||||
need support for bootparam
|
||||
small printf
|
||||
hooks for bootstrapping
|
||||
multiple ethernets
|
||||
nfs diskless stuff, i.e do we change the thing, and how.
|
||||
|
||||
High Priority:
|
||||
|
||||
Low Priority:
|
||||
remove ether-orientation? FDDI support?
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Copyright (c) 1992 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /cvsroot/src/sys/boot/Attic/arp.c,v 1.1 1993/10/12 06:02:14 glass Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "netboot.h"
|
||||
#include "bootbootp.h"
|
||||
|
||||
|
||||
/* Cache stuff */
|
||||
#define ARP_NUM 8 /* need at most 3 arp entries */
|
||||
|
||||
static struct arp_list {
|
||||
n_long addr;
|
||||
u_char ea[6];
|
||||
} arp_list[ARP_NUM] = {
|
||||
{ INADDR_BROADCAST, BA }
|
||||
};
|
||||
static int arp_num = 1;
|
||||
|
||||
/* Local forwards */
|
||||
static int arpsend __P((struct iodesc *, void *, int));
|
||||
static int arprecv __P((struct iodesc *, void *, int));
|
||||
|
||||
/* Broadcast an ARP packet, asking who has addr on interface d */
|
||||
u_char *
|
||||
arpwhohas(d, addr)
|
||||
register struct iodesc *d;
|
||||
n_long addr;
|
||||
{
|
||||
register int i;
|
||||
register struct ether_arp *ah;
|
||||
register struct arp_list *al;
|
||||
struct {
|
||||
u_char header[ETHER_SIZE];
|
||||
struct ether_arp warp;
|
||||
} wbuf;
|
||||
union {
|
||||
u_char buffer[RECV_SIZE];
|
||||
struct {
|
||||
u_char header[ETHER_SIZE];
|
||||
struct ether_arp rarp;
|
||||
} ru;
|
||||
} rbuf;
|
||||
|
||||
if (debug)
|
||||
printf("arpwhohas: called\n");
|
||||
/* Try for cached answer first */
|
||||
for (i = 0, al = arp_list; i < arp_num; ++i, ++al)
|
||||
if (addr == al->addr)
|
||||
return (al->ea);
|
||||
|
||||
/* Don't overflow cache */
|
||||
if (arp_num > ARP_NUM - 1)
|
||||
panic("arpwhohas: overflowed arp_list!");
|
||||
|
||||
if (debug)
|
||||
printf("arpwhohas: not cached\n");
|
||||
ah = &wbuf.warp;
|
||||
bzero(ah, sizeof(*ah));
|
||||
|
||||
ah->arp_hrd = htons(ARPHRD_ETHER);
|
||||
ah->arp_pro = htons(ETHERTYPE_IP);
|
||||
ah->arp_hln = sizeof(ah->arp_sha); /* hardware address length */
|
||||
ah->arp_pln = sizeof(ah->arp_spa); /* protocol address length */
|
||||
ah->arp_op = htons(ARPOP_REQUEST);
|
||||
MACPY(d->myea, ah->arp_sha);
|
||||
bcopy(&d->myip, ah->arp_spa, sizeof(ah->arp_spa));
|
||||
bcopy(&addr, ah->arp_tpa, sizeof(ah->arp_tpa));
|
||||
|
||||
/* Store ip address in cache */
|
||||
al->addr = addr;
|
||||
|
||||
(void)sendrecv(d, arpsend, ah, sizeof(*ah), arprecv,
|
||||
((u_char *)&rbuf.ru.rarp) - ETHER_SIZE,
|
||||
ETHER_SIZE + sizeof(rbuf.ru.rarp));
|
||||
|
||||
/* Store ethernet address in cache */
|
||||
MACPY(rbuf.ru.rarp.arp_sha, al->ea);
|
||||
++arp_num;
|
||||
|
||||
return (al->ea);
|
||||
}
|
||||
|
||||
static int
|
||||
arpsend(d, pkt, len)
|
||||
register struct iodesc *d;
|
||||
register void *pkt;
|
||||
register int len;
|
||||
{
|
||||
if (debug)
|
||||
printf("arpsend: called\n");
|
||||
return (sendether(d, pkt, len, bcea, ETHERTYPE_ARP));
|
||||
}
|
||||
|
||||
/* Returns 0 if this is the packet we're waiting for else -1 (and errno == 0) */
|
||||
static int
|
||||
arprecv(d, pkt, len)
|
||||
register struct iodesc *d;
|
||||
register void *pkt;
|
||||
register int len;
|
||||
{
|
||||
register struct ether_header *eh;
|
||||
register struct ether_arp *ah;
|
||||
|
||||
if (debug)
|
||||
printf("arprecv: called\n");
|
||||
if (len < sizeof(*eh) + sizeof(*ah)) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
eh = (struct ether_header *)pkt;
|
||||
|
||||
/* Must be to us */
|
||||
if (bcmp(d->myea, eh->ether_dhost, 6) != 0 &&
|
||||
bcmp(bcea, eh->ether_dhost, 6) != 0) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (eh->ether_type != ETHERTYPE_ARP) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ah = (struct ether_arp *)(eh + 1);
|
||||
HTONS(ah->arp_hrd);
|
||||
HTONS(ah->arp_pro);
|
||||
HTONS(ah->arp_op);
|
||||
if (ah->arp_hrd != ARPHRD_ETHER || ah->arp_pro != ETHERTYPE_IP ||
|
||||
ah->arp_hln != sizeof(ah->arp_sha) ||
|
||||
ah->arp_pln != sizeof(ah->arp_spa) || ah->arp_op != ARPOP_REPLY) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
if (bcmp(&arp_list[arp_num].addr, ah->arp_spa, sizeof(long)) != 0 ||
|
||||
bcmp(&d->myip, ah->arp_tpa, sizeof(d->myip)) != 0) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 1992 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /cvsroot/src/sys/boot/Attic/bootbootp.h,v 1.1 1993/10/12 06:02:15 glass Exp $ (LBL)
|
||||
*/
|
||||
|
||||
void bootp __P((struct iodesc *));
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
||||
#include "netboot.h"
|
||||
#include "config.h"
|
||||
#include "bootbootp.h"
|
||||
#include "bootp.h"
|
||||
#include "netif.h"
|
||||
|
||||
void get_bootinfo(desc)
|
||||
struct iodesc *desc;
|
||||
{
|
||||
bootp(desc);
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* Copyright (c) 1992 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /cvsroot/src/sys/boot/Attic/bootp.c,v 1.1 1993/10/12 06:02:18 glass Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "netboot.h"
|
||||
#include "config.h"
|
||||
#include "bootbootp.h"
|
||||
#include "bootp.h"
|
||||
|
||||
|
||||
/* Machinery used to insure we don't stop until we have everything we need */
|
||||
#define BOOT_MYIP 0x01
|
||||
#define BOOT_ROOT 0x02
|
||||
#define BOOT_SWAP 0x04
|
||||
#define BOOT_GATEIP 0x08 /* optional */
|
||||
#define BOOT_SMASK 0x10 /* optional */
|
||||
#define BOOT_UCRED 0x20 /* not implemented */
|
||||
|
||||
static int have;
|
||||
static int need = BOOT_MYIP | BOOT_ROOT | BOOT_SWAP;
|
||||
|
||||
/* Local forwards */
|
||||
static int bootpsend __P((struct iodesc *, void *, int));
|
||||
static int bootprecv __P((struct iodesc*, void *, int));
|
||||
|
||||
/* Fetch required bootp infomation */
|
||||
void
|
||||
bootp(d)
|
||||
register struct iodesc *d;
|
||||
{
|
||||
register struct bootp *bp;
|
||||
register void *pkt;
|
||||
struct {
|
||||
u_char header[HEADER_SIZE];
|
||||
struct bootp wbootp;
|
||||
} wbuf;
|
||||
union {
|
||||
u_char buffer[RECV_SIZE];
|
||||
struct {
|
||||
u_char header[HEADER_SIZE];
|
||||
struct bootp xrbootp;
|
||||
}xrbuf;
|
||||
#define rbootp xrbuf.xrbootp
|
||||
} rbuf;
|
||||
|
||||
if (debug)
|
||||
printf("bootp: called\n");
|
||||
have = 0;
|
||||
bp = &wbuf.wbootp;
|
||||
pkt = &rbuf.rbootp;
|
||||
pkt = (((char *) pkt) - HEADER_SIZE);
|
||||
|
||||
bzero(bp, sizeof(*bp));
|
||||
|
||||
bp->bp_op = BOOTREQUEST;
|
||||
bp->bp_htype = 1; /* 10Mb Ethernet (48 bits) */
|
||||
bp->bp_hlen = 6;
|
||||
MACPY(d->myea, bp->bp_chaddr);
|
||||
|
||||
d->myport = IPPORT_BOOTPC;
|
||||
d->destport = IPPORT_BOOTPS;
|
||||
d->destip = INADDR_BROADCAST;
|
||||
|
||||
while ((have & need) != need) {
|
||||
if (debug)
|
||||
printf("bootp: sendrecv\n");
|
||||
(void)sendrecv(d, bootpsend, bp, sizeof(*bp),
|
||||
bootprecv, pkt, RECV_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Transmit a bootp request */
|
||||
static int
|
||||
bootpsend(d, pkt, len)
|
||||
register struct iodesc *d;
|
||||
register void *pkt;
|
||||
register int len;
|
||||
{
|
||||
register struct bootp *bp;
|
||||
|
||||
if (debug)
|
||||
printf("bootpsend: called\n");
|
||||
bp = pkt;
|
||||
bzero(bp->bp_file, sizeof(bp->bp_file));
|
||||
if ((have & BOOT_ROOT) == 0)
|
||||
strcpy((char *)bp->bp_file, "root");
|
||||
else if ((have & BOOT_SWAP) == 0)
|
||||
strcpy((char *)bp->bp_file, "swap");
|
||||
bp->bp_xid = d->xid;
|
||||
bp->bp_secs = (u_long)(getsecs() - bot);
|
||||
if (debug)
|
||||
printf("bootpsend: calling sendudp\n");
|
||||
return (sendudp(d, pkt, len));
|
||||
}
|
||||
|
||||
/* Returns 0 if this is the packet we're waiting for else -1 (and errno == 0) */
|
||||
static int
|
||||
bootprecv(d, pkt, len)
|
||||
register struct iodesc *d;
|
||||
register void *pkt;
|
||||
int len;
|
||||
{
|
||||
register struct bootp *bp;
|
||||
register struct cmu_vend *vp;
|
||||
|
||||
if (debug)
|
||||
printf("bootprecv: called\n");
|
||||
bp = (struct bootp *)checkudp(d, pkt, &len);
|
||||
if (bp == NULL || len < sizeof(*bp)) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (bp->bp_xid != d->xid) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
vp = (struct cmu_vend *)bp->bp_vend;
|
||||
if (bcmp(VM_CMU, vp->v_magic, sizeof(vp->v_magic)) != 0) {
|
||||
printf("bootprecv: not cmu magic\n");
|
||||
vp = NULL;
|
||||
}
|
||||
|
||||
/* Suck out all we can */
|
||||
if (bp->bp_yiaddr.s_addr != 0 && (have & BOOT_MYIP) == 0) {
|
||||
have |= BOOT_MYIP;
|
||||
d->myip = bp->bp_yiaddr.s_addr;
|
||||
if (IN_CLASSA(d->myip))
|
||||
nmask = IN_CLASSA_NET;
|
||||
else if (IN_CLASSB(d->myip))
|
||||
nmask = IN_CLASSB_NET;
|
||||
else
|
||||
nmask = IN_CLASSC_NET;
|
||||
}
|
||||
if (vp && vp->v_smask.s_addr != 0 && (have & BOOT_SMASK) == 0) {
|
||||
have |= BOOT_SMASK;
|
||||
smask = vp->v_smask.s_addr;
|
||||
}
|
||||
if (vp && vp->v_dgate.s_addr != 0 && (have & BOOT_GATEIP) == 0) {
|
||||
have |= BOOT_GATEIP;
|
||||
gateip = vp->v_dgate.s_addr;
|
||||
}
|
||||
if (bp->bp_giaddr.s_addr != 0 && bp->bp_file[0] != '\0') {
|
||||
if ((have & BOOT_ROOT) == 0) {
|
||||
have |= BOOT_ROOT;
|
||||
rootip = bp->bp_giaddr.s_addr;
|
||||
strncpy(rootpath, (char *)bp->bp_file,
|
||||
sizeof(rootpath));
|
||||
rootpath[sizeof(rootpath) - 1] = '\0';
|
||||
|
||||
/* Bump xid so next request will be unique */
|
||||
++d->xid;
|
||||
} else if ((have & BOOT_SWAP) == 0) {
|
||||
have |= BOOT_SWAP;
|
||||
swapip = bp->bp_giaddr.s_addr;
|
||||
strncpy(swappath, (char *)bp->bp_file,
|
||||
sizeof(swappath));
|
||||
swappath[sizeof(swappath) - 1] = '\0';
|
||||
|
||||
/* Bump xid so next request will be unique */
|
||||
++d->xid;
|
||||
}
|
||||
}
|
||||
|
||||
/* Done if we don't know our ip address yet */
|
||||
if ((have & BOOT_MYIP) == 0) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Check subnet mask against net mask; toss if bogus */
|
||||
if ((have & BOOT_SMASK) != 0 && (nmask & smask) != nmask) {
|
||||
smask = 0;
|
||||
have &= ~BOOT_SMASK;
|
||||
}
|
||||
|
||||
/* Get subnet (or net) mask */
|
||||
mask = nmask;
|
||||
if ((have & BOOT_SMASK) != 0)
|
||||
mask = smask;
|
||||
|
||||
/* We need a gateway if root or swap is on a different net */
|
||||
if ((have & BOOT_ROOT) != 0 && !SAMENET(d->myip, rootip, mask))
|
||||
need |= BOOT_GATEIP;
|
||||
if ((have & BOOT_SWAP) != 0 && !SAMENET(d->myip, swapip, mask))
|
||||
need |= BOOT_GATEIP;
|
||||
|
||||
/* Toss gateway if on a different net */
|
||||
if ((have & BOOT_GATEIP) != 0 && !SAMENET(d->myip, gateip, mask)) {
|
||||
gateip = 0;
|
||||
have &= ~BOOT_GATEIP;
|
||||
}
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/* @(#) $Header: /cvsroot/src/sys/boot/Attic/bootp.h,v 1.1 1993/10/12 06:02:20 glass Exp $ (LBL) */
|
||||
/*
|
||||
* Bootstrap Protocol (BOOTP). RFC951 and RFC1048.
|
||||
*
|
||||
* This file specifies the "implementation-independent" BOOTP protocol
|
||||
* information which is common to both client and server.
|
||||
*
|
||||
* Copyright 1988 by Carnegie Mellon.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this program for any
|
||||
* purpose and without fee is hereby granted, provided that this copyright
|
||||
* and permission notice appear on all copies and supporting documentation,
|
||||
* the name of Carnegie Mellon not be used in advertising or publicity
|
||||
* pertaining to distribution of the program without specific prior
|
||||
* permission, and notice be given in supporting documentation that copying
|
||||
* and distribution is by permission of Carnegie Mellon and Stanford
|
||||
* University. Carnegie Mellon makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*/
|
||||
|
||||
|
||||
struct bootp {
|
||||
unsigned char bp_op; /* packet opcode type */
|
||||
unsigned char bp_htype; /* hardware addr type */
|
||||
unsigned char bp_hlen; /* hardware addr length */
|
||||
unsigned char bp_hops; /* gateway hops */
|
||||
unsigned long bp_xid; /* transaction ID */
|
||||
unsigned short bp_secs; /* seconds since boot began */
|
||||
unsigned short bp_unused;
|
||||
struct in_addr bp_ciaddr; /* client IP address */
|
||||
struct in_addr bp_yiaddr; /* 'your' IP address */
|
||||
struct in_addr bp_siaddr; /* server IP address */
|
||||
struct in_addr bp_giaddr; /* gateway IP address */
|
||||
unsigned char bp_chaddr[16]; /* client hardware address */
|
||||
unsigned char bp_sname[64]; /* server host name */
|
||||
unsigned char bp_file[128]; /* boot file name */
|
||||
unsigned char bp_vend[64]; /* vendor-specific area */
|
||||
};
|
||||
|
||||
/*
|
||||
* UDP port numbers, server and client.
|
||||
*/
|
||||
#define IPPORT_BOOTPS 67
|
||||
#define IPPORT_BOOTPC 68
|
||||
|
||||
#define BOOTREPLY 2
|
||||
#define BOOTREQUEST 1
|
||||
|
||||
|
||||
/*
|
||||
* Vendor magic cookie (v_magic) for CMU
|
||||
*/
|
||||
#define VM_CMU "CMU"
|
||||
|
||||
/*
|
||||
* Vendor magic cookie (v_magic) for RFC1048
|
||||
*/
|
||||
#define VM_RFC1048 { 99, 130, 83, 99 }
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* RFC1048 tag values used to specify what information is being supplied in
|
||||
* the vendor field of the packet.
|
||||
*/
|
||||
|
||||
#define TAG_PAD ((unsigned char) 0)
|
||||
#define TAG_SUBNET_MASK ((unsigned char) 1)
|
||||
#define TAG_TIME_OFFSET ((unsigned char) 2)
|
||||
#define TAG_GATEWAY ((unsigned char) 3)
|
||||
#define TAG_TIME_SERVER ((unsigned char) 4)
|
||||
#define TAG_NAME_SERVER ((unsigned char) 5)
|
||||
#define TAG_DOMAIN_SERVER ((unsigned char) 6)
|
||||
#define TAG_LOG_SERVER ((unsigned char) 7)
|
||||
#define TAG_COOKIE_SERVER ((unsigned char) 8)
|
||||
#define TAG_LPR_SERVER ((unsigned char) 9)
|
||||
#define TAG_IMPRESS_SERVER ((unsigned char) 10)
|
||||
#define TAG_RLP_SERVER ((unsigned char) 11)
|
||||
#define TAG_HOSTNAME ((unsigned char) 12)
|
||||
#define TAG_BOOTSIZE ((unsigned char) 13)
|
||||
#define TAG_END ((unsigned char) 255)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* "vendor" data permitted for CMU bootp clients.
|
||||
*/
|
||||
|
||||
struct cmu_vend {
|
||||
unsigned char v_magic[4]; /* magic number */
|
||||
unsigned long v_flags; /* flags/opcodes, etc. */
|
||||
struct in_addr v_smask; /* Subnet mask */
|
||||
struct in_addr v_dgate; /* Default gateway */
|
||||
struct in_addr v_dns1, v_dns2; /* Domain name servers */
|
||||
struct in_addr v_ins1, v_ins2; /* IEN-116 name servers */
|
||||
struct in_addr v_ts1, v_ts2; /* Time servers */
|
||||
unsigned char v_unused[25]; /* currently unused */
|
||||
};
|
||||
|
||||
|
||||
/* v_flags values */
|
||||
#define VF_SMASK 1 /* Subnet mask field contains valid data */
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 1993 Adam Glass
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Adam Glass.
|
||||
* 4. The name of the Author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/boot/Attic/bootparam.c,v 1.1 1993/10/12 06:02:23 glass Exp $
|
||||
*/
|
||||
|
||||
#include "netboot.h"
|
||||
#include "config.h"
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* Copyright (c) 1993 Adam Glass
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Adam Glass.
|
||||
* 4. The name of the Author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/boot/Attic/exec.c,v 1.1 1993/10/12 06:02:25 glass Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
||||
#include <nfs/rpcv2.h>
|
||||
#include <nfs/nfsv2.h>
|
||||
|
||||
#include <a.out.h>
|
||||
|
||||
#include "netboot.h"
|
||||
#include "config.h"
|
||||
#include "netif.h"
|
||||
#include "exec_var.h"
|
||||
|
||||
char *kern_names[] = {
|
||||
"netbsd", "onetbsd", "netbsd.old",
|
||||
MACHINE "bsd", "o" MACHINE "bsd", MACHINE "bsd.old"
|
||||
"vmunix", "ovmunix", "vmunix.old", NULL
|
||||
};
|
||||
|
||||
void nfs_load_image(desc, image, ev)
|
||||
struct iodesc *desc;
|
||||
char *image;
|
||||
struct exec_var *ev;
|
||||
{
|
||||
u_long t;
|
||||
|
||||
t = gettenths();
|
||||
printf("%s: ", image);
|
||||
readseg(desc, ev->text_info.file_offset,
|
||||
ev->text_info.segment_size, ev->text_info.segment_va);
|
||||
printf("%d", ev->text_info.segment_size);
|
||||
readseg(desc, ev->data_info.file_offset,
|
||||
ev->data_info.segment_size, ev->data_info.segment_va);
|
||||
printf("+%d", ev->data_info.segment_size);
|
||||
printf("+%d", ev->bss_info.segment_size);
|
||||
t = gettenths() - t;
|
||||
printf(" [%d.%d seconds]\n", t/10, t%10);
|
||||
}
|
||||
|
||||
unsigned int nfs_load(desc, nfsdp, image)
|
||||
struct iodesc *desc;
|
||||
struct nfs_diskless **nfsdp;
|
||||
char *image;
|
||||
{
|
||||
struct exec_var ev;
|
||||
|
||||
/* get fundamental parameters */
|
||||
if (machdep_exec_override(desc, &ev))
|
||||
if (netbsd_exec(desc, &ev))
|
||||
if (machdep_exec(desc, &ev))
|
||||
panic("nfs_load: unable to understand image");
|
||||
|
||||
machdep_exec_setup(&ev);
|
||||
|
||||
nfs_load_image(desc, image, &ev);
|
||||
|
||||
if (ev.nfs_disklessp)
|
||||
*nfsdp = (struct nfs_diskless *) ev.nfs_disklessp;
|
||||
return ev.real_entry_point;
|
||||
}
|
||||
|
||||
int netbsd_exec_compute(exec, ev)
|
||||
struct exec exec;
|
||||
struct exec_var *ev;
|
||||
{
|
||||
bzero(ev, sizeof(*ev));
|
||||
|
||||
ev->text_info.file_offset = N_TXTOFF(exec);
|
||||
ev->text_info.segment_size = exec.a_text;
|
||||
ev->text_info.segment_addr = N_TXTADDR(exec) + exec.a_entry;
|
||||
|
||||
ev->data_info.file_offset = N_DATOFF(exec);
|
||||
ev->data_info.segment_size = exec.a_data;
|
||||
ev->data_info.segment_addr = N_DATADDR(exec) + exec.a_entry;
|
||||
|
||||
ev->bss_info.file_offset = 0;
|
||||
ev->bss_info.segment_size = exec.a_bss;
|
||||
ev->bss_info.segment_addr = N_DATADDR(exec)+exec.a_data + exec.a_entry;
|
||||
|
||||
ev->entry_point = exec.a_entry;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int netbsd_exec(desc, ev)
|
||||
struct iodesc *desc;
|
||||
struct exec_var *ev;
|
||||
{
|
||||
int cc, error;
|
||||
u_long midmag, magic;
|
||||
u_short mid;
|
||||
struct exec exec;
|
||||
|
||||
cc = readdata(desc, 0, &exec, sizeof(exec));
|
||||
|
||||
if (cc != sizeof(exec))
|
||||
panic("netbsd_exec: image appears truncated\n");
|
||||
if (cc < 0)
|
||||
panic("netbsd_exec: bad exec read\n");
|
||||
if (N_GETMID(exec) != MID_MACHINE) {
|
||||
error = 1;
|
||||
goto failed;
|
||||
}
|
||||
if (N_BADMAG(exec)) {
|
||||
error = 1;
|
||||
goto failed;
|
||||
}
|
||||
error = netbsd_exec_compute(exec, ev);
|
||||
failed:
|
||||
if (error)
|
||||
printf("netbsd_exec: bad exec? code %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
void nfs_exec(desc, kernel_override)
|
||||
struct iodesc *desc;
|
||||
char *kernel_override;
|
||||
{
|
||||
time_t tenths;
|
||||
char *image;
|
||||
u_long ftype, bytes;
|
||||
u_char image_fh[NFS_FHSIZE];
|
||||
struct nfs_diskless *nfsd;
|
||||
unsigned int call_addr;
|
||||
|
||||
nfsd = NULL;
|
||||
image = NULL;
|
||||
|
||||
if (kernel_override) {
|
||||
image = kernel_override;
|
||||
/* Get image file handle and size */
|
||||
if (lookupfh(desc, image, image_fh, NULL, &bytes, &ftype) < 0)
|
||||
panic("nfs_exec: lookup failed %s: %s", image, strerror(errno));
|
||||
if (ftype != NFREG)
|
||||
panic("nfs_exec: bad image ftype %d", ftype);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
|
||||
for (i = 0; kern_names[i]; i++) {
|
||||
if (lookupfh(desc, kern_names[i], image_fh, NULL,
|
||||
&bytes, &ftype) < 0)
|
||||
continue;
|
||||
if (ftype != NFREG)
|
||||
panic("nfs_exec: %s, bad image ftype %d",
|
||||
kern_names[i], ftype);
|
||||
image = kern_names[i];
|
||||
break;
|
||||
}
|
||||
if (!image)
|
||||
panic("nfs_exec: couldn't find kernel");
|
||||
}
|
||||
printf("nfs_exec: %s\n", image);
|
||||
desc->fh = image_fh;
|
||||
call_addr = nfs_load(desc, &nfsd, image);
|
||||
|
||||
#if 0
|
||||
if (nfsd)
|
||||
nfs_diskless_munge(nfsd);
|
||||
#endif
|
||||
/* Now we're ready to fill in the nfs_diskless struct */
|
||||
#if 0
|
||||
if (nfsd)
|
||||
diskless_setup(desc, (struct nfs_diskless_v1 *)sym);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 1993 Adam Glass
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Adam Glass.
|
||||
* 4. The name of the Author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/boot/Attic/exec_var.h,v 1.1 1993/10/12 06:02:26 glass Exp $
|
||||
*/
|
||||
|
||||
struct exec_var_addr {
|
||||
unsigned int file_offset;
|
||||
unsigned int segment_size;
|
||||
unsigned int segment_addr;
|
||||
unsigned int segment_va;
|
||||
};
|
||||
|
||||
typedef struct exec_var_addr exec_var_addr;
|
||||
|
||||
struct exec_var {
|
||||
unsigned int entry_point;
|
||||
unsigned int real_entry_point;
|
||||
caddr_t nfs_disklessp;
|
||||
exec_var_addr text_info;
|
||||
exec_var_addr data_info;
|
||||
exec_var_addr bss_info;
|
||||
};
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 1992 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /cvsroot/src/sys/boot/Attic/in_cksum.c,v 1.1 1993/10/12 06:02:28 glass Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* Checksum routine for Internet Protocol family headers.
|
||||
* This routine is very heavily used in the network
|
||||
* code and should be modified for each CPU to be as fast as possible.
|
||||
* In particular, it should not be this one.
|
||||
*/
|
||||
int
|
||||
in_cksum(p, len)
|
||||
register void *p;
|
||||
register int len;
|
||||
{
|
||||
register int sum = 0, oddbyte = 0, v = 0;
|
||||
register u_char *cp = p;
|
||||
|
||||
/* we assume < 2^16 bytes being summed */
|
||||
while (len > 0) {
|
||||
if (oddbyte) {
|
||||
sum += v + *cp++;
|
||||
len--;
|
||||
}
|
||||
if (((int)cp & 1) == 0) {
|
||||
while ((len -= 2) >= 0) {
|
||||
sum += *(u_short *)cp;
|
||||
cp += 2;
|
||||
}
|
||||
} else {
|
||||
while ((len -= 2) >= 0) {
|
||||
sum += *cp++ << 8;
|
||||
sum += *cp++;
|
||||
}
|
||||
}
|
||||
if ((oddbyte = len & 1) != 0)
|
||||
v = *cp << 8;
|
||||
}
|
||||
if (oddbyte)
|
||||
sum += v;
|
||||
sum = (sum >> 16) + (sum & 0xffff); /* add in accumulated carries */
|
||||
sum += sum >> 16; /* add potential last carry */
|
||||
return (0xffff & ~sum);
|
||||
}
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* Copyright (c) 1992 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /cvsroot/src/sys/boot/Attic/net.c,v 1.1 1993/10/12 06:02:29 glass Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "netboot.h"
|
||||
#include "config.h"
|
||||
#include "netif.h"
|
||||
|
||||
/* Caller must leave room for ethernet, ip and udp headers in front!! */
|
||||
int
|
||||
sendudp(d, buf, len)
|
||||
register struct iodesc *d;
|
||||
register void *buf;
|
||||
register int len;
|
||||
{
|
||||
register int cc;
|
||||
register struct ip *ip;
|
||||
register struct udphdr *up;
|
||||
register u_char *ea;
|
||||
|
||||
if (debug)
|
||||
printf("sendudp: called\n");
|
||||
up = ((struct udphdr *)buf) - 1;
|
||||
ip = ((struct ip *)up) - 1;
|
||||
len += sizeof(*ip) + sizeof(*up);
|
||||
|
||||
bzero(ip, sizeof(*ip) + sizeof(*up));
|
||||
|
||||
ip->ip_v = IPVERSION;
|
||||
ip->ip_hl = sizeof(*ip) >> 2;
|
||||
ip->ip_len = htons(len);
|
||||
ip->ip_p = IPPROTO_UDP;
|
||||
ip->ip_ttl = IP_TTL;
|
||||
ip->ip_src.s_addr = d->myip;
|
||||
ip->ip_dst.s_addr = d->destip;
|
||||
ip->ip_sum = in_cksum(ip, sizeof(*ip));
|
||||
|
||||
up->uh_sport = htons(d->myport);
|
||||
up->uh_dport = htons(d->destport);
|
||||
up->uh_ulen = htons(len - sizeof(*ip));
|
||||
up->uh_sum = in_cksum(up, len - sizeof(*ip));
|
||||
|
||||
if (ip->ip_dst.s_addr == INADDR_BROADCAST || ip->ip_src.s_addr == 0 ||
|
||||
mask == 0 || SAMENET(ip->ip_src.s_addr, ip->ip_dst.s_addr, mask))
|
||||
ea = arpwhohas(d, ip->ip_dst.s_addr);
|
||||
else
|
||||
ea = arpwhohas(d, gateip);
|
||||
|
||||
cc = sendether(d, ip, len, ea, ETHERTYPE_IP);
|
||||
|
||||
if (cc < 0)
|
||||
return (cc);
|
||||
if (cc != len)
|
||||
panic("sendudp: bad write (%d != %d)", cc, len);
|
||||
|
||||
return (cc - (sizeof(*ip) + sizeof(*up)));
|
||||
}
|
||||
|
||||
/* Caller must leave room for ethernet header in front!! */
|
||||
int
|
||||
sendether(d, buf, len, dea, etype)
|
||||
register struct iodesc *d;
|
||||
register void *buf;
|
||||
register int len;
|
||||
register u_char *dea;
|
||||
register int etype;
|
||||
{
|
||||
register struct ether_header *eh;
|
||||
|
||||
if (debug)
|
||||
printf("sendether: called\n");
|
||||
eh = ((struct ether_header *)buf) - 1;
|
||||
len += ETHER_SIZE;
|
||||
|
||||
MACPY(d->myea, eh->ether_shost);
|
||||
MACPY(dea, eh->ether_dhost);
|
||||
|
||||
eh->ether_type = etype;
|
||||
return (ethernet_put(d, eh, len) - ETHER_SIZE);
|
||||
}
|
||||
|
||||
/* Check that packet is a valid udp packet for us */
|
||||
void *
|
||||
checkudp(d, pkt, lenp)
|
||||
register struct iodesc *d;
|
||||
register void *pkt;
|
||||
register int *lenp;
|
||||
{
|
||||
register int hlen, len;
|
||||
register struct ether_header *eh;
|
||||
register struct ip *ip;
|
||||
register struct udphdr *up;
|
||||
|
||||
if (debug)
|
||||
printf("checkudp: called\n");
|
||||
eh = pkt;
|
||||
ip = (struct ip *)(eh + 1);
|
||||
up = (struct udphdr *)(ip + 1);
|
||||
|
||||
/* Must be to us */
|
||||
if (bcmp(d->myea, eh->ether_dhost, 6) != 0 &&
|
||||
bcmp(bcea, eh->ether_dhost, 6) != 0)
|
||||
return (NULL);
|
||||
|
||||
/* And ip */
|
||||
if (eh->ether_type != ETHERTYPE_IP)
|
||||
return (NULL);
|
||||
|
||||
/* Check ip header */
|
||||
if (ip->ip_v != IPVERSION || ip->ip_p != IPPROTO_UDP)
|
||||
return (NULL);
|
||||
|
||||
hlen = ip->ip_hl << 2;
|
||||
if (hlen < sizeof(*ip) || in_cksum(ip, hlen) != 0)
|
||||
return (NULL);
|
||||
NTOHS(ip->ip_len);
|
||||
if (*lenp - sizeof(*eh) < ip->ip_len)
|
||||
return (NULL);
|
||||
if (d->myip && ip->ip_dst.s_addr != d->myip)
|
||||
return (NULL);
|
||||
|
||||
/* If there were ip options, make them go away */
|
||||
if (hlen != sizeof(*ip)) {
|
||||
bcopy(((u_char *)ip) + hlen, up,
|
||||
*lenp - (sizeof(*eh) + hlen));
|
||||
ip->ip_len = sizeof(*ip);
|
||||
*lenp -= hlen - sizeof(*ip);
|
||||
}
|
||||
if (ntohs(up->uh_dport) != d->myport)
|
||||
return (NULL);
|
||||
|
||||
if (up->uh_sum) {
|
||||
len = ntohs(up->uh_ulen);
|
||||
if (len > RECV_SIZE - (sizeof(*eh) + sizeof(*ip))) {
|
||||
printf("checkudp: huge packet, udp len %lu\n", len);
|
||||
return (NULL);
|
||||
}
|
||||
if (in_cksum(up, len) != 0)
|
||||
return (NULL);
|
||||
}
|
||||
NTOHS(up->uh_dport);
|
||||
NTOHS(up->uh_sport);
|
||||
NTOHS(up->uh_ulen);
|
||||
if (up->uh_ulen < sizeof(*up))
|
||||
return (NULL);
|
||||
*lenp -= sizeof(*eh) + sizeof(*ip) + sizeof(*up);
|
||||
return (up + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a packet and wait for a reply, with exponential backoff.
|
||||
*
|
||||
* The send routine must return the actual number of bytes written.
|
||||
*
|
||||
* The receive routine can indicate success by returning the number of
|
||||
* bytes read; it can return 0 to indicate EOF; it can return -1 with a
|
||||
* non-zero errno to indicate failure; finally, it can return -1 with a
|
||||
* zero errno to indicate it isn't done yet.
|
||||
*/
|
||||
int
|
||||
sendrecv(d, sproc, sbuf, ssize, rproc, rbuf, rsize)
|
||||
register struct iodesc *d;
|
||||
register int (*sproc)(struct iodesc *, void *, int);
|
||||
register void *sbuf;
|
||||
register int ssize;
|
||||
register int (*rproc)(struct iodesc *, void *, int);
|
||||
register void *rbuf;
|
||||
register int rsize;
|
||||
{
|
||||
register int cc;
|
||||
register time_t t, tmo, tlast, tleft;
|
||||
|
||||
if (debug)
|
||||
printf("sendrecv: called\n");
|
||||
tmo = MINTMO;
|
||||
tlast = tleft = 0;
|
||||
t = getsecs();
|
||||
for (;;) {
|
||||
if (tleft <= 0) {
|
||||
cc = (*sproc)(d, sbuf, ssize);
|
||||
if (cc < ssize)
|
||||
panic("sendrecv: short write! (%d < %d)",
|
||||
cc, ssize);
|
||||
|
||||
tleft = tmo;
|
||||
tmo <<= 1;
|
||||
if (tmo > MAXTMO)
|
||||
tmo = MAXTMO;
|
||||
tlast = t;
|
||||
}
|
||||
|
||||
cc = ethernet_get(d, rbuf, rsize, tleft);
|
||||
if (cc >= 0) {
|
||||
/* Got a packet, process it */
|
||||
cc = (*rproc)(d, rbuf, cc);
|
||||
/* Return on data, EOF or real error */
|
||||
if (cc >= 0 || errno != 0)
|
||||
return (cc);
|
||||
}
|
||||
/* Timed out or didn't get the packet we're waiting for */
|
||||
t = getsecs();
|
||||
tleft -= t - tlast;
|
||||
tlast = t;
|
||||
}
|
||||
}
|
||||
|
||||
int ethernet_get(desc, pkt, len, timeout)
|
||||
struct iodesc *desc;
|
||||
void *pkt;
|
||||
int len;
|
||||
time_t timeout;
|
||||
{
|
||||
int val;
|
||||
val = desc->io_netif->netif_get(desc, pkt, len, timeout);
|
||||
if (debug)
|
||||
printf("ethernet_get: received %d\n", val);
|
||||
return val;
|
||||
}
|
||||
int ethernet_put(desc, pkt, len)
|
||||
struct iodesc *desc;
|
||||
void *pkt;
|
||||
int len;
|
||||
{
|
||||
int count, val;
|
||||
|
||||
if (debug) {
|
||||
struct ether_header *eh;
|
||||
|
||||
printf("ethernet_put: called\n");
|
||||
eh = pkt;
|
||||
printf("ethernet_put: ether_dhost %s\n",
|
||||
ether_sprintf(eh->ether_dhost));
|
||||
printf("ethernet_put: ether_shost %s\n",
|
||||
ether_sprintf(eh->ether_shost));
|
||||
printf("ethernet_put: ether_type %x\n", eh->ether_type);
|
||||
}
|
||||
if (!desc->io_netif)
|
||||
panic("ethernet_put: no netif_put support");
|
||||
val = desc->io_netif->netif_put(desc, pkt, len);
|
||||
return val;
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (c) 1993 Adam Glass
|
||||
* Copyright (c) 1992 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /cvsroot/src/sys/boot/Attic/netboot.h,v 1.1 1993/10/12 06:02:31 glass Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#define BA { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
|
||||
|
||||
/* Returns true if n_long's on the same net */
|
||||
#define SAMENET(a1, a2, m) ((a1 & m) == (a2 & m))
|
||||
|
||||
#define MACPY(s, d) bcopy((char *)s, (char *)d, 6)
|
||||
|
||||
#define MAXTMO 20 /* seconds */
|
||||
#define MINTMO 2 /* seconds */
|
||||
|
||||
#define FNAME_SIZE 128
|
||||
#define IFNAME_SIZE 16
|
||||
#define RECV_SIZE 1536 /* XXX delete this */
|
||||
|
||||
/* Size of struct ether_header + struct ip + struct udphdr */
|
||||
#define ETHER_SIZE 14
|
||||
#define HEADER_SIZE (ETHER_SIZE + 20 + 8)
|
||||
|
||||
struct iodesc {
|
||||
n_long destip; /* destination ip address */
|
||||
n_long myip; /* my ip address */
|
||||
u_short destport; /* destination port */
|
||||
u_short myport; /* destination port */
|
||||
u_long xid; /* transaction identification */
|
||||
u_char myea[6]; /* my ethernet address */
|
||||
u_char *fh; /* pointer to file handle */
|
||||
struct netif *io_netif;
|
||||
};
|
||||
|
||||
extern u_char bcea[6];
|
||||
extern char rootpath[FNAME_SIZE];
|
||||
extern char swappath[FNAME_SIZE];
|
||||
extern char ifname[IFNAME_SIZE];
|
||||
extern n_long rootip;
|
||||
extern n_long swapip;
|
||||
extern n_long gateip;
|
||||
extern n_long smask;
|
||||
extern n_long nmask;
|
||||
extern n_long mask;
|
||||
extern time_t bot;
|
||||
extern int debug;
|
||||
|
||||
u_char *arpwhohas __P((struct iodesc *, n_long));
|
||||
|
||||
void getnfsfh __P((struct iodesc *, char *, u_char *));
|
||||
void getnfsinfo __P((struct iodesc *, time_t *, u_long *, u_long *));
|
||||
int lookupfh __P((struct iodesc *, char *, u_char *, time_t *,
|
||||
u_long *, u_long *));
|
||||
int readdata __P((struct iodesc *, u_long, void *, u_long));
|
||||
void readseg __P((struct iodesc *, u_long, u_long, u_long));
|
||||
|
||||
|
||||
void ethernet_init __P((struct iodesc *));
|
||||
int ethernet_put __P((struct iodesc *, void *, int));
|
||||
int ethernet_poll __P((struct iodesc *, void *, int));
|
||||
int ethernet_get __P((struct iodesc *, void *, int, time_t));
|
||||
void ethernet_macaddr __P((struct iodesc *, int, u_char *));
|
||||
time_t getsecs __P((void));
|
||||
u_long gettenths __P((void));
|
||||
|
||||
int sendether __P((struct iodesc *, void *, int, u_char *, int));
|
||||
int sendudp __P((struct iodesc *, void *, int));
|
||||
int recvudp __P((struct iodesc *, void *, int, time_t));
|
||||
int sendrecv __P((struct iodesc *, int (*)(struct iodesc *, void *, int),
|
||||
void *, int, int (*)(struct iodesc *, void *, int), void *, int));
|
||||
void *checkudp __P((struct iodesc *, void *, int *));
|
||||
|
||||
void panic __P((const char *, ...));
|
||||
char *ether_sprintf __P((u_char *));
|
||||
int in_cksum __P((void *, int));
|
||||
void call __P((u_long));
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 1993 Adam Glass
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Adam Glass.
|
||||
* 4. The name of the Author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/boot/Attic/netif.c,v 1.1 1993/10/12 06:02:33 glass Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/mount.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
||||
#include "netboot.h"
|
||||
#include "config.h"
|
||||
#include "netif.h"
|
||||
|
||||
static int netif_newp = 0; /* an optimization to skip over exhausted netifs */
|
||||
|
||||
void netif_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
if (debug)
|
||||
printf("netif_init: called\n");
|
||||
for (i =0; i < n_netif; i++) {
|
||||
netiftab[i]->netif_unit;
|
||||
netiftab[i]->netif_exhausted = 0;
|
||||
}
|
||||
}
|
||||
int netif_match(nif, machdep_hint, unitp)
|
||||
struct netif *nif;
|
||||
void *machdep_hint;
|
||||
int *unitp;
|
||||
{
|
||||
if (debug)
|
||||
printf("netif_match: called\n");
|
||||
return nif->netif_match(machdep_hint, unitp);
|
||||
}
|
||||
|
||||
struct netif *netif_select(machdep_hint)
|
||||
void *machdep_hint;
|
||||
{
|
||||
int i;
|
||||
struct netif *best_if = NULL;
|
||||
int best_unit;
|
||||
int best_val;
|
||||
int val, unit;
|
||||
|
||||
best_val = 0;
|
||||
if (debug)
|
||||
printf("network interfaces: %d\n", n_netif);
|
||||
for (i = netif_newp; i < n_netif; i++) {
|
||||
val = netif_match(netiftab[i], machdep_hint, &unit);
|
||||
if (val == 0) {
|
||||
netiftab[i]->netif_exhausted = 1;
|
||||
continue;
|
||||
}
|
||||
if (debug)
|
||||
printf("netif_select: %s%d = %d\n", netiftab[i]->netif_bname,
|
||||
netiftab[i]->netif_unit, val);
|
||||
if (val > best_val) {
|
||||
best_if = netiftab[i];
|
||||
best_unit = unit;
|
||||
}
|
||||
}
|
||||
if (!best_if) return NULL;
|
||||
best_if->netif_unit = best_unit;
|
||||
return best_if;
|
||||
}
|
||||
|
||||
int netif_probe(nif, machdep_hint)
|
||||
struct netif *nif;
|
||||
void *machdep_hint;
|
||||
{
|
||||
if (debug)
|
||||
printf("netif_probe: called\n");
|
||||
return nif->netif_probe(machdep_hint);
|
||||
}
|
||||
|
||||
void netif_attach(nif, desc, machdep_hint)
|
||||
struct netif *nif;
|
||||
struct iodesc *desc;
|
||||
void *machdep_hint;
|
||||
{
|
||||
if (debug)
|
||||
printf("netif_attach: called\n");
|
||||
nif->netif_init(desc, machdep_hint);
|
||||
desc->io_netif = nif;
|
||||
bzero(desc->io_netif->netif_stats, *desc->io_netif->netif_stats);
|
||||
}
|
||||
void netif_detach(nif)
|
||||
struct netif *nif;
|
||||
{
|
||||
if (debug)
|
||||
printf("netif_detach: called\n");
|
||||
nif->netif_end();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
struct netif {
|
||||
char *netif_bname;
|
||||
int netif_unit;
|
||||
int netif_exhausted;
|
||||
int (*netif_match) __P((void *, int *));
|
||||
int (*netif_probe) __P((void *));
|
||||
void (*netif_init) __P((struct iodesc *, void *));
|
||||
int (*netif_get) __P((struct iodesc *, void *, int, time_t));
|
||||
int (*netif_put) __P((struct iodesc *, void *, int));
|
||||
void (*netif_end) __P((void));
|
||||
struct netif_stats *netif_stats;
|
||||
};
|
||||
|
||||
struct netif_stats {
|
||||
int collisions;
|
||||
int collision_error;
|
||||
int missed;
|
||||
int sent;
|
||||
int received;
|
||||
int deferred;
|
||||
int overflow;
|
||||
};
|
||||
extern struct netif *netiftab[];
|
||||
|
||||
extern int n_netif;
|
||||
|
||||
void netif_init __P((void));
|
||||
struct netif *netif_select __P((void *));
|
||||
int netif_probe __P((struct netif *, void *));
|
||||
void netif_attach __P((struct netif *, struct iodesc *, void *));
|
||||
void netif_detach __P((struct netif *));
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Copyright (c) 1993 Adam Glass
|
||||
* All rights reserved.
|
||||
*
|
||||
* A lot of this code is derived material from the LBL bootbootp release,
|
||||
* thus their copyright below.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Adam Glass.
|
||||
* 4. The name of the Author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/boot/Attic/nfsboot.c,v 1.1 1993/10/12 06:02:38 glass Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1992 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /cvsroot/src/sys/boot/Attic/nfsboot.c,v 1.1 1993/10/12 06:02:38 glass Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/mount.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
||||
#include <nfs/rpcv2.h>
|
||||
#include <nfs/nfsv2.h>
|
||||
|
||||
#include "netboot.h"
|
||||
#include "config.h"
|
||||
#include "bootbootp.h"
|
||||
#include "bootp.h"
|
||||
#include "netif.h"
|
||||
|
||||
/* Globals */
|
||||
u_char bcea[6] = BA; /* broadcast ethernet address */
|
||||
char rootpath[FNAME_SIZE]; /* root mount path */
|
||||
char swappath[FNAME_SIZE]; /* swap mount path */
|
||||
char ifname[IFNAME_SIZE]; /* name of interface (e.g. "le0") */
|
||||
n_long rootip; /* root ip address */
|
||||
n_long swapip; /* swap ip address */
|
||||
n_long gateip; /* swap ip address */
|
||||
n_long smask; /* subnet mask */
|
||||
n_long nmask; /* net mask */
|
||||
n_long mask; /* subnet or net mask */
|
||||
time_t bot; /* beginning of time in seconds */
|
||||
|
||||
#ifdef DEBUG
|
||||
int debug = 1;
|
||||
#else
|
||||
int debug = 0;
|
||||
#endif
|
||||
|
||||
static u_char rootfh[NFS_FHSIZE];
|
||||
static u_char swapfh[NFS_FHSIZE];
|
||||
static u_long swapblks;
|
||||
static time_t roottime;
|
||||
|
||||
void nfs_setup(desc)
|
||||
struct iodesc *desc;
|
||||
{
|
||||
u_long ftype, bytes;
|
||||
|
||||
bcopy(&desc->myea[4], &desc->myport, 2);
|
||||
|
||||
printf("myip: %s", intoa(desc->myip));
|
||||
if (gateip)
|
||||
printf(", gateip: %s", intoa(gateip));
|
||||
if (mask)
|
||||
printf(", mask: %s", intoa(mask));
|
||||
printf("\n");
|
||||
printf("root: %s:%s\n", intoa(rootip), rootpath);
|
||||
printf("swap: %s:%s\n", intoa(swapip), swappath);
|
||||
|
||||
/* Get root file handle and timestamp */
|
||||
desc->destip = rootip;
|
||||
getnfsfh(desc, rootpath, rootfh);
|
||||
desc->fh = rootfh;
|
||||
getnfsinfo(desc, &roottime, NULL, &ftype);
|
||||
if (ftype != NFDIR)
|
||||
panic("bad root ftype %d", ftype);
|
||||
if (debug)
|
||||
printf("nfs_setup: got root fh\n");
|
||||
|
||||
desc->destip = swapip;
|
||||
getnfsfh(desc, swappath, swapfh);
|
||||
desc->fh = swapfh;
|
||||
getnfsinfo(desc, NULL, &bytes, &ftype);
|
||||
if (bytes % 512)
|
||||
printf("warning: swap is odd sized\n");
|
||||
if (ftype != NFREG)
|
||||
panic("bad swap ftype %d\n", ftype);
|
||||
swapblks = bytes / 512;
|
||||
if (debug)
|
||||
printf("nfs_setup: got swap fh\n");
|
||||
printf("swap: %d (%d blocks)\n", bytes, swapblks);
|
||||
desc->destip = rootip;
|
||||
desc->fh = rootfh;
|
||||
}
|
||||
|
||||
|
||||
unsigned int nfs_boot(kernel_override, machdep_hint)
|
||||
char *kernel_override;
|
||||
void *machdep_hint;
|
||||
{
|
||||
/*
|
||||
* 0. get common ether addr if exists
|
||||
* 1. choose interface
|
||||
* 2. set up interface
|
||||
* 3. bootp or bootparam
|
||||
* 4. get filesystem fh information
|
||||
* 5. get swap information
|
||||
* 6. load kernel
|
||||
* 7. if nfs_diskless crud, do the right thign
|
||||
* 8. run kernel
|
||||
*/
|
||||
struct iodesc *desc;
|
||||
struct iodesc desc_store;
|
||||
struct netif *nif;
|
||||
|
||||
desc = &desc_store;
|
||||
netif_init();
|
||||
while (1) {
|
||||
bzero(desc, sizeof(*desc));
|
||||
#ifdef COMMON_ETHERADDR
|
||||
machdep_common_ether(desc->myea);
|
||||
#endif
|
||||
nif = netif_select(machdep_hint);
|
||||
if (!nif)
|
||||
panic("netboot: no interfaces left untried");
|
||||
if (netif_probe(nif, machdep_hint)) {
|
||||
printf("netboot: couldn't probe %s%d\n",
|
||||
nif->netif_bname, nif->netif_unit);
|
||||
continue;
|
||||
}
|
||||
netif_attach(nif, desc, machdep_hint);
|
||||
|
||||
get_bootinfo(desc);
|
||||
nfs_setup(desc);
|
||||
nfs_exec(desc, kernel_override);
|
||||
failed: netif_detach(nif);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,617 @@
|
|||
/*
|
||||
* Copyright (c) 1992 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /cvsroot/src/sys/boot/Attic/rpc.c,v 1.1 1993/10/12 06:02:40 glass Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
||||
#include <nfs/rpcv2.h>
|
||||
#include <nfs/nfsv2.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "netboot.h"
|
||||
#include "netif.h"
|
||||
#include "config.h"
|
||||
#include "bootbootp.h"
|
||||
|
||||
/* XXX defines we can't easily get from system includes */
|
||||
#define PMAPPORT 111
|
||||
#define PMAPPROG 100000
|
||||
#define PMAPVERS 2
|
||||
#define PMAPPROC_GETPORT 3
|
||||
|
||||
#define RPC_MSG_VERSION 2
|
||||
#define MSG_ACCEPTED 0
|
||||
#define CALL 0
|
||||
#define REPLY 1
|
||||
|
||||
/* Null rpc auth info */
|
||||
struct auth_info {
|
||||
int rp_atype; /* zero (really AUTH_NULL) */
|
||||
u_long rp_alen; /* zero (size of auth struct) */
|
||||
};
|
||||
|
||||
/* Generic rpc call header */
|
||||
struct rpc_call {
|
||||
u_long rp_xid; /* request transaction id */
|
||||
int rp_direction; /* call direction */
|
||||
u_long rp_rpcvers; /* rpc version (2) */
|
||||
u_long rp_prog; /* program */
|
||||
u_long rp_vers; /* version */
|
||||
u_long rp_proc; /* procedure */
|
||||
struct auth_info rp_auth; /* AUTH_NULL */
|
||||
struct auth_info rp_verf; /* AUTH_NULL */
|
||||
};
|
||||
|
||||
/* Generic rpc reply header */
|
||||
struct rpc_reply {
|
||||
u_long rp_xid; /* request transaction id */
|
||||
int rp_direction; /* call direction */
|
||||
int rp_stat; /* accept status */
|
||||
u_long rp_prog; /* program (unused) */
|
||||
u_long rp_vers; /* version (unused) */
|
||||
u_long rp_proc; /* procedure (unused) */
|
||||
};
|
||||
|
||||
struct nfs_call_data {
|
||||
u_char fh[NFS_FHSIZE];
|
||||
u_long off;
|
||||
u_long len;
|
||||
u_long xxx; /* XXX what's this for? */
|
||||
};
|
||||
|
||||
/* Data part of nfs rpc reply (also the largest thing we receive) */
|
||||
struct nfs_reply_data {
|
||||
u_long errno;
|
||||
struct nfsv2_fattr fa;
|
||||
u_long count;
|
||||
u_char data[1200];
|
||||
};
|
||||
#define NFSREAD_SIZE sizeof(((struct nfs_reply_data *)0)->data)
|
||||
|
||||
/* Cache stuff */
|
||||
#define PMAP_NUM 8 /* need at most 5 pmap entries */
|
||||
|
||||
static struct pmap_list {
|
||||
u_long addr; /* address of server */
|
||||
u_long prog;
|
||||
u_long vers;
|
||||
u_short port; /* cached port for service */
|
||||
} pmap_list[PMAP_NUM] = {
|
||||
{ 0, PMAPPROG, PMAPVERS, PMAPPORT }
|
||||
};
|
||||
static int pmap_num = 1;
|
||||
|
||||
/* Local forwards */
|
||||
static int callrpc __P((struct iodesc *, u_long, u_long, u_long,
|
||||
void *, int, void *, int));
|
||||
static int recvrpc __P((struct iodesc *, void *, int));
|
||||
static u_short getport __P((struct iodesc *, u_long, u_long));
|
||||
|
||||
/* Make a rpc call; return length of answer */
|
||||
static int
|
||||
callrpc(d, prog, vers, proc, sdata, slen, rdata, rlen)
|
||||
register struct iodesc *d;
|
||||
register u_long prog, vers, proc;
|
||||
register void *sdata;
|
||||
register int slen;
|
||||
register void *rdata;
|
||||
register int rlen;
|
||||
{
|
||||
register int cc;
|
||||
register struct rpc_call *rpc;
|
||||
struct {
|
||||
u_char header[HEADER_SIZE];
|
||||
struct rpc_call wrpc;
|
||||
u_char data[sizeof(struct nfs_reply_data)]; /* XXX */
|
||||
} wbuf;
|
||||
struct {
|
||||
u_char header[HEADER_SIZE];
|
||||
struct rpc_reply rrpc;
|
||||
union {
|
||||
u_long errno;
|
||||
u_char data[sizeof(struct nfs_reply_data)];
|
||||
} ru;
|
||||
} rbuf;
|
||||
|
||||
if (debug)
|
||||
printf("callrpc: called\n");
|
||||
if (rlen > sizeof(rbuf.ru.data))
|
||||
panic("callrpc: huge read (%d > %d)",
|
||||
rlen, sizeof(rbuf.ru.data));
|
||||
|
||||
d->destport = getport(d, prog, vers);
|
||||
|
||||
rpc = &wbuf.wrpc;
|
||||
|
||||
bzero(rpc, sizeof(*rpc));
|
||||
|
||||
rpc->rp_xid = d->xid;
|
||||
rpc->rp_rpcvers = htonl(RPC_MSG_VERSION);
|
||||
rpc->rp_prog = htonl(prog);
|
||||
rpc->rp_vers = htonl(vers);
|
||||
rpc->rp_proc = htonl(proc);
|
||||
bcopy(sdata, wbuf.data, slen);
|
||||
|
||||
cc = sendrecv(d, sendudp, rpc, sizeof(*rpc) + slen, recvrpc,
|
||||
((u_char *)&rbuf.rrpc) - HEADER_SIZE, sizeof(rbuf) - HEADER_SIZE);
|
||||
|
||||
if (cc < rlen) {
|
||||
/* Check for an error return */
|
||||
if (cc >= sizeof(rbuf.ru.errno) && rbuf.ru.errno != 0) {
|
||||
errno = ntohl(rbuf.ru.errno);
|
||||
return (-1);
|
||||
}
|
||||
panic("callrpc: missing data (%d < %d)", cc, rlen);
|
||||
}
|
||||
if (cc > sizeof(rbuf.ru.data))
|
||||
panic("callrpc: huge return (%d > %d)",
|
||||
cc, sizeof(rbuf.ru.data));
|
||||
bcopy(rbuf.ru.data, rdata, cc);
|
||||
return (cc);
|
||||
}
|
||||
|
||||
/* Returns true if packet is the one we're waiting for */
|
||||
static int
|
||||
recvrpc(d, pkt, len)
|
||||
register struct iodesc *d;
|
||||
register void *pkt;
|
||||
int len;
|
||||
{
|
||||
register struct rpc_reply *rpc;
|
||||
|
||||
if (debug)
|
||||
printf("recvrpc: called\n");
|
||||
rpc = (struct rpc_reply *)checkudp(d, pkt, &len);
|
||||
if (rpc == NULL || len < sizeof(*rpc)) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
NTOHL(rpc->rp_direction);
|
||||
NTOHL(rpc->rp_stat);
|
||||
|
||||
if (rpc->rp_xid != d->xid || rpc->rp_direction != REPLY ||
|
||||
rpc->rp_stat != MSG_ACCEPTED) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Bump xid so next request will be unique */
|
||||
++d->xid;
|
||||
|
||||
/* Return data count (thus indicating success) */
|
||||
return (len - sizeof(*rpc));
|
||||
}
|
||||
|
||||
/* Request a port number from the port mapper */
|
||||
static u_short
|
||||
getport(d, prog, vers)
|
||||
register struct iodesc *d;
|
||||
u_long prog;
|
||||
u_long vers;
|
||||
{
|
||||
register int i;
|
||||
register struct pmap_list *pl;
|
||||
u_long port;
|
||||
struct {
|
||||
u_long prog; /* call program */
|
||||
u_long vers; /* call version */
|
||||
u_long proto; /* call protocol */
|
||||
u_long port; /* call port (unused) */
|
||||
} sdata;
|
||||
|
||||
if (debug)
|
||||
printf("getport: called\n");
|
||||
/* Try for cached answer first */
|
||||
for (i = 0, pl = pmap_list; i < pmap_num; ++i, ++pl)
|
||||
if ((pl->addr == d->destip || pl->addr == 0) &&
|
||||
pl->prog == prog && pl->vers == vers)
|
||||
return (pl->port);
|
||||
|
||||
/* Don't overflow cache */
|
||||
if (pmap_num > PMAP_NUM - 1)
|
||||
panic("getport: overflowed pmap_list!");
|
||||
|
||||
sdata.prog = htonl(prog);
|
||||
sdata.vers = htonl(vers);
|
||||
sdata.proto = htonl(IPPROTO_UDP);
|
||||
sdata.port = 0;
|
||||
|
||||
if (callrpc(d, PMAPPROG, PMAPVERS, PMAPPROC_GETPORT,
|
||||
&sdata, sizeof(sdata), &port, sizeof(port)) < 0)
|
||||
panic("getport: %s", strerror(errno));
|
||||
|
||||
/* Cache answer */
|
||||
pl->addr = d->destip;
|
||||
pl->prog = prog;
|
||||
pl->vers = vers;
|
||||
pl->port = port;
|
||||
++pmap_num;
|
||||
|
||||
return ((u_short)port);
|
||||
}
|
||||
|
||||
/* Fetch file handle */
|
||||
void
|
||||
getnfsfh(d, path, fhp)
|
||||
register struct iodesc *d;
|
||||
char *path;
|
||||
u_char *fhp;
|
||||
{
|
||||
register int len;
|
||||
struct {
|
||||
u_long len;
|
||||
char path[FNAME_SIZE];
|
||||
} sdata;
|
||||
struct {
|
||||
u_long errno;
|
||||
u_char fh[NFS_FHSIZE];
|
||||
} rdata;
|
||||
|
||||
if (debug)
|
||||
printf("getnfsfh: called\n");
|
||||
bzero(&sdata, sizeof(sdata));
|
||||
len = strlen(path);
|
||||
if (len > sizeof(sdata.path))
|
||||
len = sizeof(sdata.path);
|
||||
bcopy(path, sdata.path, len);
|
||||
sdata.len = htonl(len);
|
||||
len = sizeof(sdata) - sizeof(sdata.path) + roundup(len, sizeof(long));
|
||||
|
||||
if (callrpc(d, RPCPROG_MNT, RPCMNT_VER1, RPCMNT_MOUNT,
|
||||
&sdata, len, &rdata, sizeof(rdata)) < 0)
|
||||
panic("getnfsfh: %s", strerror(errno));
|
||||
|
||||
bcopy(rdata.fh, fhp, sizeof(rdata.fh));
|
||||
}
|
||||
|
||||
/* Fetch file timestamp and size */
|
||||
void
|
||||
getnfsinfo(d, tp, sp, fp)
|
||||
register struct iodesc *d;
|
||||
register time_t *tp;
|
||||
register u_long *sp, *fp;
|
||||
{
|
||||
struct {
|
||||
u_long errno;
|
||||
struct nfsv2_fattr fa;
|
||||
} rdata;
|
||||
|
||||
if (debug)
|
||||
printf("getnfsinfo: called\n");
|
||||
if (callrpc(d, NFS_PROG, NFS_VER2, NFSPROC_GETATTR,
|
||||
d->fh, NFS_FHSIZE, &rdata, sizeof(rdata)) < 0)
|
||||
panic("getnfsfh: %s", strerror(errno));
|
||||
|
||||
if (tp)
|
||||
*tp = ntohl(rdata.fa.fa_ctime.tv_sec);
|
||||
if (sp)
|
||||
*sp = ntohl(rdata.fa.fa_size);
|
||||
if (fp)
|
||||
*fp = ntohl(rdata.fa.fa_type);
|
||||
}
|
||||
|
||||
/* Lookup a file. Optionally return timestamp and size */
|
||||
int
|
||||
lookupfh(d, name, fhp, tp, sp, fp)
|
||||
register struct iodesc *d;
|
||||
register char *name;
|
||||
register u_char *fhp;
|
||||
register time_t *tp;
|
||||
register u_long *sp, *fp;
|
||||
{
|
||||
register int len;
|
||||
struct {
|
||||
u_char fh[NFS_FHSIZE];
|
||||
u_long len;
|
||||
char name[FNAME_SIZE];
|
||||
} sdata;
|
||||
struct {
|
||||
u_long errno;
|
||||
u_char fh[NFS_FHSIZE];
|
||||
struct nfsv2_fattr fa;
|
||||
} rdata;
|
||||
|
||||
if (debug)
|
||||
printf("lookupfh: called\n");
|
||||
|
||||
bzero(&sdata, sizeof(sdata));
|
||||
bcopy(d->fh, sdata.fh, sizeof(sdata.fh));
|
||||
len = strlen(name);
|
||||
if (len > sizeof(sdata.name))
|
||||
len = sizeof(sdata.name);
|
||||
bcopy(name, sdata.name, len);
|
||||
sdata.len = htonl(len);
|
||||
len = sizeof(sdata) - sizeof(sdata.name) + roundup(len, sizeof(long));
|
||||
|
||||
if (callrpc(d, NFS_PROG, NFS_VER2, NFSPROC_LOOKUP,
|
||||
&sdata, len, &rdata, sizeof(rdata)) < 0)
|
||||
return (-1);
|
||||
|
||||
bcopy(rdata.fh, fhp, sizeof(rdata.fh));
|
||||
if (tp)
|
||||
*tp = ntohl(rdata.fa.fa_ctime.tv_sec);
|
||||
if (sp)
|
||||
*sp = ntohl(rdata.fa.fa_size);
|
||||
if (fp)
|
||||
*fp = ntohl(rdata.fa.fa_type);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int sendreaddata __P((struct iodesc *, void *, int));
|
||||
static int recvreaddata __P((struct iodesc *, void *, int));
|
||||
|
||||
/* max number of nfs reads pending */
|
||||
#define NFS_COUNT 10
|
||||
|
||||
static struct nfsstate {
|
||||
u_long off;
|
||||
u_long len;
|
||||
int done;
|
||||
void *addr;
|
||||
u_long xid;
|
||||
} nfsstate[NFS_COUNT];
|
||||
|
||||
static u_long nfscc;
|
||||
|
||||
static int
|
||||
sendreaddata(d, pkt, len)
|
||||
register struct iodesc *d;
|
||||
register void *pkt;
|
||||
register int len;
|
||||
{
|
||||
register int i;
|
||||
register u_long cc;
|
||||
register struct rpc_call *rpc;
|
||||
register struct nfs_call_data *nfs;
|
||||
register struct nfsstate *ns;
|
||||
|
||||
if (debug)
|
||||
printf("sendreaddata: called\n");
|
||||
|
||||
if (len != sizeof(*rpc) + sizeof(*nfs))
|
||||
panic("sendreaddata: bad buffer (%d != %d)",
|
||||
len, sizeof(*rpc) + sizeof(*nfs));
|
||||
rpc = pkt;
|
||||
nfs = (struct nfs_call_data *)(rpc + 1);
|
||||
for (i = 0, ns = nfsstate; i < NFS_COUNT; ++i, ++ns) {
|
||||
if (ns->done)
|
||||
continue;
|
||||
|
||||
rpc->rp_xid = ns->xid;
|
||||
nfs->off = htonl(ns->off);
|
||||
nfs->len = htonl(ns->len);
|
||||
cc = sendudp(d, rpc, len);
|
||||
|
||||
if (cc != len)
|
||||
panic("sendreaddata: short write (%d != %d)", cc, len);
|
||||
}
|
||||
/* XXX we may have actually sent a lot more bytes... */
|
||||
|
||||
return (len);
|
||||
}
|
||||
|
||||
/* Returns char count if done else -1 (and errno == 0) */
|
||||
static int
|
||||
recvreaddata(d, pkt, len)
|
||||
register struct iodesc *d;
|
||||
register void *pkt;
|
||||
int len;
|
||||
{
|
||||
register int i;
|
||||
register struct rpc_reply *rpc;
|
||||
register struct nfs_reply_data *nfs;
|
||||
register struct nfsstate *ns;
|
||||
|
||||
if (debug)
|
||||
printf("recvreaddata: called\n");
|
||||
rpc = (struct rpc_reply *)checkudp(d, pkt, &len);
|
||||
if (rpc == NULL || len < sizeof(*rpc)) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
len -= sizeof(*rpc);
|
||||
|
||||
NTOHL(rpc->rp_direction);
|
||||
NTOHL(rpc->rp_stat);
|
||||
|
||||
if (rpc->rp_direction != REPLY || rpc->rp_stat != MSG_ACCEPTED) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (i = 0, ns = nfsstate; i < NFS_COUNT; ++i, ++ns)
|
||||
if (rpc->rp_xid == ns->xid)
|
||||
break;
|
||||
if (i >= NFS_COUNT) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (ns->done) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
nfs = (struct nfs_reply_data *)(rpc + 1);
|
||||
if (len < sizeof(nfs->errno))
|
||||
panic("recvreaddata: bad read %d", len);
|
||||
if (nfs->errno) {
|
||||
errno = ntohl(nfs->errno);
|
||||
return (-1);
|
||||
}
|
||||
if (len < sizeof(*nfs) - sizeof(nfs->data))
|
||||
panic("recvreaddata: less than nfs sized %d", len);
|
||||
len -= sizeof(*nfs) - sizeof(nfs->data);
|
||||
|
||||
if (len < nfs->count)
|
||||
panic("recvreaddata: short read (%d < %d)", len, nfs->count);
|
||||
len = nfs->count;
|
||||
if (len > ns->len)
|
||||
panic("recvreaddata: huge read (%d > %d)", len, ns->len);
|
||||
|
||||
bcopy(nfs->data, ns->addr, len);
|
||||
ns->done = 1;
|
||||
nfscc += len;
|
||||
|
||||
if (len < ns->len) {
|
||||
/* If first packet assume no more data to read */
|
||||
if (i == 0)
|
||||
return (0);
|
||||
|
||||
/* Short read, assume we are at EOF */
|
||||
++i;
|
||||
++ns;
|
||||
while (i < NFS_COUNT) {
|
||||
ns->done = 1;
|
||||
++i;
|
||||
++ns;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0, ns = nfsstate; i < NFS_COUNT; ++i, ++ns)
|
||||
if (!ns->done) {
|
||||
errno = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Return data count (thus indicating success) */
|
||||
return (nfscc);
|
||||
}
|
||||
|
||||
/* Read data from a file */
|
||||
int
|
||||
readdata(d, off, addr, len)
|
||||
register struct iodesc *d;
|
||||
register u_long off;
|
||||
register void *addr;
|
||||
register u_long len;
|
||||
{
|
||||
register int i, cc;
|
||||
register struct rpc_call *rpc;
|
||||
register struct nfsstate *ns;
|
||||
struct {
|
||||
u_char header[HEADER_SIZE];
|
||||
struct rpc_call rpc;
|
||||
struct nfs_call_data nfs;
|
||||
} sdata;
|
||||
struct {
|
||||
u_char header[HEADER_SIZE];
|
||||
struct rpc_call rpc;
|
||||
struct nfs_reply_data nfs;
|
||||
} rdata;
|
||||
|
||||
if (debug)
|
||||
printf("readdata: called\n");
|
||||
if (len == 0)
|
||||
return (0);
|
||||
d->destport = getport(d, NFS_PROG, NFS_VER2);
|
||||
|
||||
|
||||
bzero(&sdata, sizeof(sdata));
|
||||
|
||||
for (i = 0, ns = nfsstate; i < NFS_COUNT; ++i, ++ns) {
|
||||
if (len <= 0) {
|
||||
ns->done = 1;
|
||||
continue;
|
||||
}
|
||||
ns->done = 0;
|
||||
|
||||
ns->xid = d->xid;
|
||||
++d->xid;
|
||||
|
||||
ns->off = off;
|
||||
ns->len = len;
|
||||
if (ns->len > NFSREAD_SIZE)
|
||||
ns->len = NFSREAD_SIZE;
|
||||
#ifdef notdef
|
||||
/* XXX to align or not align? It doesn't seem to speed things up... */
|
||||
if ((ns->off % NFSREAD_SIZE) != 0)
|
||||
ns->len -= off % NFSREAD_SIZE;
|
||||
#endif
|
||||
|
||||
off += ns->len;
|
||||
len -= ns->len;
|
||||
|
||||
ns->addr = addr;
|
||||
addr += NFSREAD_SIZE;
|
||||
}
|
||||
|
||||
rpc = &sdata.rpc;
|
||||
rpc->rp_rpcvers = htonl(RPC_MSG_VERSION);
|
||||
rpc->rp_prog = htonl(NFS_PROG);
|
||||
rpc->rp_vers = htonl(NFS_VER2);
|
||||
rpc->rp_proc = htonl(NFSPROC_READ);
|
||||
bcopy(d->fh, sdata.nfs.fh, sizeof(sdata.nfs.fh));
|
||||
|
||||
nfscc = 0;
|
||||
cc = sendrecv(d, sendreaddata,
|
||||
&sdata.rpc,
|
||||
sizeof(struct rpc_call) + sizeof(struct nfs_call_data),
|
||||
recvreaddata,
|
||||
((u_char *)&rdata.rpc) - HEADER_SIZE, HEADER_SIZE +
|
||||
sizeof(struct rpc_call) + sizeof(struct nfs_reply_data));
|
||||
return (cc);
|
||||
}
|
||||
|
||||
void readseg(d, off, size, addr)
|
||||
register struct iodesc * d;
|
||||
register u_long off, size, addr;
|
||||
{
|
||||
register int i, cc;
|
||||
i = 0;
|
||||
while (size > 0) {
|
||||
cc = readdata(d, off, (void *)addr, size);
|
||||
if (cc <= 0) {
|
||||
/* XXX maybe should retry on certain errors */
|
||||
if (cc < 0)
|
||||
panic("\nreadseg: read: %s",
|
||||
strerror(errno));
|
||||
panic("\nreadseg: hit EOF unexpectantly");
|
||||
}
|
||||
off += cc;
|
||||
addr += cc;
|
||||
size -= cc;
|
||||
i = ~i;
|
||||
printf("%c\010", i ? '-' : '=');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "../include/stdarg.h"
|
||||
|
||||
void
|
||||
#ifdef __STDC__
|
||||
panic(const char *fmt, ...)
|
||||
#else
|
||||
panic(fmt /*, va_alist */)
|
||||
char *fmt;
|
||||
#endif
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
printf(fmt, ap);
|
||||
printf("\n");
|
||||
va_end(ap);
|
||||
machdep_stop();
|
||||
}
|
||||
|
||||
|
||||
/* Similar to inet_ntoa() */
|
||||
char *
|
||||
intoa(addr)
|
||||
n_long addr;
|
||||
{
|
||||
register char *cp;
|
||||
register u_int byte;
|
||||
register int n;
|
||||
static char buf[sizeof(".xxx.xxx.xxx.xxx")];
|
||||
|
||||
cp = &buf[sizeof buf];
|
||||
*--cp = '\0';
|
||||
|
||||
n = 4;
|
||||
do {
|
||||
byte = addr & 0xff;
|
||||
*--cp = byte % 10 + '0';
|
||||
byte /= 10;
|
||||
if (byte > 0) {
|
||||
*--cp = byte % 10 + '0';
|
||||
byte /= 10;
|
||||
if (byte > 0)
|
||||
*--cp = byte + '0';
|
||||
}
|
||||
*--cp = '.';
|
||||
addr >>= 8;
|
||||
} while (--n > 0);
|
||||
|
||||
return (cp + 1);
|
||||
}
|
||||
|
||||
char *strerror(errnum)
|
||||
int errnum;
|
||||
{
|
||||
char ebuf[1024] = "Unknown error: code ";
|
||||
char *p;
|
||||
int length;
|
||||
|
||||
|
||||
|
||||
switch (errnum) {
|
||||
case EPERM:
|
||||
return "Permission Denied";
|
||||
case ENOENT:
|
||||
return "No such file or directory";
|
||||
case ESTALE:
|
||||
return "Stale NFS file handle";
|
||||
default:
|
||||
length = strlen(ebuf);
|
||||
p = ebuf+length;
|
||||
do {
|
||||
*p++ = "0123456789"[errnum %10];
|
||||
} while (errnum /= 10);
|
||||
*p = '\0';
|
||||
return ebuf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert Ethernet address to printable (loggable) representation.
|
||||
*/
|
||||
static char digits[] = "0123456789abcdef";
|
||||
char *
|
||||
ether_sprintf(ap)
|
||||
register u_char *ap;
|
||||
{
|
||||
register i;
|
||||
static char etherbuf[18];
|
||||
register char *cp = etherbuf;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
*cp++ = digits[*ap >> 4];
|
||||
*cp++ = digits[*ap++ & 0xf];
|
||||
*cp++ = ':';
|
||||
}
|
||||
*--cp = 0;
|
||||
return (etherbuf);
|
||||
}
|
||||
|
||||
void bzero(addr, len)
|
||||
char *addr;
|
||||
int len;
|
||||
{
|
||||
while (len--)
|
||||
*addr++ = '\0';
|
||||
}
|
Loading…
Reference in New Issue