├── .gitignore ├── VERSION ├── Application.mk ├── libs ├── x86 │ └── traceroute ├── x86_64 │ └── traceroute ├── armeabi │ └── traceroute ├── arm64-v8a │ └── traceroute └── armeabi-v7a │ └── traceroute ├── include └── version.h ├── wrappers ├── Makefile ├── README.wrappers ├── tcptraceroute.8 ├── tracepath ├── tcptraceroute ├── traceroute-nanog ├── lft └── traceproto ├── libsupp ├── tcp.h ├── clif.h └── icmp6.h ├── traceroute ├── time.c ├── random.c ├── module.c ├── csum.c ├── flowlabel.h ├── poll.c ├── as_lookups.c ├── extension.c ├── traceroute.h ├── mod-raw.c ├── mod-udp.c ├── mod-tcpconn.c ├── mod-icmp.c ├── mod-dccp.c ├── mod-tcp.c └── traceroute.8 ├── CREDITS ├── Android.mk ├── Make.defines ├── TODO ├── traceroute.spec ├── README ├── store.sh ├── Makefile ├── chvers.sh ├── default.rules ├── Make.rules ├── readme.md ├── ChangeLog ├── COPYING └── COPYING.LIB /.gitignore: -------------------------------------------------------------------------------- 1 | obj -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | #define VERSION 2.1.0 2 | -------------------------------------------------------------------------------- /Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64 2 | APP_PLATFORM := android-14 3 | -------------------------------------------------------------------------------- /libs/x86/traceroute: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjing53406/traceroute-android-executable/HEAD/libs/x86/traceroute -------------------------------------------------------------------------------- /libs/x86_64/traceroute: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjing53406/traceroute-android-executable/HEAD/libs/x86_64/traceroute -------------------------------------------------------------------------------- /libs/armeabi/traceroute: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjing53406/traceroute-android-executable/HEAD/libs/armeabi/traceroute -------------------------------------------------------------------------------- /libs/arm64-v8a/traceroute: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjing53406/traceroute-android-executable/HEAD/libs/arm64-v8a/traceroute -------------------------------------------------------------------------------- /libs/armeabi-v7a/traceroute: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjing53406/traceroute-android-executable/HEAD/libs/armeabi-v7a/traceroute -------------------------------------------------------------------------------- /include/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include "../VERSION" 10 | -------------------------------------------------------------------------------- /wrappers/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2007 Dmitry Butskoy 3 | # 4 | # License: GPL v2 or any later 5 | # 6 | # See COPYING for the status of this software. 7 | # 8 | 9 | # 10 | # Nothing to do. 11 | # 12 | 13 | all depend install: 14 | @true 15 | 16 | -------------------------------------------------------------------------------- /libsupp/tcp.h: -------------------------------------------------------------------------------- 1 | //copy from netinet/tcp.h 2 | 3 | #define TCPOPT_EOL 0 4 | #define TCPOPT_NOP 1 5 | #define TCPOPT_MAXSEG 2 6 | #define TCPOLEN_MAXSEG 4 7 | #define TCPOPT_WINDOW 3 8 | #define TCPOLEN_WINDOW 3 9 | #define TCPOPT_SACK_PERMITTED 4 /* Experimental */ 10 | #define TCPOLEN_SACK_PERMITTED 2 11 | #define TCPOPT_SACK 5 /* Experimental */ 12 | #define TCPOPT_TIMESTAMP 8 13 | #define TCPOLEN_TIMESTAMP 10 14 | -------------------------------------------------------------------------------- /traceroute/time.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "traceroute.h" 14 | 15 | 16 | /* Just returns current time as double, with most possible precision... */ 17 | 18 | double get_time (void) { 19 | struct timeval tv; 20 | double d; 21 | 22 | gettimeofday (&tv, NULL); 23 | 24 | d = ((double) tv.tv_usec) / 1000000. + (unsigned long) tv.tv_sec; 25 | 26 | return d; 27 | } 28 | -------------------------------------------------------------------------------- /traceroute/random.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "traceroute.h" 14 | 15 | 16 | static void __init_random_seq (void) __attribute__ ((constructor)); 17 | static void __init_random_seq (void) { 18 | 19 | srand (times (NULL) + getpid ()); 20 | } 21 | 22 | 23 | unsigned int random_seq (void) { 24 | 25 | /* To not worry about RANDOM_MAX and precision... */ 26 | return (rand () << 16) ^ (rand () << 8) ^ rand () ^ (rand () >> 8); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /traceroute/module.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "traceroute.h" 14 | 15 | 16 | static tr_module *base = NULL; 17 | 18 | void tr_register_module (tr_module *ops) { 19 | 20 | ops->next = base; 21 | base = ops; 22 | } 23 | 24 | const tr_module *tr_get_module (const char *name) { 25 | const tr_module *ops; 26 | 27 | if (!name) return 0; 28 | 29 | for (ops = base; ops; ops = ops->next) { 30 | if (!strcasecmp (name, ops->name)) 31 | return ops; 32 | } 33 | 34 | return NULL; 35 | } 36 | -------------------------------------------------------------------------------- /traceroute/csum.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #include "traceroute.h" 13 | 14 | 15 | uint16_t in_csum (const void *ptr, size_t len) { 16 | const uint16_t *p = (const uint16_t *) ptr; 17 | size_t nw = len / 2; 18 | unsigned int sum = 0; 19 | uint16_t res; 20 | 21 | while (nw--) sum += *p++; 22 | 23 | if (len & 0x1) 24 | sum += htons (*((unsigned char *) p) << 8); 25 | 26 | sum = (sum >> 16) + (sum & 0xffff); 27 | sum += (sum >> 16); 28 | 29 | res = ~sum; 30 | if (!res) res = ~0; 31 | 32 | return res; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /wrappers/README.wrappers: -------------------------------------------------------------------------------- 1 | 2 | This directory contains various wrappers for traceroute, which provide 3 | some compatibility for some another traceroute-like software, 4 | including tcptraceroute(8). 5 | 6 | These wrappers try to emulate the command-line interface only. 7 | The actual output is the output of the underlain traceroute(8). 8 | 9 | Some of options and features certainly are not supported 10 | (especially if it is considered too extra :) ). 11 | 12 | The idea of such wrappers is mostly not wrappers itself. It is to inspect 13 | the features implemented by competitors, whether it is already supported by us, 14 | or it is useful to be supported, or it is not useful or excessive. 15 | 16 | We have no plans to implement all features of all existing software. 17 | Let the people a chance to play with something... ;) 18 | 19 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | Thanks for the testing, proposals, bug fixing: 2 | 3 | Robert Scheck (redhat-bugzilla@linuxnetz.de) 4 | Peter Bieringer (pb@bieringer.de) 5 | Martin Bacovsky (mbacovsk@redhat.com) 6 | Andy Shevchenko (andriy@asplinux.ru) 7 | Mike Frysinger (vapier@gentoo.org) 8 | Chris Ward (cward@redhat.com) 9 | Teran McKinney (sega01@gmail.com) 10 | Kaj Niemi (kajtzu@a51.org) 11 | Milos Malik (mmalik@redhat.com) 12 | Andreas Mohr (andim2@users.sourceforge.net) 13 | Vladz (vladz@devzero.fr) 14 | Daniel Baumann (daniel@debian.org) 15 | Filip Holec (fholec@redhat.com) 16 | Samuel Jero (sj323707@ohio.edu) 17 | Jan Synacek (jsynacek@redhat.com) 18 | Frederic Mangano (fmang@mg0.fr) 19 | Jeff (geogriffin@jsgriff.com) 20 | Andrew Schwartz (schwartz@amacapital.net) 21 | Felix Janda (felix.janda@posteo.de) 22 | Sergey Salnikov (serg@salnikov.ru) 23 | Richard Sheehan (richardsheehan@users.sourceforge.net) 24 | ... 25 | maybe you too? ;) 26 | 27 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_LDLIBS :=-llog 6 | 7 | APP_OPTIM := debug 8 | 9 | MY_C_LIST := $(wildcard $(LOCAL_PATH)/libsupp/*.c) 10 | MY_C_LIST += $(wildcard $(LOCAL_PATH)/traceroute/*.c) 11 | 12 | LOCAL_MODULE := traceroute 13 | 14 | LOCAL_SRC_FILES := $(MY_C_LIST:$(LOCAL_PATH)/%=%) 15 | 16 | ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) 17 | LOCAL_CFLAGS += -D__ARMV7__ 18 | LOCAL_ARM_MODE := arm 19 | else 20 | LOCAL_ARM_MODE := arm 21 | endif 22 | 23 | 24 | LOCAL_CFLAGS += -DHAVE_FCNTL_H \ 25 | -DHAVE_SYS_TIME_H \ 26 | -DHAVE_STRUCT_TIMEVAL \ 27 | -DHAVE_SYS_SELECT_H \ 28 | -DHAVE_PTHREAD \ 29 | -DHAVE_SEMAPHORE_H \ 30 | -DENABLE_TRACE \ 31 | -DOSIP_MT 32 | 33 | #兼容5.0+ 34 | LOCAL_CFLAGS += -fPIE -fPIC 35 | LOCAL_LDFLAGS += -fPIE -pie 36 | 37 | # 编译为可执行的文件 38 | include $(BUILD_EXECUTABLE) 39 | -------------------------------------------------------------------------------- /traceroute/flowlabel.h: -------------------------------------------------------------------------------- 1 | /* 2 | It is just a stripped copy of the kernel header "linux/in6.h" 3 | 4 | "Flow label" things are still not defined in "netinet/in*.h" headers, 5 | but we cannot use "linux/in6.h" immediately because it currently 6 | conflicts with "netinet/in.h" . 7 | */ 8 | 9 | struct in6_flowlabel_req 10 | { 11 | struct in6_addr flr_dst; 12 | __u32 flr_label; 13 | __u8 flr_action; 14 | __u8 flr_share; 15 | __u16 flr_flags; 16 | __u16 flr_expires; 17 | __u16 flr_linger; 18 | __u32 __flr_pad; 19 | /* Options in format of IPV6_PKTOPTIONS */ 20 | }; 21 | 22 | #define IPV6_FL_A_GET 0 23 | #define IPV6_FL_A_PUT 1 24 | #define IPV6_FL_A_RENEW 2 25 | 26 | #define IPV6_FL_F_CREATE 1 27 | #define IPV6_FL_F_EXCL 2 28 | 29 | #define IPV6_FL_S_NONE 0 30 | #define IPV6_FL_S_EXCL 1 31 | #define IPV6_FL_S_PROCESS 2 32 | #define IPV6_FL_S_USER 3 33 | #define IPV6_FL_S_ANY 255 34 | 35 | #define IPV6_FLOWINFO_FLOWLABEL 0x000fffff 36 | #define IPV6_FLOWINFO_PRIORITY 0x0ff00000 37 | 38 | #define IPV6_FLOWLABEL_MGR 32 39 | #define IPV6_FLOWINFO_SEND 33 40 | 41 | -------------------------------------------------------------------------------- /wrappers/tcptraceroute.8: -------------------------------------------------------------------------------- 1 | .\" Copyright (c) 2016 Dmitry Butskoy (dmitry@butskoy.name) 2 | .\" License: GPL v2 or any later version 3 | .\" See COPYING for the status of this software 4 | .TH TCPTRACEROUTE 8 "8 March 2016" "Traceroute" "Traceroute For Linux" 5 | .\" .UC 6 6 | .SH NAME 7 | tcptraceroute \- print the route packets trace to network host 8 | .SH SYNOPSIS 9 | .na 10 | .BR tcptraceroute 11 | .RI " [" options ] 12 | .ad 13 | .SH DESCRIPTION 14 | .I tcptraceroute 15 | is just a link to the system 16 | .B traceroute\fR, 17 | to allow run it without specifying 18 | .B \-T 19 | option each time (for switch to the TCP method). It is fully equivalent to 20 | .B traceroute \-T\fR, 21 | the rest of the command line is the same. 22 | .br 23 | See 24 | .BR traceroute (8) 25 | for more info. 26 | .SH NOTES 27 | There was an original implementation of tcptraceroute, which had some options 28 | differ (but rare used). Most common 29 | .BR "" [ "dnFi:f:m:q:w:s:t:" ] 30 | was exactly the same, but 31 | .BR "" [ "l:p:NSAE" ] 32 | was not. For full compatibility, a wrapper provided (available in the source code). 33 | .SH SEE ALSO 34 | .BR traceroute (8) 35 | -------------------------------------------------------------------------------- /Make.defines: -------------------------------------------------------------------------------- 1 | # The name of this distributive (used for tarballs etc.). 2 | # *MUST* be defined here... 3 | # 4 | NAME = traceroute 5 | 6 | # All subdir lists below are space-separated, with make's '%' wildcard 7 | # allowed. Default value is shown in commented out example. 8 | # 9 | 10 | # Subdirs to exclude anyway 11 | # 12 | #SKIPDIRS = tmp% 13 | 14 | # Subdirs to be treated as libdirs. 15 | # 16 | #LIBDIRS = lib% 17 | 18 | # An exact non-wildcard list of libdirs to be placed last in LIBDIRS list, 19 | # with the order specified. Useful, when some library should be 20 | # specified last because of referencing from another library... 21 | # 22 | #LIBLAST = 23 | 24 | # Subdirs to be treated as includedirs. 25 | # Also all LIBDIRS will be actually used for includes too. 26 | # 27 | #INCLUDEDIRS = include% 28 | 29 | # Subdirs to be treated as moduledirs. 30 | # 31 | #MODDIRS = mod% 32 | 33 | # Subdirs of executables which will use modules at run-time linking. 34 | # 35 | #MODUSERS = 36 | 37 | # Subdirs of executables to be installed in `*/sbin' instead of `*/bin'. 38 | # 39 | #SBINUSERS = 40 | 41 | # Subdirs to exclude from install 42 | # 43 | SKIPINSTALL = test% libsupp 44 | 45 | 46 | # A better way to alter the variables is to use "+=" or 47 | # "override VAR += value" 48 | # 49 | # CFLAGS += 50 | # CPPFLAGS += 51 | # LDFLAGS += 52 | # LIBS += 53 | 54 | CPPFLAGS += -D_GNU_SOURCE 55 | 56 | -------------------------------------------------------------------------------- /wrappers/tracepath: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2008 Dmitry Butskoy 4 | # 5 | # License: GPL v2 or any later 6 | # 7 | # See COPYING for the status of this software. 8 | # 9 | 10 | # 11 | # Shell wrapper providing tracepath(1) or tracepath6(1) command line interface. 12 | # 13 | # The original implementation of tracepath/tracepath6 can be obtained 14 | # from the iputils package, available at http://www.skbuff.net/iputils/ 15 | # 16 | 17 | opts="-q1 --mtu --back" 18 | port=44444 19 | prgname=$0 20 | length="" 21 | 22 | 23 | usage () { 24 | echo "Usage: $prgname [-nbh] [ -l pktlen ] host[/port]" >&2 25 | } 26 | 27 | 28 | PARSED=`getopt 'hnbl:' "$@"` 29 | [ $? != 0 ] && exit 2 30 | 31 | eval set -- "$PARSED" 32 | 33 | while [ $# -gt 0 ] 34 | do 35 | case "$1" in 36 | -n) opts="$opts $1"; shift ;; 37 | -b) shift ;; 38 | -l) length=$2; shift 2 ;; 39 | -h) usage ; exit 0 ;; 40 | --) shift; break ;; 41 | *) echo "$prgname: Internal parsing error" >&2; exit 2 ;; 42 | esac 43 | done 44 | 45 | [ $# -eq 0 ] && { 46 | usage 47 | exit 2 48 | } 49 | 50 | host=$1 51 | case "$host" in 52 | */*) port=${host##*/} 53 | host=${host%/*} 54 | ;; 55 | esac 56 | 57 | 58 | case "$prgname" in 59 | *6) opts="$opts -6" ;; 60 | esac 61 | 62 | exec traceroute $opts -p $port $host $length 63 | 64 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | * It seems that `-l' and `-g' will not work correctly together (IPv6). 2 | 3 | Wait for "flow label" API to be appeared in kernel-headers and 4 | think about it immediately after that... :) 5 | 6 | 7 | * The "final hop" issue. 8 | 9 | All methods, usable when firewalls are present in the network path, 10 | normally use some particular destination port. Most often it is a port 11 | of an already running application. 12 | 13 | It requires that the packet sent should be correct for such an application 14 | (for example, for tracing with udp to port 53, it should be correct DNS 15 | request), and the application normally should answer something on it. 16 | (TCP has no such an issue, as there are just syn to, and ack or reset from). 17 | 18 | In general, we should fill the packet's data depending on the dest port 19 | and protocol. It seems not a task for traceroute itself, it could be 20 | some cmdline option or even external hook... 21 | 22 | 23 | * Think about SCTP method. 24 | 25 | 26 | * Think about "multicast tracerouting" (mrouted(8) and other). 27 | The idea is to increase the room in the mtrace packet step-by-step 28 | (as well as we increase ttl). It seems that if there is no more space 29 | in the probe's room, the mrouted(8) daemon answers immediately, the same 30 | way as if it is a final hop. 31 | 32 | For IPv6 mtrace, there is an RFC draft for this already... 33 | 34 | -------------------------------------------------------------------------------- /traceroute.spec: -------------------------------------------------------------------------------- 1 | Summary: Traces the route taken by packets over an IPv4/IPv6 network 2 | Name: traceroute 3 | Version: 2.1.0 4 | Release: 1%{?dist} 5 | Group: Applications/Internet 6 | License: GPLv2+ 7 | URL: http://traceroute.sourceforge.net 8 | Source0: http://dl.sourceforge.net/traceroute/traceroute-%{version}.tar.gz 9 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 10 | 11 | 12 | %description 13 | The traceroute utility displays the route used by IP packets on their 14 | way to a specified network (or Internet) host. Traceroute displays 15 | the IP number and host name (if possible) of the machines along the 16 | route taken by the packets. Traceroute is used as a network debugging 17 | tool. If you're having network connectivity problems, traceroute will 18 | show you where the trouble is coming from along the route. 19 | 20 | Install traceroute if you need a tool for diagnosing network connectivity 21 | problems. 22 | 23 | 24 | %prep 25 | %setup -q 26 | 27 | 28 | %build 29 | make %{?_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" LDFLAGS="" 30 | 31 | 32 | %install 33 | rm -rf $RPM_BUILD_ROOT 34 | 35 | install -d $RPM_BUILD_ROOT/bin 36 | install -m755 traceroute/traceroute $RPM_BUILD_ROOT/bin 37 | pushd $RPM_BUILD_ROOT/bin 38 | ln -s traceroute traceroute6 39 | popd 40 | 41 | install -d $RPM_BUILD_ROOT%{_mandir}/man8 42 | install -p -m644 traceroute/traceroute.8 $RPM_BUILD_ROOT%{_mandir}/man8 43 | ln -s traceroute.8 $RPM_BUILD_ROOT%{_mandir}/man8/traceroute6.8 44 | 45 | 46 | %clean 47 | rm -rf $RPM_BUILD_ROOT 48 | 49 | 50 | %files 51 | %defattr(-,root,root,-) 52 | %doc COPYING README TODO CREDITS 53 | /bin/* 54 | %{_mandir}/*/* 55 | 56 | 57 | %changelog 58 | * Tue Oct 20 2006 Dmitry Butskoy - 2.0.2-1 59 | - initial release 60 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Fork from http://traceroute.sourceforge.net 2 | How to build with Android NDK ? 3 | Please switch to android-ver branch. 4 | 如何编译Android版本?请切换到 android-ver 分支. 5 | 6 | 7 | ##traceroute 8 | 9 | This is a new modern implementation of the traceroute(8) 10 | utility for Linux systems. 11 | 12 | Traceroute tracks the route packets taken from an IP network on their 13 | way to a given host. It utilizes the IP protocol's time to live (TTL) 14 | field and attempts to elicit an ICMP TIME_EXCEEDED response from each 15 | gateway along the path to the host. 16 | 17 | Main features: 18 | - Full support for both IPv4 and IPv6 protocols 19 | - Several tracerouting methods, including: 20 | * UDP datagrams (including udplite and udp to particlular port) 21 | * ICMP ECHO packets (including dgram icmp sockets) 22 | * TCP SYNs (in general, any TCP request with various flags and options) 23 | * DCCP Request packets 24 | * Generic IP datagrams 25 | - UDP methods do not require root privileges 26 | - Ability to send several probe packets at a time 27 | - Ability to compute a proper time to wait for each probe 28 | - perform AS path lookups for returned addresses 29 | - show ICMP extensions, including MPLS 30 | - perform path MTU discovery automatically 31 | - show guessed number of hops in backward direction 32 | - command line compatible with the original traceroute 33 | - and much more, see traceroute(8) 34 | 35 | This code was written from the scratch, using some ideas of 36 | Olaf Kirch's traceroute, the original implementation of Van Jacobson 37 | (which was long used before) and some current BSD's ones. 38 | 39 | This traceroute requires Linux kernel 2.6 and higher. 40 | 41 | You can try to contact the author at . 42 | 43 | 44 | Good tracerouting! 45 | 46 | Dmitry Butskoy 47 | 48 | -------------------------------------------------------------------------------- /store.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2000, 2001 Dmitry Butskoy 4 | # 5 | # License: GPL v2 or any later 6 | # 7 | # See COPYING for the status of this software. 8 | # 9 | 10 | # 11 | # Store package script. 12 | # Normally invoked by a Makefile. 13 | # 14 | # Stores package with an appropriate version info 15 | # as the main directory postfix (i.e., name-0.1.2/*), 16 | # even if the source dir don`t have it. 17 | # 18 | 19 | 20 | [ $# -lt 2 ] && { 21 | echo "Usage: $0 target store_dir" >&2 22 | exit 2 23 | } 24 | 25 | 26 | target=$1 27 | store_dir=$2 28 | main_dir=`basename \`pwd\`` 29 | 30 | 31 | # Find current version info. 32 | 33 | dir_v="" 34 | file_v="" 35 | 36 | dir_v=`expr $main_dir : '.*-\([0-9.]*\)$'` 37 | [ -r VERSION ] && file_v=`awk '/^ *#/ { print $3 ; exit; } 38 | /^ *VERSION *=/ {split ($0, a, "="); print a[2]; exit; } 39 | { print $0; exit; }' < VERSION ` 40 | [ -n "$file_v" ] && file_v=`echo $file_v ` # to strip possible spaces 41 | 42 | [ -z "$file_v" -a -z "$dir_v" ] && { 43 | echo "$0: Cannot determine version (use dirname postfix or VERSION file)" >&2 44 | exit 2 45 | } 46 | 47 | [ -n "$file_v" -a -n "$dir_v" -a "$dir_v" != "$file_v" ] && { 48 | echo "$0: Different version from dirname postfix and VERSION file" >&2 49 | exit 2 50 | } 51 | 52 | version="$dir_v" 53 | [ -z "$version" ] && version="$file_v" 54 | 55 | 56 | targ_vers=${target}-$version 57 | 58 | cd .. 59 | 60 | [ "$main_dir" != "$targ_vers" ] && { 61 | ln -s "$main_dir" "${main_dir}~" || exit 1 # paranoia and paranoia 62 | mv -f "$main_dir" "$targ_vers" || exit 1 63 | } 64 | 65 | tar -cvhf - "$targ_vers" | gzip -c -9 > $store_dir/${targ_vers}.tar.gz 66 | 67 | [ "$main_dir" != "$targ_vers" ] && { 68 | mv -f "$targ_vers" "$main_dir" 69 | rm -f "${main_dir}~" 70 | } 71 | 72 | exit 0 73 | -------------------------------------------------------------------------------- /wrappers/tcptraceroute: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2007 Dmitry Butskoy 4 | # 5 | # License: GPL v2 or any later 6 | # 7 | # See COPYING for the status of this software. 8 | # 9 | 10 | # 11 | # Shell wrapper providing tcptraceroute(8) command line interface. 12 | # 13 | # The original implementation of tcptraceroute(8) can be obtained 14 | # from http://michael.toren.net/code/tcptraceroute/ 15 | # 16 | 17 | opts="-T -O info" 18 | length="" 19 | prgname=$0 20 | 21 | 22 | usage () { 23 | echo "Usage: $prgname [-hvnFSAE] [-i dev] [-f furst_ttl] [-l length] 24 | [-q nqueries] [-t tos] [-m max_ttl] [-p src_port] [-s src_addr] 25 | [-w wait_time] host [dest_port] [length]" >&2 26 | } 27 | 28 | 29 | PARSED=`getopt 'hvdnNi:l:f:Fm:p:q:w:s:t:SAE' "$@"` 30 | [ $? != 0 ] && exit 2 31 | 32 | eval set -- "$PARSED" 33 | 34 | while [ $# -gt 0 ] 35 | do 36 | case "$1" in 37 | -[dnF]) opts="$opts $1"; shift ;; 38 | -N) shift ;; 39 | -[ifmqwst]) opts="$opts $1 $2"; shift 2 ;; 40 | -l) length=$2; shift 2 ;; 41 | -p) opts="$opts --sport=$2"; shift 2 ;; 42 | -S) opts="$opts -O syn"; shift ;; 43 | -A) opts="$opts -O ack"; shift ;; 44 | -E) opts="$opts -O ecn"; shift ;; 45 | -h) usage ; exit 0 ;; 46 | -v) echo "\"tcptraceroute\"-compatible wrapper for new Linux Traceroute" >&2; 47 | exit 0 ;; 48 | --) shift; break ;; 49 | *) echo "$prgname: Internal parsing error" >&2; exit 2 ;; 50 | esac 51 | done 52 | 53 | [ $# -eq 0 ] && { 54 | usage 55 | exit 2 56 | } 57 | 58 | host=$1 59 | shift 60 | 61 | [ $# -gt 0 ] && { 62 | opts="$opts -p $1" 63 | shift 64 | } 65 | 66 | [ $# -gt 0 ] && { 67 | length=$1 68 | shift 69 | } 70 | 71 | 72 | # Say to the people it is actually another program... 73 | echo "Running: 74 | traceroute $opts $host $length" >&2 75 | 76 | 77 | exec traceroute $opts $host $length 78 | 79 | -------------------------------------------------------------------------------- /wrappers/traceroute-nanog: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2007 Dmitry K. Butskoy 4 | # 5 | # License: GPL v2 or any later 6 | # 7 | # See COPYING for the status of this software. 8 | # 9 | 10 | # 11 | # Shell wrapper providing traceroute-nanog(8) command line interface. 12 | # 13 | # The original implementation of traceroute-nanog(8) can be obtained 14 | # from ftp://ftp.login.com/pub/software/traceroute/ 15 | # 16 | 17 | 18 | prgname=$0 19 | opts="" 20 | spray="" 21 | 22 | 23 | usage () { 24 | echo "Usage: $prgname [-adnruvAMOPQU$] [-w wait] [-S start_ttl] 25 | [-m max_ttl] [-p port] [-q nqueries] [-g gateway] [-t tos] 26 | [-s src_addr] [-I proto] host [data_size]" >&2 27 | } 28 | 29 | warning () { 30 | echo "$prgname: Option '$1' is not implemented in this wrapper" >&2 31 | } 32 | 33 | 34 | PARSED=`getopt 'adnruvAMOPQU$w:S:m:p:q:g:t:s:I:f:T:' "$@"` 35 | [ $? != 0 ] && { 36 | usage 37 | exit 2 38 | } 39 | 40 | eval set -- "$PARSED" 41 | 42 | while [ $# -gt 0 ] 43 | do 44 | case "$1" in 45 | -[Adrn]) opts="$opts $1"; shift ;; 46 | -[gmpqstw]) opts="$opts $1 $2"; shift 2 ;; 47 | -I) case "$2" in 48 | icmp) opts="$opts -I" ;; 49 | tcp) opts="$opts -T" ;; 50 | udp) ;; 51 | udplite) opts="$opts -UL" ;; 52 | *) opts="$opts -P $2" ;; 53 | esac 54 | shift 2 ;; 55 | -S) opts="$opts -f $2"; shift 2 ;; 56 | -P) spray=1; shift ;; 57 | -f) opts="$opts --sport=$2"; shift 2 ;; 58 | -u) ;; 59 | -$) opts="-f 64 -m 64 -q 1"; shift ;; 60 | -M) opts="$opts --mtu"; shift ;; 61 | -[aUOvQ]) warning $1; shift ;; 62 | -T) warning $1; shift 2 ;; 63 | --) shift; break ;; 64 | *) echo "$prgname: Internal parsing error" >&2; exit 2 ;; 65 | esac 66 | done 67 | 68 | [ $# -eq 0 ] && { 69 | usage 70 | exit 2 71 | } 72 | 73 | [ -z "$spray" ] && opts="$opts -N 1" 74 | 75 | exec traceroute $opts $1 $2 76 | 77 | -------------------------------------------------------------------------------- /traceroute/poll.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "traceroute.h" 16 | 17 | 18 | static struct pollfd *pfd = NULL; 19 | static unsigned int num_polls = 0; 20 | 21 | 22 | void add_poll (int fd, int events) { 23 | int i; 24 | 25 | for (i = 0; i < num_polls && pfd[i].fd > 0; i++) ; 26 | 27 | if (i == num_polls) { 28 | pfd = realloc (pfd, ++num_polls * sizeof (*pfd)); 29 | if (!pfd) error ("realloc"); 30 | } 31 | 32 | pfd[i].fd = fd; 33 | pfd[i].events = events; 34 | } 35 | 36 | 37 | void del_poll (int fd) { 38 | int i; 39 | 40 | for (i = 0; i < num_polls && pfd[i].fd != fd; i++) ; 41 | 42 | if (i < num_polls) pfd[i].fd = -1; /* or just zero it... */ 43 | } 44 | 45 | 46 | static int cleanup_polls (void) { 47 | int i; 48 | 49 | for (i = 0; i < num_polls && pfd[i].fd > 0; i++) ; 50 | 51 | if (i < num_polls) { /* a hole have found */ 52 | int j; 53 | 54 | for (j = i + 1; j < num_polls; j++) { 55 | if (pfd[j].fd > 0) { 56 | pfd[i++] = pfd[j]; 57 | pfd[j].fd = -1; 58 | } 59 | } 60 | } 61 | 62 | return i; 63 | } 64 | 65 | 66 | void do_poll (double timeout, void (*callback) (int fd, int revents)) { 67 | int nfds; 68 | int msecs = ceil (timeout * 1000); 69 | 70 | while ((nfds = cleanup_polls ()) > 0) { 71 | int i, n; 72 | 73 | n = poll (pfd, nfds, msecs); 74 | 75 | if (n <= 0) { 76 | if (n == 0 || errno == EINTR) 77 | return; 78 | error ("poll"); 79 | } 80 | 81 | for (i = 0; n && i < num_polls; i++) { 82 | if (pfd[i].revents) { 83 | callback (pfd[i].fd, pfd[i].revents); 84 | n--; 85 | } 86 | } 87 | 88 | msecs = 0; /* no more wait, just eat all the pending */ 89 | } 90 | 91 | return; 92 | } 93 | 94 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2000, 2001 Dmitry Butskoy 3 | # 4 | # License: GPL v2 or any later 5 | # 6 | # See COPYING for the status of this software. 7 | # 8 | 9 | # 10 | # Global Makefile. 11 | # Global rules, targets etc. 12 | # 13 | # See Make.defines for specific configs. 14 | # 15 | 16 | 17 | srcdir = $(CURDIR) 18 | 19 | override TARGET := .MAIN 20 | 21 | dummy: all 22 | 23 | include ./Make.rules 24 | 25 | 26 | targets = $(EXEDIRS) $(LIBDIRS) $(MODDIRS) 27 | 28 | 29 | # be happy, easy, perfomancy... 30 | .PHONY: $(subdirs) dummy all force 31 | .PHONY: depend indent clean distclean libclean release store libs mods 32 | 33 | 34 | allprereq := $(EXEDIRS) 35 | 36 | ifneq ($(LIBDIRS),) 37 | libs: $(LIBDIRS) 38 | ifneq ($(EXEDIRS),) 39 | $(EXEDIRS): libs 40 | else 41 | allprereq += libs 42 | endif 43 | endif 44 | 45 | ifneq ($(MODDIRS),) 46 | mods: $(MODDIRS) 47 | ifneq ($(MODUSERS),) 48 | $(MODUSERS): mods 49 | else 50 | allprereq += mods 51 | endif 52 | ifneq ($(LIBDIRS),) 53 | $(MODDIRS): libs 54 | endif 55 | endif 56 | 57 | all: $(allprereq) 58 | 59 | depend install: $(allprereq) 60 | 61 | $(foreach goal,$(filter install-%,$(MAKECMDGOALS)),\ 62 | $(eval $(goal): $(patsubst install-%,%,$(goal)))) 63 | 64 | 65 | what = all 66 | depend: what = depend 67 | install install-%: what = install 68 | 69 | ifneq ($(share),) 70 | $(share): shared = yes 71 | endif 72 | ifneq ($(noshare),) 73 | $(noshare): shared = 74 | endif 75 | 76 | 77 | $(targets): mkfile = $(if $(wildcard $@/Makefile),,-f $(srcdir)/default.rules) 78 | 79 | $(targets): force 80 | @$(MAKE) $(mkfile) -C $@ $(what) TARGET=$@ 81 | 82 | force: 83 | 84 | 85 | indent: 86 | find . -type f -name "*.[ch]" -print -exec $(INDENT) {} \; 87 | 88 | clean: 89 | rm -f $(foreach exe, $(EXEDIRS), ./$(exe)/$(exe)) nohup.out 90 | rm -f `find . \( -name "*.[oa]" -o -name "*.[ls]o" \ 91 | -o -name core -o -name "core.[0-9]*" -o -name a.out \) -print` 92 | 93 | distclean: clean 94 | rm -f `find $(foreach dir, $(subdirs), $(dir)/.) \ 95 | \( -name "*.[oa]" -o -name "*.[ls]o" \ 96 | -o -name core -o -name "core.[0-9]*" -o -name a.out \ 97 | -o -name .depend -o -name "_*" -o -name ".cross:*" \) \ 98 | -print` 99 | 100 | 101 | libclean: 102 | rm -f $(foreach lib, $(LIBDIRS), ./$(lib)/$(lib).a ./$(lib)/$(lib).so) 103 | 104 | 105 | # Rules to make whole-distributive operations. 106 | # 107 | 108 | STORE_DIR = $(HOME)/pub 109 | 110 | release release1 release2 release3: 111 | @./chvers.sh $@ 112 | @$(MAKE) store 113 | 114 | store: distclean 115 | @./store.sh $(NAME) $(STORE_DIR) 116 | 117 | 118 | -------------------------------------------------------------------------------- /chvers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2000, 2001 Dmitry Butskoy 4 | # 5 | # License: GPL v2 or any later 6 | # 7 | # See COPYING for the status of this software. 8 | # 9 | 10 | # 11 | # Change version script. 12 | # Normally invoked by a Makefile. 13 | # 14 | # Changes version info in directory name, in VERSION file 15 | # and rpm spec file (if some of these are used). 16 | # 17 | # `release3' changes: 0.2.7 --> 0.2.8 18 | # `release2' changes: 0.2.7 --> 0.3.0 19 | # `release1' changes: 0.2.7 --> 1.0.0 20 | # etc. 21 | # `release' without a digit increment the last number used. 22 | # 23 | # 24 | 25 | 26 | [ $# -lt 1 ] && { 27 | echo "Usage: $0 release[123...0]" >&2 28 | exit 2 29 | } 30 | 31 | level=`expr $1 : '.*\([0-9]\)$'` 32 | [ -z "$level" ] && level=0 33 | 34 | main_dir=`basename \`pwd\`` 35 | 36 | 37 | # Find current version info. 38 | 39 | dir_v="" 40 | file_v="" 41 | 42 | dir_v=`expr $main_dir : '.*-\([0-9.]*\)$'` 43 | [ -r VERSION ] && file_v=`awk '/^ *#/ { print $3 ; exit; } 44 | /^ *VERSION *=/ {split ($0, a, "="); print a[2]; exit; } 45 | { print $0; exit; }' < VERSION ` 46 | [ -n "$file_v" ] && file_v=`echo $file_v ` # to strip possible spaces 47 | 48 | [ -z "$file_v" -a -z "$dir_v" ] && { 49 | echo "$0: Cannot determine version (use dirname postfix or VERSION file)" >&2 50 | exit 2 51 | } 52 | 53 | [ -n "$file_v" -a -n "$dir_v" -a "$dir_v" != "$file_v" ] && { 54 | echo "$0: Different version from dirname postfix and VERSION file" >&2 55 | exit 2 56 | } 57 | 58 | version="$dir_v" 59 | [ -z "$version" ] && version="$file_v" 60 | 61 | 62 | # Increment current version, as specified by level. 63 | 64 | new_version=`echo $version | awk '{ 65 | level = '"$level"'; 66 | n = split ($0, a, "."); 67 | if (level == 0) level = n; 68 | for (i = 1; i <= n; i++) { 69 | if (i == level) a[i] = a[i] + 1 ; 70 | else if (i > level) a[i] = 0 ; 71 | } 72 | str = a[1] 73 | for (i = 2; i <= n; i++) str = str "." a[i] 74 | print str 75 | }' 2>/dev/null ` 76 | 77 | 78 | # Adjust VERSION file, if any. 79 | 80 | # it is ugly, because $version contains dots... 81 | [ -n "$file_v" ] && { 82 | sed "s/$version/$new_version/" < VERSION > VERSION.new && mv -f VERSION.new VERSION 83 | } 84 | 85 | # Adjust rpm .spec file, if any. 86 | for spec in *.spec 87 | do 88 | [ -f $spec ] || continue 89 | 90 | grep '^Version:[ ]*'"$version" $spec >/dev/null 2>&1 || continue 91 | sed '/^Version:[ ]*'"$version/ s/$version/$new_version/" < $spec > ${spec}.new && mv -f ${spec}.new $spec 92 | done 93 | 94 | 95 | # Adjust dirname postfix, if any. 96 | 97 | [ -n "$dir_v" ] && { 98 | base=`expr \`pwd\` : '^\(.*\)-'"$version"'$' ` 99 | mv -f ${base}-$version ${base}-$new_version 100 | } 101 | 102 | exit 0 103 | -------------------------------------------------------------------------------- /wrappers/lft: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2007 Dmitry K. Butskoy 4 | # 5 | # License: GPL v2 or any later 6 | # 7 | # See COPYING for the status of this software. 8 | # 9 | 10 | # 11 | # Shell wrapper providing lft(8) command line interface. 12 | # 13 | # The original implementation of lft(8) can be obtained 14 | # from http://pwhois.org/lft/ 15 | # 16 | 17 | 18 | prgname=$0 19 | opts="" 20 | length="" 21 | method="-T" 22 | 23 | dport="" 24 | sport="" 25 | queries=2 26 | ahead=5 27 | scatter=20 28 | timeout=1000 29 | 30 | 31 | usage () { 32 | echo "Usage: $prgname [-ACEFINRSTUVbehinpruvz] [-d dport] [-s sport] 33 | [-m retry min] [-M retry max] [-a ahead] [-c scatter ms] [-t timeout ms] 34 | [-l min ttl] [-H max ttl] [-L length] [-q ISN] [-D device] [--help] 35 | [gateway ...] target:dport" >&2 36 | } 37 | 38 | warning () { 39 | echo "$prgname: Option '$1' is not implemented in this wrapper" >&2 40 | } 41 | 42 | 43 | PARSED=`getopt -o 'ACEFINRSTUVbehinpruvzd:s:m:M:a:c:t:l:H:L:q:D:' -l help -- "$@"` 44 | [ $? != 0 ] && exit 2 45 | 46 | eval set -- "$PARSED" 47 | 48 | while [ $# -gt 0 ] 49 | do 50 | case "$1" in 51 | -d) dport=$2; shift 2 ;; 52 | -s) sport=$2; shift 2 ;; 53 | -z) sport=""; shift ;; 54 | -m) queries=$2; shift 2 ;; 55 | -a) ahead=$2; shift 2 ;; 56 | -c) scatter=$2; shift 2 ;; 57 | -t) timeout=$2; shift 2 ;; 58 | -l) opts="$opts -f $2"; shift 2 ;; 59 | -L) length=$2; shift 2 ;; 60 | -D) case "$2" in 61 | [0-9]*) opts="$opts -s $2" ;; 62 | *) opts="$opts -i $2" ;; 63 | esac 64 | shift 2 65 | ;; 66 | -H) opts="$opts -m $2"; shift 2 ;; 67 | -I) opts="$opts -t 0x10"; shift ;; 68 | -n) opts="$opts -n"; shift ;; 69 | -h) shift ;; 70 | -F) opts="$opts -O fin"; shift ;; 71 | -u) method="-U"; shift ;; 72 | -N) opts="$opts -A"; shift ;; 73 | -p) method="-I"; shift ;; 74 | -b) shift ;; 75 | -A) opts="$opts -A"; shift ;; 76 | -[ieErCTUV]) warning $1; shift ;; 77 | -[Mq]) warning $1; shift 2 ;; 78 | -[RS]) shift ;; 79 | --help) usage; exit 0 ;; 80 | -v) echo "\"lft\"-compatible wrapper for new Linux Traceroute" >&2; 81 | exit 0 ;; 82 | --) shift; break ;; 83 | *) echo "$prgname: Internal parsing error" >&2; exit 2 ;; 84 | esac 85 | done 86 | 87 | while [ $# -gt 1 ] 88 | do 89 | opts="$opts -g $1" 90 | shift 91 | done 92 | 93 | [ $# -eq 0 ] && { 94 | usage 95 | exit 2 96 | } 97 | 98 | case "$1" in 99 | *:*:*) host=$1 ;; 100 | *:*) dport=${1##*:}; host=${1%:*} ;; 101 | *) host=$1 ;; 102 | esac 103 | 104 | [ -n "$dport" ] && opts="$opts -p $dport" 105 | [ -n "$sport" ] && opts="$opts --sport=$sport" 106 | opts="$opts -q $queries" 107 | opts="$opts -N $(($ahead * $queries))" 108 | opts="$opts -z $scatter" 109 | 110 | timeout=`printf "%04d" $timeout` 111 | sec=${timeout%???} 112 | opts="$opts -w $sec.${timeout#$sec}" 113 | 114 | opts="$method $opts" 115 | 116 | exec traceroute $opts $host $length 117 | 118 | -------------------------------------------------------------------------------- /traceroute/as_lookups.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "traceroute.h" 19 | 20 | 21 | #define DEF_RADB_SERVER "whois.radb.net" 22 | #define DEF_RADB_SERVICE "nicname" 23 | 24 | 25 | static sockaddr_any ra_addr = {{ 0, }, }; 26 | static char ra_buf[512] = { 0, }; 27 | 28 | 29 | const char *get_as_path (const char *query) { 30 | int sk, n; 31 | FILE *fp; 32 | char buf[1024]; 33 | int prefix = 0, best_prefix = 0; 34 | char *rb, *re = &ra_buf[sizeof (ra_buf) / sizeof (*ra_buf) - 1]; 35 | 36 | 37 | if (!ra_addr.sa.sa_family) { 38 | const char *server, *service; 39 | struct addrinfo *res; 40 | int ret; 41 | 42 | server = getenv ("RA_SERVER"); 43 | if (!server) server = DEF_RADB_SERVER; 44 | 45 | service = getenv ("RA_SERVICE"); 46 | if (!service) service = DEF_RADB_SERVICE; 47 | 48 | 49 | ret = getaddrinfo (server, service, NULL, &res); 50 | if (ret) { 51 | fprintf (stderr, "%s/%s: %s\n", server, service, 52 | gai_strerror(ret)); 53 | exit (2); 54 | } 55 | 56 | memcpy (&ra_addr, res->ai_addr, res->ai_addrlen); 57 | 58 | freeaddrinfo (res); 59 | } 60 | 61 | 62 | sk = socket (ra_addr.sa.sa_family, SOCK_STREAM, 0); 63 | if (sk < 0) error ("socket"); 64 | 65 | if (connect (sk, &ra_addr.sa, sizeof (ra_addr)) < 0) 66 | goto err_sk; 67 | 68 | n = snprintf (buf, sizeof (buf), "%s\r\n", query); 69 | if (n >= sizeof (buf)) goto err_sk; 70 | 71 | if (write (sk, buf, n) < n) 72 | goto err_sk; 73 | 74 | fp = fdopen (sk, "r"); 75 | if (!fp) goto err_sk; 76 | 77 | 78 | strcpy (ra_buf, "*"); 79 | rb = ra_buf; 80 | 81 | while (fgets (buf, sizeof (buf), fp) != NULL) { 82 | 83 | if (!strncmp (buf, "route:", sizeof ("route:") - 1) || 84 | !strncmp (buf, "route6:", sizeof ("route6:") - 1) 85 | ) { 86 | char *p = strchr (buf, '/'); 87 | 88 | if (p) prefix = strtoul (++p, NULL, 10); 89 | else prefix = 0; /* Hmmm... */ 90 | 91 | } 92 | else if (!strncmp (buf, "origin:", sizeof ("origin:") -1)) { 93 | char *p, *as; 94 | 95 | p = buf + (sizeof ("origin:") - 1); 96 | 97 | while (isspace (*p)) p++; 98 | as = p; 99 | while (*p && !isspace (*p)) p++; 100 | *p = '\0'; 101 | 102 | if (prefix > best_prefix) { 103 | best_prefix = prefix; 104 | 105 | rb = ra_buf; 106 | while (rb < re && (*rb++ = *as++)) ; 107 | } 108 | else if (prefix == best_prefix) { 109 | char *q = strstr (ra_buf, as); 110 | 111 | if (!q || (*(q += strlen (as)) != '\0' && *q != '/')) { 112 | if (rb > ra_buf) rb[-1] = '/'; 113 | while (rb < re && (*rb++ = *as++)) ; 114 | } 115 | } 116 | /* else just ignore it */ 117 | } 118 | } 119 | 120 | fclose (fp); 121 | 122 | return ra_buf; 123 | 124 | 125 | err_sk: 126 | close (sk); 127 | return "!!"; 128 | } 129 | -------------------------------------------------------------------------------- /traceroute/extension.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "traceroute.h" 7 | 8 | 9 | struct icmp_ext_header { 10 | #if __BYTE_ORDER == __BIG_ENDIAN 11 | unsigned int version:4; 12 | unsigned int reserved:4; 13 | #else 14 | unsigned int reserved:4; 15 | unsigned int version:4; 16 | #endif 17 | uint8_t reserved1; 18 | uint16_t checksum; 19 | } __attribute__ ((packed)); 20 | 21 | 22 | struct icmp_ext_object { 23 | uint16_t length; 24 | uint8_t class; 25 | uint8_t c_type; 26 | uint8_t data[0]; 27 | }; 28 | 29 | #define MPLS_CLASS 1 30 | #define MPLS_C_TYPE 1 31 | 32 | 33 | #define do_snprintf(CURR, END, FMT, ARGS...) \ 34 | do { \ 35 | CURR += snprintf (CURR, END - CURR, (FMT), ## ARGS);\ 36 | if (CURR > END) CURR = END; \ 37 | } while (0) 38 | 39 | 40 | static int try_extension (probe *pb, char *buf, size_t len) { 41 | struct icmp_ext_header *iext = (struct icmp_ext_header *) buf; 42 | char str[1024]; 43 | char *curr = str; 44 | char *end = str + sizeof (str) / sizeof (*str); 45 | 46 | 47 | /* a check for len >= 8 already done for all cases */ 48 | 49 | if (iext->version != 2) return -1; 50 | 51 | if (iext->checksum && 52 | in_csum (iext, len) != (uint16_t) ~0 53 | ) return -1; 54 | 55 | buf += sizeof (*iext); 56 | len -= sizeof (*iext); 57 | 58 | 59 | while (len >= sizeof (struct icmp_ext_object)) { 60 | struct icmp_ext_object *obj = (struct icmp_ext_object *) buf; 61 | size_t objlen = ntohs (obj->length); 62 | size_t data_len; 63 | uint32_t *ui = (uint32_t *) obj->data; 64 | int i, n; 65 | 66 | if (objlen < sizeof (*obj) || 67 | objlen > len 68 | ) return -1; 69 | 70 | data_len = objlen - sizeof (*obj); 71 | if (data_len % sizeof (uint32_t)) 72 | return -1; /* must be 32bit rounded... */ 73 | 74 | n = data_len / sizeof (*ui); 75 | 76 | 77 | if (curr > (char *) str && curr < end) 78 | *curr++ = ';'; /* a separator */ 79 | 80 | if (obj->class == MPLS_CLASS && 81 | obj->c_type == MPLS_C_TYPE && 82 | n >= 1 83 | ) { /* people prefer MPLS to be parsed... */ 84 | 85 | do_snprintf (curr, end, "MPLS:"); 86 | 87 | for (i = 0; i < n; i++, ui++) { 88 | uint32_t mpls = ntohl (*ui); 89 | 90 | do_snprintf (curr, end, "%sL=%u,E=%u,S=%u,T=%u", 91 | i ? "/" : "", 92 | mpls >> 12, 93 | (mpls >> 9) & 0x7, 94 | (mpls >> 8) & 0x1, 95 | mpls & 0xff); 96 | } 97 | 98 | } 99 | else { /* common case... */ 100 | 101 | do_snprintf (curr, end, "%u/%u:", obj->class, obj->c_type); 102 | 103 | for (i = 0; i < n && curr < end; i++, ui++) 104 | do_snprintf (curr, end, "%s%08x", i ? "," : "", ntohl(*ui)); 105 | } 106 | 107 | buf += objlen; 108 | len -= objlen; 109 | } 110 | 111 | if (len) return -1; 112 | 113 | 114 | pb->ext = strdup (str); 115 | 116 | return 0; 117 | } 118 | 119 | 120 | void handle_extensions (probe *pb, char *buf, int len, int step) { 121 | 122 | if (!step) 123 | try_extension (pb, buf, len); 124 | else { 125 | for ( ; len >= 8; buf += step, len -= step) 126 | if (try_extension (pb, buf, len) == 0) 127 | break; 128 | } 129 | 130 | return; 131 | } 132 | 133 | -------------------------------------------------------------------------------- /traceroute/traceroute.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | 11 | #include "libsupp/clif.h" 12 | 13 | 14 | union common_sockaddr { 15 | struct sockaddr sa; 16 | struct sockaddr_in sin; 17 | struct sockaddr_in6 sin6; 18 | }; 19 | typedef union common_sockaddr sockaddr_any; 20 | 21 | struct probe_struct { 22 | int done; 23 | int final; 24 | sockaddr_any res; 25 | double send_time; 26 | double recv_time; 27 | int recv_ttl; 28 | int sk; 29 | int seq; 30 | char *ext; 31 | char err_str[16]; /* assume enough */ 32 | }; 33 | typedef struct probe_struct probe; 34 | 35 | 36 | struct tr_module_struct { 37 | struct tr_module_struct *next; 38 | const char *name; 39 | int (*init) (const sockaddr_any *dest, 40 | unsigned int port_seq, size_t *packet_len); 41 | void (*send_probe) (probe *pb, int ttl); 42 | void (*recv_probe) (int fd, int revents); 43 | void (*expire_probe) (probe *pb); 44 | CLIF_option *options; /* per module options, if any */ 45 | int one_per_time; /* no simultaneous probes */ 46 | size_t header_len; /* additional header length (aka for udp) */ 47 | }; 48 | typedef struct tr_module_struct tr_module; 49 | 50 | 51 | #define __TEXT(X) #X 52 | #define _TEXT(X) __TEXT(X) 53 | 54 | #define DEF_START_PORT 33434 /* start for traditional udp method */ 55 | #define DEF_UDP_PORT 53 /* dns */ 56 | #define DEF_TCP_PORT 80 /* web */ 57 | #define DEF_DCCP_PORT DEF_START_PORT /* is it a good choice?... */ 58 | #define DEF_RAW_PROT 253 /* for experimentation and testing, rfc3692 */ 59 | 60 | 61 | void error (const char *str) __attribute__((noreturn)); 62 | void error_or_perm (const char *str) __attribute__((noreturn)); 63 | 64 | double get_time (void); 65 | void tune_socket (int sk); 66 | void parse_icmp_res (probe *pb, int type, int code, int info); 67 | void probe_done (probe *pb); 68 | 69 | typedef probe *(*check_reply_t) (int sk, int err, sockaddr_any *from, 70 | char *buf, size_t len); 71 | void recv_reply (int sk, int err, check_reply_t check_reply); 72 | 73 | int equal_addr (const sockaddr_any *a, const sockaddr_any *b); 74 | 75 | probe *probe_by_seq (int seq); 76 | probe *probe_by_sk (int sk); 77 | 78 | void bind_socket (int sk); 79 | void use_timestamp (int sk); 80 | void use_recv_ttl (int sk); 81 | void use_recverr (int sk); 82 | void set_ttl (int sk, int ttl); 83 | int do_send (int sk, const void *data, size_t len, const sockaddr_any *addr); 84 | 85 | void add_poll (int fd, int events); 86 | void del_poll (int fd); 87 | void do_poll (double timeout, void (*callback) (int fd, int revents)); 88 | 89 | void handle_extensions (probe *pb, char *buf, int len, int step); 90 | const char *get_as_path (const char *query); 91 | 92 | int raw_can_connect (void); 93 | 94 | unsigned int random_seq (void); 95 | uint16_t in_csum (const void *ptr, size_t len); 96 | 97 | 98 | void tr_register_module (tr_module *module); 99 | const tr_module *tr_get_module (const char *name); 100 | 101 | #define TR_MODULE(MOD) \ 102 | static void __init_ ## MOD (void) __attribute__ ((constructor)); \ 103 | static void __init_ ## MOD (void) { \ 104 | \ 105 | tr_register_module (&MOD); \ 106 | } 107 | 108 | 109 | -------------------------------------------------------------------------------- /wrappers/traceproto: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2007 Dmitry K. Butskoy 4 | # 5 | # License: GPL v2 or any later 6 | # 7 | # See COPYING for the status of this software. 8 | # 9 | 10 | # 11 | # Shell wrapper providing traceproto(8) command line interface. 12 | # 13 | # The original implementation of traceproto(8) can be obtained 14 | # from http://traceproto.sourceforge.net/ 15 | # 16 | 17 | 18 | prgname=$0 19 | opts="" 20 | length="" 21 | method="tcp" 22 | sendwait=100 23 | cont="" 24 | iface=$TP_DEFAULT_IF 25 | 26 | 27 | usage () { 28 | echo "Usage: $prgname [-cCTfAhvR] [-p protocol] [-d dst_port] [-D max_dst_port] 29 | [-s src_port] [-S max_src_port] [-m min_ttl] [-M max_ttl] [-w response_timeout] 30 | [-W send_delay] [-a account_level] [-P payload_size] 31 | [-F interface] [-k skips] [-I consecutive_trace_count] 32 | [-H packets_per_hop] [-i incr_pattern] [-o output_style] [-t tcp_flags] 33 | target" >&2 34 | } 35 | 36 | warning () { 37 | echo "$prgname: Option '$1' is not implemented in this wrapper" >&2 38 | } 39 | 40 | 41 | PARSED=`getopt 'cCTfAhvRp:d:D:s:S:m:M:w:W:a:P:F:k:I:H:i:o:t:' "$@"` 42 | [ $? != 0 ] && exit 2 43 | 44 | eval set -- "$PARSED" 45 | 46 | while [ $# -gt 0 ] 47 | do 48 | case "$1" in 49 | -p) method=$2; shift 2 ;; 50 | -d) opts="$opts -p $2"; shift 2 ;; 51 | -s) opts="$opts --sport=$2"; shift 2 ;; 52 | -m) opts="$opts -f $2"; shift 2 ;; 53 | -M) opts="$opts -m $2"; shift 2 ;; 54 | -w) opts="$opts -w $2"; shift 2 ;; 55 | -W) sendwait=$2; shift 2 ;; 56 | -P) length=$2; shift 2 ;; 57 | -c) cont=100000; shift ;; 58 | -I) cont=$2; shift 2 ;; 59 | -H) opts="$opts -q $2"; shift 2 ;; 60 | -f) opts="$opts -F"; shift ;; 61 | -F) iface=$2; shift 2 ;; 62 | -A) opts="$opts -A"; shift ;; 63 | -o) [ $2 != "c" ] && warning $1; shift 2 ;; 64 | -t) case $2 in 65 | *S*) opts="$opts -O syn" ;; 66 | esac 67 | case $2 in 68 | *A*) opts="$opts -O ack" ;; 69 | esac 70 | case $2 in 71 | *R*) opts="$opts -O rst" ;; 72 | esac 73 | case $2 in 74 | *U*) opts="$opts -O urg" ;; 75 | esac 76 | case $2 in 77 | *P*) opts="$opts -O psh" ;; 78 | esac 79 | case $2 in 80 | *F*) opts="$opts -O fin" ;; 81 | esac 82 | case $2 in 83 | *E*) opts="$opts -O ece" ;; 84 | esac 85 | case $2 in 86 | *C*) opts="$opts -O cwr" ;; 87 | esac 88 | shift 2 ;; 89 | -[DSaki]) warning $1; shift 2 ;; 90 | -[TCR]) warning $1; shift ;; 91 | -h) usage; exit 0 ;; 92 | -v) echo "\"traceproto\"-compatible wrapper for new Linux Traceroute" >&2; 93 | exit 0 ;; 94 | --) shift; break ;; 95 | *) echo "$prgname: Internal parsing error" >&2; exit 2 ;; 96 | esac 97 | done 98 | 99 | 100 | 101 | [ $# -eq 0 ] && { 102 | usage 103 | exit 2 104 | } 105 | 106 | host=$1 107 | 108 | 109 | opts="-M $method $opts" 110 | opts="$opts -z $sendwait" 111 | [ -n "$iface" ] && opts="$opts -i $iface" 112 | 113 | [ -n "$TP_OUTPUT_STYLE" -a "$TP_OUTPUT_STYLE" != "classic" ] && { 114 | echo "$prgname: warning: only classic output style supported" >&2 115 | } 116 | 117 | [ -n "$TP_RA_SERVER" -a -z "$RA_SERVER" ] && RA_SERVER=$TP_RA_SERVER 118 | 119 | 120 | [ -z "$cont" ] && exec traceroute $opts $host $length 121 | 122 | while [ "$cont" -gt 0 ] 123 | do 124 | cont=$(($cont - 1)) 125 | traceroute $opts $host $length 126 | done 127 | 128 | -------------------------------------------------------------------------------- /traceroute/mod-raw.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | //#include 14 | 15 | #include "libsupp/icmp6.h" 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "traceroute.h" 23 | 24 | 25 | static sockaddr_any dest_addr = {{ 0, }, }; 26 | static int protocol = DEF_RAW_PROT; 27 | 28 | static char *data = NULL; 29 | static size_t *length_p; 30 | 31 | static int raw_sk = -1; 32 | static int last_ttl = 0; 33 | static int seq = 0; 34 | 35 | 36 | static int set_protocol (CLIF_option *optn, char *arg) { 37 | char *q; 38 | 39 | protocol = strtoul (arg, &q, 0); 40 | if (q == arg) { 41 | struct protoent *p = getprotobyname (arg); 42 | 43 | if (!p) return -1; 44 | protocol = p->p_proto; 45 | } 46 | 47 | return 0; 48 | } 49 | 50 | 51 | static CLIF_option raw_options[] = { 52 | { 0, "protocol", "PROT", "Use protocol %s (default is " 53 | _TEXT (DEF_RAW_PROT) ")", 54 | set_protocol, 0, 0, CLIF_ABBREV }, 55 | CLIF_END_OPTION 56 | }; 57 | 58 | 59 | static int raw_init (const sockaddr_any *dest, 60 | unsigned int port_seq, size_t *packet_len_p) { 61 | int i; 62 | int af = dest->sa.sa_family; 63 | 64 | dest_addr = *dest; 65 | dest_addr.sin.sin_port = 0; 66 | 67 | if (port_seq) protocol = port_seq; 68 | 69 | 70 | length_p = packet_len_p; 71 | 72 | if (*length_p && 73 | !(data = malloc (*length_p)) 74 | ) error ("malloc"); 75 | 76 | for (i = 0; i < *length_p; i++) 77 | data[i] = 0x40 + (i & 0x3f); 78 | 79 | 80 | raw_sk = socket (af, SOCK_RAW, protocol); 81 | if (raw_sk < 0) 82 | error_or_perm ("socket"); 83 | 84 | tune_socket (raw_sk); 85 | 86 | /* Don't want to catch packets from another hosts */ 87 | if (raw_can_connect () && 88 | connect (raw_sk, &dest_addr.sa, sizeof (dest_addr)) < 0 89 | ) error ("connect"); 90 | 91 | use_recverr (raw_sk); 92 | 93 | 94 | add_poll (raw_sk, POLLIN | POLLERR); 95 | 96 | return 0; 97 | } 98 | 99 | 100 | static void raw_send_probe (probe *pb, int ttl) { 101 | 102 | if (ttl != last_ttl) { 103 | 104 | set_ttl (raw_sk, ttl); 105 | 106 | last_ttl = ttl; 107 | } 108 | 109 | 110 | pb->send_time = get_time (); 111 | 112 | if (do_send (raw_sk, data, *length_p, &dest_addr) < 0) { 113 | pb->send_time = 0; 114 | return; 115 | } 116 | 117 | 118 | pb->seq = ++seq; 119 | 120 | return; 121 | } 122 | 123 | 124 | static probe *raw_check_reply (int sk, int err, sockaddr_any *from, 125 | char *buf, size_t len) { 126 | probe *pb; 127 | 128 | if (!equal_addr (&dest_addr, from)) 129 | return NULL; 130 | 131 | pb = probe_by_seq (seq); 132 | if (!pb) return NULL; 133 | 134 | if (!err) pb->final = 1; 135 | 136 | return pb; 137 | } 138 | 139 | 140 | static void raw_recv_probe (int sk, int revents) { 141 | 142 | if (!(revents & (POLLIN | POLLERR))) 143 | return; 144 | 145 | recv_reply (sk, !!(revents & POLLERR), raw_check_reply); 146 | } 147 | 148 | 149 | static void raw_expire_probe (probe *pb) { 150 | 151 | probe_done (pb); 152 | } 153 | 154 | 155 | static tr_module raw_ops = { 156 | .name = "raw", 157 | .init = raw_init, 158 | .send_probe = raw_send_probe, 159 | .recv_probe = raw_recv_probe, 160 | .expire_probe = raw_expire_probe, 161 | .options = raw_options, 162 | .one_per_time = 1, 163 | }; 164 | 165 | TR_MODULE (raw_ops); 166 | -------------------------------------------------------------------------------- /default.rules: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2000, 2001, 2007 Dmitry Butskoy 3 | # 4 | # License: GPL v2 or any later 5 | # 6 | # See COPYING for the status of this software. 7 | # 8 | 9 | # 10 | # Default a target`s Makefile. Useful for any things... 11 | # For some changes, copy it to a dir where needed and edit that copy. 12 | # 13 | 14 | 15 | ifndef srcdir 16 | rul := Make.rules 17 | path := $(word 1, $(wildcard ../$(rul) ../../$(rul))) 18 | ifeq ($(path),../$(rul)) 19 | srcdir = $(dir $(CURDIR)) 20 | endif 21 | ifeq ($(path),../../$(rul)) 22 | srcdir = $(dir $(patsubst %/,%,$(dir $(CURDIR)))) 23 | TARGET = .MODULE 24 | endif 25 | ifeq ($(srcdir),) 26 | $(error Cannot find srcdir (where $(rul) exists)) 27 | endif 28 | endif 29 | 30 | ifndef TARGET 31 | TARGET = $(notdir $(CURDIR)) 32 | endif 33 | 34 | include $(srcdir)/Make.rules 35 | 36 | 37 | # 38 | # LIBDIRS DEFAULTS 39 | # 40 | ifeq ($(filter $(TARGET),$(LIBDIRS)),$(TARGET)) 41 | 42 | ifeq ($(shared),yes) 43 | 44 | all: $(TARGET).so 45 | 46 | $(TARGET).so: $(OBJS) 47 | $(CC) -shared -o $@ -Wl,-soname -Wl,$@ $(OBJS) 48 | 49 | else 50 | 51 | all: $(TARGET).a 52 | 53 | $(TARGET).a: $(OBJS) 54 | rm -f $@ 55 | $(AR) -rc $@ $(OBJS) 56 | $(RANLIB) $@ 57 | 58 | endif 59 | 60 | install_what = $(wildcard $(TARGET).so $(TARGET).a) 61 | install_dir = $(libdir) 62 | install_includes = $(wildcard *.h) 63 | 64 | cross_stamp_file = $(wildcard .cross:*) 65 | ifeq ($(cross_stamp_file),) 66 | cross_stamp = .cross: 67 | else 68 | cross_stamp = $(cross_stamp_file) 69 | endif 70 | new_stamp = .cross:$(subst $(empty) ,:,$(CROSS)) 71 | ifneq ($(cross_stamp),$(new_stamp)) 72 | 73 | $(OBJS): force 74 | 75 | force: 76 | rm -f $(cross_stamp) > $(new_stamp) 77 | @rm -f *.o *.a *.lo *.so 78 | 79 | endif 80 | 81 | endif 82 | 83 | 84 | # 85 | # MODDIRS DEFAULTS 86 | # 87 | ifeq ($(filter $(TARGET),$(MODDIRS)),$(TARGET)) 88 | 89 | modules = $(filter-out $(SKIPDIRS), $(patsubst %/,%,$(wildcard */))) 90 | 91 | .PHONY: $(modules) 92 | 93 | what = all 94 | depend: what = depend 95 | clean: what = clean 96 | 97 | all depend clean: $(modules) 98 | 99 | $(modules): mkfile = $(if $(wildcard $@/Makefile),,-f $(srcdir)/default.rules) 100 | 101 | $(modules): force 102 | @$(MAKE) $(mkfile) -C $@ $(what) TARGET=.MODULE MODULE=$@ 103 | 104 | force: 105 | 106 | install_what = $(wildcard *.so) 107 | install_dir = $(libexecdir) 108 | 109 | endif 110 | 111 | 112 | # 113 | # MODDIRS` subdirectories (i.e., modules) defaults 114 | # 115 | ifeq ($(TARGET),.MODULE) 116 | 117 | ifndef MODULE 118 | MODULE = $(notdir $(CURDIR)) 119 | endif 120 | 121 | ifeq ($(shared),yes) 122 | 123 | all: ../$(MODULE).so 124 | 125 | ../$(MODULE).so: $(OBJS) $(LIBDEPS) 126 | $(CC) -shared -o $@ $(OBJS) $(LIBS) 127 | 128 | else 129 | 130 | all: ../$(MODULE).o 131 | 132 | ../$(MODULE).o: $(OBJS) 133 | $(LD) -r -o $@ $(OBJS) 134 | 135 | endif 136 | 137 | endif 138 | 139 | 140 | # 141 | # EXEDIRS DEFAULTS (for usual executables) 142 | # 143 | ifeq ($(filter $(TARGET),$(EXEDIRS)),$(TARGET)) 144 | 145 | ifeq ($(filter $(TARGET),$(MODUSERS)),$(TARGET)) 146 | MOD_OBJS = $(wildcard $(foreach dir,$(MODDIRS),$(srcdir)/$(dir)/*.o)) 147 | ifeq ($(shared),yes) 148 | override LDFLAGS := -rdynamic $(LDFLAGS) 149 | endif 150 | install_includes= $(wildcard $(foreach dir,$(INCLUDEDIRS),$(srcdir)/$(dir)/*.h)) 151 | install_includes:= $(filter-out $(srcdir)/include/version.h,$(install_includes)) 152 | else 153 | MOD_OBJS = 154 | endif 155 | 156 | all: $(TARGET) 157 | 158 | $(TARGET): $(OBJS) $(MOD_OBJS) $(LIBDEPS) 159 | $(CC) $(LDFLAGS) -o $@ $(OBJS) $(MOD_OBJS) $(LIBS) 160 | 161 | install_what = $(wildcard $(TARGET)) 162 | install_dir = $(if $(filter $(TARGET),$(SBINUSERS)),$(sbindir),$(bindir)) 163 | 164 | endif 165 | 166 | 167 | # 168 | # Install stuff 169 | # 170 | 171 | install_manuals = $(wildcard *.[0-9] *.[0-9]?) 172 | 173 | 174 | install: 175 | ifneq ($(install_dir),) 176 | @mkdir -p $(DESTDIR)$(install_dir) 177 | endif 178 | ifneq ($(install_what),) 179 | $(INSTALL) $(install_what) $(DESTDIR)$(install_dir) 180 | endif 181 | ifneq ($(install_includes),) 182 | @mkdir -p $(DESTDIR)$(includedir) 183 | $(INSTALL) $(install_includes) $(DESTDIR)$(includedir) 184 | endif 185 | @true 186 | ifneq ($(install_manuals),) 187 | $(foreach man,$(install_manuals),$(call inst_man,$(man))) 188 | define inst_man 189 | @mkdir -p $(DESTDIR)$(mandir)/man$(patsubst .%,%,$(suffix $(1))) 190 | cp -f $(1) $(DESTDIR)$(mandir)/man$(patsubst .%,%,$(suffix $(1))) 191 | 192 | endef 193 | endif 194 | -------------------------------------------------------------------------------- /libsupp/clif.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2000, 2003 Dmitry Butskoy 3 | 4 | License: LGPL v2.1 or any later 5 | 6 | See COPYING.LIB for the status of this software. 7 | */ 8 | 9 | #ifndef _CLIF_H 10 | #define _CLIF_H 11 | 12 | 13 | typedef struct CLIF_option_struct CLIF_option; 14 | struct CLIF_option_struct { 15 | const char *short_opt; 16 | const char *long_opt; 17 | const char *arg_name; 18 | const char *help_string; 19 | int (*function) (CLIF_option *optn, char *arg); 20 | void *data; 21 | int (*function_plus) (CLIF_option *optn, char *arg); 22 | unsigned int flags; 23 | }; 24 | #define CLIF_END_OPTION { 0, 0, 0, 0, 0, 0, 0, 0 } 25 | 26 | typedef struct CLIF_argument_struct CLIF_argument; 27 | struct CLIF_argument_struct { 28 | const char *name; 29 | const char *help_string; 30 | int (*function) (CLIF_argument *argm, char *arg, int index); 31 | void *data; 32 | unsigned int flags; 33 | }; 34 | #define CLIF_END_ARGUMENT { 0, 0, 0, 0, 0 } 35 | 36 | /* Argument flag bits. */ 37 | #define CLIF_MORE (0x01) /* null or several */ 38 | #define CLIF_STRICT (0x02) /* arg must be present */ 39 | #define CLIF_ACC_PREV (0x04) /* arg must be accompanied with previous */ 40 | 41 | 42 | /* Option flag bits. */ 43 | 44 | /* affected only by per-option flags */ 45 | #define CLIF_EXTRA (0x0001) /* don`t show in usage line */ 46 | #define CLIF_EXIT (0x0002) /* exit after handler return */ 47 | #define CLIF_EXCL (0x0004) /* at exclusive area */ 48 | 49 | /* affected by per-option flags and by common `parse_flags' argument 50 | of CLIF_parse_cmdline(). In last case appropriate bits are translated 51 | for all the options. 52 | */ 53 | #define CLIF_MAY_JOIN_ARG (0x0010) 54 | #define _CLIF_STRICT_JOIN_ARG (0x0020) 55 | #define CLIF_JOIN_ARG (CLIF_MAY_JOIN_ARG|_CLIF_STRICT_JOIN_ARG) 56 | #define CLIF_MAY_NOEQUAL (0x0040) 57 | #define _CLIF_STRICT_NOEQUAL (0x0080) 58 | #define CLIF_NOEQUAL (CLIF_MAY_NOEQUAL|_CLIF_STRICT_NOEQUAL) 59 | #define CLIF_MAY_KEYWORD (0x0100) 60 | #define _CLIF_STRICT_KEYWORD (0x0200) 61 | #define CLIF_KEYWORD (CLIF_MAY_KEYWORD|_CLIF_STRICT_KEYWORD) 62 | #define CLIF_MAY_ONEDASH (0x0400) 63 | #define _CLIF_STRICT_ONEDASH (0x0800) 64 | #define CLIF_ONEDASH (CLIF_MAY_ONEDASH|_CLIF_STRICT_ONEDASH) 65 | #define CLIF_OPTARG (0x1000) /* allow missing optarg */ 66 | #define CLIF_ABBREV (0x2000) /* allow long opt abbreviation */ 67 | #define CLIF_SEVERAL (0x4000) /* several args in one opt`s arg */ 68 | 69 | /* affected only by common `parse_flags' arg of CLIF_parse_cmdline() . */ 70 | #define CLIF_HELP_EMPTY (0x10000) /* print help on empty cmdline */ 71 | #define CLIF_POSIX (0x20000) /* follow POSIX standard */ 72 | #define CLIF_FIRST_GROUP (0x40000) /* first arg - options` group */ 73 | #define CLIF_STRICT_EXCL (0x80000) /* at least one exclusive */ 74 | #define CLIF_SILENT (0x100000) /* no errors on stderr */ 75 | 76 | #define CLIF_MIN_ABBREV 2 /* a minimal match length in abbrev */ 77 | 78 | 79 | extern int CLIF_parse (int argc, char **argv, CLIF_option *option_list, 80 | CLIF_argument *arg_list, unsigned int parse_flags); 81 | /* history compatibility... */ 82 | #define CLIF_parse_cmdline(ARGC,ARGV,OPTN,ARGS,FLAGS) \ 83 | CLIF_parse (ARGC, ARGV, OPTN, ARGS, FLAGS) 84 | 85 | extern void CLIF_print_options (const char *header, 86 | const CLIF_option *option_list); 87 | extern void CLIF_print_arguments (const char *header, 88 | const CLIF_argument *argument_list); 89 | extern void CLIF_print_usage (const char *header, const char *progname, 90 | const CLIF_option *option_list, 91 | const CLIF_argument *argument_list); 92 | 93 | extern int CLIF_current_help (void); 94 | 95 | /* Common useful option handlers. */ 96 | extern int CLIF_version_handler (CLIF_option *optn, char *arg); 97 | extern int CLIF_set_flag (CLIF_option *optn, char *arg); 98 | extern int CLIF_unset_flag (CLIF_option *optn, char *arg); 99 | extern int CLIF_set_string (CLIF_option *optn, char *arg); 100 | extern int CLIF_set_int (CLIF_option *optn, char *arg); 101 | extern int CLIF_set_uint (CLIF_option *optn, char *arg); 102 | extern int CLIF_set_double (CLIF_option *optn, char *arg); 103 | extern int CLIF_call_func (CLIF_option *optn, char *arg); 104 | 105 | extern int CLIF_arg_string (CLIF_argument *argm, char *arg, int index); 106 | extern int CLIF_arg_int (CLIF_argument *argm, char *arg, int index); 107 | extern int CLIF_arg_uint (CLIF_argument *argm, char *arg, int index); 108 | extern int CLIF_arg_double (CLIF_argument *argm, char *arg, int index); 109 | extern int CLIF_arg_func (CLIF_argument *argm, char *arg, int index); 110 | 111 | 112 | /* Some useful macros. */ 113 | 114 | #define CLIF_HELP_OPTION \ 115 | { 0, "help", 0, "Read this help and exit", \ 116 | CLIF_call_func, CLIF_current_help, 0, CLIF_EXTRA | CLIF_EXIT } 117 | #define CLIF_VERSION_OPTION(STR) \ 118 | { "V", "version", 0, "Print version info and exit", \ 119 | CLIF_version_handler, STR, 0, CLIF_EXTRA | CLIF_EXIT } 120 | 121 | #endif /* _CLIF_H */ 122 | -------------------------------------------------------------------------------- /Make.rules: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2000, 2001, 2007 Dmitry Butskoy 3 | # 4 | # License: GPL v2 or any later 5 | # 6 | # See COPYING for the status of this software. 7 | # 8 | 9 | # 10 | # Common rule and variable definitions. 11 | # This file should be included by main and by per-target Makefiles. 12 | # 13 | 14 | 15 | ifndef srcdir 16 | $(error srcdir variable not defined) 17 | endif 18 | 19 | 20 | MAKE = make --no-print-directory -r 21 | 22 | 23 | # Use env=yes on cmdline to inherit environment values 24 | 25 | ifeq ($(env),yes) 26 | define set 27 | $(eval ifneq ($$(origin $(1)),environment) 28 | $(1) = $(2) 29 | else 30 | override MAKE := $(1)="$($(strip $(1)))" $(MAKE) 31 | endif) 32 | endef 33 | else 34 | set = $(eval $(1) = $(2)) 35 | endif 36 | 37 | 38 | $(call set, CROSS, ) 39 | $(call set, CC, $$(CROSS)gcc) 40 | $(call set, AS, $$(CROSS)as) 41 | $(call set, LD, $$(CROSS)ld) 42 | $(call set, DEPEND, $$(CROSS)gcc -MM -MG) 43 | $(call set, AR, $$(CROSS)ar) 44 | $(call set, RANLIB, $$(CROSS)ranlib) 45 | $(call set, INSTALL, cp) 46 | $(call set, INDENT, true) 47 | 48 | gcc = $(findstring gcc,$(CC)) 49 | $(call set, CFLAGS, $(if $(gcc), -O2 -Wall, -O)) 50 | $(call set, CPPFLAGS, ) 51 | $(call set, LDFLAGS, -s) 52 | $(call set, LIBS, ) 53 | 54 | 55 | # install stuff 56 | prefix = /usr/local 57 | 58 | ifneq ($(wildcard /lib64/libc.* /usr/lib64/libc.*),) 59 | lib := lib64 60 | else 61 | lib := lib 62 | endif 63 | 64 | exec_prefix = $(prefix) 65 | bindir = $(exec_prefix)/bin 66 | sbindir = $(exec_prefix)/sbin 67 | libdir = $(exec_prefix)/$(lib) 68 | libexecdir = $(exec_prefix)/libexec/$(NAME) 69 | sysconfdir = $(prefix)/etc 70 | includedir = $(prefix)/include 71 | datadir = $(prefix)/share 72 | mandir = $(datadir)/man 73 | infodir = $(datadir)/info 74 | localstatedir = $(prefix)/var 75 | sharedstatedir = $(prefix)/com 76 | 77 | DESTDIR = 78 | 79 | 80 | # layout stuff 81 | SKIPDIRS = tmp% 82 | INCLUDEDIRS = include% 83 | LIBDIRS = lib% 84 | MODDIRS = mod% 85 | SKIPINSTALL = test% 86 | 87 | 88 | include $(srcdir)/Make.defines 89 | 90 | 91 | ifndef NAME 92 | NAME = $(notdir $(srcdir)) 93 | endif 94 | 95 | 96 | ifndef subdirs 97 | ifeq ($(TARGET),.MAIN) 98 | # for better performance... 99 | subdirs := $(patsubst %/,%,$(wildcard */)) 100 | else 101 | subdirs := $(patsubst $(srcdir)/%/,%,$(filter %/,$(wildcard $(srcdir)/*/))) 102 | endif 103 | subdirs := $(filter-out $(SKIPDIRS), $(subdirs)) 104 | endif 105 | 106 | install install-%: subdirs := $(filter-out $(SKIPINSTALL), $(subdirs)) 107 | 108 | 109 | override MAKE += srcdir=$(srcdir) subdirs="$(subdirs)" shared=$(shared) 110 | 111 | 112 | INCLUDEDIRS := $(filter $(INCLUDEDIRS), $(subdirs)) 113 | LIBDIRS := $(filter $(LIBDIRS), $(subdirs)) 114 | MODDIRS := $(filter $(MODDIRS), $(subdirs)) 115 | EXEDIRS := $(filter-out $(INCLUDEDIRS) $(LIBDIRS) $(MODDIRS), $(subdirs)) 116 | MODUSERS := $(filter $(MODUSERS), $(subdirs)) 117 | SBINUSERS := $(filter $(SBINUSERS), $(subdirs)) 118 | 119 | LIBDIRS := $(filter-out $(LIBLAST),$(LIBDIRS)) $(filter $(LIBDIRS),$(LIBLAST)) 120 | 121 | 122 | includes = $(foreach dir, $(INCLUDEDIRS) $(LIBDIRS), $(srcdir)/$(dir)) 123 | 124 | ifneq ($(gcc),) 125 | CPATH = $(subst $(empty) ,:,$(includes)) 126 | export CPATH 127 | else 128 | override CPPFLAGS += $(patsubst %,-I%,$(includes)) 129 | endif 130 | 131 | libraries = $(foreach dir, $(filter lib%,$(LIBDIRS)), $(srcdir)/$(dir)) 132 | 133 | vpath lib%.so $(libraries) 134 | vpath lib%.a $(libraries) 135 | 136 | _libs = $(strip $(foreach _lib,$(LIBDIRS),\ 137 | $(if $(filter lib%,$(_lib)),\ 138 | $(patsubst lib%,-l%,$(_lib)),\ 139 | $(wildcard $(srcdir)/$(_lib)/$(_lib).so \ 140 | $(srcdir)/$(_lib)/$(_lib).a)))) 141 | 142 | override LIBS := $(_libs) -lm $(LIBS) 143 | 144 | ifeq ($(CC),gcc) 145 | LIBRARY_PATH = $(subst $(empty) ,:,$(libraries)) 146 | export LIBRARY_PATH 147 | else 148 | override LIBS += $(patsubst %,-L%,$(libraries)) 149 | endif 150 | 151 | LIBDEPS = $(filter-out -L%,$(LIBS)) 152 | 153 | 154 | # 155 | # SUBDIRS STUFF 156 | # 157 | 158 | ifneq ($(TARGET),.MAIN) 159 | 160 | obj := o 161 | ifeq ($(shared),yes) 162 | ifneq ($(PIC),no) 163 | ifeq ($(filter $(TARGET),$(LIBDIRS) $(MODDIRS) .MODULE),$(TARGET)) 164 | obj := lo 165 | endif 166 | endif 167 | endif 168 | 169 | sources = $(wildcard *.c) 170 | OBJS = $(sources:.c=.$(obj)) 171 | 172 | 173 | .PHONY: dummy all depend install clean force 174 | 175 | dummy: all 176 | 177 | 178 | clean: 179 | rm -f *.o *.a *.lo *.so $(TARGET) core a.out 180 | 181 | 182 | ifneq ($(sources),) 183 | depend: $(sources) 184 | $(DEPEND) $(CFLAGS) $(CPPFLAGS) $^ >.depend 185 | else 186 | depend: 187 | @true 188 | endif 189 | 190 | 191 | %.o: %.c 192 | $(CC) $(CFLAGS) $(CPPFLAGS) -c $*.c 193 | 194 | %.lo: %.c 195 | $(CC) -fPIC $(CFLAGS) $(CPPFLAGS) -o $*.lo -c $*.c 196 | 197 | %.o: %.s 198 | $(AS) -o $*.o $*.s 199 | 200 | %.o: %.S 201 | $(CC) -traditional $(CPPFLAGS) -c $*.S 202 | 203 | # include if it is present only... 204 | ifeq (.depend, $(wildcard .depend)) 205 | include .depend 206 | endif 207 | 208 | endif 209 | 210 | # 211 | # ...end of SUBDIRS STUFF 212 | # 213 | 214 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## traceroute-android-executable 2 | 3 | --- 4 | 5 | traceroute-android-executable frok from [https://sourceforge.net/projects/traceroute/files/](https://sourceforge.net/projects/traceroute/files/),you can visit [http://traceroute.sourceforge.net/](http://traceroute.sourceforge.net/) for more details. 6 | 7 | ### what's traceroute 8 | 9 | Traceroute tracks the route packets taken from an IP network on their way to a given host. It utilizes the IP protocol's time to live (TTL) field and attempts to elicit an ICMP TIME_EXCEEDED response from each gateway along the path to the host. See traceroute(8) in the manual of your system for more info. 10 | 11 | It is well-known application, appeared long time ago. Since 2000, its initial implementation is not developed, and does not follow the modern network needs. There was already some attempts to continue or re-write it, or to create similar application with additional features, but mostly such works either provides things partially or have considerably different interface. 12 | 13 | This code was written from the scratch, using some ideas of Olaf Kirch's traceroute, the original implementation of Van Jacobson and some current BSD's ones. It is fully compatible with the original traceroute from Van Jacobson, wide used before for years. 14 | 15 | **Note**, that this implementation is intended for Linux only. It utilizes some currently Linux-specific features (including MSG_ERRQUEUE for recvmsg(2)), which allow such things like the use by unprivileged users (without setuid bit) for some type of tracerouting. The Linux kernel 2.6 or higher required. 16 | 17 | ### Main features: 18 | 19 | - Command line and output compatible with the original traceroute 20 | - Full support for both IPv4 and IPv6 protocols 21 | - Ability to send several probe packets at a time (most cases much faster results) 22 | - Several tracerouting methods, including 23 | * UDP datagrams (including udplite and udp to particlular port) 24 | * ICMP ECHO packets 25 | * TCP SYN requests (in general, any TCP request with various flags and options) 26 | * Generic IP datagrams 27 | - UDP methods do not require root privileges 28 | - Performing AS path lookups for returned addresses 29 | - Showing of ICMP extensions, including MPLS 30 | - Wrappers for tcptraceroute and others 31 | - and much more, see traceroute(8) 32 | 33 | ### how to build with ndk-build 34 | 35 | 1.download [Android NDK](https://developer.android.google.cn/ndk/downloads/) 36 | 37 | 2.add NDK_HOME to your environment variables file 38 | 39 | for mac user 40 | 41 | > vim ~/.bash_profile 42 | 43 | for linux user 44 | 45 | > vim ~/.bash_rc 46 | 47 | ``` 48 | export ANDROID_HOME=~/Library/Android/sdk 49 | export NDK_HOME=${ANDROID_HOME}/ndk-bundle 50 | export PATH=${PATH}:${NDK_HOME} 51 | ``` 52 | 53 | then source environment variables file 54 | 55 | > source ~/.bash_profile 56 | 57 | > source ~/.bash_rc 58 | 59 | 3.clone project 60 | 61 | > git clone git@github.com:wangjing53406/traceroute-android-executable.git 62 | 63 | 4.use build script to build 64 | 65 | > cd traceroute-android-executable 66 | 67 | > ./build.sh 68 | 69 | ### traceroute sample 70 | 71 | on the android result: 72 | 73 | ``` 74 | HWCOL:/data/data/com.**.** $ ./traceroute www.google.com 75 | traceroute to www.google.com (199.59.148.209), 30 hops max, 60 byte packets 76 | 1 bogon (172.16.32.1) 2.534 ms 2.519 ms 5.096 ms 77 | 2 bogon (10.10.10.1) 5.208 ms 4.526 ms 4.979 ms 78 | 3 * * * 79 | 4 bogon (10.0.12.141) 5.133 ms 4.817 ms 4.265 ms 80 | 5 bogon (10.0.12.230) 4.427 ms 5.010 ms 6.368 ms 81 | 6 124.65.242.98 (124.65.242.98) 43.360 ms 38.183 ms 37.547 ms 82 | 7 * * * 83 | 8 61.51.112.21 (61.51.112.21) 14.483 ms 15.009 ms 14.111 ms 84 | 9 123.126.7.141 (123.126.7.141) 26.295 ms * 61.148.156.65 (61.148.156.65) 13.028 ms 85 | 10 124.65.194.161 (124.65.194.161) 12.287 ms 124.65.194.29 (124.65.194.29) 6.079 ms 123.126.0.253 (123.126.0.253) 5.789 ms 86 | 11 * * * 87 | 12 * * * 88 | 13 * * * 89 | 14 * * * 90 | 15 * * * 91 | 16 * * * 92 | 17 * * * 93 | 18 * * * 94 | 19 * * * 95 | 20 * * * 96 | 21 * * * 97 | 22 * * * 98 | 23 * * * 99 | 24 * * * 100 | 25 * * * 101 | 26 * * * 102 | 27 * * * 103 | 28 * * * 104 | 29 * * * 105 | 30 * * * 106 | ``` 107 | 108 | on the computer result: 109 | 110 | ``` 111 | ~ traceroute www.google.com 112 | traceroute to www.google.com (199.59.148.209), 64 hops max, 52 byte packets 113 | 1 bogon (172.16.30.1) 2.450 ms 1.484 ms 1.350 ms 114 | 2 bogon (10.10.10.1) 2.199 ms 1.359 ms 1.304 ms 115 | 3 * * * 116 | 4 * bogon (10.0.12.141) 3.297 ms 4.251 ms 117 | 5 bogon (10.0.12.230) 4.993 ms 20.059 ms 60.508 ms 118 | 6 124.65.242.98 (124.65.242.98) 14.453 ms 8.348 ms 7.540 ms 119 | 7 * * * 120 | 8 61.51.112.21 (61.51.112.21) 7.441 ms 6.072 ms 8.698 ms 121 | 9 61.148.156.229 (61.148.156.229) 7.174 ms 122 | 123.126.8.245 (123.126.8.245) 9.173 ms 123 | 61.148.156.177 (61.148.156.177) 7.604 ms 124 | 10 202.96.12.33 (202.96.12.33) 4.741 ms 125 | 124.65.194.17 (124.65.194.17) 6.080 ms 126 | 124.65.194.173 (124.65.194.173) 14.929 ms 127 | 11 * * * 128 | 12 * * * 129 | 13 * * * 130 | 14 * * * 131 | 15 * * * 132 | 16 * * * 133 | 17 * * * 134 | 18 * * * 135 | 19 * * * 136 | 20 * * * 137 | 21 * * * 138 | 22 * * * 139 | 23 * * * 140 | 24 * * * 141 | 25 * * * 142 | 26 * * * 143 | 27 * * * 144 | 28 * * * 145 | 29 * * * 146 | 30 * * * 147 | ``` 148 | 149 | if you don't want to build source code, you can download it from [libs](libs) folder. 150 | 151 | enjoying traceroute! 152 | -------------------------------------------------------------------------------- /traceroute/mod-udp.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "traceroute.h" 18 | 19 | 20 | #ifndef IPPROTO_UDPLITE 21 | #define IPPROTO_UDPLITE 136 22 | #endif 23 | 24 | #ifndef UDPLITE_SEND_CSCOV 25 | #define UDPLITE_SEND_CSCOV 10 26 | #define UDPLITE_RECV_CSCOV 11 27 | #endif 28 | 29 | 30 | static sockaddr_any dest_addr = {{ 0, }, }; 31 | static unsigned int curr_port = 0; 32 | static unsigned int protocol = IPPROTO_UDP; 33 | 34 | 35 | static char *data = NULL; 36 | static size_t *length_p; 37 | 38 | static void fill_data (size_t *packet_len_p) { 39 | int i; 40 | 41 | length_p = packet_len_p; 42 | 43 | if (*length_p && 44 | !(data = malloc (*length_p)) 45 | ) error ("malloc"); 46 | 47 | for (i = 0; i < *length_p; i++) 48 | data[i] = 0x40 + (i & 0x3f); 49 | 50 | return; 51 | } 52 | 53 | 54 | static int udp_default_init (const sockaddr_any *dest, 55 | unsigned int port_seq, size_t *packet_len_p) { 56 | 57 | curr_port = port_seq ? port_seq : DEF_START_PORT; 58 | 59 | dest_addr = *dest; 60 | dest_addr.sin.sin_port = htons (curr_port); 61 | 62 | fill_data (packet_len_p); 63 | 64 | return 0; 65 | } 66 | 67 | 68 | static int udp_init (const sockaddr_any *dest, 69 | unsigned int port_seq, size_t *packet_len_p) { 70 | 71 | dest_addr = *dest; 72 | 73 | if (!port_seq) port_seq = DEF_UDP_PORT; 74 | dest_addr.sin.sin_port = htons ((uint16_t) port_seq); 75 | 76 | fill_data (packet_len_p); 77 | 78 | return 0; 79 | } 80 | 81 | 82 | static unsigned int coverage = 0; 83 | #define MIN_COVERAGE (sizeof (struct udphdr)) 84 | 85 | static void set_coverage (int sk) { 86 | int val = MIN_COVERAGE; 87 | 88 | if (setsockopt (sk, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV, 89 | &coverage, sizeof (coverage)) < 0 90 | ) error ("UDPLITE_SEND_CSCOV"); 91 | 92 | if (setsockopt (sk, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV, 93 | &val, sizeof (val)) < 0 94 | ) error ("UDPLITE_RECV_CSCOV"); 95 | } 96 | 97 | static CLIF_option udplite_options[] = { 98 | { 0, "coverage", "NUM", "Set udplite send coverage to %s (default is " 99 | _TEXT(MIN_COVERAGE) ")", 100 | CLIF_set_uint, &coverage, 0, CLIF_ABBREV }, 101 | CLIF_END_OPTION 102 | }; 103 | 104 | static int udplite_init (const sockaddr_any *dest, 105 | unsigned int port_seq, size_t *packet_len_p) { 106 | 107 | dest_addr = *dest; 108 | 109 | if (!port_seq) port_seq = DEF_UDP_PORT; /* XXX: Hmmm... */ 110 | dest_addr.sin.sin_port = htons ((uint16_t) port_seq); 111 | 112 | protocol = IPPROTO_UDPLITE; 113 | 114 | if (!coverage) coverage = MIN_COVERAGE; 115 | 116 | fill_data (packet_len_p); 117 | 118 | return 0; 119 | } 120 | 121 | 122 | static void udp_send_probe (probe *pb, int ttl) { 123 | int sk; 124 | int af = dest_addr.sa.sa_family; 125 | 126 | 127 | sk = socket (af, SOCK_DGRAM, protocol); 128 | if (sk < 0) error ("socket"); 129 | 130 | tune_socket (sk); /* common stuff */ 131 | 132 | if (coverage) set_coverage (sk); /* udplite case */ 133 | 134 | set_ttl (sk, ttl); 135 | 136 | 137 | if (connect (sk, &dest_addr.sa, sizeof (dest_addr)) < 0) 138 | error ("connect"); 139 | 140 | use_recverr (sk); 141 | 142 | 143 | pb->send_time = get_time (); 144 | 145 | if (do_send (sk, data, *length_p, NULL) < 0) { 146 | close (sk); 147 | pb->send_time = 0; 148 | return; 149 | } 150 | 151 | 152 | pb->sk = sk; 153 | 154 | add_poll (sk, POLLIN | POLLERR); 155 | 156 | pb->seq = dest_addr.sin.sin_port; 157 | 158 | if (curr_port) { /* traditional udp method */ 159 | curr_port++; 160 | dest_addr.sin.sin_port = htons (curr_port); /* both ipv4 and ipv6 */ 161 | } 162 | 163 | return; 164 | } 165 | 166 | 167 | static probe *udp_check_reply (int sk, int err, sockaddr_any *from, 168 | char *buf, size_t len) { 169 | probe *pb; 170 | 171 | pb = probe_by_sk (sk); 172 | if (!pb) return NULL; 173 | 174 | if (pb->seq != from->sin.sin_port) 175 | return NULL; 176 | 177 | if (!err) pb->final = 1; 178 | 179 | return pb; 180 | } 181 | 182 | 183 | static void udp_recv_probe (int sk, int revents) { 184 | 185 | if (!(revents & (POLLIN | POLLERR))) 186 | return; 187 | 188 | recv_reply (sk, !!(revents & POLLERR), udp_check_reply); 189 | } 190 | 191 | 192 | static void udp_expire_probe (probe *pb) { 193 | 194 | probe_done (pb); 195 | } 196 | 197 | 198 | /* All three modules share the same methods except the init... */ 199 | 200 | static tr_module default_ops = { 201 | .name = "default", 202 | .init = udp_default_init, 203 | .send_probe = udp_send_probe, 204 | .recv_probe = udp_recv_probe, 205 | .expire_probe = udp_expire_probe, 206 | .header_len = sizeof (struct udphdr), 207 | }; 208 | 209 | TR_MODULE (default_ops); 210 | 211 | 212 | static tr_module udp_ops = { 213 | .name = "udp", 214 | .init = udp_init, 215 | .send_probe = udp_send_probe, 216 | .recv_probe = udp_recv_probe, 217 | .expire_probe = udp_expire_probe, 218 | .header_len = sizeof (struct udphdr), 219 | }; 220 | 221 | TR_MODULE (udp_ops); 222 | 223 | 224 | static tr_module udplite_ops = { 225 | .name = "udplite", 226 | .init = udplite_init, 227 | .send_probe = udp_send_probe, 228 | .recv_probe = udp_recv_probe, 229 | .expire_probe = udp_expire_probe, 230 | .header_len = sizeof (struct udphdr), 231 | .options = udplite_options, 232 | }; 233 | 234 | TR_MODULE (udplite_ops); 235 | -------------------------------------------------------------------------------- /traceroute/mod-tcpconn.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | //#include 14 | 15 | #include "libsupp/icmp6.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "traceroute.h" 25 | 26 | 27 | static sockaddr_any dest_addr = {{ 0, }, }; 28 | 29 | static int icmp_sk = -1; 30 | 31 | 32 | static int tcp_init (const sockaddr_any *dest, 33 | unsigned int port_seq, size_t *packet_len_p) { 34 | int af = dest->sa.sa_family; 35 | 36 | dest_addr = *dest; 37 | dest_addr.sin.sin_port = htons (DEF_TCP_PORT); 38 | 39 | if (port_seq) 40 | dest_addr.sin.sin_port = htons (port_seq); 41 | 42 | 43 | /* Currently an ICMP socket is the only way 44 | to obtain the needed info... 45 | */ 46 | icmp_sk = socket (af, SOCK_RAW, (af == AF_INET) ? IPPROTO_ICMP 47 | : IPPROTO_ICMPV6); 48 | if (icmp_sk < 0) 49 | error_or_perm ("socket"); 50 | 51 | /* icmp_sk not need full tune_socket() here, just a receiving one */ 52 | bind_socket (icmp_sk); 53 | use_timestamp (icmp_sk); 54 | use_recv_ttl (icmp_sk); 55 | 56 | add_poll (icmp_sk, POLLIN); 57 | 58 | return 0; 59 | } 60 | 61 | 62 | static void tcp_send_probe (probe *pb, int ttl) { 63 | int sk; 64 | int af = dest_addr.sa.sa_family; 65 | sockaddr_any addr; 66 | socklen_t length = sizeof (addr); 67 | 68 | 69 | sk = socket (af, SOCK_STREAM, 0); 70 | if (sk < 0) error ("socket"); 71 | 72 | tune_socket (sk); /* common stuff */ 73 | 74 | set_ttl (sk, ttl); 75 | 76 | 77 | pb->send_time = get_time (); 78 | 79 | if (connect (sk, &dest_addr.sa, sizeof (dest_addr)) < 0) { 80 | if (errno != EINPROGRESS) 81 | error ("connect"); 82 | } 83 | 84 | 85 | if (getsockname (sk, &addr.sa, &length) < 0) 86 | error ("getsockname"); 87 | 88 | pb->seq = addr.sin.sin_port; /* both ipv4/ipv6 */ 89 | 90 | pb->sk = sk; 91 | 92 | add_poll (sk, POLLERR | POLLHUP | POLLOUT); 93 | 94 | return; 95 | } 96 | 97 | 98 | static probe *tcp_check_reply (int sk, int err, sockaddr_any *from, 99 | char *buf, size_t len) { 100 | int af = dest_addr.sa.sa_family; 101 | int type, code, info; 102 | probe *pb; 103 | struct tcphdr *tcp; 104 | 105 | 106 | if (len < sizeof (struct icmphdr)) 107 | return NULL; 108 | 109 | 110 | if (af == AF_INET) { 111 | struct icmp *icmp = (struct icmp *) buf; 112 | struct iphdr *ip; 113 | int hlen; 114 | 115 | type = icmp->icmp_type; 116 | code = icmp->icmp_code; 117 | info = icmp->icmp_void; 118 | 119 | if (type != ICMP_TIME_EXCEEDED && type != ICMP_DEST_UNREACH) 120 | return NULL; 121 | 122 | if (len < sizeof (struct icmphdr) + sizeof (struct iphdr) + 8) 123 | /* `8' - rfc1122: 3.2.2 */ 124 | return NULL; 125 | 126 | ip = (struct iphdr *) (((char *)icmp) + sizeof(struct icmphdr)); 127 | hlen = ip->ihl << 2; 128 | 129 | if (len < sizeof (struct icmphdr) + hlen + 8) 130 | return NULL; 131 | if (ip->protocol != IPPROTO_TCP) 132 | return NULL; 133 | 134 | tcp = (struct tcphdr *) (((char *) ip) + hlen); 135 | 136 | } 137 | else { /* AF_INET6 */ 138 | struct icmp6_hdr *icmp6 = (struct icmp6_hdr *) buf; 139 | struct ip6_hdr *ip6; 140 | 141 | type = icmp6->icmp6_type; 142 | code = icmp6->icmp6_code; 143 | info = icmp6->icmp6_mtu; 144 | 145 | if (type != ICMP6_TIME_EXCEEDED && 146 | type != ICMP6_DST_UNREACH && 147 | type != ICMP6_PACKET_TOO_BIG 148 | ) return NULL; 149 | 150 | if (len < sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr) + 8) 151 | return NULL; 152 | 153 | ip6 = (struct ip6_hdr *) (icmp6 + 1); 154 | if (ip6->ip6_nxt != IPPROTO_TCP) 155 | return NULL; 156 | 157 | tcp = (struct tcphdr *) (ip6 + 1); 158 | 159 | } 160 | 161 | 162 | if (tcp->dest != dest_addr.sin.sin_port) 163 | return NULL; 164 | 165 | pb = probe_by_seq (tcp->source); 166 | if (!pb) return NULL; 167 | 168 | 169 | /* here only, high level has no data to do this */ 170 | parse_icmp_res (pb, type, code, info); 171 | 172 | return pb; 173 | } 174 | 175 | 176 | static void tcp_recv_probe (int sk, int revents) { 177 | 178 | if (sk != icmp_sk) { /* a tcp socket */ 179 | probe *pb; 180 | 181 | pb = probe_by_sk (sk); 182 | if (!pb) { 183 | del_poll (sk); 184 | return; 185 | } 186 | 187 | 188 | /* do connect() again and check errno, regardless of revents */ 189 | if (connect (sk, &dest_addr.sa, sizeof (dest_addr)) < 0) { 190 | if (errno != EISCONN && errno != ECONNREFUSED) 191 | return; /* ICMP say more */ 192 | } 193 | 194 | /* we have reached the dest host (either connected or refused) */ 195 | 196 | memcpy (&pb->res, &dest_addr, sizeof (pb->res)); 197 | 198 | pb->final = 1; 199 | 200 | pb->recv_time = get_time (); 201 | 202 | probe_done (pb); 203 | 204 | return; 205 | } 206 | 207 | 208 | /* ICMP stuff */ 209 | 210 | if (!(revents & POLLIN)) 211 | return; 212 | 213 | recv_reply (icmp_sk, 0, tcp_check_reply); 214 | } 215 | 216 | 217 | static void tcp_expire_probe (probe *pb) { 218 | 219 | probe_done (pb); 220 | } 221 | 222 | 223 | static tr_module tcp_ops = { 224 | .name = "tcpconn", 225 | .init = tcp_init, 226 | .send_probe = tcp_send_probe, 227 | .recv_probe = tcp_recv_probe, 228 | .expire_probe = tcp_expire_probe, 229 | }; 230 | 231 | TR_MODULE (tcp_ops); 232 | -------------------------------------------------------------------------------- /traceroute/mod-icmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | #include "traceroute.h" 22 | 23 | 24 | static sockaddr_any dest_addr = {{ 0, }, }; 25 | static uint16_t seq = 1; 26 | static uint16_t ident = 0; 27 | 28 | static char *data; 29 | static size_t *length_p; 30 | 31 | static int icmp_sk = -1; 32 | static int last_ttl = 0; 33 | 34 | static int raw = 0; 35 | static int dgram = 0; 36 | 37 | 38 | static CLIF_option icmp_options[] = { 39 | { 0, "raw", 0, "Use raw sockets way only. Default is try this way " 40 | "first (probably not allowed for unprivileged users), " 41 | "then try dgram", 42 | CLIF_set_flag, &raw, 0, CLIF_EXCL }, 43 | { 0, "dgram", 0, "Use dgram sockets way only. May be not implemented " 44 | "by old kernels or restricted by sysadmins", 45 | CLIF_set_flag, &dgram, 0, CLIF_EXCL }, 46 | CLIF_END_OPTION 47 | }; 48 | 49 | 50 | static int icmp_init (const sockaddr_any *dest, 51 | unsigned int port_seq, size_t *packet_len_p) { 52 | int i; 53 | int af = dest->sa.sa_family; 54 | int protocol; 55 | 56 | dest_addr = *dest; 57 | dest_addr.sin.sin_port = 0; 58 | 59 | if (port_seq) seq = port_seq; 60 | 61 | length_p = packet_len_p; 62 | if (*length_p < sizeof (struct icmphdr)) 63 | *length_p = sizeof (struct icmphdr); 64 | 65 | data = malloc (*length_p); 66 | if (!data) error ("malloc"); 67 | 68 | for (i = sizeof (struct icmphdr); i < *length_p; i++) 69 | data[i] = 0x40 + (i & 0x3f); 70 | 71 | 72 | protocol = (af == AF_INET) ? IPPROTO_ICMP : IPPROTO_ICMPV6; 73 | 74 | if (!raw) { 75 | icmp_sk = socket (af, SOCK_DGRAM, protocol); 76 | if (icmp_sk < 0 && dgram) 77 | error ("socket"); 78 | } 79 | 80 | if (!dgram) { 81 | int raw_sk = socket (af, SOCK_RAW, protocol); 82 | if (raw_sk < 0) { 83 | if (raw || icmp_sk < 0) 84 | error_or_perm ("socket"); 85 | dgram = 1; 86 | } else { 87 | /* prefer the traditional "raw" way when possible */ 88 | close (icmp_sk); 89 | icmp_sk = raw_sk; 90 | } 91 | } 92 | 93 | 94 | tune_socket (icmp_sk); 95 | 96 | /* Don't want to catch packets from another hosts */ 97 | if (raw_can_connect () && 98 | connect (icmp_sk, &dest_addr.sa, sizeof (dest_addr)) < 0 99 | ) error ("connect"); 100 | 101 | use_recverr (icmp_sk); 102 | 103 | 104 | if (dgram) { 105 | sockaddr_any addr; 106 | socklen_t len = sizeof (addr); 107 | 108 | if (getsockname (icmp_sk, &addr.sa, &len) < 0) 109 | error ("getsockname"); 110 | ident = ntohs (addr.sin.sin_port); /* both IPv4 and IPv6 */ 111 | 112 | } else 113 | ident = getpid () & 0xffff; 114 | 115 | 116 | add_poll (icmp_sk, POLLIN | POLLERR); 117 | 118 | return 0; 119 | } 120 | 121 | 122 | static void icmp_send_probe (probe *pb, int ttl) { 123 | int af = dest_addr.sa.sa_family; 124 | 125 | 126 | if (ttl != last_ttl) { 127 | 128 | set_ttl (icmp_sk, ttl); 129 | 130 | last_ttl = ttl; 131 | } 132 | 133 | 134 | if (af == AF_INET) { 135 | struct icmp *icmp = (struct icmp *) data; 136 | 137 | icmp->icmp_type = ICMP_ECHO; 138 | icmp->icmp_code = 0; 139 | icmp->icmp_cksum = 0; 140 | icmp->icmp_id = htons (ident); 141 | icmp->icmp_seq = htons (seq); 142 | 143 | icmp->icmp_cksum = in_csum (data, *length_p); 144 | } 145 | else if (af == AF_INET6) { 146 | struct icmp6_hdr *icmp6 = (struct icmp6_hdr *) data; 147 | 148 | icmp6->icmp6_type = ICMP6_ECHO_REQUEST; 149 | icmp6->icmp6_code = 0; 150 | icmp6->icmp6_cksum = 0; 151 | icmp6->icmp6_id = htons (ident); 152 | icmp6->icmp6_seq = htons(seq); 153 | 154 | /* icmp6->icmp6_cksum always computed by kernel internally */ 155 | } 156 | 157 | 158 | pb->send_time = get_time (); 159 | 160 | if (do_send (icmp_sk, data, *length_p, &dest_addr) < 0) { 161 | pb->send_time = 0; 162 | return; 163 | } 164 | 165 | 166 | pb->seq = seq; 167 | 168 | seq++; 169 | 170 | return; 171 | } 172 | 173 | 174 | static probe *icmp_check_reply (int sk, int err, sockaddr_any *from, 175 | char *buf, size_t len) { 176 | int af = dest_addr.sa.sa_family; 177 | int type; 178 | uint16_t recv_id, recv_seq; 179 | probe *pb; 180 | 181 | 182 | if (len < sizeof (struct icmphdr)) 183 | return NULL; 184 | 185 | 186 | if (af == AF_INET) { 187 | struct icmp *icmp = (struct icmp *) buf; 188 | 189 | type = icmp->icmp_type; 190 | 191 | recv_id = ntohs (icmp->icmp_id); 192 | recv_seq = ntohs (icmp->icmp_seq); 193 | 194 | } 195 | else { /* AF_INET6 */ 196 | struct icmp6_hdr *icmp6 = (struct icmp6_hdr *) buf; 197 | 198 | type = icmp6->icmp6_type; 199 | 200 | recv_id = ntohs (icmp6->icmp6_id); 201 | recv_seq = ntohs (icmp6->icmp6_seq); 202 | } 203 | 204 | 205 | if (recv_id != ident) 206 | return NULL; 207 | 208 | pb = probe_by_seq (recv_seq); 209 | if (!pb) return NULL; 210 | 211 | 212 | if (!err) { 213 | 214 | if (!(af == AF_INET && type == ICMP_ECHOREPLY) && 215 | !(af == AF_INET6 && type == ICMP6_ECHO_REPLY) 216 | ) return NULL; 217 | 218 | pb->final = 1; 219 | } 220 | 221 | return pb; 222 | } 223 | 224 | 225 | static void icmp_recv_probe (int sk, int revents) { 226 | 227 | if (!(revents & (POLLIN | POLLERR))) 228 | return; 229 | 230 | recv_reply (sk, !!(revents & POLLERR), icmp_check_reply); 231 | } 232 | 233 | 234 | static void icmp_expire_probe (probe *pb) { 235 | 236 | probe_done (pb); 237 | } 238 | 239 | 240 | static tr_module icmp_ops = { 241 | .name = "icmp", 242 | .init = icmp_init, 243 | .send_probe = icmp_send_probe, 244 | .recv_probe = icmp_recv_probe, 245 | .expire_probe = icmp_expire_probe, 246 | .options = icmp_options, 247 | }; 248 | 249 | TR_MODULE (icmp_ops); 250 | -------------------------------------------------------------------------------- /traceroute/mod-dccp.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012 Samuel Jero 3 | License: GPL v2 or any later 4 | 5 | See COPYING for the status of this software. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | #include "traceroute.h" 19 | 20 | 21 | #define DEF_SERVICE_CODE 1885957735 22 | 23 | #define DCCP_HEADER_LEN (sizeof (struct dccp_hdr) + \ 24 | sizeof (struct dccp_hdr_ext) \ 25 | + sizeof (struct dccp_hdr_request)) 26 | 27 | static sockaddr_any dest_addr = {{ 0, }, }; 28 | static unsigned int dest_port = 0; 29 | 30 | static int raw_sk = -1; 31 | static int last_ttl = 0; 32 | 33 | static uint8_t buf[1024]; /* enough, enough... */ 34 | static size_t csum_len = 0; 35 | static struct dccp_hdr *dh = NULL; 36 | static struct dccp_hdr_ext *dhe = NULL; 37 | static struct dccp_hdr_request *dhr = NULL; 38 | static unsigned int service_code = DEF_SERVICE_CODE; 39 | 40 | 41 | static CLIF_option dccp_options[] = { 42 | { 0, "service", "NUM", "Set DCCP service code to %s (default is " 43 | _TEXT (DEF_SERVICE_CODE) ")", 44 | CLIF_set_uint, &service_code, 0, CLIF_ABBREV }, 45 | CLIF_END_OPTION 46 | }; 47 | 48 | 49 | static int dccp_init (const sockaddr_any *dest, 50 | unsigned int port_seq, size_t *packet_len_p) { 51 | int af = dest->sa.sa_family; 52 | sockaddr_any src; 53 | socklen_t len; 54 | uint8_t *ptr; 55 | uint16_t *lenp; 56 | 57 | 58 | dest_addr = *dest; 59 | dest_addr.sin.sin_port = 0; /* raw sockets can be confused */ 60 | 61 | if (!port_seq) port_seq = DEF_DCCP_PORT; 62 | dest_port = htons (port_seq); 63 | 64 | 65 | /* Create raw socket for DCCP */ 66 | raw_sk = socket (af, SOCK_RAW, IPPROTO_DCCP); 67 | if (raw_sk < 0) 68 | error_or_perm ("socket"); 69 | 70 | tune_socket (raw_sk); /* including bind, if any */ 71 | 72 | if (connect (raw_sk, &dest_addr.sa, sizeof (dest_addr)) < 0) 73 | error ("connect"); 74 | 75 | len = sizeof (src); 76 | if (getsockname (raw_sk, &src.sa, &len) < 0) 77 | error ("getsockname"); 78 | 79 | 80 | if (!raw_can_connect ()) { /* work-around for buggy kernels */ 81 | close (raw_sk); 82 | raw_sk = socket (af, SOCK_RAW, IPPROTO_DCCP); 83 | if (raw_sk < 0) error ("socket"); 84 | tune_socket (raw_sk); 85 | /* but do not connect it... */ 86 | } 87 | 88 | 89 | use_recverr (raw_sk); 90 | 91 | add_poll (raw_sk, POLLIN | POLLERR); 92 | 93 | 94 | /* Now create the sample packet. */ 95 | 96 | /* For easy checksum computing: 97 | saddr 98 | daddr 99 | length 100 | protocol 101 | dccphdr 102 | */ 103 | 104 | ptr = buf; 105 | 106 | if (af == AF_INET) { 107 | len = sizeof (src.sin.sin_addr); 108 | memcpy (ptr, &src.sin.sin_addr, len); 109 | ptr += len; 110 | memcpy (ptr, &dest_addr.sin.sin_addr, len); 111 | ptr += len; 112 | } else { 113 | len = sizeof (src.sin6.sin6_addr); 114 | memcpy (ptr, &src.sin6.sin6_addr, len); 115 | ptr += len; 116 | memcpy (ptr, &dest_addr.sin6.sin6_addr, len); 117 | ptr += len; 118 | } 119 | 120 | lenp = (uint16_t *) ptr; 121 | ptr += sizeof (uint16_t); 122 | *((uint16_t *) ptr) = htons ((uint16_t) IPPROTO_DCCP); 123 | ptr += sizeof (uint16_t); 124 | 125 | 126 | /* Construct DCCP header */ 127 | dh = (struct dccp_hdr *) ptr; 128 | 129 | dh->dccph_ccval = 0; 130 | dh->dccph_checksum = 0; 131 | dh->dccph_cscov = 0; 132 | dh->dccph_dport = dest_port; 133 | dh->dccph_reserved = 0; 134 | dh->dccph_sport = 0; /* temporary */ 135 | dh->dccph_x = 1; 136 | dh->dccph_type = DCCP_PKT_REQUEST; 137 | dh->dccph_seq2 = 0; /* reserved if using 48 bit sequence numbers */ 138 | /* high 16 bits of sequence number. Always make 0 for simplicity. */ 139 | dh->dccph_seq = 0; 140 | ptr += sizeof (struct dccp_hdr); 141 | 142 | dhe = (struct dccp_hdr_ext *) ptr; 143 | dhe->dccph_seq_low = 0; /* temporary */ 144 | ptr += sizeof (struct dccp_hdr_ext); 145 | 146 | dhr = (struct dccp_hdr_request *) ptr; 147 | dhr->dccph_req_service = htonl (service_code); 148 | ptr += sizeof (struct dccp_hdr_request); 149 | 150 | 151 | csum_len = ptr - buf; 152 | 153 | if (csum_len > sizeof (buf)) 154 | error ("impossible"); /* paranoia */ 155 | 156 | len = ptr - (uint8_t *) dh; 157 | if (len & 0x03) error ("impossible"); /* as >>2 ... */ 158 | 159 | *lenp = htons (len); 160 | dh->dccph_doff = len >> 2; 161 | 162 | 163 | *packet_len_p = len; 164 | 165 | return 0; 166 | } 167 | 168 | 169 | static void dccp_send_probe (probe *pb, int ttl) { 170 | int sk; 171 | int af = dest_addr.sa.sa_family; 172 | sockaddr_any addr; 173 | socklen_t len = sizeof (addr); 174 | 175 | 176 | /* To make sure we have chosen a free unused "source port", 177 | just create, (auto)bind and hold a socket while the port is needed. 178 | */ 179 | 180 | sk = socket (af, SOCK_DCCP, IPPROTO_DCCP); 181 | if (sk < 0) error ("socket"); 182 | 183 | bind_socket (sk); 184 | 185 | if (getsockname (sk, &addr.sa, &len) < 0) 186 | error ("getsockname"); 187 | 188 | /* When we reach the target host, it can send us either Reset or Response. 189 | For Reset all is OK (we and kernel just answer nothing), but 190 | for Response we should reply with our Close. 191 | It is well-known "half-open technique", used by port scanners etc. 192 | This way we do not touch remote applications at all, unlike 193 | the ordinary connect(2) call. 194 | As the port-holding socket neither connect() nor listen(), 195 | it means "no such port yet" for remote ends, and kernel always 196 | send Reset in such a situation automatically (we have to do nothing). 197 | */ 198 | 199 | 200 | dh->dccph_sport = addr.sin.sin_port; 201 | 202 | dhe->dccph_seq_low = random_seq (); 203 | 204 | dh->dccph_checksum = 0; 205 | dh->dccph_checksum = in_csum (buf, csum_len); 206 | 207 | 208 | if (ttl != last_ttl) { 209 | set_ttl (raw_sk, ttl); 210 | last_ttl = ttl; 211 | } 212 | 213 | 214 | pb->send_time = get_time (); 215 | 216 | if (do_send (raw_sk, dh, dh->dccph_doff << 2, &dest_addr) < 0) { 217 | close (sk); 218 | pb->send_time = 0; 219 | return; 220 | } 221 | 222 | 223 | pb->seq = dh->dccph_sport; 224 | 225 | pb->sk = sk; 226 | 227 | return; 228 | } 229 | 230 | 231 | static probe *dccp_check_reply (int sk, int err, sockaddr_any *from, 232 | char *buf, size_t len) { 233 | probe *pb; 234 | struct dccp_hdr *ndh = (struct dccp_hdr *) buf; 235 | uint16_t sport, dport; 236 | 237 | 238 | if (len < 8) return NULL; /* too short */ 239 | 240 | 241 | if (err) { 242 | sport = ndh->dccph_sport; 243 | dport = ndh->dccph_dport; 244 | } else { 245 | sport = ndh->dccph_dport; 246 | dport = ndh->dccph_sport; 247 | } 248 | 249 | 250 | if (dport != dest_port) 251 | return NULL; 252 | 253 | if (!equal_addr (&dest_addr, from)) 254 | return NULL; 255 | 256 | pb = probe_by_seq (sport); 257 | if (!pb) return NULL; 258 | 259 | if (!err) pb->final = 1; 260 | 261 | return pb; 262 | } 263 | 264 | 265 | static void dccp_recv_probe (int sk, int revents) { 266 | 267 | if (!(revents & (POLLIN | POLLERR))) 268 | return; 269 | 270 | recv_reply (sk, !!(revents & POLLERR), dccp_check_reply); 271 | } 272 | 273 | 274 | static void dccp_expire_probe (probe *pb) { 275 | 276 | probe_done (pb); 277 | } 278 | 279 | 280 | static tr_module dccp_ops = { 281 | .name = "dccp", 282 | .init = dccp_init, 283 | .send_probe = dccp_send_probe, 284 | .recv_probe = dccp_recv_probe, 285 | .expire_probe = dccp_expire_probe, 286 | .options = dccp_options, 287 | }; 288 | 289 | TR_MODULE (dccp_ops); 290 | -------------------------------------------------------------------------------- /traceroute/mod-tcp.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006, 2007 Dmitry Butskoy 3 | 4 | License: GPL v2 or any later 5 | 6 | See COPYING for the status of this software. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | //#include 15 | 16 | #include "libsupp/icmp6.h" 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "libsupp/tcp.h" 24 | //#include 25 | 26 | 27 | #include "traceroute.h" 28 | 29 | 30 | #ifndef IP_MTU 31 | #define IP_MTU 14 32 | #endif 33 | 34 | 35 | static sockaddr_any dest_addr = {{ 0, }, }; 36 | static unsigned int dest_port = 0; 37 | 38 | static int raw_sk = -1; 39 | static int last_ttl = 0; 40 | 41 | static uint8_t buf[1024]; /* enough, enough... */ 42 | static size_t csum_len = 0; 43 | static struct tcphdr *th = NULL; 44 | 45 | #define TH_FLAGS(TH) (((uint8_t *) (TH))[13]) 46 | #define TH_FIN 0x01 47 | #define TH_SYN 0x02 48 | #define TH_RST 0x04 49 | #define TH_PSH 0x08 50 | #define TH_ACK 0x10 51 | #define TH_URG 0x20 52 | #define TH_ECE 0x40 53 | #define TH_CWR 0x80 54 | 55 | 56 | static int flags = 0; /* & 0xff == tcp_flags ... */ 57 | static int sysctl = 0; 58 | static int reuse = 0; 59 | static unsigned int mss = 0; 60 | static int info = 0; 61 | 62 | #define FL_FLAGS 0x0100 63 | #define FL_ECN 0x0200 64 | #define FL_SACK 0x0400 65 | #define FL_TSTAMP 0x0800 66 | #define FL_WSCALE 0x1000 67 | 68 | 69 | static struct { 70 | const char *name; 71 | unsigned int flag; 72 | } tcp_flags[] = { 73 | { "fin", TH_FIN }, 74 | { "syn", TH_SYN }, 75 | { "rst", TH_RST }, 76 | { "psh", TH_PSH }, 77 | { "ack", TH_ACK }, 78 | { "urg", TH_URG }, 79 | { "ece", TH_ECE }, 80 | { "cwr", TH_CWR }, 81 | }; 82 | 83 | static char *names_by_flags (unsigned int flags) { 84 | int i; 85 | char str[64]; /* enough... */ 86 | char *curr = str; 87 | char *end = str + sizeof (str) / sizeof (*str); 88 | 89 | for (i = 0; i < sizeof (tcp_flags) / sizeof (*tcp_flags); i++) { 90 | const char *p; 91 | 92 | if (!(flags & tcp_flags[i].flag)) continue; 93 | 94 | if (curr > str && curr < end) *curr++ = ','; 95 | for (p = tcp_flags[i].name; *p && curr < end; *curr++ = *p++) ; 96 | } 97 | 98 | *curr = '\0'; 99 | 100 | return strdup (str); 101 | } 102 | 103 | static int set_tcp_flag (CLIF_option *optn, char *arg) { 104 | int i; 105 | 106 | for (i = 0; i < sizeof (tcp_flags) / sizeof (*tcp_flags); i++) { 107 | if (!strcmp (optn->long_opt, tcp_flags[i].name)) { 108 | flags |= tcp_flags[i].flag; 109 | return 0; 110 | } 111 | } 112 | 113 | return -1; 114 | } 115 | 116 | static int set_tcp_flags (CLIF_option *optn, char *arg) { 117 | char *q; 118 | unsigned long value; 119 | 120 | value = strtoul (arg, &q, 0); 121 | if (q == arg) return -1; 122 | 123 | flags = (flags & ~0xff) | (value & 0xff) | FL_FLAGS; 124 | return 0; 125 | } 126 | 127 | static int set_flag (CLIF_option *optn, char *arg) { 128 | 129 | flags |= (unsigned long) optn->data; 130 | 131 | return 0; 132 | } 133 | 134 | static CLIF_option tcp_options[] = { 135 | { 0, "syn", 0, "Set tcp flag SYN (default if no other " 136 | "tcp flags specified)", set_tcp_flag, 0, 0, 0 }, 137 | { 0, "ack", 0, "Set tcp flag ACK,", set_tcp_flag, 0, 0, 0 }, 138 | { 0, "fin", 0, "FIN,", set_tcp_flag, 0, 0, 0 }, 139 | { 0, "rst", 0, "RST,", set_tcp_flag, 0, 0, 0 }, 140 | { 0, "psh", 0, "PSH,", set_tcp_flag, 0, 0, 0 }, 141 | { 0, "urg", 0, "URG,", set_tcp_flag, 0, 0, 0 }, 142 | { 0, "ece", 0, "ECE,", set_tcp_flag, 0, 0, 0 }, 143 | { 0, "cwr", 0, "CWR", set_tcp_flag, 0, 0, 0 }, 144 | { 0, "flags", "NUM", "Set tcp flags exactly to value %s", 145 | set_tcp_flags, 0, 0, CLIF_ABBREV }, 146 | { 0, "ecn", 0, "Send syn packet with tcp flags ECE and CWR " 147 | "(for Explicit Congestion Notification, rfc3168)", 148 | set_flag, (void *) FL_ECN, 0, 0 }, 149 | { 0, "sack", 0, "Use sack,", 150 | set_flag, (void *) FL_SACK, 0, 0 }, 151 | { 0, "timestamps", 0, "timestamps,", 152 | set_flag, (void *) FL_TSTAMP, 0, CLIF_ABBREV }, 153 | { 0, "window_scaling", 0, "window_scaling option for tcp", 154 | set_flag, (void *) FL_WSCALE, 0, CLIF_ABBREV }, 155 | { 0, "sysctl", 0, "Use current sysctl (/proc/sys/net/*) setting " 156 | "for the tcp options and ecn. Always set by default " 157 | "(with \"syn\") if nothing else specified", 158 | CLIF_set_flag, &sysctl, 0, 0 }, 159 | { 0, "reuse", 0, "Allow to reuse local port numbers " 160 | "for the huge workloads (SO_REUSEADDR)", 161 | CLIF_set_flag, &reuse, 0, 0 }, 162 | { 0, "mss", "NUM", "Use value of %s for maxseg tcp option (when syn)", 163 | CLIF_set_uint, &mss, 0, 0 }, 164 | { 0, "info", 0, "Print tcp flags of final tcp replies when target " 165 | "host is reached. Useful to determine whether " 166 | "an application listens the port etc.", 167 | CLIF_set_flag, &info, 0, 0 }, 168 | CLIF_END_OPTION 169 | }; 170 | 171 | 172 | #define SYSCTL_PREFIX "/proc/sys/net/ipv4/tcp_" 173 | static int check_sysctl (const char *name) { 174 | int fd, res; 175 | char buf[sizeof (SYSCTL_PREFIX) + strlen (name) + 1]; 176 | uint8_t ch; 177 | 178 | strcpy (buf, SYSCTL_PREFIX); 179 | strcat (buf, name); 180 | 181 | fd = open (buf, O_RDONLY, 0); 182 | if (fd < 0) return 0; 183 | 184 | res = read (fd, &ch, sizeof (ch)); 185 | close (fd); 186 | 187 | if (res != sizeof (ch)) 188 | return 0; 189 | 190 | /* since kernel 2.6.31 "tcp_ecn" can have value of '2'... */ 191 | if (ch == '1') return 1; 192 | 193 | return 0; 194 | } 195 | 196 | 197 | static int tcp_init (const sockaddr_any *dest, 198 | unsigned int port_seq, size_t *packet_len_p) { 199 | int af = dest->sa.sa_family; 200 | sockaddr_any src; 201 | int mtu; 202 | socklen_t len; 203 | uint8_t *ptr; 204 | uint16_t *lenp; 205 | 206 | 207 | dest_addr = *dest; 208 | dest_addr.sin.sin_port = 0; /* raw sockets can be confused */ 209 | 210 | if (!port_seq) port_seq = DEF_TCP_PORT; 211 | dest_port = htons (port_seq); 212 | 213 | 214 | /* Create raw socket for tcp */ 215 | 216 | raw_sk = socket (af, SOCK_RAW, IPPROTO_TCP); 217 | if (raw_sk < 0) 218 | error_or_perm ("socket"); 219 | 220 | tune_socket (raw_sk); /* including bind, if any */ 221 | 222 | if (connect (raw_sk, &dest_addr.sa, sizeof (dest_addr)) < 0) 223 | error ("connect"); 224 | 225 | len = sizeof (src); 226 | if (getsockname (raw_sk, &src.sa, &len) < 0) 227 | error ("getsockname"); 228 | 229 | 230 | len = sizeof (mtu); 231 | if (getsockopt (raw_sk, af == AF_INET ? SOL_IP : SOL_IPV6, 232 | af == AF_INET ? IP_MTU : IPV6_MTU, 233 | &mtu, &len) < 0 || mtu < 576 234 | ) mtu = 576; 235 | 236 | /* mss = mtu - headers */ 237 | mtu -= af == AF_INET ? sizeof (struct iphdr) : sizeof (struct ip6_hdr); 238 | mtu -= sizeof (struct tcphdr); 239 | 240 | 241 | if (!raw_can_connect ()) { /* work-around for buggy kernels */ 242 | close (raw_sk); 243 | raw_sk = socket (af, SOCK_RAW, IPPROTO_TCP); 244 | if (raw_sk < 0) error ("socket"); 245 | tune_socket (raw_sk); 246 | /* but do not connect it... */ 247 | } 248 | 249 | 250 | use_recverr (raw_sk); 251 | 252 | add_poll (raw_sk, POLLIN | POLLERR); 253 | 254 | 255 | /* Now create the sample packet. */ 256 | 257 | if (!flags) sysctl = 1; 258 | 259 | if (sysctl) { 260 | if (check_sysctl ("ecn")) flags |= FL_ECN; 261 | if (check_sysctl ("sack")) flags |= FL_SACK; 262 | if (check_sysctl ("timestamps")) flags |= FL_TSTAMP; 263 | if (check_sysctl ("window_scaling")) flags |= FL_WSCALE; 264 | } 265 | 266 | if (!(flags & (FL_FLAGS | 0xff))) { /* no any tcp flag set */ 267 | flags |= TH_SYN; 268 | if (flags & FL_ECN) 269 | flags |= TH_ECE | TH_CWR; 270 | } 271 | 272 | 273 | /* For easy checksum computing: 274 | saddr 275 | daddr 276 | length 277 | protocol 278 | tcphdr 279 | tcpoptions 280 | */ 281 | 282 | ptr = buf; 283 | 284 | if (af == AF_INET) { 285 | len = sizeof (src.sin.sin_addr); 286 | memcpy (ptr, &src.sin.sin_addr, len); 287 | ptr += len; 288 | memcpy (ptr, &dest_addr.sin.sin_addr, len); 289 | ptr += len; 290 | } else { 291 | len = sizeof (src.sin6.sin6_addr); 292 | memcpy (ptr, &src.sin6.sin6_addr, len); 293 | ptr += len; 294 | memcpy (ptr, &dest_addr.sin6.sin6_addr, len); 295 | ptr += len; 296 | } 297 | 298 | lenp = (uint16_t *) ptr; 299 | ptr += sizeof (uint16_t); 300 | *((uint16_t *) ptr) = htons ((uint16_t) IPPROTO_TCP); 301 | ptr += sizeof (uint16_t); 302 | 303 | 304 | /* Construct TCP header */ 305 | 306 | th = (struct tcphdr *) ptr; 307 | 308 | th->source = 0; /* temporary */ 309 | th->dest = dest_port; 310 | th->seq = 0; /* temporary */ 311 | th->ack_seq = 0; 312 | th->doff = 0; /* later... */ 313 | TH_FLAGS(th) = flags & 0xff; 314 | th->window = htons (4 * mtu); 315 | th->check = 0; 316 | th->urg_ptr = 0; 317 | 318 | 319 | /* Build TCP options */ 320 | 321 | ptr = (uint8_t *) (th + 1); 322 | 323 | if (flags & TH_SYN) { 324 | *ptr++ = TCPOPT_MAXSEG; /* 2 */ 325 | *ptr++ = TCPOLEN_MAXSEG; /* 4 */ 326 | *((uint16_t *) ptr) = htons (mss ? mss : mtu); 327 | ptr += sizeof (uint16_t); 328 | } 329 | 330 | if (flags & FL_TSTAMP) { 331 | 332 | if (flags & FL_SACK) { 333 | *ptr++ = TCPOPT_SACK_PERMITTED; /* 4 */ 334 | *ptr++ = TCPOLEN_SACK_PERMITTED;/* 2 */ 335 | } else { 336 | *ptr++ = TCPOPT_NOP; /* 1 */ 337 | *ptr++ = TCPOPT_NOP; /* 1 */ 338 | } 339 | *ptr++ = TCPOPT_TIMESTAMP; /* 8 */ 340 | *ptr++ = TCPOLEN_TIMESTAMP; /* 10 */ 341 | 342 | *((uint32_t *) ptr) = random_seq (); /* really! */ 343 | ptr += sizeof (uint32_t); 344 | *((uint32_t *) ptr) = (flags & TH_ACK) ? random_seq () : 0; 345 | ptr += sizeof (uint32_t); 346 | } 347 | else if (flags & FL_SACK) { 348 | *ptr++ = TCPOPT_NOP; /* 1 */ 349 | *ptr++ = TCPOPT_NOP; /* 1 */ 350 | *ptr++ = TCPOPT_SACK_PERMITTED; /* 4 */ 351 | *ptr++ = TCPOLEN_SACK_PERMITTED; /* 2 */ 352 | } 353 | 354 | if (flags & FL_WSCALE) { 355 | *ptr++ = TCPOPT_NOP; /* 1 */ 356 | *ptr++ = TCPOPT_WINDOW; /* 3 */ 357 | *ptr++ = TCPOLEN_WINDOW; /* 3 */ 358 | *ptr++ = 2; /* assume some corect value... */ 359 | } 360 | 361 | 362 | csum_len = ptr - buf; 363 | 364 | if (csum_len > sizeof (buf)) 365 | error ("impossible"); /* paranoia */ 366 | 367 | len = ptr - (uint8_t *) th; 368 | if (len & 0x03) error ("impossible"); /* as >>2 ... */ 369 | 370 | *lenp = htons (len); 371 | th->doff = len >> 2; 372 | 373 | 374 | *packet_len_p = len; 375 | 376 | return 0; 377 | } 378 | 379 | 380 | static void tcp_send_probe (probe *pb, int ttl) { 381 | int sk; 382 | int af = dest_addr.sa.sa_family; 383 | sockaddr_any addr; 384 | socklen_t len = sizeof (addr); 385 | 386 | 387 | /* To make sure we have chosen a free unused "source port", 388 | just create, (auto)bind and hold a socket while the port is needed. 389 | */ 390 | 391 | sk = socket (af, SOCK_STREAM, 0); 392 | if (sk < 0) error ("socket"); 393 | 394 | if (reuse && setsockopt (sk, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) 395 | error ("setsockopt SO_REUSEADDR"); 396 | 397 | bind_socket (sk); 398 | 399 | if (getsockname (sk, &addr.sa, &len) < 0) 400 | error ("getsockname"); 401 | 402 | /* When we reach the target host, it can send us either RST or SYN+ACK. 403 | For RST all is OK (we and kernel just answer nothing), but 404 | for SYN+ACK we should reply with our RST. 405 | It is well-known "half-open technique", used by port scanners etc. 406 | This way we do not touch remote applications at all, unlike 407 | the ordinary connect(2) call. 408 | As the port-holding socket neither connect() nor listen(), 409 | it means "no such port yet" for remote ends, and kernel always 410 | send RST in such a situation automatically (we have to do nothing). 411 | */ 412 | 413 | 414 | th->source = addr.sin.sin_port; 415 | 416 | th->seq = random_seq (); 417 | 418 | th->check = 0; 419 | th->check = in_csum (buf, csum_len); 420 | 421 | 422 | if (ttl != last_ttl) { 423 | 424 | set_ttl (raw_sk, ttl); 425 | 426 | last_ttl = ttl; 427 | } 428 | 429 | 430 | pb->send_time = get_time (); 431 | 432 | if (do_send (raw_sk, th, th->doff << 2, &dest_addr) < 0) { 433 | close (sk); 434 | pb->send_time = 0; 435 | return; 436 | } 437 | 438 | 439 | pb->seq = th->source; 440 | 441 | pb->sk = sk; 442 | 443 | return; 444 | } 445 | 446 | 447 | static probe *tcp_check_reply (int sk, int err, sockaddr_any *from, 448 | char *buf, size_t len) { 449 | probe *pb; 450 | struct tcphdr *tcp = (struct tcphdr *) buf; 451 | uint16_t sport, dport; 452 | 453 | 454 | if (len < 8) return NULL; /* too short */ 455 | 456 | 457 | if (err) { 458 | sport = tcp->source; 459 | dport = tcp->dest; 460 | } else { 461 | sport = tcp->dest; 462 | dport = tcp->source; 463 | } 464 | 465 | 466 | if (dport != dest_port) 467 | return NULL; 468 | 469 | if (!equal_addr (&dest_addr, from)) 470 | return NULL; 471 | 472 | pb = probe_by_seq (sport); 473 | if (!pb) return NULL; 474 | 475 | 476 | if (!err) { 477 | 478 | pb->final = 1; 479 | 480 | if (info) 481 | pb->ext = names_by_flags (TH_FLAGS(tcp)); 482 | } 483 | 484 | return pb; 485 | } 486 | 487 | 488 | static void tcp_recv_probe (int sk, int revents) { 489 | 490 | if (!(revents & (POLLIN | POLLERR))) 491 | return; 492 | 493 | recv_reply (sk, !!(revents & POLLERR), tcp_check_reply); 494 | } 495 | 496 | 497 | static void tcp_expire_probe (probe *pb) { 498 | 499 | probe_done (pb); 500 | } 501 | 502 | 503 | static tr_module tcp_ops = { 504 | .name = "tcp", 505 | .init = tcp_init, 506 | .send_probe = tcp_send_probe, 507 | .recv_probe = tcp_recv_probe, 508 | .expire_probe = tcp_expire_probe, 509 | .options = tcp_options, 510 | }; 511 | 512 | TR_MODULE (tcp_ops); 513 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2016-03-08 Dmitry Butskoy - 2.1.0 2 | 3 | * Improve the main loop for better interactivity. 4 | 5 | Instead of waiting silently for maximum expiration time of probes 6 | in progress, use timeout of the first probe (which will be printed 7 | first from now) only. 8 | 9 | * Speedup wait mechanism. 10 | 11 | Traditional traceroute implementation always waited the whole timeout 12 | for any probe. But if we already have some replies from the same hop, 13 | or even from some next hop, we can use the round trip time 14 | of such a reply as a hint to determine the actual reasonable 15 | amount of time to wait. 16 | 17 | Now the `-w' option has a form of three (in general) float values 18 | separated by a comma (or a slash): `-w MAX_SECS,HERE,NEAR' . 19 | (last two are optional). MAX_SECS specifies the maximum time 20 | (in seconds) to wait, in any case. 21 | 22 | The optional HERE specifies a factor to multiply the round trip time 23 | of an already received response from the same hop. 24 | The resulting value is used as a timeout for the probe, instead of 25 | (but no more than) MAX_SECS. The optional NEAR specifies a similar 26 | factor for a response from some next hop. 27 | The time of the first found result is used in both cases. 28 | 29 | First, we look for the same hop (of the probe which will be printed 30 | first from now). If nothing found, then look for some next hop. 31 | If nothing found, use MAX_SECS. If HERE and/or NEAR have zero values, 32 | the corresponding computation is skipped. 33 | 34 | HERE and NEAR are always set to zero if only MAX_SECS is specified 35 | (which provides compatibility with previous versions). Thus, if your 36 | scripts use `-w SECS', then nothing changed for you, since 37 | the lonely SECS implies `-w SECS,0,0' . 38 | 39 | Defaults are 5.0 seconds for MAX_SECS, 3.0 times for HERE and 40 | 10.0 times for NEAR. 41 | 42 | Certainly, the new algorithm can lead to premature expiry 43 | (especially when response times differ at times) and printing "*" 44 | instead of a time. Anyway, you can always switch this algorithm off, 45 | just by specifying `-w' with the desired timeout only (fe. `-w 5'). 46 | 47 | We continue to wait whole MAX_SECS when one probe per time 48 | must be sent (`--sport', `-P proto'), because it seems more harmful 49 | rather than helpful to try to wait less in such cases. 50 | 51 | To provide compatibility with 2.0.x versions, use: 52 | 53 | traceroute -w 5 54 | 55 | (or any other desired `-w' value). 56 | 57 | * Hint people to use the system traceroute(8) instead of 58 | tcptraceroute wrapper (by providing a stderr header). 59 | 60 | The using of this wrapper is a little bit harmful, since it has 61 | less possibilities and a little different set of options. 62 | 63 | For those who are used to use tcptraceroute in cmdline, 64 | just create a link with that name to the system traceroute. 65 | When invoked as "tcp*", it then behaves as `traceroute -T'. 66 | (The simple manual page added for this case in the wrapper subdir). 67 | 68 | The original tcptraceroute had some options differ ("lpNSAE"), 69 | but they was rare used. Most common "dnFifmqwst" was just the same. 70 | Therefore it should be painless to use the system binary directly, 71 | instead of the limited wrapper (which is still provided indeed). 72 | 73 | 74 | 2016-02-15 Dmitry Butskoy - 2.0.22 75 | 76 | * Some portability fixing and improvements (Felix Janda) 77 | 78 | * Require clear numbers for options and arguments (Sergey Salnikov) 79 | 80 | * Drop compilation date from the version string (Debian #774365) 81 | 82 | * New tcp module option `reuse', which utilize SO_REUSEADDR 83 | to reuse local port numbers for the huge workloads (Richard Sheehan) 84 | 85 | * Avoid poll(2) call with spurious zero timeout in some rare cases 86 | by rounding the value properly using ceil(3) 87 | 88 | 89 | 2014-11-12 Dmitry Butskoy - 2.0.21 90 | 91 | * Fix `--mtu' and `-F' working on kernels >= 3.13 92 | 93 | * Some manual page improving (Christopher Mann) 94 | 95 | 96 | 2014-06-14 Dmitry Butskoy - 2.0.20 97 | 98 | * Describe all complementary long options in the man page (Jan Synacek) 99 | 100 | * Use correct service name for AS lookups (Frederic Mangano) 101 | 102 | * Avoid some rare case null dereference (geogriffin@jsgriff.com) 103 | 104 | * Improve expiration check for simultaneous probes 105 | 106 | 107 | 2012-11-19 Dmitry Butskoy - 2.0.19 108 | 109 | * DCCP protocol support (rfc4340), by Samuel Jero 110 | 111 | Use "-D" option for it (the protocol-specific options 112 | are available too). 113 | 114 | * Update COPYING and COPYING.LIB license files to the latest 115 | published ones (due to FSF address changes etc.) (Jan Synacek) 116 | 117 | * Add mention of "-l" option to manual (Filip Holec) 118 | 119 | 120 | 2011-08-16 Dmitry Butskoy - 2.0.18 121 | 122 | * Handle new dgram icmp sockets ("echo ping sockets"), 123 | appeared in kernel 3.0 . 124 | 125 | Now unprivileged users may perform ICMP tracerouting 126 | without any special rights of the executable 127 | (neither setuid bits nor cap_net_raw settings). 128 | It is allowed if any group of a user matches sysctl range 129 | of "net/ipv4/ping_group_range". 130 | 131 | The support for dgram icmp way (and whether it is allowed) 132 | is auto-detected at runtime. First, the traditional raw socket 133 | is tried (for full compatibility reasons), then new dgram 134 | socket as a fallback. 135 | The icmp module now has two additional options "raw" and "dgram", 136 | which cause to try one particular way only. 137 | 138 | Note, that there is no IPv6 implementation for dgram icmp sockets 139 | in kernels 3.0 yet, but new traceroute is ready for it anyway. 140 | 141 | * New tcp module option `info' ("-T -O info"), 142 | which prints all tcp flags of tcp reply from the reached 143 | target host. 144 | 145 | The flags are shown comma-separated in the same place 146 | where icmp extensions is printed (ie. in `<>' brackets) 147 | 148 | This feature is utilized by tcptraceroute wrapper now, 149 | and allow it to be completely functional replacement 150 | of the original tcptraceroute. 151 | 152 | * Fix determination of system-wide ECN setings for tcp module. 153 | 154 | Since the kernel 2.6.31 the default sysctl net/ipv4/tcp_ecn 155 | was changed from zero to '2', whereas the actual value 156 | for ecn to be set is still '1' 157 | 158 | * Allow different packet sizes for `--mtu'. 159 | Suport `-l' option for tracepath wrapper. 160 | 161 | * Some code and manual cleanups 162 | 163 | 164 | 2010-12-14 Dmitry Butskoy - 2.0.17 165 | 166 | * Adapt code to make possible the use of Linux capabilities 167 | (for raw sockets etc.) instead of superuser privileges only. 168 | 169 | On modern systems the capabilities can be stored as 170 | file attributes, ie.: 171 | 172 | "setcap cap_net_raw=pe /usr/bin/traceroute" 173 | 174 | 175 | 2010-09-13 Dmitry Butskoy - 2.0.16 176 | 177 | * A little work-around in the build system 178 | for the new (buggy?) make 3.82 179 | 180 | * Add `--fwmark=num' option for firewall mark (for kernel >= 2.6.25). 181 | Idea comes from an anonymous SF patch #3042539 182 | 183 | 184 | 2010-07-14 Dmitry Butskoy - 2.0.15 185 | 186 | * Use string routines more safely (fix SF bug #3029216) 187 | 188 | * Provide help for lft wrapper 189 | 190 | 191 | 2010-04-21 Dmitry Butskoy - 2.0.14 192 | 193 | * Fix support for IPv6's flow_labels and tclass. 194 | Thanks to Peter Bieringer for testing 195 | 196 | * Use route header "type 2" instead of deprecated "type 0" 197 | for `-g' option for IPv6. The default value can be changed 198 | by specifying a number in the place of the first `-g' address. 199 | 200 | 201 | 2009-11-02 Dmitry Butskoy - 2.0.13 202 | 203 | * Check for first_hop is not zero value (vladz@devzero.fr) 204 | 205 | * Always fill unresolved IP address by its numeric interpretation, 206 | even if getnameinfo(3) leaves it untouched (as it does for ipv6 207 | in some glibc versions, whereas always fills for ipv4) 208 | 209 | * Cosmetic changes for man page (Andreas Mohr) 210 | 211 | 212 | 2008-09-15 Dmitry Butskoy - 2.0.12 213 | 214 | * Use common recv_reply() routine for all modules which 215 | do recvmsg(2) call. Method-specific things go to callbacks. 216 | 217 | Pass to init methods pointer to datalen instead of the value. 218 | 219 | * Implement ICMP Extension support (rfc4884), `-e' option. 220 | Parse MPLS info (rfc4950) to be more readable (Kaj Niemi) 221 | 222 | * Implement Path MTU Discovery (similar to tracepath(1)), 223 | with `--mtu' option. Changed mtu is printed once in a form 224 | of `F=NUM' at the first probe of a hop which requires 225 | such mtu to be reached. (Actually, the correspond "frag needed" 226 | icmp message is normally sent by the previous hop). 227 | 228 | * Print the number of backward hops when it differs with forward, 229 | by `--back' option. The backward hops is guessed by a technique 230 | similar to tracepath(1), there is no reliable way to obtain 231 | such info though. 232 | 233 | * The optional second argument (packet_len) now is the full length 234 | of the packet, including IP headers. (It is obvious enough due to 235 | the nature of this feature, and this is the behaviour of the 236 | original traceroute). Particular trace methods can ignore this 237 | (fe. tcp), or increase it up to the minimal value (udp, icmp). 238 | The actual packet's size is alvays reported in the output header. 239 | 240 | * Add tracepath(1)/tracepath6(1) shell wrapper. 241 | 242 | * Allow DEF_AF to be redefined at cmdline (Teran McKinney) 243 | 244 | * Do not check the correctness of `sim_probes' value -- it is 245 | unneeded at all. This also fixes a bug when a value of sim_probes 246 | appears to be more than the total number of probes. 247 | Reported by Milos Malik. 248 | 249 | * Allow default UDP method to cross zero port boundary (Milos Malik). 250 | It is a strange corner case, but traditional traceroute 251 | behaves exactly so. 252 | 253 | 254 | 2008-04-25 Dmitry Butskoy - 2.0.11 255 | 256 | * Use new pmtudisc value "probe" instead of "do" for `-F' option 257 | (available since the kernel 2.6.22). 258 | 259 | For kernels before 2.6.22, the `-F' (dontfragment) option 260 | seems completely useless for IPv6 and partially useful 261 | for IPv4 (when a user can flush routing caches some way). 262 | 263 | * Fix installation in build system (Mike Frysinger) 264 | 265 | * Don't compute checksum for ipv6 icmp packets ourselves, 266 | the kernel overwrites it anyway by the proper values. 267 | 268 | * Don't use explicit path to traceroute in wrapper scripts 269 | 270 | 271 | 2008-04-17 Dmitry Butskoy - 2.0.10 272 | 273 | * raw_can_connect(): ipv6 connected raw sockets 274 | receive MSG_ERRQUEUE properly only for kernels >= 2.6.25 275 | 276 | * remove useless "host" parameter for init methods 277 | 278 | * add probe_by_seq() and probe_by_sk() routines, 279 | don't pass whole probes' pointer to recv_probe method 280 | 281 | * collect all sends in do_send() routine 282 | 283 | * Interpret ENOBUFS errors for send(2) as "can retry later". 284 | 285 | Slow devices (like ppp) with small tx_queue_len can reject 286 | the sending of too many packets simultaneously. To handle this, 287 | do_send() now returns a negate value in a case of ENOBUFS 288 | and similar (instead of program exit). The send_probe method 289 | clears the probe and returns immediately in such cases. 290 | Then, if there is an amount of time to wait for something, 291 | the failed probe will be attempted again after that time expired. 292 | If nothing to wait more, the program is exited. 293 | 294 | 295 | 2007-09-26 Dmitry Butskoy - 2.0.9 296 | 297 | * Complete manual page. 298 | 299 | * Edit manual page to sound more English, thanks to Chris Ward 300 | 301 | 302 | 2007-09-04 Dmitry Butskoy - 2.0.8 303 | 304 | * Move all wrappers to special "wrappers/" dir. 305 | Add lft(8) shell wrapper. 306 | Add traceproto(8) shell wrapper. 307 | Add traceroute-nanog(8) shell wrapper. 308 | 309 | * Interpret first_hop as number, not index 310 | 311 | * Build system is re-worked to match more the modern requirements 312 | (Thanks to Mike Frysinger for testing). 313 | 314 | * Check for kernel version >= 2.6.22.2 in raw_can_connect() 315 | 316 | * Add generic "raw" method, "-P protonum" option. 317 | New "one_per_time" flag for tr_module. 318 | 319 | 320 | 2007-07-31 Dmitry Butskoy - 2.0.7 321 | 322 | * Fix revents checking typo 323 | 324 | * Expect normal data reply from udp too. 325 | 326 | * Implement udp to port (-U) and udplite (-UL) methods. 327 | Both available for unprivileged users. 328 | Add "coverage" option for udplite. 329 | 330 | * Allow non-digit service names for `-p' and `--sport' 331 | 332 | * Drop period at the end of "SEE ALSO" section, and 333 | avoid specific distro names in the manual (Mike Frysinger) 334 | 335 | * Explicitly mention that this program is licensed 336 | as "GPL version 2 or any later version". 337 | (Similar for libsupp subdir: LGPL version 2.1 or any later). 338 | 339 | * Always check whether the dest and source port match in 340 | received packets. Can decrease an amount of (hypothetical) 341 | garbage received just after the bind() but before connect() 342 | 343 | 344 | 2007-07-19 Dmitry Butskoy - 2.0.6 345 | 346 | * Rename tr_ops to tr_module 347 | 348 | * Implement module-specific options (-O opt,...) 349 | 350 | * Add TCP specific options (all the tcp header flags, 351 | ecn, sack, timestamps, window_scaling, mss, sysctl) 352 | Build tcp probe packet depending on them. 353 | 354 | * Add "--sport" option for explicit source port selection. 355 | Always cause "-N 1" when it is set. 356 | 357 | * Add new routine bind_socket(). 358 | Always (auto)bind sockets in tune_socket(). 359 | 360 | * Add tcptraceroute(8) shell wrapper 361 | 362 | 363 | 2007-07-16 Dmitry Butskoy - 2.0.5 364 | 365 | * Use MSG_ERRQUEUE for raw sockets too. 366 | 367 | * raw_can_connect () work-around for kernel bug #8747 368 | 369 | * random.c, csum.c: new separate files 370 | 371 | * New implementation of tcp method ("-T"), using 372 | half-open technique. The old implementation module 373 | renamed to "tcpconn" ("-M tcpconn"). 374 | 375 | * Common parse_cmsg() routine 376 | 377 | * put ee_info for parse_icmp_res() too, 378 | handle ICMP6_PACKET_TOO_BIG for IPv6, 379 | report "!F-num" when "frag needed" (legacy compatibility) 380 | 381 | 382 | 2007-07-11 Dmitry Butskoy - 2.0.4 383 | 384 | * clear includes of unneeded headers 385 | 386 | * move poll stuff to separate poll.c 387 | 388 | * add module stuff (module.c), options etc. 389 | Adapt udp/icmp/tcp for this. 390 | 391 | * Add common routines use_recverr() and set_ttl() 392 | 393 | 394 | 2007-02-28 Dmitry Butskoy 395 | 396 | * fix variable type for getsockname (Mike Frysinger) 397 | 398 | 399 | 2007-01-09 Dmitry Butskoy - 2.0.3 400 | 401 | * version 2.0.3 402 | 403 | * allow option args without separator (add CLIF_MAY_JOIN_ARG flag), 404 | for compatibility (Benjamin LaHaise) 405 | 406 | * no more "tcptraceroute" symlink for rpm packages, because 407 | it conflicts with the same-name old package anyway (James Ralston) 408 | 409 | * fix compilation on glibc < 2.4 (Andy Shevchenko) 410 | 411 | 412 | 2006-10-30 Dmitry Butskoy - 2.0.2 413 | 414 | * version 2.0.2 415 | 416 | * More accurate check_expired() routine. 417 | 418 | * Some minor fixes. 419 | 420 | * Add NOTES section to manual 421 | 422 | 423 | 2006-10-20 Dmitry Butskoy - 2.0.1 424 | 425 | * version 2.0.1 426 | 427 | * Now ops methods write send_time (as well as recv_time) 428 | 429 | * Use SO_TIMESTAMP to obtain msecs precisely 430 | 431 | * Complete manual 432 | 433 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /traceroute/traceroute.8: -------------------------------------------------------------------------------- 1 | .\" Copyright (c) 2006 Dmitry Butskoy (dmitry@butskoy.name) 2 | .\" License: GPL v2 or any later version 3 | .\" See COPYING for the status of this software 4 | .TH TRACEROUTE 8 "11 October 2006" "Traceroute" "Traceroute For Linux" 5 | .\" .UC 6 6 | .SH NAME 7 | traceroute \- print the route packets trace to network host 8 | .SH SYNOPSIS 9 | .na 10 | .BR traceroute " [" \-46dFITUnreAV "] [" "\-f first_ttl" "] [" "\-g gate,..." ] 11 | .br 12 | .ti +8 13 | .BR "" [ "-i device" "] [" "-m max_ttl" "] [" "-p port" "] [" "-s src_addr" ] 14 | .br 15 | .ti +8 16 | .BR "" [ "-q nqueries" "] [" "-N squeries" "] [" "-t tos" ] 17 | .br 18 | .ti +8 19 | .BR "" [ "-l flow_label" "] [" "-w waittimes" "] [" "-z sendwait" "] [" "-UL" "] [" "-D" ] 20 | .br 21 | .ti +8 22 | .BR "" [ "-P proto" "] [" "--sport=port" "] [" "-M method" "] [" "-O mod_options" ] 23 | .br 24 | .ti +8 25 | .BR "" [ "--mtu" "] [" "--back" ] 26 | .br 27 | .ti +8 28 | .BR host " [" "packet_len" "]" 29 | .br 30 | .BR traceroute6 31 | .RI " [" options ] 32 | .ad 33 | .SH DESCRIPTION 34 | .I traceroute 35 | tracks the route packets taken from an IP network on their 36 | way to a given host. It utilizes the IP protocol's time to live (TTL) field 37 | and attempts to elicit an ICMP TIME_EXCEEDED response from each gateway 38 | along the path to the host. 39 | .P 40 | .I traceroute6 41 | is equivalent to 42 | .I traceroute 43 | .B \-6 44 | .PP 45 | The only required parameter is the name or IP address of the 46 | destination 47 | .BR host \ . 48 | The optional 49 | .B packet_len\fR`gth 50 | is the total size of the probing packet (default 60 bytes 51 | for IPv4 and 80 for IPv6). The specified size can be ignored 52 | in some situations or increased up to a minimal value. 53 | .PP 54 | This program attempts to trace the route an IP packet would follow to some 55 | internet host by launching probe 56 | packets with a small ttl (time to live) then listening for an 57 | ICMP "time exceeded" reply from a gateway. We start our probes 58 | with a ttl of one and increase by one until we get an ICMP "port 59 | unreachable" (or TCP reset), which means we got to the "host", or hit a max (which 60 | defaults to 30 hops). Three probes (by default) are sent at each ttl setting 61 | and a line is printed showing the ttl, address of the gateway and 62 | round trip time of each probe. The address can be followed by additional 63 | information when requested. If the probe answers come from 64 | different gateways, the address of each responding system will 65 | be printed. If there is no response within a certain timeout, 66 | an "*" (asterisk) is printed for that probe. 67 | .PP 68 | After the trip time, some additional annotation can be printed: 69 | .BR !H , 70 | .BR !N , 71 | or 72 | .B !P 73 | (host, network or protocol unreachable), 74 | .B !S 75 | (source route failed), 76 | .B !F 77 | (fragmentation needed), 78 | .B !X 79 | (communication administratively prohibited), 80 | .B !V 81 | (host precedence violation), 82 | .B !C 83 | (precedence cutoff in effect), or 84 | .B ! 85 | (ICMP unreachable code ). 86 | If almost all the probes result in some kind of unreachable, traceroute 87 | will give up and exit. 88 | .PP 89 | We don't want the destination host to process the UDP probe packets, 90 | so the destination port is set to an unlikely value (you can change it with the 91 | .B \-p 92 | flag). There is no such a problem for ICMP or TCP tracerouting (for TCP we 93 | use half-open technique, which prevents our probes to be seen by applications 94 | on the destination host). 95 | .PP 96 | In the modern network environment the traditional traceroute methods 97 | can not be always applicable, because of widespread use of firewalls. 98 | Such firewalls filter the "unlikely" UDP ports, or even ICMP echoes. 99 | To solve this, some additional tracerouting methods are implemented 100 | (including tcp), see 101 | .B LIST OF AVAILABLE METHODS 102 | below. Such methods try to use particular protocol 103 | and source/destination port, in order to bypass firewalls (to be seen 104 | by firewalls just as a start of allowed type of a network session). 105 | .SH OPTIONS 106 | .TP 107 | .BI \--help 108 | Print help info and exit. 109 | .TP 110 | .BR \-4 ", " \-6 111 | Explicitly force IPv4 or IPv6 tracerouting. By default, the program 112 | will try to resolve the name given, and choose the appropriate 113 | protocol automatically. If resolving a host name returns both 114 | IPv4 and IPv6 addresses, 115 | .I traceroute 116 | will use IPv4. 117 | .TP 118 | .B \-I, \-\-icmp 119 | Use ICMP ECHO for probes 120 | .TP 121 | .B \-T, \-\-tcp 122 | Use TCP SYN for probes 123 | .TP 124 | .B \-d, --debug 125 | Enable socket level debugging (when the Linux kernel supports it) 126 | .TP 127 | .B \-F, --dont-fragment 128 | Do not fragment probe packets. (For IPv4 it also sets DF bit, which tells 129 | intermediate routers not to fragment remotely as well). 130 | .br 131 | 132 | .br 133 | Varying the size of the probing packet by the 134 | .B packet_len 135 | command line parameter, you can manually obtain information 136 | about the MTU of individual network hops. The 137 | .B \--mtu 138 | option (see below) tries to do this automatically. 139 | .br 140 | 141 | .br 142 | Note, that non-fragmented features (like 143 | .B \-F 144 | or 145 | .B \--mtu\fR) 146 | work properly since the Linux kernel 2.6.22 only. 147 | Before that version, IPv6 was always fragmented, IPv4 could use 148 | the once the discovered final mtu only (from the route cache), which can be 149 | less than the actual mtu of a device. 150 | .TP 151 | .BI \-f " first_ttl" ", --first=" first_ttl 152 | Specifies with what TTL to start. Defaults to 1. 153 | .TP 154 | .BI \-g " gateway" ", --gateway=" gateway 155 | Tells traceroute to add an IP source routing option to the outgoing 156 | packet that tells the network to route the packet through the 157 | specified 158 | .IR gateway 159 | (most routers have disabled source routing for security reasons). 160 | In general, several 161 | .IR gateway\fR's 162 | is allowed (comma separated). For IPv6, the form of 163 | .IR num\fB,\fIaddr\fB,\fIaddr... 164 | is allowed, where 165 | .IR num 166 | is a route header type (default is type 2). Note the type 0 route header 167 | is now deprecated (rfc5095). 168 | .TP 169 | .BI \-i " interface" ", --interface=" interface 170 | Specifies the interface through which 171 | .I traceroute 172 | should send packets. By default, the interface is selected 173 | according to the routing table. 174 | .TP 175 | .BI \-m " max_ttl" ", --max-hops=" max_ttl 176 | Specifies the maximum number of hops (max time-to-live value) 177 | .I traceroute 178 | will probe. The default is 30. 179 | .TP 180 | .BI \-N " squeries" ", --sim-queries=" squeries 181 | Specifies the number of probe packets sent out simultaneously. 182 | Sending several probes concurrently can speed up 183 | .I traceroute 184 | considerably. The default value is 16. 185 | .br 186 | Note that some routers and hosts can use ICMP rate throttling. In such 187 | a situation specifying too large number can lead to loss of some responses. 188 | .TP 189 | .BI \-n 190 | Do not try to map IP addresses to host names when displaying them. 191 | .TP 192 | .BI \-p " port" ", --port=" port 193 | For UDP tracing, specifies the destination port base 194 | .I traceroute 195 | will use (the destination port number will be incremented by each probe). 196 | .br 197 | For ICMP tracing, specifies the initial ICMP sequence value (incremented 198 | by each probe too). 199 | .br 200 | For TCP and others specifies just the (constant) destination 201 | port to connect. 202 | .TP 203 | .BI \-t " tos" ", --tos=" tos 204 | For IPv4, set the Type of Service (TOS) and Precedence value. Useful values 205 | are 16 (low delay) and 8 (high throughput). Note that in order to use 206 | some TOS precedence values, you have to be super user. 207 | .br 208 | For IPv6, set the Traffic Control value. 209 | .TP 210 | .BI \-l " flow_label" ", --flowlabel=" flow_label 211 | Use specified flow_label for IPv6 packets. 212 | .TP 213 | .BI \-w " max\fR[\fB,\fIhere\fB,\fInear\fR]" ", --wait=" max\fR[\fB,\fIhere\fB,\fInear\fR] 214 | Determines how long to wait for a response to a probe. 215 | .br 216 | 217 | .br 218 | There are three (in general) float values separated by a comma 219 | (or a slash). 220 | .IR Max 221 | specifies the maximum time (in seconds, default 5.0) to wait, in any case. 222 | .br 223 | 224 | .br 225 | Traditional traceroute implementation always waited whole 226 | .IR max 227 | seconds for any probe. But if we already have some replies from the 228 | .B same 229 | hop, or even from some 230 | .B next 231 | hop, we can use the round trip time of such a reply as a hint 232 | to determine the actual reasonable amount of time to wait. 233 | .br 234 | 235 | .br 236 | The optional 237 | .IR here 238 | (default 3.0) specifies a factor to multiply the round trip time of an already 239 | received response from the 240 | .B same 241 | hop. The resulting value is used as a timeout for the probe, instead of 242 | (but no more than) 243 | .IR max\fR. 244 | The optional 245 | .IR near 246 | (default 10.0) specifies a similar factor for a response from some 247 | .B next 248 | hop. 249 | (The time of the first found result is used in both cases). 250 | .br 251 | 252 | .br 253 | First, we look for the 254 | .B same 255 | hop (of the probe which will be printed first from now). 256 | If nothing found, then look for some 257 | .B next 258 | hop. If nothing found, use 259 | .IR max\fR. 260 | If 261 | .IR here 262 | and/or 263 | .IR near 264 | have zero values, the corresponding computation is skipped. 265 | .br 266 | .IR Here 267 | and 268 | .IR near 269 | are always set to zero if only 270 | .IR max 271 | is specified (for compatibility with previous versions). 272 | .TP 273 | .BI \-q " nqueries" ", --queries=" nqueries 274 | Sets the number of probe packets per hop. The default is 3. 275 | .TP 276 | .BI \-r 277 | Bypass the normal routing tables and send directly to a host on 278 | an attached network. If the host is not on a directly-attached 279 | network, an error is returned. This option can be used to ping a 280 | local host through an interface that has no route through it. 281 | .TP 282 | .BI \-s " source_addr" ", --source=" source_addr 283 | Chooses an alternative source address. Note that you must select the 284 | address of one of the interfaces. 285 | By default, the address of the outgoing interface is used. 286 | .TP 287 | .BI \-z " sendwait" ", --sendwait=" sendwait 288 | Minimal time interval between probes (default 0). 289 | If the value is more than 10, then it specifies a number in milliseconds, 290 | else it is a number of seconds (float point values allowed too). 291 | Useful when some routers use rate-limit for ICMP messages. 292 | .TP 293 | .B \-e, \-\-extensions 294 | Show ICMP extensions (rfc4884). The general form is 295 | .I CLASS\fB/\fITYPE\fB: 296 | followed by a hexadecimal dump. 297 | The MPLS (rfc4950) is shown parsed, in a form: 298 | .B MPLS:L=\fIlabel\fB,E=\fIexp_use\fB,S=\fIstack_bottom\fB,T=\fITTL 299 | (more objects separated by 300 | .B / 301 | ). 302 | .TP 303 | .B \-A, \-\-as\-path\-lookups 304 | Perform AS path lookups in routing registries and print results 305 | directly after the corresponding addresses. 306 | .TP 307 | .B \-V, \-\-version 308 | Print the version and exit. 309 | .br 310 | .P 311 | There are additional options intended for advanced usage 312 | (such as alternate trace methods etc.): 313 | .TP 314 | .B \--sport\fR=\fIport 315 | Chooses the source port to use. Implies 316 | .B \-N\ 1\fR\ -w\ 5 . 317 | Normally source ports (if applicable) are chosen by the system. 318 | .TP 319 | .B \--fwmark\fR=\fImark 320 | Set the firewall mark for outgoing packets (since the Linux kernel 2.6.25). 321 | .TP 322 | .BI \-M " method" ", --module=" name 323 | Use specified method for traceroute operations. Default traditional udp method 324 | has name 325 | .IR default , 326 | icmp 327 | .BR "" ( "-I" ) " 328 | and tcp 329 | .BR "" ( "-T" ) " 330 | have names 331 | .I icmp 332 | and 333 | .I tcp 334 | respectively. 335 | .br 336 | Method-specific options can be passed by 337 | .BR \-O\ . 338 | Most methods have their simple shortcuts, 339 | .BR "" ( "-I " means " -M icmp" , 340 | etc). 341 | .TP 342 | .BI \-O " option" ", --options=" options 343 | Specifies some method-specific option. Several options are separated by comma (or use several 344 | .B \-O 345 | on cmdline). 346 | Each method may have its own specific options, or many not have them at all. 347 | To print information about available options, use 348 | .BR \-O\ help . 349 | .TP 350 | .B \-U, \-\-udp 351 | Use UDP to particular destination port for tracerouting (instead of increasing 352 | the port per each probe). Default port is 53 (dns). 353 | .TP 354 | .BI \-UL 355 | Use UDPLITE for tracerouting (default port is 53). 356 | .TP 357 | .B \-D, \-\-dccp 358 | Use DCCP Requests for probes. 359 | .TP 360 | .BI \-P " protocol" ", --protocol=" protocol 361 | Use raw packet of specified protocol for tracerouting. Default protocol is 362 | 253 (rfc3692). 363 | .TP 364 | .BI \--mtu 365 | Discover MTU along the path being traced. Implies 366 | .BR \-F\ \-N\ 1 . 367 | New 368 | .I mtu 369 | is printed once in a form of 370 | .B F=\fINUM 371 | at the first probe of a hop which requires such 372 | .I mtu 373 | to be reached. (Actually, the correspond "frag needed" icmp message 374 | normally is sent by the previous hop). 375 | .br 376 | 377 | .br 378 | Note, that some routers might cache once the seen information 379 | on a fragmentation. Thus you can receive the final mtu from a closer hop. 380 | Try to specify an unusual 381 | .I tos 382 | by 383 | .B \-t 384 | , this can help for one attempt (then it can be cached there as well). 385 | .br 386 | See 387 | .B \-F 388 | option for more info. 389 | .TP 390 | .BI \--back 391 | Print the number of backward hops when it seems different with the forward 392 | direction. This number is guessed in assumption that remote hops send reply 393 | packets with initial ttl set to either 64, or 128 or 255 (which seems 394 | a common practice). It is printed as a negate value in a form of '-NUM' . 395 | .SH LIST OF AVAILABLE METHODS 396 | In general, a particular traceroute method may have to be chosen by 397 | .BR \-M\ name , 398 | but most of the methods have their simple cmdline switches 399 | (you can see them after the method name, if present). 400 | .SS default 401 | The traditional, ancient method of tracerouting. Used by default. 402 | .P 403 | Probe packets are udp datagrams with so-called "unlikely" destination ports. 404 | The "unlikely" port of the first probe is 33434, then for each next probe 405 | it is incremented by one. Since the ports are expected to be unused, 406 | the destination host normally returns "icmp unreach port" as a final response. 407 | (Nobody knows what happens when some application listens for such ports, 408 | though). 409 | .P 410 | This method is allowed for unprivileged users. 411 | .SS icmp \ \ \ \-I 412 | Most usual method for now, which uses icmp echo packets for probes. 413 | .br 414 | If you can ping(8) the destination host, icmp tracerouting is applicable 415 | as well. 416 | .P 417 | This method may be allowed for unprivileged users 418 | since the kernel 3.0 (IPv4, for IPv6 since 3.11), which supports new 419 | .I dgram icmp 420 | (or 421 | .IR \fR"\fIping\fR") 422 | sockets. To allow such sockets, sysadmin should provide 423 | .I net/ipv4/ping_group_range 424 | sysctl range to match any group of the user. 425 | .br 426 | Options: 427 | .TP 428 | .B raw 429 | Use only raw sockets (the traditional way). 430 | .br 431 | This way is tried first by default (for compatibility reasons), 432 | then new dgram icmp sockets as fallback. 433 | .TP 434 | .B dgram 435 | Use only dgram icmp sockets. 436 | .SS tcp \ \ \ \ \-T 437 | Well-known modern method, intended to bypass firewalls. 438 | .br 439 | Uses the constant destination port (default is 80, http). 440 | .P 441 | If some filters are present in the network path, then most probably 442 | any "unlikely" udp ports (as for 443 | .I default 444 | method) or even icmp echoes (as for 445 | .IR icmp ) 446 | are filtered, and whole tracerouting will just stop at such a firewall. 447 | To bypass a network filter, we have to use only allowed protocol/port 448 | combinations. If we trace for some, say, mailserver, then more likely 449 | .B \-T \-p 25 450 | can reach it, even when 451 | .B \-I 452 | can not. 453 | .P 454 | This method uses well-known "half-open technique", which prevents 455 | applications on the destination host from seeing our probes at all. 456 | Normally, a tcp syn is sent. For non-listened ports we receive tcp reset, 457 | and all is done. For active listening ports we receive tcp syn+ack, but 458 | answer by tcp reset (instead of expected tcp ack), this way the remote tcp 459 | session is dropped even without the application ever taking notice. 460 | .P 461 | There is a couple of options for 462 | .I tcp 463 | method: 464 | .TP 465 | .B syn,ack,fin,rst,psh,urg,ece,cwr 466 | Sets specified tcp flags for probe packet, in any combination. 467 | .TP 468 | .B flags\fR=\fInum 469 | Sets the flags field in the tcp header exactly to 470 | .IR num . 471 | .TP 472 | .B ecn 473 | Send syn packet with tcp flags ECE and CWR (for Explicit Congestion 474 | Notification, rfc3168). 475 | .TP 476 | .B sack,timestamps,window_scaling 477 | Use the corresponding tcp header option in the outgoing probe packet. 478 | .TP 479 | .B sysctl 480 | Use current sysctl 481 | .IR "" ( "/proc/sys/net/*" ) 482 | setting for the tcp header options above and 483 | .BR ecn . 484 | Always set by default, if nothing else specified. 485 | .TP 486 | .B mss\fR=\fInum 487 | Use value of 488 | .I num 489 | for maxseg tcp header option (when 490 | .BR syn ). 491 | .TP 492 | .B info 493 | Print tcp flags of final tcp replies when the target host is reached. 494 | Allows to determine whether an application listens the port and 495 | other useful things. 496 | .P 497 | Default options is 498 | .BR syn,sysctl . 499 | .SS tcpconn 500 | An initial implementation of tcp method, simple using connect(2) call, 501 | which does full tcp session opening. Not recommended for normal use, because 502 | a destination application is always affected (and can be confused). 503 | .SS udp \ \ \ \ \-U 504 | Use udp datagram with constant destination port (default 53, dns). 505 | .br 506 | Intended to bypass firewall as well. 507 | .P 508 | Note, that unlike in 509 | .I tcp 510 | method, the correspond application on the destination host 511 | .B always 512 | receive our probes (with random data), and most can easily be confused 513 | by them. Most cases it will not respond to our packets though, so we will never 514 | see the final hop in the trace. (Fortunately, it seems that at least 515 | dns servers replies with something angry). 516 | .P 517 | This method is allowed for unprivileged users. 518 | .SS udplite \ \ \-UL 519 | Use udplite datagram for probes (with constant destination port, 520 | default 53). 521 | .P 522 | This method is allowed for unprivileged users. 523 | .br 524 | Options: 525 | .TP 526 | .B coverage\fR=\fInum 527 | Set udplite send coverage to 528 | .IR num . 529 | .SS dccp \ \ \-D 530 | Use DCCP Request packets for probes (rfc4340). 531 | .P 532 | This method uses the same "half-open technique" as used for TCP. 533 | The default destination port is 33434. 534 | .P 535 | Options: 536 | .TP 537 | .B service\fR=\fInum 538 | Set DCCP service code to 539 | .IR num 540 | (default is 1885957735). 541 | .SS raw \ \ \ \ \-P proto 542 | Send raw packet of protocol 543 | .IR proto . 544 | .br 545 | No protocol-specific headers are used, just IP header only. 546 | .br 547 | Implies 548 | .B \-N\ 1\fR\ -w\ 5 . 549 | .br 550 | Options: 551 | .TP 552 | .B protocol\fR=\fIproto 553 | Use IP protocol 554 | .I proto 555 | (default 253). 556 | .SH NOTES 557 | .PP 558 | To speed up work, normally several probes are sent simultaneously. 559 | On the other hand, it creates a "storm of packages", especially 560 | in the reply direction. Routers can throttle the rate of icmp responses, 561 | and some of replies can be lost. To avoid this, decrease the number 562 | of simultaneous probes, or even set it to 1 (like in initial traceroute 563 | implementation), i.e. 564 | .B \-N 1 565 | .PP 566 | The final (target) host can drop some of the simultaneous probes, 567 | and might even answer only the latest ones. It can lead to extra 568 | "looks like expired" hops near the final hop. We use a smart algorithm 569 | to auto-detect such a situation, but if it cannot help in your case, just use 570 | .B \-N 1 571 | too. 572 | .PP 573 | For even greater stability you can slow down the program's work by 574 | .B \-z 575 | option, for example use 576 | .B \-z 0.5 577 | for half-second pause between probes. 578 | .PP 579 | To avoid an extra waiting, we use adaptive algorithm for timeouts (see 580 | .B \-w 581 | option for more info). It can lead to premature expiry 582 | (especially when response times differ at times) and printing "*" 583 | instead of a time. In such a case, switch this algorithm off, by specifying 584 | .B \-w 585 | with the desired timeout only (for example, 586 | .B \-w 5\fR). 587 | .PP 588 | If some hops report nothing for every method, the last chance to obtain 589 | something is to use 590 | .B ping -R 591 | command (IPv4, and for nearest 8 hops only). 592 | .SH SEE ALSO 593 | .BR ping (8), 594 | .BR ping6 (8), 595 | .BR tcpdump (8), 596 | .BR netstat (8) 597 | -------------------------------------------------------------------------------- /libsupp/icmp6.h: -------------------------------------------------------------------------------- 1 | /* $NetBSD: icmp6.h,v 1.40 2009/10/31 22:32:17 christos Exp $ */ 2 | /* $KAME: icmp6.h,v 1.84 2003/04/23 10:26:51 itojun Exp $ */ 3 | 4 | 5 | /* 6 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. Neither the name of the project nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | */ 33 | 34 | /* 35 | * Copyright (c) 1982, 1986, 1993 36 | * The Regents of the University of California. All rights reserved. 37 | * 38 | * Redistribution and use in source and binary forms, with or without 39 | * modification, are permitted provided that the following conditions 40 | * are met: 41 | * 1. Redistributions of source code must retain the above copyright 42 | * notice, this list of conditions and the following disclaimer. 43 | * 2. Redistributions in binary form must reproduce the above copyright 44 | * notice, this list of conditions and the following disclaimer in the 45 | * documentation and/or other materials provided with the distribution. 46 | * 3. Neither the name of the University nor the names of its contributors 47 | * may be used to endorse or promote products derived from this software 48 | * without specific prior written permission. 49 | * 50 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 51 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 54 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 | * SUCH DAMAGE. 61 | * 62 | * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93 63 | */ 64 | #include 65 | 66 | #ifndef _NETINET_ICMP6_H_ 67 | #define _NETINET_ICMP6_H_ 68 | 69 | #define ICMPV6_PLD_MAXLEN 1232 /* IPV6_MMTU - sizeof(struct ip6_hdr) 70 | - sizeof(struct icmp6_hdr) */ 71 | 72 | struct icmp6_hdr { 73 | u_int8_t icmp6_type; /* type field */ 74 | u_int8_t icmp6_code; /* code field */ 75 | u_int16_t icmp6_cksum; /* checksum field */ 76 | union { 77 | u_int32_t icmp6_un_data32[1]; /* type-specific field */ 78 | u_int16_t icmp6_un_data16[2]; /* type-specific field */ 79 | u_int8_t icmp6_un_data8[4]; /* type-specific field */ 80 | } icmp6_dataun; 81 | } __packed; 82 | 83 | #define icmp6_data32 icmp6_dataun.icmp6_un_data32 84 | #define icmp6_data16 icmp6_dataun.icmp6_un_data16 85 | #define icmp6_data8 icmp6_dataun.icmp6_un_data8 86 | #define icmp6_pptr icmp6_data32[0] /* parameter prob */ 87 | #define icmp6_mtu icmp6_data32[0] /* packet too big */ 88 | #define icmp6_id icmp6_data16[0] /* echo request/reply */ 89 | #define icmp6_seq icmp6_data16[1] /* echo request/reply */ 90 | #define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */ 91 | 92 | #define ICMP6_DST_UNREACH 1 /* dest unreachable, codes: */ 93 | #define ICMP6_PACKET_TOO_BIG 2 /* packet too big */ 94 | #define ICMP6_TIME_EXCEEDED 3 /* time exceeded, code: */ 95 | #define ICMP6_PARAM_PROB 4 /* ip6 header bad */ 96 | 97 | #define ICMP6_ECHO_REQUEST 128 /* echo service */ 98 | #define ICMP6_ECHO_REPLY 129 /* echo reply */ 99 | #define MLD_LISTENER_QUERY 130 /* multicast listener query */ 100 | #define MLD_LISTENER_REPORT 131 /* multicast listener report */ 101 | #define MLD_LISTENER_DONE 132 /* multicast listener done */ 102 | 103 | /* RFC2292 decls */ 104 | #define ICMP6_MEMBERSHIP_QUERY 130 /* group membership query */ 105 | #define ICMP6_MEMBERSHIP_REPORT 131 /* group membership report */ 106 | #define ICMP6_MEMBERSHIP_REDUCTION 132 /* group membership termination */ 107 | 108 | #ifndef _KERNEL 109 | /* the followings are for backward compatibility to old KAME apps. */ 110 | #define MLD6_LISTENER_QUERY MLD_LISTENER_QUERY 111 | #define MLD6_LISTENER_REPORT MLD_LISTENER_REPORT 112 | #define MLD6_LISTENER_DONE MLD_LISTENER_DONE 113 | #endif 114 | 115 | #define ND_ROUTER_SOLICIT 133 /* router solicitation */ 116 | #define ND_ROUTER_ADVERT 134 /* router advertisement */ 117 | #define ND_NEIGHBOR_SOLICIT 135 /* neighbor solicitation */ 118 | #define ND_NEIGHBOR_ADVERT 136 /* neighbor advertisement */ 119 | #define ND_REDIRECT 137 /* redirect */ 120 | 121 | #define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */ 122 | 123 | #define ICMP6_WRUREQUEST 139 /* who are you request */ 124 | #define ICMP6_WRUREPLY 140 /* who are you reply */ 125 | #define ICMP6_FQDN_QUERY 139 /* FQDN query */ 126 | #define ICMP6_FQDN_REPLY 140 /* FQDN reply */ 127 | #define ICMP6_NI_QUERY 139 /* node information request */ 128 | #define ICMP6_NI_REPLY 140 /* node information reply */ 129 | 130 | /* The definitions below are experimental. TBA */ 131 | #define MLD_MTRACE_RESP 200 /* mtrace response(to sender) */ 132 | #define MLD_MTRACE 201 /* mtrace messages */ 133 | 134 | #ifndef _KERNEL 135 | /* the followings are for backward compatibility to old KAME apps. */ 136 | #define MLD6_MTRACE_RESP MLD_MTRACE_RESP 137 | #define MLD6_MTRACE MLD_MTRACE 138 | #endif 139 | 140 | #define ICMP6_MAXTYPE 201 141 | 142 | #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ 143 | #define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */ 144 | #define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */ 145 | #define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ 146 | #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ 147 | #define ICMP6_DST_UNREACH_NOPORT 4 /* port unreachable */ 148 | 149 | #define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */ 150 | #define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */ 151 | 152 | #define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ 153 | #define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */ 154 | #define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */ 155 | 156 | #define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */ 157 | 158 | #define ICMP6_NI_SUBJ_IPV6 0 /* Query Subject is an IPv6 address */ 159 | #define ICMP6_NI_SUBJ_FQDN 1 /* Query Subject is a Domain name */ 160 | #define ICMP6_NI_SUBJ_IPV4 2 /* Query Subject is an IPv4 address */ 161 | 162 | #define ICMP6_NI_SUCCESS 0 /* node information successful reply */ 163 | #define ICMP6_NI_REFUSED 1 /* node information request is refused */ 164 | #define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */ 165 | 166 | #define ICMP6_ROUTER_RENUMBERING_COMMAND 0 /* rr command */ 167 | #define ICMP6_ROUTER_RENUMBERING_RESULT 1 /* rr result */ 168 | #define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 /* rr seq num reset */ 169 | 170 | /* Used in kernel only */ 171 | #define ND_REDIRECT_ONLINK 0 /* redirect to an on-link node */ 172 | #define ND_REDIRECT_ROUTER 1 /* redirect to a better router */ 173 | 174 | /* 175 | * Multicast Listener Discovery 176 | */ 177 | struct mld_hdr { 178 | struct icmp6_hdr mld_icmp6_hdr; 179 | struct in6_addr mld_addr; /* multicast address */ 180 | } __packed; 181 | 182 | /* definitions to provide backward compatibility to old KAME applications */ 183 | #ifndef _KERNEL 184 | #define mld6_hdr mld_hdr 185 | #define mld6_type mld_type 186 | #define mld6_code mld_code 187 | #define mld6_cksum mld_cksum 188 | #define mld6_maxdelay mld_maxdelay 189 | #define mld6_reserved mld_reserved 190 | #define mld6_addr mld_addr 191 | #endif 192 | 193 | /* shortcut macro definitions */ 194 | #define mld_type mld_icmp6_hdr.icmp6_type 195 | #define mld_code mld_icmp6_hdr.icmp6_code 196 | #define mld_cksum mld_icmp6_hdr.icmp6_cksum 197 | #define mld_maxdelay mld_icmp6_hdr.icmp6_data16[0] 198 | #define mld_reserved mld_icmp6_hdr.icmp6_data16[1] 199 | 200 | #define MLD_MINLEN 24 201 | 202 | /* 203 | * Neighbor Discovery 204 | */ 205 | 206 | struct nd_router_solicit { /* router solicitation */ 207 | struct icmp6_hdr nd_rs_hdr; 208 | /* could be followed by options */ 209 | } __packed; 210 | 211 | #define nd_rs_type nd_rs_hdr.icmp6_type 212 | #define nd_rs_code nd_rs_hdr.icmp6_code 213 | #define nd_rs_cksum nd_rs_hdr.icmp6_cksum 214 | #define nd_rs_reserved nd_rs_hdr.icmp6_data32[0] 215 | 216 | struct nd_router_advert { /* router advertisement */ 217 | struct icmp6_hdr nd_ra_hdr; 218 | u_int32_t nd_ra_reachable; /* reachable time */ 219 | u_int32_t nd_ra_retransmit; /* retransmit timer */ 220 | /* could be followed by options */ 221 | } __packed; 222 | 223 | #define nd_ra_type nd_ra_hdr.icmp6_type 224 | #define nd_ra_code nd_ra_hdr.icmp6_code 225 | #define nd_ra_cksum nd_ra_hdr.icmp6_cksum 226 | #define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0] 227 | #define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1] 228 | #define ND_RA_FLAG_MANAGED 0x80 229 | #define ND_RA_FLAG_OTHER 0x40 230 | #define ND_RA_FLAG_HOME_AGENT 0x20 231 | 232 | /* 233 | * Router preference values based on RFC4199. 234 | */ 235 | #define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */ 236 | 237 | #define ND_RA_FLAG_RTPREF_HIGH 0x08 /* 00001000 */ 238 | #define ND_RA_FLAG_RTPREF_MEDIUM 0x00 /* 00000000 */ 239 | #define ND_RA_FLAG_RTPREF_LOW 0x18 /* 00011000 */ 240 | #define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */ 241 | 242 | #define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1] 243 | 244 | struct nd_neighbor_solicit { /* neighbor solicitation */ 245 | struct icmp6_hdr nd_ns_hdr; 246 | struct in6_addr nd_ns_target; /*target address */ 247 | /* could be followed by options */ 248 | } __packed; 249 | 250 | #define nd_ns_type nd_ns_hdr.icmp6_type 251 | #define nd_ns_code nd_ns_hdr.icmp6_code 252 | #define nd_ns_cksum nd_ns_hdr.icmp6_cksum 253 | #define nd_ns_reserved nd_ns_hdr.icmp6_data32[0] 254 | 255 | struct nd_neighbor_advert { /* neighbor advertisement */ 256 | struct icmp6_hdr nd_na_hdr; 257 | struct in6_addr nd_na_target; /* target address */ 258 | /* could be followed by options */ 259 | } __packed; 260 | 261 | #define nd_na_type nd_na_hdr.icmp6_type 262 | #define nd_na_code nd_na_hdr.icmp6_code 263 | #define nd_na_cksum nd_na_hdr.icmp6_cksum 264 | #define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0] 265 | #if BYTE_ORDER == BIG_ENDIAN 266 | #define ND_NA_FLAG_ROUTER 0x80000000 267 | #define ND_NA_FLAG_SOLICITED 0x40000000 268 | #define ND_NA_FLAG_OVERRIDE 0x20000000 269 | #else 270 | #if BYTE_ORDER == LITTLE_ENDIAN 271 | #define ND_NA_FLAG_ROUTER 0x80 272 | #define ND_NA_FLAG_SOLICITED 0x40 273 | #define ND_NA_FLAG_OVERRIDE 0x20 274 | #endif 275 | #endif 276 | 277 | struct nd_redirect { /* redirect */ 278 | struct icmp6_hdr nd_rd_hdr; 279 | struct in6_addr nd_rd_target; /* target address */ 280 | struct in6_addr nd_rd_dst; /* destination address */ 281 | /* could be followed by options */ 282 | } __packed; 283 | 284 | #define nd_rd_type nd_rd_hdr.icmp6_type 285 | #define nd_rd_code nd_rd_hdr.icmp6_code 286 | #define nd_rd_cksum nd_rd_hdr.icmp6_cksum 287 | #define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] 288 | 289 | struct nd_opt_hdr { /* Neighbor discovery option header */ 290 | u_int8_t nd_opt_type; 291 | u_int8_t nd_opt_len; 292 | /* followed by option specific data*/ 293 | } __packed; 294 | 295 | #define ND_OPT_SOURCE_LINKADDR 1 296 | #define ND_OPT_TARGET_LINKADDR 2 297 | #define ND_OPT_PREFIX_INFORMATION 3 298 | #define ND_OPT_REDIRECTED_HEADER 4 299 | #define ND_OPT_MTU 5 300 | #define ND_OPT_ADVINTERVAL 7 301 | #define ND_OPT_HOMEAGENT_INFO 8 302 | #define ND_OPT_SOURCE_ADDRLIST 9 303 | #define ND_OPT_TARGET_ADDRLIST 10 304 | #define ND_OPT_RDNSS 25 305 | /* draft-ietf-ipngwg-router-preference, not officially assigned yet */ 306 | #define ND_OPT_ROUTE_INFO 200 307 | /* draft-ietf-mobileip-hmipv6, not officially assigned yet */ 308 | #define ND_OPT_MAP 201 309 | 310 | struct nd_opt_route_info { /* route info */ 311 | u_int8_t nd_opt_rti_type; 312 | u_int8_t nd_opt_rti_len; 313 | u_int8_t nd_opt_rti_prefixlen; 314 | u_int8_t nd_opt_rti_flags; 315 | u_int32_t nd_opt_rti_lifetime; 316 | /* prefix follows */ 317 | }; 318 | 319 | struct nd_opt_prefix_info { /* prefix information */ 320 | u_int8_t nd_opt_pi_type; 321 | u_int8_t nd_opt_pi_len; 322 | u_int8_t nd_opt_pi_prefix_len; 323 | u_int8_t nd_opt_pi_flags_reserved; 324 | u_int32_t nd_opt_pi_valid_time; 325 | u_int32_t nd_opt_pi_preferred_time; 326 | u_int32_t nd_opt_pi_reserved2; 327 | struct in6_addr nd_opt_pi_prefix; 328 | } __packed; 329 | 330 | #define ND_OPT_PI_FLAG_ONLINK 0x80 331 | #define ND_OPT_PI_FLAG_AUTO 0x40 332 | 333 | struct nd_opt_rd_hdr { /* redirected header */ 334 | u_int8_t nd_opt_rh_type; 335 | u_int8_t nd_opt_rh_len; 336 | u_int16_t nd_opt_rh_reserved1; 337 | u_int32_t nd_opt_rh_reserved2; 338 | /* followed by IP header and data */ 339 | } __packed; 340 | 341 | struct nd_opt_mtu { /* MTU option */ 342 | u_int8_t nd_opt_mtu_type; 343 | u_int8_t nd_opt_mtu_len; 344 | u_int16_t nd_opt_mtu_reserved; 345 | u_int32_t nd_opt_mtu_mtu; 346 | } __packed; 347 | 348 | struct nd_opt_rdnss { /* RDNSS option RFC 5006 */ 349 | u_int8_t nd_opt_rdnss_type; 350 | u_int8_t nd_opt_rdnss_len; 351 | u_int16_t nd_opt_rdnss_reserved; 352 | u_int32_t nd_opt_rdnss_lifetime; 353 | /* followed by list of IP prefixes */ 354 | } __packed; 355 | 356 | /* 357 | * icmp6 namelookup 358 | */ 359 | 360 | struct icmp6_namelookup { 361 | struct icmp6_hdr icmp6_nl_hdr; 362 | u_int8_t icmp6_nl_nonce[8]; 363 | int32_t icmp6_nl_ttl; 364 | #if 0 365 | u_int8_t icmp6_nl_len; 366 | u_int8_t icmp6_nl_name[3]; 367 | #endif 368 | /* could be followed by options */ 369 | } __packed; 370 | 371 | /* 372 | * icmp6 node information 373 | */ 374 | struct icmp6_nodeinfo { 375 | struct icmp6_hdr icmp6_ni_hdr; 376 | u_int8_t icmp6_ni_nonce[8]; 377 | /* could be followed by reply data */ 378 | } __packed; 379 | 380 | #define ni_type icmp6_ni_hdr.icmp6_type 381 | #define ni_code icmp6_ni_hdr.icmp6_code 382 | #define ni_cksum icmp6_ni_hdr.icmp6_cksum 383 | #define ni_qtype icmp6_ni_hdr.icmp6_data16[0] 384 | #define ni_flags icmp6_ni_hdr.icmp6_data16[1] 385 | 386 | #define NI_QTYPE_NOOP 0 /* NOOP */ 387 | #define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes */ 388 | #define NI_QTYPE_FQDN 2 /* FQDN (draft 04) */ 389 | #define NI_QTYPE_DNSNAME 2 /* DNS Name */ 390 | #define NI_QTYPE_NODEADDR 3 /* Node Addresses */ 391 | #define NI_QTYPE_IPV4ADDR 4 /* IPv4 Addresses */ 392 | 393 | #if BYTE_ORDER == BIG_ENDIAN 394 | #define NI_SUPTYPE_FLAG_COMPRESS 0x1 395 | #define NI_FQDN_FLAG_VALIDTTL 0x1 396 | #elif BYTE_ORDER == LITTLE_ENDIAN 397 | #define NI_SUPTYPE_FLAG_COMPRESS 0x0100 398 | #define NI_FQDN_FLAG_VALIDTTL 0x0100 399 | #endif 400 | 401 | #ifdef NAME_LOOKUPS_04 402 | #if BYTE_ORDER == BIG_ENDIAN 403 | #define NI_NODEADDR_FLAG_LINKLOCAL 0x1 404 | #define NI_NODEADDR_FLAG_SITELOCAL 0x2 405 | #define NI_NODEADDR_FLAG_GLOBAL 0x4 406 | #define NI_NODEADDR_FLAG_ALL 0x8 407 | #define NI_NODEADDR_FLAG_TRUNCATE 0x10 408 | #define NI_NODEADDR_FLAG_ANYCAST 0x20 /* just experimental. not in spec */ 409 | #elif BYTE_ORDER == LITTLE_ENDIAN 410 | #define NI_NODEADDR_FLAG_LINKLOCAL 0x0100 411 | #define NI_NODEADDR_FLAG_SITELOCAL 0x0200 412 | #define NI_NODEADDR_FLAG_GLOBAL 0x0400 413 | #define NI_NODEADDR_FLAG_ALL 0x0800 414 | #define NI_NODEADDR_FLAG_TRUNCATE 0x1000 415 | #define NI_NODEADDR_FLAG_ANYCAST 0x2000 /* just experimental. not in spec */ 416 | #endif 417 | #else /* draft-ietf-ipngwg-icmp-name-lookups-05 (and later?) */ 418 | #if BYTE_ORDER == BIG_ENDIAN 419 | #define NI_NODEADDR_FLAG_TRUNCATE 0x1 420 | #define NI_NODEADDR_FLAG_ALL 0x2 421 | #define NI_NODEADDR_FLAG_COMPAT 0x4 422 | #define NI_NODEADDR_FLAG_LINKLOCAL 0x8 423 | #define NI_NODEADDR_FLAG_SITELOCAL 0x10 424 | #define NI_NODEADDR_FLAG_GLOBAL 0x20 425 | #define NI_NODEADDR_FLAG_ANYCAST 0x40 /* just experimental. not in spec */ 426 | #elif BYTE_ORDER == LITTLE_ENDIAN 427 | #define NI_NODEADDR_FLAG_TRUNCATE 0x0100 428 | #define NI_NODEADDR_FLAG_ALL 0x0200 429 | #define NI_NODEADDR_FLAG_COMPAT 0x0400 430 | #define NI_NODEADDR_FLAG_LINKLOCAL 0x0800 431 | #define NI_NODEADDR_FLAG_SITELOCAL 0x1000 432 | #define NI_NODEADDR_FLAG_GLOBAL 0x2000 433 | #define NI_NODEADDR_FLAG_ANYCAST 0x4000 /* just experimental. not in spec */ 434 | #endif 435 | #endif 436 | 437 | struct ni_reply_fqdn { 438 | u_int32_t ni_fqdn_ttl; /* TTL */ 439 | u_int8_t ni_fqdn_namelen; /* length in octets of the FQDN */ 440 | u_int8_t ni_fqdn_name[3]; /* XXX: alignment */ 441 | } __packed; 442 | 443 | /* 444 | * Router Renumbering. as router-renum-08.txt 445 | */ 446 | struct icmp6_router_renum { /* router renumbering header */ 447 | struct icmp6_hdr rr_hdr; 448 | u_int8_t rr_segnum; 449 | u_int8_t rr_flags; 450 | u_int16_t rr_maxdelay; 451 | u_int32_t rr_reserved; 452 | } __packed; 453 | 454 | #define ICMP6_RR_FLAGS_TEST 0x80 455 | #define ICMP6_RR_FLAGS_REQRESULT 0x40 456 | #define ICMP6_RR_FLAGS_FORCEAPPLY 0x20 457 | #define ICMP6_RR_FLAGS_SPECSITE 0x10 458 | #define ICMP6_RR_FLAGS_PREVDONE 0x08 459 | 460 | #define rr_type rr_hdr.icmp6_type 461 | #define rr_code rr_hdr.icmp6_code 462 | #define rr_cksum rr_hdr.icmp6_cksum 463 | #define rr_seqnum rr_hdr.icmp6_data32[0] 464 | 465 | struct rr_pco_match { /* match prefix part */ 466 | u_int8_t rpm_code; 467 | u_int8_t rpm_len; 468 | u_int8_t rpm_ordinal; 469 | u_int8_t rpm_matchlen; 470 | u_int8_t rpm_minlen; 471 | u_int8_t rpm_maxlen; 472 | u_int16_t rpm_reserved; 473 | struct in6_addr rpm_prefix; 474 | } __packed; 475 | 476 | #define RPM_PCO_ADD 1 477 | #define RPM_PCO_CHANGE 2 478 | #define RPM_PCO_SETGLOBAL 3 479 | #define RPM_PCO_MAX 4 480 | 481 | struct rr_pco_use { /* use prefix part */ 482 | u_int8_t rpu_uselen; 483 | u_int8_t rpu_keeplen; 484 | u_int8_t rpu_ramask; 485 | u_int8_t rpu_raflags; 486 | u_int32_t rpu_vltime; 487 | u_int32_t rpu_pltime; 488 | u_int32_t rpu_flags; 489 | struct in6_addr rpu_prefix; 490 | } __packed; 491 | #define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x80 492 | #define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x40 493 | 494 | #if BYTE_ORDER == BIG_ENDIAN 495 | #define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000 496 | #define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000 497 | #elif BYTE_ORDER == LITTLE_ENDIAN 498 | #define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80 499 | #define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40 500 | #endif 501 | 502 | struct rr_result { /* router renumbering result message */ 503 | u_int16_t rrr_flags; 504 | u_int8_t rrr_ordinal; 505 | u_int8_t rrr_matchedlen; 506 | u_int32_t rrr_ifid; 507 | struct in6_addr rrr_prefix; 508 | } __packed; 509 | #if BYTE_ORDER == BIG_ENDIAN 510 | #define ICMP6_RR_RESULT_FLAGS_OOB 0x0002 511 | #define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001 512 | #elif BYTE_ORDER == LITTLE_ENDIAN 513 | #define ICMP6_RR_RESULT_FLAGS_OOB 0x0200 514 | #define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100 515 | #endif 516 | 517 | /* 518 | * icmp6 filter structures. 519 | */ 520 | 521 | struct icmp6_filter { 522 | u_int32_t icmp6_filt[8]; 523 | }; 524 | 525 | #define ICMP6_FILTER_SETPASSALL(filterp) \ 526 | (void)memset(filterp, 0xff, sizeof(struct icmp6_filter)) 527 | #define ICMP6_FILTER_SETBLOCKALL(filterp) \ 528 | (void)memset(filterp, 0x00, sizeof(struct icmp6_filter)) 529 | #define ICMP6_FILTER_SETPASS(type, filterp) \ 530 | (((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31))) 531 | #define ICMP6_FILTER_SETBLOCK(type, filterp) \ 532 | (((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))) 533 | #define ICMP6_FILTER_WILLPASS(type, filterp) \ 534 | ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0) 535 | #define ICMP6_FILTER_WILLBLOCK(type, filterp) \ 536 | ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0) 537 | 538 | /* 539 | * Variables related to this implementation 540 | * of the internet control message protocol version 6. 541 | */ 542 | 543 | /* 544 | * IPv6 ICMP statistics. 545 | * Each counter is an unsigned 64-bit value. 546 | */ 547 | #define ICMP6_STAT_ERROR 0 /* # of calls to icmp6_error */ 548 | #define ICMP6_STAT_CANTERROR 1 /* no error (old was icmp) */ 549 | #define ICMP6_STAT_TOOFREQ 2 /* no error (rate limitation) */ 550 | #define ICMP6_STAT_OUTHIST 3 /* # of output messages */ 551 | /* space for 256 counters */ 552 | #define ICMP6_STAT_BADCODE 259 /* icmp6_code out of range */ 553 | #define ICMP6_STAT_TOOSHORT 260 /* packet < sizeof(struct icmp6_hdr) */ 554 | #define ICMP6_STAT_CHECKSUM 261 /* bad checksum */ 555 | #define ICMP6_STAT_BADLEN 262 /* calculated bound mismatch */ 556 | /* 557 | * number of responses; this member is inherited from the netinet code, 558 | * but for netinet6 code, it is already available in outhist[]. 559 | */ 560 | #define ICMP6_STAT_REFLECT 263 561 | #define ICMP6_STAT_INHIST 264 /* # of input messages */ 562 | /* space for 256 counters */ 563 | #define ICMP6_STAT_ND_TOOMANYOPT 520 /* too many ND options */ 564 | #define ICMP6_STAT_OUTERRHIST 521 565 | /* space for 13 counters */ 566 | #define ICMP6_STAT_PMTUCHG 534 /* path MTU changes */ 567 | #define ICMP6_STAT_ND_BADOPT 535 /* bad ND options */ 568 | #define ICMP6_STAT_BADNS 536 /* bad neighbor solicititation */ 569 | #define ICMP6_STAT_BADNA 537 /* bad neighbor advertisement */ 570 | #define ICMP6_STAT_BADRS 538 /* bad router solicitiation */ 571 | #define ICMP6_STAT_BADRA 539 /* bad router advertisement */ 572 | #define ICMP6_STAT_BADREDIRECT 540 /* bad redirect message */ 573 | 574 | #define ICMP6_NSTATS 541 575 | 576 | #define ICMP6_ERRSTAT_DST_UNREACH_NOROUTE 0 577 | #define ICMP6_ERRSTAT_DST_UNREACH_ADMIN 1 578 | #define ICMP6_ERRSTAT_DST_UNREACH_BEYONDSCOPE 2 579 | #define ICMP6_ERRSTAT_DST_UNREACH_ADDR 3 580 | #define ICMP6_ERRSTAT_DST_UNREACH_NOPORT 4 581 | #define ICMP6_ERRSTAT_PACKET_TOO_BIG 5 582 | #define ICMP6_ERRSTAT_TIME_EXCEED_TRANSIT 6 583 | #define ICMP6_ERRSTAT_TIME_EXCEED_REASSEMBLY 7 584 | #define ICMP6_ERRSTAT_PARAMPROB_HEADER 8 585 | #define ICMP6_ERRSTAT_PARAMPROB_NEXTHEADER 9 586 | #define ICMP6_ERRSTAT_PARAMPROB_OPTION 10 587 | #define ICMP6_ERRSTAT_REDIRECT 11 588 | #define ICMP6_ERRSTAT_UNKNOWN 12 589 | 590 | /* 591 | * Names for ICMP sysctl objects 592 | */ 593 | #define ICMPV6CTL_STATS 1 594 | #define ICMPV6CTL_REDIRACCEPT 2 /* accept/process redirects */ 595 | #define ICMPV6CTL_REDIRTIMEOUT 3 /* redirect cache time */ 596 | #if 0 /*obsoleted*/ 597 | #define ICMPV6CTL_ERRRATELIMIT 5 /* ICMPv6 error rate limitation */ 598 | #endif 599 | #define ICMPV6CTL_ND6_PRUNE 6 600 | #define ICMPV6CTL_ND6_DELAY 8 601 | #define ICMPV6CTL_ND6_UMAXTRIES 9 602 | #define ICMPV6CTL_ND6_MMAXTRIES 10 603 | #define ICMPV6CTL_ND6_USELOOPBACK 11 604 | /*#define ICMPV6CTL_ND6_PROXYALL 12 obsoleted, do not reuse here */ 605 | #define ICMPV6CTL_NODEINFO 13 606 | #define ICMPV6CTL_ERRPPSLIMIT 14 /* ICMPv6 error pps limitation */ 607 | #define ICMPV6CTL_ND6_MAXNUDHINT 15 608 | #define ICMPV6CTL_MTUDISC_HIWAT 16 609 | #define ICMPV6CTL_MTUDISC_LOWAT 17 610 | #define ICMPV6CTL_ND6_DEBUG 18 611 | #define ICMPV6CTL_ND6_DRLIST 19 612 | #define ICMPV6CTL_ND6_PRLIST 20 613 | #define ICMPV6CTL_ND6_MAXQLEN 24 614 | #define ICMPV6CTL_MAXID 25 615 | 616 | #define ICMPV6CTL_NAMES { \ 617 | { 0, 0 }, \ 618 | { 0, 0 }, \ 619 | { "rediraccept", CTLTYPE_INT }, \ 620 | { "redirtimeout", CTLTYPE_INT }, \ 621 | { 0, 0 }, \ 622 | { 0, 0 }, \ 623 | { "nd6_prune", CTLTYPE_INT }, \ 624 | { 0, 0 }, \ 625 | { "nd6_delay", CTLTYPE_INT }, \ 626 | { "nd6_umaxtries", CTLTYPE_INT }, \ 627 | { "nd6_mmaxtries", CTLTYPE_INT }, \ 628 | { "nd6_useloopback", CTLTYPE_INT }, \ 629 | { 0, 0 }, \ 630 | { "nodeinfo", CTLTYPE_INT }, \ 631 | { "errppslimit", CTLTYPE_INT }, \ 632 | { "nd6_maxnudhint", CTLTYPE_INT }, \ 633 | { "mtudisc_hiwat", CTLTYPE_INT }, \ 634 | { "mtudisc_lowat", CTLTYPE_INT }, \ 635 | { "nd6_debug", CTLTYPE_INT }, \ 636 | { 0, 0 }, \ 637 | { 0, 0 }, \ 638 | { 0, 0 }, \ 639 | { 0, 0 }, \ 640 | { 0, 0 }, \ 641 | { "nd6_maxqueuelen", CTLTYPE_INT }, \ 642 | } 643 | 644 | #define RTF_PROBEMTU RTF_PROTO1 645 | 646 | #ifdef _KERNEL 647 | struct rtentry; 648 | struct rttimer; 649 | struct in6_multi; 650 | 651 | void icmp6_init(void); 652 | void icmp6_paramerror(struct mbuf *, int); 653 | void icmp6_error(struct mbuf *, int, int, int); 654 | void icmp6_error2(struct mbuf *, int, int, int, struct ifnet *); 655 | int icmp6_input(struct mbuf **, int *, int); 656 | void icmp6_fasttimo(void); 657 | void icmp6_reflect(struct mbuf *, size_t); 658 | void icmp6_prepare(struct mbuf *); 659 | void icmp6_redirect_input(struct mbuf *, int); 660 | void icmp6_redirect_output(struct mbuf *, struct rtentry *); 661 | int icmp6_sysctl(int *, u_int, void *, size_t *, void *, size_t); 662 | 663 | void icmp6_statinc(u_int); 664 | 665 | struct ip6ctlparam; 666 | void icmp6_mtudisc_update(struct ip6ctlparam *, int); 667 | void icmp6_mtudisc_callback_register(void (*)(struct in6_addr *)); 668 | 669 | /* XXX: is this the right place for these macros? */ 670 | #define icmp6_ifstat_inc(ifp, tag) \ 671 | do { \ 672 | if (ifp) \ 673 | ((struct in6_ifextra *)((ifp)->if_afdata[AF_INET6]))->icmp6_ifstat->tag++; \ 674 | } while (/*CONSTCOND*/ 0) 675 | 676 | #define icmp6_ifoutstat_inc(ifp, type, code) \ 677 | do { \ 678 | icmp6_ifstat_inc(ifp, ifs6_out_msg); \ 679 | switch(type) { \ 680 | case ICMP6_DST_UNREACH: \ 681 | icmp6_ifstat_inc(ifp, ifs6_out_dstunreach); \ 682 | if (code == ICMP6_DST_UNREACH_ADMIN) \ 683 | icmp6_ifstat_inc(ifp, ifs6_out_adminprohib); \ 684 | break; \ 685 | case ICMP6_PACKET_TOO_BIG: \ 686 | icmp6_ifstat_inc(ifp, ifs6_out_pkttoobig); \ 687 | break; \ 688 | case ICMP6_TIME_EXCEEDED: \ 689 | icmp6_ifstat_inc(ifp, ifs6_out_timeexceed); \ 690 | break; \ 691 | case ICMP6_PARAM_PROB: \ 692 | icmp6_ifstat_inc(ifp, ifs6_out_paramprob); \ 693 | break; \ 694 | case ICMP6_ECHO_REQUEST: \ 695 | icmp6_ifstat_inc(ifp, ifs6_out_echo); \ 696 | break; \ 697 | case ICMP6_ECHO_REPLY: \ 698 | icmp6_ifstat_inc(ifp, ifs6_out_echoreply); \ 699 | break; \ 700 | case MLD_LISTENER_QUERY: \ 701 | icmp6_ifstat_inc(ifp, ifs6_out_mldquery); \ 702 | break; \ 703 | case MLD_LISTENER_REPORT: \ 704 | icmp6_ifstat_inc(ifp, ifs6_out_mldreport); \ 705 | break; \ 706 | case MLD_LISTENER_DONE: \ 707 | icmp6_ifstat_inc(ifp, ifs6_out_mlddone); \ 708 | break; \ 709 | case ND_ROUTER_SOLICIT: \ 710 | icmp6_ifstat_inc(ifp, ifs6_out_routersolicit); \ 711 | break; \ 712 | case ND_ROUTER_ADVERT: \ 713 | icmp6_ifstat_inc(ifp, ifs6_out_routeradvert); \ 714 | break; \ 715 | case ND_NEIGHBOR_SOLICIT: \ 716 | icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit); \ 717 | break; \ 718 | case ND_NEIGHBOR_ADVERT: \ 719 | icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert); \ 720 | break; \ 721 | case ND_REDIRECT: \ 722 | icmp6_ifstat_inc(ifp, ifs6_out_redirect); \ 723 | break; \ 724 | } \ 725 | } while (/*CONSTCOND*/ 0) 726 | 727 | extern int icmp6_rediraccept; /* accept/process redirects */ 728 | extern int icmp6_redirtimeout; /* cache time for redirect routes */ 729 | #endif /* _KERNEL */ 730 | 731 | #endif /* !_NETINET_ICMP6_H_ */ 732 | -------------------------------------------------------------------------------- /COPYING.LIB: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 489 | 490 | Also add information on how to contact you by electronic and paper mail. 491 | 492 | You should also get your employer (if you work as a programmer) or your 493 | school, if any, to sign a "copyright disclaimer" for the library, if 494 | necessary. Here is a sample; alter the names: 495 | 496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker. 498 | 499 | , 1 April 1990 500 | Ty Coon, President of Vice 501 | 502 | That's all there is to it! 503 | --------------------------------------------------------------------------------