Example #1
0
/*
 * Dissector that returns:
 *
 *	The amount of data in the protocol's PDU, if it was able to
 *	dissect all the data;
 *
 *	0, if the tvbuff doesn't contain a PDU for that protocol;
 *
 *	The negative of the amount of additional data needed, if
 *	we need more data (e.g., from subsequent TCP segments) to
 *	dissect the entire PDU.
 */
static int
dissect_ccn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint tvb_size = 0;
    proto_tree *ccn_tree;
    proto_item *ti = NULL;
    const unsigned char *ccnb;
    struct ccn_skeleton_decoder skel_decoder;
    struct ccn_skeleton_decoder *sd;
    struct ccn_charbuf *c;
    int packet_type = 0;
    int packet_type_length = 0;
    /* a couple of basic checks to rule out packets that are definitely not ours */
    tvb_size = tvb_length(tvb);
    if (tvb_size < CCN_MIN_PACKET_SIZE || tvb_get_guint8(tvb, 0) == 0)
        return (0);
    
    sd = &skel_decoder;
    memset(sd, 0, sizeof(*sd));
    sd->state |= CCN_DSTATE_PAUSE;
    ccnb = ep_tvb_memdup(tvb, 0, tvb_size);
    ccn_skeleton_decode(sd, ccnb, tvb_size);
    if (sd->state < 0)
        return (0);
    if (CCN_GET_TT_FROM_DSTATE(sd->state) == CCN_DTAG) {
        packet_type = sd->numval;
        packet_type_length = sd->index;
    } else {
        return (0);
    }
    memset(sd, 0, sizeof(*sd));
    ccn_skeleton_decode(sd, ccnb, tvb_size);
    if (!CCN_FINAL_DSTATE(sd->state)) {
        pinfo->desegment_offset = 0;
        pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
        return (-1); /* what should this be? */
    }
    
    /* Make it visible that we're taking this packet */
    if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "CCN");
    }
    
    /* Clear out stuff in the info column */
    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_clear(pinfo->cinfo, COL_INFO);
    }
    
    c = ccn_charbuf_create();
    ccn_uri_append(c, ccnb, tvb_size, 1);
    
    /* Add the packet type and CCN URI to the info column */
    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_add_str(pinfo->cinfo, COL_INFO,
                    val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x"));
        col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, ccn_charbuf_as_string(c));
    }
    
    if (tree == NULL) {
        ccn_charbuf_destroy(&c);
        return (sd->index);
    }
    
    ti = proto_tree_add_protocol_format(tree, proto_ccn, tvb, 0, -1,
                                        "Content-centric Networking Protocol, %s, %s",
                                        val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x"),
                                        ccn_charbuf_as_string(c));
    ccn_tree = proto_item_add_subtree(ti, ett_ccn);
    ccn_charbuf_destroy(&c);
    ti = proto_tree_add_uint(ccn_tree, hf_ccn_type, tvb, 0, packet_type_length, packet_type);
    
    switch (packet_type) {
        case CCN_DTAG_ContentObject:
            if (0 > dissect_ccn_contentobject(ccnb, sd->index, tvb, pinfo, ccn_tree))
                return (0);
            break;
        case CCN_DTAG_Interest:
            if (0 > dissect_ccn_interest(ccnb, sd->index, tvb, pinfo, ccn_tree))
                return (0);
            break;
    }
    
    return (sd->index);
}
Example #2
0
static void dissect_mqpcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, mq_parm_t* p_mq_parm)
{
    gint offset = 0;
    gboolean bLittleEndian;

    bLittleEndian = ((p_mq_parm->mq_cur_ccsid.encod & MQ_MQENC_INTEGER_MASK) == MQ_MQENC_INTEGER_REVERSED) ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;

    if (tvb_length(tvb) >= 36)
    {
        gint iSizeMQCFH = 36;
        guint32 iCommand = tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian);

        if (tree)
        {
            proto_item *ti;
            proto_tree *mq_tree;
            proto_tree *mqroot_tree;
            char        sTmp[256];
            guint32     uCnt;
            guint32     uTyp;
            guint32     uCmd;
            guint32     uCC;
            guint32     uRC;

            uTyp = tvb_get_guint32_endian(tvb, offset     , bLittleEndian);
            uCmd = tvb_get_guint32_endian(tvb, offset + 12, bLittleEndian);
            uCC  = tvb_get_guint32_endian(tvb, offset + 24, bLittleEndian);
            uRC  = tvb_get_guint32_endian(tvb, offset + 28, bLittleEndian);
            uCnt = tvb_get_guint32_endian(tvb, offset + 32, bLittleEndian);

            if (uCC || uRC)
            {
                g_snprintf(sTmp, (gulong)sizeof(sTmp)-1, " %-s [%d-%s] {%d-%s} PrmCnt(%d) CC(%d-%s) RC(%d-%s)",
                    MQ_TEXT_CFH,
                    uTyp, val_to_str_const(uTyp, GET_VALSV(mqcft), "Unknown"),
                    uCmd, val_to_str_const(uCmd, GET_VALSV(mqcmd), "Unknown"),
                    uCnt,
                    uCC, val_to_str_const(uCC, GET_VALSV(mqcc), "Unknown"),
                    uRC, val_to_str_const(uRC, GET_VALSV(mqrc), "Unknown"));
            }
            else
            {
                g_snprintf(sTmp, (gulong)sizeof(sTmp)-1, " %-s [%d-%s] {%d-%s} PrmCnt(%d)",
                    MQ_TEXT_CFH,
                    uTyp, val_to_str_const(uTyp, GET_VALSV(mqcft), "Unknown"),
                    uCmd, val_to_str_const(uCmd, GET_VALSV(mqcmd), "Unknown"),
                    uCnt);
            }

            ti = proto_tree_add_item(tree, proto_mqpcf, tvb, offset, -1, ENC_NA);

            proto_item_append_text(ti, " (%s)", val_to_str(iCommand, GET_VALSV(mqcmd), "Unknown (0x%02x)"));
            mqroot_tree = proto_item_add_subtree(ti, ett_mqpcf);

            ti = proto_tree_add_text(mqroot_tree, tvb, offset, iSizeMQCFH, "%s", sTmp);
            mq_tree = proto_item_add_subtree(ti, ett_mqpcf_cfh);

            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_type     , tvb, offset +  0, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_length   , tvb, offset +  4, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_version  , tvb, offset +  8, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_command  , tvb, offset + 12, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_MsgSeqNbr, tvb, offset + 16, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_control  , tvb, offset + 20, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_compcode , tvb, offset + 24, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_reason   , tvb, offset + 28, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_ParmCount, tvb, offset + 32, 4, bLittleEndian);
            dissect_mqpcf_parm(tvb, pinfo, mqroot_tree, offset + iSizeMQCFH, uCnt, bLittleEndian, TRUE);
        }
    }
}
/*
* Dissect DISP PDUs inside a ROS PDUs
*/
static void
dissect_disp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	int offset = 0;
	int old_offset;
	proto_item *item=NULL;
	proto_tree *tree=NULL;
	int (*disp_dissector)(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_) = NULL;
	char *disp_op_name;
	asn1_ctx_t asn1_ctx;

	asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);

	/* do we have operation information from the ROS dissector?  */
	if( !pinfo->private_data ){
		if(parent_tree){
			proto_tree_add_text(parent_tree, tvb, offset, -1,
				"Internal error: can't get operation information from ROS dissector.");
		} 
		return  ;
	} else {
		session  = ( (struct SESSION_DATA_STRUCTURE*)(pinfo->private_data) );
	}

	if(parent_tree){
		item = proto_tree_add_item(parent_tree, proto_disp, tvb, 0, -1, FALSE);
		tree = proto_item_add_subtree(item, ett_disp);
	}
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "DISP");
  	col_clear(pinfo->cinfo, COL_INFO);

	switch(session->ros_op & ROS_OP_MASK) {
	case (ROS_OP_BIND | ROS_OP_ARGUMENT):	/*  BindInvoke */
	  disp_dissector = dissect_disp_DSAShadowBindArgument;
	  disp_op_name = "Shadow-Bind-Argument";
	  break;
	case (ROS_OP_BIND | ROS_OP_RESULT):	/*  BindResult */
	  disp_dissector = dissect_disp_DSAShadowBindResult;
	  disp_op_name = "Shadow-Bind-Result";
	  break;
	case (ROS_OP_BIND | ROS_OP_ERROR):	/*  BindError */
	  disp_dissector = dissect_disp_DSAShadowBindError;
	  disp_op_name = "Shadow-Bind-Error";
	  break;
	case (ROS_OP_INVOKE | ROS_OP_ARGUMENT):	/*  Invoke Argument */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* requestShadowUpdate */
	    disp_dissector = dissect_disp_RequestShadowUpdateArgument;
	    disp_op_name = "Request-Shadow-Update-Argument";
	    break;
	  case 2: /* updateShadow*/
	    disp_dissector = dissect_disp_UpdateShadowArgument;
	    disp_op_name = "Update-Shadow-Argument";
	    break;
	  case 3: /* coordinateShadowUpdate */
	    disp_dissector = dissect_disp_CoordinateShadowUpdateArgument;
	    disp_op_name = "Coordinate-Shadow-Update-Argument";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP opcode (%d)",
				session->ros_op & ROS_OP_OPCODE_MASK);
	    break;
	  }
	  break;
	case (ROS_OP_INVOKE | ROS_OP_RESULT):	/*  Return Result */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* requestShadowUpdate */
	    disp_dissector = dissect_disp_RequestShadowUpdateResult;
	    disp_op_name = "Request-Shadow-Result";
	    break;
	  case 2: /* updateShadow */
	    disp_dissector = dissect_disp_UpdateShadowResult;
	    disp_op_name = "Update-Shadow-Result";
	    break;
	  case 3: /* coordinateShadowUpdate */
	    disp_dissector = dissect_disp_CoordinateShadowUpdateResult;
	    disp_op_name = "Coordinate-Shadow-Update-Result";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP opcode (%d)",
				session->ros_op & ROS_OP_OPCODE_MASK);
	    break;
	  }
	  break;
	case (ROS_OP_INVOKE | ROS_OP_ERROR):	/*  Return Error */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* shadowError */
	    disp_dissector = dissect_disp_ShadowError;
	    disp_op_name = "Shadow-Error";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP errcode (%d)",
				session->ros_op & ROS_OP_OPCODE_MASK);
	    break;
	  }
	  break;
	default:
	  proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP PDU");
	  return;
	}

	if(disp_dissector) {
	  col_set_str(pinfo->cinfo, COL_INFO, disp_op_name);

	  while (tvb_reported_length_remaining(tvb, offset) > 0){
	    old_offset=offset;
	    offset=(*disp_dissector)(FALSE, tvb, offset, &asn1_ctx, tree, -1);
	    if(offset == old_offset){
	      proto_tree_add_text(tree, tvb, offset, -1,"Internal error, zero-byte DISP PDU");
	      offset = tvb_length(tvb);
	      break;
	    }
	  }
	}
}
Example #4
0
static void
dissect_rtacser_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* Set up structures needed to add the protocol subtree and manage it */
    proto_item    *rtacser_item, *ts_item, *cl_item, *data_payload;
    proto_tree    *rtacser_tree, *cl_tree;
    int           offset=0, len=0;
    guint         event_type;
    guint32       timestamp1, timestamp2;
    gboolean      cts, dcd, dsr, rts, dtr, ring, mbok;
    tvbuff_t      *payload_tvb;

    len = RTACSER_HEADER_LEN;

    /* Make entries in Protocol column on summary display */
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTAC Serial");
    col_clear(pinfo->cinfo, COL_INFO);

    if (tree) {

        rtacser_item = proto_tree_add_protocol_format(tree, proto_rtacser, tvb, 0, len, "RTAC Serial Line");
        rtacser_tree = proto_item_add_subtree(rtacser_item, ett_rtacser);

        /* Time-stamp is stored as 2 x 32-bit unsigned integers, the left and right-hand side of the decimal point respectively */
        /* The format mirrors the timeval struct - absolute Epoch time (seconds since 1/1/1970) with an added microsecond component */
        timestamp1 = tvb_get_ntohl(tvb, offset);
        timestamp2 = tvb_get_ntohl(tvb, offset+4);
        ts_item = proto_tree_add_item(rtacser_tree, hf_rtacser_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN);
        proto_item_set_text(ts_item, "Arrived At Time: %u.%u" , timestamp1, timestamp2);
        offset += 8;

        /* Set INFO column with RTAC Serial Event Type */
        event_type = tvb_get_guint8(tvb, offset);
        col_add_fstr(pinfo->cinfo, COL_INFO, "%-21s", val_to_str_const(event_type, rtacser_eventtype_vals, "Unknown Type"));

        /* Add event type to tree */
        proto_tree_add_item(rtacser_tree, hf_rtacser_event_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        /* Retrieve EIA-232 serial control line states */
        cts = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_CTS;
        dcd = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DCD;
        dsr = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DSR;
        rts = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_RTS;
        dtr = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DTR;
        ring = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_RING;
        mbok = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_MBOK;

        cl_item = proto_tree_add_text(rtacser_tree, tvb, offset, 1, "Control Lines");
        cl_tree = proto_item_add_subtree(cl_item, ett_rtacser_cl);

        /* Add UART Control Line information to INFO column */
        col_append_str(pinfo->cinfo, COL_INFO, " ( ");
        (cts)  ? col_append_str(pinfo->cinfo, COL_INFO, "CTS") : col_append_str(pinfo->cinfo, COL_INFO, "/CTS");
        (dcd)  ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DCD") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DCD");
        (dsr)  ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DSR") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DSR");
        (rts)  ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RTS") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/RTS");
        (dtr)  ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DTR") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DTR");
        (ring) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RING") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/RING");
        (mbok) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "MBOK") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/MBOK");
        col_append_str(pinfo->cinfo, COL_INFO, " )");

        /* Add UART Control Line information to tree */
        proto_item_append_text(cl_item, " (");
        (cts)  ? proto_item_append_text(cl_item, "CTS, ") : proto_item_append_text(cl_item, "/CTS, ");
        (dcd)  ? proto_item_append_text(cl_item, "DCD, ") : proto_item_append_text(cl_item, "/DCD, ");
        (dsr)  ? proto_item_append_text(cl_item, "DSR, ") : proto_item_append_text(cl_item, "/DSR, ");
        (rts)  ? proto_item_append_text(cl_item, "RTS, ") : proto_item_append_text(cl_item, "/RTS, ");
        (dtr)  ? proto_item_append_text(cl_item, "DTR, ") : proto_item_append_text(cl_item, "/DTR, ");
        (ring) ? proto_item_append_text(cl_item, "RING, ") : proto_item_append_text(cl_item, "/RING, ");
        (mbok) ? proto_item_append_text(cl_item, "MBOK") : proto_item_append_text(cl_item, "/MBOK");
        proto_item_append_text(cl_item, ")");

        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_cts, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dcd, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dsr, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_rts, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dtr, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_ring, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_mbok, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        /* 2-byte footer */
        proto_tree_add_item(rtacser_tree, hf_rtacser_footer, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;

        /* If no payload dissector has been selected, indicate to the user the preferences options */
        if ((tvb_reported_length_remaining(tvb, offset) > 0) && (global_rtacser_payload_proto == RTACSER_PAYLOAD_NONE)) {
            data_payload = proto_tree_add_item(tree, hf_rtacser_data, tvb, offset, -1, ENC_NA);
            proto_item_set_text(data_payload,"Payload Protocol not selected.  Check 'Preferences-> Protocols-> RTAC Serial' for options");
            return;
        }

    } /* tree */

    /* Determine correct message type and call appropriate dissector */
    if (tvb_reported_length_remaining(tvb, RTACSER_HEADER_LEN) > 0) {

        switch (global_rtacser_payload_proto) {
            case RTACSER_PAYLOAD_SELFM:
                payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN);
                call_dissector(selfm_handle, payload_tvb, pinfo, tree);
                break;
            case RTACSER_PAYLOAD_DNP3:
                payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN);
                call_dissector(dnp3_handle, payload_tvb, pinfo, tree);
                break;
            case RTACSER_PAYLOAD_MODBUS:
                payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN);
                call_dissector(modbus_handle, payload_tvb, pinfo, tree);
                break;
            case RTACSER_PAYLOAD_SYNPHASOR:
                payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN);
                call_dissector(synphasor_handle, payload_tvb, pinfo, tree);
                break;
            default:
                break;
        }
    }

}
Example #5
0
dissect_lge_monitor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
	int offset = 0;
	guint32 lge_monitor_proto_id;
	tvbuff_t* next_tvb = NULL;
	proto_tree* header_tree;

/* Set up structures needed to add the protocol subtree and manage it */
	proto_item *ti;
	proto_tree *lge_monitor_tree;

/* Make entries in Protocol column and Info column on summary display */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "LGE Monitor");

	ti = proto_tree_add_item(tree, proto_lge_monitor, tvb, 0, LGEMON_PROTO_HEADER_LENGTH, ENC_NA);
	lge_monitor_tree = proto_item_add_subtree(ti, ett_lge_monitor);

	header_tree = proto_tree_add_subtree(lge_monitor_tree, tvb, offset, LGEMON_PROTO_HEADER_LENGTH, ett_lge_header, NULL, "LGE Monitor PDU");
	proto_tree_add_item(header_tree, hf_lge_monitor_dir, tvb, offset, 4, ENC_BIG_ENDIAN);
	offset += 4;
	lge_monitor_proto_id = tvb_get_ntohl(tvb,offset);
	proto_tree_add_item(header_tree, hf_lge_monitor_prot, tvb, offset, 4, ENC_BIG_ENDIAN);
	offset += 4;
	proto_tree_add_item(header_tree, hf_lge_monitor_length, tvb, offset, 4, ENC_BIG_ENDIAN);
	offset += 4;

	next_tvb = tvb_new_subset_remaining(tvb, offset);

	switch (lge_monitor_proto_id){
	case 0: /* MTP3 */
		call_dissector(mtp3_handle, next_tvb, pinfo, tree);
Example #6
0
static void
dissect_status (packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 flags)
{
    proto_item *item = NULL;
    proto_tree *tree = NULL;

    if (parent_tree) {
        item=proto_tree_add_uint(parent_tree, hf_sbccs_dib_status,
                                 tvb, offset, 1, flags);
        tree=proto_item_add_subtree(item, ett_sbccs_dib_status);
    }


    proto_tree_add_boolean(tree, hf_sbccs_dib_status_attention, tvb, offset, 1, flags);
    if (flags & 0x80) {
        proto_item_append_text(item, "  Attention");
        col_append_str(pinfo->cinfo, COL_INFO, "  Attention");
    }
    flags &= (~( 0x80 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_modifier, tvb, offset, 1, flags);
    if (flags & 0x40) {
        proto_item_append_text(item, "  Status Modifier");
        col_append_str(pinfo->cinfo, COL_INFO, "  Status Modifier");
    }
    flags &= (~( 0x40 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_cue, tvb, offset, 1, flags);
    if (flags & 0x20) {
        proto_item_append_text(item, "  Control-Unit End");
        col_append_str(pinfo->cinfo, COL_INFO, "  Control-Unit End");
    }
    flags &= (~( 0x20 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_busy, tvb, offset, 1, flags);
    if (flags & 0x10) {
        proto_item_append_text(item, "  Busy");
        col_append_str(pinfo->cinfo, COL_INFO, "  Busy");
    }
    flags &= (~( 0x10 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_channelend, tvb, offset, 1, flags);
    if (flags & 0x08) {
        proto_item_append_text(item, "  Channel End");
        col_append_str(pinfo->cinfo, COL_INFO, "  Channel End");
    }
    flags &= (~( 0x08 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_deviceend, tvb, offset, 1, flags);
    if (flags & 0x04) {
        proto_item_append_text(item, "  Device End");
        col_append_str(pinfo->cinfo, COL_INFO, "  Device End");
    }
    flags &= (~( 0x04 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_unit_check, tvb, offset, 1, flags);
    if (flags & 0x02) {
        proto_item_append_text(item, "  Unit Check");
        col_append_str(pinfo->cinfo, COL_INFO, "  Unit Check");
    }
    flags &= (~( 0x02 ));

    proto_tree_add_boolean(tree, hf_sbccs_dib_status_unit_exception, tvb, offset, 1, flags);
    if (flags & 0x01) {
        proto_item_append_text(item, "  Unit Exception");
        col_append_str(pinfo->cinfo, COL_INFO, "  Unit Exception");
    }
    flags &= (~( 0x01 ));

}
Example #7
0
/* Look for conversation info and display any setup info found */
void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	/* Conversation and current data */
	conversation_t *p_conv = NULL;
	struct _msrp_conversation_info *p_conv_data = NULL;

	/* Use existing packet data if available */
	p_conv_data = p_get_proto_data(pinfo->fd, proto_msrp);

	if (!p_conv_data)
	{
		/* First time, get info from conversation */
		p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
		                           PT_TCP,
		                           pinfo->destport, pinfo->srcport, 0);

		if (p_conv)
		{
			/* Look for data in conversation */
			struct _msrp_conversation_info *p_conv_packet_data;
			p_conv_data = conversation_get_proto_data(p_conv, proto_msrp);

			if (p_conv_data)
			{
				/* Save this conversation info into packet info */
				p_conv_packet_data = se_alloc(sizeof(struct _msrp_conversation_info));
				if (!p_conv_packet_data)
				{
					return;
				}
				memcpy(p_conv_packet_data, p_conv_data,
				       sizeof(struct _msrp_conversation_info));

				p_add_proto_data(pinfo->fd, proto_msrp, p_conv_packet_data);
			}
		}
	}

	/* Create setup info subtree with summary info. */
	if (p_conv_data && p_conv_data->setup_method_set)
	{
		proto_tree *msrp_setup_tree;
		proto_item *ti =  proto_tree_add_string_format(tree, hf_msrp_setup, tvb, 0, 0,
		                                               "",
		                                               "Stream setup by %s (frame %u)",
		                                               p_conv_data->setup_method,
		                                               p_conv_data->setup_frame_number);
		PROTO_ITEM_SET_GENERATED(ti);
		msrp_setup_tree = proto_item_add_subtree(ti, ett_msrp_setup);
		if (msrp_setup_tree)
		{
			/* Add details into subtree */
			proto_item* item = proto_tree_add_uint(msrp_setup_tree, hf_msrp_setup_frame,
			                                       tvb, 0, 0, p_conv_data->setup_frame_number);
			PROTO_ITEM_SET_GENERATED(item);
			item = proto_tree_add_string(msrp_setup_tree, hf_msrp_setup_method,
			                             tvb, 0, 0, p_conv_data->setup_method);
			PROTO_ITEM_SET_GENERATED(item);
		}
	}
}
Example #8
0
static void dissect_tns_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
                             proto_tree *tree, proto_tree *tns_tree)
{
    proto_tree *data_tree = NULL, *ti;
    proto_item *hidden_item;
    int is_sns = 0;

    if ( tvb_bytes_exist(tvb, offset+2, 4) )
    {
        if ( tvb_get_guint8(tvb, offset+2) == 0xDE &&
                tvb_get_guint8(tvb, offset+3) == 0xAD &&
                tvb_get_guint8(tvb, offset+4) == 0xBE &&
                tvb_get_guint8(tvb, offset+5) == 0xEF )
        {
            is_sns = 1;
        }
    }

    if ( tree )
    {
        if ( is_sns )
        {
            ti = proto_tree_add_text(tns_tree, tvb, offset, -1,
                                     "Secure Network Services");
        }
        else
        {
            ti = proto_tree_add_text(tns_tree, tvb, offset, -1,
                                     "Data");
        }
        data_tree = proto_item_add_subtree(ti, ett_tns_data);

        hidden_item = proto_tree_add_boolean(tns_tree, hf_tns_data, tvb, 0, 0,
                                             TRUE);
        PROTO_ITEM_SET_HIDDEN(hidden_item);
    }

    if ( tree )
    {
        proto_tree *df_tree = NULL;

        ti = proto_tree_add_item(data_tree, hf_tns_data_flag, tvb, offset, 2, ENC_BIG_ENDIAN);

        df_tree = proto_item_add_subtree(ti, ett_tns_data_flag);
        proto_tree_add_item(df_tree, hf_tns_data_flag_send, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(df_tree, hf_tns_data_flag_rc, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(df_tree, hf_tns_data_flag_c, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(df_tree, hf_tns_data_flag_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(df_tree, hf_tns_data_flag_more, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(df_tree, hf_tns_data_flag_eof, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(df_tree, hf_tns_data_flag_dic, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(df_tree, hf_tns_data_flag_rts, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(df_tree, hf_tns_data_flag_sntt, tvb, offset, 2, ENC_BIG_ENDIAN);
    }
    offset += 2;

    if ( check_col(pinfo->cinfo, COL_INFO) )
    {
        if ( is_sns )
        {
            col_append_str(pinfo->cinfo, COL_INFO, ", SNS");
        }
        else
        {
            col_append_str(pinfo->cinfo, COL_INFO, ", Data");
        }
    }

    if ( data_tree )
    {
        call_dissector(data_handle,
                       tvb_new_subset_remaining(tvb, offset), pinfo, data_tree);
    }

    return;
}
Example #9
0
static void dissect_tns_connect(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                proto_tree *tree, proto_tree *tns_tree)
{
    proto_tree *connect_tree = NULL, *ti;
    proto_item *hidden_item;
    int cd_offset;
    int cd_len;
    int tns_offset = offset-8;

    if ( tree )
    {
        ti = proto_tree_add_text(tns_tree, tvb, offset, -1,
                                 "Connect");
        connect_tree = proto_item_add_subtree(ti, ett_tns_connect);

        hidden_item = proto_tree_add_boolean(tns_tree, hf_tns_connect, tvb,
                                             0, 0, TRUE);
        PROTO_ITEM_SET_HIDDEN(hidden_item);
    }

    col_append_str(pinfo->cinfo, COL_INFO, ", Connect");

    if ( connect_tree )
    {
        proto_tree_add_item(connect_tree, hf_tns_version, tvb,
                            offset, 2, ENC_BIG_ENDIAN);
    }
    offset += 2;

    if ( connect_tree )
    {
        proto_tree_add_item(connect_tree, hf_tns_compat_version, tvb,
                            offset, 2, ENC_BIG_ENDIAN);
    }
    offset += 2;

    if ( connect_tree )
    {
        proto_tree *sopt_tree = NULL;

        ti = proto_tree_add_item(connect_tree, hf_tns_service_options, tvb,
                                 offset, 2, ENC_BIG_ENDIAN);

        sopt_tree = proto_item_add_subtree(ti, ett_tns_sopt_flag);

        dissect_tns_service_options(tvb, offset, sopt_tree);


    }
    offset += 2;

    if ( connect_tree )
    {
        proto_tree_add_item(connect_tree, hf_tns_sdu_size, tvb,
                            offset, 2, ENC_BIG_ENDIAN);
    }
    offset += 2;

    if ( connect_tree )
    {
        proto_tree_add_item(connect_tree, hf_tns_max_tdu_size, tvb,
                            offset, 2, ENC_BIG_ENDIAN);
    }
    offset += 2;

    if ( connect_tree )
    {
        proto_tree *ntp_tree = NULL;

        ti = proto_tree_add_item(connect_tree, hf_tns_nt_proto_characteristics, tvb,
                                 offset, 2, ENC_BIG_ENDIAN);

        ntp_tree = proto_item_add_subtree(ti, ett_tns_ntp_flag);

        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_hangon, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_crel, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_tduio, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_srun, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_dtest, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_cbio, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_asio, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_pio, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_grant, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_handoff, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_sigio, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_sigpipe, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_sigurg, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_urgentio, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_fdio, tvb, offset, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(ntp_tree, hf_tns_ntp_flag_testop, tvb, offset, 2, ENC_BIG_ENDIAN);
    }
    offset += 2;

    if ( connect_tree )
    {
        proto_tree_add_item(connect_tree, hf_tns_line_turnaround, tvb,
                            offset, 2, ENC_BIG_ENDIAN);
    }
    offset += 2;

    if ( connect_tree )
    {
        proto_tree_add_item(connect_tree, hf_tns_value_of_one, tvb,
                            offset, 2, ENC_NA);
    }
    offset += 2;

    cd_len = tvb_get_ntohs(tvb, offset);
    if ( connect_tree )
    {
        proto_tree_add_uint(connect_tree, hf_tns_connect_data_length, tvb,
                            offset, 2, cd_len);
    }
    offset += 2;

    cd_offset = tvb_get_ntohs(tvb, offset);
    if ( connect_tree )
    {
        proto_tree_add_uint(connect_tree, hf_tns_connect_data_offset, tvb,
                            offset, 2, cd_offset);
    }
    offset += 2;

    if ( connect_tree )
    {
        proto_tree_add_item(connect_tree, hf_tns_connect_data_max, tvb,
                            offset, 4, ENC_BIG_ENDIAN);
    }
    offset += 4;

    if ( connect_tree )
    {
        proto_tree *cflag_tree = NULL;

        ti = proto_tree_add_item(connect_tree, hf_tns_connect_flags0, tvb,
                                 offset, 1, ENC_BIG_ENDIAN);

        cflag_tree = proto_item_add_subtree(ti, ett_tns_conn_flag);

        dissect_tns_connect_flag(tvb, offset, cflag_tree);
    }
    offset += 1;

    if ( connect_tree )
    {
        proto_tree *cflag_tree = NULL;

        ti = proto_tree_add_item(connect_tree, hf_tns_connect_flags1, tvb,
                                 offset, 1, ENC_BIG_ENDIAN);

        cflag_tree = proto_item_add_subtree(ti, ett_tns_conn_flag);

        dissect_tns_connect_flag(tvb, offset, cflag_tree);
    }
    offset += 1;

    /*
     * XXX - sometimes it appears that this stuff isn't present
     * in the packet.
     */
    if (offset + 16 <= tns_offset+cd_offset)
    {
        if ( connect_tree )
        {
            proto_tree_add_item(connect_tree, hf_tns_trace_cf1, tvb,
                                offset, 4, ENC_BIG_ENDIAN);
        }
        offset += 4;

        if ( connect_tree )
        {
            proto_tree_add_item(connect_tree, hf_tns_trace_cf2, tvb,
                                offset, 4, ENC_BIG_ENDIAN);
        }
        offset += 4;

        if ( connect_tree )
        {
            proto_tree_add_item(connect_tree, hf_tns_trace_cid, tvb,
                                offset, 8, ENC_BIG_ENDIAN);
        }
        offset += 8;
    }

    if ( connect_tree && cd_len > 0)
    {
        proto_tree_add_item(connect_tree, hf_tns_connect_data, tvb,
                            tns_offset+cd_offset, -1, ENC_ASCII|ENC_NA);
    }
    return;
}
Example #10
0
/*
 * Name: isis_dissect_isis_hello()
 *
 * Description:
 *	This procedure rips apart the various types of ISIS hellos.  L1H and
 *	L2H's are identical for the most part, while the PTP hello has
 *	a shorter header.
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to add to.  May be NULL.
 *	int offset : our offset into packet data.
 *	int : hello type, a la packet-isis.h ISIS_TYPE_* values
 *	int : header length of packet.
 *	int : length of IDs in packet.
 *
 * Output:
 *	void, will modify proto_tree if not NULL.
 */
void
isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
	int hello_type, int header_length, int id_length)
{
	proto_item	*ti;
	proto_tree	*hello_tree = NULL;
	int 		len;
	guint8		octet;
	const guint8	*source_id;
	guint16		pdu_length;
	const guint8	*lan_id;

	if (tree) {
		ti = proto_tree_add_text(tree, tvb, offset, -1, "ISIS HELLO");
		hello_tree = proto_item_add_subtree(ti, ett_isis_hello);
		octet = tvb_get_guint8(tvb, offset);
		proto_tree_add_uint_format(hello_tree,
			hf_isis_hello_circuit_reserved,
			tvb, offset, 1, octet,
			"Circuit type              : %s, reserved(0x%02x == 0)",
				val_to_str(octet&ISIS_HELLO_CTYPE_MASK,
					isis_hello_circuit_type_vals,
					"Unknown (0x%x)"),
				octet&ISIS_HELLO_CT_RESERVED_MASK
			);
	}
	offset += 1;

	if (tree) {
		source_id = tvb_get_ptr(tvb, offset, id_length);
		proto_tree_add_bytes_format(hello_tree, hf_isis_hello_source_id, tvb,
			            offset, id_length, source_id,
			            "System-ID {Sender of PDU} : %s", 
			            print_system_id( source_id, id_length ) );
	}
	if (check_col(pinfo->cinfo, COL_INFO)) {
		col_append_fstr(pinfo->cinfo, COL_INFO, ", System-ID: %s",
			print_system_id( tvb_get_ptr(tvb, offset, id_length), id_length ) );
	}
	offset += id_length;

	if (tree) {
		proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, tvb,
			            offset, 2, FALSE);
	}
	offset += 2;

	pdu_length = tvb_get_ntohs(tvb, offset);
	if (tree) {
		proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
			            offset, 2, pdu_length);
	}
	offset += 2;

	if (hello_type == ISIS_TYPE_PTP_HELLO) {
		if (tree) {
			proto_tree_add_item(hello_tree, hf_isis_hello_local_circuit_id, tvb,
				         offset, 1, FALSE );
		}
		offset += 1;
	} else {
		if (tree) {
			octet = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint_format(hello_tree, hf_isis_hello_priority_reserved, tvb,
				    offset, 1, octet,
				    "Priority                  : %d, reserved(0x%02x == 0)",
					octet&ISIS_HELLO_PRIORITY_MASK,
					octet&ISIS_HELLO_P_RESERVED_MASK );
		}
		offset += 1;

		if (tree) {
			lan_id = tvb_get_ptr(tvb, offset, id_length+1);
			proto_tree_add_bytes_format(hello_tree, hf_isis_hello_lan_id, tvb,
				     offset, id_length + 1, lan_id,
					 "System-ID {Designated IS} : %s",
					      print_system_id( lan_id, id_length + 1 ) );
		}
		offset += id_length + 1;
	}

	len = pdu_length;
	len -= header_length;
	if (len < 0) {
		isis_dissect_unknown(tvb, tree, offset,
			"Packet header length %d went beyond packet",
			header_length );
		return;
	}
	/*
	 * Now, we need to decode our CLVs.  We need to pass in
	 * our list of valid ones!
	 */
	if (hello_type == ISIS_TYPE_L1_HELLO){
		isis_dissect_clvs(tvb, hello_tree, offset,
			clv_l1_hello_opts, len, id_length,
			ett_isis_hello_clv_unknown);
	} else if (hello_type == ISIS_TYPE_L2_HELLO) {
		isis_dissect_clvs(tvb, hello_tree, offset,
			clv_l2_hello_opts, len, id_length,
			ett_isis_hello_clv_unknown);
	} else {
		isis_dissect_clvs(tvb, hello_tree, offset,
			clv_ptp_hello_opts, len, id_length,
			ett_isis_hello_clv_unknown);
	}
}
Example #11
0
static
void dissect_pw_cesopsn( tvbuff_t * tvb_original
						,packet_info * pinfo
						,proto_tree * tree
						,pwc_demux_type_t demux)
{
	const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/
	gint      packet_size;
	gint      payload_size;
	gint      padding_size;
	int properties;

	packet_size = tvb_reported_length_remaining(tvb_original, 0);

	/*
	 * FIXME
	 * "4" below should be replaced by something like "min_packet_size_this_dissector"
	 * Also call to dissect_try_cw_first_nibble() should be moved before this block
	 */
	if (packet_size < 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */
	{
		proto_item  *item;
		item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA);
		expert_add_info_format(pinfo, item, &ei_packet_size_too_small,
				       "PW packet size (%d) is too small to carry sensible information"
				       ,(int)packet_size);
		col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname);
		col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small");
		return;
	}

	switch (demux)
	{
	case PWC_DEMUX_MPLS:
		if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree))
		{
			return;
		}
		break;
	case PWC_DEMUX_UDP:
		break;
	default:
		DISSECTOR_ASSERT_NOT_REACHED();
		return;
	}

	/* check how "good" is this packet */
	/* also decide payload length from packet size and CW */
	properties = PWC_PACKET_PROPERTIES_T_INITIALIZER;
	if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/))
	{
		properties |= PWC_CW_BAD_BITS03;
	}
	if (0 != (tvb_get_guint8(tvb_original, 1) & 0xc0 /*frag*/))
	{
		properties |= PWC_CW_BAD_FRAG;
	}
	{
		/* RFC5086:
		 * [LEN (bits (10 to 15) MAY be used to carry the length of the CESoPSN
		 * packet (defined as the size of the CESoPSN header + the payload size)
		 * if it is less than 64 bytes, and MUST be set to zero otherwise.
		 * Note:  If fixed RTP header is used in the encapsulation, it is
		 * considered part of the CESoPSN header.]
		 *
		 * Note that this differs from RFC4385's definition of length:
		 * [ If the MPLS payload is less than 64 bytes, the length field
		 * MUST be set to the length of the PW payload...]
		 *
		 * We will use RFC5086's definition here.
		 */
		int  cw_len;
		gint payload_size_from_packet;

		cw_len = tvb_get_guint8(tvb_original, 1) & 0x3f;
		payload_size_from_packet = packet_size - encaps_size;
		if (cw_len != 0)
		{
			gint payload_size_from_cw;
			payload_size_from_cw = cw_len - encaps_size;
			/*
			 * Assumptions for error case,
			 * will be overwritten if no errors found:
			 */
			payload_size = payload_size_from_packet;
			padding_size = 0;

			if (payload_size_from_cw < 0)
			{
				properties |= PWC_CW_BAD_PAYLEN_LT_0;
			}
			else if (payload_size_from_cw > payload_size_from_packet)
			{
				properties |= PWC_CW_BAD_PAYLEN_GT_PACKET;
			}
			else if (payload_size_from_packet >= 64)
			{
				properties |= PWC_CW_BAD_LEN_MUST_BE_0;
			}
			else /* ok */
			{
				payload_size = payload_size_from_cw;
				padding_size = payload_size_from_packet - payload_size_from_cw; /* >=0 */
			}
		}
		else
		{
			payload_size = payload_size_from_packet;
			padding_size = 0;
		}
	}

	{
		guint8 cw_lm;
		cw_lm = tvb_get_guint8(tvb_original, 0) & 0x0b /*l+mod*/;
		if (NULL == try_val_to_str(cw_lm, vals_cw_lm))
		{
			properties |= PWC_CW_SUSPECT_LM;
		}

		{
			guint8 l_bit, m_bits;
			l_bit  = (cw_lm & 0x08) >> 3;
			m_bits = (cw_lm & 0x03) >> 0;
			if ((l_bit == 0 && m_bits == 0x0) /*CESoPSN data packet - normal situation*/
			    ||(l_bit == 0 && m_bits == 0x2) /*CESoPSN data packet - RDI on the AC*/ )
			{
				if ((payload_size == 0) || ((payload_size % 8) != 0))
				{
					properties |= PWC_PAY_SIZE_BAD;
				}
			}
			else if (l_bit == 1 && m_bits == 0x0) /*TDM data is invalid; payload MAY be omitted*/
			{
				/*allow any size of payload*/
			}
			else /*reserved combinations*/
			{
				/*allow any size of payload*/
			}
		}
	}

	/* fill up columns*/
	col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname);
	col_clear(pinfo->cinfo, COL_INFO);
	if (properties & PWC_ANYOF_CW_BAD)
	{
		col_set_str(pinfo->cinfo, COL_INFO, "CW:Bad, ");
	}
	else if (properties & PWC_ANYOF_CW_SUSPECT)
	{
		col_append_str(pinfo->cinfo, COL_INFO, "CW:Suspect, ");
	}

	if (properties & PWC_PAY_SIZE_BAD)
	{
		col_append_str(pinfo->cinfo, COL_INFO, "Payload size:Bad, ");
	}

	col_append_fstr(pinfo->cinfo, COL_INFO, "TDM octets:%d", (int)payload_size);

	if (padding_size != 0)
	{
		col_append_fstr(pinfo->cinfo, COL_INFO, ", Padding:%d", (int)padding_size);
	}

	{
		proto_item* item;
		item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA);
		pwc_item_append_cw(item,tvb_get_ntohl(tvb_original, 0),TRUE);
		pwc_item_append_text_n_items(item,(int)payload_size,"octet");
		{
			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				tvbuff_t* tvb;
				proto_item* item2;
				tvb = tvb_new_subset_length(tvb_original, 0, PWC_SIZEOF_CW);
				item2 = proto_tree_add_item(tree2, hf_cw, tvb, 0, -1, ENC_NA);
				pwc_item_append_cw(item2,tvb_get_ntohl(tvb, 0),FALSE);
				{
					proto_tree* tree3;
					tree3 = proto_item_add_subtree(item, ett);
					{
						proto_item* item3;
						if (properties & PWC_CW_BAD_BITS03) /*display only if value is wrong*/
						{
							item3 = proto_tree_add_item(tree3, hf_cw_bits03, tvb, 0, 1, ENC_BIG_ENDIAN);
							expert_add_info(pinfo, item3, &ei_cw_bits03);
						}

						item3 = proto_tree_add_item(tree3, hf_cw_lm,  tvb, 0, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_SUSPECT_LM)
						{
							expert_add_info(pinfo, item3, &ei_cw_lm);
						}

						proto_tree_add_item(tree3, hf_cw_r, tvb, 0, 1, ENC_BIG_ENDIAN);

						item3 = proto_tree_add_item(tree3, hf_cw_frg, tvb, 1, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_BAD_FRAG)
						{
							expert_add_info(pinfo, item3, &ei_cw_frg);
						}

						item3 = proto_tree_add_item(tree3, hf_cw_len, tvb, 1, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_BAD_PAYLEN_LT_0)
						{
							expert_add_info_format(pinfo, item3, &ei_pref_cw_len,
								"Bad Length: too small, must be > %d",
								(int)encaps_size);
						}
						if (properties & PWC_CW_BAD_PAYLEN_GT_PACKET)
						{
							expert_add_info_format(pinfo, item3, &ei_pref_cw_len,
								"Bad Length: must be <= than PSN packet size (%d)",
								(int)packet_size);
						}
						if (properties & PWC_CW_BAD_LEN_MUST_BE_0)
						{
							expert_add_info_format(pinfo, item3, &ei_pref_cw_len,
								"Bad Length: must be 0 if CESoPSN packet size (%d) is > 64",
								(int)packet_size);
						}

						proto_tree_add_item(tree3, hf_cw_seq, tvb, 2, 2, ENC_BIG_ENDIAN);

					}
				}
			}
		}

		/* payload */
		if (payload_size == 0)
		{
			if (properties & PWC_PAY_SIZE_BAD)
			{
				expert_add_info_format(pinfo, item, &ei_payload_size_invalid_error,
					"CESoPSN payload: none found. Size of payload must be <> 0");
			}
			else
			{
				expert_add_info_format(pinfo, item, &ei_payload_size_invalid_undecoded,
					"CESoPSN payload: omitted to conserve bandwidth");
			}
		}
		else
		{
			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				proto_item* item2;
				tvbuff_t* tvb;
				tvb = tvb_new_subset_length(tvb_original, PWC_SIZEOF_CW, payload_size);
				item2 = proto_tree_add_item(tree2, hf_payload, tvb, 0, -1, ENC_NA);
				pwc_item_append_text_n_items(item2,(int)payload_size,"octet");
				if (properties & PWC_PAY_SIZE_BAD)
				{
					expert_add_info_format(pinfo, item2, &ei_payload_size_invalid_error,
						"CESoPSN packet payload size must be multiple of 8");
				}
				tree2 = proto_item_add_subtree(item2, ett);
				call_dissector(data_handle, tvb, pinfo, tree2);
				item2 = proto_tree_add_int(tree2, hf_payload_l, tvb, 0, 0
					,(int)payload_size); /* allow filtering */
				PROTO_ITEM_SET_HIDDEN(item2);
			}
		}

		/* padding */
		if (padding_size > 0)
		{
			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				tvbuff_t* tvb;
				tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1);
				call_dissector(pw_padding_handle, tvb, pinfo, tree2);
			}
		}
	}
	return;
}
static void
dissect_dtp_tlv(packet_info *pinfo, tvbuff_t *tvb, int offset, int length,
		proto_tree *tree, proto_item *ti, proto_item *tlv_length_item, guint8 type)
{
	switch (type) {

	case DTP_TLV_DOMAIN:
		if (length <= 33) { /* VTP domain name is at most 32 bytes long and is null-terminated */
			proto_item_append_text(ti, ": %s", tvb_format_text(tvb, offset, length - 1));
			proto_tree_add_item(tree, hf_dtp_domain, tvb, offset, length, ENC_ASCII|ENC_NA);
		}
		else
			expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid);

		break;

	case DTP_TLV_TRSTATUS:
		if (length == 1) { /* Value field length must be 1 byte */
			proto_item * value_item = NULL;
			proto_tree * field_tree = NULL;
			guint8 trunk_status = tvb_get_guint8(tvb, offset);

			proto_item_append_text(ti,
				" (Operating/Administrative): %s/%s (0x%02x)",
				val_to_str_const(DTP_TOSVALUE(trunk_status), dtp_tos_vals, "Unknown operating status"),
				val_to_str_const(DTP_TASVALUE(trunk_status), dtp_tas_vals, "Unknown administrative status"),
				trunk_status);
			value_item = proto_tree_add_text(tree, tvb, offset, length, "Value: %s/%s (0x%02x)",
				val_to_str_const(DTP_TOSVALUE(trunk_status), dtp_tos_vals, "Unknown operating status"),
				val_to_str_const(DTP_TASVALUE(trunk_status), dtp_tas_vals, "Unknown administrative status"),
				trunk_status);
			field_tree = proto_item_add_subtree(value_item, ett_dtp_status);
			proto_tree_add_item(field_tree, hf_dtp_tos, tvb, offset, length, ENC_NA);
			proto_tree_add_item(field_tree, hf_dtp_tas, tvb, offset, length, ENC_NA);
			}
			else
				expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid);

		break;

	case DTP_TLV_TRTYPE:
		if (length == 1) { /* Value field length must be 1 byte */
			proto_item * value_item = NULL;
			proto_tree * field_tree = NULL;
			guint8 trunk_type = tvb_get_guint8(tvb, offset);
			proto_item_append_text(ti,
				" (Operating/Administrative): %s/%s (0x%02x)",
				val_to_str_const(DTP_TOTVALUE(trunk_type), dtp_tot_vals, "Unknown operating type"),
				val_to_str_const(DTP_TATVALUE(trunk_type), dtp_tat_vals, "Unknown administrative type"),
				trunk_type);
			value_item = proto_tree_add_text(tree, tvb, offset, length, "Value: %s/%s (0x%02x)",
				val_to_str_const(DTP_TOTVALUE(trunk_type), dtp_tot_vals, "Unknown operating type"),
				val_to_str_const(DTP_TATVALUE(trunk_type), dtp_tat_vals, "Unknown administrative type"),
				trunk_type);
			field_tree = proto_item_add_subtree(value_item, ett_dtp_type);
			proto_tree_add_item(field_tree, hf_dtp_tot, tvb, offset, length, ENC_NA);
			proto_tree_add_item(field_tree, hf_dtp_tat, tvb, offset, length, ENC_NA);
			}
			else
				expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid);

		break;

	case DTP_TLV_SENDERID:
		if (length == 6) { /* Value length must be 6 bytes for a MAC address */
			proto_item_append_text(ti, ": %s",
				tvb_ether_to_str(tvb, offset));	/* XXX - resolve? */
			proto_tree_add_item(tree, hf_dtp_senderid, tvb, offset, length, ENC_NA);
		}
		else
			expert_add_info(pinfo, tlv_length_item, &ei_dtp_tlv_length_invalid);

		break;

	default:
		proto_tree_add_text(tree, tvb, offset, length, "Data");
		break;
	}
}
Example #13
0
static int
dissect_ccn_contentobject(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *signature_tree;
    proto_tree *name_tree;
    proto_tree *signedinfo_tree;
    proto_tree *content_tree;
    proto_item *titem;
    struct ccn_parsed_ContentObject co;
    struct ccn_parsed_ContentObject *pco = &co;
    struct ccn_charbuf *c;
    struct ccn_indexbuf *comps;
    const unsigned char *comp;
    size_t comp_size;
    size_t blob_size;
    const unsigned char *blob;
    int l;
    unsigned int i;
    double dt;
    nstime_t timestamp;
    int res;
    
    comps = ccn_indexbuf_create();
    res = ccn_parse_ContentObject(ccnb, ccnb_size, pco, comps);
    if (res < 0) return (-1);
    
    /* Signature */
    l = pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature];
    titem = proto_tree_add_item(tree, hf_ccn_signature, tvb, pco->offset[CCN_PCO_B_Signature], l, FALSE);
    signature_tree = proto_item_add_subtree(titem, ett_signature);
    
    /* DigestAlgorithm */
    l = pco->offset[CCN_PCO_E_DigestAlgorithm] - pco->offset[CCN_PCO_B_DigestAlgorithm];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, ccnb,
                                  pco->offset[CCN_PCO_B_DigestAlgorithm],
                                  pco->offset[CCN_PCO_E_DigestAlgorithm],
                                  &blob, &blob_size);
        titem = proto_tree_add_item(signature_tree, hf_ccn_signaturedigestalg, tvb,
                                    blob - ccnb, blob_size, FALSE);
    }
    /* Witness */
    l = pco->offset[CCN_PCO_E_Witness] - pco->offset[CCN_PCO_B_Witness];
    if (l > 0) {
        /* add the witness item to the signature tree */
    }
    
    /* Signature bits */
    l = pco->offset[CCN_PCO_E_SignatureBits] - pco->offset[CCN_PCO_B_SignatureBits];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, ccnb,
                                  pco->offset[CCN_PCO_B_SignatureBits],
                                  pco->offset[CCN_PCO_E_SignatureBits],
                                  &blob, &blob_size);
        titem = proto_tree_add_bytes(signature_tree, hf_ccn_signaturebits, tvb,
                                     blob - ccnb, blob_size, blob);
    }
    
    /* /Signature */
    
    /* Name */
    l = pco->offset[CCN_PCO_E_Name] - pco->offset[CCN_PCO_B_Name];
    c = ccn_charbuf_create();
    ccn_uri_append(c, ccnb, ccnb_size, 1);
    titem = proto_tree_add_string(tree, hf_ccn_name, tvb,
                                  pco->offset[CCN_PCO_B_Name], l,
                                  ccn_charbuf_as_string(c));
    name_tree = proto_item_add_subtree(titem, ett_name);
    ccn_charbuf_destroy(&c);
    
    /* Name Components */
    for (i = 0; i < comps->n - 1; i++) {
        res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size);
        titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE);
    }
    
    /* /Name */
    
    /* SignedInfo */
    l = pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo];
    titem = proto_tree_add_text(tree, tvb,
                                pco->offset[CCN_PCO_B_SignedInfo], l,
                                "SignedInfo");
    signedinfo_tree = proto_item_add_subtree(titem, ett_signedinfo);
    
    /* PublisherPublicKeyDigest */
    l = pco->offset[CCN_PCO_E_PublisherPublicKeyDigest] - pco->offset[CCN_PCO_B_PublisherPublicKeyDigest];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, ccnb,
                                  pco->offset[CCN_PCO_B_PublisherPublicKeyDigest],
                                  pco->offset[CCN_PCO_E_PublisherPublicKeyDigest],
                                  &blob, &blob_size);
        titem = proto_tree_add_bytes(signedinfo_tree, hf_ccn_publisherpublickeydigest, tvb, blob - ccnb, blob_size, blob);
    }
    
    /* Timestamp */
    l = pco->offset[CCN_PCO_E_Timestamp] - pco->offset[CCN_PCO_B_Timestamp];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, ccnb,
                                  pco->offset[CCN_PCO_B_Timestamp],
                                  pco->offset[CCN_PCO_E_Timestamp],
                                  &blob, &blob_size);
        dt = 0.0;
        for (i = 0; i < blob_size; i++)
            dt = dt * 256.0 + (double)blob[i];
        dt /= 4096.0;
        timestamp.secs = dt; /* truncates */
        timestamp.nsecs = (dt - (double) timestamp.secs) *  1000000000.0;
        titem = proto_tree_add_time(signedinfo_tree, hf_ccn_timestamp, tvb, blob - ccnb, blob_size, &timestamp);
    }
    
    /* Type */
    l = pco->offset[CCN_PCO_E_Type] - pco->offset[CCN_PCO_B_Type];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Type, ccnb,
                                  pco->offset[CCN_PCO_B_Type],
                                  pco->offset[CCN_PCO_E_Type],
                                  &blob, &blob_size);
        titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_contenttype, tvb, blob - ccnb, blob_size, pco->type);
    } else {
        titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_contenttype, NULL, 0, 0, pco->type);
    }
    
    /* FreshnessSeconds */
    l = pco->offset[CCN_PCO_E_FreshnessSeconds] - pco->offset[CCN_PCO_B_FreshnessSeconds];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_FreshnessSeconds, ccnb,
                                  pco->offset[CCN_PCO_B_FreshnessSeconds],
                                  pco->offset[CCN_PCO_E_FreshnessSeconds],
                                  &blob, &blob_size);
        i = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_FreshnessSeconds, ccnb,
                                                pco->offset[CCN_PCO_B_FreshnessSeconds],
                                                pco->offset[CCN_PCO_E_FreshnessSeconds]);
        
        titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_freshnessseconds, tvb, blob - ccnb, blob_size, i);
    }
    
    /* FinalBlockID */
    l = pco->offset[CCN_PCO_E_FinalBlockID] - pco->offset[CCN_PCO_B_FinalBlockID];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb,
                                  pco->offset[CCN_PCO_B_FinalBlockID],
                                  pco->offset[CCN_PCO_E_FinalBlockID],
                                  &blob, &blob_size);
        
        titem = proto_tree_add_item(signedinfo_tree, hf_ccn_finalblockid, tvb, blob - ccnb, blob_size, FALSE);
    }
    /* TODO: KeyLocator */
    /* /SignedInfo */
    
    /* Content */
    l = pco->offset[CCN_PCO_E_Content] - pco->offset[CCN_PCO_B_Content];
    res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnb,
                              pco->offset[CCN_PCO_B_Content],
                              pco->offset[CCN_PCO_E_Content],
                              &blob, &blob_size);
    titem = proto_tree_add_text(tree, tvb,
                                pco->offset[CCN_PCO_B_Content], l,
                                "Content: %d bytes", blob_size);
    if (blob_size > 0) {
        content_tree = proto_item_add_subtree(titem, ett_content);
        titem = proto_tree_add_item(content_tree, hf_ccn_contentdata, tvb, blob - ccnb, blob_size, FALSE);
    }
    
    return (ccnb_size);
}
Example #14
0
static int
dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *name_tree;
    proto_tree *exclude_tree;
    proto_item *titem;
    struct ccn_parsed_interest interest;
    struct ccn_parsed_interest *pi = &interest;
    struct ccn_charbuf *c;
    struct ccn_indexbuf *comps;
    const unsigned char *comp;
    size_t comp_size;
    const unsigned char *blob;
    size_t blob_size;
    ssize_t l;
    unsigned int i;
    double lifetime;
    int res;
    
    comps = ccn_indexbuf_create();
    res = ccn_parse_interest(ccnb, ccnb_size, pi, comps);
    if (res < 0)
        return (res);
    
    /* Name */
    l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name];
    c = ccn_charbuf_create();
    ccn_uri_append(c, ccnb, ccnb_size, 1);
    titem = proto_tree_add_string(tree, hf_ccn_name, tvb,
                                  pi->offset[CCN_PI_B_Name], l,
                                  ccn_charbuf_as_string(c));
    name_tree = proto_item_add_subtree(titem, ett_name);
    ccn_charbuf_destroy(&c);
    
    for (i = 0; i < comps->n - 1; i++) {
        res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size);
        titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE);
    }
    
    /* MinSuffixComponents */
    l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents];
    if (l > 0) {
        i = pi->min_suffix_comps;
        titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i);
    }
    
    /* MaxSuffixComponents */
    l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents];
    if (l > 0) {
        i = pi->max_suffix_comps;
        titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i);
    }
    
    /* PublisherPublicKeyDigest */
    /* Exclude */
    l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude];
    if (l > 0) {
        titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l,
                                    "Exclude");
        exclude_tree = proto_item_add_subtree(titem, ett_exclude);
    }
    /* ChildSelector */
    l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector];
    if (l > 0) {
        i = pi->orderpref;
        titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i);
        proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), ""));
        
    }
    
    /* AnswerOriginKind */
    l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind];
    if (l > 0) {
        i = pi->answerfrom;
        titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i);
    }
    
    /* Scope */
    l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope];
    if (l > 0) {
        i = pi->scope;
        titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i);
    }
    
    /* InterestLifetime */
    l = pi->offset[CCN_PI_E_InterestLifetime] - pi->offset[CCN_PI_B_InterestLifetime];
    if (l > 0) {
        i = ccn_ref_tagged_BLOB(CCN_DTAG_InterestLifetime, ccnb,
                                pi->offset[CCN_PI_B_InterestLifetime],
                                pi->offset[CCN_PI_E_InterestLifetime],
                                &blob, &blob_size);
        lifetime = 0.0;
        for (i = 0; i < blob_size; i++)
            lifetime = lifetime * 256.0 + (double)blob[i];
        lifetime /= 4096.0;
        titem = proto_tree_add_double(tree, hf_ccn_interestlifetime, tvb, blob - ccnb, blob_size, lifetime);
    }
    
    /* Nonce */
    l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce];
    if (l > 0) {
        i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb,
                                pi->offset[CCN_PI_B_Nonce],
                                pi->offset[CCN_PI_E_Nonce],
                                &blob, &blob_size);
        if (check_col(pinfo->cinfo, COL_INFO)) {
            col_append_str(pinfo->cinfo, COL_INFO, ", <");
            for (i = 0; i < blob_size; i++)
                col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]);
            col_append_str(pinfo->cinfo, COL_INFO, ">");
        }
        titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb,
                                    blob - ccnb, blob_size, FALSE);
    }
    
    return (1);
    
}
Example #15
0
static int dissect_dvb_s2_bb(tvbuff_t *tvb, int cur_off, proto_tree *tree, packet_info *pinfo)
{
    proto_item *ti, *tf;
    proto_tree *dvb_s2_bb_tree, *dvb_s2_bb_matype1_tree;

    guint8      input8;
    guint16     input16, bb_data_len = 0;

    int         sub_dissected        = 0, flag_is_ms = 0, new_off = 0;

    col_append_str(pinfo->cinfo, COL_PROTOCOL, "BB ");
    col_append_str(pinfo->cinfo, COL_INFO, "Baseband ");

    /* create display subtree for the protocol */
    ti = proto_tree_add_item(tree, proto_dvb_s2_bb, tvb, cur_off, DVB_S2_BB_HEADER_LEN, ENC_NA);
    dvb_s2_bb_tree = proto_item_add_subtree(ti, ett_dvb_s2_bb);

    input8 = tvb_get_guint8(tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1);
    new_off += 1;

    if (BIT_IS_CLEAR(input8, DVB_S2_BB_MIS_POS))
        flag_is_ms = 1;

    tf = proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_matype1, tvb, cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, input8);
    dvb_s2_bb_matype1_tree = proto_item_add_subtree(tf, ett_dvb_s2_bb_matype1);
    proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_gs, tvb,
                        cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_mis, tvb,
                        cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_acm, tvb,
                        cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_issyi, tvb,
                        cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_npd, tvb,
                        cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(dvb_s2_bb_matype1_tree, hf_dvb_s2_bb_matype1_ro, tvb,
                        cur_off + DVB_S2_BB_OFFS_MATYPE1, 1, ENC_BIG_ENDIAN);

    input8 = tvb_get_guint8(tvb, cur_off + DVB_S2_BB_OFFS_MATYPE2);
    new_off += 1;
    if (flag_is_ms) {
        proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_matype2, tvb,
                                   cur_off + DVB_S2_BB_OFFS_MATYPE2, 1, input8, "Input Stream Identifier (ISI): %d",
                                   input8);
    } else {
        proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_matype2, tvb,
                                   cur_off + DVB_S2_BB_OFFS_MATYPE2, 1, input8, "reserved");
    }

    input16 = tvb_get_ntohs(tvb, cur_off + DVB_S2_BB_OFFS_UPL);
    new_off += 2;

    proto_tree_add_uint_format(dvb_s2_bb_tree, hf_dvb_s2_bb_upl, tvb,
                               cur_off + DVB_S2_BB_OFFS_UPL, 2, input16, "User Packet Length: %d bits (%d bytes)",
                               (guint16) input16, (guint16) input16 / 8);

    bb_data_len = input16 = tvb_get_ntohs(tvb, cur_off + DVB_S2_BB_OFFS_DFL);
    bb_data_len /= 8;
    new_off += 2;

    proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_dfl, tvb,
                               cur_off + DVB_S2_BB_OFFS_DFL, 2, input16, "%d bits (%d bytes)", input16, input16 / 8);

    new_off += 1;
    proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_sync, tvb, cur_off + DVB_S2_BB_OFFS_SYNC, 1, ENC_BIG_ENDIAN);

    new_off += 2;
    proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_syncd, tvb, cur_off + DVB_S2_BB_OFFS_SYNCD, 2, ENC_BIG_ENDIAN);

    input8 = tvb_get_guint8(tvb, cur_off + DVB_S2_BB_OFFS_CRC);
    new_off += 1;
    if (check_crc8(tvb, DVB_S2_BB_HEADER_LEN - 1, cur_off, input8)) {
        proto_tree_add_uint_format(dvb_s2_bb_tree, hf_dvb_s2_bb_crc, tvb,
                                   cur_off + DVB_S2_BB_OFFS_CRC, 1, 1, "Checksum: correct (0x%2.2x)", input8);
    } else {
        proto_tree_add_uint_format(dvb_s2_bb_tree, hf_dvb_s2_bb_crc, tvb,
                                   cur_off + DVB_S2_BB_OFFS_CRC, 1, -1, "Checksum: incorrect! (0x%2.2x)", input8);
    }

    while (bb_data_len) {
        /* start DVB-GSE dissector */
        sub_dissected = dissect_dvb_s2_gse(tvb, cur_off + new_off, tree, pinfo);
        new_off += sub_dissected;

        if ((sub_dissected <= bb_data_len) && (sub_dissected >= DVB_S2_GSE_MINSIZE)) {
            bb_data_len -= sub_dissected;
            if (bb_data_len < DVB_S2_GSE_MINSIZE)
                bb_data_len = 0;
        } else
            bb_data_len = 0;
    }

    return new_off;
}
Example #16
0
static void dissect_tns_accept(tvbuff_t *tvb, int offset, packet_info *pinfo,
                               proto_tree *tree, proto_tree *tns_tree)
{
    proto_tree *accept_tree = NULL, *ti;
    proto_item *hidden_item;
    int accept_offset;
    int accept_len;
    int tns_offset = offset-8;

    if ( tree )
    {
        ti = proto_tree_add_text(tns_tree, tvb, offset, -1,
                                 "Accept");
        accept_tree = proto_item_add_subtree(ti, ett_tns_accept);

        hidden_item = proto_tree_add_boolean(tns_tree, hf_tns_accept, tvb,
                                             0, 0, TRUE);
        PROTO_ITEM_SET_HIDDEN(hidden_item);
    }

    col_append_str(pinfo->cinfo, COL_INFO, ", Accept");

    if ( accept_tree )
    {
        proto_tree_add_item(accept_tree, hf_tns_version, tvb,
                            offset, 2, ENC_BIG_ENDIAN);
    }
    offset += 2;

    if ( accept_tree )
    {
        proto_tree *sopt_tree = NULL;

        ti = proto_tree_add_item(accept_tree, hf_tns_service_options,
                                 tvb, offset, 2, ENC_BIG_ENDIAN);

        sopt_tree = proto_item_add_subtree(ti, ett_tns_sopt_flag);

        dissect_tns_service_options(tvb, offset, sopt_tree);

    }
    offset += 2;

    if ( accept_tree )
    {
        proto_tree_add_item(accept_tree, hf_tns_sdu_size, tvb,
                            offset, 2, ENC_BIG_ENDIAN);
    }
    offset += 2;

    if ( accept_tree )
    {
        proto_tree_add_item(accept_tree, hf_tns_max_tdu_size, tvb,
                            offset, 2, ENC_BIG_ENDIAN);
    }
    offset += 2;

    if ( accept_tree )
    {
        proto_tree_add_item(accept_tree, hf_tns_value_of_one, tvb,
                            offset, 2, ENC_NA);
    }
    offset += 2;

    accept_len = tvb_get_ntohs(tvb, offset);
    if ( accept_tree )
    {
        proto_tree_add_uint(accept_tree, hf_tns_accept_data_length, tvb,
                            offset, 2, accept_len);
    }
    offset += 2;

    accept_offset = tvb_get_ntohs(tvb, offset);
    if ( accept_tree )
    {
        proto_tree_add_uint(accept_tree, hf_tns_accept_data_offset, tvb,
                            offset, 2, accept_offset);
    }
    offset += 2;

    if ( accept_tree )
    {
        proto_tree *cflag_tree = NULL;

        ti = proto_tree_add_item(accept_tree, hf_tns_connect_flags0, tvb,
                                 offset, 1, ENC_BIG_ENDIAN);

        cflag_tree = proto_item_add_subtree(ti, ett_tns_conn_flag);

        dissect_tns_connect_flag(tvb, offset, cflag_tree);

    }
    offset += 1;

    if ( accept_tree )
    {
        proto_tree *cflag_tree = NULL;

        ti = proto_tree_add_item(accept_tree, hf_tns_connect_flags1, tvb,
                                 offset, 1, ENC_BIG_ENDIAN);

        cflag_tree = proto_item_add_subtree(ti, ett_tns_conn_flag);

        dissect_tns_connect_flag(tvb, offset, cflag_tree);

    }
    offset += 1;

    if ( accept_tree && accept_len > 0)
    {
        proto_tree_add_item(accept_tree, hf_tns_accept_data, tvb,
                            tns_offset+accept_offset, -1, ENC_ASCII|ENC_NA);
    }
    return;
}
Example #17
0
static int hf_bthci_sco_data = -1;

/* Initialize the subtree pointers */
static gint ett_bthci_sco = -1;


/* Code to actually dissect the packets */
static void
dissect_bthci_sco(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
    proto_item *ti;
    proto_tree *bthci_sco_tree;
    int         offset = 0;

    ti = proto_tree_add_item(tree, proto_bthci_sco, tvb, offset, -1, ENC_NA);
    bthci_sco_tree = proto_item_add_subtree(ti, ett_bthci_sco);


    proto_tree_add_item(bthci_sco_tree, hf_bthci_sco_chandle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
    offset+=2;

    proto_tree_add_item(bthci_sco_tree, hf_bthci_sco_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
    offset++;

    proto_tree_add_item(bthci_sco_tree, hf_bthci_sco_data, tvb, offset, -1, ENC_NA);
}


void
proto_register_bthci_sco(void)
{
Example #18
0
static void
dissect_usb_midi_event(tvbuff_t *tvb, packet_info *pinfo,
                       proto_tree *usb_audio_tree, proto_tree *parent_tree,
                       gint offset)
{
    guint8      code;
    guint8      cable;
    gboolean    save_fragmented;
    proto_tree *tree = NULL;

    col_set_str(pinfo->cinfo, COL_INFO, "USB-MIDI Event Packets");

    code = tvb_get_guint8(tvb, offset);
    cable = (code & 0xF0) >> 4;
    code &= 0x0F;

    if (parent_tree)
    {
        proto_item *ti;

        ti = proto_tree_add_protocol_format(usb_audio_tree, proto_usb_audio, tvb, offset, 4, "USB Midi Event Packet");
        tree = proto_item_add_subtree(ti, ett_usb_audio);
        proto_tree_add_item(tree, hf_midi_cable_number, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_midi_code_index, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_midi_event, tvb, offset+1, 3, ENC_BIG_ENDIAN);
    }

    save_fragmented = pinfo->fragmented;

    /* Reassemble SysEx commands */
    if (is_sysex_code(code))
    {
        tvbuff_t* new_tvb = NULL;
        fragment_head *frag_sysex_msg = NULL;

        pinfo->fragmented = TRUE;

        if (code == 0x04)
        {
            frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table,
                                                   tvb, offset+1,
                                                   pinfo,
                                                   cable, /* ID for fragments belonging together */
                                                   NULL,
                                                   3,
                                                   TRUE);
        }
        else
        {
            frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table,
                                                   tvb, offset+1,
                                                   pinfo,
                                                   cable, /* ID for fragments belonging together */
                                                   NULL,
                                                   (gint)(code - 4),
                                                   FALSE);
        }

        if (is_last_sysex_packet_in_tvb(tvb, offset))
        {
            new_tvb = process_reassembled_data(tvb, offset+1, pinfo,
                                               "Reassembled Message", frag_sysex_msg, &sysex_msg_frag_items,
                                               NULL, usb_audio_tree);

            if (code != 0x04) { /* Reassembled */
                col_append_str(pinfo->cinfo, COL_INFO,
                               " (SysEx Reassembled)");
            } else { /* Not last packet of reassembled Short Message */
                col_append_str(pinfo->cinfo, COL_INFO,
                               " (SysEx fragment)");
            }

            if (new_tvb)
            {
                call_dissector(sysex_handle, new_tvb, pinfo, parent_tree);
            }
        }
    }

    pinfo->fragmented = save_fragmented;
}
Example #19
0
static void
dissect_who(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	int		offset = 0;
	proto_tree	*who_tree = NULL;
	proto_item	*who_ti = NULL;
	gchar		server_name[33];
	double		loadav_5 = 0.0, loadav_10 = 0.0, loadav_15 = 0.0;
	nstime_t	ts;

	/* Summary information */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "WHO");
	col_clear(pinfo->cinfo, COL_INFO);

	ts.nsecs = 0;

	if (tree) {
		who_ti = proto_tree_add_item(tree, proto_who, tvb, offset, -1,
		    ENC_NA);
		who_tree = proto_item_add_subtree(who_ti, ett_who);
	}

	if (tree)
		proto_tree_add_item(who_tree, hf_who_vers, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	if (tree)
		proto_tree_add_item(who_tree, hf_who_type, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	/* 2 filler bytes */
	offset += 2;

	if (tree) {
		ts.secs = tvb_get_ntohl(tvb, offset);
		proto_tree_add_time(who_tree, hf_who_sendtime, tvb, offset, 4,
		    &ts);
	}
	offset += 4;

	if (tree) {
		ts.secs = tvb_get_ntohl(tvb, offset);
		proto_tree_add_time(who_tree, hf_who_recvtime, tvb, offset, 4,
		    &ts);
	}
	offset += 4;

	tvb_get_nstringz0(tvb, offset, sizeof(server_name), (guint8*)server_name);
	if (tree)
		proto_tree_add_string(who_tree, hf_who_hostname, tvb, offset,
		    32, server_name);
	offset += 32;

	loadav_5  = (double) tvb_get_ntohl(tvb, offset) / 100.0;
	if (tree)
		proto_tree_add_double(who_tree, hf_who_loadav_5, tvb, offset,
		    4, loadav_5);
	offset += 4;

	loadav_10 = (double) tvb_get_ntohl(tvb, offset) / 100.0;
	if (tree)
		proto_tree_add_double(who_tree, hf_who_loadav_10, tvb, offset,
		    4, loadav_10);
	offset += 4;

	loadav_15 = (double) tvb_get_ntohl(tvb, offset) / 100.0;
	if (tree)
		proto_tree_add_double(who_tree, hf_who_loadav_15, tvb, offset,
		    4, loadav_15);
	offset += 4;

	/* Summary information */
	if (check_col(pinfo->cinfo, COL_INFO))
		col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %.02f %.02f %.02f",
				server_name, loadav_5, loadav_10, loadav_15);

	if (tree) {
		ts.secs = tvb_get_ntohl(tvb, offset);
		proto_tree_add_time(who_tree, hf_who_boottime, tvb, offset, 4,
		    &ts);
		offset += 4;

		dissect_whoent(tvb, offset, who_tree);
	}
}
Example #20
0
static gint
dissect_ancp_tlv(tvbuff_t *tvb, proto_tree *tlv_tree, gint offset)
{
        guint16     tlen, ttype;
        gint16      num_stlvs;
        proto_item *tti;

            proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
            ttype = tvb_get_ntohs(tvb, offset);
            offset += 2;

            tti = proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_len, tvb, offset, 2, ENC_BIG_ENDIAN);
            tlen = tvb_get_ntohs(tvb, offset);
            offset += 2;

            /*
             * Extension Block is common for event message and port
             * management message, but the TLVs that can appear
             * are different
             */
            switch (ttype) {
                case TLV_DSL_LINE_ATTRIBUTES:
                {
                    proto_tree *dsl_tree;
                    guint16     stlvtype, stlvlen;
                    gint        val;

                    /* Create a DSL Attribute SubTree */
                    dsl_tree = proto_item_add_subtree(tti, ett_ancp_ext_tlv_type);
                    num_stlvs = tlen / 8; /* TODO - better way? */
                    for ( ;num_stlvs; num_stlvs--) {
                        proto_tree_add_item(dsl_tree,
                                hf_ancp_dsl_line_stlv_type, tvb, offset,
                                2, ENC_BIG_ENDIAN);
                        stlvtype = tvb_get_ntohs(tvb, offset);
                        offset += 2;
                        proto_tree_add_item(dsl_tree,
                                hf_ancp_dsl_line_stlv_len, tvb, offset,
                                2, ENC_BIG_ENDIAN);
                        stlvlen = tvb_get_ntohs(tvb, offset);
                        offset += 2; /* Sub TLV Length */

                        tti = proto_tree_add_item(dsl_tree,
                                hf_ancp_dsl_line_stlv_value, tvb, offset,
                                stlvlen, ENC_BIG_ENDIAN);
                        val = tvb_get_ntohl(tvb, offset);
                        offset += stlvlen; /* Except loop-encap, rest are 4B */

                        switch (stlvtype) {
                            case TLV_DSL_LINE_STATE:
                                proto_item_append_text(tti, " (%s)",
                                        val_to_str(val, dsl_line_state_names,
                                            "Unknown (0x%02x)"));
                                break;
                            case TLV_DSL_TYPE:
                                proto_item_append_text(tti, " (%s)",
                                        val_to_str(val, dsl_line_type_names,
                                            "Unknown (0x%02x)"));
                                break;

                            default:
                                /* Add Unit */
                                proto_item_append_text(tti, " %s",
                                        val_to_str(stlvtype,
                                            dsl_line_attr_units,
                                            "Unknown (0x%02x)"));
                                break;
                        }
                        SKIPPADDING(offset, stlvlen);
                    }
                    break;
                }
                case TLV_PING_OPAQUE_DATA:
                    /* 2 32b values*/
                    proto_tree_add_item(tlv_tree, hf_ancp_oam_opaque,
                            tvb, offset, 4, ENC_BIG_ENDIAN);
                    offset += 4;
                    proto_tree_add_item(tlv_tree, hf_ancp_oam_opaque,
                            tvb, offset, 4, ENC_BIG_ENDIAN);
                    offset += 4;
                    break;
                case TLV_PING_PARAMS:
                    /* Count (1B) Timeout (1B), 2B empty */
                    proto_tree_add_item(tlv_tree,
                            hf_ancp_oam_loopb_cnt, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;
                    proto_tree_add_item(tlv_tree,
                            hf_ancp_oam_timeout, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;
                    /* Lets not bother about 2B until IETF WG figures out */
                    offset += 2;
                    break;
                default:
                    /* Assume TLV value is string - covers ALCID, OAM resp */
                    proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_value_str,
                            tvb, offset, tlen, ENC_ASCII|ENC_NA);
                    offset += tlen;
                    SKIPPADDING(offset, tlen);
                    break;
            } /* end switch {ttype} */
            return offset;
}
Example #21
0
/* Code to actually dissect the packets */
static int
dissect_msrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gint offset = 0;
	gint next_offset = 0;
	proto_item *ti, *th, *msrp_headers_item, *msrp_element_item;
	proto_tree *msrp_tree, *reqresp_tree, *raw_tree, *msrp_hdr_tree, *msrp_end_tree;
	proto_tree *msrp_element_tree, *msrp_data_tree;
	gint linelen;
	gint space_offset;
	gint token_2_start;
	guint token_2_len;
	gint token_3_start;
	guint token_3_len;
	gint token_4_start = 0;
	guint token_4_len = 0;
	gboolean is_msrp_response;
	gint end_line_offset;
	gint end_line_len;
	gint line_end_offset;
	gint message_end_offset;
	gint colon_offset;
	char *transaction_id_str = NULL;
	gint header_len;
	gint hf_index;
	gint value_offset;
	guchar c;
	gint value_len;
	char *value;
	gboolean have_body = FALSE;
	gboolean found_match = FALSE;
	gint content_type_len, content_type_parameter_str_len;
	gchar *media_type_str_lower_case = NULL;
	char *content_type_parameter_str = NULL;
	tvbuff_t *next_tvb;
	gint parameter_offset;
	gint semi_colon_offset;

	if ( !check_msrp_header(tvb)){
		return 0;
	}
	/* We have a MSRP header with at least three tokens
	 *
	 * Note that "tvb_find_line_end()" will return a value that
	 * is not longer than what's in the buffer, so the
	 * "tvb_get_ptr()" calls below won't throw exceptions.	 *
	 */
	offset = 0;
	linelen = tvb_find_line_end(tvb, 0, -1, &next_offset, FALSE);

	/* Find the first SP and skip the first token */
	token_2_start = tvb_find_guint8(tvb, 0, linelen, ' ') + 1;

	/* Work out 2nd token's length by finding next space */
	space_offset = tvb_find_guint8(tvb, token_2_start, linelen-token_2_start, ' ');
	token_2_len = space_offset - token_2_start;

	/* Transaction ID found store it for later use */
	transaction_id_str = tvb_get_ephemeral_string(tvb, token_2_start, token_2_len);

	/* Look for another space in this line to indicate a 4th token */
	token_3_start = space_offset + 1;
	space_offset = tvb_find_guint8(tvb, token_3_start,linelen-token_3_start, ' ');
	if ( space_offset == -1){
		/* 3rd token runs to the end of the line */
		token_3_len = linelen - token_3_start;
	}else{
		/* We have a fourth token */
		token_3_len = space_offset - token_3_start;
		token_4_start = space_offset + 1;
		token_4_len = linelen - token_4_start;
	}

	/*
	 * Yes, so this is either a msrp-request or msrp-response.
	 * To be a msrp-response, the second token must be
	 * a 3-digit number.
	 */
	is_msrp_response = FALSE;
	if (token_3_len == 3) {
			if (isdigit(tvb_get_guint8(tvb, token_3_start)) &&
			    isdigit(tvb_get_guint8(tvb, token_3_start + 1)) &&
			    isdigit(tvb_get_guint8(tvb, token_3_start + 2))) {
				is_msrp_response = TRUE;
			}
	}

	/* Make entries in Protocol column and Info column on summary display */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "MSRP");
	if (is_msrp_response){
		if (check_col(pinfo->cinfo, COL_INFO)) {
			col_add_fstr(pinfo->cinfo, COL_INFO, "Response: %s ",
					tvb_format_text(tvb, token_3_start, token_3_len));

			if (token_4_len )
				col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
					tvb_format_text(tvb, token_4_start, token_4_len));

			col_append_fstr(pinfo->cinfo, COL_INFO, "Transaction ID: %s",
					tvb_format_text(tvb, token_2_start, token_2_len));
		}
	}else{
		if (check_col(pinfo->cinfo, COL_INFO)) {
			proto_tree_add_text(tree, tvb, token_3_start, token_3_len,
					"Col %s L=%u", tvb_format_text(tvb, token_3_start, token_3_len),token_3_len);

			col_add_fstr(pinfo->cinfo, COL_INFO, "Request: %s ",
					tvb_format_text(tvb, token_3_start, token_3_len));

			col_append_fstr(pinfo->cinfo, COL_INFO, "Transaction ID: %s",
					tvb_format_text(tvb, token_2_start, token_2_len));
		}
	}

	/* Find the end line to be able to process the headers
	 * Note that in case of [content-stuff] headers and [content-stuff] is separated by CRLF
	 */

	offset = next_offset;
	end_line_offset = find_end_line(tvb,offset);
	/* TODO if -1 (No end line found, is returned do something) */
	end_line_len =  tvb_find_line_end(tvb, end_line_offset, -1, &next_offset, FALSE);
	message_end_offset = end_line_offset + end_line_len + 2;


	if (tree) {
		ti = proto_tree_add_item(tree, proto_msrp, tvb, 0, message_end_offset, FALSE);
		msrp_tree = proto_item_add_subtree(ti, ett_msrp);

		if (is_msrp_response){
			th = proto_tree_add_item(msrp_tree,hf_msrp_response_line,tvb,0,linelen,FALSE);
			reqresp_tree = proto_item_add_subtree(th, ett_msrp_reqresp);
			proto_tree_add_item(reqresp_tree,hf_msrp_transactionID,tvb,token_2_start,token_2_len,FALSE);
			proto_tree_add_uint(reqresp_tree,hf_msrp_status_code,tvb,token_3_start,token_3_len,
			                    atoi(tvb_get_ephemeral_string(tvb, token_3_start, token_3_len)));

		}else{
			th = proto_tree_add_item(msrp_tree,hf_msrp_request_line,tvb,0,linelen,FALSE);
			reqresp_tree = proto_item_add_subtree(th, ett_msrp_reqresp);
			proto_tree_add_item(reqresp_tree,hf_msrp_transactionID,tvb,token_2_start,token_2_len,FALSE);
			proto_tree_add_item(reqresp_tree,hf_msrp_method,tvb,token_3_start,token_3_len,FALSE);
		}

		/* Conversation setup info */
		if (global_msrp_show_setup_info)
		{
			show_setup_info(tvb, pinfo, msrp_tree);
		}

		/* Headers */
		msrp_headers_item = proto_tree_add_item(msrp_tree, hf_msrp_msg_hdr, tvb, offset,(end_line_offset - offset), FALSE);
		msrp_hdr_tree = proto_item_add_subtree(msrp_headers_item, ett_msrp_hdr);

		/*
		 * Process the headers
		 */
		while (tvb_reported_length_remaining(tvb, offset) > 0 && offset < end_line_offset  ) {
			/* 'desegment' is FALSE so will set next_offset to beyond the end of
			   the buffer if no line ending is found */
			linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
			if (linelen == 0) {
				/*
				 * This is a blank line separating the
				 * message header from the message body.
				 */
				have_body = TRUE;
				break;
			}
			line_end_offset = offset + linelen;
			colon_offset = tvb_find_guint8(tvb, offset, linelen, ':');
			if (colon_offset == -1) {
				/*
				 * Malformed header - no colon after the name.
				 */
				proto_tree_add_text(msrp_hdr_tree, tvb, offset,
					                next_offset - offset, "%s",
						            tvb_format_text(tvb, offset, linelen));
			} else {
				header_len = colon_offset - offset;
				hf_index = msrp_is_known_msrp_header(tvb, offset, header_len);

				if (hf_index == -1) {
					proto_tree_add_text(msrp_hdr_tree, tvb,
				                    offset, next_offset - offset, "%s",
				                    tvb_format_text(tvb, offset, linelen));
				} else {
					/*
					 * Skip whitespace after the colon.
					 */
					value_offset = colon_offset + 1;
					while (value_offset < line_end_offset &&
					       ((c = tvb_get_guint8(tvb, value_offset)) == ' ' ||
					         c == '\t'))
						value_offset++;
					/*
					 * Fetch the value.
					 */
					value_len = line_end_offset - value_offset;
					value = tvb_get_ephemeral_string(tvb, value_offset,
				                       value_len);

					/*
					 * Add it to the protocol tree,
					 * but display the line as is.
					 */
					msrp_element_item = proto_tree_add_string_format(msrp_hdr_tree,
				                   hf_header_array[hf_index], tvb,
				                   offset, next_offset - offset,
				                   value, "%s",
				                   tvb_format_text(tvb, offset, linelen));
					msrp_element_tree = proto_item_add_subtree( msrp_element_item, ett_msrp_element);

					switch ( hf_index ) {

						case MSRP_CONTENT_TYPE :
							content_type_len = value_len;
							semi_colon_offset = tvb_find_guint8(tvb, value_offset,linelen, ';');
							if ( semi_colon_offset != -1) {
								parameter_offset = semi_colon_offset +1;
								/*
								 * Skip whitespace after the semicolon.
								 */
								while (parameter_offset < line_end_offset
								       && ((c = tvb_get_guint8(tvb, parameter_offset)) == ' '
								         || c == '\t'))
									parameter_offset++;
								content_type_len = semi_colon_offset - value_offset;
								content_type_parameter_str_len = line_end_offset - parameter_offset;
								content_type_parameter_str = tvb_get_ephemeral_string(tvb,
										     parameter_offset, content_type_parameter_str_len);
							}
							media_type_str_lower_case = ascii_strdown_inplace(
                                                            (gchar *)tvb_get_ephemeral_string(tvb, value_offset, content_type_len));
							break;

						default:
							break;
					}
				}
			}
			offset = next_offset;
		}/* End while */

		if ( have_body ){
			/*
			 * There's a message body starting at "next_offset".
			 * Set the length of the header item.
			 */
			proto_item_set_end(msrp_headers_item, tvb, next_offset);

			/* Create new tree & tvb for data */
			next_tvb = tvb_new_subset_remaining(tvb, next_offset);
			ti = proto_tree_add_item(msrp_tree, hf_msrp_data, tvb,
			                         next_offset, -1, FALSE);
			msrp_data_tree = proto_item_add_subtree(ti, ett_msrp_data);

			/* give the content type parameters to sub dissectors */

			if ( media_type_str_lower_case != NULL ) {
				void *save_private_data = pinfo->private_data;
				pinfo->private_data = content_type_parameter_str;
				found_match = dissector_try_string(media_type_dissector_table,
			                                   media_type_str_lower_case,
			                                   next_tvb, pinfo,
			                                   msrp_data_tree);
				pinfo->private_data = save_private_data;
				/* If no match dump as text */
			}
			if ( found_match != TRUE )
			{
				offset = 0;
				while (tvb_offset_exists(next_tvb, offset)) {
					tvb_find_line_end(next_tvb, offset, -1, &next_offset, FALSE);
					linelen = next_offset - offset;
					proto_tree_add_text(msrp_data_tree, next_tvb, offset, linelen,
				                    "%s", tvb_format_text(next_tvb, offset, linelen));
					offset = next_offset;
				}/* end while */
			}

		}



		/* End line */
		ti = proto_tree_add_item(msrp_tree,hf_msrp_end_line,tvb,end_line_offset,end_line_len,FALSE);
		msrp_end_tree = proto_item_add_subtree(ti, ett_msrp_end_line);

		proto_tree_add_item(msrp_end_tree,hf_msrp_transactionID,tvb,end_line_offset + 7,token_2_len,FALSE);
		/* continuation-flag */
		proto_tree_add_item(msrp_end_tree,hf_msrp_cnt_flg,tvb,end_line_offset+end_line_len-1,1,FALSE);

		if (global_msrp_raw_text){
			ti = proto_tree_add_text(tree, tvb, 0, -1,"Message Session Relay Protocol(as raw text)");
			raw_tree = proto_item_add_subtree(ti, ett_msrp);
			tvb_raw_text_add(tvb,raw_tree);
		}

	}/* if tree */
	return message_end_offset;
	/*	return tvb_length(tvb); */

