void PacketListRecord::dissect(capture_file *cap_file, bool dissect_color)
{
    // packet_list_store.c:packet_list_dissect_and_cache_record
    epan_dissect_t edt;
    column_info *cinfo = NULL;
    gboolean create_proto_tree;
    wtap_rec rec; /* Record metadata */
    Buffer buf;   /* Record data */

    if (!col_text_) col_text_ = new ColumnTextList;
    gboolean dissect_columns = col_text_->isEmpty() || data_ver_ != col_data_ver_;

    if (!cap_file) {
        return;
    }

    memset(&rec, 0, sizeof rec);

    if (dissect_columns) {
        cinfo = &cap_file->cinfo;
    }

    ws_buffer_init(&buf, 1500);
    if (!cf_read_record_r(cap_file, fdata_, &rec, &buf)) {
        /*
         * Error reading the record.
         *
         * Don't set the color filter for now (we might want
         * to colorize it in some fashion to warn that the
         * row couldn't be filled in or colorized), and
         * set the columns to placeholder values, except
         * for the Info column, where we'll put in an
         * error message.
         */
        if (dissect_columns) {
            col_fill_in_error(cinfo, fdata_, FALSE, FALSE /* fill_fd_columns */);

            cacheColumnStrings(cinfo);
        }
        if (dissect_color) {
            fdata_->color_filter = NULL;
            colorized_ = true;
        }
        ws_buffer_free(&buf);
        return;    /* error reading the record */
    }

    /*
     * Determine whether we need to create a protocol tree.
     * We do if:
     *
     *    we're going to apply a color filter to this packet;
     *
     *    we're need to fill in the columns and we have custom columns
     *    (which require field values, which currently requires that
     *    we build a protocol tree).
     *
     *    XXX - field extractors?  (Not done for GTK+....)
     */
    create_proto_tree = ((dissect_color && color_filters_used()) ||
                         (dissect_columns && (have_custom_cols(cinfo) ||
                                              have_field_extractors())));

    epan_dissect_init(&edt, cap_file->epan,
                      create_proto_tree,
                      FALSE /* proto_tree_visible */);

    /* Re-color when the coloring rules are changed via the UI. */
    if (dissect_color) {
        color_filters_prime_edt(&edt);
        fdata_->flags.need_colorize = 1;
    }
    if (dissect_columns)
        col_custom_prime_edt(&edt, cinfo);

    /*
     * XXX - need to catch an OutOfMemoryError exception and
     * attempt to recover from it.
     */
    epan_dissect_run(&edt, cap_file->cd_t, &rec,
                     frame_tvbuff_new_buffer(&cap_file->provider, fdata_, &buf),
                     fdata_, cinfo);

    if (dissect_columns) {
        /* "Stringify" non frame_data vals */
        epan_dissect_fill_in_columns(&edt, FALSE, FALSE /* fill_fd_columns */);
        cacheColumnStrings(cinfo);
    }

    if (dissect_color) {
        colorized_ = true;
    }
    data_ver_ = col_data_ver_;

    packet_info *pi = &edt.pi;
    conv_ = find_conversation_pinfo(pi, 0);

    epan_dissect_cleanup(&edt);
    ws_buffer_free(&buf);
}
Exemple #2
0
static ros_call_response_t *
ros_match_call_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint invokeId, gboolean isInvoke)
{
  ros_call_response_t rcr, *rcrp=NULL;
  ros_conv_info_t *ros_info;
  conversation_t *conversation;

  /* first see if we have already matched this */
  conversation = find_conversation_pinfo(pinfo, 0);
  if (conversation == NULL)
    return NULL;

  ros_info = (ros_conv_info_t *)conversation_get_proto_data(conversation, proto_ros);
  if (ros_info == NULL)
    return NULL;

  rcr.invokeId=invokeId;
  rcr.is_request = isInvoke;

  if(isInvoke) {
    rcr.req_frame=pinfo->num;
    rcr.rep_frame=0;
  } else {
    rcr.req_frame=0;
    rcr.rep_frame=pinfo->num;
  }

  rcrp=(ros_call_response_t *)wmem_map_lookup(ros_info->matched, &rcr);

  if(rcrp) {
    /* we have found a match */
    rcrp->is_request=rcr.is_request;

  } else {

    /* we haven't found a match - try and match it up */

    if(isInvoke) {
      /* this a a request - add it to the unmatched list */

      /* check that we don't already have one of those in the
	 unmatched list and if so remove it */

      rcr.invokeId=invokeId;

      rcrp=(ros_call_response_t *)wmem_map_lookup(ros_info->unmatched, &rcr);

      if(rcrp){
	wmem_map_remove(ros_info->unmatched, rcrp);
      }

      /* if we can't reuse the old one, grab a new chunk */
      if(!rcrp){
	rcrp=wmem_new(wmem_file_scope(), ros_call_response_t);
      }
      rcrp->invokeId=invokeId;
      rcrp->req_frame=pinfo->num;
      rcrp->req_time=pinfo->abs_ts;
      rcrp->rep_frame=0;
      rcrp->is_request=TRUE;
      wmem_map_insert(ros_info->unmatched, rcrp, rcrp);
      return NULL;

    } else {

      /* this is a result - it should be in our unmatched list */

      rcr.invokeId=invokeId;
      rcrp=(ros_call_response_t *)wmem_map_lookup(ros_info->unmatched, &rcr);

      if(rcrp){

	if(!rcrp->rep_frame){
	  wmem_map_remove(ros_info->unmatched, rcrp);
	  rcrp->rep_frame=pinfo->num;
	  rcrp->is_request=FALSE;
	  wmem_map_insert(ros_info->matched, rcrp, rcrp);
	}
      }
    }
  }

  if(rcrp){ /* we have found a match */
    proto_item *item = NULL;

    if(rcrp->is_request){
      item=proto_tree_add_uint(tree, hf_ros_response_in, tvb, 0, 0, rcrp->rep_frame);
      PROTO_ITEM_SET_GENERATED (item);
    } else {
      nstime_t ns;
      item=proto_tree_add_uint(tree, hf_ros_response_to, tvb, 0, 0, rcrp->req_frame);
      PROTO_ITEM_SET_GENERATED (item);
      nstime_delta(&ns, &pinfo->abs_ts, &rcrp->req_time);
      item=proto_tree_add_time(tree, hf_ros_time, tvb, 0, 0, &ns);
      PROTO_ITEM_SET_GENERATED (item);
    }
  }

  return rcrp;
}
/*
* Dissect RTSE PDUs inside a PPDU.
*/
static int
dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
{
    int offset = 0;
    int old_offset;
    proto_item *item;
    proto_tree *tree;
    proto_tree *next_tree=NULL;
    tvbuff_t *next_tvb = NULL;
    tvbuff_t *data_tvb = NULL;
    fragment_head *frag_msg = NULL;
    guint32 fragment_length;
    guint32 rtse_id = 0;
    gboolean data_handled = FALSE;
    struct SESSION_DATA_STRUCTURE* session;
    conversation_t *conversation = NULL;
    asn1_ctx_t asn1_ctx;
    asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);

    /* do we have application context from the acse dissector? */
    if (data == NULL)
        return 0;
    session = (struct SESSION_DATA_STRUCTURE*)data;

    /* save parent_tree so subdissectors can create new top nodes */
    top_tree=parent_tree;

    asn1_ctx.private_data = session;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTSE");
    col_clear(pinfo->cinfo, COL_INFO);

    if (rtse_reassemble &&
        ((session->spdu_type == SES_DATA_TRANSFER) ||
         (session->spdu_type == SES_MAJOR_SYNC_POINT)))
    {
        /* Use conversation index as fragment id */
        conversation  = find_conversation_pinfo(pinfo, 0);
        if (conversation != NULL) {
            rtse_id = conversation->conv_index;
        }
        session->rtse_reassemble = TRUE;
    }
    if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) {
        frag_msg = fragment_end_seq_next (&rtse_reassembly_table,
                          pinfo, rtse_id, NULL);
        next_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled RTSE",
                             frag_msg, &rtse_frag_items, NULL, parent_tree);
    }

    item = proto_tree_add_item(parent_tree, proto_rtse, next_tvb ? next_tvb : tvb, 0, -1, ENC_NA);
    tree = proto_item_add_subtree(item, ett_rtse);

    if (rtse_reassemble && session->spdu_type == SES_DATA_TRANSFER) {
        /* strip off the OCTET STRING encoding - including any CONSTRUCTED OCTET STRING */
        dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, offset, hf_rtse_segment_data, &data_tvb);

        if (data_tvb) {
            fragment_length = tvb_captured_length_remaining (data_tvb, 0);
            proto_item_append_text(asn1_ctx.created_item, " (%u byte%s)", fragment_length,
                                        plurality(fragment_length, "", "s"));
            frag_msg = fragment_add_seq_next (&rtse_reassembly_table,
                              data_tvb, 0, pinfo,
                              rtse_id, NULL,
                              fragment_length, TRUE);
            if (frag_msg && pinfo->num != frag_msg->reassembled_in) {
                /* Add a "Reassembled in" link if not reassembled in this frame */
                proto_tree_add_uint (tree, *(rtse_frag_items.hf_reassembled_in),
                             data_tvb, 0, 0, frag_msg->reassembled_in);
            }
            pinfo->fragmented = TRUE;
            data_handled = TRUE;
        } else {
            fragment_length = tvb_captured_length_remaining (tvb, offset);
        }

        col_append_fstr(pinfo->cinfo, COL_INFO, "[RTSE fragment, %u byte%s]",
                    fragment_length, plurality(fragment_length, "", "s"));
    } else if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) {
        if (next_tvb) {
            /* ROS won't do this for us */
            session->ros_op = (ROS_OP_INVOKE | ROS_OP_ARGUMENT);
            /*offset=*/dissect_ber_external_type(FALSE, tree, next_tvb, 0, &asn1_ctx, -1, call_rtse_external_type_callback);
            top_tree = NULL;
            /* Return other than 0 to indicate that we handled this packet */
            return 1;
        } else {
            offset = tvb_captured_length (tvb);
        }
        pinfo->fragmented = FALSE;
        data_handled = TRUE;
    }

    if (!data_handled) {
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
            old_offset=offset;
            offset=dissect_rtse_RTSE_apdus(TRUE, tvb, offset, &asn1_ctx, tree, -1);
            if (offset == old_offset) {
                next_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
                                ett_rtse_unknown, &item, "Unknown RTSE PDU");
                expert_add_info (pinfo, item, &ei_rtse_unknown_rtse_pdu);
                dissect_unknown_ber(pinfo, tvb, offset, next_tree);
                break;
            }
        }
    }

    top_tree = NULL;
    return tvb_captured_length(tvb);
}
Exemple #4
0
static int
socks_udp_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {

/* Conversation dissector called from UDP dissector. Decode and display */
/* the socks header, the pass the rest of the data to the udp port  */
/* decode routine to  handle the payload.               */

    int                 offset = 0;
    guint32            *ptr;
    socks_hash_entry_t *hash_info;
    conversation_t     *conversation;
    proto_tree         *socks_tree;
    proto_item         *ti;

    conversation = find_conversation_pinfo( pinfo, 0);

    DISSECTOR_ASSERT( conversation);    /* should always find a conversation */

    hash_info = (socks_hash_entry_t *)conversation_get_proto_data(conversation, proto_socks);

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Socks");
    col_set_str(pinfo->cinfo, COL_INFO, "Version: 5, UDP Associated packet");

    if ( tree) {
        ti = proto_tree_add_protocol_format( tree, proto_socks, tvb, offset, -1, "Socks" );

        socks_tree = proto_item_add_subtree(ti, ett_socks);

        proto_tree_add_item(socks_tree, hf_socks_reserved2, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;