Add some additional sanity checking.
[obnox/wireshark/wip.git] / packet-ip.c
index 46f59b944ae88917a1d7e43e8d6d64eb9db56d61..f43f977a28a354ef7c5d8731c8a57ceb65ec2c83 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-ip.c
  * Routines for IP and miscellaneous IP protocol packet disassembly
  *
- * $Id: packet-ip.c,v 1.190 2003/04/20 11:36:13 guy Exp $
+ * $Id: packet-ip.c,v 1.201 2003/11/13 08:16:52 sahlberg Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -37,6 +37,7 @@
 #include <epan/packet.h>
 #include <epan/resolv.h>
 #include "ipproto.h"
+#include "ip_opts.h"
 #include "prefs.h"
 #include "reassemble.h"
 #include "etypes.h"
@@ -124,8 +125,7 @@ static const fragment_items ip_frag_items = {
        "fragments"
 };
 
-/* Used by IPv6 as well, so not static */
-dissector_table_t ip_dissector_table;
+static dissector_table_t ip_dissector_table;
 
 static dissector_handle_t ip_handle;
 static dissector_handle_t data_handle;
@@ -135,6 +135,11 @@ static int hf_icmp_type = -1;
 static int hf_icmp_code = -1;
 static int hf_icmp_checksum = -1;
 static int hf_icmp_checksum_bad = -1;
+static int hf_icmp_ident = -1;
+static int hf_icmp_seq_num = -1;
+static int hf_icmp_mtu = -1;
+static int hf_icmp_redir_gw = -1;
+
 
 /* Mobile ip */
 static int hf_icmp_mip_type = -1;
@@ -798,11 +803,6 @@ static const true_false_string tos_set_high = {
   "Normal"
 };
 
-static const true_false_string flags_set_truth = {
-  "Set",
-  "Not set"
-};
-
 static guint16 ip_checksum(const guint8 *ptr, int len)
 {
        vec_t cksum_vec[1];
@@ -817,6 +817,7 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
   proto_tree *ip_tree = NULL, *field_tree;
   proto_item *ti = NULL, *tf;
+  guint32    addr;
   int        offset = 0;
   guint      hlen, optlen;
   guint16    flags;
@@ -835,7 +836,6 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
      eip_current=0;
   }
   iph=&eip_arr[eip_current];
-  pinfo->private_data=iph;
 
   if (check_col(pinfo->cinfo, COL_PROTOCOL))
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "IP");
@@ -971,24 +971,31 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
       proto_tree_add_uint(ip_tree, hf_ip_checksum, tvb, offset + 10, 2, iph->ip_sum);
   }
 
-  tvb_memcpy(tvb, (guint8 *)&iph->ip_src, offset + 12, 4);
+  SET_ADDRESS(&pinfo->net_src, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_SRC, 4));
+  SET_ADDRESS(&pinfo->src, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_SRC, 4));
+  SET_ADDRESS(&iph->ip_src, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_SRC, 4));
   if (tree) {
+    memcpy(&addr, iph->ip_src.data, 4);
     if (ip_summary_in_tree) {
       proto_item_append_text(ti, ", Src Addr: %s (%s)",
-               get_hostname(iph->ip_src), ip_to_str((guint8 *) &iph->ip_src));
+               get_hostname(addr), ip_to_str((guint8 *) iph->ip_src.data));
     }
-    proto_tree_add_ipv4(ip_tree, hf_ip_src, tvb, offset + 12, 4, iph->ip_src);
-    proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, tvb, offset + 12, 4, iph->ip_src);
+    proto_tree_add_ipv4(ip_tree, hf_ip_src, tvb, offset + 12, 4, addr);
+    proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, tvb, offset + 12, 4, addr);
   }
 
-  tvb_memcpy(tvb, (guint8 *)&iph->ip_dst, offset + 16, 4);
+  SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_DST, 4));
+  SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_DST, 4));
+  SET_ADDRESS(&iph->ip_dst, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_DST, 4));
+
   if (tree) {
+    memcpy(&addr, iph->ip_dst.data, 4);
     if (ip_summary_in_tree) {
       proto_item_append_text(ti, ", Dst Addr: %s (%s)",
-               get_hostname(iph->ip_dst), ip_to_str((guint8 *) &iph->ip_dst));
+               get_hostname(addr), ip_to_str((guint8 *) iph->ip_dst.data));
     }
-    proto_tree_add_ipv4(ip_tree, hf_ip_dst, tvb, offset + 16, 4, iph->ip_dst);
-    proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, tvb, offset + 16, 4, iph->ip_dst);
+    proto_tree_add_ipv4(ip_tree, hf_ip_dst, tvb, offset + 16, 4, addr);
+    proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, tvb, offset + 16, 4, addr);
   }
 
   if (tree) {
@@ -1011,11 +1018,6 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
   pinfo->iphdrlen = hlen;
 
-  SET_ADDRESS(&pinfo->net_src, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_SRC, 4));
-  SET_ADDRESS(&pinfo->src, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_SRC, 4));
-  SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_DST, 4));
-  SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_DST, 4));
-
   /* Skip over header + options */
   offset += hlen;
   nxt = iph->ip_p;     /* XXX - what if this isn't the same for all fragments? */
