Squelch some compiler warnings.
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 11 Mar 2010 00:36:45 +0000 (00:36 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 11 Mar 2010 00:36:45 +0000 (00:36 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@32165 f5534014-38df-0310-8fa8-9805f1628bb7

12 files changed:
disabled_protos.c
docbook/README.txt
epan/dissectors/packet-6lowpan.c
epan/dissectors/packet-bootp.c
epan/dissectors/packet-gsm_a_gm.c
epan/dissectors/packet-ieee802154.c
gtk/scsi_stat.c
print.c
ringbuffer.c
tap-diameter-avp.c
tempfile.c
util.c

index 701ac21ad058075515bc9d685c308f3e7a9b81de..fc6bfc2bc25c270fd9ed345fd8441ebbf25b84f8 100644 (file)
@@ -176,7 +176,7 @@ read_disabled_protos_list_file(const char *ff_path, FILE *ff,
 
   /* Allocate the protocol name buffer. */
   prot_name_len = INIT_BUF_SIZE;
-  prot_name = g_malloc(prot_name_len + 1);
+  prot_name = (char *)g_malloc(prot_name_len + 1);
 
   for (line = 1; ; line++) {
     /* Lines in a disabled protocol file contain the "filter name" of
@@ -212,7 +212,7 @@ read_disabled_protos_list_file(const char *ff_path, FILE *ff,
       if (prot_name_index >= prot_name_len) {
        /* protocol name buffer isn't long enough; double its length. */
        prot_name_len *= 2;
-       prot_name = g_realloc(prot_name, prot_name_len + 1);
+       prot_name = (char *)g_realloc(prot_name, prot_name_len + 1);
       }
       prot_name[prot_name_index] = c;
       prot_name_index++;
@@ -250,7 +250,7 @@ read_disabled_protos_list_file(const char *ff_path, FILE *ff,
     if (prot_name_index >= prot_name_len) {
       /* protocol name buffer isn't long enough; double its length. */
       prot_name_len *= 2;
-      prot_name = g_realloc(prot_name, prot_name_len + 1);
+      prot_name = (char *)g_realloc(prot_name, prot_name_len + 1);
     }
     prot_name[prot_name_index] = '\0';
 
index 27f0b067209b99c71c64428584529f14e737cf93..6878c24fb77a298d9c1b92c11de0f7ceed9fa632 100644 (file)
@@ -115,7 +115,8 @@ format.
 
 Packages for Win32
 ------------------
-See ..\config.nmake for Win32 settings.
+See ..\config.nmake for Win32 settings. You may need to run
+"build-docbook-catalog" in order to register your catalog properly.
 
 Tool/File           Cygwin Package          Opt./Mand.  Comments
 ---------           --------------          ----------  --------
@@ -128,6 +129,7 @@ fop:                -                       O           URL: http://xml.apache.o
 jimi:               -                       O           URL: http://java.sun.com/products/jimi/ - see above
 hhc:                -                       O           URL: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp 
 zip:                Archive/zip             O
+getopt:             Utils/util-linux        O           Required to run "build-docbook-catalog"
 
 
 Packages for Suse 9.3
index b20a4337fce69ece54e3611ac056b0b67653752f..028f38f6afb68cc6aee2d116a5a3eb2eb82a325e 100644 (file)
@@ -27,6 +27,7 @@
 #include "config.h"
 #endif
 
+#include <stdio.h>
 #include <string.h>
 #include <glib.h>
 #include <epan/packet.h>
 #define LOWPAN_IPHC_HLIM_255            0x3
 
 /* IPHC address modes. */
+#define LOWPAN_IPHC_ADDR_SRC_UNSPEC     0x0
 #define LOWPAN_IPHC_ADDR_FULL_INLINE    0x0
 #define LOWPAN_IPHC_ADDR_64BIT_INLINE   0x1
 #define LOWPAN_IPHC_ADDR_16BIT_INLINE   0x2
 #define LOWPAN_IPHC_MCAST_32BIT         0x2
 #define LOWPAN_IPHC_MCAST_8BIT          0x3
 
+#define LOWPAN_IPHC_MCAST_STATEFUL_48BIT 0x1
+
 /* IPHC Traffic class and flow label field sizes (in bits) */
 #define LOWPAN_IPHC_ECN_BITS            2
 #define LOWPAN_IPHC_DSCP_BITS           6
@@ -403,17 +407,18 @@ struct lowpan_nhdr {
 };
 
 /* Dissector prototypes */
-static void         proto_init_6lowpan      (void);
-static gboolean     dissect_6lowpan_heur    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static void         dissect_6lowpan         (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static tvbuff_t *   dissect_6lowpan_ipv6    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static tvbuff_t *   dissect_6lowpan_hc1     (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static tvbuff_t *   dissect_6lowpan_bc0     (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static tvbuff_t *   dissect_6lowpan_iphc    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static struct lowpan_nhdr * dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset);
-static tvbuff_t *   dissect_6lowpan_mesh    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static tvbuff_t *   dissect_6lowpan_frag    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean first);
-static tvbuff_t *   dissect_6lowpan_unknown (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void         proto_init_6lowpan          (void);
+static gboolean     dissect_6lowpan_heur        (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void         dissect_6lowpan             (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static tvbuff_t *   dissect_6lowpan_ipv6        (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static tvbuff_t *   dissect_6lowpan_hc1         (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint dgram_size, proto_item *length_item);
+static tvbuff_t *   dissect_6lowpan_bc0         (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static tvbuff_t *   dissect_6lowpan_iphc        (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint dgram_size);
+static struct lowpan_nhdr * dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint dgram_size);
+static tvbuff_t *   dissect_6lowpan_mesh        (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static tvbuff_t *   dissect_6lowpan_frag_first  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static tvbuff_t *   dissect_6lowpan_frag_middle (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void         dissect_6lowpan_unknown     (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 
 /* Helper functions. */
 static gboolean     lowpan_dlsrc_to_ifcid   (packet_info *pinfo, guint8 *ifcid);
@@ -480,11 +485,7 @@ lowpan_dlsrc_to_ifcid(packet_info *pinfo, guint8 *ifcid)
         return TRUE;
     }
 
-    /* Sanity-Check to ensure the parent dissector was IEEE 802.15.4 */
-    if (!pinfo->layer_names) return FALSE;
-    if (!pinfo->layer_names->str) return FALSE;
-    if (strstr(pinfo->layer_names->str, "wpan")) return FALSE;
-
+    /* Derive the IID from the IEEE 802.15.4 packet structure. */
     if (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) {
         guint64     addr;
         addr = pntoh64(&packet->src.addr64);
@@ -529,11 +530,7 @@ lowpan_dldst_to_ifcid(packet_info *pinfo, guint8 *ifcid)
         return TRUE;
     }
 
-    /* Sanity-Check to ensure the parent dissector was IEEE 802.15.4 */
-    if (!pinfo->layer_names) return FALSE;
-    if (!pinfo->layer_names->str) return FALSE;
-    if (strstr(pinfo->layer_names->str, "wpan")) return FALSE;
-
+    /* Derive the IID from the IEEE 802.15.4 packet structure. */
     if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT) {
         guint64     addr;
         addr = pntoh64(&packet->dst.addr64);
@@ -714,34 +711,44 @@ dissect_6lowpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     /* Add the protocol name. */
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "6LoWPAN");
 
-    /* Dissect headers in a loop until we find the end of the buffer. */
-    while (next) {
-        /* Parse patterns until we find a match. */
-        if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_IPV6_BITS) == LOWPAN_PATTERN_IPV6) {
-            next = dissect_6lowpan_ipv6(next, pinfo, lowpan_tree);
-        }
-        else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_HC1_BITS) == LOWPAN_PATTERN_HC1) {
-            next = dissect_6lowpan_hc1(next, pinfo, lowpan_tree);
-        }
-        else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_BC0_BITS) == LOWPAN_PATTERN_BC0) {
-            next = dissect_6lowpan_bc0(next, pinfo, lowpan_tree);
-        }
-        else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) {
-            next = dissect_6lowpan_iphc(next, pinfo, lowpan_tree);
-        }
-        else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_MESH_BITS) == LOWPAN_PATTERN_MESH) {
-            next = dissect_6lowpan_mesh(next, pinfo, lowpan_tree);
-        }
-        else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAG1) {
-            next = dissect_6lowpan_frag(next, pinfo, lowpan_tree, TRUE);
-        }
-        else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAGN) {
-            next = dissect_6lowpan_frag(next, pinfo, lowpan_tree, FALSE);
-        }
-        else {
-            next = dissect_6lowpan_unknown(next, pinfo, lowpan_tree);
-        }
-    } /* while */
+    /* Mesh and Broadcast headers always come first in a 6LoWPAN frame. */
+    if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_MESH_BITS) == LOWPAN_PATTERN_MESH) {
+        next = dissect_6lowpan_mesh(next, pinfo, lowpan_tree);
+        if (!next) return;
+    }
+    if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_BC0_BITS) == LOWPAN_PATTERN_BC0) {
+        next = dissect_6lowpan_bc0(next, pinfo, lowpan_tree);
+        if (!next) return;
+    }
+
+    /* Reassemble first fragments. */
+    if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAG1) {
+        next = dissect_6lowpan_frag_first(next, pinfo, lowpan_tree);
+    }
+    /* Reassemble intermediate fragments. */
+    else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAGN) {
+        next = dissect_6lowpan_frag_middle(next, pinfo, lowpan_tree);
+    }
+    /* Next should be either an uncompressed IPv6, HC1, or IPHC datagram. */
+    else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_IPV6_BITS) == LOWPAN_PATTERN_IPV6) {
+        next = dissect_6lowpan_ipv6(next, pinfo, lowpan_tree);
+    }
+    else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_HC1_BITS) == LOWPAN_PATTERN_HC1) {
+        next = dissect_6lowpan_hc1(next, pinfo, lowpan_tree, -1, NULL);
+    }
+    else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) {
+        next = dissect_6lowpan_iphc(next, pinfo, lowpan_tree, -1);
+    }
+    /* Unknown 6LoWPAN dispatch type */
+    else {
+        dissect_6lowpan_unknown(next, pinfo, lowpan_tree);
+        return;
+    }
+
+    /* The last step should have returned an uncompressed IPv6 datagram. */
+    if (next) {
+        call_dissector(ipv6_handle, next, pinfo, tree);
+    }
 } /* dissect_6lowpan */
 
 /*FUNCTION:------------------------------------------------------
@@ -749,6 +756,10 @@ dissect_6lowpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  *      dissect_6lowpan_ipv6
  *  DESCRIPTION
  *      Dissector routine for an uncompressed IPv6 header type.
+ *
+ *      This is one of the final encapsulation types, and will
+ *      returned an uncompressed IPv6 datagram (or fragment
+ *      thereof).
  *  PARAMETERS
  *      tvb             ; packet buffer.
  *      pinfo           ; packet info.
@@ -759,21 +770,15 @@ dissect_6lowpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  *---------------------------------------------------------------
  */
 static tvbuff_t *