/* If this protocol has a sub-dissector call it here, see section 1.8 */
}
Example #22
0
static void
dissect_ancp_port_up_dn_mgmt(tvbuff_t *tvb, proto_tree *ancp_tree, gint offset, guint8 mtype)
{
    guint8 tech_type;
    gint16 num_tlvs;
    proto_item *sti;

    if (mtype == ANCP_MTYPE_PORT_MGMT) {
        proto_tree_add_item(ancp_tree, hf_ancp_pudm_unused,    tvb, offset, 14, ENC_NA);
        offset += 14;

        proto_tree_add_item(ancp_tree, hf_ancp_function,       tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        proto_tree_add_item(ancp_tree, hf_ancp_x_function,     tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        proto_tree_add_item(ancp_tree, hf_ancp_pudm_unused,    tvb, offset, 4, ENC_NA);
        offset += 4;
    } else {
        proto_tree_add_item(ancp_tree, hf_ancp_pudm_unused,    tvb, offset, 20, ENC_NA);
        offset += 20;
    }

    proto_tree_add_item(ancp_tree, hf_ancp_ext_flags_res, tvb, offset, 1, ENC_NA);
    offset += 1;

    proto_tree_add_item(ancp_tree, hf_ancp_mtype,         tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    if (mtype == ANCP_MTYPE_PORT_MGMT) {
        proto_tree_add_item(ancp_tree, hf_ancp_reserved,      tvb, offset, 2, ENC_NA);
        offset += 2;
        tech_type = 0;
    } else {
        proto_tree_add_item(ancp_tree, hf_ancp_tech_type,     tvb, offset, 1, ENC_BIG_ENDIAN);
        tech_type = tvb_get_guint8(tvb, offset);
        offset += 1;

        proto_tree_add_item(ancp_tree, hf_ancp_reserved,      tvb, offset, 1, ENC_NA);
        offset += 1;
    }

    proto_tree_add_item(ancp_tree, hf_ancp_num_ext_tlvs, tvb, offset, 2, ENC_BIG_ENDIAN);
    num_tlvs = tvb_get_ntohs(tvb, offset);
    offset += 2;

    sti = proto_tree_add_item(ancp_tree, hf_ancp_blk_len,       tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    if (tech_type == TECH_TYPE_DSL || tech_type == TECH_TYPE_PON) {
        proto_tree *tlv_tree;

        /* Create a TLV sub tree */
        tlv_tree = proto_item_add_subtree(sti, ett_ancp_len);

        for( ;num_tlvs; num_tlvs--) {
            offset = dissect_ancp_tlv(tvb, tlv_tree, offset);
        } /* end for {numtlvs} */
    } /* end if {DSL} */
}
Example #23
0
static void
dissect_qllc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree	*qllc_tree = NULL;
    proto_item	*qllc_ti = NULL;
    gboolean	*q_bit_set = pinfo->private_data;
    guint8	addr, ctrl;
    gboolean	command = FALSE;

    /*
     * If the Q bit isn't set, this is just SNA data.
     */
    if (!(*q_bit_set)) {
	call_dissector(sna_handle, tvb, pinfo, tree);
	return;
    }

    /* Summary information */
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "QLLC");
    col_clear(pinfo->cinfo, COL_INFO);

    if (tree) {
	qllc_ti = proto_tree_add_item(tree, proto_qllc, tvb, 0, -1, ENC_NA);
	qllc_tree = proto_item_add_subtree(qllc_ti, ett_qllc);
    }

    /* Get the address; we need it to determine if this is a
     * COMMAND or a RESPONSE */
    addr = tvb_get_guint8(tvb, 0);
    if (tree) {
	proto_tree_add_item(qllc_tree, hf_qllc_address, tvb, 0, 1, ENC_BIG_ENDIAN);
    }

    /* The address field equals X'FF' in commands (except QRR)
     * and anything in responses. */
    ctrl = tvb_get_guint8(tvb, 1);
    if (ctrl != QRR && addr == 0xff) {
        command = TRUE;
    }


    /* Disambiguate QRD_QDISC_VALUE, based on whether this packet is
     * a COMMAND or RESPONSE. */
    if (ctrl == QRD_QDISC_VALUE) {
        if (command) {
	    col_set_str(pinfo->cinfo, COL_INFO, QDISC_TEXT);
            if (tree) {
                proto_tree_add_text(qllc_tree, tvb,
                        1, 1, "Control Field: %s (0x%02x)", QDISC_TEXT, ctrl);
            }
        }
        else {
	    col_set_str(pinfo->cinfo, COL_INFO, QRD_TEXT);
            if (tree) {
                proto_tree_add_text(qllc_tree, tvb,
                        1, 1, "Control Field: %s (0x%02x)", QRD_TEXT, ctrl);
            }
        }

        /* Add the field for filtering purposes */
        if (tree) {
            proto_item *hidden_item;
            hidden_item = proto_tree_add_uint(qllc_tree, hf_qllc_control, tvb,
                    1, 1, ctrl);
            PROTO_ITEM_SET_HIDDEN(hidden_item);
        }
    }
    else {
        /* Non-ambiguous control field value */
        if (check_col(pinfo->cinfo, COL_INFO)) {
            col_add_str(pinfo->cinfo, COL_INFO,
                    val_to_str(ctrl, qllc_control_vals,
                        "Control Field: 0x%02x (unknown)"));
        }
        if (tree) {
            proto_tree_add_uint(qllc_tree, hf_qllc_control, tvb,
                    1, 1, ctrl);
        }
    }

    /* Do we have an I field ? */
    /* XXX - I field exists for QUI too, but only for subarea nodes.
     * Need to test for this. */
    if (ctrl == QXID || ctrl == QTEST || ctrl == QFRMR) {
        /* yes */
    }
}
Example #24
0
static void
dissect_ancp_adj_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ancp_tree,
                     gint offset, struct ancp_tap_t *ancp_info
)
{
    proto_item *sti;
    proto_tree *ancp_cap_tree;
    guint8      byte, numcaps, adjcode;
    guint16     tlv_len;

    sti = proto_tree_add_item(ancp_tree, hf_ancp_timer, tvb, offset, 1,
            ENC_BIG_ENDIAN);
    offset += 1;
    proto_item_append_text(sti, " msec");

    sti = proto_tree_add_item(ancp_tree, hf_ancp_adj_code, tvb, offset, 1,
            ENC_BIG_ENDIAN);
    byte = tvb_get_guint8(tvb, offset);
    offset += 1;
    adjcode = byte & ADJ_CODE_MASK;
    ancp_info->ancp_adjcode = adjcode; /* stats */
    proto_item_append_text(sti, " (%s, M Flag %s)",
            val_to_str(adjcode, adj_code_names, "Unknown (0x%02x)"),
            (byte >> 7) ? "Set" : "Unset");
    col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
            val_to_str(adjcode, adj_code_names, "Unknown (0x%02x)"));

    proto_tree_add_item(ancp_tree, hf_ancp_sender_name, tvb, offset, 6, ENC_NA);
    offset += 6;

    proto_tree_add_item(ancp_tree, hf_ancp_receiver_name, tvb,offset, 6, ENC_NA);
    offset += 6;

    proto_tree_add_item(ancp_tree, hf_ancp_sender_port, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset += 4;

    proto_tree_add_item(ancp_tree, hf_ancp_receiver_port, tvb,offset, 4, ENC_BIG_ENDIAN);
    offset += 4;

    sti = proto_tree_add_item(ancp_tree, hf_ancp_p_info, tvb,
            offset, 1, ENC_BIG_ENDIAN);
    byte = tvb_get_guint8(tvb, offset);
    offset += 1;
    proto_item_append_text(sti, " (Type = %d, Flag = %d)",
            byte >> 4, byte & 0x0F);

    proto_tree_add_item(ancp_tree, hf_ancp_sender_instance, tvb, offset, 3, ENC_BIG_ENDIAN);
    offset += 3;

    proto_tree_add_item(ancp_tree, hf_ancp_p_id, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    proto_tree_add_item(ancp_tree, hf_ancp_receiver_instance, tvb, offset, 3, ENC_BIG_ENDIAN);
    offset += 3;

    proto_tree_add_item(ancp_tree, hf_ancp_reserved, tvb, offset, 1, ENC_NA);
    offset += 1;

    sti = proto_tree_add_item(ancp_tree, hf_ancp_num_tlvs, tvb, offset, 1, ENC_BIG_ENDIAN);
    numcaps = tvb_get_guint8(tvb, offset);
    offset += 1;

    /* Start the capability subtree */
    ancp_cap_tree = proto_item_add_subtree(sti, ett_ancp_tot_len);

    proto_tree_add_item(ancp_cap_tree, hf_ancp_tot_len, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    for ( ;numcaps; numcaps--) {
        sti = proto_tree_add_item(ancp_cap_tree, hf_ancp_cap, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;

        tlv_len = tvb_get_ntohs(tvb, offset);
        offset += 2;
        proto_item_append_text(sti, " (%d bytes)", tlv_len);
        /* TODO - if there are non boolean caps, validate before use */
    }
}
Example #25
0
static void dissect_mqpcf_parm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mq_tree,
                               guint offset, guint32 uCount, guint bLittleEndian, gboolean bParse)
{
    guint32 u    = 0;
    guint32 tOfs = 0;
    guint32 uLenF;
    char    strPrm[256];
    guint32 uTyp;
    guint32 uLen = 0;
    guint32 uPrm;
    guint32 uCnt;
    guint32 uCCS;
    guint32 uSLn;
    guint32 uVal;
    guint64 uVal64;
    guint32 uDig;

    const char sMaxLst[] = " Max # of List reached. DECODE interrupted   (actual %u of %u)";
    const char sPrmLn0[] = " MQPrm[%3u] has a zero length. DECODE Failed (MQPrm Count: %u)";
    const char sMaxPrm[] = " Max # of Parm reached. DECODE interrupted   (actual %u of %u)";
    const char sPrmCnt[] = " Cnt=-1 and Length(%u) < 16. DECODE interrupted for elem %u";

    proto_item *ti   = NULL;
    proto_tree *tree = NULL;

    if (uCount == (guint32)-1)
    {
        guint32 xOfs = offset;

        uCnt = 0;
        while (tvb_length_remaining(tvb, xOfs) >= 16)
        {
            uLen = tvb_get_guint32_endian(tvb, xOfs + 4, bLittleEndian);
            if (uLen < 16)
            {
                ti = proto_tree_add_text(mq_tree, tvb, xOfs, 16, sPrmCnt, uLen, uCnt);
                expert_add_info(pinfo, ti, &ei_mq_pcf_PrmCnt);
                break;
            }
            uCnt++;
            xOfs += uLen;
        }
        uCount = uCnt;
    }

    uDig = dissect_mqpcf_getDigits(uCount);

    for (u = 0; u < uCount && u < mq_pcf_maxprm; u++)
    {
        tOfs = offset;
        uTyp = tvb_get_guint32_endian(tvb, offset    , bLittleEndian);
        uLen = tvb_get_guint32_endian(tvb, offset + 4, bLittleEndian);
        if (uLen == 0)
        {
            ti = proto_tree_add_text(mq_tree, tvb, offset, 12, sPrmLn0, u+1, uCount);
            expert_add_info(pinfo, ti, &ei_mq_pcf_prmln0);
            u = uCount;
            break;
        }
        uPrm = tvb_get_guint32_endian(tvb, offset + 8, bLittleEndian);
        uLenF = 12;

        if (bParse)
            g_snprintf(strPrm, (gulong)sizeof(strPrm) - 1, " %-s[%*u] {%2d-%-15.15s} %8x/%5d-%-30.30s",
                "MQPrm", uDig, u+1,
                uTyp, val_to_str_const(uTyp, GET_VALSV(PrmTyp), "      Unknown") + 6,
                uPrm, uPrm, val_to_str_const(uPrm, GET_VALSV(PrmId), "Unknown"));
        else
            g_snprintf(strPrm, (gulong)sizeof(strPrm) - 1, " %-s[%*u] {%2d-%-15.15s} %8x/%5d",
                "XtraD", uDig, u+1,
                uTyp, val_to_str_const(uTyp, GET_VALSV(PrmTyp), "      Unknown") + 6,
                uPrm, uPrm);

        switch (uTyp)
        {
        case MQ_MQCFT_NONE:
            break;
        case MQ_MQCFT_COMMAND:
            break;
        case MQ_MQCFT_RESPONSE:
            break;
        case MQ_MQCFT_INTEGER:
            {
                const guint8 *pVal = NULL;
                uVal = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
                if (bParse)
                    pVal = dissect_mqpcf_parm_getintval(uPrm, uVal);
                if (pVal)
                {
                    ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %d-%s",
                        strPrm, uVal, pVal);
                }
                else
                {
                    ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %8x-%d",
                        strPrm, uVal, uVal);
                }
                tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
                proto_tree_add_item(tree, hf_mq_pcf_prmtyp, tvb, offset    , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen, tvb, offset + 4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset + 8, 4, bLittleEndian);

                dissect_mqpcf_parm_int(tvb, tree, offset+uLenF, uPrm, uVal, hf_mq_pcf_int, 0, 0, 0, bParse);
            }
            break;
        case MQ_MQCFT_STRING:
            {
                guint8 *sStr;

                uCCS = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
                uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian);
                sStr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8,
                    uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC);
                if (*sStr)
                    strip_trailing_blanks(sStr, uSLn);
                if (*sStr)
                    format_text_chr(sStr, strlen(sStr), '.');

                ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s", strPrm, sStr);
                tree = proto_item_add_subtree(ti, ett_mqpcf_prm);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 12, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 16, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_string, tvb, offset + uLenF + 8, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC);
            }
            break;
        case MQ_MQCFT_INTEGER_LIST:
            {
                guint32 u2;
                guint32 uDigit = 0;

                uCnt = tvb_get_guint32_endian(tvb, offset+uLenF, bLittleEndian);
                uDigit = dissect_mqpcf_getDigits(uCnt);

                ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s Cnt(%d)", strPrm, uCnt);
                tree = proto_item_add_subtree(ti, ett_mqpcf_prm);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp  , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen  , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmcount, tvb, offset + 12, 4, bLittleEndian);

                offset += uLenF+4;
                for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++)
                {
                    uVal = tvb_get_guint32_endian(tvb, offset, bLittleEndian);
                    dissect_mqpcf_parm_int(tvb, tree, offset, uPrm, uVal, hf_mq_pcf_intlist, u2+1, uCnt, uDigit, bParse);
                    offset += 4;
                }
                if (u2 != uCnt)
                {
                    ti = proto_tree_add_text(tree, tvb, offset, uLen, sMaxLst, u2, uCnt);
                    expert_add_info(pinfo, ti, &ei_mq_pcf_MaxInt);
                }
            }
            break;
        case MQ_MQCFT_STRING_LIST:
            {
                guint32  u2;
                guint32  uDigit;
                guint8  *sStr;
                header_field_info *hfinfo;

                hfinfo = proto_registrar_get_nth(hf_mq_pcf_stringlist);

                uCCS = tvb_get_guint32_endian(tvb, offset + uLenF    , bLittleEndian);
                uCnt = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian);
                uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 8, bLittleEndian);

                ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s Cnt(%d)", strPrm, uCnt);

                tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 12, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmcount , tvb, offset + 16, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 20, 4, bLittleEndian);

                uDigit = dissect_mqpcf_getDigits(uCnt);

                offset += uLenF+12;
                for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++)
                {
                    sStr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset,
                        uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC);
                    if (*sStr)
                        strip_trailing_blanks(sStr, uSLn);
                    if (*sStr)
                        format_text_chr(sStr, strlen(sStr),  '.');

                    proto_tree_add_string_format(tree, hf_mq_pcf_stringlist, tvb, offset, uSLn, sStr,
                        "%s[%*d]: %s", hfinfo->name, uDigit, u2+1, sStr);
                    offset += uSLn;
                }
                if (u2 != uCnt)
                {
                    ti = proto_tree_add_text(tree, tvb, offset, uLen, sMaxLst, u2, uCnt);
                    expert_add_info(pinfo, ti, &ei_mq_pcf_MaxStr);
                }
            }
            break;
        case MQ_MQCFT_EVENT:
            break;
        case MQ_MQCFT_USER:
            {
                ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s", strPrm);
                tree = proto_item_add_subtree(ti, ett_mqpcf_prm);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + 8, uLen - 8, bLittleEndian);
            }
            break;
        case MQ_MQCFT_BYTE_STRING:
            {
                uSLn = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
                if (uSLn)
                {
                    guint8 *sStrA = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_ASCII) , uSLn, '.');
                    guint8 *sStrE = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_EBCDIC), uSLn, '.');
                    if (uSLn > 35)
                    {
                        ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s [Truncated] A(%-.35s) E(%-.35s)", strPrm, sStrA, sStrE);
                    }
                    else
                    {
                        ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s A(%s) E(%s)", strPrm, sStrA, sStrE);
                    }
                }
                else
                {
                    ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s <MISSING>", strPrm);
                }
                tree = proto_item_add_subtree(ti, ett_mqpcf_prm);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 12, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + uLenF + 4 , uSLn, bLittleEndian);
            }
            break;
        case MQ_MQCFT_TRACE_ROUTE:
            break;
        case MQ_MQCFT_REPORT:
            break;
        case MQ_MQCFT_INTEGER_FILTER:
            {
                guint32 uOpe;

                uOpe = tvb_get_guint32_endian(tvb, offset + uLenF    , bLittleEndian);
                uVal = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian);

                ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s %d",
                    strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), "       Unknown (0x%02x)")+7, uVal);
                tree = proto_item_add_subtree(ti, ett_mqpcf_prm);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_int, tvb, offset + uLenF + 4, 4, bLittleEndian);
            }
            break;
        case MQ_MQCFT_STRING_FILTER:
            {
                guint8 *sStr;
                guint32 uOpe;

                uOpe = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
                uCCS = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian);
                uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 8, bLittleEndian);
                sStr = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 12, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC), uSLn, '.');
                strip_trailing_blanks(sStr, uSLn);

                ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s %s",
                    strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), "       Unknown (0x%02x)")+7, sStr);
                tree = proto_item_add_subtree(ti, ett_mqpcf_prm);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmccsid , tvb, offset + 16, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 20, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_string, tvb, offset + uLenF + 12, uSLn, (uCCS != 500) ? ENC_ASCII : ENC_EBCDIC);
            }
            break;
        case MQ_MQCFT_BYTE_STRING_FILTER:
            {
                guint32 uOpe;
                uOpe = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
                uSLn = tvb_get_guint32_endian(tvb, offset + uLenF + 4, bLittleEndian);
                if (uSLn)
                {
                    guint8 *sStrA = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, ENC_ASCII), uSLn, '.');
                    guint8 *sStrE = format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, ENC_EBCDIC), uSLn, '.');
                    ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s A(%s) E(%s)",
                        strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), "       Unknown (0x%02x)")+7, sStrA, sStrE);
                }
                else
                {
                    ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %s <MISSING>",
                        strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), "       Unknown (0x%02x)")+7);
                }
                tree = proto_item_add_subtree(ti, ett_mqpcf_prm);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_filterop , tvb, offset + 12, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmstrlen, tvb, offset + 16, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_bytestring, tvb, offset + uLenF + 8 , uSLn, bLittleEndian);
            }
            break;
        case MQ_MQCFT_COMMAND_XR:
            break;
        case MQ_MQCFT_XR_MSG:
            break;
        case MQ_MQCFT_XR_ITEM:
            break;
        case MQ_MQCFT_XR_SUMMARY:
            break;
        case MQ_MQCFT_GROUP:
            break;
        case MQ_MQCFT_STATISTICS:
            break;
        case MQ_MQCFT_ACCOUNTING:
            break;
        case MQ_MQCFT_INTEGER64:
            {
                uVal64 = tvb_get_guint64_endian(tvb, offset + uLenF + 4, bLittleEndian);
                ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s %" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)",
                    strPrm, uVal64, uVal64);
                tree = proto_item_add_subtree(ti, ett_mqpcf_prm);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp   , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen   , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmunused, tvb, offset + 12, 4, bLittleEndian);

                proto_tree_add_item(tree, hf_mq_pcf_int64, tvb, offset + uLenF + 4, 8, bLittleEndian);
            }
            break;
        case MQ_MQCFT_INTEGER64_LIST:
            {
                guint32 u2;
                guint32 uDigit;
                header_field_info *hfinfo;

                hfinfo = proto_registrar_get_nth(hf_mq_pcf_int64list);

                uCnt = tvb_get_guint32_endian(tvb, offset + uLenF, bLittleEndian);
                ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, "%s Cnt(%d)", strPrm, uCnt);
                tree = proto_item_add_subtree(ti, ett_mqpcf_prm);
                uDigit = dissect_mqpcf_getDigits(uCnt);

                proto_tree_add_item(tree, hf_mq_pcf_prmtyp  , tvb, offset     , 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmlen  , tvb, offset +  4, 4, bLittleEndian);
                proto_tree_add_item(tree, (bParse) ? hf_mq_pcf_prmid : hf_mq_pcf_prmidnovals, tvb, offset +  8, 4, bLittleEndian);
                proto_tree_add_item(tree, hf_mq_pcf_prmcount, tvb, offset + 12, 4, bLittleEndian);

                offset += uLenF + 4;
                for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++)
                {
                    uVal64 = tvb_get_guint64_endian(tvb, offset, bLittleEndian);
                    proto_tree_add_int64_format(tree, hf_mq_pcf_int64list, tvb, offset, 8, uVal64,
                        "%s[%*d]: %" G_GINT64_MODIFIER "d", hfinfo->name, uDigit, u2+1, uVal64);
                    offset += 8;
                }
                if (u2 != uCnt)
                {
                    ti = proto_tree_add_text(tree, tvb, offset, uLen, sMaxLst, u2, uCnt);
                    expert_add_info(pinfo, ti, &ei_mq_pcf_MaxI64);
                }
            }
            break;
        }
        offset = tOfs+uLen;
    }
    if (u != uCount)
    {
        ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, sMaxPrm, u, uCount);
        expert_add_info(pinfo, ti, &ei_mq_pcf_MaxPrm);
    }
}
static gint ett_spray_clock = -1;


