From 3d7a6e262b86c7c803cf9ce87bbc84ae2b8bef84 Mon Sep 17 00:00:00 2001 From: wpaul Date: Sun, 26 Feb 1995 23:40:53 +0000 Subject: 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. --- usr.sbin/bootparamd/Makefile | 4 + usr.sbin/bootparamd/bootparamd/Makefile | 29 ++ usr.sbin/bootparamd/bootparamd/README | 75 +++++ usr.sbin/bootparamd/bootparamd/bootparam_prot.h | 81 +++++ usr.sbin/bootparamd/bootparamd/bootparam_prot.x | 100 +++++++ .../bootparamd/bootparamd/bootparam_prot_xdr.c | 166 +++++++++++ usr.sbin/bootparamd/bootparamd/bootparamd.8 | 65 ++++ usr.sbin/bootparamd/bootparamd/bootparamd.c | 329 +++++++++++++++++++++ usr.sbin/bootparamd/bootparamd/main.c | 139 +++++++++ usr.sbin/bootparamd/callbootd/Makefile | 28 ++ usr.sbin/bootparamd/callbootd/callbootd.c | 187 ++++++++++++ 11 files changed, 1203 insertions(+) create mode 100644 usr.sbin/bootparamd/Makefile create mode 100644 usr.sbin/bootparamd/bootparamd/Makefile create mode 100644 usr.sbin/bootparamd/bootparamd/README create mode 100644 usr.sbin/bootparamd/bootparamd/bootparam_prot.h create mode 100644 usr.sbin/bootparamd/bootparamd/bootparam_prot.x create mode 100644 usr.sbin/bootparamd/bootparamd/bootparam_prot_xdr.c create mode 100644 usr.sbin/bootparamd/bootparamd/bootparamd.8 create mode 100644 usr.sbin/bootparamd/bootparamd/bootparamd.c create mode 100644 usr.sbin/bootparamd/bootparamd/main.c create mode 100644 usr.sbin/bootparamd/callbootd/Makefile create mode 100644 usr.sbin/bootparamd/callbootd/callbootd.c (limited to 'usr.sbin/bootparamd') diff --git a/usr.sbin/bootparamd/Makefile b/usr.sbin/bootparamd/Makefile new file mode 100644 index 0000000..c4f6198 --- /dev/null +++ b/usr.sbin/bootparamd/Makefile @@ -0,0 +1,4 @@ + +SUBDIR= bootparamd callbootd + +.include diff --git a/usr.sbin/bootparamd/bootparamd/Makefile b/usr.sbin/bootparamd/bootparamd/Makefile new file mode 100644 index 0000000..fbfdc42 --- /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 diff --git a/usr.sbin/bootparamd/bootparamd/README b/usr.sbin/bootparamd/bootparamd/README new file mode 100644 index 0000000..85a2a54 --- /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 + + +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 0000000..66c7227 --- /dev/null +++ b/usr.sbin/bootparamd/bootparamd/bootparam_prot.h @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#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 0000000..6d3c3e7 --- /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 +%#include +%#include +%#include +#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; +typedef string bp_path_t; +typedef string bp_fileid_t; + +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 0000000..72fc2ee --- /dev/null +++ b/usr.sbin/bootparamd/bootparamd/bootparam_prot_xdr.c @@ -0,0 +1,166 @@ +#include +#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 0000000..9a19868 --- /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 + + diff --git a/usr.sbin/bootparamd/bootparamd/bootparamd.c b/usr.sbin/bootparamd/bootparamd/bootparamd.c new file mode 100644 index 0000000..d91b053 --- /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 + + $Id$ + +*/ + + +#include +#include "bootparam_prot.h" +#include +#include +#include +#include +#include +#include +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 0000000..70381c8 --- /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 + + + $Id$ + +*/ + +#include +#include +#include +#include +#include "bootparam_prot.h" +#include +#include +#include +#include +#include + +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 0000000..9be4af3 --- /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 diff --git a/usr.sbin/bootparamd/callbootd/callbootd.c b/usr.sbin/bootparamd/callbootd/callbootd.c new file mode 100644 index 0000000..22dbd5a --- /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 + + $Id$ +*/ + + +#include "bootparam_prot.h" +#include +#include +#include +#include + + +/* #define bp_address_u bp_address */ +#include + +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); + } + } -- cgit v1.1