-dissect_6lowpan_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_6lowpan_ipv6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
 {
-    tvbuff_t *          ipv6_tvb;
-
     /* Get and display the pattern. */
     if (tree) {
         proto_tree_add_bits_item(tree, hf_6lowpan_pattern, tvb, 0, LOWPAN_PATTERN_IPV6_BITS, FALSE);
     }
 
     /* Create a tvbuff subset for the ipv6 datagram. */
-    ipv6_tvb = tvb_new_subset(tvb, sizeof(guint8), -1, tvb_reported_length(tvb) - sizeof(guint8));
-    call_dissector(ipv6_handle, ipv6_tvb, pinfo, proto_tree_get_root(tree));
-
-    /* No data remaining, we gave it all to the IPv6 dissector. */
-    return NULL;
+    return tvb_new_subset(tvb, sizeof(guint8), -1, tvb_reported_length(tvb) - sizeof(guint8));
 } /* dissect_6lowpan_ipv6 */
 
 /*FUNCTION:------------------------------------------------------
@@ -785,12 +790,13 @@ dissect_6lowpan_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  *      tvb             ; packet buffer.
  *      pinfo           ; packet info.
  *      tree            ; 6LoWPAN display tree.
+ *      dgram_size      ; Datagram size (or <0 if not fragmented).
  *  RETURNS
  *      tvbuff_t *      ; The remaining payload to be parsed.
  *---------------------------------------------------------------
  */
 static tvbuff_t *
-dissect_6lowpan_hc1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_6lowpan_hc1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint dgram_size, proto_item *length_item)
 {
     gint                offset = 0;
     gint                bit_offset;
@@ -951,8 +957,11 @@ dissect_6lowpan_hc1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         proto_tree_add_ipv6(tree, hf_6lowpan_source, tvb, offset>>3,
                 BITS_TO_BYTE_LEN(offset, (bit_offset-offset)), (guint8 *)&ipv6.ip6_src);
     }
-    SET_ADDRESS(&pinfo->src, AT_IPv6, sizeof(struct e_in6_addr), &ipv6.ip6_src);
-    SET_ADDRESS(&pinfo->net_src, AT_IPv6, sizeof(struct e_in6_addr), &ipv6.ip6_src);
+    /*
+     * Do not set the address columns until after defragmentation, since we have
+     * to do decompression before reassembly, and changing the address will cause
+     * wireshark to think that the middle fragments came from another device.
+     */
 
     /*=====================================================
      * Parse/Decompress IPv6 Destination Address
@@ -985,8 +994,11 @@ dissect_6lowpan_hc1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         proto_tree_add_ipv6(tree, hf_6lowpan_dest, tvb, offset>>3,
                 BITS_TO_BYTE_LEN(offset, (bit_offset-offset)), (guint8 *)&ipv6.ip6_dst);
     }
-    SET_ADDRESS(&pinfo->dst, AT_IPv6, sizeof(struct e_in6_addr), &ipv6.ip6_dst);
-    SET_ADDRESS(&pinfo->net_dst, AT_IPv6, sizeof(struct e_in6_addr), &ipv6.ip6_dst);
+    /*
+     * Do not set the address columns until after defragmentation, since we have
+     * to do decompression before reassembly, and changing the address will cause
+     * wireshark to think that the middle fragments came from another device.
+     */
 
     /*=====================================================
      * Parse and Reconstruct the UDP Header
@@ -1038,6 +1050,17 @@ dissect_6lowpan_hc1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
             }
             bit_offset += LOWPAN_UDP_LENGTH_BITS;
         }
+        /* Compute the length from the fragmentation headers. */
+        else if (dgram_size >= 0) {
+            if (dgram_size < (gint)sizeof(struct ip6_hdr)) {
+                /* Datagram size is too small */
+                expert_add_info_format(pinfo, length_item, PI_MALFORMED,
+                    PI_ERROR, "Length is less than IPv6 header length %u",
+                    (guint)sizeof(struct ip6_hdr));
+                return NULL;
+            }
+            udp.length = dgram_size - (gint)sizeof(struct ip6_hdr);
+        }
         /* Compute the length from the tvbuff size. */
         else {
             udp.length = tvb_reported_length(tvb);
@@ -1078,17 +1101,19 @@ dissect_6lowpan_hc1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         nhdr_list->next = NULL;
         nhdr_list->proto = ipv6.ip6_nxt;
         nhdr_list->length = tvb_length_remaining(tvb, offset);
-        nhdr_list->reported = tvb_reported_length_remaining(tvb, offset);
+        if (dgram_size < 0) {
+            nhdr_list->reported = tvb_reported_length_remaining(tvb, offset);
+        }
+        else {
+            nhdr_list->reported = dgram_size - sizeof(struct ip6_hdr);
+        }
         tvb_memcpy(tvb, nhdr_list->hdr, offset, nhdr_list->length);
     }
 
     /* Link the reassembled tvbuff together.  */
     ipv6_tvb = lowpan_reassemble_ipv6(tvb, &ipv6, nhdr_list);
-    add_new_data_source(pinfo, ipv6_tvb, "6LoWPAN header decompression");
-
-    /* Pass the reassembled packet to the IPv6 dissector. */
-    call_dissector(ipv6_handle, ipv6_tvb, pinfo, proto_tree_get_root(tree));
-    return NULL;
+    add_new_data_source(pinfo, ipv6_tvb, "Decompressed 6LoWPAN header");
+    return ipv6_tvb;
 } /* dissect_6lowpan_hc1 */
 
 /*FUNCTION:------------------------------------------------------
@@ -1100,17 +1125,18 @@ dissect_6lowpan_hc1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  *      This header is still in the draft phase, but is expected
  *      to replace HC1.
  *
- *      See draft-ietf-6lowpan-hc-05.txt
+ *      See draft-ietf-6lowpan-hc-06.txt
  *  PARAMETERS
  *      tvb             ; packet buffer.
  *      pinfo           ; packet info.
  *      tree            ; 6LoWPAN display tree.
+ *      dgram_size      ; Datagram size (or <0 if not fragmented).
  *  RETURNS
  *      tvbuff_t *      ; The remaining payload to be parsed.
  *---------------------------------------------------------------
  */
 static tvbuff_t *
-dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint dgram_size)
 {
     gint                offset = 0;
     gint                length;
@@ -1300,7 +1326,12 @@ dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
          * For now, just set the address to 0 and ignore the context bits.
          */
         addr_err = TRUE;
-        if (iphc_src_mode == LOWPAN_IPHC_ADDR_64BIT_INLINE) length = sizeof(guint64);
+        /* The unspecified address (::) */
+        if (iphc_src_mode == LOWPAN_IPHC_ADDR_SRC_UNSPEC) {
+               length = 0;
+               addr_err = FALSE;
+        }
+        else if (iphc_src_mode == LOWPAN_IPHC_ADDR_64BIT_INLINE) length = sizeof(guint64);
         else if (iphc_src_mode == LOWPAN_IPHC_ADDR_16BIT_INLINE) length = sizeof(guint16);
         else if (iphc_src_mode == LOWPAN_IPHC_ADDR_COMPRESSED) length = 0;
         else {
@@ -1318,8 +1349,11 @@ dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_WARN, "Failed to recover source IPv6 address");
     }
     offset += length;
