diff -ur mtr-0.72/ChangeLog mtr-0.72-pmtu/ChangeLog
--- mtr-0.72/ChangeLog	2004-08-26 03:56:53.000000000 -0400
+++ mtr-0.72-pmtu/ChangeLog	2008-05-15 01:10:39.000000000 -0400
@@ -1,3 +1,7 @@
+2008-05-15  Mark Kamichoff <prox@prolixium.com>
+
+	* Added PMTU detection, and forced DF bit set.
+
 2002-03-06  Cougar <cougar@random.ee>
 	+ If hop doesn't respond, draw its name in red (GTK) or bold (curses)
 
diff -ur mtr-0.72/curses.c mtr-0.72-pmtu/curses.c
--- mtr-0.72/curses.c	2006-09-29 15:40:09.000000000 -0400
+++ mtr-0.72-pmtu/curses.c	2008-05-15 01:10:39.000000000 -0400
@@ -271,6 +271,8 @@
 {
   int max;
   int at;
+  uint16 pmtu = 0; /* path MTU, MK */
+  uint16 pmtus = 0;
   ip_t *addr, *addrs;
   int y, x;
   char *name;
@@ -284,6 +286,7 @@
   for(at = net_min () + display_offset; at < max; at++) {
     printw("%2d. ", at + 1);
     addr = net_addr(at);
+    pmtu = net_pmtu(at);
 
     if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
       name = dns_lookup(addr);
@@ -294,6 +297,9 @@
       } else {
 	printw("%s", strlongip( addr ) );
       }
+      if(pmtu) {    /* if our MTU changed, label it, MK */
+     printw(" [PMTU: %d]", pmtu);
+      }
       attroff(A_BOLD);
 
       getyx(stdscr, y, x);
@@ -325,6 +331,7 @@
       /* Multi path by Min */
       for (i=0; i < MAXPATH; i++ ) {
         addrs = net_addrs(at, i);
+        pmtus = net_pmtus(at, i);  /* path MTU, MK */
 	if ( addrcmp( (void *) addrs, (void *) addr, af ) == 0 ) continue;
 	if ( addrcmp( (void *) addrs, (void *) &unspec_addr, af ) == 0 ) break;
 
@@ -335,6 +342,9 @@
         } else {
 	  printw("\n    %s", strlongip( addrs ) );
         }
+        if(pmtus) {
+       printw(" [PMTU: %d]", pmtus);
+        }
         attroff(A_BOLD);
       }
 
diff -ur mtr-0.72/net.c mtr-0.72-pmtu/net.c
--- mtr-0.72/net.c	2006-09-29 15:31:01.000000000 -0400
+++ mtr-0.72-pmtu/net.c	2008-05-15 01:10:39.000000000 -0400
@@ -72,6 +72,8 @@
 
 #define ICMP_ECHO		8
 #define ICMP_ECHOREPLY		0
+#define ICMP_DEST_UNREACH	3
+#define ICMP_FRAG_NEEDED      4
 
 #define ICMP_TSTAMP		13
 #define ICMP_TSTAMPREPLY	14
@@ -103,6 +105,8 @@
   int transit;
   int saved[SAVED_PINGS];
   int saved_seq_offset;
+  uint16 pmtu; /* path MTU, if this hop decided to change it, MK */
+  uint16 pmtus[MAXPATH];
 };
 
 
@@ -269,7 +273,7 @@
   ip->tos = tos;
   ip->len = BSDfix ? abs(packetsize): htons (abs(packetsize));
   ip->id = 0;
-  ip->frag = 0;    /* 1, if want to find mtu size? Min */
+  ip->frag = htons(16384);    /* set DF bit */
     ip->ttl = ttl;
   ip->protocol = IPPROTO_ICMP;
   ip->check = 0;
@@ -328,7 +332,7 @@
 
 /*   We got a return on something we sent out.  Record the address and
      time.  */
