⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pnp.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char sccsid[] = "@(#)pnp.c 1.1 92/07/30 SMI";#endif/* * Copyright (c) 1988-1990 by Sun Microsystems, Inc. */#include	<sys/param.h>#include 	<sys/dir.h>#include	<sys/user.h>#include	<sys/uio.h>#include	<sys/socket.h>#include	<sys/kernel.h>#include	<sys/ioctl.h>#include 	<sys/reboot.h>#include 	<sys/bootconf.h>#include	<net/if.h>#include	<net/if_arp.h>#include	<netinet/in.h>#include	<rpc/rpc.h>#include	<rpc/pmap_rmt.h>#include	<rpc/pmap_prot.h>#include	<rpcsvc/pnprpc.h>#include	<stand/saio.h>#ifndef sun3x#include 	<mon/cpu.addrs.h>#endif  sun3x#include	<mon/sunromvec.h>#include	<mon/idprom.h>#ifdef sun386i#include 	<i386/380.h>#endif sun386i#include	"boot/systm.h"#include	"boot/if_ether.h"#ifdef	DUMP_DEBUGstatic	int	dump_debug = 20;#endif	/* DUMP_DEBUG */#undef ustruct	user	u;#ifdef	DRARP_REQUESTextern int	use_drarp;#endif#ifdef RPCDEBUGextern int rpcdebug;#endif    /* Default "printf" is gated according to NVRAM verbosity control.     * Bypass by using bpprintf ... here we REALLY want to see the     * status, it's meaningful to very naive users.     */#ifdef sun386i#define		printf	bpprintf#endif sun386i#define	if_broadaddr	if_addrlist->ifa_broadaddr/* * PNP Boot program ... downloaded when the network has granted * an IP address to this system, and it issues TFTP boot requests, * but no hostname is stored for this IP address. * * This follows the "plug'n'play" protocol to get configured on * the network or to generate reasonable diagnostics. * * Note ... bastardized from boot.c, there's a lot in this * boot program that can be deleted.  All it really needs is to * issue RPCs! */struct	bootparam	*boot_bp;extern int		memory_avail;extern struct ifnet	*if_ifwithaf();#undef	u;extern struct user	u;extern struct in_addr	my_in_addr;extern int		ethernet_started;    /* Checkpoints for progress meter.  Defined according to     * performance near FCS.     */#define	CHKPT_START	0#define	CHKPT_VERIFY	5#define	CHKPT_ACQUIRE	10#define	CHKPT_SETUP	20#define	CHKPT_POLL	30#define	CHKPT_POLL_INCR	10#define	CHKPT_BACKWARDS	75#define	CHKPT_PNPDONE	100#define	CHKPT_MAX	100#ifdef	sun386static int		chkpt_now = 0;#define	PMeter(x)	PROGRESS(chkpt_now = (x))#else#define	PMeter(x)#endif	sun386/* * Verbose mode -- * Not (yet) implemented. */extern int verbosemode;static char *msgs [] = {    /* 000 series:  fatal errors     */#define	MSG_NONPNPNET		msgs[0]    "This network does not support Automatic System Installation.",#define	MSG_NOmesg		msgs[1]    "",#define	MSG_NOSOFTWARE		msgs[2]    "No software for this architecture installed.",#define	MSG_NOSPACE		msgs[3]    "Not enough disk space to support a diskless client.",#define	MSG_NOCLIENTS		msgs[4]    "Unwilling to accept more clients.",	/* 100 series:  diagnostics, the user must take some action	 */#define	MSG_SEEADMIN		msgs[5]    "See your Network Administrator to resolve this problem.",#define	MSG_PROTOERR		msgs[6]    "A nonfatal protocol error ocurred.  Installation may not work.",	/* 200 series:  diagnostics, information only	 */#define	MSG_ACQUIRETIMEOUT	msgs[7]    "No server responded, restarting Automatic System Installation",#define	MSG_POLLTIMEOUT		msgs[8]    "The server installing this system may have crashed, restarting.",#define	MSG_RETRY		msgs[9]    "Retrying automatic system installation.",#define	MSG_POLLERR		msgs[10]    "An error ocurred during the POLL sequence.",#define	MSG_BUSYRETRY		msgs[11]    "The server is busy, retrying.",#define	MSG_SETUPFAIL		msgs[12]    "The SETUP request failed, retrying.",#define	MSG_WAIT		msgs[13]    "Your Network Administrator must configure this system.",#define	MSG_WHOAREYOU		msgs[14]    "The server seems to have rebooted.",#define	MSG_SETUPERR		msgs[15]    "Error in setup sequence.",};extern enum clnt_stat	clntkudp_callit_addr ();static voidtwiddler (eh){    static char dialbuf [] = "|/-\\";	/* 4 chars */    static int i;    if (!eh) {	putchar (dialbuf [i++]);	putchar ('\b');	i = i % 4;    } else {	putchar (' ');	putchar ('\b');	i = 0;    }}/* * pmapper remote-call-service interface. * This routine is used to call the pmapper remote call service * which will look up a service program in the port maps, and then * remotely call that routine with the given parameters.  This allows * programs to do a lookup and call in one step. */static enum clnt_statpmap_rmtcall (call_addr, prog, vers, proc,		xdrargs, argsp, xdrres, resp, tout, resp_addr)    struct sockaddr_in *call_addr;    u_long prog, vers, proc;    xdrproc_t xdrargs, xdrres;    caddr_t argsp, resp;    struct timeval tout;    struct sockaddr_in *resp_addr;{    register CLIENT *client;    struct rmtcallargs a;    struct rmtcallres r;    enum clnt_stat stat;    u_long port;    call_addr->sin_port = htons(PMAPPORT);    client = clntkudp_create(call_addr, PMAPPROG, PMAPVERS, 10, u.u_cred);    if (client != (CLIENT *)NULL) {	a.prog = prog;	a.vers = vers;	a.proc = proc;	a.args_ptr = argsp;	a.xdr_args = xdrargs;	r.port_ptr = &port;	r.results_ptr = resp;	r.xdr_results = xdrres;	    /* XXX this call doesn't produce any sort of ongoing	     * activity indicator at all. UNFRIENDLY !!	     */	stat = clntkudp_callit_addr(client, PMAPPROC_CALLIT,		xdr_rmtcall_args, (caddr_t)&a, xdr_rmtcallres,		(caddr_t)&r, tout, resp_addr);	resp_addr->sin_port = htons(port);	CLNT_DESTROY(client);    } else {	printf("PNPBoot: remote call failed - port mapper failure?\n");    }    return (stat);}static voidxsleep (nsec)    register nsec;{    while (nsec-- > 0) {	twiddler (0);	DELAY (1000000);    }    twiddler (1);}static intinit_inet (ifpp)    register struct ifnet **ifpp;{    register struct in_addr *ip1;	/* ensure the net's started up and the tables are	 * initialized.	 */    if (!ethernet_started) {	ethersetup ();	domaininit ();	ip_init ();	ethernet_started++;    }    *ifpp = if_ifwithaf (AF_INET);    if (!*ifpp) {	printf ("?? No INET interface ??\n");	return -1;    }    if (!address_known (*ifpp))	revarp_myaddr (*ifpp);	/* this is to ensure the interface has a valid IP	 * broadcast address.	 */    ip1 = &(((struct sockaddr_in *)&((*ifpp)->if_broadaddr))->sin_addr);    ip1->s_net = my_in_addr.s_net;    ip1->s_host = my_in_addr.s_host;    ip1->s_lh = my_in_addr.s_lh;    ip1->s_impno = 0;    return 0;}    /* This code will never get loaded except during a PNP sequence     * on a pnp network ... but servers go away sometimes.  Make     * certain there's one to talk to.     * TIME:  30 seconds max.     */static intis_pnp_net (ifp)    register struct ifnet *ifp;{    register int i;    struct sockaddr_in pnpaddr;    register enum clnt_stat stat;    struct timeval tv;    PMeter (CHKPT_VERIFY);    tv.tv_sec = 15;    tv.tv_usec = 0;    for (i = 0; i < 2; i++) {	twiddler (1);	stat = pmap_rmtcall (&(ifp->if_broadaddr), (u_long)PNPD_PROG,		(u_long)PNPD_VERS, NULLPROC,		xdr_void, (char *) 0,		xdr_void, (char *) 0,		tv, &pnpaddr);	if (!stat) {	    twiddler (1);	    return 1;	} else	    twiddler (0);    }    return 0;}    /* the only time this will succeed is if someone's changed the     * network configuration, and this system is already known but     * at a different location.     *     * This only supports automated installation just now, NOT     * reconfiguration.     */static pnp_errcodepnp_whoami (ifp)    struct ifnet *ifp;{    PMeter (CHKPT_START);	/* XXX IMPLEMENT	 *	This requires a broadcast RPC mechanism.  Pending	 *	that, a complete restart of the boot sequence works,	 *	though it's slower.	 */    xsleep (15);    return pnp_success;}static voidlchex (where, val)    char *where;    u_char val;{    int i;    static char x [17] = "0123456789abcdef";    i = (val >> 4) & 0x0f;    where [0] = x [i];    i = val & 0x0f;    where [1] = x [i];}    /* assumes only one bootable INET interface, and it's     * Ethernet/IEEE 802 48 bit.     */static pnp_acquire_arg *get_acquire_arg (ifp)    struct ifnet *ifp;{    static pnp_acquire_arg pa;    static int didit = 0;    static char hostid [9];    struct idprom id;#ifdef OPENPROMS    register struct memlist *pmem;#endif    if (!didit) {	pa.linkaddr.hw = ethernet;	myetheraddr (pa.linkaddr.hw_addr_u.enetaddr);	pa.inetaddr = ntohl (my_in_addr.s_addr);	/* pa.inetaddr = ntohl (ifp->if_addr.s_addr); */	    /* architecture codes are 5 chars or less; they are 	     * not always the same as the architecture.  Cases	     * in mind:  68030 kernel won't run on a 68020, but	     * is the same from user mode; 'sun386' is too many	     * characters.  (TFTP boot filenames must be 14 chars	     * or less, hence the 5 char limit.)	     */#if	sun2	pa.arch = "sun2";#endif	sun2#if	sun3	pa.arch = "sun3";#endif	sun3#if     sun3x        pa.arch = "sun3x";#endif  sun3x#if	sun4	pa.arch = "sun4";#endif	sun4#if	sun4c	pa.arch = "sun4c";#endif	sun4c#if	sun386	pa.arch = "s386";#endif	sun386	pa.how = b_diskless;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -