예제 #1
0
gboolean
proto_tree_print(print_args_t *print_args, epan_dissect_t *edt,
    print_stream_t *stream)
{
	print_data data;
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "in proto_tree_print");

	/* Create the output */
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "1");
	data.level = 0;
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "2");
	data.stream = stream;
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "3");
	data.success = TRUE;
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "4");
	data.src_list = edt->pi.data_src;
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "5");
	data.encoding = edt->pi.fd->flags.encoding;
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "6");
	data.print_dissections = print_args->print_dissections;
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "7");
	/* If we're printing the entire packet in hex, don't
	   print uninterpreted data fields in hex as well. */
	data.print_hex_for_data = !print_args->print_hex;
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "8");
	data.edt = edt;
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "9");

  __android_log_print(ANDROID_LOG_INFO, "libtshark", "about to call proto_tree_print_node");
	proto_tree_children_foreach(edt->tree, proto_tree_print_node, &data);
	return data.success;
}
예제 #2
0
void ProtoTreeModel::foreachFindField(proto_node *node, gpointer find_finfo_ptr)
{
    struct find_field_info_ *find_finfo = (struct find_field_info_ *) find_finfo_ptr;
    if (PNODE_FINFO(node) == find_finfo->fi) {
        find_finfo->node = ProtoNode(node);
        return;
    }
    proto_tree_children_foreach(node, foreachFindField, find_finfo);
}
예제 #3
0
void ProtoTreeModel::foreachFindHfid(proto_node *node, gpointer find_hfid_ptr)
{
    struct find_hfid_ *find_hfid = (struct find_hfid_ *) find_hfid_ptr;
    if (PNODE_FINFO(node)->hfinfo->id == find_hfid->hfid) {
        find_hfid->node = ProtoNode(node);
        return;
    }
    proto_tree_children_foreach(node, foreachFindHfid, find_hfid);
}
예제 #4
0
/**
 * This function gets all field values for a packet.  It does this by
 * Creating a data structure to pass to libwireshark's
 * proto_tree_children_foreach(), which subsequently recursively traverses
 * the dissector tree.
 *
 * @param stdata Sharktools data structure,
 * @param edt dissector tree
 */
