Esempio n. 1
0
static void
j1939_fmt_address(gchar *result, guint32 addr )
{
    if ((addr < 128) || (addr > 247))
        g_snprintf(result, ITEM_LABEL_LENGTH, "%d (%s)", addr, val_to_str_ext_const(addr, &j1939_address_vals_ext, "Reserved"));
    else
        g_snprintf(result, ITEM_LABEL_LENGTH, "%d (Arbitrary)", addr);
}
Esempio n. 2
0
static gint
dissect_usb_dfu_descriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    proto_item       *main_item;
    proto_tree       *main_tree;
    proto_item       *length_item;
    gint              offset = 0;
    guint8            descriptor_length;
    guint8            descriptor_type;
    usb_conv_info_t  *usb_conv_info = (usb_conv_info_t *) data;

    if (!usb_conv_info) return offset;

    if (!(usb_conv_info->interfaceClass == IF_CLASS_APPLICATION_SPECIFIC &&
            usb_conv_info->interfaceSubclass == 0x01)) return offset;

    descriptor_length = tvb_get_guint8(tvb, offset);
    descriptor_type = tvb_get_guint8(tvb, offset + 1);

    switch (descriptor_type) {
    case 0x21:
        main_item = proto_tree_add_item(tree, hf_usb_dfu_descriptor, tvb, offset, -1, ENC_NA);
        main_tree = proto_item_add_subtree(main_item, ett_usb_dfu_descriptor);

        proto_item_append_text(main_item, ": %s", val_to_str_ext_const(descriptor_type, &descriptor_type_vals_ext, "Unknown"));

        length_item = dissect_usb_descriptor_header(main_tree, tvb, offset, &descriptor_type_vals_ext);
        if (descriptor_length != 7 && descriptor_length != 9)
            expert_add_info(pinfo, length_item, &ei_descriptor_invalid_length);
        offset += 2;

        proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bmAttributes_reserved, tvb, offset, 1, ENC_NA);
        proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bmAttributes_WillDetach, tvb, offset, 1, ENC_NA);
        proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bmAttributes_ManifestationTolerant, tvb, offset, 1, ENC_NA);
        proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bmAttributes_CanUpload, tvb, offset, 1, ENC_NA);
        proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bmAttributes_CanDownload, tvb, offset, 1, ENC_NA);
        offset += 1;

        proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_wDetachTimeOut, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;

        proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_wTransferSize, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;

        if (descriptor_length > 7) {
            proto_tree_add_item(main_tree, hf_usb_dfu_descriptor_bcdDFUVersion, tvb, offset, 2, ENC_LITTLE_ENDIAN);
            offset += 2;
        }

        break;
    }

    return offset;
}
Esempio n. 3
0
/*
 * Insert common descriptor type and length fields.
 */