@@ -1035,13 +1037,8 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                             pinfo->iplen - pinfo->iphdrlen,
                             iph->ip_off & IP_MF);
 
-    if (ipfd_head != NULL) {
-      next_tvb = process_reassembled_data(tvb, pinfo, "Reassembled IPv4",
-        ipfd_head, &ip_frag_items, &update_col_info, ip_tree);
-    } else {
-      /* We don't have the complete reassembled payload. */
-      next_tvb = NULL;
-    }
+    next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled IPv4",
+      ipfd_head, &ip_frag_items, &update_col_info, ip_tree);
   } else {
     /* If this is the first fragment, dissect its contents, otherwise
        just show it as a fragment.
@@ -1076,7 +1073,7 @@ dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     }
     if( ipfd_head && ipfd_head->reassembled_in != pinfo->fd->num ){
       if (check_col(pinfo->cinfo, COL_INFO)) {
-        col_append_fstr(pinfo->cinfo, COL_INFO, " [Reassembled in #%d]",
+        col_append_fstr(pinfo->cinfo, COL_INFO, " [Reassembled in #%u]",
           ipfd_head->reassembled_in);
       }
     }
@@ -1284,8 +1281,8 @@ static const gchar *redir_str[] = {"Redirect for network",
 
 #define        N_REDIRECT      (sizeof redir_str / sizeof redir_str[0])
 
-static const gchar *ttl_str[] = {"TTL equals 0 during transit",
-                                 "TTL equals 0 during reassembly"};
+static const gchar *ttl_str[] = {"Time to live exceeded in transit",
+                                 "Fragment reassembly time exceeded"};
 
 #define        N_TIMXCEED      (sizeof ttl_str / sizeof ttl_str[0])
 
@@ -1452,17 +1449,14 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
       case ICMP_IREQREPLY:
       case ICMP_MASKREQ:
       case ICMP_MASKREPLY:
-       proto_tree_add_text(icmp_tree, tvb, 4, 2, "Identifier: 0x%04x",
-         tvb_get_ntohs(tvb, 4));
-       proto_tree_add_text(icmp_tree, tvb, 6, 2, "Sequence number: %02x:%02x",
-         tvb_get_guint8(tvb, 6), tvb_get_guint8(tvb, 7));
+        proto_tree_add_item(icmp_tree, hf_icmp_ident, tvb, 4, 2, FALSE);
+        proto_tree_add_item(icmp_tree, hf_icmp_seq_num, tvb, 6, 2, FALSE);
        break;
 
       case ICMP_UNREACH:
         switch (icmp_code) {
           case ICMP_FRAG_NEEDED:
-            proto_tree_add_text(icmp_tree, tvb, 6, 2, "MTU of next hop: %u",
-                  tvb_get_ntohs(tvb, 6));
+            proto_tree_add_item(icmp_tree, hf_icmp_mtu, tvb, 6, 2, FALSE);
             break;
        }
         break;
@@ -1484,8 +1478,7 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        break;
 
       case ICMP_REDIRECT:
-       proto_tree_add_text(icmp_tree, tvb, 4, 4, "Gateway address: %s",
-         ip_to_str(tvb_get_ptr(tvb, 4, 4)));
+        proto_tree_add_item(icmp_tree, hf_icmp_redir_gw, tvb, 4, 4, FALSE);
        break;
     }
 
@@ -1785,6 +1778,22 @@ proto_register_icmp(void)
       { "Bad Checksum",        "icmp.checksum_bad",    FT_BOOLEAN, BASE_NONE,  NULL, 0x0,
        "", HFILL }},
 
+    { &hf_icmp_ident,
+      {"Identifier", "icmp.ident",              FT_UINT16, BASE_HEX,    NULL, 0x0,
+       "", HFILL }},
+
+    { &hf_icmp_seq_num,
+      {"Sequence number", "icmp.seq",           FT_UINT16, BASE_HEX,    NULL, 0x0,
+       "", HFILL }},
+
+    { &hf_icmp_mtu,
+      {"MTU of next hop", "icmp.mtu",           FT_UINT16, BASE_DEC,    NULL, 0x0,
+       "", HFILL}},
+
+    { &hf_icmp_redir_gw,
+      {"Gateway address", "icmp.redir_gw",      FT_IPv4, BASE_NONE,     NULL, 0x0,
+       "", HFILL }},
+
     { &hf_icmp_mip_type,
       { "Extension Type", "icmp.mip.type",     FT_UINT8, BASE_DEC,
        VALS(mip_extensions), 0x0,"", HFILL}},