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