Virgin import of LBL traceroute version 1.3.2.

Obtained from: ftp://ftp.ee.lbl.gov/traceroute.tar.Z on 30-Sep-1996.
This commit is contained in:
Bill Fenner 1996-09-30 19:09:55 +00:00
commit 38a623ef96
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/traceroute/dist/; revision=18579
svn path=/vendor/traceroute/1.3.2/; revision=18581; tag=vendor/traceroute/1.3.2
22 changed files with 6321 additions and 0 deletions

View File

@ -0,0 +1,66 @@
@(#) $Header: CHANGES,v 1.12 96/09/28 18:24:35 leres Exp $ (LBL)
v1.3.2 Thu Sep 26 18:06:16 PDT 1996
- Rewrite source routing code to eliminate a number of problems on
systems using raw ip options. Also pad options with a noop so gateway
addresses are aligned.
- Don't call inet_ntoa() twice in the same printf(). Thanks to NetBSD
via Bill Fenner (fenner@parc.xerox.com)
- Decode "administratively prohibited filter" icmp code and print
numeric value for unknown codes. Thanks to Bill Fenner.
v1.3.1 Wed Sep 18 21:08:16 PDT 1996
- Some systems (e.g. AIX) need sys/select.h. Thanks to Brett Hogden
(hogden@rge.com)
- Byte swap ip header length under Solaris. (This has no effect on the
sparc but is required on the i386.)
- Made optional packet length control total size of packet.
v1.3 Mon Sep 16 14:55:44 PDT 1996
- Overrun buffer security fixes. Thanks to Bill Fenner
(fenner@parc.xerox.com)
- Wait for response packet relative to start of probe. Thanks to Bill
Fenner.
- Fix bug that prevented changing the packet size. Thanks to Gregory
Decker (gdecker@nate.dcrt.nih.gov)
- Add support for RAW_OPTIONS (e.g. 4.4 BSD systems such as BSD/OS and
FreeBSD) thanks to Jeffrey C Honig (jch@bsdi.com)
- Remove ip header byte swap fix from v1.2; most kernels swap the ip
header length in the kernel (and it causes OSF3 to crash).
- Fix to not exit when the number of probes is set to 1 (i.e. "-q 1")
- Improve autoconf configuration.
v1.2 Tue Oct 17 23:50:05 PDT 1995
- Convert to autoconf and ansify.
- Byte swap ip header length for little endian machines. Fix thanks to
Y Badri (yb@greybox.demon.co.uk).
v1.1 Thu Jun 15 02:32:55 PDT 1995
- Check for too many arguments.
- Recode to make timing of packet's round trip more obvious and to
tighten up code.
- Ifdef IP_OPTIONS code.
- Display time in microseconds.
v1.0 Tue Feb 28 23:50:05 PDT 1989
- Initial public release.

22
contrib/traceroute/FILES Normal file
View File

@ -0,0 +1,22 @@
CHANGES
FILES
INSTALL
Makefile.in
README
VERSION
acsite.m4
config.guess
config.sub
configure
configure.in
install-sh
lbl/gnuc.h
lbl/os-solaris2.h
lbl/os-sunos4.h
mean.awk
median.awk
mkdep
rip_output.c
strerror.c
traceroute.8
traceroute.c

View File

@ -0,0 +1,82 @@
@(#) $Header: INSTALL,v 1.7 96/09/18 21:09:56 leres Exp $ (LBL)
Traceroute is known to build and run under SunOS 4.1.4 and Solaris 5.4.
If you are running a really old kernel, see the instructions under the
title "KERNEL MODIFICATIONS" further down.
To build traceroute, first customize any paths in Makefile.in, then run
"./configure" (a shell script). The configure script will determine
your system attributes and generate an appropriate Makefile from
Makefile.in. Next run "make". If everything goes well you can su to
root and run "make install" and "make install-man". Note that traceroute
must be installed setuid to root or run as root.
If configure fails for some reason and decide to submit a bug report to
traceroute@ee.lbl.gov, please include a copy of config.log.
You will need an ANSI C compiler to build libpcap. The configure script
will abort if your compiler is not ANSI compliant. If this happens, use
the GNU C compiler, available via anonymous ftp:
ftp://prep.ai.mit.edu/pub/gnu/gcc-*.tar.gz
KERNEL MODIFICATIONS
--------------------
If yor have a really old system, it may be necessary to modify your
kernel before traceroute will work. If you want to hack on your kernel,
a modified version of the routine rip_output (normally found in the
file /sys/netinet/raw_ip.c) can be found in rip_output.c. This code may
or may not resemble the code in your kernel. It may offer you a place
to start but we make no promises. If you do hack your kernel, remember
to test everything that uses raw ip sockets (e.g., ping and
egpup/gated) & make sure they still work. We wish you the best of luck
and you're on your own.
Some older kernels forward icmp packets that have a ttl of zero. If
your system has this bug, you might want to fix it while you're in the
kernel. (This bug appears in all releases of BSD up to but not
including 4.3tahoe. If your version of netinet/ip_icmp.c is any earlier
than 7.3 (April, '87), it has the bug.) The fix is just to add the
line:
ip->ip_ttl = MAXTTL;
after the line:
ip->ip_src = t;
(or anywhere before the call to icmp_send) in routine icmp_reflect.
If you're running this on a pre-4.3bsd system (e.g., SunOS 3) that
strips ip headers from icmp messages, add -DARCHAIC to CFLAGS in the
Makefile. Also note that rip_output contains a conditional for a
4.2/4.3 change in the location of a raw socket's protocol number. I've
checked this under 4.3 & SunOS 3 but you should double-check your
system to make sure the appropriate branch of the #if is taken (check
the line that assigned to ip->ip_p in your system's original
rip_output).
FILES
-----
CHANGES - description of differences between releases
FILES - list of files exported as part of the distribution
INSTALL - this file
Makefile.in - compilation rules (input to the configure script)
README - description of distribution
VERSION - version of this release
acsite.m4 - autoconf macros
config.guess - autoconf support
config.sub - autoconf support
configure - configure script (run this first)
configure.in - configure script source
install-sh - BSD style install script
lbl/gnuc.h - gcc macros and defines
lbl/os-*.h - os dependent defines and prototypes
mean.awk - awk script to print out the mean time along a route
median.awk - awk script to print out the median time along a route
mkdep - construct Makefile dependency list
rip_output.c - sample rip_output() from /sys/netinet/raw_ip.c
traceroute.8 - manual entry
traceroute.c - main program
strerror.c - emulation routine

View File

@ -0,0 +1,126 @@
# Copyright (c) 1988, 1989, 1990, 1991, 1992, 1995, 1996
# The Regents of the University of California. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that: (1) source code distributions
# retain the above copyright notice and this paragraph in its entirety, (2)
# distributions including binary code include the above copyright notice and
# this paragraph in its entirety in the documentation or other materials
# provided with the distribution, and (3) all advertising materials mentioning
# features or use of this software display the following acknowledgement:
# ``This product includes software developed by the University of California,
# Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
# the University nor the names of its contributors may be used to endorse
# or promote products derived from this software without specific prior
# written permission.
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# @(#) $Header: Makefile.in,v 1.21 96/09/16 18:49:46 leres Exp $ (LBL)
#
# Various configurable paths (remember to edit Makefile.in, not Makefile)
#
# Top level hierarchy
prefix = @prefix@
exec_prefix = @exec_prefix@
# Pathname of directory to install the binary
BINDEST = @sbindir@
# Pathname of directory to install the man page
MANDEST = @mandir@
# VPATH
srcdir = @srcdir@
VPATH = @srcdir@
#
# You shouldn't need to edit anything below here.
#
CC = @CC@
CCOPT = @V_CCOPT@
INCLS = -I. @V_INCLS@
DEFS = @DEFS@
# Standard CFLAGS
CFLAGS = $(CCOPT) $(DEFS) $(INCLS)
# Standard LIBS
LIBS = @LIBS@
INSTALL = @INSTALL@
# Explicitly define compilation rule since SunOS 4's make doesn't like gcc.
# Also, gcc does not remove the .o before forking 'as', which can be a
# problem if you don't own the file but can write to the directory.
.c.o:
@rm -f $@
$(CC) $(CFLAGS) -c $*.c
CSRC = traceroute.c
GENSRC = version.c
SRC = $(CSRC) $(GENSRC)
TAGHDR = \
/usr/include/netinet/in.h \
/usr/include/netinet/ip_icmp.h \
/usr/include/netinet/udp.h
TAGFILES = $(SRC) $(TAGHDR)
# We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot
# hack the extra indirection
OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) @LIBOBJS@
CLEANFILES = $(OBJ) traceroute $(GENSRC)
traceroute: $(OBJ)
@rm -f $@
$(CC) $(CFLAGS) -o $@ $(OBJ) $(LIBS)
version.o: version.c
version.c: $(srcdir)/VERSION
@rm -f $@
sed -e 's/.*/char version[] = "&";/' $(srcdir)/VERSION > $@
install: force
$(INSTALL) -m 4555 -o root -g bin traceroute $(DESTDIR)$(BINDEST)
install-man: force
$(INSTALL) -m 444 -o bin -g bin traceroute.8 $(DESTDIR)$(MANDEST)/man8
lint: $(GENSRC) force
lint -hbxn $(SRC) | \
grep -v 'struct/union .* never defined' | \
grep -v 'possible pointer alignment problem'
clean: force
rm -f $(CLEANFILES)
distclean: force
rm -f $(CLEANFILES) Makefile config.cache config.log config.status \
gnuc.h os-proto.h
tags: $(TAGFILES)
ctags -wtd $(TAGFILES)
tar: force
@cwd=`pwd` ; dir=`basename $$cwd` ; name=traceroute-`cat VERSION` ; \
list="" ; tar="tar chFFf" ; \
for i in `cat FILES` ; do list="$$list $$name/$$i" ; done; \
echo \
"rm -f ../$$name; ln -s $$dir ../$$name" ; \
rm -f ../$$name; ln -s $$dir ../$$name ; \
echo \
"(cd .. ; $$tar - [lots of files]) | compress > /tmp/$$name.tar.Z" ; \
(cd .. ; $$tar - $$list) | compress > /tmp/$$name.tar.Z ; \
echo \
"rm -f ../$$name" ; \
rm -f ../$$name
force: /tmp
depend: $(GENSRC) force
./mkdep -c $(CC) $(DEFS) $(INCLS) $(SRC)

29
contrib/traceroute/README Normal file
View File

@ -0,0 +1,29 @@
@(#) $Header: README,v 1.7 96/07/06 02:08:32 leres Exp $ (LBL)
TRACEROUTE 1.3
Lawrence Berkeley National Laboratory
Network Research Group
traceroute@ee.lbl.gov
ftp://ftp.ee.lbl.gov/traceroute.tar.Z
Traceroute is a system administrators utility to trace the route
ip packets from the current system take in getting to some
destination system. See the comments at the front of the
program for a description of its use.
This program uses raw ip sockets and must be run as root (or installed
setuid to root).
A couple of awk programs to massage the traceroute output are
included. "mean.awk" and "median.awk" compute the mean and median time
to each hop, respectively. I've found that something like
traceroute -q 7 foo.somewhere >t
awk -f median.awk t | graph
can give you a quick picture of the bad spots on a long path (median is
usually a better noise filter than mean).
Problems, bugs, questions, desirable enhancements, source code
contributions, etc., should be sent to the email address
"traceroute@ee.lbl.gov".

View File

@ -0,0 +1 @@
1.3.2

View File

@ -0,0 +1,494 @@
dnl @(#) $Header: acsite.m4,v 1.38 96/09/26 21:18:41 leres Exp $ (LBL)
dnl
dnl Copyright (c) 1995, 1996
dnl The Regents of the University of California. All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that: (1) source code distributions
dnl retain the above copyright notice and this paragraph in its entirety, (2)
dnl distributions including binary code include the above copyright notice and
dnl this paragraph in its entirety in the documentation or other materials
dnl provided with the distribution, and (3) all advertising materials mentioning
dnl features or use of this software display the following acknowledgement:
dnl ``This product includes software developed by the University of California,
dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
dnl the University nor the names of its contributors may be used to endorse
dnl or promote products derived from this software without specific prior
dnl written permission.
dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
dnl
dnl LBL autoconf macros
dnl
dnl
dnl Determine which compiler we're using (cc or gcc)
dnl If using gcc, determine the version number
dnl If using cc, require that it support ansi prototypes
dnl If using gcc, use -O2 (otherwise use -O)
dnl If using cc, explicitly specify /usr/local/include
dnl
dnl usage:
dnl
dnl AC_LBL_C_INIT(copt, incls)
dnl
dnl results:
dnl
dnl $1 (copt set)
dnl $2 (incls set)
dnl CC
dnl ac_cv_gcc_vers
dnl
AC_DEFUN(AC_LBL_C_INIT,
[$1=-O
$2=""
if test -z "$CC" ; then
case "$target_os" in
bsdi*)
AC_CHECK_PROG(SHLICC2, shlicc2, yes, no)
if test $SHLICC2 = yes ; then
CC=shlicc2
export CC
fi
;;
esac
fi
AC_PROG_CC
if test $ac_cv_prog_gcc = yes ; then
if test "$SHLICC2" = yes ; then
ac_cv_gcc_vers=2
$1=-O2
else
AC_MSG_CHECKING(gcc version)
AC_CACHE_VAL(ac_cv_gcc_vers,
ac_cv_gcc_vers=`$CC -v 2>&1 | \
sed -n -e '$s/.* //' -e '$s/\..*//p'`)
AC_MSG_RESULT($ac_cv_gcc_vers)
if test $ac_cv_gcc_vers -gt 1 ; then
$1=-O2
fi
fi
else
AC_MSG_CHECKING(that $CC handles ansi prototypes)
AC_CACHE_VAL(ac_cv_cc_ansi_prototypes,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[int frob(int, char *)],
ac_cv_cc_ansi_prototypes=yes,
ac_cv_cc_ansi_prototypes=no))
AC_MSG_RESULT($ac_cv_cc_ansi_prototypes)
if test $ac_cv_cc_ansi_prototypes = no ; then
case "$target_os" in
hpux*)
AC_MSG_CHECKING(for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE))
savedcflags="$CFLAGS"
CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS"
AC_CACHE_VAL(ac_cv_cc_hpux_cc_aa,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[int frob(int, char *)],
ac_cv_cc_hpux_cc_aa=yes,
ac_cv_cc_hpux_cc_aa=no))
AC_MSG_RESULT($ac_cv_cc_hpux_cc_aa)
if test $ac_cv_cc_hpux_cc_aa = no ; then
AC_MSG_ERROR(see the INSTALL for more info)
fi
CFLAGS="$savedcflags"
V_CCOPT="-Aa $V_CCOPT"
AC_DEFINE(_HPUX_SOURCE)
;;
*)
AC_MSG_ERROR(see the INSTALL for more info)
;;
esac
fi
$2=-I/usr/local/include
case "$target_os" in
irix*)
V_CCOPT="$V_CCOPT -xansi -signed -g3"
;;
osf*)
V_CCOPT="$V_CCOPT -g3"
;;
ultrix*)
AC_MSG_CHECKING(that Ultrix $CC hacks const in prototypes)
AC_CACHE_VAL(ac_cv_cc_const_proto,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[struct a { int b; };
void c(const struct a *)],
ac_cv_cc_const_proto=yes,
ac_cv_cc_const_proto=no))
AC_MSG_RESULT($ac_cv_cc_const_proto)
if test $ac_cv_cc_const_proto = no ; then
AC_DEFINE(const,)
fi
;;
esac
fi
])
dnl
dnl Use pfopen.c if available and pfopen() not in standard libraries
dnl Require libpcap
dnl Look for libpcap in ..
dnl Use the installed libpcap if there is no local version
dnl
dnl usage:
dnl
dnl AC_LBL_LIBPCAP(pcapdep, incls)
dnl
dnl results:
dnl
dnl $1 (pcapdep set)
dnl $2 (incls appended)
dnl LIBS
dnl
AC_DEFUN(AC_LBL_LIBPCAP,
[pfopen=/usr/examples/packetfilter/pfopen.c
if test -f $pfopen ; then
AC_CHECK_FUNCS(pfopen)
if test $ac_cv_func_pfopen = "no" ; then
AC_MSG_RESULT(Using $pfopen)
LIBS="$LIBS $pfopen"
fi
fi
AC_MSG_CHECKING(for local pcap library)
libpcap=FAIL
lastdir=FAIL
places=`ls .. | sed -e 's,/$,,' -e 's,^,../,' | \
egrep '/libpcap-[[0-9]]*\.[[0-9]]*(\.[[0-9]]*)?([[ab]][[0-9]]*)?$'`
for dir in $places ../libpcap libpcap ; do
basedir=`echo $dir | sed -e 's/[[ab]][[0-9]]*$//'`
if test $lastdir = $basedir ; then
dnl skip alphas when an actual release is present
continue;
fi
lastdir=$dir
if test -r $dir/pcap.c ; then
libpcap=$dir/libpcap.a
d=$dir
dnl continue and select the last one that exists
fi
done
if test $libpcap = FAIL ; then
AC_MSG_RESULT(not found)
AC_CHECK_LIB(pcap, main, libpcap="-lpcap")
if test $libpcap = FAIL ; then
AC_MSG_ERROR(see the INSTALL doc for more info)
fi
else
$1=$libpcap
$2="-I$d $$2"
AC_MSG_RESULT($libpcap)
fi
LIBS="$libpcap $LIBS"])
dnl
dnl Define RETSIGTYPE and RETSIGVAL
dnl
dnl usage:
dnl
dnl AC_LBL_TYPE_SIGNAL
dnl
dnl results:
dnl
dnl RETSIGTYPE (defined)
dnl RETSIGVAL (defined)
dnl
AC_DEFUN(AC_LBL_TYPE_SIGNAL,
[AC_TYPE_SIGNAL
if test "$ac_cv_type_signal" = void ; then
AC_DEFINE(RETSIGVAL,)
else
AC_DEFINE(RETSIGVAL,(0))
fi
case "$target_os" in
irix*)
AC_DEFINE(_BSD_SIGNALS)
;;
*)
AC_CHECK_FUNCS(sigset)
if test $ac_cv_func_sigset = yes ; then
AC_DEFINE(signal, sigset)
fi
;;
esac])
dnl
dnl If using gcc, see if fixincludes should be run
dnl
dnl usage:
dnl
dnl AC_LBL_FIXINCLUDES
dnl
AC_DEFUN(AC_LBL_FIXINCLUDES,
[if test $ac_cv_prog_gcc = yes ; then
AC_MSG_CHECKING(if fixincludes is needed)
AC_CACHE_VAL(ac_cv_gcc_fixincludes,
AC_TRY_COMPILE(
[/*
* This generates a "duplicate case value" when fixincludes
* has not be run.
*/
# include <sys/types.h>
# include <sys/time.h>
# include <sys/ioctl.h>
# ifdef HAVE_SYS_IOCCOM_H
# include <sys/ioccom.h>
# endif],
[switch (0) {
case _IO('A', 1):;
case _IO('B', 1):;
}],
ac_cv_gcc_fixincludes=yes,
ac_cv_gcc_fixincludes=no))
AC_MSG_RESULT($ac_cv_gcc_fixincludes)
if test $ac_cv_gcc_fixincludes = no ; then
# Don't cache failure
unset ac_cv_gcc_fixincludes
AC_MSG_ERROR(see the INSTALL for more info)
fi
fi])
dnl
dnl Check for flex, default to lex
dnl Require flex 2.4 or higher
dnl Check for bison, default to yacc
dnl Default to lex/yacc if both flex and bison are not available
dnl Define the yy prefix string if using flex and bison
dnl
dnl usage:
dnl
dnl AC_LBL_LEX_AND_YACC(lex, yacc, yyprefix)
dnl
dnl results:
dnl
dnl $1 (lex set)
dnl $2 (yacc appended)
dnl $3 (optional flex and bison -P prefix)
dnl
AC_DEFUN(AC_LBL_LEX_AND_YACC,
[AC_CHECK_PROGS($1, flex, lex)
if test "$$1" = flex ; then
# The -V flag was added in 2.4
AC_MSG_CHECKING(for flex 2.4 or higher)
AC_CACHE_VAL(ac_cv_flex_v24,
if flex -V >/dev/null 2>&1; then
ac_cv_flex_v24=yes
else
ac_cv_flex_v24=no
fi)
AC_MSG_RESULT($ac_cv_flex_v24)
if test $ac_cv_flex_v24 = no ; then
s="2.4 or higher required"
AC_MSG_WARN(ignoring obsolete flex executable ($s))
$1=lex
fi
fi
AC_CHECK_PROGS($2, bison, yacc)
if test "$$2" = bison ; then
$2="$$2 -y"
fi
if test "$$1" != lex -a "$$2" = yacc -o "$$1" = lex -a "$$2" != yacc ; then
AC_MSG_WARN(don't have both flex and bison; reverting to lex/yacc)
$1=lex
$2=yacc
fi
if test "$$1" = flex -a -n "$3" ; then
$1="$$1 -P$3"
$2="$$2 -p $3"
fi])
dnl
dnl Checks to see if union wait is used with WEXITSTATUS()
dnl
dnl usage:
dnl
dnl AC_LBL_UNION_WAIT
dnl
dnl results:
dnl
dnl DECLWAITSTATUS (defined)
dnl
AC_DEFUN(AC_LBL_UNION_WAIT,
[AC_MSG_CHECKING(if union wait is used)
AC_CACHE_VAL(ac_cv_union_wait,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/wait.h>],
[int status;
u_int i = WEXITSTATUS(status);
u_int j = waitpid(0, &status, 0);],
ac_cv_union_wait=no,
ac_cv_union_wait=yes))
AC_MSG_RESULT($ac_cv_union_wait)
if test $ac_cv_union_wait = yes ; then
AC_DEFINE(DECLWAITSTATUS,union wait)
else
AC_DEFINE(DECLWAITSTATUS,int)
fi])
dnl
dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member
dnl
dnl usage:
dnl
dnl AC_LBL_SOCKADDR_SA_LEN
dnl
dnl results:
dnl
dnl HAVE_SOCKADDR_SA_LEN (defined)
dnl
AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN,
[AC_MSG_CHECKING(if sockaddr struct has sa_len member)
AC_CACHE_VAL(ac_cv_sockaddr_has_sa_len,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/socket.h>],
[u_int i = sizeof(((struct sockaddr *)0)->sa_len)],
ac_cv_sockaddr_has_sa_len=yes,
ac_cv_sockaddr_has_sa_len=no))
AC_MSG_RESULT($ac_cv_sockaddr_has_sa_len)
if test $ac_cv_sockaddr_has_sa_len = yes ; then
AC_DEFINE(HAVE_SOCKADDR_SA_LEN)
fi])
dnl
dnl Checks to see if -R is used
dnl
dnl usage:
dnl
dnl AC_LBL_HAVE_RUN_PATH
dnl
dnl results:
dnl
dnl ac_cv_have_run_path (yes or no)
dnl
AC_DEFUN(AC_LBL_HAVE_RUN_PATH,
[AC_MSG_CHECKING(for ${CC-cc} -R)
AC_CACHE_VAL(ac_cv_have_run_path,
[echo 'main(){}' > conftest.c
${CC-cc} -o conftest conftest.c -R/a1/b2/c3 >conftest.out 2>&1
if test ! -s conftest.out ; then
ac_cv_have_run_path=yes
else
ac_cv_have_run_path=no
fi
rm -f conftest*])
AC_MSG_RESULT($ac_cv_have_run_path)
])
dnl
dnl Checks to see if unaligned memory accesses fail
dnl
dnl usage:
dnl
dnl AC_LBL_UNALIGNED_ACCESS
dnl
dnl results:
dnl
dnl LBL_ALIGN (DEFINED)
dnl
AC_DEFUN(AC_LBL_UNALIGNED_ACCESS,
[AC_MSG_CHECKING(if unaligned accesses fail)
AC_CACHE_VAL(ac_cv_unaligned_fail,
[case "$target_cpu" in
alpha|hp*|mips|sparc)
ac_cv_unaligned_fail=yes
;;
*)
cat >conftest.c <<EOF
# include <sys/types.h>
# include <sys/wait.h>
# include <stdio.h>
unsigned char a[[5]] = { 1, 2, 3, 4, 5 };
main() {
unsigned int i;
pid_t pid;
int status;
/* avoid "core dumped" message */
pid = fork();
if (pid < 0)
exit(2);
if (pid > 0) {
/* parent */
pid = waitpid(pid, &status, 0);
if (pid < 0)
exit(3);
exit(!WIFEXITED(status));
}
/* child */
i = *(unsigned int *)&a[[1]];
printf("%d\n", i);
exit(0);
}
EOF
${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \
conftest.c $LIBS >/dev/null 2>&1
if test ! -x conftest ; then
dnl failed to compile for some reason
ac_cv_unaligned_fail=yes
else
./conftest >conftest.out
if test ! -s conftest.out ; then
ac_cv_unaligned_fail=yes
else
ac_cv_unaligned_fail=no
fi
fi
rm -f conftest* core core.conftest
;;
esac])
AC_MSG_RESULT($ac_cv_unaligned_fail)
if test $ac_cv_unaligned_fail = yes ; then
AC_DEFINE(LBL_ALIGN)
fi])
dnl
dnl If using gcc and the file .devel exists:
dnl Compile with -g (if supported) and -Wall
dnl If using gcc 2, do extra prototype checking
dnl If an os prototype include exists, symlink os-proto.h to it
dnl
dnl usage:
dnl
dnl AC_LBL_DEVEL(copt)
dnl
dnl results:
dnl
dnl $1 (copt appended)
dnl HAVE_OS_PROTO_H (defined)
dnl os-proto.h (symlinked)
dnl
AC_DEFUN(AC_LBL_DEVEL,
[rm -f os-proto.h
if test $ac_cv_prog_gcc = yes -a -f .devel ; then
if test $ac_cv_prog_gcc_g = yes ; then
$1="-g $$1"
fi
$1="$$1 -Wall"
if test $ac_cv_gcc_vers -gt 1 ; then
$1="$$1 -Wmissing-prototypes -Wstrict-prototypes"
fi
os=`echo $target_os | sed -e 's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'`
name="lbl/os-$os.h"
if test -f $name ; then
ln -s $name os-proto.h
AC_DEFINE(HAVE_OS_PROTO_H)
else
AC_MSG_WARN(can't find $name)
fi
fi])

600
contrib/traceroute/config.guess vendored Executable file
View File

@ -0,0 +1,600 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Written by Per Bothner <bothner@cygnus.com>.
# The master version of this file is at the FSF in /home/gd/gnu/lib.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
#
# The plan is that this can be called by configure scripts if you
# don't specify an explicit system type (host/target name).
#
# Only a few systems have been added to this list; please add others
# (but try to keep the structure clean).
#
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 8/24/94.)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
alpha:OSF1:*:*)
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'`
exit 0 ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit 0 ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-cbm-sysv4
exit 0;;
amiga:NetBSD:*:*)
echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
Pyramid*:OSx*:*:*)
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit 0 ;;
sun4*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
i86pc:SunOS:5.*:*)
echo i386-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
exit 0 ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
atari*:NetBSD:*:*)
echo m68k-atari-netbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:NetBSD:*:*)
echo m68k-apple-netbsd${UNAME_RELEASE}
exit 0 ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
mips:*:4*:UMIPS)
echo mips-mips-riscos4sysv
exit 0 ;;
mips:*:5*:RISCos)
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit 0 ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit 0 ;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
exit 0 ;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
exit 0 ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88100 ] ; then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else echo i586-dg-dgux${UNAME_RELEASE}
fi
exit 0 ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit 0 ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
exit 0 ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
exit 0 ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
exit 0 ;;
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit 0 ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i[34]86:AIX:*:*)
echo i386-ibm-aix
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
sed 's/^ //' << EOF >dummy.c
#include <sys/systemcfg.h>
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
exit 0 ;;
*:AIX:*:4)
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=4.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit 0 ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit 0 ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit 0 ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit 0 ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
exit 0 ;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
exit 0 ;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
exit 0 ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit 0 ;;
9000/[3478]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;;
9000/8?? ) HP_ARCH=hppa1.0 ;;
esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
sed 's/^ //' << EOF >dummy.c
#include <unistd.h>
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
exit 0 ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit 0 ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit 0 ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit 0 ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit 0 ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit 0 ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
CRAY*X-MP:*:*:*)
echo xmp-cray-unicos
exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY*C90:*:*:*)
echo c90-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0 ;;
i[34]86:BSD/386:*:* | *:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
*:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
i*:CYGWIN*:*)
echo i386-unknown-cygwin32
exit 0 ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin32
exit 0 ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
*:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
*:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us.
ld_help_string=`ld --help 2>&1`
if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then
echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then
echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then
echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then
echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then
echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
elif test "${UNAME_MACHINE}" = "alpha" ; then
echo alpha-unknown-linux ; exit 0
else
# Either a pre-BFD a.out linker (linuxoldld) or one that does not give us
# useful --help. Gcc wants to distinguish between linuxoldld and linuxaout.
test ! -d /usr/lib/ldscripts/. \
&& echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0
# Determine whether the default compiler is a.out or elf
cat >dummy.c <<EOF
main(argc, argv)
int argc;
char *argv[];
{
#ifdef __ELF__
printf ("%s-unknown-linux\n", argv[1]);
#else
printf ("%s-unknown-linuxaout\n", argv[1]);
#endif
return 0;
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
fi ;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
# are messed up and put the nodename in both sysname and nodename.
i[34]86:DYNIX/ptx:4*:*)
echo i386-sequent-sysv4
exit 0 ;;
i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*)
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
else
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}
fi
exit 0 ;;
i[34]86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-unknown-sysv32
fi
exit 0 ;;
Intel:Mach:3*:*)
echo i386-unknown-mach3
exit 0 ;;
paragon:*:*:*)
echo i860-intel-osf1
exit 0 ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
exit 0 ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
M680[234]0:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4.3 && exit 0 ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4 && exit 0 ;;
m680[234]0:LynxOS:2.[23]*:*)
echo m68k-lynx-lynxos${UNAME_RELEASE}
exit 0 ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
i[34]86:LynxOS:2.[23]*:*)
echo i386-lynx-lynxos${UNAME_RELEASE}
exit 0 ;;
TSUNAMI:LynxOS:2.[23]*:*)
echo sparc-lynx-lynxos${UNAME_RELEASE}
exit 0 ;;
rs6000:LynxOS:2.[23]*:*)
echo rs6000-lynx-lynxos${UNAME_RELEASE}
exit 0 ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
echo ${UNAME_MACHINE}-sni-sysv4
else
echo ns32k-sni-sysv
fi
exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
R3000:*System_V*:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
cat >dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3");
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-unknown-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
#if !defined (ultrix)
printf ("vax-dec-bsd\n"); exit (0);
#else
printf ("vax-dec-ultrix\n"); exit (0);
#endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
exit 0 ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit 0 ;;
c34*)
echo c34-convex-bsd
exit 0 ;;
c38*)
echo c38-convex-bsd
exit 0 ;;
c4*)
echo c4-convex-bsd
exit 0 ;;
esac
fi
#echo '(Unable to guess system type)' 1>&2
exit 1

867
contrib/traceroute/config.sub vendored Executable file
View File

@ -0,0 +1,867 @@
#! /bin/sh
# Configuration validation subroutine script, version 1.1.
# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support. The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
if [ x$1 = x ]
then
echo Configuration name missing. 1>&2
echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
echo "or $0 ALIAS" 1>&2
echo where ALIAS is a recognized configuration type. 1>&2
exit 1
fi
# First pass through any local machine types.
case $1 in
*local*)
echo $1
exit 0
;;
*)
;;
esac
# Separate what the user gave into CPU-COMPANY and OS (if any).
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
### recognize some manufacturers as not being operating systems, so we
### can provide default operating systems below.
case $os in
-sun*os*)
# Prevent following clause from handling this invalid input.
;;
-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp )
os=
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
;;
-lynx*)
os=-lynxos
;;
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm \
| arme[lb] | pyramid \
| tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
| alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
| powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
| pdp11 | mips64el | mips64orion | mips64orionel \
| sparc)
basic_machine=$basic_machine-unknown
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \
| sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
| none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
| hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
| pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
| pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
alliant | fx80)
basic_machine=fx80-alliant
;;
altos | altos3068)
basic_machine=m68k-altos
;;
am29k)
basic_machine=a29k-none
os=-bsd
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-cbm
;;
amigados)
basic_machine=m68k-cbm
os=-amigados
;;
amigaunix | amix)
basic_machine=m68k-cbm
os=-sysv4
;;
apollo68)
basic_machine=m68k-apollo
os=-sysv
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
;;
convex-c2)
basic_machine=c2-convex
os=-bsd
;;
convex-c32)
basic_machine=c32-convex
os=-bsd
;;
convex-c34)
basic_machine=c34-convex
os=-bsd
;;
convex-c38)
basic_machine=c38-convex
os=-bsd
;;
cray | ymp)
basic_machine=ymp-cray
os=-unicos
;;
cray2)
basic_machine=cray2-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
;;
delta88)
basic_machine=m88k-motorola
os=-sysv3
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
;;
dpx2* | dpx2*-bull)
basic_machine=m68k-bull
os=-sysv3
;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
;;
elxsi)
basic_machine=elxsi-elxsi
os=-bsd
;;
encore | umax | mmax)
basic_machine=ns32k-encore
;;
fx2800)
basic_machine=i860-alliant
;;
genix)
basic_machine=ns32k-ns
;;
gmicro)
basic_machine=tron-gmicro
os=-sysv
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
h8300hms)
basic_machine=h8300-hitachi
os=-hms
;;
harris)
basic_machine=m88k-harris
os=-sysv3
;;
hp300-*)
basic_machine=m68k-hp
;;
hp300bsd)
basic_machine=m68k-hp
os=-bsd
;;
hp300hpux)
basic_machine=m68k-hp
os=-hpux
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
os=-mvs
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i[345]86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
os=-sysv32
;;
i[345]86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
os=-sysv4
;;
i[345]86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
os=-sysv
;;
i[345]86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
os=-solaris2
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
-irix*)
;;
*)
os=-irix4
;;
esac
;;
isi68 | isi)
basic_machine=m68k-isi
os=-sysv
;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
;;
merlin)
basic_machine=ns32k-utek
os=-sysv
;;
miniframe)
basic_machine=m68000-convergent
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
;;
news1000)
basic_machine=m68030-sony
os=-newsos
;;
news-3600 | risc-news)
basic_machine=mips-sony
os=-newsos
;;
next | m*-next )
basic_machine=m68k-next
case $os in
-nextstep* )
;;
-ns2*)
os=-nextstep2
;;
*)
os=-nextstep3
;;
esac
;;
nh3000)
basic_machine=m68k-harris
os=-cxux
;;
nh[45]000)
basic_machine=m88k-harris
os=-cxux
;;
nindy960)
basic_machine=i960-intel
os=-nindy
;;
np1)
basic_machine=np1-gould
;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
paragon)
basic_machine=i860-intel
os=-osf
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | p6)
# We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium
basic_machine=i586-intel
;;
pentium-* | p5-* | p6-*)
# We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
k5)
# We don't have specific support for AMD's K5 yet, so just call it a Pentium
basic_machine=i586-amd
;;
nexen)
# We don't have specific support for Nexgen yet, so just call it a Pentium
basic_machine=i586-nexgen
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=rs6000-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
rm[46]00)
basic_machine=mips-siemens
;;
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
sequent)
basic_machine=i386-sequent
;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sps7)
basic_machine=m68k-bull
os=-sysv2
;;
spur)
basic_machine=spur-unknown
;;
sun2)
basic_machine=m68000-sun
;;
sun2os3)
basic_machine=m68000-sun
os=-sunos3
;;
sun2os4)
basic_machine=m68000-sun
os=-sunos4
;;
sun3os3)
basic_machine=m68k-sun
os=-sunos3
;;
sun3os4)
basic_machine=m68k-sun
os=-sunos4
;;
sun4os3)
basic_machine=sparc-sun
os=-sunos3
;;
sun4os4)
basic_machine=sparc-sun
os=-sunos4
;;
sun4sol2)
basic_machine=sparc-sun
os=-solaris2
;;
sun3 | sun3-*)
basic_machine=m68k-sun
;;
sun4)
basic_machine=sparc-sun
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
udi29k)
basic_machine=a29k-amd
os=-udi
;;
ultra3)
basic_machine=a29k-nyu
os=-sym1
;;
vaxv)
basic_machine=vax-dec
os=-sysv
;;
vms)
basic_machine=vax-dec
os=-vms
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
;;
vxworks68)
basic_machine=m68k-wrs
os=-vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
os=-vxworks
;;
xmp)
basic_machine=xmp-cray
os=-unicos
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
none)
basic_machine=none-none
os=-none
;;
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
mips)
basic_machine=mips-mips
;;
romp)
basic_machine=romp-ibm
;;
rs6000)
basic_machine=rs6000-ibm
;;
vax)
basic_machine=vax-dec
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sparc)
basic_machine=sparc-sun
;;
cydra)
basic_machine=cydra-cydrome
;;
orion)
basic_machine=orion-highlevel
;;
orion105)
basic_machine=clipper-highlevel
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
;;
*-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
;;
*)
;;
esac
# Decode manufacturer-specific aliases for certain operating systems.
if [ x"$os" != x"" ]
then
case $os in
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
-solaris)
os=-solaris2
;;
-unixware* | svr4*)
os=-sysv4
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux|'`
;;
# First accept the basic system types.
# The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[345]* \
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigados* | -msdos* | -newsos* | -unicos* | -aos* \
| -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
| -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* )
# Remember, each alternative MUST END IN *, to match a version number.
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*)
os=-bsd
;;
-dynix*)
os=-bsd
;;
-acis*)
os=-aos
;;
-ctix* | -uts*)
os=-sysv
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
-sinix*)
os=-sysv4
;;
-triton*)
os=-sysv3
;;
-oss*)
os=-sysv3
;;
-svr4)
os=-sysv4
;;
-svr3)
os=-sysv3
;;
-sysvr4)
os=-sysv4
;;
# This must come after -sysvr4.
-sysv*)
;;
-xenix)
os=-xenix
;;
-none)
;;
*)
# Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
exit 1
;;
esac
else
# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.
# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system. Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
case $basic_machine in
*-acorn)
os=-riscix1.2
;;
arm*-semi)
os=-aout
;;
pdp11-*)
os=-none
;;
*-dec | vax-*)
os=-ultrix4.2
;;
m68*-apollo)
os=-domain
;;
i386-sun)
os=-sunos4.0.2
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-ibm)
os=-aix
;;
*-hp)
os=-hpux
;;
*-hitachi)
os=-hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
os=-sysv
;;
*-cbm)
os=-amigados
;;
*-dg)
os=-dgux
;;
*-dolphin)
os=-sysv3
;;
m68k-ccur)
os=-rtu
;;
m88k-omron*)
os=-luna
;;
*-sequent)
os=-ptx
;;
*-crds)
os=-unos
;;
*-ns)
os=-genix
;;
i370-*)
os=-mvs
;;
*-next)
os=-nextstep3
;;
*-gould)
os=-sysv
;;
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
os=-irix
;;
*-siemens)
os=-sysv4
;;
*-masscomp)
os=-rtu
;;
*)
os=-none
;;
esac
fi
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
vendor=unknown
case $basic_machine in
*-unknown)
case $os in
-riscix*)
vendor=acorn
;;
-sunos*)
vendor=sun
;;
-lynxos*)
vendor=lynx
;;
-aix*)
vendor=ibm
;;
-hpux*)
vendor=hp
;;
-hiux*)
vendor=hitachi
;;
-unos*)
vendor=crds
;;
-dgux*)
vendor=dg
;;
-luna*)
vendor=omron
;;
-genix*)
vendor=ns
;;
-mvs*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-vxworks*)
vendor=wrs
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os

1753
contrib/traceroute/configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
dnl @(#) $Header: configure.in,v 1.10 96/09/24 18:44:24 leres Exp $ (LBL)
dnl
dnl Copyright (c) 1995, 1996
dnl The Regents of the University of California. All rights reserved.
dnl
dnl Process this file with autoconf to produce a configure script.
dnl
AC_INIT(traceroute.c)
AC_CANONICAL_SYSTEM
umask 002
if test -z "$PWD" ; then
PWD=`pwd`
fi
AC_LBL_C_INIT(V_CCOPT, V_INCLS)
AC_CHECK_HEADERS(malloc.h sys/select.h)
AC_REPLACE_FUNCS(strerror)
AC_CHECK_FUNCS(setlinebuf)
AC_CHECK_LIB(socket, main)
AC_CHECK_LIB(nsl, main)
case "$target_os" in
bsd4*)
AC_DEFINE(HAVE_RAW_OPTIONS)
;;
bsdi*)
AC_DEFINE(HAVE_RAW_OPTIONS)
;;
freebsd*)
AC_DEFINE(HAVE_RAW_OPTIONS)
;;
osf3*)
dnl Workaround around ip_hl vs. ip_vhl problem in netinet/ip.h
AC_DEFINE(__STDC__,2)
;;
solaris*)
AC_DEFINE(BYTESWAP_IP_LEN)
;;
esac
AC_CHECK_TYPE(int32_t, int)
AC_CHECK_TYPE(u_int32_t, u_int)
AC_LBL_DEVEL(V_CCOPT)
if test -r lbl/gnuc.h ; then
rm -f gnuc.h
ln -s lbl/gnuc.h gnuc.h
fi
AC_SUBST(V_CCOPT)
AC_SUBST(V_INCLS)
AC_PROG_INSTALL
AC_OUTPUT(Makefile)
if test -f .devel ; then
make depend
fi
exit 0

