When dissecting an ICMP datagram that contains part of an IP datagram,
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 27 Sep 2001 10:35:40 +0000 (10:35 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 27 Sep 2001 10:35:40 +0000 (10:35 +0000)
hand the (possibly-partial) IP datagram to the IP dissector, as we do
for IPv6 datagrams inside ICMPv6 and CLNP datagrams inside CLNP ER PDUs.

When dissecting IPv6 datagrams inside ICMPv6 and CLNP datagrams inside
CLNP ER PDUs, catch the ReportedLengthError exception and ignore it, as
they don't guarantee that all of the original PDU is present.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@3960 f5534014-38df-0310-8fa8-9805f1628bb7

packet-clnp.c
packet-icmpv6.c
packet-ip.c

index c5216410fe8e49b21b4c79986d81af499974e24e..b16c0971494678541e151b78a680a6a6eb853c95 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-clnp.c
  * Routines for ISO/OSI network and transport protocol packet disassembly
  *
- * $Id: packet-clnp.c,v 1.33 2001/06/18 02:17:45 guy Exp $
+ * $Id: packet-clnp.c,v 1.34 2001/09/27 10:35:40 guy Exp $
  * Laurent Deniel <deniel@worldnet.fr>
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
@@ -1593,7 +1593,7 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   address     save_src;
   address     save_dst;
   fragment_data *fd_head;
-  tvbuff_t   *next_tvb;
+  tvbuff_t   *volatile next_tvb;
   packet_info save_pi;
   gboolean must_restore_pi = FALSE;
   gboolean update_col_info = TRUE;
@@ -2022,11 +2022,20 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
           save_src = pinfo->src;
           save_dst = pinfo->dst;
 
-          /* Dissect the contained packet. */
+          /* Dissect the contained packet.
+             Catch ReportedBoundsError, and do nothing if we see it,
+             because it's not an error if the contained packet is short;
+             there's no guarantee that all of it was included. */
           ti = proto_tree_add_text(clnp_tree, tvb, offset, next_length,
             "Discarded PDU");
           discpdu_tree = proto_item_add_subtree(ti, ett_clnp_disc_pdu);
-          dissect_clnp(next_tvb, pinfo, discpdu_tree);
+          TRY {
+            dissect_clnp(next_tvb, pinfo, discpdu_tree);
+          }
+          CATCH(ReportedBoundsError) {
+            ; /* do nothing */
+          }
+          ENDTRY;
 
           /* Restore the addresses. */
           pinfo->dl_src = save_dl_src;
index 5bbc5e2b18fb55f2cbcb885f6c657946963f1473..dc5ee6acc103269b3ef591f2d77083a1f89552e3 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-icmpv6.c
  * Routines for ICMPv6 packet disassembly
  *
- * $Id: packet-icmpv6.c,v 1.51 2001/09/25 18:27:35 guy Exp $
+ * $Id: packet-icmpv6.c,v 1.52 2001/09/27 10:35:40 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -139,8 +139,17 @@ dissect_contained_icmpv6(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tr
        save_src = pinfo->src;
        save_dst = pinfo->dst;
 
-       /* Dissect the contained packet. */
-       call_dissector(ipv6_handle, next_tvb, pinfo, tree);
+       /* Dissect the contained packet.
+          Catch ReportedBoundsError, and do nothing if we see it,
+          because it's not an error if the contained packet is short;
+          there's no guarantee that all of it was included. */
+       TRY {
+           call_dissector(ipv6_handle, next_tvb, pinfo, tree);
+       }
+       CATCH(ReportedBoundsError) {
+           ; /* do nothing */
+       }
+       ENDTRY;
 
        /* Restore the addresses. */
        pinfo->dl_src = save_dl_src;
index dc36acaf10e45f90b06ff96e8c214b1d716df279..88e13f9cc655251c01fe54950bef8f2776f03505 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-ip.c
  * Routines for IP and miscellaneous IP protocol packet disassembly
  *
- * $Id: packet-ip.c,v 1.140 2001/07/20 07:11:56 guy Exp $
+ * $Id: packet-ip.c,v 1.141 2001/09/27 10:35:40 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -116,6 +116,8 @@ static gint ett_ip_fragment  = -1;
 /* Used by IPv6 as well, so not static */
 dissector_table_t ip_dissector_table;
 
+static dissector_handle_t ip_handle;
+
 static int proto_icmp = -1;
 static int hf_icmp_type = -1;
 static int hf_icmp_code = -1;
@@ -814,7 +816,12 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   iph.ip_off = ntohs(iph.ip_off);
   iph.ip_sum = ntohs(iph.ip_sum);
 
-  /* Length of IP datagram. */
+  /* Length of IP datagram.
+     XXX - what if this is greater than the reported length of the
+     tvbuff?  This could happen, for example, in an IP datagram
+     inside an ICMP datagram; we need to somehow let the
+     dissector we call know that, as it might want to avoid
+     doing its checksumming. */
   len = iph.ip_len;
 
   /* Adjust the length of this tvbuff to include only the IP datagram. */
@@ -1161,6 +1168,13 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   guint8     num_addrs = 0;
   guint8     addr_entry_size = 0;
   int        i;
+  address    save_dl_src;
+  address    save_dl_dst;
+  address    save_net_src;
+  address    save_net_dst;
+  address    save_src;
+  address    save_dst;
+  tvbuff_t   *next_tvb;
 
   if (check_col(pinfo->fd, COL_PROTOCOL))
     col_set_str(pinfo->fd, COL_PROTOCOL, "ICMP");
@@ -1338,9 +1352,42 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        /* Decode the IP header and first 64 bits of data from the
           original datagram.
 
-          XXX - for now, just display it as data; not all dissection
-          routines can handle a short packet without exploding. */
-       dissect_data(tvb, 8, pinfo, icmp_tree);
+          Set the columns non-writable, so that the packet list
+          shows this as an ICMP packet, not as the type of packet
+          for which the ICMP packet was generated. */
+       col_set_writable(pinfo->fd, FALSE);
+
+       /* Also, save the current values of the addresses, and restore
+          them when we're finished dissecting the contained packet, so
+          that the address columns in the summary don't reflect the
+          contained packet, but reflect this packet instead. */
+       save_dl_src = pinfo->dl_src;
+       save_dl_dst = pinfo->dl_dst;
+       save_net_src = pinfo->net_src;
+       save_net_dst = pinfo->net_dst;
+       save_src = pinfo->src;
+       save_dst = pinfo->dst;
+
+       /* Dissect the contained packet.
+          Catch ReportedBoundsError, and do nothing if we see it,
+          because it's not an error if the contained packet is short;
+          there's no guarantee that all of it was included. */
+       next_tvb = tvb_new_subset(tvb, 8, -1, -1);
+       TRY {
+         call_dissector(ip_handle, next_tvb, pinfo, icmp_tree);
+       }
+       CATCH(ReportedBoundsError) {
+         ; /* do nothing */
+       }
+       ENDTRY;
+
+       /* Restore the addresses. */
+       pinfo->dl_src = save_dl_src;
+       pinfo->dl_dst = save_dl_dst;
+       pinfo->net_src = save_net_src;
+       pinfo->net_dst = save_net_dst;
+       pinfo->src = save_src;
+       pinfo->dst = save_dst;
        break;
 
       case ICMP_ECHOREPLY:
@@ -1610,5 +1657,10 @@ proto_register_icmp(void)
 void
 proto_reg_handoff_icmp(void)
 {
+  /*
+   * Get handle for the IP dissector.
+   */
+  ip_handle = find_dissector("ip");
+
   dissector_add("ip.proto", IP_PROTO_ICMP, dissect_icmp, proto_icmp);
 }