Пример #1
0
QString ProtoNode::labelText() const
{
    if (!node_) {
        return QString();
    }
    field_info *fi = PNODE_FINFO(node_);
    if (!fi) {
        return QString();
    }

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

    // Generated takes precedence.
    if (proto_item_is_generated(node_)) {
        label.prepend("[");
        label.append("]");
    }
    if (proto_item_is_hidden(node_)) {
        label.prepend("<");
        label.append(">");
    }
    return label;
}
Пример #2
0
static field_info *
proto_finfo_find(proto_tree *tree, field_info *old_finfo)
{
	proto_node *node;

	for (node = tree->first_child; node != NULL; node = node->next) {
		field_info *cur = PNODE_FINFO(node);

		if (!cur)
			continue;

		/* check everything, if it doesn't work report to me */
		if (cur->hfinfo == old_finfo->hfinfo &&
			cur->start == old_finfo->start && cur->length == old_finfo->length &&
			cur->appendix_start == old_finfo->appendix_start && cur->appendix_length == old_finfo->appendix_length &&
			cur->tree_type == old_finfo->tree_type && cur->flags == old_finfo->flags)
		{
			return cur;
		}

		if ((cur = proto_finfo_find((proto_tree *)node, old_finfo)))
			return cur;
	}
	return NULL;
}
Пример #3
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);
}
Пример #4
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);
}
Пример #5
0
static void
process_node(proto_node *ptree_node, GNode *parent_stat_node, ph_stats_t *ps, guint pkt_len)
{
	field_info		*finfo;
	ph_stats_node_t		*stats;
	proto_node		*proto_sibling_node;
	GNode			*stat_node;

	finfo = PNODE_FINFO(ptree_node);
	/* We don't fake protocol nodes we expect them to have a field_info.
	 * Dissection with faked proto tree? */
	g_assert(finfo);

	/* If the field info isn't related to a protocol but to a field,
	 * don't count them, as they don't belong to any protocol.
	 * (happens e.g. for toplevel tree item of desegmentation "[Reassembled TCP Segments]") */
	if (finfo->hfinfo->parent != -1) {
		/* Skip this element, use parent status node */
		stat_node = parent_stat_node;
		stats = STAT_NODE_STATS(stat_node);
	} else {
		stat_node = find_stat_node(parent_stat_node, finfo->hfinfo);

		stats = STAT_NODE_STATS(stat_node);
		stats->num_pkts_total++;
		stats->num_bytes_total += pkt_len;
	}

	proto_sibling_node = ptree_node->next;

	if (proto_sibling_node) {
		/* If the name does not exist for this proto_sibling_node, then it is
		 * not a normal protocol in the top-level tree.  It was instead
		 * added as a normal tree such as IPv6's Hop-by-hop Option Header and
		 * should be skipped when creating the protocol hierarchy display. */
		if(strlen(PNODE_FINFO(proto_sibling_node)->hfinfo->name) == 0 && ptree_node->next)
			proto_sibling_node = proto_sibling_node->next;

		process_node(proto_sibling_node, stat_node, ps, pkt_len);
	} else {
		stats->num_pkts_last++;
		stats->num_bytes_last += pkt_len;
	}
}
Пример #6
0
static void
proto_tree_model_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value)
{
	ProtoTreeModel *model;
	proto_node *node;
	field_info *fi;

	g_return_if_fail(PROTO_IS_TREE(tree_model));
	model = (ProtoTreeModel *) tree_model;

	g_return_if_fail(iter != NULL);
	g_return_if_fail(iter->stamp == model->stamp);
	g_return_if_fail(column == 0 || column == 1);

	node = (proto_node *)iter->user_data;
	fi = PNODE_FINFO(node);

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

	switch (column) {
		case 0:
		{
			g_value_init(value, G_TYPE_STRING);
			if (model->resolv_forced) {
				e_addr_resolve old_flags = gbl_resolv_flags;

				gbl_resolv_flags = model->resolv_flags;
				g_value_take_string(value, fi_get_string(fi));
				gbl_resolv_flags = old_flags;

			} else
				g_value_take_string(value, fi_get_string(fi));
			break;
		}

		case 1:
			g_value_init(value, G_TYPE_POINTER);
			g_value_set_pointer(value, fi);
			break;
	}
}
Пример #7
0
static gboolean fvt_cache_cb(proto_node * node, gpointer data _U_) {
	field_info* finfo = PNODE_FINFO(node);
	fvt_cache_entry_t* e;

	if (!finfo) return FALSE;

	if ((e = (fvt_cache_entry_t*)g_hash_table_lookup(fvt_cache,finfo->hfinfo->abbrev))) {
		e->usable = FALSE;
	} else if (finfo->value.ftype->val_to_string_repr) {
		switch (finfo->hfinfo->type) {
			case FT_NONE:
			case FT_PROTOCOL:
				return FALSE;
			default:
				break;
		}
		e = g_new(fvt_cache_entry_t,1);
		e->name = finfo->hfinfo->abbrev,
		e->repr = fvalue_to_string_repr(&(finfo->value), FTREPR_DFILTER, NULL);
		e->usable = TRUE;
		g_hash_table_insert(fvt_cache,(void*)finfo->hfinfo->abbrev,e);
	}
	return FALSE;
}
Пример #8
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);
    }
}
Пример #9
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);
	}
}
Пример #10
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;
		}
	}
}
Пример #11
0
/**
	Convert a proto_node to a datamodel node(hf_datanode), preserve only necessary information

	@param node actually processed node of the proto_tree
	@param data supporting structure containing concrete data in byte arrays
	
	@return newly created node of a datamodel or NULL if failed
*/
hf_datanode *
hf_transform_ptree_node_to_datamodel_node(proto_node *node, gpointer data)
{
	field_info	*fi = PNODE_FINFO(node);
	hf_prototree_data	*pdata = (hf_prototree_data*) data;
	hf_datanode *newnode;

	// create a new node which will be used to store extracted data
	newnode = (hf_datanode *)malloc(sizeof(hf_datanode));
	if(newnode == NULL) {
		fprintf(stderr,"hf_datanode malloc failed when transforming ptree to dtree!\n");
		return NULL;
	}
	newnode->first_child = NULL;
	newnode->first_sibling = NULL;
	newnode->value = NULL;

	// test whether we have a valid file info structure
	g_assert(fi);

	// text data will be represented as a string for fuzzing
	if (fi->hfinfo->id == hf_text_only) {
		// DOES NOT HAVE NAME, ONLY VALUE
		// therefore we use an artificial sequential name
		newnode->name = generate_seq_name();
		newnode->size = fi->length;
		newnode->pos = fi->start;
		newnode->value = hf_extract_value(pdata, fi);
	}

	// uninterpreted data are just "data"
	else if (fi->hfinfo->id == proto_data) {
		char * novname = (char*)malloc(sizeof(char)*5);
		novname[0] = 'd';
		novname[1] = 'a';
		novname[2] = 't';
		novname[3] = 'a';
		novname[4] = '\0';
		newnode->size = fi->length;
		newnode->pos = fi->start;
		newnode->name = novname;
		newnode->value = hf_extract_value(pdata, fi);
	}
	// classic protocols and fields
	else {
		newnode->name = hf_copy_string(fi->hfinfo->abbrev);
		newnode->size = fi->length;
		newnode->pos = fi->start;

		// extract value attributes
		switch (fi->hfinfo->type)
		{
		case FT_PROTOCOL:
			if (fi->length > 0) {
				newnode->value = hf_extract_value(pdata, fi);
			}
			break;
		case FT_NONE:
			break;
		default:
			if (fi->length > 0) {
				if (fi->hfinfo->bitmask!=0) {
					// bitmasking is not interesting for us, but might be used in the future  so keep it here
					/*fprintf(pdata->fh, "%X", fvalue_get_uinteger(&fi->value));
					fputs("\" unmaskedvalue=\"", pdata->fh);*/
					newnode->value = hf_extract_value(pdata, fi);
				}
				else {
					newnode->value = hf_extract_value(pdata, fi);
				}
			}
		}

	}
	newnode->type = fi->hfinfo->type;
	// interpret text as descriptive, non-interesting data for fuzzing(in fact it is string data for this purpose)
	if(fi->hfinfo->type == 0) {
		newnode->type = FT_PROTOCOL;
	}

	// debug print
	if(debug_mode==DEBUG_MODE) {
		if(newnode->size>0) {
			hf_print_datamodel(newnode,0,0);
		}
	}

	// recurse for all children
	if (node->first_child != NULL) {
		proto_node *current;
		hf_datanode *actlast;

		// process the first child, it will be the first child of the newly created node
		node = node->first_child;
		current = node;
		node = current->next;
		newnode->first_child = hf_transform_ptree_node_to_datamodel_node(current, data);
		actlast = newnode->first_child;

		// process all siblings, these will be siblings of the first child of the newly created node
		while (node != NULL) {
			current = node;
			node = current->next;
			actlast->first_sibling = hf_transform_ptree_node_to_datamodel_node(current, data);
			actlast = actlast->first_sibling;
		}
		actlast->first_sibling = NULL;
	}

	return newnode;
}
Пример #12
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;

	/* 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;
		}
	}
}