From Anders: Add support for options in the SHB.
authortuexen <tuexen@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 14 Feb 2012 17:07:52 +0000 (17:07 +0000)
committertuexen <tuexen@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 14 Feb 2012 17:07:52 +0000 (17:07 +0000)
From me: Some whitespace changes.

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

dumpcap.c
pcapio.c
pcapio.h
wiretap/pcapng.c

index 21e342c1ffb33067d5881ea7c431eefb2404bcf7..8e001a95880982e8783173ea38bc728aeb4c9561 100644 (file)
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -2559,9 +2559,23 @@ capture_loop_init_output(capture_options *capture_opts, loop_data *ld, char *err
     if (ld->pdh) {
         if (capture_opts->use_pcapng) {
             char appname[100];
+            GString             *runtime_info_str;
+
+            runtime_info_str = g_string_new("");
+            get_runtime_version_info(runtime_info_str, NULL);
 
             g_snprintf(appname, sizeof(appname), "Dumpcap " VERSION "%s", wireshark_svnversion);
-            successful = libpcap_write_session_header_block(ld->pdh, appname, &ld->bytes_written, &err);
+            successful = libpcap_write_session_header_block(ld->pdh, 
+                                NULL,                        /* Comment*/
+                                NULL,                        /* HW*/
+                                runtime_info_str->str,       /* OS*/
+                                appname,
+                                                               -1,                          /* section_length */
+                                &ld->bytes_written, 
+                                &err);
+
+            g_string_free(runtime_info_str, TRUE);
+
             for (i = 0; successful && (i < capture_opts->ifaces->len); i++) {
                 interface_opts = g_array_index(capture_opts->ifaces, interface_options, i);
                 pcap_opts = g_array_index(ld->pcaps, pcap_options *, i);
@@ -2994,9 +3008,23 @@ do_file_switch_or_stop(capture_options *capture_opts,
             global_ld.bytes_written = 0;
             if (capture_opts->use_pcapng) {
                 char appname[100];
+                GString             *runtime_info_str;
+
+                runtime_info_str = g_string_new("");
+                get_runtime_version_info(runtime_info_str, NULL);
 
                 g_snprintf(appname, sizeof(appname), "Dumpcap " VERSION "%s", wireshark_svnversion);
-                successful = libpcap_write_session_header_block(global_ld.pdh, appname, &(global_ld.bytes_written), &global_ld.err);
+                successful = libpcap_write_session_header_block(global_ld.pdh, 
+                                NULL,                        /* Comment */
+                                NULL,                        /* HW */
+                                runtime_info_str->str,       /* OS */
+                                appname,
+                                                               -1,                          /* section_length */
+                                &(global_ld.bytes_written), 
+                                &global_ld.err);
+
+                g_string_free(runtime_info_str, TRUE);
+
                 for (i = 0; successful && (i < capture_opts->ifaces->len); i++) {
                     interface_opts = g_array_index(capture_opts->ifaces, interface_options, i);
                     pcap_opts = g_array_index(global_ld.pcaps, pcap_options *, i);
index 6029532d72a23d924eca492f8877a0ed749a4897..b12217bd993d4cf258c96e240406a100ec7fe14c 100644 (file)
--- a/pcapio.c
+++ b/pcapio.c
@@ -160,7 +160,7 @@ struct option {
 #define OPT_ENDOFOPT 0
 #define OPT_COMMENT  1 /* currently not used */
 #define SHB_HARDWARE 2 /* currently not used */
-#define SHB_OS       3 /* currently not used */
+#define SHB_OS       3 
 #define SHB_USERAPPL 4
 #define IDB_NAME     2
 #define IDB_FILTER  11
@@ -268,7 +268,11 @@ libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
 
 gboolean
 libpcap_write_session_header_block(FILE *fp,
+                                   const char *comment,
+                                   const char *hw,
+                                   const char *os,
                                    const char *appname,
+                                   guint64 section_length,
                                    long *bytes_written,
                                    int *err)
 {
@@ -276,12 +280,34 @@ libpcap_write_session_header_block(FILE *fp,
        struct option option;
        guint32 block_total_length;
        const guint32 padding = 0;
+       gboolean have_options = FALSE;
 
+       /* Size of base header */
        block_total_length = sizeof(struct shb) +
                             sizeof(guint32);
-       if ((strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
-               block_total_length += 2 * sizeof(struct option) +
+       if ((comment)&&(strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
+               block_total_length += sizeof(struct option) +
+                                     (guint16)(ADD_PADDING(strlen(comment) + 1));
+               have_options = TRUE;
+       }
+       if ((hw)&&(strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
+               block_total_length += sizeof(struct option) +
+                                     (guint16)(ADD_PADDING(strlen(hw) + 1));
+               have_options = TRUE;
+       }
+       if ((os)&&(strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
+               block_total_length += sizeof(struct option) +
+                                     (guint16)(ADD_PADDING(strlen(os) + 1));
+               have_options = TRUE;
+       }
+       if ((appname)&&(strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
+               block_total_length += sizeof(struct option) +
                                      (guint16)(ADD_PADDING(strlen(appname) + 1));
+               have_options = TRUE;
+       }
+       /* If we have options add size of end-of-options */
+       if(have_options){
+               block_total_length += sizeof(struct option);
        }
        /* write shb header */
        shb.block_type = SECTION_HEADER_BLOCK_TYPE;
@@ -289,10 +315,40 @@ libpcap_write_session_header_block(FILE *fp,
        shb.byte_order_magic = PCAPNG_MAGIC;
        shb.major_version = PCAPNG_MAJOR_VERSION;
        shb.minor_version = PCAPNG_MINOR_VERSION;
-       shb.section_length = -1;
+       shb.section_length = section_length;
        WRITE_DATA(fp, &shb, sizeof(struct shb), *bytes_written, err);
 
-       if ((strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
+       if ((comment)&&(strlen(comment) > 0) && (strlen(comment) < G_MAXUINT16)) {
+               /* write opt_comment options */
+               option.type = OPT_COMMENT;
+               option.value_length = (guint16)(strlen(comment) + 1);
+               WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
+               WRITE_DATA(fp, comment, strlen(comment) + 1, *bytes_written, err);
+               if ((strlen(comment) + 1) % 4) {
+                       WRITE_DATA(fp, &padding, 4 - (strlen(hw) + 1) % 4, *bytes_written, err);
+               }
+       }
+       if ((hw)&&(strlen(hw) > 0) && (strlen(hw) < G_MAXUINT16)) {
+               /* write shb_hardware options */
+               option.type = SHB_HARDWARE;
+               option.value_length = (guint16)(strlen(hw) + 1);
+               WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
+               WRITE_DATA(fp, hw, strlen(hw) + 1, *bytes_written, err);
+               if ((strlen(hw) + 1) % 4) {
+                       WRITE_DATA(fp, &padding, 4 - (strlen(hw) + 1) % 4, *bytes_written, err);
+               }
+       }
+       if ((os)&&(strlen(os) > 0) && (strlen(os) < G_MAXUINT16)) {
+               /* write shb_os options */
+               option.type = SHB_OS;
+               option.value_length = (guint16)(strlen(os) + 1);
+               WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
+               WRITE_DATA(fp, os, strlen(os) + 1, *bytes_written, err);
+               if ((strlen(os) + 1) % 4) {
+                       WRITE_DATA(fp, &padding, 4 - (strlen(os) + 1) % 4, *bytes_written, err);
+               }
+       }
+       if ((appname)&&(strlen(appname) > 0) && (strlen(appname) < G_MAXUINT16)) {
                /* write shb_userappl options */
                option.type = SHB_USERAPPL;
                option.value_length = (guint16)(strlen(appname) + 1);
@@ -301,11 +357,14 @@ libpcap_write_session_header_block(FILE *fp,
                if ((strlen(appname) + 1) % 4) {
                        WRITE_DATA(fp, &padding, 4 - (strlen(appname) + 1) % 4, *bytes_written, err);
                }
-               /* write last option */
+       }
+       if(have_options){
+               /* write end of options */
                option.type = OPT_ENDOFOPT;
                option.value_length = 0;
                WRITE_DATA(fp, &option, sizeof(struct option), *bytes_written, err);
        }
+
        /* write the trailing block total length */
        WRITE_DATA(fp, &block_total_length, sizeof(guint32), *bytes_written, err);
        return TRUE;
index 80d28da8bc68e35b6c936b8bb8979d3bceb84af9..e7f28f76dd7ab84addd67154d5a645cd2f3aedb4 100644 (file)
--- a/pcapio.h
+++ b/pcapio.h
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-/* Returns a FILE * to write to on success, NULL on failure */
+/** Returns a FILE * to write to on success, NULL on failure */
 extern FILE *
 libpcap_fdopen(int fd, int *err);
 
-/* Write the file header to a dump file.
+/** Write the file header to a dump file.
    Returns TRUE on success, FALSE on failure.
    Sets "*err" to an error code, or 0 for a short write, on failure*/
 extern gboolean
 libpcap_write_file_header(FILE *fp, int linktype, int snaplen, long *bytes_written, int *err);
 
-/* Write a record for a packet to a dump file.
+/** Write a record for a packet to a dump file.
    Returns TRUE on success, FALSE on failure. */
 extern gboolean
 libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
     long *bytes_written, int *err);
 
+/** Write a section header block (SHB)
+ *
+ */
 extern gboolean
-libpcap_write_session_header_block(FILE *fp,
-                                   const char *appname,
+libpcap_write_session_header_block(FILE *fp,             /**< File pointer */
+                                   const char *comment,  /**< Comment on the section, Optinon 1 opt_comment
+                                                          * A UTF-8 string containing a comment that is associated to the current block.
+                                                          */
+                                   const char *hw,       /**< HW, Optinon 2 shb_hardware 
+                                                          * An UTF-8 string containing the description of the hardware  used to create this section.
+                                                          */
+                                   const char *os,       /**< Operating system name, Optinon 3 shb_os 
+                                                          * An UTF-8 string containing the name of the operating system used to create this section.
+                                                          */
+                                   const char *appname,  /**< Application name, Optinon 4 shb_userappl 
+                                                          * An UTF-8 string containing the name of the application  used to create this section.
+                                                          */
+                                   guint64 section_length,
                                    long *bytes_written,
                                    int *err);
 
index 920eb9079ae814a5e443325656707ce76b89bdee..bbe26c026ffd9f575b278f672a426b6c5d1ede9b 100644 (file)
@@ -171,7 +171,7 @@ typedef struct pcapng_option_header_s {
        guint16 option_code;
        guint16 option_length;
        /* ... x bytes Option Body ... */
-    /* ... Padding ... */
+       /* ... Padding ... */
 } pcapng_option_header_t;
 
 /* Block types */
@@ -399,10 +399,10 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
 {
        int     bytes_read;
        int     block_read;
-       int to_read;
+       int to_read, opt_cont_buf_len;
        pcapng_section_header_block_t shb;
        pcapng_option_header_t oh;
-       char option_content[100]; /* XXX - size might need to be increased, if we see longer options */
+       char *option_content = NULL; /* Allocate as large as the options block */
 
 
        /* read block content */
@@ -486,18 +486,23 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
        /* Option defaults */
        wblock->data.section.opt_comment        = NULL;
        wblock->data.section.shb_hardware       = NULL;
-       wblock->data.section.shb_os             = NULL;
+       wblock->data.section.shb_os                     = NULL;
        wblock->data.section.shb_user_appl      = NULL;
 
        /* Options */
        errno = WTAP_ERR_CANT_READ;
-       to_read = bh->block_total_length
-        - (int)sizeof(pcapng_block_header_t)
-        - (int)sizeof (pcapng_section_header_block_t)
-        - (int)sizeof(bh->block_total_length);
+       to_read = bh->block_total_length -
+                 (int)sizeof(pcapng_block_header_t) -
+                 (int)sizeof(pcapng_section_header_block_t) -
+                 (int)sizeof(bh->block_total_length);
+       /* Allocate enough memory to hold all options */
+       opt_cont_buf_len = to_read;
+       option_content = g_malloc(opt_cont_buf_len);
+       pcapng_debug1("pcapng_read_section_header_block: Options %u bytes", to_read);
        while(to_read > 0) {
                /* read option */
-               bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
+               pcapng_debug1("pcapng_read_section_header_block: Options %u bytes remaining", to_read);
+               bytes_read = pcapng_read_option(fh, pn, &oh, option_content, opt_cont_buf_len, err, err_info);
                if (bytes_read <= 0) {
                        pcapng_debug0("pcapng_read_section_header_block: failed to read option");
                        return bytes_read;
@@ -515,32 +520,32 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
                        to_read = 0;
                        break;
                    case(1): /* opt_comment */
-                       if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
-                               wblock->data.section.opt_comment = g_strndup(option_content, sizeof(option_content));
+                       if(oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
+                               wblock->data.section.opt_comment = g_strndup(option_content, oh.option_length);
                                pcapng_debug1("pcapng_read_section_header_block: opt_comment %s", wblock->data.section.opt_comment);
                        } else {
                                pcapng_debug1("pcapng_read_section_header_block: opt_comment length %u seems strange", oh.option_length);
                        }
                        break;
                    case(2): /* shb_hardware */
-                       if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
-                               wblock->data.section.shb_hardware = g_strndup(option_content, sizeof(option_content));
+                       if(oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
+                               wblock->data.section.shb_hardware = g_strndup(option_content, oh.option_length);
                                pcapng_debug1("pcapng_read_section_header_block: shb_hardware %s", wblock->data.section.shb_hardware);
                        } else {
                                pcapng_debug1("pcapng_read_section_header_block: shb_hardware length %u seems strange", oh.option_length);
                        }
                        break;
                    case(3): /* shb_os */
-                       if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
-                               wblock->data.section.shb_os = g_strndup(option_content, sizeof(option_content));
+                       if(oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
+                               wblock->data.section.shb_os = g_strndup(option_content, oh.option_length);
                                pcapng_debug1("pcapng_read_section_header_block: shb_os %s", wblock->data.section.shb_os);
                        } else {
-                               pcapng_debug1("pcapng_read_section_header_block: shb_os length %u seems strange", oh.option_length);
+                               pcapng_debug2("pcapng_read_section_header_block: shb_os length %u seems strange, opt buffsize %u", oh.option_length,to_read);
                        }
                        break;
                    case(4): /* shb_userappl */
-                       if(oh.option_length > 0 && oh.option_length < sizeof(option_content)) {
-                               wblock->data.section.shb_user_appl = g_strndup(option_content, sizeof(option_content));
+                       if(oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
+                               wblock->data.section.shb_user_appl = g_strndup(option_content, oh.option_length);
                                pcapng_debug1("pcapng_read_section_header_block: shb_userappl %s", wblock->data.section.shb_user_appl);
                        } else {
                                pcapng_debug1("pcapng_read_section_header_block: shb_userappl length %u seems strange", oh.option_length);
@@ -551,6 +556,7 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
                                      oh.option_code, oh.option_length);
                }
        }
+       g_free(option_content);
 
        if (pn->interface_data != NULL) {
                g_array_free(pn->interface_data, TRUE);
@@ -637,10 +643,10 @@ pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn,
 
        /* Options */
        errno = WTAP_ERR_CANT_READ;
-       to_read = bh->block_total_length
-        - (int)sizeof(pcapng_block_header_t)
-        - (int)sizeof (pcapng_interface_description_block_t)
-        - (int)sizeof(bh->block_total_length);
+       to_read = bh->block_total_length -
+                 (int)sizeof(pcapng_block_header_t) -
+                 (int)sizeof (pcapng_interface_description_block_t) -
+                 (int)sizeof(bh->block_total_length);
        while (to_read > 0) {
                /* read option */
                bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
@@ -926,10 +932,10 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
         * epb_dropcount  4
         */
        errno = WTAP_ERR_CANT_READ;
-       to_read = block_total_length
-        - (int)sizeof(pcapng_block_header_t)
-        - block_read    /* fixed and variable part, including padding */
-        - (int)sizeof(bh->block_total_length);
+       to_read = block_total_length -
+                 (int)sizeof(pcapng_block_header_t) -
+                 block_read -    /* fixed and variable part, including padding */
+                 (int)sizeof(bh->block_total_length);
        while(to_read > 0) {
                /* read option */
                bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
@@ -1254,10 +1260,10 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
 
        /* Options */
        errno = WTAP_ERR_CANT_READ;
-       to_read = bh->block_total_length
-        - sizeof(pcapng_block_header_t)
-        - block_read    /* fixed and variable part, including padding */
-        - sizeof(bh->block_total_length);
+       to_read = bh->block_total_length -
+                 sizeof(pcapng_block_header_t) -
+                 block_read -    /* fixed and variable part, including padding */
+                 sizeof(bh->block_total_length);
        while(to_read > 0) {
                /* read option */
                bytes_read = pcapng_read_option(fh, pn, &oh, option_content, sizeof(option_content), err, err_info);
@@ -2114,8 +2120,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;