static int
dissect_get_reply(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
{
    proto_item* lock_item = NULL;
    proto_tree* lock_tree = NULL;

    offset = dissect_rpc_uint32(tvb, tree,
                                hf_spray_counter, offset);

    lock_item = proto_tree_add_item(tree, hf_spray_clock, tvb,
                                    offset, -1, ENC_NA);

    lock_tree = proto_item_add_subtree(lock_item, ett_spray_clock);

    offset = dissect_rpc_uint32(tvb, lock_tree,
                                hf_spray_sec, offset);

    offset = dissect_rpc_uint32(tvb, lock_tree,
                                hf_spray_usec, offset);

    return offset;
}

static int
dissect_spray_call(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
{
    offset = dissect_rpc_data(tvb, tree,
                              hf_spray_sprayarr, offset);
Example #27
0
static int
dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
{
	proto_item  *volatile ti = NULL, *comment_item;
	guint	     cap_len = 0, frame_len = 0;
	proto_tree  *volatile tree;
	proto_tree  *comments_tree;
	proto_item  *item;
	const gchar *cap_plurality, *frame_plurality;
	frame_data_t *fr_data = (frame_data_t*)data;

	tree=parent_tree;

	switch (pinfo->phdr->rec_type) {

	case REC_TYPE_PACKET:
		pinfo->current_proto = "Frame";
		if (pinfo->pseudo_header != NULL) {
			switch (pinfo->fd->lnk_t) {

			case WTAP_ENCAP_WFLEET_HDLC:
			case WTAP_ENCAP_CHDLC_WITH_PHDR:
			case WTAP_ENCAP_PPP_WITH_PHDR:
			case WTAP_ENCAP_SDLC:
			case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR:
				pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ?
				    P2P_DIR_SENT : P2P_DIR_RECV;
				break;

			case WTAP_ENCAP_BLUETOOTH_HCI:
				pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent;
				break;

			case WTAP_ENCAP_LAPB:
			case WTAP_ENCAP_FRELAY_WITH_PHDR:
				pinfo->p2p_dir =
				    (pinfo->pseudo_header->x25.flags & FROM_DCE) ?
				    P2P_DIR_RECV : P2P_DIR_SENT;
				break;

			case WTAP_ENCAP_ISDN:
			case WTAP_ENCAP_V5_EF:
			case WTAP_ENCAP_DPNSS:
			case WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR:
				pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ?
				    P2P_DIR_SENT : P2P_DIR_RECV;
				break;

			case WTAP_ENCAP_LINUX_LAPD:
				pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 ||
					pinfo->pseudo_header->lapd.pkttype == 4) ?
					P2P_DIR_SENT : P2P_DIR_RECV;
				break;

			case WTAP_ENCAP_MTP2_WITH_PHDR:
				pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ?
				    P2P_DIR_SENT : P2P_DIR_RECV;
				pinfo->link_number  = pinfo->pseudo_header->mtp2.link_number;
				break;

			case WTAP_ENCAP_GSM_UM:
				pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ?
				    P2P_DIR_SENT : P2P_DIR_RECV;
				break;
			}
		}
		break;

	case REC_TYPE_FT_SPECIFIC_EVENT:
		pinfo->current_proto = "Event";
		break;

	case REC_TYPE_FT_SPECIFIC_REPORT:
		pinfo->current_proto = "Report";
		break;

	default:
		g_assert_not_reached();
		break;
	}

	if (fr_data && fr_data->pkt_comment) {
		item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, 0, ENC_NA);
		comments_tree = proto_item_add_subtree(item, ett_comments);
		comment_item = proto_tree_add_string_format(comments_tree, hf_comments_text, tvb, 0, 0,
							                   fr_data->pkt_comment, "%s",
							                   fr_data->pkt_comment);
		expert_add_info_format(pinfo, comment_item, &ei_comments_text,
					                       "%s",  fr_data->pkt_comment);


	}

	/* if FRAME is not referenced from any filters we don't need to worry about
	   generating any tree items.  */
	if (!proto_field_is_referenced(tree, proto_frame)) {
		tree=NULL;
		if (pinfo->fd->flags.has_ts) {
			if (pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000)
				expert_add_info(pinfo, NULL, &ei_arrive_time_out_of_range);
		}
	} else {
		proto_tree *fh_tree;
		gboolean old_visible;

		/* Put in frame header information. */
		cap_len = tvb_length(tvb);
		frame_len = tvb_reported_length(tvb);

		cap_plurality = plurality(cap_len, "", "s");
		frame_plurality = plurality(frame_len, "", "s");

		ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, tvb_captured_length(tvb),
		    "Frame %u: %u byte%s on wire",
		    pinfo->fd->num, frame_len, frame_plurality);
		if (generate_bits_field)
			proto_item_append_text(ti, " (%u bits)", frame_len * 8);
		proto_item_append_text(ti, ", %u byte%s captured",
		    cap_len, cap_plurality);
		if (generate_bits_field) {
			proto_item_append_text(ti, " (%u bits)",
			    cap_len * 8);
		}
		if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID) {
			proto_item_append_text(ti, " on interface %u",
			    pinfo->phdr->interface_id);
		}
		if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
			if (pinfo->phdr->pack_flags & 0x00000001) {
				proto_item_append_text(ti, " (inbound)");
				pinfo->p2p_dir = P2P_DIR_RECV;
			}
			if (pinfo->phdr->pack_flags & 0x00000002) {
				proto_item_append_text(ti, " (outbound)");
				pinfo->p2p_dir = P2P_DIR_SENT;
			}
		}

		fh_tree = proto_item_add_subtree(ti, ett_frame);

		if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID && proto_field_is_referenced(tree, hf_frame_interface_id)) {
			const char *interface_name = epan_get_interface_name(pinfo->epan, pinfo->phdr->interface_id);

			if (interface_name)
				proto_tree_add_uint_format_value(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id, "%u (%s)", pinfo->phdr->interface_id, interface_name);
			else
				proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id);
		}

		if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
			proto_tree *flags_tree;
			proto_item *flags_item;

			flags_item = proto_tree_add_uint(fh_tree, hf_frame_pack_flags, tvb, 0, 0, pinfo->phdr->pack_flags);
			flags_tree = proto_item_add_subtree(flags_item, ett_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_direction, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_reception_type, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_fcs_length, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_reserved, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_crc_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_long_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_short_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_inter_frame_gap_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_unaligned_frame_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_start_frame_delimiter_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_preamble_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_symbol_error, tvb, 0, 0, pinfo->phdr->pack_flags);
		}

		if (pinfo->phdr->rec_type == REC_TYPE_PACKET)
			proto_tree_add_int(fh_tree, hf_frame_wtap_encap, tvb, 0, 0, pinfo->fd->lnk_t);

		if (pinfo->fd->flags.has_ts) {
			proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb,
					    0, 0, &(pinfo->fd->abs_ts));
			if (pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) {
				expert_add_info_format(pinfo, ti, &ei_arrive_time_out_of_range,
								  "Arrival Time: Fractional second %09ld is invalid,"
								  " the valid range is 0-1000000000",
								  (long) pinfo->fd->abs_ts.nsecs);
			}
			item = proto_tree_add_time(fh_tree, hf_frame_shift_offset, tvb,
					    0, 0, &(pinfo->fd->shift_offset));
			PROTO_ITEM_SET_GENERATED(item);

			if (generate_epoch_time) {
				proto_tree_add_time(fh_tree, hf_frame_arrival_time_epoch, tvb,
						    0, 0, &(pinfo->fd->abs_ts));
			}

			if (proto_field_is_referenced(tree, hf_frame_time_delta)) {
				nstime_t     del_cap_ts;

				frame_delta_abs_time(pinfo->epan, pinfo->fd, pinfo->fd->num - 1, &del_cap_ts);

				item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb,
							   0, 0, &(del_cap_ts));
				PROTO_ITEM_SET_GENERATED(item);
			}

			if (proto_field_is_referenced(tree, hf_frame_time_delta_displayed)) {
				nstime_t del_dis_ts;

				frame_delta_abs_time(pinfo->epan, pinfo->fd, pinfo->fd->prev_dis_num, &del_dis_ts);

				item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb,
							   0, 0, &(del_dis_ts));
				PROTO_ITEM_SET_GENERATED(item);
			}

			item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb,
						   0, 0, &(pinfo->rel_ts));
			PROTO_ITEM_SET_GENERATED(item);

			if (pinfo->fd->flags.ref_time) {
				ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, ENC_NA);
				PROTO_ITEM_SET_GENERATED(ti);
			}
		}

		proto_tree_add_uint(fh_tree, hf_frame_number, tvb,
				    0, 0, pinfo->fd->num);

		proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb,
					   0, 0, frame_len, "Frame Length: %u byte%s (%u bits)",
					   frame_len, frame_plurality, frame_len * 8);

		proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb,
					   0, 0, cap_len, "Capture Length: %u byte%s (%u bits)",
					   cap_len, cap_plurality, cap_len * 8);

		if (generate_md5_hash) {
			const guint8 *cp;
			md5_state_t   md_ctx;
			md5_byte_t    digest[16];
			const gchar  *digest_string;

			cp = tvb_get_ptr(tvb, 0, cap_len);

			md5_init(&md_ctx);
			md5_append(&md_ctx, cp, cap_len);
			md5_finish(&md_ctx, digest);

			digest_string = bytestring_to_str(wmem_packet_scope(), digest, 16, '\0');
			ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string);
			PROTO_ITEM_SET_GENERATED(ti);
		}

		ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked);
		PROTO_ITEM_SET_GENERATED(ti);

		ti = proto_tree_add_boolean(fh_tree, hf_frame_ignored, tvb, 0, 0,pinfo->fd->flags.ignored);
		PROTO_ITEM_SET_GENERATED(ti);

		if (proto_field_is_referenced(tree, hf_frame_protocols)) {
			/* we are going to be using proto_item_append_string() on
			 * hf_frame_protocols, and we must therefore disable the
			 * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by
			 * setting it as visible.
			 *
			 * See proto.h for details.
			 */
			old_visible = proto_tree_set_visible(fh_tree, TRUE);
			ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, "");
			PROTO_ITEM_SET_GENERATED(ti);
			proto_tree_set_visible(fh_tree, old_visible);
		}

		/* Check for existences of P2P pseudo header */
		if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) {
			proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb,
					   0, 0, pinfo->p2p_dir);
		}

		/* Check for existences of MTP2 link number */
		if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) {
			proto_tree_add_uint(fh_tree, hf_link_number, tvb,
					    0, 0, pinfo->link_number);
		}

		if (show_file_off) {
			proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb,
						    0, 0, pinfo->fd->file_off,
						    "%" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)",
						    pinfo->fd->file_off, pinfo->fd->file_off);
		}

		if (pinfo->fd->color_filter != NULL) {
			const color_filter_t *color_filter = (const color_filter_t *)pinfo->fd->color_filter;
			item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb,
						     0, 0, color_filter->filter_name);
			PROTO_ITEM_SET_GENERATED(item);
			item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb,
						     0, 0, color_filter->filter_text);
			PROTO_ITEM_SET_GENERATED(item);
		}
	}

	if (pinfo->fd->flags.ignored) {
		/* Ignored package, stop handling here */
		col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>");
		proto_tree_add_text (tree, tvb, 0, 0, "This frame is marked as ignored");
		return tvb_captured_length(tvb);
	}

	/* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
	TRY {
#ifdef _MSC_VER
		/* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions
		   like memory access violations.
		   (a running debugger will be called before the except part below) */
		/* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
		   stack in an inconsistent state thus causing a crash at some point in the
		   handling of the exception.
		   See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
		*/
		__try {
#endif
			switch (pinfo->phdr->rec_type) {

			case REC_TYPE_PACKET:
				if ((force_docsis_encap) && (docsis_handle)) {
					call_dissector(docsis_handle, tvb, pinfo, parent_tree);
				} else {
					if (!dissector_try_uint(wtap_encap_dissector_table, pinfo->fd->lnk_t,
								tvb, pinfo, parent_tree)) {

						col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
						col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d",
							     pinfo->fd->lnk_t);
						call_dissector(data_handle,tvb, pinfo, parent_tree);
					}
				}
				break;

			case REC_TYPE_FT_SPECIFIC_EVENT:
			case REC_TYPE_FT_SPECIFIC_REPORT:
				{
					int file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;

					if (fr_data) {
						file_type_subtype = fr_data->file_type_subtype;
					}

					if (!dissector_try_uint(wtap_fts_rec_dissector_table, file_type_subtype,
								tvb, pinfo, parent_tree)) {

						col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
						col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d",
							     file_type_subtype);
						call_dissector(data_handle,tvb, pinfo, parent_tree);
					}
				}
				break;
			}
