static void
dissect_ipvs_syncd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	proto_tree *tree;
	proto_item *item;
	int offset = 0;
	guint8 cnt = 0;
	int conn = 0;

	item = proto_tree_add_item(parent_tree, proto_ipvs_syncd, tvb, offset, -1, ENC_NA);
	tree = proto_item_add_subtree(item, ett_ipvs_syncd);


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

	cnt = tvb_get_guint8(tvb, offset);
	proto_tree_add_item(tree, hf_conn_count, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	proto_tree_add_item(tree, hf_syncid, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	proto_tree_add_item(tree, hf_size, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	for (conn = 0; conn < cnt; conn++)
	{
		proto_tree *ctree, *ti;
		proto_tree *ftree, *fi;
		guint16 flags;

		ti = proto_tree_add_text(tree, tvb, offset, 24, "Connection #%d", conn+1);
		ctree = proto_item_add_subtree(ti, ett_conn);

		proto_tree_add_item(ctree, hf_resv8, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(ctree, hf_proto, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(ctree, hf_cport, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		proto_tree_add_item(ctree, hf_vport, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		proto_tree_add_item(ctree, hf_dport, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		proto_tree_add_item(ctree, hf_caddr, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;

		proto_tree_add_item(ctree, hf_vaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;

		proto_tree_add_item(ctree, hf_daddr, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;

		flags = tvb_get_ntohs(tvb, offset);
		fi = proto_tree_add_item(ctree, hf_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
		ftree = proto_item_add_subtree(fi, ett_flags);

		if ( (flags & 0x0F) == IP_VS_CONN_F_MASQ )
		{
			proto_tree_add_text(ftree, tvb, offset+1, 1, "Connection Type: Masquerade");
		}
		else if ( (flags & 0x0F) == IP_VS_CONN_F_LOCALNODE )
		{
			proto_tree_add_text(ftree, tvb, offset+1, 1, "Connection Type: Local Node");
		}
		else if ( (flags & 0x0F) == IP_VS_CONN_F_TUNNEL )
		{
			proto_tree_add_text(ftree, tvb, offset+1, 1, "Connection Type: Tunnel");
		}
		else if ( (flags & 0x0F) == IP_VS_CONN_F_DROUTE )
		{
			proto_tree_add_text(ftree, tvb, offset+1, 1, "Connection Type: Direct Routing");
		}
		else
		{
			proto_tree_add_text(ftree, tvb, offset+1, 1, "Connection Type: Unknown (%d)",
				flags & IP_VS_CONN_F_FWD_MASK);
		}

		if ( flags & IP_VS_CONN_F_HASHED )
		{
			proto_tree_add_text(ftree, tvb, offset+1, 1, "Hashed Entry");
		}

		if ( flags & IP_VS_CONN_F_NOOUTPUT )
		{
			proto_tree_add_text(ftree, tvb, offset+1, 1, "No Output Packets");
		}

		if ( flags & IP_VS_CONN_F_INACTIVE )
		{
			proto_tree_add_text(ftree, tvb, offset, 1, "Connection Not Established");
		}

		if ( flags & IP_VS_CONN_F_OUT_SEQ )
		{
			proto_tree_add_text(ftree, tvb, offset, 1, "Adjust Output Sequence");
		}

		if ( flags & IP_VS_CONN_F_IN_SEQ )
		{
			proto_tree_add_text(ftree, tvb, offset, 1, "Adjust Input Sequence");
		}

		if ( flags & IP_VS_CONN_F_NO_CPORT )
		{
			proto_tree_add_text(ftree, tvb, offset, 1, "No Client Port Set");
		}

		offset += 2;

		proto_tree_add_item(ctree, hf_state, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* we have full connection info */
		if ( flags & IP_VS_CONN_F_SEQ_MASK )
		{
			proto_tree_add_item(ctree, hf_in_seq_init, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(ctree, hf_in_seq_delta, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(ctree, hf_in_seq_pdelta, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(ctree, hf_out_seq_init, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(ctree, hf_out_seq_delta, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(ctree, hf_out_seq_pdelta, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
		}

	}
}
Example #2
0
static void
dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint       op;
    guint       sub;
    guint       rlen;
    proto_item *ti;
    proto_item *item;
    proto_tree *fip_tree;
    proto_tree *subtree;
    guint       dtype;
    guint       dlen;
    guint       desc_offset;
    guint       val;
    tvbuff_t   *desc_tvb;
    const char *info;
    const char *text;

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

    if (!tvb_bytes_exist(tvb, 0, FIP_HEADER_LEN)) {
        col_set_str(pinfo->cinfo, COL_INFO, "[packet too short]");
        if (tree)
            proto_tree_add_protocol_format(tree, proto_fip, tvb, 0,
                                            -1, "FIP [packet too short]");
        return;
    }

    op  = tvb_get_ntohs(tvb, 2);
    sub = tvb_get_guint8(tvb, 5);

    switch (op) {
    case FIP_OP_DISC:
        info = val_to_str(sub, fip_disc_subcodes, "Discovery 0x%x");
        break;
    case FIP_OP_LS:
        info = val_to_str(sub, fip_ls_subcodes, "Link Service 0x%x");
        break;
    case FIP_OP_CTRL:
        info = val_to_str(sub, fip_ctrl_subcodes, "Control 0x%x");
        break;
    case FIP_OP_VLAN:
        info = val_to_str(sub, fip_vlan_subcodes, "VLAN 0x%x");
        break;
    case FIP_OP_VN2VN:
        info = val_to_str(sub, fip_vn2vn_subcodes, "VN2VN 0x%x");
        break;
    default:
        info = val_to_str(op, fip_opcodes, "Unknown op 0x%x");
        break;
    }

    col_add_str(pinfo->cinfo, COL_INFO, info);

    rlen = tvb_get_ntohs(tvb, 6);

    ti = proto_tree_add_protocol_format(tree, proto_fip, tvb, 0,
                                        FIP_HEADER_LEN + rlen * FIP_BPW,
                                        "FIP %s", info);
    fip_tree = proto_item_add_subtree(ti, ett_fip);
    proto_tree_add_item(fip_tree, hf_fip_ver, tvb, 0, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(fip_tree, hf_fip_op, tvb, 2, 2, ENC_BIG_ENDIAN);
    switch (op) {
    case FIP_OP_DISC:
        proto_tree_add_item(fip_tree, hf_fip_disc_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    case FIP_OP_LS:
        proto_tree_add_item(fip_tree, hf_fip_ls_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    case FIP_OP_CTRL:
        proto_tree_add_item(fip_tree, hf_fip_ctrl_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    case FIP_OP_VLAN:
        proto_tree_add_item(fip_tree, hf_fip_vlan_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    case FIP_OP_VN2VN:
        proto_tree_add_item(fip_tree, hf_fip_vn2vn_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    default:
        proto_tree_add_item(fip_tree, hf_fip_hex_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    }
    proto_tree_add_item(fip_tree, hf_fip_dlen, tvb, 6, 2, ENC_BIG_ENDIAN);

    proto_tree_add_bitmask(fip_tree, tvb, 8, hf_fip_flags,
            ett_fip_flags, hf_fip_flags_fields, ENC_BIG_ENDIAN);

    desc_offset = FIP_HEADER_LEN;
    rlen *= FIP_BPW;
    proto_tree_add_bytes_format(fip_tree, hf_fip_descriptors, tvb, desc_offset, rlen, NULL, "Descriptors");

    while ((rlen > 0) && tvb_bytes_exist(tvb, desc_offset, 2)) {
        dlen = tvb_get_guint8(tvb, desc_offset + 1) * FIP_BPW;
        if (!dlen) {
            proto_tree_add_expert(fip_tree, pinfo, &ei_fip_descriptors, tvb, desc_offset, -1);
            break;
        }
        if (!tvb_bytes_exist(tvb, desc_offset, dlen) || dlen > rlen) {
            break;
        }
        desc_tvb = tvb_new_subset(tvb, desc_offset, dlen, -1);
        dtype = tvb_get_guint8(desc_tvb, 0);
        desc_offset += dlen;
        rlen -= dlen;

        switch (dtype) {
        case FIP_DT_PRI:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_pri, &item);
            proto_tree_add_item(subtree, hf_fip_desc_pri, desc_tvb,
                    3, 1, ENC_BIG_ENDIAN);
            proto_item_append_text(item, "%u", tvb_get_guint8(desc_tvb, 3));
            break;
        case FIP_DT_MAC:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mac, &item);
            proto_tree_add_item(subtree, hf_fip_desc_mac, desc_tvb,
                    2, 6, ENC_NA);
            proto_item_append_text(item, "%s",
                    tvb_bytes_to_ep_str_punct(desc_tvb, 2, 6, ':'));
            break;
        case FIP_DT_MAP_OUI:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_map, &item);
            text = tvb_fc_to_str(desc_tvb, 5);
            proto_tree_add_string(subtree, hf_fip_desc_map, desc_tvb,
                    5, 3, text);
            proto_item_append_text(item, "%s", text);
            break;
        case FIP_DT_NAME:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_name, &item);
            text = tvb_fcwwn_to_str(desc_tvb, 4);
            proto_tree_add_string(subtree, hf_fip_desc_name,
                    desc_tvb, 4, 8, text);
            proto_item_append_text(item, "%s", text);
            break;
        case FIP_DT_FAB:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fab, &item);
            proto_tree_add_item(subtree, hf_fip_desc_fab_vfid, desc_tvb,
                    2, 2, ENC_BIG_ENDIAN);
            text = tvb_fc_to_str(desc_tvb, 5);
            proto_tree_add_string(subtree, hf_fip_desc_fab_map, desc_tvb,
                    5, 3, text);
            text = tvb_fcwwn_to_str(desc_tvb, 8);
            proto_tree_add_string(subtree, hf_fip_desc_fab_name,
                    desc_tvb, 8, 8, text);
            proto_item_append_text(item, "%s", text);
            break;
        case FIP_DT_FCOE_SIZE:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mdl, &item);
            proto_tree_add_item(subtree, hf_fip_desc_fcoe_size, desc_tvb,
                    2, 2, ENC_BIG_ENDIAN);
            proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2));
            break;
        case FIP_DT_FLOGI:
        case FIP_DT_FDISC:
        case FIP_DT_LOGO:
        case FIP_DT_ELP: {
            tvbuff_t *ls_tvb;
            fc_data_t fc_data = {ETHERTYPE_FIP, 0};

            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_caps, &item);
            ls_tvb = tvb_new_subset(desc_tvb, 4, dlen - 4, -1);
            call_dissector_with_data(fc_handle, ls_tvb, pinfo, subtree, &fc_data);
            proto_item_append_text(item, "%u bytes", dlen - 4);
        }
            break;
        case FIP_DT_VN:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vn, &item);
            proto_tree_add_item(subtree, hf_fip_desc_vn_mac, desc_tvb,
                    2, 6, ENC_NA);
            proto_tree_add_item(subtree, hf_fip_desc_vn_fid, desc_tvb,
                    9, 3, ENC_BIG_ENDIAN);
            text = tvb_fcwwn_to_str(desc_tvb, 12);
            proto_tree_add_string(subtree, hf_fip_desc_vn_wwpn,
                    desc_tvb, 12, 8, text);
            proto_item_append_text(item, "MAC %s  FC_ID %6.6x",
                    tvb_bytes_to_ep_str_punct(desc_tvb, 2, 6, ':'),
                    tvb_get_ntoh24(desc_tvb, 9));
            break;
        case FIP_DT_FKA:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fka, &item);
            val = tvb_get_ntohl(desc_tvb, 4);
            proto_tree_add_uint_format_value(subtree, hf_fip_desc_fka,
                    desc_tvb, 4, 4, val, "%u ms", val);
            proto_item_append_text(item, "%u ms", val);
            break;
        case FIP_DT_VEND:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vend, &item);
            proto_tree_add_item(subtree, hf_fip_desc_vend, desc_tvb,
                    4, 8, ENC_NA);
            if (tvb_bytes_exist(desc_tvb, 9, -1)) {
                proto_tree_add_item(subtree, hf_fip_desc_vend_data,
                     desc_tvb, 9, -1, ENC_NA);
            }
            break;
        case FIP_DT_VLAN:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vlan, &item);
            proto_tree_add_item(subtree, hf_fip_desc_vlan, desc_tvb,
                    2, 2, ENC_BIG_ENDIAN);
            proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2));
            break;
        case FIP_DT_FC4F:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fc4f, &item);
            fip_desc_fc4f(desc_tvb, subtree, item);
            break;
        default:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_unk, &item);
            proto_tree_add_item(subtree, hf_fip_desc_unk, desc_tvb,
                    2, -1, ENC_NA);
            break;
        }
    }
}
Example #3
0
static void
dissect_ipxwan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item *ti;
	proto_tree *ipxwan_tree = NULL;
	int offset = 0;
	guint8 packet_type;
	guint8 num_options;
	guint8 option_number;
	proto_tree *option_tree;
	guint16 option_data_len;
	guint16 wan_link_delay;
	guint32 delay;
	guint32 throughput;
	guint32 delta_time;
	guint8 compression_type;

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

	if (tree) {
		ti = proto_tree_add_item(tree, proto_ipxwan, tvb, 0, -1,
		    FALSE);
		ipxwan_tree = proto_item_add_subtree(ti, ett_ipxwan);
	}

	if (tree) {
		proto_tree_add_item(ipxwan_tree, hf_ipxwan_identifier, tvb,
		    offset, 4, FALSE);
	}
	offset += 4;
	packet_type = tvb_get_guint8(tvb, offset);
	if (check_col(pinfo->cinfo, COL_INFO)) {
		col_add_str(pinfo->cinfo, COL_INFO,
		    val_to_str(packet_type, ipxwan_packet_type_vals,
		        "Unknown packet type %u"));
	}
	if (tree) {
		proto_tree_add_uint(ipxwan_tree, hf_ipxwan_packet_type, tvb,
			offset, 1, packet_type);
		offset += 1;
		proto_tree_add_item(ipxwan_tree, hf_ipxwan_node_id, tvb,
			offset, 4, FALSE);
		offset += 4;
		proto_tree_add_item(ipxwan_tree, hf_ipxwan_sequence_number, tvb,
			offset, 1, FALSE);
		offset += 1;
		num_options = tvb_get_guint8(tvb, offset);
		proto_tree_add_uint(ipxwan_tree, hf_ipxwan_num_options, tvb,
			offset, 1, num_options);
		offset += 1;

		while (num_options != 0) {
			option_number = tvb_get_guint8(tvb, offset);
			ti = proto_tree_add_text(ipxwan_tree, tvb, offset, -1,
			    "Option: %s",
			    val_to_str(option_number, ipxwan_option_num_vals,
			        "Unknown (%u)"));
			option_tree = proto_item_add_subtree(ti,
			    ett_ipxwan_option);

			proto_tree_add_uint(option_tree, hf_ipxwan_option_num,
			    tvb, offset, 1, option_number);
			offset += 1;
			proto_tree_add_item(option_tree, hf_ipxwan_accept_option,
			    tvb, offset, 1, FALSE);
			offset += 1;
			option_data_len = tvb_get_ntohs(tvb, offset);
			proto_tree_add_uint(option_tree, hf_ipxwan_option_data_len,
			    tvb, offset, 2, option_data_len);
			offset += 2;
			proto_item_set_len(ti, option_data_len+4);
			switch (option_number) {

			case OPT_ROUTING_TYPE:
				if (option_data_len != 1) {
					proto_tree_add_text(option_tree,
					    tvb, offset, option_data_len,
					    "Bogus length: %u, should be 1",
					    option_data_len);
				} else {
					proto_tree_add_item(option_tree,
					    hf_ipxwan_routing_type, tvb,
					    offset, 1, FALSE);
				}
				break;

			case OPT_RIP_SAP_INFO_EXCHANGE:
				if (option_data_len != 54) {
					proto_tree_add_text(option_tree,
					    tvb, offset, option_data_len,
					    "Bogus length: %u, should be 54",
					    option_data_len);
				} else {
					wan_link_delay = tvb_get_ntohs(tvb,
					    offset);
					proto_tree_add_uint_format(option_tree,
					    hf_ipxwan_wan_link_delay, tvb,
					    offset, 2, wan_link_delay,
					    "WAN Link Delay: %ums",
					    wan_link_delay);
					proto_tree_add_item(option_tree,
					    hf_ipxwan_common_network_number,
					    tvb, offset+2, 4, FALSE);
					proto_tree_add_item(option_tree,
					    hf_ipxwan_router_name, tvb,
					    offset+6, 48, FALSE);
				}
				break;

			case OPT_NLSP_INFORMATION:
				if (option_data_len != 8) {
					proto_tree_add_text(option_tree,
					    tvb, offset, option_data_len,
					    "Bogus length: %u, should be 8",
					    option_data_len);
				} else {
					delay = tvb_get_ntohl(tvb, offset);
					proto_tree_add_uint_format(option_tree,
					    hf_ipxwan_delay, tvb,
					    offset, 4, delay,
					    "Delay: %uus", delay);
					throughput = tvb_get_ntohl(tvb, offset);
					proto_tree_add_uint_format(option_tree,
					    hf_ipxwan_throughput, tvb,
					    offset, 4, throughput,
					    "Throughput: %uus",
					    throughput);
				}
				break;

			case OPT_NLSP_RAW_THROUGHPUT_DATA:
				if (option_data_len != 8) {
					proto_tree_add_text(option_tree,
					    tvb, offset, option_data_len,
					    "Bogus length: %u, should be 8",
					    option_data_len);
				} else {
					proto_tree_add_item(option_tree,
					    hf_ipxwan_request_size, tvb,
					    offset, 4, FALSE);
					delta_time = tvb_get_ntohl(tvb, offset);
					proto_tree_add_uint_format(option_tree,
					    hf_ipxwan_delta_time, tvb,
					    offset, 4, delta_time,
					    "Delta Time: %uus",
					    delta_time);
				}
				break;

			case OPT_EXTENDED_NODE_ID:
				if (option_data_len != 4) {
					proto_tree_add_text(option_tree,
					    tvb, offset, option_data_len,
					    "Bogus length: %u, should be 4",
					    option_data_len);
				} else {
					proto_tree_add_item(option_tree,
					    hf_ipxwan_extended_node_id, tvb,
					    offset, 4, FALSE);
				}
				break;

			case OPT_NODE_NUMBER:
				if (option_data_len != 6) {
					proto_tree_add_text(option_tree,
					    tvb, offset, option_data_len,
					    "Bogus length: %u, should be 6",
					    option_data_len);
				} else {
					proto_tree_add_item(option_tree,
					    hf_ipxwan_node_number, tvb,
					    offset, 6, FALSE);
				}
				break;

			case OPT_COMPRESSION:
				if (option_data_len < 1) {
					proto_tree_add_text(option_tree,
					    tvb, offset, option_data_len,
					    "Bogus length: %u, should be >= 1",
					    option_data_len);
				} else {
					compression_type = tvb_get_guint8(tvb,
					    offset);
					proto_tree_add_uint(option_tree,
					    hf_ipxwan_compression_type, tvb,
					    offset, 1, compression_type);
					switch (compression_type) {

					case COMP_TYPE_TELEBIT:
						if (option_data_len < 3) {
							proto_tree_add_text(option_tree,
							    tvb, offset+1,
							    option_data_len-1,
							    "Bogus length: %u, should be >= 3",
							    option_data_len);
						} else {
							proto_tree_add_text(
							    option_tree,
							    tvb, offset+1, 1,
							    "Compression options: 0x%02x",
							    tvb_get_guint8(tvb,
							        offset+1));
							proto_tree_add_text(
							    option_tree,
							    tvb, offset+2, 1,
							    "Number of compression slots: %u",
							    tvb_get_guint8(tvb,
							        offset+2));
						}
						break;

					default:
						proto_tree_add_text(option_tree,
						    tvb, offset+1,
						    option_data_len-1,
						    "Option parameters");
						break;
					}
				}
				break;

			case OPT_PAD:
				proto_tree_add_text(option_tree,
				    tvb, offset, option_data_len,
				    "Padding");
				break;

			default:
				proto_tree_add_text(option_tree,
				    tvb, offset, option_data_len,
				    "Option value");
				break;
			}

			offset += option_data_len;
			num_options--;
		}
	}
}
Example #4
0
void
xmpp_iq(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet)
{
    proto_item *xmpp_iq_item;
    proto_tree *xmpp_iq_tree;

    xmpp_attr_t *attr_id, *attr_type;

    xmpp_attr_info attrs_info[] = {
        {"xmlns", hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
        {"id", hf_xmpp_id, TRUE, TRUE, NULL, NULL},
        {"type", hf_xmpp_type, TRUE, TRUE, NULL, NULL},
        {"from", hf_xmpp_from, FALSE, TRUE, NULL, NULL},
        {"to", hf_xmpp_to, FALSE, TRUE, NULL, NULL},
        {"xml:lang", -1, FALSE, FALSE, NULL, NULL}
    };

    conversation_t     *conversation;
    xmpp_conv_info_t   *xmpp_info;
    xmpp_transaction_t *reqresp_trans;

    xmpp_elem_info elems_info [] = {
        {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","http://jabber.org/protocol/disco#items"), xmpp_disco_items_query, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "jabber:iq:roster"), xmpp_roster_query, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/disco#info"), xmpp_disco_info_query, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/bytestreams"), xmpp_bytestreams_query, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/muc#owner"), xmpp_muc_owner_query, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns", "http://jabber.org/protocol/muc#admin"), xmpp_muc_admin_query, ONE},
        {NAME, "bind", xmpp_iq_bind, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("session", "xmlns", "urn:ietf:params:xml:ns:xmpp-session"), xmpp_session, ONE},
        {NAME, "vCard", xmpp_vcard, ONE},
        {NAME, "jingle", xmpp_jingle, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("services", "xmlns", "http://jabber.org/protocol/jinglenodes"), xmpp_jinglenodes_services, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("channel", "xmlns", "http://jabber.org/protocol/jinglenodes#channel"), xmpp_jinglenodes_channel, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("open", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_open, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("close", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_close, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("data", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_data, ONE},
        {NAME, "si", xmpp_si, ONE},
        {NAME, "error", xmpp_error, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("session", "xmlns", "http://www.google.com/session"), xmpp_gtalk_session, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:jingleinfo"), xmpp_gtalk_jingleinfo_query, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("usersetting", "xmlns","google:setting"), xmpp_gtalk_usersetting, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","jabber:iq:last"), xmpp_last_query, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","jabber:iq:version"), xmpp_version_query, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:mail:notify"), xmpp_gtalk_mail_query, ONE},
        {NAME, "mailbox", xmpp_gtalk_mail_mailbox, ONE},
        {NAME, "new-mail", xmpp_gtalk_mail_new_mail, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("query", "xmlns","google:shared-status"), xmpp_gtalk_status_query, ONE},
        {NAME, "conference-info", xmpp_conference_info, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("ping", "xmlns","urn:xmpp:ping"), xmpp_ping, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("inputevt", "xmlns","http://jitsi.org/protocol/inputevt"), xmpp_jitsi_inputevt, ONE},
    };

    attr_id      = xmpp_get_attr(packet, "id");
    attr_type    = xmpp_get_attr(packet, "type");

    conversation = find_or_create_conversation(pinfo);
    xmpp_info    = (xmpp_conv_info_t *)conversation_get_proto_data(conversation, proto_xmpp);

    xmpp_iq_item = proto_tree_add_item(tree, hf_xmpp_iq, tvb, packet->offset, packet->length, ENC_LITTLE_ENDIAN);
    xmpp_iq_tree = proto_item_add_subtree(xmpp_iq_item,ett_xmpp_iq);

    xmpp_display_attrs(xmpp_iq_tree, packet, pinfo, tvb, attrs_info,  array_length(attrs_info));


    col_clear(pinfo->cinfo, COL_INFO);
    col_add_fstr(pinfo->cinfo, COL_INFO, "IQ(%s) ", attr_type?attr_type->value:"");

    xmpp_display_elems(xmpp_iq_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));

    /*displays generated info such as req/resp tracking, jingle sid
     * in each packet related to specified jingle session and IBB sid in packet related to it*/
    if(xmpp_info && attr_id)
    {
        gchar *jingle_sid, *ibb_sid, *gtalk_sid;

        jingle_sid = (gchar *)se_tree_lookup_string(xmpp_info->jingle_sessions, attr_id->value, EMEM_TREE_STRING_NOCASE);

        if (jingle_sid) {
            proto_item *it = proto_tree_add_string(tree, hf_xmpp_jingle_session, tvb, 0, 0, jingle_sid);
            PROTO_ITEM_SET_GENERATED(it);
        }

        ibb_sid = (gchar *)se_tree_lookup_string(xmpp_info->ibb_sessions, attr_id->value, EMEM_TREE_STRING_NOCASE);

        if (ibb_sid) {
            proto_item *it = proto_tree_add_string(tree, hf_xmpp_ibb, tvb, 0, 0, ibb_sid);
            PROTO_ITEM_SET_GENERATED(it);
        }

        gtalk_sid = (gchar *)se_tree_lookup_string(xmpp_info->gtalk_sessions, attr_id->value, EMEM_TREE_STRING_NOCASE);

        if (gtalk_sid) {
            proto_item *it = proto_tree_add_string(tree, hf_xmpp_gtalk, tvb, 0, 0, gtalk_sid);
            PROTO_ITEM_SET_GENERATED(it);
        }

        reqresp_trans = (xmpp_transaction_t *)se_tree_lookup_string(xmpp_info->req_resp, attr_id->value, EMEM_TREE_STRING_NOCASE);
        /*displays request/response field in each iq packet*/
        if (reqresp_trans) {

            if (reqresp_trans->req_frame == pinfo->fd->num) {
                if (reqresp_trans->resp_frame) {
                    proto_item *it = proto_tree_add_uint(tree, hf_xmpp_response_in, tvb, 0, 0, reqresp_trans->resp_frame);
                    PROTO_ITEM_SET_GENERATED(it);
                } else
                {
                    expert_add_info_format(pinfo, xmpp_iq_item , PI_PROTOCOL, PI_CHAT, "Packet without response");
                }

            } else {
                if (reqresp_trans->req_frame) {
                    proto_item *it = proto_tree_add_uint(tree, hf_xmpp_response_to, tvb, 0, 0, reqresp_trans->req_frame);
                    PROTO_ITEM_SET_GENERATED(it);
                } else
                {
                    expert_add_info_format(pinfo, xmpp_iq_item , PI_PROTOCOL, PI_CHAT, "Packet without response");
                }
            }
        }
    }
}
Example #5
0
static void
dissect_nbd_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	guint32 magic, error, packet;
	guint32 handle[2];
	guint64 from;
	int offset=0;
	proto_tree *tree=NULL;
	proto_item *item=NULL;
	conversation_t *conversation;
	nbd_conv_info_t *nbd_info;
	nbd_transaction_t *nbd_trans=NULL;
	emem_tree_key_t hkey[3];

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

	col_clear(pinfo->cinfo, COL_INFO);

	item = proto_tree_add_item(parent_tree, proto_nbd, tvb, 0, -1, ENC_NA);
	tree = proto_item_add_subtree(item, ett_nbd);


	magic=tvb_get_ntohl(tvb, offset);
	proto_tree_add_item(tree, hf_nbd_magic, tvb, offset, 4, ENC_BIG_ENDIAN);
	offset+=4;


	/* grab what we need to do the request/response matching */
	switch(magic){
	case NBD_REQUEST_MAGIC:
	case NBD_RESPONSE_MAGIC:
		handle[0]=tvb_get_ntohl(tvb, offset+4);
		handle[1]=tvb_get_ntohl(tvb, offset+8);
		break;
	default:
		return;
	}

	conversation = find_or_create_conversation(pinfo);

	/*
	 * Do we already have a state structure for this conv
	 */
	nbd_info = conversation_get_proto_data(conversation, proto_nbd);
	if (!nbd_info) {
		/* No.  Attach that information to the conversation, and add
		 * it to the list of information structures.
		 */
		nbd_info = se_alloc(sizeof(nbd_conv_info_t));
		nbd_info->unacked_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "nbd_unacked_pdus");
		nbd_info->acked_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "nbd_acked_pdus");

		conversation_add_proto_data(conversation, proto_nbd, nbd_info);
	}
	if(!pinfo->fd->flags.visited){
		if(magic==NBD_REQUEST_MAGIC){
			/* This is a request */
			nbd_trans=se_alloc(sizeof(nbd_transaction_t));
			nbd_trans->req_frame=pinfo->fd->num;
			nbd_trans->rep_frame=0;
			nbd_trans->req_time=pinfo->fd->abs_ts;
			nbd_trans->type=tvb_get_ntohl(tvb, offset);
			nbd_trans->datalen=tvb_get_ntohl(tvb, offset+20);

			hkey[0].length=2;
			hkey[0].key=handle;
			hkey[1].length=0;

			se_tree_insert32_array(nbd_info->unacked_pdus, hkey, (void *)nbd_trans);
		} else if(magic==NBD_RESPONSE_MAGIC){
			hkey[0].length=2;
			hkey[0].key=handle;
			hkey[1].length=0;

			nbd_trans=se_tree_lookup32_array(nbd_info->unacked_pdus, hkey);
			if(nbd_trans){
				nbd_trans->rep_frame=pinfo->fd->num;

				hkey[0].length=1;
				hkey[0].key=&nbd_trans->rep_frame;
				hkey[1].length=2;
				hkey[1].key=handle;
				hkey[2].length=0;
				se_tree_insert32_array(nbd_info->acked_pdus, hkey, (void *)nbd_trans);
				hkey[0].length=1;
				hkey[0].key=&nbd_trans->req_frame;
				hkey[1].length=2;
				hkey[1].key=handle;
				hkey[2].length=0;
				se_tree_insert32_array(nbd_info->acked_pdus, hkey, (void *)nbd_trans);
			}
		}
	} else {
		packet=pinfo->fd->num;
		hkey[0].length=1;
		hkey[0].key=&packet;
		hkey[1].length=2;
		hkey[1].key=handle;
		hkey[2].length=0;

		nbd_trans=se_tree_lookup32_array(nbd_info->acked_pdus, hkey);
	}
	/* The bloody handles are reused !!! eventhough they are 64 bits.
	 * So we must verify we got the "correct" one
	 */
	if( (magic==NBD_RESPONSE_MAGIC)
	&&  (nbd_trans)
	&&  (pinfo->fd->num<nbd_trans->req_frame) ){
		/* must have been the wrong one */
		nbd_trans=NULL;
	}

	if(!nbd_trans){
		/* create a "fake" nbd_trans structure */
		nbd_trans=ep_alloc(sizeof(nbd_transaction_t));
		nbd_trans->req_frame=0;
		nbd_trans->rep_frame=0;
		nbd_trans->req_time=pinfo->fd->abs_ts;
		nbd_trans->type=0xff;
		nbd_trans->datalen=0;
	}

	/* print state tracking in the tree */
	if(magic==NBD_REQUEST_MAGIC){
		/* This is a request */
		if(nbd_trans->rep_frame){
			proto_item *it;

			it=proto_tree_add_uint(tree, hf_nbd_response_in, tvb, 0, 0, nbd_trans->rep_frame);
			PROTO_ITEM_SET_GENERATED(it);
		}
	} else if(magic==NBD_RESPONSE_MAGIC){
		/* This is a reply */
		if(nbd_trans->req_frame){
			proto_item *it;
			nstime_t ns;

			it=proto_tree_add_uint(tree, hf_nbd_response_to, tvb, 0, 0, nbd_trans->req_frame);
			PROTO_ITEM_SET_GENERATED(it);

			nstime_delta(&ns, &pinfo->fd->abs_ts, &nbd_trans->req_time);
			it=proto_tree_add_time(tree, hf_nbd_time, tvb, 0, 0, &ns);
			PROTO_ITEM_SET_GENERATED(it);
		}
	}


	switch(magic){
	case NBD_REQUEST_MAGIC:
		proto_tree_add_item(tree, hf_nbd_type, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset+=4;

		proto_tree_add_item(tree, hf_nbd_handle, tvb, offset, 8, ENC_BIG_ENDIAN);
		offset+=8;

		from=tvb_get_ntoh64(tvb, offset);
		proto_tree_add_item(tree, hf_nbd_from, tvb, offset, 8, ENC_BIG_ENDIAN);
		offset+=8;

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

		if(check_col(pinfo->cinfo, COL_INFO)){
			switch(nbd_trans->type){
			case NBD_CMD_WRITE:
				col_add_fstr(pinfo->cinfo, COL_INFO, "Write Request  Offset:0x%" G_GINT64_MODIFIER "x Length:%d", from, nbd_trans->datalen);
				break;
			case NBD_CMD_READ:
				col_add_fstr(pinfo->cinfo, COL_INFO, "Read Request  Offset:0x%" G_GINT64_MODIFIER "x Length:%d", from, nbd_trans->datalen);
				break;
			case NBD_CMD_DISC:
				col_set_str(pinfo->cinfo, COL_INFO, "Disconnect Request");
				break;
			}
		}

		if(nbd_trans->type==NBD_CMD_WRITE){
			proto_tree_add_item(tree, hf_nbd_data, tvb, offset, nbd_trans->datalen, ENC_NA);
		}
		break;
	case NBD_RESPONSE_MAGIC:
		item=proto_tree_add_uint(tree, hf_nbd_type, tvb, 0, 0, nbd_trans->type);
		PROTO_ITEM_SET_GENERATED(item);

		error=tvb_get_ntohl(tvb, offset);
		proto_tree_add_item(tree, hf_nbd_error, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset+=4;

		proto_tree_add_item(tree, hf_nbd_handle, tvb, offset, 8, ENC_BIG_ENDIAN);
		offset+=8;

		if(check_col(pinfo->cinfo, COL_INFO)){
			col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response  Error:%d", (nbd_trans->type==NBD_CMD_WRITE)?"Write":"Read", error);
		}

		if(nbd_trans->type==NBD_CMD_READ){
			proto_tree_add_item(tree, hf_nbd_data, tvb, offset, nbd_trans->datalen, ENC_NA);
		}
		break;
	}

	return;
}
Example #6
0
static void
dissect_ax25_nol3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree )
{
	proto_item *ti;
	proto_tree *ax25_nol3_tree;
	char       *info_buffer;
	int         offset;
	tvbuff_t   *next_tvb = NULL;
	guint8      dti      = 0;
	gboolean    dissected;

	info_buffer = (char *)wmem_alloc( wmem_packet_scope(), STRLEN );
	info_buffer[0] = '\0';

	col_set_str( pinfo->cinfo, COL_PROTOCOL, "AX.25-NoL3");

	col_clear( pinfo->cinfo, COL_INFO);

	offset = 0;
	g_snprintf( info_buffer, STRLEN, "Text" );

	if ( gPREF_APRS )
		{
		dti = tvb_get_guint8( tvb, offset );
		if ( isaprs( dti ) )
			g_snprintf( info_buffer, STRLEN, "APRS" );
		}
	if ( gPREF_DX )
		{
		if ( tvb_get_guint8( tvb, offset ) == 'D' && tvb_get_guint8( tvb, offset + 1 ) == 'X' )
		g_snprintf( info_buffer, STRLEN, "DX cluster" );
		}

	col_add_str( pinfo->cinfo, COL_INFO, info_buffer );

	/* Call sub-dissectors here */

	if ( parent_tree )
		{
		/* create display subtree for the protocol */
		ti = proto_tree_add_protocol_format( parent_tree,
							proto_ax25_nol3,
							tvb,
							0,
							-1,
							"AX.25 No Layer 3 - (%s)", info_buffer );
		ax25_nol3_tree = proto_item_add_subtree( ti, ett_ax25_nol3 );

		next_tvb = tvb_new_subset_remaining(tvb, offset);
		dissected = FALSE;
		if ( gPREF_APRS )
			{
			if ( isaprs( dti ) )
				{
				dissected = TRUE;
				call_dissector( aprs_handle , next_tvb, pinfo, ax25_nol3_tree );
				}
			}
		if ( gPREF_DX )
			{
			if ( tvb_get_guint8( tvb, offset ) == 'D' && tvb_get_guint8( tvb, offset + 1 ) == 'X' )
				{
				dissected = TRUE;
				dissect_dx( next_tvb, pinfo, ax25_nol3_tree );
				}
			}
		if ( ! dissected )
			call_dissector( default_handle , next_tvb, pinfo, ax25_nol3_tree );

		}
}
static void
dissect_ipvs_syncd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	proto_tree *tree;
	proto_item *item;
	int offset = 0;
	guint8 cnt = 0;
	int conn = 0;

	item = proto_tree_add_item(parent_tree, proto_ipvs_syncd, tvb, offset, -1, ENC_NA);
	tree = proto_item_add_subtree(item, ett_ipvs_syncd);


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

	cnt = tvb_get_guint8(tvb, offset);
	proto_tree_add_item(tree, hf_conn_count, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	proto_tree_add_item(tree, hf_syncid, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	proto_tree_add_item(tree, hf_size, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	for (conn = 0; conn < cnt; conn++)
	{
		proto_tree *ctree, *ti;
		proto_tree *ftree, *fi;
		guint16 flags;

		ti = proto_tree_add_text(tree, tvb, offset, 24, "Connection #%d", conn+1);
		ctree = proto_item_add_subtree(ti, ett_conn);

		proto_tree_add_item(ctree, hf_resv8, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(ctree, hf_proto, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(ctree, hf_cport, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		proto_tree_add_item(ctree, hf_vport, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		proto_tree_add_item(ctree, hf_dport, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		proto_tree_add_item(ctree, hf_caddr, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;

		proto_tree_add_item(ctree, hf_vaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;

		proto_tree_add_item(ctree, hf_daddr, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;

		flags = tvb_get_ntohs(tvb, offset);
		fi = proto_tree_add_item(ctree, hf_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
		ftree = proto_item_add_subtree(fi, ett_flags);
		proto_tree_add_item(ftree, hf_flags_conn_type, tvb, offset, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(ftree, hf_flags_hashed_entry, tvb, offset, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(ftree, hf_flags_no_output_packets, tvb, offset, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(ftree, hf_flags_conn_not_established, tvb, offset, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(ftree, hf_flags_adjust_output_seq, tvb, offset, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(ftree, hf_flags_adjust_input_seq, tvb, offset, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(ftree, hf_flags_no_client_port_set, tvb, offset, 2, ENC_BIG_ENDIAN);

		offset += 2;

		proto_tree_add_item(ctree, hf_state, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* we have full connection info */
		if ( flags & IP_VS_CONN_F_SEQ_MASK )
		{
			proto_tree_add_item(ctree, hf_in_seq_init, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(ctree, hf_in_seq_delta, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(ctree, hf_in_seq_pdelta, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(ctree, hf_out_seq_init, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(ctree, hf_out_seq_delta, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			proto_tree_add_item(ctree, hf_out_seq_pdelta, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
		}

	}
}
Example #8
0
static void
dissect_ipxsap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*sap_tree, *s_tree;
	proto_item	*ti, *hidden_item;
	int		cursor;
	struct sap_query query;
	guint16		server_type;
	gchar		*server_name;
	guint16		server_port;
	guint16		intermediate_network;

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

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

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

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

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

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

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

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

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

				proto_tree_add_text(s_tree, tvb, cursor, 2, "Server Type: %s (0x%04X)",
				    val_to_str_ext_const(server_type, &novell_server_vals_ext, "Unknown"),
				    server_type);
				proto_tree_add_text(s_tree, tvb, cursor+50, 4, "Network: %s",
						ipxnet_to_string(tvb_get_ptr(tvb, cursor+50, 4)));
				proto_tree_add_text(s_tree, tvb, cursor+54, 6, "Node: %s",
						tvb_ether_to_str(tvb, cursor+54));
				server_port = tvb_get_ntohs(tvb, cursor+60);
				proto_tree_add_text(s_tree, tvb, cursor+60, 2, "Socket: %s (0x%04x)",
						socket_text(server_port),
						server_port);
				intermediate_network = tvb_get_ntohs(tvb, cursor+62);
				proto_tree_add_text(s_tree, tvb, cursor+62, 2,
						"Intermediate Networks: %d",
						intermediate_network);
			}
		}
		else {  /* queries */
			proto_tree_add_text(sap_tree, tvb, 2, 2, "Server Type: %s (0x%04X)",
				val_to_str_ext_const(query.server_type, &novell_server_vals_ext, "Unknown"),
				query.server_type);
		}
	}
}
Example #9
0
static void
dissect_ipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	tvbuff_t	*next_tvb;

	proto_tree	*ipx_tree = NULL;
	proto_item	*ti = NULL, *hidden_item;

	const guint8	*src_net_node, *dst_net_node;

	guint8		ipx_hops;
	char 		*str;
	guint16		first_socket, second_socket;
	guint32		ipx_snet, ipx_dnet;
	static ipxhdr_t ipxh_arr[4];
	static int ipx_current=0;
	ipxhdr_t *ipxh;

	ipx_current++;
	if(ipx_current==4){
		ipx_current=0;
	}
	ipxh=&ipxh_arr[ipx_current];


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

	/* Calculate here for use in pinfo and in tree */
	ipxh->ipx_dsocket = tvb_get_ntohs(tvb, 16);
	ipxh->ipx_ssocket = tvb_get_ntohs(tvb, 28);
	ipxh->ipx_type    = tvb_get_guint8(tvb, 5);
	ipxh->ipx_length  = tvb_get_ntohs(tvb, 2);

	pinfo->ptype = PT_IPX;
	pinfo->srcport = ipxh->ipx_ssocket;
	pinfo->destport = ipxh->ipx_dsocket;

	/* Adjust the tvbuff length to include only the IPX datagram. */
	set_actual_length(tvb, ipxh->ipx_length);

	src_net_node = tvb_get_ptr(tvb, 18, 10);
	dst_net_node = tvb_get_ptr(tvb, 6,  10);

	SET_ADDRESS(&pinfo->net_src,	AT_IPX, 10, src_net_node);
	SET_ADDRESS(&pinfo->src,	AT_IPX, 10, src_net_node);
	SET_ADDRESS(&ipxh->ipx_src,	AT_IPX, 10, src_net_node);
	SET_ADDRESS(&pinfo->net_dst,	AT_IPX, 10, dst_net_node);
	SET_ADDRESS(&pinfo->dst,	AT_IPX, 10, dst_net_node);
	SET_ADDRESS(&ipxh->ipx_dst,	AT_IPX, 10, dst_net_node);

	if (check_col(pinfo->cinfo, COL_INFO))
		col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%04x)",
				socket_text(ipxh->ipx_dsocket), ipxh->ipx_dsocket);

	if (tree) {

		ti = proto_tree_add_item(tree, proto_ipx, tvb, 0, IPX_HEADER_LEN, ENC_NA);
		ipx_tree = proto_item_add_subtree(ti, ett_ipx);
	}

	str=ep_address_to_str(&pinfo->net_src);
	hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_src, tvb, 0, 0, str);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_addr, tvb, 0, 0, str);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	str=ep_address_to_str(&pinfo->net_dst);
	hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_dst, tvb, 0, 0, str);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	hidden_item = proto_tree_add_string(ipx_tree, hf_ipx_addr, tvb, 0, 0, str);
	PROTO_ITEM_SET_HIDDEN(hidden_item);

	proto_tree_add_item(ipx_tree, hf_ipx_checksum, tvb, 0, 2, ENC_BIG_ENDIAN);
	proto_tree_add_uint_format(ipx_tree, hf_ipx_len, tvb, 2, 2, ipxh->ipx_length,
		"Length: %d bytes", ipxh->ipx_length);
	ipx_hops = tvb_get_guint8(tvb, 4);
	proto_tree_add_uint_format(ipx_tree, hf_ipx_hops, tvb, 4, 1, ipx_hops,
		"Transport Control: %d hops", ipx_hops);
	proto_tree_add_uint(ipx_tree, hf_ipx_packet_type, tvb, 5, 1, ipxh->ipx_type);

	/* Destination */
	ipx_dnet = tvb_get_ntohl(tvb, 6);
	proto_tree_add_ipxnet(ipx_tree, hf_ipx_dnet, tvb, 6, 4,
		ipx_dnet);
	hidden_item = proto_tree_add_ipxnet(ipx_tree, hf_ipx_net, tvb, 6, 4,
		ipx_dnet);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	proto_tree_add_item(ipx_tree, hf_ipx_dnode, tvb, 10, 6, ENC_NA);
	hidden_item = proto_tree_add_item(ipx_tree, hf_ipx_node, tvb, 10, 6, ENC_NA);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	proto_tree_add_uint(ipx_tree, hf_ipx_dsocket, tvb, 16, 2,
		ipxh->ipx_dsocket);
	hidden_item = proto_tree_add_uint(ipx_tree, hf_ipx_socket, tvb, 16, 2,
		ipxh->ipx_dsocket);
	PROTO_ITEM_SET_HIDDEN(hidden_item);

	/* Source */
	ipx_snet = tvb_get_ntohl(tvb, 18);
	proto_tree_add_ipxnet(ipx_tree, hf_ipx_snet, tvb, 18, 4,
		ipx_snet);
	hidden_item = proto_tree_add_ipxnet(ipx_tree, hf_ipx_net, tvb, 18, 4,
		ipx_snet);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	proto_tree_add_item(ipx_tree, hf_ipx_snode, tvb, 22, 6, ENC_NA);
	hidden_item = proto_tree_add_item(ipx_tree, hf_ipx_node, tvb, 22, 6, ENC_NA);
	PROTO_ITEM_SET_HIDDEN(hidden_item);
	proto_tree_add_uint(ipx_tree, hf_ipx_ssocket, tvb, 28, 2,
		ipxh->ipx_ssocket);
	hidden_item = proto_tree_add_uint(ipx_tree, hf_ipx_socket, tvb, 28, 2,
		ipxh->ipx_ssocket);
	PROTO_ITEM_SET_HIDDEN(hidden_item);

	/* Make the next tvbuff */
	next_tvb = tvb_new_subset_remaining(tvb, IPX_HEADER_LEN);

	/*
	 * Let the subdissector know what type of IPX packet this is.
	 */
	pinfo->ipxptype = ipxh->ipx_type;

	/*
	 * Check the socket numbers before we check the packet type;
	 * we've seen non-NCP packets with a type of NCP and a
	 * destination socket of IPX_SOCKET_IPX_MESSAGE, and SAP
	 * packets with a type of NCP and a destination socket of
	 * IPX_SOCKET_SAP.
	 *
	 * We've seen NCP packets with a type of NCP, a source socket of
	 * IPX_SOCKET_NCP, and a destination socket of IPX_SOCKET_IPX_MESSAGE,
	 * and we've seen NCP packets with a type of NCP, a source socket of
	 * IPX_SOCKET_IPX_MESSAGE, and a destination socket of
	 * IPX_SOCKET_NCP, so testing the destination socket first doesn't
	 * always give the right answer.  We've also seen SAP packets with
	 * a source socket of IPX_SOCKET_SAP and a destination socket of
	 * IPX_SOCKET_IPX_MESSAGE.
	 *
	 * Unfortunately, we've also seen packets with a source socket
	 * of IPX_SOCKET_NWLINK_SMB_SERVER and a destination socket
	 * of IPX_SOCKET_NWLINK_SMB_NAMEQUERY that were NMPI packets,
	 * not SMB packets, so testing the lower-valued socket first
	 * also doesn't always give the right answer.
	 *
	 * So we start out assuming we should test the lower-numbered
	 * socket number first, but, if the higher-numbered socket is
	 * IPX_SOCKET_NWLINK_SMB_NAMEQUERY, we assume that it's a
	 * NMPI query, and test only that socket.
	 */
	if (ipxh->ipx_ssocket > ipxh->ipx_dsocket) {
		first_socket = ipxh->ipx_dsocket;
		second_socket = ipxh->ipx_ssocket;
	} else {
		first_socket = ipxh->ipx_ssocket;
		second_socket = ipxh->ipx_dsocket;
	}

	tap_queue_packet(ipx_tap, pinfo, ipxh);

	if (second_socket != IPX_SOCKET_NWLINK_SMB_NAMEQUERY) {
		if (dissector_try_uint(ipx_socket_dissector_table, first_socket,
		    next_tvb, pinfo, tree))
			return;
	}
	if (dissector_try_uint(ipx_socket_dissector_table, second_socket,
	    next_tvb, pinfo, tree))
		return;

	/*
	 * Neither of them are known; try the packet type, which will
	 * at least let us, for example, dissect SPX packets as SPX.
	 */
	if (dissector_try_uint(ipx_type_dissector_table, ipxh->ipx_type, next_tvb,
	    pinfo, tree))
		return;

	call_dissector(data_handle,next_tvb, pinfo, tree);
}
Example #10
0
static void
dissect_sdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*sdlc_tree;
	proto_item	*sdlc_ti;
	guint8		addr;
	guint16		control;
	int		sdlc_header_len;
	gboolean	is_response;
	tvbuff_t	*next_tvb;

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

	addr = tvb_get_guint8(tvb, 0);
	sdlc_header_len = 1;	/* address */

	/*
	 * XXX - is there something in the SDLC header that indicates
	 * how to interpret "command vs. response" based on the
	 * direction?
	 */
	if (pinfo->p2p_dir == P2P_DIR_SENT) {
		is_response = FALSE;
		col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
		col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
	}
	else {
		/* XXX - what if the direction is unknown? */
		is_response = TRUE;
		col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
		col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
	}

	if (tree) {
		sdlc_ti = proto_tree_add_item(tree, proto_sdlc, tvb, 0, -1,
		    ENC_NA);
		sdlc_tree = proto_item_add_subtree(sdlc_ti, ett_sdlc);

		proto_tree_add_uint(sdlc_tree, hf_sdlc_address, tvb, 0, 1,
		    addr);
	} else {
		sdlc_ti = NULL;
		sdlc_tree = NULL;
	}

	/*
	 * XXX - SDLC has a mod-128 mode as well as a mod-7 mode.
	 * We can infer the mode from an SNRM/SRME frame, but if
	 * we don't see one of them, we may have to have a preference
	 * to control what to use.
	 */
	control = dissect_xdlc_control(tvb, 1, pinfo, sdlc_tree, hf_sdlc_control,
	    ett_sdlc_control, &sdlc_cf_items, NULL, NULL, NULL,
	    is_response, FALSE, FALSE);
	sdlc_header_len += XDLC_CONTROL_LEN(control, FALSE);

	if (tree)
		proto_item_set_len(sdlc_ti, sdlc_header_len);

	/*
	 * XXX - is there an FCS at the end, at least in Sniffer
	 * captures?  (There doesn't appear to be.)
	 */
	next_tvb = tvb_new_subset_remaining(tvb, sdlc_header_len);
	if (XDLC_IS_INFORMATION(control)) {
		/* call the SNA dissector */
		call_dissector(sna_handle, next_tvb, pinfo, tree);
	} else
		call_dissector(data_handle, next_tvb, pinfo, tree);
}
/*
* Dissect X518 PDUs inside a ROS PDUs
*/
static void
dissect_dsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	int offset = 0;
	int old_offset;
	proto_item *item=NULL;
	proto_tree *tree=NULL;
	int (*dsp_dissector)(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_) = NULL;
	const char *dsp_op_name;
	asn1_ctx_t asn1_ctx;

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

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

	if(parent_tree){
		item = proto_tree_add_item(parent_tree, proto_dsp, tvb, 0, -1, ENC_NA);
		tree = proto_item_add_subtree(item, ett_dsp);
	}
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "DAP");
  	col_clear(pinfo->cinfo, COL_INFO);

	switch(session->ros_op & ROS_OP_MASK) {
	case (ROS_OP_BIND | ROS_OP_ARGUMENT):	/*  BindInvoke */
	  dsp_dissector = dissect_dsp_DSASystemBindArgument;
	  dsp_op_name = "System-Bind-Argument";
	  break;
	case (ROS_OP_BIND | ROS_OP_RESULT):	/*  BindResult */
	  dsp_dissector = dissect_dsp_DSASystemBindResult;
	  dsp_op_name = "System-Bind-Result";
	  break;
	case (ROS_OP_BIND | ROS_OP_ERROR):	/*  BindError */
	  dsp_dissector = dissect_dsp_DSASystemBindError;
	  dsp_op_name = "System-Bind-Error";
	  break;
	case (ROS_OP_INVOKE | ROS_OP_ARGUMENT):	/*  Invoke Argument */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* read */
	    dsp_dissector = dissect_dsp_ChainedReadArgument;
	    dsp_op_name = "Chained-Read-Argument";
	    break;
	  case 2: /* compare */
	    dsp_dissector = dissect_dsp_ChainedCompareArgument;
	    dsp_op_name = "Chained-Compare-Argument";
	    break;
	  case 3: /* abandon */
	    dsp_dissector = dissect_dsp_ChainedAbandonArgument;
	    dsp_op_name = "Chained-Abandon-Argument";
	    break;
	  case 4: /* list */
	    dsp_dissector = dissect_dsp_ChainedListArgument;
	    dsp_op_name = "Chained-List-Argument";
	    break;
	  case 5: /* search */
	    dsp_dissector = dissect_dsp_ChainedSearchArgument;
	    dsp_op_name = "Chained-Search-Argument";
	    break;
	  case 6: /* addEntry */
	    dsp_dissector = dissect_dsp_ChainedAddEntryArgument;
	    dsp_op_name = "Chained-Add-Entry-Argument";
	    break;
	  case 7: /* removeEntry */
	    dsp_dissector = dissect_dsp_ChainedRemoveEntryArgument;
	    dsp_op_name = "Chained-Remove-Entry-Argument";
	    break;
	  case 8: /* modifyEntry */
	    dsp_dissector = dissect_dsp_ChainedModifyEntryArgument;
	    dsp_op_name = "ChainedModify-Entry-Argument";
	    break;
	  case 9: /* modifyDN */
	    dsp_dissector = dissect_dsp_ChainedModifyDNArgument;
	    dsp_op_name = "ChainedModify-DN-Argument";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DSP opcode (%d)",
				session->ros_op & ROS_OP_OPCODE_MASK);
	    break;
	  }
	  break;
	case (ROS_OP_INVOKE | ROS_OP_RESULT):	/*  Return Result */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* read */
	    dsp_dissector = dissect_dsp_ChainedReadResult;
	    dsp_op_name = "Chained-Read-Result";
	    break;
	  case 2: /* compare */
	    dsp_dissector = dissect_dsp_ChainedCompareResult;
	    dsp_op_name = "Chained-Compare-Result";
	    break;
	  case 3: /* abandon */
	    dsp_dissector = dissect_dsp_ChainedAbandonResult;
	    dsp_op_name = "Chained-Abandon-Result";
	    break;
	  case 4: /* list */
	    dsp_dissector = dissect_dsp_ChainedListResult;
	    dsp_op_name = "Chained-List-Result";
	    break;
	  case 5: /* search */
	    dsp_dissector = dissect_dsp_ChainedSearchResult;
	    dsp_op_name = "Chained-Search-Result";
	    break;
	  case 6: /* addEntry */
	    dsp_dissector = dissect_dsp_ChainedAddEntryResult;
	    dsp_op_name = "Chained-Add-Entry-Result";
	    break;
	  case 7: /* removeEntry */
	    dsp_dissector = dissect_dsp_ChainedRemoveEntryResult;
	    dsp_op_name = "Chained-Remove-Entry-Result";
	    break;
	  case 8: /* modifyEntry */
	    dsp_dissector = dissect_dsp_ChainedModifyEntryResult;
	    dsp_op_name = "Chained-Modify-Entry-Result";
	    break;
	  case 9: /* modifyDN */
	    dsp_dissector = dissect_dsp_ChainedModifyDNResult;
	    dsp_op_name = "ChainedModify-DN-Result";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DSP opcode");
	    break;
	  }
	  break;
	case (ROS_OP_INVOKE | ROS_OP_ERROR):	/*  Return Error */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* attributeError */
	    dsp_dissector = dissect_dap_AttributeError;
	    dsp_op_name = "Attribute-Error";
	    break;
	  case 2: /* nameError */
	    dsp_dissector = dissect_dap_NameError;
	    dsp_op_name = "Name-Error";
	    break;
	  case 3: /* serviceError */
	    dsp_dissector = dissect_dap_ServiceError;
	    dsp_op_name = "Service-Error";
	    break;
	  case 4: /* referral */
	    dsp_dissector = dissect_dap_Referral;
	    dsp_op_name = "Referral";
	    break;
	  case 5: /* abandoned */
	    dsp_dissector = dissect_dap_Abandoned;
	    dsp_op_name = "Abandoned";
	    break;
	  case 6: /* securityError */
	    dsp_dissector = dissect_dap_SecurityError;
	    dsp_op_name = "Security-Error";
	    break;
	  case 7: /* abandonFailed */
	    dsp_dissector = dissect_dap_AbandonFailedError;
	    dsp_op_name = "Abandon-Failed-Error";
	    break;
	  case 8: /* updateError */
	    dsp_dissector = dissect_dap_UpdateError;
	    dsp_op_name = "Update-Error";
	    break;
	  case 9: /* DSAReferral */
	    dsp_dissector = dissect_dsp_DSAReferral;
	    dsp_op_name = "DSA-Referral";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DSP errcode");
	    break;
	  }
	  break;
	default:
	  proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DSP PDU");
	  return;
	}

	if(dsp_dissector) {
    col_set_str(pinfo->cinfo, COL_INFO, dsp_op_name);

	  while (tvb_reported_length_remaining(tvb, offset) > 0){
	    old_offset=offset;
	    offset=(*dsp_dissector)(FALSE, tvb, offset, &asn1_ctx, tree, -1);
	    if(offset == old_offset){
	      proto_tree_add_text(tree, tvb, offset, -1,"Internal error, zero-byte DSP PDU");
	      break;
	    }
	  }
	}
}
Example #12
0
static void
dissect_exec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    /* Set up structures needed to add the protocol subtree and manage it */
    proto_item *ti;
    proto_tree *exec_tree=NULL;

    /* Variables for extracting and displaying data from the packet */
    guchar *field_stringz; /* Temporary storage for each field we extract */

    gint length;
    guint offset = 0;
    conversation_t *conversation;
    exec_hash_entry_t *hash_info;

    conversation = find_or_create_conversation(pinfo);

    /* Retrieve information from conversation
     * or add it if it isn't there yet
     */
    hash_info = conversation_get_proto_data(conversation, proto_exec);
    if(!hash_info) {
        hash_info = se_alloc(sizeof(exec_hash_entry_t));

        hash_info->first_packet_number = pinfo->fd->num;
        hash_info->second_packet_number = 0;
        hash_info->third_packet_number  = 0;
        hash_info->fourth_packet_number  = 0;

        hash_info->state = WAIT_FOR_STDERR_PORT; /* The first field we'll see */

        /* Start with empty username and command strings */
        hash_info->username=NULL;
        hash_info->command=NULL;

        /* These will be set on the first pass by the first
         * four packets of the conversation
         */
        hash_info->first_packet_state  = NONE;
        hash_info->second_packet_state = NONE;
        hash_info->third_packet_state  = NONE;
        hash_info->fourth_packet_state  = NONE;

        conversation_add_proto_data(conversation, proto_exec, hash_info);
    }

    /* Store the number of the first three packets of this conversation
     * as we reach them the first time */

    if(!hash_info->second_packet_number
            && pinfo->fd->num > hash_info->first_packet_number) {
        /* We're on the second packet of the conversation */
        hash_info->second_packet_number = pinfo->fd->num;
    } else if(hash_info->second_packet_number
              && !hash_info->third_packet_number
              && pinfo->fd->num > hash_info->second_packet_number) {
        /* We're on the third packet of the conversation */
        hash_info->third_packet_number = pinfo->fd->num;
    } else if(hash_info->third_packet_number
              && !hash_info->fourth_packet_number
              && pinfo->fd->num > hash_info->third_packet_number) {
        /* We're on the fourth packet of the conversation */
        hash_info->fourth_packet_number = pinfo->fd->num;
    }

    /* Save this packet's state so we can retrieve it if this packet
     * is selected again later.  If the packet's state was already stored,
     * then retrieve it */
    if(pinfo->fd->num == hash_info->first_packet_number) {
        if(hash_info->first_packet_state == NONE) {
            hash_info->first_packet_state = hash_info->state;
        } else {
            hash_info->state = hash_info->first_packet_state;
        }
    }

    if(pinfo->fd->num == hash_info->second_packet_number) {
        if(hash_info->second_packet_state == NONE) {
            hash_info->second_packet_state = hash_info->state;
        } else {
            hash_info->state = hash_info->second_packet_state;
        }
    }

    if(pinfo->fd->num == hash_info->third_packet_number) {
        if(hash_info->third_packet_state == NONE) {
            hash_info->third_packet_state = hash_info->state;
        } else {
            hash_info->state = hash_info->third_packet_state;
        }
    }

    if(pinfo->fd->num == hash_info->fourth_packet_number) {
        if(hash_info->fourth_packet_state == NONE) {
            hash_info->fourth_packet_state = hash_info->state;
        } else {
            hash_info->state = hash_info->fourth_packet_state;
        }
    }

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

    if(check_col(pinfo->cinfo, COL_INFO)) {
        /* First, clear the info column */
        col_clear(pinfo->cinfo, COL_INFO);

        /*username */
        if(hash_info->username && preference_info_show_username == TRUE) {
            col_append_fstr(pinfo->cinfo, COL_INFO, "Username:%s ", hash_info->username);
        }

        /* Command */
        if(hash_info->command && preference_info_show_command == TRUE) {
            col_append_fstr(pinfo->cinfo, COL_INFO, "Command:%s ", hash_info->command);
        }
    }

    /* create display subtree for the protocol */
    ti = proto_tree_add_item(tree, proto_exec, tvb, 0, -1, ENC_NA);
    exec_tree = proto_item_add_subtree(ti, ett_exec);

    /* If this packet doesn't end with a null terminated string,
     * then it must be session data only and we can skip looking
     * for the other fields.
     */
    if(tvb_find_guint8(tvb, tvb_length(tvb)-1, 1, '\0') == -1) {
        hash_info->state = WAIT_FOR_DATA;
    }

    if(hash_info->state == WAIT_FOR_STDERR_PORT
            && tvb_length_remaining(tvb, offset)) {
        field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);

        /* Check if this looks like the stderr_port field.
         * It is optional, so it may only be 1 character long
         * (the NULL)
         */
        if(length == 1 || (isdigit_string(field_stringz)
                           && length <= EXEC_STDERR_PORT_LEN)) {
            proto_tree_add_string(exec_tree, hf_exec_stderr_port, tvb, offset, length, (gchar*)field_stringz);
            /* Next field we need */
            hash_info->state = WAIT_FOR_USERNAME;
        } else {
            /* Since the data doesn't match this field, it must be data only */
            hash_info->state = WAIT_FOR_DATA;
        }

        /* Used if the next field is in the same packet */
        offset += length;
    }


    if(hash_info->state == WAIT_FOR_USERNAME
            && tvb_length_remaining(tvb, offset)) {
        field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);

        /* Check if this looks like the username field */
        if(length != 1 && length <= EXEC_USERNAME_LEN
                && isprint_string(field_stringz)) {
            proto_tree_add_string(exec_tree, hf_exec_username, tvb, offset, length, (gchar*)field_stringz);

            /* Store the username so we can display it in the
             * info column of the entire conversation
             */
            if(!hash_info->username) {
                hash_info->username=se_strdup((gchar*)field_stringz);
            }

            /* Next field we need */
            hash_info->state = WAIT_FOR_PASSWORD;
        } else {
            /* Since the data doesn't match this field, it must be data only */
            hash_info->state = WAIT_FOR_DATA;
        }

        /* Used if the next field is in the same packet */
        offset += length;
    }


    if(hash_info->state == WAIT_FOR_PASSWORD
            && tvb_length_remaining(tvb, offset)) {
        field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);

        /* Check if this looks like the password field */
        if(length != 1 && length <= EXEC_PASSWORD_LEN
                && isprint_string(field_stringz)) {
            proto_tree_add_string(exec_tree, hf_exec_password, tvb, offset, length, (gchar*)field_stringz);

            /* Next field we need */
            hash_info->state = WAIT_FOR_COMMAND;
        } else {
            /* Since the data doesn't match this field, it must be data only */
            hash_info->state = WAIT_FOR_DATA;
        }

        /* Used if the next field is in the same packet */
        offset += length;
        /* Next field we are looking for */
        hash_info->state = WAIT_FOR_COMMAND;
    }


    if(hash_info->state == WAIT_FOR_COMMAND
            && tvb_length_remaining(tvb, offset)) {
        field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);

        /* Check if this looks like the command field */
        if(length != 1 && length <= EXEC_COMMAND_LEN
                && isprint_string(field_stringz)) {
            proto_tree_add_string(exec_tree, hf_exec_command, tvb, offset, length, (gchar*)field_stringz);

            /* Store the command so we can display it in the
             * info column of the entire conversation
             */
            if(!hash_info->command) {
                hash_info->command=se_strdup((gchar*)field_stringz);
            }

        } else {
            /* Since the data doesn't match this field, it must be data only */
            hash_info->state = WAIT_FOR_DATA;
        }
    }


    if(hash_info->state == WAIT_FOR_DATA
            && tvb_length_remaining(tvb, offset)) {
        if(pinfo->destport == EXEC_PORT) {
            /* Packet going to the server */
            /* offset = 0 since the whole packet is data */
            proto_tree_add_text(exec_tree, tvb, 0, -1, "Client -> Server Data");

            col_append_str(pinfo->cinfo, COL_INFO, "Client -> Server data");
        } else {
            /* This packet must be going back to the client */
            /* offset = 0 since the whole packet is data */
            proto_tree_add_text(exec_tree, tvb, 0, -1, "Server -> Client Data");

            col_append_str(pinfo->cinfo, COL_INFO, "Server -> Client Data");
        }
    }

    /* We haven't seen all of the fields yet */
    if(hash_info->state < WAIT_FOR_DATA) {
        col_set_str(pinfo->cinfo, COL_INFO, "Session Establishment");
    }
}
Example #13
0
static void
dissect_tzsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree         *tzsp_tree     = NULL;
    proto_item         *ti            = NULL;
    int                 pos           = 0;
    tvbuff_t           *next_tvb;
    guint16             encapsulation = 0;
    int                 wtap_encap;
    dissector_handle_t  encap_dissector;
    const char         *encap_name;
    const char         *info;
    guint8              type;

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

    type = tvb_get_guint8(tvb, 1);

    /* Find the dissector. */
    encapsulation = tvb_get_ntohs(tvb, 2);
    if (encapsulation != 0) {
        wtap_encap = tzsp_encap_to_wtap_encap(encapsulation);
        if ((wtap_encap != -1) &&
            (encap_dissector = dissector_get_uint_handle(encap_dissector_table, wtap_encap))) {
            encap_name = dissector_handle_get_short_name(encap_dissector);
        }
        else {
            encap_name = "Unknown";
        }
        info = encap_name;
    }
    else {
        wtap_encap = -1;
        encap_name = "Nothing";
        info = val_to_str(type, tzsp_type, "Unknown (%u)");
    }

    col_add_str(pinfo->cinfo, COL_INFO, info);

    if (tree) {
        /* Adding TZSP item and subtree */
        ti = proto_tree_add_protocol_format(tree, proto_tzsp, tvb, 0,
            -1, "TZSP: %s: ", info);
        tzsp_tree = proto_item_add_subtree(ti, ett_tzsp);

        proto_tree_add_item (tzsp_tree, hf_tzsp_version, tvb, 0, 1,
                    ENC_BIG_ENDIAN);
        proto_tree_add_uint (tzsp_tree, hf_tzsp_type, tvb, 1, 1,
                    type);
        proto_tree_add_uint_format (tzsp_tree, hf_tzsp_encap, tvb, 2, 2,
                    encapsulation, "Encapsulates: %s (%d)",
                    encap_name, encapsulation);
    }

    /*
     * XXX - what about TZSP_CONFIG frames?
     *
     * The MIB at
     *
     *  http://web.archive.org/web/20021221195733/http://www.networkchemistry.com/support/appnotes/SENSOR-MIB
     *
     * seems to indicate that you can configure the probe using SNMP;
     * does TZSP_CONFIG also support that?  An old version of Kismet
     * included code to control a Network Chemistry WSP100 sensor:
     *
     *  https://www.kismetwireless.net/code-old/svn/tags/kismet-2004-02-R1/wsp100source.cc
     *
     * and it used SNMP to configure the probe.
     */
    if ((type != TZSP_NULL) && (type != TZSP_PORT)) {
        pos = add_option_info(tvb, 4, tzsp_tree, ti);

        if (tree)
            proto_item_set_end(ti, tvb, pos);
        next_tvb = tvb_new_subset_remaining(tvb, pos);
        if ((encapsulation != 0)
            && ((wtap_encap == -1)
            || !dissector_try_uint(encap_dissector_table, wtap_encap,
                                   next_tvb, pinfo, tree))) {

            col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
            col_add_fstr(pinfo->cinfo, COL_INFO, "TZSP_ENCAP = %u",
                    encapsulation);
            call_dissector(data_handle, next_tvb, pinfo, tree);
        }
    }
}
static void
dissect_interlink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	int		offset = 0;
	proto_tree	*il_tree = NULL;
	proto_tree	*ilh_tree = NULL;
	proto_tree	*ilb_tree = NULL;
	guint8		ilb_type;
	guint8		ilb_version;
	guint16		type_version = 0;
	dissector_handle_t	handle;
	tvbuff_t	*next_tvb;

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

	if (tree) {
		proto_item	*il_item;
		il_item = proto_tree_add_item(tree, proto_interlink,
								tvb, 0, 16, FALSE);
		if (il_item)
			il_tree = proto_item_add_subtree(il_item, ett_interlink);
	}

	if (il_tree) {
		proto_item	*ilh_item = NULL;
		ilh_item = proto_tree_add_text(il_tree, tvb, 0, 12, "Interlink Header");
		if (ilh_item)
			ilh_tree = proto_item_add_subtree(ilh_item, ett_interlink_header);
	}

	if (ilh_tree) {
		proto_tree_add_item(ilh_tree, hf_interlink_id, tvb, offset, 4, FALSE);
		offset += 4;
		proto_tree_add_item(ilh_tree, hf_interlink_version, tvb, offset, 2, TRUE);
		offset += 2;
		proto_tree_add_item(ilh_tree, hf_interlink_cmd, tvb, offset, 2, TRUE);
		offset += 2;
		proto_tree_add_item(ilh_tree, hf_interlink_seq, tvb, offset, 2, TRUE);
		offset += 2;
	} else {
		offset += 10;
	}

	if (ilh_tree) {
		proto_item	*flags_item;
		proto_tree	*flags_tree = NULL;

		flags_item = proto_tree_add_item(ilh_tree, hf_interlink_flags,
			tvb, offset, 2, TRUE);
		if (flags_item) {
			flags_tree = proto_item_add_subtree(flags_item, ett_interlink_flags);
		}
		if (flags_tree) {
			guint16		il_flags;
			il_flags = tvb_get_letohs(tvb, offset);
			proto_tree_add_boolean(flags_tree, hf_interlink_flags_req_ack, tvb, offset, 2, il_flags);
			proto_tree_add_boolean(flags_tree, hf_interlink_flags_inc_ack_port, tvb, offset, 2, il_flags);
		}
	}
	offset += 2;

	if (tree) {
		proto_item	*ilb_item;
		ilb_item = proto_tree_add_text(il_tree, tvb, offset, 4, "Block Header");
		if (ilb_item)
			ilb_tree = proto_item_add_subtree(ilb_item, ett_interlink_block);
	}

	ilb_type = tvb_get_guint8(tvb, offset);
	ilb_version = tvb_get_guint8(tvb, offset + 1);
	type_version = ilb_type << 8 | ilb_version;
	col_append_fstr(pinfo->cinfo, COL_INFO, "Type: 0x%02x, Version: %d",
		ilb_type, ilb_version);

	if (ilb_tree) {
		proto_tree_add_item(ilb_tree, hf_interlink_block_type, tvb, offset, 1, FALSE);
		offset += 1;
		proto_tree_add_item(ilb_tree, hf_interlink_block_version, tvb, offset, 1, FALSE);
		offset += 1;
		proto_tree_add_item(ilb_tree, hf_interlink_block_length, tvb, offset, 2, TRUE);
		offset += 2;
	} else {
		offset += 4;
	}

	/* Generate a new tvb for the rest. */
	next_tvb = tvb_new_subset_remaining(tvb, offset);

	/* Probably a sub-dissector exists for this type/version combination. */
	handle = dissector_get_port_handle(subdissector_table, type_version);

	/* Without a proper sub-dissector, we use "data". */
	if (handle == NULL) handle = data_handle;

	/* Call the sub-dissector. */
	call_dissector(handle, next_tvb, pinfo, tree);
}
static void
dissect_omapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  proto_item *ti;
  proto_tree *omapi_tree;
  ptvcursor_t* cursor;

  guint32 authlength;
  guint32 msglength;
  guint32 objlength;


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

  col_clear(pinfo->cinfo, COL_INFO);

  ti = proto_tree_add_item(tree, proto_omapi, tvb, 0, -1, ENC_NA);
  omapi_tree = proto_item_add_subtree(ti, ett_omapi);
  cursor = ptvcursor_new(omapi_tree, tvb, 0);

  if (tvb_reported_length_remaining(tvb, 0) < 8)
  {
    /* Payload too small for OMAPI */
    DISSECTOR_ASSERT_NOT_REACHED();
  }
  else if (tvb_reported_length_remaining(tvb, 0) < 24)
  {
    /* This is a startup message */
    ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN);
    ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN);

    col_set_str(pinfo->cinfo, COL_INFO, "Status message");
    proto_item_append_text(ti, ", Status message");

    return;
  }
  else if ( !(tvb_get_ntohl(tvb, 8) || tvb_get_ntohl(tvb, 12)) )
  {
    /* This is a startup message, and more */
    ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN);
    ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN);

    col_append_str(pinfo->cinfo, COL_INFO, "Status message");

    proto_item_append_text(ti, ", Status message");
  }

  ptvcursor_add(cursor, hf_omapi_auth_id, 4, ENC_BIG_ENDIAN);
  authlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor));
  ptvcursor_add(cursor, hf_omapi_auth_len, 4, ENC_BIG_ENDIAN);

  col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
      val_to_str(tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)), omapi_opcode_vals, "Unknown opcode (0x%04x)"));

  proto_item_append_text(ti, ", Opcode: %s",
    val_to_str(tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)), omapi_opcode_vals, "Unknown opcode (0x%04x)"));

  ptvcursor_add(cursor, hf_omapi_opcode, 4, ENC_BIG_ENDIAN);
  ptvcursor_add(cursor, hf_omapi_handle, 4, ENC_BIG_ENDIAN);
  ptvcursor_add(cursor, hf_omapi_id, 4, ENC_BIG_ENDIAN);
  ptvcursor_add(cursor, hf_omapi_rid, 4, ENC_BIG_ENDIAN);

  msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
  while (msglength)
  {
    ptvcursor_add(cursor, hf_omapi_msg_name_len, 2, ENC_BIG_ENDIAN);
    ptvcursor_add(cursor, hf_omapi_msg_name, msglength, ENC_ASCII|ENC_NA);
    msglength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor));
    ptvcursor_add(cursor, hf_omapi_msg_value_len, 4, ENC_BIG_ENDIAN);

    if (msglength == 0)
    {
      proto_tree_add_text(omapi_tree, tvb, 0, 0, "Empty string");
    }
    else if (msglength == (guint32)~0)
    {
      proto_tree_add_text(omapi_tree, tvb, 0, 0, "No value");
    }
    else
    {
      ptvcursor_add(cursor, hf_omapi_msg_value, msglength, ENC_ASCII|ENC_NA);
    }

    msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
  }

  proto_tree_add_text(omapi_tree, tvb, ptvcursor_current_offset(cursor), 2, "Message end tag");
  ptvcursor_advance(cursor, 2);

  objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
  while (objlength)
  {
    ptvcursor_add(cursor, hf_omapi_obj_name_len, 2, ENC_BIG_ENDIAN);
    ptvcursor_add(cursor, hf_omapi_obj_name, objlength, ENC_ASCII|ENC_NA);
    objlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor));
    ptvcursor_add(cursor, hf_omapi_obj_value_len, 4, ENC_BIG_ENDIAN);

    if (objlength == 0)
    {
      proto_tree_add_text(omapi_tree, tvb, 0, 0, "Empty string");
    }
    else if (objlength == (guint32)~0)
    {
      proto_tree_add_text(omapi_tree, tvb, 0, 0, "No value");
    }
    else
    {
      ptvcursor_add(cursor, hf_omapi_obj_value, objlength, ENC_NA);
    }

    objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
  }

  proto_tree_add_text(omapi_tree, tvb, ptvcursor_current_offset(cursor), 2, "Object end tag");
  ptvcursor_advance(cursor, 2);

  if (authlength > 0) {
    ptvcursor_add(cursor, hf_omapi_signature, authlength, ENC_NA);
  }
}
Example #16
0
/* ================================================================= */
static void
dissect_ipxrip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*rip_tree;
	proto_item	*ti, *hidden_item;
	guint16		operation;
	ipx_rt_def_t 	route;
	int		cursor;
	int		available_length;

	static const char	*rip_type[3] = { "Request", "Response", "Unknown" };

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

	operation = tvb_get_ntohs(tvb, 0) - 1;

	if (check_col(pinfo->cinfo, COL_INFO)) {
		/* rip_types 0 and 1 are valid, anything else becomes 2 or "Unknown" */
		col_set_str(pinfo->cinfo, COL_INFO, rip_type[MIN(operation, 2)]);
	}

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

		if (operation < 2) {
			proto_tree_add_text(rip_tree, tvb, 0, 2,
			"RIP packet type: %s", rip_type[operation]);

			if (operation == 0) {
			  hidden_item = proto_tree_add_boolean(rip_tree,
						     hf_ipxrip_request,
						     tvb, 0, 2, 1);
			} else {
			  hidden_item = proto_tree_add_boolean(rip_tree,
						     hf_ipxrip_response,
						     tvb, 0, 2, 1);
			}
			PROTO_ITEM_SET_HIDDEN(hidden_item);

		}
		else {
			proto_tree_add_text(rip_tree, tvb, 0, 2, "Unknown RIP packet type");
		}

		available_length = tvb_reported_length(tvb);
		for (cursor =  2; cursor < available_length; cursor += 8) {
			tvb_memcpy(tvb, (guint8 *)&route.network, cursor, 4);
			route.hops = tvb_get_ntohs(tvb, cursor+4);
			route.ticks = tvb_get_ntohs(tvb, cursor+6);

			if (operation == IPX_RIP_REQUEST - 1) {
				proto_tree_add_text(rip_tree, tvb, cursor,      8,
					"Route Vector: %s, %d hop%s, %d tick%s",
					ipxnet_to_string((guint8*)&route.network),
					route.hops,  route.hops  == 1 ? "" : "s",
					route.ticks, route.ticks == 1 ? "" : "s");
			}
			else {
				proto_tree_add_text(rip_tree, tvb, cursor,      8,
					"Route Vector: %s, %d hop%s, %d tick%s (%d ms)",
					ipxnet_to_string((guint8*)&route.network),
					route.hops,  route.hops  == 1 ? "" : "s",
					route.ticks, route.ticks == 1 ? "" : "s",
					route.ticks * 1000 / 18);
			}
		}
	}
}
Example #17
0
static void
dissect_lpd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*lpd_tree;
	proto_item	*ti, *hidden_item;
	enum lpr_type	lpr_packet_type;
	guint8		code;
	gint		printer_len;

	/* This information comes from the LPRng HOWTO, which also describes
		RFC 1179. http://www.astart.com/lprng/LPRng-HOWTO.html */
	static const value_string lpd_client_code[] = {
		{ 1, "LPC: start print / jobcmd: abort" },
		{ 2, "LPR: transfer a printer job / jobcmd: receive control file" },
		{ 3, "LPQ: print short form of queue status / jobcmd: receive data file" },
		{ 4, "LPQ: print long form of queue status" },
		{ 5, "LPRM: remove jobs" },
		{ 6, "LPRng lpc: do control operation" },
		{ 7, "LPRng lpr: transfer a block format print job" },
		{ 8, "LPRng lpc: secure command transfer" },
		{ 9, "LPRng lpq: verbose status information" },
		{ 0, NULL }
	};
	static const value_string lpd_server_code[] = {
		{ 0, "Success: accepted, proceed" },
		{ 1, "Queue not accepting jobs" },
		{ 2, "Queue temporarily full, retry later" },
		{ 3, "Bad job format, do not retry" },
		{ 0, NULL }
	};

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

	/* rfc1179 states that all responses are 1 byte long */
	code = tvb_get_guint8(tvb, 0);
	if (tvb_reported_length(tvb) == 1) {
		lpr_packet_type = response;
	}
	else if (code <= 9) {
		lpr_packet_type = request;
	}
	else {
		lpr_packet_type = unknown;
	}

	if (lpr_packet_type == request && code !=0) {
		col_add_str(pinfo->cinfo, COL_INFO, val_to_str(code, lpd_client_code, "Unknown client code: %u"));
	}
	else if (lpr_packet_type == response) {
		col_set_str(pinfo->cinfo, COL_INFO, "LPD response");
	}
	else {
		col_set_str(pinfo->cinfo, COL_INFO, "LPD continuation");
	}

	if (tree) {
		ti = proto_tree_add_item(tree, proto_lpd, tvb, 0, -1, ENC_NA);
		lpd_tree = proto_item_add_subtree(ti, ett_lpd);

		if (lpr_packet_type == response) {
		  hidden_item = proto_tree_add_boolean(lpd_tree, hf_lpd_response,
		  				tvb, 0, 0, TRUE);
		} else {
		  hidden_item = proto_tree_add_boolean(lpd_tree, hf_lpd_request,
		  				tvb, 0, 0, TRUE);
		}
		PROTO_ITEM_SET_HIDDEN(hidden_item);

		if (lpr_packet_type == request) {
			printer_len = find_printer_string(tvb, 1);

			if (code <= 9 && printer_len != -1) {
				proto_tree_add_text(lpd_tree, tvb, 0, 1, "%s",
					val_to_str(code, lpd_client_code, "Unknown client code: %u"));
				proto_tree_add_text(lpd_tree, tvb, 1, printer_len,
					 "Printer/options: %s",
					 tvb_format_text(tvb, 1, printer_len));
			}
			else {
				call_dissector(data_handle,tvb, pinfo, lpd_tree);
			}
		}
		else if (lpr_packet_type == response) {
			if (code <= 3) {
				proto_tree_add_text(lpd_tree, tvb, 0, 1,
					"Response: %s", val_to_str(code, lpd_server_code, "Unknown server code: %u"));
			}
			else {
				call_dissector(data_handle,tvb, pinfo, lpd_tree);
			}
		}
		else {
			call_dissector(data_handle,tvb, pinfo, lpd_tree);
		}
	}
}
Example #18
0
/*
* Dissect RTSE PDUs inside a PPDU.
*/
static int
dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
{
	int offset = 0;
	int old_offset;
	proto_item *item;
	proto_tree *tree;
	proto_tree *next_tree=NULL;
	tvbuff_t *next_tvb = NULL;
	tvbuff_t *data_tvb = NULL;
	fragment_head *frag_msg = NULL;
	guint32 fragment_length;
	guint32 rtse_id = 0;
	gboolean data_handled = FALSE;
	struct SESSION_DATA_STRUCTURE* session;
	conversation_t *conversation = NULL;
	asn1_ctx_t asn1_ctx;
	asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);

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

	/* do we have application context from the acse dissector?  */
	if( data == NULL ){
		if(parent_tree){
			proto_tree_add_text(parent_tree, tvb, offset, -1,
				"Internal error:can't get application context from ACSE dissector.");
		}
		return 0;
	}

	session  = ( (struct SESSION_DATA_STRUCTURE*)data);

	asn1_ctx.private_data = session;

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

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

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

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

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

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

	if (!data_handled) {
		while (tvb_reported_length_remaining(tvb, offset) > 0){
			old_offset=offset;
			offset=dissect_rtse_RTSE_apdus(TRUE, tvb, offset, &asn1_ctx, tree, -1);
			if(offset == old_offset){
				item = proto_tree_add_text(tree, tvb, offset, -1, "Unknown RTSE PDU");

				expert_add_info (pinfo, item, &ei_rtse_unknown_rtse_pdu);
				next_tree=proto_item_add_subtree(item, ett_rtse_unknown);
				dissect_unknown_ber(pinfo, tvb, offset, next_tree);
				break;
			}
		}
	}

	top_tree = NULL;
	return tvb_length(tvb);
}
Example #19
0
static void
dissect_hdfs_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint offset = 0;
    int success = 0;
    guint length = 0;


    col_set_str(pinfo->cinfo, COL_PROTOCOL, "HDFS");
    /* Clear out stuff in the info column */
    col_clear(pinfo->cinfo,COL_INFO);

    if (tree) {

        proto_item *ti = NULL;
        proto_tree *hdfs_tree = NULL;

        ti = proto_tree_add_item(tree, proto_hdfs, tvb, 0, -1, ENC_NA);
        hdfs_tree = proto_item_add_subtree(ti, ett_hdfs);

        /* Response */
        if (pinfo->srcport == tcp_port) {
            /* 4 bytes = sequence number */
            proto_tree_add_item(hdfs_tree, hf_hdfs_packetno, tvb, offset, 4, ENC_BIG_ENDIAN);
            offset += 4;

            /* 4 bytes = status -> 0000 = success, 0001 = error, ffff = fatal */
            success = tvb_get_ntohl(tvb, offset);
            proto_tree_add_item(hdfs_tree, hf_hdfs_success, tvb, offset, 4, ENC_BIG_ENDIAN);
            offset += 4;

            if (success != 0) {
                return;
            }

            if (!tvb_memeql(tvb, offset + 2, "long", 4)) {
                dissect_resp_long (tvb, hdfs_tree,  offset);

            } else {

                /* name length = 2 B */
                length = tvb_get_ntohs(tvb, offset);
                proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;

                /* length bytes = method name */
                proto_tree_add_item(hdfs_tree, hf_hdfs_objname, tvb, offset, length, ENC_ASCII|ENC_NA);
                offset += length;

                /* get length that we just dissected */
                length = tvb_get_ntohs(tvb, offset);

                /* 2 bytes = objects length */
                proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;

                /* length bytes = object name */
                proto_tree_add_item(hdfs_tree, hf_hdfs_objname, tvb, offset, length, ENC_ASCII|ENC_NA);
                offset += length;

                /* responses about block location info */
                if (!tvb_memeql(tvb, offset - length, "org.apache.hadoop.hdfs.protocol.LocatedBlocks", length)) {
                    dissect_resp_locatedblocks (tvb, hdfs_tree, offset);

                    /* responses about file statuses */
                } else if (!tvb_memeql(tvb, offset - length, "org.apache.hadoop.hdfs.protocol.HdfsFileStatus", length)) {
                    dissect_resp_filestatus (tvb, hdfs_tree, offset);

                } else {
                    /* get length */
                    length = tvb_get_ntohs(tvb, offset);

                    /* 2 bytes = parameter value length */
                    proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN);
                    offset += 2;

                    /* the value of the parameter */
                    proto_tree_add_item(hdfs_tree, hf_hdfs_paramval, tvb, offset, length, ENC_ASCII|ENC_NA);
                    offset += length;
                }
            }

            /* Request to namenode */
        } else {

            /* check the packet length */
            guint auth = tvb_get_ntohl(tvb, offset);

            /* first setup packet starts with "hrpc" */
            if (!tvb_memeql(tvb, offset, REQUEST_STR, sizeof(REQUEST_STR) - 1)) {

                proto_tree_add_item(hdfs_tree, hf_hdfs_sequenceno, tvb, offset, sizeof(REQUEST_STR) - 1, ENC_ASCII|ENC_NA);
                offset += sizeof(REQUEST_STR) - 1;

                proto_tree_add_item(hdfs_tree, hf_hdfs_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

                proto_tree_add_item(hdfs_tree, hf_hdfs_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

            } else {
                /* second authentication packet */
                if (auth + 4 != tvb_reported_length(tvb)) {

                    /* authentication length (read out of first 4 bytes) */
                    length = tvb_get_ntohl(tvb, offset);
                    proto_tree_add_item(hdfs_tree, hf_hdfs_authlen, tvb, offset, 4, ENC_ASCII|ENC_NA);
                    offset += 4;

                    /* authentication (length the number we just got) */
                    proto_tree_add_item(hdfs_tree, hf_hdfs_auth, tvb, offset, length, ENC_ASCII|ENC_NA);
                    offset += length;
                }

                /* data packets */

                /* 4 bytes = length */
                proto_tree_add_item(hdfs_tree, hf_hdfs_len, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;

                /* 4 bytes = sequence number */
                proto_tree_add_item(hdfs_tree, hf_hdfs_packetno, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;

                /* dissect packet data */
                dissect_data (tvb, hdfs_tree, offset);
            }
        }
    }
}
static void
dissect_drda(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*drda_tree = NULL;
	proto_tree	*drdaroot_tree = NULL;
	proto_item	*ti = NULL;
	gint offset = 0;
	static gint iPreviousFrameNumber = -1;

	guint16 iCommand;
	guint16 iLength;

	guint8 iFormatFlags;
	guint8 iDSSType;
	guint8 iDSSFlags;

	guint16 iParameterCP;
	proto_tree	*drda_tree_sub;
	gint iLengthParam;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRDA");
	if (check_col(pinfo->cinfo, COL_INFO))
	{
		/* This is a trick to know whether this is the first PDU in this packet or not */
		if (iPreviousFrameNumber != (gint) pinfo->fd->num)
			col_clear(pinfo->cinfo, COL_INFO);
		else
			col_append_str(pinfo->cinfo, COL_INFO, " | ");
	}
	iPreviousFrameNumber = pinfo->fd->num;
	if (tvb_length(tvb) >= 10)
	{
		iCommand = tvb_get_ntohs(tvb, offset + 8);
		iLength = tvb_get_ntohs(tvb, offset + 0);

		if (check_col(pinfo->cinfo, COL_INFO))
		{
			col_append_str(pinfo->cinfo, COL_INFO, val_to_str(iCommand, drda_opcode_abbr, "Unknown (0x%02x)"));
		}

		if (tree)
		{
			ti = proto_tree_add_item(tree, proto_drda, tvb, offset, -1, FALSE);
			proto_item_append_text(ti, " (%s)", val_to_str(iCommand, drda_opcode_vals, "Unknown (0x%02x)"));
			drdaroot_tree = proto_item_add_subtree(ti, ett_drda);

			ti = proto_tree_add_text(drdaroot_tree, tvb, offset, 10, DRDA_TEXT_DDM);
			proto_item_append_text(ti, " (%s)", val_to_str(iCommand, drda_opcode_abbr, "Unknown (0x%02x)"));
			drda_tree = proto_item_add_subtree(ti, ett_drda_ddm);

			proto_tree_add_item(drda_tree, hf_drda_ddm_length, tvb, offset + 0, 2, FALSE);
			proto_tree_add_item(drda_tree, hf_drda_ddm_magic, tvb, offset + 2, 1, FALSE);

			{
				drda_tree_sub = NULL;
				iFormatFlags = tvb_get_guint8(tvb, offset + 3);
				iDSSType = iFormatFlags & 0x0F;
				iDSSFlags = iFormatFlags >> 4;

				ti = proto_tree_add_item(drda_tree, hf_drda_ddm_format, tvb, offset + 3, 1, FALSE);
				drda_tree_sub = proto_item_add_subtree(ti, ett_drda_ddm_format);

				proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_reserved, tvb, offset + 3, 1, iDSSFlags);
				proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_chained, tvb, offset + 3, 1, iDSSFlags);
				proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_errcont, tvb, offset + 3, 1, iDSSFlags);
				proto_tree_add_boolean(drda_tree_sub, hf_drda_ddm_fmt_samecorr, tvb, offset + 3, 1, iDSSFlags);
				proto_tree_add_uint(drda_tree_sub, hf_drda_ddm_fmt_dsstyp, tvb, offset + 3, 1, iDSSType);
			}

			proto_tree_add_item(drda_tree, hf_drda_ddm_rc, tvb, offset + 4, 2, FALSE);
			proto_tree_add_item(drda_tree, hf_drda_ddm_length2, tvb, offset + 6, 2, FALSE);
			proto_tree_add_item(drda_tree, hf_drda_ddm_codepoint, tvb, offset + 8, 2, FALSE);

			/* The number of attributes is variable */
			for (offset = 10; offset <= iLength; )
			{
				if (tvb_length_remaining(tvb, offset) >= 2)
				{
					iLengthParam = tvb_get_ntohs(tvb, offset + 0);
					if (iLengthParam == 0 || iLengthParam == 1) iLengthParam = iLength - 10;
					if (tvb_length_remaining(tvb, offset) >= iLengthParam)
					{
						drda_tree_sub = NULL;
						iParameterCP = tvb_get_ntohs(tvb, offset + 2);
						ti = proto_tree_add_text(drdaroot_tree, tvb, offset, iLengthParam, DRDA_TEXT_PARAM);
						proto_item_append_text(ti, " (%s)", val_to_str(iParameterCP, drda_opcode_vals, "Unknown (0x%02x)"));
						drda_tree_sub = proto_item_add_subtree(ti, ett_drda_param);
						proto_tree_add_item(drda_tree_sub, hf_drda_param_length, tvb, offset, 2, FALSE);
						proto_tree_add_item(drda_tree_sub, hf_drda_param_codepoint, tvb, offset + 2, 2, FALSE);
						proto_tree_add_item(drda_tree_sub, hf_drda_param_data, tvb, offset + 4, iLengthParam - 4, FALSE);
						proto_tree_add_item(drda_tree_sub, hf_drda_param_data_ebcdic, tvb, offset + 4, iLengthParam - 4, FALSE);
						if (iCommand == DRDA_CP_SQLSTT)
						{
							/* Extract SQL statement from packet */
							tvbuff_t* next_tvb = NULL;
							next_tvb = tvb_new_subset(tvb, offset + 4, iLengthParam - 4, iLengthParam - 4);
							add_new_data_source(pinfo, next_tvb, "SQL statement");
							proto_tree_add_item(drdaroot_tree, hf_drda_sqlstatement, next_tvb, 0, iLengthParam - 5, FALSE);
							proto_tree_add_item(drdaroot_tree, hf_drda_sqlstatement_ebcdic, next_tvb, 0, iLengthParam - 4, FALSE);
						}
					}
					offset += iLengthParam;
				}
				else
				{
					break;
				}
			}
		}
	}
