diff --git a/.gitignore b/.gitignore
index df0f762..4cefe3e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,23 @@
-autom4te.cache
-.deps
+# .gitignore
+*.o
+
+Makefile
+Makefile.in
+aclocal.m4
+confdefs.h
+config.*
+configure
+confinc
+confmf
+conftest.*
+depcomp
+install-sh
+missing
+stamp-h1*
+
+/autom4te.cache/
+/.deps/
+/ChangeLog
+/INSTALL
+/mtr
+
diff --git a/AUTHORS b/AUTHORS
index 19ad594..690151a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -45,6 +45,7 @@
         Rob Foehl (rwf@loonybin.net)
         Mircea Damian
         Cougar (cougar@random.ee)
+        Travis Cross <tc@traviscross.com>
         Brian Casey
         Andrew Brown (atatat@atatdot.net)
         Bill Bogstad (bogstad@pobox.com) 
diff --git a/FORMATS b/FORMATS
index 5404e87..7cddb55 100644
--- a/FORMATS
+++ b/FORMATS
@@ -29,3 +29,72 @@ t <pos> <pingtime> <timestamp>
 Timestampline is not  yet implemented. Need to find out how to do
 ICMP timestamping first. :-)
 
+
+Someone suggested to put the following text here. As to context: Some
+people are wondering why mtr sometimes reports hosts beyond the
+destination host. 
+
+
+The FINAL host will occasionally be mentioned at position n, n+1, n+2
+etc.
+
+You know traceroute, right? It sends a packet, waits for the reply to
+come back and when it comes back, it sends the next packet.
+
+If say hosts 5-8 do not send "time exceeded" packets, you'll wait a
+4*3 = twelve seconds extra before you get any results on hosts 9 and
+further. MTR doesn't work like that.
+
+In theory we could send out a probe for host 1-40 all at once. But
+this would pose an unnecessary burden on the network. So what we do,
+is we send out probes for a max of 5 hosts beyond where we've seen a
+reply. So in the example above, we'd see a reply from router at
+position 4, then we'd send out 5-9 (and because the max-host is now at
+9, we'll send them out at 1s/9 = 111ms intervals). When the reply from
+host 9 comes back, we'll start probing for host 10-15 (at about 60ms
+intervals). But suppose the network delay upto host 9 is already 200ms
+and suppose our destination host is at position 11. Then by the time
+the packet from host 11 comes back, we'll already have sent probe
+packets for position 12, 13, and 14! Those will come back as
+"destination reached" and be reported by the "raw" mode.
+
+Curses mode will stop showing hosts with position numbers beyond the
+first reply of the destination host. It could gather the information
+about replies to packets sent as probes FURTHER than it actually is
+into the line displayed at its true position, but it doesn't (yet).
+
+In fact the above example is almost completely true:
+
+% mtr -r -n -c 2 152.179.99.218 | tail -5
+ 13.|-- 144.232.18.238 0.0% 2 94.8 95.4 94.8 96.0 0.8
+ 14.|-- 152.63.16.182 0.0% 2 95.1 95.5 95.1 95.8 0.5
+ 15.|-- 152.63.64.106 0.0% 2 163.9 163.9 163.9 164.0 0.1
+ 16.|-- 152.63.50.89 50.0% 2 163.7 163.7 163.7 163.7 0.0
+ 17.|-- 152.179.99.218 50.0% 2 168.2 168.2 168.2 168.2 0.0
+% mtr -l -c 2 152.179.99.218 | grep -v "^[dp]" |tail -7
+h 10 144.232.1.41
+h 11 144.232.4.96
+h 16 152.179.99.218
+h 17 152.179.99.218
+h 18 152.179.99.218
+h 12 144.232.18.238
+h 13 152.63.16.182
+
+As you can see we get the reply from the destination host at position
+16 AFTER we've sent probes for position 17 and 18. When those come
+back, they are reported. That's what raw mode does. It reports the raw
+information.
+
+If you write a backend for the raw mode, it's up to you to
+filter/display the results.
+
+h 10 144.232.1.41
+h 11 144.232.4.96
+h 12 144.232.18.238
+h 13 152.63.16.182
+h 14 152.63.64.106
+h 15 152.63.50.89
+h 16 152.179.99.218
+h 17 152.179.99.218
+h 18 152.179.99.218
+
diff --git a/Makefile.am b/Makefile.am
index 3e60cdb..013ef42 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,6 +6,7 @@ install-exec-hook:
 	chmod u+s $(DESTDIR)$(sbindir)/mtr
 
 mtr_SOURCES = mtr.c \
+              asn.c asn.h \
               net.c net.h \
               dns.c dns.h \
               raw.c raw.h \
diff --git a/NEWS b/NEWS
index a4766b5..ae64755 100644
--- a/NEWS
+++ b/NEWS
@@ -1,71 +1,104 @@
 WHAT'S NEW?
+
+V0.83 Move to github. Mostly done by Travis.
+
+Author: Travis Cross <tc@traviscross.com>
+    Add autotools bootstrap script
+    Update README for building from git repository
+    Cleanup whitespace in the NEWS file
+    Resolve -Wunused-but-set-variable warnings
+    Resolve -Wnull-dereference clang warning
+    Add -z / --show-ip support
+Author: R.E. Wolff <R.E.Wolff@BitWizard.nl> (mostly from patches by others)
+    some running patches
+    Made report wide switch properly to displayreport mode. Bug #780647
+    fixed gtk field order. Bug #701513
+    added aslookup patch from bug #701514
+    added some extra clarifications to the SECURITY file.
+    enable ipv6 resolvers. By Antonio Querubin. Fixes bug #752583
+
   V0.82 Removed old Changelog file appended at the end as oldest
-        changes. 
+        changes.
         2011-03-28  Mark Kamichoff <prox@prolixium.com>
-        Enable decoding of ICMP extensions for MPLS for curses and 
-	report interfaces.  Use the -e flag or press 'e' to enable it.
+        Enable decoding of ICMP extensions for MPLS for curses and
+        report interfaces.  Use the -e flag or press 'e' to enable it.
+
   V0.81 Moved to git. Testing git...
-  V0.80 Some compilation fixes for BSD by Jeremy Chadwick 
+
+  V0.80 Some compilation fixes for BSD by Jeremy Chadwick
         <freebsd@jdc.parodius.com>
-  V0.78/0.79 some compilation fixes for BSD&others by 
+
+  V0.78/0.79 some compilation fixes for BSD&others by
         Thomas Klausner <wiz@NetBSD.org>
-  V0.76 display load sharing hosts in --raw output. 
-        added about button in gui. 
+
+  V0.76 display load sharing hosts in --raw output.
+        added about button in gui.
+
   v0.75 Feelgood patch to move sprintf to snprintf. People might think
-        that sprintf might cause a buffer overflow. Now it's clean. 
+        that sprintf might cause a buffer overflow. Now it's clean.
         cut-paste patches: you can now copy an intermediate host to the
-        clipboard. 
-  v0.74 Martin Pels' patch to allow UDP probes. 
+        clipboard.
+
+  v0.74 Martin Pels' patch to allow UDP probes.
         KES reported a build problem. Turns out I need to install gtk-1.2
-        on my development sytem, otherwise my release script causes the 
-        build to break. 
-        changed some docs to advertise the new mailing list. 
+        on my development sytem, otherwise my release script causes the
+        build to break.
+        changed some docs to advertise the new mailing list.
         added documentation for the Mac OS X compilation problem.
-        added -Wno-pointer-sign to the compiler options. 
+        added -Wno-pointer-sign to the compiler options.
         Nico Lichtmaier's cleanup-gtk patch. (now mtr uses a more modern
-        dialect of gtk). 
+        dialect of gtk).
+
   v0.73 Some securty patches. Although MTR drops privileges as soon
         as possible after opening the sockets, it still had some
-        sprintf calls, which have now been converted into snprintf. 
+        sprintf calls, which have now been converted into snprintf.
+
   v0.72 Fix signed/unsigned bug in IPV6 part
         improved random packet size behaviour. --REW
-  v0.71 Some IPV6 fixes, introduce packet size cmdline option. 
-        (was already present as a cmdline argument) 
+
+  v0.71 Some IPV6 fixes, introduce packet size cmdline option.
+        (was already present as a cmdline argument)
+
   v0.70 Antinio submitted a cumulative patch containing some
         nice improvements. He also submitted an automake patch
-        that causes mtr to no longer compile on my system. I 
+        that causes mtr to no longer compile on my system. I
         refuse to have mtr "in the dark" that I can't test-compile