-    SET_ADDRESS(&pinfo->src, AT_IPv6, sizeof(struct e_in6_addr), &ipv6.ip6_src);
-    SET_ADDRESS(&pinfo->net_src, AT_IPv6, sizeof(struct e_in6_addr), &ipv6.ip6_src);
+    /*
+     * Do not set the address columns until after defragmentation, since we have
+     * to do decompression before reassembly, and changing the address will cause
+     * wireshark to think that the middle fragments came from another device.
+     */
 
     /*=====================================================
      * Parse and decompress the destination address.
@@ -1360,7 +1394,11 @@ dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
      *---------------------------------
      */
     else if (!(iphc_flags & LOWPAN_IPHC_FLAG_DST_COMP) && (iphc_flags & LOWPAN_IPHC_FLAG_MCAST_COMP)) {
-        if (iphc_dst_mode == LOWPAN_IPHC_MCAST_48BIT) {
+       if (iphc_dst_mode == LOWPAN_IPHC_ADDR_FULL_INLINE) {
+               length = sizeof(ipv6.ip6_dst);
+               tvb_memcpy(tvb, &ipv6.ip6_dst.bytes[sizeof(ipv6.ip6_dst) - length], offset, length);
+       }
+       else if (iphc_dst_mode == LOWPAN_IPHC_MCAST_48BIT) {
             ipv6.ip6_dst.bytes[0] = 0xff;
             ipv6.ip6_dst.bytes[1] = tvb_get_guint8(tvb, offset + (length++));
             ipv6.ip6_dst.bytes[11] = tvb_get_guint8(tvb, offset + (length++));
@@ -1408,7 +1446,7 @@ dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
      *---------------------------------
      */
     else {
-        if (iphc_dst_mode == LOWPAN_IPHC_MCAST_48BIT) {
+        if (iphc_dst_mode == LOWPAN_IPHC_MCAST_STATEFUL_48BIT) {
             ipv6.ip6_dst.bytes[0] = 0xff;
             ipv6.ip6_dst.bytes[1] = tvb_get_guint8(tvb, offset + (length++));
             ipv6.ip6_dst.bytes[2] = tvb_get_guint8(tvb, offset + (length++));
@@ -1435,8 +1473,11 @@ dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         expert_add_info_format(pinfo, ti, PI_UNDECODED, PI_WARN, "Failed to recover destination IPv6 address");
     }
     offset += length;
-    SET_ADDRESS(&pinfo->dst, AT_IPv6, sizeof(struct e_in6_addr), &ipv6.ip6_dst);
-    SET_ADDRESS(&pinfo->net_dst, AT_IPv6, sizeof(struct e_in6_addr), &ipv6.ip6_dst);
+    /*
+     * Do not set the address columns until after defragmentation, since we have
+     * to do decompression before reassembly, and changing the address will cause
+     * wireshark to think that the middle fragments came from another device.
+     */
 
     /*=====================================================
      * Decompress extension headers.
@@ -1448,7 +1489,7 @@ dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         ipv6.ip6_nxt = lowpan_parse_nhc_proto(tvb, offset);
 
         /* Parse the 6LoWPAN NHC fields. */
-        nhdr_list = dissect_6lowpan_iphc_nhc(tvb, pinfo, tree, offset);
+        nhdr_list = dissect_6lowpan_iphc_nhc(tvb, pinfo, tree, offset, dgram_size - sizeof(struct ip6_hdr));
     }
     /* Create an extension header for the remaining payload. */
     else {
@@ -1456,7 +1497,12 @@ dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         nhdr_list->next = NULL;
         nhdr_list->proto = ipv6.ip6_nxt;
         nhdr_list->length = tvb_length_remaining(tvb, offset);
-        nhdr_list->reported = tvb_reported_length_remaining(tvb, offset);
+        if (dgram_size < 0) {
+            nhdr_list->reported = tvb_reported_length_remaining(tvb, offset);
+        }
+        else {
+            nhdr_list->reported = dgram_size - sizeof(struct ip6_hdr);
+        }
         tvb_memcpy(tvb, nhdr_list->hdr, offset, nhdr_list->length);
     }
 
@@ -1466,11 +1512,8 @@ dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
      */
     /* Reassemble the IPv6 packet. */
     ipv6_tvb = lowpan_reassemble_ipv6(tvb, &ipv6, nhdr_list);
-    add_new_data_source(pinfo, ipv6_tvb, "6LoWPAN header decompression");
-
-    /* Pass the reassembled packet to the IPv6 dissector. */
-    call_dissector(ipv6_handle, ipv6_tvb, pinfo, proto_tree_get_root(tree));
-    return NULL;
+    add_new_data_source(pinfo, ipv6_tvb, "Decompressed 6LoWPAN header");
+    return ipv6_tvb;
 } /* dissect_6lowpan_iphc */
 
 /*FUNCTION:------------------------------------------------------
@@ -1483,12 +1526,13 @@ dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  *      pinfo           ; packet info.
  *      tree            ; 6LoWPAN display tree.
  *      offset          ; packet buffer offset.
+ *      dgram_size      ; Remaining datagram size (or <0 if unknown).
  *  RETURNS
  *      lowpan_nhdr *   ; List of ep_alloc'd next header structures.
  *---------------------------------------------------------------
  */
 static struct lowpan_nhdr *
-dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint dgram_size)
 {
     gint                length;
     proto_item *        ti = NULL;
@@ -1544,11 +1588,11 @@ dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gi
         length = (length + 7) & ~0x7;
 
         /* Create the next header structure for the IPv6 extension header. */
-        nhdr = ep_alloc0(sizeof(struct lowpan_nhdr) + sizeof(struct ip6_ext) + length);
+        nhdr = ep_alloc0(sizeof(struct lowpan_nhdr) + length);
         nhdr->next = NULL;
         nhdr->proto = ext_proto;
-        nhdr->length = length + sizeof(struct ip6_ext);
-        nhdr->reported = length + sizeof(struct ip6_ext);
+        nhdr->length = length;
+        nhdr->reported = length;
 
         /* Add the IPv6 extension header to the buffer. */
         if (ext_flags & LOWPAN_NHC_EXT_NHDR) {
@@ -1581,22 +1625,27 @@ dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gi
         tvb_memcpy(tvb, nhdr->hdr + sizeof(struct ip6_ext), offset, ext_len);
         offset += ext_len;
 
-        if (!(ext_flags & LOWPAN_NHC_EXT_NHDR)) {
+        if (ext_flags & LOWPAN_NHC_EXT_NHDR) {
+            /*
+             * There are more LOWPAN_NHC structures to parse. Call ourself again
+             * recursively to parse them and build the linked list.
+             */
+            nhdr->next = dissect_6lowpan_iphc_nhc(tvb, pinfo, tree, offset, dgram_size - ext_len - sizeof(struct ip6_ext));
+        }
+        else {
             /* Create another next header structure for the remaining payload. */
             nhdr->next = ep_alloc(sizeof(struct lowpan_nhdr) + tvb_length_remaining(tvb, offset));
             nhdr->next->next = NULL;
             nhdr->next->proto = ipv6_ext.ip6e_nxt;
             nhdr->next->length = tvb_length_remaining(tvb, offset);
-            nhdr->next->reported = tvb_reported_length_remaining(tvb, offset);
+            if (dgram_size < 0) {
+                nhdr->next->reported = tvb_reported_length_remaining(tvb, offset);
+            }
+            else {
+                nhdr->next->reported = dgram_size - ext_len - sizeof(struct ip6_ext);
+            }
             tvb_memcpy(tvb, nhdr->next->hdr, offset, nhdr->next->length);
         }
-        else {
-            /*
-             * There are more LOWPAN_NHC structures to parse. Call ourself again
-             * recursively to parse them and build the linked list.
-             */
-            nhdr->next = dissect_6lowpan_iphc_nhc(tvb, pinfo, tree, offset);
-        }
 
         /* Done. */
         return nhdr;
@@ -1681,8 +1730,14 @@ dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gi
         }
 
         /* Compute the datagram length. */
-        length = tvb_reported_length_remaining(tvb, offset);
-        udp.length = g_htons(length + sizeof(struct udp_hdr));
+        if (dgram_size < 0) {
+            length = tvb_reported_length_remaining(tvb, offset);
+            udp.length = g_htons(length + sizeof(struct udp_hdr));
+        }
+        else {
+            length = dgram_size - sizeof(struct udp_hdr);
+            udp.length = g_htons(dgram_size);
+        }
 
         /*
          * Although rfc768 (udp) allows a packet to be sent with a checksum of
@@ -1692,6 +1747,15 @@ dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gi
          *
          * If the datagram is incomplete, then leave the checsum at 0.
          */
+#if 0
+        /*
+         * This has been disabled, since we might only be dissecting a fragment
+         * of the packet, and thus we might not have the entire UDP payload at
+         * this time.
+         *
+         * If we want to display the checksums, they will have to be recomputed
+         * after packet reassembly.
+         */
         if ((udp_flags & LOWPAN_NHC_UDP_CHECKSUM) && tvb_bytes_exist(tvb, offset, length)) {
             vec_t      cksum_vec[3];
             struct {
@@ -1719,6 +1783,7 @@ dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gi
             udp.checksum = in_cksum(cksum_vec, 3);
             if (udp.checksum == 0) udp.checksum = 0xffff;
         }
+#endif
 
         /* Create the next header structure for the UDP datagram. */
         nhdr = ep_alloc(sizeof(struct lowpan_nhdr) + sizeof(struct udp_hdr) + tvb_length_remaining(tvb, offset));
@@ -1727,9 +1792,9 @@ dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gi
         nhdr->length = tvb_length_remaining(tvb, offset) + sizeof(struct udp_hdr);
         nhdr->reported = g_ntohs(udp.length);
 
-        /* Copy the UDP header into the buffer. */
+        /* Copy the UDP header and payload into the buffer. */
         memcpy(nhdr->hdr, &udp, sizeof(struct udp_hdr));
-        tvb_memcpy(tvb, nhdr->hdr + sizeof(struct udp_hdr), offset, length);
+        tvb_memcpy(tvb, nhdr->hdr + sizeof(struct udp_hdr), offset, tvb_length_remaining(tvb, offset));
         return nhdr;
     }
     /*=====================================================
@@ -1893,20 +1958,131 @@ dissect_6lowpan_mesh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
 /*FUNCTION:------------------------------------------------------
  *  NAME
- *      dissect_6lowpan_frag
+ *      dissect_6lowpan_frag_first
+ *  DESCRIPTION
+ *      Dissector routine for a 6LoWPAN FRAG1 headers.
+ *
+ *      If reassembly could be completed, this should return an
+ *      uncompressed IPv6 packet. If reassembly had to be delayed
+ *      for more packets, this will return NULL.
+ *  PARAMETERS
+ *      tvb             ; packet buffer.
+ *      pinfo           ; packet info.
+ *      tree            ; 6LoWPAN display tree.
+ *  RETURNS
+ *      tvbuff_t *      ; reassembled IPv6 packet.
+ *---------------------------------------------------------------
+ */
+static tvbuff_t *
+dissect_6lowpan_frag_first(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+    gint                offset = 0;
+    gint                frag_size;
+    guint16             dgram_size;
+    guint16             dgram_tag;
+    proto_tree *        frag_tree = NULL;
+    proto_item *        ti = NULL;
+    proto_item *        length_item = NULL;
+    /* Reassembly parameters. */
+    tvbuff_t *          new_tvb = NULL;
+    tvbuff_t *          frag_tvb = NULL;
+    fragment_data *     frag_data = NULL;
+    gboolean            save_fragmented;
+
+    /* Create a tree for the fragmentation header. */
+    if (tree) {
+        ti = proto_tree_add_text(tree, tvb, offset, 0, "Fragmentation Header");
+        frag_tree = proto_item_add_subtree(ti, ett_6lowpan_frag);
+    }
+
+    /* Get and display the pattern and datagram size. */
+    dgram_size = tvb_get_bits16(tvb, (offset * 8) + LOWPAN_PATTERN_FRAG_BITS, LOWPAN_FRAG_DGRAM_SIZE_BITS, FALSE);
+    if (tree) {
+        proto_tree_add_bits_item(frag_tree, hf_6lowpan_pattern, tvb, offset * 8, LOWPAN_PATTERN_FRAG_BITS, FALSE);
+        length_item = proto_tree_add_uint(frag_tree, hf_6lowpan_frag_dgram_size, tvb, offset, sizeof(guint16), dgram_size);
+    }
+    offset += sizeof(guint16);
+
+    /* Get and display the datagram tag. */
+    dgram_tag = tvb_get_ntohs(tvb, offset);
+    if (tree) {
+        proto_tree_add_uint(frag_tree, hf_6lowpan_frag_dgram_tag, tvb, offset, sizeof(guint16), dgram_tag);
+    }
+    offset += sizeof(guint16);
+
+    /* Adjust the fragmentation header length. */
+    if (tree) {
+        proto_item_set_end(ti, tvb, offset);
+    }
+
+    /* The first fragment should be followed by  */
+    frag_tvb = tvb_new_subset(tvb, offset, -1, -1);
+    if (tvb_get_bits8(frag_tvb, 0, LOWPAN_PATTERN_IPV6_BITS) == LOWPAN_PATTERN_IPV6) {
+        frag_tvb = dissect_6lowpan_ipv6(frag_tvb, pinfo, tree);
+    }
+    else if (tvb_get_bits8(frag_tvb, 0, LOWPAN_PATTERN_HC1_BITS) == LOWPAN_PATTERN_HC1) {
+        frag_tvb = dissect_6lowpan_hc1(frag_tvb, pinfo, tree, dgram_size, length_item);
+    }
+    else if (tvb_get_bits8(frag_tvb, 0, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) {
+        frag_tvb = dissect_6lowpan_iphc(frag_tvb, pinfo, tree, dgram_size);
+    }
+    /* Unknown 6LoWPAN dispatch type */
+    else {
+        dissect_6lowpan_unknown(frag_tvb, pinfo, tree);
+        return NULL;
+    }
+
+    /* Add this datagram to the fragment table. */
+    frag_size = tvb_length(frag_tvb);
+    tvb_set_reported_length(frag_tvb, frag_size);
+    save_fragmented = pinfo->fragmented;
+    pinfo->fragmented = TRUE;
+    frag_data = fragment_add_check(frag_tvb, 0, pinfo, dgram_tag,
+                    lowpan_fragment_table, lowpan_reassembled_table,
+                    0, frag_size, (frag_size < dgram_size));
+
+    /* Attempt reassembly. */
+    new_tvb = process_reassembled_data(frag_tvb, 0, pinfo,
+                    "Reassembled 6LowPAN", frag_data, &lowpan_frag_items,
+                    NULL, tree);
+
+    /* If reassembly was successful, then return the completed datagram. */
+    if (new_tvb) {
+        return new_tvb;
+    }
+    /* If reassembly failed, display the payload fragment using the data dissector. */
+    else {
+        /*
+         * BUG?: We could actually continue dissecting, since frag_tvb should contain
+         * a truncated IPv6 packet, and we know the reported length from dgram_size.
+         *
+         * But this seems to cause problems with the TCP dissector if we resubmit the
+         * datagram for reassembly again once we have the entire IPv6 packet.
+         */
+        call_dissector(data_handle, frag_tvb, pinfo, proto_tree_get_root(tree));
+        return NULL;
+    }
+} /* dissect_6lowpan_frag_first */
+
+/*FUNCTION:------------------------------------------------------
+ *  NAME
+ *      dissect_6lowpan_frag_middle
  *  DESCRIPTION
- *      Dissector routine for a 6LoWPAN FRAG headers.
+ *      Dissector routine for a 6LoWPAN FRAGN headers.
+ *
+ *      If reassembly could be completed, this should return an
+ *      uncompressed IPv6 packet. If reassembly had to be delayed
+ *      for more packets, this will return NULL.
  *  PARAMETERS
  *      tvb             ; packet buffer.
  *      pinfo           ; packet info.
  *      tree            ; 6LoWPAN display tree.
- *      first           ; TRUE if dispatch was FRAG1, FALSE if FRAGN.
  *  RETURNS
- *      tvbuff_t *      ; reassembled/next buffer.
+ *      tvbuff_t *      ; reassembled IPv6 packet.
  *---------------------------------------------------------------
  */
 static tvbuff_t *
-dissect_6lowpan_frag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean first)
+dissect_6lowpan_frag_middle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
     gint                offset = 0;
     gint                frag_size;
@@ -1941,13 +2117,12 @@ dissect_6lowpan_frag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboole
     }
     offset += sizeof(guint16);
 
-    if (!first) {
-        dgram_offset = tvb_get_guint8(tvb, offset) * 8;
-        if (tree) {
-            proto_tree_add_uint(frag_tree, hf_6lowpan_frag_dgram_offset, tvb, offset, sizeof(guint8), dgram_offset);
-        }
-        offset += sizeof(guint8);
+    /* Get and display the datagram offset. */
+    dgram_offset = tvb_get_guint8(tvb, offset) * 8;
+    if (tree) {
+        proto_tree_add_uint(frag_tree, hf_6lowpan_frag_dgram_offset, tvb, offset, sizeof(guint8), dgram_offset);
     }
+    offset += sizeof(guint8);
 
     /* Adjust the fragmentation header length. */
     frag_size = tvb_reported_length_remaining(tvb, offset);
@@ -1971,23 +2146,13 @@ dissect_6lowpan_frag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboole
     if (new_tvb) {
         return new_tvb;
     }
-    /*
-     * Otherwise, we were unable to reassemble the packet. If this is the
-     * first fragment, we can still return the remainder for more processing.
-     */
-    else if (first) {
-        return tvb_new_subset(tvb, offset, -1, dgram_size);
-    }
-    /*
-     * If reassembly failed, and this is not the first fragment, then display
-     * the payload fragment using the data dissector.
-     */
+    /* If reassembly failed, display the payload fragment using the data dissector. */
     else {
-        tvbuff_t *      data_tvb = tvb_new_subset(tvb, offset, -1, dgram_size);
-        call_dissector(data_handle, data_tvb, pinfo, proto_tree_get_root(tree));
+        new_tvb = tvb_new_subset(tvb, offset, -1, -1);
+        call_dissector(data_handle, new_tvb, pinfo, proto_tree_get_root(tree));
         return NULL;
     }
-} /* dissect_6lowpan_frag */
+} /* dissect_6lowpan_frag_middle */
 
 /*FUNCTION:------------------------------------------------------
  *  NAME
@@ -2003,7 +2168,7 @@ dissect_6lowpan_frag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboole
  *      void            ;
  *---------------------------------------------------------------
  */
-static tvbuff_t *
+void
 dissect_6lowpan_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
     tvbuff_t *          data_tvb;
@@ -2016,9 +2181,6 @@ dissect_6lowpan_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     /* Create a tvbuff subset for the remaining data. */
     data_tvb = tvb_new_subset(tvb, sizeof(guint8), -1, tvb_reported_length(tvb) - sizeof(guint8));
     call_dissector(data_handle, data_tvb, pinfo, proto_tree_get_root(tree));
-
-    /* No data remaining, we gave it all to the data dissector. */
-    return NULL;
 } /* dissect_6lowpan_unknown */
 
 /*FUNCTION:------------------------------------------------------
index 42cc203e64de43532c3476dd3579ecfbad54181b..adfbc03502d924344225fc2d0626c9b1f396e57f 100644 (file)
@@ -22,6 +22,7 @@
  * RFC 3594: PacketCable Security Ticket Control Sub-Option (122.9)
  * RFC 3442: Classless Static Route Option for DHCP version 4
  * RFC 3825: Dynamic Host Configuration Protocol Option for Coordinate-based Location Configuration Information
+ * RFC 3925: Vendor-Identifying Vendor Options for Dynamic Host Configuration Protocol version 4 (DHCPv4)
  * RFC 3942: Reclassifying DHCPv4 Options
  * RFC 4243: Vendor-Specific Information Suboption for the Dynamic Host Configuration Protocol (DHCP) Relay Agent Option
  * RFC 4388: Dynamic Host Configuration Protocol (DHCP) Leasequery
@@ -615,7 +616,7 @@ static struct opt_info default_bootp_opt[BOOTP_OPT_NUM] = {
 /* 121 */ { "Classless Static Route",                  special, NULL },
 /* 122 */ { "CableLabs Client Configuration [TODO:RFC3495]",   opaque, NULL },
 /* 123 */ { "Coordinate-based Location Configuration", special, NULL },
-/* 124 */ { "V-I Vendor Class [TODO:RFC3925]",         opaque, NULL },
+/* 124 */ { "V-I Vendor Class",                                special, NULL },
 /* 125 */ { "V-I Vendor-specific Information",         special, NULL },
 /* 126 */ { "Removed/Unassigned",                      opaque, NULL },
 /* 127 */ { "Removed/Unassigend",                      opaque, NULL },
@@ -800,6 +801,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
        int                     o52voff, o52eoff;
        gboolean                o52at_end;
        guint8                  s_option;
+       guint8                  s_len;
        int                     ava_vid;
        const guchar            *dns_name;
 
@@ -1592,11 +1594,63 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                                proto_tree_add_text(v_tree, tvb, optoff+10, 1, "Altitude type: %s (%d)", val_to_str(location.altitude_type, altitude_type_values, "Unknown"), location.altitude_type);
                                proto_tree_add_text(v_tree, tvb, optoff+15, 1, "Map Datum: %s (%d)", val_to_str(location.datum_type, map_datum_type_values, "Unknown"), location.datum_type);
                        }
