#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"
/*
* 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;
}
}
+#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
/* 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);
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);
/* 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 {
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 */
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);
}
}
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)
}
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, ", ");
+ }
}
}
}
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;