Ejemplo n.º 1
0
static void dissect_cnip (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
   tvbuff_t *next_tvb;
   gint offset;
   gint type, exth_len, pf_pcode;

   proto_tree *ti;
   proto_tree *cnip_tree;

   static const gint *pf_fields[] = {
      &hf_cnip_pf_sec,
      &hf_cnip_pf_pcode,
      NULL
   };

   col_set_str(pinfo->cinfo, COL_PROTOCOL, "CN/IP");
   col_clear(pinfo->cinfo, COL_INFO);

   type = tvb_get_guint8(tvb, 3);
   col_add_fstr(pinfo->cinfo, COL_INFO,"Priority: %s Type: %s",
         (pinfo->destport == 1629 )? "urgent":"normal",
         val_to_str_const(type, type_tuple, "Unknown"));

   exth_len = tvb_get_guint8(tvb, 4);
   pf_pcode = tvb_get_guint8(tvb, 5) & 0x1F;

   offset = 0;

   /* Take whole packet for now, we'll adjust it later */
   ti = proto_tree_add_item(tree, proto_cnip, tvb, offset, -1, ENC_NA);
   cnip_tree = proto_item_add_subtree(ti, ett_cnip);

   proto_tree_add_item(cnip_tree, hf_cnip_len, tvb, offset, 2, ENC_BIG_ENDIAN);
   offset += 2;

   proto_tree_add_item(cnip_tree, hf_cnip_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
   offset += 1;

   proto_tree_add_item(cnip_tree, hf_cnip_type, tvb, offset, 1, ENC_BIG_ENDIAN);
   offset += 1;

   proto_tree_add_item(cnip_tree, hf_cnip_exth, tvb, offset, 1, ENC_BIG_ENDIAN);
   offset += 1;

   proto_tree_add_bitmask(cnip_tree, tvb, offset,
         hf_cnip_pf, ett_pf, pf_fields, ENC_BIG_ENDIAN);
   offset += 1;

   proto_tree_add_item(cnip_tree, hf_cnip_vcode, tvb, offset, 2, ENC_BIG_ENDIAN);
   offset += 2;

   proto_tree_add_item(cnip_tree, hf_cnip_sessid, tvb, offset, 4, ENC_BIG_ENDIAN);
   offset += 4;

   proto_tree_add_item(cnip_tree, hf_cnip_seqno, tvb, offset, 4, ENC_BIG_ENDIAN);
   offset += 4;

   proto_tree_add_item(cnip_tree, hf_cnip_tstamp, tvb, offset, 4, ENC_BIG_ENDIAN);
   offset += 4;

   /* Jump over any unknown header extensions */
   offset += 4 * exth_len;

   proto_item_set_len(ti, offset);

   next_tvb = tvb_new_subset_remaining(tvb, offset);
   if (type == DATA_PACKET) {
      if (dissector_try_uint(cnip_dissector_table, pf_pcode, next_tvb, pinfo, tree))
         return;
   }
   else {
      expert_add_info_format_text(pinfo, cnip_tree, &ei_cnip_type_unknown,
            "This dissector doesn't yet decode packets of type %s (0x%x)",
            val_to_str_const(type, type_tuple, "Unknown"), type);
   }
   call_dissector(data_handle, next_tvb, pinfo, tree);
}
Ejemplo n.º 2
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;
    }
}
Ejemplo n.º 3
0
static void
dissect_netrom_proto(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item   *ti;
	proto_tree   *netrom_tree;
	int           offset;
	const guint8 *src_addr;
	const guint8 *dst_addr;
	const guint8 *user_addr;
	const guint8 *node_addr;
#if 0
	guint8        src_ssid;
	guint8        dst_ssid;
#endif
	guint8        op_code;
	guint8        cct_index;
	guint8        cct_id;
	void         *saved_private_data;
	tvbuff_t     *next_tvb = NULL;

	col_set_str( pinfo->cinfo, COL_PROTOCOL, "NET/ROM" );
	col_clear( pinfo->cinfo, COL_INFO );

	offset = 0;

	/* source */
	src_addr = tvb_get_ptr( tvb,  offset, AX25_ADDR_LEN );
	SET_ADDRESS(&pinfo->dl_src,	AT_AX25, AX25_ADDR_LEN, src_addr);
	SET_ADDRESS(&pinfo->src,	AT_AX25, AX25_ADDR_LEN, src_addr);
	/* src_ssid = *(src_addr + 6); */
	offset += AX25_ADDR_LEN; /* step over src addr */

	/* destination */
	dst_addr = tvb_get_ptr( tvb,  offset, AX25_ADDR_LEN );
	SET_ADDRESS(&pinfo->dl_dst,	AT_AX25, AX25_ADDR_LEN, dst_addr);
	SET_ADDRESS(&pinfo->dst,	AT_AX25, AX25_ADDR_LEN, dst_addr);
	/* dst_ssid = *(dst_addr + 6); */
	offset += AX25_ADDR_LEN; /* step over dst addr */

	offset += 1; /* step over ttl */
	cct_index =  tvb_get_guint8( tvb, offset );
	offset += 1; /* step over cct index*/
	cct_id =  tvb_get_guint8( tvb, offset );
	offset += 1; /* step over cct id */
	offset += 1; /* step over n_s */
	offset += 1; /* step over n_r */

	/* frame type */
	op_code =  tvb_get_guint8( tvb, offset ) & 0x0f;
	offset += 1; /* step over op_code */

	col_add_fstr( pinfo->cinfo, COL_INFO, "%s", val_to_str_const( op_code, op_code_vals_text, "Unknown" ));

	if ( tree )
		{
		/* create display subtree for the protocol */

		ti = proto_tree_add_protocol_format( tree, proto_netrom, tvb, 0, NETROM_HEADER_SIZE,
			"NET/ROM, Src: %s (%s), Dst: %s (%s)",
			get_ax25_name( src_addr ),
			ax25_to_str( src_addr ),
			get_ax25_name( dst_addr ),
			ax25_to_str( dst_addr ) );

		netrom_tree = proto_item_add_subtree( ti, ett_netrom );

		offset = 0;

		/* source */
		proto_tree_add_ax25( netrom_tree, hf_netrom_src, tvb, offset, AX25_ADDR_LEN, src_addr );
		offset += AX25_ADDR_LEN;

		/* destination */
		proto_tree_add_ax25( netrom_tree, hf_netrom_dst, tvb, offset, AX25_ADDR_LEN, dst_addr );
		offset += AX25_ADDR_LEN;

		/* ttl */
		proto_tree_add_item( netrom_tree, hf_netrom_ttl, tvb, offset, 1, ENC_BIG_ENDIAN );
		offset += 1;

		switch ( op_code )
			{
			case NETROM_PROTOEXT	:
						/* cct index */
						proto_tree_add_item( netrom_tree, hf_netrom_my_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* cct id */
						proto_tree_add_item( netrom_tree, hf_netrom_my_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* unused */
						offset += 1;

						/* unused */
						offset += 1;
						break;
			case NETROM_CONNREQ	:
						/* cct index */
						proto_tree_add_item( netrom_tree, hf_netrom_my_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* cct id */
						proto_tree_add_item( netrom_tree, hf_netrom_my_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* unused */
						offset += 1;

						/* unused */
						offset += 1;

						break;
			case NETROM_CONNACK	:
						/* your cct index */
						proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* your cct id */
						proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* my cct index */
						proto_tree_add_item( netrom_tree, hf_netrom_my_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* my cct id */
						proto_tree_add_item( netrom_tree, hf_netrom_my_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						break;
			case NETROM_DISCREQ	:
						/* your cct index */
						proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* your cct id */
						proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* unused */
						offset += 1;

						/* unused */
						offset += 1;

						break;
			case NETROM_DISCACK	:
						/* your cct index */
						proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* your cct id */
						proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* unused */
						offset += 1;

						/* unused */
						offset += 1;

						break;
			case NETROM_INFO	:
						/* your cct index */
						proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* your cct id */
						proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* n_s */
						proto_tree_add_item( netrom_tree, hf_netrom_n_s, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* n_r */
						proto_tree_add_item( netrom_tree, hf_netrom_n_r, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						break;
			case NETROM_INFOACK	:
						/* your cct index */
						proto_tree_add_item( netrom_tree, hf_netrom_your_cct_index, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* your cct id */
						proto_tree_add_item( netrom_tree, hf_netrom_your_cct_id, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						/* unused */
						offset += 1;

						/* n_r */
						proto_tree_add_item( netrom_tree, hf_netrom_n_r, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						break;
			default			:
						offset += 1;
						offset += 1;
						offset += 1;
						offset += 1;

						break;
			}

		/* type */
		dissect_netrom_type(	tvb,
					offset,
					pinfo,
					netrom_tree,
					hf_netrom_type,
					ett_netrom_type,
					&netrom_type_items
					);
		offset += 1;

		switch ( op_code )
			{
			case NETROM_PROTOEXT	:
						break;
			case NETROM_CONNREQ	:
						/* proposed window size */
						proto_tree_add_item( netrom_tree, hf_netrom_pwindow, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						user_addr = tvb_get_ptr( tvb,  offset, AX25_ADDR_LEN );
						proto_tree_add_ax25( netrom_tree, hf_netrom_user, tvb, offset, AX25_ADDR_LEN, user_addr );
						offset += AX25_ADDR_LEN;

						node_addr = tvb_get_ptr( tvb,  offset, AX25_ADDR_LEN );
						proto_tree_add_ax25( netrom_tree, hf_netrom_node, tvb, offset, AX25_ADDR_LEN, node_addr );
						offset += AX25_ADDR_LEN;

						break;
			case NETROM_CONNACK	:
						/* accepted window size */
						proto_tree_add_item( netrom_tree, hf_netrom_awindow, tvb, offset, 1, ENC_BIG_ENDIAN );
						offset += 1;

						break;
			case NETROM_DISCREQ	:
						break;
			case NETROM_DISCACK	:
						break;
			case NETROM_INFO	:
						break;
			case NETROM_INFOACK	:
						break;
			default			:
						break;
			}
		}

	/* Call sub-dissectors here */

	saved_private_data = pinfo->private_data;
	next_tvb = tvb_new_subset_remaining(tvb, offset);

	switch ( op_code )
		{
		case NETROM_PROTOEXT	:
					if ( cct_index == NETROM_PROTO_IP && cct_id == NETROM_PROTO_IP )
						call_dissector( ip_handle , next_tvb, pinfo, tree );
					else
						call_dissector( default_handle , next_tvb, pinfo, tree );

					break;
		case NETROM_INFO	:
		default			:
					call_dissector( default_handle , next_tvb, pinfo, tree );
					break;
		}

	pinfo->private_data = saved_private_data;
}
Ejemplo n.º 4
0
static void dissect_mqpcf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, mq_parm_t* p_mq_parm)
{
    gint offset = 0;
    gboolean bLittleEndian;

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

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

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

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

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

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

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

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

            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_type     , tvb, offset +  0, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_length   , tvb, offset +  4, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_version  , tvb, offset +  8, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_command  , tvb, offset + 12, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_MsgSeqNbr, tvb, offset + 16, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_control  , tvb, offset + 20, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_compcode , tvb, offset + 24, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_reason   , tvb, offset + 28, 4, bLittleEndian);
            proto_tree_add_item(mq_tree, hf_mqpcf_cfh_ParmCount, tvb, offset + 32, 4, bLittleEndian);
            dissect_mqpcf_parm(tvb, pinfo, mqroot_tree, offset + iSizeMQCFH, uCnt, bLittleEndian, TRUE);
        }
    }
}
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;
}
Ejemplo n.º 6
0
static void
dissect_dtp_tlv(packet_info *pinfo, tvbuff_t *tvb, int offset, int length,
		proto_tree *tree, proto_item *ti, proto_item *tlv_length_item, guint8 type)
{
	switch (type) {

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

		break;

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

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

		break;

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

		break;

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

		break;

	default:
		proto_tree_add_text(tree, tvb, offset, length, "Data");
		break;
	}
}
Ejemplo n.º 7
0
/*
 * Returns TRUE if there's a User Information field in this SPDU, FALSE
 * otherwise.
 */
static gboolean
dissect_parameters(tvbuff_t *tvb, int offset, guint16 len, proto_tree *tree,
	           proto_tree *ses_tree, packet_info *pinfo,
	           guint8 *enclosure_item_flags, struct SESSION_DATA_STRUCTURE *session)
{
	gboolean has_user_information = TRUE;
	proto_item *ti;
	proto_tree *param_tree;
	guint8 param_type;
	const char *param_str;
	int len_len;
	guint16 param_len;

	while (len != 0)
	{
		param_type = tvb_get_guint8(tvb, offset);
		ti = proto_tree_add_text(ses_tree, tvb, offset, -1, "%s",
		    val_to_str(param_type, param_vals,
		      "Unknown parameter type (0x%02x)"));
		param_tree = proto_item_add_subtree(ti, ett_ses_param);
		param_str = val_to_str_const(param_type, param_vals, "Unknown");
		proto_tree_add_text(param_tree, tvb, offset, 1,
		    "Parameter type: %s", param_str);
		offset++;
		len--;
		param_len = get_item_len(tvb, offset, &len_len);
		if (len_len > len) {
			proto_item_set_len(ti, len + 1 );
			proto_tree_add_text(param_tree, tvb, offset, len,
			    "Parameter length doesn't fit in parameter");
			return has_user_information;
		}
		len -= len_len;
		if (param_len > len) {
			proto_item_set_len(ti, len + 1 + len_len);
			proto_tree_add_text(param_tree, tvb, offset, len,
			    "Parameter length: %u, should be <= %u",
			    param_len, len);
			return has_user_information;
		}
		proto_item_set_len(ti, 1 + len_len + param_len);
		proto_tree_add_text(param_tree, tvb, offset, len_len,
		    "Parameter length: %u", param_len);
		offset += len_len;

		if (param_str != NULL)
		{
			switch(param_type)
			{
			case Extended_User_Data:
				call_pres_dissector(tvb, offset, param_len,
				    pinfo, tree, param_tree, session);
				break;

			case User_Data:
				call_pres_dissector(tvb, offset, param_len,
				    pinfo, tree, param_tree, session);
				break;

			/* handle PGI's  */
			case Connect_Accept_Item:
			case Connection_Identifier:
			case Linking_Information:
				/* Yes. */
				if (!dissect_parameter_group(tvb, offset, tree,
				    param_tree, pinfo, param_len, enclosure_item_flags, session))
					has_user_information = FALSE;
				break;

			/* everything else is a PI */
			default:
				if (!dissect_parameter(tvb, offset, tree,
				    param_tree, pinfo, param_type, param_len,
				    enclosure_item_flags, session))
					has_user_information = FALSE;
				break;
			}
		}
		offset += param_len;
		len -= param_len;
	}
	return has_user_information;
}
Ejemplo n.º 8
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_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_text(wtp_tree, tvb, dataOffset, -1, "Payload");
                }
            } 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_text(wtp_tree, tvb, dataOffset, -1, "Payload");
            }
            /* Now reset fragmentation information in pinfo */
            pinfo->fragmented = save_fragmented;
        }
        else if ( ((pdut == INVOKE) || (pdut == RESULT)) && (fTTR) )
        {
            /* Non-fragmented payload */
            wsp_tvb = tvb_new_subset_remaining(tvb, dataOffset);
            /* We can safely hand the tvb to the WSP dissector */
            call_dissector(wsp_handle, wsp_tvb, pinfo, tree);
        }
        else
        {
            /* Nothing to hand to subdissector */
            col_append_str(pinfo->cinfo, COL_INFO, szInfo);
        }
    }
    else
    {
        /* Nothing to hand to subdissector */
        col_append_str(pinfo->cinfo, COL_INFO, szInfo);
    }
}
Ejemplo n.º 9
0
static void
dissect_nflog(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	const int start_tlv_offset = 4;

	proto_tree *nflog_tree = NULL;
	proto_item *ti;

	int offset = 0;

	tvbuff_t *next_tvb = NULL;
	int aftype;

	int enc;
	guint16 (*val16_get)(tvbuff_t *, int);

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

	aftype = tvb_get_guint8(tvb, 0);
	enc = nflog_tvb_byte_order(tvb, start_tlv_offset);
	switch (enc) {
		case ENC_LITTLE_ENDIAN:
			val16_get = tvb_get_letohs;
			break;

		case ENC_BIG_ENDIAN:
		default:
			val16_get = tvb_get_ntohs;
			break;
	}

	/* Header */
	if (proto_field_is_referenced(tree, hfi_nflog->id)) {
		ti = proto_tree_add_item(tree, hfi_nflog, tvb, 0, -1, ENC_NA);
		nflog_tree = proto_item_add_subtree(ti, ett_nflog);

		proto_tree_add_item(nflog_tree, &hfi_nflog_family, tvb, offset, 1, ENC_NA);
		offset += 1;

		proto_tree_add_item(nflog_tree, &hfi_nflog_version, tvb, offset, 1, ENC_NA);
		offset += 1;

		proto_tree_add_item(nflog_tree, &hfi_nflog_resid, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		ti = proto_tree_add_uint(nflog_tree, &hfi_nflog_encoding,
					 tvb, offset, tvb_length_remaining(tvb, offset), enc);
		PROTO_ITEM_SET_GENERATED(ti);
	}

	offset = start_tlv_offset;
	/* TLVs */
	while (tvb_length_remaining(tvb, offset) >= 4) {
		guint16 tlv_len = val16_get(tvb, offset + 0);
		guint16 tlv_type;
		guint16 value_len;

		proto_tree *tlv_tree;

		/* malformed */
		if (tlv_len < 4)
			return;

		value_len = tlv_len - 4;
		tlv_type = (val16_get(tvb, offset + 2) & 0x7fff);

		if (nflog_tree) {
			gboolean handled = FALSE;

			ti = proto_tree_add_bytes_format(nflog_tree, hfi_nflog_tlv.id,
							 tvb, offset, tlv_len, NULL,
							 "TLV Type: %s (%u), Length: %u",
							 val_to_str_const(tlv_type, nflog_tlv_vals, "Unknown"),
							 tlv_type, tlv_len);
			tlv_tree = proto_item_add_subtree(ti, ett_nflog_tlv);

			proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_length, tvb, offset + 0, 2, enc);
			proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_type, tvb, offset + 2, 2, enc);
			switch (tlv_type) {
				case WS_NFULA_PAYLOAD:
					handled = TRUE;
					break;

				case WS_NFULA_PREFIX:
					if (value_len >= 1) {
						proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_prefix,
								    tvb, offset + 4, value_len, ENC_NA);
						handled = TRUE;
					}
					break;

				case WS_NFULA_UID:
					if (value_len == 4) {
						proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_uid,
								    tvb, offset + 4, value_len, ENC_BIG_ENDIAN);
						handled = TRUE;
					}
					break;

				case WS_NFULA_GID:
					if (value_len == 4) {
						proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_gid,
								    tvb, offset + 4, value_len, ENC_BIG_ENDIAN);
						handled = TRUE;
					}
					break;

				case WS_NFULA_TIMESTAMP:
					if (value_len == 16) {
						nstime_t ts;

						ts.secs  = (time_t)tvb_get_ntoh64(tvb, offset + 4);
						/* XXX - add an "expert info" warning if this is >= 10^9? */
						ts.nsecs = (int)tvb_get_ntoh64(tvb, offset + 12);
						proto_tree_add_time(tlv_tree, &hfi_nflog_tlv_timestamp,
									tvb, offset + 4, value_len, &ts);
						handled = TRUE;
					}
					break;
			}

			if (!handled)
					proto_tree_add_item(tlv_tree, &hfi_nflog_tlv_unknown,
							    tvb, offset + 4, value_len, ENC_NA);
		}

		if (tlv_type == WS_NFULA_PAYLOAD)
			next_tvb = tvb_new_subset(tvb, offset + 4, value_len, value_len);

		offset += ((tlv_len + 3) & ~3);	/* next TLV aligned to 4B */
	}

	if (next_tvb) {
		switch (aftype) {
			case LINUX_AF_INET:
				call_dissector(ip_handle, next_tvb, pinfo, tree);
				break;
			case LINUX_AF_INET6:
				call_dissector(ip6_handle, next_tvb, pinfo, tree);
				break;
			default:
				call_dissector(data_handle, next_tvb, pinfo, tree);
				break;
		}
	}
}
Ejemplo n.º 10
0
	proto_tree *wow_tree, *wow_realms_tree;

	gchar *string, *realm_name;
	guint8 cmd, srp_i_len, srp_g_len, srp_n_len;
	guint16 num_realms;
	guint32 offset = 0;
	gint len, ii;

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

	col_clear(pinfo->cinfo, COL_INFO);

	cmd = tvb_get_guint8(tvb, offset);

	col_set_str(pinfo->cinfo, COL_INFO,
			    val_to_str_const(cmd, cmd_vs,
				       "Unrecognized packet type"));

	if(tree) {
		ti = proto_tree_add_item(tree, proto_wow, tvb, 0, -1, ENC_NA);
		wow_tree = proto_item_add_subtree(ti, ett_wow);

		proto_tree_add_item(wow_tree, hf_wow_command, tvb, offset, 1,
				    ENC_LITTLE_ENDIAN);
		offset += 1;

		switch(cmd) {

		case AUTH_LOGON_CHALLENGE :

			if(WOW_CLIENT_TO_SERVER) {
				proto_tree_add_item(wow_tree, hf_wow_error, tvb,
Ejemplo n.º 11
0
static void
dissect_nettl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
      proto_tree *nettl_tree;
      proto_item *nettl_item;

      pinfo->current_proto = "nettl";

      if (tree) {
	    nettl_item = proto_tree_add_protocol_format(tree, proto_nettl, tvb,
		0, -1, "HP-UX Network Tracing and Logging (nettl) header");
	    nettl_tree = proto_item_add_subtree(nettl_item, ett_nettl);
            proto_tree_add_uint_format(nettl_tree, hf_nettl_subsys, tvb,
		0, 0, pinfo->pseudo_header->nettl.subsys,
		"Subsystem: %d (%s)", pinfo->pseudo_header->nettl.subsys,
		val_to_str_const(pinfo->pseudo_header->nettl.subsys, subsystem, "Unknown"));
            proto_tree_add_int(nettl_tree, hf_nettl_devid, tvb,
		0, 0, pinfo->pseudo_header->nettl.devid);
            proto_tree_add_uint_format(nettl_tree, hf_nettl_kind, tvb,
		0, 0, pinfo->pseudo_header->nettl.kind,
		"Trace Kind: 0x%08x (%s)", pinfo->pseudo_header->nettl.kind,
		val_to_str_const(pinfo->pseudo_header->nettl.kind & ~NETTL_HDR_SUBSYSTEM_BITS_MASK, trace_kind, "Unknown"));
            proto_tree_add_int(nettl_tree, hf_nettl_pid, tvb,
		0, 0, pinfo->pseudo_header->nettl.pid);
            proto_tree_add_uint(nettl_tree, hf_nettl_uid, tvb,
		0, 0, pinfo->pseudo_header->nettl.uid);

      }

      switch (pinfo->fd->lnk_t) {
         case WTAP_ENCAP_NETTL_ETHERNET:
            call_dissector(eth_withoutfcs_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_TOKEN_RING:
            call_dissector(tr_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_FDDI:
            if (!dissector_try_uint(wtap_dissector_table,
			WTAP_ENCAP_FDDI_BITSWAPPED, tvb, pinfo, tree))
	            call_dissector(data_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_RAW_IP:
            if ( (pinfo->pseudo_header->nettl.kind & NETTL_HDR_PDU_MASK) == 0 )
                    /* not actually a data packet (PDU) trace record */
	            call_dissector(data_handle, tvb, pinfo, tree);
            else if (pinfo->pseudo_header->nettl.subsys == NETTL_SUBSYS_NS_LS_SCTP )
                    call_dissector(sctp_handle, tvb, pinfo, tree);
            else if (!dissector_try_uint(wtap_dissector_table,
			WTAP_ENCAP_RAW_IP, tvb, pinfo, tree))
	            call_dissector(data_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_RAW_ICMP:
            if (!dissector_try_uint(ip_proto_dissector_table,
			IP_PROTO_ICMP, tvb, pinfo, tree))
	            call_dissector(data_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_RAW_ICMPV6:
            if (!dissector_try_uint(ip_proto_dissector_table,
	                IP_PROTO_ICMPV6, tvb, pinfo, tree))
	            call_dissector(data_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_X25:
	    if (pinfo->pseudo_header->nettl.kind == NETTL_HDR_PDUIN)
            	pinfo->p2p_dir = P2P_DIR_RECV;
	    else if (pinfo->pseudo_header->nettl.kind == NETTL_HDR_PDUOUT)
            	pinfo->p2p_dir = P2P_DIR_SENT;
	    if (pinfo->pseudo_header->nettl.subsys == NETTL_SUBSYS_SX25L2)
            	call_dissector(lapb_handle, tvb, pinfo, tree);
	    else
            	call_dissector(x25_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_RAW_TELNET:
            if (!dissector_try_uint(tcp_subdissector_table,
	                TCP_PORT_TELNET, tvb, pinfo, tree))
	            call_dissector(data_handle, tvb, pinfo, tree);
            break;
         default:
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
            if (check_col(pinfo->cinfo, COL_INFO))
                col_add_fstr(pinfo->cinfo, COL_INFO,
		"Unsupported nettl subsytem: %d (%s)",
                pinfo->pseudo_header->nettl.subsys,
		val_to_str_const(pinfo->pseudo_header->nettl.subsys, subsystem, "Unknown"));
            call_dissector(data_handle, tvb, pinfo, tree);
      }
}
Ejemplo n.º 12
0
static void
dissect_rip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    int offset = 0;
    proto_tree *rip_tree = NULL;
    proto_item *ti;
    guint8 command;
    guint8 version;
    guint16 family;
    gint trailer_len = 0;
    gboolean is_md5_auth = FALSE;

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

    command = tvb_get_guint8(tvb, 0);
    version = tvb_get_guint8(tvb, 1);

    col_set_str(pinfo->cinfo, COL_PROTOCOL,
		    val_to_str_const(version, version_vals, "RIP"));
    col_add_str(pinfo->cinfo, COL_INFO,
		    val_to_str(command, command_vals, "Unknown command (%u)"));

    if (tree) {
	ti = proto_tree_add_item(tree, hfi_rip, tvb, 0, -1, ENC_NA);
	rip_tree = proto_item_add_subtree(ti, ett_rip);

	proto_tree_add_uint(rip_tree, &hfi_rip_command, tvb, 0, 1, command);
	proto_tree_add_uint(rip_tree, &hfi_rip_version, tvb, 1, 1, version);
	if (version == RIPv2 && pref_display_routing_domain == TRUE)
	    proto_tree_add_uint(rip_tree, &hfi_rip_routing_domain, tvb, 2, 2,
			tvb_get_ntohs(tvb, 2));

	/* skip header */
	offset = RIP_HEADER_LENGTH;

        /* zero or more entries */
	while (tvb_reported_length_remaining(tvb, offset) > trailer_len ) {
	    family = tvb_get_ntohs(tvb, offset);
	    switch (family) {
	    case AFVAL_UNSPEC: /* Unspecified */
	        /*
	         * There should be one entry in the request, and a metric
	         * of infinity, meaning "show the entire routing table".
	         */
		dissect_unspec_rip_vektor(tvb, offset, version, rip_tree);
		break;
	    case AFVAL_IP: /* IP */
		dissect_ip_rip_vektor(tvb, offset, version, rip_tree);
		break;
	    case 0xFFFF:
		if( offset == RIP_HEADER_LENGTH ) {
			trailer_len=dissect_rip_authentication(tvb, offset, rip_tree);
			is_md5_auth = TRUE;
		break;
		}
		if(is_md5_auth && tvb_reported_length_remaining(tvb, offset) == 20)
			break;
		/* Intentional fall through: auth Entry MUST be the first! */
	    default:
	        proto_tree_add_text(rip_tree, tvb, offset,
				RIP_ENTRY_LENGTH, "Unknown address family %u",
				family);
		break;
	    }

            offset += RIP_ENTRY_LENGTH;
        }
    }
}
Ejemplo n.º 13
0
static void
dissect_ieee802a(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*ieee802a_tree = NULL;
	proto_item	*ti;
	tvbuff_t	*next_tvb;
	guint32		oui;
	guint16		pid;
	oui_info_t	*oui_info;
	dissector_table_t subdissector_table;
	int		hf;

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

	if (tree) {
		ti = proto_tree_add_item(tree, proto_ieee802a, tvb, 0, 5, ENC_NA);
		ieee802a_tree = proto_item_add_subtree(ti, ett_ieee802a);
	}

	oui =	tvb_get_ntoh24(tvb, 0);
	pid = tvb_get_ntohs(tvb, 3);

	if (check_col(pinfo->cinfo, COL_INFO)) {
		col_add_fstr(pinfo->cinfo, COL_INFO,
		    "OUI 0x%06X (%s), PID 0x%04X",
		    oui, val_to_str_const(oui, oui_vals, "Unknown"), pid);
	}
	if (tree) {
		proto_tree_add_uint(ieee802a_tree, hf_ieee802a_oui,
		    tvb, 0, 3, oui);
	}

	/*
	 * Do we have information for this OUI?
	 */
	if (oui_info_table != NULL &&
	    (oui_info = g_hash_table_lookup(oui_info_table,
	      GUINT_TO_POINTER(oui))) != NULL) {
		/*
		 * Yes - use it.
		 */
		hf = *oui_info->field_info->p_id;
		subdissector_table = oui_info->table;
	} else {
		/*
		 * No, use hf_ieee802a_pid for the PID and just dissect
		 * the payload as data.
		 */
		hf = hf_ieee802a_pid;
		subdissector_table = NULL;
	}
	if (tree)
		proto_tree_add_uint(ieee802a_tree, hf, tvb, 3, 2, pid);
	next_tvb = tvb_new_subset_remaining(tvb, 5);
	if (subdissector_table != NULL) {
		/* do lookup with the subdissector table */
		if (dissector_try_uint(subdissector_table, pid, next_tvb,
		    pinfo, tree))
			return;
	}
	call_dissector(data_handle, next_tvb, pinfo, tree);
}
Ejemplo n.º 14
0
/* This function is only called from the IGMP dissector */
int
dissect_igap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
{
    proto_tree *tree;
    proto_item *item;
    guint8 type, tsecs, subtype, asize, msize;
    guchar account[ACCOUNT_SIZE+1], message[MESSAGE_SIZE+1];

    if (!proto_is_protocol_enabled(find_protocol_by_id(proto_igap))) {
	/* we are not enabled, skip entire packet to be nice
	   to the igmp layer. (so clicking on IGMP will display the data)
	   */
	return offset + tvb_length_remaining(tvb, offset);
    }

    item = proto_tree_add_item(parent_tree, proto_igap, tvb, offset, -1, ENC_NA);
    tree = proto_item_add_subtree(item, ett_igap);

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

    type = tvb_get_guint8(tvb, offset);
	col_add_str(pinfo->cinfo, COL_INFO,
		     val_to_str(type, igap_types, "Unknown Type: 0x%02x"));
    proto_tree_add_uint(tree, hf_type, tvb, offset, 1, type);
    offset += 1;

    tsecs = tvb_get_guint8(tvb, offset);
    proto_tree_add_uint_format_value(tree, hf_max_resp, tvb, offset, 1, tsecs,
	"%.1f sec (0x%02x)", tsecs * 0.1, tsecs);
    offset += 1;

    igmp_checksum(tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 0);
    offset += 2;

    proto_tree_add_item(tree, hf_maddr, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset += 4;

    proto_tree_add_uint(tree, hf_version, tvb, offset, 1,
	tvb_get_guint8(tvb, offset));
    offset += 1;

    subtype = tvb_get_guint8(tvb, offset);
    proto_tree_add_uint(tree, hf_subtype, tvb, offset, 1, subtype);
    offset += 2;

    proto_tree_add_uint(tree, hf_challengeid, tvb, offset, 1,
	tvb_get_guint8(tvb, offset));
    offset += 1;

    asize = tvb_get_guint8(tvb, offset);
    proto_tree_add_uint(tree, hf_asize, tvb, offset, 1, asize);
    offset += 1;

    msize = tvb_get_guint8(tvb, offset);
    proto_tree_add_uint(tree, hf_msize, tvb, offset, 1, msize);
    offset += 3;

    if (asize > 0) {
    	if (asize > ACCOUNT_SIZE) {
    	    /* Bogus account size.
    	       XXX - flag this? */
    	    asize = ACCOUNT_SIZE;
    	}
	tvb_memcpy(tvb, account, offset, asize);
	account[asize] = '\0';
	proto_tree_add_string(tree, hf_account, tvb, offset, asize, account);
    }
    offset += ACCOUNT_SIZE;

    if (msize > 0) {
    	if (msize > MESSAGE_SIZE) {
    	    /* Bogus message size.
    	       XXX - flag this? */
    	    msize = MESSAGE_SIZE;
    	}
	tvb_memcpy(tvb, message, offset, msize);
	switch (subtype) {
	case IGAP_SUBTYPE_PASSWORD_JOIN:
	case IGAP_SUBTYPE_PASSWORD_LEAVE:
	    /* Challenge field is user's password */
	    message[msize] = '\0';
	    proto_tree_add_text(tree, tvb, offset, msize,
				"User password: %s", message);
	    break;
	case IGAP_SUBTYPE_CHALLENGE_RESPONSE_JOIN:
	case IGAP_SUBTYPE_CHALLENGE_RESPONSE_LEAVE:
	    /* Challenge field is the results of MD5 calculation */
	    proto_tree_add_text(tree, tvb, offset, msize,
				"Result of MD5 calculation: 0x%s",
				bytes_to_ep_str(message, msize));
	    break;
	case IGAP_SUBTYPE_CHALLENGE:
	    /* Challenge field is the challenge value */
	    proto_tree_add_text(tree, tvb, offset, msize,
				"Challenge: 0x%s",
				bytes_to_ep_str(message, msize));
	    break;
	case IGAP_SUBTYPE_AUTH_MESSAGE:
	    /* Challenge field indicates the result of the authenticaion */
	    proto_tree_add_text(tree, tvb, offset, msize,
				"Authentication result: %s (0x%x)",
				val_to_str_const(message[0], igap_auth_result, "Unknown"),
				message[0]);
	    break;
	case IGAP_SUBTYPE_ACCOUNTING_MESSAGE:
	    /* Challenge field indicates the accounting status */
	    proto_tree_add_text(tree, tvb, offset, msize,
				"Accounting status: %s (0x%x)",
				val_to_str_const(message[0], igap_account_status, "Unknown"),
				message[0]);
	    break;
	default:
	    proto_tree_add_text(tree, tvb, offset, msize,
				"Message: (Unknown)");
	}
    }
    offset += MESSAGE_SIZE;

    if (item) proto_item_set_len(item, offset);
    return offset;
}
Ejemplo n.º 15
0
/* Code to actually dissect the packets */
static void
dissect_dlm3_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                 guint length, int offset)
{
  guint32     m_type;

  m_type   = tvb_get_letohl(tvb, offset);
  proto_tree_add_uint(tree,
                      hf_dlm3_m_type, tvb, offset, 4, m_type);
  col_append_fstr(pinfo->cinfo, COL_INFO,
                ": %s",
                val_to_str_const(m_type,
                                 dlm3_msg,
                                 "Unknown"));

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_nodeid, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_pid, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_lkid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
  /* TODO: See `create_lkb'
     lkid has some structure. We dissect more. */

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_remid, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_parent_lkid, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_parent_remid, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_bitmask(tree, tvb, offset,
                         hf_dlm3_m_exflags, ett_dlm3_m_exflags,
                         m_exflags_fields, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_bitmask(tree, tvb, offset,
                         hf_dlm3_m_sbflags, ett_dlm3_sbflags,
                         m_sbflags_fields, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_bitmask(tree, tvb, offset,
                         hf_dlm3_m_flags, ett_dlm3_m_flags,
                         m_flags_fields, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_lvbseq, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_hash, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_grmode, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_rqmode, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_bastmode, tvb, offset, 4, ENC_LITTLE_ENDIAN);


  offset += 4;
  proto_tree_add_bitmask(tree, tvb, offset,
                         hf_dlm3_m_asts, ett_dlm3_m_asts,
                         m_asts_fields, ENC_LITTLE_ENDIAN);
  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_m_result, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  if ((length - offset) > 0) {
    proto_tree_add_item(tree,
                        hf_dlm3_m_extra,
                        tvb,
                        offset,
                        -1,
                        ENC_NA);
  }
}
Ejemplo n.º 16
0
static void
dissect_lwres(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint16 version, flags, authtype, authlength ;
    guint32 length, opcode, result, recvlength, serial;
    guint32 message_type;

    proto_item* lwres_item;
    proto_tree* lwres_tree;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "lw_res");
    length = tvb_get_ntohl(tvb, LW_LENGTH_OFFSET);
    version = tvb_get_ntohs(tvb, LW_VERSION_OFFSET);
    flags = tvb_get_ntohs(tvb, LW_PKTFLASG_OFFSET);
    serial = tvb_get_ntohl(tvb, LW_SERIAL_OFFSET);
    opcode = tvb_get_ntohl(tvb,LW_OPCODE_OFFSET);
    result = tvb_get_ntohl(tvb, LW_RESULT_OFFSET);
    recvlength = tvb_get_ntohl(tvb, LW_RECVLEN_OFFSET);
    authtype = tvb_get_ntohs(tvb, LW_AUTHTYPE_OFFSET);
    authlength = tvb_get_ntohs(tvb, LW_AUTHLEN_OFFSET);

    message_type = (flags & LWRES_LWPACKETFLAG_RESPONSE) ? 2 : 1;

    col_clear(pinfo->cinfo, COL_INFO);

    if(flags & LWRES_LWPACKETFLAG_RESPONSE)
    {
        col_add_fstr(pinfo->cinfo, COL_INFO,
            "%s, opcode=%s, serial=0x%x, result=%s",
                val_to_str_const((guint32)message_type,message_types_values,"unknown"),
                val_to_str_const(opcode, opcode_values, "unknown"),
                serial,
                val_to_str_const(result,result_values,"unknown"));
    }
    else
    {
        col_add_fstr(pinfo->cinfo, COL_INFO,
                "%s, opcode=%s, serial=0x%x",
                val_to_str_const((guint32)message_type,message_types_values,"unknown"),
                val_to_str_const(opcode, opcode_values, "unknown"),
        serial);
    }

    if(tree)
    {
        lwres_item = proto_tree_add_item(tree,proto_lwres, tvb,0, -1, ENC_NA);
        lwres_tree = proto_item_add_subtree(lwres_item, ett_lwres);
    }
    else return;


    proto_tree_add_uint(lwres_tree,
            hf_length,
            tvb,
            LW_LENGTH_OFFSET,
            sizeof(guint32),
            length);


    proto_tree_add_uint(lwres_tree,
                hf_version,
                tvb,
                LW_VERSION_OFFSET,
                sizeof(guint16),
                version);




    proto_tree_add_uint(lwres_tree,
                hf_flags,
                tvb,
                LW_PKTFLASG_OFFSET,
                sizeof(guint16),
                flags);

    proto_tree_add_uint(lwres_tree,
                hf_serial,
                tvb,
                LW_SERIAL_OFFSET,
                sizeof(guint32),
                serial);

    proto_tree_add_uint(lwres_tree,
                hf_opcode,
                tvb,
                LW_OPCODE_OFFSET,
                sizeof(guint32),
                opcode);

    proto_tree_add_uint(lwres_tree,
                hf_result,
                tvb,
                LW_RESULT_OFFSET,
                sizeof(guint32),
                result);

    proto_tree_add_uint(lwres_tree,
                hf_recvlen,
                tvb,
                LW_RECVLEN_OFFSET,
                sizeof(guint32),
                recvlength);

    proto_tree_add_uint(lwres_tree,
                hf_authtype,
                tvb,
                LW_AUTHTYPE_OFFSET,
                sizeof(guint16),
                authtype);

    proto_tree_add_uint(lwres_tree,
                hf_authlen,
                tvb,
                LW_AUTHLEN_OFFSET,
                sizeof(guint16),
                authlength);

    if(!result)
    {
        switch(opcode)
        {
            case LWRES_OPCODE_NOOP:
                dissect_noop(tvb, lwres_tree);
            break;

            case LWRES_OPCODE_GETADDRSBYNAME:
                dissect_getaddrsbyname(tvb, lwres_tree, message_type);
            break;

            case LWRES_OPCODE_GETNAMEBYADDR:
                dissect_getnamebyaddr(tvb, lwres_tree, message_type);
            break;

            case LWRES_OPCODE_GETRDATABYNAME:
                dissect_getrdatabyname(tvb, lwres_tree, message_type);
            break;
        }
    }
}
Ejemplo n.º 17
0
static void
dissect_dlm3_rcom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                  guint length, int offset)
{
  guint32     rc_type;

  proto_item *sub_item;
  proto_tree *sub_tree;


  rc_type  = tvb_get_letohl(tvb, offset);
  proto_tree_add_uint(tree,
                      hf_dlm3_rc_type, tvb, offset, 4, rc_type);
  col_append_fstr(pinfo->cinfo, COL_INFO,
                  ": %s",
                  val_to_str_const(rc_type,
                                   dlm3_rcom,
                                   "Unknown"));

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_rc_result, tvb, offset, 4, ENC_LITTLE_ENDIAN);

  offset += 4;
  proto_tree_add_item(tree,
                      hf_dlm3_rc_id, tvb, offset, 8, ENC_LITTLE_ENDIAN);

  offset += 8;
  proto_tree_add_item(tree,
                      hf_dlm3_rc_seq, tvb, offset, 8, ENC_LITTLE_ENDIAN);

  offset += 8;
  proto_tree_add_item(tree,
                      hf_dlm3_rc_seq_reply, tvb, offset, 8, ENC_LITTLE_ENDIAN);

  offset += 8;
  if ((length - offset) == 0) {
    /* No rc_buf: Just return */
    return;
  }

  /* Decode rc_buf */
  sub_item = proto_tree_add_item(tree,
                                 hf_dlm3_rc_buf,
                                 tvb,
                                 offset,
                                 -1,
                                 ENC_NA);

  offset += 0;
  if (rc_type == DLM3_RCOM_LOCK) {
    sub_tree = proto_item_add_subtree(sub_item,
                                      ett_dlm3_rcom_lock);
    dissect_dlm3_rcom_lock(tvb, sub_tree, length, offset);
  } else if (rc_type == DLM3_RCOM_STATUS_REPLY) {
    sub_tree = proto_item_add_subtree(sub_item,
                                      ett_dlm3_rcom_config);
    dissect_dlm3_rcom_config(tvb, sub_tree, length, offset);
  }

}
Ejemplo n.º 18
0
/* Code to actually dissect the packets */
static void
dissect_sm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item *ti;
	proto_tree *sm_tree;
	tvbuff_t *next_tvb = NULL;
	guint32 sm_message_type;
	guint32 bsn_num = 0;
	guint32 bh_event_code = 0;
	guint16 protocol;
	guint16 msg_type = 0;
	guint16 length;
	guint16 tag;
	int     offset = 0;

	sm_message_type = tvb_get_ntohl(tvb,offset);

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

	col_add_fstr(pinfo->cinfo, COL_INFO, "Cisco SM Packet (%s)",
		val_to_str_const(sm_message_type, sm_message_type_value_info,"reserved"));

	ti = proto_tree_add_item(tree, proto_sm, tvb, offset, 0, ENC_NA);
	sm_tree = proto_item_add_subtree(ti, ett_sm);

	proto_tree_add_uint_format(sm_tree, hf_sm_sm_msg_type, tvb, offset, 4, sm_message_type,
		"SM Message type: %s (0x%0x)", val_to_str_const(sm_message_type, sm_message_type_value, "reserved"), sm_message_type);

	offset = offset + 4;
	if (sm_message_type ==  MESSAGE_TYPE_PDU) {
		proto_tree_add_item(sm_tree, hf_sm_protocol, tvb, offset, 2, ENC_BIG_ENDIAN);
		protocol = tvb_get_ntohs(tvb,offset);
		offset = offset + 2;
		switch(protocol){
		/* start case RUDP BSM v.1  ---------------------------------------------------------- */
		case SM_PROTOCOL_X004:
			if (!tree)
				return;

			proto_tree_add_item(sm_tree, hf_sm_msg_id, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset = offset +2;
			msg_type = tvb_get_ntohs(tvb,offset);
			proto_tree_add_uint_format(sm_tree, hf_sm_msg_type, tvb, offset, 2, msg_type,
				"Message type: %s (0x%0x)", val_to_str_const(msg_type, sm_pdu_type_value, "reserved"),
				msg_type);
			msg_type = tvb_get_ntohs(tvb,offset);
			offset = offset + 2;
			proto_tree_add_item(sm_tree, hf_sm_channel, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset = offset + 2;
			proto_tree_add_item(sm_tree, hf_sm_bearer, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset = offset +2;
			proto_tree_add_item(sm_tree, hf_sm_len, tvb, offset, 2, ENC_BIG_ENDIAN);
			length = tvb_get_ntohs(tvb,offset);
			offset = offset +2;
			proto_item_set_len(ti, 16);

			if (length > 0) {
				next_tvb = tvb_new_subset(tvb, offset, length, length);

				if ((msg_type == PDU_MTP3_TO_SLT || msg_type == PDU_MTP3_FROM_SLT)) {
					call_dissector(q931_handle, next_tvb, pinfo, tree);
				} else {
					call_dissector(data_handle, next_tvb, pinfo, tree);
				}
			}

			break;
			/* end case RUDP BSM v.1 ---------------------------------------------------------- */

		case SM_PROTOCOL_X100:
		case SM_PROTOCOL_X122:
			if (!tree)
				return;
			/* Protocol 0x100/0x122 only contains a length and then an EISUP packet */
			proto_tree_add_item(sm_tree, hf_sm_len, tvb, offset, 2, ENC_BIG_ENDIAN);
			length = tvb_get_ntohs(tvb,offset);
			offset = offset + 2;
			proto_item_set_len(ti, 8);

			/* This should be the EISUP dissector but we havent got one
			 * right now - so decode it as data for now ... */
			next_tvb = tvb_new_subset(tvb, offset, length, length);
			call_dissector(data_handle, next_tvb, pinfo, sm_tree);

			break;
		case SM_PROTOCOL_X101:
			if (!tree)
				return;
			/* XXX Reverse enginered so this may not be correct!!!
			 * EISUP - used between Cisco HSI and Cisco PGW devices,
			 * uses RUDP with default port number 8003.
			 * Protocol stack is RUDP->Cisco SM->SDP.
			 * This implementation is PROPRIETARY
			 */
			proto_tree_add_item(sm_tree, hf_sm_len, tvb, offset, 2, ENC_BIG_ENDIAN);
			length = tvb_get_ntohs(tvb,offset);
			offset = offset + 2;
			proto_item_set_len(ti, length + offset);
			/* The next stuff seems to be IP addr */
			proto_tree_add_item(sm_tree, hf_sm_ip_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset = offset + 4;
			/* This part looks to be the same per session */
			proto_tree_add_item(sm_tree, hf_sm_context, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset = offset +4;
			/* Some sort of message type? */
			proto_tree_add_item(sm_tree, hf_sm_eisup_msg_id, tvb, offset, 1, ENC_BIG_ENDIAN);
			offset = offset + 1;
			/* XXX Problem are tags 1 or two bytes???*/
			proto_tree_add_item(sm_tree, hf_sm_tag, tvb, offset, 2, ENC_BIG_ENDIAN);

			tag = tvb_get_ntohs(tvb,offset);
			offset = offset +2;
			if (tag== 0x01ac) {
				proto_tree_add_item(sm_tree, hf_sm_len, tvb, offset, 2, ENC_BIG_ENDIAN);
				length = tvb_get_ntohs(tvb,offset);
				offset = offset +2;
				next_tvb = tvb_new_subset(tvb, offset, length, length);
				call_dissector(sdp_handle, next_tvb, pinfo, sm_tree);
				offset = offset+length;

			}
			/*return;*/
			break;
		case SM_PROTOCOL_X114:
			if (!tree)
				return;
			/* XXX Reverse enginered so this may not be correct!!! */
			proto_tree_add_item(sm_tree, hf_sm_len, tvb, offset, 2, ENC_BIG_ENDIAN);
			length = tvb_get_ntohs(tvb,offset);
			offset = offset + 2;
			proto_item_set_len(ti, length + offset);
			/* The next stuff seems to be IP addr */
			proto_tree_add_item(sm_tree, hf_sm_ip_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset = offset + 4;
			proto_tree_add_item(sm_tree, hf_sm_context, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset = offset +4;
			/* Some sort of message type? */
			proto_tree_add_item(sm_tree, hf_sm_eisup_msg_id, tvb, offset, 1, ENC_BIG_ENDIAN);
			offset = offset + 1;
			/* XXX Problem are tags 1 or two bytes???*/
			proto_tree_add_item(sm_tree, hf_sm_tag, tvb, offset, 2, ENC_BIG_ENDIAN);

			tag = tvb_get_ntohs(tvb,offset);
			offset = offset +2;
			if (tag== 0x01ac) {
				proto_tree_add_item(sm_tree, hf_sm_len, tvb, offset, 2, ENC_BIG_ENDIAN);
				length = tvb_get_ntohs(tvb,offset);
				offset = offset +2;
				next_tvb = tvb_new_subset(tvb, offset, length, length);
				call_dissector(sdp_handle, next_tvb, pinfo, sm_tree);
				offset = offset+length;

			}
			break;
		default:
			proto_tree_add_item(sm_tree, hf_sm_msg_id, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset = offset +2;
			msg_type = tvb_get_ntohs(tvb,offset);
			proto_tree_add_uint_format(sm_tree, hf_sm_msg_type, tvb, offset, 2, msg_type,
				"Message type: %s (0x%0x)", val_to_str_const(msg_type, sm_pdu_type_value, "reserved"),
				msg_type);
			msg_type = tvb_get_ntohs(tvb,offset);
			offset = offset + 2;
			proto_tree_add_item(sm_tree, hf_sm_channel, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset = offset + 2;
			proto_tree_add_item(sm_tree, hf_sm_bearer, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset = offset +2;
			proto_tree_add_item(sm_tree, hf_sm_len, tvb, offset, 2, ENC_BIG_ENDIAN);
			length = tvb_get_ntohs(tvb,offset);
			offset = offset +2;
			proto_item_set_len(ti, 16);

			if (length > 0) {
				next_tvb = tvb_new_subset(tvb, offset, length, length);

				switch (msg_type) {
				case PDU_MTP3_TO_SLT:
				case PDU_MTP3_FROM_SLT:
					call_dissector(mtp3_handle, next_tvb, pinfo, tree);
					break;
				case PDU_CONNECT_REQUEST:
				case PDU_CONNECT_CONFIRM:
					proto_tree_add_item(sm_tree, hf_sm_alignment_type, tvb, offset, 4, ENC_BIG_ENDIAN);
					break;
				case PDU_DISCONNECT_CONFIRM:
				case PDU_DISCONNECT_INDICATION:
					proto_tree_add_item(sm_tree, hf_sm_backhaul_reason_code, tvb, offset, 4, ENC_BIG_ENDIAN);
					break;
				case PDU_RETRIEVAL_REQUEST:
				case PDU_RETRIEVAL_CONFIRM:
					proto_tree_add_item(sm_tree, hf_sm_retrieval_type, tvb, offset, 4, ENC_BIG_ENDIAN);
					if (msg_type == PDU_RETRIEVAL_CONFIRM && tvb_get_ntohl(tvb,offset) == 0x01) {
						offset += 4;
						bsn_num = tvb_get_ntohl(tvb,offset);
						proto_tree_add_uint_format(sm_tree, hf_sm_bsn_num, tvb, offset, 4,
												   bsn_num, "BSN: %d", bsn_num);
					}
					break;
				case PDU_LSC_REQUEST:
				case PDU_LSC_CONFIRM:
					proto_tree_add_item(sm_tree, hf_sm_lsc_state_type, tvb, offset, 4, ENC_BIG_ENDIAN);
					break;
				case PDU_LSC_INDICATION:
					proto_tree_add_item(sm_tree, hf_sm_backhaul_event_code, tvb, offset, 4, ENC_BIG_ENDIAN);
					bh_event_code = tvb_get_ntohl(tvb,offset);
					if (bh_event_code == 0x02 || bh_event_code == 0x04) {
						offset += 4;
						proto_tree_add_item(sm_tree, hf_sm_linkdown_cause_code, tvb, offset, 4, ENC_BIG_ENDIAN);
					} else if (bh_event_code == 0x06) {
						offset += 4;
						proto_tree_add_item(sm_tree, hf_sm_backhaul_cause_code, tvb, offset, 4, ENC_BIG_ENDIAN);
					}
					break;
				case PDU_STAT_REQUEST:
					proto_tree_add_item(sm_tree, hf_sm_stat_request_type, tvb, offset, 4, ENC_BIG_ENDIAN);
					break;
				default:
					call_dissector(data_handle, next_tvb, pinfo, tree);
				}
			}
		}
	}
}
Ejemplo n.º 19
0
/* Broadcasts are searches, offers or promises.
 *
 * Searches are sent by
 * a peer when it needs a file (ie. while applying its policy, when it needs
 * files such as installers to install software.)
 *
 * Each broadcast relates to one file and each file is identified only by its
 * checksum - no file names are ever used. A search times out after 10 seconds
 * (configurable) and the peer will then attempt to act on any offers by
 * downloading (via push or pull - see dissect_ldss_transfer) from those peers.
 *
 * If no offers are received, the search fails and the peer fetches the file
 * from a remote server, generally a HTTP server on the other side of a WAN.
 * The protocol exists to minimize the number of WAN downloads needed.
 *
 * While downloading from WAN the peer sends promises to inform other peers
 * when it will be available for them to download. This prevents multiple peers
 * simultaneously downloading the same file. Promises also inform other peers
 * how much download bandwidth is being used by their download. Other peers use
 * this information and the configured knowledge of the WAN bandwidth to avoid
 * saturating the WAN link, as file downloads are a non-time-critical and
 * non-business-critical network function. LDSS is intended for networks of
 * 5-20 machines connected by slow WAN link. The current implementation of the
 * protocol allows administrator to configure "time windows" when WAN usage is
 * throttled/unthrottled, though this isn't visible in LDSS.
 *
 * Once a WAN download or a LAN transfer (see below above dissect_ldss_transfer)
 * has complete the peer will offer the file to other peers on the LAN so they
 * don't need to download it themselves.
 *
 * Peers also notify when they shut down in case any other peer is waiting for
 * a file. */
static int
dissect_ldss_broadcast(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint16	messageID;
	guint8 digest_type;
	guint8 compression;
	guint32 cookie;
	guint8 *digest;
	guint64	size;
	guint64	offset;
	guint32	targetTime;
	guint16 port;
	guint16	rate;
	guint16 messageDetail = INFERRED_NONE;

	proto_tree	*ti, *ldss_tree;

	const gchar *packet_type, *packet_detail;

	messageID   = tvb_get_ntohs  (tvb,  0);
	digest_type = tvb_get_guint8 (tvb,  2);
	compression = tvb_get_guint8 (tvb,  3);
	cookie      = tvb_get_ntohl  (tvb,  4);
	digest      = (guint8 *)tvb_memdup (NULL, tvb,  8, DIGEST_LEN);
	size	    = tvb_get_ntoh64 (tvb, 40);
	offset	    = tvb_get_ntoh64 (tvb, 48);
	targetTime  = tvb_get_ntohl  (tvb, 56);
	port        = tvb_get_ntohs  (tvb, 64);
	rate	    = tvb_get_ntohs  (tvb, 66);

	packet_type = val_to_str_const(messageID, ldss_message_id_value, "unknown");

	if (messageID == MESSAGE_ID_WILLSEND) {
		if (cookie == 0) {
			/* Shutdown: Dishonor promises from this peer. Current
			 * implementation abuses WillSend for this. */
			messageDetail = INFERRED_PEERSHUTDOWN;
		}
		else if (size == 0 && offset == 0) {
			/* NeedFile search failed - going to WAN */
			messageDetail = INFERRED_WANDOWNLOAD;
		}
		else if (size > 0) {
			/* Size is known (not always the case) */
			if (size == offset) {
				/* File is available for pull on this peer's TCP port */
				messageDetail = INFERRED_OFFER;
			}
			else {
				/* WAN download progress announcement from this peer */
				messageDetail = INFERRED_PROMISE;
			}
		}
	}
	else if (messageID == MESSAGE_ID_NEEDFILE) {
		messageDetail = INFERRED_SEARCH;
	}
	packet_detail = val_to_str_const(messageDetail, ldss_inferred_info, "unknown");

	/* Set the info column */
	col_add_fstr(pinfo->cinfo, COL_INFO, "LDSS Broadcast (%s%s)",
			     packet_type,
			     packet_detail);

	/* If we have a non-null tree (ie we are building the proto_tree
	 * instead of just filling out the columns), then give more detail. */
	if (tree) {
		ti = proto_tree_add_item(tree, proto_ldss,
					 tvb, 0, (tvb_captured_length(tvb) > 72) ? tvb_captured_length(tvb) : 72, ENC_NA);
		ldss_tree = proto_item_add_subtree(ti, ett_ldss_broadcast);

		proto_tree_add_item(ldss_tree, hf_ldss_message_id,
				    tvb, 0, 2, ENC_BIG_ENDIAN);
		ti = proto_tree_add_uint(ldss_tree, hf_ldss_message_detail,
					 tvb, 0, 0, messageDetail);
		PROTO_ITEM_SET_GENERATED(ti);
		proto_tree_add_item(ldss_tree, hf_ldss_digest_type,
				    tvb, 2,	    1,	ENC_BIG_ENDIAN);
		proto_tree_add_item(ldss_tree, hf_ldss_compression,
				    tvb, 3,	    1,	ENC_BIG_ENDIAN);
		proto_tree_add_uint_format_value(ldss_tree, hf_ldss_cookie,
						 tvb, 4,	    4,	FALSE,
						 "0x%x%s",
						 cookie,
						 (cookie == 0)
						 ? " - shutdown (promises from this peer are no longer valid)"
						 : "");
		proto_tree_add_item(ldss_tree, hf_ldss_digest,
				    tvb, 8,	    DIGEST_LEN, ENC_NA);
		proto_tree_add_item(ldss_tree, hf_ldss_size,
				    tvb, 40,    8,	ENC_BIG_ENDIAN);
		proto_tree_add_item(ldss_tree, hf_ldss_offset,
				    tvb, 48,    8,	ENC_BIG_ENDIAN);
		proto_tree_add_uint_format_value(ldss_tree, hf_ldss_target_time,
						 tvb, 56,    4,	FALSE,
						 "%d:%02d:%02d",
						 (int)(targetTime / 3600),
						 (int)((targetTime / 60) % 60),
						 (int)(targetTime % 60));
		proto_tree_add_item(ldss_tree, hf_ldss_reserved_1,
				    tvb, 60,    4,	ENC_BIG_ENDIAN);
		proto_tree_add_uint_format_value(ldss_tree, hf_ldss_port,
						 tvb, 64,    2,	FALSE,
						 "%d%s",
						 port,
						 (messageID == MESSAGE_ID_WILLSEND &&
						  size > 0 &&
						  size == offset)
						 ? " - file can be pulled at this TCP port"
						 : (messageID == MESSAGE_ID_NEEDFILE
						    ? " - file can be pushed to this TCP port"
						    : ""));
		proto_tree_add_uint_format_value(ldss_tree, hf_ldss_rate,
						 tvb, 66,    2,	FALSE,
						 "%ld",
						 (rate > 0)
						 ? (long)floor(exp(rate * G_LN2 / 2048))
						 : 0);
		proto_tree_add_item(ldss_tree, hf_ldss_priority,
				    tvb, 68, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(ldss_tree, hf_ldss_property_count,
				    tvb, 70, 2, ENC_BIG_ENDIAN);
		if (tvb_reported_length(tvb) > 72) {
			proto_tree_add_item(ldss_tree, hf_ldss_properties,
					    tvb, 72, tvb_captured_length(tvb) - 72, ENC_NA);
		}
	}

	/* Finally, store the broadcast and register ourselves to dissect
	 * any pushes or pulls that result from this broadcast. All data
	 * is pushed/pulled over TCP using the port from the broadcast
	 * packet's port field.
	 * Track each by a TCP conversation with the remote end wildcarded.
	 * The TCP conv tracks back to a broadcast conv to determine what it
	 * is in response to.
	 *
	 * These steps only need to be done once per packet, so a variable
	 * tracks the highest frame number seen. Handles the case of first frame
	 * being frame zero. */
	if (messageDetail != INFERRED_PEERSHUTDOWN &&
	    (highest_num_seen == 0 ||
	     highest_num_seen < pinfo->num)) {

		ldss_broadcast_t *data;

		/* Populate data from the broadcast */
		data = wmem_new0(wmem_file_scope(), ldss_broadcast_t);
		data->num = pinfo->num;
		data->ts = pinfo->abs_ts;
		data->message_id = messageID;
		data->message_detail = messageDetail;
		data->port = port;
		data->size = size;
		data->offset = offset;
		data->compression = compression;

		data->file = wmem_new0(wmem_file_scope(), ldss_file_t);
		data->file->digest = digest;
		data->file->digest_type = digest_type;

		data->broadcaster = wmem_new0(wmem_file_scope(), ldss_broadcaster_t);
		copy_address(&data->broadcaster->addr, &pinfo->src);
		data->broadcaster->port = port;

		/* Dissect any future pushes/pulls */
		if (port > 0) {
			prepare_ldss_transfer_conv(data);
		}

		/* Record that the frame was processed */
		highest_num_seen = pinfo->num;
	}

	return tvb_captured_length(tvb);
}
Ejemplo n.º 20
0
/*
 * Dissect SNAP header; used elsewhere, e.g. in the Frame Relay dissector.
 */
void
dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
    proto_tree *snap_tree, int control, int hf_oui, int hf_type, int hf_pid,
    int bridge_pad)
{
	guint32		oui;
	guint16		etype;
	tvbuff_t	*next_tvb;
	oui_info_t	*oui_info;
	dissector_table_t subdissector_table;
	int		hf;
	int		mesh_header_len;

	/*
	 * XXX - what about non-UI frames?
	 */
	oui =	tvb_get_ntoh24(tvb, offset);
	etype = tvb_get_ntohs(tvb, offset+3);

	col_append_fstr(pinfo->cinfo, COL_INFO,
		    "; SNAP, OUI 0x%06X (%s), PID 0x%04X",
		    oui, val_to_str_const(oui, oui_vals, "Unknown"), etype);

	proto_tree_add_uint(snap_tree, hf_oui, tvb, offset, 3, oui);

	switch (oui) {

	case OUI_HP_2:
		oui_info = get_snap_oui_info(oui);
		hf = *oui_info->field_info->p_id;
		proto_tree_add_uint(snap_tree, hf, tvb, offset+3, 2, etype);
		next_tvb = tvb_new_subset_remaining(tvb, offset+5);

		if(!dissector_try_uint(hpteam_subdissector_table,etype, next_tvb, pinfo, tree))
	 		call_dissector(data_handle, next_tvb, pinfo, tree);
		break;

	case OUI_ENCAP_ETHER:
	case OUI_CISCO_90:
	case OUI_APPLE_ATALK:
		/* No, I have no idea why Apple used
		   one of their own OUIs, rather than
		   OUI_ENCAP_ETHER, and an Ethernet
		   packet type as protocol ID, for
		   AppleTalk data packets - but used
		   OUI_ENCAP_ETHER and an Ethernet
		   packet type for AARP packets. */
		if (XDLC_IS_INFORMATION(control)) {
			if (tree) {
				proto_tree_add_uint(snap_tree, hf_type,
				    tvb, offset+3, 2, etype);
			}
			next_tvb = tvb_new_subset_remaining(tvb, offset+5);
			if (!dissector_try_uint(ethertype_subdissector_table,
			    etype, next_tvb, pinfo, tree))
				call_dissector(data_handle, next_tvb, pinfo,
				    tree);
		} else {
			next_tvb = tvb_new_subset_remaining(tvb, offset+5);
			call_dissector(data_handle, next_tvb, pinfo, tree);
		}
		break;

	case OUI_BRIDGED:
		/*
		 * MAC frames bridged over ATM (RFC 2684) or Frame Relay
		 * (RFC 2427).
		 *
		 * We have to figure out how much padding to put
		 * into the frame.  We were handed a "bridge_pad"
		 * argument which should be 0 for Frame Relay and
		 * 2 for ATM; we add to that the amount of padding
		 * common to both bridging types.
		 */
		if (tree) {
			proto_tree_add_uint(snap_tree, hf_pid, tvb, offset+3, 2,
			    etype);
		}

		switch (etype) {

		case BPID_ETH_WITH_FCS:
			next_tvb = tvb_new_subset_remaining(tvb, offset+5+bridge_pad);
			call_dissector(eth_withfcs_handle, next_tvb, pinfo,
			    tree);
			break;

		case BPID_ETH_WITHOUT_FCS:
			next_tvb = tvb_new_subset_remaining(tvb, offset+5+bridge_pad);
			call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree);
			break;

		case BPID_802_5_WITH_FCS:
		case BPID_802_5_WITHOUT_FCS:
			/*
			 * We treat the last padding byte as the Access
			 * Control byte, as that's what the Token
			 * Ring dissector expects the first byte to
			 * be.
			 */
			next_tvb = tvb_new_subset_remaining(tvb, offset+5+bridge_pad);
			call_dissector(tr_handle, next_tvb, pinfo, tree);
			break;

		case BPID_FDDI_WITH_FCS:
		case BPID_FDDI_WITHOUT_FCS:
			next_tvb = tvb_new_subset_remaining(tvb, offset+5+1+bridge_pad);
			call_dissector(fddi_handle, next_tvb, pinfo, tree);
			break;

		case BPID_BPDU:
			next_tvb = tvb_new_subset_remaining(tvb, offset+5);
			call_dissector(bpdu_handle, next_tvb, pinfo, tree);
			break;

		default:
			next_tvb = tvb_new_subset_remaining(tvb, offset+5);
			call_dissector(data_handle, next_tvb, pinfo, tree);
			break;
		}
		break;

	case OUI_CABLE_BPDU:    /* DOCSIS cable modem spanning tree BPDU */
		if (tree) {
			proto_tree_add_uint(snap_tree, hf_pid, tvb, offset+3, 2,
			    etype);
		}
		next_tvb = tvb_new_subset_remaining(tvb, offset+5);
		call_dissector(bpdu_handle, next_tvb, pinfo, tree);
		break;

	case OUI_TURBOCELL:
		next_tvb = tvb_new_subset_remaining(tvb, offset+3);
		call_dissector(turbo_handle, next_tvb, pinfo, tree);
		break;

	case OUI_MARVELL:
		/*
		 * OLPC packet.  The PID is an Ethertype, but
		 * there's a mesh header between the PID and
		 * the payload.
		 */
		if (XDLC_IS_INFORMATION(control)) {
			if (tree) {
				proto_tree_add_uint(snap_tree, hf_type,
				    tvb, offset+3, 2, etype);
			}
			next_tvb = tvb_new_subset_remaining(tvb, offset+5);
			mesh_header_len = call_dissector(mesh_handle,
			    next_tvb, pinfo, tree);
			next_tvb = tvb_new_subset_remaining(tvb, offset+5+mesh_header_len);
			if (!dissector_try_uint(ethertype_subdissector_table,
			    etype, next_tvb, pinfo, tree))
				call_dissector(data_handle, next_tvb, pinfo,
				    tree);
		} else {
			next_tvb = tvb_new_subset_remaining(tvb, offset+5);
			call_dissector(data_handle, next_tvb, pinfo, tree);
		}
		break;

	default:
		/*
		 * Do we have information for this OUI?
		 */
		oui_info = get_snap_oui_info(oui);
		if (oui_info != NULL) {
			/*
			 * Yes - use it.
			 */
			hf = *oui_info->field_info->p_id;
			subdissector_table = oui_info->table;
		} else {
			/*
			 * No, use hf_pid for the PID and just dissect
			 * the payload as data.
			 */
			hf = hf_pid;
			subdissector_table = NULL;
		}
		if (tree) {
			proto_tree_add_uint(snap_tree, hf, tvb, offset+3, 2,
			    etype);
		}
		next_tvb = tvb_new_subset_remaining(tvb, offset+5);
		if (XDLC_IS_INFORMATION(control)) {
			if (subdissector_table != NULL) {
				/* do lookup with the subdissector table */
				if (dissector_try_uint(subdissector_table,
				    etype, next_tvb, pinfo, tree))
					break;
			}
		}
		call_dissector(data_handle, next_tvb, pinfo, tree);
		break;
	}
}
Ejemplo n.º 21
0
static void dissect_mqpcf_parm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mq_tree,
                               guint offset, guint32 uCount, guint bLittleEndian, gboolean bParse)
{
    guint32 u    = 0;
    guint32 tOfs = 0;
    guint32 uLenF;
    char    strPrm[256];
    guint32 uTyp;
    guint32 uLen = 0;
    guint32 uPrm;
    guint32 uCnt;
    guint32 uCCS;
    guint32 uSLn;
    guint32 uVal;
    guint64 uVal64;
    guint32 uDig;

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

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

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

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

    uDig = dissect_mqpcf_getDigits(uCount);

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

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

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

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

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

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

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

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

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

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

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

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

                hfinfo = proto_registrar_get_nth(hf_mq_pcf_stringlist);

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

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

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

                uDigit = dissect_mqpcf_getDigits(uCnt);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                hfinfo = proto_registrar_get_nth(hf_mq_pcf_int64list);

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

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

                offset += uLenF + 4;
                for (u2 = 0; u2 < uCnt && u2 < mq_pcf_maxlst; u2++)
                {
                    uVal64 = tvb_get_guint64_endian(tvb, offset, bLittleEndian);
                    proto_tree_add_int64_format(tree, hf_mq_pcf_int64list, tvb, offset, 8, uVal64,
                        "%s[%*d]: %" G_GINT64_MODIFIER "d", hfinfo->name, uDigit, u2+1, uVal64);
                    offset += 8;
                }
                if (u2 != uCnt)
                {
                    ti = proto_tree_add_text(tree, tvb, offset, uLen, sMaxLst, u2, uCnt);
                    expert_add_info(pinfo, ti, &ei_mq_pcf_MaxI64);
                }
            }
            break;
        }
        offset = tOfs+uLen;
    }
    if (u != uCount)
    {
        ti = proto_tree_add_text(mq_tree, tvb, offset, uLen, sMaxPrm, u, uCount);
        expert_add_info(pinfo, ti, &ei_mq_pcf_MaxPrm);
    }
}
Ejemplo n.º 22
0
static int
add_option_info(tvbuff_t *tvb, int pos, proto_tree *tree, proto_item *ti)
{
    guint8      tag, length, fcs_err = 0, encr = 0, seen_fcs_err = 0;
    proto_tree *tag_tree;
    proto_item *tag_item;

    /*
     * Read all option tags in an endless loop. If the packet is malformed this
     * loop might be a problem.
     */
    while (TRUE) {
        tag = tvb_get_guint8(tvb, pos);
        if ((tag != TZSP_HDR_PAD) && (tag != TZSP_HDR_END)) {
            length = tvb_get_guint8(tvb, pos+1);
            tag_item = proto_tree_add_text(tree, tvb, pos, 2+length, "%s", val_to_str_const(tag, option_tag_vals, "Unknown"));
        } else {
            tag_item = proto_tree_add_text(tree, tvb, pos, 1, "%s", val_to_str_const(tag, option_tag_vals, "Unknown"));
            length = 0;
        }

        tag_tree = proto_item_add_subtree(tag_item, ett_tag);

        proto_tree_add_item(tag_tree, hf_option_tag, tvb, pos, 1, ENC_NA);
        pos++;
        if ((tag != TZSP_HDR_PAD) && (tag != TZSP_HDR_END)) {
            proto_tree_add_item(tag_tree, hf_option_length, tvb, pos, 1, ENC_NA);
            pos++;
        }

        switch (tag) {
        case TZSP_HDR_PAD:
            break;

        case TZSP_HDR_END:
            /* Fill in header with information from other tags. */
            if (seen_fcs_err) {
                proto_item_append_text(ti,"%s", fcs_err?"FCS Error":(encr?"Encrypted":"Good"));
            }
            return pos;

        case TZSP_HDR_ORIGINAL_LENGTH:
            proto_tree_add_item(tag_tree, hf_original_length, tvb, pos, 2, ENC_BIG_ENDIAN);
            break;

        case WLAN_RADIO_HDR_SIGNAL:
            proto_tree_add_item(tag_tree, hf_signal, tvb, pos, 1, ENC_NA);
            break;

        case WLAN_RADIO_HDR_NOISE:
            proto_tree_add_item(tag_tree, hf_silence, tvb, pos, 1, ENC_NA);
            break;

        case WLAN_RADIO_HDR_RATE:
            proto_tree_add_item(tag_tree, hf_rate, tvb, pos, 1, ENC_NA);
            break;

        case WLAN_RADIO_HDR_TIMESTAMP:
            proto_tree_add_item(tag_tree, hf_time, tvb, pos, 4, ENC_BIG_ENDIAN);
            break;

        case WLAN_RADIO_HDR_MSG_TYPE:
            proto_tree_add_item(tag_tree, hf_status_msg_type, tvb, pos, 1, ENC_NA);
            break;

        case WLAN_RADIO_HDR_CF:
            proto_tree_add_item(tag_tree, hf_status_pcf, tvb, pos, 1, ENC_NA);
            break;

        case WLAN_RADIO_HDR_UN_DECR:
            proto_tree_add_item(tag_tree, hf_status_undecrypted, tvb, pos, 1, ENC_NA);
            encr = tvb_get_guint8(tvb, pos);
            break;

        case WLAN_RADIO_HDR_FCS_ERR:
            seen_fcs_err = 1;
            proto_tree_add_item(tag_tree, hf_status_fcs_error, tvb, pos, 1, ENC_NA);
            fcs_err = tvb_get_guint8(tvb, pos);
            break;

        case WLAN_RADIO_HDR_CHANNEL:
            proto_tree_add_item(tag_tree, hf_channel, tvb, pos, 1, ENC_NA);
            break;

        case TZSP_HDR_SENSOR:
            proto_tree_add_item(tag_tree, hf_sensormac, tvb, pos, 6, ENC_NA);
            break;

        default:
            proto_tree_add_item(tag_tree, hf_unknown, tvb, pos, length, ENC_NA);
            break;
        }

        pos += length;
    }
}
Ejemplo n.º 23
0
static void
llc_sap_value( gchar *result, guint32 sap )
{
	g_snprintf( result, ITEM_LABEL_LENGTH, "%s", val_to_str_const(sap<<1, sap_vals, "Unknown"));
}
Ejemplo n.º 24
0
static proto_tree *
add_integer_tree(proto_tree *tree, tvbuff_t *tvb, int offset,
                 int name_length, int value_length, guint8 tag)
{
    proto_tree *subtree;
    guint8      bool_val;

    switch (tag) {

    case TAG_BOOLEAN:
        if (value_length != 1) {
            subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                     1 + 2 + name_length + 2 + value_length,
                                     ett_ipp_attr, NULL, "%s: Invalid boolean (length is %u, should be 1)",
                                     tvb_format_text(tvb, offset + 1 + 2, name_length),
                                     value_length);
        } else {
            bool_val = tvb_get_guint8(tvb,
                                      offset + 1 + 2 + name_length + 2);
            subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                     1 + 2 + name_length + 2 + value_length,
                                     ett_ipp_attr, NULL, "%s: %s",
                                     tvb_format_text(tvb, offset + 1 + 2, name_length),
                                     val_to_str(bool_val, bool_vals, "Unknown (0x%02x)"));
        }
        break;

    case TAG_INTEGER:
    case TAG_ENUM:
        if (value_length != 4) {
            subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                     1 + 2 + name_length + 2 + value_length,
                                     ett_ipp_attr, NULL, "%s: Invalid integer (length is %u, should be 4)",
                                     tvb_format_text(tvb, offset + 1 + 2, name_length),
                                     value_length);
        } else {
            const char *name_val;
            /* Some fields in IPP are really unix timestamps but IPP
             * transports these as 4 byte integers.
             * A simple heuristic to make the display of these fields
             * more human readable is to assume that if the field name
             * ends in '-time' then assume they are timestamps instead
             * of integers.
             */
            name_val=tvb_get_ptr(tvb, offset + 1 + 2, name_length);
            if ((name_length > 5) && name_val && !tvb_memeql(tvb, offset + 1 + 2 + name_length - 5, "-time", 5)) {
                subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                         1 + 2 + name_length + 2 + value_length,
                                         ett_ipp_attr, NULL, "%s: %s",
                                         format_text(name_val, name_length),
                                         abs_time_secs_to_str(wmem_packet_scope(), tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2),
                                                              ABSOLUTE_TIME_LOCAL,
                                                              TRUE));

            }
            else if ((name_length > 5) && name_val && !tvb_memeql(tvb, offset + 1 + 2, "printer-state", 13)) {
                subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                         1 + 2 + name_length + 2 + value_length,
                                         ett_ipp_attr, NULL, "%s: %s",
                                         format_text(name_val, name_length),
                                         val_to_str_const(tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2),
                                                          printer_state_vals,
                                                          "Unknown Printer State"));
            }
            else if ((name_length > 5) && name_val && !tvb_memeql(tvb, offset + 1 + 2, "job-state", 9)) {
                subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                         1 + 2 + name_length + 2 + value_length,
                                         ett_ipp_attr, NULL, "%s: %s",
                                         format_text(name_val, name_length),
                                         val_to_str_const(tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2),
                                                          job_state_vals,
                                                          "Unknown Job State"));
            }
            else {
                subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                         1 + 2 + name_length + 2 + value_length,
                                         ett_ipp_attr, NULL, "%s: %u",
                                         format_text(name_val, name_length),
                                         tvb_get_ntohl(tvb, offset + 1 + 2 + name_length + 2));
            }
        }
        break;

    default:
        subtree = proto_tree_add_subtree_format(tree, tvb, offset,
                                 1 + 2 + name_length + 2 + value_length,
                                 ett_ipp_attr, NULL, "%s: Unknown integer type 0x%02x",
                                 tvb_format_text(tvb, offset + 1 + 2, name_length),
                                 tag);
        break;
    }
    return subtree;
}
Ejemplo n.º 25
0
/* Dissect details of packet */
static void rlogin_display(rlogin_hash_entry_t *hash_info,
			   tvbuff_t *tvb,
			   packet_info *pinfo,
			   proto_tree *tree,
			   struct tcpinfo *tcpinfo)
{
	/* Display the proto tree */
	int             offset = 0;
	proto_tree      *rlogin_tree, *user_info_tree, *window_tree;
	proto_item      *ti;
	guint           length;
	int             str_len;
	gint            ti_offset;
	proto_item      *user_info_item, *window_info_item;

	/* Create rlogin subtree */
	ti = proto_tree_add_item(tree, proto_rlogin, tvb, 0, -1, ENC_NA);
	rlogin_tree = proto_item_add_subtree(ti, ett_rlogin);

	/* Return if data empty */
	length = tvb_captured_length(tvb);
	if (length == 0)
	{
		return;
	}

	/*
	 * XXX - this works only if the urgent pointer points to something
	 * in this segment; to make it work if the urgent pointer points
	 * to something past this segment, we'd have to remember the urgent
	 * pointer setting for this conversation.
	 */
	if (tcpinfo && IS_TH_URG(tcpinfo->flags) &&      /* if urgent pointer set */
	    length >= tcpinfo->urgent_pointer) /* and it's in this frame */
	{
		/* Get urgent byte into Temp */
		int urgent_offset = tcpinfo->urgent_pointer - 1;
		guint8 control_byte;

		/* Check for text data in front */
		if (urgent_offset > offset)
		{
			proto_tree_add_item(rlogin_tree, hf_data, tvb, offset, urgent_offset, ENC_ASCII|ENC_NA);
		}

		/* Show control byte */
		proto_tree_add_item(rlogin_tree, hf_control_message, tvb,
		                    urgent_offset, 1, ENC_BIG_ENDIAN);
		control_byte = tvb_get_guint8(tvb, urgent_offset);
		col_append_fstr(pinfo->cinfo, COL_INFO,
			               " (%s)", val_to_str_const(control_byte, control_message_vals, "Unknown"));

		offset = urgent_offset + 1; /* adjust offset */
	}
	else
	if (tvb_get_guint8(tvb, offset) == '\0')
	{
		/* Startup */
		if (pinfo->srcport == RLOGIN_PORT)   /* from server */
		{
			proto_tree_add_item(rlogin_tree, hf_startup_info_received_flag,
			                    tvb, offset, 1, ENC_BIG_ENDIAN);
		}
		else
		{
			proto_tree_add_item(rlogin_tree, hf_client_startup_flag,
			                    tvb, offset, 1, ENC_BIG_ENDIAN);
		}
		++offset;
	}

	if (!tvb_offset_exists(tvb, offset))
	{
		/* No more data to check */
		return;
	}

	if (hash_info->info_framenum == pinfo->num)
	{
		gint info_len;
		gint slash_offset;

		/* First frame of conversation, assume user info... */

		info_len = tvb_captured_length_remaining(tvb, offset);
		if (info_len <= 0)
			return;

		/* User info tree */
		user_info_item = proto_tree_add_string_format(rlogin_tree, hf_user_info, tvb,
		                                              offset, info_len, FALSE,
		                                              "User info (%s)",
		                                              tvb_format_text(tvb, offset, info_len));
		user_info_tree = proto_item_add_subtree(user_info_item,
		                                        ett_rlogin_user_info);

		/* Client user name. */
		str_len = tvb_strsize(tvb, offset);
		proto_tree_add_item(user_info_tree, hf_user_info_client_user_name,
		                    tvb, offset, str_len, ENC_ASCII|ENC_NA);
		offset += str_len;

		/* Server user name. */
		str_len = tvb_strsize(tvb, offset);
		proto_tree_add_item(user_info_tree, hf_user_info_server_user_name,
		                    tvb, offset, str_len, ENC_ASCII|ENC_NA);
		offset += str_len;

		/* Terminal type/speed. */
		slash_offset = tvb_find_guint8(tvb, offset, -1, '/');
		if (slash_offset != -1)
		{
			guint8* str = NULL;
			guint32 term_len = 0;
			gboolean term_len_valid;
			proto_item* pi = NULL;

			/* Terminal type */
			proto_tree_add_item(user_info_tree, hf_user_info_terminal_type,
			                    tvb, offset, slash_offset-offset, ENC_ASCII|ENC_NA);
			offset = slash_offset + 1;

			/* Terminal speed */
			str_len = tvb_strsize(tvb, offset);
			str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, str_len,
				ENC_NA|ENC_ASCII);
			term_len_valid = ws_strtou32(str, NULL, &term_len);
			pi = proto_tree_add_uint(user_info_tree,
				hf_user_info_terminal_speed,
				tvb, offset, str_len, term_len);
			if (!term_len_valid)
				expert_add_info(pinfo, pi, &ei_rlogin_termlen_invalid);

			offset += str_len;
		}
	}

	if (!tvb_offset_exists(tvb, offset))
	{
		/* No more data to check */
		return;
	}

	/* Test for terminal information, the data will have 2 0xff bytes */
	/* look for first 0xff byte */
	ti_offset = tvb_find_guint8(tvb, offset, -1, 0xff);

	/* Next byte must also be 0xff */
	if (ti_offset != -1 &&
	    tvb_bytes_exist(tvb, ti_offset + 1, 1) &&
	    tvb_get_guint8(tvb, ti_offset + 1) == 0xff)
	{
		guint16 rows, columns;

		/* Have found terminal info. */
		if (ti_offset > offset)
		{
			/* There's data before the terminal info. */
			proto_tree_add_item(rlogin_tree, hf_data, tvb,
			                    offset, ti_offset - offset, ENC_ASCII|ENC_NA);
		}

		/* Create window info tree */
		window_info_item =
			proto_tree_add_item(rlogin_tree, hf_window_info, tvb, offset, 12, ENC_NA);
		window_tree = proto_item_add_subtree(window_info_item, ett_rlogin_window);

		/* Cookie */
		proto_tree_add_item(window_tree, hf_magic_cookie, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* These bytes should be "ss" */
		proto_tree_add_item(window_tree, hf_window_info_ss, tvb, offset, 2, ENC_ASCII|ENC_NA);
		offset += 2;

		/* Character rows */
		rows = tvb_get_ntohs(tvb, offset);
		proto_tree_add_item(window_tree, hf_window_info_rows, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* Characters per row */
		columns = tvb_get_ntohs(tvb, offset);
		proto_tree_add_item(window_tree, hf_window_info_cols, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* x pixels */
		proto_tree_add_item(window_tree, hf_window_info_x_pixels, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* y pixels */
		proto_tree_add_item(window_tree, hf_window_info_y_pixels, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* Show setting highlights in info column */
		col_append_fstr(pinfo->cinfo, COL_INFO, " (rows=%u, cols=%u)",
			                rows, columns);
	}

	if (tvb_offset_exists(tvb, offset))
	{
		/* There's more data in the frame. */
		proto_tree_add_item(rlogin_tree, hf_data, tvb, offset, -1, ENC_ASCII|ENC_NA);
	}
}
Ejemplo n.º 26
0
static int
dissect_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
{
    proto_item  *pitem = NULL;
    guint        control_type;
    guint8       unknown_control_type;
    guint8       uuid_size;
    guint16      uuid_dst;
    guint16      uuid_src;
    guint16      response_message;
    guint        list_length;
    guint        i_item;

    proto_tree_add_item(tree, hf_btbnep_control_type, tvb, offset, 1, ENC_BIG_ENDIAN);
    control_type = tvb_get_guint8(tvb, offset);
    offset += 1;

    col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", val_to_str_const(control_type, control_type_vals,  "Unknown type"));

    switch(control_type) {
        case 0x00: /* Command Not Understood */
            proto_tree_add_item(tree, hf_btbnep_unknown_control_type, tvb, offset, 1, ENC_BIG_ENDIAN);
            unknown_control_type = tvb_get_guint8(tvb, offset);
            offset += 1;

            col_append_fstr(pinfo->cinfo, COL_INFO, " - Unknown(%s)", val_to_str_const(unknown_control_type, control_type_vals,  "Unknown type"));

            break;
        case 0x01: /* Setup Connection Request */
            proto_tree_add_item(tree, hf_btbnep_uuid_size, tvb, offset, 1, ENC_BIG_ENDIAN);
            uuid_size = tvb_get_guint8(tvb, offset);
            offset += 1;

            pitem = proto_tree_add_item(tree, hf_btbnep_destination_service_uuid, tvb, offset, uuid_size, ENC_NA);
            uuid_dst = tvb_get_ntohs(tvb, offset);
            proto_item_append_text(pitem, " (%s)", val_to_str_ext(uuid_dst, &vs_service_classes_ext,  "Unknown uuid"));
            offset += uuid_size;

            pitem = proto_tree_add_item(tree, hf_btbnep_source_service_uuid, tvb, offset, uuid_size, ENC_NA);
            uuid_src = tvb_get_ntohs(tvb, offset);
            proto_item_append_text(pitem, " (%s)", val_to_str_ext(uuid_src, &vs_service_classes_ext,  "Unknown uuid"));
            offset += uuid_size;

            col_append_fstr(pinfo->cinfo, COL_INFO, " - dst: <%s>, src: <%s>",
                    val_to_str_ext(uuid_dst, &vs_service_classes_ext,  "Unknown uuid"),
                    val_to_str_ext(uuid_src, &vs_service_classes_ext,  "Unknown uuid"));
            break;
        case 0x02: /* Setup Connection Response */
            proto_tree_add_item(tree, hf_btbnep_setup_connection_response_message, tvb, offset, 2, ENC_BIG_ENDIAN);
            response_message = tvb_get_ntohs(tvb, offset);
            offset += 2;
            col_append_fstr(pinfo->cinfo, COL_INFO, " - %s",
                    val_to_str_const(response_message, setup_connection_response_message_vals,  "Unknown response message"));
            break;
        case 0x03: /* Filter Net Type Set */
            proto_tree_add_item(tree, hf_btbnep_list_length, tvb, offset, 2, ENC_BIG_ENDIAN);
            list_length = tvb_get_ntohs(tvb, offset);
            offset += 2;

            for (i_item = 0; i_item < list_length; i_item += 4) {
                proto_tree_add_item(tree, hf_btbnep_network_type_start, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;

                proto_tree_add_item(tree, hf_btbnep_network_type_end, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
            }
            break;
        case 0x04: /* Filter Net Type Response */
            proto_tree_add_item(tree, hf_btbnep_filter_net_type_response_message, tvb, offset, 2, ENC_BIG_ENDIAN);
            response_message = tvb_get_ntohs(tvb, offset);
            offset += 2;
            col_append_fstr(pinfo->cinfo, COL_INFO, " - %s",
                    val_to_str_const(response_message, filter_net_type_response_message_vals,  "Unknown response message"));
            break;
        case 0x05: /*Filter Multi Addr Set*/
            proto_tree_add_item(tree, hf_btbnep_list_length, tvb, offset, 2, ENC_BIG_ENDIAN);
            list_length = tvb_get_ntohs(tvb, offset);
            offset += 2;

            for (i_item = 0; i_item < list_length; i_item += 12) {
                proto_tree_add_item(tree, hf_btbnep_multicast_address_start, tvb, offset, 6, ENC_NA);
                offset += 6;

                proto_tree_add_item(tree, hf_btbnep_multicast_address_end, tvb, offset, 6, ENC_NA);
                offset += 6;
            }
            break;
        case 0x06: /* Filter Multi Addr Response */
            proto_tree_add_item(tree, hf_btbnep_filter_multi_addr_response_message, tvb, offset, 2, ENC_BIG_ENDIAN);
            response_message = tvb_get_ntohs(tvb, offset);
            offset += 2;
            col_append_fstr(pinfo->cinfo, COL_INFO, " - %s",
                    val_to_str_const(response_message, filter_multi_addr_response_message_vals,  "Unknown response message"));
            break;

    };

    return offset;
}
Ejemplo n.º 27
0
static void
dissect_parameter(tvbuff_t *parameter_tvb, proto_tree *asap_tree)
{
  guint16 type, length, padding_length;
  proto_item *parameter_item;
  proto_tree *parameter_tree;

  /* extract tag and length from the parameter */
  type           = tvb_get_ntohs(parameter_tvb, PARAMETER_TYPE_OFFSET);
  length         = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET);
  padding_length = tvb_reported_length(parameter_tvb) - length;

  /* create proto_tree stuff */
  parameter_tree = proto_tree_add_subtree(asap_tree, parameter_tvb, PARAMETER_HEADER_OFFSET, -1,
      ett_asap_parameter, &parameter_item, val_to_str_const(type, parameter_type_values, "Unknown Parameter"));

  /* add tag and length to the asap tree */
  proto_tree_add_item(parameter_tree, hf_parameter_type,   parameter_tvb, PARAMETER_TYPE_OFFSET,   PARAMETER_TYPE_LENGTH,   ENC_BIG_ENDIAN);
  proto_tree_add_item(parameter_tree, hf_parameter_length, parameter_tvb, PARAMETER_LENGTH_OFFSET, PARAMETER_LENGTH_LENGTH, ENC_BIG_ENDIAN);

  switch(type) {
  case IPV4_ADDRESS_PARAMETER_TYPE:
    dissect_ipv4_parameter(parameter_tvb, parameter_tree, parameter_item);
    break;
  case IPV6_ADDRESS_PARAMETER_TYPE:
    dissect_ipv6_parameter(parameter_tvb, parameter_tree, parameter_item);
    break;
  case DCCP_TRANSPORT_PARAMETER_TYPE:
    dissect_dccp_transport_parameter(parameter_tvb, parameter_tree);
    break;
  case SCTP_TRANSPORT_PARAMETER_TYPE:
    dissect_sctp_transport_parameter(parameter_tvb, parameter_tree);
    break;
  case TCP_TRANSPORT_PARAMETER_TYPE:
    dissect_tcp_transport_parameter(parameter_tvb, parameter_tree);
    break;
  case UDP_TRANSPORT_PARAMETER_TYPE:
    dissect_udp_transport_parameter(parameter_tvb, parameter_tree);
    break;
  case UDP_LITE_TRANSPORT_PARAMETER_TYPE:
    dissect_udp_lite_transport_parameter(parameter_tvb, parameter_tree);
    break;
  case POOL_MEMBER_SELECTION_POLICY_PARAMETER_TYPE:
    dissect_pool_member_selection_policy_parameter(parameter_tvb, parameter_tree);
    break;
  case POOL_HANDLE_PARAMETER_TYPE:
    dissect_pool_handle_parameter(parameter_tvb, parameter_tree);
    break;
  case POOL_ELEMENT_PARAMETER_TYPE:
    dissect_pool_element_parameter(parameter_tvb, parameter_tree);
    break;
  case SERVER_INFORMATION_PARAMETER_TYPE:
    dissect_server_information_parameter(parameter_tvb, parameter_tree);
    break;
  case OPERATION_ERROR_PARAMETER_TYPE:
    dissect_operation_error_parameter(parameter_tvb, parameter_tree);
    break;
  case COOKIE_PARAMETER_TYPE:
    dissect_cookie_parameter(parameter_tvb, parameter_tree, parameter_item);
    break;
  case PE_IDENTIFIER_PARAMETER_TYPE:
    dissect_pe_identifier_parameter(parameter_tvb, parameter_tree, parameter_item);
    break;
  case PE_CHECKSUM_PARAMETER_TYPE:
    dissect_pe_checksum_parameter(parameter_tvb, parameter_tree, parameter_item);
    break;
  case HANDLE_RESOLUTION_OPTION_PARAMETER_TYPE:
    dissect_handle_resolution_option_parameter(parameter_tvb, parameter_tree);
    break;
  default:
    dissect_unknown_parameter(parameter_tvb, parameter_tree, parameter_item);
    break;
  };

  if (padding_length > 0)
    proto_tree_add_item(parameter_tree, hf_parameter_padding, parameter_tvb, PARAMETER_HEADER_OFFSET + length, padding_length, ENC_NA);
}
Ejemplo n.º 28
0
/*FUNCTION:------------------------------------------------------
 *  NAME
 *      dissect_zbee_zcl_msg
 *  DESCRIPTION
 *      ZigBee ZCL Messaging cluster dissector for wireshark.
 *  PARAMETERS
 *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
 *      packet_info *pinfo  - pointer to packet information fields
 *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
 *  RETURNS
 *      none
 *---------------------------------------------------------------
 */
static void
dissect_zbee_zcl_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item        *payload_root;
    proto_tree        *payload_tree;
    zbee_zcl_packet   *zcl = (zbee_zcl_packet *)pinfo->private_data;
    guint             offset = 0;
    guint8            cmd_id = zcl->cmd_id;
    gint              rem_len;

    /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
    if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
        /* Append the command name to the info column. */
        col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
            val_to_str_const(cmd_id, zbee_zcl_msg_srv_rx_cmd_names, "Unknown Command"),
            zcl->tran_seqno);

        /* Add the command ID. */
        proto_tree_add_item(tree, hf_zbee_zcl_msg_srv_rx_cmd_id, tvb, offset, 1, cmd_id);

        /* Check is this command has a payload, than add the payload tree */
        rem_len = tvb_reported_length_remaining(tvb, ++offset);
        if (rem_len > 0) {
            payload_root = proto_tree_add_text(tree, tvb, offset, rem_len, "Payload");
            payload_tree = proto_item_add_subtree(payload_root, ett_zbee_zcl_msg);

            /* Call the appropriate command dissector */
            switch (cmd_id) {

                case ZBEE_ZCL_CMD_ID_MSG_GET_LAST_MSG:
                    /* No payload */
                    break;

                case ZBEE_ZCL_CMD_ID_MSG_MSG_CONFIRM:
                    dissect_zcl_msg_confirm(tvb, payload_tree, &offset);
                    break;

                default:
                    break;
            }
        }
    }
    else { /* ZBEE_ZCL_FCF_TO_CLIENT */
        /* Append the command name to the info column. */
        col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
            val_to_str_const(cmd_id, zbee_zcl_msg_srv_tx_cmd_names, "Unknown Command"),
            zcl->tran_seqno);

        /* Add the command ID. */
        proto_tree_add_item(tree, hf_zbee_zcl_msg_srv_tx_cmd_id, tvb, offset, 1, cmd_id);

        /* Check is this command has a payload, than add the payload tree */
        rem_len = tvb_reported_length_remaining(tvb, ++offset);
        if (rem_len > 0) {
            payload_root = proto_tree_add_text(tree, tvb, offset, rem_len, "Payload");
            payload_tree = proto_item_add_subtree(payload_root, ett_zbee_zcl_msg);

            /* Call the appropriate command dissector */
            switch (cmd_id) {

                case ZBEE_ZCL_CMD_ID_MSG_DISPLAY_MSG:
                    dissect_zcl_msg_display(tvb, payload_tree, &offset);
                    break;

                case ZBEE_ZCL_CMD_ID_MSG_CANCEL_MSG:
                    dissect_zcl_msg_cancel(tvb, payload_tree, &offset);
                    break;

                default:
                    break;
            }
        }
    }
} /*dissect_zbee_zcl_msg*/
Ejemplo n.º 29
0
static void
dissect_rpl_container(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint16 len, type, sublen, subtyp;
	proto_item *ti;
	proto_tree *rpl_container_tree;
	guint16 offset;
	gint ett_type;
	gint length, reported_length;

	len = tvb_get_ntohs(tvb, 0);
	proto_tree_add_text(tree, tvb, 0, 2, "Length: %u", len);

	type = tvb_get_ntohs(tvb, 2);
	proto_tree_add_text(tree, tvb, 2, 2, "Type: %s",
		val_to_str_const(type, rpl_type_vals, "Unknown Type"));
	offset = 4;

	switch (type) {
		case 1:
		case 2:
		case 4:
		case 8:
		case 0x10:
		case 0x20:
			while (len >= offset+4) {
				sublen = tvb_get_ntohs(tvb, offset);
				subtyp = tvb_get_ntohs(tvb, offset+2);
				ett_type = ett_rpl_unkn;
				if(subtyp == 0x0004) ett_type = ett_rpl_0004;
				if(subtyp == 0x0008) ett_type = ett_rpl_0008;
				if(subtyp == 0x4003) ett_type = ett_rpl_4003;
				if(subtyp == 0x4006) ett_type = ett_rpl_4006;
				if(subtyp == 0x4007) ett_type = ett_rpl_4007;
				if(subtyp == 0x4009) ett_type = ett_rpl_4009;
				if(subtyp == 0x400a) ett_type = ett_rpl_400a;
				if(subtyp == 0x400b) ett_type = ett_rpl_400b;
				if(subtyp == 0x400c) ett_type = ett_rpl_400c;
				if(subtyp == 0x4011) ett_type = ett_rpl_4011;
				if(subtyp == 0x4018) ett_type = ett_rpl_4018;
				if(subtyp == 0xc005) ett_type = ett_rpl_c005;
				if(subtyp == 0xc014) ett_type = ett_rpl_c014;
				ti = proto_tree_add_text(tree, tvb,
					offset, sublen, "%s",
					val_to_str_const(subtyp,
						rpl_type_vals,
						"Unknown Type"));
				rpl_container_tree = proto_item_add_subtree(ti,
					ett_type);
				length = tvb_length_remaining(tvb, offset);
				if (length > sublen)
					length = sublen;
				reported_length = tvb_reported_length_remaining(tvb, offset);
				if (reported_length > sublen)
					reported_length = sublen;
				if ( length > 0) {
				  dissect_rpl_container(tvb_new_subset(tvb,
					offset, length, reported_length),
					pinfo, rpl_container_tree);
				  offset += reported_length;
				} else {
				  /* no more data, exit the loop */
				  offset += reported_length;
				  break;
				}
			}
			break;

		case 0x4003:
			proto_tree_add_item(tree, hf_rpl_corrval,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
			break;

		case 0x4006:
			proto_tree_add_item(tree, hf_rpl_lmac,
				tvb, offset, 6, ENC_NA);
			offset += 6;
			break;

		case 0x4007:
			proto_tree_add_item(tree, hf_rpl_sap,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset ++;
			break;

		case 0x4009:
			proto_tree_add_item(tree, hf_rpl_maxframe,
				tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
			break;

		case 0x400a:
			proto_tree_add_item(tree, hf_rpl_connclass,
				tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
			break;

		case 0x400b:
			proto_tree_add_item(tree, hf_rpl_respval,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset ++;
			break;

		case 0x400c:
			proto_tree_add_item(tree, hf_rpl_smac,
				tvb, offset, 6, ENC_NA);
			offset += 6;
			break;

		case 0x4011:
			proto_tree_add_item(tree, hf_rpl_sequence,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
			break;

		case 0x4018:
			proto_tree_add_item(tree, hf_rpl_data,
				tvb, offset, len-4, ENC_NA);
			offset += len - 4;
			break;

		case 0xc005:
			proto_tree_add_item(tree, hf_rpl_config,
				tvb, offset, 8, ENC_NA);
			offset += 8;
			proto_tree_add_item(tree, hf_rpl_equipment,
				tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
			proto_tree_add_item(tree, hf_rpl_memsize,
				tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
			proto_tree_add_item(tree, hf_rpl_bsmversion,
				tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
			proto_tree_add_item(tree, hf_rpl_ec,
				tvb, offset, 6, ENC_NA);
			offset += 6;
			proto_tree_add_item(tree, hf_rpl_adapterid,
				tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
			proto_tree_add_item(tree, hf_rpl_shortname,
				tvb, offset, 10, ENC_NA);
			offset += 10;
			break;

		case 0xc014:
			proto_tree_add_item(tree, hf_rpl_laddress,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
			proto_tree_add_item(tree, hf_rpl_xaddress,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
			proto_tree_add_item(tree, hf_rpl_flags,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset ++;
			break;

		default:
			call_dissector(data_handle,
				tvb_new_subset_remaining(tvb, 4), pinfo,
				tree);
			break;
	}
	if (tvb_reported_length(tvb) > offset)
		call_dissector(data_handle,
			tvb_new_subset_remaining(tvb, offset), pinfo, tree);
}
Ejemplo n.º 30
0
static gint
dissect_adb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    proto_item      *main_item;
    proto_tree      *main_tree;
    proto_item      *arg0_item;
    proto_tree      *arg0_tree;
    proto_item      *arg1_item;
    proto_tree      *arg1_tree;
    proto_item      *magic_item;
    proto_item      *crc_item;
    proto_tree      *crc_tree = NULL;
    proto_item      *sub_item;
    gint             offset = 0;
    guint32          command;
    guint32          arg0;
    guint32          arg1;
    guint32          data_length = 0;
    guint32          crc32 = 0;
    usb_conv_info_t *usb_conv_info = NULL;
    wmem_tree_key_t  key[5];
    guint32          interface_id;
    guint32          bus_id;
    guint32          device_address;
    guint32          side_id;
    guint32          frame_number;
    gboolean         is_command = TRUE;
    gboolean         is_next_fragment = FALSE;
    gboolean         is_service = FALSE;
    gint             proto;
    gint             direction = P2P_DIR_UNKNOWN;
    wmem_tree_t     *wmem_tree;
    command_data_t  *command_data = NULL;
    service_data_t  *service_data = NULL;

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

    main_item = proto_tree_add_item(tree, proto_adb, tvb, offset, -1, ENC_NA);
    main_tree = proto_item_add_subtree(main_item, ett_adb);

    frame_number       = pinfo->num;

    /* XXX: Why? If interface is USB only first try is correct
     * (and seems strange...), in other cases standard check for
     * previous protocol is correct */
    proto = (gint) GPOINTER_TO_INT(wmem_list_frame_data(/*wmem_list_frame_prev*/(wmem_list_tail(pinfo->layers))));
    if (proto != proto_usb) {
        proto = (gint) GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers))));
    }

    if (proto == proto_usb) {
        usb_conv_info = (usb_conv_info_t *) data;
        DISSECTOR_ASSERT(usb_conv_info);

        direction = usb_conv_info->direction;
    } else if (proto == proto_tcp) {
        if (pinfo->destport == ADB_TCP_PORT)
            direction = P2P_DIR_SENT;
        else
            direction = P2P_DIR_RECV;
    } else {
        return offset;
    }

    if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID)
        interface_id = pinfo->phdr->interface_id;
    else
        interface_id = 0;

    if (proto == proto_usb) {
        bus_id             = usb_conv_info->bus_id;
        device_address     = usb_conv_info->device_address;

        key[0].length = 1;
        key[0].key = &interface_id;
        key[1].length = 1;
        key[1].key = &bus_id;
        key[2].length = 1;
        key[2].key = &device_address;
        key[3].length = 0;
        key[3].key = NULL;
    } else { /* tcp */
        key[0].length = 1;
        key[0].key = &interface_id;
        key[1].length = 1;
        key[2].length = 1;
        if (direction == P2P_DIR_SENT) {
            key[1].key = &pinfo->srcport;
            key[2].key = &pinfo->destport;
        } else {
            key[1].key = &pinfo->destport;
            key[2].key = &pinfo->srcport;
        }
        key[3].length = 0;
        key[3].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, frame_number);
        if (command_data && command_data->completed_in_frame >= frame_number &&
                command_data->command_in_frame <= frame_number) {

            if (command_data->command_in_frame != frame_number) {
                is_command = FALSE;
                is_next_fragment = TRUE;
            }

            data_length = command_data->data_length;
            crc32 = command_data->crc32;

            if (direction == P2P_DIR_SENT) {
                if (command_data->command == A_CLSE)
                    side_id = command_data->arg1; /* OUT: local id */
                else
                    side_id = command_data->arg0; /* OUT: local id */
            } else {
                    side_id = command_data->arg1; /* IN: remote id */
            }

            key[3].length = 1;
            key[3].key = &side_id;
            key[4].length = 0;
            key[4].key = NULL;

            wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(service_info, key);
            if (wmem_tree) {
                service_data = (service_data_t *) wmem_tree_lookup32_le(wmem_tree, frame_number);
                if (service_data && command_data->command == A_OPEN) {
                    is_service = TRUE;
                }
            }
        }
    }

/* Simple heuristics to check if packet is command or data */
    if ((command_data && command_data->completed_in_frame <= frame_number) || !command_data) {
        if (tvb_reported_length(tvb) < 24) {
            is_command = FALSE;
        } else if (tvb_reported_length(tvb) >= 24) {
            command = tvb_get_letohl(tvb, offset);

            if (command != A_SYNC && command != A_CLSE && command != A_WRTE &&
                    command != A_AUTH && command != A_CNXN && command != A_OPEN && command != A_OKAY)
                is_command = FALSE;
            else if (command != (0xFFFFFFFF ^ tvb_get_letohl(tvb, offset + 20)))
                is_command = FALSE;

            if (is_command) {
                data_length = tvb_get_letohl(tvb, offset + 12);
                crc32 = tvb_get_letohl(tvb, offset + 16);
            }
            if (command == A_OPEN) is_service = TRUE;
        }
    }

    if (service_data && !(command_data->command == A_OPEN && is_next_fragment)) {
        sub_item = proto_tree_add_string(main_tree, hf_service, tvb, offset, 0, service_data->service);
        PROTO_ITEM_SET_GENERATED(sub_item);
    }

    if (service_data) {
        sub_item = proto_tree_add_uint(main_tree, hf_service_start_in_frame, tvb, offset, 0, service_data->start_in_frame);
        PROTO_ITEM_SET_GENERATED(sub_item);

        if (service_data->close_local_in_frame < max_in_frame) {
            sub_item = proto_tree_add_uint(main_tree, hf_close_local_in_frame, tvb, offset, 0, service_data->close_local_in_frame);
            PROTO_ITEM_SET_GENERATED(sub_item);
        }

        if (service_data->close_remote_in_frame < max_in_frame) {
            sub_item = proto_tree_add_uint(main_tree, hf_close_remote_in_frame, tvb, offset, 0, service_data->close_remote_in_frame);
            PROTO_ITEM_SET_GENERATED(sub_item);
        }
    }

    if (is_command) {
        proto_tree_add_item(main_tree, hf_command, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        command = tvb_get_letohl(tvb, offset);
        offset += 4;

        col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const(command, command_vals, "Unknown command"));

        arg0_item = proto_tree_add_item(main_tree, hf_argument_0, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        arg0_tree = proto_item_add_subtree(arg0_item, ett_adb_arg0);
        arg0 = tvb_get_letohl(tvb, offset);
        offset += 4;

        arg1_item = proto_tree_add_item(main_tree, hf_argument_1, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        arg1_tree = proto_item_add_subtree(arg1_item, ett_adb_arg1);
        arg1 = tvb_get_letohl(tvb, offset);
        offset += 4;

        switch (command) {
        case A_CNXN:
            proto_tree_add_item(arg0_tree, hf_version, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_max_data, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(version=%u.%u.%u, max_data=%u)", tvb_get_guint8(tvb, offset - 5), tvb_get_guint8(tvb, offset - 6), tvb_get_letohs(tvb, offset - 7), tvb_get_letohl(tvb, offset - 4));
            break;
        case A_AUTH:
            proto_tree_add_item(arg0_tree, hf_auth_type, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_zero, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(type=%s, 0)", val_to_str_const(tvb_get_letohl(tvb, offset - 8), auth_type_vals, "Unknown"));
            break;
        case A_OPEN:
            proto_tree_add_item(arg0_tree, hf_local_id, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_zero, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(local=%u, 0)", tvb_get_letohl(tvb, offset - 8));
            break;
        case A_WRTE:
            proto_tree_add_item(arg0_tree, hf_zero, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_remote_id, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(0, remote=%u)", tvb_get_letohl(tvb, offset - 4));
            break;
        case A_CLSE:
        case A_OKAY:
            proto_tree_add_item(arg0_tree, hf_local_id, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_remote_id, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(local=%u, remote=%u)", tvb_get_letohl(tvb, offset - 8), tvb_get_letohl(tvb, offset - 4));
            break;
        case A_SYNC:
            proto_tree_add_item(arg0_tree, hf_online, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_sequence, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(online=%s, sequence=%u)", tvb_get_letohl(tvb, offset - 8) ? "Yes": "No", tvb_get_letohl(tvb, offset - 4));
            break;
        }

        proto_tree_add_item(main_tree, hf_data_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        offset += 4;

        if (data_length > 0)
            col_append_fstr(pinfo->cinfo, COL_INFO, " length=%u ", data_length);

        crc_item = proto_tree_add_item(main_tree, hf_data_crc32, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        crc_tree = proto_item_add_subtree(crc_item, ett_adb_crc);
        crc32 = tvb_get_letohl(tvb, offset);
        offset += 4;

        magic_item = proto_tree_add_item(main_tree, hf_magic, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        if ((tvb_get_letohl(tvb, offset) ^ 0xFFFFFFFF) != command) {
            proto_tree  *expert_tree;

            expert_tree = proto_item_add_subtree(magic_item, ett_adb_magic);
            proto_tree_add_expert(expert_tree, pinfo, &ei_invalid_magic, tvb, offset, 4);
        }

        if (!pinfo->fd->flags.visited)
            save_command(command, arg0, arg1, data_length, crc32, service_data, proto, data, pinfo, &service_data, &command_data);
        offset += 4;
    }

    if (!pinfo->fd->flags.visited && command_data) {
            if (command_data->command_in_frame != frame_number) {
                is_command = FALSE;
                is_next_fragment = TRUE;
            }

            data_length = command_data->data_length;
            crc32 = command_data->crc32;

            if ((command_data->command_in_frame != frame_number && tvb_captured_length(tvb) == data_length) ||
                (command_data->command_in_frame == frame_number && tvb_captured_length(tvb) == data_length + 24)
            ) {
                command_data->reassemble_data_length = command_data->data_length;
                command_data->completed_in_frame = frame_number;
            }
    }

    if (is_next_fragment && command_data) {
        sub_item = proto_tree_add_uint(main_tree, hf_command_in_frame, tvb, offset, 0, command_data->command_in_frame);
        PROTO_ITEM_SET_GENERATED(sub_item);

        sub_item = proto_tree_add_uint(main_tree, hf_command, tvb, offset, 0, command_data->command);
        PROTO_ITEM_SET_GENERATED(sub_item);

        sub_item = proto_tree_add_uint(main_tree, hf_data_length, tvb, offset, 0, command_data->data_length);
        PROTO_ITEM_SET_GENERATED(sub_item);

        crc_item = proto_tree_add_uint(main_tree, hf_data_crc32, tvb, offset, 0, command_data->crc32);
        crc_tree = proto_item_add_subtree(crc_item, ett_adb_crc);
        PROTO_ITEM_SET_GENERATED(crc_item);
    }

    if (command_data && command_data->completed_in_frame != frame_number) {
        sub_item = proto_tree_add_uint(main_tree, hf_completed_in_frame, tvb, offset, 0, command_data->completed_in_frame);
        PROTO_ITEM_SET_GENERATED(sub_item);
    }


    if (tvb_captured_length_remaining(tvb, offset) > 0 && (!is_command || data_length > 0)) {
        guint32 crc = 0;
        guint32 i_offset;

        if ((!pinfo->fd->flags.visited && command_data && command_data->reassemble_data_length < command_data->data_length) || data_length > (guint32) tvb_captured_length_remaining(tvb, offset)) { /* need reassemble */
            if (!pinfo->fd->flags.visited && command_data && command_data->reassemble_data_length < command_data->data_length) {
                tvb_memcpy(tvb, command_data->reassemble_data + command_data->reassemble_data_length, offset, tvb_captured_length_remaining(tvb, offset));
                command_data->reassemble_data_length += tvb_captured_length_remaining(tvb, offset);

                if (command_data->reassemble_data_length >= command_data->data_length)
                    command_data->completed_in_frame = frame_number;
            }

            proto_tree_add_item(main_tree, hf_data_fragment, tvb, offset, -1, ENC_NA);
            col_append_str(pinfo->cinfo, COL_INFO, "Data Fragment");
            offset = tvb_captured_length(tvb);

            if (service_data && command_data && command_data->reassemble_data_length >= command_data->data_length && frame_number == command_data->completed_in_frame) {
                tvbuff_t            *next_tvb;
                adb_service_data_t   adb_service_data;

                next_tvb = tvb_new_child_real_data(tvb, command_data->reassemble_data, command_data->reassemble_data_length, command_data->reassemble_data_length);
                add_new_data_source(pinfo, next_tvb, "ADB Reassembled Data");

                adb_service_data.service = service_data->service;
                adb_service_data.direction = direction;

                adb_service_data.session_key_length = 3;
                adb_service_data.session_key = (guint32 *) wmem_alloc(wmem_packet_scope(), adb_service_data.session_key_length * sizeof(guint32));
                adb_service_data.session_key[0] = interface_id;

                if (proto == proto_usb) {
                    adb_service_data.session_key[1] = usb_conv_info->bus_id;
                    adb_service_data.session_key[2] = usb_conv_info->device_address;
                } else { /* tcp */
                    if (direction == P2P_DIR_SENT) {
                        adb_service_data.session_key[1] = pinfo->srcport;
                        adb_service_data.session_key[2] = pinfo->destport;
                    } else {
                        adb_service_data.session_key[1] = pinfo->destport;
                        adb_service_data.session_key[2] = pinfo->srcport;
                    }
                }

                call_dissector_with_data(adb_service_handle, next_tvb, pinfo, tree, &adb_service_data);
            }
        } else { /* full message */
            for (i_offset = 0; i_offset < data_length; ++i_offset)
                crc += tvb_get_guint8(tvb, offset + i_offset);

            if (crc32 > 0 && crc32 != crc)
                proto_tree_add_expert(crc_tree, pinfo, &ei_invalid_crc, tvb, offset, -1);

            if (is_service) {
                proto_tree_add_item(main_tree, hf_service, tvb, offset, -1, ENC_ASCII | ENC_NA);
                if (!pinfo->fd->flags.visited && service_data) {
                    service_data->service = tvb_get_stringz_enc(wmem_file_scope(), tvb, offset, NULL, ENC_ASCII);
                }
                col_append_fstr(pinfo->cinfo, COL_INFO, "Service: %s", tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, NULL, ENC_ASCII));
                offset = tvb_captured_length(tvb);
            } else if (command_data && command_data->command == A_CNXN) {
                    gchar       *info;
                    gint         len;

                info = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &len, ENC_ASCII);
                col_append_fstr(pinfo->cinfo, COL_INFO, "Connection Info: %s", info);
                proto_tree_add_item(main_tree, hf_connection_info, tvb, offset, len, ENC_ASCII | ENC_NA);
                offset += len;
            } else {
                col_append_str(pinfo->cinfo, COL_INFO, "Data");

                /* Decode service payload */
                if (service_data) {
                    tvbuff_t           *next_tvb;
                    adb_service_data_t  adb_service_data;

                    adb_service_data.service = service_data->service;
                    adb_service_data.direction = direction;

                    adb_service_data.session_key_length = 3;
                    adb_service_data.session_key = (guint32 *) wmem_alloc(wmem_packet_scope(), adb_service_data.session_key_length * sizeof(guint32));
                    adb_service_data.session_key[0] = interface_id;

                    if (proto == proto_usb) {
                        adb_service_data.session_key[1] = usb_conv_info->bus_id;
                        adb_service_data.session_key[2] = usb_conv_info->device_address;
                    } else { /* tcp */
                        if (direction == P2P_DIR_SENT) {
                            adb_service_data.session_key[1] = pinfo->srcport;
                            adb_service_data.session_key[2] = pinfo->destport;
                        } else {
                            adb_service_data.session_key[1] = pinfo->destport;
                            adb_service_data.session_key[2] = pinfo->srcport;
                        }
                    }

                    next_tvb = tvb_new_subset_length_caplen(tvb, offset, tvb_captured_length_remaining(tvb, offset), tvb_captured_length_remaining(tvb, offset));
                    call_dissector_with_data(adb_service_handle, next_tvb, pinfo, tree, &adb_service_data);

                } else {
                    proto_item  *data_item;
                    gchar       *data_str;

                    data_item = proto_tree_add_item(main_tree, hf_data, tvb, offset, data_length, ENC_NA);
                    data_str = tvb_format_text(tvb, offset, data_length);
                    proto_item_append_text(data_item, ": %s", data_str);
                    col_append_fstr(pinfo->cinfo, COL_INFO, " Raw: %s", data_str);
                }

                offset = tvb_captured_length(tvb);
            }
        }
    }

    return offset;
}