diff options
Diffstat (limited to 'usr.sbin/bootparamd')
-rw-r--r-- | usr.sbin/bootparamd/Makefile | 5 | ||||
-rw-r--r-- | usr.sbin/bootparamd/Makefile.inc | 6 | ||||
-rw-r--r-- | usr.sbin/bootparamd/bootparamd/Makefile | 29 | ||||
-rw-r--r-- | usr.sbin/bootparamd/bootparamd/Makefile.depend | 33 | ||||
-rw-r--r-- | usr.sbin/bootparamd/bootparamd/README | 61 | ||||
-rw-r--r-- | usr.sbin/bootparamd/bootparamd/bootparamd.8 | 76 | ||||
-rw-r--r-- | usr.sbin/bootparamd/bootparamd/bootparamd.c | 358 | ||||
-rw-r--r-- | usr.sbin/bootparamd/bootparamd/bootparams.5 | 86 | ||||
-rw-r--r-- | usr.sbin/bootparamd/bootparamd/main.c | 115 | ||||
-rw-r--r-- | usr.sbin/bootparamd/callbootd/Makefile | 24 | ||||
-rw-r--r-- | usr.sbin/bootparamd/callbootd/Makefile.depend | 31 | ||||
-rw-r--r-- | usr.sbin/bootparamd/callbootd/callbootd.c | 204 |
12 files changed, 1028 insertions, 0 deletions
diff --git a/usr.sbin/bootparamd/Makefile b/usr.sbin/bootparamd/Makefile new file mode 100644 index 0000000..c4e3361 --- /dev/null +++ b/usr.sbin/bootparamd/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ + +SUBDIR= bootparamd callbootd + +.include <bsd.subdir.mk> diff --git a/usr.sbin/bootparamd/Makefile.inc b/usr.sbin/bootparamd/Makefile.inc new file mode 100644 index 0000000..5c01215 --- /dev/null +++ b/usr.sbin/bootparamd/Makefile.inc @@ -0,0 +1,6 @@ +# @(#)Makefile.inc 5.1 (Berkeley) 5/11/90 +# $FreeBSD$ + +BINDIR?= /usr/sbin + +WARNS?= 2 diff --git a/usr.sbin/bootparamd/bootparamd/Makefile b/usr.sbin/bootparamd/bootparamd/Makefile new file mode 100644 index 0000000..0596993 --- /dev/null +++ b/usr.sbin/bootparamd/bootparamd/Makefile @@ -0,0 +1,29 @@ +# from: @(#)Makefile 5.8 (Berkeley) 7/28/90 +# $FreeBSD$ + +.include <src.opts.mk> + +PROG= bootparamd +MAN= bootparams.5 bootparamd.8 +SRCS= bootparamd.c main.c ${GENSRCS} +GENSRCS=bootparam_prot.h bootparam_prot_svc.c bootparam_prot_xdr.c + +CFLAGS+= -DTFTP_DIR=\"/tftpboot\" -I. +.if ${MK_NIS} != "no" +CFLAGS+= -DYP +.endif + +CLEANFILES= ${GENSRCS} + +RPCSRC= ${DESTDIR}/usr/include/rpcsvc/bootparam_prot.x + +bootparam_prot_svc.c: ${RPCSRC} + RPCGEN_CPP=${CPP:Q} rpcgen -C -m -o ${.TARGET} ${RPCSRC} + +bootparam_prot_xdr.c: ${RPCSRC} + RPCGEN_CPP=${CPP:Q} rpcgen -C -c -o ${.TARGET} ${RPCSRC} + +bootparam_prot.h: ${RPCSRC} + RPCGEN_CPP=${CPP:Q} rpcgen -C -h -o ${.TARGET} ${RPCSRC} + +.include <bsd.prog.mk> diff --git a/usr.sbin/bootparamd/bootparamd/Makefile.depend b/usr.sbin/bootparamd/bootparamd/Makefile.depend new file mode 100644 index 0000000..a1d24b5 --- /dev/null +++ b/usr.sbin/bootparamd/bootparamd/Makefile.depend @@ -0,0 +1,33 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + gnu/lib/libgcc \ + include \ + include/arpa \ + include/rpc \ + include/rpcsvc \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +bootparam_prot_svc.o: bootparam_prot.h +bootparam_prot_svc.o: bootparam_prot_svc.c +bootparam_prot_svc.po: bootparam_prot.h +bootparam_prot_svc.po: bootparam_prot_svc.c +bootparam_prot_xdr.o: bootparam_prot.h +bootparam_prot_xdr.o: bootparam_prot_xdr.c +bootparam_prot_xdr.po: bootparam_prot.h +bootparam_prot_xdr.po: bootparam_prot_xdr.c +bootparamd.o: bootparam_prot.h +bootparamd.po: bootparam_prot.h +main.o: bootparam_prot.h +main.po: bootparam_prot.h +.endif diff --git a/usr.sbin/bootparamd/bootparamd/README b/usr.sbin/bootparamd/bootparamd/README new file mode 100644 index 0000000..c49b990 --- /dev/null +++ b/usr.sbin/bootparamd/bootparamd/README @@ -0,0 +1,61 @@ +$FreeBSD$ + +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 reside 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-address +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/bootparamd.8 b/usr.sbin/bootparamd/bootparamd/bootparamd.8 new file mode 100644 index 0000000..183302a --- /dev/null +++ b/usr.sbin/bootparamd/bootparamd/bootparamd.8 @@ -0,0 +1,76 @@ +.\" @(#)bootparamd.8 +.\" $FreeBSD$ +.Dd December 14, 2000 +.Dt BOOTPARAMD 8 +.Os +.Sh NAME +.Nm bootparamd +.Nd boot parameter server +.Sh SYNOPSIS +.Nm +.Op Fl ds +.Op Fl r Ar router +.Op Fl f Ar file +.Sh DESCRIPTION +The +.Nm +utility is a server process that provides information to +.Xr diskless 8 +clients necessary for booting. +It consults the +.Pa /etc/bootparams +file. +.Pp +This version will allow the use of aliases on the hostname in the +.Pa /etc/bootparams +file. +The returned hostname to the +.Em whoami +request done by the booting client +will be the name that appears in +.Pa /etc/bootparams +and not the canonical name. +In this way you can keep the answer short enough +so that machines that cannot handle long hostnames will not fail during boot. +.Sh OPTIONS +.Bl -tag -width Fl +.It Fl d +Display the debugging information. +.It Fl s +Log the debugging information with +.Xr syslog 3 . +.It Fl r Ar router +The default router (a machine or an IP-address). +This defaults to the machine running the server. +.It Fl f Ar file +The file to use as boot parameter file instead of +.Pa /etc/bootparams . +.El +.Sh FILES +.Bl -tag -width /etc/bootparams -compact +.It Pa /etc/bootparams +default boot parameter file +.El +.Sh EXAMPLES +When netbooting diskless SunOS/Xkernel SPARCstations the booted SunOS kernel +also broadcasts to the all-0 address. +The SunOS kernel hangs until it receives a reply. +To accommodate this behaviour add an alias address +that responds to an all-0 broadcast. +So, add something like +.Ql "ifconfig xl0 192.168.200.254 netmask 255.255.255.255 broadcast 192.168.200.0 alias" +on the relevant network interface on your +.Nm +server. +The alias address must of course be free for use. +.Sh SEE ALSO +.Xr syslog 3 , +.Xr bootparams 5 , +.Xr diskless 8 +.Sh AUTHORS +Written by +.An Klas Heggemann Aq Mt klas@nada.kth.se . +.Sh BUGS +You may find the +.Xr syslog 3 +loggings to be verbose. diff --git a/usr.sbin/bootparamd/bootparamd/bootparamd.c b/usr.sbin/bootparamd/bootparamd/bootparamd.c new file mode 100644 index 0000000..0921305 --- /dev/null +++ b/usr.sbin/bootparamd/bootparamd/bootparamd.c @@ -0,0 +1,358 @@ +/* + +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> + +*/ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#ifdef YP +#include <rpc/rpc.h> +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> +#endif +#include "bootparam_prot.h" +#include <ctype.h> +#include <err.h> +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +extern int debug, dolog; +extern in_addr_t 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]; + +int getthefile(char *, char *, char *, int); +int checkhost(char *, char *, int); + +bp_whoami_res * +bootparamproc_whoami_1_svc(whoami, req) +bp_whoami_arg *whoami; +struct svc_req *req; +{ + in_addr_t 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) warnx("this is host %s", he->h_name); + if (dolog) syslog(LOG_NOTICE,"This is host %s\n", he->h_name); + + strncpy(askname, he->h_name, sizeof(askname)); + askname[sizeof(askname)-1] = 0; + + if (checkhost(askname, hostname, sizeof 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, sizeof(in_addr_t)); + } + 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) warnx("whoami failed"); + if (dolog) syslog(LOG_NOTICE,"whoami failed\n"); + return(NULL); +} + + +bp_getfile_res * + bootparamproc_getfile_1_svc(getfile, req) +bp_getfile_arg *getfile; +struct svc_req *req; +{ + char *where; + static bp_getfile_res res; + + if (debug) + warnx("getfile got question for \"%s\" and file \"%s\"", + 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; + + strncpy(askname, he->h_name, sizeof(askname)); + askname[sizeof(askname)-1] = 0; + + if (getthefile(askname, getfile->file_id,buffer,sizeof(buffer))) { + if ( (where = strchr(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) warnx("getfile failed for %s", 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") */ + +int +getthefile(askname,fileid,buffer,blen) +char *askname; +char *fileid, *buffer; +int blen; +{ + FILE *bpf; + char *where; +#ifdef YP + static char *result; + int resultlen; + static char *yp_domain; +#endif + + 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 ) + errx(1, "no %s", bootpfile); + + /* XXX see comment below */ + while ( fscanf(bpf, "%255s", 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 */ +#ifdef YP + if (yp_get_default_domain(&yp_domain)) { + if (debug) warn("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 { + snprintf(buffer, blen, + "%s",strchr(strstr(result,fileid), '=') + 1); + if (strchr(buffer, ' ') != NULL) + *(char *)(strchr(buffer, ' ')) = '\0'; + } + if (fclose(bpf)) + warnx("could not close %s", bootpfile); + return(1); +#else + return(0); /* ENOTSUP */ +#endif + } + /* 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)) { warnx("could not close %s", 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 */ + +int +checkhost(askname, hostname, len) +char *askname; +char *hostname; +int len; +{ + int ch, pch; + FILE *bpf; + int res = 0; +#ifdef YP + static char *result; + int resultlen; + static char *yp_domain; +#endif + +/* struct hostent *cmp_he;*/ + + bpf = fopen(bootpfile, "r"); + if ( ! bpf ) + errx(1, "no %s", bootpfile); + + /* XXX there is no way in ISO C to specify the maximal length for a + conversion in a variable way */ + while ( fscanf(bpf, "%254s", 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 */ +#ifdef YP + if (yp_get_default_domain(&yp_domain)) { + if (debug) warn("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; + snprintf(hostname, len, "%s", he->h_name); + } + } + if (fclose(bpf)) + warnx("could not close %s", bootpfile); + return(res); +#else + return(0); /* ENOTSUP */ +#endif + } + /* skip to next entry */ + pch = ch = getc(bpf); + while ( ! ( ch == '\n' && pch != '\\') && ch != EOF) { + pch = ch; ch = getc(bpf); + } + } + if (fclose(bpf)) { warnx("could not close %s", bootpfile); } + return(res); +} diff --git a/usr.sbin/bootparamd/bootparamd/bootparams.5 b/usr.sbin/bootparamd/bootparamd/bootparams.5 new file mode 100644 index 0000000..c7c6785 --- /dev/null +++ b/usr.sbin/bootparamd/bootparamd/bootparams.5 @@ -0,0 +1,86 @@ +.\" +.\" 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. +.\" +.\" from: Id: bootparams.5,v 1.2 1994/10/03 19:26:13 gwr Exp +.\" $FreeBSD$ +.\" +.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 +file specifies the boot parameters that +.Xr diskless 8 +clients may request when booting over the network. +Each client supported by this server must have an entry in the +.Nm +file containing the pathnames for its +.Dq root +and (optionally) +.Dq swap +areas. +.Pp +Each line in the file +(other than comment lines that begin with a +.Ql # ) +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=host:/export/dummy/root \\ + swap=host:/export/dummy/swap \\ + dump=host:/export/dummy/swap +.Ed +.Pp +When the client named +.Dq dummy +requests the pathname for its logical +.Dq root +it will be given the pathname +.Dq Pa host:/export/dummy/root +as the response to its +.Tn RPC +request. +The +.Dq host: +component must be supplied. +.Sh FILES +.Bl -tag -width /etc/bootparams -compact +.It Pa /etc/bootparams +default configuration file +.El +.Sh SEE ALSO +.Xr bootparamd 8 , +.Xr diskless 8 diff --git a/usr.sbin/bootparamd/bootparamd/main.c b/usr.sbin/bootparamd/bootparamd/main.c new file mode 100644 index 0000000..04f5cef --- /dev/null +++ b/usr.sbin/bootparamd/bootparamd/main.c @@ -0,0 +1,115 @@ +/* + +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> + +*/ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#include <ctype.h> +#include <err.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> +#include <rpc/rpc.h> +#include <rpc/pmap_clnt.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include "bootparam_prot.h" + +int debug = 0; +int dolog = 0; +in_addr_t route_addr = -1; +struct sockaddr_in my_addr; +char *bootpfile = "/etc/bootparams"; + +static void usage(void); + +int +main(int argc, char **argv) +{ + SVCXPRT *transp; + struct hostent *he; + struct stat buf; + int c; + + while ((c = getopt(argc, argv,"dsr:f:")) != -1) + switch (c) { + case 'd': + debug = 1; + break; + case 'r': + if (isdigit((unsigned char)*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 { + errx(1, "no such host %s", optarg); + } + } + case 'f': + bootpfile = optarg; + break; + case 's': + dolog = 1; +#ifndef LOG_DAEMON + openlog("bootparamd", 0 , 0); +#else + openlog("bootparamd", 0 , LOG_DAEMON); + setlogmask(LOG_UPTO(LOG_NOTICE)); +#endif + break; + default: + usage(); + } + + if ( stat(bootpfile, &buf ) ) + err(1, "%s", bootpfile); + + if (route_addr == INADDR_NONE) { + get_myaddress(&my_addr); + bcopy(&my_addr.sin_addr.s_addr, &route_addr, sizeof (route_addr)); + } + + if (!debug) { + if (daemon(0,0)) + err(1, "fork"); + } + + + (void)pmap_unset(BOOTPARAMPROG, BOOTPARAMVERS); + + transp = svcudp_create(RPC_ANYSOCK); + if (transp == NULL) + errx(1, "cannot create udp service"); + if (!svc_register(transp, BOOTPARAMPROG, BOOTPARAMVERS, bootparamprog_1, IPPROTO_UDP)) + errx(1, "unable to register (BOOTPARAMPROG, BOOTPARAMVERS, udp)"); + + svc_run(); + errx(1, "svc_run returned"); +} + +static void +usage(void) +{ + fprintf(stderr, + "usage: bootparamd [-d] [-s] [-r router] [-f bootparmsfile]\n"); + exit(1); +} diff --git a/usr.sbin/bootparamd/callbootd/Makefile b/usr.sbin/bootparamd/callbootd/Makefile new file mode 100644 index 0000000..28b1e26 --- /dev/null +++ b/usr.sbin/bootparamd/callbootd/Makefile @@ -0,0 +1,24 @@ +# from: @(#)Makefile 5.8 (Berkeley) 7/28/90 +# $FreeBSD$ + +PROG= callbootd +MAN= +SRCS= callbootd.c ${GENSRCS} +GENSRCS=bootparam_prot.h bootparam_prot_clnt.c bootparam_prot_xdr.c + +CFLAGS+= -I. + +CLEANFILES= ${GENSRCS} + +RPCSRC= ${DESTDIR}/usr/include/rpcsvc/bootparam_prot.x + +bootparam_prot_clnt.c: ${RPCSRC} + RPCGEN_CPP=${CPP:Q} rpcgen -C -l -o ${.TARGET} ${RPCSRC} + +bootparam_prot_xdr.c: ${RPCSRC} + RPCGEN_CPP=${CPP:Q} rpcgen -C -c -o ${.TARGET} ${RPCSRC} + +bootparam_prot.h: ${RPCSRC} + RPCGEN_CPP=${CPP:Q} rpcgen -C -h -o ${.TARGET} ${RPCSRC} + +.include <bsd.prog.mk> diff --git a/usr.sbin/bootparamd/callbootd/Makefile.depend b/usr.sbin/bootparamd/callbootd/Makefile.depend new file mode 100644 index 0000000..e34ede1 --- /dev/null +++ b/usr.sbin/bootparamd/callbootd/Makefile.depend @@ -0,0 +1,31 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + gnu/lib/libgcc \ + include \ + include/arpa \ + include/rpc \ + include/rpcsvc \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +bootparam_prot_clnt.o: bootparam_prot.h +bootparam_prot_clnt.o: bootparam_prot_clnt.c +bootparam_prot_clnt.po: bootparam_prot.h +bootparam_prot_clnt.po: bootparam_prot_clnt.c +bootparam_prot_xdr.o: bootparam_prot.h +bootparam_prot_xdr.o: bootparam_prot_xdr.c +bootparam_prot_xdr.po: bootparam_prot.h +bootparam_prot_xdr.po: bootparam_prot_xdr.c +callbootd.o: bootparam_prot.h +callbootd.po: bootparam_prot.h +.endif diff --git a/usr.sbin/bootparamd/callbootd/callbootd.c b/usr.sbin/bootparamd/callbootd/callbootd.c new file mode 100644 index 0000000..7c32fee --- /dev/null +++ b/usr.sbin/bootparamd/callbootd/callbootd.c @@ -0,0 +1,204 @@ +/* + +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> + +*/ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#include "bootparam_prot.h" +#include <rpc/rpc.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <err.h> +#include <netdb.h> +#include <stdlib.h> + + +/* #define bp_address_u bp_address */ +#include <stdio.h> +#include <string.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(); +static void usage(void); +int printgetfile(bp_getfile_res *); +int printwhoami(bp_whoami_res *); + +bool_t +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); +} + +bool_t +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); +} + + +int +main(argc, argv) +int argc; +char **argv; +{ + 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; + + 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) + usage(); + + server = argv[1]; + if ( ! strcmp(server , "all") ) broadcast = 1; + + if ( ! broadcast ) { + clnt = clnt_create(server,BOOTPARAMPROG, BOOTPARAMVERS, "udp"); + if ( clnt == NULL ) + errx(1, "could not contact bootparam server on host %s", server); + } + + switch (argc) { + case 3: + whoami_arg.client_address.address_type = IP_ADDR_TYPE; + the_inet_addr = inet_addr(argv[2]); + if ( the_inet_addr == INADDR_NONE) + errx(2, "bogus addr %s", argv[2]); + 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)) { + errx(1, "bad answer returned from server %s", server); + } else + exit(0); + } else { + (void)clnt_broadcast(BOOTPARAMPROG, BOOTPARAMVERS, + BOOTPARAMPROC_WHOAMI, + (xdrproc_t)xdr_bp_whoami_arg, + (char *)&whoami_arg, + (xdrproc_t)xdr_bp_whoami_res, + (char *)&stat_whoami_res, + (resultproc_t)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)) { + errx(1, "bad answer returned from server %s", server); + } else + exit(0); + } else { + (void)clnt_broadcast(BOOTPARAMPROG, BOOTPARAMVERS, + BOOTPARAMPROC_GETFILE, + (xdrproc_t)xdr_bp_getfile_arg, + (char *)&getfile_arg, + (xdrproc_t)xdr_bp_getfile_res, + (char *)&stat_getfile_res, + (resultproc_t)eachres_getfile); + exit(0); + } + + default: + + usage(); + } + +} + + +static void +usage() +{ + fprintf(stderr, + "usage: callbootd server procnum (IP-addr | host fileid)\n"); + 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 { + warnx("null answer!!!"); + 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(*(struct in_addr *)&res->server_address.bp_address_u.ip_addr), + res->server_path); + return(0); + } else { + warnx("null answer!!!"); + return(1); + } + } |