-void net_process_ping(int seq, void * addr, struct timeval now) 
+void net_process_ping(int seq, void * addr, uint16 pmtu, struct timeval now) 
 {
   int index;
   int totusec;
@@ -361,10 +365,12 @@
 		(void *) &unspec_addr, af ) == 0 ) {
     // should be out of if as addr can change
     addrcpy( (void *) &(host[index].addr), addrcopy, af );
+    host[index].pmtu = pmtu;  /* add PMTU, MK */
     display_rawhost(index, (void *) &(host[index].addr));
 
   /* multi paths by Min */
     addrcpy( (void *) &(host[index].addrs[0]), addrcopy, af );
+    host[index].pmtus[0] = pmtu;  /* add PMTU, MK */
   } else {
     for( i=0; i<MAXPATH; ) {
       if( addrcmp( (void *) &(host[index].addrs[i]), (void *) &addrcopy,
@@ -376,6 +382,7 @@
     if( addrcmp( (void *) &(host[index].addrs[i]), addrcopy, af ) != 0 && 
         i<MAXPATH ) {
       addrcpy( (void *) &(host[index].addrs[i]), addrcopy, af );
+      host[index].pmtus[i] = pmtu;  /* add PMTU, MK */
     }
   /* end multi paths */
   }
@@ -452,7 +459,10 @@
   struct ICMPHeader *header = NULL;
   struct timeval now;
   ip_t * fromaddress = NULL;
-  int echoreplytype = 0, timeexceededtype = 0;
+  int echoreplytype = 0, timeexceededtype = 0, destunreachtype = 0, fragneededcode = 0;
+  int tempseq = 0;
+
+  char buf[128];
 
   gettimeofday(&now, NULL);
   switch ( af ) {
@@ -461,6 +471,9 @@
     fromaddress = (ip_t *) &(fsa4->sin_addr);
     echoreplytype = ICMP_ECHOREPLY;
     timeexceededtype = ICMP_TIME_EXCEEDED;
+    /* extra type/code, MK */
+    destunreachtype = ICMP_DEST_UNREACH;
+    fragneededcode = ICMP_FRAG_NEEDED;
     break;
 #ifdef ENABLE_IPV6
   case AF_INET6:
@@ -494,7 +507,33 @@
     if(header->id != (uint16)getpid())
       return;
 
-    net_process_ping (header->sequence, (void *) fromaddress, now);
+    net_process_ping (header->sequence, (void *) fromaddress, 0, now);
+  /* Check for a type 3 code 4 ICMP message, MK */
+  } else if (header->type == destunreachtype && header->code == fragneededcode) {
+    /* look at embedded ICMP header */
+    header = (struct ICMPHeader *)(packet + sizeof (struct IPHeader) + 
+                                            sizeof (struct ICMPHeader) + 
+                                            sizeof (struct IPHeader));
+
+    if(header->id != (uint16)getpid())
+      return;
+
+    tempseq = header->sequence;
+
+    /* switch back to outer ICMP header */
+    header = (struct ICMPHeader *)(packet + sizeof(struct IPHeader));
+
+/*    if(!strcmp(inet_ntop(af, fromaddress, buf, sizeof buf), "10.3.5.107")) {
+      return;
+    }     */
+
+    /* field for sequence in echo reply is == to MTU in type 3 code 4 */
+    if(0) {
+      fprintf(stderr, "Sweet.  Hop wants us to lower MTU to: %d\n",
+          ntohs(header->sequence));
+    }
+    cpacketsize = ntohs(header->sequence);   /* change our IP length for the next packet */
+    net_process_ping(tempseq, (void *) fromaddress, ntohs(header->sequence), now);
   } else if (header->type == timeexceededtype) {
     switch ( af ) {
     case AF_INET:
@@ -523,7 +562,7 @@
     if (header->id != (uint16)getpid())
       return;
 
-    net_process_ping(header->sequence, (void *)fromaddress, now);
+    net_process_ping(header->sequence, (void *)fromaddress, 0, now);
   }
 }
 
@@ -540,6 +579,19 @@
 }
 
 
+/* path MTU, MK */
+uint16 net_pmtu(int at)
+{
+  return host[at].pmtu;
+}
+
+
+uint16 net_pmtus(int at, int i)
+{
+  return host[at].pmtus[i];
+}
+
+
 int net_loss(int at) 
 {
   if ((host[at].xmit - host[at].transit) == 0) 
@@ -719,6 +771,7 @@
 
   /* printf ("cpacketsize = %d, packetsize = %d\n", cpacketsize, packetsize);  */
 
+  packetsize = cpacketsize;   /* XXX update packet size after every sequence, MK */
   net_send_query(batch_at);
 
   for (i=fstTTL-1;i<batch_at;i++) {
diff -ur mtr-0.72/net.h mtr-0.72-pmtu/net.h
--- mtr-0.72/net.h	2006-03-23 00:59:27.000000000 -0500
+++ mtr-0.72-pmtu/net.h	2008-05-15 01:10:39.000000000 -0400
@@ -40,6 +40,7 @@
 int net_min(void);
 int net_last(int at);
 ip_t * net_addr(int at);
+uint16 net_pmtu(int);
 int net_loss(int at);
 int net_drop(int at);
 int net_last(int at);
@@ -53,6 +54,7 @@
 int net_javg(int at);
 int net_jinta(int at);
 ip_t * net_addrs(int at, int i);
+uint16 net_pmtus(int, int);
 char *net_localaddr(void); 
 
 int net_send_batch(void);
