diff -x .deps -x autom4te.cache -ur mtr-0.73/aclocal.m4 mtr-0.74/aclocal.m4
--- mtr-0.73/aclocal.m4	2008-04-07 18:32:46.000000000 +0200
+++ mtr-0.74/aclocal.m4	2008-08-19 19:08:26.000000000 +0200
@@ -537,18 +537,6 @@
      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
 ])
 
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 8
-
-# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
-AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
-
 # Do all the work for Automake.                             -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Only in mtr-0.73: config.h
diff -x .deps -x autom4te.cache -ur mtr-0.73/config.h.in mtr-0.74/config.h.in
--- mtr-0.73/config.h.in	2006-10-05 10:49:15.000000000 +0200
+++ mtr-0.74/config.h.in	2008-08-19 19:08:37.000000000 +0200
@@ -108,6 +108,18 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define if you don't have the curses libraries available. */
+#undef NO_CURSES
+
+/* Define if you don't have the GTK+ libraries available. */
+#undef NO_GTK
+
+/* Define if you don't have the herror() function available. */
+#undef NO_HERROR
+
+/* Define if you don't have the strerror() function available. */
+#undef NO_STRERROR
+
 /* Name of package */
 #undef PACKAGE
 
@@ -126,16 +138,16 @@
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
-/* The size of a `unsigned char', as computed by sizeof. */
+/* The size of `unsigned char', as computed by sizeof. */
 #undef SIZEOF_UNSIGNED_CHAR
 
-/* The size of a `unsigned int', as computed by sizeof. */
+/* The size of `unsigned int', as computed by sizeof. */
 #undef SIZEOF_UNSIGNED_INT
 
-/* The size of a `unsigned long', as computed by sizeof. */
+/* The size of `unsigned long', as computed by sizeof. */
 #undef SIZEOF_UNSIGNED_LONG
 
-/* The size of a `unsigned short', as computed by sizeof. */
+/* The size of `unsigned short', as computed by sizeof. */
 #undef SIZEOF_UNSIGNED_SHORT
 
 /* Define to 1 if you have the ANSI C header files. */
diff -x .deps -x autom4te.cache -ur mtr-0.73/configure mtr-0.74/configure
--- mtr-0.73/configure	2008-04-07 18:32:49.000000000 +0200
+++ mtr-0.74/configure	2008-08-19 20:11:50.000000000 +0200
@@ -1282,7 +1282,6 @@
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --disable-dependency-tracking  speeds up one-time build
   --enable-dependency-tracking   do not reject slow dependency extractors
-  --enable-gtk2           Compile against GTK2 instead of GTK+
   --disable-ipv6          Do not enable IPv6
   --disable-gtktest       do not try to compile and run a test GTK+ program
 
@@ -2040,7 +2039,7 @@
 
 # Define the identity of the package.
  PACKAGE=mtr
- VERSION=0.73
+ VERSION=0.74
 
 
 cat >>confdefs.h <<_ACEOF
@@ -5921,7 +5920,8 @@
 else
   { echo "$as_me:$LINENO: WARNING: Building without curses display support" >&5
 echo "$as_me: WARNING: Building without curses display support" >&2;}
-	cat >>confdefs.h <<\_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
 #define NO_CURSES 1
 _ACEOF
 
@@ -6401,14 +6401,6 @@
 fi
 
 
-# Check whether --enable-gtk2 was given.
-if test "${enable_gtk2+set}" = set; then
-  enableval=$enable_gtk2; WANTS_GTK2=$enableval
-else
-  WANTS_GTK2=no
-fi
-
-
 # Check whether --enable-ipv6 was given.
 if test "${enable_ipv6+set}" = set; then
   enableval=$enable_ipv6; WANTS_IPV6=$enableval
@@ -6418,8 +6410,7 @@
 
 
 if test "x$WANTS_GTK" = "xyes"; then
-	if test "x$WANTS_GTK2" = "xyes"; then
-                # Check whether --enable-gtktest was given.
+        # Check whether --enable-gtktest was given.
 if test "${enable_gtktest+set}" = set; then
   enableval=$enable_gtktest;
 else
@@ -6493,7 +6484,7 @@
     no_gtk=yes
   fi
 
-  min_gtk_version=2.0.0
+  min_gtk_version=2.4.0
   { echo "$as_me:$LINENO: checking for GTK+ - version >= $min_gtk_version" >&5
 echo $ECHO_N "checking for GTK+ - version >= $min_gtk_version... $ECHO_C" >&6; }
 
@@ -6728,7 +6719,8 @@
      GTK_LIBS=""
      { echo "$as_me:$LINENO: WARNING: Building without GTK2 display support" >&5
 echo "$as_me: WARNING: Building without GTK2 display support" >&2;}
-                           cat >>confdefs.h <<\_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
 #define NO_GTK 1
 _ACEOF
 
@@ -6738,17 +6730,6 @@
 
   rm -f conf.gtktest
 
-        else
-		AM_PATH_GTK(1.0.0, CFLAGS="$CFLAGS $GTK_CFLAGS"
-                           LIBS="$LIBS $GTK_LIBS",
-                           { echo "$as_me:$LINENO: WARNING: Building without GTK+ display support" >&5
-echo "$as_me: WARNING: Building without GTK+ display support" >&2;}
-                           cat >>confdefs.h <<\_ACEOF
-#define NO_GTK 1
-_ACEOF
-
-                           GTK_OBJ="")
-	fi
 else
 	cat >>confdefs.h <<\_ACEOF
 #define NO_GTK 1
@@ -7576,7 +7557,8 @@
 if test $ac_cv_func_herror = yes; then
   :
 else
-  cat >>confdefs.h <<\_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
 #define NO_HERROR 1
 _ACEOF
 
@@ -7666,7 +7648,8 @@
 if test $ac_cv_func_strerror = yes; then
   :
 else
-  cat >>confdefs.h <<\_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
 #define NO_STRERROR 1
 _ACEOF
 
@@ -7972,7 +7955,7 @@
 echo $ECHO_N "checking for C flags to get more warnings... $ECHO_C" >&6; }
 ac_save_CFLAGS="$CFLAGS"
 if test "x$ac_cv_c_compiler_gnu" = "xyes" ; then
-    warning_CFLAGS="-Wall"
+    warning_CFLAGS="-Wall -Wno-pointer-sign"
 else
     case "$host_os" in
         irix*)
diff -x .deps -x autom4te.cache -ur mtr-0.73/configure.in mtr-0.74/configure.in
--- mtr-0.73/configure.in	2006-10-05 09:26:41.000000000 +0200
+++ mtr-0.74/configure.in	2008-08-19 19:07:33.000000000 +0200
@@ -1,5 +1,5 @@
 AC_INIT(mtr.c)
-AM_INIT_AUTOMAKE(mtr, 0.73)
+AM_INIT_AUTOMAKE(mtr, 0.74)
 
 
 AC_SUBST(GTK_OBJ)
@@ -29,7 +29,7 @@
     AC_CHECK_LIB(curses, initscr, , 
       AC_CHECK_LIB(cursesX, initscr, , 
 	AC_MSG_WARN(Building without curses display support)
-	AC_DEFINE(NO_CURSES)
+	AC_DEFINE(NO_CURSES, 1, Define if you don't have the curses libraries available.)
 	CURSES_OBJ=))))
 
 AC_CHECK_FUNCS(attron)
@@ -45,28 +45,16 @@
 [  --without-gtk           Do not try to use GTK+ at all],
 WANTS_GTK=$withval, WANTS_GTK=yes)
 
