Add the abillity to read and write option comments unedited.
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 11 Feb 2012 12:34:39 +0000 (12:34 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 11 Feb 2012 12:34:39 +0000 (12:34 +0000)
This is POC we may want to have more efficient use of the frame data
structure etc. But this allows for work to be done on the GUI to actually add comments.

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

epan/dissectors/packet-frame.c
epan/frame_data.c
epan/frame_data.h
file.c
wiretap/pcapng.c
wiretap/wtap-int.h
wiretap/wtap.h

index 700b3ab..8bf1436 100644 (file)
@@ -45,6 +45,7 @@
 #include "color_filters.h"
 
 int proto_frame = -1;
+int proto_pkt_comment = -1;
 int hf_frame_arrival_time = -1;
 int hf_frame_shift_offset = -1;
 int hf_frame_arrival_time_epoch = -1;
@@ -65,12 +66,15 @@ static int hf_link_number = -1;
 static int hf_frame_protocols = -1;
 static int hf_frame_color_filter_name = -1;
 static int hf_frame_color_filter_text = -1;
+static int hf_frame_interface_id = -1;
+static int hf_comments_text = -1;
 
 static int proto_short = -1;
 int proto_malformed = -1;
 static int proto_unreassembled = -1;
 
 static gint ett_frame = -1;
+static gint ett_comments = -1;
 
 static int frame_tap = -1;
 
@@ -121,7 +125,8 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        proto_item      *volatile ti = NULL;
        guint           cap_len = 0, frame_len = 0;
        proto_tree      *volatile tree;
-        proto_item  *item;
+       proto_tree  *comments_tree;
+    proto_item  *item;
        const gchar *cap_plurality, *frame_plurality;
 
        tree=parent_tree;
@@ -177,6 +182,15 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                }
        }
 
+       if(pinfo->fd->opt_comment){
+               item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, -1, ENC_NA);
+               comments_tree = proto_item_add_subtree(item, ett_comments);
+               proto_tree_add_string_format(comments_tree, hf_comments_text, tvb, 0, -1,
+                                                                          pinfo->fd->opt_comment, "%s",
+                                                                          pinfo->fd->opt_comment);
+
+       }
+
        /* if FRAME is not referenced from any filters we dont need to worry about
           generating any tree items.  */
        if(!proto_field_is_referenced(tree, proto_frame)) {
@@ -197,16 +211,18 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
 
                if (generate_bits_field)
                        ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1,
-                           "Frame %u: %u byte%s on wire (%u bits), %u byte%s captured (%u bits)",
+                           "Frame %u: %u byte%s on wire (%u bits), %u byte%s captured (%u bits) on interface %u",
                            pinfo->fd->num, frame_len, frame_plurality, frame_len * 8,
-                           cap_len, cap_plurality, cap_len * 8);
+                           cap_len, cap_plurality, cap_len * 8, pinfo->fd->interface_id);
                else
                        ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1,
-                           "Frame %u: %u byte%s on wire, %u byte%s captured", pinfo->fd->num,
-                            frame_len, frame_plurality, cap_len, cap_plurality);
+                           "Frame %u: %u byte%s on wire, %u byte%s captured, on interface %u", pinfo->fd->num,
+                            frame_len, frame_plurality, cap_len, cap_plurality, pinfo->fd->interface_id);
 
                fh_tree = proto_item_add_subtree(ti, ett_frame);
 
+               proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->fd->interface_id);
+
                proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb,
                                    0, 0, &(pinfo->fd->abs_ts));
                if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) {
@@ -619,10 +635,19 @@ proto_register_frame(void)
 
                { &hf_frame_color_filter_text,
                { "Coloring Rule String", "frame.coloring_rule.string", FT_STRING, BASE_NONE, NULL, 0x0,
-                       "The frame matched this coloring rule string", HFILL }}
+                       "The frame matched this coloring rule string", HFILL }},
+
+               { &hf_frame_interface_id,
+               { "Interface id",               "frame.interface_id", FT_UINT32, BASE_DEC, NULL, 0x0,
+                       NULL, HFILL }},
+
+               { &hf_comments_text,
+               { "Comment", "comment", FT_STRING, BASE_NONE, NULL, 0x0,
+                       NULL, HFILL }},
        };
        static gint *ett[] = {
-               &ett_frame
+               &ett_frame,
+               &ett_comments
        };
        module_t *frame_module;
 