Example #21
0
void
xmpp_message(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *packet)
{
    proto_item *message_item;
    proto_tree *message_tree;

    const gchar  *type_enums[] = {"chat", "error", "groupchat", "headline", "normal"};
    xmpp_array_t *type_array = xmpp_ep_init_array_t(type_enums, array_length(type_enums));

    xmpp_attr_info attrs_info[] = {
        {"from", hf_xmpp_from, FALSE, FALSE, NULL, NULL},
        {"id", hf_xmpp_id, FALSE, TRUE, NULL, NULL},
        {"to", hf_xmpp_to, FALSE, FALSE, NULL, NULL},
        {"type", hf_xmpp_type, FALSE, TRUE, xmpp_val_enum_list, type_array},
        {"xml:lang",-1, FALSE, FALSE, NULL,NULL},
        {"chatstate", hf_xmpp_message_chatstate, FALSE, TRUE, NULL, NULL}
    };

    xmpp_elem_info elems_info [] = {
        {NAME_AND_ATTR, xmpp_name_attr_struct("data", "xmlns", "http://jabber.org/protocol/ibb"), xmpp_ibb_data, ONE},
        {NAME, "thread", xmpp_message_thread, ONE},
        {NAME, "body", xmpp_message_body, MANY},
        {NAME, "subject", xmpp_message_subject, MANY},
        {NAME, "delay", xmpp_delay, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","jabber:x:event"), xmpp_x_event, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","http://jabber.org/protocol/muc#user"), xmpp_muc_user_x, ONE},
        {NAME_AND_ATTR, xmpp_name_attr_struct("x","xmlns","google:nosave"), xmpp_gtalk_nosave_x, ONE},
        {NAME, "error", xmpp_error, ONE}
    };

    xmpp_element_t *chatstate;

    xmpp_attr_t *id;

    conversation_t *conversation;
    xmpp_conv_info_t *xmpp_info;

    col_clear(pinfo->cinfo, COL_INFO);
    col_append_fstr(pinfo->cinfo, COL_INFO, "MESSAGE ");

    id = xmpp_get_attr(packet, "id");

    conversation = find_or_create_conversation(pinfo);
    xmpp_info = (xmpp_conv_info_t *)conversation_get_proto_data(conversation, proto_xmpp);

    message_item = proto_tree_add_item(tree, hf_xmpp_message, tvb, packet->offset, packet->length, ENC_BIG_ENDIAN);
    message_tree = proto_item_add_subtree(message_item, ett_xmpp_message);

    if((chatstate = xmpp_steal_element_by_attr(packet, "xmlns", "http://jabber.org/protocol/chatstates"))!=NULL)
    {
        xmpp_attr_t *fake_chatstate_attr = xmpp_ep_init_attr_t(chatstate->name, chatstate->offset, chatstate->length);
        g_hash_table_insert(packet->attrs, (gpointer)"chatstate", fake_chatstate_attr);
    }

    xmpp_display_attrs(message_tree, packet, pinfo, tvb, attrs_info, array_length(attrs_info));

    xmpp_display_elems(message_tree, packet, pinfo, tvb, elems_info, array_length(elems_info));

    /*Displays data about IBB session*/
    if(xmpp_info && id)
    {
        gchar *ibb_sid;

        ibb_sid = (gchar *)se_tree_lookup_string(xmpp_info->ibb_sessions, id->value, EMEM_TREE_STRING_NOCASE);

        if (ibb_sid) {
            proto_item *it = proto_tree_add_string(tree, hf_xmpp_ibb, tvb, 0, 0, ibb_sid);
            PROTO_ITEM_SET_GENERATED(it);
        }

    }
}
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;
}
static void
dissect_aarp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
  guint16     ar_hrd;
  guint16     ar_pro;
  guint8      ar_hln;
  guint8      ar_pln;
  guint16     ar_op;
  proto_tree  *aarp_tree;
  proto_item  *ti;
  const gchar *op_str;
  int         sha_offset, spa_offset, tha_offset, tpa_offset;
  gchar       *sha_str, *spa_str, /* *tha_str, */ *tpa_str;

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

  ar_hrd = tvb_get_ntohs(tvb, AR_HRD);
  ar_pro = tvb_get_ntohs(tvb, AR_PRO);
  ar_hln = tvb_get_guint8(tvb, AR_HLN);
  ar_pln = tvb_get_guint8(tvb, AR_PLN);
  ar_op  = tvb_get_ntohs(tvb, AR_OP);

  /* Get the offsets of the addresses. */
  sha_offset = MIN_AARP_HEADER_SIZE;
  spa_offset = sha_offset + ar_hln;
  tha_offset = spa_offset + ar_pln;
  tpa_offset = tha_offset + ar_hln;

  /* Extract the addresses.  */
  sha_str = tvb_aarphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd);
  spa_str = tvb_aarpproaddr_to_str(tvb, spa_offset, ar_pln, ar_pro);
