From Colin O'Flynn:
[obnox/wireshark/wip.git] / print.c
diff --git a/print.c b/print.c
index 1de8bbfde59046eaf916dc17e15f2775bddf9327..0f0014cbb0e11d9e7896459f6fdd64893c8a13e4 100644 (file)
--- a/print.c
+++ b/print.c
 #include <epan/tvbuff.h>
 #include <epan/packet.h>
 #include <epan/emem.h>
+#include <epan/expert.h>
 
 #include "packet-range.h"
 #include "print.h"
+#include "isprint.h"
 #include "ps.h"
 #include "version_info.h"
 #include <wsutil/file_util.h>
 #include <epan/charsets.h>
 #include <epan/dissectors/packet-data.h>
 #include <epan/dissectors/packet-frame.h>
+#include <epan/filesystem.h>
 
 #define PDML_VERSION "0"
 #define PSML_VERSION "0"
@@ -194,9 +197,12 @@ void proto_tree_print_node(proto_node *node, gpointer data)
 
        /*
         * If -O is specified, only display the protocols which are in the
-        * lookup table.
+        * lookup table.  Only check on the first level: once we start printing
+        * a tree, print the rest of the subtree.  Otherwise we won't print
+        * subitems whose abbreviation doesn't match the protocol--for example
+        * text items (whose abbreviation is simply "text").
         */
-       if (output_only_tables != NULL
+       if (output_only_tables != NULL && pdata->level == 0
         && g_hash_table_lookup(output_only_tables, fi->hfinfo->abbrev) == NULL) {
          pdata->success = TRUE;
          return;
@@ -240,12 +246,19 @@ void proto_tree_print_node(proto_node *node, gpointer data)
        }
 }
 
+#define PDML2HTML_XSL "pdml2html.xsl"
 void
-write_pdml_preamble(FILE *fh)
+write_pdml_preamble(FILE *fh, const gchar* filename)
 {
+       time_t t=time(NULL);
+       char *ts=asctime(localtime(&t));
+       ts[strlen(ts)-1]=0; /* overwrite \n */
+
        fputs("<?xml version=\"1.0\"?>\n", fh);
+       fputs("<?xml-stylesheet type=\"text/xsl\" href=\"" PDML2HTML_XSL "\"?>\n", fh);
+       fprintf(fh, "<!-- You can find " PDML2HTML_XSL " in %s or at http://anonsvn.wireshark.org/trunk/wireshark/" PDML2HTML_XSL ". -->\n", get_datafile_dir());
        fputs("<pdml version=\"" PDML_VERSION "\" ", fh);
-       fprintf(fh, "creator=\"%s/%s\">\n", PACKAGE, VERSION);
+       fprintf(fh, "creator=\"%s/%s\" time=\"%s\" capture_file=\"%s\">\n", PACKAGE, VERSION, ts, filename ? filename : "");
 }
 
 void
@@ -301,7 +314,7 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
                /* Open fake protocol wrapper */
                fputs("<proto name=\"fake-field-wrapper\">\n", pdata->fh);
 
-               /* Indent to increased level before writint out field */
+               /* Indent to increased level before writing out field */
                pdata->level++;
                for (i = -1; i < pdata->level; i++) {
                        fputs("  ", pdata->fh);
@@ -324,7 +337,11 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
                print_escaped_xml(pdata->fh, label_ptr);
 
                fprintf(pdata->fh, "\" size=\"%d", fi->length);
-               fprintf(pdata->fh, "\" pos=\"%d", fi->start);
+               if (node->parent && node->parent->finfo && (fi->start < node->parent->finfo->start)) {
+                       fprintf(pdata->fh, "\" pos=\"%d", node->parent->finfo->start + fi->start);
+               } else {
+                       fprintf(pdata->fh, "\" pos=\"%d", fi->start);
+               }
 
                fputs("\" value=\"", pdata->fh);
                write_pdml_field_hex_value(pdata, fi);
@@ -344,11 +361,11 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
                /* Write out field with data */
                fputs("<field name=\"data\" value=\"", pdata->fh);
                write_pdml_field_hex_value(pdata, fi);
-               fputs("\"/>\n", pdata->fh);
+               fputs("\">\n", pdata->fh);
        }
        /* Normal protocols and fields */
        else {
-               if (fi->hfinfo->type == FT_PROTOCOL) {
+               if (fi->hfinfo->type == FT_PROTOCOL && fi->hfinfo->id != proto_expert) {
                        fputs("<proto name=\"", pdata->fh);
                }
                else {
@@ -389,7 +406,11 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
                        fprintf(pdata->fh, "\" hide=\"yes");
 
                fprintf(pdata->fh, "\" size=\"%d", fi->length);
-               fprintf(pdata->fh, "\" pos=\"%d", fi->start);
+               if (node->parent && node->parent->finfo && (fi->start < node->parent->finfo->start)) {
+                       fprintf(pdata->fh, "\" pos=\"%d", node->parent->finfo->start + fi->start);
+               } else {
+                       fprintf(pdata->fh, "\" pos=\"%d", fi->start);
+               }
 /*             fprintf(pdata->fh, "\" id=\"%d", fi->hfinfo->id);*/
 
                /* show, value, and unmaskedvalue attributes */
@@ -473,13 +494,16 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
                        fputs("  ", pdata->fh);
                }
                /* Close off current element */
-               if (fi->hfinfo->id != proto_data) {   /* Data protocol uses simple tags */
+               /* Data and expert "protocols" use simple tags */
+               if (fi->hfinfo->id != proto_data && fi->hfinfo->id != proto_expert) {
                        if (fi->hfinfo->type == FT_PROTOCOL) {
                                fputs("</proto>\n", pdata->fh);
                        }
                        else {
                                fputs("</field>\n", pdata->fh);
                        }
+               } else {
+                       fputs("</field>\n", pdata->fh);
                }
        }
 
@@ -648,7 +672,7 @@ static void csv_write_str(const char *str, char sep, FILE *fh)
     csv_str = csv_massage_str(str, NULL);
     fprintf(fh, "\"%s\"%c", csv_str, sep);
     g_free(csv_str);
-}    
+}
 
 void
 proto_tree_write_csv(epan_dissect_t *edt, FILE *fh)