238
contrib/traceroute/install-sh Executable file
View File

@ -0,0 +1,238 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

View File

@ -0,0 +1,43 @@
/* @(#) $Header: gnuc.h,v 1.3 95/10/09 02:47:01 leres Exp $ (LBL) */
/* Define __P() macro, if necessary */
#ifndef __P
#if __STDC__
#define __P(protos) protos
#else
#define __P(protos) ()
#endif
#endif
/* inline foo */
#ifdef __GNUC__
#define inline __inline
#else
#define inline
#endif
/*
* Handle new and old "dead" routine prototypes
*
* For example:
*
* __dead void foo(void) __attribute__((volatile));
*
*/
#ifdef __GNUC__
#ifndef __dead
#define __dead volatile
#endif
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
#ifndef __attribute__
#define __attribute__(args)
#endif
#endif
#else
#ifndef __dead
#define __dead
#endif
#ifndef __attribute__
#define __attribute__(args)
#endif
#endif

View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: os-solaris2.h,v 1.16 96/07/05 22:11:23 leres Locked $ (LBL)
*/
/* Signal routines are this type */
#define SIGRET void
/* Signal routines use "return SIGRETVAL;" */
#define SIGRETVAL
/* The wait() status variable is this type */
#define WAITSTATUS int
#define major(x) ((int)(((unsigned)(x)>>8)&0377))
#define minor(x) ((int)((x)&0377))
/* Prototypes missing in SunOS 5 */
int daemon(int, int);
int dn_expand(u_char *, u_char *, u_char *, u_char *, int);
int dn_skipname(u_char *, u_char *);
int flock(int, int);
int getdtablesize(void);
int gethostname(char *, int);
int getpagesize(void);
char *getusershell(void);
char *getwd(char *);
int iruserok(u_int, int, char *, char *);
#ifdef __STDC__
struct utmp;
void login(struct utmp *);
#endif
int logout(const char *);
int res_query(char *, int, int, u_char *, int);
int setenv(const char *, const char *, int);
#if defined(_STDIO_H) && defined(HAVE_SETLINEBUF)
int setlinebuf(FILE *);
#endif
int sigblock(int);
int sigsetmask(int);
char *strerror(int);
int snprintf(char *, size_t, const char *, ...);
int strcasecmp(const char *, const char *);
void unsetenv(const char *);
#ifdef __STDC__
struct timeval;
#endif
int utimes(const char *, struct timeval *);
/* Solaris signal compat */
#ifndef sigmask
#define sigmask(m) (1 << ((m)-1))
#endif
#ifndef signal
#define signal(s, f) sigset(s, f)
#endif
/* Solaris random compat */
#ifndef srandom
#define srandom(seed) srand48((long)seed)
#endif
#ifndef random
#define random() lrand48()
#endif
#ifdef notdef
#ifndef CBREAK
#define CBREAK O_CBREAK
#define CRMOD O_CRMOD
#define RAW O_RAW
#define TBDELAY O_TBDELAY
#endif
#endif
#ifndef TIOCPKT_DATA
#define TIOCPKT_DATA 0x00 /* data packet */
#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */
#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */
#define TIOCPKT_STOP 0x04 /* stop output */
#define TIOCPKT_START 0x08 /* start output */
#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */
#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */
#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */
#endif
#ifndef STDERR_FILENO
#define STDERR_FILENO 2
#define STDOUT_FILENO 1
#define STDIN_FILENO 0
#endif
#ifndef FD_SET
#define FD_SET(n, p) ((p)->fds_bits[0] |= (1<<(n)))
#define FD_CLR(n, p) ((p)->fds_bits[0] &= ~(1<<(n)))
#define FD_ISSET(n, p) ((p)->fds_bits[0] & (1<<(n)))
#define FD_ZERO(p) ((p)->fds_bits[0] = 0)
#endif
#ifndef S_ISTXT
#define S_ISTXT S_ISVTX
#endif

View File