-        the dist. 
-  v0.69 make distclean should now also remove "rej" files. 
+        the dist.
+
+  v0.69 make distclean should now also remove "rej" files.
         Antonio Querubin: update getopt.h . More cleanups using
-        new infrastructure. 
+        new infrastructure.
         rcw: Fixed IPV6 support: When compiled in an IPV6-supporting
         environment, but when the kernel doesn't support IPV6, mtr would
-        fail to start. 
+        fail to start.
+
   v0.68 included some old patches.
         included patch from Antonio Querubin for better IPV6 support
-        restructured some more whitespace. 
+        restructured some more whitespace.
         added mtr.h where "global" things should go. Not finished
-        moving things around, but now that the infrastructure is there, 
-        it should be easy. 
-  v0.67 Bad keyboarding by REW caused this one out the door. Sorry. 
-        No changes. 
+        moving things around, but now that the infrastructure is there,
+        it should be easy.
+
+  v0.67 Bad keyboarding by REW caused this one out the door. Sorry.
+        No changes.
+
   v0.66 Through the Debian bugtracking system a bug report and
-        fix was sent my way, that deals with stupid optmization 
-        trying to save some 768 bytes of memory, sacrificing "it 
+        fix was sent my way, that deals with stupid optmization
+        trying to save some 768 bytes of memory, sacrificing "it
         works" on a different architecture... (default char signedness)
+
   v0.65 Dancer Vesperman noted that mtr no longer traces past
         a section of non-responding hosts. Apparently I added
-        a line in net.c that didn't make sense in mtr-0.56. I 
-        can't find the reason for adding that line, so someone 
-        who thinks (s)he needs it, should holler. 
+        a line in net.c that didn't make sense in mtr-0.56. I
+        can't find the reason for adding that line, so someone
+        who thinks (s)he needs it, should holler.
 
-  v0.64 Philippe suggests to do the time_t thingy before socket.h. 
+  v0.64 Philippe suggests to do the time_t thingy before socket.h.
         Apparently, MAC OS X doesn't compile socket.h otherwise.
 
   v0.63 Suggestion by RCW: Add -lm at line 70 of Configure.in.
-        On my system no ill effects ensued, so this version released 
-        so that he can test if it still works on his sytem. 
+        On my system no ill effects ensued, so this version released
+        so that he can test if it still works on his sytem.
 
         Let me add that it's stupid that I have to specify that this
         this program now requires Automake version 1.5 to build, where
@@ -73,67 +106,67 @@ WHAT'S NEW?
         versions of build software!
 
         For those concerned about the above statement: If you're just
-        trying to compile and use MTR, there is no need for automake. 
+        trying to compile and use MTR, there is no need for automake.
         Just when you're messing with the configure and build system of
-        mtr is automake a tool you need. 
-	
+        mtr is automake a tool you need.
+
   v0.62 Apparently someone changed gethostbyname into gethostbyname2
         in mtr.c in an attempt to add IPV6 support. For systems without
-        ipv6 support, the old gethostbyname should be used! Linux 
+        ipv6 support, the old gethostbyname should be used! Linux
         has the call even if you don't enable IPV6. Thanks Gary (rsub)
 
   v0.61 Attempt to get/print the local IP address. Now shows as
         0.0.0.0 :-( Hints and tips appreciated! -- REW
         Lots of blank space reformatting.
         moved the interface address setting to net.c (where it
-        belongs). 
+        belongs).
 
   v0.60 John Thacker submitted a surprisingly simple patch to
         enable linking against GTK2.  (up to 2.4.0)
 
-  v0.59 Josh Martin suggested to add some bounds checking to 
+  v0.59 Josh Martin suggested to add some bounds checking to
         the dynamic field code. This caused me to delve in, and
         rewrite some things. Now 50 lines of code less, but cleaner
         code. :-)
 
-  v0.58 I don't remember. Fogot to update this. :-( Check the 
+  v0.58 I don't remember. Fogot to update this. :-( Check the
         patch.
 
   v0.57 Lots of whitespace cleanups. And a DNS fix: Don't do DNS
-        lookups in raw mode with -n specified. 
+        lookups in raw mode with -n specified.
 
   v0.56 Fixed compile warnings. Now compiles with -Wall. If your
-        compiler finds things mine didn't feel free to shout. 
+        compiler finds things mine didn't feel free to shout.
 
-  v0.55 Cleanup patch. I'm going to do some maintenance on MTR, 
+  v0.55 Cleanup patch. I'm going to do some maintenance on MTR,
         but I want to be able to say: Can you see which version
-        fixed/broke things for you, so you're going to see a 
-        bunch of new releases soon. 
+        fixed/broke things for you, so you're going to see a
+        bunch of new releases soon.
 
-  v0.54 Added "scrolling" patch from Roland Illig, to allow 
+  v0.54 Added "scrolling" patch from Roland Illig, to allow
         scrolling in text mode. I've always wanted this......
- 
-  v0.53 Added fix for raw mode. 
 
-  v0.52 Mostly cleanups from Brett Johnson on MacOS X. It may 
-        clean up some compilation problems on MacOS X as well. 
+  v0.53 Added fix for raw mode.
+
+  v0.52 Mostly cleanups from Brett Johnson on MacOS X. It may
+        clean up some compilation problems on MacOS X as well.
 
-  v0.51 Fixed the bug introduced by the previous select loop fix... 
+  v0.51 Fixed the bug introduced by the previous select loop fix...
         Thanks Evgeniy
 
   v0.50 Make "interface address" option work.
