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.
This commit is contained in:
Bill Paul 1995-02-26 23:40:53 +00:00
parent 23adc6b882
commit b9fefab743
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/bootparamd/; revision=6751
11 changed files with 1203 additions and 0 deletions

View File

@ -0,0 +1,4 @@
SUBDIR= bootparamd callbootd
.include <bsd.subdir.mk>

View File

@ -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>

View File

@ -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.)

View File

@ -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();

View File

@ -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;

View File

@ -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);
}

View File

@ -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>

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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>

View File

@ -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);
}
}