@ -0,0 +1,237 @@
/*
* Copyright (c) 1989, 1990, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: os-sunos4.h,v 1.31 96/06/24 02:39:07 leres Exp $ (LBL)
*/
#define SIGRET void
#define SIGRETVAL
#define WAITSTATUS int
/* Prototypes missing in SunOS 4 */
#ifdef FILE
int _filbuf(FILE *);
int _flsbuf(u_char, FILE *);
int fclose(FILE *);
int fflush(FILE *);
int fgetc(FILE *);
int fprintf(FILE *, const char *, ...);
int fputc(int, FILE *);
int fputs(const char *, FILE *);
u_int fread(void *, u_int, u_int, FILE *);
int fseek(FILE *, long, int);
u_int fwrite(const void *, u_int, u_int, FILE *);
int pclose(FILE *);
void rewind(FILE *);
void setbuf(FILE *, char *);
int setlinebuf(FILE *);
int ungetc(int, FILE *);
int vfprintf(FILE *, const char *, ...);
int vprintf(const char *, ...);
#endif
#if __GNUC__ <= 1
int read(int, char *, u_int);
int write(int, char *, u_int);
#endif
long a64l(const char *);
#ifdef __STDC__
struct sockaddr;
#endif
int accept(int, struct sockaddr *, int *);
int bind(int, struct sockaddr *, int);
int bcmp(const void *, const void *, u_int);
void bcopy(const void *, void *, u_int);
void bzero(void *, int);
int chroot(const char *);
int close(int);
void closelog(void);
int connect(int, struct sockaddr *, int);
char *crypt(const char *, const char *);
int daemon(int, int);
int fchmod(int, int);
int fchown(int, int, int);
void endgrent(void);
void endpwent(void);
void endservent(void);
#ifdef __STDC__
struct ether_addr;
#endif
struct ether_addr *ether_aton(const char *);
int flock(int, int);
#ifdef __STDC__
struct stat;
#endif
int fstat(int, struct stat *);
#ifdef __STDC__
struct statfs;
#endif
int fstatfs(int, struct statfs *);
int fsync(int);
#ifdef __STDC__
struct timeb;
#endif
int ftime(struct timeb *);
int ftruncate(int, off_t);
int getdtablesize(void);
long gethostid(void);
int gethostname(char *, int);
int getopt(int, char * const *, const char *);
int getpagesize(void);
char *getpass(char *);
int getpeername(int, struct sockaddr *, int *);
int getpriority(int, int);
#ifdef __STDC__
struct rlimit;
#endif
int getrlimit(int, struct rlimit *);
int getsockname(int, struct sockaddr *, int *);
int getsockopt(int, int, int, char *, int *);
#ifdef __STDC__
struct timeval;
struct timezone;
#endif
int gettimeofday(struct timeval *, struct timezone *);
char *getusershell(void);
char *getwd(char *);
int initgroups(const char *, int);
int ioctl(int, int, caddr_t);
int iruserok(u_long, int, char *, char *);
int isatty(int);
int killpg(int, int);
int listen(int, int);
#ifdef __STDC__
struct utmp;
#endif
void login(struct utmp *);
int logout(const char *);
off_t lseek(int, off_t, int);
int lstat(const char *, struct stat *);
int mkstemp(char *);
char *mktemp(char *);
int munmap(caddr_t, int);
void openlog(const char *, int, int);
void perror(const char *);
int printf(const char *, ...);
int puts(const char *);
long random(void);
int readlink(const char *, char *, int);
#ifdef __STDC__
struct iovec;
#endif
int readv(int, struct iovec *, int);
int recv(int, char *, u_int, int);
int recvfrom(int, char *, u_int, int, struct sockaddr *, int *);
int rename(const char *, const char *);
int rcmd(char **, u_short, char *, char *, char *, int *);
int rresvport(int *);
int send(int, char *, u_int, int);
int sendto(int, char *, u_int, int, struct sockaddr *, int);
int setenv(const char *, const char *, int);
int seteuid(int);
int setpriority(int, int, int);
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
int setpgrp(int, int);
void setpwent(void);
int setrlimit(int, struct rlimit *);
void setservent(int);
int setsockopt(int, int, int, char *, int);
int shutdown(int, int);
int sigblock(int);
void (*signal (int, void (*) (int))) (int);
int sigpause(int);
int sigsetmask(int);
#ifdef __STDC__
struct sigvec;
#endif
int sigvec(int, struct sigvec *, struct sigvec*);
int snprintf(char *, size_t, const char *, ...);
int socket(int, int, int);
int socketpair(int, int, int, int *);
int symlink(const char *, const char *);
void srandom(int);
int sscanf(char *, const char *, ...);
int stat(const char *, struct stat *);
int statfs(char *, struct statfs *);
char *strerror(int);
int strcasecmp(const char *, const char *);
#ifdef __STDC__
struct tm;
#endif
int strftime(char *, int, char *, struct tm *);
int strncasecmp(const char *, const char *, int);
long strtol(const char *, char **, int);
void sync(void);
void syslog(int, const char *, ...);
int system(const char *);
long tell(int);
time_t time(time_t *);
char *timezone(int, int);
int tolower(int);
int toupper(int);
int truncate(char *, off_t);
void unsetenv(const char *);
int vfork(void);
int vsprintf(char *, const char *, ...);
int writev(int, struct iovec *, int);
#ifdef __STDC__
struct rusage;
#endif
int utimes(const char *, struct timeval *);
#if __GNUC__ <= 1
int wait(int *);
pid_t wait3(int *, int, struct rusage *);
#endif
extern int opterr, optind, optopt;
extern char *optarg;
/* Map protocol types */
#define ETHERPUP_IPTYPE ETHERTYPE_IP
#define ETHERPUP_REVARPTYPE ETHERTYPE_REVARP
#define ETHERPUP_ARPTYPE ETHERTYPE_ARP
/* Ugly signal hacking */
#ifdef SIG_ERR
#undef SIG_ERR
#define SIG_ERR (void (*)(int))-1
#undef SIG_DFL
#define SIG_DFL (void (*)(int))0
#undef SIG_IGN
#define SIG_IGN (void (*)(int))1
#ifdef KERNEL
#undef SIG_CATCH
#define SIG_CATCH (void (*)(int))2
#endif
#undef SIG_HOLD
#define SIG_HOLD (void (*)(int))3
#endif
#ifndef S_ISTXT
#define S_ISTXT S_ISVTX
#endif
#ifndef S_IRWXU
#define S_IRWXU 0000700 /* RWX mask for owner */
#define S_IRWXG 0000070 /* RWX mask for group */
#define S_IRWXO 0000007 /* RWX mask for other */
#endif

View File

@ -0,0 +1,12 @@
/^ *[0-9]/ {
# print out the average time to each hop along a route.
tottime = 0; n = 0;
for (f = 5; f <= NF; ++f) {
if ($f == "ms") {
tottime += $(f - 1)
++n
}
}
if (n > 0)
print $1, tottime/n, median
}

View File

@ -0,0 +1,29 @@
/^ *[0-9]/ {
# print out the median time to each hop along a route.
tottime = 0; n = 0;
for (f = 5; f <= NF; ++f) {
if ($f == "ms") {
++n
time[n] = $(f - 1)
}
}
if (n > 0) {
# insertion sort the times to find the median
for (i = 2; i <= n; ++i) {
v = time[i]; j = i - 1;
while (time[j] > v) {
time[j+1] = time[j];
j = j - 1;
if (j < 0)
break;
}
time[j+1] = v;
}
if (n > 1 && (n % 2) == 0)
median = (time[n/2] + time[(n/2) + 1]) / 2
else
median = time[(n+1)/2]
print $1, median
}
}

109
contrib/traceroute/mkdep Executable file
View File

@ -0,0 +1,109 @@
#!/bin/sh -
#
# Copyright (c) 1994, 1996
# The Regents of the University of California. All rights reserved.
#
# Redistribution and use in source and binary forms are permitted
# provided that this notice is preserved and that due credit is given
# to the University of California at Berkeley. The name of the University
# may not be used to endorse or promote products derived from this
# software without specific prior written permission. This software
# is provided ``as is'' without express or implied warranty.
#
# @(#)mkdep.sh 5.11 (Berkeley) 5/5/88
#
PATH=/bin:/usr/bin:/usr/ucb:/usr/local:/usr/local/bin
export PATH
MAKE=Makefile # default makefile name is "Makefile"
CC=cc # default C compiler is "cc"
while :
do case "$1" in
# -c allows you to specify the C compiler
-c)
CC=$2
shift; shift ;;
# -f allows you to select a makefile name
-f)
MAKE=$2
shift; shift ;;
# the -p flag produces "program: program.c" style dependencies
# so .o's don't get produced
-p)
SED='s;\.o;;'
shift ;;
*)
break ;;
esac
done
if [ $# = 0 ] ; then
echo 'usage: mkdep [-p] [-c cc] [-f makefile] [flags] file ...'
exit 1
fi
if [ ! -w $MAKE ]; then
echo "mkdep: no writeable file \"$MAKE\""
exit 1
fi
TMP=/tmp/mkdep$$
trap 'rm -f $TMP ; exit 1' 1 2 3 13 15
cp $MAKE ${MAKE}.bak
sed -e '/DO NOT DELETE THIS LINE/,$d' < $MAKE > $TMP
cat << _EOF_ >> $TMP
# DO NOT DELETE THIS LINE -- mkdep uses it.
# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
_EOF_
# If your compiler doesn't have -M, add it. If you can't, the next two
# lines will try and replace the "cc -M". The real problem is that this
# hack can't deal with anything that requires a search path, and doesn't
# even try for anything using bracket (<>) syntax.
#
# egrep '^#include[ ]*".*"' /dev/null $* |
# sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' |
# XXX this doesn't work with things like "-DDECLWAITSTATUS=union\ wait"
$CC -M $* |
sed "
s; \./; ;g
$SED" |
awk '{
if ($1 != prev) {
if (rec != "")
print rec;
rec = $0;
prev = $1;
}
else {
if (length(rec $2) > 78) {
print rec;
rec = $0;
}
else
rec = rec " " $2
}
}
END {
print rec
}' >> $TMP
cat << _EOF_ >> $TMP
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
_EOF_
# copy to preserve permissions
cp $TMP $MAKE
rm -f ${MAKE}.bak $TMP
exit 0

View File

