aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorBill Paul <wpaul@FreeBSD.org>1995-02-26 23:40:53 +0000
committerBill Paul <wpaul@FreeBSD.org>1995-02-26 23:40:53 +0000
commitb9fefab743b44b2e5e2793f594d81e37870889eb (patch)
tree9dcac368d8cc752f47ddef4932679048ffc2afd0 /usr.sbin
parent23adc6b8821b05c2bb64068f0e561643f5bf967b (diff)
downloadsrc-b9fefab743b44b2e5e2793f594d81e37870889eb.tar.gz
src-b9fefab743b44b2e5e2793f594d81e37870889eb.zip
Obtained from: The Xkernel source distribution
I hope I'm doing this right. This is an initial version of bootparamd for FreeBSD based on a public domain rpc.bootparamd implementation by a gentleman named Klas Heggemann. This program has apparently been around for a while. The README explicitly lists the code as public domain, so I guess it's safe to use. This program is needed for booting diskless SunOS and Solaris machines. rarpd is also required, but that's in the works too. I have made two changes to this code: - Implemented NIS lookups. If /etc/bootparams contains a '+' then the bootparams map is consulted. - Allow 0.0.0.0 as a user-specified router address. The SunOS rpc.bootparamd returns this value in many cases.
Notes
Notes: svn path=/cvs2svn/branches/bootparamd/; revision=6751
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bootparamd/Makefile4
-rw-r--r--usr.sbin/bootparamd/bootparamd/Makefile29
-rw-r--r--usr.sbin/bootparamd/bootparamd/README75
-rw-r--r--usr.sbin/bootparamd/bootparamd/bootparam_prot.h81
-rw-r--r--usr.sbin/bootparamd/bootparamd/bootparam_prot.x100
-rw-r--r--usr.sbin/bootparamd/bootparamd/bootparam_prot_xdr.c166
-rw-r--r--usr.sbin/bootparamd/bootparamd/bootparamd.865
-rw-r--r--usr.sbin/bootparamd/bootparamd/bootparamd.c329
-rw-r--r--usr.sbin/bootparamd/bootparamd/main.c139
-rw-r--r--usr.sbin/bootparamd/callbootd/Makefile28
-rw-r--r--usr.sbin/bootparamd/callbootd/callbootd.c187
11 files changed, 1203 insertions, 0 deletions
diff --git a/usr.sbin/bootparamd/Makefile b/usr.sbin/bootparamd/Makefile
new file mode 100644
index 000000000000..c4f61985a209
--- /dev/null
+++ b/usr.sbin/bootparamd/Makefile
@@ -0,0 +1,4 @@
+
+SUBDIR= bootparamd callbootd
+
+.include <bsd.subdir.mk>
diff --git a/usr.sbin/bootparamd/bootparamd/Makefile b/usr.sbin/bootparamd/bootparamd/Makefile
new file mode 100644
index 000000000000..fbfdc424ac77
--- /dev/null
+++ b/usr.sbin/bootparamd/bootparamd/Makefile
@@ -0,0 +1,29 @@
+# from: @(#)Makefile 5.8 (Berkeley) 7/28/90
+# $Id: Makefile,v 1.1 1994/08/08 01:03:57 wollman Exp $
+
+PROG= bootparamd
+SRCS= bootparam_prot_xdr.c bootparam_prot_svc.c bootparamd.c main.c
+MAN8= bootparamd.8
+CFLAGS+= -DTFTP_DIR=\"/tftpboot\"
+CLEANFILES= bootparam_prot_svc.c bootparam_prot_xdr.c \
+ bootparam_prot.h bootparam_prot.x
+
+bootparam_prot_svc.c: bootparam_prot.h
+ rm -f ${.CURDIR}/bootparam_prot.x
+ cp /usr/include/rpcsvc/bootparam_prot.x ${.CURDIR}
+ rpcgen -m -o ${.CURDIR}/bootparam_prot_svc.c \
+ ${.CURDIR}/bootparam_prot.x
+
+bootparam_prot_xdr.c: bootparam_prot.h
+ rm -f ${.CURDIR}/bootparam_prot.x
+ cp /usr/include/rpcsvc/bootparam_prot.x ${.CURDIR}
+ rpcgen -c -o ${.CURDIR}/bootparam_prot_xdr.c \
+ ${.CURDIR}/bootparam_prot.x
+
+bootparam_prot.h:
+ rm -f ${.CURDIR}/bootparam_prot.x
+ cp /usr/include/rpcsvc/bootparam_prot.x ${.CURDIR}
+ rpcgen -h -o ${.CURDIR}/bootparam_prot.h \
+ ${.CURDIR}/bootparam_prot.x
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bootparamd/bootparamd/README b/usr.sbin/bootparamd/bootparamd/README
new file mode 100644
index 000000000000..85a2a5444f24
--- /dev/null
+++ b/usr.sbin/bootparamd/bootparamd/README
@@ -0,0 +1,75 @@
+
+
+This directory contains a version of the rpc.bootparamd, which have been
+written using the Sun's RPC protocol for bootparamd. To use it you must
+have a copy of the bootparam_prot.x file which on Sun systems you find in
+
+ /usr/include/rpcsvc/bootparam_prot.x
+
+(( This file was retrieved from the Sun-RPC source package ))
+
+
+This code is not copyright, and is placed in the public domain. Feel free to
+use and modify. Please send modifications and/or suggestions + bug fixes to
+
+ Klas Heggemann <klas@nada.kth.se>
+
+
+RPC.BOOTPARAMD
+
+
+The rpc.bootparamd program does NOT use the yellow pages for the bootparams
+database. This data should recide in /etc/bootparams on the local host,
+or another file given when the server is started.
+
+The default router is set to the address of the machine running the server.
+This may not be a good thing to do, so it can be modified using the -r
+option when startning the daemon.
+
+This program was written with the need to keep short hostnames in the
+/etc/bootparams file and long (canonical) names in the hosts database.
+It probably also will work in conjunction with a nameserver, since matching
+is done by comparing the canonical name of the booting machine with the
+canonical name of the hosts found in the bootparams database.
+
+It is kept simple, e g there is no caching of data, but the bootparameter file
+is read at each request.
+
+
+CALLBOOTD
+
+The debugging tool callbootd is used to check the response you get
+to a specific (booting) request. It can be used as
+ callbootd server inet-adress
+or
+ callbootd server hostname file
+where "server" is a machine running the rpc.bootparamd program, "inet-address"
+is the internet address of a booting machine, "hostname" is the name of a
+booting machine and "file" the requested file, typically "root", "swap" or
+"dump".
+
+You may also use "all" instead of a specific server, in which case a RPC
+broadcast is performed. The broadcast is performed 4 times and then the
+program times out, after printing all responses.
+
+
+TODO
+
+Cache the date, instead of rereading it.
+Maybe match by comparing the inet address instead. (But beware that caching
+will prevent the server from detecting that a machine has changed name
+or address.)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/usr.sbin/bootparamd/bootparamd/bootparam_prot.h b/usr.sbin/bootparamd/bootparamd/bootparam_prot.h
new file mode 100644
index 000000000000..66c72274a5fc
--- /dev/null
+++ b/usr.sbin/bootparamd/bootparamd/bootparam_prot.h
@@ -0,0 +1,81 @@
+#include <rpc/types.h>
+#include <sys/time.h>
+#include <sys/errno.h>
+#include <nfs/nfs.h>
+#define MAX_MACHINE_NAME 255
+#define MAX_PATH_LEN 1024
+#define MAX_FILEID 32
+#define IP_ADDR_TYPE 1
+
+typedef char *bp_machine_name_t;
+bool_t xdr_bp_machine_name_t();
+
+
+typedef char *bp_path_t;
+bool_t xdr_bp_path_t();
+
+
+typedef char *bp_fileid_t;
+bool_t xdr_bp_fileid_t();
+
+
+struct ip_addr_t {
+ char net;
+ char host;
+ char lh;
+ char impno;
+};
+typedef struct ip_addr_t ip_addr_t;
+bool_t xdr_ip_addr_t();
+
+
+struct bp_address {
+ int address_type;
+ union {
+ ip_addr_t ip_addr;
+ } bp_address_u;
+};
+typedef struct bp_address bp_address;
+bool_t xdr_bp_address();
+
+
+struct bp_whoami_arg {
+ bp_address client_address;
+};
+typedef struct bp_whoami_arg bp_whoami_arg;
+bool_t xdr_bp_whoami_arg();
+
+
+struct bp_whoami_res {
+ bp_machine_name_t client_name;
+ bp_machine_name_t domain_name;
+ bp_address router_address;
+};
+typedef struct bp_whoami_res bp_whoami_res;
+bool_t xdr_bp_whoami_res();
+
+
+struct bp_getfile_arg {
+ bp_machine_name_t client_name;
+ bp_fileid_t file_id;
+};
+typedef struct bp_getfile_arg bp_getfile_arg;
+bool_t xdr_bp_getfile_arg();
+
+
+struct bp_getfile_res {
+ bp_machine_name_t server_name;
+ bp_address server_address;
+ bp_path_t server_path;
+};
+typedef struct bp_getfile_res bp_getfile_res;
+bool_t xdr_bp_getfile_res();
+
+
+#define BOOTPARAMPROG ((u_long)100026)
+#define BOOTPARAMVERS ((u_long)1)
+#define BOOTPARAMPROC_WHOAMI ((u_long)1)
+extern bp_whoami_res *bootparamproc_whoami_1();
+#define BOOTPARAMPROC_GETFILE ((u_long)2)
+extern bp_getfile_res *bootparamproc_getfile_1();
+
diff --git a/usr.sbin/bootparamd/bootparamd/bootparam_prot.x b/usr.sbin/bootparamd/bootparamd/bootparam_prot.x
new file mode 100644
index 000000000000..6d3c3e79658c
--- /dev/null
+++ b/usr.sbin/bootparamd/bootparamd/bootparam_prot.x
@@ -0,0 +1,100 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * RPC for bootparms service.
+ * There are two procedures:
+ * WHOAMI takes a net address and returns a client name and also a
+ * likely net address for routing
+ * GETFILE takes a client name and file identifier and returns the
+ * server name, server net address and pathname for the file.
+ * file identifiers typically include root, swap, pub and dump
+ */
+
+#ifdef RPC_HDR
+%#include <rpc/types.h>
+%#include <sys/time.h>
+%#include <sys/errno.h>
+%#include <nfs/nfs.h>
+#else
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)bootparam_prot.x 1.2 87/06/24 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)bootparam_prot.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static char rcsid[] = "$Id: bootparam_prot.x,v 1.1 1994/08/04 19:01:44 wollman Exp $";
+%#endif /* not lint */
+#endif
+
+const MAX_MACHINE_NAME = 255;
+const MAX_PATH_LEN = 1024;
+const MAX_FILEID = 32;
+const IP_ADDR_TYPE = 1;
+
+typedef string bp_machine_name_t<MAX_MACHINE_NAME>;
+typedef string bp_path_t<MAX_PATH_LEN>;
+typedef string bp_fileid_t<MAX_FILEID>;
+
+struct ip_addr_t {
+ char net;
+ char host;
+ char lh;
+ char impno;
+};
+
+union bp_address switch (int address_type) {
+ case IP_ADDR_TYPE:
+ ip_addr_t ip_addr;
+};
+
+struct bp_whoami_arg {
+ bp_address client_address;
+};
+
+struct bp_whoami_res {
+ bp_machine_name_t client_name;
+ bp_machine_name_t domain_name;
+ bp_address router_address;
+};
+
+struct bp_getfile_arg {
+ bp_machine_name_t client_name;
+ bp_fileid_t file_id;
+};
+
+struct bp_getfile_res {
+ bp_machine_name_t server_name;
+ bp_address server_address;
+ bp_path_t server_path;
+};
+
+program BOOTPARAMPROG {
+ version BOOTPARAMVERS {
+ bp_whoami_res BOOTPARAMPROC_WHOAMI(bp_whoami_arg) = 1;
+ bp_getfile_res BOOTPARAMPROC_GETFILE(bp_getfile_arg) = 2;
+ } = 1;
+} = 100026;
diff --git a/usr.sbin/bootparamd/bootparamd/bootparam_prot_xdr.c b/usr.sbin/bootparamd/bootparamd/bootparam_prot_xdr.c
new file mode 100644
index 000000000000..72fc2eefcdb8
--- /dev/null
+++ b/usr.sbin/bootparamd/bootparamd/bootparam_prot_xdr.c
@@ -0,0 +1,166 @@
+#include <rpc/rpc.h>
+#include "/a/wpaul/CVSWORK/src/usr.sbin/bootparamd/bootparamd/bootparam_prot.h"
+#ifndef lint
+/*static char sccsid[] = "from: @(#)bootparam_prot.x 1.2 87/06/24 Copyr 1987 Sun Micro";*/
+/*static char sccsid[] = "from: @(#)bootparam_prot.x 2.1 88/08/01 4.0 RPCSRC";*/
+static char rcsid[] = "$Id: bootparam_prot.x,v 1.1 1994/08/04 19:01:44 wollman Exp $";
+#endif /* not lint */
+
+
+bool_t
+xdr_bp_machine_name_t(xdrs, objp)
+ XDR *xdrs;
+ bp_machine_name_t *objp;
+{
+ if (!xdr_string(xdrs, objp, MAX_MACHINE_NAME)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+
+
+bool_t
+xdr_bp_path_t(xdrs, objp)
+ XDR *xdrs;
+ bp_path_t *objp;
+{
+ if (!xdr_string(xdrs, objp, MAX_PATH_LEN)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+
+
+bool_t
+xdr_bp_fileid_t(xdrs, objp)
+ XDR *xdrs;
+ bp_fileid_t *objp;
+{
+ if (!xdr_string(xdrs, objp, MAX_FILEID)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+
+
+bool_t
+xdr_ip_addr_t(xdrs, objp)
+ XDR *xdrs;
+ ip_addr_t *objp;
+{
+ if (!xdr_char(xdrs, &objp->net)) {
+ return (FALSE);
+ }
+ if (!xdr_char(xdrs, &objp->host)) {
+ return (FALSE);
+ }
+ if (!xdr_char(xdrs, &objp->lh)) {
+ return (FALSE);
+ }
+ if (!xdr_char(xdrs, &objp->impno)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+
+
+bool_t
+xdr_bp_address(xdrs, objp)
+ XDR *xdrs;
+ bp_address *objp;
+{
+ if (!xdr_int(xdrs, &objp->address_type)) {
+ return (FALSE);
+ }
+ switch (objp->address_type) {
+ case IP_ADDR_TYPE:
+ if (!xdr_ip_addr_t(xdrs, &objp->bp_address_u.ip_addr)) {
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+
+
+bool_t
+xdr_bp_whoami_arg(xdrs, objp)
+ XDR *xdrs;
+ bp_whoami_arg *objp;
+{
+ if (!xdr_bp_address(xdrs, &objp->client_address)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+
+
+bool_t
+xdr_bp_whoami_res(xdrs, objp)
+ XDR *xdrs;
+ bp_whoami_res *objp;
+{
+ if (!xdr_bp_machine_name_t(xdrs, &objp->client_name)) {
+ return (FALSE);
+ }
+ if (!xdr_bp_machine_name_t(xdrs, &objp->domain_name)) {
+ return (FALSE);
+ }
+ if (!xdr_bp_address(xdrs, &objp->router_address)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+
+
+bool_t
+xdr_bp_getfile_arg(xdrs, objp)
+ XDR *xdrs;
+ bp_getfile_arg *objp;
+{
+ if (!xdr_bp_machine_name_t(xdrs, &objp->client_name)) {
+ return (FALSE);
+ }
+ if (!xdr_bp_fileid_t(xdrs, &objp->file_id)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+
+
+bool_t
+xdr_bp_getfile_res(xdrs, objp)
+ XDR *xdrs;
+ bp_getfile_res *objp;
+{
+ if (!xdr_bp_machine_name_t(xdrs, &objp->server_name)) {
+ return (FALSE);
+ }
+ if (!xdr_bp_address(xdrs, &objp->server_address)) {
+ return (FALSE);
+ }
+ if (!xdr_bp_path_t(xdrs, &objp->server_path)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
diff --git a/usr.sbin/bootparamd/bootparamd/bootparamd.8 b/usr.sbin/bootparamd/bootparamd/bootparamd.8
new file mode 100644
index 000000000000..9a1986805b29
--- /dev/null
+++ b/usr.sbin/bootparamd/bootparamd/bootparamd.8
@@ -0,0 +1,65 @@
+.\" @(#)bootparamd.8
+.TH BOOTPARAMD 8 "8 November 1989"
+.SH NAME
+bootparamd \- boot parameter server
+.SH SYNOPSIS
+.B rpc.bootparamd
+[
+.B \-d
+]
+[
+.B \-s
+]
+[
+.B \-r
+router
+]
+[
+.B \-f
+file
+]
+.SH DESCRIPTION
+.IX "bootparamd daemon" "" "\fLbootparamd\fP daemon"
+.LP
+.B bootparamd
+is a server process that provides information to diskless clients
+necessary for booting. It consults
+.B /etc/bootparams
+file.
+.LP
+This version will allow the use of aliases on the hostname in the
+.B /etc/bootparams
+file. The returned hostname to the whoami request done by the booting client
+will be the name that appears in
+.B /etc/bootparams
+and not the canonical name. In this way you can keep the answer short enough
+so that machines that can not handle long hostnames won't fail during boot.
+.SH OPTIONS
+.TP
+.B \-d
+Display the debugging information.
+.TP
+.B \-s
+Log the debugging information with syslog.
+.TP
+.B
+\-r router
+The default router (a machine or an IP-address).
+This defaults to the machine running the server.
+.TP
+.B
+\-f file
+The file to use as boot parameter file instead of /etc/bootparams.
+.SH FILES
+.PD 0
+.TP 20
+.B /etc/bootparams
+.PD
+
+.SH BUGS
+You may find the syslog loggings to verbose.
+
+.SH AUTHOR
+Written by Klas Heggemann <klas@nada.kth.se>
+
+
diff --git a/usr.sbin/bootparamd/bootparamd/bootparamd.c b/usr.sbin/bootparamd/bootparamd/bootparamd.c
new file mode 100644
index 000000000000..d91b0532a797
--- /dev/null
+++ b/usr.sbin/bootparamd/bootparamd/bootparamd.c
@@ -0,0 +1,329 @@
+/*
+
+This code is not copyright, and is placed in the public domain. Feel free to
+use and modify. Please send modifications and/or suggestions + bug fixes to
+
+ Klas Heggemann <klas@nada.kth.se>
+
+ $Id$
+
+*/
+
+
+#include <rpc/rpc.h>
+#include "bootparam_prot.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <syslog.h>
+extern int debug, dolog;
+extern unsigned long route_addr;
+extern char *bootpfile;
+
+#define MAXLEN 800
+
+struct hostent *he;
+static char buffer[MAXLEN];
+static char hostname[MAX_MACHINE_NAME];
+static char askname[MAX_MACHINE_NAME];
+static char path[MAX_PATH_LEN];
+static char domain_name[MAX_MACHINE_NAME];
+
+
+bp_whoami_res *
+bootparamproc_whoami_1(whoami)
+bp_whoami_arg *whoami;
+{
+ long haddr;
+ static bp_whoami_res res;
+ if (debug)
+ fprintf(stderr,"whoami got question for %d.%d.%d.%d\n",
+ 255 & whoami->client_address.bp_address_u.ip_addr.net,
+ 255 & whoami->client_address.bp_address_u.ip_addr.host,
+ 255 & whoami->client_address.bp_address_u.ip_addr.lh,
+ 255 & whoami->client_address.bp_address_u.ip_addr.impno);
+ if (dolog)
+ syslog(LOG_NOTICE, "whoami got question for %d.%d.%d.%d\n",
+ 255 & whoami->client_address.bp_address_u.ip_addr.net,
+ 255 & whoami->client_address.bp_address_u.ip_addr.host,
+ 255 & whoami->client_address.bp_address_u.ip_addr.lh,
+ 255 & whoami->client_address.bp_address_u.ip_addr.impno);
+
+ bcopy((char *)&whoami->client_address.bp_address_u.ip_addr, (char *)&haddr,
+ sizeof(haddr));
+ he = gethostbyaddr((char *)&haddr,sizeof(haddr),AF_INET);
+ if ( ! he ) goto failed;
+
+ if (debug) fprintf(stderr,"This is host %s\n", he->h_name);
+ if (dolog) syslog(LOG_NOTICE,"This is host %s\n", he->h_name);
+
+ strcpy(askname, he->h_name);
+ if (checkhost(askname, hostname) ) {
+ res.client_name = hostname;
+ getdomainname(domain_name, MAX_MACHINE_NAME);
+ res.domain_name = domain_name;
+
+ if ( res.router_address.address_type != IP_ADDR_TYPE ) {
+ res.router_address.address_type = IP_ADDR_TYPE;
+ bcopy( &route_addr, &res.router_address.bp_address_u.ip_addr, 4);
+ }
+ if (debug) fprintf(stderr,
+ "Returning %s %s %d.%d.%d.%d\n",
+ res.client_name,
+ res.domain_name,
+ 255 & res.router_address.bp_address_u.ip_addr.net,
+ 255 & res.router_address.bp_address_u.ip_addr.host,
+ 255 & res.router_address.bp_address_u.ip_addr.lh,
+ 255 & res.router_address.bp_address_u.ip_addr.impno);
+ if (dolog) syslog(LOG_NOTICE,
+ "Returning %s %s %d.%d.%d.%d\n",
+ res.client_name,
+ res.domain_name,
+ 255 & res.router_address.bp_address_u.ip_addr.net,
+ 255 & res.router_address.bp_address_u.ip_addr.host,
+ 255 & res.router_address.bp_address_u.ip_addr.lh,
+ 255 & res.router_address.bp_address_u.ip_addr.impno);
+
+ return(&res);
+ }
+ failed:
+ if (debug) fprintf(stderr,"whoami failed\n");
+ if (dolog) syslog(LOG_NOTICE,"whoami failed\n");
+ return(NULL);
+}
+
+
+bp_getfile_res *
+ bootparamproc_getfile_1(getfile)
+bp_getfile_arg *getfile;
+{
+ char *where, *index();
+ static bp_getfile_res res;
+
+ if (debug)
+ fprintf(stderr,"getfile got question for \"%s\" and file \"%s\"\n",
+ getfile->client_name, getfile->file_id);
+
+ if (dolog)
+ syslog(LOG_NOTICE,"getfile got question for \"%s\" and file \"%s\"\n",
+ getfile->client_name, getfile->file_id);
+
+ he = NULL;
+ he = gethostbyname(getfile->client_name);
+ if (! he ) goto failed;
+
+ strcpy(askname,he->h_name);
+ if (getthefile(askname, getfile->file_id,buffer)) {
+ if ( where = index(buffer,':')) {
+ /* buffer is re-written to contain the name of the info of file */
+ strncpy(hostname, buffer, where - buffer);
+ hostname[where - buffer] = '\0';
+ where++;
+ strcpy(path, where);
+ he = gethostbyname(hostname);
+ if ( !he ) goto failed;
+ bcopy( he->h_addr, &res.server_address.bp_address_u.ip_addr, 4);
+ res.server_name = hostname;
+ res.server_path = path;
+ res.server_address.address_type = IP_ADDR_TYPE;
+ }
+ else { /* special for dump, answer with null strings */
+ if (!strcmp(getfile->file_id, "dump")) {
+ res.server_name = "";
+ res.server_path = "";
+ res.server_address.address_type = IP_ADDR_TYPE;
+ bzero(&res.server_address.bp_address_u.ip_addr,4);
+ } else goto failed;
+ }
+ if (debug)
+ fprintf(stderr, "returning server:%s path:%s address: %d.%d.%d.%d\n",
+ res.server_name, res.server_path,
+ 255 & res.server_address.bp_address_u.ip_addr.net,
+ 255 & res.server_address.bp_address_u.ip_addr.host,
+ 255 & res.server_address.bp_address_u.ip_addr.lh,
+ 255 & res.server_address.bp_address_u.ip_addr.impno);
+ if (dolog)
+ syslog(LOG_NOTICE, "returning server:%s path:%s address: %d.%d.%d.%d\n",
+ res.server_name, res.server_path,
+ 255 & res.server_address.bp_address_u.ip_addr.net,
+ 255 & res.server_address.bp_address_u.ip_addr.host,
+ 255 & res.server_address.bp_address_u.ip_addr.lh,
+ 255 & res.server_address.bp_address_u.ip_addr.impno);
+ return(&res);
+ }
+ failed:
+ if (debug) fprintf(stderr, "getfile failed for %s\n", getfile->client_name);
+ if (dolog) syslog(LOG_NOTICE,
+ "getfile failed for %s\n", getfile->client_name);
+ return(NULL);
+}
+
+/* getthefile return 1 and fills the buffer with the information
+ of the file, e g "host:/export/root/client" if it can be found.
+ If the host is in the database, but the file is not, the buffer
+ will be empty. (This makes it possible to give the special
+ empty answer for the file "dump") */
+
+getthefile(askname,fileid,buffer)
+char *askname;
+char *fileid, *buffer;
+{
+ FILE *bpf;
+ char *where;
+ static char *result;
+ int resultlen;
+ extern int yp_get_default_domain();
+ extern int yp_match();
+ static char *yp_domain;
+
+ int ch, pch, fid_len, res = 0;
+ int match = 0;
+ char info[MAX_FILEID + MAX_PATH_LEN+MAX_MACHINE_NAME + 3];
+
+ bpf = fopen(bootpfile, "r");
+ if ( ! bpf ) {
+ fprintf(stderr, "No %s\n", bootpfile);
+ exit(1);
+ }
+
+ while ( fscanf(bpf, "%s", hostname) > 0 && !match ) {
+ if ( *hostname != '#' ) { /* comment */
+ if ( ! strcmp(hostname, askname) ) {
+ match = 1;
+ } else {
+ he = gethostbyname(hostname);
+ if (he && !strcmp(he->h_name, askname)) match = 1;
+ }
+ }
+ if (*hostname == '+' ) { /* NIS */
+ if (yp_get_default_domain(&yp_domain)) {
+ if (debug) perror("NIS");
+ return(0);
+ }
+ if (yp_match(yp_domain, "bootparams", askname, strlen(askname),
+ &result, &resultlen))
+ return (0);
+ if (strstr(result, fileid) == NULL) {
+ buffer[0] = '\0';
+ } else {
+ sprintf(buffer,"%s",strchr(strstr(result,fileid), '=') + 1);
+ if (strchr(buffer, ' ') != NULL)
+ *(char *)(strchr(buffer, ' ')) = '\0';
+ }
+ if (fclose(bpf))
+ fprintf(stderr,"Could not close %s\n", bootpfile);
+ return(1);
+ }
+ /* skip to next entry */
+ if ( match ) break;
+ pch = ch = getc(bpf);
+ while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) {
+ pch = ch; ch = getc(bpf);
+ }
+ }
+
+ /* if match is true we read the rest of the line to get the
+ info of the file */
+
+ if (match) {
+ fid_len = strlen(fileid);
+ while ( ! res && (fscanf(bpf,"%s", info)) > 0) { /* read a string */
+ ch = getc(bpf); /* and a character */
+ if ( *info != '#' ) { /* Comment ? */
+ if (! strncmp(info, fileid, fid_len) && *(info + fid_len) == '=') {
+ where = info + fid_len + 1;
+ if ( isprint( *where )) {
+ strcpy(buffer, where); /* found file */
+ res = 1; break;
+ }
+ } else {
+ while (isspace(ch) && ch != '\n') ch = getc(bpf);
+ /* read to end of line */
+ if ( ch == '\n' ) { /* didn't find it */
+ res = -1; break; /* but host is there */
+ }
+ if ( ch == '\\' ) { /* more info */
+ ch = getc(bpf); /* maybe on next line */
+ if (ch == '\n') continue; /* read it in next loop */
+ ungetc(ch, bpf); ungetc('\\',bpf); /* push the character(s) back */
+ } else ungetc(ch, bpf); /* but who know what a `\` is */
+ } /* needed for. */
+ } else break; /* a commented rest-of-line */
+ }
+ }
+ if (fclose(bpf)) { fprintf(stderr,"Could not close %s\n", bootpfile); }
+ if ( res == -1) buffer[0] = '\0'; /* host found, file not */
+ return(match);
+}
+
+/* checkhost puts the hostname found in the database file in
+ the hostname-variable and returns 1, if askname is a valid
+ name for a host in the database */
+
+checkhost(askname, hostname)
+char *askname;
+char *hostname;
+{
+ int ch, pch;
+ FILE *bpf;
+ int res = 0;
+ static char *result;
+ int resultlen;
+ extern int yp_get_default_domain();
+ extern int yp_match();
+ static char *yp_domain;
+
+/* struct hostent *cmp_he;*/
+
+ bpf = fopen(bootpfile, "r");
+ if ( ! bpf ) {
+ fprintf(stderr, "No %s\n", bootpfile);
+ exit(1);
+ }
+
+ while ( fscanf(bpf, "%s", hostname) > 0 ) {
+ if ( *hostname != '#' ) { /* comment */
+ if ( ! strcmp(hostname, askname) ) {
+ /* return true for match of hostname */
+ res = 1;
+ break;
+ } else {
+ /* check the alias list */
+ he = NULL;
+ he = gethostbyname(hostname);
+ if (he && !strcmp(askname, he->h_name)) {
+ res = 1;
+ break;
+ }
+ }
+ }
+ if (*hostname == '+' ) { /* NIS */
+ if (yp_get_default_domain(&yp_domain)) {
+ if (debug) perror("NIS");
+ return(0);
+ }
+ if (!yp_match(yp_domain, "bootparams", askname, strlen(askname),
+ &result, &resultlen)) {
+ /* return true for match of hostname */
+ he = NULL;
+ he = gethostbyname(askname);
+ if (he && !strcmp(askname, he->h_name)) {
+ res = 1;
+ sprintf(hostname,"%s", he->h_name);
+ }
+ }
+ if (fclose(bpf))
+ fprintf(stderr,"Could not close %s\n", bootpfile);
+ return(res);
+ }
+ /* skip to next entry */
+ pch = ch = getc(bpf);
+ while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) {
+ pch = ch; ch = getc(bpf);
+ }
+ }
+ if (fclose(bpf)) { fprintf(stderr,"Could not close %s\n", bootpfile); }
+ return(res);
+}
diff --git a/usr.sbin/bootparamd/bootparamd/main.c b/usr.sbin/bootparamd/bootparamd/main.c
new file mode 100644
index 000000000000..70381c880168
--- /dev/null
+++ b/usr.sbin/bootparamd/bootparamd/main.c
@@ -0,0 +1,139 @@
+/*
+
+This code is not copyright, and is placed in the public domain. Feel free to
+use and modify. Please send modifications and/or suggestions + bug fixes to
+
+ Klas Heggemann <klas@nada.kth.se>
+
+
+ $Id$
+
+*/
+
+#include <syslog.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <rpc/rpc.h>
+#include "bootparam_prot.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <ctype.h>
+
+int debug = 0;
+int dolog = 0;
+unsigned long route_addr = -1, inet_addr();
+struct sockaddr_in my_addr;
+char *progname;
+char *bootpfile = "/etc/bootparams";
+
+extern void bootparamprog_1();
+
+extern char *optarg;
+extern int optind;
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+ SVCXPRT *transp;
+ int i,s, pid;
+ char *rindex();
+ struct hostent *he;
+ struct stat buf;
+ char *optstring;
+ char c;
+
+ progname = rindex(argv[0],'/');
+ if ( progname ) progname++;
+ else progname = argv[0];
+
+ while ((c = getopt(argc, argv,"dsr:f:")) != EOF)
+ switch (c) {
+ case 'd':
+ debug = 1;
+ break;
+ case 'r':
+ if ( isdigit( *optarg)) {
+ route_addr = inet_addr(optarg);
+ break;
+ } else {
+ he = gethostbyname(optarg);
+ if (he) {
+ bcopy(he->h_addr, (char *)&route_addr, sizeof(route_addr));
+ break;
+ } else {
+ fprintf(stderr,"%s: No such host %s\n", progname, argv[i]);
+ exit(1);
+ }
+ }
+ case 'f':
+ bootpfile = optarg;
+ break;
+ case 's':
+ dolog = 1;
+#ifndef LOG_DAEMON
+ openlog(progname, 0 , 0);
+#else
+ openlog(progname, 0 , LOG_DAEMON);
+ setlogmask(LOG_UPTO(LOG_NOTICE));
+#endif
+ break;
+ default:
+ fprintf(stderr,
+ "Usage: %s [-d ] [ -s ] [ -r router ] [ -f bootparmsfile ]\n");
+ exit(1);
+ }
+
+ if ( stat(bootpfile, &buf ) ) {
+ fprintf(stderr,"%s: ", progname);
+ perror(bootpfile);
+ exit(1);
+ }
+
+
+ if (route_addr == -1) {
+ get_myaddress(&my_addr);
+ bcopy(&my_addr.sin_addr.s_addr, &route_addr, sizeof (route_addr));
+ }
+
+ if (!debug) {
+ pid = fork();
+ if ( pid < 0) {
+ perror("bootparamd: fork");
+ exit(1);
+ }
+ if (pid) exit(0); /* parent */
+
+ /* child */
+ for ( s = 0; s < 20 ; s++) close(s);
+ open("/", 0);
+ dup2(0, 1);
+ dup2(0, 2);
+ s = open("/dev/tty",2);
+ if ( s >= 0 ) {
+ ioctl(s, TIOCNOTTY, 0);
+ close(s);
+ }
+ }
+
+
+ (void)pmap_unset(BOOTPARAMPROG, BOOTPARAMVERS);
+
+ transp = svcudp_create(RPC_ANYSOCK);
+ if (transp == NULL) {
+ (void)fprintf(stderr, "cannot create udp service.\n");
+ exit(1);
+ }
+ if (!svc_register(transp, BOOTPARAMPROG, BOOTPARAMVERS, bootparamprog_1, IPPROTO_UDP)) {
+ (void)fprintf(stderr, "unable to register (BOOTPARAMPROG, BOOTPARAMVERS, udp).\n");
+ exit(1);
+ }
+
+ svc_run();
+ (void)fprintf(stderr, "svc_run returned\n");
+ exit(1);
+}
+
+
diff --git a/usr.sbin/bootparamd/callbootd/Makefile b/usr.sbin/bootparamd/callbootd/Makefile
new file mode 100644
index 000000000000..9be4af399b70
--- /dev/null
+++ b/usr.sbin/bootparamd/callbootd/Makefile
@@ -0,0 +1,28 @@
+# from: @(#)Makefile 5.8 (Berkeley) 7/28/90
+# $Id: Makefile,v 1.1 1994/08/08 01:03:57 wollman Exp $
+
+PROG= callbootd
+SRCS= bootparam_prot_xdr.c bootparam_prot_clnt.c callbootd.c
+NOMAN=
+CLEANFILES= bootparam_prot_clnt.c bootparam_prot_xdr.c \
+ bootparam_prot.h bootparam_prot.x
+
+bootparam_prot_clnt.c: bootparam_prot.h
+ rm -f ${.CURDIR}/bootparam_prot.x
+ cp /usr/include/rpcsvc/bootparam_prot.x ${.CURDIR}
+ rpcgen -l -o ${.CURDIR}/bootparam_prot_clnt.c \
+ ${.CURDIR}/bootparam_prot.x
+
+bootparam_prot_xdr.c: bootparam_prot.h
+ rm -f ${.CURDIR}/bootparam_prot.x
+ cp /usr/include/rpcsvc/bootparam_prot.x ${.CURDIR}
+ rpcgen -c -o ${.CURDIR}/bootparam_prot_xdr.c \
+ ${.CURDIR}/bootparam_prot.x
+
+bootparam_prot.h:
+ rm -f ${.CURDIR}/bootparam_prot.x
+ cp /usr/include/rpcsvc/bootparam_prot.x ${.CURDIR}
+ rpcgen -h -o ${.CURDIR}/bootparam_prot.h \
+ ${.CURDIR}/bootparam_prot.x
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bootparamd/callbootd/callbootd.c b/usr.sbin/bootparamd/callbootd/callbootd.c
new file mode 100644
index 000000000000..22dbd5a9b115
--- /dev/null
+++ b/usr.sbin/bootparamd/callbootd/callbootd.c
@@ -0,0 +1,187 @@
+/*
+
+This code is not copyright, and is placed in the public domain. Feel free to
+use and modify. Please send modifications and/or suggestions + bug fixes to
+
+ Klas Heggemann <klas@nada.kth.se>
+
+ $Id$
+*/
+
+
+#include "bootparam_prot.h"
+#include <rpc/rpc.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+
+/* #define bp_address_u bp_address */
+#include <stdio.h>
+
+int broadcast;
+
+char cln[MAX_MACHINE_NAME+1];
+char dmn[MAX_MACHINE_NAME+1];
+char path[MAX_PATH_LEN+1];
+extern char *inet_ntoa();
+
+eachres_whoami(resultp, raddr)
+bp_whoami_res *resultp;
+struct sockaddr_in *raddr;
+{
+ struct hostent *he;
+
+ he = gethostbyaddr((char *)&raddr->sin_addr.s_addr,4,AF_INET);
+ printf("%s answered:\n", he ? he->h_name : inet_ntoa(raddr->sin_addr));
+ printwhoami(resultp);
+ printf("\n");
+ return(0);
+}
+
+eachres_getfile(resultp, raddr)
+bp_getfile_res *resultp;
+struct sockaddr_in *raddr;
+{
+ struct hostent *he;
+
+ he = gethostbyaddr((char *)&raddr->sin_addr.s_addr,4,AF_INET);
+ printf("%s answered:\n", he ? he->h_name : inet_ntoa(raddr->sin_addr));
+ printgetfile(resultp);
+ printf("\n");
+ return(0);
+}
+
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+ int stat;
+ char *server;
+
+ bp_whoami_arg whoami_arg;
+ bp_whoami_res *whoami_res, stat_whoami_res;
+ bp_getfile_arg getfile_arg;
+ bp_getfile_res *getfile_res, stat_getfile_res;
+
+
+ long the_inet_addr;
+ CLIENT *clnt;
+ enum clnt_stat clnt_stat;
+
+ stat_whoami_res.client_name = cln;
+ stat_whoami_res.domain_name = dmn;
+
+ stat_getfile_res.server_name = cln;
+ stat_getfile_res.server_path = path;
+
+ if (argc < 3) {
+ fprintf(stderr,
+ "Usage: %s server procnum (IP-addr | host fileid)\n", argv[0]);
+ exit(1);
+ }
+
+
+ server = argv[1];
+ if ( ! strcmp(server , "all") ) broadcast = 1;
+
+ if ( ! broadcast ) {
+ clnt = clnt_create(server,BOOTPARAMPROG, BOOTPARAMVERS, "udp");
+ }
+
+
+ switch (argc) {
+ case 3:
+ whoami_arg.client_address.address_type = IP_ADDR_TYPE;
+ the_inet_addr = inet_addr(argv[2]);
+ if ( the_inet_addr == -1) {
+ fprintf(stderr, "bogus addr %s\n", argv[2]);
+ exit(1);
+ }
+ bcopy(&the_inet_addr,&whoami_arg.client_address.bp_address_u.ip_addr,4);
+
+ if (! broadcast ) {
+ whoami_res = bootparamproc_whoami_1(&whoami_arg, clnt);
+ printf("Whoami returning:\n");
+ if (printwhoami(whoami_res)) {
+ fprintf(stderr, "Bad answer returned from server %s\n", server);
+ exit(1);
+ } else
+ exit(0);
+ } else {
+ clnt_stat=clnt_broadcast(BOOTPARAMPROG, BOOTPARAMVERS,
+ BOOTPARAMPROC_WHOAMI,
+ xdr_bp_whoami_arg, &whoami_arg,
+ xdr_bp_whoami_res, &stat_whoami_res, eachres_whoami);
+ exit(0);
+ }
+
+ case 4:
+
+ getfile_arg.client_name = argv[2];
+ getfile_arg.file_id = argv[3];
+
+ if (! broadcast ) {
+ getfile_res = bootparamproc_getfile_1(&getfile_arg,clnt);
+ printf("getfile returning:\n");
+ if (printgetfile(getfile_res)) {
+ fprintf(stderr, "Bad answer returned from server %s\n", server);
+ exit(1);
+ } else
+ exit(0);
+ } else {
+ clnt_stat=clnt_broadcast(BOOTPARAMPROG, BOOTPARAMVERS,
+ BOOTPARAMPROC_GETFILE,
+ xdr_bp_getfile_arg, &getfile_arg,
+ xdr_bp_getfile_res, &stat_getfile_res,eachres_getfile);
+ exit(0);
+ }
+
+ default:
+
+ fprintf(stderr,
+ "Usage: %s server procnum (IP-addr | host fileid)\n", argv[0]);
+ exit(1);
+ }
+
+}
+
+
+
+int printwhoami(res)
+bp_whoami_res *res;
+{
+ if ( res) {
+ printf("client_name:\t%s\ndomain_name:\t%s\n",
+ res->client_name, res->domain_name);
+ printf("router:\t%d.%d.%d.%d\n",
+ 255 & res->router_address.bp_address_u.ip_addr.net,
+ 255 & res->router_address.bp_address_u.ip_addr.host,
+ 255 & res->router_address.bp_address_u.ip_addr.lh,
+ 255 & res->router_address.bp_address_u.ip_addr.impno);
+ return(0);
+ } else {
+ fprintf(stderr,"Null answer!!!\n");
+ return(1);
+ }
+ }
+
+
+
+
+int
+printgetfile(res)
+bp_getfile_res *res;
+{
+ if (res) {
+ printf("server_name:\t%s\nserver_address:\t%s\npath:\t%s\n",
+ res->server_name,
+ inet_ntoa(res->server_address.bp_address_u.ip_addr),
+ res->server_path);
+ return(0);
+ } else {
+ fprintf(stderr,"Null answer!!!\n");
+ return(1);
+ }
+ }