/* Returns an ep_alloced string or a static constant*/ static const gchar* get_node_field_value_as_string(field_info* fi, epan_dissect_t* edt) { /* Text label. */ if (fi->hfinfo->id == hf_text_only) { /* Get the text */ if (fi->rep) { return fi->rep->representation; } else { // XXX APB do we get here or later in this function? return get_field_hex_value2(edt->pi.data_src, fi); } } #if 0 /* Uninterpreted data, i.e., the "Data" protocol, is * printed as a field instead of a protocol. */ else if (fi->hfinfo->id == proto_data) { return get_field_hex_value2(edt->pi.data_src, fi); } #endif /* Normal protocols and fields */ else { gchar *dfilter_string; gint chop_len; switch (fi->hfinfo->type) { case FT_PROTOCOL: /* Print out the full details for the protocol. */ if (fi->rep) { return fi->rep->representation; } else { /* Just print out the protocol abbreviation */ return fi->hfinfo->abbrev;; } case FT_NONE: return NULL; default: /* XXX - this is a hack until we can just call * fvalue_to_string_repr() for *all* FT_* types. */ dfilter_string = proto_construct_match_selected_string(fi, edt); if (dfilter_string != NULL) { chop_len = strlen(fi->hfinfo->abbrev) + 4; /* for " == " */ /* XXX - Remove double-quotes. Again, once we * can call fvalue_to_string_repr(), we can * ask it not to produce the version for * display-filters, and thus, no * double-quotes. */ if (dfilter_string[strlen(dfilter_string)-1] == '"') { dfilter_string[strlen(dfilter_string)-1] = '\0'; chop_len++; } return &(dfilter_string[chop_len]); } else { return get_field_hex_value2(edt->pi.data_src, fi); } } } }
/* Write out a tree's data, and any child nodes, as PDML */ static void proto_tree_write_node_pdml(proto_node *node, gpointer data) { field_info *fi = PNODE_FINFO(node); write_pdml_data *pdata = (write_pdml_data*) data; const gchar *label_ptr; gchar label_str[ITEM_LABEL_LENGTH]; char *dfilter_string; size_t chop_len; int i; gboolean wrap_in_fake_protocol; g_assert(fi && "dissection with an invisible proto tree?"); /* Will wrap up top-level field items inside a fake protocol wrapper to preserve the PDML schema */ wrap_in_fake_protocol = (((fi->hfinfo->type != FT_PROTOCOL) || (fi->hfinfo->id == proto_data)) && (pdata->level == 0)); /* Indent to the correct level */ for (i = -1; i < pdata->level; i++) { fputs(" ", pdata->fh); } if (wrap_in_fake_protocol) { /* Open fake protocol wrapper */ fputs("<proto name=\"fake-field-wrapper\">\n", pdata->fh); /* Indent to increased level before writint out field */ pdata->level++; for (i = -1; i < pdata->level; i++) { fputs(" ", pdata->fh); } } /* Text label. It's printed as a field with no name. */ if (fi->hfinfo->id == hf_text_only) { /* Get the text */ if (fi->rep) { label_ptr = fi->rep->representation; } else { label_ptr = ""; } /* Show empty name since it is a required field */ fputs("<field name=\"", pdata->fh); fputs("\" show=\"", pdata->fh); print_escaped_xml(pdata->fh, label_ptr); fprintf(pdata->fh, "\" size=\"%d", fi->length); fprintf(pdata->fh, "\" pos=\"%d", fi->start); fputs("\" value=\"", pdata->fh); write_pdml_field_hex_value(pdata, fi); if (node->first_child != NULL) { fputs("\">\n", pdata->fh); } else { fputs("\"/>\n", pdata->fh); } } /* Uninterpreted data, i.e., the "Data" protocol, is * printed as a field instead of a protocol. */ else if (fi->hfinfo->id == proto_data) { /* Write out field with data */ fputs("<field name=\"data\" value=\"", pdata->fh); write_pdml_field_hex_value(pdata, fi); fputs("\"/>\n", pdata->fh); } /* Normal protocols and fields */ else { if (fi->hfinfo->type == FT_PROTOCOL) { fputs("<proto name=\"", pdata->fh); } else { fputs("<field name=\"", pdata->fh); } print_escaped_xml(pdata->fh, fi->hfinfo->abbrev); #if 0 /* PDML spec, see: * http://www.nbee.org/doku.php?id=netpdl:pdml_specification * * the show fields contains things in 'human readable' format * showname: contains only the name of the field * show: contains only the data of the field * showdtl: contains additional details of the field data * showmap: contains mappings of the field data (e.g. the hostname to an IP address) * * XXX - the showname shouldn't contain the field data itself * (like it's contained in the fi->rep->representation). * Unfortunately, we don't have the field data representation for * all fields, so this isn't currently possible */ fputs("\" showname=\"", pdata->fh); print_escaped_xml(pdata->fh, fi->hfinfo->name); #endif if (fi->rep) { fputs("\" showname=\"", pdata->fh); print_escaped_xml(pdata->fh, fi->rep->representation); } else { label_ptr = label_str; proto_item_fill_label(fi, label_str); fputs("\" showname=\"", pdata->fh); print_escaped_xml(pdata->fh, label_ptr); } if (PROTO_ITEM_IS_HIDDEN(node)) fprintf(pdata->fh, "\" hide=\"yes"); fprintf(pdata->fh, "\" size=\"%d", fi->length); fprintf(pdata->fh, "\" pos=\"%d", fi->start); /* fprintf(pdata->fh, "\" id=\"%d", fi->hfinfo->id);*/ /* show, value, and unmaskedvalue attributes */ switch (fi->hfinfo->type) { case FT_PROTOCOL: break; case FT_NONE: fputs("\" show=\"\" value=\"", pdata->fh); break; default: /* XXX - this is a hack until we can just call * fvalue_to_string_repr() for *all* FT_* types. */ dfilter_string = proto_construct_match_selected_string(fi, pdata->edt); if (dfilter_string != NULL) { chop_len = strlen(fi->hfinfo->abbrev) + 4; /* for " == " */ /* XXX - Remove double-quotes. Again, once we * can call fvalue_to_string_repr(), we can * ask it not to produce the version for * display-filters, and thus, no * double-quotes. */ if (dfilter_string[strlen(dfilter_string)-1] == '"') { dfilter_string[strlen(dfilter_string)-1] = '\0'; chop_len++; } fputs("\" show=\"", pdata->fh); print_escaped_xml(pdata->fh, &dfilter_string[chop_len]); } /* * XXX - should we omit "value" for any fields? * What should we do for fields whose length is 0? * They might come from a pseudo-header or from * the capture header (e.g., time stamps), or * they might be generated fields. */ if (fi->length > 0) { fputs("\" value=\"", pdata->fh); if (fi->hfinfo->bitmask!=0) { fprintf(pdata->fh, "%X", fvalue_get_uinteger(&fi->value)); fputs("\" unmaskedvalue=\"", pdata->fh); write_pdml_field_hex_value(pdata, fi); } else { write_pdml_field_hex_value(pdata, fi); } } } if (node->first_child != NULL) { fputs("\">\n", pdata->fh); } else if (fi->hfinfo->id == proto_data) { fputs("\">\n", pdata->fh); } else { fputs("\"/>\n", pdata->fh); } } /* We always print all levels for PDML. Recurse here. */ if (node->first_child != NULL) { pdata->level++; proto_tree_children_foreach(node, proto_tree_write_node_pdml, pdata); pdata->level--; } /* Take back the extra level we added for fake wrapper protocol */ if (wrap_in_fake_protocol) { pdata->level--; } if (node->first_child != NULL) { /* Indent to correct level */ for (i = -1; i < pdata->level; i++) { fputs(" ", pdata->fh); } /* Close off current element */ if (fi->hfinfo->id != proto_data) { /* Data protocol uses simple tags */ if (fi->hfinfo->type == FT_PROTOCOL) { fputs("</proto>\n", pdata->fh); } else { fputs("</field>\n", pdata->fh); } } } /* Close off fake wrapper protocol */ if (wrap_in_fake_protocol) { fputs("</proto>\n", pdata->fh); } }