-AC_ARG_ENABLE(gtk2,
-[  --enable-gtk2           Compile against GTK2 instead of GTK+],
-WANTS_GTK2=$enableval, WANTS_GTK2=no)
-   
 AC_ARG_ENABLE(ipv6,
 [  --disable-ipv6          Do not enable IPv6],
 WANTS_IPV6=$enableval, WANTS_IPV6=yes)
    
 if test "x$WANTS_GTK" = "xyes"; then
-	if test "x$WANTS_GTK2" = "xyes"; then
-                AM_PATH_GTK_2_0(2.0.0, CFLAGS="$CFLAGS $GTK_CFLAGS"
+        AM_PATH_GTK_2_0(2.4.0, CFLAGS="$CFLAGS $GTK_CFLAGS"
                            LIBS="$LIBS $GTK_LIBS -lm",
                            AC_MSG_WARN(Building without GTK2 display support)
-                           AC_DEFINE(NO_GTK)
-                           GTK_OBJ="")
-        else
-		AM_PATH_GTK(1.0.0, CFLAGS="$CFLAGS $GTK_CFLAGS"
-                           LIBS="$LIBS $GTK_LIBS",
-                           AC_MSG_WARN(Building without GTK+ display support)
-                           AC_DEFINE(NO_GTK)
+                   AC_DEFINE(NO_GTK, 1, [Define if you don't have the GTK+ libraries available.])
                            GTK_OBJ="")
-	fi
 else
 	AC_DEFINE(NO_GTK)
 	GTK_OBJ=""
@@ -95,8 +83,8 @@
 # removing it hurts your OS.... -- REW
 #LIBS="$LIBS -lresolv"
 
-AC_CHECK_FUNC(herror, , AC_DEFINE(NO_HERROR))
-AC_CHECK_FUNC(strerror, , AC_DEFINE(NO_STRERROR))
+AC_CHECK_FUNC(herror, , AC_DEFINE(NO_HERROR, 1, [Define if you don't have the herror() function available.]))
+AC_CHECK_FUNC(strerror, , AC_DEFINE(NO_STRERROR, 1, [Define if you don't have the strerror() function available.]))
 
 AC_CHECK_FUNC(getaddrinfo,
 [if test "$WANTS_IPV6" = "yes"; then
@@ -119,25 +107,23 @@
 dnl Add C flags to display more warnings
 AC_MSG_CHECKING(for C flags to get more warnings)
 ac_save_CFLAGS="$CFLAGS"
-if test "x$ac_cv_prog_gcc" = "xyes" ; then
+if test "x$ac_cv_c_compiler_gnu" = "xyes" ; then
   dnl gcc is the easiest C compiler
-  warning_CFLAGS="-Wall"
+  warning_CFLAGS="-Wall -Wno-pointer-sign"
 else
   dnl Vendor supplied C compilers are a bit tricky
   case "$host_os" in
     dnl SGI IRIX with the MipsPRO C compiler
     irix*)
       CFLAGS="$CFLAGS -fullwarn"
-      AC_TRY_COMPILE([#include <stdio.h>],[printf("test");],
-        warning_CFLAGS="-fullwarn",)
+      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]], [[printf("test");]])],[warning_CFLAGS="-fullwarn"],[])
       ;;
 
     dnl SunOS 4.x with the SparcWorks(?) acc compiler
     sunos*)
         if "$CC" = "acc" ; then
           CFLAGS="$CFLAGS -vc"
-          AC_TRY_COMPILE([#include <stdio.h>],[printf("test");],
-            warning_CFLAGS="-vc",)
+          AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]], [[printf("test");]])],[warning_CFLAGS="-vc"],[])
         fi
       ;;
 
@@ -158,6 +144,7 @@
 
 
 
-AM_CONFIG_HEADER(config.h)
-AC_OUTPUT(Makefile img/Makefile)
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_FILES([Makefile img/Makefile])
+AC_OUTPUT
 
Only in mtr-0.73: configure.odl
diff -x .deps -x autom4te.cache -ur mtr-0.73/curses.c mtr-0.74/curses.c
--- mtr-0.73/curses.c	2008-03-24 20:35:58.000000000 +0100
+++ mtr-0.74/curses.c	2008-08-19 18:55:48.000000000 +0200
@@ -76,6 +76,7 @@
 extern int tos;
 extern float WaitTime;
 extern int af;
+extern int mtrtype;
 
 void pwcenter(char *str) 
 {
@@ -247,6 +248,17 @@
     }
     return ActionNone;
   }
+  if (tolower(c) == 'u') {
+    switch ( mtrtype ) {
+    case IPPROTO_ICMP:
+      mtrtype = IPPROTO_UDP;
+      break;
+    case IPPROTO_UDP:
+      mtrtype = IPPROTO_ICMP;
+      break;
+    }
+    return ActionNone;
+  }
   /* reserve to display help message -Min */
   if (tolower(c) == '?'|| tolower(c) == 'h') {
     mvprintw(2, 0, "Command:\n" );
@@ -261,7 +273,8 @@
     printw("  m <n>   set the max time-to-live, default n= # of hops\n" );
     printw("  s <n>   set the packet size to n or random(n<0)\n" );
     printw("  b <c>   set ping bit pattern to c(0..255) or random(c<0)\n" );
-    printw("  Q <t>   set ping packet's TOS to t\n\n\n" );
+    printw("  Q <t>   set ping packet's TOS to t\n" );
+    printw("  u       switch between ICMP ECHO and UDP datagrams\n\n" );
     mvprintw(16, 0, " press any key to go back..." );
 
     getch();                  /* get any key */
Only in mtr-0.73: curses.o
Only in mtr-0.73: display.o
diff -x .deps -x autom4te.cache -ur mtr-0.73/dns.c mtr-0.74/dns.c
--- mtr-0.73/dns.c	2007-08-10 18:16:45.000000000 +0200
+++ mtr-0.74/dns.c	2008-08-19 19:07:33.000000000 +0200
@@ -32,6 +32,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+
 #define BIND_8_COMPAT
 #include <arpa/nameser.h>
 #include <netdb.h>
@@ -49,6 +50,15 @@
 #include "dns.h"
 #include "net.h"
 
+/* 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
+ */
+#if 0 
+#include "nameser8_compat.h"
+#endif
+
+
 #ifdef NO_STRERROR
 extern int sys_nerr;
 extern char *sys_errlist[];
@@ -453,7 +463,7 @@
 }
 
 
-struct hostent * dns_forward(char *name)
+struct hostent * dns_forward(const char *name)
 {
   struct hostent *host;
 
diff -x .deps -x autom4te.cache -ur mtr-0.73/dns.h mtr-0.74/dns.h
--- mtr-0.73/dns.h	2006-03-23 06:45:58.000000000 +0100
+++ mtr-0.74/dns.h	2008-08-19 19:07:33.000000000 +0200
@@ -28,7 +28,7 @@
 void dns_events(double *sinterval);
 char *dns_lookup(ip_t * address);
 char *dns_lookup2(ip_t * address);
-struct hostent * dns_forward(char *name);
+struct hostent * dns_forward(const char *name);
 char *strlongip(ip_t * ip);
 
 void addr2ip6arpa( ip_t * ip, char * buf );
Only in mtr-0.73: dns.o
Only in mtr-0.73: getopt1.o
Only in mtr-0.73: getopt.o
diff -x .deps -x autom4te.cache -ur mtr-0.73/gtk.c mtr-0.74/gtk.c
--- mtr-0.73/gtk.c	2006-10-04 09:30:33.000000000 +0200
+++ mtr-0.74/gtk.c	2008-08-19 19:07:33.000000000 +0200
@@ -56,7 +56,7 @@
   int dt;
 
   dt = calc_deltatime (WaitTime);
-  tag = gtk_timeout_add(dt / 1000, gtk_ping, NULL);
+  tag = g_timeout_add(dt / 1000, gtk_ping, NULL);
 }
 
 