-        Changes to "select" loop to allow window resizes (select 
+        Changes to "select" loop to allow window resizes (select
         interruption) to work. Thanks Mike!
 
   v0.49 Fix compilation problems on several platforms.
 
-  v0.48 Draw names in red (GTK) or bold (Curses) if host doesn't 
-        respond. 
+  v0.48 Draw names in red (GTK) or bold (Curses) if host doesn't
+        respond.
 
-  v0.47 Fixed a (believed-) non-exploitable bufferoverflow. 
-        Thanks Damian. 
+  v0.47 Fixed a (believed-) non-exploitable bufferoverflow.
+        Thanks Damian.
 
-  v0.46 Included patch to be able to specify outgoing interface 
+  v0.46 Included patch to be able to specify outgoing interface
         address.
 
   v0.45 People are pressuring me to release new versions with their
@@ -142,154 +175,152 @@ WHAT'S NEW?
         stuff I forgot. This release serves as a code-sync-release.
         new version with even more new stuff in about two weeks!
         I'm afraid I don't know how to fix the MaxOS-X compilation
-        problems in the source. Help wanted... 
+        problems in the source. Help wanted...
 
-  v0.44 David Stone adds the "last" column to the gtk version. 
+  v0.44 David Stone adds the "last" column to the gtk version.
 
   v0.43 Compile fixes.
 
-  v0.41 Added afr's patch to allow disabling of gtk without Robn's hack. 
-        Made report mode report the newly added extra resolution. 
+  v0.41 Added afr's patch to allow disabling of gtk without Robn's hack.
+        Made report mode report the newly added extra resolution.
 
   v0.40 Fixed some problems with HPUX and SunOS.
-	Included Olav Kvittem's patch to do packetsize option.
-	Made the timekeeping in micro seconds.
+        Included Olav Kvittem's patch to do packetsize option.
+        Made the timekeeping in micro seconds.
 
   v0.39 Forgot the parentheses around the previous fix... :-(
 
   v0.38 fixed some dubious code in dns.c (noted by someone's lint)
 
-  v0.37 Added Bill Bogstad's "show the local host & time" patch. 
-	Added R. Sparks' show-last-ping patch, submitted by Philip Kizer.
+  v0.37 Added Bill Bogstad's "show the local host & time" patch.
+        Added R. Sparks' show-last-ping patch, submitted by Philip Kizer.
 
   v0.36 Added Craigs change-the-interval-on-the-fly patch.
-        Added Moritz Barsnick's "do something sensible if host not found" 
-	    patch.
+        Added Moritz Barsnick's "do something sensible if host not found"
+            patch.
         Some cleanup of both Craigs and Moritz' patches.
 
   v0.35 Added Craig Milo Rogers pause/resume for GTK patch.
         Added Craig Milo Rogers cleanup of "reset". (restart at the beginning)
-        Net_open used to send a first packet. After that the display-driver 
-            got a chance to distort the timing by taking its time to 
+        Net_open used to send a first packet. After that the display-driver
+            got a chance to distort the timing by taking its time to
             initialize.
 
   v0.34 Added Matt's nifty "use the icmp unreachables to do the timing" patch.
-        Added Steve Kann's pause/resume patch. 
+        Added Steve Kann's pause/resume patch.
 
   v0.33 Fixed the Linux glibc resolver problems.
-        Fixed the off-by-one problem with -c option. 
+        Fixed the off-by-one problem with -c option.
 
-  v0.32 Fixed the FreeBSD bug detection stuff. 
+  v0.32 Fixed the FreeBSD bug detection stuff.
 
   v0.31 Fixed a few documentation issues. -- Matt
-        Changed the autoconf stuff to find the resolver library on 
+        Changed the autoconf stuff to find the resolver library on
             Solaris. -- REW
         Cleaned up the autoconf.in file a bit. -- Matt.
 
   v0.30 Fixed a typo in the changelog (NEWS) entry for 0.27. :-)
-	added use of "MTR_OPTIONS" environment variable for defaults.
+        added use of "MTR_OPTIONS" environment variable for defaults.
 
-  v0.29 Lots of stuff. 
-        Neato overview display by David Sward. 
-        FreeBSD does wrong in the kernel the same that Solaris/x86 (see 
+  v0.29 Lots of stuff.
+        Neato overview display by David Sward.
+        FreeBSD does wrong in the kernel the same that Solaris/x86 (see
             note for 0.27 does right. It forces mtr to send bad packets....
         Adjusted "not too much at once" algorithm. Now probing
            continues as long as not more than 5 hosts are unknown.
-           Returning packets usually allow us to do the first sweep 
-           in one go. 
+           Returning packets usually allow us to do the first sweep
+           in one go.
 
-
-  v0.28 DNS lookups are now suppressed if you don't want them. 
+  v0.28 DNS lookups are now suppressed if you don't want them.
 
   v0.27
-	Fixed bug that showed up on Solaris/x86.
-	GTK mainloop now runs as it's supposed to.
+        Fixed bug that showed up on Solaris/x86.
+        GTK mainloop now runs as it's supposed to.
 
   v0.26
-        Added "-n" flag for numeric output. 
+        Added "-n" flag for numeric output.
         fixed IP numbers displaying backwards.
-        GTK mainloop now runs at 10 packets per second. 
+        GTK mainloop now runs at 10 packets per second.
           - That's too much if there are only 3 hosts
           - that's too little if there are 20 hosts.
-        -> Someone tell me how to change the "ping-timeout" 
+        -> Someone tell me how to change the "ping-timeout"
            callback time in gtk. Can't find it in the docs.
         The default for "hostname" is now "localhost" so that
-        you can start mtr without any arguments and later 
-        fill in the host you want to trace to. 
+        you can start mtr without any arguments and later
+        fill in the host you want to trace to.
 
   v0.25
         Included two "raw" formats. One for separating GUI from
         the setuid program, and one suitable for later parsing and
-        displaying. Volunteers wanted to separate the GTK 
-        backend. Thanks to Bertrand Leconte for contributing 
-        the format that's now called "split". 
+        displaying. Volunteers wanted to separate the GTK
+        backend. Thanks to Bertrand Leconte for contributing
+        the format that's now called "split".
 
-  v0.24 
-        Fixed number of probes. Accidentally was counted per 
-        packet sent instead of per round of packets. 
+  v0.24
+        Fixed number of probes. Accidentally was counted per
+        packet sent instead of per round of packets.
 
   v0.23
         Fixed Sparc alignment problem with statmalloc
 
-  v0.22 
-        Roger has take over maintenance. 
-        mtr now uses an "int" to pass options to the kernel. 
-        Makes things work on Solaris and *BSD I'm told. 
+  v0.22
+        Roger has take over maintenance.
+        mtr now uses an "int" to pass options to the kernel.
+        Makes things work on Solaris and *BSD I'm told.
         mtr doesn't fire off a flurry of packets when a new
         second comes around. Instead they are spaced evenly
-        around the whole second. This allows people with a 
+        around the whole second. This allows people with a
         relatively slow first link to do meaningful measurements
         of whatever is behind that.
 
   v0.21
         mtr now drops root permissions after it acquires the raw
         sockets it needs.
-	mtr should be a bit happier about building under SCO and
+        mtr should be a bit happier about building under SCO and
         Solaris.
-	Fixed the problem with packets arriving after a reset.
+        Fixed the problem with packets arriving after a reset.
 
   v0.20
-	The build process for mtr now uses automake.
+        The build process for mtr now uses automake.
         Fixed a build problem for Irix.
         Now uses non-blocking DNS code, so mtr can attempt
         to do reverse lookup on multiple hosts at once.
-	Fewer packets are sent out each cycle, so mtr
-	doesn't hog quite so much bandwidth.
+        Fewer packets are sent out each cycle, so mtr
+        doesn't hog quite so much bandwidth.
 
   v0.19
-	Fixed a type-o in curses.c
+        Fixed a type-o in curses.c
 
   v0.18
-	Fixed the network code to work properly under FreeBSD.  
-	Hopefully this will fix some other operating systems too.
-	Also, fixed a build problem and the DNS hanging bug.
+        Fixed the network code to work properly under FreeBSD.
+        Hopefully this will fix some other operating systems too.
+        Also, fixed a build problem and the DNS hanging bug.
 
   v0.17
         Fixed the configure script to always like with the math
-	library.  Added an icon.
+        library.  Added an icon.
 
   v0.16
-	Added one #include to select.c.  Some people were unable
-	to build mtr without this line.  
+        Added one #include to select.c.  Some people were unable
+        to build mtr without this line.
 
   v0.15
-	Both the build process and the networking code have
-	been cleaned up and reorganized.  mtr now builds 
-	cleanly with GTK+ 0.99.8.  
+        Both the build process and the networking code have
+        been cleaned up and reorganized.  mtr now builds
+        cleanly with GTK+ 0.99.8.
 
 --- Below is the contents of the old "Changelog file" that annoyed some
-people as it didn't contain any recent changes/news. 
+people as it didn't contain any recent changes/news.
 
 2002-03-06  Cougar <cougar@random.ee>
-	+ If hop doesn't respond, draw its name in red (GTK) or bold (curses)
+        + If hop doesn't respond, draw its name in red (GTK) or bold (curses)
 
 2002-02-09  bodq  <bohdan@vstu.edu.ua>
-	* Added --address option to bind to given IP addess
+        + Added --address option to bind to given IP addess
 
 2001-04-15  root  <alane@geeksrus.net>
-
-	* Added this file so that automake won't complain.
-	* Commented out the test for res_init in configure.in;
-	it does not work for GLIBC2 systems (e.g., RedHat 7+).
-	* Fixed the subordinate CHECK_LIBS on the test for res_mkquery,
-	so that they test for res_mkquery, not res_init.
+        + Added this file so that automake won't complain.
+        + Commented out the test for res_init in configure.in;
+        it does not work for GLIBC2 systems (e.g., RedHat 7+).
+        + Fixed the subordinate CHECK_LIBS on the test for res_mkquery,
+        so that they test for res_mkquery, not res_init.
diff --git a/README b/README
index 625f9eb..72be08c 100644
--- a/README
+++ b/README
@@ -15,16 +15,18 @@ WHAT IS MTR?
 
 INSTALLING
 
-  Slightly more hints are in the file INSTALL. If this doesn't work
-  you could try reading that too.... 
-
-  Compiling mtr should be as simple as:
+  If you're building this from a tarball, compiling mtr should be as
+  simple as:
 
 	make
 
   It should first call the "configure" script and then run "make" again
   with the makefile that "configure" just generated. 
 
+  If you're building from the git repository, you'll need to run:
+
+	./bootstrap.sh && ./configure && make
+
   After compiling, install:
 
 	make install
diff --git a/SECURITY b/SECURITY
index 1ebf15c..6cfc40b 100644
--- a/SECURITY
+++ b/SECURITY
@@ -29,5 +29,14 @@ raw socket descriptors, which would allow the malicious user to listen
 to all ICMP packets arriving at the system, and send forged packets
 with arbitrary contents.
 
+The mtr-code does its best to prevent calling of external library
+code before dropping privileges. It seems that C++ library code has 
+the ability to issue a "please execute me before calling main" to the
+loader/linker.  That would mean that we're still vulnerable to 
+errors in that code. This is why I would prefer to drop the backends, 
+have mtr-core always run in "raw" mode, and have the backends interpret
+the output from the mtr-core. Maybe a nice project for a college-level
+student. 
+
 If you have further questions or comments about security issues,
 please direct them to the mtr mailing list.  See README for details.
diff --git a/asn.c b/asn.c
new file mode 100644
index 0000000..f9484a8
--- /dev/null
+++ b/asn.c
@@ -0,0 +1,108 @@
+/*
+    mtr  --  a network diagnostic tool
+    Copyright (C) 1997,1998  Matt Kimball
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License version 2 as
+    published by the Free Software Foundation.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+    Copyright (C) 2010 by Roderick Groesbeek <mtr@roderick.triple-it.nl>
+    Released under GPL, as above.
+*/
+
+#include <config.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <resolv.h>
+#include <string.h>
+#include <sys/socket.h>
+
+
+#include <glib.h>
+
+
+int  PrintAS = 0;
+GHashTable * ashash = NULL;
+
+char *asn_lookup(const char *domain)
+{
+    unsigned char answer[PACKETSZ],  *pt;
+    char host[128];
+    char *txt;
+    int len, exp, size, txtlen, type;
+
+
+    if(res_init() < 0) {
+        fprintf(stderr,"@res_init failed\n");
+        return NULL;
+    }
+
+    memset(answer, 0, PACKETSZ);
+    if((len = res_query(domain, C_IN, T_TXT, answer, PACKETSZ)) < 0) {
+        return "-1";
+    }
+
+    pt = answer + sizeof(HEADER);
+
+    if((exp = dn_expand(answer, answer + len, pt, host, sizeof(host))) < 0) {
+        printf("@dn_expand failed\n"); return NULL;
+    }
+
+    pt += exp;
+
+    GETSHORT(type, pt);
+    if(type != T_TXT) {
+        printf("@Broken DNS reply.\n"); return NULL;
+    }
+
+    pt += INT16SZ; /* class */
+
+    if((exp = dn_expand(answer, answer + len, pt, host, sizeof(host))) < 0) {
+        printf("@second dn_expand failed\n"); return NULL;
+    }
+
+    pt += exp;
+    GETSHORT(type, pt);
+    if(type != T_TXT) {
+        printf("@Not a TXT record\n"); return NULL;
+    }
+
+    pt += INT16SZ; /* class */
+    GETSHORT(size, pt);
+    txtlen = *pt;
+
+
+    if(txtlen >= size || !txtlen) {
+        printf("@Broken TXT record (txtlen = %d, size = %d)\n", txtlen, size); return NULL;
+    }
+
+    if(!(txt = malloc(txtlen + 1)))
+        return NULL;
+
+    pt++;
+    strncpy(txt, (char*) pt, txtlen);
+    txt[txtlen] = 0;
+
+    return txt;
+}
+
+
+
+
diff --git a/asn.h b/asn.h
new file mode 100644
index 0000000..fde9af2
--- /dev/null
+++ b/asn.h
@@ -0,0 +1,27 @@
+/*
+    mtr  --  a network diagnostic tool
+    Copyright (C) 1997,1998  Matt Kimball
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License version 2 as
+    published by the Free Software Foundation.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <glib.h>
+
+
+/*  Prototypes for asn.c  */
+
+extern int PrintAS;
+extern GHashTable * ashash;
+char *asn_lookup(const char *domain);
+
diff --git a/bootstrap.sh b/bootstrap.sh
new file mode 100755
index 0000000..e05d84f
--- /dev/null
+++ b/bootstrap.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+aclocal
+autoheader
+automake --add-missing --copy --foreign
+autoconf
+
diff --git a/configure.in b/configure.in
index 8474543..4b81c44 100644
--- a/configure.in
+++ b/configure.in
@@ -1,5 +1,5 @@
 AC_INIT(mtr.c)
-AM_INIT_AUTOMAKE(mtr, 0.82)
+AM_INIT_AUTOMAKE(mtr, 0.83)
 
 
 AC_SUBST(GTK_OBJ)
diff --git a/curses.c b/curses.c
index 3a3f8c5..0652e87 100644
--- a/curses.c
+++ b/curses.c
@@ -63,6 +63,8 @@
 #include "display.h"
 #include "net.h"
 #include "dns.h"
+#include "asn.h"
+#include <glib.h>
 #endif
 
 #include <time.h>
@@ -77,12 +79,14 @@ extern float WaitTime;
 extern int af;
 extern int mtrtype;
 
+static int __unused_int;
+
 void pwcenter(char *str) 
 {
-  int maxx, maxy;
+  int maxx;
   int cx;
 
-  getmaxyx(stdscr, maxy, maxx);
+  getmaxyx(stdscr, __unused_int, maxx);
   cx = (signed)(maxx - strlen(str)) / 2;
   while(cx-- > 0)
     printw(" ");
@@ -264,9 +268,11 @@ int mtr_curses_keyaction(void)
   if (tolower(c) == '?'|| tolower(c) == 'h') {
     mvprintw(2, 0, "Command:\n" );
     printw("  ?|h     help\n" );
+    printw("  p       pause (SPACE to resume)\n" );
     printw("  d       switching display mode\n" );
     printw("  e       toggle MPLS information on/off\n" );
     printw("  n       toggle DNS on/off\n" );
+    printw("  r       reset all counters\n" );
     printw("  o str   set the columns to display, default str='LRS N BAWV'\n" );
     printw("  j       toggle latency(LS NABWV)/jitter(DR AGJMXI) stats\n" );
     printw("  c <n>   report cycle n, default n=infinite\n" );
@@ -293,7 +299,7 @@ void mtr_curses_hosts(int startstat)
   int at;
   struct mplslen *mpls, *mplss;
   ip_t *addr, *addrs;
-  int y, x;
+  int y;
   char *name;
 
   int i, j, k;
@@ -308,17 +314,56 @@ void mtr_curses_hosts(int startstat)
     mpls = net_mpls(at);
 
     if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
+      struct in6_addr addr6 = *addr;
+
+      if (PrintAS) {
+              u_char ipv4[4];
+              ipv4[0] = addr6.s6_addr[0];
+              ipv4[1] = addr6.s6_addr[1];
+              ipv4[2] = addr6.s6_addr[2];
+              ipv4[3] = addr6.s6_addr[3];
+
+#define NAMELEN 127
+              char ipv4_buf[NAMELEN];
+              char* chip = (char*) &ipv4_buf;
+              char* chas = NULL;
+              char** key_ptr = &chip;
+              char** value_ptr = &chas;
+
+
+              if (snprintf(ipv4_buf, NAMELEN, "%d.%d.%d.%d.asn.routeviews.org", ipv4[3],
+                                      ipv4[2], ipv4[1], ipv4[0]) >= NAMELEN) {
+                      return;
+              }
+
+
+
+              gboolean result =
+                      g_hash_table_lookup_extended
+                      (ashash, ipv4_buf, (gpointer*)key_ptr, (gpointer*)value_ptr);
+              if (!result) {
+                      char* as = asn_lookup(ipv4_buf);
+                      chip = (char*) strdup(ipv4_buf);
+                      chas = (char*) as;
+                      g_hash_table_insert(ashash, chip, chas);
+              }
+              //g_hash_table_destroy(hash);
+
+
+              printw("[AS%s] ", chas);
+      }
       name = dns_lookup(addr);
       if (! net_up(at))
 	attron(A_BOLD);
       if(name != NULL) {
-	printw("%s", name);
+        if (show_ips) printw("%s (%s)", name, strlongip(addr));
+        else printw("%s", name);
       } else {
 	printw("%s", strlongip( addr ) );
       }
       attroff(A_BOLD);
 
-      getyx(stdscr, y, x);
+      getyx(stdscr, y, __unused_int);
       move(y, startstat);
 
       /* net_xxx returns times in usecs. Just display millisecs */
@@ -465,7 +510,7 @@ void mtr_fill_graph(int at, int cols)
 
 void mtr_curses_graph(int startstat, int cols) 
 {
-	int max, at, y, x;
+	int max, at, y;
 	ip_t * addr;
 	char* name;
 
@@ -490,7 +535,7 @@ void mtr_curses_graph(int startstat, int cols)
 		}
 		attroff(A_BOLD);
 
-		getyx(stdscr, y, x);
+		getyx(stdscr, y, __unused_int);
 		move(y, startstat);
 
 		printw(" ");
@@ -502,7 +547,7 @@ void mtr_curses_graph(int startstat, int cols)
 
 void mtr_curses_redraw(void)
 {
-  int maxx, maxy;
+  int maxx;
   int startstat;
   int rowstat;
   time_t t;
@@ -514,7 +559,7 @@ void mtr_curses_redraw(void)
   
 
   erase();
-  getmaxyx(stdscr, maxy, maxx);
+  getmaxyx(stdscr, __unused_int, maxx);
 
   rowstat = 5;
 
@@ -599,6 +644,7 @@ void mtr_curses_redraw(void)
 
 void mtr_curses_open(void)
 {
+  ashash = g_hash_table_new(g_str_hash, g_str_equal);
   initscr();
   raw();
   noecho(); 
diff --git a/dns.c b/dns.c
index 512da97..5d10d1c 100644
--- a/dns.c
+++ b/dns.c
@@ -49,6 +49,16 @@
 #include "dns.h"
 #include "net.h"
 
+#ifdef ENABLE_IPV6
+#ifdef __GLIBC__
+#define NSCOUNT6 myres._u._ext.nscount6
+#define NSSOCKADDR6(i) (myres._u._ext.nsaddrs[i])
+#else
+#define NSCOUNT6 myres.nscount
+#define NSSOCKADDR6(i) (&(myres._u._ext.ext->nsaddrs[i].sin6))
+#endif
+#endif
+
 /* OSX  Needs this. I don't know how to enable this for them automatically. 
  * Should be easy with autoconf. Please submit a patch if you know 
  * autoconf.... -- REW
@@ -262,6 +272,9 @@ struct logline *lastlog = NULL;
 
 ip_t alignedip;
 ip_t localhost;
+#ifdef ENABLE_IPV6
+ip_t localhost6;
+#endif
 
 double sweeptime;
 
@@ -298,6 +311,9 @@ struct sockaddr_in * from4 = (struct sockaddr_in *) &from_sastruct;
 struct sockaddr * from = (struct sockaddr *) &from_sastruct;
 
 int resfd;
+#ifdef ENABLE_IPV6
+int resfd6;
+#endif
 socklen_t fromlen = sizeof from_sastruct;
 
 char tempstring[16384+1+1];
@@ -371,12 +387,12 @@ void statfree(void *p)
   if (p) {
     if (*((dword *)p - HEAD_SLACK) == 0) {
       fprintf(stderr,"ERROR: Attempt to free pointer twice.\n");
-      *(int*)0=0;
+      abort();
       exit(-1);
     } else {
       if (*((dword *)p - HEAD_SLACK) > 8192) {
 	fprintf (stderr,"ERROR: Corrupted free() buffer. (header)\n");
-	*(int*)0=0;
+        abort();
 	exit(-1);
       }
 #ifdef CorruptCheck
@@ -385,7 +401,7 @@ void statfree(void *p)
 	  (*(byte *)((char *)p + (*((dword *)p - 1)) + sizeof(byte) * 2) != 0xbe) ||
 	  (*(byte *)((char *)p + (*((dword *)p - 1)) + sizeof(byte) * 3) != 0xef)) {
 	fprintf(stderr,"ERROR: Corrupted free() buffer. (footer)\n");
-	*(int*)0=0;
+	abort();
 	exit(-1);
       }
 #endif
@@ -454,9 +470,9 @@ void clearset(fd_set *set)
 char *strlongip(ip_t * ip)
 {
 #ifdef ENABLE_IPV6
-  static char buf[INET6_ADDRSTRLEN];
+  static char addrstr[INET6_ADDRSTRLEN];
 
-  return (char *) inet_ntop( af, ip, buf, sizeof buf );
+  return (char *) inet_ntop( af, ip, addrstr, sizeof addrstr );
 #else
   return inet_ntoa( *ip );
 #endif
@@ -488,6 +504,12 @@ int dns_waitfd(void)
 {
   return resfd;
 }
+#ifdef ENABLE_IPV6
+int dns_waitfd6(void)
+{
+  return resfd6;
+}
+#endif
 
 
 void dns_open(void)
@@ -501,21 +523,41 @@ void dns_open(void)
     exit(-1);
   }
   myres.options|= RES_RECURSE | RES_DEFNAMES | RES_DNSRCH;
-  for (i = 0;i < myres.nscount;i++)
-    myres.nsaddr_list[i].sin_family = AF_INET;
   resfd = socket(AF_INET, SOCK_DGRAM, 0);
   if (resfd == -1) {
-    fprintf(stderr,"Unable to allocate socket for nameserver communication: %s\n",
+    fprintf(stderr,
+            "Unable to allocate IPv4 socket for nameserver communication: %s\n",
+	    strerror(errno));
+    exit(-1);
+  }
+#ifdef ENABLE_IPV6
+  resfd6 = socket(AF_INET6, SOCK_DGRAM, 0);
+  if (resfd6 == -1) {
+    fprintf(stderr,
+            "Unable to allocate IPv6 socket for nameserver communication: %s\n",
 	    strerror(errno));
     exit(-1);
   }
+#endif
   option = 1;
   if (setsockopt(resfd,SOL_SOCKET,SO_BROADCAST,(char *)&option,sizeof(option))) {
-    fprintf(stderr,"Unable to setsockopt() on nameserver communication socket: %s\n",
+    fprintf(stderr,
+            "Unable to setsockopt() on IPv4 nameserver communication socket: %s\n",
 	    strerror(errno));
     exit(-1);
   }
+#ifdef ENABLE_IPV6
+  if (setsockopt(resfd6,SOL_SOCKET,SO_BROADCAST,(char *)&option,sizeof(option))) {
+    fprintf(stderr,
+            "Unable to setsockopt() on IPv6 nameserver communication socket: %s\n",
+	    strerror(errno));
+    exit(-1);
+  }
+#endif
   longipstr( "127.0.0.1", &localhost, AF_INET );
+#ifdef ENABLE_IPV6
+  longipstr( "::1", &localhost6, AF_INET6 );
+#endif
   aseed = time(NULL) ^ (time(NULL) << 3) ^ (dword)getpid();
   for (i = 0;i < BashSize;i++) {
     idbash[i] = NULL;
@@ -894,9 +936,17 @@ void dorequest(char *s,int type,word id)
   }
   hp = (packetheader *)buf;
   hp->id = id;	/* htons() deliberately left out (redundant) */
+#ifdef ENABLE_IPV6
+  for (i = 0;i < NSCOUNT6;i++) {
+    if (NSSOCKADDR6(i)->sin6_family == AF_INET6)
+      (void)sendto(resfd6,buf,r,0,(struct sockaddr *) NSSOCKADDR6(i),
+		   sizeof(struct sockaddr_in6));
+  }
+#endif
   for (i = 0;i < myres.nscount;i++)
-    (void)sendto(resfd,buf,r,0,(struct sockaddr *)&myres.nsaddr_list[i],
-		 sizeof(struct sockaddr));
+    if (myres.nsaddr_list[i].sin_family == AF_INET)
+      (void)sendto(resfd,buf,r,0,(struct sockaddr *)&myres.nsaddr_list[i],
+		   sizeof(struct sockaddr));
 }
 
 void resendrequest(struct resolve *rp,int type)
@@ -1273,6 +1323,45 @@ void dns_ack(void)
     restell(tempstring);
   }
 }
+#ifdef ENABLE_IPV6
+void dns_ack6(void)
+{
+  int r,i;
+  static char addrstr[INET6_ADDRSTRLEN];
+
+  r = recvfrom(resfd6,(byte *)resrecvbuf,MaxPacketsize,0,
+               from, &fromlen);
+  if (r > 0) {
+    /* Check to see if this server is actually one we sent to */
+    if ( addrcmp( (void *) &(from6->sin6_addr), (void *) &localhost6,
+                  (int) AF_INET6 ) == 0 ) {
+      for (i = 0;i < NSCOUNT6;i++) {
+	if ( addrcmp( (void *) &(NSSOCKADDR6(i)->sin6_addr),
+		      (void *) &(from6->sin6_addr), (int) AF_INET6 ) == 0 ||
+	     addrcmp( (void *) &(NSSOCKADDR6(i)->sin6_addr),
+		      (void *) &unspec_addr, (int) AF_INET6 ) == 0 )	/* 0.0.0.0 replies as 127.0.0.1 */
+	  break;
+      }
+    } else
+      for (i = 0;i < NSCOUNT6;i++) {
+	if ( addrcmp( (void *) &(NSSOCKADDR6(i)->sin6_addr),
+		      (void *) &(from6->sin6_addr), AF_INET6 ) == 0 )
+	  break;
+      }
+    if (i == NSCOUNT6) {
+      snprintf(tempstring, sizeof(tempstring), 
+	       "Resolver error: Received reply from unknown source: %s",
+	       inet_ntop( AF_INET6, &(from6->sin6_addr), addrstr,
+			  sizeof addrstr ));
+      restell(tempstring);
+    } else
+      parserespacket((byte *)resrecvbuf,r);
+  } else {
+    snprintf(tempstring, sizeof(tempstring), "Resolver: Socket error: %s",strerror(errno));
+    restell(tempstring);
+  }
+}
+#endif
 
 
 int istime(double x,double *sinterval)
@@ -1376,9 +1465,9 @@ char *dns_lookup(ip_t * ip)
 {
   char *t;
 
-  if (!dns) return strlongip (ip);
-  t = dns_lookup2 (ip);
-  return (t&&use_dns)?t:strlongip(ip);
+  if (!dns) return NULL;
+  t = dns_lookup2(ip);
+  return (t && use_dns) ? t : NULL;
 }
 
 #ifdef ENABLE_IPV6
diff --git a/dns.h b/dns.h
index b25c267..4bf3fc1 100644
--- a/dns.h
+++ b/dns.h
@@ -24,6 +24,29 @@
 void dns_open(void);
 int dns_waitfd(void);
 void dns_ack(void);
+#ifdef ENABLE_IPV6
+int dns_waitfd6(void);
+void dns_ack6(void);
+#ifdef BSD
+/* __res_state_ext is missing on many (most?) BSD systems
+   - this should probably be handled by autoconf */
+#ifndef __res_state_ext
+struct __res_state_ext {
+	union res_sockaddr_union nsaddrs[MAXNS];
+	struct sort_list {
+		int     af;
+		union {
+			struct in_addr  ina;
+			struct in6_addr in6a;
+		} addr, mask;
+	} sort_list[MAXRESOLVSORT];
+	char nsuffix[64];
+	char nsuffix2[64];
+};
+#endif
+#endif
+#endif
+
 void dns_events(double *sinterval);
 char *dns_lookup(ip_t * address);
 char *dns_lookup2(ip_t * address);
diff --git a/gtk.c b/gtk.c
index e42f4f6..5a04b3e 100644
--- a/gtk.c
+++ b/gtk.c
@@ -383,16 +383,6 @@ void TreeViewCreate(void)
 
   renderer = gtk_cell_renderer_text_new ();
   g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
-  column = gtk_tree_view_column_new_with_attributes ("Rcv",
-    renderer,
-    "text", 2,
-    "foreground", COL_COLOR,
-    NULL);
-  gtk_tree_view_column_set_resizable(column, TRUE);
-  gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
-
-  renderer = gtk_cell_renderer_text_new ();
-  g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
   column = gtk_tree_view_column_new_with_attributes ("Snt",
     renderer,
     "text", 3,
@@ -413,25 +403,25 @@ void TreeViewCreate(void)
 
   renderer = gtk_cell_renderer_text_new ();
   g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
-  column = gtk_tree_view_column_new_with_attributes ("Best",
+  column = gtk_tree_view_column_new_with_attributes ("Avg",
     renderer,
-    "text", 5,
+    "text", 6,
     "foreground", COL_COLOR,
     NULL);
   gtk_tree_view_column_set_resizable(column, TRUE);
   gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
-
+  
   renderer = gtk_cell_renderer_text_new ();
   g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
-  column = gtk_tree_view_column_new_with_attributes ("Avg",
+  column = gtk_tree_view_column_new_with_attributes ("Best",
     renderer,
-    "text", 6,
+    "text", 5,
     "foreground", COL_COLOR,
     NULL);
   gtk_tree_view_column_set_resizable(column, TRUE);
   gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
 
-  renderer = gtk_cell_renderer_text_new ();
+    renderer = gtk_cell_renderer_text_new ();
   g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
   column = gtk_tree_view_column_new_with_attributes ("Worst",
     renderer,
@@ -457,16 +447,16 @@ void TreeViewCreate(void)
 void update_tree_row(int row, GtkTreeIter *iter)
 {
   ip_t *addr;
-  char str[256], *name;
+  char str[256]="???", *name=str;
 
   addr = net_addr(row);
-  name = "???";
-  if ( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
-    name = dns_lookup(addr);
-    if(!name) {
-      sprintf(str, "%s", strlongip( addr ));
-      name = str;
-    }
+  if (addrcmp( (void *) addr, (void *) &unspec_addr, af)) {
+    if ((name = dns_lookup(addr))) {
+      if (show_ips) {
+        snprintf(str, sizeof(str), "%s (%s)", name, strlongip(addr));
+        name = str;
+      }
+    } else name = strlongip(addr);
   }
 
   gtk_list_store_set(ReportStore, iter,
@@ -603,6 +593,14 @@ gboolean gtk_dns_data(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, UNUS
   gtk_redraw();
   return TRUE;
 }
+#ifdef ENABLE_IPV6
+gboolean gtk_dns_data6(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, UNUSED gpointer data)
+{
+  dns_ack6();
+  gtk_redraw();
+  return TRUE;
+}
+#endif
 
 
 void gtk_loop(void) 
@@ -613,6 +611,10 @@ void gtk_loop(void)
   
   net_iochannel = g_io_channel_unix_new(net_waitfd());
   g_io_add_watch(net_iochannel, G_IO_IN, gtk_net_data, NULL);
+#ifdef ENABLE_IPV6
+  dns_iochannel = g_io_channel_unix_new(dns_waitfd6());
+  g_io_add_watch(dns_iochannel, G_IO_IN, gtk_dns_data6, NULL);
+#endif
   dns_iochannel = g_io_channel_unix_new(dns_waitfd());
   g_io_add_watch(dns_iochannel, G_IO_IN, gtk_dns_data, NULL);
 
diff --git a/mtr.8 b/mtr.8
index 694c631..81e1926 100644
--- a/mtr.8
+++ b/mtr.8
@@ -41,6 +41,9 @@ mtr \- a network diagnostic tool
 .B \-\-no-dns\c
 ]
 [\c
+.B \-\-show-ips\c
+]
+[\c
 .B \-\-gtk\c
 ]
 [\c
@@ -71,16 +74,20 @@ starts, it investigates the network connection between the host
 .B mtr
 runs on and 
 .BR HOSTNAME . 
-by sending packets with purposly low TTLs. It continues to send
+by sending packets with purposely low TTLs. It continues to send
 packets with low TTL, noting the response time of the intervening
 routers.  This allows 
 .B mtr 
 to print the response percentage and response times of the internet
 route to 
 .BR HOSTNAME . 
-A sudden increase in packetloss or response time is often an indication
+A sudden increase in packet loss or response time is often an indication
 of a bad (or simply overloaded) link. 
 
+.PP
+The results are usually reported as round-trip-response times in miliseconds 
+and the percentage of packetloss. 
+
 .SH OPTIONS
 
 .TP
@@ -148,12 +155,12 @@ those machines.  Each cycle lasts one second.
 .B \-\-psize\ BYTES
 .TP
 .B PACKETSIZE
-These options or a trailing PACKETSIZE on the commandline sets 
+These options or a trailing PACKETSIZE on the command line sets 
 the packet size used for probing.
 It is in bytes inclusive IP and ICMP headers
 
 If set to a negative number, every iteration will use a different, random
-packetsize upto that number. 
+packet size upto that number. 
 .TP
 .B \-t
 .TP
@@ -185,15 +192,47 @@ to display numeric IP numbers and not try to resolve the
 host names. 
 
 .TP
+.B \-b
+.TP
+.B \-\-show-ips
+.br
+Use this option to tell
+.B mtr
+to display both the host names and numeric IP numbers.  In split mode
+this adds an extra field to the output. In report mode, there is usually
+too little space to add the IPs, and they will be truncated. Use the 
+wide report (-w) mode to see the IPs in report mode. 
+
+.TP
 .B \-o\ fields\ order
 .TP
 .B \-\-order\ fields\ order
 .br
 Use this option to specify the fields and their order when loading mtr.
 .br
+Available fields:
+.TS
+center allbox tab(%);
+ll.
+L%Loss ratio
+D%Dropped packets
+R%Received packets
+S%Sent Packets
+N%Newest RTT(ms)
+B%Min/Best RTT(ms)
+A%Average RTT(ms)
+W%Max/Worst RTT(ms)
+V%Standard Deviation
+G%Geometric Mean
+J%Current Jitter
+M%Jitter Mean/Avg.
+X%Worst Jitter
+I%Interarrival Jitter
+.TE
+.br
+
 Example:
 -o "LSD NBAW"
-
 .TP
 .B \-g
 .TP
@@ -205,7 +244,7 @@ to use the GTK+ based X11 window interface (if available).
 GTK+ must have been available on the system when 
 .B mtr 
 was built for this to work.  See the GTK+ web page at 
-.B http://www.gimp.org/gtk/
+.B http://www.gtk.org/
 for more information about GTK+.
 
 .TP
@@ -278,20 +317,14 @@ For the latest version, see the mtr web page at
 .BR http://www.bitwizard.nl/mtr/ .
 
 .PP
-Subscribe to the mtr mailing list.  All mtr related announcements
-are posted to the mtr mailing list.  To subscribe, send email to
-.B majordomo@lists.xmission.com
-with 
-.B subscribe\ mtr
-in the body of the message.  To send a message to the mailing list, mail to 
-.BR mtr@lists.xmission.com .
+The mtr mailinglist was little used and is no longer active. 
 
 .PP
-Bug reports and feature requests should be sent to the mtr
-mailing list.
-
+Bug reports and feature requests should be submitted to the
+launchpad mtr bugtracker. 
 
 .SH "SEE ALSO"
 
 traceroute(8),
-ping(8).
+ping(8)
+TCP/IP Illustrated (Stevens, ISBN 0201633469).
diff --git a/mtr.c b/mtr.c
index 5f1b651..044fac5 100644
--- a/mtr.c
+++ b/mtr.c
@@ -34,6 +34,7 @@
 #include "dns.h"
 #include "report.h"
 #include "net.h"
+#include "asn.h"
 
 
 #ifdef ENABLE_IPV6
@@ -60,6 +61,7 @@ char *Hostname = NULL;
 char *InterfaceAddress = NULL;
 char  LocalHostname[128];
 int   dns = 1;
+int   show_ips = 0;
 int   enablempls = 0;
 int   cpacketsize = 64;          /* default packet size */
 int   bitpattern = 0;
@@ -140,16 +142,18 @@ void parse_arg (int argc, char **argv)
     { "report-cycles", 1, 0, 'c' },
     { "psize", 1, 0, 's' },	/* changed 'p' to 's' to match ping option
 				   overload psize<0, ->rand(min,max) */
-    { "bitpattern", 1, 0, 'b' },/* overload b>255, ->rand(0,255) */
+    { "bitpattern", 1, 0, 'B' },/* overload b>255, ->rand(0,255) */
     { "tos", 1, 0, 'Q' },	/* typeof service (0,255) */
     { "mpls", 0, 0, 'e' },
     { "no-dns", 0, 0, 'n' },
+    { "show-ips", 0, 0, 'b' },
     { "address", 1, 0, 'a' },
     { "first-ttl", 1, 0, 'f' },	/* -f & -m are borrowed from traceroute */
     { "max-ttl", 1, 0, 'm' },
     { "udp", 0, 0, 'u' },	/* UDP (default is ICMP) */
     { "inet", 0, 0, '4' },	/* IPv4 only */
     { "inet6", 0, 0, '6' },	/* IPv6 only */
+    { "aslookup", 0, 0, 'z' },  /* Do AS lookup */
     { 0, 0, 0, 0 }
   };
 
@@ -157,7 +161,7 @@ void parse_arg (int argc, char **argv)
   while(1) {
     /* added f:m:o: byMin */
     opt = getopt_long(argc, argv,
-		      "vhrwxtglpo:i:c:s:b:Q:ena:f:m:u46", long_options, NULL);
+		      "vhrwxtglpo:B:i:c:s:Q:ena:f:m:ubz46", long_options, NULL);
     if(opt == -1)
       break;
 
@@ -174,6 +178,7 @@ void parse_arg (int argc, char **argv)
       break;
     case 'w':
       reportwide = 1;
+      DisplayMode = DisplayReport;
       break;
     case 't':
       DisplayMode = DisplayCurses;
@@ -213,8 +218,10 @@ void parse_arg (int argc, char **argv)
 	fprintf (stderr, "mtr: wait time must be positive\n");
 	exit (1);
       }
-      if (getuid() != 0 && WaitTime < 1.0)
-	WaitTime = 1.0;
+      if (getuid() != 0 && WaitTime < 1.0) {
+        fprintf (stderr, "non-root users cannot request an interval < 1.0 seconds\r\n");
+	exit (1);
+      }
       break;
     case 'f':
       fstTTL = atoi (optarg);
@@ -251,7 +258,7 @@ void parse_arg (int argc, char **argv)
       }
       strcpy ((char*)fld_active, optarg);
       break;
-    case 'b':
+    case 'B':
       bitpattern = atoi (optarg);
       if (bitpattern > 255)
 	bitpattern = -1;
@@ -267,6 +274,9 @@ void parse_arg (int argc, char **argv)
     case 'u':
       mtrtype = IPPROTO_UDP;
       break;
+    case 'b':
+      show_ips = 1;
+      break;
     case '4':
       af = AF_INET;
       break;
@@ -278,6 +288,9 @@ void parse_arg (int argc, char **argv)
       fprintf( stderr, "IPv6 not enabled.\n" );
       break;
 #endif
+    case 'z':
+      PrintAS = 1;
+      break;
     }
   }
 
@@ -324,7 +337,6 @@ void parse_mtr_options (char *string)
 
 int main(int argc, char **argv) 
 {
-  ip_t *            traddr;
   struct hostent *  host                = NULL;
   int               net_preopen_result;
 #ifdef ENABLE_IPV6
@@ -382,7 +394,8 @@ int main(int argc, char **argv)
   if (PrintHelp) {
     printf("usage: %s [-hvrwctglspniu46] [--help] [--version] [--report]\n"
 	   "\t\t[--report-wide] [--report-cycles=COUNT] [--curses] [--gtk]\n"
-           "\t\t[--raw] [--split] [--mpls] [--no-dns] [--address interface]\n" /* BL */
+           "\t\t[--raw] [--split] [--mpls] [--no-dns] [--show-ips]\n"
+           "\t\t[--address interface]  [--aslookup]\n" /* BL */
            "\t\t[--psize=bytes/-s bytes]\n"            /* ok */
            "\t\t[--report-wide|-w] [-u]\n"            /* rew */
 	   "\t\t[--interval=SECONDS] HOSTNAME [PACKETSIZE]\n", argv[0]);
@@ -445,8 +458,6 @@ int main(int argc, char **argv)
   af = host->h_addrtype;
 #endif
 
-  traddr = (ip_t *) host->h_addr;
-  
   if (net_open(host) != 0) {
 	fprintf(stderr, "mtr: Unable to start net module.\n");
         exit(1);
diff --git a/mtr.h b/mtr.h
index 9cfee0b..ec76190 100644
--- a/mtr.h
+++ b/mtr.h
@@ -60,6 +60,7 @@ typedef struct in_addr ip_t;
 
 extern int enablempls;
 extern int dns;
+extern int show_ips;
 extern int use_dns;
 
 #ifdef __GNUC__
diff --git a/net.c b/net.c
index bd7ee41..431ad1e 100644
--- a/net.c
+++ b/net.c
@@ -295,7 +295,7 @@ void net_send_query(int index)
   /*ok  int packetsize = sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + datasize;*/
   int rv;
   static int first=1;
-  int ttl, iphsize = 0, echotype = 0, salen = 0, udphsize = 0;
+  int ttl, iphsize = 0, echotype = 0, salen = 0;
 
   ttl = index + 1;
 
@@ -369,7 +369,6 @@ void net_send_query(int index)
 
   case IPPROTO_UDP:
     udp = (struct UDPHeader *)(packet + iphsize);
-    udphsize = sizeof (struct UDPHeader);
     udp->checksum  = 0;
     mypid = (uint16)getpid();
     if (mypid < MinPort)
@@ -527,7 +526,7 @@ void net_process_ping(int seq, struct mplslen mpls, void * addr, struct timeval
   /* begin addByMin do more stats */
   oldavg = host[index].avg;
   host[index].avg += (totusec - oldavg +.0) / host[index].returned;
-  host[index].var += (totusec - oldavg +.0) * (totusec - host[index].avg);
+  host[index].var += (totusec - oldavg +.0) * (totusec - host[index].avg) / 1000000;
 
   oldjavg = host[index].javg;
   host[index].javg += (host[index].jitter - oldjavg) / host[index].returned;
@@ -772,7 +771,7 @@ int net_gmean(int at)
 int net_stdev(int at) 
 {
   if( host[at].returned > 1 ) {
-    return ( sqrt( host[at].var/(host[at].returned -1.0) ) );
+    return ( 1000.0 * sqrt( host[at].var/(host[at].returned -1.0) ) );
   } else {
     return( 0 );
   }
diff --git a/report.c b/report.c
index 9834128..6a8baec 100644
--- a/report.c
+++ b/report.c
@@ -24,6 +24,7 @@
 #include <sys/socket.h>
 #include <string.h>
 #include <strings.h>
+#include <time.h>
 
 #include "mtr.h"
 #include "report.h"
@@ -45,8 +46,30 @@ extern int af;
 extern int reportwide;
 
 
-void report_open(void) 
+char *get_time_string (void) 
 {
+  time_t now; 
+  char *t;
+  now = time (NULL);
+  t = ctime (&now);
+  t [ strlen (t) -1] = 0; // remove the trailing newline
+  return t;
+}
+
+void report_open(void)
+{
+  printf ("Start: %s\n", get_time_string ());
+}
+
+static size_t snprint_addr(char *dst, size_t dst_len, ip_t *addr)
+{
+  if(addrcmp((void *) addr, (void *) &unspec_addr, af)) {
+    struct hostent *host = dns ? addr2host((void *) addr, af) : NULL;
+    if (!host) return snprintf(dst, dst_len, "%s", strlongip(addr));
+    else if (dns && show_ips)
+      return snprintf(dst, dst_len, "%s (%s)", host->h_name, strlongip(addr));
+    else return snprintf(dst, dst_len, "%s", host->h_name);
+  } else return snprintf(dst, dst_len, "%s", "???");
 }
 
 
@@ -61,7 +84,6 @@ void report_close(void)
   char fmt[16];
   int len=0;
   int len_hosts = 33;
-  struct hostent *host;
 
   if (reportwide)
   {
@@ -70,19 +92,11 @@ void report_close(void)
     max = net_max();
     at  = net_min();
     for (; at < max; at++) {
+      int nlen;
       addr = net_addr(at);
-      if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
-        host = dns ? addr2host( (void *) addr, af ) : NULL;
-        if (host != NULL) {
-          strncpy( name, host->h_name, (sizeof name) - 1 );
-          name[ (sizeof name) - 1 ] = '\0'; 
-        } else {
-          snprintf(name, sizeof(name), "%s", strlongip( addr ) );
-        }
-        if (len_hosts < strlen(name)) {
-          len_hosts = strlen(name);
-        }
-      }    
+      if ((nlen = snprint_addr(name, sizeof(name), addr)))
+        if (len_hosts < nlen)
+          len_hosts = nlen;
     }
   }
   
@@ -104,18 +118,7 @@ void report_close(void)
   for(; at < max; at++) {
     addr = net_addr(at);
     mpls = net_mpls(at);
-    if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) == 0 ) {
-      sprintf(name, "???");
-    } else {
-      host = dns ? addr2host( (void *) addr, af ) : NULL;
-
-      if (host != NULL) {
-        strncpy( name, host->h_name, (sizeof name) - 1 );
-        name[ (sizeof name) - 1 ] = '\0'; 
-      } else {
-        snprintf(name, sizeof(name), "%s", strlongip( addr ) );
-      }
-    }
+    snprint_addr(name, sizeof(name), addr);
 
     snprintf( fmt, sizeof(fmt), " %%2d.|-- %%-%ds", len_hosts);
     snprintf(buf, sizeof(buf), fmt, at+1, name);
@@ -208,7 +211,6 @@ void xml_close(void)
   int i, j, at, max;
   ip_t *addr;
   char name[81];
-  struct hostent *host;
 
   printf("<MTR SRC=%s DST=%s", LocalHostname, Hostname);
   printf(" TOS=0x%X", tos);
@@ -228,19 +230,7 @@ void xml_close(void)
   at  = net_min();
   for(; at < max; at++) {
     addr = net_addr(at);
-    
-    if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) == 0 ) {
-      sprintf(name, "???");
-    } else {
-      host = dns ? addr2host( (void *) addr, af ) : NULL;
-
-      if (host != NULL) {
-	 strncpy( name, host->h_name, (sizeof name) - 1 );
-	 name[ (sizeof name) - 1 ] = '\0'; 
-      } else {
-	sprintf(name, "%s", strlongip( addr ) );
-      }
-    }
+    snprint_addr(name, sizeof(name), addr);
 
     printf("    <HUB COUNT=%d HOST=%s>\n", at+1, name);
     for( i=0; i<MAXFLD; i++ ) {
@@ -279,7 +269,6 @@ void csv_close(void)
   int i, j, at, max;
   ip_t *addr;
   char name[81];
-  struct hostent *host;
 
   /* Caption */
   printf("<SRC=%s DST=%s", LocalHostname, Hostname);
@@ -310,19 +299,7 @@ void csv_close(void)
   at  = net_min();
   for(; at < max; at++) {
     addr = net_addr(at);
-    
-    if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) == 0 ) {
-      sprintf(name, "???");
-    } else {
-      host = dns ? addr2host( (void *) addr, af ) : NULL;
-
-      if (host != NULL) {
-	 strncpy( name, host->h_name, (sizeof name) - 1 );
-	 name[ (sizeof name) - 1 ] = '\0'; 
-      } else {
-	sprintf(name, "%s", strlongip( addr ) );
-      }
-    }
+    snprint_addr(name, sizeof(name), addr);
 
     printf("%d, %s", at+1, name);
     for( i=0; i<MAXFLD; i++ ) {
diff --git a/select.c b/select.c
index e7a8237..4134080 100644
--- a/select.c
+++ b/select.c
@@ -48,6 +48,9 @@ void select_loop(void) {
   int anyset = 0;
   int maxfd = 0;
   int dnsfd, netfd;
+#ifdef ENABLE_IPV6
+  int dnsfd6;
+#endif
   int NumPing = 0;
   int paused = 0;
   struct timeval lasttime, thistime, selecttime;
@@ -70,6 +73,14 @@ void select_loop(void) {
       maxfd = 1;
     }
 
+#ifdef ENABLE_IPV6
+    if (dns) {
+      dnsfd6 = dns_waitfd6();
+      FD_SET(dnsfd6, &readfd);
+      if(dnsfd6 >= maxfd) maxfd = dnsfd6 + 1;
+    } else
+      dnsfd6 = 0;
+#endif
     if (dns) {
       dnsfd = dns_waitfd();
       FD_SET(dnsfd, &readfd);
@@ -148,6 +159,12 @@ void select_loop(void) {
     }
 
     /*  Have we finished a nameservice lookup?  */
+#ifdef ENABLE_IPV6
+    if(dns && FD_ISSET(dnsfd6, &readfd)) {
+      dns_ack6();
+      anyset = 1;
+    }
+#endif
     if(dns && FD_ISSET(dnsfd, &readfd)) {
       dns_ack();
       anyset = 1;
diff --git a/split.c b/split.c
index 4453dac..642353e 100644
--- a/split.c
+++ b/split.c
@@ -74,7 +74,6 @@ void split_redraw(void)
   int   max;
   int   at;
   ip_t *addr;
-  char *name;
   char  newLine[MAX_LINE_SIZE];
   int   i;
 
@@ -97,24 +96,20 @@ void split_redraw(void)
    */
   for(at = 0; at < max; at++) {
     addr = net_addr(at);
-    
-    if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
-      name = dns_lookup(addr);
-      if(name != NULL) {
-	/* May be we should test name's length */
-	snprintf(newLine, sizeof(newLine), "%s %d %d %d %d %d %d", name,
-		net_loss(at),
-		net_returned(at), net_xmit(at),
-		net_best(at) /1000, net_avg(at)/1000, 
-		net_worst(at)/1000);
-      } else {
-	snprintf(newLine, sizeof(newLine), "%s %d %d %d %d %d %d", 
-		strlongip( addr ),
-		net_loss(at),
-		net_returned(at), net_xmit(at),
-		net_best(at) /1000, net_avg(at)/1000, 
-		net_worst(at)/1000);
+    if(addrcmp((void*)addr, (void*)&unspec_addr, af)) {
+      char str[256], *name;
+      if (!(name = dns_lookup(addr)))
+        name = strlongip(addr);
+      if (show_ips) {
+        snprintf(str, sizeof(str), "%s %s", name, strlongip(addr));
+        name = str;
       }
+      /* May be we should test name's length */
+      snprintf(newLine, sizeof(newLine), "%s %d %d %d %d %d %d", name,
+               net_loss(at),
+               net_returned(at), net_xmit(at),
+               net_best(at) /1000, net_avg(at)/1000,
+               net_worst(at)/1000);
     } else {
       sprintf(newLine, "???");
     }