@@ -630,6 +655,7 @@ proto_register_frame(void)
            "Wiretap encapsulation type", FT_UINT32, BASE_DEC);
 
        proto_frame = proto_register_protocol("Frame", "Frame", "frame");
+       proto_pkt_comment = proto_register_protocol("Packet comments", "Pkt_Comment", "pkt_comment");
        proto_register_field_array(proto_frame, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
        register_dissector("frame",dissect_frame,proto_frame);
index a233c75..08609c4 100644 (file)
@@ -194,6 +194,7 @@ frame_data_init(frame_data *fdata, guint32 num,
 {
   fdata->pfd = NULL;
   fdata->num = num;
+  fdata->interface_id = phdr->interface_id;
   fdata->pkt_len = phdr->len;
   fdata->cum_bytes = cum_bytes + phdr->len;
   fdata->cap_len = phdr->caplen;
@@ -212,6 +213,7 @@ frame_data_init(frame_data *fdata, guint32 num,
   fdata->flags.ref_time = 0;
   fdata->flags.ignored = 0;
   fdata->color_filter = NULL;
+  fdata->opt_comment = phdr->opt_comment;
 }
 
 void
index df9b7ba..cdf8704 100644 (file)
    it's 1-origin.  In various contexts, 0 as a frame number means "frame
    number unknown". */
 typedef struct _frame_data {
-  GSList      *pfd;         /**< Per frame proto data */
-  guint32      num;         /**< Frame number */
-  guint32      pkt_len;     /**< Packet length */
-  guint32      cap_len;     /**< Amount actually captured */
-  guint32      cum_bytes;   /**< Cumulative bytes into the capture */
-  gint64       file_off;    /**< File offset */
-  guint16      subnum;      /**< subframe number, for protocols that require this */
-  gint16       lnk_t;       /**< Per-packet encapsulation/data-link type */
+  GSList      *pfd;          /**< Per frame proto data */
+  guint32      num;          /**< Frame number */
+  guint32      interface_id; /**< identifier of the interface. */
+  guint32      pkt_len;      /**< Packet length */
+  guint32      cap_len;      /**< Amount actually captured */
+  guint32      cum_bytes;    /**< Cumulative bytes into the capture */
+  gint64       file_off;     /**< File offset */
+  guint16      subnum;       /**< subframe number, for protocols that require this */
+  gint16       lnk_t;        /**< Per-packet encapsulation/data-link type */
   struct {
     unsigned int passed_dfilter : 1; /**< 1 = display, 0 = no display */
     unsigned int encoding       : 2; /**< Character encoding (ASCII, EBCDIC...) */
@@ -57,13 +58,14 @@ typedef struct _frame_data {
     unsigned int ignored        : 1; /**< 1 = ignore this frame, 0 = normal */
   } flags;
 
-  const void *color_filter; /**< Per-packet matching color_filter_t object */
+  const void *color_filter;  /**< Per-packet matching color_filter_t object */
 
-  nstime_t     abs_ts;      /**< Absolute timestamp */
-  nstime_t     shift_offset;/**< How much the abs_tm of the frame is shifted */
-  nstime_t     rel_ts;      /**< Relative timestamp (yes, it can be negative) */
-  nstime_t     del_dis_ts;  /**< Delta timestamp to previous displayed frame (yes, it can be negative) */
-  nstime_t     del_cap_ts;  /**< Delta timestamp to previous captured frame (yes, it can be negative) */
+  nstime_t     abs_ts;       /**< Absolute timestamp */
+  nstime_t     shift_offset; /**< How much the abs_tm of the frame is shifted */
+  nstime_t     rel_ts;       /**< Relative timestamp (yes, it can be negative) */
+  nstime_t     del_dis_ts;   /**< Delta timestamp to previous displayed frame (yes, it can be negative) */
+  nstime_t     del_cap_ts;   /**< Delta timestamp to previous captured frame (yes, it can be negative) */
+  gchar        *opt_comment; /**< NULL if not available */
 } frame_data;
 
 #ifdef WANT_PACKET_EDITOR
diff --git a/file.c b/file.c
index 22c6bcf..48dfb5f 100644 (file)
--- a/file.c
+++ b/file.c
@@ -3645,12 +3645,19 @@ save_packet(capture_file *cf _U_, frame_data *fdata,
   int           err;
 
   /* init the wtap header for saving */
-  hdr.ts.secs    = fdata->abs_ts.secs;
-  hdr.ts.nsecs   = fdata->abs_ts.nsecs;
-  hdr.caplen     = fdata->cap_len;
-  hdr.len        = fdata->pkt_len;
-  hdr.pkt_encap  = fdata->lnk_t;
-
+  hdr.ts.secs      = fdata->abs_ts.secs;
+  hdr.ts.nsecs     = fdata->abs_ts.nsecs;
+  hdr.caplen       = fdata->cap_len;
+  hdr.len          = fdata->pkt_len;
+  hdr.pkt_encap    = fdata->lnk_t;
+  /* pcapng */
+  hdr.interface_id = fdata->interface_id;   /* identifier of the interface. */
+  /* options */
+  hdr.opt_comment  = fdata->opt_comment; /* NULL if not available */
+#if 0
+  hdr.drop_count   =
+  hdr.pack_flags   =     /* XXX - 0 for now (any value for "we don't have it"?) */
+#endif
   /* and save the packet */
   if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
     if (err < 0) {
index 1f0db90..e0f4775 100644 (file)
@@ -946,8 +946,8 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
                        break;
                    case(1): /* opt_comment */
                        if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
-                               wblock->data.packet.opt_comment = g_strndup(option_content, sizeof(option_content));
-                               pcapng_debug1("pcapng_read_packet_block: opt_comment %s", wblock->data.packet.opt_comment);
+                               wblock->data.packet.opt_comment = g_strndup(option_content, oh.option_length);
+                               pcapng_debug2("pcapng_read_packet_block: length %u opt_comment '%s'", oh.option_length, wblock->data.packet.opt_comment);
                        } else {
                                pcapng_debug1("pcapng_read_packet_block: opt_comment length %u seems strange", oh.option_length);
                        }
@@ -1560,7 +1560,6 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
                wth->phdr.ts.nsecs = (int)(((ts % time_units_per_second) * 1000000000) / time_units_per_second);
 
                wth->phdr.interface_id = wblock.data.packet.interface_id;
-               wth->phdr.drops_count  = wblock.data.packet.drops_count;
                wth->phdr.opt_comment  = wblock.data.packet.opt_comment;
                wth->phdr.drop_count   = wblock.data.packet.drop_count;
                wth->phdr.pack_flags   = wblock.data.packet.pack_flags;
@@ -1738,6 +1737,10 @@ pcapng_write_packet_block(wtap_dumper *wdh, wtapng_block_t *wblock, int *err)
        const guint32 zero_pad = 0;
        guint32 pad_len;
        guint32 phdr_len;
+       gboolean have_options = FALSE;
+       guint32 options_total_length = 0;
+       guint32 options_hdr = 0; 
+       guint32 comment_len = 0, comment_pad_len = 0;
 
        phdr_len = (guint32)pcap_get_phdr_size(wblock->data.packet.wtap_encap, wblock->pseudo_header);
        if ((phdr_len + wblock->data.packet.cap_len) % 4) {
@@ -1746,9 +1749,27 @@ pcapng_write_packet_block(wtap_dumper *wdh, wtapng_block_t *wblock, int *err)
                pad_len = 0;
        }
 
+       /* Check if we should write comment option */
+       if(wblock->data.packet.opt_comment){
+               have_options = TRUE;
+               comment_len = (guint32)strlen(wblock->data.packet.opt_comment) & 0xffff;
+               if((comment_len % 4)){
+                       comment_pad_len = 4 - (comment_len % 4);
+               }else{
+                       comment_pad_len = 0;
+               }
+               options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
+       }
+
+       if(have_options){
+               /* End-of optios tag */
+               options_total_length += 4;
+       }
+
+
        /* write (enhanced) packet block header */
        bh.block_type = wblock->type;
-       bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(epb) + phdr_len + wblock->data.packet.cap_len + pad_len /* + options */ + 4;
+       bh.block_total_length = (guint32)sizeof(bh) + (guint32)sizeof(epb) + phdr_len + wblock->data.packet.cap_len + pad_len + options_total_length + 4;
 
        if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
                return FALSE;
@@ -1785,6 +1806,59 @@ pcapng_write_packet_block(wtap_dumper *wdh, wtapng_block_t *wblock, int *err)
        }
 
        /* XXX - write (optional) block options */
+       /* options defined in Section 2.5 (Options) 
+        * Name           Code Length     Description 
+        * opt_comment    1    variable   A UTF-8 string containing a comment that is associated to the current block. 
+        *
+        * Enhanced Packet Block options
+        * epb_flags      2    4          A flags word containing link-layer information. A complete specification of 
+        *                                the allowed flags can be found in Appendix A (Packet Block Flags Word). 
+        * epb_hash       3    variable   This option contains a hash of the packet. The first byte specifies the hashing algorithm, 
+        *                                while the following bytes contain the actual hash, whose size depends on the hashing algorithm, 
+        *                                                                and hence from the value in the first bit. The hashing algorithm can be: 2s complement 
+        *                                                                (algorithm byte = 0, size=XXX), XOR (algorithm byte = 1, size=XXX), CRC32 (algorithm byte = 2, size = 4), 
+        *                                                                MD-5 (algorithm byte = 3, size=XXX), SHA-1 (algorithm byte = 4, size=XXX). 
+        *                                                                The hash covers only the packet, not the header added by the capture driver: 
+        *                                                                this gives the possibility to calculate it inside the network card. 
+        *                                                                The hash allows easier comparison/merging of different capture files, and reliable data transfer between the 
+        *                                                                data acquisition system and the capture library. 
+        * epb_dropcount   4   8          A 64bit integer value specifying the number of packets lost (by the interface and the operating system) 
+        *                                between this packet and the preceding one.
+        * opt_endofopt    0   0          It delimits the end of the optional fields. This block cannot be repeated within a given list of options. 
+        */
+       if(wblock->data.packet.opt_comment){
+               options_hdr = comment_len;
+               options_hdr = options_hdr << 16;
+               /* Option 1  */
+               options_hdr += 1;
+               if (!wtap_dump_file_write(wdh, &options_hdr, 4, err))
+                       return FALSE;
+               wdh->bytes_dumped += 4;
+
+               /* Write the comments string */
+               pcapng_debug3("pcapng_write_packet_block, comment:'%s' comment_len %u comment_pad_len %u" , wblock->data.packet.opt_comment, comment_len, comment_pad_len);
+               if (!wtap_dump_file_write(wdh, wblock->data.packet.opt_comment, comment_len, err))
+                       return FALSE;
+               wdh->bytes_dumped += comment_len;
+
+               /* write padding (if any) */
+               if (comment_pad_len != 0) {
+                       if (!wtap_dump_file_write(wdh, &zero_pad, comment_pad_len, err))
+                               return FALSE;
+                       wdh->bytes_dumped += comment_pad_len;
+               }
+
+               pcapng_debug2("pcapng_write_packet_block: Wrote Options comments: comment_len %u, comment_pad_len %u",
+                       comment_len,
+                       comment_pad_len);
+       }
+
+       /* Write end of options if we have otions */
+       if(have_options){
+               if (!wtap_dump_file_write(wdh, &zero_pad, 4, err))
+                       return FALSE;
+               wdh->bytes_dumped += 4;
+       }
 
        /* write block footer */
        if (!wtap_dump_file_write(wdh, &bh.block_total_length,
@@ -2017,8 +2091,8 @@ static gboolean pcapng_dump(wtap_dumper *wdh,
        ts = (((guint64)phdr->ts.secs) * 1000000) + (phdr->ts.nsecs / 1000);
 
        /* Split the 64-bit timestamp into two 32-bit pieces */
-        wblock.data.packet.ts_high      = (guint32)(ts >> 32);
-        wblock.data.packet.ts_low       = (guint32)ts;
+    wblock.data.packet.ts_high      = (guint32)(ts >> 32);
+    wblock.data.packet.ts_low       = (guint32)ts;
 
        wblock.data.packet.cap_len      = phdr->caplen;
        wblock.data.packet.packet_len   = phdr->len;
@@ -2026,8 +2100,9 @@ static gboolean pcapng_dump(wtap_dumper *wdh,
        wblock.data.packet.wtap_encap   = phdr->pkt_encap;
 
        /* currently unused */
-       wblock.data.packet.drop_count   = -1;
-       wblock.data.packet.opt_comment  = NULL;
+       wblock.data.packet.drop_count   = phdr->drop_count;
+       wblock.data.packet.opt_comment  = phdr->opt_comment;
+       pcapng_debug1("pcapng_dump: Comment %s",phdr->opt_comment);
 
        if (!pcapng_write_block(wdh, &wblock, err)) {
                return FALSE;
index 0e00d68..3c7ecb6 100644 (file)
@@ -45,33 +45,33 @@ typedef gboolean (*subtype_read_func)(struct wtap*, int*, char**, gint64*);
 typedef gboolean (*subtype_seek_read_func)(struct wtap*, gint64, union wtap_pseudo_header*,
                                        guint8*, int, int *, char **);
 struct wtap {
-       FILE_T                  fh;
-       FILE_T                  random_fh;    /* Secondary FILE_T for random access */
-       int                     file_type;
-       guint                   snapshot_length;
-       struct Buffer           *frame_buffer;
-       struct wtap_pkthdr      phdr;
-       union wtap_pseudo_header pseudo_header;
-
-       gint64                  data_offset;
-
-       void                    *priv;
-
-       subtype_read_func       subtype_read;
-       subtype_seek_read_func  subtype_seek_read;
-       void                    (*subtype_sequential_close)(struct wtap*);
-       void                    (*subtype_close)(struct wtap*);
-       int                     file_encap;     /* per-file, for those
+       FILE_T                                          fh;
+       FILE_T                                          random_fh;    /* Secondary FILE_T for random access */
+       int                                                     file_type;
+       guint                                           snapshot_length;
+       struct Buffer                           *frame_buffer;
+       struct wtap_pkthdr                      phdr;
+       union wtap_pseudo_header        pseudo_header;
+
+       gint64                                          data_offset;
+
+       void                                            *priv;
+
+       subtype_read_func                       subtype_read;
+       subtype_seek_read_func          subtype_seek_read;
+       void                                            (*subtype_sequential_close)(struct wtap*);
+       void                                            (*subtype_close)(struct wtap*);
+       int                                                     file_encap;     /* per-file, for those
                                                                                         * file formats that have
                                                                                         * per-file encapsulation
                                                                                         * types
                                                                                         */
-       int                     tsprecision;    /* timestamp precision of the lower 32bits
+       int                                                     tsprecision;    /* timestamp precision of the lower 32bits
                                                                                                 * e.g. WTAP_FILE_TSPREC_USEC
                                                                                                 */
-       wtap_new_ipv4_callback_t add_new_ipv4;
-       wtap_new_ipv6_callback_t add_new_ipv6;
-       GPtrArray *fast_seek;
+       wtap_new_ipv4_callback_t        add_new_ipv4;
+       wtap_new_ipv6_callback_t        add_new_ipv6;
+       GPtrArray                                       *fast_seek;
 };
 
 struct wtap_dumper;
index d070f91..e8a0ebe 100644 (file)
@@ -821,17 +821,15 @@ struct wtap_nstime {
 };
 
 struct wtap_pkthdr {
-       struct wtap_nstime ts;
+       struct wtap_nstime      ts;
        guint32                         caplen;                 /* data length in the file */
        guint32                         len;                    /* data length on the wire */
-       int pkt_encap;
+       int                                     pkt_encap;
        /* pcapng variables */
        guint32                         interface_id;   /* identifier of the interface. */
-       guint16                         drops_count;    /* drops count, only valid for packet block */
-                                                                               /* 0xffff if information not available */
        /* options */
        gchar                           *opt_comment;   /* NULL if not available */
-       guint64                         drop_count;
+       guint64                         drop_count;             /* number of packets lost (by the interface and the operating system) between this packet and the preceding one. */
        guint32                         pack_flags;     /* XXX - 0 for now (any value for "we don't have it"?) */
 };