@ -0,0 +1,73 @@
/* A sample version of rip_output() from /sys/netinet/raw_ip.c */
rip_output(m, so)
register struct mbuf *m;
struct socket *so;
{
register struct ip *ip;
int error;
struct rawcb *rp = sotorawcb(so);
struct sockaddr_in *sin;
#if BSD>=43
short proto = rp->rcb_proto.sp_protocol;
#else
short proto = so->so_proto->pr_protocol;
#endif
/*
* if the protocol is IPPROTO_RAW, the user handed us a
* complete IP packet. Otherwise, allocate an mbuf for a
* header and fill it in as needed.
*/
if (proto != IPPROTO_RAW) {
/*
* Calculate data length and get an mbuf
* for IP header.
*/
int len = 0;
struct mbuf *m0;
for (m0 = m; m; m = m->m_next)
len += m->m_len;
m = m_get(M_DONTWAIT, MT_HEADER);
if (m == 0) {
m = m0;
error = ENOBUFS;
goto bad;
}
m->m_off = MMAXOFF - sizeof(struct ip);
m->m_len = sizeof(struct ip);
m->m_next = m0;
ip = mtod(m, struct ip *);
ip->ip_tos = 0;
ip->ip_off = 0;
ip->ip_p = proto;
ip->ip_len = sizeof(struct ip) + len;
ip->ip_ttl = MAXTTL;
} else
ip = mtod(m, struct ip *);
if (rp->rcb_flags & RAW_LADDR) {
sin = (struct sockaddr_in *)&rp->rcb_laddr;
if (sin->sin_family != AF_INET) {
error = EAFNOSUPPORT;
goto bad;
}
ip->ip_src.s_addr = sin->sin_addr.s_addr;
} else
ip->ip_src.s_addr = 0;
ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr;
#if BSD>=43
return (ip_output(m, rp->rcb_options, &rp->rcb_route,
(so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
#else
return (ip_output(m, (struct mbuf *)0, &rp->rcb_route,
(so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST));
#endif
bad:
m_freem(m);
return (error);
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
char *
strerror(num)
int num;
{
extern int sys_nerr;
extern char *sys_errlist[];
#define UPREFIX "Unknown error: "
static char ebuf[40] = UPREFIX; /* 64-bit number + slop */
register unsigned int errnum;
register char *p, *t;
char tmp[40];
errnum = num; /* convert to unsigned */
if (errnum < sys_nerr)
return(sys_errlist[errnum]);
/* Do this by hand, so we don't include stdio(3). */
t = tmp;
do {
*t++ = "0123456789"[errnum % 10];
} while (errnum /= 10);
for (p = ebuf + sizeof(UPREFIX) - 1;;) {
*p++ = *--t;
if (t <= tmp)
break;
}
return(ebuf);
}

View File

@ -0,0 +1,298 @@
.\" Copyright (c) 1989, 1995, 1996
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms are permitted
.\" provided that the above copyright notice and this paragraph are
.\" duplicated in all such forms and that any documentation,
.\" advertising materials, and other materials related to such
.\" distribution and use acknowledge that the software was developed
.\" by the University of California, Berkeley. The name of the
.\" University may not be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.\" $Header: traceroute.8,v 1.7 96/09/27 20:02:41 leres Exp $
.\"
.TH TRACEROUTE 8 "27 September 1996"
.UC 6
.SH NAME
traceroute \- print the route packets take to network host
.SH SYNOPSIS
.. while ((op = getopt(argc, argv, "dnrvg:m:p:q:s:t:w:")) != EOF)
.na
.B traceroute
[
.B \-dnrv
] [
.B \-g
.I gw_host
] [
.B \-m
max_ttl
.I ]
.br
.ti +8
[
.B \-p
.I port
] [
.B \-q
.I nqueries
] [
.B \-s
.I src_addr
]
.br
.ti +8
[
.B \-t
.I tos
] [
.B \-w
.I waittime
]
.I host
[
.I packetlen
]
.ad
.SH DESCRIPTION
The Internet is a large and complex aggregation of
network hardware, connected together by gateways.
Tracking the route one's packets follow (or finding the miscreant
gateway that's discarding your packets) can be difficult.
.I Traceroute
utilizes the IP protocol `time to live' field and attempts to elicit an
ICMP TIME_EXCEEDED response from each gateway along the path to some
host.
.PP
The only mandatory parameter is the destination host name or IP number.
The default probe datagram length is 40 bytes, but this may be increased
by specifying a packet length (in bytes) after the destination host
name.
.PP
Other options are:
.TP
.B \-g
Specify a loose source route gateway (8 maximum).
.TP
.B \-m
Set the max time-to-live (max number of hops) used in outgoing probe
packets. The default is 30 hops (the same default used for TCP
connections).
.TP
.B \-n
Print hop addresses numerically rather than symbolically and numerically
(saves a nameserver address-to-name lookup for each gateway found on the
path).
.TP
.B \-p
Set the base UDP port number used in probes (default is 33434).
Traceroute hopes that nothing is listening on UDP ports
.I base
to
.I base + nhops - 1
at the destination host (so an ICMP PORT_UNREACHABLE message will
be returned to terminate the route tracing). If something is
listening on a port in the default range, this option can be used
to pick an unused port range.
.TP
.B \-r
Bypass the normal routing tables and send directly to a host on an attached
network.
If the host is not on a directly-attached network,
an error is returned.
This option can be used to ping a local host through an interface
that has no route through it (e.g., after the interface was dropped by
.IR routed (8C)).
.TP
.B \-s
Use the following IP address (which must be given as an IP number, not
a hostname) as the source address in outgoing probe packets. On
hosts with more than one IP address, this option can be used to
force the source address to be something other than the IP address
of the interface the probe packet is sent on. If the IP address
is not one of this machine's interface addresses, an error is
returned and nothing is sent.
.TP
.B \-t
Set the
.I type-of-service
in probe packets to the following value (default zero). The value must be
a decimal integer in the range 0 to 255. This option can be used to
see if different types-of-service result in different paths. (If you
are not running 4.4bsd, this may be academic since the normal network
services like telnet and ftp don't let you control the TOS).
Not all values of TOS are legal or
meaningful \- see the IP spec for definitions. Useful values are
probably `-t 16' (low delay) and `-t 8' (high throughput).
.TP
.B \-v
Verbose output. Received ICMP packets other than TIME_EXCEEDED and
UNREACHABLEs are listed.
.TP
.B \-w
Set the time (in seconds) to wait for a response to a probe (default 5
sec.).
.PP
This program attempts to trace the route an IP packet would follow to some
internet host by launching UDP probe
packets with a small ttl (time to live) then listening for an
ICMP "time exceeded" reply from a gateway. We start our probes
with a ttl of one and increase by one until we get an ICMP "port
unreachable" (which means we got to "host") or hit a max (which
defaults to 30 hops & can be changed with the \-m flag). Three
probes (change with \-q flag) are sent at each ttl setting and a
line is printed showing the ttl, address of the gateway and
round trip time of each probe. If the probe answers come from
different gateways, the address of each responding system will
be printed. If there is no response within a 5 sec. timeout
interval (changed with the \-w flag), a "*" is printed for that
probe.
.PP
We don't want the destination
host to process the UDP probe packets so the destination port is set to an
unlikely value (if some clod on the destination is using that
value, it can be changed with the \-p flag).
.PP
A sample use and output might be:
.RS
.nf
[yak 71]% traceroute nis.nsf.net.
traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 38 byte packet
1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms
2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39 ms
5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 39 ms 39 ms 39 ms
6 128.32.197.4 (128.32.197.4) 40 ms 59 ms 59 ms
7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 59 ms
8 129.140.70.13 (129.140.70.13) 99 ms 99 ms 80 ms
9 129.140.71.6 (129.140.71.6) 139 ms 239 ms 319 ms
10 129.140.81.7 (129.140.81.7) 220 ms 199 ms 199 ms
11 nic.merit.edu (35.1.1.48) 239 ms 239 ms 239 ms
.fi
.RE
Note that lines 2 & 3 are the same. This is due to a buggy
kernel on the 2nd hop system \- lbl-csam.arpa \- that forwards
packets with a zero ttl (a bug in the distributed version
of 4.3BSD). Note that you have to guess what path
the packets are taking cross-country since the NSFNet (129.140)
doesn't supply address-to-name translations for its NSSes.
.PP
A more interesting example is:
.RS
.nf
[yak 72]% traceroute allspice.lcs.mit.edu.
traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
2 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 19 ms 19 ms
3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 19 ms
4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 19 ms 39 ms 39 ms
5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 20 ms 39 ms 39 ms
6 128.32.197.4 (128.32.197.4) 59 ms 119 ms 39 ms
7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 39 ms
8 129.140.70.13 (129.140.70.13) 80 ms 79 ms 99 ms
9 129.140.71.6 (129.140.71.6) 139 ms 139 ms 159 ms
10 129.140.81.7 (129.140.81.7) 199 ms 180 ms 300 ms
11 129.140.72.17 (129.140.72.17) 300 ms 239 ms 239 ms
12 * * *
13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms
14 * * *
15 * * *
16 * * *
17 * * *
18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms
.fi
.RE
Note that the gateways 12, 14, 15, 16 & 17 hops away
either don't send ICMP "time exceeded" messages or send them
with a ttl too small to reach us. 14 \- 17 are running the
MIT C Gateway code that doesn't send "time exceeded"s. God
only knows what's going on with 12.
.PP
The silent gateway 12 in the above may be the result of a bug in
the 4.[23]BSD network code (and its derivatives): 4.x (x <= 3)
sends an unreachable message using whatever ttl remains in the
original datagram. Since, for gateways, the remaining ttl is
zero, the ICMP "time exceeded" is guaranteed to not make it back
to us. The behavior of this bug is slightly more interesting
when it appears on the destination system:
.RS
.nf
1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 39 ms
3 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 39 ms 19 ms
4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 19 ms
5 ccn-nerif35.Berkeley.EDU (128.32.168.35) 39 ms 39 ms 39 ms
6 csgw.Berkeley.EDU (128.32.133.254) 39 ms 59 ms 39 ms
7 * * *
8 * * *
9 * * *
10 * * *
11 * * *
12 * * *
13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms !
.fi
.RE
Notice that there are 12 "gateways" (13 is the final
destination) and exactly the last half of them are "missing".
What's really happening is that rip (a Sun-3 running Sun OS3.5)
is using the ttl from our arriving datagram as the ttl in its
ICMP reply. So, the reply will time out on the return path
(with no notice sent to anyone since ICMP's aren't sent for
ICMP's) until we probe with a ttl that's at least twice the path
length. I.e., rip is really only 7 hops away. A reply that
returns with a ttl of 1 is a clue this problem exists.
Traceroute prints a "!" after the time if the ttl is <= 1.
Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
non-standard (HPUX) software, expect to see this problem
frequently and/or take care picking the target host of your
probes.
Other possible annotations after the time are
.BR !H ,
.BR !N ,
or
.B !P
(got a host, network or protocol unreachable, respectively),
.B !S
or
.B !F
(source route failed or fragmentation needed \- neither of these should
ever occur and the associated gateway is busted if you see one),
.B !X
(communication administratively prohibited), or
.B !<N>
(ICMP unreachable code N).
If almost all the probes result in some kind of unreachable, traceroute
will give up and exit.
.PP
This program is intended for use in network testing, measurement
and management.
It should be used primarily for manual fault isolation.
Because of the load it could impose on the network, it is unwise to use
.I traceroute
during normal operations or from automated scripts.
.SH SEE ALSO
netstat(1), ping(8)
.SH AUTHOR
Implemented by Van Jacobson from a suggestion by Steve Deering. Debugged
by a cast of thousands with particularly cogent suggestions or fixes from
C. Philip Wood, Tim Seaver and Ken Adelman.
.LP
The current version is available via anonymous ftp:
.LP
.RS
.I ftp://ftp.ee.lbl.gov/traceroute.tar.Z
.RE
.SH BUGS
Please send bug reports to traceroute@ee.lbl.gov.

View File

@ -0,0 +1,977 @@
/*
* Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996\n\
The Regents of the University of California. All rights reserved.\n";
static const char rcsid[] =
"@(#)$Header: traceroute.c,v 1.43 96/09/27 20:08:10 leres Exp $ (LBL)";
#endif
/*
* traceroute host - trace the route ip packets follow going to "host".
*
* Attempt to trace the route an ip packet would follow to some
* internet host. We find out intermediate hops by launching probe
* packets with a small ttl (time to live) then listening for an
* icmp "time exceeded" reply from a gateway. We start our probes
* with a ttl of one and increase by one until we get an icmp "port
* unreachable" (which means we got to "host") or hit a max (which
* defaults to 30 hops & can be changed with the -m flag). Three
* probes (change with -q flag) are sent at each ttl setting and a
* line is printed showing the ttl, address of the gateway and
* round trip time of each probe. If the probe answers come from
* different gateways, the address of each responding system will
* be printed. If there is no response within a 5 sec. timeout
* interval (changed with the -w flag), a "*" is printed for that
* probe.
*
* Probe packets are UDP format. We don't want the destination
* host to process them so the destination port is set to an
* unlikely value (if some clod on the destination is using that
* value, it can be changed with the -p flag).
*
* A sample use might be:
*
* [yak 71]% traceroute nis.nsf.net.
* traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
* 1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms
* 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
* 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
* 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39 ms
* 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 39 ms 39 ms 39 ms
* 6 128.32.197.4 (128.32.197.4) 40 ms 59 ms 59 ms
* 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 59 ms
* 8 129.140.70.13 (129.140.70.13) 99 ms 99 ms 80 ms
* 9 129.140.71.6 (129.140.71.6) 139 ms 239 ms 319 ms
* 10 129.140.81.7 (129.140.81.7) 220 ms 199 ms 199 ms
* 11 nic.merit.edu (35.1.1.48) 239 ms 239 ms 239 ms
*
* Note that lines 2 & 3 are the same. This is due to a buggy
* kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
* packets with a zero ttl.
*
* A more interesting example is:
*
* [yak 72]% traceroute allspice.lcs.mit.edu.
* traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
* 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
* 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 19 ms 19 ms
* 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 19 ms
* 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 19 ms 39 ms 39 ms
* 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 20 ms 39 ms 39 ms
* 6 128.32.197.4 (128.32.197.4) 59 ms 119 ms 39 ms
* 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 39 ms
* 8 129.140.70.13 (129.140.70.13) 80 ms 79 ms 99 ms
* 9 129.140.71.6 (129.140.71.6) 139 ms 139 ms 159 ms
* 10 129.140.81.7 (129.140.81.7) 199 ms 180 ms 300 ms
* 11 129.140.72.17 (129.140.72.17) 300 ms 239 ms 239 ms
* 12 * * *
* 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms
* 14 * * *
* 15 * * *
* 16 * * *
* 17 * * *
* 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms
*
* (I start to see why I'm having so much trouble with mail to
* MIT.) Note that the gateways 12, 14, 15, 16 & 17 hops away
* either don't send ICMP "time exceeded" messages or send them
* with a ttl too small to reach us. 14 - 17 are running the
* MIT C Gateway code that doesn't send "time exceeded"s. God
* only knows what's going on with 12.
*
* The silent gateway 12 in the above may be the result of a bug in
* the 4.[23]BSD network code (and its derivatives): 4.x (x <= 3)
* sends an unreachable message using whatever ttl remains in the
* original datagram. Since, for gateways, the remaining ttl is
* zero, the icmp "time exceeded" is guaranteed to not make it back
* to us. The behavior of this bug is slightly more interesting
* when it appears on the destination system:
*
* 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
* 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 39 ms
* 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 39 ms 19 ms
* 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 19 ms
* 5 ccn-nerif35.Berkeley.EDU (128.32.168.35) 39 ms 39 ms 39 ms
* 6 csgw.Berkeley.EDU (128.32.133.254) 39 ms 59 ms 39 ms
* 7 * * *
* 8 * * *
* 9 * * *
* 10 * * *
* 11 * * *
* 12 * * *
* 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms !
*
* Notice that there are 12 "gateways" (13 is the final
* destination) and exactly the last half of them are "missing".
* What's really happening is that rip (a Sun-3 running Sun OS3.5)
* is using the ttl from our arriving datagram as the ttl in its
* icmp reply. So, the reply will time out on the return path
* (with no notice sent to anyone since icmp's aren't sent for
* icmp's) until we probe with a ttl that's at least twice the path
* length. I.e., rip is really only 7 hops away. A reply that
* returns with a ttl of 1 is a clue this problem exists.
* Traceroute prints a "!" after the time if the ttl is <= 1.
* Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
* non-standard (HPUX) software, expect to see this problem
* frequently and/or take care picking the target host of your
* probes.
*
* Other possible annotations after the time are !H, !N, !P (got a host,
* network or protocol unreachable, respectively), !S or !F (source
* route failed or fragmentation needed -- neither of these should
* ever occur and the associated gateway is busted if you see one). If
* almost all the probes result in some kind of unreachable, traceroute
* will give up and exit.
*
* Notes
* -----
* This program must be run by root or be setuid. (I suggest that
* you *don't* make it setuid -- casual use could result in a lot
* of unnecessary traffic on our poor, congested nets.)
*
* This program requires a kernel mod that does not appear in any
* system available from Berkeley: A raw ip socket using proto
* IPPROTO_RAW must interpret the data sent as an ip datagram (as
* opposed to data to be wrapped in a ip datagram). See the README
* file that came with the source to this program for a description
* of the mods I made to /sys/netinet/raw_ip.c. Your mileage may
* vary. But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
* MODIFIED TO RUN THIS PROGRAM.
*
* The udp port usage may appear bizarre (well, ok, it is bizarre).
* The problem is that an icmp message only contains 8 bytes of
* data from the original datagram. 8 bytes is the size of a udp
* header so, if we want to associate replies with the original
* datagram, the necessary information must be encoded into the
* udp header (the ip id could be used but there's no way to
* interlock with the kernel's assignment of ip id's and, anyway,
* it would have taken a lot more kernel hacking to allow this
* code to set the ip id). So, to allow two or more users to
* use traceroute simultaneously, we use this task's pid as the
* source port (the high bit is set to move the port number out
* of the "likely" range). To keep track of which probe is being
* replied to (so times and/or hop counts don't get confused by a
* reply that was delayed in transit), we increment the destination
* port number before each probe.
*
* Don't use this as a coding example. I was trying to find a
* routing problem and this code sort-of popped out after 48 hours
* without sleep. I was amazed it ever compiled, much less ran.
*
* I stole the idea for this program from Steve Deering. Since
* the first release, I've learned that had I attended the right
* IETF working group meetings, I also could have stolen it from Guy
* Almes or Matt Mathis. I don't know (or care) who came up with
* the idea first. I envy the originators' perspicacity and I'm
* glad they didn't keep the idea a secret.
*
* Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
* enhancements to the original distribution.
*
* I've hacked up a round-trip-route version of this that works by
* sending a loose-source-routed udp datagram through the destination
* back to yourself. Unfortunately, SO many gateways botch source
* routing, the thing is almost worthless. Maybe one day...
*
* -- Van Jacobson (van@ee.lbl.gov)
* Tue Dec 20 03:50:13 PST 1988
*/
#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#include <memory.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/* Maximum number of gateways (include room for one noop) */
#define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
#define Fprintf (void)fprintf
#define Printf (void)printf
/* Data section of the probe packet */
struct outdata {
u_char seq; /* sequence number of this packet */
u_char ttl; /* ttl packet left with */
struct timeval tv; /* time packet left */
};
u_char packet[512]; /* last inbound (icmp) packet */
struct ip *outip; /* last output (udp) packet */
struct udphdr *outudp; /* last output (udp) packet */
struct outdata *outdata; /* last output (udp) packet */
/* loose source route gateway list (including room for final destination) */
u_int32_t gwlist[NGATEWAYS + 1];
int s; /* receive (icmp) socket file descriptor */
int sndsock; /* send (udp) socket file descriptor */
struct sockaddr whereto; /* Who to try to reach */
int packlen; /* total length of packet */
int maxpacket = 32 * 1024; /* max ip packet size */
char *prog;
char *source;
char *hostname;
int nprobes = 3;
int max_ttl = 30;
u_short ident;
u_short port = 32768 + 666; /* start udp dest port # for probe packets */
int options; /* socket options */
int verbose;
int waittime = 5; /* time to wait for response (in seconds) */
int nflag; /* print addresses numerically */
extern int optind;
extern int opterr;
extern char *optarg;
/* Forwards */
double deltaT(struct timeval *, struct timeval *);
char *inetname(struct in_addr);
int main(int, char **);
int packet_ok(u_char *, int, struct sockaddr_in *, int);
char *pr_type(u_char);
void print(u_char *, int, struct sockaddr_in *);
char *getaddr(u_int32_t *, char *);
char *getsin(struct sockaddr_in *, char *);
char *savestr(const char *);
void send_probe(int, int, struct timeval *);
void tvsub(struct timeval *, struct timeval *);
__dead void usage(void);
int wait_for_reply(int, struct sockaddr_in *, struct timeval *);
int
main(int argc, char **argv)
{
register int op, code;
register char *cp;
struct sockaddr_in from;
register struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
int on = 1;
register struct protoent *pe;
register int ttl, probe, i;
register int seq = 0;
register int tos = 0;
register int lsrr = 0;
register int optlen = 0;
if ((cp = strrchr(argv[0], '/')) != NULL)
prog = cp + 1;
else
prog = argv[0];
opterr = 0;
while ((op = getopt(argc, argv, "dnrvg:m:p:q:s:t:w:")) != EOF)
switch (op) {
case 'd':
options |= SO_DEBUG;
break;
case 'g':
if (lsrr >= NGATEWAYS) {
Fprintf(stderr,
"%s: No more than %d gateways\n",
prog, NGATEWAYS);
exit(1);
}
(void)getaddr(gwlist + lsrr, optarg);
++lsrr;
break;
case 'm':
max_ttl = atoi(optarg);
if (max_ttl <= 1) {
Fprintf(stderr, "%s: max ttl must be > 1\n",
prog);
exit(1);
}
break;
case 'n':
++nflag;
break;
case 'p':
port = atoi(optarg);
if (port <= 0) {
Fprintf(stderr, "%s: port must be > 0\n", prog);
exit(1);
}
break;
case 'q':
nprobes = atoi(optarg);
if (nprobes <= 0) {
Fprintf(stderr, "%s: nprobes must be > 0\n",
prog);
exit(1);
}
break;
case 'r':
options |= SO_DONTROUTE;
break;
case 's':
/*
* set the ip source address of the outbound
* probe (e.g., on a multi-homed host).
*/
source = optarg;
break;
case 't':
tos = atoi(optarg);
if (tos < 0 || tos > 255) {
Fprintf(stderr, "%s: tos must be 0 to 255\n",
prog);
exit(1);
}
break;
case 'v':
++verbose;
break;
case 'w':
waittime = atoi(optarg);
if (waittime <= 1) {
Fprintf(stderr, "%s: wait must be > 1 sec\n",
prog);
exit(1);
}
break;
default:
usage();
}
/* Process destination and optional packet size */
switch (argc - optind) {
case 2:
packlen = atoi(argv[optind + 1]);
/* Fall thorugh */
case 1:
hostname = savestr(getsin(to, argv[optind]));
break;
default:
usage();
}
#ifdef HAVE_SETLINEBUF
setlinebuf (stdout);
#else
setvbuf(stdout, NULL, _IOLBF, 0);
#endif
if (lsrr > 0)
optlen = (lsrr + 1) * sizeof(gwlist[0]);
i = sizeof(*outip) + sizeof(*outudp) + sizeof(*outdata) + optlen;
if (packlen == 0)
packlen = i; /* minimum sized packet */
else if (i > packlen || packlen > maxpacket) {
Fprintf(stderr, "%s: packet size must be %d <= s <= %d\n",
prog, i, maxpacket);
exit(1);
}
outip = (struct ip *)malloc((unsigned)packlen);
if (outip == NULL) {
Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
exit(1);
}
memset((char *)outip, 0, packlen);
outip->ip_v = IPVERSION;
outip->ip_tos = tos;
#ifdef BYTESWAP_IP_LEN
outip->ip_len = htons(packlen);
#else
outip->ip_len = packlen;
#endif
outip->ip_p = IPPROTO_UDP;
outudp = (struct udphdr *)(outip + 1);
#ifdef HAVE_RAW_OPTIONS
if (lsrr > 0) {
register u_char *optlist;
optlist = (u_char *)outudp;
(u_char *)outudp += optlen;
/* final hop */
gwlist[lsrr] = to->sin_addr.s_addr;
outip->ip_dst.s_addr = gwlist[0];
/* force 4 byte alignment */
optlist[0] = IPOPT_NOP;
/* loose source route option */
optlist[1] = IPOPT_LSRR;
i = lsrr * sizeof(gwlist[0]);
optlist[2] = i + 3;
/* Pointer to LSRR addresses */
optlist[3] = IPOPT_MINOFF;
memcpy(optlist + 4, gwlist + 1, i);
} else
#endif
outip->ip_dst = to->sin_addr;
outip->ip_hl = ((u_char *)outudp - (u_char *)outip) >> 2;
ident = (getpid() & 0xffff) | 0x8000;
outudp->uh_sport = htons(ident);
outudp->uh_ulen = htons((u_short)(packlen - (sizeof(*outip) + optlen)));
outdata = (struct outdata *)(outudp + 1);
cp = "icmp";
if ((pe = getprotobyname(cp)) == NULL) {
Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
exit(1);
}
if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0) {
Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
exit(1);
}
if (options & SO_DEBUG)
(void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
sizeof(on));
if (options & SO_DONTROUTE)
(void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
sizeof(on));
if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
exit(1);
}
/* Revert to non-privileged user after opening sockets */
setuid(getuid());
#if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
if (lsrr > 0) {
u_char optlist[MAX_IPOPTLEN];
cp = "ip";
if ((pe = getprotobyname(cp)) == NULL) {
Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
exit(1);
}
/* final hop */
gwlist[lsrr] = to->sin_addr.s_addr;
++lsrr;
/* force 4 byte alignment */
optlist[0] = IPOPT_NOP;
/* loose source route option */
optlist[1] = IPOPT_LSRR;
i = lsrr * sizeof(gwlist[0]);
optlist[2] = i + 3;
/* Pointer to LSRR addresses */
optlist[3] = IPOPT_MINOFF;
memcpy(optlist + 4, gwlist, i);
if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS, optlist,
i + sizeof(gwlist[0]))) < 0) {
Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
prog, strerror(errno));
exit(1);
}
}
#endif
#ifdef SO_SNDBUF
if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
sizeof(packlen)) < 0) {
Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
exit(1);
}
#endif
#ifdef IP_HDRINCL
if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
sizeof(on)) < 0) {
Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
exit(1);
}
#endif
if (options & SO_DEBUG)
(void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
sizeof(on));
if (options & SO_DONTROUTE)
(void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
sizeof(on));
if (source != NULL) {
source = savestr(getsin(&from, source));
outip->ip_src = from.sin_addr;
#ifndef IP_HDRINCL
if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0) {
Fprintf(stderr, "%s: bind: %s\n",
prog, strerror(errno));
exit (1);
}
#endif
}
Fprintf(stderr, "%s to %s (%s)",
prog, hostname, inet_ntoa(to->sin_addr));
if (source)
Fprintf(stderr, " from %s", source);
Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
(void)fflush(stderr);
for (ttl = 1; ttl <= max_ttl; ++ttl) {
u_int32_t lastaddr = 0;
int got_there = 0;
int unreachable = 0;
Printf("%2d ", ttl);
for (probe = 0; probe < nprobes; ++probe) {
register int cc;
struct timeval t1, t2;
struct timezone tz;
register struct ip *ip;
(void)gettimeofday(&t1, &tz);
send_probe(++seq, ttl, &t1);
while ((cc = wait_for_reply(s, &from, &t1)) != 0) {
(void)gettimeofday(&t2, &tz);
i = packet_ok(packet, cc, &from, seq);
/* Skip short packet */
if (i == 0)
continue;
if (from.sin_addr.s_addr != lastaddr) {
print(packet, cc, &from);
lastaddr = from.sin_addr.s_addr;
}
Printf(" %.3f ms", deltaT(&t1, &t2));
/* time exceeded in transit */
if (i == -1)
break;
code = i - 1;
switch (code) {
case ICMP_UNREACH_PORT:
#ifndef ARCHAIC
ip = (struct ip *)packet;
if (ip->ip_ttl <= 1)
Printf(" !");
#endif
++got_there;
break;
case ICMP_UNREACH_NET:
++unreachable;
Printf(" !N");
break;
case ICMP_UNREACH_HOST:
++unreachable;
Printf(" !H");
break;
case ICMP_UNREACH_PROTOCOL:
++got_there;
Printf(" !P");
break;
case ICMP_UNREACH_NEEDFRAG:
++unreachable;
Printf(" !F");
break;
case ICMP_UNREACH_SRCFAIL:
++unreachable;
Printf(" !S");
break;
/* rfc1716 */
#ifndef ICMP_UNREACH_FILTER_PROHIB
#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */
#endif
case ICMP_UNREACH_FILTER_PROHIB:
++unreachable;
Printf(" !X");
break;
default:
++unreachable;
Printf(" !<%d>", code);
break;
}
break;
}
if (cc == 0)
Printf(" *");
(void)fflush(stdout);
}
putchar('\n');
if (got_there ||
(unreachable > 0 && unreachable >= nprobes - 1))
break;
}
exit(0);
}
int
wait_for_reply(register int sock, register struct sockaddr_in *fromp,
register struct timeval *tp)
{
fd_set fds;
struct timeval now, wait;
struct timezone tz;
register int cc = 0;
int fromlen = sizeof(*fromp);
FD_ZERO(&fds);
FD_SET(sock, &fds);
wait.tv_sec = tp->tv_sec + waittime;
wait.tv_usec = tp->tv_usec;
(void)gettimeofday(&now, &tz);
tvsub(&wait, &now);
if (select(sock + 1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0)
cc = recvfrom(s, (char *)packet, sizeof(packet), 0,
(struct sockaddr *)fromp, &fromlen);
return(cc);
}
void
send_probe(register int seq, register int ttl, register struct timeval *tp)
{
register int i;
outip->ip_ttl = ttl;
outip->ip_id = htons(ident + seq);
outudp->uh_dport = htons(port + seq);
outdata->seq = seq;
outdata->ttl = ttl;
outdata->tv = *tp;
i = sendto(sndsock, (char *)outip, packlen, 0, &whereto,
sizeof(whereto));
if (i < 0 || i != packlen) {
if (i < 0)
Fprintf(stderr, "%s: sendto: %s\n",
prog, strerror(errno));
Printf("%s: wrote %s %d chars, ret=%d\n",
prog, hostname, packlen, i);
(void)fflush(stdout);
}
}
double
deltaT(struct timeval *t1p, struct timeval *t2p)
{
register double dt;
dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
(double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
return (dt);
}
/*
* Convert an ICMP "type" field to a printable string.
*/
char *
pr_type(register u_char t)
{
static char *ttab[] = {
"Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
"Source Quench", "Redirect", "ICMP 6", "ICMP 7",
"Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
"Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
"Info Reply"
};
if (t > 16)
return("OUT-OF-RANGE");
return(ttab[t]);
}
int
packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
register int seq)
{
register struct icmp *icp;
register u_char type, code;
register int hlen;
#ifndef ARCHAIC
register struct ip *ip;
ip = (struct ip *) buf;
hlen = ip->ip_hl << 2;
if (cc < hlen + ICMP_MINLEN) {
if (verbose)
Printf("packet too short (%d bytes) from %s\n", cc,
inet_ntoa(from->sin_addr));
return (0);
}
cc -= hlen;
icp = (struct icmp *)(buf + hlen);
#else
icp = (struct icmp *)buf;
#endif
type = icp->icmp_type;
code = icp->icmp_code;
if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
type == ICMP_UNREACH) {
struct ip *hip;
struct udphdr *up;
hip = &icp->icmp_ip;
hlen = hip->ip_hl << 2;
up = (struct udphdr *)((u_char *)hip + hlen);
if (hlen + 12 <= cc && hip->ip_p == IPPROTO_UDP &&
up->uh_sport == htons(ident) &&
up->uh_dport == htons(port + seq))
return (type == ICMP_TIMXCEED ? -1 : code + 1);
}
#ifndef ARCHAIC
if (verbose) {
register int i;
u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
Printf("%s: icmp type %d (%s) code %d\n",
inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
for (i = 4; i < cc ; i += sizeof(*lp))
Printf("%2d: x%8.8x\n", i, *lp++);
}
#endif
return(0);
}
void
print(register u_char *buf, register int cc, register struct sockaddr_in *from)
{
register struct ip *ip;
register int hlen;
ip = (struct ip *) buf;
hlen = ip->ip_hl << 2;
cc -= hlen;
if (nflag)
Printf(" %s", inet_ntoa(from->sin_addr));
else
Printf(" %s (%s)", inetname(from->sin_addr),
inet_ntoa(from->sin_addr));
if (verbose)
Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
}
#ifdef notyet
/*
* Checksum routine for Internet Protocol family headers (C Version)
*/
in_cksum(register u_short *addr, register int len)
{
register int nleft = len;
register u_short *w = addr;
register u_short answer;
register int sum = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum),
* we add sequential 16 bit words to it, and at the end, fold
* back all the carry bits from the top 16 bits into the lower
* 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1)
sum += *(u_char *)w;
/*
* add back carry outs from top 16 bits to low 16 bits
*/
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}
#endif
/*
* Subtract 2 timeval structs: out = out - in.
* Out is assumed to be >= in.
*/
void
tvsub(register struct timeval *out, register struct timeval *in)
{
if ((out->tv_usec -= in->tv_usec) < 0) {
--out->tv_sec;
out->tv_usec += 1000000;
}
out->tv_sec -= in->tv_sec;
}
/*
* Construct an Internet address representation.
* If the nflag has been supplied, give
* numeric value, otherwise try for symbolic name.
*/
char *
inetname(struct in_addr in)
{
register char *cp;
register struct hostent *hp;
static int first = 1;
static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
if (first && !nflag) {
first = 0;
if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
(cp = strchr(domain, '.')) != NULL) {
(void)strncpy(domain, cp + 1, sizeof(domain) - 1);
domain[sizeof(domain) - 1] = '\0';
} else
domain[0] = '\0';
}
if (!nflag && in.s_addr != INADDR_ANY) {
hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
if (hp != NULL) {
if ((cp = strchr(hp->h_name, '.')) != NULL &&
strcmp(cp + 1, domain) == 0)
*cp = '\0';
(void)strncpy(line, hp->h_name, sizeof(line) - 1);
line[sizeof(line) - 1] = '\0';
return (line);
}
}
return (inet_ntoa(in));
}
char *
getaddr(register u_int32_t *ap, register char *hostname)
{
register struct hostent *hp;
*ap = inet_addr(hostname);
if ((int32_t)*ap != -1)
return (hostname);
hp = gethostbyname(hostname);
if (hp == NULL) {
Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
exit(1);
}
if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
exit(1);
}
memcpy((caddr_t)ap, hp->h_addr, hp->h_length);
return (hp->h_name);
}
char *
getsin(register struct sockaddr_in *sin, register char *hostname)
{
memset(sin, 0, sizeof(*sin));
sin->sin_family = AF_INET;
return (getaddr((u_int32_t *)&sin->sin_addr.s_addr, hostname));
}
char *
savestr(register const char *str)
{
register char *cp;
cp = strdup(str);
if (cp == NULL) {
Fprintf(stderr, "%s: strdup: %s\n", prog, strerror(errno));
exit(1);
}
return (cp);
}
__dead void
usage(void)
{
extern char version[];
Fprintf(stderr, "Version %s\n", version);
Fprintf(stderr, "Usage: %s [-dnrv] [-w wait] [-m max_ttl] [-p port#] \
[-q nqueries]\n\t [-t tos] [-s src_addr] [-g gateway] host [data_size]\n",
prog);
exit(1);
}