@@ -109,7 +109,7 @@
   if (paused) {
     gtk_add_ping_timeout ();
   } else {
-    gtk_timeout_remove (tag);
+    g_source_remove (tag);
   }
   paused = ! paused;
   gtk_redraw();
@@ -129,8 +129,8 @@
 
 gint WaitTime_changed(UNUSED GtkAdjustment *Adj, UNUSED GtkWidget *Button) 
 {
-  WaitTime = gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(Button));
-  gtk_timeout_remove (tag);
+  WaitTime = gtk_spin_button_get_value(GTK_SPIN_BUTTON(Button));
+  g_source_remove (tag);
   gtk_add_ping_timeout ();
   gtk_redraw();
 
@@ -147,10 +147,11 @@
     net_reopen(addr);
     /* If we are "Paused" at this point it is usually because someone
        entered a non-existing host. Therefore do the go-ahead... --REW */
-    gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( Pause_Button ) , 0);
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( Pause_Button ) , 0);
   } else {
-    gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( Pause_Button ) , 1);
-    gtk_entry_append_text( GTK_ENTRY(Entry), ": not found" );
+    int pos = strlen(gtk_entry_get_text( GTK_ENTRY(Entry)));
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( Pause_Button ) , 1);
+    gtk_editable_insert_text( GTK_EDITABLE(Entry), ": not found", -1, &pos);
   }
 
   return FALSE;
@@ -172,27 +173,24 @@
   GtkWidget *Entry;
   GtkAdjustment *Adjustment;
 
-  Button = gtk_button_new_with_label("Quit");
+  Button = gtk_button_new_from_stock(GTK_STOCK_QUIT);
   gtk_box_pack_end(GTK_BOX(Toolbar), Button, FALSE, FALSE, 0);
