Import bootpd-2.4.3 from ftp.mc.com
This commit is contained in:
parent
a270abb407
commit
e08ac58bbe
3
libexec/bootpd/.indent.pro
vendored
Normal file
3
libexec/bootpd/.indent.pro
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
-nbad -nbap -nbbb -nbc -br -bli4 -c33 -cd33 -cdb -ce -ci4
|
||||
-cli0 -cp1 -d0 -di0 -nfc1 -nfca -i4 -ip4 -l75 -lp -npcs
|
||||
-psl -sc -nsob -nss -ts4
|
@ -45,6 +45,7 @@ Problems fixed in this version:
|
||||
When lookup_hwa fails, assume numeric HW address.
|
||||
|
||||
Systems on which I have seen this code work:
|
||||
NetBSD-1.0 (BSD-4.4 derivative)
|
||||
SunOS 4.X (Solaris 1.X)
|
||||
SunOS 5.X (Solaris 2.X)
|
||||
System V/386 Rel. 4.0
|
||||
@ -52,7 +53,7 @@ Systems on which I have seen this code work:
|
||||
Systems on which others say this code works:
|
||||
CDC EP/IX (1.4.3, 2.1.1)
|
||||
DEC Ultrix (4.2, 4.3)
|
||||
NetBSD (Current-8/94)
|
||||
Linux 1.1.81
|
||||
OSF/1 (DEC Alpha CPU)
|
||||
|
||||
Please direct questions, comments, and bug reports to:
|
||||
|
@ -2,6 +2,53 @@ Changes, most recent first
|
||||
Date, <email> Real Name
|
||||
what...
|
||||
|
||||
--> bootp-2.4.3
|
||||
|
||||
03/27/96 gwr@mc.com (Gordon W. Ross)
|
||||
Use LOG_NOTICE in place of LOG_INFO for messages related
|
||||
to unsatisfied clients [at request of <otto@tukki.jyu.fi>]
|
||||
Fix the irix Makefile targets, and other misc.
|
||||
|
||||
03/25/95 gwr@mc.com (Gordon W. Ross)
|
||||
Corrected a bug I introduced into SunOS setarp, where
|
||||
bad IP address caused "network unreachable" errors.
|
||||
[Thanks to andrew@ntplx.net (Andrew Lindh) for the fix!]
|
||||
|
||||
--> bootp-2.4.2
|
||||
|
||||
01/14/95 middelin@polyware.iaf.nl (Pauline Middelink)
|
||||
Corrected support for the Linux networking code.
|
||||
Fixed lots of warnings (gcc -Wall)
|
||||
Added "linux" Makefile target.
|
||||
|
||||
01/02/95 Jukka Ukkonen <ukkonen@csc.fi>
|
||||
Allow bootptab syntax: ha="0:0:c0:80:e8:a7"
|
||||
|
||||
11/30/94 Tonny van Lankveld <A.L.M.G.v.Lankveld@urc.tue.nl>
|
||||
Fix reporting of duplicate Ethernet addresses.
|
||||
|
||||
09/06/94 longyear@netcom.com (Al Longyear)
|
||||
Better setarp for linux, allows non-ether types.
|
||||
|
||||
09/02/94 Robert MacKinnon <rbm@montrouge.mis.slb.com>
|
||||
Add support for IBM's AIX 3.2.5
|
||||
|
||||
08/30/94 piercarl@ltd.c-d.com (Piercarlo Grandi)
|
||||
Fix select calls on linux (modifies timeval arg).
|
||||
Fix setarp (specify Ethernet type for now).
|
||||
|
||||
08/27/94 drew@drewsun.FEITH.COM (Andrew B. Sudell)
|
||||
Add support for Wollongong Win-TCP (SysVr4 variant).
|
||||
|
||||
08/24/94 gwr@mc.com (Gordon W. Ross)
|
||||
Use sigaction() on systems that define SA_NOCLDSTOP
|
||||
(a symbol required by POSIX) for HP/UX and others.
|
||||
|
||||
--> bootp-2.4.1
|
||||
|
||||
08/24/94 gwr@mc.com (Gordon W. Ross)
|
||||
Fix bug in boot file name generation (missing init)
|
||||
|
||||
--> bootp-2.4.0
|
||||
|
||||
08/20/94 gwr@mc.com (Gordon W. Ross)
|
||||
|
@ -44,9 +44,7 @@ CFLAGS= $(OPTDEFS) $(SYSDEFS) $(FILEDEFS) $(MOREDEFS)
|
||||
PROGS= bootpd bootpef bootpgw bootptest
|
||||
TESTS= trylook trygetif trygetea
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
tests: $(TESTS)
|
||||
all: $(PROGS) $(TESTS)
|
||||
|
||||
system: install
|
||||
|
||||
@ -76,7 +74,8 @@ distclean:
|
||||
-rm -f *.BAK *.CKP *~ .emacs*
|
||||
|
||||
#
|
||||
# Handy targets for individual systems:
|
||||
# Handy targets for systems needing special treatment:
|
||||
# (Most POSIX systems should work with just "make all")
|
||||
#
|
||||
|
||||
# DEC/OSF1 on the Alpha
|
||||
@ -96,9 +95,13 @@ epix211:
|
||||
SYSDEFS="-DSVR4" \
|
||||
SYSLIBS="-lsocket -lnsl"
|
||||
|
||||
# Silicon Graphics IRIX (no <sys/sockio.h>, so not SVR4)
|
||||
# IRIX 5.X (Silicon Graphics)
|
||||
irix:
|
||||
$(MAKE) SYSDEFS="-DSYSV -DIRIX"
|
||||
$(MAKE) SYSDEFS= SYSLIBS=
|
||||
|
||||
# Linux 1.1.80+ on [34]86
|
||||
linux:
|
||||
$(MAKE) SYSDEFS="-O6 -Wall -fomit-frame-pointer"
|
||||
|
||||
# SunOS 4.X
|
||||
sunos4:
|
||||
@ -110,11 +113,27 @@ sunos5:
|
||||
$(MAKE) SYSDEFS="-DSVR4 -DETC_ETHERS" \
|
||||
SYSLIBS="-lsocket -lnsl"
|
||||
|
||||
# UNIX System V Rel. 4 (also: IRIX 5.X, others)
|
||||
# Solaris 2.X (i.e. SunOS 5.X) with GCC. Note that GCC normally
|
||||
# defines __STDC__=1 which breaks many Solaris header files...
|
||||
sunos5gcc:
|
||||
$(MAKE) SYSDEFS="-DSVR4 -DETC_ETHERS -D__STDC__=0" \
|
||||
SYSLIBS="-lsocket -lnsl" CC="gcc -Wall"
|
||||
|
||||
# UNIX System V Rel. 3
|
||||
svr3:
|
||||
$(MAKE) SYSDEFS="-DSYSV"
|
||||
|
||||
# UNIX System V Rel. 4
|
||||
svr4:
|
||||
$(MAKE) SYSDEFS="-DSVR4" \
|
||||
SYSLIBS="-lsocket -lnsl"
|
||||
|
||||
# AT&T/GIS - Both AT&T StarServer and NCR 3000
|
||||
# may work for others using Wollongong's WIN-TCP
|
||||
wollongong gis :
|
||||
$(MAKE) SYSDEFS="-DSVR4 -DWIN_TCP" \
|
||||
SYSLIBS="-lsocket -lnsl"
|
||||
|
||||
#
|
||||
# How to build each program:
|
||||
#
|
||||
|
@ -1,6 +1,11 @@
|
||||
|
||||
Common problems and ways to work around them:
|
||||
|
||||
Bootpd complains: "bind: Address already in use" and fails to start.
|
||||
You are already running something that has bound the
|
||||
BOOTP listening port number. Check /etc/inetd.conf or
|
||||
the equivalent for a bootp line (or in startup files).
|
||||
|
||||
Bootpd complains that it "can not get IP addr for HOSTNAME"
|
||||
|
||||
If the entry is a "dummy" (not a real host) used only for
|
||||
@ -45,3 +50,16 @@ not a fully specified path.
|
||||
:td=/tftpboot: (or)
|
||||
:hd=/usr/boot: (for example)
|
||||
|
||||
My PC clients running Sun's PC-NFS Pro v1.1 fail to receive
|
||||
acceptable responses from the bootp server.
|
||||
|
||||
These clients send a request with the DHCP "message length"
|
||||
option and the (new) BOOTP "broadcast flag" both set.
|
||||
The bootp server (on SunOS) will send a fragmented reply
|
||||
unless you override the length with :ms=1024: (or less).
|
||||
The "broadcast flag" is not yet supported, but there is
|
||||
a simple work-around, just add :ra=255.255.255.255:
|
||||
for any clients that need their reply broadcasted.
|
||||
You may need to use a differnet broadcast address.
|
||||
(Thanks to Ivan Auger <ivan.auger@wadsworth.org>)
|
||||
|
||||
|
@ -90,6 +90,7 @@ Pittsburgh, PA 15213
|
||||
|
||||
Announce* Text of release announcements
|
||||
Changes Change history, reverse chronological
|
||||
ConvOldTab.sh Script to convert old (1.x) bootptab files
|
||||
Installation Instructions for building and installing
|
||||
Makefile* for "make"
|
||||
README This file
|
||||
@ -111,6 +112,7 @@ dovend.c Vendor Option builder (for bootpd, bootpef)
|
||||
dovend.h header for above
|
||||
dumptab.c Implements debugging dump for bootpd
|
||||
getether.c For bootptest (not used yet)
|
||||
getether.h header for above
|
||||
getif.c Get network interface info.
|
||||
getif.h header for above
|
||||
hash.c The hash table module
|
||||
|
61
libexec/bootpd/ToDo
Normal file
61
libexec/bootpd/ToDo
Normal file
@ -0,0 +1,61 @@
|
||||
ToDo: -*- text -*-
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Memory allocation locality:
|
||||
|
||||
Currently mallocs memory in a very haphazard manner. As such, most of
|
||||
the program ends up core-resident all the time just to follow all the
|
||||
stupid pointers around. . . .
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Input parser:
|
||||
|
||||
The reader implemented in readfile.c could use improvement. Some sort
|
||||
of "data-driven" parser should be used so the big switch statements
|
||||
would have only one case for each data type instead of one case for
|
||||
every recognized option symbol. Then adding a new tag would involve
|
||||
only adding a new element to the data table describing known symbols.
|
||||
Hopefully, this would shrink the code a bit too. -gwr
|
||||
|
||||
----------------------------------------------------------------------
|
||||
SLIP Initialization via BOOTP:
|
||||
|
||||
In the function handle_request(), both in bootpd and bootpgw,
|
||||
we might want to add code like the following just before testing
|
||||
the client IP address field for zero. (bp->bp_ciaddr == 0)
|
||||
(David suggests we leave this out for now. -gwr)
|
||||
|
||||
#if 1 /* XXX - Experimental */
|
||||
/*
|
||||
* SLIP initialization support.
|
||||
*
|
||||
* If this packet came from a SLIP driver that does
|
||||
* automatic IP address initialization, then the socket
|
||||
* will have the IP address and the packet will
|
||||
* have zeros for both the IP and HW addresses.
|
||||
*
|
||||
* Thanks to David P. Maynard <dpm@depend.com>
|
||||
* for explaining how this works. -gwr
|
||||
*/
|
||||
if ((bp->bp_ciaddr.s_addr == 0) &&
|
||||
(bp->bp_htype == 0))
|
||||
{
|
||||
/* Pretend the client knows its address. It will soon. */
|
||||
bp->bp_ciaddr = recv_addr.sin_addr;
|
||||
if (debug)
|
||||
report(LOG_INFO, "fixed blank request from IP addr %s",
|
||||
inet_ntoa(recv_addr.sin_addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
----------------------------------------------------------------------
|
||||
DHCP Support:
|
||||
|
||||
There is a set of patches from Jeanette Pauline Middelink
|
||||
<middelin@calvin.polyware.iaf.nl> to add DHCP support.
|
||||
|
||||
Those patches will be integrated into the BOOTP release stream
|
||||
very soon, but if you can't wait, you can get them from:
|
||||
nimbus.anu.edu.au:/pub/tridge/samba/contributed/DHCP.patch
|
||||
|
||||
----------------------------------------------------------------------
|
@ -23,7 +23,7 @@ SOFTWARE.
|
||||
/*
|
||||
* Bootstrap Protocol (BOOTP). RFC951 and RFC1395.
|
||||
*
|
||||
* $Id: bootp.h,v 1.1.1.1 1994/09/10 14:44:54 csgr Exp $
|
||||
* $Id: bootp.h $
|
||||
*
|
||||
*
|
||||
* This file specifies the "implementation-independent" BOOTP protocol
|
||||
|
@ -20,10 +20,6 @@ ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
************************************************************************/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: bootpd.c,v 1.1.1.1 1994/09/30 05:45:04 pst Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* BOOTP (bootstrap protocol) server daemon.
|
||||
*
|
||||
@ -49,6 +45,7 @@ static char rcsid[] = "$Id: bootpd.c,v 1.1.1.1 1994/09/30 05:45:04 pst Exp $";
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
@ -57,6 +54,7 @@ static char rcsid[] = "$Id: bootpd.c,v 1.1.1.1 1994/09/30 05:45:04 pst Exp $";
|
||||
#ifndef NO_UNISTD
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
@ -71,11 +69,6 @@ static char rcsid[] = "$Id: bootpd.c,v 1.1.1.1 1994/09/30 05:45:04 pst Exp $";
|
||||
# include <fcntl.h> /* for O_RDONLY, etc */
|
||||
#endif
|
||||
|
||||
#ifdef SVR4
|
||||
/* Using sigset() avoids the need to re-arm each time. */
|
||||
#define signal sigset
|
||||
#endif
|
||||
|
||||
#ifndef USE_BFUNCS
|
||||
# include <memory.h>
|
||||
/* Yes, memcpy is OK here (no overlapped copies). */
|
||||
@ -164,9 +157,11 @@ char *pktbuf; /* Receive packet buffer */
|
||||
int pktlen;
|
||||
char *progname;
|
||||
char *chdir_path;
|
||||
char hostname[MAXHOSTNAMELEN]; /* System host name */
|
||||
struct in_addr my_ip_addr;
|
||||
|
||||
struct utsname my_uname;
|
||||
char *hostname;
|
||||
|
||||
/* Flags set by signal catcher. */
|
||||
PRIVATE int do_readtab = 0;
|
||||
PRIVATE int do_dumptab = 0;
|
||||
@ -198,6 +193,9 @@ main(argc, argv)
|
||||
int n, ba_len, ra_len;
|
||||
int nfound, readfds;
|
||||
int standalone;
|
||||
#ifdef SA_NOCLDSTOP /* Have POSIX sigaction(2). */
|
||||
struct sigaction sa;
|
||||
#endif
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname) progname++;
|
||||
@ -255,6 +253,12 @@ main(argc, argv)
|
||||
stmp = NULL;
|
||||
timeout = &actualtimeout;
|
||||
|
||||
if (uname(&my_uname) < 0) {
|
||||
fprintf(stderr, "bootpd: can't get hostname\n");
|
||||
exit(1);
|
||||
}
|
||||
hostname = my_uname.nodename;
|
||||
|
||||
/*
|
||||
* Read switches.
|
||||
*/
|
||||
@ -315,7 +319,7 @@ main(argc, argv)
|
||||
"bootpd: missing hostname\n");
|
||||
break;
|
||||
}
|
||||
strncpy(hostname, stmp, sizeof(hostname)-1);
|
||||
hostname = stmp;
|
||||
break;
|
||||
|
||||
case 'i': /* inetd mode */
|
||||
@ -369,12 +373,7 @@ main(argc, argv)
|
||||
/*
|
||||
* Get my hostname and IP address.
|
||||
*/
|
||||
if (hostname[0] == '\0') {
|
||||
if (gethostname(hostname, sizeof(hostname)) == -1) {
|
||||
fprintf(stderr, "bootpd: can't get hostname\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
hep = gethostbyname(hostname);
|
||||
if (!hep) {
|
||||
fprintf(stderr, "Can not get my IP address\n");
|
||||
@ -481,6 +480,20 @@ main(argc, argv)
|
||||
/*
|
||||
* Set up signals to read or dump the table.
|
||||
*/
|
||||
#ifdef SA_NOCLDSTOP /* Have POSIX sigaction(2). */
|
||||
sa.sa_handler = catcher;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
if (sigaction(SIGHUP, &sa, NULL) < 0) {
|
||||
report(LOG_ERR, "sigaction: %s", get_errmsg());
|
||||
exit(1);
|
||||
}
|
||||
if (sigaction(SIGUSR1, &sa, NULL) < 0) {
|
||||
report(LOG_ERR, "sigaction: %s", get_errmsg());
|
||||
exit(1);
|
||||
}
|
||||
#else /* SA_NOCLDSTOP */
|
||||
/* Old-fashioned UNIX signals */
|
||||
if ((int) signal(SIGHUP, catcher) < 0) {
|
||||
report(LOG_ERR, "signal: %s", get_errmsg());
|
||||
exit(1);
|
||||
@ -489,13 +502,20 @@ main(argc, argv)
|
||||
report(LOG_ERR, "signal: %s", get_errmsg());
|
||||
exit(1);
|
||||
}
|
||||
#endif /* SA_NOCLDSTOP */
|
||||
|
||||
/*
|
||||
* Process incoming requests.
|
||||
*/
|
||||
for (;;) {
|
||||
struct timeval tv;
|
||||
|
||||
readfds = 1 << s;
|
||||
nfound = select(s + 1, (fd_set *)&readfds, NULL, NULL, timeout);
|
||||
if (timeout)
|
||||
tv = *timeout;
|
||||
|
||||
nfound = select(s + 1, (fd_set *)&readfds, NULL, NULL,
|
||||
(timeout) ? &tv : NULL);
|
||||
if (nfound < 0) {
|
||||
if (errno != EINTR) {
|
||||
report(LOG_ERR, "select: %s", get_errmsg());
|
||||
@ -532,7 +552,7 @@ main(argc, argv)
|
||||
}
|
||||
if (n < sizeof(struct bootp)) {
|
||||
if (debug) {
|
||||
report(LOG_INFO, "received short packet");
|
||||
report(LOG_NOTICE, "received short packet");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -580,9 +600,8 @@ catcher(sig)
|
||||
do_readtab = 1;
|
||||
if (sig == SIGUSR1)
|
||||
do_dumptab = 1;
|
||||
#ifdef SYSV
|
||||
/* For older "System V" derivatives with no sigset(). */
|
||||
/* XXX - Should just do it the POSIX way (sigaction). */
|
||||
#if !defined(SA_NOCLDSTOP) && defined(SYSV)
|
||||
/* For older "System V" derivatives with no sigaction(). */
|
||||
signal(sig, catcher);
|
||||
#endif
|
||||
}
|
||||
@ -676,8 +695,8 @@ HW addr type is IEEE 802. convert to %s and check again\n",
|
||||
/*
|
||||
* XXX - Add dynamic IP address assignment?
|
||||
*/
|
||||
if (debug > 1)
|
||||
report(LOG_INFO, "unknown client %s address %s",
|
||||
if (debug)
|
||||
report(LOG_NOTICE, "unknown client %s address %s",
|
||||
netname(bp->bp_htype),
|
||||
haddrtoa(bp->bp_chaddr, bp->bp_hlen));
|
||||
return; /* not found */
|
||||
@ -698,7 +717,7 @@ HW addr type is IEEE 802. convert to %s and check again\n",
|
||||
hp = (struct host *) hash_Lookup(iphashtable, hashcode, iplookcmp,
|
||||
&dummyhost);
|
||||
if (hp == NULL) {
|
||||
if (debug > 1) {
|
||||
if (debug) {
|
||||
report(LOG_NOTICE, "IP address not found: %s",
|
||||
inet_ntoa(bp->bp_ciaddr));
|
||||
}
|
||||
@ -911,7 +930,9 @@ HW addr type is IEEE 802. convert to %s and check again\n",
|
||||
if (debug > 2)
|
||||
report(LOG_INFO, "bootfile=\"%s\"", clntpath);
|
||||
|
||||
#ifdef CHECK_FILE_ACCESS
|
||||
null_file_name:
|
||||
#endif /* CHECK_FILE_ACCESS */
|
||||
|
||||
|
||||
/*
|
||||
@ -994,7 +1015,7 @@ sendreply(forward, dst_override)
|
||||
struct in_addr dst;
|
||||
u_short port = bootpc_port;
|
||||
unsigned char *ha;
|
||||
int len;
|
||||
int len, haf;
|
||||
|
||||
/*
|
||||
* XXX - Should honor bp_flags "broadcast" bit here.
|
||||
@ -1033,11 +1054,14 @@ sendreply(forward, dst_override)
|
||||
len = bp->bp_hlen;
|
||||
if (len > MAXHADDRLEN)
|
||||
len = MAXHADDRLEN;
|
||||
haf = (int) bp->bp_htype;
|
||||
if (haf == 0)
|
||||
haf = HTYPE_ETHERNET;
|
||||
|
||||
if (debug > 1)
|
||||
report(LOG_INFO, "setarp %s - %s",
|
||||
inet_ntoa(dst), haddrtoa(ha, len));
|
||||
setarp(s, &dst, ha, len);
|
||||
setarp(s, &dst, haf, ha, len);
|
||||
}
|
||||
|
||||
if ((forward == 0) &&
|
||||
@ -1206,7 +1230,6 @@ dovend_rfc1048(bp, hp, bootsize)
|
||||
{
|
||||
int bytesleft, len;
|
||||
byte *vp;
|
||||
char *tmpstr;
|
||||
|
||||
static char noroom[] = "%s: No room for \"%s\" option";
|
||||
|
||||
@ -1235,7 +1258,7 @@ dovend_rfc1048(bp, hp, bootsize)
|
||||
byte *p, *ep;
|
||||
byte tag, len;
|
||||
short msgsz = 0;
|
||||
|
||||
|
||||
p = vp + 4;
|
||||
ep = p + BP_VEND_LEN - 4;
|
||||
while (p < ep) {
|
||||
|
687
libexec/bootpd/bootpgw/bootpgw.c
Normal file
687
libexec/bootpd/bootpgw/bootpgw.c
Normal file
@ -0,0 +1,687 @@
|
||||
/*
|
||||
* bootpgw.c - BOOTP GateWay
|
||||
* This program forwards BOOTP Request packets to a BOOTP server.
|
||||
*/
|
||||
|
||||
/************************************************************************
|
||||
Copyright 1988, 1991 by Carnegie Mellon University
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted, provided
|
||||
that the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Carnegie Mellon University not be used
|
||||
in advertising or publicity pertaining to distribution of the software
|
||||
without specific, written prior permission.
|
||||
|
||||
CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
************************************************************************/
|
||||
|
||||
/*
|
||||
* BOOTPGW is typically used to forward BOOTP client requests from
|
||||
* one subnet to a BOOTP server on a different subnet.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h> /* inet_ntoa */
|
||||
|
||||
#ifndef NO_UNISTD
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
#include <syslog.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef NO_SETSID
|
||||
# include <fcntl.h> /* for O_RDONLY, etc */
|
||||
#endif
|
||||
|
||||
#ifndef USE_BFUNCS
|
||||
# include <memory.h>
|
||||
/* Yes, memcpy is OK here (no overlapped copies). */
|
||||
# define bcopy(a,b,c) memcpy(b,a,c)
|
||||
# define bzero(p,l) memset(p,0,l)
|
||||
# define bcmp(a,b,c) memcmp(a,b,c)
|
||||
#endif
|
||||
|
||||
#include "bootp.h"
|
||||
#include "getif.h"
|
||||
#include "hwaddr.h"
|
||||
#include "report.h"
|
||||
#include "patchlevel.h"
|
||||
|
||||
/* Local definitions: */
|
||||
#define MAX_MSG_SIZE (3*512) /* Maximum packet size */
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define get_network_errmsg get_errmsg
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Externals, forward declarations, and global variables
|
||||
*/
|
||||
|
||||
#ifdef __STDC__
|
||||
#define P(args) args
|
||||
#else
|
||||
#define P(args) ()
|
||||
#endif
|
||||
|
||||
static void usage P((void));
|
||||
static void handle_reply P((void));
|
||||
static void handle_request P((void));
|
||||
|
||||
#undef P
|
||||
|
||||
/*
|
||||
* IP port numbers for client and server obtained from /etc/services
|
||||
*/
|
||||
|
||||
u_short bootps_port, bootpc_port;
|
||||
|
||||
|
||||
/*
|
||||
* Internet socket and interface config structures
|
||||
*/
|
||||
|
||||
struct sockaddr_in bind_addr; /* Listening */
|
||||
struct sockaddr_in recv_addr; /* Packet source */
|
||||
struct sockaddr_in send_addr; /* destination */
|
||||
|
||||
|
||||
/*
|
||||
* option defaults
|
||||
*/
|
||||
int debug = 0; /* Debugging flag (level) */
|
||||
struct timeval actualtimeout =
|
||||
{ /* fifteen minutes */
|
||||
15 * 60L, /* tv_sec */
|
||||
0 /* tv_usec */
|
||||
};
|
||||
u_int maxhops = 4; /* Number of hops allowed for requests. */
|
||||
u_int minwait = 3; /* Number of seconds client must wait before
|
||||
its bootrequest packets are forwarded. */
|
||||
|
||||
/*
|
||||
* General
|
||||
*/
|
||||
|
||||
int s; /* Socket file descriptor */
|
||||
char *pktbuf; /* Receive packet buffer */
|
||||
int pktlen;
|
||||
char *progname;
|
||||
char *servername;
|
||||
int32 server_ipa; /* Real server IP address, network order. */
|
||||
|
||||
struct in_addr my_ip_addr;
|
||||
|
||||
struct utsname my_uname;
|
||||
char *hostname;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Initialization such as command-line processing is done and then the
|
||||
* main server loop is started.
|
||||
*/
|
||||
|
||||
void
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
struct timeval *timeout;
|
||||
struct bootp *bp;
|
||||
struct servent *servp;
|
||||
struct hostent *hep;
|
||||
char *stmp;
|
||||
int n, ba_len, ra_len;
|
||||
int nfound, readfds;
|
||||
int standalone;
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname) progname++;
|
||||
else progname = argv[0];
|
||||
|
||||
/*
|
||||
* Initialize logging.
|
||||
*/
|
||||
report_init(0); /* uses progname */
|
||||
|
||||
/*
|
||||
* Log startup
|
||||
*/
|
||||
report(LOG_INFO, "version %s.%d", VERSION, PATCHLEVEL);
|
||||
|
||||
/* Debugging for compilers with struct padding. */
|
||||
assert(sizeof(struct bootp) == BP_MINPKTSZ);
|
||||
|
||||
/* Get space for receiving packets and composing replies. */
|
||||
pktbuf = malloc(MAX_MSG_SIZE);
|
||||
if (!pktbuf) {
|
||||
report(LOG_ERR, "malloc failed");
|
||||
exit(1);
|
||||
}
|
||||
bp = (struct bootp *) pktbuf;
|
||||
|
||||
/*
|
||||
* Check to see if a socket was passed to us from inetd.
|
||||
*
|
||||
* Use getsockname() to determine if descriptor 0 is indeed a socket
|
||||
* (and thus we are probably a child of inetd) or if it is instead
|
||||
* something else and we are running standalone.
|
||||
*/
|
||||
s = 0;
|
||||
ba_len = sizeof(bind_addr);
|
||||
bzero((char *) &bind_addr, ba_len);
|
||||
errno = 0;
|
||||
standalone = TRUE;
|
||||
if (getsockname(s, (struct sockaddr *) &bind_addr, &ba_len) == 0) {
|
||||
/*
|
||||
* Descriptor 0 is a socket. Assume we are a child of inetd.
|
||||
*/
|
||||
if (bind_addr.sin_family == AF_INET) {
|
||||
standalone = FALSE;
|
||||
bootps_port = ntohs(bind_addr.sin_port);
|
||||
} else {
|
||||
/* Some other type of socket? */
|
||||
report(LOG_INFO, "getsockname: not an INET socket");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Set defaults that might be changed by option switches.
|
||||
*/
|
||||
stmp = NULL;
|
||||
timeout = &actualtimeout;
|
||||
|
||||
if (uname(&my_uname) < 0) {
|
||||
fprintf(stderr, "bootpgw: can't get hostname\n");
|
||||
exit(1);
|
||||
}
|
||||
hostname = my_uname.nodename;
|
||||
|
||||
hep = gethostbyname(hostname);
|
||||
if (!hep) {
|
||||
printf("Can not get my IP address\n");
|
||||
exit(1);
|
||||
}
|
||||
bcopy(hep->h_addr, (char *)&my_ip_addr, sizeof(my_ip_addr));
|
||||
|
||||
/*
|
||||
* Read switches.
|
||||
*/
|
||||
for (argc--, argv++; argc > 0; argc--, argv++) {
|
||||
if (argv[0][0] != '-')
|
||||
break;
|
||||
switch (argv[0][1]) {
|
||||
|
||||
case 'd': /* debug level */
|
||||
if (argv[0][2]) {
|
||||
stmp = &(argv[0][2]);
|
||||
} else if (argv[1] && argv[1][0] == '-') {
|
||||
/*
|
||||
* Backwards-compatible behavior:
|
||||
* no parameter, so just increment the debug flag.
|
||||
*/
|
||||
debug++;
|
||||
break;
|
||||
} else {
|
||||
argc--;
|
||||
argv++;
|
||||
stmp = argv[0];
|
||||
}
|
||||
if (!stmp || (sscanf(stmp, "%d", &n) != 1) || (n < 0)) {
|
||||
fprintf(stderr,
|
||||
"%s: invalid debug level\n", progname);
|
||||
break;
|
||||
}
|
||||
debug = n;
|
||||
break;
|
||||
|
||||
case 'h': /* hop count limit */
|
||||
if (argv[0][2]) {
|
||||
stmp = &(argv[0][2]);
|
||||
} else {
|
||||
argc--;
|
||||
argv++;
|
||||
stmp = argv[0];
|
||||
}
|
||||
if (!stmp || (sscanf(stmp, "%d", &n) != 1) ||
|
||||
(n < 0) || (n > 16))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"bootpgw: invalid hop count limit\n");
|
||||
break;
|
||||
}
|
||||
maxhops = (u_int)n;
|
||||
break;
|
||||
|
||||
case 'i': /* inetd mode */
|
||||
standalone = FALSE;
|
||||
break;
|
||||
|
||||
case 's': /* standalone mode */
|
||||
standalone = TRUE;
|
||||
break;
|
||||
|
||||
case 't': /* timeout */
|
||||
if (argv[0][2]) {
|
||||
stmp = &(argv[0][2]);
|
||||
} else {
|
||||
argc--;
|
||||
argv++;
|
||||
stmp = argv[0];
|
||||
}
|
||||
if (!stmp || (sscanf(stmp, "%d", &n) != 1) || (n < 0)) {
|
||||
fprintf(stderr,
|
||||
"%s: invalid timeout specification\n", progname);
|
||||
break;
|
||||
}
|
||||
actualtimeout.tv_sec = (int32) (60 * n);
|
||||
/*
|
||||
* If the actual timeout is zero, pass a NULL pointer
|
||||
* to select so it blocks indefinitely, otherwise,
|
||||
* point to the actual timeout value.
|
||||
*/
|
||||
timeout = (n > 0) ? &actualtimeout : NULL;
|
||||
break;
|
||||
|
||||
case 'w': /* wait time */
|
||||
if (argv[0][2]) {
|
||||
stmp = &(argv[0][2]);
|
||||
} else {
|
||||
argc--;
|
||||
argv++;
|
||||
stmp = argv[0];
|
||||
}
|
||||
if (!stmp || (sscanf(stmp, "%d", &n) != 1) ||
|
||||
(n < 0) || (n > 60))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"bootpgw: invalid wait time\n");
|
||||
break;
|
||||
}
|
||||
minwait = (u_int)n;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: unknown switch: -%c\n",
|
||||
progname, argv[0][1]);
|
||||
usage();
|
||||
break;
|
||||
|
||||
} /* switch */
|
||||
} /* for args */
|
||||
|
||||
/* Make sure server name argument is suplied. */
|
||||
servername = argv[0];
|
||||
if (!servername) {
|
||||
fprintf(stderr, "bootpgw: missing server name\n");
|
||||
usage();
|
||||
}
|
||||
/*
|
||||
* Get address of real bootp server.
|
||||
*/
|
||||
if (isdigit(servername[0]))
|
||||
server_ipa = inet_addr(servername);
|
||||
else {
|
||||
hep = gethostbyname(servername);
|
||||
if (!hep) {
|
||||
fprintf(stderr, "bootpgw: can't get addr for %s\n", servername);
|
||||
exit(1);
|
||||
}
|
||||
bcopy(hep->h_addr, (char *)&server_ipa, sizeof(server_ipa));
|
||||
}
|
||||
|
||||
if (standalone) {
|
||||
/*
|
||||
* Go into background and disassociate from controlling terminal.
|
||||
* XXX - This is not the POSIX way (Should use setsid). -gwr
|
||||
*/
|
||||
if (debug < 3) {
|
||||
if (fork())
|
||||
exit(0);
|
||||
#ifdef NO_SETSID
|
||||
setpgrp(0,0);
|
||||
#ifdef TIOCNOTTY
|
||||
n = open("/dev/tty", O_RDWR);
|
||||
if (n >= 0) {
|
||||
ioctl(n, TIOCNOTTY, (char *) 0);
|
||||
(void) close(n);
|
||||
}
|
||||
#endif /* TIOCNOTTY */
|
||||
#else /* SETSID */
|
||||
if (setsid() < 0)
|
||||
perror("setsid");
|
||||
#endif /* SETSID */
|
||||
} /* if debug < 3 */
|
||||
/*
|
||||
* Nuke any timeout value
|
||||
*/
|
||||
timeout = NULL;
|
||||
|
||||
/*
|
||||
* Here, bootpd would do:
|
||||
* chdir
|
||||
* tzone_init
|
||||
* rdtab_init
|
||||
* readtab
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create a socket.
|
||||
*/
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
report(LOG_ERR, "socket: %s", get_network_errmsg());
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
* Get server's listening port number
|
||||
*/
|
||||
servp = getservbyname("bootps", "udp");
|
||||
if (servp) {
|
||||
bootps_port = ntohs((u_short) servp->s_port);
|
||||
} else {
|
||||
bootps_port = (u_short) IPPORT_BOOTPS;
|
||||
report(LOG_ERR,
|
||||
"udp/bootps: unknown service -- assuming port %d",
|
||||
bootps_port);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind socket to BOOTPS port.
|
||||
*/
|
||||
bind_addr.sin_family = AF_INET;
|
||||
bind_addr.sin_port = htons(bootps_port);
|
||||
bind_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
if (bind(s, (struct sockaddr *) &bind_addr,
|
||||
sizeof(bind_addr)) < 0)
|
||||
{
|
||||
report(LOG_ERR, "bind: %s", get_network_errmsg());
|
||||
exit(1);
|
||||
}
|
||||
} /* if standalone */
|
||||
/*
|
||||
* Get destination port number so we can reply to client
|
||||
*/
|
||||
servp = getservbyname("bootpc", "udp");
|
||||
if (servp) {
|
||||
bootpc_port = ntohs(servp->s_port);
|
||||
} else {
|
||||
report(LOG_ERR,
|
||||
"udp/bootpc: unknown service -- assuming port %d",
|
||||
IPPORT_BOOTPC);
|
||||
bootpc_port = (u_short) IPPORT_BOOTPC;
|
||||
}
|
||||
|
||||
/* no signal catchers */
|
||||
|
||||
/*
|
||||
* Process incoming requests.
|
||||
*/
|
||||
for (;;) {
|
||||
struct timeval tv;
|
||||
|
||||
readfds = 1 << s;
|
||||
if (timeout)
|
||||
tv = *timeout;
|
||||
|
||||
nfound = select(s + 1, (fd_set *)&readfds, NULL, NULL,
|
||||
(timeout) ? &tv : NULL);
|
||||
if (nfound < 0) {
|
||||
if (errno != EINTR) {
|
||||
report(LOG_ERR, "select: %s", get_errmsg());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!(readfds & (1 << s))) {
|
||||
report(LOG_INFO, "exiting after %ld minutes of inactivity",
|
||||
actualtimeout.tv_sec / 60);
|
||||
exit(0);
|
||||
}
|
||||
ra_len = sizeof(recv_addr);
|
||||
n = recvfrom(s, pktbuf, MAX_MSG_SIZE, 0,
|
||||
(struct sockaddr *) &recv_addr, &ra_len);
|
||||
if (n <= 0) {
|
||||
continue;
|
||||
}
|
||||
if (debug > 3) {
|
||||
report(LOG_INFO, "recvd pkt from IP addr %s",
|
||||
inet_ntoa(recv_addr.sin_addr));
|
||||
}
|
||||
if (n < sizeof(struct bootp)) {
|
||||
if (debug) {
|
||||
report(LOG_INFO, "received short packet");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
pktlen = n;
|
||||
|
||||
switch (bp->bp_op) {
|
||||
case BOOTREQUEST:
|
||||
handle_request();
|
||||
break;
|
||||
case BOOTREPLY:
|
||||
handle_reply();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Print "usage" message and exit
|
||||
*/
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: bootpgw [-d level] [-i] [-s] [-t timeout] server\n");
|
||||
fprintf(stderr, "\t -d n\tset debug level\n");
|
||||
fprintf(stderr, "\t -h n\tset max hop count\n");
|
||||
fprintf(stderr, "\t -i\tforce inetd mode (run as child of inetd)\n");
|
||||
fprintf(stderr, "\t -s\tforce standalone mode (run without inetd)\n");
|
||||
fprintf(stderr, "\t -t n\tset inetd exit timeout to n minutes\n");
|
||||
fprintf(stderr, "\t -w n\tset min wait time (secs)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Process BOOTREQUEST packet.
|
||||
*
|
||||
* Note, this just forwards the request to a real server.
|
||||
*/
|
||||
static void
|
||||
handle_request()
|
||||
{
|
||||
struct bootp *bp = (struct bootp *) pktbuf;
|
||||
u_short secs, hops;
|
||||
|
||||
/* XXX - SLIP init: Set bp_ciaddr = recv_addr here? */
|
||||
|
||||
if (debug) {
|
||||
report(LOG_INFO, "request from %s",
|
||||
inet_ntoa(recv_addr.sin_addr));
|
||||
}
|
||||
/* Has the client been waiting long enough? */
|
||||
secs = ntohs(bp->bp_secs);
|
||||
if (secs < minwait)
|
||||
return;
|
||||
|
||||
/* Has this packet hopped too many times? */
|
||||
hops = ntohs(bp->bp_hops);
|
||||
if (++hops > maxhops) {
|
||||
report(LOG_NOTICE, "reqest from %s reached hop limit",
|
||||
inet_ntoa(recv_addr.sin_addr));
|
||||
return;
|
||||
}
|
||||
bp->bp_hops = htons(hops);
|
||||
|
||||
/*
|
||||
* Here one might discard a request from the same subnet as the
|
||||
* real server, but we can assume that the real server will send
|
||||
* a reply to the client before it waits for minwait seconds.
|
||||
*/
|
||||
|
||||
/* If gateway address is not set, put in local interface addr. */
|
||||
if (bp->bp_giaddr.s_addr == 0) {
|
||||
#if 0 /* BUG */
|
||||
struct sockaddr_in *sip;
|
||||
struct ifreq *ifr;
|
||||
/*
|
||||
* XXX - This picks the wrong interface when the receive addr
|
||||
* is the broadcast address. There is no portable way to
|
||||
* find out which interface a broadcast was received on. -gwr
|
||||
* (Thanks to <walker@zk3.dec.com> for finding this bug!)
|
||||
*/
|
||||
ifr = getif(s, &recv_addr.sin_addr);
|
||||
if (!ifr) {
|
||||
report(LOG_NOTICE, "no interface for request from %s",
|
||||
inet_ntoa(recv_addr.sin_addr));
|
||||
return;
|
||||
}
|
||||
sip = (struct sockaddr_in *) &(ifr->ifr_addr);
|
||||
bp->bp_giaddr = sip->sin_addr;
|
||||
#else /* BUG */
|
||||
/*
|
||||
* XXX - Just set "giaddr" to our "official" IP address.
|
||||
* RFC 1532 says giaddr MUST be set to the address of the
|
||||
* interface on which the request was received. Setting
|
||||
* it to our "default" IP address is not strictly correct,
|
||||
* but is good enough to allow the real BOOTP server to
|
||||
* get the reply back here. Then, before we forward the
|
||||
* reply to the client, the giaddr field is corrected.
|
||||
* (In case the client uses giaddr, which it should not.)
|
||||
* See handle_reply()
|
||||
*/
|
||||
bp->bp_giaddr = my_ip_addr;
|
||||
#endif /* BUG */
|
||||
|
||||
/*
|
||||
* XXX - DHCP says to insert a subnet mask option into the
|
||||
* options area of the request (if vendor magic == std).
|
||||
*/
|
||||
}
|
||||
/* Set up socket address for send. */
|
||||
send_addr.sin_family = AF_INET;
|
||||
send_addr.sin_port = htons(bootps_port);
|
||||
send_addr.sin_addr.s_addr = server_ipa;
|
||||
|
||||
/* Send reply with same size packet as request used. */
|
||||
if (sendto(s, pktbuf, pktlen, 0,
|
||||
(struct sockaddr *) &send_addr,
|
||||
sizeof(send_addr)) < 0)
|
||||
{
|
||||
report(LOG_ERR, "sendto: %s", get_network_errmsg());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Process BOOTREPLY packet.
|
||||
*/
|
||||
static void
|
||||
handle_reply()
|
||||
{
|
||||
struct bootp *bp = (struct bootp *) pktbuf;
|
||||
struct ifreq *ifr;
|
||||
struct sockaddr_in *sip;
|
||||
unsigned char *ha;
|
||||
int len, haf;
|
||||
|
||||
if (debug) {
|
||||
report(LOG_INFO, " reply for %s",
|
||||
inet_ntoa(bp->bp_yiaddr));
|
||||
}
|
||||
/* Make sure client is directly accessible. */
|
||||
ifr = getif(s, &(bp->bp_yiaddr));
|
||||
if (!ifr) {
|
||||
report(LOG_NOTICE, "no interface for reply to %s",
|
||||
inet_ntoa(bp->bp_yiaddr));
|
||||
return;
|
||||
}
|
||||
#if 1 /* Experimental (see BUG above) */
|
||||
/* #ifdef CATER_TO_OLD_CLIENTS ? */
|
||||
/*
|
||||
* The giaddr field has been set to our "default" IP address
|
||||
* which might not be on the same interface as the client.
|
||||
* In case the client looks at giaddr, (which it should not)
|
||||
* giaddr is now set to the address of the correct interface.
|
||||
*/
|
||||
sip = (struct sockaddr_in *) &(ifr->ifr_addr);
|
||||
bp->bp_giaddr = sip->sin_addr;
|
||||
#endif
|
||||
|
||||
/* Set up socket address for send to client. */
|
||||
send_addr.sin_family = AF_INET;
|
||||
send_addr.sin_addr = bp->bp_yiaddr;
|
||||
send_addr.sin_port = htons(bootpc_port);
|
||||
|
||||
/* Create an ARP cache entry for the client. */
|
||||
ha = bp->bp_chaddr;
|
||||
len = bp->bp_hlen;
|
||||
if (len > MAXHADDRLEN)
|
||||
len = MAXHADDRLEN;
|
||||
haf = (int) bp->bp_htype;
|
||||
if (haf == 0)
|
||||
haf = HTYPE_ETHERNET;
|
||||
|
||||
if (debug > 1)
|
||||
report(LOG_INFO, "setarp %s - %s",
|
||||
inet_ntoa(bp->bp_yiaddr), haddrtoa(ha, len));
|
||||
setarp(s, &bp->bp_yiaddr, haf, ha, len);
|
||||
|
||||
/* Send reply with same size packet as request used. */
|
||||
if (sendto(s, pktbuf, pktlen, 0,
|
||||
(struct sockaddr *) &send_addr,
|
||||
sizeof(send_addr)) < 0)
|
||||
{
|
||||
report(LOG_ERR, "sendto: %s", get_network_errmsg());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* tab-width: 4
|
||||
* c-indent-level: 4
|
||||
* c-argdecl-indent: 4
|
||||
* c-continued-statement-offset: 4
|
||||
* c-continued-brace-offset: -4
|
||||
* c-label-offset: -4
|
||||
* c-brace-offset: 0
|
||||
* End:
|
||||
*/
|
@ -1,6 +1,6 @@
|
||||
.\" Copyright (c) 1988, 1989, 1991 Carnegie Mellon University
|
||||
.\"
|
||||
.\" $Header: /home/ncvs/src/usr.sbin/bootpd/bootptab.5,v 1.1.1.1 1994/09/10 14:44:54 csgr Exp $
|
||||
.\" $Header: $
|
||||
.\"
|
||||
.TH BOOTPTAB 5 "October 31, 1991" "Carnegie Mellon University"
|
||||
.UC 6
|
||||
|
@ -85,8 +85,5 @@ tp885: tc=.subnet17:ha=08.00.4C.00.2F.74:bf=tp885sys2.cfe:
|
||||
#mvme147:tc=.subnet17:ha=08.00.3e.20.da.47:bf=mv147vxw.st:
|
||||
|
||||
# These are just for testing
|
||||
|
||||
walnut:tc=.subnet16:ha=walnut:
|
||||
banana:tc=.subnet17:ha=banana:
|
||||
thor:tc=.subnet17:ha=thor:
|
||||
classic:tc=.subnet16:ha=classic:
|
||||
bach: tc=.subnet16:ha="08:00:20:04:98:8d":bf=boot.sun4m:
|
||||
xanadu:tc=.subnet17:ha="00:80:42:42:04:c7":bf=boot.sun4c:
|
||||
|
@ -56,7 +56,6 @@ dovend_rfc1497(hp, buf, len)
|
||||
{
|
||||
int bytesleft = len;
|
||||
byte *vp = buf;
|
||||
char *tmpstr;
|
||||
|
||||
static char noroom[] = "%s: No room for \"%s\" option";
|
||||
#define NEED(LEN, MSG) do \
|
||||
@ -220,7 +219,7 @@ dovend_rfc1497(hp, buf, len)
|
||||
* Not enough room for full (domain-qualified) hostname, try
|
||||
* stripping it down to just the first field (host).
|
||||
*/
|
||||
tmpstr = hp->hostname->string;
|
||||
char *tmpstr = hp->hostname->string;
|
||||
len = 0;
|
||||
while (*tmpstr && (*tmpstr != '.')) {
|
||||
tmpstr++;
|
||||
|
@ -59,7 +59,7 @@ dumptab(filename)
|
||||
int n;
|
||||
struct host *hp;
|
||||
FILE *fp;
|
||||
time_t t;
|
||||
long t;
|
||||
/* Print symbols in alphabetical order for reader's convenience. */
|
||||
static char legend[] = "#\n# Legend:\t(see bootptab.5)\n\
|
||||
#\tfirst field -- hostname (not indented)\n\
|
||||
|
@ -11,9 +11,14 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifndef NO_UNISTD
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "getether.h"
|
||||
#include "report.h"
|
||||
#define EALEN 6
|
||||
|
||||
@ -101,7 +106,7 @@ getether(ifname, eap)
|
||||
#endif /* SUNOS */
|
||||
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#if defined(__386BSD__) || defined(__NetBSD__)
|
||||
/* Thanks to John Brezak <brezak@ch.hp.com> for this code. */
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
@ -168,10 +173,12 @@ getether(ifname, eap)
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/dlpi.h>
|
||||
#include <stropts.h>
|
||||
#include <string.h>
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getether(ifname, eap)
|
||||
char *ifname; /* interface name from ifconfig structure */
|
||||
char *eap; /* Ether address (output) */
|
||||
@ -308,30 +315,31 @@ getether(ifname, eap)
|
||||
#endif /* SVR4 */
|
||||
|
||||
|
||||
#ifdef linux
|
||||
#ifdef __linux__
|
||||
/*
|
||||
* This is really easy on Linux! This version (for linux)
|
||||
* written by Nigel Metheringham <nigelm@ohm.york.ac.uk>
|
||||
* written by Nigel Metheringham <nigelm@ohm.york.ac.uk> and
|
||||
* updated by Pauline Middelink <middelin@polyware.iaf.nl>
|
||||
*
|
||||
* The code is almost identical to the Ultrix code - however
|
||||
* the names are different to confuse the innocent :-)
|
||||
* Most of this code was stolen from the Ultrix bit above.
|
||||
*/
|
||||
|
||||
#include <memory.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h> /* struct ifreq */
|
||||
#include <sys/socketio.h> /* Needed for IOCTL defs */
|
||||
|
||||
/* In a properly configured system this should be either sys/socketio.h
|
||||
or sys/sockios.h, but on my distribution these don't line up correctly */
|
||||
#include <linux/sockios.h> /* Needed for IOCTL defs */
|
||||
|
||||
int
|
||||
getether(ifname, eap)
|
||||
char *ifname, *eap;
|
||||
{
|
||||
int rc = -1;
|
||||
int fd;
|
||||
struct ifreq phys;
|
||||
bzero(&phys, sizeof(phys));
|
||||
|
||||
memset(&phys, 0, sizeof(phys));
|
||||
strcpy(phys.ifr_name, ifname);
|
||||
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
report(LOG_ERR, "getether: socket(INET,DGRAM) failed");
|
||||
@ -340,7 +348,7 @@ getether(ifname, eap)
|
||||
if (ioctl(fd, SIOCGIFHWADDR, &phys) < 0) {
|
||||
report(LOG_ERR, "getether: ioctl SIOCGIFHWADDR failed");
|
||||
} else {
|
||||
bcopy(phys.ifr_hwaddr, eap, EALEN);
|
||||
memcpy(eap, &phys.ifr_hwaddr.sa_data, EALEN);
|
||||
rc = 0;
|
||||
}
|
||||
close(fd);
|
||||
@ -348,11 +356,12 @@ getether(ifname, eap)
|
||||
}
|
||||
|
||||
#define GETETHER
|
||||
#endif /* linux */
|
||||
#endif /* __linux__ */
|
||||
|
||||
|
||||
/* If we don't know how on this system, just return an error. */
|
||||
#ifndef GETETHER
|
||||
int
|
||||
getether(ifname, eap)
|
||||
char *ifname, *eap;
|
||||
{
|
||||
|
7
libexec/bootpd/getether.h
Normal file
7
libexec/bootpd/getether.h
Normal file
@ -0,0 +1,7 @@
|
||||
/* getether.h */
|
||||
|
||||
#ifdef __STDC__
|
||||
extern int getether(char *ifname, char *eaptr);
|
||||
#else
|
||||
extern int getether();
|
||||
#endif
|
@ -13,6 +13,9 @@
|
||||
#include <sys/stropts.h>
|
||||
#endif
|
||||
|
||||
#ifdef _AIX32
|
||||
#include <sys/time.h> /* for struct timeval in net/if.h */
|
||||
#endif
|
||||
#include <net/if.h> /* for struct ifreq */
|
||||
#include <netinet/in.h>
|
||||
|
||||
|
@ -20,11 +20,6 @@ ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
************************************************************************/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: hash.c,v 1.1.1.1 1994/09/10 14:44:55 csgr Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Generalized hash table ADT
|
||||
*
|
||||
|
@ -17,8 +17,19 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef _AIX32
|
||||
#include <sys/time.h> /* for struct timeval in net/if.h */
|
||||
#include <net/if.h> /* for struct ifnet in net/if_arp.h */
|
||||
#endif
|
||||
|
||||
#include <net/if_arp.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifdef WIN_TCP
|
||||
#include <netinet/if_ether.h>
|
||||
#include <sys/dlpi.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifndef NO_UNISTD
|
||||
#include <unistd.h>
|
||||
@ -33,11 +44,8 @@
|
||||
#define bcmp(a,b,c) memcmp(a,b,c)
|
||||
#endif
|
||||
|
||||
/* For BSD 4.4, set arp entry by writing to routing socket */
|
||||
#if defined(BSD)
|
||||
#if BSD >= 199306
|
||||
extern int bsd_arp_set __P((struct in_addr *, char *, int));
|
||||
#endif
|
||||
#ifndef ATF_INUSE /* Not defined on some systems (i.e. Linux) */
|
||||
#define ATF_INUSE 0
|
||||
#endif
|
||||
|
||||
#include "bptypes.h"
|
||||
@ -72,21 +80,43 @@ int hwinfocnt = sizeof(hwinfolist) / sizeof(hwinfolist[0]);
|
||||
* bound to hardware address 'ha' of length 'len'.
|
||||
*/
|
||||
void
|
||||
setarp(s, ia, ha, len)
|
||||
setarp(s, ia, hafamily, haddr, halen)
|
||||
int s; /* socket fd */
|
||||
struct in_addr *ia;
|
||||
u_char *ha;
|
||||
int len;
|
||||
struct in_addr *ia; /* protocol address */
|
||||
int hafamily; /* HW address family */
|
||||
u_char *haddr; /* HW address data */
|
||||
int halen;
|
||||
{
|
||||
#ifdef SIOCSARP
|
||||
#ifdef WIN_TCP
|
||||
/* This is an SVR4 with different networking code from
|
||||
* Wollongong WIN-TCP. Not quite like the Lachman code.
|
||||
* Code from: drew@drewsun.FEITH.COM (Andrew B. Sudell)
|
||||
*/
|
||||
#undef SIOCSARP
|
||||
#define SIOCSARP ARP_ADD
|
||||
struct arptab arpreq; /* Arp table entry */
|
||||
|
||||
bzero((caddr_t) &arpreq, sizeof(arpreq));
|
||||
arpreq.at_flags = ATF_COM;
|
||||
|
||||
/* Set up IP address */
|
||||
arpreq.at_in = ia->s_addr;
|
||||
|
||||
/* Set up Hardware Address */
|
||||
bcopy(haddr, arpreq.at_enaddr, halen);
|
||||
|
||||
/* Set the Date Link type. */
|
||||
/* XXX - Translate (hafamily) to dltype somehow? */
|
||||
arpreq.at_dltype = DL_ETHER;
|
||||
|
||||
#else /* WIN_TCP */
|
||||
/* Good old Berkeley way. */
|
||||
struct arpreq arpreq; /* Arp request ioctl block */
|
||||
struct sockaddr_in *si;
|
||||
#ifdef SVR4
|
||||
int fd;
|
||||
struct strioctl iocb;
|
||||
#endif /* SVR4 */
|
||||
char *p;
|
||||
|
||||
bzero((caddr_t) & arpreq, sizeof(arpreq));
|
||||
bzero((caddr_t) &arpreq, sizeof(arpreq));
|
||||
arpreq.arp_flags = ATF_INUSE | ATF_COM;
|
||||
|
||||
/* Set up the protocol address. */
|
||||
@ -95,7 +125,18 @@ setarp(s, ia, ha, len)
|
||||
si->sin_addr = *ia;
|
||||
|
||||
/* Set up the hardware address. */
|
||||
bcopy(ha, arpreq.arp_ha.sa_data, len);
|
||||
#ifdef __linux__ /* XXX - Do others need this? -gwr */
|
||||
/*
|
||||
* Linux requires the sa_family field set.
|
||||
* longyear@netcom.com (Al Longyear)
|
||||
*/
|
||||
arpreq.arp_ha.sa_family = hafamily;
|
||||
#endif /* linux */
|
||||
|
||||
/* This variable is just to help catch type mismatches. */
|
||||
p = arpreq.arp_ha.sa_data;
|
||||
bcopy(haddr, p, halen);
|
||||
#endif /* WIN_TCP */
|
||||
|
||||
#ifdef SVR4
|
||||
/*
|
||||
@ -106,18 +147,22 @@ setarp(s, ia, ha, len)
|
||||
* bear@upsys.se (Bj|rn Sj|holm),
|
||||
* Michael Kuschke <Michael.Kuschke@Materna.DE>,
|
||||
*/
|
||||
if ((fd=open("/dev/arp", O_RDWR)) < 0) {
|
||||
report(LOG_ERR, "open /dev/arp: %s\n", get_errmsg());
|
||||
}
|
||||
iocb.ic_cmd = SIOCSARP;
|
||||
iocb.ic_timout = 0;
|
||||
iocb.ic_dp = (char *)&arpreq;
|
||||
iocb.ic_len = sizeof(arpreq);
|
||||
if (ioctl(fd, I_STR, (caddr_t)&iocb) < 0) {
|
||||
report(LOG_ERR, "ioctl I_STR: %s\n", get_errmsg());
|
||||
}
|
||||
close (fd);
|
||||
{
|
||||
int fd;
|
||||
struct strioctl iocb;
|
||||
|
||||
if ((fd=open("/dev/arp", O_RDWR)) < 0) {
|
||||
report(LOG_ERR, "open /dev/arp: %s\n", get_errmsg());
|
||||
}
|
||||
iocb.ic_cmd = SIOCSARP;
|
||||
iocb.ic_timout = 0;
|
||||
iocb.ic_dp = (char *)&arpreq;
|
||||
iocb.ic_len = sizeof(arpreq);
|
||||
if (ioctl(fd, I_STR, (caddr_t)&iocb) < 0) {
|
||||
report(LOG_ERR, "ioctl I_STR: %s\n", get_errmsg());
|
||||
}
|
||||
close (fd);
|
||||
}
|
||||
#else /* SVR4 */
|
||||
/*
|
||||
* On SunOS, the ioctl sometimes returns ENXIO, and it
|
||||
@ -125,30 +170,30 @@ setarp(s, ia, ha, len)
|
||||
* to add is already in the cache. (Sigh...)
|
||||
* XXX - Should this error simply be ignored? -gwr
|
||||
*/
|
||||
if (ioctl(s, SIOCSARP, (caddr_t) & arpreq) < 0) {
|
||||
if (ioctl(s, SIOCSARP, (caddr_t) &arpreq) < 0) {
|
||||
report(LOG_ERR, "ioctl SIOCSARP: %s", get_errmsg());
|
||||
}
|
||||
#endif /* SVR4 */
|
||||
#else /* SIOCSARP */
|
||||
#if defined(BSD) && (BSD >= 199306)
|
||||
bsd_arp_set(ia, ha, len);
|
||||
#else /* Not BSD 4.4, and SIOCSARP not defined */
|
||||
/*
|
||||
* Oh well, SIOCSARP is not defined. Just run arp(8).
|
||||
* Need to delete partial entry first on some systems.
|
||||
* XXX - Gag!
|
||||
*/
|
||||
char buf[256];
|
||||
int status;
|
||||
char buf[256];
|
||||
char *a;
|
||||
extern char *inet_ntoa();
|
||||
|
||||
sprintf(buf, "arp -s %s %s temp",
|
||||
inet_ntoa(*ia), haddrtoa(ha, len));
|
||||
a = inet_ntoa(*ia);
|
||||
sprintf(buf, "arp -d %s; arp -s %s %s temp",
|
||||
a, a, haddrtoa(haddr, halen));
|
||||
if (debug > 2)
|
||||
report(LOG_INFO, buf);
|
||||
status = system(buf);
|
||||
if (status)
|
||||
report(LOG_ERR, "arp failed, exit code=0x%x", status);
|
||||
return;
|
||||
#endif /* ! 4.4 BSD */
|
||||
#endif /* SIOCSARP */
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ extern int hwinfocnt;
|
||||
#define P(args) ()
|
||||
#endif
|
||||
|
||||
extern void setarp P((int, struct in_addr *, u_char *, int));
|
||||
extern void setarp P((int, struct in_addr *, int, u_char *, int));
|
||||
extern char *haddrtoa P((u_char *, int));
|
||||
extern void haddr_conv802 P((u_char *, u_char *, int));
|
||||
|
||||
|
@ -5,6 +5,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef _AIX32
|
||||
#include <sys/time.h> /* for struct timeval in net/if.h */
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
/* patchlevel.h */
|
||||
#define VERSION "2.4"
|
||||
#define PATCHLEVEL 1
|
||||
#define PATCHLEVEL 3
|
||||
|
@ -20,11 +20,6 @@ ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
************************************************************************/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: readfile.c,v 1.1.1.1 1994/09/10 14:44:55 csgr Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* bootpd configuration file reading code.
|
||||
*
|
||||
@ -446,7 +441,7 @@ readtab(force)
|
||||
if (hash_Insert(hwhashtable, hashcode, hwinscmp, hp, hp) < 0) {
|
||||
report(LOG_NOTICE, "duplicate %s address: %s",
|
||||
netname(hp->htype),
|
||||
haddrtoa(hp->haddr, hp->htype));
|
||||
haddrtoa(hp->haddr, haddrlength(hp->htype)));
|
||||
free_host((hash_datum *) hp);
|
||||
continue;
|
||||
}
|
||||
@ -768,8 +763,8 @@ process_entry(host, src)
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Parse an integer value for MEMBER */
|
||||
#define PARSE_INT(MEMBER) do \
|
||||
/* Parse an unsigned integer value for MEMBER */
|
||||
#define PARSE_UINT(MEMBER) do \
|
||||
{ \
|
||||
if (optype == OP_BOOLEAN) \
|
||||
return E_SYNTAX_ERROR; \
|
||||
@ -796,7 +791,6 @@ eval_symbol(symbol, hp)
|
||||
{
|
||||
char tmpstr[MAXSTRINGLEN];
|
||||
byte *tmphaddr;
|
||||
struct shared_string *ss;
|
||||
struct symbolmap *symbolptr;
|
||||
u_int32 value;
|
||||
int32 timeoff;
|
||||
@ -820,7 +814,7 @@ eval_symbol(symbol, hp)
|
||||
if ((*symbol)[0] == 'T') { /* generic symbol */
|
||||
(*symbol)++;
|
||||
value = get_u_long(symbol);
|
||||
sprintf(current_tagname, "T%d", value);
|
||||
sprintf(current_tagname, "T%d", (int)value);
|
||||
eat_whitespace(symbol);
|
||||
if ((*symbol)[0] != '=') {
|
||||
return E_SYNTAX_ERROR;
|
||||
@ -985,7 +979,7 @@ eval_symbol(symbol, hp)
|
||||
if (!strncmp(tmpstr, "auto", 4)) {
|
||||
hp->time_offset = secondswest;
|
||||
} else {
|
||||
if (sscanf(tmpstr, "%d", &timeoff) != 1)
|
||||
if (sscanf(tmpstr, "%d", (int*)&timeoff) != 1)
|
||||
return E_BAD_LONGWORD;
|
||||
hp->time_offset = timeoff;
|
||||
}
|
||||
@ -1121,16 +1115,14 @@ eval_symbol(symbol, hp)
|
||||
#endif
|
||||
|
||||
case SYM_MSG_SIZE:
|
||||
PARSE_INT(msg_size);
|
||||
PARSE_UINT(msg_size);
|
||||
if (hp->msg_size < BP_MINPKTSZ ||
|
||||
hp->msg_size > MAX_MSG_SIZE)
|
||||
return E_BAD_VALUE;
|
||||
break;
|
||||
|
||||
case SYM_MIN_WAIT:
|
||||
PARSE_INT(min_wait);
|
||||
if (hp->min_wait < 0)
|
||||
return E_BAD_VALUE;
|
||||
PARSE_UINT(min_wait);
|
||||
break;
|
||||
|
||||
/* XXX - Add new tags here */
|
||||
@ -1682,7 +1674,6 @@ prs_inetaddr(src, result)
|
||||
int n;
|
||||
char *s, *t;
|
||||
|
||||
#if 1 /* XXX - experimental */
|
||||
/* Leading alpha char causes IP addr lookup. */
|
||||
if (isalpha(**src)) {
|
||||
/* Lookup IP address. */
|
||||
@ -1700,7 +1691,6 @@ prs_inetaddr(src, result)
|
||||
report(LOG_ERR, "can not get IP addr for %s", tmpstr);
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Parse an address in Internet format:
|
||||
@ -1794,7 +1784,6 @@ prs_haddr(src, htype)
|
||||
get_string(src, tmpstr, &tmplen);
|
||||
p = tmpstr;
|
||||
|
||||
#if 1 /* XXX - experimental */
|
||||
/* If it's a valid host name, try to lookup the HW address. */
|
||||
if (goodname(p)) {
|
||||
/* Lookup Hardware Address for hostname. */
|
||||
@ -1803,11 +1792,10 @@ prs_haddr(src, htype)
|
||||
report(LOG_ERR, "Add 0x prefix if hex value starts with A-F");
|
||||
/* OK, assume it must be numeric. */
|
||||
}
|
||||
#endif
|
||||
|
||||
hap = haddr;
|
||||
while (hap < haddr + hal) {
|
||||
if (*p == '.')
|
||||
if ((*p == '.') || (*p == ':'))
|
||||
p++;
|
||||
if (interp_byte(&p, hap++) < 0) {
|
||||
return NULL;
|
||||
|
@ -20,11 +20,6 @@ ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
************************************************************************/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: bootpef.c,v 1.1.1.1 1994/09/10 14:44:54 csgr Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* bootpef - BOOTP Extension File generator
|
||||
* Makes an "Extension File" for each host entry that
|
||||
@ -97,7 +92,6 @@ static char rcsid[] = "$Id: bootpef.c,v 1.1.1.1 1994/09/10 14:44:54 csgr Exp $";
|
||||
#define P(args) ()
|
||||
#endif
|
||||
|
||||
static void dovend_rfc1048 P((struct bootp *, struct host *, int32));
|
||||
static void mktagfile P((struct host *));
|
||||
static void usage P((void));
|
||||
|
||||
@ -291,7 +285,6 @@ mktagfile(hp)
|
||||
FILE *fp;
|
||||
int bytesleft, len;
|
||||
byte *vp;
|
||||
char *tmpstr;
|
||||
|
||||
if (!hp->flags.exten_file)
|
||||
return;
|
||||
@ -332,7 +325,7 @@ mktagfile(hp)
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
} /* dovend_rfc1048 */
|
||||
} /* mktagfile */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
|
@ -40,11 +40,16 @@ char *usage = "bootptest [-h] server-name [vendor-data-template-file]";
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h> /* inet_ntoa */
|
||||
|
||||
#ifndef NO_UNISTD
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
@ -57,8 +62,12 @@ char *usage = "bootptest [-h] server-name [vendor-data-template-file]";
|
||||
#include "bootp.h"
|
||||
#include "bootptest.h"
|
||||
#include "getif.h"
|
||||
#include "getether.h"
|
||||
|
||||
#include "patchlevel.h"
|
||||
|
||||
static void send_request();
|
||||
|
||||
#define LOG_ERR 1
|
||||
#define BUFLEN 1024
|
||||
#define WAITSECS 1
|
||||
@ -94,10 +103,12 @@ u_char eaddr[16]; /* Ethernet address */
|
||||
*/
|
||||
|
||||
int debug = 1; /* Debugging flag (level) */
|
||||
char hostname[64];
|
||||
char *sndbuf; /* Send packet buffer */
|
||||
char *rcvbuf; /* Receive packet buffer */
|
||||
|
||||
struct utsname my_uname;
|
||||
char *hostname;
|
||||
|
||||
/*
|
||||
* Vendor magic cookies for CMU and RFC1048
|
||||
*/
|
||||
@ -114,6 +125,7 @@ extern void bootp_print();
|
||||
* the receiver loop is started. Die when interrupted.
|
||||
*/
|
||||
|
||||
void
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
@ -127,7 +139,7 @@ main(argc, argv)
|
||||
char *bp_file = NULL;
|
||||
int32 server_addr; /* inet addr, network order */
|
||||
int s; /* Socket file descriptor */
|
||||
int n, tolen, fromlen, recvcnt;
|
||||
int n, fromlen, recvcnt;
|
||||
int use_hwa = 0;
|
||||
int32 vend_magic;
|
||||
int32 xid;
|
||||
@ -149,6 +161,12 @@ main(argc, argv)
|
||||
*/
|
||||
assert(sizeof(struct bootp) == BP_MINPKTSZ);
|
||||
|
||||
if (uname(&my_uname) < 0) {
|
||||
fprintf(stderr, "%s: can't get hostname\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
hostname = my_uname.nodename;
|
||||
|
||||
sndbuf = malloc(BUFLEN);
|
||||
rcvbuf = malloc(BUFLEN);
|
||||
if (!sndbuf || !rcvbuf) {
|
||||
@ -302,7 +320,7 @@ main(argc, argv)
|
||||
printf("No interface for %s\n", servername);
|
||||
exit(1);
|
||||
}
|
||||
if (getether(ifr->ifr_name, eaddr)) {
|
||||
if (getether(ifr->ifr_name, (char*)eaddr)) {
|
||||
printf("Can not get ether addr for %s\n", ifr->ifr_name);
|
||||
exit(1);
|
||||
}
|
||||
@ -312,7 +330,6 @@ main(argc, argv)
|
||||
bcopy(eaddr, bp->bp_chaddr, bp->bp_hlen);
|
||||
} else {
|
||||
/* Fill in the client IP address. */
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
hep = gethostbyname(hostname);
|
||||
if (!hep) {
|
||||
printf("Can not get my IP address\n");
|
||||
@ -422,6 +439,7 @@ main(argc, argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
send_request(s)
|
||||
int s;
|
||||
{
|
||||
@ -451,7 +469,7 @@ printfn(s, ep)
|
||||
register u_char c;
|
||||
|
||||
putchar('"');
|
||||
while (c = *s++) {
|
||||
while ((c = *s++) != '\0') {
|
||||
if (s > ep) {
|
||||
putchar('"');
|
||||
return (1);
|
||||
|
@ -23,18 +23,19 @@
|
||||
* This file was copied from tcpdump-2.1.1 and modified.
|
||||
* There is an e-mail list for tcpdump: <tcpdump@ee.lbl.gov>
|
||||
*/
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: print-bootp.c,v 1.1.1.1 1994/09/10 14:44:55 csgr Exp $";
|
||||
/* 93/10/10 <gwr@mc.com> New data-driven option print routine. */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef _AIX32
|
||||
#include <sys/time.h> /* for struct timeval in net/if.h */
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
@ -42,6 +43,7 @@ static char rcsid[] = "$Id: print-bootp.c,v 1.1.1.1 1994/09/10 14:44:55 csgr Exp
|
||||
#include "bootptest.h"
|
||||
|
||||
/* These decode the vendor data. */
|
||||
extern int printfn();
|
||||
static void rfc1048_print();
|
||||
static void cmu_print();
|
||||
static void other_print();
|
||||
@ -271,8 +273,6 @@ rfc1048_opts[] = {
|
||||
};
|
||||
#define KNOWN_OPTIONS (sizeof(rfc1048_opts) / sizeof(rfc1048_opts[0]))
|
||||
|
||||
static void print_string();
|
||||
|
||||
static void
|
||||
rfc1048_print(bp, length)
|
||||
register u_char *bp;
|
||||
@ -280,7 +280,7 @@ rfc1048_print(bp, length)
|
||||
{
|
||||
u_char tag;
|
||||
u_char *ep;
|
||||
register int len, j;
|
||||
register int len;
|
||||
u_int32 ul;
|
||||
u_short us;
|
||||
struct in_addr ia;
|
||||
@ -433,7 +433,6 @@ other_print(bp, length)
|
||||
{
|
||||
u_char *ep; /* end pointer */
|
||||
u_char *zp; /* points one past last non-zero byte */
|
||||
register int i, j;
|
||||
|
||||
/* Setup end pointer */
|
||||
ep = bp + length;
|
||||
|
@ -9,6 +9,9 @@
|
||||
#include <sys/sockio.h>
|
||||
#endif
|
||||
|
||||
#ifdef _AIX32
|
||||
#include <sys/time.h> /* for struct timeval in net/if.h */
|
||||
#endif
|
||||
#include <net/if.h> /* for struct ifreq */
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h> /* inet_ntoa */
|
||||
@ -18,10 +21,14 @@
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "getether.h"
|
||||
|
||||
int debug = 0;
|
||||
char *progname;
|
||||
|
||||
void
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
u_char ea[16]; /* Ethernet address */
|
||||
@ -33,7 +40,7 @@ main(argc, argv)
|
||||
printf("need interface name\n");
|
||||
exit(1);
|
||||
}
|
||||
if ((i = getether(argv[1], ea)) < 0) {
|
||||
if ((i = getether(argv[1], (char*)ea)) < 0) {
|
||||
printf("Could not get Ethernet address (rc=%d)\n", i);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -9,6 +9,9 @@
|
||||
#include <sys/sockio.h>
|
||||
#endif
|
||||
|
||||
#ifdef _AIX32
|
||||
#include <sys/time.h> /* for struct timeval in net/if.h */
|
||||
#endif
|
||||
#include <net/if.h> /* for struct ifreq */
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h> /* inet_ntoa */
|
||||
@ -23,23 +26,26 @@
|
||||
int debug = 0;
|
||||
char *progname;
|
||||
|
||||
void
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
struct hostent *hep;
|
||||
struct sockaddr ea; /* Ethernet address */
|
||||
struct sockaddr_in *sip; /* Interface address */
|
||||
struct ifreq *ifr;
|
||||
struct in_addr dst_addr;
|
||||
struct in_addr *dap;
|
||||
int i, s;
|
||||
int s;
|
||||
|
||||
progname = argv[0]; /* for report */
|
||||
|
||||
dap = NULL;
|
||||
if (argc > 1) {
|
||||
dap = &dst_addr;
|
||||
if (inet_aton(argv[1], &dst_addr) == 0) {
|
||||
if (isdigit(argv[1][0]))
|
||||
dst_addr.s_addr = inet_addr(argv[1]);
|
||||
else {
|
||||
hep = gethostbyname(argv[1]);
|
||||
if (!hep) {
|
||||
printf("gethostbyname(%s)\n", argv[1]);
|
||||
|
@ -15,7 +15,9 @@ extern char *inet_ntoa();
|
||||
int debug = 0;
|
||||
char *progname;
|
||||
|
||||
void
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int i;
|
||||
@ -38,12 +40,16 @@ main(argc, argv)
|
||||
printf(" ipa=%s", a);
|
||||
|
||||
/* Ether addr */
|
||||
printf(" hwa=");
|
||||
hwa = lookup_hwa(argv[i], 1);
|
||||
if (!hwa)
|
||||
a = "?";
|
||||
else
|
||||
a = ether_ntoa(hwa);
|
||||
printf(" hwa=%s\n", a);
|
||||
printf("?\n");
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < 6; i++)
|
||||
printf(":%x", hwa[i] & 0xFF);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
}
|
||||
exit(0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user