void proto_tree_get_fields(st_data_t* stdata, epan_dissect_t *edt)
{
  g_assert(stdata);
  g_assert(edt);
  
  stdata_edt_tuple_t arg;
  arg.stdata = stdata;
  arg.edt = edt;  
  
  proto_tree_children_foreach(edt->tree,
                              proto_tree_get_node_field_values,
			      &arg);
}
예제 #5
0
QModelIndex ProtoTreeModel::findFirstHfid(int hf_id)
{
    if (!root_node_ || hf_id < 0) return QModelIndex();

    struct find_hfid_ find_hfid;
    find_hfid.hfid = hf_id;

    proto_tree_children_foreach(root_node_, foreachFindHfid, &find_hfid);

    if (find_hfid.node.isValid()) {
        return indexFromProtoNode(find_hfid.node);
    }
    return QModelIndex();
}
예제 #6
0
QModelIndex ProtoTreeModel::findFieldInformation(FieldInformation *finfo)
{
    if (!root_node_ || !finfo) return QModelIndex();
    field_info * fi = finfo->fieldInfo();
    if (!fi) return QModelIndex();

    struct find_field_info_ find_finfo;
    find_finfo.fi = fi;

    proto_tree_children_foreach(root_node_, foreachFindField, &find_finfo);
    if (find_finfo.node.isValid()) {
        return indexFromProtoNode(find_finfo.node);
    }
    return QModelIndex();
}
예제 #7
0
void
proto_tree_write_pdml(epan_dissect_t *edt, FILE *fh)
{
	write_pdml_data data;

	/* Create the output */
	data.level = 0;
	data.fh = fh;
	data.src_list = edt->pi.data_src;
	data.edt = edt;

	fprintf(fh, "<packet>\n");

	/* Print a "geninfo" protocol as required by PDML */
	print_pdml_geninfo(edt->tree, fh);

	proto_tree_children_foreach(edt->tree, proto_tree_write_node_pdml,
	    &data);

	fprintf(fh, "</packet>\n\n");
}
예제 #8
0
파일: print.c 프로젝트: dogphilly/wireshark
gboolean
proto_tree_print(print_args_t *print_args, epan_dissect_t *edt,
    print_stream_t *stream)
{
	print_data data;

	/* Create the output */
	data.level = 0;
	data.stream = stream;
	data.success = TRUE;
	data.src_list = edt->pi.data_src;
	data.encoding = edt->pi.fd->flags.encoding;
	data.print_dissections = print_args->print_dissections;
	/* If we're printing the entire packet in hex, don't
	   print uninterpreted data fields in hex as well. */
	data.print_hex_for_data = !print_args->print_hex;
	data.edt = edt;

	proto_tree_children_foreach(edt->tree, proto_tree_print_node, &data);
	return data.success;
}
예제 #9
0
/* Fill a single protocol tree item with its string value and set its color. */
static void
proto_tree_draw_node(proto_node *node, gpointer data)
{
    field_info   *fi = PNODE_FINFO(node);
    gchar         label_str[ITEM_LABEL_LENGTH];
    gchar        *label_ptr;
    gboolean      is_branch;

    /* dissection with an invisible proto tree? */
    g_assert(fi);

    if (PROTO_ITEM_IS_HIDDEN(node) && !prefs.display_hidden_proto_items)
        return;

    // Fill in our label
    /* was a free format label produced? */
    if (fi->rep) {
        label_ptr = fi->rep->representation;
    }
    else { /* no, make a generic label */
        label_ptr = label_str;
        proto_item_fill_label(fi, label_str);
    }

    if (node->first_child != NULL) {
        is_branch = TRUE;
        g_assert(fi->tree_type >= 0 && fi->tree_type < num_tree_types);
    }
    else {
        is_branch = FALSE;
    }

    if (PROTO_ITEM_IS_GENERATED(node)) {
        if (PROTO_ITEM_IS_HIDDEN(node)) {
            label_ptr = g_strdup_printf("<[%s]>", label_ptr);
        } else {
            label_ptr = g_strdup_printf("[%s]", label_ptr);
        }
    } else if (PROTO_ITEM_IS_HIDDEN(node)) {
        label_ptr = g_strdup_printf("<%s>", label_ptr);
    }

    QTreeWidgetItem *parentItem = (QTreeWidgetItem *)data;
    QTreeWidgetItem *item;
    ProtoTree *proto_tree = qobject_cast<ProtoTree *>(parentItem->treeWidget());

    item = new QTreeWidgetItem(parentItem, 0);

    // Set our colors.
    QPalette pal = QApplication::palette();
    if (fi && fi->hfinfo) {
        if(fi->hfinfo->type == FT_PROTOCOL) {
            item->setData(0, Qt::BackgroundRole, pal.alternateBase());
        }

        if((fi->hfinfo->type == FT_FRAMENUM) ||
                (FI_GET_FLAG(fi, FI_URL) && IS_FT_STRING(fi->hfinfo->type))) {
            QFont font = item->font(0);

            item->setData(0, Qt::ForegroundRole, pal.link());
            font.setUnderline(true);
            item->setData(0, Qt::FontRole, font);

            if (fi->hfinfo->type == FT_FRAMENUM) {
                proto_tree->emitRelatedFrame(fi->value.value.uinteger);
            }
        }
    }

    // XXX - Add routines to get our severity colors.
    if(FI_GET_FLAG(fi, PI_SEVERITY_MASK)) {
        switch(FI_GET_FLAG(fi, PI_SEVERITY_MASK)) {
        case(PI_COMMENT):
            item->setData(0, Qt::BackgroundRole, expert_color_comment);
            break;
        case(PI_CHAT):
            item->setData(0, Qt::BackgroundRole, expert_color_chat);
            break;
        case(PI_NOTE):
            item->setData(0, Qt::BackgroundRole, expert_color_note);
            break;
        case(PI_WARN):
            item->setData(0, Qt::BackgroundRole, expert_color_warn);
            break;
        case(PI_ERROR):
            item->setData(0, Qt::BackgroundRole, expert_color_error);
            break;
        default:
            g_assert_not_reached();
        }
        item->setData(0, Qt::ForegroundRole, expert_color_foreground);
    }

    item->setText(0, label_ptr);
    item->setData(0, Qt::UserRole, qVariantFromValue(fi));

    if (PROTO_ITEM_IS_GENERATED(node) || PROTO_ITEM_IS_HIDDEN(node)) {
        g_free(label_ptr);
    }

    if (is_branch) {
        if (tree_expanded(fi->tree_type)) {
            item->setExpanded(true);
        } else {
            item->setExpanded(false);
        }

        proto_tree_children_foreach(node, proto_tree_draw_node, item);
    }
}
예제 #10
0
void ProtoTree::fillProtocolTree(proto_tree *protocol_tree) {
    clear();
    setFont(mono_font_);

    proto_tree_children_foreach(protocol_tree, proto_tree_draw_node, invisibleRootItem());
}
예제 #11
0
/**
 * This function is called for each node on the dissector tree, for a each packet,
 * First, this function sees if this node is one of the keys (e.g. 'frame.number')
 * we are looking for (nodes store the key in PITEM_FINFO(node)->hfinfo->abbrev).
 * If we found an appropriate field, copy the native value or string representation
 * of the value as appropriate.
 * 
 * Finally, recurse on child nodes.
 */
