summaryrefslogtreecommitdiff
path: root/usr.sbin/rpc.bootparamd
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /usr.sbin/rpc.bootparamd
initial import of NetBSD tree
Diffstat (limited to 'usr.sbin/rpc.bootparamd')
-rw-r--r--usr.sbin/rpc.bootparamd/Makefile22
-rw-r--r--usr.sbin/rpc.bootparamd/bootparamd.c383
-rw-r--r--usr.sbin/rpc.bootparamd/bootparams.578
-rw-r--r--usr.sbin/rpc.bootparamd/pathnames.h10
-rw-r--r--usr.sbin/rpc.bootparamd/rpc.bootparamd.862
5 files changed, 555 insertions, 0 deletions
diff --git a/usr.sbin/rpc.bootparamd/Makefile b/usr.sbin/rpc.bootparamd/Makefile
new file mode 100644
index 00000000000..9a275277b92
--- /dev/null
+++ b/usr.sbin/rpc.bootparamd/Makefile
@@ -0,0 +1,22 @@
+# $Id: Makefile,v 1.1 1995/10/18 08:48:05 deraadt Exp $
+
+CFLAGS+=-DYP
+
+PROG= rpc.bootparamd
+SRCS= bootparamd.c bootparam_prot_svc.c
+MAN= bootparams.5 rpc.bootparamd.8
+MLINKS= rpc.bootparamd.8 bootparamd.8
+
+DPADD= ${LIBRPCSVC}
+LDADD= -lrpcsvc
+
+bootparam_prot_svc.c: ${DESTDIR}/usr/include/rpcsvc/bootparam_prot.x
+ rm -f bootparam_prot.x
+ ln -s ${DESTDIR}/usr/include/rpcsvc/bootparam_prot.x .
+ rm -f bootparam_prot.h
+ ln -s ${DESTDIR}/usr/include/rpcsvc/bootparam_prot.h .
+ rpcgen -m -o $@ bootparam_prot.x
+
+CLEANFILES += bootparam_prot_svc.c bootparam_prot.x bootparam_prot.h
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/rpc.bootparamd/bootparamd.c b/usr.sbin/rpc.bootparamd/bootparamd.c
new file mode 100644
index 00000000000..bd0dabebfcc
--- /dev/null
+++ b/usr.sbin/rpc.bootparamd/bootparamd.c
@@ -0,0 +1,383 @@
+/*
+ * 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>
+ *
+ * Various small changes by Theo de Raadt <deraadt@fsa.ca>
+ * Parser rewritten (adding YP support) by Roland McGrath <roland@frob.com>
+ *
+ * $Id: bootparamd.c,v 1.1 1995/10/18 08:48:05 deraadt Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/bootparam_prot.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <syslog.h>
+#include <string.h>
+#include "pathnames.h"
+
+#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];
+
+extern void bootparamprog_1 __P((struct svc_req *, SVCXPRT *));
+
+int _rpcsvcdirty = 0;
+int _rpcpmstart = 0;
+int debug = 0;
+int dolog = 0;
+unsigned long route_addr, inet_addr();
+struct sockaddr_in my_addr;
+char *progname;
+char *bootpfile = _PATH_BOOTPARAMS;
+
+extern char *optarg;
+extern int optind;
+
+void
+usage()
+{
+ fprintf(stderr,
+ "usage: rpc.bootparamd [-d] [-s] [-r router] [-f bootparmsfile]\n");
+}
+
+
+/*
+ * ever familiar
+ */
+int
+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;
+ }
+ he = gethostbyname(optarg);
+ if (!he) {
+ fprintf(stderr, "%s: No such host %s\n",
+ progname, optarg);
+ usage();
+ exit(1);
+ }
+ bcopy(he->h_addr, (char *) &route_addr, sizeof(route_addr));
+ break;
+ 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:
+ usage();
+ exit(1);
+ }
+
+ if (stat(bootpfile, &buf)) {
+ fprintf(stderr, "%s: ", progname);
+ perror(bootpfile);
+ exit(1);
+ }
+ if (!route_addr) {
+ get_myaddress(&my_addr);
+ bcopy(&my_addr.sin_addr.s_addr, &route_addr, sizeof(route_addr));
+ }
+ if (!debug)
+ daemon();
+
+ (void) pmap_unset(BOOTPARAMPROG, BOOTPARAMVERS);
+
+ transp = svcudp_create(RPC_ANYSOCK);
+ if (transp == NULL) {
+ fprintf(stderr, "cannot create udp service.\n");
+ exit(1);
+ }
+ if (!svc_register(transp, BOOTPARAMPROG, BOOTPARAMVERS,
+ bootparamprog_1, IPPROTO_UDP)) {
+ fprintf(stderr,
+ "bootparamd: unable to register BOOTPARAMPROG version %d, udp)\n",
+ BOOTPARAMVERS);
+ exit(1);
+ }
+ svc_run();
+ fprintf(stderr, "svc_run returned\n");
+ exit(1);
+}
+
+bp_whoami_res *
+bootparamproc_whoami_1_svc(whoami, rqstp)
+ bp_whoami_arg *whoami;
+ struct svc_req *rqstp;
+{
+ 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 (!lookup_bootparam(askname, hostname, NULL, NULL, NULL)) {
+ 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_svc(getfile, rqstp)
+ bp_getfile_arg *getfile;
+ struct svc_req *rqstp;
+{
+ char *where, *index();
+ static bp_getfile_res res;
+ int err;
+
+ 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);
+ err = lookup_bootparam(askname, NULL, getfile->file_id,
+ &res.server_name, &res.server_path);
+ if (err == 0) {
+ he = gethostbyname(res.server_name);
+ if (!he)
+ goto failed;
+ bcopy(he->h_addr, &res.server_address.bp_address_u.ip_addr, 4);
+ res.server_address.address_type = IP_ADDR_TYPE;
+ } else if (err == ENOENT && !strcmp(getfile->file_id, "dump")) {
+ /* Special for dump, answer with null strings. */
+ res.server_name[0] = '\0';
+ res.server_path[0] = '\0';
+ bzero(&res.server_address.bp_address_u.ip_addr, 4);
+ } else {
+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);
+ }
+
+ 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);
+}
+
+
+int
+lookup_bootparam(client, client_canonical, id, server, path)
+ char *client;
+ char *client_canonical;
+ char *id;
+ char **server;
+ char **path;
+{
+ FILE *f = fopen(bootpfile, "r");
+#ifdef YP
+ static char *ypbuf = NULL;
+ static int ypbuflen = 0;
+#endif
+ static char buf[BUFSIZ];
+ char *bp, *word;
+ size_t idlen = id == NULL ? 0 : strlen(id);
+ int contin = 0;
+ int found = 0;
+
+ if (f == NULL)
+ return EINVAL; /* ? */
+
+ while (fgets(buf, sizeof buf, f)) {
+ int wascontin = contin;
+ contin = buf[strlen(buf) - 2] == '\\';
+ bp = buf + strspn(buf, " \t\n");
+
+ switch (wascontin) {
+ case -1:
+ /* Continuation of uninteresting line */
+ contin *= -1;
+ continue;
+ case 0:
+ /* New line */
+ contin *= -1;
+ if (*bp == '#')
+ continue;
+ if ((word = strsep(&bp, " \t\n")) == NULL)
+ continue;
+#ifdef YP
+ /* A + in the file means try YP now */
+ if (!strcmp(word, "+")) {
+ char *ypdom;
+
+ if (yp_get_default_domain(&ypdom) ||
+ yp_match(ypdom, "bootparams", client,
+ strlen(client), &ypbuf, &ypbuflen))
+ continue;
+ bp = ypbuf;
+ word = client;
+ contin *= -1;
+ break;
+ }
+#endif
+ /* See if this line's client is the one we are
+ * looking for */
+ if (strcmp(word, client) != 0) {
+ /*
+ * If it didn't match, try getting the
+ * canonical host name of the client
+ * on this line and comparing that to
+ * the client we are looking for
+ */
+ struct hostent *hp = gethostbyname(word);
+ if (hp == NULL || strcmp(hp->h_name, client))
+ continue;
+ }
+ contin *= -1;
+ break;
+ case 1:
+ /* Continued line we want to parse below */
+ break;
+ }
+
+ if (client_canonical)
+ strncpy(client_canonical, word, MAX_MACHINE_NAME);
+
+ /* We have found a line for CLIENT */
+ if (id == NULL) {
+ (void) fclose(f);
+ return 0;
+ }
+
+ /* Look for a value for the parameter named by ID */
+ while ((word = strsep(&bp, " \t\n")) != NULL) {
+ if (!strncmp(word, id, idlen) && word[idlen] == '=') {
+ /* We have found the entry we want */
+ *server = &word[idlen + 1];
+ *path = strchr(*server, ':');
+ if (*path == NULL)
+ /* Malformed entry */
+ continue;
+ *(*path)++ = '\0';
+ (void) fclose(f);
+ return 0;
+ }
+ }
+
+ found = 1;
+ }
+
+ (void) fclose(f);
+ return found ? ENOENT : EPERM;
+}
diff --git a/usr.sbin/rpc.bootparamd/bootparams.5 b/usr.sbin/rpc.bootparamd/bootparams.5
new file mode 100644
index 00000000000..06a965144af
--- /dev/null
+++ b/usr.sbin/rpc.bootparamd/bootparams.5
@@ -0,0 +1,78 @@
+.\"
+.\" Copyright (c) 1994 Gordon W. Ross
+.\" 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. 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 THE AUTHOR ``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 AUTHOR 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.
+.\"
+.\" $Id: bootparams.5,v 1.1 1995/10/18 08:48:05 deraadt Exp $
+.\"
+.Dd October 2, 1994
+.Dt BOOTPARAMS 5
+.Os
+.Sh NAME
+.Nm bootparams
+.Nd boot parameter database
+.Sh SYNOPSIS
+.Nm /etc/bootparams
+.Sh DESCRIPTION
+The
+.Nm bootparams
+file specifies the boot parameters that
+.Xr diskless
+clients may request when booting over the network.
+Each client supported by this server must have an entry in the
+.Nm bootparams
+file containing the pathnames for its
+.Nm root
+and (optionally)
+.Nm swap
+areas.
+.Pp
+Each line in the file
+(other than comment lines that begin with a #)
+specifies the client name followed by the pathnames that
+the client may request by their logical names.
+The components of the line are delimited with blank or tab,
+and may be continued onto multiple lines with a backslash.
+.Pp
+For example:
+.Bd -literal -offset indent
+dummy root=/export/dummy/root \\
+ swap=/export/dummy/swap \\
+ dump=/export/dummy/swap
+.Ed
+.Pp
+When the client named "dummy" requests the pathname for
+its logical "root" it will be given the pathname
+.Dq Pa "/export/dummy/root"
+as the response to its
+.Tn RPC
+request.
+.Sh FILES
+.Bl -tag -width /etc/bootparams -compact
+.It Pa /etc/bootparams
+default configuration file
+.El
+.Sh "SEE ALSO"
+.Xr diskless 8 ,
+.Xr rpc.bootparamd 8
diff --git a/usr.sbin/rpc.bootparamd/pathnames.h b/usr.sbin/rpc.bootparamd/pathnames.h
new file mode 100644
index 00000000000..f8048ead3a1
--- /dev/null
+++ b/usr.sbin/rpc.bootparamd/pathnames.h
@@ -0,0 +1,10 @@
+/*
+ * Written Roland McGrath <roland@frob.com> 10/15/93.
+ * Public domain.
+ *
+ * $Id: pathnames.h,v 1.1 1995/10/18 08:48:05 deraadt Exp $
+ */
+
+#include <paths.h>
+
+#define _PATH_BOOTPARAMS "/etc/bootparams"
diff --git a/usr.sbin/rpc.bootparamd/rpc.bootparamd.8 b/usr.sbin/rpc.bootparamd/rpc.bootparamd.8
new file mode 100644
index 00000000000..ceb52e8f2d4
--- /dev/null
+++ b/usr.sbin/rpc.bootparamd/rpc.bootparamd.8
@@ -0,0 +1,62 @@
+.\" $Id: rpc.bootparamd.8,v 1.1 1995/10/18 08:48:06 deraadt Exp $
+.\" @(#)bootparamd.8
+.Dd Jan 8, 1994
+.Dt BOOTPARAMD 8
+.Os NetBSD
+.Sh NAME
+.Nm bootparamd ,
+.Nm rpc.bootparamd
+.Nd boot parameter server
+.Sh SYNOPSIS
+.Nm /usr/sbin/rpc.bootparamd
+.Op Fl d
+.Op Fl s
+.Op Fl r router
+.Op Fl f file
+.Sh DESCRIPTION
+.Nm \&Bootparamd
+is a server process that provides information to diskless clients
+necessary for booting. It consults the file
+.Dq Pa /etc/bootparams .
+It should normally be started from
+.Dq Pa /etc/rc .
+.Pp
+This version will allow the use of aliases on the hostname in the
+.Dq Pa /etc/bootparams
+file. The hostname returned in response to the booting client's whoami request
+will be the name that appears in the config file, not the canonical name.
+In this way you can keep the answer short enough
+so that machines that cannot handle long hostnames won't fail during boot.
+.Pp
+While parsing, if a line containing just ``+'' is found, and
+the YP subsystem is active, the YP map
+.Pa bootparams
+will be searched immediately.
+.Sh OPTIONS
+.Bl -tag -width indent
+.It Fl d
+Display the debugging information. The daemon does not fork in this
+case.
+.It Fl s
+Log the debugging information with syslog.
+.It Fl r
+Set the default router (a hostname or IP-address).
+This defaults to the machine running the server.
+.It Fl f
+Specify the file to use as boot parameter file instead of
+.Dq Pa /etc/bootparams .
+.El
+.Pp
+.Sh FILES
+.Bl -tag -width /etc/bootparams -compact
+.It Pa /etc/bootparams
+default configuration file
+.El
+.Sh "SEE ALSO"
+.Xr bootparams 5
+.Sh BUGS
+You may find the syslog loggings too verbose.
+.Pp
+It's not clear if the non-cannonical hack mentioned above is a good idea.
+.Sh AUTHOR
+Originally written by Klas Heggemann <klas@nada.kth.se>