#ifdef _MSC_VER
		} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
			switch (GetExceptionCode()) {
			case(STATUS_ACCESS_VIOLATION):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
				break;
			case(STATUS_INTEGER_DIVIDE_BY_ZERO):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
				break;
			case(STATUS_STACK_OVERFLOW):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
				/* XXX - this will have probably corrupted the stack,
				   which makes problems later in the exception code */
				break;
				/* XXX - add other hardware exception codes as required */
			default:
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
			}
		}
#endif
	}
	CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

	if (proto_field_is_referenced(tree, hf_frame_protocols)) {
		wmem_strbuf_t *val = wmem_strbuf_sized_new(wmem_packet_scope(), 128, 0);
		wmem_list_frame_t *frame;
		/* skip the first entry, it's always the "frame" protocol */
		frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
		if (frame) {
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		while (frame) {
			wmem_strbuf_append_c(val, ':');
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		proto_item_append_string(ti, wmem_strbuf_get_str(val));
	}

	/*  Call postdissectors if we have any (while trying to avoid another
	 *  TRY/CATCH)
	 */
	if (have_postdissector()) {
		TRY {
#ifdef _MSC_VER
			/* Win32: Visual-C Structured Exception Handling (SEH)
			   to trap hardware exceptions like memory access violations */
			/* (a running debugger will be called before the except part below) */
			/* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
			   stack in an inconsistent state thus causing a crash at some point in the
			   handling of the exception.
			   See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
			*/
			__try {
#endif
				call_all_postdissectors(tvb, pinfo, parent_tree);
#ifdef _MSC_VER
			} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
				switch (GetExceptionCode()) {
				case(STATUS_ACCESS_VIOLATION):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
					break;
				case(STATUS_INTEGER_DIVIDE_BY_ZERO):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
					break;
				case(STATUS_STACK_OVERFLOW):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
					/* XXX - this will have probably corrupted the stack,
					   which makes problems later in the exception code */
					break;
					/* XXX - add other hardware exception codes as required */
				default:
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
				}
			}
#endif
		}
		CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
			show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
		}
		ENDTRY;
	}

	tap_queue_packet(frame_tap, pinfo, NULL);


	if (pinfo->frame_end_routines) {
		g_slist_foreach(pinfo->frame_end_routines, &call_frame_end_routine, NULL);
		g_slist_free(pinfo->frame_end_routines);
		pinfo->frame_end_routines = NULL;
	}

	return tvb_captured_length(tvb);
}
Example #28
0
/* *** Code to actually dissect the packets *** */
static int dissect_dvb_s2_gse(tvbuff_t *tvb, int cur_off, proto_tree *tree, packet_info *pinfo)
{
    int         new_off                      = 0;
    int         frag_len;
    guint16     gse_hdr, data_len, gse_proto = 0;

    proto_item *ti, *tf;
    proto_tree *dvb_s2_gse_tree, *dvb_s2_gse_hdr_tree;

    tvbuff_t   *next_tvb;

    col_append_str(pinfo->cinfo, COL_INFO, "GSE");

    /* get header and determine length */
    gse_hdr = tvb_get_ntohs(tvb, cur_off + DVB_S2_GSE_OFFS_HDR);
    new_off += 2;
    frag_len = (gse_hdr & DVB_S2_GSE_HDR_LENGTH_MASK)+2;

    ti = proto_tree_add_item(tree, proto_dvb_s2_gse, tvb, cur_off, frag_len, ENC_NA);
    dvb_s2_gse_tree = proto_item_add_subtree(ti, ett_dvb_s2_gse);

    tf = proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_hdr, tvb, cur_off + DVB_S2_GSE_OFFS_HDR, 2, gse_hdr);

    dvb_s2_gse_hdr_tree = proto_item_add_subtree(tf, ett_dvb_s2_gse_hdr);
    proto_tree_add_item(dvb_s2_gse_hdr_tree, hf_dvb_s2_gse_hdr_start, tvb, cur_off + DVB_S2_GSE_OFFS_HDR, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(dvb_s2_gse_hdr_tree, hf_dvb_s2_gse_hdr_stop, tvb, cur_off + DVB_S2_GSE_OFFS_HDR, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(dvb_s2_gse_hdr_tree, hf_dvb_s2_gse_hdr_labeltype, tvb,
                        cur_off + DVB_S2_GSE_OFFS_HDR, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(dvb_s2_gse_hdr_tree, hf_dvb_s2_gse_hdr_length, tvb, cur_off + DVB_S2_GSE_OFFS_HDR, 2, ENC_BIG_ENDIAN);

    if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) &&
        BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_STOP_POS) &&
        BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS1) && BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS2)) {
        col_append_str(pinfo->cinfo, COL_INFO, " ");
        return new_off;
    } else {
        if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) || BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) {

            proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_fragid, tvb, cur_off + new_off, 1, ENC_BIG_ENDIAN);

            new_off += 1;
        }
        if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_START_POS) && BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) {

            proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_totlength, tvb, cur_off + new_off, 2, ENC_BIG_ENDIAN);
            col_append_str(pinfo->cinfo, COL_INFO, "(frag) ");

            new_off += 2;
        }
        if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_START_POS)) {
            gse_proto = tvb_get_ntohs(tvb, cur_off + new_off);

            proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_proto, tvb, cur_off + new_off, 2, ENC_BIG_ENDIAN);

            new_off += 2;

            if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS1) && BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS2)) {
                /* 6 byte label */
                if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS))
                    col_append_str(pinfo->cinfo, COL_INFO, "6 ");

                proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_label6, tvb, cur_off + new_off, 6, ENC_NA);

                new_off += 6;
            } else if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS1) &&
                       BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_LABELTYPE_POS2)) {
                /* 3 byte label */
                if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS))
                    col_append_str(pinfo->cinfo, COL_INFO, "3 ");

                proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_label3, tvb, cur_off + new_off, 3, ENC_BIG_ENDIAN);

                new_off += 3;
            } else {
                /* 0 byte label */
                if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS))
                    col_append_str(pinfo->cinfo, COL_INFO, "0 ");
            }
            if (gse_proto < 0x0600 && gse_proto >= 0x100) {
                /* Only display optional extension headers */
                /* TODO: needs to be tested */

                /* TODO: implementation needs to be checked (len of ext-header??) */
                proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_exthdr, tvb, cur_off + new_off, 1, ENC_BIG_ENDIAN);

                new_off += 1;
            }
        }
        else
        {
            /* correct cinfo */
            col_append_str(pinfo->cinfo, COL_INFO, "(frag) ");
        }

        next_tvb = tvb_new_subset_remaining(tvb, cur_off + new_off);

        if (dvb_s2_full_dissection)
        {
            switch (gse_proto) {
            case ETHERTYPE_IP:
                new_off += call_dissector(ip_handle, next_tvb, pinfo, tree);
                break;
            case ETHERTYPE_IPv6:
                new_off += call_dissector(ipv6_handle, next_tvb, pinfo, tree);
                break;
            default:
                if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) && BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) {
                    data_len = (gse_hdr & DVB_S2_GSE_HDR_LENGTH_MASK) - (new_off - DVB_S2_GSE_MINSIZE) - DVB_S2_GSE_CRC32_LEN;
                } else
                    data_len = (gse_hdr & DVB_S2_GSE_HDR_LENGTH_MASK) - (new_off - DVB_S2_GSE_MINSIZE);

                proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_data, tvb, cur_off + new_off, data_len, ENC_NA);
                new_off += data_len;
                break;
            }
        }
        else
        {
            if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) && BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) {
                data_len = (gse_hdr & DVB_S2_GSE_HDR_LENGTH_MASK) - (new_off - DVB_S2_GSE_MINSIZE) - DVB_S2_GSE_CRC32_LEN;
            } else
                data_len = (gse_hdr & DVB_S2_GSE_HDR_LENGTH_MASK) - (new_off - DVB_S2_GSE_MINSIZE);

            proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_data, tvb, cur_off + new_off, data_len, ENC_NA);
            new_off += data_len;
        }

        /* add crc32 if last fragment */
        if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) && BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) {
            proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_crc32, tvb, cur_off + new_off, DVB_S2_GSE_CRC32_LEN, ENC_BIG_ENDIAN);
            new_off += DVB_S2_GSE_CRC32_LEN;
        }
    }

    return new_off;
}
Example #29
0
};