-  gtk_signal_connect(GTK_OBJECT(Button), "clicked",
+  g_signal_connect(GTK_OBJECT(Button), "clicked",
 		     GTK_SIGNAL_FUNC(Window_destroy), NULL);
-  gtk_widget_show(Button);
 
-  Button = gtk_button_new_with_label("Restart");
+  Button = gtk_button_new_with_mnemonic("_Restart");
   gtk_box_pack_end(GTK_BOX(Toolbar), Button, FALSE, FALSE, 0);
-  gtk_signal_connect(GTK_OBJECT(Button), "clicked",
+  g_signal_connect(GTK_OBJECT(Button), "clicked",
 		     GTK_SIGNAL_FUNC(Restart_clicked), NULL);
-  gtk_widget_show(Button);
 
-  Pause_Button = gtk_toggle_button_new_with_label("Pause");
+  Pause_Button = gtk_toggle_button_new_with_mnemonic("_Pause");
   gtk_box_pack_end(GTK_BOX(Toolbar), Pause_Button, FALSE, FALSE, 0);
-  gtk_signal_connect(GTK_OBJECT(Pause_Button), "clicked",
+  g_signal_connect(GTK_OBJECT(Pause_Button), "clicked",
                     GTK_SIGNAL_FUNC(Pause_clicked), NULL);
-  gtk_widget_show(Pause_Button);
 
   /* allow root only to set zero delay */
   Adjustment = (GtkAdjustment *)gtk_adjustment_new(WaitTime,
-                                                  getuid()==0 ? 0.00:1.00,
+                                                  getuid()==0 ? 0.01:1.00,
                                                  999.99,
                                                   1.0, 10.0,
                                                   0.0);
@@ -202,127 +200,182 @@
   /* gtk_spin_button_set_set_update_policy(GTK_SPIN_BUTTON(Button),
      GTK_UPDATE_IF_VALID); */
   gtk_box_pack_end(GTK_BOX(Toolbar), Button, FALSE, FALSE, 0);
-  gtk_signal_connect(GTK_OBJECT(Adjustment), "value_changed",
+  g_signal_connect(GTK_OBJECT(Adjustment), "value_changed",
                     GTK_SIGNAL_FUNC(WaitTime_changed), Button);
-  gtk_widget_show(Button);
  
-  Label = gtk_label_new("Hostname");
+  Label = gtk_label_new_with_mnemonic("_Hostname:");
   gtk_box_pack_start(GTK_BOX(Toolbar), Label, FALSE, FALSE, 0);
-  gtk_widget_show(Label);
 
   Entry = gtk_entry_new();
   gtk_entry_set_text(GTK_ENTRY(Entry), Hostname);
-  gtk_signal_connect(GTK_OBJECT(Entry), "activate",
+  g_signal_connect(GTK_OBJECT(Entry), "activate",
 		     GTK_SIGNAL_FUNC(Host_activate), NULL);
   gtk_box_pack_start(GTK_BOX(Toolbar), Entry, TRUE, TRUE, 0);
-  gtk_widget_show(Entry);
-}
-
-
-char *Report_Text[] = { "Hostname", "Loss", "Rcv", "Snt", "Last", "Best", "Avg", "Worst", "StDev", NULL };
-int Report_Positions[] = { 10, 200, 240, 280, 320, 360, 400, 440, 480, 0 };
-GtkWidget *Report;
-GtkWidget *ReportBody;
-
-GtkWidget *GetRow(int index) 
-{
-  ip_t * addr;
-  char *name;
-  GtkWidget *Row, *Label;
-
-  Row = gtk_fixed_new();
   
-  addr = net_addr(index);
-  name = "???";
-  if ( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
-    name = dns_lookup(addr);
-    if(!name) {
-      /* Actually this is not neccesary: 
-	 dns_lookup always returns a printable string */
-      name = strlongip (addr);
-    }
-  }
-
-  Label = gtk_label_new(name);
-  gtk_fixed_put(GTK_FIXED(Row), Label, Report_Positions[0], 0);
-  gtk_widget_show(Label);
-
-  return Row;
-}
-
-
-GtkWidget *Scrollarea_create(void)
-{
-  GtkWidget *List;
-  GtkWidget *scroll;
-  int count;
-
-  for(count = 0; Report_Positions[count]; count++);
-
-  List = GTK_WIDGET(gtk_clist_new_with_titles(count, Report_Text));
-  scroll = gtk_scrolled_window_new(NULL, NULL);
-  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-  for(count = 0; Report_Positions[count + 1]; count++) {
-    gtk_clist_set_column_width(GTK_CLIST(List), count, 
-			       Report_Positions[count + 1] - 
-			       Report_Positions[count]);
-  }
-  gtk_clist_set_column_width(GTK_CLIST(List), count, 0);
-  for(count = 1; Report_Positions[count]; count++) {
-    gtk_clist_set_column_justification(GTK_CLIST(List), count, GTK_JUSTIFY_RIGHT);
-  }
-  gtk_container_add(GTK_CONTAINER(scroll), List);
-  gtk_widget_show(List);
-
-  ReportBody = List;
-  return scroll;
+  gtk_label_set_mnemonic_widget(GTK_LABEL(Label), Entry);
 }
 
+static GtkWidget *ReportTreeView;
+static GtkListStore *ReportStore;
 
-void gtk_add_row(GtkWidget *List) 
-{
-  int at;
-  GtkWidget *Row, *Label;
-
-  Row = gtk_fixed_new();
+enum {
+  COL_HOSTNAME,
+  COL_LOSS,
+  COL_RCV,
+  COL_SNT,
+  COL_LAST,
+  COL_BEST,
+  COL_AVG,
+  COL_WORST,
+  COL_STDEV,
+  COL_COLOR,
+  N_COLS
+};
+
+void  float_formatter(GtkTreeViewColumn *tree_column,
+  GtkCellRenderer   *cell, 
+  GtkTreeModel      *tree_model,
+  GtkTreeIter       *iter, 
+  gpointer           data)
+{
+  gfloat f;
+  gchar text[64];
+  gtk_tree_model_get(tree_model, iter, (gint)data, &f, -1);
+  sprintf(text, "%.2f", f);
+  g_object_set(cell, "text", text, NULL);
+}
+
+void  percent_formatter(GtkTreeViewColumn *tree_column,
+  GtkCellRenderer   *cell, 
+  GtkTreeModel      *tree_model,
+  GtkTreeIter       *iter, 
+  gpointer           data)
+{
+  gfloat f;
+  gchar text[64];
+  gtk_tree_model_get(tree_model, iter, (gint)data, &f, -1);
+  sprintf(text, "%.1f%%", f);
+  g_object_set(cell, "text", text, NULL);
+}
+
+void TreeViewCreate(void)
+{
+  GtkCellRenderer *renderer;
+  GtkTreeViewColumn *column;
+
+  ReportStore = gtk_list_store_new(N_COLS,
+    G_TYPE_STRING,
+    G_TYPE_FLOAT,
+    G_TYPE_INT,
+    G_TYPE_INT,
+    G_TYPE_INT,
+    G_TYPE_INT,
+    G_TYPE_INT,
+    G_TYPE_INT,
+    G_TYPE_FLOAT,
+    G_TYPE_STRING
+    );
+    
+  ReportTreeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ReportStore));
   
-  for(at = 0; Report_Positions[at] != 0; at++) {
-    Label = gtk_label_new("-");
-    if(at) {
-      gtk_widget_set_usize(Label, 40, 0);
-      gtk_label_set_justify(GTK_LABEL(Label), GTK_JUSTIFY_RIGHT);
-    }
-    gtk_fixed_put(GTK_FIXED(Row), Label, Report_Positions[at], 0);
-    gtk_widget_show(Label);
-  }
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes ("Hostname",
+    renderer,
+    "text", COL_HOSTNAME,
+    "foreground", COL_COLOR,
+    NULL);
+  gtk_tree_view_column_set_expand(column, TRUE);
+  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 ("Loss",
+    renderer,
+    "text", COL_LOSS,
+    "foreground", COL_COLOR,
+    NULL);
+  gtk_tree_view_column_set_resizable(column, TRUE);
+  gtk_tree_view_column_set_cell_data_func(column, renderer, percent_formatter, (void*)COL_LOSS, NULL);
+  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 ("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,
+    "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 ("Last",
+    renderer,
+    "text", 4,
+    "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 ("Best",
+    renderer,
+    "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 ();
+  g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
+  column = gtk_tree_view_column_new_with_attributes ("Avg",
+    renderer,
+    "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 ("Worst",
+    renderer,
+    "text", 7,
+    "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 ("StDev",
+    renderer,
+    "text", 8,
+    "foreground", COL_COLOR,
+    NULL);
+  gtk_tree_view_column_set_resizable(column, TRUE);
+  gtk_tree_view_column_set_cell_data_func(column, renderer, float_formatter, (void*)COL_STDEV, NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
 
-  gtk_box_pack_start(GTK_BOX(List), Row, FALSE, FALSE, 0);
-  gtk_widget_show(Row);
 }
 
-
-void gtk_set_field(GtkCList *List, int row, int ix, char *str) {
-  gtk_clist_set_text(List, row, ix, str);
-}
-
-
-/*   void gtk_set_field_num(GtkCList *List, int row, int ix, char *format, int num) {
-             changed int to dobule byMin */
-void gtk_set_field_num(GtkCList *List, int row, int ix, char *format, double num) 
-{
-  char str[32];
-
-  sprintf(str, format, num);
-  gtk_set_field(List, row, ix, str);
-}
-
-
-void gtk_update_row(GtkCList *List, int row) 
+void update_tree_row(int row, GtkTreeIter *iter)
 {
   ip_t *addr;
   char str[256], *name;
-  GdkColor color;
-  GdkColormap *cmap;
 
   addr = net_addr(row);
   name = "???";
@@ -334,54 +387,46 @@
     }
   }
 
-  cmap = gtk_widget_get_colormap(ReportBody);
-  if (net_up(row)) {
-    gdk_color_black(cmap, &color);
-  } else {
-    color.red = 0xffff;
-    color.green = 0;
-    color.blue = 0;
-  }
-  gdk_color_alloc (cmap, &color);
-  gtk_clist_set_foreground(List, row, &color);
+  gtk_list_store_set(ReportStore, iter,
+    COL_HOSTNAME, name,
+    COL_LOSS, (float)(net_loss(row)/1000.0),
+
+    COL_RCV, net_returned(row),
+    COL_SNT, net_xmit(row),
+
+    COL_LAST, net_last(row)/1000,
+    COL_BEST, net_best(row)/1000,
+    COL_AVG, net_avg(row)/1000,
+    COL_WORST, net_worst(row)/1000,
+    COL_STDEV, (float)(net_stdev(row)/1000.0),
+    
+    COL_COLOR, net_up(row) ? "black" : "red",
 
-  /* changed the format type and added stdev and first/max TTL byMin */
-  /* the row - net_min() is kind of not clean, need some more work */
-  gtk_set_field(List, row - net_min(), 0, name);
-
-  gtk_set_field_num(List, row - net_min(), 1, "%.1f%%", net_loss(row)/1000.0);
-  gtk_set_field_num(List, row - net_min(), 2, "%.0f", net_returned(row));  
-  gtk_set_field_num(List, row - net_min(), 3, "%.0f", net_xmit(row));
-  
-  gtk_set_field_num(List, row - net_min(), 4, "%.0f", net_last(row)/1000.0);
-  gtk_set_field_num(List, row - net_min(), 5, "%.0f", net_best(row)/1000.0);
-  gtk_set_field_num(List, row - net_min(), 6, "%.0f", net_avg(row)/1000.0);  
-  gtk_set_field_num(List, row - net_min(), 7, "%.0f", net_worst(row)/1000.0);
-  gtk_set_field_num(List, row - net_min(), 8, "%.2f", net_stdev(row)/1000.0);
+    -1);
 }
 
-
 void gtk_redraw(void)
 {
-  int at  = net_min();	/* changed from 0 to net_min for TTL stuff byMin */
   int max = net_max();
-
-  gtk_clist_freeze(GTK_CLIST(ReportBody));
-
-  while(GTK_CLIST(ReportBody)->rows < max -at) {	/* byMin */
-    gtk_clist_append(GTK_CLIST(ReportBody), Report_Text);
-  }
-
-  while(GTK_CLIST(ReportBody)->rows > max) {
-    gtk_clist_remove(GTK_CLIST(ReportBody), GTK_CLIST(ReportBody)->rows - 1);
+  
+  GtkTreeIter iter;
+  int row = net_min();
+  gboolean valid;
+
+  valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(ReportStore), &iter);
+
+  while(valid) {
+    if(row < max) {
+      update_tree_row(row++, &iter);
+      valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(ReportStore), &iter);
+    } else {
+      valid = gtk_list_store_remove(ReportStore, &iter);
+    }
   }
-
-  /* for(at=0; at < max; at++) {	 replaced byMin */
-  for(; at < max; at++) {
-    gtk_update_row(GTK_CLIST(ReportBody), at);
+  while(row < max) {
+    gtk_list_store_append(ReportStore, &iter);
+    update_tree_row(row++, &iter);
   }
-
-  gtk_clist_thaw(GTK_CLIST(ReportBody));
 }
 
 
@@ -389,25 +434,25 @@
 {
   GtkWidget *VBox;
   GtkWidget *Toolbar;
-  GtkWidget *List;
+  GtkWidget *scroll;
 
   gtk_window_set_title(GTK_WINDOW(Window), "My traceroute  [v" VERSION "]");
-  gtk_window_set_wmclass(GTK_WINDOW(Window), "mtr", "Mtr");
-  gtk_widget_set_usize(Window, 600, 400); 
-  gtk_container_border_width(GTK_CONTAINER(Window), 10);
+  gtk_window_set_default_size(GTK_WINDOW(Window), 650, 400); 
+  gtk_container_set_border_width(GTK_CONTAINER(Window), 10);
   VBox = gtk_vbox_new(FALSE, 10);
 
   Toolbar = gtk_hbox_new(FALSE, 10);
   Toolbar_fill(Toolbar);
   gtk_box_pack_start(GTK_BOX(VBox), Toolbar, FALSE, FALSE, 0);
-  gtk_widget_show(Toolbar);
-
-  List = Scrollarea_create();
-  gtk_box_pack_start(GTK_BOX(VBox), List, TRUE, TRUE, 0);
-  gtk_widget_show(List);
   
+  TreeViewCreate();
+  scroll = gtk_scrolled_window_new(NULL, NULL);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_IN);
+  gtk_container_add(GTK_CONTAINER(scroll), ReportTreeView);
+  gtk_box_pack_start(GTK_BOX(VBox), scroll, TRUE, TRUE, 0);
+
   gtk_container_add(GTK_CONTAINER(Window), VBox);
-  gtk_widget_show(VBox);
 }
 
 
@@ -429,14 +474,13 @@
 
   Window_fill(Window);
 
-  gtk_signal_connect_object(GTK_OBJECT(Window), "delete_event",
-			    GTK_SIGNAL_FUNC(gtk_widget_destroy), 
-			    GTK_OBJECT(Window));
-  gtk_signal_connect(GTK_OBJECT(Window), "destroy",
+  g_signal_connect(GTK_OBJECT(Window), "delete_event",
+                     GTK_SIGNAL_FUNC(Window_destroy), NULL);
+  g_signal_connect(GTK_OBJECT(Window), "destroy",
 		     GTK_SIGNAL_FUNC(Window_destroy), NULL);
 
   icon = gtk_load_pixmap(mtr_icon);
-  gtk_widget_show(Window);
+  gtk_widget_show_all(Window);
   gdk_window_set_icon(Window->window, NULL, icon, NULL);
   gdk_window_set_icon_name(Window->window, "mtr");
 }
@@ -457,30 +501,37 @@
 {
   gtk_redraw();
   net_send_batch();
-  gtk_timeout_remove (tag);
+  g_source_remove (tag);
   gtk_add_ping_timeout ();
   return TRUE;
 }
 
 
-void gtk_net_data(UNUSED gpointer data, UNUSED gint fd, UNUSED GdkInputCondition cond) 
+gboolean gtk_net_data(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, UNUSED gpointer data) 
 {
   net_process_return();
+  return TRUE;
 }
 
 
-void gtk_dns_data(UNUSED gpointer data, UNUSED gint fd, UNUSED GdkInputCondition cond) 
+gboolean gtk_dns_data(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, UNUSED gpointer data)
 {
   dns_ack();
   gtk_redraw();
+  return TRUE;
 }
 
 
 void gtk_loop(void) 
 {
+  GIOChannel *net_iochannel, *dns_iochannel;
+
   gtk_add_ping_timeout ();
-  gdk_input_add(net_waitfd(), GDK_INPUT_READ, gtk_net_data, NULL);
-  gdk_input_add(dns_waitfd(), GDK_INPUT_READ, gtk_dns_data, NULL);
+  
+  net_iochannel = g_io_channel_unix_new(net_waitfd());
+  g_io_add_watch(net_iochannel, G_IO_IN, gtk_net_data, NULL);
+  dns_iochannel = g_io_channel_unix_new(dns_waitfd());
+  g_io_add_watch(dns_iochannel, G_IO_IN, gtk_dns_data, NULL);
 
   gtk_main();
 }
Only in mtr-0.73: gtk.o
Only in mtr-0.73/img: Makefile
diff -x .deps -x autom4te.cache -ur mtr-0.73/img/Makefile.in mtr-0.74/img/Makefile.in
--- mtr-0.73/img/Makefile.in	2006-10-05 09:15:58.000000000 +0200
+++ mtr-0.74/img/Makefile.in	2008-08-19 19:08:28.000000000 +0200
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -67,8 +67,8 @@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GREP = @GREP@
 GTK_CFLAGS = @GTK_CFLAGS@
-GTK_CONFIG = @GTK_CONFIG@
 GTK_LIBS = @GTK_LIBS@
 GTK_OBJ = @GTK_OBJ@
 INSTALL_DATA = @INSTALL_DATA@
@@ -94,7 +94,6 @@
 STRIP = @STRIP@
 VERSION = @VERSION@
 ac_ct_CC = @ac_ct_CC@
-ac_ct_STRIP = @ac_ct_STRIP@
 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
 am__include = @am__include@
@@ -105,19 +104,26 @@
 bindir = @bindir@
 build_alias = @build_alias@
 datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 host_alias = @host_alias@
+htmldir = @htmldir@
 includedir = @includedir@
 infodir = @infodir@
 install_sh = @install_sh@
 libdir = @libdir@
 libexecdir = @libexecdir@
+localedir = @localedir@
 localstatedir = @localstatedir@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
+psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sysconfdir = @sysconfdir@
@@ -135,9 +141,9 @@
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  img/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  img/Makefile'; \
 	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu  img/Makefile
+	  $(AUTOMAKE) --foreign  img/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
Only in mtr-0.73: Makefile
Only in mtr-0.73: mtr
diff -x .deps -x autom4te.cache -ur mtr-0.73/mtr.8 mtr-0.74/mtr.8
--- mtr-0.73/mtr.8	2007-05-07 08:10:16.000000000 +0200
+++ mtr-0.74/mtr.8	2008-08-19 18:55:48.000000000 +0200
@@ -8,7 +8,7 @@
 .SH SYNOPSIS
 .B mtr 
 [\c
-.B \-hvrctglspni46\c
+.B \-hvrctglspniu46\c
 ]
 [\c
 .B \-\-help\c
@@ -218,6 +218,11 @@
 ECHO requests.  The default value for this parameter is one second.
 
 .TP
+.B \-u
+.br
+Use UDP datagrams instead of ICMP ECHO.
+
+.TP
 .B \-4
 .br
 Use IPv4 only.
diff -x .deps -x autom4te.cache -ur mtr-0.73/mtr.c mtr-0.74/mtr.c
--- mtr-0.73/mtr.c	2008-04-07 18:28:46.000000000 +0200
+++ mtr-0.74/mtr.c	2008-08-19 19:07:33.000000000 +0200
@@ -65,6 +65,7 @@
 int   bitpattern = 0;
 int   tos = 0;
 int af = DEFAULT_AF;
+int mtrtype = IPPROTO_ICMP;     /* Use ICMP as default packet type */
 
                                 /* begin ttl windows addByMin */
 int  fstTTL = 1;                /* default start at first hop */
@@ -143,6 +144,7 @@
     { "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 */
     { 0, 0, 0, 0 }
@@ -152,7 +154,7 @@
   while(1) {
     /* added f:m:o: byMin */
     opt = getopt_long(argc, argv,
-		      "vhrxtglpo:i:c:s:b:Q:na:f:m:46", long_options, NULL);
+		      "vhrxtglpo:i:c:s:b:Q:na:f:m:u46", long_options, NULL);
     if(opt == -1)
       break;
 
@@ -238,7 +240,7 @@
           exit (1);
         }
       }
-      strcpy (fld_active, optarg);
+      strcpy ((char*)fld_active, optarg);
       break;
     case 'b':
       bitpattern = atoi (optarg);
@@ -253,6 +255,9 @@
 	tos = 0;
       }
       break;
+    case 'u':
+      mtrtype = IPPROTO_UDP;
+      break;
     case '4':
       af = AF_INET;
       break;
@@ -354,13 +359,19 @@
 
   parse_arg (argc, argv);
 
+  /* Now that we know mtrtype we can select which socket to use */
+  if (net_selectsocket() != 0) {
+    fprintf( stderr, "mtr: Couldn't determine raw socket type.\n" );
+    exit( EXIT_FAILURE );
+  }
+
   if (PrintVersion) {
     printf ("mtr " VERSION "\n");
     exit(0);
   }
 
   if (PrintHelp) {
-    printf("usage: %s [-hvrctglspni46] [--help] [--version] [--report]\n"
+    printf("usage: %s [-hvrctglspniu46] [--help] [--version] [--report]\n"
 	   "\t\t[--report-cycles=COUNT] [--curses] [--gtk]\n"
            "\t\t[--raw] [--split] [--no-dns] [--address interface]\n" /* BL */
            "\t\t[--psize=bytes/-s bytes]\n"            /* ok */
diff -x .deps -x autom4te.cache -ur mtr-0.73/mtr.h mtr-0.74/mtr.h
--- mtr-0.73/mtr.h	2006-10-05 10:49:44.000000000 +0200
+++ mtr-0.74/mtr.h	2008-08-19 19:10:02.000000000 +0200
@@ -20,6 +20,42 @@
 
 /* Typedefs */
 
+#if 0
+
+// Neat trick! However, on my system, "config.h" already defines these types
+// so I get a compiler error if I leave this in.  -- REW
+
+/*  Find the proper type for 8 bits  */
+#if SIZEOF_UNSIGNED_CHAR == 1
+typedef unsigned char uint8;
+#else
+#error No 8 bit type
+#endif
+
+/*  Find the proper type for 16 bits  */
+#if SIZEOF_UNSIGNED_SHORT == 2
+typedef unsigned short uint16;
+#elif SIZEOF_UNSIGNED_INT == 2
+typedef unsigned int uint16;
+#elif SIZEOF_UNSIGNED_LONG == 2
+typedef unsigned long uint16;
+#else
+#error No 16 bit type
+#endif
+
+/*  Find the proper type for 32 bits  */
+#if SIZEOF_UNSIGNED_SHORT == 4
+typedef unsigned short uint32;
+#elif SIZEOF_UNSIGNED_INT == 4
+typedef unsigned int uint32;
+#elif SIZEOF_UNSIGNED_LONG == 4
+typedef unsigned long uint32;
+#else
+#error No 32 bit type
+#endif
+
+#endif
+
 typedef unsigned char byte;
 typedef unsigned short word;
 typedef unsigned long dword;
Only in mtr-0.73: mtr.o
diff -x .deps -x autom4te.cache -ur mtr-0.73/net.c mtr-0.74/net.c
--- mtr-0.73/net.c	2006-10-04 09:31:13.000000000 +0200
+++ mtr-0.74/net.c	2008-08-19 18:55:48.000000000 +0200
@@ -54,6 +54,22 @@
   uint16 sequence;
 };
 
+/* Structure of an UDP header.  */
+struct UDPHeader {
+  uint16 srcport;
+  uint16 dstport;
+  uint16 length;
+  uint16 checksum;
+};
+
+/* Structure of an IPv4 UDP pseudoheader.  */
+struct UDPv4PHeader {
+  uint32 saddr;
+  uint32 daddr;
+  uint8 zero;
+  uint8 protocol;
+  uint16 len;
+};
 
 /*  Structure of an IP header.  */
 struct IPHeader {
@@ -77,6 +93,7 @@
 #define ICMP_TSTAMPREPLY	14
 
 #define ICMP_TIME_EXCEEDED	11
+#define ICMP_UNREACHABLE        3
 
 #ifndef SOL_IP
 #define SOL_IP 0
@@ -131,8 +148,12 @@
 
 int    timestamp;
 int    sendsock4;
+int    sendsock4_icmp;
+int    sendsock4_udp;
 int    recvsock4;
 int    sendsock6;
+int    sendsock6_icmp;
+int    sendsock6_udp;
 int    recvsock6;
 int    sendsock;
 int    recvsock;
@@ -175,7 +196,7 @@
 extern int bitpattern;		/* packet bit pattern used by ping */
 extern int tos;			/* type of service set in ping packet*/
 extern int af;			/* address family of remote target */
-
+extern int mtrtype;		/* type of query packet used */
 
 /* return the number of microseconds to wait before sending the next
    ping */
@@ -206,14 +227,40 @@
 }
 
 
+/* Prepend pseudoheader to the udp datagram and calculate checksum */
+int udp_checksum(void *pheader, void *udata, int psize, int dsize)
+{
+  unsigned int tsize = psize + dsize;
+  char csumpacket[tsize];
+  memset(csumpacket, (unsigned char) abs(bitpattern), abs(tsize));
+
+  struct UDPv4PHeader *prepend = (struct UDPv4PHeader *) csumpacket;
+  struct UDPv4PHeader *udppheader = (struct UDPv4PHeader *) pheader;
+  prepend->saddr = udppheader->saddr;
+  prepend->daddr = udppheader->daddr;
+  prepend->zero = 0;
+  prepend->protocol = udppheader->protocol;
+  prepend->len = udppheader->len;
+
+  struct UDPHeader *content = (struct UDPHeader *)(csumpacket + psize);
+  struct UDPHeader *udpdata = (struct UDPHeader *) udata;
+  content->srcport = udpdata->srcport;
+  content->dstport = udpdata->dstport;
+  content->length = udpdata->length;
+  content->checksum = udpdata->checksum;
+
+  return checksum(csumpacket,tsize);
+}
+
+
 int new_sequence(int index) 
 {
-  static int next_sequence = 0;
+  static int next_sequence = MinSequence;
   int seq;
 
   seq = next_sequence++;
   if (next_sequence >= MaxSequence)
-    next_sequence = 0;
+    next_sequence = MinSequence;
 
   sequence[seq].index = index;
   sequence[seq].transit = 1;
@@ -236,15 +283,21 @@
   /*ok  char packet[sizeof(struct IPHeader) + sizeof(struct ICMPHeader)];*/
   char packet[MAXPACKET];
   struct IPHeader *ip = (struct IPHeader *) packet;
-  struct ICMPHeader *icmp;
+  struct ICMPHeader *icmp = NULL;
+  struct UDPHeader *udp = NULL;
+  struct UDPv4PHeader *udpp = NULL;
+  uint16 mypid;
 
   /*ok  int packetsize = sizeof(struct IPHeader) + sizeof(struct ICMPHeader) + datasize;*/
   int rv;
   static int first=1;
-  int ttl, iphsize = 0, echotype = 0, salen = 0;
+  int ttl, iphsize = 0, echotype = 0, salen = 0, udphsize = 0;
 
   ttl = index + 1;
 
+  /* offset for ipv6 checksum calculation */
+  int offset = 6;
+
   if ( packetsize < MINPACKET ) packetsize = MINPACKET;
   if ( packetsize > MAXPACKET ) packetsize = MAXPACKET;
 
@@ -271,7 +324,7 @@
   ip->id = 0;
   ip->frag = 0;    /* 1, if want to find mtu size? Min */
     ip->ttl = ttl;
-  ip->protocol = IPPROTO_ICMP;
+  ip->protocol = mtrtype;
   ip->check = 0;
 
   /* BSD needs the source address here, Linux & others do not... */
@@ -295,22 +348,71 @@
 #endif
   }
 
-  icmp = (struct ICMPHeader *)(packet + iphsize);
-  icmp->type     = echotype;
-  icmp->code     = 0;
-  icmp->checksum = 0;
-  icmp->id       = getpid();
-  icmp->sequence = new_sequence(index);
-  icmp->checksum = checksum(icmp, abs(packetsize) - iphsize);
+  switch ( mtrtype ) {
+  case IPPROTO_ICMP:
+    icmp = (struct ICMPHeader *)(packet + iphsize);
+    icmp->type     = echotype;
+    icmp->code     = 0;
+    icmp->checksum = 0;
+    icmp->id       = getpid();
+    icmp->sequence = new_sequence(index);
+    icmp->checksum = checksum(icmp, abs(packetsize) - iphsize);
+    
+    gettimeofday(&sequence[icmp->sequence].time, NULL);
+    break;
+
+  case IPPROTO_UDP:
+    udp = (struct UDPHeader *)(packet + iphsize);
+    udphsize = sizeof (struct UDPHeader);
+    udp->checksum  = 0;
+    mypid = (uint16)getpid();
+    if (mypid < MinPort)
+      mypid += MinPort;
+
+    udp->srcport = htons(mypid);
+    udp->length = abs(packetsize) - iphsize;
+    if(!BSDfix)
+      udp->length = htons(udp->length);
+ 
+    udp->dstport = new_sequence(index);
+    gettimeofday(&sequence[udp->dstport].time, NULL);
+    udp->dstport = htons(udp->dstport);
+    break;
+  }
 
   switch ( af ) {
   case AF_INET:
+    switch ( mtrtype ) {
+    case IPPROTO_UDP:
+      /* checksum is not mandatory. only calculate if we know ip->saddr */
+      if (ip->saddr) {
+        udpp = (struct UDPv4PHeader *)(malloc(sizeof(struct UDPv4PHeader)));
+        udpp->saddr = ip->saddr;
+        udpp->daddr = ip->daddr;
+        udpp->protocol = ip->protocol;
+        udpp->len = udp->length;
+        udp->checksum = udp_checksum(udpp, udp, sizeof(struct UDPv4PHeader), abs(packetsize) - iphsize);
+      }
+      break;
+    }
+
     ip->check = checksum(packet, abs(packetsize));
     break;
+#ifdef ENABLE_IPV6
+  case AF_INET6:
+    switch ( mtrtype ) {
+    case IPPROTO_UDP:
+      /* kernel checksum calculation */
+      if ( setsockopt(sendsock, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)) ) {
+        perror( "setsockopt IPV6_CHECKSUM" );
+        exit( EXIT_FAILURE);
+      }
+      break;
+    }
+    break;
+#endif
   }
 
-  gettimeofday(&sequence[icmp->sequence].time, NULL);
-
   rv = sendto(sendsock, packet, abs(packetsize), 0, 
 	      remotesockaddr, salen);
   if (first && (rv < 0) && ((errno == EINVAL) || (errno == EMSGSIZE))) {
@@ -450,9 +552,11 @@
   socklen_t fromsockaddrsize;
   int num;
   struct ICMPHeader *header = NULL;
+  struct UDPHeader *udpheader = NULL;
   struct timeval now;
   ip_t * fromaddress = NULL;
-  int echoreplytype = 0, timeexceededtype = 0;
+  int echoreplytype = 0, timeexceededtype = 0, unreachabletype = 0;
+  int sequence = 0;
 
   gettimeofday(&now, NULL);
   switch ( af ) {
@@ -461,6 +565,7 @@
     fromaddress = (ip_t *) &(fsa4->sin_addr);
     echoreplytype = ICMP_ECHOREPLY;
     timeexceededtype = ICMP_TIME_EXCEEDED;
+    unreachabletype = ICMP_UNREACHABLE;
     break;
 #ifdef ENABLE_IPV6
   case AF_INET6:
@@ -468,6 +573,7 @@
     fromaddress = (ip_t *) &(fsa6->sin6_addr);
     echoreplytype = ICMP6_ECHO_REPLY;
     timeexceededtype = ICMP6_TIME_EXCEEDED;
+    unreachabletype = ICMP6_DST_UNREACH;
     break;
 #endif
   }
@@ -490,41 +596,78 @@
     break;
 #endif
   }
-  if (header->type == echoreplytype) {
-    if(header->id != (uint16)getpid())
-      return;
 
-    net_process_ping (header->sequence, (void *) fromaddress, now);
-  } else if (header->type == timeexceededtype) {
-    switch ( af ) {
-    case AF_INET:
-
-      if ((size_t) num < sizeof(struct IPHeader) + 
-                         sizeof(struct ICMPHeader) + 
-                         sizeof (struct IPHeader) + 
-                         sizeof (struct ICMPHeader))
+  switch ( mtrtype ) {
+  case IPPROTO_ICMP:
+    if (header->type == echoreplytype) {
+      if(header->id != (uint16)getpid())
         return;
-      header = (struct ICMPHeader *)(packet + sizeof (struct IPHeader) + 
-                                              sizeof (struct ICMPHeader) + 
-                                              sizeof (struct IPHeader));
-    break;
+
+      sequence = header->sequence;
+    } else if (header->type == timeexceededtype) {
+      switch ( af ) {
+      case AF_INET:
+
+        if ((size_t) num < sizeof(struct IPHeader) + 
+                           sizeof(struct ICMPHeader) + 
+                           sizeof (struct IPHeader) + 
+                           sizeof (struct ICMPHeader))
+          return;
+        header = (struct ICMPHeader *)(packet + sizeof (struct IPHeader) + 
+                                                sizeof (struct ICMPHeader) + 
+                                                sizeof (struct IPHeader));
+      break;
 #ifdef ENABLE_IPV6
-    case AF_INET6:
-      if ( num < sizeof (struct ICMPHeader) + 
-                 sizeof (struct ip6_hdr) + sizeof (struct ICMPHeader) )
+      case AF_INET6:
+        if ( num < sizeof (struct ICMPHeader) + 
+                   sizeof (struct ip6_hdr) + sizeof (struct ICMPHeader) )
+          return;
+        header = (struct ICMPHeader *) ( packet + 
+                                         sizeof (struct ICMPHeader) +
+                                         sizeof (struct ip6_hdr) );
+        break;
+#endif
+      }
+  
+      if (header->id != (uint16)getpid())
         return;
-      header = (struct ICMPHeader *) ( packet + 
-                                       sizeof (struct ICMPHeader) +
-                                       sizeof (struct ip6_hdr) );
+  
+      sequence = header->sequence;
+    }
+    break;
+  
+  case IPPROTO_UDP:
+    if (header->type == timeexceededtype || header->type == unreachabletype) {
+      switch ( af ) {
+      case AF_INET:
+
+        if ((size_t) num < sizeof(struct IPHeader) +
+                           sizeof(struct ICMPHeader) +
+                           sizeof (struct IPHeader) +
+                           sizeof (struct UDPHeader))
+          return;
+        udpheader = (struct UDPHeader *)(packet + sizeof (struct IPHeader) +
+                                                  sizeof (struct ICMPHeader) +
+                                                  sizeof (struct IPHeader));
       break;
+#ifdef ENABLE_IPV6
+      case AF_INET6:
+        if ( num < sizeof (struct ICMPHeader) +
+                   sizeof (struct ip6_hdr) + sizeof (struct UDPHeader) )
+          return;
+        udpheader = (struct UDPHeader *) ( packet +
+                                           sizeof (struct ICMPHeader) +
+                                           sizeof (struct ip6_hdr) );
+        break;
 #endif
+      }
+      sequence = ntohs(udpheader->dstport);
     }
-
-    if (header->id != (uint16)getpid())
-      return;
-
-    net_process_ping(header->sequence, (void *)fromaddress, now);
+    break;
   }
+
+  if (sequence)
+    net_process_ping(sequence, (void *)fromaddress, now);
 }
 
 
@@ -758,14 +901,16 @@
   int trueopt = 1;
 
 #if !defined(IP_HDRINCL) && defined(IP_TOS) && defined(IP_TTL)
-  sendsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+  sendsock4_icmp = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+  sendsock4_udp = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
 #else
   sendsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
 #endif
   if (sendsock4 < 0) 
     return -1;
 #ifdef ENABLE_IPV6
-  sendsock6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+  sendsock6_icmp = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+  sendsock6_udp = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP);
 #endif
 
 #ifdef IP_HDRINCL
@@ -787,7 +932,38 @@
   return 0;
 }
 
- 
+
+int net_selectsocket(void)
+{
+#if !defined(IP_HDRINCL) && defined(IP_TOS) && defined(IP_TTL)
+  switch ( mtrtype ) {
+  case IPPROTO_ICMP:
+    sendsock4 = sendsock4_icmp;
+    break;
+  case IPPROTO_UDP:
+    sendsock4 = sendsock4_udp;
+    break;
+  }
+#endif
+  if (sendsock4 < 0)
+    return -1;
+#ifdef ENABLE_IPV6
+  switch ( mtrtype ) {
+  case IPPROTO_ICMP:
+    sendsock6 = sendsock6_icmp;
+    break;
+  case IPPROTO_UDP:
+    sendsock6 = sendsock6_udp;
+    break;
+  }
+  if (sendsock6 < 0)
+    return -1;
+#endif
+
+ return 0;
+}
+
+
 int net_open(struct hostent * host) 
 {
 #ifdef ENABLE_IPV6
@@ -946,9 +1122,15 @@
 
 void net_close(void)
 {
-  if (sendsock4 >= 0) close(sendsock4);
+  if (sendsock4 >= 0) {
+    close(sendsock4_icmp);
+    close(sendsock4_udp);
+  }
   if (recvsock4 >= 0) close(recvsock4);
-  if (sendsock6 >= 0) close(sendsock6);
+  if (sendsock6 >= 0) {
+    close(sendsock6_icmp);
+    close(sendsock6_udp);
+  }
   if (recvsock6 >= 0) close(recvsock6);
 }
 
diff -x .deps -x autom4te.cache -ur mtr-0.73/net.h mtr-0.74/net.h
--- mtr-0.73/net.h	2006-03-23 06:59:27.000000000 +0100
+++ mtr-0.74/net.h	2008-08-19 18:55:48.000000000 +0200
@@ -28,6 +28,7 @@
 #endif
 
 int net_preopen(void);
+int net_selectsocket(void);
 int net_open(struct hostent *host);
 void net_reopen(struct hostent *address);
 int net_set_interfaceaddress (char *InterfaceAddress); 
@@ -80,10 +81,12 @@
 
 #define MAXPATH 8
 #define MaxHost 256
+#define MinSequence 33000
 #define MaxSequence 65536
+#define MinPort 1024
 
-#define MAXPACKET 4470		/* largest test ICMP packet size */
-#define MINPACKET 28		/* 20 bytes IP header and 8 bytes ICMP */
+#define MAXPACKET 4470		/* largest test packet size */
+#define MINPACKET 28		/* 20 bytes IP header and 8 bytes ICMP or UDP */
 
 /* stuff used by display such as report, curses... --Min */
 #define MAXFLD 20		/* max stats fields to display */
Only in mtr-0.73: net.o
diff -x .deps -x autom4te.cache -ur mtr-0.73/NEWS mtr-0.74/NEWS
--- mtr-0.73/NEWS	2006-09-30 10:27:29.000000000 +0200
+++ mtr-0.74/NEWS	2008-08-19 19:59:25.000000000 +0200
@@ -1,4 +1,16 @@
 WHAT'S NEW?
+  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. 
+        added documentation for the Mac OS X compilation problem.
+        added -Wno-pointer-sign to the compiler options. 
+        Nico Lichtmaier's cleanup-gtk patch. (now mtr uses a more modern
+        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. 
   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. 
Only in mtr-0.73: raw.o
diff -x .deps -x autom4te.cache -ur mtr-0.73/README mtr-0.74/README
--- mtr-0.73/README	2004-08-26 09:56:53.000000000 +0200
+++ mtr-0.74/README	2008-08-19 20:07:45.000000000 +0200
@@ -32,14 +32,10 @@
   Note that mtr must be suid-root because it requires access to raw IP 
   sockets.  See SECURITY for security information.
 
-  If you want to build a version that doesn't use GTK, but if you
-  DO have GTK installed, you can use 
-
-	./configure --with-gtk-prefix=/we_dont_want_gtk_so_we_use_a_name_that_certainly_doesnt_exist
-
-  It seems the --no_gtk (whatever) doesn't work. Feel free to submit 
-  a patch for this, I'm not that familiar with autoconf (it works for
-  me :-). 
+  Older versions used to require a non-existant path to GTK for a
+  correct build of a non-gtk version while GTK was installed. This is
+  no longer neccesary. ./configure --WITHOUT_GTK should now work. 
+  If it doesn't, try "make WITHOUT_X11=YES" as the make step. 
 
   On Solaris (and possibly other systems) the "gtk" library may be
   installed in a directory where the dynamic linker refuses to look when
@@ -59,6 +55,11 @@
   doing the linking into a terminal window, and add "-lcurses" by hand. 
   Then it will link. Help on how to catch this in autoconf appreciated.
 
+  On Mac OS X the nameserver8_compat.h needs to be included. I put the 
+  include inside an "#if 0" section in the file "dns.c". If someone 
+  knows how to make this automatic using autoconf / the configure script, 
+  please tell me.... 
+
 
 WHERE CAN I GET THE LATEST VERSION OR MORE INFORMATION?
 
@@ -67,16 +68,20 @@
 
   Subscribe to the mtr mailing list.  All mtr related announcements
   are posted to the mtr mailing list.  To subscribe, send email to
-  'majordomo@lists.xmission.com' with 'subscribe mtr' in the body of
-  the message.  To send a message to the mailing list, mail to 
-  'mtr@lists.xmission.com'.
-
-  Bug reports and feature requests should be submitted into the 
-  jitterbug bug-tracking system at http://www.BitWizard.nl/cgi-bin/mtr .
-  If you don't have web-access, mail the mailinglist. 
+  the 'mtr-subscribe' with the hostname part set to 'BitWizard.nl'.
+  The body or subject of the message doesn't matter. To send an
+  Email to the list, mail to the username part set to 'mtr'. To
+  prevent SPAM to this list, please don't put the full name on 
+  the internet. 
+
+  Bug reports and feature requests should be submitted the mailing
+  list.
 
   Patches can be submitted by Email to me, or submitted to the 
-  bug tracking system. Please use unified diffs. 
+  mailing list. Please use unified diffs. Usually the diff is sort of
+  messy, so please check that the diff is clean and doesn't contain too
+  much of your local stuff (for example, I don't want/need the "configure"
+  script that /your/ automake made for you). 
 
 -- REW
 
Only in mtr-0.73: report.o
Only in mtr-0.73: select.o
Only in mtr-0.73: split.o
Only in mtr-0.73: stamp-h1
