diff -ur mtr-0.72-orig/ChangeLog mtr-0.72/ChangeLog
--- mtr-0.72-orig/ChangeLog	2004-08-26 03:56:53.000000000 -0400
+++ mtr-0.72/ChangeLog	2008-05-10 21:35:36.000000000 -0400
@@ -1,3 +1,6 @@
+2008-05-10  Mark Kamichoff  <prox@prolixium.com>
+	* Added decoding for MPLS ICMP extensions via curses only.
+
 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-orig/curses.c mtr-0.72/curses.c
--- mtr-0.72-orig/curses.c	2006-09-29 15:40:09.000000000 -0400
+++ mtr-0.72/curses.c	2008-05-10 21:35:36.000000000 -0400
@@ -271,6 +271,8 @@
 {
   int max;
   int at;
+  struct mplslen *mpls;
+  struct mplslen *mplss;    /* MK */
   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);
+    mpls = net_mpls(at);   /* MK */
 
     if( addrcmp( (void *) addr, (void *) &unspec_addr, af ) != 0 ) {
       name = dns_lookup(addr);
@@ -293,6 +296,9 @@
 	printw("%s", name);
       } else {
 	printw("%s", strlongip( addr ) );
+      } 
+      if (mpls->inclabel) {
+     printw(" [MPLS: Label %lu Exp %u]", mpls->label, mpls->exp);    /* MK */
       }
       attroff(A_BOLD);
 
@@ -325,6 +331,7 @@
       /* Multi path by Min */
       for (i=0; i < MAXPATH; i++ ) {
         addrs = net_addrs(at, i);
+        mplss = net_mplss(at, i);    /* 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 (mpls->inclabel) {
+       printw(" [MPLS: Label %lu Exp %d]", mplss->label, mplss->exp);    /* MK */
+        }
         attroff(A_BOLD);
       }
 
diff -ur mtr-0.72-orig/net.c mtr-0.72/net.c
--- mtr-0.72-orig/net.c	2006-09-29 15:31:01.000000000 -0400
+++ mtr-0.72/net.c	2008-05-10 21:35:36.000000000 -0400
@@ -68,7 +68,7 @@
   uint32 saddr;
   uint32 daddr;
 };
-  
+
 
 #define ICMP_ECHO		8
 #define ICMP_ECHOREPLY		0
@@ -103,6 +103,8 @@
   int transit;
   int saved[SAVED_PINGS];
   int saved_seq_offset;
+  struct mplslen mpls;     /* size of ICMP reply, MK */
+  struct mplslen mplss[MAXPATH];
 };
 
 
@@ -328,7 +330,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, struct mplslen mpls, void * addr, struct timeval now) 
 {
   int index;
   int totusec;
@@ -361,10 +363,12 @@
 		(void *) &unspec_addr, af ) == 0 ) {
     // should be out of if as addr can change
     addrcpy( (void *) &(host[index].addr), addrcopy, af );
+    host[index].mpls = mpls;    /* add MPLS, MK */
     display_rawhost(index, (void *) &(host[index].addr));
 
   /* multi paths by Min */
     addrcpy( (void *) &(host[index].addrs[0]), addrcopy, af );
+    host[index].mplss[0] = mpls;    /* add MPLS, MK */
   } else {
     for( i=0; i<MAXPATH; ) {
       if( addrcmp( (void *) &(host[index].addrs[i]), (void *) &addrcopy,
@@ -376,6 +380,7 @@
     if( addrcmp( (void *) &(host[index].addrs[i]), addrcopy, af ) != 0 && 
         i<MAXPATH ) {
       addrcpy( (void *) &(host[index].addrs[i]), addrcopy, af );
+      host[index].mplss[i] = mpls;    /* add MPLS, MK */
     }
   /* end multi paths */
   }
@@ -453,6 +458,11 @@
   struct timeval now;
   ip_t * fromaddress = NULL;
   int echoreplytype = 0, timeexceededtype = 0;
+  unsigned int ext_ver, ext_res, ext_chk, obj_hdr_len;
+  u_char obj_hdr_class, obj_hdr_type;
+  struct mplslen mpls;
+
+  mpls.inclabel = 0;     /* we might not get it, MK */
 
   gettimeofday(&now, NULL);
   switch ( af ) {
@@ -494,7 +504,7 @@
     if(header->id != (uint16)getpid())
       return;
 
-    net_process_ping (header->sequence, (void *) fromaddress, now);
+    net_process_ping (header->sequence, mpls, (void *) fromaddress, now);
   } else if (header->type == timeexceededtype) {
     switch ( af ) {
     case AF_INET:
@@ -507,6 +517,31 @@
       header = (struct ICMPHeader *)(packet + sizeof (struct IPHeader) + 
                                               sizeof (struct ICMPHeader) + 
                                               sizeof (struct IPHeader));
+
+      /* mostly stolen from the NANOG-modified traceroute.c, MK */
+      mpls.len = num;
+      if(num > 160) {
+        ext_ver = packet[156]>>4;
+        ext_res = (packet[156]&15)+ packet[157];
+        ext_chk = ((unsigned int)packet[158]<<8)+packet[159];
+
+        if (ext_ver == 2 && ext_res == 0 && ext_chk != 0) {
+        /* Ok. This is an ICMP ext header. But we haven't checked
+          that the checksum is correct */ 
+          obj_hdr_len = ((int)packet[160]<<8)+packet[161];
+          obj_hdr_class = packet[162];
+          obj_hdr_type = packet[163];
+
+          if (obj_hdr_len >= 8 && obj_hdr_class == 1 && obj_hdr_type == 1) {
+            mpls.label = ((unsigned long)packet[164]<<12) +
+                ((unsigned int)packet[165]<<4) + ((packet[166]>>4) & 0xff); 
+            mpls.exp = (packet[166] >> 1) & 0x7;
+            mpls.inclabel = 1;
+          }
+
+          if (obj_hdr_len >= 12) mpls.more = 1;
+        }
+      }
     break;
 #ifdef ENABLE_IPV6
     case AF_INET6:
@@ -523,7 +558,7 @@
     if (header->id != (uint16)getpid())
       return;
 
-    net_process_ping(header->sequence, (void *)fromaddress, now);
+    net_process_ping(header->sequence, mpls, (void *)fromaddress, now);
   }
 }
 
@@ -540,6 +575,20 @@
 }
 
 
+/* return MPLS struct, MK */
+void *net_mpls(int at)
+{
+  return (struct mplslen *)&(host[at].mplss);
+}
+
+
+/* return an MPLS struct, MK */
+void *net_mplss(int at, int i)
+{
+  return (struct mplslen *)&(host[at].mplss[i]);
+}
+
+
 int net_loss(int at) 
 {
   if ((host[at].xmit - host[at].transit) == 0) 
diff -ur mtr-0.72-orig/net.h mtr-0.72/net.h
--- mtr-0.72-orig/net.h	2006-03-23 00:59:27.000000000 -0500
+++ mtr-0.72/net.h	2008-05-10 21:35:36.000000000 -0400
@@ -40,6 +40,8 @@
 int net_min(void);
 int net_last(int at);
 ip_t * net_addr(int at);
+void * net_mpls(int at);     /* MK */
+void * net_mplss(int, int);  /* MK */
 int net_loss(int at);
 int net_drop(int at);
 int net_last(int at);
@@ -117,3 +119,14 @@
 extern char available_options[];
 
 ip_t unspec_addr;
+
+
+/*  MPLS and length structure.  */
+struct mplslen {
+  uint16 len;
+  unsigned long label;
+  uint8 exp;
+  char more, inclabel;
+};
+
+