#if 0
  /* TODO: tha_str is currently not shown nor parsed */
  tha_str = tvb_aarphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd);
#endif
  tpa_str = tvb_aarpproaddr_to_str(tvb, tpa_offset, ar_pln, ar_pro);

  switch (ar_op) {
    case AARP_REQUEST:
    case AARP_REQUEST_SWAPPED:
      col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s?  Tell %s", tpa_str, spa_str);
      break;
    case AARP_REPLY:
    case AARP_REPLY_SWAPPED:
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s", spa_str, sha_str);
      break;
    case AARP_PROBE:
    case AARP_PROBE_SWAPPED:
      col_add_fstr(pinfo->cinfo, COL_INFO, "Is there a %s", tpa_str);
      break;
    default:
      col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown AARP opcode 0x%04x", ar_op);
      break;
  }

  if (tree) {
    if ((op_str = match_strval(ar_op, op_vals)))
      ti = proto_tree_add_protocol_format(tree, proto_aarp, tvb, 0,
				      MIN_AARP_HEADER_SIZE + 2*ar_hln +
				      2*ar_pln, "AppleTalk Address Resolution Protocol (%s)", op_str);
    else
      ti = proto_tree_add_protocol_format(tree, proto_aarp, tvb, 0,
				      MIN_AARP_HEADER_SIZE + 2*ar_hln +
				      2*ar_pln,
				      "AppleTalk Address Resolution Protocol (opcode 0x%04x)", ar_op);
    aarp_tree = proto_item_add_subtree(ti, ett_aarp);
    proto_tree_add_uint(aarp_tree, hf_aarp_hard_type, tvb, AR_HRD, 2,
			       ar_hrd);
    proto_tree_add_uint(aarp_tree, hf_aarp_proto_type, tvb, AR_PRO, 2,
			       ar_pro);
    proto_tree_add_uint(aarp_tree, hf_aarp_hard_size, tvb, AR_HLN, 1,
			       ar_hln);
    proto_tree_add_uint(aarp_tree, hf_aarp_proto_size, tvb, AR_PLN, 1,
			       ar_pln);
    proto_tree_add_uint(aarp_tree, hf_aarp_opcode, tvb, AR_OP, 2,
			       ar_op);
    if (ar_hln != 0) {
      proto_tree_add_item(aarp_tree,
	AARP_HW_IS_ETHER(ar_hrd, ar_hln) ? hf_aarp_src_hw_mac : hf_aarp_src_hw,
	tvb, sha_offset, ar_hln, ENC_NA);
    }

    if (ar_pln != 0) {
      if (AARP_PRO_IS_ATALK(ar_pro, ar_pln)) {
        proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_src_proto_id, tvb,
					  spa_offset, ar_pln, NULL,
					  "%s", spa_str);
      } else {
        proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_src_proto, tvb,
					  spa_offset, ar_pln, NULL,
					  "%s", spa_str);
      }
    }

    if (ar_hln != 0) {
      proto_tree_add_item(aarp_tree,
	AARP_HW_IS_ETHER(ar_hrd, ar_hln) ? hf_aarp_dst_hw_mac : hf_aarp_dst_hw,
	tvb, tha_offset, ar_hln, ENC_NA);
    }

    if (ar_pln != 0) {
      if (AARP_PRO_IS_ATALK(ar_pro, ar_pln)) {
        proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_dst_proto_id, tvb,
					  tpa_offset, ar_pln,
					  NULL, "%s", tpa_str);
      } else {
        proto_tree_add_bytes_format_value(aarp_tree, hf_aarp_dst_proto, tvb,
					  tpa_offset, ar_pln,
					  NULL, "%s", tpa_str);
      }
    }
  }
}
Example #24
0
static void
dissect_qllc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree	*qllc_tree = NULL;
    proto_item	*qllc_ti = NULL;
    gboolean	*q_bit_set = (gboolean *)pinfo->private_data;
    guint8	addr, ctrl;
    gboolean	command = FALSE;

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

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

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

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

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


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

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

        proto_tree_add_uint(qllc_tree, hf_qllc_control, tvb,
                    1, 1, ctrl);
    }

    /* Do we have an I field ? */
    /* XXX - I field exists for QUI too, but only for subarea nodes.
     * Need to test for this. */
    if (ctrl == QXID || ctrl == QTEST || ctrl == QFRMR) {
        /* yes */
    }
}
Example #25
0
static
void dissect_pw_cesopsn( tvbuff_t * tvb_original
						,packet_info * pinfo
						,proto_tree * tree
						,pwc_demux_type_t demux)
{
	const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/
	gint      packet_size;
	gint      payload_size;
	gint      padding_size;
	int properties;

	packet_size = tvb_reported_length_remaining(tvb_original, 0);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

					}
				}
			}
		}

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

		/* padding */
		if (padding_size > 0)
		{
			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				tvbuff_t* tvb;
				tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1);
				call_dissector(pw_padding_handle, tvb, pinfo, tree2);
			}
		}
	}
	return;
}
Example #26
0
static void
dissect_sap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    int offset = 0;
    int sap_version, is_ipv6, is_del, is_enc, is_comp, addr_len;
    guint8 vers_flags;
    guint8 auth_len;
    guint8 auth_flags;
    tvbuff_t *next_tvb;

    proto_item *si, *sif;
    proto_tree *sap_tree = NULL, *sap_flags_tree;

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

    vers_flags = tvb_get_guint8(tvb, offset);
    is_ipv6 = vers_flags&MCAST_SAP_BIT_A;
    is_del = vers_flags&MCAST_SAP_BIT_T;
    is_enc = vers_flags&MCAST_SAP_BIT_E;
    is_comp = vers_flags&MCAST_SAP_BIT_C;

    sap_version = (vers_flags&MCAST_SAP_VERSION_MASK)>>MCAST_SAP_VERSION_SHIFT;
    addr_len = (is_ipv6) ? (int)sizeof(struct e_in6_addr) : 4;

    col_add_fstr(pinfo->cinfo, COL_INFO, "%s (v%u)",
                            (is_del) ? "Deletion" : "Announcement", sap_version);

    if (tree) {
        si = proto_tree_add_item(tree, proto_sap, tvb, offset, -1, ENC_NA);
        sap_tree = proto_item_add_subtree(si, ett_sap);

        sif = proto_tree_add_item(sap_tree, hf_sap_flags, tvb, offset, 1, ENC_NA);
        sap_flags_tree = proto_item_add_subtree(sif, ett_sap_flags);
        proto_tree_add_item(sap_flags_tree, hf_sap_flags_v, tvb, offset, 1, ENC_NA);
        proto_tree_add_item(sap_flags_tree, hf_sap_flags_a, tvb, offset, 1, ENC_NA);
        proto_tree_add_item(sap_flags_tree, hf_sap_flags_r, tvb, offset, 1, ENC_NA);
        proto_tree_add_item(sap_flags_tree, hf_sap_flags_t, tvb, offset, 1, ENC_NA);
        proto_tree_add_item(sap_flags_tree, hf_sap_flags_e, tvb, offset, 1, ENC_NA);
        proto_tree_add_item(sap_flags_tree, hf_sap_flags_c, tvb, offset, 1, ENC_NA);
    }

    offset++;

    auth_len = tvb_get_guint8(tvb, offset);
    proto_tree_add_item(sap_tree, hf_sap_auth_len, tvb, offset, 1, ENC_NA);
    offset++;

    proto_tree_add_item(sap_tree, hf_sap_message_identifier_hash, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset +=2;

    if (is_ipv6)
        proto_tree_add_item(sap_tree, hf_sap_originating_source_ipv6, tvb, offset, addr_len, ENC_NA);
    else
        proto_tree_add_item(sap_tree, hf_sap_originating_source_ipv4, tvb, offset, addr_len, ENC_BIG_ENDIAN);
    offset += addr_len;

    /* Authentication data lives in its own subtree */
    if (auth_len > 0) {
        guint32 auth_data_len;
        proto_item *sdi, *sai;
        proto_tree *sa_tree, *saf_tree;
        int has_pad;
        guint8 pad_len = 0;

        auth_data_len = (guint32)(auth_len * sizeof(guint32));

        sdi = proto_tree_add_item(sap_tree, hf_auth_data, tvb, offset, auth_data_len, ENC_NA);
        sa_tree = proto_item_add_subtree(sdi, ett_sap_auth);

        auth_flags = tvb_get_guint8(tvb, offset);
        sai = proto_tree_add_item(sa_tree, hf_auth_flags, tvb, offset, 1, ENC_NA);
        saf_tree = proto_item_add_subtree(sai, ett_sap_authf);
        proto_tree_add_item(saf_tree, hf_auth_flags_v, tvb, offset, 1, ENC_NA);
        proto_tree_add_item(saf_tree, hf_auth_flags_p, tvb, offset, 1, ENC_NA);
        proto_tree_add_item(saf_tree, hf_auth_flags_t, tvb, offset, 1, ENC_NA);

        has_pad = auth_flags&MCAST_SAP_AUTH_BIT_P;
        if (has_pad) {
            pad_len = tvb_get_guint8(tvb, offset+auth_data_len-1);
        }

        if ((int) auth_data_len - pad_len - 1 < 0) {
            expert_add_info_format(pinfo, sai, &ei_sap_bogus_authentication_or_pad_length,
                                        "Bogus authentication length (%d) or pad length (%d)", auth_len, pad_len);
            return;
        }


        proto_tree_add_item(sa_tree, hf_sap_auth_subheader, tvb, offset+1, auth_data_len-pad_len-1, ENC_NA);
        if (has_pad) {
            proto_tree_add_item(sa_tree, hf_sap_auth_data_padding_len, tvb, offset+auth_data_len-1, 1, ENC_NA);
            proto_tree_add_item(sa_tree, hf_sap_auth_data_padding, tvb, offset+auth_data_len-pad_len, pad_len, ENC_NA);
        }

        offset += auth_data_len;
    }

    if (is_enc || is_comp) {
        expert_field *mangle;
        if (is_enc && is_comp)
            mangle = &ei_sap_compressed_and_encrypted;
        else if (is_enc)
            mangle = &ei_sap_encrypted;
        else
            mangle = &ei_sap_compressed;

        proto_tree_add_expert(sap_tree, pinfo, mangle, tvb, offset, -1);
        return;
    }

    if (tree) {
        /* Do we have the optional payload type aka. MIME content specifier */
        if (tvb_strneql(tvb, offset, "v=", strlen("v="))) {
            gint remaining_len;
            guint32 pt_len;
            int pt_string_len;
            guint8* pt_str;

            remaining_len = tvb_captured_length_remaining(tvb, offset);
            if (remaining_len == 0) {
                /*
                    * "tvb_strneql()" failed because there was no
                    * data left in the packet.
                    *
                    * Set the remaining length to 1, so that
                    * we throw the appropriate exception in
                    * "tvb_get_ptr()", rather than displaying
                    * the payload type.
                    */
                remaining_len = 1;
            }

            pt_string_len = tvb_strnlen(tvb, offset, remaining_len);
            if (pt_string_len == -1) {
                /*
                 * We didn't find a terminating '\0'; run to the
                 * end of the buffer.
                 */
                pt_string_len = remaining_len;
                pt_len = pt_string_len;
            } else {
                /*
                 * Include the '\0' in the total item length.
                 */
                pt_len = pt_string_len + 1;
            }

            pt_str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, pt_string_len, ENC_ASCII);
            proto_tree_add_string_format_value(sap_tree, hf_sap_payload_type, tvb, offset, pt_len,
                pt_str, "%.*s", pt_string_len, pt_str);
            offset += pt_len;
        }
    }

    /* Done with SAP */
    next_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector(sdp_handle, next_tvb, pinfo, tree);
}
Example #27
0
// content format
static void dissect_mysensors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  // your variable definitions go here
  int bitoffset = 0;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "mysensors");
  
  // Clear out stuff in the info column
  col_clear(pinfo->cinfo,COL_INFO);
  if (tree)
  {
    // in case that someone wants to know some details of our protocol
    // spawn a subtree and cut the sequence in readable parts
    proto_item *pi = NULL;
    proto_item *ti = NULL;
    proto_tree *mysensors_tree = NULL;
    tvbuff_t* tvb_next;
    guint8 payloadLen, dataType, type, sensor, sender, last, dest, reqack, isack;
    MySensors_Command commandType;
    gchar* info;
    
    ti = proto_tree_add_item(tree, proto_mysensors, tvb, 0 /*start*/, -1 /*to end*/, ENC_NA);
    mysensors_tree = proto_item_add_subtree(ti, ett_mysensors);
    
    proto_tree_add_item(mysensors_tree, hf_mysensors_last, tvb, bitoffset>>3, 1, encoding);
    last = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;
    proto_tree_add_item(mysensors_tree, hf_mysensors_sender, tvb, bitoffset>>3, 1, encoding);
    sender = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;
    proto_tree_add_item(mysensors_tree, hf_mysensors_dest, tvb, bitoffset>>3, 1, encoding);
    dest = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;

    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_length, tvb, bitoffset, 5, encoding);
    payloadLen = tvb_get_bits8(tvb, bitoffset, 5);
    bitoffset += 5;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_version, tvb, bitoffset, 3, encoding);
    bitoffset += 3;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_datatype, tvb, bitoffset, 3, encoding);
    dataType = tvb_get_bits8(tvb, bitoffset, 3);  // Type of payload
    bitoffset += 3;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_isack, tvb, bitoffset, 1, encoding);
    isack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1);
    bitoffset += 1;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_reqack, tvb, bitoffset, 1, encoding);
    reqack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1);
    bitoffset += 1;
    proto_tree_add_bits_item(mysensors_tree, hf_mysensors_commandtype, tvb, bitoffset, 3, encoding);
    commandType = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 3);
    bitoffset += 3;

    type = tvb_get_guint8(tvb, bitoffset>>3);
    proto_tree_add_uint_format_value(mysensors_tree, hf_mysensors_type, tvb, bitoffset>>3, 1, type, "%s (%d)", typeToStr(commandType, type), (guint8)type);
    bitoffset += 8;
    proto_tree_add_item(mysensors_tree, hf_mysensors_sensor, tvb, bitoffset>>3, 1, encoding);
    sensor = tvb_get_guint8(tvb, bitoffset>>3);
    bitoffset += 8;

    // Create tvb for the payload.
    tvb_next = tvb_new_subset(tvb, bitoffset>>3, payloadLen, payloadLen);

    info = buildColInfo( pinfo, payloadLen, dataType, commandType, reqack, isack, type, sensor, tvb_next );
    col_add_str(pinfo->cinfo, COL_INFO, info);
    proto_item_append_text(ti, " - %s", info);
    col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "%d", sender);
    col_add_fstr(pinfo->cinfo, COL_DEF_DST, "%d", dest);

    // Pass payload to generic data dissector
    call_dissector(data_handle, tvb_next, pinfo, mysensors_tree);
  }
}
Example #28
0
/*
* Dissect DOP PDUs inside a ROS PDUs
*/
static int
dissect_dop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
{
	int offset = 0;
	int old_offset;
	proto_item *item;
	proto_tree *tree;
	struct SESSION_DATA_STRUCTURE* session;
	int (*dop_dissector)(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_) = NULL;
	const char *dop_op_name;
	asn1_ctx_t asn1_ctx;

	/* do we have operation information from the ROS dissector? */
	if (data == NULL)
		return 0;
	session = (struct SESSION_DATA_STRUCTURE*)data;

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

	item = proto_tree_add_item(parent_tree, proto_dop, tvb, 0, -1, ENC_NA);
	tree = proto_item_add_subtree(item, ett_dop);

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

	asn1_ctx.private_data = session;

	switch(session->ros_op & ROS_OP_MASK) {
	case (ROS_OP_BIND | ROS_OP_ARGUMENT):	/*  BindInvoke */
	  dop_dissector = dissect_dop_DSAOperationalManagementBindArgument;
	  dop_op_name = "DSA-Operational-Bind-Argument";
	  break;
	case (ROS_OP_BIND | ROS_OP_RESULT):	/*  BindResult */
	  dop_dissector = dissect_dop_DSAOperationalManagementBindResult;
	  dop_op_name = "DSA-Operational-Bind-Result";
	  break;
	case (ROS_OP_BIND | ROS_OP_ERROR):	/*  BindError */
	  dop_dissector = dissect_dop_DSAOperationalManagementBindError;
	  dop_op_name = "DSA-Operational-Management-Bind-Error";
	  break;
	case (ROS_OP_INVOKE | ROS_OP_ARGUMENT):	/*  Invoke Argument */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 100: /* establish */
	    dop_dissector = dissect_dop_EstablishOperationalBindingArgument;
	    dop_op_name = "Establish-Operational-Binding-Argument";
	    break;
	  case 101: /* terminate */
	    dop_dissector = dissect_dop_TerminateOperationalBindingArgument;
	    dop_op_name = "Terminate-Operational-Binding-Argument";
	    break;
	  case 102: /* modify */
	    dop_dissector = dissect_dop_ModifyOperationalBindingArgument;
	    dop_op_name = "Modify-Operational-Binding-Argument";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DOP Argument opcode (%d)",
				session->ros_op & ROS_OP_OPCODE_MASK);
	    break;
	  }
	  break;
	case (ROS_OP_INVOKE | ROS_OP_RESULT):	/*  Return Result */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 100: /* establish */
	    dop_dissector = dissect_dop_EstablishOperationalBindingResult;
	    dop_op_name = "Establish-Operational-Binding-Result";
	    break;
	  case 101: /* terminate */
	    dop_dissector = dissect_dop_TerminateOperationalBindingResult;
	    dop_op_name = "Terminate-Operational-Binding-Result";
	    break;
	  case 102: /* modify */
	    dop_dissector = dissect_dop_ModifyOperationalBindingResult;
	    dop_op_name = "Modify-Operational-Binding-Result";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DOP Result opcode (%d)",
				session->ros_op & ROS_OP_OPCODE_MASK);
	    break;
	  }
	  break;
	case (ROS_OP_INVOKE | ROS_OP_ERROR):	/*  Return Error */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 100: /* operational-binding */
	    dop_dissector = dissect_dop_OpBindingErrorParam;
	    dop_op_name = "Operational-Binding-Error";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DOP Error opcode (%d)",
				session->ros_op & ROS_OP_OPCODE_MASK);
	    break;
	  }
	  break;
	default:
	  proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DOP PDU");
	  return tvb_length(tvb);
	}

	if(dop_dissector) {
      col_set_str(pinfo->cinfo, COL_INFO, dop_op_name);

	  while (tvb_reported_length_remaining(tvb, offset) > 0){
	    old_offset=offset;
	    offset=(*dop_dissector)(FALSE, tvb, offset, &asn1_ctx, tree, -1);
	    if(offset == old_offset){
	      proto_tree_add_text(tree, tvb, offset, -1,"Internal error, zero-byte DOP PDU");
	      break;
	    }
	  }
	}

	return tvb_length(tvb);
}
/* Code to actually dissect the packets */
static gboolean
dissect_epl_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint8  epl_v1_service, epl_v1_dest, epl_v1_src, epl_v1_ainv_ch, epl_v1_asnd_ch;
	gint    offset;
	proto_item *ti=NULL;
	proto_tree *epl_v1_tree=NULL;


	if(tvb_length(tvb) < 3){
		/* Not enough data for an EPL_V1 header; don't try to interpret it */
		return FALSE;
	}

	offset = 0;

	/* make entries in Protocol column and Info column on summary display */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "EPL_V1");
	col_clear(pinfo->cinfo, COL_INFO);

	/* get service type */
	epl_v1_service = tvb_get_guint8(tvb, EPL_V1_SERVICE_OFFSET) & 0x7F;

	/* get destination */
	epl_v1_dest = tvb_get_guint8(tvb, EPL_V1_DEST_OFFSET);

	/* get source */
	epl_v1_src = tvb_get_guint8(tvb, EPL_V1_SRC_OFFSET);

	/* choose the right string for "Info" column */
	switch(epl_v1_service){
	case EPL_V1_SOC:
		col_add_fstr(pinfo->cinfo, COL_INFO, "SoC    dest = %3d   src = %3d   ", epl_v1_dest, epl_v1_src);
		break;

	case EPL_V1_EOC:
		col_add_fstr(pinfo->cinfo, COL_INFO, "EoC    dest = %3d   src = %3d   ", epl_v1_dest, epl_v1_src);
		break;

	case EPL_V1_PREQ:
		col_add_fstr(pinfo->cinfo, COL_INFO, "PReq   dest = %3d   src = %3d   ", epl_v1_dest, epl_v1_src);
		break;

	case EPL_V1_PRES:
		col_add_fstr(pinfo->cinfo, COL_INFO, "PRes   dest = %3d   src = %3d   ", epl_v1_dest, epl_v1_src);
		break;

	case EPL_V1_AINV:
		/* get AInv channel */
		epl_v1_ainv_ch = tvb_get_guint8(tvb, EPL_V1_AINV_CHANNEL_OFFSET);
		col_add_fstr(pinfo->cinfo, COL_INFO, "AInv   dest = %3d   src = %3d   channel = %s   ",
			epl_v1_dest, epl_v1_src, val_to_str(epl_v1_ainv_ch, ainv_channel_number_vals, "unknown Channel (%d)"));
		break;

	case EPL_V1_ASND:
		/* get ASnd channel */
		epl_v1_asnd_ch = tvb_get_guint8(tvb, EPL_V1_ASND_CHANNEL_OFFSET);
		col_add_fstr(pinfo->cinfo, COL_INFO, "ASnd   dest = %3d   src = %3d   channel = %s   ",
			epl_v1_dest, epl_v1_src, val_to_str(epl_v1_asnd_ch, asnd_channel_number_vals, "unknown Channel (%d)"));
		break;

	default:     /* no valid EPL packet */
		return FALSE;
	}

	if(tree){
		/* create display subtree for the protocol */
		ti = proto_tree_add_item(tree, proto_epl_v1, tvb, 0, -1, TRUE);

		epl_v1_tree = proto_item_add_subtree(ti, ett_epl_v1);
	}
	proto_tree_add_item(epl_v1_tree, hf_epl_v1_service, tvb, offset, 1, TRUE);
	offset += 1;

	proto_tree_add_item(epl_v1_tree, hf_epl_v1_dest, tvb, offset, 1, TRUE);
	offset += 1;

	proto_tree_add_item(epl_v1_tree, hf_epl_v1_src, tvb, offset, 1, TRUE);
	offset += 1;

	/* The rest of the epl_v1 dissector depends on the message type  */
	switch(epl_v1_service){
	case EPL_V1_SOC:
		offset = dissect_epl_v1_soc(epl_v1_tree, tvb, offset);
		break;

	case EPL_V1_EOC:
		offset = dissect_epl_v1_eoc(epl_v1_tree, tvb, offset);
		break;

	case EPL_V1_PREQ:
		offset = dissect_epl_v1_preq(epl_v1_tree, tvb, offset);
		break;

	case EPL_V1_PRES:
		offset = dissect_epl_v1_pres(epl_v1_tree, tvb,  offset);
		break;

	case EPL_V1_AINV:
		offset = dissect_epl_v1_ainv(epl_v1_tree, tvb,  offset);
		break;

	case EPL_V1_ASND:
		offset = dissect_epl_v1_asnd(epl_v1_tree, tvb,  offset);
		break;

	default: /* not a valid MessageType - can't dissect any further. */
		return FALSE;
	}
	return TRUE;
}
Example #30
0
/* Code to actually dissect the packets */
static void
dissect_ipa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean is_udp)
{
	gint remaining;
	gint header_length = 3;
	int offset = 0;

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

	while ((remaining = tvb_reported_length_remaining(tvb, offset)) > 0) {
		proto_item *ti;
		proto_tree *ipa_tree = NULL;
		guint16 len, msg_type;
		tvbuff_t *next_tvb;

		len = tvb_get_ntohs(tvb, offset);
		msg_type = tvb_get_guint8(tvb, offset+2);

		col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
		                val_to_str(msg_type, ipa_protocol_vals,
		                           "unknown 0x%02x"));

		/*
		 * The IPA header is different depending on the transport protocol.
		 * With UDP there seems to be a fourth byte for the IPA header.
		 * We attempt to detect this by checking if the length from the
		 * header + four bytes of the IPA header equals the remaining size.
		 */
		if (is_udp && (len + 4 == remaining)) {
			header_length++;
		}

		if (tree) {
			ti = proto_tree_add_protocol_format(tree, proto_ipa,
					tvb, offset, len+header_length,
					"IPA protocol ip.access, type: %s",
					val_to_str(msg_type, ipa_protocol_vals,
						   "unknown 0x%02x"));
			ipa_tree = proto_item_add_subtree(ti, ett_ipa);
			proto_tree_add_item(ipa_tree, hf_ipa_data_len,
					    tvb, offset, 2, ENC_BIG_ENDIAN);
			proto_tree_add_item(ipa_tree, hf_ipa_protocol,
					    tvb, offset+2, 1, ENC_BIG_ENDIAN);
		}

		next_tvb = tvb_new_subset_length(tvb, offset+header_length, len);

		switch (msg_type) {
		case ABISIP_OML:
			/* hand this off to the standard A-bis OML dissector */
			if (sub_handles[SUB_OML])
				call_dissector(sub_handles[SUB_OML], next_tvb,
						 pinfo, tree);
			break;
		case ABISIP_IPACCESS:
			dissect_ipaccess(next_tvb, pinfo, tree);
			break;
		case AIP_SCCP:
			/* hand this off to the standard SCCP dissector */
			call_dissector(sub_handles[SUB_SCCP], next_tvb, pinfo, tree);
			break;
		case IPA_MGCP:
			/* hand this off to the standard MGCP dissector */
			call_dissector(sub_handles[SUB_MGCP], next_tvb, pinfo, tree);
			break;
		case OSMO_EXT:
			dissect_osmo(next_tvb, pinfo, ipa_tree, tree);
			break;
		case HSL_DEBUG:
			if (tree) {
				proto_tree_add_item(ipa_tree, hf_ipa_hsl_debug,
						    next_tvb, 0, len, ENC_ASCII|ENC_NA);
				if (global_ipa_in_root == TRUE)
					proto_tree_add_item(tree, hf_ipa_hsl_debug,
							    next_tvb, 0, len, ENC_ASCII|ENC_NA);
			}
			if (global_ipa_in_info == TRUE)
				col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
						tvb_get_stringz_enc(wmem_packet_scope(), next_tvb, 0, NULL, ENC_ASCII));
			break;
		default:
			if (msg_type < ABISIP_RSL_MAX) {
				/* hand this off to the standard A-bis RSL dissector */
				call_dissector(sub_handles[SUB_RSL], next_tvb, pinfo, tree);
			}
			break;
		}
		offset += len + header_length;
	}
}