static int
dissect_db_lsp_pdu (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
  proto_tree *db_lsp_tree;
  proto_item *db_lsp_item;
  gint        offset = 0;
  guint8      type, opvalue;
  guint16     magic, length;

  col_set_str (pinfo->cinfo, COL_PROTOCOL, PSNAME);
  col_set_str (pinfo->cinfo, COL_INFO, PNAME);

  db_lsp_item = proto_tree_add_item (tree, proto_db_lsp, tvb, offset, -1, ENC_NA);
  db_lsp_tree = proto_item_add_subtree (db_lsp_item, ett_db_lsp);

  type = tvb_get_guint8 (tvb, offset);
  proto_tree_add_item (db_lsp_tree, hf_type, tvb, offset, 1, ENC_BIG_ENDIAN);
  offset += 1;

  if (type == 0x80) {
    /* Two unknown bytes */
    offset += 2;
  }

  magic = tvb_get_ntohs (tvb, offset);
  proto_tree_add_item (db_lsp_tree, hf_magic, tvb, offset, 2, ENC_BIG_ENDIAN);
  offset += 2;

  length = tvb_get_ntohs (tvb, offset);
Example #30
0
/* Code to actually dissect the packets */
static void
dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    char *szInfo;
    int			offCur		= 0;   /* current offset from start of WTP data */
    gint		returned_length, str_index = 0;

    unsigned char	b0;

    /* continuation flag */
    unsigned char  	fCon;			/* Continue flag	*/
    unsigned char  	fRID;			/* Re-transmission indicator*/
    unsigned char  	fTTR = '\0';		/* Transmission trailer	*/
    guint 		cbHeader   	= 0;	/* Fixed header length	*/
    guint 		vHeader   	= 0;	/* Variable header length*/
    int 		abortType  	= 0;

    /* Set up structures we'll need to add the protocol subtree and manage it */
    proto_item		*ti = NULL;
    proto_tree		*wtp_tree = NULL;

    char		pdut;
    char		clsTransaction = 3;
    int			numMissing = 0;		/* Number of missing packets in a negative ack */
    int			i;
    tvbuff_t		*wsp_tvb = NULL;
    guint8		psn = 0;		/* Packet sequence number*/
    guint16		TID = 0;		/* Transaction-Id	*/
    int			dataOffset;
    gint		dataLen;

#define SZINFO_SIZE 256
    szInfo=ep_alloc(SZINFO_SIZE);

    b0 = tvb_get_guint8 (tvb, offCur + 0);
    /* Discover Concatenated PDUs */
    if (b0 == 0) {
	guint	c_fieldlen = 0;		/* Length of length-field	*/
	guint	c_pdulen = 0;		/* Length of conc. PDU	*/

	if (tree) {
	    ti = proto_tree_add_item(tree, proto_wtp,
				    tvb, offCur, 1, ENC_NA);
	    wtp_tree = proto_item_add_subtree(ti, ett_wtp_sub_pdu_tree);
		proto_item_append_text(ti, ", PDU concatenation");
	}
	offCur = 1;
	i = 1;
	while (offCur < (int) tvb_reported_length(tvb)) {
	    tvbuff_t *wtp_tvb;
	    /* The length of an embedded WTP PDU is coded as either:
	     *	- a 7-bit value contained in one octet with highest bit == 0.
	     *	- a 15-bit value contained in two octets (little endian)
	     *	  if the 1st octet has its highest bit == 1.
	     * This means that this is NOT encoded as an uintvar-integer!!!
	     */
	    b0 = tvb_get_guint8(tvb, offCur + 0);
	    if (b0 & 0x80) {
		c_fieldlen = 2;
		c_pdulen = ((b0 & 0x7f) << 8) | tvb_get_guint8(tvb, offCur + 1);
	    } else {
		c_fieldlen = 1;
		c_pdulen = b0;
	    }
	    if (tree) {
		proto_tree_add_uint(wtp_tree, hf_wtp_header_sub_pdu_size,
				    tvb, offCur, c_fieldlen, c_pdulen);
	    }
	    if (i > 1) {
		col_append_str(pinfo->cinfo, COL_INFO, ", ");
	    }
	    /* Skip the length field for the WTP sub-tvb */
	    wtp_tvb = tvb_new_subset(tvb, offCur + c_fieldlen, c_pdulen, c_pdulen);
	    dissect_wtp_common(wtp_tvb, pinfo, wtp_tree);
	    offCur += c_fieldlen + c_pdulen;
	    i++;
	}
	if (tree) {
		proto_item_append_text(ti, ", PDU count: %u", i);
	}
	return;
    }
    /* No concatenation */
    fCon = b0 & 0x80;
    fRID = retransmission_indicator(b0);
    pdut = pdu_type(b0);

#ifdef DEBUG
	printf("WTP packet %u: tree = %p, pdu = %s (%u) length: %u\n",
			pinfo->fd->num, tree,
			val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x"),
			pdut, tvb_length(tvb));
#endif

    /* Develop the string to put in the Info column */
    returned_length =  g_snprintf(szInfo, SZINFO_SIZE, "WTP %s",
		    val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x"));
    str_index += MIN(returned_length, SZINFO_SIZE-str_index);

    switch (pdut) {
	case INVOKE:
	    fTTR = transmission_trailer(b0);
	    TID = tvb_get_ntohs(tvb, offCur + 1);
	    psn = 0;
	    clsTransaction = transaction_class(tvb_get_guint8(tvb, offCur + 3));
	    returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index,
		" Class %d", clsTransaction);
            str_index += MIN(returned_length, SZINFO_SIZE-str_index);
	    cbHeader = 4;
	    break;

	case SEGMENTED_INVOKE:
	case SEGMENTED_RESULT:
	    fTTR = transmission_trailer(b0);
	    TID = tvb_get_ntohs(tvb, offCur + 1);
	    psn = tvb_get_guint8(tvb, offCur + 3);
	    if (psn != 0) {
		returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index,
			" (%u)", psn);
                str_index += MIN(returned_length, SZINFO_SIZE-str_index);
	    }
	    cbHeader = 4;
	    break;

	case ABORT:
	    cbHeader = 4;
	    break;

	case RESULT:
	    fTTR = transmission_trailer(b0);
	    TID = tvb_get_ntohs(tvb, offCur + 1);
	    psn = 0;
	    cbHeader = 3;
	    break;

	case ACK:
	    cbHeader = 3;
	    break;

	case NEGATIVE_ACK:
	    /* Variable number of missing packets */
	    numMissing = tvb_get_guint8(tvb, offCur + 3);
	    cbHeader = numMissing + 4;
	    break;

	default:
	    break;
    };
    if (fRID) {
	returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " R" );
        str_index += MIN(returned_length, SZINFO_SIZE-str_index);
    };
    /* In the interest of speed, if "tree" is NULL, don't do any work not
       necessary to generate protocol tree items. */
    if (tree) {
#ifdef DEBUG
	fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader);