@@ -681,28 +705,62 @@ write_carrays_preamble(FILE *fh _U_)
 }
 
 void
-proto_tree_write_carrays(const guint8 *pd, guint32 len, guint32 num, FILE *fh)
+proto_tree_write_carrays(guint32 num, FILE *fh, epan_dissect_t *edt)
 {
-        guint32 i = 0;
-
-       if (!len)
-               return;
-
-       fprintf(fh, "char pkt%u[] = {\n", num);
+       guint32 i = 0, src_num = 0;
+       GSList *src_le;
+       data_source *src;
+       tvbuff_t *tvb;
+       const char *name;
+       const guchar *cp;
+       guint length;
+       char ascii[9];
 
-        for (i = 0; i < len; i++) {
+       for (src_le = edt->pi.data_src; src_le != NULL; src_le = src_le->next) {
+               memset(ascii, 0, sizeof(ascii));
+               src = (data_source *)src_le->data;
+               tvb = src->tvb;
+               length = tvb_length(tvb);
+               if (length == 0)
+                       continue;
 
-               fprintf(fh, "0x%02x", *(pd + i));
+               cp = tvb_get_ptr(tvb, 0, length);
 
-               if (i == (len - 1)) {
-                       fprintf(fh, " };\n\n");
-                       break;
+               name = get_data_source_name(src);
+               if (name)
+                       fprintf(fh, "/* %s */\n", name);
+               if (src_num) {
+                       fprintf(fh, "static const unsigned char pkt%u_%u[%u] = {\n",
+                               num, src_num, length);
+               } else {
+                       fprintf(fh, "static const unsigned char pkt%u[%u] = {\n",
+                               num, length);
                }
+               src_num++;
+
+               for (i = 0; i < length; i++) {
+                       fprintf(fh, "0x%02x", *(cp + i));
+                       ascii[i % 8] = isprint(*(cp + i)) ? *(cp + i) : '.';
+
+                       if (i == (length - 1)) {
+                               guint rem;
+                               rem = length % 8;
+                               if (rem) {
+                                       guint j;
+                                       for ( j = 0; j < 8 - rem; j++ )
+                                               fprintf(fh, "      ");
+                               }
+                               fprintf(fh, "  /* %s */\n};\n\n", ascii);
+                               break;
+                       }
 
-               if (!((i + 1) % 8)) {
-                       fprintf(fh, ", \n");
-               } else {
-                       fprintf(fh, ", ");
+                       if (!((i + 1) % 8)) {
+                               fprintf(fh, ", /* %s */\n", ascii);
+                               memset(ascii, 0, sizeof(ascii));
+                       }
+                       else {
+                               fprintf(fh, ", ");
+                       }
                }
        }
 }
@@ -1282,7 +1340,7 @@ print_stream_ps_stdio_new(FILE *fh)
        return print_stream_ps_alloc(TRUE, fh);
 }
 
-output_fields_t* output_fields_new()
+output_fields_t* output_fields_new(void)
 {
     output_fields_t* fields = g_new(output_fields_t, 1);
     fields->print_header = FALSE;