static void proto_tree_get_node_field_values(proto_node *node, gpointer data)
{
  stdata_edt_tuple_t *args;
  field_info	*fi;
  gpointer field_index;
  gpointer orig_key;
  gboolean key_found;

  args = data;
  fi = PITEM_FINFO(node);

  dprintf("fi->hfinfo->abbrev = %s\n", fi->hfinfo->abbrev);

  key_found = g_hash_table_lookup_extended(args->stdata->field_indicies,
                                           fi->hfinfo->abbrev,
                                           &orig_key,
                                           &field_index);

  const gchar* val_str;
  gulong actual_index = (gulong)(field_index);

  if(key_found)
    {
      gulong type = fi->hfinfo->type;

      if(type == FT_STRING)
        {
          dprintf("found a string!\n");
          dprintf("string is: %s\n", (char*)fvalue_get(&(fi->value)));
          dprintf("string as gnfvas: %s\n", get_node_field_value_as_string(fi, args->edt));

        }

      if(type == FT_NONE)
        {
	  args->stdata->field_values_str[actual_index] = NULL;
	  args->stdata->field_values_native[actual_index] = 0;
	  args->stdata->field_types[actual_index] = FT_NONE;
        }
      else if(is_native_type(type) == TRUE)
        {
          // If we can natively store the type,
          // do that and don't convert to a string
	  args->stdata->field_values_str[actual_index] = NULL;
          memcpy(args->stdata->field_values_native[actual_index], &(fi->value), sizeof(fvalue_t));
	  args->stdata->field_types[actual_index] = type;
        }
      else
        {
          // As a last ditch options, convert the value to a string,
          // and don't bother storing the native type
          val_str = get_node_field_value_as_string(fi, args->edt); 
	  args->stdata->field_values_str[actual_index] = val_str;
	  args->stdata->field_types[actual_index] = type;
        }
    }

  /* Recurse here. */
  if (node->first_child != NULL)
    {
      proto_tree_children_foreach(node,
				  proto_tree_get_node_field_values, args);
    }
}
예제 #12
0
/* 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);
	}
}
예제 #13
0
/* Print a tree's data, and any child nodes. */
static
void proto_tree_print_node(proto_node *node, gpointer data)
{
	field_info	*fi = PNODE_FINFO(node);
	print_data	*pdata = (print_data*) data;
	const guint8	*pd;
	gchar		label_str[ITEM_LABEL_LENGTH];
	gchar		*label_ptr;

  __android_log_print(ANDROID_LOG_INFO, "libtshark", "in proto_tree_print_node !");

	g_assert(fi && "dissection with an invisible proto tree?");
  
	/* Don't print invisible entries. */
	if (PROTO_ITEM_IS_HIDDEN(node))
		return;
  
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "the proto tree is not invisible");

	/* Give up if we've already gotten an error. */
	if (!pdata->success)
		return;
  
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "success so far");

	/* was a free format label produced? */
	if (fi->rep) {
		label_ptr = fi->rep->representation;
    __android_log_print(ANDROID_LOG_INFO, "libtshark", "free format");
	}
	else { /* no, make a generic label */
    __android_log_print(ANDROID_LOG_INFO, "libtshark", "generic label");
		label_ptr = label_str;
		proto_item_fill_label(fi, label_str);
	}
  
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "A-OK");

	if (PROTO_ITEM_IS_GENERATED(node)) {
		label_ptr = g_strdup_printf("[%s]", label_ptr);
	}
  
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "proto was generated");

	//if (!print_line(pdata->stream, pdata->level, label_ptr)) {
	//	pdata->success = FALSE;
	//	return;
	//}
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "line: %s", label_ptr);
  
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "line is printed");

	if (PROTO_ITEM_IS_GENERATED(node)) {
		g_free(label_ptr);
	}
  
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "item is generated");
  
	/* If it's uninterpreted data, dump it (unless our caller will
	   be printing the entire packet in hex). */
	if (fi->hfinfo->id == proto_data && pdata->print_hex_for_data) {
		/*
		 * Find the data for this field.
		 */
		pd = get_field_data(pdata->src_list, fi);
    __android_log_print(ANDROID_LOG_INFO, "libtshark", "uninterpreted");
		if (pd) {
			if (!print_hex_data_buffer(pdata->stream, pd,
			    fi->length, pdata->encoding)) {
				pdata->success = FALSE;
				return;
			}
		}
	}
  
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "getting ready to traverse all subtrees");

	/* If we're printing all levels, or if this node is one with a
	   subtree and its subtree is expanded, recurse into the subtree,
	   if it exists. */
	g_assert(fi->tree_type >= -1 && fi->tree_type < num_tree_types);
  __android_log_print(ANDROID_LOG_INFO, "libtshark", "passed the assert");
	if (pdata->print_dissections == print_dissections_expanded ||
	    (pdata->print_dissections == print_dissections_as_displayed &&
		fi->tree_type >= 0 && tree_is_expanded[fi->tree_type])) {
    __android_log_print(ANDROID_LOG_INFO, "libtshark", "made it in");
		if (node->first_child != NULL) {
      __android_log_print(ANDROID_LOG_INFO, "libtshark", "and we're about to level up");
			pdata->level++;
      __android_log_print(ANDROID_LOG_INFO, "libtshark", "for each child...");
			proto_tree_children_foreach(node,
				proto_tree_print_node, pdata);
			pdata->level--;
			if (!pdata->success)
				return;
		}
	}
}
예제 #14
0
파일: print.c 프로젝트: dogphilly/wireshark
/* Print a tree's data, and any child nodes. */
static
void proto_tree_print_node(proto_node *node, gpointer data)
{
	field_info	*fi = PNODE_FINFO(node);
	print_data	*pdata = (print_data*) data;
	const guint8	*pd;
	gchar		label_str[ITEM_LABEL_LENGTH];
	gchar		*label_ptr;

	/* dissection with an invisible proto tree? */
	g_assert(fi);

	/* Don't print invisible entries. */
	if (PROTO_ITEM_IS_HIDDEN(node))
		return;

	/* Give up if we've already gotten an error. */
	if (!pdata->success)
		return;

	/* was a free format label produced? */
	if (fi->rep) {
		label_ptr = fi->rep->representation;
	}
	else { /* no, make a generic label */
		label_ptr = label_str;
		proto_item_fill_label(fi, label_str);
	}

	if (PROTO_ITEM_IS_GENERATED(node)) {
		label_ptr = g_strdup_printf("[%s]", label_ptr);
	}

	if (!print_line(pdata->stream, pdata->level, label_ptr)) {
		pdata->success = FALSE;
		return;
	}

	/*
	 * If -O is specified, only display the protocols which are in the
	 * 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 && pdata->level == 0
	 && g_hash_table_lookup(output_only_tables, fi->hfinfo->abbrev) == NULL) {
	  pdata->success = TRUE;
	  return;
	}

	if (PROTO_ITEM_IS_GENERATED(node)) {
		g_free(label_ptr);
	}

	/* If it's uninterpreted data, dump it (unless our caller will
	   be printing the entire packet in hex). */
	if (fi->hfinfo->id == proto_data && pdata->print_hex_for_data) {
		/*
		 * Find the data for this field.
		 */
		pd = get_field_data(pdata->src_list, fi);
		if (pd) {
			if (!print_line(pdata->stream, 0, "")) {
				pdata->success = FALSE;
				return;
			}
			if (!print_hex_data_buffer(pdata->stream, pd,
			    fi->length, pdata->encoding)) {
				pdata->success = FALSE;
				return;
			}
		}
	}

	/* If we're printing all levels, or if this node is one with a
	   subtree and its subtree is expanded, recurse into the subtree,
	   if it exists. */
	g_assert(fi->tree_type >= -1 && fi->tree_type < num_tree_types);
	if (pdata->print_dissections == print_dissections_expanded ||
	    (pdata->print_dissections == print_dissections_as_displayed &&
		fi->tree_type >= 0 && tree_is_expanded[fi->tree_type])) {
		if (node->first_child != NULL) {
			pdata->level++;
			proto_tree_children_foreach(node,
				proto_tree_print_node, pdata);
			pdata->level--;
			if (!pdata->success)
				return;
		}
	}
}