#endif
	/* NOTE - Length will be set when we process the TPI */
	ti = proto_tree_add_item(tree, proto_wtp, tvb, offCur, 0, ENC_NA);
#ifdef DEBUG
	fprintf(stderr, "dissect_wtp: (7) Returned from proto_tree_add_item\n");
#endif
	wtp_tree = proto_item_add_subtree(ti, ett_wtp);

/* Code to process the packet goes here */
#ifdef DEBUG
	fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader);
	fprintf(stderr, "dissect_wtp: offCur = %d\n", offCur);
#endif
	/* Add common items: only CON and PDU Type */
	proto_tree_add_item(
			wtp_tree,	 		/* tree */
			hf_wtp_header_flag_continue, 	/* id */
			tvb,
			offCur, 			/* start of highlight */
			1,				/* length of highlight*/
			b0				/* value */
	     );
	proto_tree_add_item(wtp_tree, hf_wtp_header_pdu_type, tvb, offCur, 1, ENC_LITTLE_ENDIAN);

	switch(pdut) {
	    case INVOKE:
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);

		proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_version , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_TIDNew, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_UP, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_Reserved, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_TransactionClass, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
		proto_item_append_text(ti,
				", PDU: Invoke (%u)"
				", Transaction Class: %s (%u)",
				INVOKE,
				val_to_str(clsTransaction, vals_transaction_classes, "Undefined"),
				clsTransaction);
		break;

	    case RESULT:
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
		proto_item_append_text(ti, ", PDU: Result (%u)", RESULT);
		break;

	    case ACK:
		proto_tree_add_item(wtp_tree, hf_wtp_header_Ack_flag_TVETOK, tvb, offCur, 1, ENC_BIG_ENDIAN);

		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
		proto_item_append_text(ti, ", PDU: ACK (%u)", ACK);
		break;

	    case ABORT:
		abortType = tvb_get_guint8 (tvb, offCur) & 0x07;
		proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_type , tvb, offCur , 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);

		if (abortType == PROVIDER)
		{
			guint8 reason = tvb_get_guint8(tvb, offCur + 3);
		    proto_tree_add_item( wtp_tree, hf_wtp_header_Abort_reason_provider , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN);
			proto_item_append_text(ti,
					", PDU: Abort (%u)"
					", Type: Provider (%u)"
					", Reason: %s (%u)",
					ABORT,
					PROVIDER,
					val_to_str(reason, vals_abort_reason_provider, "Undefined"),
					reason);
		}
		else if (abortType == USER)
		{
			guint8 reason = tvb_get_guint8(tvb, offCur + 3);
		    proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_reason_user , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN);
			proto_item_append_text(ti,
					", PDU: Abort (%u)"
					", Type: User (%u)"
					", Reason: %s (%u)",
					ABORT,
					PROVIDER,
					val_to_str_ext_const(reason, &vals_wsp_reason_codes_ext, "Undefined"),
					reason);
		}
		break;

	    case SEGMENTED_INVOKE:
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);

		proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
		proto_item_append_text(ti,
				", PDU: Segmented Invoke (%u)"
				", Packet Sequence Number: %u",
				SEGMENTED_INVOKE, psn);
		break;

	    case SEGMENTED_RESULT:
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);

		proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
		proto_item_append_text(ti,
				", PDU: Segmented Result (%u)"
				", Packet Sequence Number: %u",
				SEGMENTED_RESULT, psn);
		break;

	    case NEGATIVE_ACK:
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN);

		proto_tree_add_item(wtp_tree, hf_wtp_header_missing_packets , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN);
		/* Iterate through missing packets */
		for (i = 0; i < numMissing; i++)
		{
		    proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number, tvb, offCur + 4 + i, 1, ENC_LITTLE_ENDIAN);
		}
		proto_item_append_text(ti,
				", PDU: Negative Ack (%u)"
				", Missing Packets: %u",
				NEGATIVE_ACK, numMissing);
		break;

	    default:
		break;
	};
	if (fRID) {
		proto_item_append_text(ti, ", Retransmission");
	}
    } else { /* tree is NULL */
#ifdef DEBUG
	fprintf(stderr, "dissect_wtp: (4) tree was %p\n", tree);
#endif
    }
	/* Process the variable part */
	if (fCon) {			/* Now, analyze variable part	*/
	    unsigned char	 tCon;
	    unsigned char	 tByte;
	    unsigned char	 tpiLen;
	    tvbuff_t		*tmp_tvb;

	    vHeader = 0;		/* Start scan all over	*/

	    do {
		tByte = tvb_get_guint8(tvb, offCur + cbHeader + vHeader);
		tCon = tByte & 0x80;
		if (tByte & 0x04)	/* Long TPI	*/
		    tpiLen = 2 + tvb_get_guint8(tvb,
					    offCur + cbHeader + vHeader + 1);
		else
		    tpiLen = 1 + (tByte & 0x03);
		if (tree)
		{
		tmp_tvb = tvb_new_subset(tvb, offCur + cbHeader + vHeader,
					tpiLen, tpiLen);
		wtp_handle_tpi(wtp_tree, tmp_tvb);
		}
		vHeader += tpiLen;
	    } while (tCon);
	} else {
		/* There is no variable part */
	}	/* End of variable part of header */

	/* Set the length of the WTP protocol part now we know the length of the
	 * fixed and variable WTP headers */
	if (tree)
	proto_item_set_len(ti, cbHeader + vHeader);

#ifdef DEBUG
    fprintf( stderr, "dissect_wtp: cbHeader = %d\n", cbHeader );
#endif

    /*
     * Any remaining data ought to be WSP data (if not WTP ACK, NACK
     * or ABORT pdu), so, if we have any remaining data, and it's
     * not an ACK, NACK, or ABORT PDU, hand it off (defragmented) to the
     * WSP dissector.
     * Note that the last packet of a fragmented WTP message needn't
     * contain any data, so we allow payloadless packets to be
     * reassembled.  (XXX - does the reassembly code handle this
     * for packets other than the last packet?)
     *
	 * Try calling a subdissector only if:
	 *	- The WTP payload is ressembled in this very packet,
	 *	- The WTP payload is not fragmented across packets.
	 */
    dataOffset = offCur + cbHeader + vHeader;
    dataLen = tvb_reported_length_remaining(tvb, dataOffset);
    if ((dataLen >= 0) &&
			! ((pdut==ACK) || (pdut==NEGATIVE_ACK) || (pdut==ABORT)))
    {
		/* Try to reassemble if needed, and hand over to WSP
		 * A fragmented WTP packet is either:
		 *	- An INVOKE with fTTR (transmission trailer) not set,
		 *	- a SEGMENTED_INVOKE,
		 *	- A RESULT with fTTR (transmission trailer) not set,
		 *	- a SEGMENTED_RESULT.
		 */
		if ( ( (pdut == SEGMENTED_INVOKE) || (pdut == SEGMENTED_RESULT)
				|| ( ((pdut == INVOKE) || (pdut == RESULT)) && (!fTTR) )
			) && tvb_bytes_exist(tvb, dataOffset, dataLen) )
		{
			/* Try reassembling fragments */
			fragment_data *fd_wtp = NULL;
			guint32 reassembled_in = 0;
			gboolean save_fragmented = pinfo->fragmented;

			pinfo->fragmented = TRUE;
			fd_wtp = fragment_add_seq(tvb, dataOffset, pinfo, TID,
					wtp_fragment_table, psn, dataLen, !fTTR);
			/* XXX - fragment_add_seq() yields NULL unless Wireshark knows
			 * that the packet is part of a reassembled whole. This means
			 * that fd_wtp will be NULL as long as Wireshark did not encounter
			 * (and process) the packet containing the last fragment.
			 * This implies that Wireshark needs two passes over the data for
			 * correct reassembly. At the first pass, a capture containing
			 * three fragments plus a retransmssion of the last fragment
			 * will progressively show:
			 *
			 *		Packet 1: (Unreassembled fragment 1)
			 *		Packet 2: (Unreassembled fragment 2)
			 *		Packet 3: (Reassembled WTP)
			 *		Packet 4: (WTP payload reassembled in packet 3)
			 *
			 * However at subsequent evaluation (e.g., by applying a display
			 * filter) the packet summary will show:
			 *
			 *		Packet 1: (WTP payload reassembled in packet 3)
			 *		Packet 2: (WTP payload reassembled in packet 3)
			 *		Packet 3: (Reassembled WTP)
			 *		Packet 4: (WTP payload reassembled in packet 3)
			 *
			 * This is important to know, and also affects read filters!
			 */
			wsp_tvb = process_reassembled_data(tvb, dataOffset, pinfo,
					"Reassembled WTP", fd_wtp, &wtp_frag_items,
					NULL, wtp_tree);
#ifdef DEBUG
			printf("WTP: Packet %u %s -> %d: wsp_tvb = %p, fd_wtp = %p, frame = %u\n",
					pinfo->fd->num,
					fd_wtp ? "Reassembled" : "Not reassembled",
					fd_wtp ? fd_wtp->reassembled_in : -1,
					wsp_tvb,
					fd_wtp
					);
#endif
			if (fd_wtp) {
				/* Reassembled */
				reassembled_in = fd_wtp->reassembled_in;
				if (pinfo->fd->num == reassembled_in) {
					/* Reassembled in this very packet:
					 * We can safely hand the tvb to the WSP dissector */
					call_dissector(wsp_handle, wsp_tvb, pinfo, tree);
				} else {
					/* Not reassembled in this packet */
					if (check_col(pinfo->cinfo, COL_INFO)) {
						col_append_fstr(pinfo->cinfo, COL_INFO,
								"%s (WTP payload reassembled in packet %u)",
								szInfo, fd_wtp->reassembled_in);
					}
					if (tree) {
						proto_tree_add_text(wtp_tree, tvb, dataOffset, -1,
								"Payload");
					}
				}
			} else {
				/* Not reassembled yet, or not reassembled at all */
				if (check_col(pinfo->cinfo, COL_INFO)) {
					col_append_fstr(pinfo->cinfo, COL_INFO,
								"%s (Unreassembled fragment %u)",
								szInfo, psn);
				}
				if (tree) {
					proto_tree_add_text(wtp_tree, tvb, dataOffset, -1,
							"Payload");
				}
			}
			/* Now reset fragmentation information in pinfo */
			pinfo->fragmented = save_fragmented;
		}
		else if ( ((pdut == INVOKE) || (pdut == RESULT)) && (fTTR) )
		{
			/* Non-fragmented payload */
			wsp_tvb = tvb_new_subset_remaining(tvb, dataOffset);
			/* We can safely hand the tvb to the WSP dissector */
			call_dissector(wsp_handle, wsp_tvb, pinfo, tree);
		}
		else
		{
			/* Nothing to hand to subdissector */
			if (check_col(pinfo->cinfo, COL_INFO))
				col_append_str(pinfo->cinfo, COL_INFO, szInfo);
		}
	}
	else
	{
		/* Nothing to hand to subdissector */
		if (check_col(pinfo->cinfo, COL_INFO))
			col_append_str(pinfo->cinfo, COL_INFO, szInfo);
	}
}