commit-inetutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Inetutils branch, master, updated. inetutils-1_9_1-93-g3fe343


From: Mats Erik Andersson
Subject: [SCM] GNU Inetutils branch, master, updated. inetutils-1_9_1-93-g3fe3430
Date: Mon, 14 May 2012 17:04:18 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Inetutils ".

The branch, master has been updated
       via  3fe34309295537e0c494b591d800f272985d2129 (commit)
      from  d5298c7cf092f160f135d206dece09040e2c2410 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=3fe34309295537e0c494b591d800f272985d2129


commit 3fe34309295537e0c494b591d800f272985d2129
Author: Mats Erik Andersson <address@hidden>
Date:   Mon May 14 18:46:23 2012 +0200

    traceroute: Handle unreachable destinations.

diff --git a/ChangeLog b/ChangeLog
index f2562e9..f73a5eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2012-05-14  Mats Erik Andersson  <address@hidden>
+
+       traceroute: Stop at unreachable destinations.
+
+       * src/traceroute.c (unreach_sign): New variable.
+       (do_try): New local variables RC, TYPE, and CODE.  Let negative
+       return status from trace_read() be abnormal.  Print additional
+       packet failure information for ICMP_DEST_UNREACH.
+       (CAPTURE_LEN): New macro.
+       (trace_read): Set new signature to `(trace_t *, int *, int *)'.
+       Change size of DATA to CAPTURE_LEN.  New variable RC.  Capture
+       type and code of incoming ICMP message.
+       <TRACE_UDP>: Inspect all ICMP_DEST_UNREACH packets.  Calculate
+       port number using length offset in IP header.  Set `stop' for
+       all kinds of ICMP_DEST_UNREACH, and set positive return code,
+       except for ICMP_PORT_UNREACH.
+       <TRACE_ICMP>: Inspect also ICMP_DEST_UNREACH packets.  Check
+       their identity only, not seqno.  Set `stop' also for these,
+       and have them return positive status.  Calculate OLD_ICMP
+       using length offset in IP header.
+
+       * ping/ping_echo.c (ping_echo): Size of RSPACE is MAX_IPOPTLEN.
+
 2012-05-12  Mats Erik Andersson  <address@hidden>
 
        ping: Support IP option Timestamp.
@@ -14,7 +37,7 @@
        New setup case.
        (print_ip_opt): New variable K.
        <IPOPT_TS>: New printout case.
-       * ping/ping_impl.h [!USE_IPV6] (suboptions): New external.
+       * ping/ping_impl.h (suboptions) [!USE_IPV6]: New external.
 
 2012-05-11  Mats Erik Andersson  <address@hidden>
 
diff --git a/ping/ping_echo.c b/ping/ping_echo.c
index 9eac495..cd3cdf1 100644
--- a/ping/ping_echo.c
+++ b/ping/ping_echo.c
@@ -67,7 +67,7 @@ int
 ping_echo (char *hostname)
 {
 #ifdef IP_OPTIONS
-  char rspace[3 + 4 * NROUTES + 1];    /* record route space */
+  char rspace[MAX_IPOPTLEN];   /* Maximal IP option space.  */
 #endif
   struct ping_stat ping_stat;
   int status;
diff --git a/src/traceroute.c b/src/traceroute.c
index cc9abb5..1c98d7c 100644
--- a/src/traceroute.c
+++ b/src/traceroute.c
@@ -30,7 +30,7 @@
 #include <netinet/in.h>
 #include <netinet/ip.h>
 /* #include <netinet/ip_icmp.h> -- Deliberately not including this
-   since the definitions are are using are pulled in by libicmp. */
+   since the definitions in use are being pulled in by libicmp. */
 
 #include <arpa/inet.h>
 #include <netdb.h>
@@ -75,7 +75,7 @@ void trace_init (trace_t * t, const struct sockaddr_in to,
 void trace_inc_ttl (trace_t * t);
 void trace_inc_port (trace_t * t);
 void trace_port (trace_t * t, const unsigned short port);
-int trace_read (trace_t * t);
+int trace_read (trace_t * t, int * type, int * code);
 int trace_write (trace_t * t);
 int trace_udp_sock (trace_t * t);
 int trace_icmp_sock (trace_t * t);
@@ -94,6 +94,11 @@ static char *hostname = NULL;
 char addrstr[INET6_ADDRSTRLEN];
 struct sockaddr_in dest;
 
+/* Cause for destination unreachable reply,
+ * encoded as a single character.
+ */
+const char unreach_sign[NR_ICMP_UNREACH + 2] = "NHPPFS**U**TTXXX";
+
 static enum trace_type opt_type = TRACE_ICMP;
 int opt_port = 33434;
 int opt_max_hops = 64;
@@ -295,10 +300,14 @@ do_try (trace_t * trace, const int hop,
        {
          if (FD_ISSET (fd, &readset))
            {
+             int rc, type, code;
+
              triptime = ((double) now.tv_sec) * 1000.0 +
                ((double) now.tv_usec) / 1000.0;
 
-             if (trace_read (trace))
+             rc = trace_read (trace, &type, &code);
+
+             if (rc < 0)
                {
                  /* FIXME: printf ("Some error ocurred\n"); */
                  tries--;
@@ -316,6 +325,10 @@ do_try (trace_t * trace, const int hop,
                    }
                  printf (" %.3fms ", triptime);
 
+                 /* Additional messages.  */
+                 if (rc > 0 && type == ICMP_DEST_UNREACH)
+                   printf ("!%c ", unreach_sign[code & 0x0f]);
+
                }
              prev_addr = trace->from.sin_addr.s_addr;
            }
@@ -398,11 +411,20 @@ trace_port (trace_t * t, const unsigned short int port)
     t->to.sin_port = port;
 }
 
+/* Returned packet may contain, according to specifications:
+ *
+ *   IP-header + IP-options            (new IP-header)
+ *     + ICMP-header + old-IP-header   (ICMP message)
+ *     + old-IP-options + old-ICMP-header
+ */
+
+#define CAPTURE_LEN (MAXIPLEN + MAXICMPLEN)
+
 int
-trace_read (trace_t * t)
+trace_read (trace_t * t, int * type, int * code)
 {
-  int len;
-  unsigned char data[56];              /* For a TIME_EXCEEDED datagram. */
+  int len, rc = 0;
+  unsigned char data[CAPTURE_LEN];
   struct ip *ip;
   icmphdr_t *ic;
   socklen_t siz;
@@ -418,56 +440,77 @@ trace_read (trace_t * t)
 
   icmp_generic_decode (data, sizeof (data), &ip, &ic);
 
+  /* Pass type and code of incoming packet.  */
+  *type = ic->icmp_type;
+  *code = ic->icmp_code;
+
   switch (t->type)
     {
     case TRACE_UDP:
       {
        unsigned short *port;
        if ((ic->icmp_type != ICMP_TIME_EXCEEDED
-            && ic->icmp_type != ICMP_DEST_UNREACH)
-           || (ic->icmp_type == ICMP_DEST_UNREACH
-               && ic->icmp_code != ICMP_PORT_UNREACH))
+            && ic->icmp_type != ICMP_DEST_UNREACH))
          return -1;
 
        /* check whether it's for us */
         port = (unsigned short *) ((void *) &ic->icmp_ip +
-                       sizeof (struct ip) + sizeof (in_port_t));
+                       (ic->icmp_ip.ip_hl << 2) + sizeof (in_port_t));
        if (*port != t->to.sin_port)    /* Network byte order!  */
          return -1;
 
-       if (ic->icmp_code == ICMP_PORT_UNREACH)
+       if (ic->icmp_type == ICMP_DEST_UNREACH)
          /* FIXME: Ugly hack. */
          stop = 1;
+
+       /* Only ICMP_PORT_UNREACH is an expected reply,
+        * all other denials produce additional information.
+        */
+       if (ic->icmp_type == ICMP_DEST_UNREACH
+           && ic->icmp_code != ICMP_PORT_UNREACH)
+         rc = 1;
       }
       break;
 
     case TRACE_ICMP:
-      if (ic->icmp_type != ICMP_TIME_EXCEEDED
-         && ic->icmp_type != ICMP_ECHOREPLY)
+      if (! (ic->icmp_type == ICMP_TIME_EXCEEDED
+            || ic->icmp_type == ICMP_ECHOREPLY
+            || ic->icmp_type == ICMP_DEST_UNREACH) )
        return -1;
 
       if (ic->icmp_type == ICMP_ECHOREPLY
          && (ntohs (ic->icmp_seq) != seqno
              || ntohs (ic->icmp_id) != pid))
        return -1;
-      else if (ic->icmp_type == ICMP_TIME_EXCEEDED)
+
+      if (ic->icmp_type == ICMP_TIME_EXCEEDED
+         || ic->icmp_type == ICMP_DEST_UNREACH)
        {
          unsigned short seq, ident;
          struct ip *old_ip;
          icmphdr_t *old_icmp;
 
          old_ip = (struct ip *) &ic->icmp_ip;
-         old_icmp = (icmphdr_t *) ((void *) old_ip + sizeof (struct ip));
+         old_icmp = (icmphdr_t *) ((void *) old_ip + (old_ip->ip_hl <<2));
          seq = ntohs (old_icmp->icmp_seq);
          ident = ntohs (old_icmp->icmp_id);
 
-         if (seq != seqno || ident != pid)
+         /* An expired packet tests identity and sequence number,
+          * whereas an undeliverable packet only checks identity.
+          */
+         if (ident != pid
+             || (ic->icmp_type == ICMP_TIME_EXCEEDED
+                 && seq != seqno))
            return -1;
        }
 
-      if (ip->ip_src.s_addr == dest.sin_addr.s_addr)
+      if (ip->ip_src.s_addr == dest.sin_addr.s_addr
+         || ic->icmp_type == ICMP_DEST_UNREACH)
        /* FIXME: Ugly hack. */
        stop = 1;
+
+      if (ic->icmp_type == ICMP_DEST_UNREACH)
+       rc = 1;
       break;
 
       /* FIXME: Type according to RFC 1393. */
@@ -476,7 +519,7 @@ trace_read (trace_t * t)
       break;
     }
 
-  return 0;
+  return rc;
 }
 
 int

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog        |   25 ++++++++++++++++-
 ping/ping_echo.c |    2 +-
 src/traceroute.c |   79 +++++++++++++++++++++++++++++++++++++++++------------
 3 files changed, 86 insertions(+), 20 deletions(-)


hooks/post-receive
-- 
GNU Inetutils 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]