+               } else if (optlen == 34) {
+                       s_option = tvb_get_guint8(tvb, optoff);
+                       s_len = tvb_get_guint8(tvb, optoff+1);
+                       if (s_option == 1) {
+                               proto_tree_add_text(v_tree, tvb, optoff, optlen, "Suboption 1: Primary DSS_ID = %s",
+                                       arphrdaddr_to_str(tvb_get_ptr(tvb, optoff+2, s_len+1), s_len+1, s_option));
+                       } else if (s_option == 2) {
+                               proto_tree_add_text(v_tree, tvb, optoff, optlen, "Suboption 2: Secondary DSS_ID = %s", 
+                                       arphrdaddr_to_str(tvb_get_ptr(tvb, optoff+2, s_len+1), s_len+1, s_option));
+                       } else {
+                               proto_tree_add_text(v_tree, tvb, optoff, optlen, "Unknown");
+                       }
                } else {
                        proto_tree_add_text(v_tree, tvb, optoff, optlen, "Error: Invalid length of DHCP option!");
                }
                break;
 
+       case 124: {     /* V-I Vendor Class */
+               int enterprise = 0;
+               int data_len;
+
+               optend = optoff + optlen;
+               optleft = optlen;
+
+               while (optleft > 0) {
+
+                 if (optleft < 5) {
+                   proto_tree_add_text(v_tree, tvb, optoff,
+                                       optleft, "Vendor Class: malformed option");
+                   break;
+                 }
+
+                 enterprise = tvb_get_ntohl(tvb, optoff);
+
+                 vti = proto_tree_add_text(v_tree, tvb, optoff, 4,
+                                           "Enterprise-number: %s (%u)",
+                                           val_to_str(enterprise, sminmpec_values, "Unknown"),
+                                           enterprise);
+
+                 data_len = tvb_get_guint8(tvb, optoff + 4);
+
+                 proto_tree_add_text(v_tree, tvb, optoff + 4, 1,
+                                     "Data len: %d", data_len);
+                 optoff += 5;
+                 optleft -= 5;
+
+                 proto_tree_add_text(v_tree, tvb, optoff, data_len,
+                                     "Vendor Class data: %s",
+                                     tvb_bytes_to_str(tvb, optoff, data_len));
+
+                 /* look for next enterprise number */
+                 optoff += data_len;
+                 optleft -= data_len;
+               }
+               break;
+       }
+
        case 125: {     /* V-I Vendor-specific Information */
                int enterprise = 0;
                int s_end = 0;
@@ -1618,7 +1672,7 @@ bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, int voff,
                  enterprise = tvb_get_ntohl(tvb, optoff);
 
                  vti = proto_tree_add_text(v_tree, tvb, optoff, 4,
-                                           "Enterprise-number: %s-%u",
+                                           "Enterprise-number: %s (%u)",
                                            val_to_str( enterprise, sminmpec_values, "Unknown"),
                                            enterprise);
 
@@ -1941,7 +1995,7 @@ bootp_dhcp_decode_agent_info(proto_tree *v_tree, tvbuff_t *tvb, int optoff,
                while (suboptoff < optend) {
                        enterprise = tvb_get_ntohl(tvb, suboptoff);
                        vti = proto_tree_add_text(v_tree, tvb, suboptoff, 4,
-                                           "Enterprise-number: %s-%u",
+                                           "Enterprise-number: %s (%u)",
                                            val_to_str( enterprise, sminmpec_values, "Unknown"),
                                            enterprise);
                        suboptoff += 4;
index 59a117593abb0173947dc66257d765706de988d8..39ab3e575e76463bc686e9b466a47cb395a703d7 100644 (file)
@@ -3275,6 +3275,7 @@ de_sm_pdp_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar
 
        if (pdp_type_org == 0 )
        {
+               /* ETSI allocated address */
                switch (pdp_type_num)
                {
                        case 0x00: str="Reserved, used in earlier version of this protocol"; break;
@@ -3284,6 +3285,7 @@ de_sm_pdp_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar
        }
        else if (pdp_type_org == 1)
        {
+               /* IETF allocated addres */
                switch (pdp_type_num)
                {
                        case 0x21: str="IPv4 address"; break;
@@ -3306,7 +3308,7 @@ de_sm_pdp_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar
                proto_tree_add_text(tree,
                        tvb, curr_offset, 1,
                        "Dynamic addressing");
-
+               curr_offset += 1;
                return(curr_offset - offset);
        }
        else if ( len == 2 )
@@ -3314,7 +3316,7 @@ de_sm_pdp_addr(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gchar
                proto_tree_add_text(tree,
                        tvb, curr_offset, 1,
                        "No PDP address is included");
-
+               curr_offset += 1;
                return(curr_offset - offset);
        }
 
@@ -4243,26 +4245,26 @@ de_sm_tflow_temp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gch
                        curr_len -= 2;
                        switch (param) {
                        case 0x01:
-                               proto_tree_add_text(tf_tree, tvb, curr_offset, pf_length, "Authorization token value: %s",
+                               proto_tree_add_text(tf_tree, tvb, curr_offset, pf_length, "Authorization token value: 0x%s",
                                                tvb_bytes_to_str(tvb, curr_offset, pf_length));
                                break;
                                
                        case 0x02:
-                               proto_tree_add_text(tf_tree, tvb, curr_offset, 2, "Media Component number value: %s",
-                                               tvb_bytes_to_str(tvb, curr_offset, 2));
-                               proto_tree_add_text(tf_tree, tvb, curr_offset+2, 2, "IP flow number: %s",
-                                               tvb_bytes_to_str(tvb, curr_offset+2, 2));
+                               proto_tree_add_text(tf_tree, tvb, curr_offset, 2, "Media Component number value: 0x%x",
+                                               tvb_get_bits16(tvb, curr_offset<<3, 16, FALSE));
+                               proto_tree_add_text(tf_tree, tvb, curr_offset+2, 2, "IP flow number: 0x%x",
+                                               tvb_get_bits16(tvb, (curr_offset+2)<<3, 16, FALSE));
                                break;
 
                        case 0x03:
                                for (i = 0; i < pf_length; i++) {
-                                       proto_tree_add_text(tf_tree, tvb, curr_offset+i, 1, "Packet filter identifier %d: %s",
-                                                   i, tvb_bytes_to_str(tvb, curr_offset+i, 1));
+                                       proto_tree_add_text(tf_tree, tvb, curr_offset+i, 1, "Packet filter identifier %d: %d",
+                                                   i, tvb_get_guint8(tvb, curr_offset+i));
                                }
                                break;
 
                        default:
-                               proto_tree_add_text(tf_tree, tvb, curr_offset, pf_length, "Parameter content: %s",
+                               proto_tree_add_text(tf_tree, tvb, curr_offset, pf_length, "Parameter content: 0x%s",
                                                    tvb_bytes_to_str(tvb, curr_offset, pf_length));
                                break;
                        }
index b07ec69d57127eca724d8a4223c52abc2b0ed8de..a45e0a781392c6c4a67bbaf6493a2edef524e5ac 100644 (file)
@@ -55,7 +55,6 @@
  *  of the frame check sequence:
  *      - IEEE 802.15.4 compliant FCS.
  *      - ChipCon/Texas Instruments CC24xx style FCS.
- *      - No FCS at all.
  *------------------------------------------------------------
  */
 
@@ -138,13 +137,12 @@ typedef enum {
     DECRYPT_NOT_ENCRYPTED,
     DECRYPT_VERSION_UNSUPPORTED,
     DECRYPT_PACKET_TOO_SMALL,
-    DECRYPT_SNAPLEN_TOO_SMALL,
     DECRYPT_PACKET_NO_EXT_SRC_ADDR,
     DECRYPT_PACKET_NO_KEY,
     DECRYPT_PACKET_DECRYPT_FAILED,
     DECRYPT_PACKET_MIC_CHECK_FAILED,
-    DECRYPT_PACKET_NO_PAYLOAD
 } ws_decrypt_status;
+
 static tvbuff_t * dissect_ieee802154_decrypt(tvbuff_t *, guint, packet_info *, ieee802154_packet *, ws_decrypt_status *);
 static void ccm_init_block                  (gchar * block, gboolean adata, gint M, guint64 addr, guint32 counter, ieee802154_security_level level, gint ctr_val);
 static gboolean ccm_ctr_encrypt             (const gchar *key, const gchar *iv, gchar *mic, gchar *data, gint length);
@@ -934,62 +932,70 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
     /* Encrypted Payload. */
     if (packet->security_enable) {
         payload_tvb = dissect_ieee802154_decrypt(tvb, offset, pinfo, packet, &status);
-        switch (status) {
 
-        case DECRYPT_PACKET_SUCCEEDED:
-            /* No problem. */
-            break;
+        /* Get the unencrypted data if decryption failed.  */
+        if (!payload_tvb) {
+            /* Deal with possible truncation and the FCS field at the end. */
+            gint            reported_len = tvb_reported_length(tvb)-offset-IEEE802154_FCS_LEN;
+            gint            captured_len = tvb_length(tvb)-offset;
+            if (reported_len < captured_len) captured_len = reported_len;
+            payload_tvb = tvb_new_subset(tvb, offset, captured_len, reported_len);
+        }
 
+        /* Display the reason for failure, and abort if the error was fatal. */
+        switch (status) {
+        case DECRYPT_PACKET_SUCCEEDED:
         case DECRYPT_NOT_ENCRYPTED:
-            /* Packet wasn't encrypted */
+            /* No problem. */
             break;
 
         case DECRYPT_VERSION_UNSUPPORTED:
             /* We don't support decryption with that version of the protocol */
             expert_add_info_format(pinfo, proto_root, PI_UNDECODED, PI_WARN, "We don't support decryption with protocol version %u",
                                    packet->version);
-            break;
+            call_dissector(data_handle, payload_tvb, pinfo, tree);
+            goto dissect_ieee802154_fcs;
 
         case DECRYPT_PACKET_TOO_SMALL:
-            /* Packet was too small to include CRC and MIC */
             expert_add_info_format(pinfo, proto_root, PI_UNDECODED, PI_WARN, "Packet was too small to include the CRC and MIC");
-            break;
-
-        case DECRYPT_SNAPLEN_TOO_SMALL:
-            expert_add_info_format(pinfo, proto_root, PI_UNDECODED, PI_WARN, "Snapshot length was too small to include the CRC and MIC");
-            break;
+            call_dissector(data_handle, payload_tvb, pinfo, tree);
+            goto dissect_ieee802154_fcs;
 
         case DECRYPT_PACKET_NO_EXT_SRC_ADDR:
             expert_add_info_format(pinfo, proto_root, PI_UNDECODED, PI_WARN, "No extended source address - can't decrypt");
-            break;
+            call_dissector(data_handle, payload_tvb, pinfo, tree);
+            goto dissect_ieee802154_fcs;
 
         case DECRYPT_PACKET_NO_KEY:
             expert_add_info_format(pinfo, proto_root, PI_UNDECODED, PI_WARN, "No encryption key set - can't decrypt");
-            break;
+            call_dissector(data_handle, payload_tvb, pinfo, tree);
+            goto dissect_ieee802154_fcs;
 
         case DECRYPT_PACKET_DECRYPT_FAILED:
             expert_add_info_format(pinfo, proto_root, PI_UNDECODED, PI_WARN, "Decrypt failed");
-            break;
+            call_dissector(data_handle, payload_tvb, pinfo, tree);
+            goto dissect_ieee802154_fcs;
 
         case DECRYPT_PACKET_MIC_CHECK_FAILED:
             expert_add_info_format(pinfo, proto_root, PI_UNDECODED, PI_WARN, "MIC check failed");
+            /*
+             * Abort only if the payload was encrypted, in which case we
+             * probably didn't decrypt the packet right (eg: wrong key).
+             */
+            if (IEEE802154_IS_ENCRYPTED(packet->security_level)) {
+                call_dissector(data_handle, payload_tvb, pinfo, tree);
+                goto dissect_ieee802154_fcs;
+            }
             break;
-
-        case DECRYPT_PACKET_NO_PAYLOAD:
-            break;
-        }
-        if (!payload_tvb) {
-            /* Display the remaining payload using the data dissector. */
-            payload_tvb = tvb_new_subset(tvb, offset, -1, tvb_reported_length(tvb)-offset-IEEE802154_FCS_LEN);
-            tvb_set_reported_length(payload_tvb, tvb_reported_length(tvb)-offset-IEEE802154_FCS_LEN);
-            call_dissector(data_handle, payload_tvb, pinfo, tree);
-            goto dissect_ieee802154_fcs;
         }
     }
     /* Plaintext Payload. */
     else {
-        payload_tvb = tvb_new_subset(tvb, offset, -1, tvb_reported_length(tvb)-offset-IEEE802154_FCS_LEN);
-        tvb_set_reported_length(payload_tvb, tvb_reported_length(tvb)-offset-IEEE802154_FCS_LEN);
+        /* Deal with possible truncation and the FCS field at the end. */
+        gint            reported_len = tvb_reported_length(tvb)-offset-IEEE802154_FCS_LEN;
+        gint            captured_len = tvb_length(tvb)-offset;
+        if (reported_len < captured_len) captured_len = reported_len;
+        payload_tvb = tvb_new_subset(tvb, offset, captured_len, reported_len);
     }
 
     /*
@@ -1041,12 +1047,14 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
 
               case IEEE802154_CMD_DATA_RQ:
                 IEEE802154_CMD_ADDR_CHECK(pinfo, proto_root, packet->command_id, packet->src_addr_mode != IEEE802154_FCF_ADDR_NONE);
+                /* No payload expected. */
                 break;
 
               case IEEE802154_CMD_PANID_ERR:
                 IEEE802154_CMD_ADDR_CHECK(pinfo, proto_root, packet->command_id,
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_EXT) &&
                     (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT));
+                /* No payload expected. */
                 break;
 
               case IEEE802154_CMD_ORPH_NOTIF:
@@ -1056,6 +1064,7 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
                     (packet->dst.addr16 == IEEE802154_BCAST_ADDR) &&
                     (packet->src_pan == IEEE802154_BCAST_PAN) &&
                     (packet->dst_pan == IEEE802154_BCAST_PAN));
+                /* No payload expected. */
                 break;
 
               case IEEE802154_CMD_BCN_RQ:
@@ -1064,6 +1073,7 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
                     (packet->src_addr_mode == IEEE802154_FCF_ADDR_NONE) &&
                     (packet->dst.addr16 == IEEE802154_BCAST_ADDR) &&
                     (packet->dst_pan == IEEE802154_BCAST_PAN));
+                /* No payload expected. */
                 break;
 
               case IEEE802154_CMD_COORD_REAL:
@@ -1093,7 +1103,6 @@ dissect_ieee802154_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
                 call_dissector(data_handle, payload_tvb, pinfo, ieee802154_tree);
                 break;
             } /* switch */
-
         }
         /* Otherwise, dump whatever is left over to the data dissector. */
         else {
@@ -1679,44 +1688,34 @@ dissect_ieee802154_gtsreq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
  *      ieee802154_packet *packet   - IEEE 802.15.4 packet information.
  *      ws_decrypt_status *status   - status of decryption returned through here on failure.
  *  RETURNS
- *      tvbuff_t *                  - Decrypted payload, or NULL on decryption failure.
+ *      tvbuff_t *                  - Decrypted payload.
  *---------------------------------------------------------------
  */
 static tvbuff_t *
 dissect_ieee802154_decrypt(tvbuff_t * tvb, guint offset, packet_info * pinfo, ieee802154_packet * packet, ws_decrypt_status * status)
 {
-    tvbuff_t *          dec_tvb;
+    tvbuff_t *          ptext_tvb;
     gboolean            have_mic = FALSE;
     guint64             srcAddr;
     unsigned char       key[16];
     unsigned char       tmp[16];
     unsigned char       rx_mic[16];
-    guint               M;
-    void *              text;
-    guint               captured_len;
-    guint               reported_len;
+    guint               M = IEEE802154_MIC_LENGTH(packet->security_level);
+    gint                captured_len;
+    gint                reported_len;
 
     /* Get the captured and on-the-wire length of the payload. */
-    captured_len = tvb_length(tvb);
-    reported_len = tvb_reported_length(tvb);
-
-    /*
-     * If the payload is not encrypted, then we can get out now.
-     *
-     * NOTE: even though the payload may not be encrypted, it might still
-     * be verified by an authentication tag. By exiting early we are
-     * skipping the message verification proceedure.
-     *
-     * I'm not sure if we really care or not whether the tag is valid. If
-     * anyone feels strongly about it, you're welcome to modify the code to
-     * implement it. If you do go down that route, don't forget that l(m)==0
-     * and 'a' includes the payload when security_level < encryption.
-     *
-     * XXX - this probably shouldn't include the MIC.
-     */
-    if (!IEEE802154_IS_ENCRYPTED(packet->security_level)) {
-        *status = DECRYPT_NOT_ENCRYPTED;
-        return tvb_new_subset(tvb, offset, captured_len, reported_len);
+    reported_len = tvb_reported_length_remaining(tvb, offset) - IEEE802154_FCS_LEN - M;
+    if (reported_len < 0) {
+        *status = DECRYPT_PACKET_TOO_SMALL;
+        return NULL;
+    }
+    /* Check of the payload is truncated.  */
+    if (tvb_bytes_exist(tvb, offset, reported_len)) {
+        captured_len = reported_len;
+    }
+    else {
+        captured_len = tvb_length_remaining(tvb, offset);
     }
 
     /* Check the version, we only support IEEE 802.15.4-2006 */
@@ -1725,47 +1724,10 @@ dissect_ieee802154_decrypt(tvbuff_t * tvb, guint offset, packet_info * pinfo, ie
         return NULL;
     }
 
-    /* Is there at least enough room for the FCS? */
-    if (reported_len < IEEE802154_FCS_LEN) {
-        /* No - the FCS is past the end of the packet */
-        *status = DECRYPT_PACKET_TOO_SMALL;
-        return NULL;
-    }
-    if (captured_len < IEEE802154_FCS_LEN) {
-        /* No - the FCS is past the end of the captured_data */
-        *status = DECRYPT_SNAPLEN_TOO_SMALL;
-        return NULL;
-    }
-    reported_len -= IEEE802154_FCS_LEN;
-    if (captured_len > reported_len)
-        captured_len = reported_len;
-
-    /*
-     * Compute the length of the MIC from the security level.
-     * IEEE802154_MIC_LENGTH() returns a value that's either 0, 4, 8, or 16.
-     */
-    M = IEEE802154_MIC_LENGTH(packet->security_level);
-    /*
-     * If 'M' is non-zero, and the last 'M' bytes of the payload exist,
-     * then parse the MIC.
-     *
-     * "The last 'M' bytes of the payload exist" only if the payload
-     * wasn't cut short by the snapshot length, i.e. only if
-     * captured_len >= reported_len (captured_len shouldn't be >
-     * reported_len, but...).
-     */
-    if (M != 0) {
-        if (reported_len < M) {
-            *status = DECRYPT_PACKET_TOO_SMALL;
-            return NULL;       /* packet too short for the MIC */
-        }
-        if (captured_len >= reported_len) {
-            have_mic = TRUE;
-            tvb_memcpy(tvb, rx_mic, reported_len - M, M);
-        }
-        reported_len -= M;
-        if (captured_len > reported_len)
-            captured_len = reported_len;
+    /* Check if the MIC is present in the captured data. */
+    have_mic = tvb_bytes_exist(tvb, offset + reported_len, M);
+    if (have_mic) {
+        tvb_memcpy(tvb, rx_mic, offset + reported_len, M);
     }
 
     /*=====================================================
@@ -1804,21 +1766,48 @@ dissect_ieee802154_decrypt(tvbuff_t * tvb, guint offset, packet_info * pinfo, ie
     }
     memcpy(key, ieee802154_key, IEEE802154_CIPHER_SIZE);
 
-    /* Make a copy of the ciphertext w/o the MIC. */
-    /* We will decrypt the message in-place and then use this for the new tvb. */
-    text = tvb_memdup(tvb, offset, captured_len);
-
     /*=====================================================
      * CCM* - CTR mode payload encryption
      *=====================================================
      */
     /* Create the CCM* initial block for decryption (Adata=0, M=0, counter=0). */
     ccm_init_block(tmp, FALSE, 0, srcAddr, packet->frame_counter, packet->security_level, 0);
-    /* Perform CTR-mode transformation. */
-    if (!ccm_ctr_encrypt(key, tmp, rx_mic, text, captured_len)) {
-        g_free(text);
-        *status = DECRYPT_PACKET_DECRYPT_FAILED;
-        return NULL;
+
+    /* Decrypt the ciphertext, and place the plaintext in a new tvb. */
+    if (IEEE802154_IS_ENCRYPTED(packet->security_level) && captured_len) {
+        void *          text;
+        /*
+         * Make a copy of the ciphertext in heap memory.
+         *
+         * We will decrypt the message in-place and then use the buffer as the
+         * real data for the new tvb.
+         */
+        text = tvb_memdup(tvb, offset, captured_len);
+
+        /* Perform CTR-mode transformation. */
+        if (!ccm_ctr_encrypt(key, tmp, rx_mic, text, captured_len)) {
+            g_free(text);
+            *status = DECRYPT_PACKET_DECRYPT_FAILED;
+            return NULL;
+        }
+
+        /* Create a tvbuff for the plaintext. */
+        ptext_tvb = tvb_new_real_data(text, captured_len, reported_len);
+        tvb_set_child_real_data_tvbuff(tvb, ptext_tvb);
+        add_new_data_source(pinfo, ptext_tvb, "Decrypted IEEE 802.15.4 payload");
+        *status = DECRYPT_PACKET_SUCCEEDED;
+    }
+    /* There is no ciphertext. Wrap the plaintext in a new tvb. */
+    else {
+        /* Decrypt the MIC (if present). */
+        if ((have_mic) && (!ccm_ctr_encrypt(key, tmp, rx_mic, NULL, 0))) {
+            *status = DECRYPT_PACKET_DECRYPT_FAILED;
+            return NULL;
+        }
+
+        /* Create a tvbuff for the plaintext. This might result in a zero-length tvbuff. */
+        ptext_tvb = tvb_new_subset(tvb, offset, captured_len, reported_len);
+        *status = DECRYPT_PACKET_SUCCEEDED;
     }
 
     /*=====================================================
@@ -1828,36 +1817,37 @@ dissect_ieee802154_decrypt(tvbuff_t * tvb, guint offset, packet_info * pinfo, ie
     /* We can only verify the message if the MIC wasn't truncated. */
     if (have_mic) {
         unsigned char           dec_mic[16];
+        guint                   l_m = captured_len;
+        guint                   l_a = offset;
+
+        /* Adjust the lengths of the plantext and additional data if unencrypted. */
+        if (!IEEE802154_IS_ENCRYPTED(packet->security_level)) {
+            l_a += l_m;
+            l_m = 0;
+        }
 
         /* Create the CCM* initial block for authentication (Adata!=0, M!=0, counter=l(m)). */
-        ccm_init_block(tmp, TRUE, M, srcAddr, packet->frame_counter, packet->security_level, captured_len);
+        ccm_init_block(tmp, TRUE, M, srcAddr, packet->frame_counter, packet->security_level, l_m);
+
         /* Compute CBC-MAC authentication tag. */
-        if (!ccm_cbc_mac(key, tmp, ep_tvb_memdup(tvb, 0, offset), offset, text, captured_len, dec_mic)) {
-            g_free(text);
+        /*
+         * And yes, despite the warning in tvbuff.h, I think tvb_get_ptr is the
+         * right function here since either A) the payload wasn't encrypted, in
+         * which case l_m is zero, or B) the payload was encrypted, and the tvb
+         * already points to contiguous memory, since we just allocated it in
+         * decryption phase.
+         */
+        if (!ccm_cbc_mac(key, tmp, ep_tvb_memdup(tvb, 0, l_a), l_a, tvb_get_ptr(ptext_tvb, 0, l_m), l_m, dec_mic)) {
             *status = DECRYPT_PACKET_MIC_CHECK_FAILED;
-            return NULL;
         }
-
         /* Compare the received MIC with the one we generated. */
-        if (memcmp(rx_mic, dec_mic, M) != 0) {
-            g_free(text);
+        else if (memcmp(rx_mic, dec_mic, M) != 0) {
             *status = DECRYPT_PACKET_MIC_CHECK_FAILED;
-            return NULL;
         }
     }
 
-    /* Done! Do we actually have any decrypted payload? */
-    if (captured_len == 0) {
-        /* No. */
-        *status = DECRYPT_PACKET_NO_PAYLOAD;
-        return NULL;
-    }
-    /* Yes */
-    dec_tvb = tvb_new_real_data(text, captured_len, reported_len);
-    tvb_set_child_real_data_tvbuff(tvb, dec_tvb);
-    add_new_data_source(pinfo, dec_tvb, "IEEE 802.15.4 decryption");
-    *status = DECRYPT_PACKET_SUCCEEDED;
-    return dec_tvb;
+    /* Done! */
+    return ptext_tvb;
 } /* dissect_ieee802154_decrypt */
 
 /*FUNCTION:------------------------------------------------------
index be82660bb85736eae28f9996f8ae29b39ea51fa0..8b9a4d080f55c9cc77fcaf60816a6958ccde7d89 100644 (file)
@@ -80,7 +80,7 @@ enum
 {
    SCSI_STAT_PROG_LABEL_SBC,
    SCSI_STAT_PROG_LABEL_SSC,
-   SCSI_STAT_PROG_LABEL_MMC,
+   SCSI_STAT_PROG_LABEL_MMC
 };
 
 
@@ -107,7 +107,7 @@ scsistat_set_title(scsistat_t *rs)
 static void
 scsistat_reset(void *arg)
 {
-       scsistat_t *rs = arg;
+       scsistat_t *rs = (scsistat_t *)arg;
 
        reset_srt_table_data(&rs->srt_table);
        scsistat_set_title(rs);
@@ -145,8 +145,8 @@ scsistat_program_select(GtkWidget *w, gpointer key _U_)
 static int
 scsistat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *arg2)
 {
-       scsistat_t *rs = arg;
-       const scsi_task_data_t *ri = arg2;
+       scsistat_t *rs = (scsistat_t *)arg;
+       const scsi_task_data_t *ri = (const scsi_task_data_t *)arg2;
 
        /* we are only interested in response packets */
        if(ri->type!=SCSI_PDU_TYPE_RSP){
@@ -169,7 +169,7 @@ scsistat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const vo
 static void
 scsistat_draw(void *arg)
 {
-       scsistat_t *rs = arg;
+       scsistat_t *rs = (scsistat_t *)arg;
 
        draw_srt_table_data(&rs->srt_table);
 }
@@ -213,7 +213,7 @@ gtk_scsistat_init(const char *optarg, void* userdata _U_)
        int program, pos;
        const char *filter=NULL;
        GString *error_string;
-       char *hf_name=NULL;
+       const char *hf_name=NULL;
 
        pos=0;
        if(sscanf(optarg,"scsi,srt,%d,%n",&program,&pos)==1){
@@ -228,7 +228,7 @@ gtk_scsistat_init(const char *optarg, void* userdata _U_)
        }
 
        scsi_program=program;
-       rs=g_malloc(sizeof(scsistat_t));
+       rs=(scsistat_t *)g_malloc(sizeof(scsistat_t));
         rs->cmdset=program;
         switch(program){
        case SCSI_DEV_SBC:
@@ -301,7 +301,7 @@ gtk_scsistat_init(const char *optarg, void* userdata _U_)
        bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
        gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
 
-       close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
+       close_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
        window_set_cancel_button(rs->win, close_bt, window_cancel_button_cb);
 
        g_signal_connect(rs->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
@@ -427,11 +427,11 @@ gtk_scsistat_cb(GtkWidget *w _U_, gpointer d _U_)
        gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
         gtk_widget_show(bbox);
 
-        start_button = g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CREATE_STAT);
+        start_button = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CREATE_STAT);
         g_signal_connect_swapped(start_button, "clicked",
                             G_CALLBACK(scsistat_start_button_clicked), NULL);
 
-        cancel_button = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
+        cancel_button = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
         window_set_cancel_button(dlg, cancel_button, window_cancel_button_cb);
 
        /* Give the initial focus to the "Filter" entry box. */
diff --git a/print.c b/print.c
index 91d259b1ad9991fdc446d036ab51a2cff836d08d..984b31da4ab41fcac449e5b35e91a6233160b539 100644 (file)
--- a/print.c
+++ b/print.c
@@ -492,7 +492,7 @@ print_pdml_geninfo(proto_tree *tree, FILE *fh)
        if (g_ptr_array_len(finfo_array) < 1) {
                return;
        }
-       frame_finfo = finfo_array->pdata[0];
+       frame_finfo = (field_info *)finfo_array->pdata[0];
        g_ptr_array_free(finfo_array, TRUE);
 
        /* frame.number --> geninfo.num */
@@ -524,7 +524,7 @@ print_pdml_geninfo(proto_tree *tree, FILE *fh)
        if (g_ptr_array_len(finfo_array) < 1) {
                return;
        }
-       timestamp = fvalue_get(&((field_info*)finfo_array->pdata[0])->value);
+       timestamp = (nstime_t *)fvalue_get(&((field_info*)finfo_array->pdata[0])->value);
        g_ptr_array_free(finfo_array, TRUE);
 
        /* Print geninfo start */
@@ -692,7 +692,7 @@ get_field_data(GSList *src_list, field_info *fi)
        gint length, tvbuff_length;
 
        for (src_le = src_list; src_le != NULL; src_le = src_le->next) {
-               src = src_le->data;
+               src = (data_source *)src_le->data;
                src_tvb = src->tvb;
                if (fi->ds_tvb == src_tvb) {
                        /*
@@ -807,7 +807,7 @@ print_hex_data(print_stream_t *stream, epan_dissect_t *edt)
 
        for (src_le = edt->pi.data_src; src_le != NULL;
            src_le = src_le->next) {
-               src = src_le->data;
+               src = (data_source *)src_le->data;
                tvb = src->tvb;
                if (multiple_sources) {
                        name = get_data_source_name(src);
@@ -1012,7 +1012,7 @@ print_preamble_text(print_stream_t *self _U_, gchar *filename _U_)
 static gboolean
 print_line_text(print_stream_t *self, int indent, const char *line)
 {
-       output_text *output = self->data;
+       output_text *output = (output_text *)self->data;
        char space[MAX_INDENT+1];
        int i;
        int num_spaces;
@@ -1045,7 +1045,7 @@ print_bookmark_text(print_stream_t *self _U_, const gchar *name _U_,
 static gboolean
 new_page_text(print_stream_t *self)
 {
-       output_text *output = self->data;
+       output_text *output = (output_text *)self->data;
 
        fputs("\f", output->fh);
        return !ferror(output->fh);
@@ -1061,7 +1061,7 @@ print_finale_text(print_stream_t *self _U_)
 static gboolean
 destroy_text(print_stream_t *self)
 {
-       output_text *output = self->data;
+       output_text *output = (output_text *)self->data;
        gboolean ret;
 
        ret = close_print_dest(output->to_file, output->fh);
@@ -1085,10 +1085,10 @@ print_stream_text_alloc(int to_file, FILE *fh)
        print_stream_t *stream;
        output_text *output;
 
-       output = g_malloc(sizeof *output);
+       output = (output_text *)g_malloc(sizeof *output);
        output->to_file = to_file;
        output->fh = fh;
-       stream = g_malloc(sizeof (print_stream_t));
+       stream = (print_stream_t *)g_malloc(sizeof (print_stream_t));
        stream->ops = &print_text_ops;
        stream->data = output;
 
@@ -1121,7 +1121,7 @@ typedef struct {
 static gboolean
 print_preamble_ps(print_stream_t *self, gchar *filename)
 {
-       output_ps *output = self->data;
+       output_ps *output = (output_ps *)self->data;
        unsigned char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
 
        print_ps_preamble(output->fh);
@@ -1139,7 +1139,7 @@ print_preamble_ps(print_stream_t *self, gchar *filename)
 static gboolean
 print_line_ps(print_stream_t *self, int indent, const char *line)
 {
-       output_ps *output = self->data;
+       output_ps *output = (output_ps *)self->data;
        unsigned char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
 
        ps_clean_string(psbuffer, line, MAX_PS_LINE_LENGTH);
@@ -1150,7 +1150,7 @@ print_line_ps(print_stream_t *self, int indent, const char *line)
 static gboolean
 print_bookmark_ps(print_stream_t *self, const gchar *name, const gchar *title)
 {
-       output_ps *output = self->data;
+       output_ps *output = (output_ps *)self->data;
        unsigned char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
 
        /*
@@ -1180,7 +1180,7 @@ print_bookmark_ps(print_stream_t *self, const gchar *name, const gchar *title)
 static gboolean
 new_page_ps(print_stream_t *self)
 {
-       output_ps *output = self->data;
+       output_ps *output = (output_ps *)self->data;
 
        fputs("formfeed\n", output->fh);
        return !ferror(output->fh);
@@ -1189,7 +1189,7 @@ new_page_ps(print_stream_t *self)
 static gboolean
 print_finale_ps(print_stream_t *self)
 {
-       output_ps *output = self->data;
+       output_ps *output = (output_ps *)self->data;
 
        print_ps_finale(output->fh);
        return !ferror(output->fh);
@@ -1198,7 +1198,7 @@ print_finale_ps(print_stream_t *self)
 static gboolean
 destroy_ps(print_stream_t *self)
 {
-       output_ps *output = self->data;
+       output_ps *output = (output_ps *)self->data;
        gboolean ret;
 
        ret = close_print_dest(output->to_file, output->fh);
@@ -1222,10 +1222,10 @@ print_stream_ps_alloc(int to_file, FILE *fh)
        print_stream_t *stream;
        output_ps *output;
 
-       output = g_malloc(sizeof *output);
+       output = (output_ps *)g_malloc(sizeof *output);
        output->to_file = to_file;
        output->fh = fh;
-       stream = g_malloc(sizeof (print_stream_t));
+       stream = (print_stream_t *)g_malloc(sizeof (print_stream_t));
        stream->ops = &print_ps_ops;
        stream->data = output;
 
@@ -1286,7 +1286,7 @@ void output_fields_free(output_fields_t* fields)
     if(NULL != fields->fields) {
         gsize i;
         for(i = 0; i < fields->fields->len; ++i) {
-            gchar* field = g_ptr_array_index(fields->fields,i);
+            gchar* field = (gchar *)g_ptr_array_index(fields->fields,i);
             g_free(field);
         }
         g_ptr_array_free(fields->fields, TRUE);
@@ -1405,7 +1405,7 @@ void write_fields_preamble(output_fields_t* fields, FILE *fh)
     }
 
     for(i = 0; i < fields->fields->len; ++i) {
-        const gchar* field = g_ptr_array_index(fields->fields,i);
+        const gchar* field = (const gchar *)g_ptr_array_index(fields->fields,i);
         if(i != 0 ) {
             fputc(fields->separator, fh);
         }
@@ -1420,7 +1420,7 @@ static void proto_tree_get_node_field_values(proto_node *node, gpointer data)
     field_info *fi;
     gpointer field_index;
 
-    call_data = data;
+    call_data = (write_field_data_t *)data;
     fi = PNODE_FINFO(node);
 
     g_assert(fi && "dissection with an invisible proto tree?");
@@ -1465,7 +1465,7 @@ void proto_tree_write_fields(output_fields_t* fields, epan_dissect_t *edt, FILE
 
         i = 0;
         while( i < fields->fields->len) {
-            gchar* field = g_ptr_array_index(fields->fields, i);
+            gchar* field = (gchar *)g_ptr_array_index(fields->fields, i);
              /* Store field indicies +1 so that zero is not a valid value,
               * and can be distinguished from NULL as a pointer.
               */
index b32f03caf20a79227dbce25515f85b848bbe5d00..94efe0b5c710801bcf0f7925e5335c9e24f10a4f 100644 (file)
@@ -200,7 +200,7 @@ ringbuf_init(const char *capfile_name, guint num_files)
     rb_data.num_files = 1;
   }
 
-  rb_data.files = g_malloc(rb_data.num_files * sizeof(rb_file));
+  rb_data.files = (rb_file *)g_malloc(rb_data.num_files * sizeof(rb_file));
   if (rb_data.files == NULL) {
     return -1;
   }
index 3e94be6cda2bb0e32029b90c6b9981a49e750759..f7d8eb35d27f84f219c24983867f8687daa5b735 100644 (file)
@@ -240,7 +240,7 @@ diameteravp_init(const char *optarg, void* userdata _U_)
        }
        filter_len=strlen(optarg)+sizeof("diameter")+field_count*sizeof("||diameter.");
        ds->filter=g_malloc0(filter_len);
-       strcat(ds->filter,"diameter");
+       g_strlcat(ds->filter, "diameter", filter_len);
 
 #if defined (_WIN32)
        for(str=strtok_s(options+sizeof("diameter,avp"),",",&saveptr);str;str=strtok_s(NULL,",",&saveptr))
@@ -249,12 +249,12 @@ diameteravp_init(const char *optarg, void* userdata _U_)
 #endif
        {
                /* Connect all requested fields with logical OR. */
-               strcat(ds->filter,"||");
+               g_strlcat(ds->filter, "||", filter_len);
                /* Prefix field name with "diameter." by default. */
                if(!strchr(str,'.'))
-                       strcat(ds->filter,"diameter.");
+                       g_strlcat(ds->filter, "diameter.", filter_len);
                /* Append field name to the filter. */
-               strcat(ds->filter,str);
+               g_strlcat(ds->filter, str, filter_len);
        }
        g_free(options);
 
index 1a292b5fc73d472dd6a8309dcd6b782626110174..7a6b5656f93ade2cdc44ee304c9758348e5d3557 100644 (file)
@@ -175,7 +175,7 @@ create_tempfile(char **namebuf, const char *pfx)
         */
        if (tf_path[idx] == NULL) {
                tf_path_len[idx] = INITIAL_PATH_SIZE;
-               tf_path[idx] = g_malloc(tf_path_len[idx]);
+               tf_path[idx] = (char *)g_malloc(tf_path_len[idx]);
        }
 
        /*
@@ -185,7 +185,7 @@ create_tempfile(char **namebuf, const char *pfx)
 
        while (g_snprintf(tf_path[idx], tf_path_len[idx], "%s%c%s" TMP_FILE_SUFFIX, tmp_dir, G_DIR_SEPARATOR, pfx) > tf_path_len[idx]) {
                tf_path_len[idx] *= 2;
-               tf_path[idx] = g_realloc(tf_path[idx], tf_path_len[idx]);
+               tf_path[idx] = (char *)g_realloc(tf_path[idx], tf_path_len[idx]);
        }
 
        if (namebuf) {
@@ -226,7 +226,7 @@ create_tempdir(char **namebuf, const char *pfx)
         */
        if (td_path[idx] == NULL) {
                td_path_len[idx] = INITIAL_PATH_SIZE;
-               td_path[idx] = g_malloc(td_path_len[idx]);
+               td_path[idx] = (char *)g_malloc(td_path_len[idx]);
        }
 
        /*
@@ -236,7 +236,7 @@ create_tempdir(char **namebuf, const char *pfx)
 
        while (g_snprintf(td_path[idx], td_path_len[idx], "%s%c%s" TMP_FILE_SUFFIX, tmp_dir, G_DIR_SEPARATOR, pfx) > td_path_len[idx]) {
                td_path_len[idx] *= 2;
-               td_path[idx] = g_realloc(td_path[idx], td_path_len[idx]);
+               td_path[idx] = (char *)g_realloc(td_path[idx], td_path_len[idx]);
        }
 
        if (namebuf) {
diff --git a/util.c b/util.c
index a86b48afd34a7c09c9e971927294b062c37ab812..cbf010a19bd641238385defe3aef1b6b685163da 100644 (file)
--- a/util.c
+++ b/util.c
@@ -66,7 +66,7 @@ get_args_as_string(int argc, char **argv, int optindex)
        /*
         * Allocate the buffer for the string.
         */
-       argstring = g_malloc(len);
+       argstring = (char *)g_malloc(len);
 
        /*
         * Now construct the string.
@@ -255,7 +255,7 @@ const gchar *get_conn_cfilter(void) {
                if (hostlen == 0)
                        return "";      /* no hostname supplied */
 
-               phostname = g_malloc(hostlen + 1);
+               phostname = (char *)g_malloc(hostlen + 1);
                memcpy(phostname, lastp, hostlen);
                phostname[hostlen] = '\0';