static proto_tree*
fip_desc_type_len(proto_tree *tree, tvbuff_t *tvb, guint8 dtype, int ett, proto_item** item)
{
    proto_tree* ret_tree;

    ret_tree = proto_tree_add_subtree_format(tree, tvb, 0, -1, ett, item,
            "Descriptor: %s ", val_to_str_ext_const(dtype, &fip_desc_types_ext, "Unknown 0x%x"));
    proto_tree_add_item(ret_tree, hf_fip_desc_type, tvb, 0, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(ret_tree, hf_fip_desc_len, tvb, 1, 1, ENC_BIG_ENDIAN);

    return ret_tree;
}
Esempio n. 4
0
static void dissect_mac_mgmt_msg_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint offset = 0;
	guint message_type;
	proto_item *message_item;
	proto_tree *message_tree;
	const char* mgt_msg_str;

	message_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_decoder, tvb, offset, -1,
					"MAC Management Message Type (%u bytes)", tvb_reported_length(tvb));
	message_tree = proto_item_add_subtree(message_item, ett_mac_mgmt_msg_decoder);

	if (tvb_reported_length(tvb) == 0)
	{
		expert_add_info(pinfo, message_item, &ei_empty_payload);
		return;
	}

	/* Get the payload type */
	message_type = tvb_get_guint8(tvb, offset);
	proto_tree_add_item(message_tree, hf_mac_mgmt_msg_type, tvb, offset, 1, ENC_NA);
	mgt_msg_str = val_to_str_ext_const(message_type, &mgt_msg_abbrv_vals_ext, "Unknown");

	/* Display message type in Info column */
	col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", mgt_msg_str);

	/* add the payload type into the info column */
	if (try_val_to_str_ext(message_type, &mgt_msg_abbrv_vals_ext) == NULL)
	{
		/* display the MAC payload in Hex */
		proto_tree_add_item(message_tree, hf_mac_mgmt_msg_values, tvb, offset, -1, ENC_NA);
		return;
	}

	/* add the MAC header info to parent*/
	proto_item_append_text(proto_tree_get_parent(tree), ", %s", mgt_msg_str);

	/* Decode and display the MAC payload */
	if (!dissector_try_uint(subdissector_message_table, message_type,
		tvb_new_subset_remaining(tvb, 1), pinfo, tree))
	{
		proto_tree_add_item(message_tree, hf_mac_mgmt_msg_values, tvb, offset, -1, ENC_NA);
	}
}
Esempio n. 5
0
static const char*
socket_text(guint16 socket)
{
	return val_to_str_ext_const(socket, &ipx_socket_vals_ext, "Unknown");
}
Esempio n. 6
0
static void
dissect_ipxsap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*sap_tree, *s_tree;
	proto_item	*ti, *hidden_item;
	int		cursor;
	struct sap_query query;
	guint16		server_type;
	gchar		*server_name;
	guint16		server_port;
	guint16		intermediate_network;

	static const char	*sap_type[4] = { "General Query", "General Response",
		"Nearest Query", "Nearest Response" };

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

	query.query_type = tvb_get_ntohs(tvb, 0);
	query.server_type = tvb_get_ntohs(tvb, 2);

	if (check_col(pinfo->cinfo, COL_INFO)) {
		if (query.query_type >= 1 && query.query_type <= 4) {
			col_set_str(pinfo->cinfo, COL_INFO, sap_type[query.query_type - 1]);
		}
		else {
			col_set_str(pinfo->cinfo, COL_INFO, "Unknown Packet Type");
		}
	}

	if (tree) {
		ti = proto_tree_add_item(tree, proto_sap, tvb, 0, -1, ENC_NA);
		sap_tree = proto_item_add_subtree(ti, ett_ipxsap);

		if (query.query_type >= 1 && query.query_type <= 4) {
			proto_tree_add_text(sap_tree, tvb, 0, 2, "%s", sap_type[query.query_type - 1]);
			if ((query.query_type - 1) % 2) {
			  hidden_item = proto_tree_add_boolean(sap_tree,
						     hf_sap_response,
						     tvb, 0, 2, 1);
			} else {
			  hidden_item = proto_tree_add_boolean(sap_tree,
						     hf_sap_request,
						     tvb, 0, 2, 1);
			}
			PROTO_ITEM_SET_HIDDEN(hidden_item);
		}
		else {
			proto_tree_add_text(sap_tree, tvb, 0, 2,
					"Unknown SAP Packet Type %d", query.query_type);
		}

		if (query.query_type == IPX_SAP_GENERAL_RESPONSE ||
				query.query_type == IPX_SAP_NEAREST_RESPONSE) { /* responses */

			int available_length = tvb_reported_length(tvb);
			for (cursor =  2; (cursor + 64) <= available_length; cursor += 64) {
				server_type = tvb_get_ntohs(tvb, cursor);
				server_name = tvb_format_stringzpad(tvb, cursor+2, 48);

				ti = proto_tree_add_text(sap_tree, tvb, cursor+2, 48,
					"Server Name: %s", server_name);
				s_tree = proto_item_add_subtree(ti, ett_ipxsap_server);

				proto_tree_add_text(s_tree, tvb, cursor, 2, "Server Type: %s (0x%04X)",
				    val_to_str_ext_const(server_type, &novell_server_vals_ext, "Unknown"),
				    server_type);
				proto_tree_add_text(s_tree, tvb, cursor+50, 4, "Network: %s",
						ipxnet_to_string(tvb_get_ptr(tvb, cursor+50, 4)));
				proto_tree_add_text(s_tree, tvb, cursor+54, 6, "Node: %s",
						tvb_ether_to_str(tvb, cursor+54));
				server_port = tvb_get_ntohs(tvb, cursor+60);
				proto_tree_add_text(s_tree, tvb, cursor+60, 2, "Socket: %s (0x%04x)",
						socket_text(server_port),
						server_port);
				intermediate_network = tvb_get_ntohs(tvb, cursor+62);
				proto_tree_add_text(s_tree, tvb, cursor+62, 2,
						"Intermediate Networks: %d",
						intermediate_network);
			}
		}
		else {  /* queries */
			proto_tree_add_text(sap_tree, tvb, 2, 2, "Server Type: %s (0x%04X)",
				val_to_str_ext_const(query.server_type, &novell_server_vals_ext, "Unknown"),
				query.server_type);
		}
	}
}
Esempio n. 7
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=(char *)wmem_alloc(wmem_packet_scope(), 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_length(tvb, offCur + c_fieldlen, 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_captured_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_const(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_const(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    */
        guint8    tCon;
        guint8    tByte;
        guint     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_length(tvb, offCur + cbHeader + vHeader, 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_head *fd_wtp = NULL;
            guint32 reassembled_in = 0;
            gboolean save_fragmented = pinfo->fragmented;

            pinfo->fragmented = TRUE;
            fd_wtp = fragment_add_seq(&wtp_reassembly_table, tvb, dataOffset,
                    pinfo, TID, NULL, psn, dataLen, !fTTR, 0);
            /* 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 */
                    col_append_fstr(pinfo->cinfo, COL_INFO,
                            "%s (WTP payload reassembled in packet %u)",
                            szInfo, fd_wtp->reassembled_in);

                    proto_tree_add_item(wtp_tree, hf_wtp_payload, tvb, dataOffset, -1, ENC_NA);
                }
            } else {
                /* Not reassembled yet, or not reassembled at all */
                col_append_fstr(pinfo->cinfo, COL_INFO,
                        "%s (Unreassembled fragment %u)",
                        szInfo, psn);
                proto_tree_add_item(wtp_tree, hf_wtp_payload, tvb, dataOffset, -1, ENC_NA);
            }
            /* 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 */
            col_append_str(pinfo->cinfo, COL_INFO, szInfo);
        }
    }
    else
    {
        /* Nothing to hand to subdissector */
        col_append_str(pinfo->cinfo, COL_INFO, szInfo);
    }
}
Esempio n. 8
0
static void
dissect_btatt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    int offset = 0;
    proto_item *ti, *item;
    proto_tree *st, *ltree;
    guint8 opcode;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATT");

    switch (pinfo->p2p_dir) {
        case P2P_DIR_SENT:
            col_add_str(pinfo->cinfo, COL_INFO, "Sent ");
            break;
        case P2P_DIR_RECV:
            col_add_str(pinfo->cinfo, COL_INFO, "Rcvd ");
            break;
        default:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
                pinfo->p2p_dir);
            break;
    }

    if (tvb_length_remaining(tvb, 0) < 1)
        return;

    ti = proto_tree_add_item(tree, proto_btatt, tvb, 0, -1, ENC_NA);
    st = proto_item_add_subtree(ti, ett_btatt);

    item = proto_tree_add_item(st, hf_btatt_opcode, tvb, 0, 1, ENC_LITTLE_ENDIAN);
    opcode = tvb_get_guint8(tvb, 0);
    offset++;

    col_append_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_const(opcode, opcode_vals, "<unknown>"));

    switch (opcode) {
    case 0x01: /* Error Response */
        proto_tree_add_item(st, hf_btatt_req_opcode_in_error, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        offset++;
        proto_tree_add_item(st, hf_btatt_handle_in_error, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        col_append_fstr(pinfo->cinfo, COL_INFO, " - %s, Handle: 0x%04x",
                        val_to_str_const(tvb_get_guint8(tvb, offset+2), error_vals, "<unknown>"),
                        tvb_get_letohs(tvb, offset));
        offset += 2;
        proto_tree_add_item(st, hf_btatt_error_code, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        offset++;
        break;

    case 0x02: /* Exchange MTU Request */
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Client Rx MTU: %u", tvb_get_letohs(tvb, offset));
        proto_tree_add_item(st, hf_btatt_client_rx_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        break;

    case 0x03: /* Exchange MTU Response */
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Server Rx MTU: %u", tvb_get_letohs(tvb, offset));
        proto_tree_add_item(st, hf_btatt_server_rx_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        break;

    case 0x04: /* Find Information Request */
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Handles: 0x%04x..0x%04x",
                            tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2));
        proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        break;

    case 0x05: /* Find Information Response */
        {
            guint8 format = tvb_get_guint8(tvb, offset);

            item = proto_tree_add_item(st, hf_btatt_uuid_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
            offset++;

            if( format == 1 ) {
                while( tvb_length_remaining(tvb, offset) > 0) {
                    proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                    offset += 2;
                    proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                    offset += 2;
                }
            }
            else if( format == 2 ) {
                while( tvb_length_remaining(tvb, offset) > 0) {
                    proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                    offset += 2;
                    proto_tree_add_item(st, hf_btatt_uuid128, tvb, offset, 16, ENC_NA);
                    offset += 16;
                }
            }
            else {
                expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "Unknown format");
            }
        }
        break;

    case 0x06: /* Find By Type Value Request */
        col_append_fstr(pinfo->cinfo, COL_INFO, ", %s, Handles: 0x%04x..0x%04x",
                            val_to_str_ext_const(tvb_get_letohs(tvb, offset+4), &uuid_vals_ext, "<unknown>"),
                            tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2));
        
        proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        if( tvb_length_remaining(tvb, offset)  > 0)
            proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA);
        break;

    case 0x07: /* Find By Type Value Response */
        while( tvb_length_remaining(tvb, offset) > 0 ) {
            item = proto_tree_add_text(st, tvb, offset, 4,
                                            "Handles Info, Handle: 0x%04x, Group End Handle: 0x%04x",
                                            tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2));

            ltree = proto_item_add_subtree(item, ett_btatt_list);
            
            proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
            offset += 2;
            proto_tree_add_item(ltree, hf_btatt_group_end_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
            offset += 2;
        }
        break;

    case 0x08: /* Read By Type Request */
    case 0x10: /* Read By Group Type Request */
        col_append_fstr(pinfo->cinfo, COL_INFO, ", %s, Handles: 0x%04x..0x%04x",
                            val_to_str_ext_const(tvb_get_letohs(tvb, offset+4), &uuid_vals_ext, "<unknown>"),
                            tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2));
        
        proto_tree_add_item(st, hf_btatt_starting_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        proto_tree_add_item(st, hf_btatt_ending_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        
        if (tvb_length_remaining(tvb, offset) == 2) {
            proto_tree_add_item(st, hf_btatt_uuid16, tvb, offset, 2, ENC_LITTLE_ENDIAN);
            offset += 2;
        }
        else if (tvb_length_remaining(tvb, offset) == 16) {
            item = proto_tree_add_item(st, hf_btatt_uuid128, tvb, offset, 16, ENC_NA);
            proto_item_append_text(item, " (%s)", val_to_str_ext_const(tvb_get_letohs(tvb, offset),
                                            &uuid_vals_ext, "<unknown>"));
            offset += 16;
        }
        break;

    case 0x09: /* Read By Type Response */
        {
            guint8 length = tvb_get_guint8(tvb, offset);

            proto_tree_add_item(st, hf_btatt_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
            offset++;

            if(length > 0) {
                col_append_fstr(pinfo->cinfo, COL_INFO, ", Attribute List Length: %u",
                                        tvb_length_remaining(tvb, offset)/length);

                while (tvb_length_remaining(tvb, offset) >= length)
                {
                    item = proto_tree_add_text(st, tvb, offset, length, "Attribute Data, Handle: 0x%04x",
                                                    tvb_get_letohs(tvb, offset));

                    ltree = proto_item_add_subtree(item, ett_btatt_list);
                    
                    proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                    offset += 2;
                    proto_tree_add_item(ltree, hf_btatt_value, tvb, offset, length - 2, ENC_NA);
                    offset += (length-2);
                }
            }
        }
        break;

    case 0x0a: /* Read Request */
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset));
        proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        break;

    case 0x0b: /* Read Response */
    case 0x0d: /* Read Blob Response */
    case 0x0f: /* Multiple Read Response */
        proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA);
        break;

    case 0x0c: /* Read Blob Request */
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x, Offset: %u",
                        tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2));
        proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        proto_tree_add_item(st, hf_btatt_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        break;

    case 0x0e: /* Multiple Read Request */
        if(tvb_length_remaining(tvb, offset) < 4) {
            expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN,
                                                    "Too few handles, should be 2 or more");
            break;
        }
        
        col_append_str(pinfo->cinfo, COL_INFO, ", Handles: ");
        while (tvb_length_remaining(tvb, offset) >= 2) {
            proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
            col_append_fstr(pinfo->cinfo, COL_INFO, "0x%04x ", tvb_get_letohs(tvb, offset));
            offset += 2;
        }
        break;

    case 0x11: /* Read By Group Type Response */
        {
            guint8 length = tvb_get_guint8(tvb, offset);

            proto_tree_add_item(st, hf_btatt_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
            offset++;

            if(length > 0) {
                col_append_fstr(pinfo->cinfo, COL_INFO, ", Attribute List Length: %u", tvb_length_remaining(tvb, offset)/length);
            
                while (tvb_length_remaining(tvb, offset) >= length) {
                    item = proto_tree_add_text(st, tvb, offset, length,
                                                    "Attribute Data, Handle: 0x%04x, Group End Handle: 0x%04x",
                                                    tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2));

                    ltree = proto_item_add_subtree(item, ett_btatt_list);
                
                    proto_tree_add_item(ltree, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                    offset += 2;
                    proto_tree_add_item(ltree, hf_btatt_group_end_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
                    offset += 2;
                    proto_tree_add_item(ltree, hf_btatt_value, tvb, offset, length - 4, ENC_NA);
                    offset += (length-4);
                }
            }
        }
        break;

    case 0x12: /* Write Request */
    case 0x52: /* Write Command */
    case 0x1b: /* Handle Value Notification */
    case 0x1d: /* Handle Value Indication */
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset));
        proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA);
        break;

    case 0x16: /* Prepare Write Request */
    case 0x17: /* Prepare Write Response */
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x, Offset: %u",
                        tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+2));
        proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        proto_tree_add_item(st, hf_btatt_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        proto_tree_add_item(st, hf_btatt_value, tvb, offset, -1, ENC_NA);
        break;

    case 0x18: /* Execute Write Request */
        col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
                        val_to_str_const(tvb_get_guint8(tvb, offset), flags_vals, "<unknown>"));
        proto_tree_add_item(st, hf_btatt_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        offset++;
        break;

    case 0xd2: /* Signed Write Command */
        {
            guint8 length;

            col_append_fstr(pinfo->cinfo, COL_INFO, ", Handle: 0x%04x", tvb_get_letohs(tvb, offset));
            proto_tree_add_item(st, hf_btatt_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
            offset += 2;
            length = tvb_length_remaining(tvb, offset);
            if (length > 12) {
                proto_tree_add_item(st, hf_btatt_value, tvb, offset, length-12, ENC_NA);
                offset+=length-12;
            }

            proto_tree_add_item(st, hf_btatt_sign_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
            offset+=4;
            proto_tree_add_item(st, hf_btatt_signature, tvb, offset, 8, ENC_NA);
            offset+=8;
        break;
        }
    default:
        break;
    }
}
Esempio n. 9
0
static int
dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo)
{
    proto_tree *hdrs_tree   = NULL;
    proto_tree *hdr_tree    = NULL;
    proto_item *hdr         = NULL;
    proto_item *handle_item;
    gint        item_length = -1;
    guint8      hdr_id, i;

    if (tvb_length_remaining(tvb, offset) > 0) {
        proto_item *hdrs;
        hdrs      = proto_tree_add_text(tree, tvb, offset, item_length, "Headers");
        hdrs_tree = proto_item_add_subtree(hdrs, ett_btobex_hdrs);
    }
    else {
        return offset;
    }

    while (tvb_length_remaining(tvb, offset) > 0) {
        hdr_id = tvb_get_guint8(tvb, offset);

        switch(0xC0 & hdr_id)
        {
            case 0x00: /* null terminated unicode */
                item_length = tvb_get_ntohs(tvb, offset+1);
                break;
            case 0x40:  /* byte sequence */
                item_length = tvb_get_ntohs(tvb, offset+1);
                break;
            case 0x80:  /* 1 byte */
                item_length = 2;
                break;
            case 0xc0:  /* 4 bytes */
                item_length = 5;
                break;
        }

        hdr = proto_tree_add_text(hdrs_tree, tvb, offset, item_length, "%s",
                                  val_to_str_ext_const(hdr_id, &header_id_vals_ext, "Unknown"));
        hdr_tree = proto_item_add_subtree(hdr, ett_btobex_hdr);

        proto_tree_add_item(hdr_tree, hf_hdr_id, tvb, offset, 1, ENC_BIG_ENDIAN);

        offset++;

        switch(0xC0 & hdr_id)
        {
            case 0x00: /* null terminated unicode */
                {
                    proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN);
                    offset += 2;

                    if ((item_length - 3) > 0) {
                        char *str;

                        display_unicode_string(tvb, hdr_tree, offset, &str);
                        proto_item_append_text(hdr_tree, " (\"%s\")", str);
                        col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", str);
                    }
                    else {
                        col_append_str(pinfo->cinfo, COL_INFO, " \"\"");
                    }

                    offset += item_length - 3;
                }
                break;
            case 0x40:  /* byte sequence */
                proto_tree_add_item(hdr_tree, hf_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;

                handle_item = proto_tree_add_item(hdr_tree, hf_hdr_val_byte_seq, tvb, offset, item_length - 3, ENC_NA);

                if (((hdr_id == 0x46) || (hdr_id == 0x4a)) && (item_length == 19)) { /* target or who */
                    for(i=0; target_vals[i].strptr != NULL; i++) {
                        if (tvb_memeql(tvb, offset, target_vals[i].value, 16) == 0) {
                            proto_item_append_text(handle_item, ": %s", target_vals[i].strptr);
                            proto_item_append_text(hdr_tree, " (%s)", target_vals[i].strptr);
                            col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", target_vals[i].strptr);
                        }
                    }
                }

                if (!tvb_strneql(tvb, offset, "<?xml", 5))
                {
                    tvbuff_t* next_tvb = tvb_new_subset_remaining(tvb, offset);

                    call_dissector(xml_handle, next_tvb, pinfo, tree);
                }
                else if (is_ascii_str(tvb_get_ptr(tvb, offset,item_length - 3), item_length - 3))
                {
                    proto_item_append_text(hdr_tree, " (\"%s\")", tvb_get_ephemeral_string(tvb, offset,item_length - 3));
                    col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", tvb_get_ephemeral_string(tvb, offset,item_length - 3));
                }

                offset += item_length - 3;
                break;
            case 0x80:  /* 1 byte */
                proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset));
                proto_tree_add_item(hdr_tree, hf_hdr_val_byte, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset++;
                break;
            case 0xc0:  /* 4 bytes */
                proto_item_append_text(hdr_tree, " (%i)", tvb_get_ntohl(tvb, offset));
                proto_tree_add_item(hdr_tree, hf_hdr_val_long, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            default:
                break;
        }
    }

    return offset;
}
Esempio n. 10
0
const char *ipprotostr(const int proto) {
    return val_to_str_ext_const(proto, &ipproto_val_ext, "Unknown");
}
Esempio n. 11
0
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_reported_length_remaining(tvb, xOfs) >= 16)
        {
            uLen = tvb_get_guint32(tvb, xOfs + 4, bLittleEndian);
            if (uLen < 16)
            {
                proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_PrmCnt, tvb, xOfs, 16, sPrmCnt, uLen, uCnt);
                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(tvb, offset    , bLittleEndian);
        uLen = tvb_get_guint32(tvb, offset + 4, bLittleEndian);
        if (uLen == 0)
        {
            proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_prmln0, tvb, offset, 12, sPrmLn0, u+1, uCount);
            u = uCount;
            break;
        }
        uPrm = tvb_get_guint32(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_ext_const(uTyp, GET_VALS_EXTP(PrmTyp), "      Unknown") + 6,
                uPrm, uPrm, val_to_str_ext_const(uPrm, GET_VALS_EXTP(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_ext_const(uTyp, GET_VALS_EXTP(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(tvb, offset + uLenF, bLittleEndian);
                if (bParse)
                    pVal = dissect_mqpcf_parm_getintval(uPrm, uVal);

                if (pVal)
                {
                    tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL,
                                                             "%s %8x-(%9d) %s", strPrm, uVal, uVal, pVal);
                }
                else
                {
                    tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL,
                                                             "%s %8x-(%9d)", strPrm, uVal, uVal);
                }

                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(tvb, offset + uLenF, bLittleEndian);
                uSLn = tvb_get_guint32(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((const char *)sStr), '.');

                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s", strPrm, sStr);

                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(tvb, offset+uLenF, bLittleEndian);
                uDigit = dissect_mqpcf_getDigits(uCnt);

                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, &ti, "%s Cnt(%d)", strPrm, 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++)
                {
                    uVal = tvb_get_guint32(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)
                {
                    proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_MaxInt, tvb, offset, (uCnt- u2) * 4, sMaxLst, u2, uCnt);
                }
            }
            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(tvb, offset + uLenF    , bLittleEndian);
                uCnt = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian);
                uSLn = tvb_get_guint32(tvb, offset + uLenF + 8, bLittleEndian);

                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s Cnt(%d)", strPrm, 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_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((const char *)sStr),  '.');

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

                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(tvb, offset + uLenF, bLittleEndian);
                if (uSLn)
                {
                    guint8 *sStrA = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_ASCII) , uSLn, '.');
                    guint8 *sStrE = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 4, uSLn, ENC_EBCDIC), uSLn, '.');
                    if (uSLn > 35)
                    {
                        tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL,
                                                        "%s [Truncated] A(%-.35s) E(%-.35s)", strPrm, sStrA, sStrE);
                    }
                    else
                    {
                        tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL,
                                                        "%s A(%s) E(%s)", strPrm, sStrA, sStrE);
                    }
                }
                else
                {
                    tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s <MISSING>", strPrm);
                }

                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(tvb, offset + uLenF    , bLittleEndian);
                uVal = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian);

                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s %8x-(%9d)",
                    strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), "       Unknown (0x%02x)")+7, uVal, uVal);

                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(tvb, offset + uLenF, bLittleEndian);
                uCCS = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian);
                uSLn = tvb_get_guint32(tvb, offset + uLenF + 8, bLittleEndian);
                sStr = (guint8 *)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);

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

                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(tvb, offset + uLenF, bLittleEndian);
                uSLn = tvb_get_guint32(tvb, offset + uLenF + 4, bLittleEndian);
                if (uSLn)
                {
                    guint8 *sStrA = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, ENC_ASCII), uSLn, '.');
                    guint8 *sStrE = (guint8 *)format_text_chr(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + uLenF + 8, uSLn, ENC_EBCDIC), uSLn, '.');
                    tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s A(%s) E(%s)",
                        strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), "       Unknown (0x%02x)")+7, sStrA, sStrE);
                }
                else
                {
                    tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s %s <MISSING>",
                        strPrm, val_to_str(uOpe, GET_VALSV(FilterOP), "       Unknown (0x%02x)")+7);
                }

                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(tvb, offset + uLenF + 4, bLittleEndian);
                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL,
                    "%s %" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)", strPrm, uVal64, uVal64);

                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(tvb, offset + uLenF, bLittleEndian);
                tree = proto_tree_add_subtree_format(mq_tree, tvb, offset, uLen, ett_mqpcf_prm, NULL, "%s Cnt(%d)", strPrm, uCnt);
                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(tvb, offset, bLittleEndian);
                    proto_tree_add_int64_format(tree, hf_mq_pcf_int64list, tvb, offset, 8, uVal64,
                        "%s[%*d]: %" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)",
                        hfinfo->name, uDigit, u2+1, uVal64, uVal64);
                    offset += 8;
                }
                if (u2 != uCnt)
                {
                    proto_tree_add_expert_format(tree, pinfo, &ei_mq_pcf_MaxI64, tvb, offset, (uCnt - u2) * 8, sMaxLst, u2, uCnt);
                }
            }
            break;
        }
        offset = tOfs+uLen;
    }
    if (u != uCount)
    {
        proto_tree_add_expert_format(mq_tree, pinfo, &ei_mq_pcf_MaxPrm, tvb, offset, tvb_reported_length_remaining(tvb, offset), sMaxPrm, u, uCount);
    }
}
Esempio n. 12
0
static int
dissect_device(proto_tree *tree, tvbuff_t *tvb, int offset)
{
    guint32 product;
    guint32 vendor_id;
    guint32 product_id;

    /* Device path on host (usually /sys/devices/usb/... */
    proto_tree_add_item(tree, hf_usbip_path, tvb, offset, 256, ENC_ASCII | ENC_NA);
    offset += 256;

    /* Bus id string - Id of the bus the device is connected to */
    proto_tree_add_item(tree, hf_usbip_busid, tvb, offset, 32, ENC_ASCII | ENC_NA);
    offset += 32;

    /* bus number */
    proto_tree_add_item(tree, hf_usbip_busnum, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset += 4;

    /* device number */
    proto_tree_add_item(tree, hf_usbip_devnum, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset += 4;

    /* USB Speed */
    proto_tree_add_item(tree, hf_usbip_speed, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset += 4;

    /* idVendor */
    proto_tree_add_item_ret_uint(tree, hf_usbip_idVendor, tvb, offset, 2, ENC_BIG_ENDIAN, &vendor_id);
    offset += 2;

    /* idProduct */
    product_id = tvb_get_ntohs(tvb, offset);
    product = vendor_id << 16 | product_id;

    proto_tree_add_uint_format_value(tree, hf_usbip_idProduct, tvb, offset, 2,
                                     product_id, "%s (0x%04x)", val_to_str_ext_const(product, &ext_usb_products_vals,
                                             "Unknown"), product_id);
    offset += 2;

    /* bcdDevice */
    proto_tree_add_item(tree, hf_usbip_bcdDevice, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    /* Device Class */
    proto_tree_add_item(tree, hf_usbip_bDeviceClass, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    /* Device Sub Class */
    proto_tree_add_item(tree, hf_usbip_bDeviceSubClass, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    /* Device Protocol */
    proto_tree_add_item(tree, hf_usbip_bDeviceProtocol, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    /* Current Configuration */
    proto_tree_add_item(tree, hf_usbip_bConfigurationValue, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    /* Number of Configurations */
    proto_tree_add_item(tree, hf_usbip_bNumConfigurations, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    /* Number of Interfaces */
    proto_tree_add_item(tree, hf_usbip_bNumInterfaces, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;
    return offset;
}
Esempio n. 13
0
static void
dissect_wai_data(tvbuff_t *tvb, proto_tree *tree, guint8 subtype, guint16 lenx)
{
    proto_item  *data_item;
    proto_tree  *data_tree;
    const gchar *type_name;

    data_item = proto_tree_add_item(tree, hf_wai_data, tvb, 0, lenx, ENC_NA);
    data_tree = proto_item_add_subtree (data_item, ett_wai_data);

    type_name = val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type");

    proto_item_set_text(data_item, "%s data (%d bytes)", type_name, lenx);

    switch (subtype) {
        case WAI_SUB_PRE_AUTHENTICATION:
        {
            /* Chapter 8.1.4.6 Preauthentication [ref: 1] */
            dissect_flag(tvb, 0, data_tree);
            dissect_uskid(tvb, 1, data_tree);
            dissect_addid(tvb, 2, data_tree);
            dissect_counter(tvb, 14, data_tree);
            dissect_message_auth_code(tvb, 30, data_tree);
            break;
        }
        case WAI_SUB_STAKEY_REQ:
        {
            /* Chapter 8.1.4.5 STAKey Establishment procedure [ref: 1] */
            dissect_flag(tvb, 0, data_tree);
            proto_tree_add_item(data_tree, hf_wai_sta_key_id, tvb, 1, 1, ENC_BIG_ENDIAN);
            dissect_uskid(tvb, 2, data_tree);
            dissect_addid(tvb, 3, data_tree);
            dissect_counter(tvb, 15, data_tree);
            dissect_message_auth_code(tvb, 31, data_tree);
            break;
        }
        case WAI_SUB_AUTH_ACTIVATION:
        {
            /* Chapter 8.1.4.2.1 WAI Authentication Activation  [ref: 1] */
            guint16 offset = 0;

            dissect_flag(tvb, offset, data_tree);
            offset += 1;
            dissect_authentication_id(tvb, offset, data_tree);
            offset += 32;
            offset += dissect_identity(tvb, offset, data_tree, "Local ASU ");
            offset += dissect_certificate(tvb, offset, data_tree, "STE AE ");
            dissect_ecdh_parameter(tvb, offset, data_tree);
            break;
        }
        case WAI_SUB_ACCESS_AUTH_REQ:
        {
            /* Chapter 8.1.4.2.2 Access WAI Authentication Request  [ref: 1] */
            guint16 offset = 0;
            guint8  optional_field;

            optional_field = tvb_get_guint8(tvb, 0) & FLAG_BIT3;

            dissect_flag(tvb, offset, data_tree);
            offset += 1;
            dissect_authentication_id(tvb, offset, data_tree);
            offset += 32;
            offset += dissect_challenge(tvb, offset, data_tree, "ASUE ");
            offset += dissect_key_data(tvb, offset, data_tree, "ASUE ");
            offset += dissect_identity(tvb, offset, data_tree, "STA AE ");
            offset += dissect_certificate(tvb, offset, data_tree, "STA ASUE ");
            offset += dissect_ecdh_parameter(tvb, offset, data_tree);

            if (optional_field) {
                offset += dissect_identity_list(tvb, offset, data_tree);
            }

            dissect_signature(tvb, offset, data_tree, "ASUE Signature");
            break;
        }
        case WAI_SUB_ACCESS_AUTH_RESP:
        {
            /* Chapter 8.1.4.2.5 Access WAI Authentication Response  [ref: 1] */
            guint16 offset = 0;
            guint8  optional_field;

            optional_field = tvb_get_guint8(tvb, 0) & FLAG_BIT3;

            dissect_flag(tvb, offset, data_tree);
            offset += 1;
            offset += dissect_challenge(tvb, offset, data_tree, "ASUE ");
            offset += dissect_challenge(tvb, offset, data_tree, "AE ");
            proto_tree_add_item(data_tree, hf_wai_access_res, tvb, offset, 1, ENC_BIG_ENDIAN);
            offset += 1;
            offset += dissect_key_data(tvb, offset, data_tree, "ASUE ");
            offset += dissect_key_data(tvb, offset, data_tree, "AE ");
            offset += dissect_identity(tvb, offset, data_tree, "STA AE ");
            offset += dissect_identity(tvb, offset, data_tree, "STA ASUE ");

            if (optional_field) {
                guint  length = 0;
                offset += dissect_multiple_certificate(tvb, offset, data_tree);
                offset += dissect_signature(tvb, offset, data_tree, "Server Signature trusted by ASUE");
                length  = tvb_get_ntohs(tvb, offset+1);
                if (length + 3 + offset + 1 < lenx)
                    offset += dissect_signature(tvb, offset, data_tree, "Server Signature trusted by AE");
            }

            dissect_signature(tvb, offset, data_tree, "AE Signature");
            break;
        }
        case WAI_SUB_CERT_AUTH_REQ:
        {
            /* Chapter 8.1.4.2.3 Certificate Authentication Request  [ref: 1] */
            guint16 offset = 0;
            guint8  optional_field;

            optional_field = tvb_get_guint8(tvb, 0) & FLAG_BIT3;

            dissect_addid(tvb, offset, data_tree);
            offset += 12;
            offset += dissect_challenge(tvb, offset, data_tree, "AE ");
            offset += dissect_challenge(tvb, offset, data_tree, "ASUE ");
            offset += dissect_certificate(tvb, offset, data_tree, "STE ASUE ");
            offset += dissect_certificate(tvb, offset, data_tree, "STE AE ");
            if (optional_field) {
                dissect_identity_list(tvb, offset, data_tree);
            }
            break;
        }
        case WAI_SUB_CERT_AUTH_RESP:
        {
            /* Chapter 8.1.4.2.4 Certificate Authentication Response  [ref: 1] */
            guint16 offset = 0;

            dissect_addid(tvb, offset, data_tree);
            offset += 12;
            offset += dissect_multiple_certificate(tvb, offset, data_tree);
            offset += dissect_signature(tvb, offset, data_tree, "Server Signature trusted by ASUE");
            if (offset < lenx)
                dissect_signature(tvb, offset, data_tree, "Server Signature trusted by AE");
            break;
        }
        case WAI_SUB_UNICAST_KEY_REQ:
        {
            /* Chapter 8.1.4.3.1 Unicast Key Negotiation Request [ref: 1] */
            dissect_flag(tvb, 0, data_tree);
            dissect_bkid(tvb, 1, data_tree);
            dissect_uskid(tvb, 17, data_tree);
            dissect_addid(tvb, 18, data_tree);
            dissect_challenge(tvb, 30, data_tree , "AE ");
            break;
        }
        case WAI_SUB_UNICAST_KEY_RESP:
        {
            /* Chapter 8.1.4.3.2 Unicast Key Negotiation Response [ref: 1] */
            tvbuff_t *next_tvb;
            guint     length = 0;

            dissect_flag(tvb, 0, data_tree);
            dissect_bkid(tvb, 1, data_tree);
            dissect_uskid(tvb, 17, data_tree);
            dissect_addid(tvb, 18, data_tree);
            dissect_challenge(tvb, 30, data_tree, "ASUE ");
            dissect_challenge(tvb, 62, data_tree, "AE ");

            next_tvb = tvb_new_subset_remaining(tvb, 96);
            length = tvb_reported_length(next_tvb);

            dissect_wie(next_tvb, 0, length-20, data_tree);
            dissect_message_auth_code(next_tvb, length-20, data_tree);
            break;
        }
        case WAI_SUB_UNICAST_KEY_CONFIRM:
        {
            /* Chapter 8.1.4.3.3 Unicast Key Negotiation Confirmation [ref: 1] */
            tvbuff_t *next_tvb;
            guint     length = 0;

            dissect_flag(tvb, 0, data_tree);
            dissect_bkid(tvb, 1, data_tree);
            dissect_uskid(tvb, 17, data_tree);
            dissect_addid(tvb, 18, data_tree);
            dissect_challenge(tvb, 30, data_tree, "ASUE ");

            next_tvb = tvb_new_subset_remaining(tvb, 62);
            length = tvb_reported_length(next_tvb);

            dissect_wie(next_tvb, 0, length-20, data_tree);
            dissect_message_auth_code(next_tvb, length-20, data_tree);
            break;
        }
        case WAI_SUB_MULTICAST_ANNOUNCE:
        {
            /* Chapter 8.1.4.4.1 Multicast Key/STAKey Announcement [ref: 1] */
            guint16 offset = 0;

            dissect_flag(tvb, offset, data_tree);
            offset += 1;
            dissect_mskid(tvb, offset, data_tree);
            offset += 1;
            dissect_uskid(tvb, offset, data_tree);
            offset += 1;
            dissect_addid(tvb, offset, data_tree);
            offset += 12;
            proto_tree_add_item(data_tree, hf_wai_data_pack_num, tvb, offset, 16, ENC_NA);
            offset += 16;
            dissect_key_announcement_identifier(tvb, offset, data_tree);
            offset += 16;
            offset += dissect_key_data(tvb, offset, data_tree, NULL);
            dissect_message_auth_code(tvb, offset, data_tree);
            break;
        }
        case WAI_SUB_MULTICAST_ANNOUNCE_RESP:
        {
            /* Chapter 8.1.4.4.2 Multicast Key/STAKey Announcement Response [ref: 1] */
            dissect_flag(tvb,  0, data_tree);
            dissect_mskid(tvb, 1, data_tree);
            dissect_uskid(tvb, 2, data_tree);
            dissect_addid(tvb, 3, data_tree);
            dissect_key_announcement_identifier(tvb, 15, data_tree);
            dissect_message_auth_code(tvb, 31, data_tree);
            break;
        }
        default:
            break;
    }
}
Esempio n. 14
0
static void
dissect_wai(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* Format of WAPI protocol packet in WAI authentication system

0      2      3         4         6         8        10        11      12
-------------------------------------------------------------------------------
| Ver. | Type | Subtype | Reserved | Length | packet  |  fragm. | flag | data |
|                                           | seq. no | seq. no |             |
|-----------------------------------------------------------------------------|
Figure 18 from [ref:1]
*/
#define WAI_MESSAGE_LENGTH 12   /*Length of all fields without 'Data' field*/
#define WAI_DATA_OFFSET    WAI_MESSAGE_LENGTH
    guint16        version;
    guint8         subtype;
    guint16        length;
    guint16        packet_num;
    guint8         fragment_num;
    guint8         flags;
    fragment_head *frag_msg;
    proto_tree    *wai_tree     = NULL;
    tvbuff_t      *next_tvb;
    tvbuff_t      *new_tvb;
    const gchar   *subtype_name = "Unknown type";

    length = tvb_get_ntohs(tvb, 6)-WAI_MESSAGE_LENGTH;
    subtype = tvb_get_guint8(tvb, 3);

    /* quick sanity check */
    if ((length != tvb_reported_length (tvb)-WAI_MESSAGE_LENGTH) ||
        (subtype > WAI_SUB_MULTICAST_ANNOUNCE_RESP)) {
        return;
    }

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "WAI");
    col_clear(pinfo->cinfo, COL_INFO);
    version = tvb_get_ntohs(tvb, 0);

    if (version == 1) {
        subtype_name = val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type");
    }
    col_append_fstr(pinfo->cinfo, COL_INFO, "%s", subtype_name);

    /* Field lengths and offsets in WAI protocol described above */
    packet_num   = tvb_get_ntohs(tvb, 8);
    fragment_num = tvb_get_guint8(tvb, 10);
    flags        = tvb_get_guint8(tvb, 11);

    if (tree) {
        proto_item *wai_item;

        wai_item = proto_tree_add_item(tree, proto_wai, tvb, 0, -1, ENC_NA);

        proto_item_set_text (wai_item, "WAI Protocol (%s)",
                                val_to_str_ext_const(subtype, &wai_subtype_names_ext, "Unknown type"));
        wai_tree = proto_item_add_subtree(wai_item, ett_wai);

        /* Field lengths and offsets in WAI protocol described above */
        proto_tree_add_item(wai_tree, hf_wai_version,   tvb, 0,  2, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_type,      tvb, 2,  1, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_subtype,   tvb, 3,  1, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_reserved,  tvb, 4,  2, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_length,    tvb, 6,  2, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_seq,       tvb, 8,  2, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_fragm_seq, tvb, 10, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(wai_tree, hf_wai_flag,      tvb, 11, 1, ENC_BIG_ENDIAN);
    }

    frag_msg =  fragment_add_seq_check (&wai_reassembly_table,
                                        tvb, WAI_DATA_OFFSET,
                                        pinfo,
                                        packet_num,
                                        NULL,
                                        fragment_num,
                                        length,
                                        flags);

    next_tvb = tvb_new_subset_remaining(tvb, WAI_DATA_OFFSET);

    /* Replace INFO column if message is fragmented and call data_handle */
    if (flags) {
        col_add_fstr(pinfo->cinfo, COL_INFO,
                     "Fragment (%d) of message, data not dissected", fragment_num);

        process_reassembled_data(tvb, WAI_DATA_OFFSET, pinfo,
                                 "Reassembled WAI", frag_msg, &wai_frag_items,
                                 NULL, wai_tree);

        call_dissector(data_handle, next_tvb, pinfo, tree);
    } else {
        /* If this is the last fragment of fragmented message, then reassamble and dissect
           otherwise only dissect */
        if (fragment_num > 0) {
            new_tvb = process_reassembled_data(tvb, WAI_DATA_OFFSET, pinfo,
                                               "Reassembled WAI", frag_msg, &wai_frag_items,
                                               NULL, wai_tree);

            if (new_tvb) {
                col_set_str(pinfo->cinfo, COL_INFO, "Last fragment of message, data dissected");
                col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", subtype_name);
                next_tvb=new_tvb;
                length = tvb_reported_length (next_tvb);
            }
        }
        /* dissect Data field of WAI packet */
        if (tree) {
            dissect_wai_data(next_tvb, wai_tree, subtype, length);
        }
    }

}
Esempio n. 15
0
static int
dissect_tlvs(tvbuff_t *tvb, proto_tree *njack_tree, guint32 offset)
{
	guint8      tlv_type;
	guint8      tlv_length;
	proto_item *tlv_item;
	proto_item *tlv_tree;

	for (;;) {
		tlv_type = tvb_get_guint8(tvb, offset);
		/* Special cases that don't have a length field */
		if (tlv_type == NJACK_CMD_ENDOFPACKET) {
			proto_tree_add_item(njack_tree, hf_njack_tlv_type,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			break;
		}
		if (tlv_type == NJACK_CMD_GETALLPARMAMS) {
			proto_tree_add_item(njack_tree, hf_njack_tlv_type,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			continue;
		}
		tlv_length = tvb_get_guint8(tvb, offset + 1);
		tlv_item = proto_tree_add_text(njack_tree, tvb,
			offset, tlv_length + 2,
			"T %02x, L %02x: %s",
			tlv_type,
			tlv_length,
			val_to_str_ext_const(tlv_type, &njack_cmd_vals_ext, "Unknown"));
		tlv_tree = proto_item_add_subtree(tlv_item,
			ett_njack_tlv_header);
		proto_tree_add_item(tlv_tree, hf_njack_tlv_type,
			tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;
		proto_tree_add_item(tlv_tree, hf_njack_tlv_length,
			tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;
		switch (tlv_type) {
		case NJACK_CMD_STARTOFPARAMS:
			break;
		case NJACK_CMD_COUNTERMODE:
			proto_tree_add_item(tlv_tree, hf_njack_tlv_countermode,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			break;
		case NJACK_CMD_QUEUEING:
			proto_tree_add_item(tlv_tree, hf_njack_tlv_scheduling,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			break;
		case NJACK_CMD_ADDTAGSCHEME:
			proto_tree_add_item(tlv_tree, hf_njack_tlv_addtagscheme,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			break;
		case NJACK_CMD_REMOVETAG:
			proto_tree_add_item(tlv_tree, hf_njack_tlv_portingressmode,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			break;
		case NJACK_CMD_MAXFRAMESIZE:
			proto_tree_add_item(tlv_tree, hf_njack_tlv_maxframesize,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			break;
		case NJACK_CMD_ENABLESNMPWRITE:
			proto_tree_add_item(tlv_tree, hf_njack_tlv_snmpwrite,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			break;
		case NJACK_CMD_POWERFORWARDING:
			proto_tree_add_item(tlv_tree, hf_njack_tlv_powerforwarding,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			break;
		case NJACK_CMD_DHCPCONTROL:
			proto_tree_add_item(tlv_tree, hf_njack_tlv_dhcpcontrol,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			break;
		case NJACK_CMD_MACADDRESS:
			proto_tree_add_item(tlv_tree, hf_njack_tlv_devicemac,
				tvb, offset, 6, ENC_NA);
			offset += 6;
			break;
		case NJACK_CMD_VERSION:
			/* XXX Don't misuse ip address printing here */
			proto_tree_add_item(tlv_tree, hf_njack_tlv_version,
				tvb, offset, 4, ENC_LITTLE_ENDIAN);
			offset += 4;
			break;
		case NJACK_CMD_IPADDRESS:
		case NJACK_CMD_NETWORK:
		case NJACK_CMD_MASK:
		case NJACK_CMD_IPGATEWAY:
			proto_tree_add_item(tlv_tree, hf_njack_tlv_typeip,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
			break;
		case NJACK_CMD_GROUP:
		case NJACK_CMD_LOCATION:
		case NJACK_CMD_PASSWORD:
		case NJACK_CMD_ROCOMMUNITY:
		case NJACK_CMD_RWCOMMUNITY:
		case 0x25: /* ? */
		case NJACK_CMD_PRODUCTNAME:
		case NJACK_CMD_SERIALNO:
			proto_tree_add_item(tlv_tree, hf_njack_tlv_typestring,
				tvb, offset, tlv_length, ENC_ASCII|ENC_NA);
			offset += tlv_length;
			break;
		case NJACK_CMD_PORT1:
		case NJACK_CMD_PORT2:
		case NJACK_CMD_PORT3:
		case NJACK_CMD_PORT4:
			if (tlv_length == 8) {
				dissect_portsettings(tvb, tlv_tree, offset);
			}
			offset += tlv_length;
			break;
		default:
			if (tlv_length != 0) {
				proto_tree_add_item(tlv_tree, hf_njack_tlv_data,
					tvb, offset, tlv_length, ENC_NA);
				offset += tlv_length;
			}
			break;
		}
	}
	return offset;
}
Esempio n. 16
0
/*
 * Get a string describing the type of a NetBIOS name.
 */
const char *
netbios_name_type_descr(int name_type)

{
	return val_to_str_ext_const(name_type, &nb_name_type_vals_ext, "Unknown");
}
Esempio n. 17
0
static void
dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item    *ti;
    proto_tree    *st;
    fragment_data *frag_msg       = NULL;
    gboolean       save_fragmented, complete;
    tvbuff_t*      new_tvb        = NULL;
    tvbuff_t*      next_tvb       = NULL;
    guint32        no_of_segments = 0;
    int            offset         = 0;

    save_fragmented = pinfo->fragmented;

    complete = FALSE;

    if (fragment_get(pinfo, pinfo->p2p_dir, fragment_table)) {
        /* not the first fragment */
        frag_msg = fragment_add_seq_next(tvb, 0, pinfo, pinfo->p2p_dir,
                                fragment_table, reassembled_table, tvb_length(tvb), TRUE);

        new_tvb = process_reassembled_data(tvb, 0, pinfo,
                        "Reassembled Obex packet", frag_msg, &btobex_frag_items, NULL, tree);

        pinfo->fragmented = TRUE;
    }
    else    {
        if (tvb_length(tvb) < tvb_get_ntohs(tvb, offset+1)) {
            /* first fragment in a sequence */
            no_of_segments = tvb_get_ntohs(tvb, offset+1)/tvb_length(tvb);
            if (tvb_get_ntohs(tvb, offset+1) > (no_of_segments * tvb_length(tvb)))
                no_of_segments++;

            frag_msg = fragment_add_seq_next(tvb, 0, pinfo, pinfo->p2p_dir,
                                fragment_table, reassembled_table, tvb_length(tvb), TRUE);

            fragment_set_tot_len(pinfo, pinfo->p2p_dir, fragment_table, no_of_segments-1);

            new_tvb = process_reassembled_data(tvb, 0, pinfo,
                        "Reassembled Obex packet", frag_msg, &btobex_frag_items, NULL, tree);

            pinfo->fragmented = TRUE;
            }
        else if (tvb_length(tvb) == tvb_get_ntohs(tvb, offset+1)) {
            /* non-fragmented */
            complete = TRUE;
            pinfo->fragmented = FALSE;
        }
    }

    if (new_tvb) { /* take it all */
        next_tvb = new_tvb;
        complete = TRUE;
    }
    else { /* make a new subset */
        next_tvb = tvb_new_subset_remaining(tvb, offset);
    }

    if (complete) {
        guint8 code, final_flag;

        /* fully dissectable packet ready */
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "OBEX");

        ti = proto_tree_add_item(tree, proto_btobex, next_tvb, 0, -1, ENC_NA);
        st = proto_item_add_subtree(ti, ett_btobex);

        /* op/response code */
        code = tvb_get_guint8(next_tvb, offset) & BTOBEX_CODE_VALS_MASK;
        final_flag = tvb_get_guint8(next_tvb, offset) & 0x80;

        switch (pinfo->p2p_dir)
        {
        case P2P_DIR_SENT:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Sent ");
            break;

        case P2P_DIR_RECV:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Rcvd ");
            break;

        case P2P_DIR_UNKNOWN:
            break;

        default:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
                pinfo->p2p_dir);
            break;
        }

        col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
                        val_to_str_ext_const(code, &code_vals_ext, "Unknown"));

        if ((code < BTOBEX_CODE_VALS_CONTINUE) || (code == BTOBEX_CODE_VALS_ABORT)) {
            proto_tree_add_item(st, hf_opcode, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            if (pinfo->p2p_dir == P2P_DIR_SENT || pinfo->p2p_dir == P2P_DIR_RECV) {
                last_opcode[pinfo->p2p_dir] = code;
            }
            }
        else    {
            proto_tree_add_item(st, hf_response_code, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            }
        proto_tree_add_item(st, hf_final_flag, next_tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;

        /* length */
        proto_tree_add_item(st, hf_length, next_tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;

        switch(code)
        {
        case BTOBEX_CODE_VALS_CONNECT:
            proto_tree_add_item(st, hf_version, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;

            proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;

            proto_tree_add_item(st, hf_max_pkt_len, next_tvb, offset, 2, ENC_BIG_ENDIAN);
            offset += 2;
            break;

        case BTOBEX_CODE_VALS_PUT:
        case BTOBEX_CODE_VALS_GET:
            col_append_fstr(pinfo->cinfo, COL_INFO, " %s",  (final_flag == 0x80) ? "final" : "continue");
            break;

        case BTOBEX_CODE_VALS_SET_PATH:
            proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(st, hf_set_path_flags_0, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(st, hf_set_path_flags_1, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;

            proto_tree_add_item(st, hf_constants, next_tvb, offset, 1, ENC_BIG_ENDIAN);
            offset++;
            break;

        case BTOBEX_CODE_VALS_DISCONNECT:
        case BTOBEX_CODE_VALS_ABORT:
            break;

        default:
            {
                guint8 response_opcode = last_opcode[(pinfo->p2p_dir + 1) & 0x01];

                if (response_opcode == BTOBEX_CODE_VALS_CONNECT) {
                    proto_tree_add_item(st, hf_version, next_tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset++;

                    proto_tree_add_item(st, hf_flags, next_tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset++;

                    proto_tree_add_item(st, hf_max_pkt_len, next_tvb, offset, 2, ENC_BIG_ENDIAN);
                    offset += 2;
                }
            }
            break;
        }

        dissect_headers(st, next_tvb, offset, pinfo);
    }
    else
    {
        /* packet fragment */
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s Obex fragment",
                     (pinfo->p2p_dir==P2P_DIR_SENT) ? "Sent" : "Rcvd");

        call_dissector(data_handle, next_tvb, pinfo, tree);
    }

    pinfo->fragmented = save_fragmented;
}
Esempio n. 18
0
static gint
dissect_hci_mon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    proto_tree       *hci_mon_item;
    proto_item       *hci_mon_tree;
    proto_item       *sub_item;
    gint              offset = 0;
    guint16           opcode;
    guint16           adapter_id;
    bluetooth_data_t *bluetooth_data;
    tvbuff_t         *next_tvb;
    guint32          *adapter_disconnect_in_frame;
    wmem_tree_t      *subtree;
    wmem_tree_key_t  key[4];
    guint32          k_interface_id;
    guint32          k_adapter_id;
    guint32          k_frame_number;

    bluetooth_data = (bluetooth_data_t *) data;

    DISSECTOR_ASSERT(bluetooth_data->previous_protocol_data_type == BT_PD_BTMON);
    adapter_id = bluetooth_data->previous_protocol_data.btmon->adapter_id;
    opcode = bluetooth_data->previous_protocol_data.btmon->opcode;

    if (opcode == 0x00 || opcode == 0x01)
        pinfo->p2p_dir = P2P_DIR_RECV;
    else if (opcode % 2)
        pinfo->p2p_dir = P2P_DIR_RECV;
    else
        pinfo->p2p_dir = P2P_DIR_SENT;

    hci_mon_item = proto_tree_add_item(tree, proto_hci_mon, tvb, offset, tvb_captured_length(tvb), ENC_NA);
    hci_mon_tree = proto_item_add_subtree(hci_mon_item, ett_hci_mon);

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "HCI_MON");

    if (opcode == 0x00 || opcode == 0x01)
        col_set_str(pinfo->cinfo, COL_INFO, "Info ");
    else switch (pinfo->p2p_dir) {

    case P2P_DIR_SENT:
        col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
        break;

    case P2P_DIR_RECV:
        col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
        break;

    default:
        col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection ");
        break;
    }

    sub_item = proto_tree_add_uint(hci_mon_tree, hf_adapter_id,  tvb, offset, 0, adapter_id);
    PROTO_ITEM_SET_GENERATED(sub_item);

    sub_item = proto_tree_add_uint(hci_mon_tree, hf_opcode, tvb, offset, 0, opcode);
    PROTO_ITEM_SET_GENERATED(sub_item);

    col_append_fstr(pinfo->cinfo, COL_INFO, "Adapter Id: %u, Opcode: %s",
            adapter_id, val_to_str_ext_const(opcode, &hci_mon_opcode_vals_ext, "Unknown"));

    bluetooth_data->adapter_id = adapter_id;

    k_interface_id = bluetooth_data->interface_id;
    k_adapter_id   = adapter_id;
    k_frame_number = pinfo->num;

    key[0].length = 1;
    key[0].key    = &k_interface_id;
    key[1].length = 1;
    key[1].key    = &k_adapter_id;

    if (!pinfo->fd->flags.visited && opcode == 0x01) { /* Delete Index */
        guint32           *disconnect_in_frame;

        key[2].length = 1;
        key[2].key    = &k_frame_number;
        key[3].length = 0;
        key[3].key    = NULL;

        disconnect_in_frame = wmem_new(wmem_file_scope(), guint32);

        if (disconnect_in_frame) {
            *disconnect_in_frame = pinfo->num;

            wmem_tree_insert32_array(adapter_to_disconnect_in_frame, key, disconnect_in_frame);
        }
    }

    key[2].length = 0;
    key[2].key    = NULL;

    subtree = (wmem_tree_t *) wmem_tree_lookup32_array(adapter_to_disconnect_in_frame, key);
    adapter_disconnect_in_frame = (subtree) ? (guint32 *) wmem_tree_lookup32_le(subtree, k_frame_number) : NULL;
    if (adapter_disconnect_in_frame) {
        bluetooth_data->adapter_disconnect_in_frame = adapter_disconnect_in_frame;
    } else {
        bluetooth_data->adapter_disconnect_in_frame = &max_disconnect_in_frame;
    }

    pinfo->ptype = PT_BLUETOOTH;

    next_tvb = tvb_new_subset_remaining(tvb, offset);

    switch(opcode) {
    case 0x00: /* New Index */
        proto_tree_add_item(hci_mon_tree, hf_bus, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        proto_tree_add_item(hci_mon_tree, hf_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        offset = dissect_bd_addr(hf_bd_addr, pinfo, hci_mon_tree, tvb, offset, TRUE, bluetooth_data->interface_id, bluetooth_data->adapter_id, NULL);

        proto_tree_add_item(hci_mon_tree, hf_name, tvb, offset, 8, ENC_NA | ENC_ASCII);
        offset += 8;

        break;
    case 0x01: /* Delete Index */
        /* No parameters */

        break;
    case 0x02: /* HCI Command Packet */
        call_dissector_with_data(bthci_cmd_handle, next_tvb, pinfo, tree, bluetooth_data);
        offset = tvb_reported_length(tvb);

        break;
   case 0x03:  /* HCI Event Packet */
        call_dissector_with_data(bthci_evt_handle, next_tvb, pinfo, tree, bluetooth_data);
        offset = tvb_reported_length(tvb);

        break;
   case 0x04:  /* ACL Tx Packet */
   case 0x05:  /* ACL Rx Packet */
        call_dissector_with_data(bthci_acl_handle, next_tvb, pinfo, tree, bluetooth_data);
        offset = tvb_reported_length(tvb);

        break;
   case 0x06:  /* SCO Tx Packet */
   case 0x07:  /* SCO Rx Packet */
        call_dissector_with_data(bthci_sco_handle, next_tvb, pinfo, tree, bluetooth_data);
        offset = tvb_reported_length(tvb);

        break;
    }

    if (tvb_reported_length_remaining(tvb, offset) > 0) {
        proto_tree_add_expert(hci_mon_tree, pinfo, &ei_unknown_data, tvb, offset, tvb_reported_length_remaining(tvb, offset));
        offset = tvb_reported_length(tvb);
    }

   /* NOTE: Oops... HCI_MON have special packet with length 0, but there is a pseudo-header with certain infos,
            mark it as dissected */
    if (opcode == 0x01)
        return 1;

    return offset;
}
Esempio n. 19
0
static gint
dissect_usb_dfu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    proto_item       *main_item;
    proto_tree       *main_tree;
    proto_item       *command_item;
    proto_item       *sub_item;
    proto_tree       *command_tree;
    gint              offset = 0;
    gint              p2p_dir_save;
    guint8            command;
    gint16            command_response = -1;
    command_data_t   *command_data = NULL;
    wmem_tree_t      *wmem_tree;
    wmem_tree_key_t   key[5];
    guint32           bus_id;
    guint32           device_address;
    guint32           k_bus_id;
    guint32           k_device_address;
    guint32           k_frame_number;
    gint32            block_number = -1;
    usb_conv_info_t  *usb_conv_info = (usb_conv_info_t *)data;

    if (!usb_conv_info) return offset;

    bus_id         = usb_conv_info->bus_id;
    device_address = usb_conv_info->device_address;

    k_bus_id          = bus_id;
    k_device_address  = device_address;
    k_frame_number    = pinfo->fd->num;

    key[0].length = 1;
    key[0].key = &k_bus_id;
    key[1].length = 1;
    key[1].key = &k_device_address;

    main_item = proto_tree_add_item(tree, proto_usb_dfu, tvb, offset, -1, ENC_NA);
    main_tree = proto_item_add_subtree(main_item, ett_usb_dfu);

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "USB DFU");

    p2p_dir_save = pinfo->p2p_dir;
    pinfo->p2p_dir = (usb_conv_info->is_request) ? P2P_DIR_SENT : P2P_DIR_RECV;

    switch (pinfo->p2p_dir) {

    case P2P_DIR_SENT:
        col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
        break;

    case P2P_DIR_RECV:
        col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
        break;

    default:
        col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction ");
        break;
    }

    if (usb_conv_info->is_setup) {
        guint16  interface;

        command_item = proto_tree_add_item(main_tree, hf_setup_command, tvb, offset, 1, ENC_NA);
        command = tvb_get_guint8(tvb, offset);

        if (!((usb_conv_info->setup_requesttype == 0x21 && (command == 0x00 || command == 0x01 || command == 0x04 || command == 0x06)) ||
            (usb_conv_info->setup_requesttype == 0xa1 && (command == 0x02 || command == 0x03 || command == 0x05))))
            expert_add_info(pinfo, command_item, &ei_invalid_command_for_request_type);
        offset += 1;

        col_append_fstr(pinfo->cinfo, COL_INFO, "Command: %s",
                val_to_str_ext_const(command, &command_vals_ext, "Unknown"));

        if (command == 0x00) { /* Detach */
            proto_tree_add_item(main_tree, hf_setup_timeout, tvb, offset, 2, ENC_LITTLE_ENDIAN);
            col_append_fstr(pinfo->cinfo, COL_INFO, " Timeout=%u", tvb_get_letohs(tvb, offset));
        } else if (command == 0x01 || command == 0x02) { /* Download || Upload */
            proto_tree_add_item(main_tree, hf_setup_block_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
            col_append_fstr(pinfo->cinfo, COL_INFO, " Block Number=%u", tvb_get_letohs(tvb, offset));
            block_number = tvb_get_letohs(tvb, offset);
        } else {
            proto_tree_add_item(main_tree, hf_setup_unused, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        }
        offset += 2;

        proto_tree_add_item(main_tree, hf_setup_interface, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        interface = tvb_get_letohs(tvb, offset);
        offset += 2;

        proto_tree_add_item(main_tree, hf_setup_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;

        if (command == 0x01) { /* Download */
            proto_tree_add_item(main_tree, hf_data, tvb, offset, -1, ENC_NA);
            offset = tvb_length(tvb);
        }

        if (tvb_length_remaining(tvb, offset) > 0) {
            proto_tree_add_expert(main_tree, pinfo, &ei_unexpected_data, tvb, offset, tvb_length_remaining(tvb, offset));
            offset = tvb_length(tvb);
        }

        /* Save request info (command_data) */
        if (!pinfo->fd->flags.visited && command != 21) {
            key[2].length = 1;
            key[2].key = &k_frame_number;
            key[3].length = 0;
            key[3].key = NULL;

            command_data = wmem_new(wmem_file_scope(), command_data_t);
            command_data->bus_id = bus_id;
            command_data->device_address = device_address;

            command_data->command = command;
            command_data->interface = interface;
            command_data->command_frame_number = pinfo->fd->num;
            command_data->block_number = block_number;

            wmem_tree_insert32_array(command_info, key, command_data);
        }

        pinfo->p2p_dir = p2p_dir_save;

        return offset;
    }

    /* Get request info (command_data) */
    key[2].length = 0;
    key[2].key = NULL;

    wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(command_info, key);
    if (wmem_tree) {
        command_data = (command_data_t *) wmem_tree_lookup32_le(wmem_tree, pinfo->fd->num);
        if (command_data) {
            command_response = command_data->command;
            block_number = command_data->block_number;
        }
    }

    if (!command_data) {
        col_append_str(pinfo->cinfo, COL_INFO, "Response: Unknown");

        proto_tree_add_expert(main_tree, pinfo, &ei_unknown_data, tvb, offset, tvb_length_remaining(tvb, offset));

        pinfo->p2p_dir = p2p_dir_save;

        return tvb_length(tvb);
    }

    col_append_fstr(pinfo->cinfo, COL_INFO, "Response: %s",
            val_to_str_ext_const(command_response, &command_vals_ext, "Unknown"));

    command_item = proto_tree_add_uint(main_tree, hf_response, tvb, offset, 0, command_response);
    command_tree = proto_item_add_subtree(command_item, ett_command);
    PROTO_ITEM_SET_GENERATED(command_item);

    if (command_data) {
        command_item = proto_tree_add_uint(main_tree, hf_setup_interface, tvb, offset, 0, command_data->interface);
        PROTO_ITEM_SET_GENERATED(command_item);

        command_item = proto_tree_add_uint(main_tree, hf_command_in_frame, tvb, offset, 0, command_data->command_frame_number);
        PROTO_ITEM_SET_GENERATED(command_item);
    }

    switch (command_response) {
    case 0x02: /* Upload */
        if (block_number != -1) {
            sub_item = proto_tree_add_uint(main_tree, hf_setup_block_number, tvb, offset, 0, block_number);
            PROTO_ITEM_SET_GENERATED(sub_item);
            col_append_fstr(pinfo->cinfo, COL_INFO, " Block Number=%u", block_number);
        }

        proto_tree_add_item(main_tree, hf_data, tvb, offset, -1, ENC_NA);
        offset = tvb_length(tvb);

        break;
    case 0x03: /* Get Status */
        col_append_fstr(pinfo->cinfo, COL_INFO, " = Status: %s, PollTimeout: %u ms, State: %s",
                val_to_str_ext_const(tvb_get_guint8(tvb, offset), &status_vals_ext, "Unknown"),
                tvb_get_letoh24(tvb, offset + 1),
                val_to_str_ext_const(tvb_get_guint8(tvb, offset + 4), &state_vals_ext, "Unknown"));

        proto_tree_add_item(main_tree, hf_status, tvb, offset, 1, ENC_NA);
        offset += 1;

        proto_tree_add_item(main_tree, hf_poll_timeout, tvb, offset, 3, ENC_LITTLE_ENDIAN);
        offset += 3;

        proto_tree_add_item(main_tree, hf_state, tvb, offset, 1, ENC_NA);
        offset += 1;

        proto_tree_add_item(main_tree, hf_iString, tvb, offset, 1, ENC_NA);
        offset += 1;

        break;
    case 0x05: /* Get State */
        proto_tree_add_item(main_tree, hf_state, tvb, offset, 1, ENC_NA);

        col_append_fstr(pinfo->cinfo, COL_INFO, " = %s",
                val_to_str_ext_const(tvb_get_guint8(tvb, offset), &state_vals_ext, "Unknown"));

        offset += 1;

        break;
    case 0x00: /* Detach */
    case 0x01: /* Download */
    case 0x04: /* Clear Status */
    case 0x06: /* Abort */
    default:
        proto_tree_add_expert(command_tree, pinfo, &ei_unexpected_response, tvb, offset, 0);
        if (tvb_length_remaining(tvb, offset) > 0) {
            proto_tree_add_expert(main_tree, pinfo, &ei_unknown_data, tvb, offset, -1);
            offset = tvb_length(tvb);
        }
    }

    pinfo->p2p_dir = p2p_dir_save;

    return offset;
}
Esempio n. 20
0
static void
dissect_pn532(tvbuff_t * tvb, packet_info * pinfo, proto_tree *tree)
{
    proto_item *item;
    proto_tree *pn532_tree;
    guint8      cmd;
    tvbuff_t   *next_tvb;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "PN532");
    col_set_str(pinfo->cinfo, COL_INFO, "PN532 Packet");

    /* Start with a top-level item to add everything else to */
    item = proto_tree_add_item(tree, proto_pn532, tvb, 0, -1, ENC_NA);
    pn532_tree = proto_item_add_subtree(item, ett_pn532);

    proto_tree_add_item(pn532_tree, hf_pn532_direction, tvb, 0, 1, ENC_NA);
    proto_tree_add_item(pn532_tree, hf_pn532_command, tvb, 1, 1, ENC_NA);

    /* Direction byte */
    cmd = tvb_get_guint8(tvb, 1);

    col_set_str(pinfo->cinfo, COL_INFO, val_to_str_ext_const(cmd, &pn532_commands_ext, "Unknown"));

    switch (cmd) {

    /* Device Diagnosis Request */
    case DIAGNOSE_REQ:
        break;

    /* Device Diagnosis Response */
    case DIAGNOSE_RSP:
        break;

    /* Device Firmware Version Request */
    case GET_FIRMWARE_VERSION_REQ:
        break;

    /* Device Firmware Version Response */
    case GET_FIRMWARE_VERSION_RSP:
        proto_tree_add_item(pn532_tree, hf_pn532_ic_version,  tvb, 2, 1, ENC_NA);
        proto_tree_add_item(pn532_tree, hf_pn532_fw_version,  tvb, 3, 1, ENC_NA);
        proto_tree_add_item(pn532_tree, hf_pn532_fw_revision, tvb, 4, 1, ENC_NA);
        proto_tree_add_item(pn532_tree, hf_pn532_fw_support,  tvb, 5, 1, ENC_NA);
        break;

    case GET_GENERAL_STATUS:
        break;

    case READ_REGISTER_REQ:
        break;

    case READ_REGISTER_RSP:
        break;

    case WRITE_REGISTER_REQ:
        break;

    case WRITE_REGISTER_RSP:
        break;

    case READ_GPIO:
        break;

    case WRITE_GPIO:
        break;

    case SET_SERIAL_BAUD_RATE:
        break;

    case SET_PARAMETERS_REQ:
        break;

    case SET_PARAMETERS_RSP:
        break;

    /* Secure Application/Security Access Module Configuration Request */
    case SAM_CONFIGURATION_REQ:
        /* Mode */
        proto_tree_add_item(pn532_tree, hf_pn532_sam_mode, tvb, 2, 1, ENC_BIG_ENDIAN);
        
        /* Timeout */
        
        /* IRQ */
        break;
        
    case SAM_CONFIGURATION_RSP:
        break;
        
    case POWER_DOWN:
        break;

    case RF_CONFIGURATION_REQ:
        break;

    case RF_CONFIGURATION_RSP:
        break;

    case RF_REGULATION_TEST:
        break;

    case IN_JUMP_FOR_DEP:
        break;

    case IN_JUMP_FOR_PSL:
        break;

        /* List targets (tags) in the field */
    case IN_LIST_PASSIVE_TARGET_REQ:

        /* Maximum number of supported tags */
        proto_tree_add_item(pn532_tree, hf_pn532_MaxTg, tvb, 2, 1, ENC_BIG_ENDIAN);

        /* Modulation and Baud Rate Type */
        proto_tree_add_item(pn532_tree, hf_pn532_BrTy, tvb, 3, 1, ENC_BIG_ENDIAN);

        /* Attempt to dissect FeliCa payloads */
        if ((tvb_get_guint8(tvb, 3) == FELICA_212) || (tvb_get_guint8(tvb, 3) == FELICA_424)) {

            next_tvb = tvb_new_subset_remaining(tvb, 4);
            call_dissector(sub_handles[SUB_FELICA], next_tvb, pinfo, tree);

        }

        break;

    case IN_LIST_PASSIVE_TARGET_RSP:
        proto_tree_add_item(pn532_tree, hf_pn532_NbTg, tvb, 2, 1, ENC_BIG_ENDIAN);

        /* Probably an ISO/IEC 14443-B tag */
        if (tvb_reported_length(tvb) == 20) {

            /* Add the PUPI */
            proto_tree_add_item(pn532_tree, hf_pn532_14443b_pupi, tvb, 5, 4, ENC_BIG_ENDIAN);

            /* Add the Application Data */
            proto_tree_add_item(pn532_tree, hf_pn532_14443b_app_data, tvb, 9, 4, ENC_BIG_ENDIAN);

            /* Add the Protocol Info */
            proto_tree_add_item(pn532_tree, hf_pn532_14443b_proto_info, tvb, 13, 3, ENC_BIG_ENDIAN);
        }

        /* Probably one of:
         * a MiFare DESFire card (23 bytes),
         * an MF UltraLight tag (17 bytes)
         * an MF Classic card with a 4 byte UID (14 bytes) */

        if ((tvb_reported_length(tvb) == 23) || (tvb_reported_length(tvb) == 17) || (tvb_reported_length(tvb) == 14)) {

            /* Add the ATQA/SENS_RES */
            proto_tree_add_item(pn532_tree, hf_pn532_14443a_atqa, tvb, 4, 2, ENC_BIG_ENDIAN);

            /* Add the SAK/SEL_RES value */
            proto_tree_add_item(pn532_tree, hf_pn532_14443a_sak, tvb, 6, 1, ENC_BIG_ENDIAN);
            
            /* Add the UID length */
            proto_tree_add_item(pn532_tree, hf_pn532_14443a_uid_length, tvb, 7, 1, ENC_BIG_ENDIAN);
            
            /* Add the UID */
            if (tvb_reported_length(tvb) != 14) {
                proto_tree_add_item(pn532_tree, hf_pn532_14443a_uid, tvb, 8, 7, ENC_BIG_ENDIAN);

                /* Probably MiFare DESFire, or some other 14443-A card with an ATS value/7 byte UID */
                if (tvb_reported_length(tvb) == 23) {

                    /* Add the ATS value */
                    proto_tree_add_item(pn532_tree, hf_pn532_14443a_ats, tvb, 16, 5, ENC_BIG_ENDIAN);
                }
            }
            /* Probably MiFare Classic with a 4 byte UID */
            else {
                proto_tree_add_item(pn532_tree, hf_pn532_14443a_uid, tvb, 8, 4, ENC_BIG_ENDIAN);
            }

        }

        /* Probably an EMV/ISO 14443-A (VISA - 30 bytes payload/MC - 33 bytes payload)
                 card with a 4 byte UID */

        if (tvb_reported_length(tvb) == 30 || tvb_reported_length(tvb) == 33) {

        /* Check to see if there's a plausible ATQA value (0x0004 for my MC/VISA cards) */

            if ((tvb_get_guint8(tvb, 4) == 0x00 && tvb_get_guint8(tvb, 5) == 0x04)) {
            
                /* Add the ATQA/SENS_RES */
                proto_tree_add_item(pn532_tree, hf_pn532_14443a_atqa, tvb, 4, 2, ENC_BIG_ENDIAN);
                
                /* Add the SAK/SEL_RES value */
                proto_tree_add_item(pn532_tree, hf_pn532_14443a_sak, tvb, 6, 1, ENC_BIG_ENDIAN);
                                        
                /* Add the UID length */
                proto_tree_add_item(pn532_tree, hf_pn532_14443a_uid_length, tvb, 7, 1, ENC_BIG_ENDIAN);
                
                /* Add the UID */
                proto_tree_add_item(pn532_tree, hf_pn532_14443a_uid, tvb, 8, 4, ENC_BIG_ENDIAN);
                
                /* ATS length is probably prepended to the ATS data... */
                
                /* Pass the ATS value to the Data dissector, since it's too long to handle normally
                    Don't care about the "status word" at the end, right now */
                next_tvb = tvb_new_subset_remaining(tvb, 13);
                call_dissector(sub_handles[SUB_DATA], next_tvb, pinfo, tree);
            }
        }

        /* See if we've got a FeliCa payload with a System Code */
        if (tvb_reported_length(tvb) == 26) {

            /* For FeliCa, this is at position 4. This doesn't exist for other payload types. */
            proto_tree_add_item(pn532_tree, hf_pn532_payload_length, tvb, 4, 1, ENC_BIG_ENDIAN);

            /* Use the length value (20?) at position 4, and skip the Status Word (9000) at the end */
            next_tvb = tvb_new_subset(tvb, 5, tvb_get_guint8(tvb, 4) - 1, 19);
            call_dissector(sub_handles[SUB_FELICA], next_tvb, pinfo, tree);
        }

        break;

    case IN_ATR:
        break;

    case IN_PSL:
        break;

    case IN_DATA_EXCHANGE_REQ:

        if (sub_selected == SUB_MIFARE) {
            /* Logical target number */
            proto_tree_add_item(pn532_tree, hf_pn532_Tg, tvb, 2, 1, ENC_BIG_ENDIAN);

            /* Seems to work for payloads from LibNFC's "nfc-mfultralight" command */
            next_tvb = tvb_new_subset_remaining(tvb, 3);
            call_dissector(sub_handles[SUB_MIFARE], next_tvb, pinfo, tree);
        } 
        else if (sub_selected == SUB_ISO7816) {
            /* Logical target number */
            proto_tree_add_item(pn532_tree, hf_pn532_Tg, tvb, 2, 1, ENC_BIG_ENDIAN);

            /* Seems to work for EMV payloads sent using TAMA shell scripts */
            next_tvb = tvb_new_subset_remaining(tvb, 3);

            /* Need to do this, for the ISO7816 dissector to work, it seems */
            pinfo->p2p_dir = P2P_DIR_SENT;
            call_dissector(sub_handles[SUB_ISO7816], next_tvb, pinfo, tree);
        }
        else {
        }

        break;

    case IN_DATA_EXCHANGE_RSP:

        if (sub_selected == SUB_ISO7816) {

            /* Seems to work for identifying responses to Select File requests...
               Might need to investigate "Status Words", later */
            next_tvb = tvb_new_subset_remaining(tvb, 2);

            /* Need to do this, for the ISO7816 dissector to work, it seems */
            pinfo->p2p_dir = P2P_DIR_RECV;
            call_dissector(sub_handles[SUB_ISO7816], next_tvb, pinfo, tree);
        }
        else {
        }
            
        break;

    case IN_COMMUNICATE_THRU_REQ:

        if (sub_selected == SUB_FELICA) {

            /* Alleged payload length for FeliCa */
            proto_tree_add_item(pn532_tree, hf_pn532_payload_length, tvb, 2, 1, ENC_BIG_ENDIAN);

            /* Attempt to dissect FeliCa payloads */
            next_tvb = tvb_new_subset_remaining(tvb, 3);
            call_dissector(sub_handles[SUB_FELICA], next_tvb, pinfo, tree);
        }

        /* MiFare transmissions may identify as spurious FeliCa packets, in some cases */
        else {
        }
      
        break;

    case IN_COMMUNICATE_THRU_RSP:
        if (sub_selected == SUB_FELICA) {

            /* Alleged payload length for FeliCa */
            proto_tree_add_item(pn532_tree, hf_pn532_payload_length, tvb, 3, 1, ENC_BIG_ENDIAN);

            /* Attempt to dissect FeliCa payloads */
            next_tvb = tvb_new_subset_remaining(tvb, 4);
            call_dissector(sub_handles[SUB_FELICA], next_tvb, pinfo, tree);
        }

        /* MiFare transmissions may identify as spurious FeliCa packets, in some cases */
        else {
        }

        break;

    /* Deselect a token */
    case IN_DESELECT_REQ:
        /* Logical target number */
        proto_tree_add_item(pn532_tree, hf_pn532_Tg, tvb, 2, 1, ENC_BIG_ENDIAN);
        break;

    case IN_DESELECT_RSP:
        proto_tree_add_item(pn532_tree, hf_pn532_error, tvb, 2, 1, ENC_BIG_ENDIAN);
        break;

    /* Release a token */
    case IN_RELEASE_REQ:
        /* Logical target number */
        proto_tree_add_item(pn532_tree, hf_pn532_Tg, tvb, 2, 1, ENC_BIG_ENDIAN);
        break;

    case IN_RELEASE_RSP:
        proto_tree_add_item(pn532_tree, hf_pn532_error, tvb, 2, 1, ENC_BIG_ENDIAN);
        break;

    /* Select a token */
    case IN_SELECT_REQ:
        /* Logical target number */
        proto_tree_add_item(pn532_tree, hf_pn532_Tg, tvb, 2, 1, ENC_BIG_ENDIAN);
        break;

    case IN_SELECT_RSP:
        proto_tree_add_item(pn532_tree, hf_pn532_error, tvb, 2, 1, ENC_BIG_ENDIAN);
        break;

    case IN_AUTO_POLL_REQ:
        break;

    case IN_AUTO_POLL_RSP:
        break;

    case TG_INIT_AS_TARGET:
        break;

    case TG_SET_GENERAL_BYTES:
        break;

    case TG_GET_DATA:
        break;

    case TG_SET_DATA:
        break;

    case TG_SET_METADATA:
        break;

    case TG_GET_INITIATOR_CMD:
        break;

    case TG_RESP_TO_INITIATOR:
        break;

    case TG_GET_TARGET_STATUS:
        break;

    default:
        break;
    }
}
tap_packet_status BluetoothDevicesDialog::tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data)
{
    bluetooth_devices_tapinfo_t  *tapinfo    = static_cast<bluetooth_devices_tapinfo_t *>(tapinfo_ptr);
    BluetoothDevicesDialog       *dialog     = static_cast<BluetoothDevicesDialog *>(tapinfo->ui);
    bluetooth_device_tap_t       *tap_device = static_cast<bluetooth_device_tap_t *>(const_cast<void *>(data));
    QString                       bd_addr;
    QString                       bd_addr_oui;
    const gchar                  *manuf;
    QTreeWidgetItem              *item = NULL;

    if (dialog->file_closed_)
        return TAP_PACKET_DONT_REDRAW;

    if (pinfo->rec->rec_type != REC_TYPE_PACKET)
        return TAP_PACKET_DONT_REDRAW;

    if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
        gchar       *interface;
        const char  *interface_name;

        interface_name = epan_get_interface_name(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id);
        interface = wmem_strdup_printf(wmem_packet_scope(), "%u: %s", pinfo->rec->rec_header.packet_header.interface_id, interface_name);

        if (dialog->ui->interfaceComboBox->findText(interface) == -1)
            dialog->ui->interfaceComboBox->addItem(interface);

        if (interface && dialog->ui->interfaceComboBox->currentIndex() > 0) {
            if (dialog->ui->interfaceComboBox->currentText() != interface)
            return TAP_PACKET_REDRAW;
        }
    }

    if (tap_device->has_bd_addr) {
        bd_addr.sprintf("%02x:%02x:%02x:%02x:%02x:%02x", tap_device->bd_addr[0], tap_device->bd_addr[1], tap_device->bd_addr[2], tap_device->bd_addr[3], tap_device->bd_addr[4], tap_device->bd_addr[5]);

        manuf = get_ether_name(tap_device->bd_addr);
        if (manuf) {
            int pos;

            bd_addr_oui = QString(manuf);
            pos = bd_addr_oui.indexOf('_');
            if (pos < 0) {
                manuf = NULL;
            } else {
                bd_addr_oui.remove(pos, bd_addr_oui.size());
            }
        }

        if (!manuf)
            bd_addr_oui = "";
    }

    if (dialog->ui->showInformationStepsCheckBox->checkState() != Qt::Checked) {
        QTreeWidgetItemIterator i_item(dialog->ui->tableTreeWidget);

        while (*i_item) {
            QTreeWidgetItem *current_item = static_cast<QTreeWidgetItem*>(*i_item);
            bluetooth_item_data_t *item_data = VariantPointer<bluetooth_item_data_t>::asPtr(current_item->data(0, Qt::UserRole));

            if ((tap_device->has_bd_addr && current_item->text(column_number_bd_addr) == bd_addr) ||
                    (tap_device->is_local &&
                    item_data->interface_id == tap_device->interface_id &&
                    item_data->adapter_id == tap_device->adapter_id &&
                    !current_item->text(column_number_is_local_adapter).isEmpty())) {
                item = current_item;
                break;
            }
            ++i_item;
        }
    }

    if (!item) {
        item = new QTreeWidgetItem(dialog->ui->tableTreeWidget);
        item->setText(column_number_bd_addr, bd_addr);
        item->setText(column_number_bd_addr_oui, bd_addr_oui);
        if (tap_device->is_local) {
            item->setText(column_number_is_local_adapter,  tr("true"));
        }

        bluetooth_item_data_t *item_data = wmem_new(wmem_file_scope(), bluetooth_item_data_t);
        item_data->interface_id = tap_device->interface_id;
        item_data->adapter_id = tap_device->adapter_id;
        item_data->frame_number = pinfo->num;
        item->setData(0, Qt::UserRole, VariantPointer<bluetooth_item_data_t>::asQVariant(item_data));
    }

    if (tap_device->type == BLUETOOTH_DEVICE_BD_ADDR) {
        item->setText(column_number_bd_addr, bd_addr);
        item->setText(column_number_bd_addr_oui, bd_addr_oui);
    }

    if (tap_device->type == BLUETOOTH_DEVICE_NAME) {
        item->setText(column_number_name,  tap_device->data.name);
    }

    if (tap_device->type == BLUETOOTH_DEVICE_LOCAL_ADAPTER)
        item->setText(column_number_is_local_adapter,  tr("true"));

    if (tap_device->type == BLUETOOTH_DEVICE_LOCAL_VERSION) {
        item->setText(column_number_hci_version,    val_to_str_const(tap_device->data.local_version.hci_version, bthci_evt_hci_version, "Unknown 0x%02x"));
        item->setText(column_number_hci_revision,   QString("").sprintf("%u", tap_device->data.local_version.hci_revision));
        item->setText(column_number_lmp_version,    val_to_str_const(tap_device->data.local_version.lmp_version, bthci_evt_lmp_version, "Unknown 0x%02x"));
        item->setText(column_number_lmp_subversion, QString("").sprintf("%u", tap_device->data.local_version.lmp_subversion));
        item->setText(column_number_manufacturer,   val_to_str_ext_const(tap_device->data.local_version.manufacturer, &bluetooth_company_id_vals_ext, "Unknown 0x%04x"));
    }
    if (tap_device->type == BLUETOOTH_DEVICE_REMOTE_VERSION) {
        item->setText(column_number_lmp_version,    val_to_str_const(tap_device->data.remote_version.lmp_version, bthci_evt_lmp_version, "Unknown 0x%02x"));
        item->setText(column_number_lmp_subversion, QString("").sprintf("%u", tap_device->data.remote_version.lmp_subversion));
        item->setText(column_number_manufacturer,   val_to_str_ext_const(tap_device->data.remote_version.manufacturer, &bluetooth_company_id_vals_ext, "Unknown 0x%04x"));
    }

    for (int i = 0; i < dialog->ui->tableTreeWidget->columnCount(); i++) {
        dialog->ui->tableTreeWidget->resizeColumnToContents(i);
    }

    dialog->ui->hintLabel->setText(QString(tr("%1 items; Right click for more option; Double click for device details")).arg(dialog->ui->tableTreeWidget->topLevelItemCount()));

    return TAP_PACKET_REDRAW;
}
Esempio n. 22
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_reported_length(tvb) >= 36)
    {
        gint iSizeMQCFH = 36;
        guint32 iCommand = tvb_get_guint32(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(tvb, offset     , bLittleEndian);
            uCmd = tvb_get_guint32(tvb, offset + 12, bLittleEndian);
            uCC  = tvb_get_guint32(tvb, offset + 24, bLittleEndian);
            uRC  = tvb_get_guint32(tvb, offset + 28, bLittleEndian);
            uCnt = tvb_get_guint32(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_ext_const(uCmd, GET_VALS_EXTP(mqcmd), "Unknown"),
                    uCnt,
                    uCC, val_to_str_const(uCC, GET_VALSV(mqcc), "Unknown"),
                    uRC, val_to_str_ext_const(uRC, GET_VALS_EXTP(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_ext_const(uCmd, GET_VALS_EXTP(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_ext_const(iCommand, GET_VALS_EXTP(mqcmd), "Unknown (0x%02x)"));
            mqroot_tree = proto_item_add_subtree(ti, ett_mqpcf);

            mq_tree = proto_tree_add_subtree(mqroot_tree, tvb, offset, iSizeMQCFH, ett_mqpcf_cfh, NULL, sTmp);

            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);
        }
    }
}
Esempio n. 23
0
/* Dissect OSC message */
static int
dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len)
{
    proto_tree  *message_tree;
    proto_tree  *header_tree;
    gint         slen;
    gint         rem;
    gint         end = offset + len;
    const gchar *path;
    gint         path_len;
    gint         path_offset;
    const gchar *format;
    gint         format_offset;
    gint         format_len;
    const gchar *ptr;

    /* peek/read path */
    path_offset = offset;
    path = tvb_get_const_stringz(tvb, path_offset, &path_len);
    if( (rem = path_len%4) ) path_len += 4-rem;

    if(!is_valid_path(path))
        return -1;

    /* peek/read fmt */
    format_offset = path_offset + path_len;
    format = tvb_get_const_stringz(tvb, format_offset, &format_len);
    if( (rem = format_len%4) ) format_len += 4-rem;

    if(!is_valid_format(format))
        return -1;

    /* create message */
    ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format);
    message_tree = proto_item_add_subtree(ti, ett_osc_message);

    /* append header */
    ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA);
    header_tree = proto_item_add_subtree(ti, ett_osc_message_header);

    /* append path */
    proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA);

    /* append format */
    proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA);

    offset += path_len + format_len;

    /* ::parse argument:: */
    ptr = format + 1; /* skip ',' */
    while( (*ptr != '\0') && (offset < end) )
    {
        switch(*ptr)
        {
            case OSC_INT32:
                proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            case OSC_FLOAT:
                proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            case OSC_STRING:
                slen = tvb_strsize(tvb, offset);
                if( (rem = slen%4) ) slen += 4-rem;
                proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA);
                offset += slen;
                break;
            case OSC_BLOB:
            {
                proto_item *bi;
                proto_tree *blob_tree;

                gint32 blen = tvb_get_ntohl(tvb, offset);
                slen = blen;
                if( (rem = slen%4) ) slen += 4-rem;

                bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen);
                blob_tree = proto_item_add_subtree(bi, ett_osc_blob);

                proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen);
                offset += 4;

                /* check for zero length blob */
                if(blen == 0)
                    break;

                proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA);
                offset += slen;
                break;
            }

            case OSC_TRUE:
                proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_FALSE:
                proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_NIL:
                proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_BANG:
                proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA);
                break;

            case OSC_INT64:
                proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
                break;
            case OSC_DOUBLE:
                proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
                break;
            case OSC_TIMETAG:
            {
                guint32  sec  = tvb_get_ntohl(tvb, offset);
                guint32  frac = tvb_get_ntohl(tvb, offset+4);
                nstime_t ns;
                if( (sec == 0) && (frac == 1) )
                    proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str);
                else
                    proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN);
                offset += 8;
            }
                break;

            case OSC_SYMBOL:
                slen = tvb_strsize(tvb, offset);
                if( (rem = slen%4) ) slen += 4-rem;
                proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA);
                offset += slen;
                break;
            case OSC_CHAR:
                offset += 3;
                proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA);
                offset += 1;
                break;
            case OSC_RGBA:
            {
                proto_item *ri;
                proto_tree *rgba_tree;

                ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba);

                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                break;
            }
            case OSC_MIDI:
            {
                const gchar *status_str;
                proto_item  *mi = NULL;
                proto_tree  *midi_tree;
                guint8       port;
                guint8       command;
                guint8       data1;
                guint8       data2;
                guint8       status;
                guint8       channel;
                gboolean     system_msg;
                guint8       status_shifted;

                port = tvb_get_guint8(tvb, offset);
                command  = tvb_get_guint8(tvb, offset+1);
                data1   = tvb_get_guint8(tvb, offset+2);
                data2   = tvb_get_guint8(tvb, offset+3);

                status  = command & 0xF0;
                channel = command & 0x0F;

                system_msg = status == 0xF0; /* is system message */
                status_shifted = status >> 4;

                if(system_msg)
                    status_str = val_to_str_ext_const(command, &MIDI_system_ext, "Unknown");
                else
                    status_str = val_to_str_ext_const(status_shifted, &MIDI_status_ext, "Unknown");

                if(system_msg)
                {
                    mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                            "MIDI: Port %i, %s, %i, %i",
                            port, status_str, data1, data2);
                }
                else
                {
                    switch(status_shifted)
                    {
                        case MIDI_STATUS_NOTE_ON:
                        case MIDI_STATUS_NOTE_OFF:
                        case MIDI_STATUS_NOTE_PRESSURE:
                        {
                            const gchar *note_str;
                            note_str = val_to_str_ext_const(data1, &MIDI_note_ext, "Unknown");

                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %s, %i",
                                    port, channel, status_str, note_str, data2);
                            break;
                        }
                        case MIDI_STATUS_CONTROLLER:
                        {
                            const gchar *control_str;
                            control_str = val_to_str_ext_const(data1, &MIDI_control_ext, "Unknown");

                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %s, %i",
                                    port, channel, status_str, control_str, data2);
                            break;
                        }
                        case MIDI_STATUS_PITCH_BENDER:
                        {
                            const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000;

                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %i",
                                    port, channel, status_str, bender);
                            break;
                        }
                        default:
                        {
                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %i, %i",
                                    port, channel, status_str, data1, data2);
                            break;
                        }
                    }
                }
                midi_tree = proto_item_add_subtree(mi, ett_osc_midi);

                proto_tree_add_item(midi_tree, hf_osc_message_midi_port_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

                if(system_msg)
                {
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_system_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;
                }
                else
                {
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    switch(status_shifted)
                    {
                        case MIDI_STATUS_NOTE_ON:
                        case MIDI_STATUS_NOTE_OFF:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_velocity_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_NOTE_PRESSURE:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_CONTROLLER:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_CHANNEL_PRESSURE:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_PITCH_BENDER:
                        {
                            const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000;

                            proto_tree_add_int(midi_tree, hf_osc_message_midi_bender_type, tvb, offset, 2, bender);
                            offset += 2;

                            break;
                        }
                        default:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                    }
                }

                break;
            }

            default:
                /* if we get here, there must be a bug in the dissector  */
                DISSECTOR_ASSERT_NOT_REACHED();
                break;
        }
        ptr++;
    }

    if(offset != end)
        return -1;
    else
        return 0;
}
Esempio n. 24
0
	guint8 ninemsg;
	guint offset = 0;
	const char *mname;
	gint len,reportedlen;
	tvbuff_t *next_tvb;
	proto_item *ti;
	proto_tree *ninep_tree,*tmp_tree;
	nstime_t tv;

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

	/*ninesz = tvb_get_letohl(tvb, offset);*/
	ninemsg = tvb_get_guint8(tvb, offset + 4);

	mname = val_to_str_ext_const(ninemsg, &ninep_msg_type_ext, "Unknown");

	if(strcmp(mname,"Unknown") == 0) {
		col_add_fstr(pinfo->cinfo, COL_INFO, "9P Data Continuation(?) (Tag %u)",(guint)ninemsg);

		return 0;
	}

	col_append_fstr(pinfo->cinfo, COL_INFO, "%s Tag=%u",mname,(guint)tvb_get_letohs(tvb,offset+5));

	if (!tree) /*not much more of one line summary interrest yet.. */
		return 0;

	ti = proto_tree_add_item(tree, proto_9P, tvb, 0, -1, ENC_NA);
	ninep_tree = proto_item_add_subtree(ti, ett_9P);
	proto_tree_add_item(ninep_tree, hf_9P_msgsz, tvb, offset, 4, ENC_LITTLE_ENDIAN);
Esempio n. 25
0
/* Dissect an individual actrace CAS message */
static void dissect_actrace_cas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *actrace_tree)
{
	/* Declare variables */
	gint32 value, function, trunk, bchannel, source, event, curr_state, next_state;
	gint32 par0, par1, par2;
	gchar *frame_label = NULL;
	int direction = 0;
	int offset = 0;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_CAS");

	value = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_time, tvb, offset, 4, value);
	offset += 4;

	source = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_source, tvb, offset, 4, source);
	offset += 4;

	curr_state = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_current_state, tvb, offset, 4, curr_state);
	offset += 4;

	event = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_event, tvb, offset, 4, event);
	offset += 4;

	next_state = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_next_state, tvb, offset, 4, next_state);
	offset += 4;

	function = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_function, tvb, offset, 4, function);
	offset += 4;

	col_append_fstr(pinfo->cinfo, COL_INFO, "%s|%d|%s|%d|%s|",
			val_to_str_const(source, actrace_cas_source_vals_short, "ukn"),
			curr_state,
			val_to_str_ext(event, &actrace_cas_event_vals_ext, "%d"),
			next_state,
			val_to_str_ext(function, &actrace_cas_function_vals_ext, "%d"));

	par0 = tvb_get_ntohl(tvb, offset);
	switch (function)
	{
		case SEND_EVENT:
			proto_tree_add_text(actrace_tree, tvb, offset, 4,
				"Parameter 0: %s",  val_to_str_ext(par0,
				&actrace_cas_pstn_event_vals_ext, "Unknown (%d)"));
			col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
					val_to_str_ext(par0, &actrace_cas_pstn_event_vals_ext, "%d"));
			break;
		case CHANGE_COLLECT_TYPE:
			proto_tree_add_text(actrace_tree, tvb, offset, 4,
				"Parameter 0: %s", val_to_str(par0,
				actrace_cas_collect_type_vals, "Unknown (%d)"));
			col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
					val_to_str(par0, actrace_cas_collect_type_vals, "%d"));
			break;
		case SEND_MF:
		case SEND_DEST_NUM:
			proto_tree_add_text(actrace_tree, tvb, offset, 4,
				"Parameter 0: %s", val_to_str(par0,
				actrace_cas_send_type_vals, "Unknown (%d)"));
			col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
					val_to_str(par0, actrace_cas_send_type_vals, "%d"));
			break;
		default:
			proto_tree_add_int(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4, par0);
			col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par0);
	}
	offset += 4;

	par1 = tvb_get_ntohl(tvb, offset);
	if (function == SEND_EVENT) {
		proto_tree_add_text(actrace_tree, tvb, offset, 4,
			"Parameter 1: %s", val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "Unknown (%d)"));
		col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
				val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "%d"));
	} else {
		proto_tree_add_int(actrace_tree, hf_actrace_cas_par1, tvb, offset, 4, par1);
		col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par1);
	}
	offset += 4;

	par2 = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_par2, tvb, offset, 4, par2);
	col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par2);
	offset += 4;

	trunk = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_trunk, tvb, offset, 4, trunk);
	offset += 4;

	bchannel = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_bchannel, tvb, offset, 4, bchannel);
	offset += 4;

	col_prepend_fstr(pinfo->cinfo, COL_INFO, "t%db%d|", trunk, bchannel);

	value = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_connection_id, tvb, offset, 4, value);

	/* Add tap info for the Voip Graph */
	if (source == ACTRACE_CAS_SOURCE_DSP) {
		direction = 1;
		if ( (event >= ACTRACE_CAS_EV_11) && (event <= ACTRACE_CAS_EV_00 ) ) {
			frame_label = ep_strdup_printf("AB: %s", val_to_str_const(event, actrace_cas_event_ab_vals, "ERROR") );
		} else if ( (event >= 32) && (event <= 46 ) ) { /* is an MF tone */
			frame_label = ep_strdup_printf("MF: %s", val_to_str_ext_const(event, &actrace_cas_mf_vals_ext, "ERROR") );
		} else if ( (event == ACTRACE_CAS_EV_DTMF ) || (event == ACTRACE_CAS_EV_FIRST_DIGIT ) ) { /* DTMF digit */
			frame_label = ep_strdup_printf("DTMF: %u", par0 );
		}
	} else if (source == ACTRACE_CAS_SOURCE_TABLE) {
		direction = 0;
		if (function == SEND_MF) {
			if (par0 == SEND_TYPE_SPECIFIC ) {
				frame_label = ep_strdup_printf("MF: %u", par1);
			} else if (par0 == SEND_TYPE_ADDRESS ) {
				frame_label = ep_strdup("MF: DNIS digit");
			} else if (par0 == SEND_TYPE_ANI  ) {
				frame_label = ep_strdup("MF: ANI digit");
			} else if (par0 == SEND_TYPE_SOURCE_CATEGORY ) {
				frame_label = ep_strdup("MF: src_category");
			} else if (par0 == SEND_TYPE_TRANSFER_CAPABILITY ) {
				frame_label = ep_strdup("MF: trf_capability");
			} else if (par0 == SEND_TYPE_INTER_EXCHANGE_SWITCH ) {
				frame_label = ep_strdup("MF: inter_exch_sw");
			}
		} else if (function == SEND_CAS) {
			frame_label = ep_strdup_printf("AB: %s", val_to_str_const(ACTRACE_CAS_EV_00-par0, actrace_cas_event_ab_vals, "ERROR"));
		} else if (function == SEND_DEST_NUM) {
			if (par0 == SEND_TYPE_ADDRESS ) {
				frame_label = ep_strdup("DTMF/MF: sending DNIS");
			} else if (par0 == SEND_TYPE_ANI ) {
				frame_label = ep_strdup("DTMF/MF: sending ANI");
			}
		}
	}

	if (frame_label != NULL) {
		/* Initialise packet info for passing to tap */
		actrace_pi = ep_new(actrace_info_t);

		actrace_pi->type = ACTRACE_CAS;
		actrace_pi->direction = direction;
		actrace_pi->trunk = trunk;
		actrace_pi->cas_bchannel = bchannel;
		actrace_pi->cas_frame_label = frame_label;
		/* Report this packet to the tap */
		tap_queue_packet(actrace_tap, pinfo, actrace_pi);
	}
}