Example #1
0
static void
dissect_wsmp(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 *wsmp_tree, *wsmdata_tree;
    tvbuff_t   *wsmdata_tvb;
    guint16     wsmlength, offset;
    guint32     psidLen, psid, supLen;
    guint8      elemenId, elemenLen, msb;

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

    col_set_str(pinfo->cinfo, COL_INFO, "WAVE Short Message Protocol IEEE P1609.3");

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

    wsmp_tree = proto_item_add_subtree(ti, ett_wsmp);

    offset = 0;
    proto_tree_add_item(wsmp_tree,
                        hf_wsmp_version, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset++;

    psid    = tvb_get_guint8(tvb, offset);
    psidLen = (guint32)wme_getpsidlen((guint8*)&psid);


    if (psidLen == 2)
        psid = tvb_get_ntohs(tvb, offset);
    else if (psidLen == 3)
        psid = tvb_get_ntoh24(tvb, offset);
    else if (psidLen == 4)
        psid = tvb_get_ntohl(tvb, offset);

    proto_tree_add_item(wsmp_tree,
                        hf_wsmp_psid, tvb, offset, psidLen, ENC_BIG_ENDIAN);
    offset += psidLen;


    /* TLV decoder that does not display the T and L elements */
    elemenId = tvb_get_guint8(tvb, offset);
    while ((elemenId != WSMP) && (elemenId != WSMP_S) && (elemenId != WSMP_I))
    {
        offset++;
        if (elemenId == CHANNUM)
        {
            elemenLen = tvb_get_guint8(tvb, offset);
            offset++;
            proto_tree_add_item(wsmp_tree,
                                hf_wsmp_channel, tvb, offset, elemenLen, ENC_BIG_ENDIAN);
            offset += elemenLen;
        }
        else if (elemenId == DATARATE)
        {
            elemenLen = tvb_get_guint8(tvb, offset);
            offset++;
            proto_tree_add_item(wsmp_tree,
                                hf_wsmp_rate, tvb, offset, elemenLen, ENC_BIG_ENDIAN);
            offset += elemenLen;
        }
        else if (elemenId == TRANSMITPW)
        {
            elemenLen = tvb_get_guint8(tvb, offset);
            offset++;
            proto_tree_add_item(wsmp_tree,
                                hf_wsmp_txpower, tvb, offset, elemenLen, ENC_BIG_ENDIAN);
            offset += elemenLen;
        }
        elemenId  = tvb_get_guint8(tvb, offset);
    }

    proto_tree_add_item(wsmp_tree,
                        hf_wsmp_WAVEid, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset++;

    wsmlength = tvb_get_letohs( tvb, offset);
    proto_tree_add_item(wsmp_tree,
                        hf_wsmp_wsmlength, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    if (elemenId == WSMP_S)
    {
        msb    = 1;
        supLen = 0;
        while (msb)
        {
            msb = tvb_get_guint8(tvb, offset + supLen);
            msb = msb & 0x80;
            supLen++;
        }
        proto_tree_add_item(wsmp_tree,
                            hf_wsmp_WSMP_S_data, tvb, offset, supLen, ENC_BIG_ENDIAN);
        wsmlength -= supLen;
        offset    += supLen;
    }

    wsmdata_tree = proto_tree_add_subtree(wsmp_tree, tvb, offset, wsmlength,
                                        ett_wsmdata, NULL, "Wave Short Message");

    wsmdata_tvb  = tvb_new_subset(tvb, offset, -1, wsmlength);

    /* TODO: Branch on the application context and display accordingly
     * Default: call the data dissector
     */
    if (psid == 0xbff0)
    {
        call_dissector(data_handle, wsmdata_tvb, pinfo, wsmdata_tree);
    }
}
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_jpeg( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
{
	proto_item *ti = NULL;
	proto_tree *jpeg_tree = NULL;
	proto_tree *main_hdr_tree = NULL;
	proto_tree *restart_hdr_tree = NULL;
	proto_tree *qtable_hdr_tree = NULL;
	guint32 fragment_offset = 0;
	guint16 len = 0;
	guint8 type = 0;
	guint8 q = 0;
	gint h = 0;
	gint w = 0;

	unsigned int offset       = 0;

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

	col_set_str(pinfo->cinfo, COL_INFO, "JPEG message");

	if ( tree ) {
		ti = proto_tree_add_item( tree, hfi_jpeg, tvb, offset, -1, ENC_NA );
		jpeg_tree = proto_item_add_subtree( ti, ett_jpeg );

		ti = proto_tree_add_item(jpeg_tree, &hfi_rtp_jpeg_main_hdr, tvb, offset, 8, ENC_NA);
		main_hdr_tree = proto_item_add_subtree(ti, ett_jpeg);

		proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_ts, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;
		proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_offs, tvb, offset, 3, ENC_BIG_ENDIAN);
		fragment_offset = tvb_get_ntoh24(tvb, offset);
		offset += 3;
		proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_type, tvb, offset, 1, ENC_BIG_ENDIAN);
		type = tvb_get_guint8(tvb, offset);
		offset += 1;
		proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_q, tvb, offset, 1, ENC_BIG_ENDIAN);
		q = tvb_get_guint8(tvb, offset);
		offset += 1;
		w = tvb_get_guint8(tvb, offset) * 8;
		proto_tree_add_uint(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_width, tvb, offset, 1, w);
		offset += 1;
		h = tvb_get_guint8(tvb, offset) * 8;
		proto_tree_add_uint(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_height, tvb, offset, 1, h);
		offset += 1;

		if (type >= 64 && type <= 127) {
			ti = proto_tree_add_item(jpeg_tree, &hfi_rtp_jpeg_restart_hdr, tvb, offset, 4, ENC_NA);
			restart_hdr_tree = proto_item_add_subtree(ti, ett_jpeg);
			proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
			proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_f, tvb, offset, 2, ENC_BIG_ENDIAN);
			proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_l, tvb, offset, 2, ENC_BIG_ENDIAN);
			proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_count, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
		}

		if (q >= 128 && fragment_offset == 0) {
			ti = proto_tree_add_item(jpeg_tree, &hfi_rtp_jpeg_qtable_hdr, tvb, offset, -1, ENC_NA);
			qtable_hdr_tree = proto_item_add_subtree(ti, ett_jpeg);
			proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_mbz, tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_prec, tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN);
			len = tvb_get_ntohs(tvb, offset);
			offset += 2;
			if (len > 0) {
				proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_data, tvb, offset, len, ENC_NA);
				offset += len;
			}
			proto_item_set_len(ti, len + 4);
		}

		/* The rest of the packet is the JPEG data */
		proto_tree_add_item( jpeg_tree, &hfi_rtp_jpeg_payload, tvb, offset, -1, ENC_NA );
	}
}
Example #4
0
/* Sub-vectors */
static int
sv_text(tvbuff_t *tvb, int svoff, packet_info *pinfo, proto_tree *tree)
{
	guint	sv_length, sv_id;
	guint16	beacon_type, ring;
	guint32	error_report_timer_value;

	proto_tree	*sv_tree, *sv_subtree;
	proto_item	*sv_item, *len_item, *ti;

	guchar		errors[6];	/* isolating or non-isolating */

	sv_item = proto_tree_add_text(tree, tvb, svoff+0, 1, "Subvector");
	sv_tree = proto_item_add_subtree(sv_item, ett_tr_sv);

	sv_length = tvb_get_guint8(tvb, svoff+0);
	len_item = proto_tree_add_item(sv_tree, hf_trmac_sv_len, tvb, svoff+0, 1, ENC_NA);

	/* Check the SV length; it must be at least 2, to include
	   the subvector length and indicator. */
	if (sv_length < 2) {
		expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
			"Invalid subvector: length < 2");
		return 0;	/* tells our caller to give up */
	}

	sv_id = tvb_get_guint8(tvb, svoff+1);
	proto_tree_add_item(sv_tree, hf_trmac_sv_id, tvb, svoff+1, 1, ENC_NA);
	proto_item_append_text(sv_item, " (%s)", val_to_str(sv_id, subvector_vs, "Unknown subvector ID 0x%02X"));

	switch(sv_id) {
		case 0x01: /* Beacon Type */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 4");
				break;
			}
			beacon_type = tvb_get_ntohs(tvb, svoff+2);
			proto_tree_add_uint_format_value(sv_tree, hf_trmac_beacon_type, tvb, svoff+2, sv_length-2,
					beacon_type, "%s", val_to_str(beacon_type, beacon_vs, "Illegal value: %d"));
			proto_item_append_text(sv_item,
					": %s", val_to_str(beacon_type, beacon_vs, "Illegal value: %d"));
			break;

		case 0x02: /* Upstream Neighbor's Address */
			if (sv_length != 8) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 8");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_naun, tvb, svoff+2, sv_length-2, ENC_NA);
			proto_item_append_text(sv_item, ": %s",
					tvb_ether_to_str(tvb, svoff+2));
			break;

		case 0x03: /* Local Ring Number */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 4");
				break;
			}
			ring = tvb_get_ntohs(tvb, svoff+2);
			proto_tree_add_item(sv_tree, hf_trmac_local_ring_number, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN);
			proto_item_append_text(sv_item,
				": 0x%04X (%d)", ring, ring);
			break;

		case 0x04: /* Assign Physical Drop Number */
			if (sv_length != 6) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 6");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_assign_physical_drop_number, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN);
			proto_item_append_text(sv_item,
				": 0x%08X", tvb_get_ntohl(tvb, svoff+2) );
			break;

		case 0x05: /* Error Report Timer Value */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 4");
				break;
			}

			error_report_timer_value = 10 * tvb_get_ntohs(tvb, svoff+2);
			proto_tree_add_uint_format_value(sv_tree, hf_trmac_error_report_timer_value, tvb, svoff+2, sv_length-2,
											error_report_timer_value, "%d ms", error_report_timer_value );
			proto_item_append_text(sv_item,
				": %d ms", error_report_timer_value );
			break;

		case 0x06: /* Authorized Function Classes */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_authorized_function_classes, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN);
			proto_item_append_text(sv_item,
				": %04X",  tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x07: /* Authorized Access Priority */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_authorized_access_priority, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN);
			proto_item_append_text(sv_item,
				": %04X",  tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x09: /* Correlator */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_correlator, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN);
			proto_item_append_text(sv_item,
				": %04X",  tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x0A: /* SA of Last AMP or SMP Frame */
			if (sv_length != 8) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 8");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_sa_of_last_amp_or_smp_frame, tvb, svoff+2, sv_length-2, ENC_NA);
			proto_item_append_text(sv_item,
				": %s",
				tvb_ether_to_str(tvb, svoff+2));
			break;

		case 0x0B: /* Physical Drop Number */
			if (sv_length != 6) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 6");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_physical_drop_number, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN);
			proto_item_append_text(sv_item,
				": 0x%08X", tvb_get_ntohl(tvb, svoff+2) );
			break;

		case 0x20: /* Response Code */
			if (sv_length != 4 && sv_length != 6) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 4 and != 6");
				break;
			}
			if (sv_length == 4) {
				proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
					"Response Code: 0x%04X 0x%02X 0x%02x",
					tvb_get_ntohs(tvb, svoff+2),
					tvb_get_guint8(tvb, svoff+4),
					tvb_get_guint8(tvb, svoff+5));
				proto_item_append_text(sv_item,
					": 0x%04X 0x%02X 0x%02x",
					tvb_get_ntohs(tvb, svoff+2),
					tvb_get_guint8(tvb, svoff+4),
					tvb_get_guint8(tvb, svoff+5));
			} else {
				proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
					"Response Code: 0x%04X 0x%02X 0x%06X",
					tvb_get_ntohs(tvb, svoff+2),
					tvb_get_guint8(tvb, svoff+4),
					tvb_get_ntoh24(tvb, svoff+5));
				proto_item_append_text(sv_item,
					": 0x%04X 0x%02X 0x%06X",
					tvb_get_ntohs(tvb, svoff+2),
					tvb_get_guint8(tvb, svoff+4),
					tvb_get_ntoh24(tvb, svoff+5));
			}
			break;

		case 0x21: /* Individual Address Count */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_individual_address_count, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN);
			proto_item_append_text(sv_item,
				": %u", tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x22: /* Product Instance ID */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Product Instance ID: ...");
			break;

		case 0x23: /* Ring Station Version Number */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Ring Station Version Number: ...");
			break;

		case 0x26: /* Wrap data */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Wrap Data: ... (%u bytes)", sv_length - 2);
			break;

		case 0x27: /* Frame Forward */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Frame Forward: ... (%d bytes)", sv_length - 2);
			break;

		case 0x28: /* Station Identifier */
			if (sv_length != 8) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 8");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_station_identifier, tvb, svoff+2, sv_length-2, ENC_NA);
			proto_item_append_text(sv_item,
				": %s",
				tvb_ether_to_str(tvb, svoff+2));
			break;

		case 0x29: /* Ring Station Status */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Ring Station Status: ...");
			break;

		case 0x2A: /* Transmit Status Code */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_transmit_status_code, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN);
			proto_item_append_text(sv_item,
				": %04X", tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x2B: /* Group Address */
			if (sv_length != 6 && sv_length != 8) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 6 and != 8");
				break;
			}
			if (sv_length == 6) {
				proto_tree_add_item(sv_tree, hf_trmac_group_address32, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN);
				proto_item_append_text(sv_item,
					": %08X", tvb_get_ntohl(tvb, svoff+2) );
			} else {
				proto_tree_add_item(sv_tree, hf_trmac_group_address_ether, tvb, svoff+2, sv_length-2, ENC_NA);
				proto_item_append_text(sv_item,
					": %s",
					tvb_ether_to_str(tvb, svoff+2));
			}
			break;

		case 0x2C: /* Functional Addresses */
			if (sv_length != 6) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 6");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_functional_addresses, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN);
			proto_item_append_text(sv_item,
				": %08X", tvb_get_ntohl(tvb, svoff+2) );
			break;

		case 0x2D: /* Isolating Error Counts */
			if (sv_length != 8) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 8");
				break;
			}
			tvb_memcpy(tvb, errors, svoff+2, 6);
			ti = proto_tree_add_uint(sv_tree, hf_trmac_errors_iso, tvb, svoff+2, sv_length-2,
				errors[0] + errors[1] + errors[2] + errors[3] + errors[4]);
			sv_subtree = proto_item_add_subtree(ti, ett_tr_ierr_cnt);

			proto_tree_add_uint(sv_subtree, hf_trmac_errors_line, tvb, svoff+2, 1, errors[0]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_internal, tvb, svoff+3, 1, errors[1]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_burst, tvb, svoff+4, 1, errors[2]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_ac, tvb, svoff+5, 1, errors[3]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_abort, tvb, svoff+6, 1, errors[4]);

			break;

		case 0x2E: /* Non-Isolating Error Counts */
			if (sv_length != 8) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 8");
				break;
			}
			tvb_memcpy(tvb, errors, svoff+2, 6);
			ti = proto_tree_add_uint(sv_tree, hf_trmac_errors_noniso, tvb, svoff+2, sv_length-2,
				errors[0] + errors[1] + errors[2] + errors[3] + errors[4]);
			sv_subtree = proto_item_add_subtree(ti, ett_tr_nerr_cnt);

			proto_tree_add_uint(sv_subtree, hf_trmac_errors_lost, tvb, svoff+2, 1, errors[0]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_congestion, tvb, svoff+3, 1, errors[1]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_fc, tvb, svoff+4, 1, errors[2]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_freq, tvb, svoff+5, 1, errors[3]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_token, tvb, svoff+6, 1, errors[4]);
			break;

		case 0x30: /* Error Code */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_error_code, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN);
			proto_item_append_text(sv_item,
				": %04X", tvb_get_ntohs(tvb, svoff+2) );
			break;

		default: /* Unknown */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Unknown Subvector");
			break;
	}
	return sv_length;
}
Example #5
0
static int
dissect_ppcap_destination_address(tvbuff_t *tvb, packet_info * pinfo, proto_tree * ppcap_tree1, int offset, guint16 msg_len )
{
	int key2;
	const guchar *dst_addr;
	/*guint32 dst_addr1;*/

	proto_tree_add_item(ppcap_tree1, hf_ppcap_destreserved, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	key2 = tvb_get_ntohs(tvb, offset);
	proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	if (key2 == 1)
	{
		ssn = tvb_get_guint8(tvb, offset);
		proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn1, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(ppcap_tree1, hf_ppcap_spc1, tvb, offset, 3, ENC_BIG_ENDIAN);

		/*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_dpc = ep_alloc0(sizeof(mtp3_addr_pc_t));
		mtp3_addr_dpc->pc = (guint32)tvb_get_ntoh24(tvb, offset);
		mtp3_addr_dpc->type = 1; /* ITU_STANDARD */
		mtp3_addr_dpc->ni = 0;
                SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc);
		/*dst_addr = tvb_get_ptr(tvb, offset, msg_len-1);
		SET_ADDRESS(&pinfo->net_dst, AT_SS7PC, msg_len-1, dst_addr);
		SET_ADDRESS(&pinfo->dst, AT_SS7PC, msg_len-1, dst_addr);*/

		if (msg_len%4)
			msg_len = msg_len + (4 - (msg_len%4));

        offset += msg_len-1;
        return offset;

	}
	else if (key2 == 2)
	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_dpc, tvb, offset, 4, ENC_BIG_ENDIAN);

		/*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_dpc = ep_alloc0(sizeof(mtp3_addr_pc_t));
		mtp3_addr_dpc->pc = tvb_get_ntohl(tvb, offset);
		mtp3_addr_dpc->type = 1; /* ITU_STANDARD */
		mtp3_addr_dpc->ni = 0;
        SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc);
	}
	else if (key2 == 3)
	{
		if (msg_len%4 == 0)
		{
			proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_destination_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset));
			dst_addr = tvb_get_ptr(tvb, offset, 4);
			SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, dst_addr);
			SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, dst_addr);
		}
		else
		{
			struct e_in6_addr value;

			tvb_get_ipv6(tvb, offset,&value);
			proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_destination_ip_address2, tvb, offset, msg_len, (guint8*)&value);
			dst_addr = tvb_get_ptr(tvb, offset, 6);
			SET_ADDRESS(&pinfo->net_dst, AT_IPv6, 6, dst_addr);
			SET_ADDRESS(&pinfo->dst, AT_IPv6, 6, dst_addr);
		}
	}

	else if (key2 == 4)
	{
		char *string;
		string = tvb_get_string(tvb, offset, msg_len);
		proto_tree_add_string(ppcap_tree1, hf_ppcap_destination_nodeid, tvb, offset, msg_len, string);
		dst_addr = tvb_get_ptr(tvb, offset, msg_len);
		SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, msg_len, dst_addr);
		SET_ADDRESS(&pinfo->dst, AT_STRINGZ, msg_len, dst_addr);
		/*g_free(string);*/
	}

	if (msg_len%4)
		msg_len = msg_len+(4-(msg_len%4));
		offset += msg_len;
	return offset;
}
Example #6
0
/* generic juniper header dissector  */
static int
dissect_juniper_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint8 *flags)
{
  proto_item *tisub;
  guint8     direction,l2hdr_presence,proto,ext_type,ext_len;
  guint16    ext_total_len,ext_offset=6,hdr_len;
  guint32    magic_number,ext_val;

  proto_tree *juniper_ext_subtree = NULL, *juniper_ext_subtree_item = NULL;

  magic_number = tvb_get_ntoh24(tvb, 0);
  *flags = tvb_get_guint8(tvb, 3);
  direction = *flags & JUNIPER_FLAG_PKT_IN;
  l2hdr_presence = *flags & JUNIPER_FLAG_NO_L2;

  juniper_subtree = proto_item_add_subtree(ti, ett_juniper);

  /* be liberal with magic-number detection -
   * some older JUNOS releases (e.g. 6.4),
   * which are still in the field do not generate magic-numbers */
  if (magic_number != JUNIPER_PCAP_MAGIC) {
    proto_tree_add_text (juniper_subtree, tvb, 0, 0, "no Magic-Number found !");
    return 0;
  }

  proto_tree_add_text (juniper_subtree, tvb, 0, 3,
                       "Magic-Number: 0x%06x", magic_number);

  proto_tree_add_uint_format (juniper_subtree, hf_juniper_direction, tvb, 3, 1,
                              direction, "Direction: %s",
                              val_to_str_const(direction,juniper_direction_vals,"Unknown"));

  proto_tree_add_uint_format (juniper_subtree, hf_juniper_l2hdr_presence, tvb, 3, 1,
                              l2hdr_presence, "L2-header: %s",
                              val_to_str_const(l2hdr_presence,juniper_l2hdr_presence_vals,"Unknown"));

  /* calculate hdr_len before cookie, payload */

  /* meta-info extensions (JUNOS >= 7.5) ? */
  if ((*flags & JUNIPER_FLAG_EXT) == JUNIPER_FLAG_EXT) {
    ext_total_len = tvb_get_ntohs(tvb,4);
    hdr_len = 6 + ext_total_len; /* MGC,flags,ext_total_len */

    tisub = proto_tree_add_uint (juniper_subtree, hf_juniper_ext_total_len, tvb, 4, 2, ext_total_len);
    juniper_ext_subtree = proto_item_add_subtree(tisub, ett_juniper);

    while (ext_total_len > EXT_TLV_HEADER_SIZE) {
      ext_type = tvb_get_guint8(tvb, ext_offset);
      ext_len = tvb_get_guint8(tvb, ext_offset+1);

      if (ext_len == 0 || ext_len > (ext_total_len - EXT_TLV_HEADER_SIZE)) /* a few sanity checks */
        break;

      tisub = proto_tree_add_text (juniper_ext_subtree, tvb, ext_offset, EXT_TLV_HEADER_SIZE + ext_len,
                                   "%s Extension TLV #%u, length: %u",
                                   val_to_str_const(ext_type, ext_tlv_vals, "Unknown"),
                                   ext_type,
                                   ext_len);

      ext_val = juniper_ext_get_tlv_value(tvb, ext_type, ext_len, ext_offset+EXT_TLV_HEADER_SIZE);
      juniper_ext_subtree_item = proto_item_add_subtree(tisub, ett_juniper);

      switch (ext_type) {
      case EXT_TLV_IFD_MEDIATYPE:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifmt,
                                    tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;
      case EXT_TLV_TTP_IFD_MEDIATYPE:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ttp_ifmt,
                                    tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;
      case EXT_TLV_IFL_ENCAPS:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifle,
                                    tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;
      case EXT_TLV_TTP_IFL_ENCAPS:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ttp_ifle,
                                    tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;

      case EXT_TLV_IFL_IDX:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifl,
                            tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;

      case EXT_TLV_IFL_UNIT:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_unit,
                            tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;
      case EXT_TLV_IFD_IDX:
        proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifd,
                            tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
        break;
      case EXT_TLV_IFD_NAME: /* FIXME print ifname string - lets fall-through for now */
      default:
        proto_item_append_text(tisub, "Unknown");
        break;
      }

      ext_offset += EXT_TLV_HEADER_SIZE + ext_len;
      ext_total_len -= EXT_TLV_HEADER_SIZE + ext_len;
    }

  } else
    hdr_len = 4; /* MGC,flags */

  if ((*flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) { /* no link header present ? */
    proto = tvb_get_letohl(tvb,hdr_len); /* proto is stored in host-order */
    dissect_juniper_payload_proto(tvb, pinfo, tree, ti, proto, hdr_len + 4);
    return -1;
  }

  return hdr_len; /* bytes parsed */

}
Example #7
0
static void
dissect_itdm_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  tvbuff_t	*next_tvb;
  proto_item *itdm_ctl_item = NULL;
  proto_tree *itdm_ctl_tree = NULL;
  int offset;
  guint32 flowid;
  guint8 command;
  guint32 trans_id;
  guint32 paired_trans_id;
  guint32 allocd_flowid;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ITDM-Control");

  flowid = tvb_get_ntoh24(tvb, ITDM_FLOWID_OFFSET);
  command = tvb_get_guint8(tvb, ITDM_CTL_CMD_OFFSET);
  allocd_flowid = tvb_get_ntoh24(tvb, ITDM_CTL_FLOWID_OFFSET);
  trans_id = tvb_get_ntohl(tvb, ITDM_CTL_TRANSID_OFFSET);
  paired_trans_id = tvb_get_ntohl(tvb, ITDM_CTL_PAIRED_TRANSID_OFFSET);

  col_add_fstr(pinfo->cinfo, COL_INFO,
      "Flow %d Command %s ",
      flowid, val_to_str_const(command, itdm_ctl_command_vals, "Reserved"));

  if (command != ITDM_CTL_CMD_AFI_REQ )
  {
    col_append_fstr(pinfo->cinfo, COL_INFO,
        " Alloc'd FlowID %d", allocd_flowid);
  }

  col_append_fstr(pinfo->cinfo, COL_INFO, " TransID 0x%x ", trans_id);

  if (command != ITDM_CTL_CMD_AFI_REQ )
  {
    col_append_fstr(pinfo->cinfo, COL_INFO,
        " Paired TransID 0x%x", paired_trans_id);
  }

  offset = 0;

  if (tree)
  {
	itdm_ctl_item = proto_tree_add_item(tree, proto_itdm, tvb, 0, -1, ENC_NA);
	itdm_ctl_tree = proto_item_add_subtree(itdm_ctl_item, ett_itdm_ctl);

	/* These eventually should go into a SFP.0 dissector... */
	proto_tree_add_item(itdm_ctl_tree, hf_itdm_timestamp, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;
	proto_tree_add_item(itdm_ctl_tree, hf_itdm_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;
	proto_tree_add_item(itdm_ctl_tree, hf_itdm_sop_eop, tvb, offset, 1, ENC_BIG_ENDIAN);
	proto_tree_add_item(itdm_ctl_tree, hf_itdm_last_pack, tvb, offset, 1, ENC_BIG_ENDIAN);
	proto_tree_add_item(itdm_ctl_tree, hf_itdm_pktlen, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;
	proto_tree_add_item(itdm_ctl_tree, hf_itdm_chksum, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;
	proto_tree_add_item(itdm_ctl_tree, hf_itdm_uid, tvb, offset, 3, ENC_BIG_ENDIAN);
	offset += 3;

	proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_transid, tvb, offset, 4, ENC_BIG_ENDIAN);
	offset += 4;

	proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_command, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;
	if (command != ITDM_CTL_CMD_AFI_REQ) {
		proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_flowid, tvb, offset, 3, ENC_BIG_ENDIAN);
	}
	offset += 3;
	proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_dm, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;
	/* rsvd.. */
	offset += 1;
	proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_emts, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;
	proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_pktrate, tvb, offset, 4, ENC_BIG_ENDIAN);
	offset += 4;
	if (command != ITDM_CTL_CMD_AFI_REQ) {
		proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_ptid, tvb, offset, 4, ENC_BIG_ENDIAN);
	}
	offset += 4;
	/* rsvd.. */
	offset += 2;
	proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_cksum, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;
  }

  next_tvb = tvb_new_subset_remaining(tvb, offset);
  call_dissector(data_handle, next_tvb, pinfo, tree);
}
Example #8
0
/* Code to actually dissect the packets */
static void
dissect_fcfzs_zoneset(tvbuff_t *tvb, proto_tree *tree, int offset)
{
    int numzones, nummbrs, i, j, len;

    /* The zoneset structure has the following format */
    /* zoneset name (len[not including pad], name, pad),
     * number of zones,
     * for each zone,
     *     Zone name (len[not including pad], name, pad), num zone mbrs
     *     for each zone mbr,
     *         zone mbr id type, zone mbr id (len, name, pad)
     */
    if (tree) {

        /* Zoneset Name */
        len = tvb_get_guint8(tvb, offset);
        proto_tree_add_item(tree, hf_fcfzs_zonesetnmlen, tvb, offset,
                            1, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_fcfzs_zonesetname, tvb, offset+4,
                            len, ENC_ASCII|ENC_NA);
        offset += 4 + len + (4-(len % 4));


        /* Number of zones */
        numzones = tvb_get_ntohl(tvb, offset);
        proto_tree_add_item(tree, hf_fcfzs_numzones, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;

        /* For each zone... */
        for (i = 0; i < numzones; i++) {
            len = tvb_get_guint8(tvb, offset);
            proto_tree_add_item(tree, hf_fcfzs_zonenmlen, tvb, offset,
                                1, ENC_BIG_ENDIAN);
            proto_tree_add_item(tree, hf_fcfzs_zonename, tvb, offset+4,
                                len, ENC_ASCII|ENC_NA);
            offset += 4 + len + (4-(len % 4));

            nummbrs = tvb_get_ntohl(tvb, offset);
            proto_tree_add_item(tree, hf_fcfzs_nummbrentries, tvb, offset,
                                4, ENC_BIG_ENDIAN);

            offset += 4;
            for (j = 0; j < nummbrs; j++) {
                proto_tree_add_item(tree, hf_fcfzs_mbrtype, tvb, offset, 1, ENC_BIG_ENDIAN);

                switch (tvb_get_guint8(tvb, offset)) {
                case FC_FZS_ZONEMBR_PWWN:
                case FC_FZS_ZONEMBR_NWWN:
                    proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb,
                                          offset+4, 8,
                                          tvb_fcwwn_to_str(tvb, offset+4));
                    break;
                case FC_FZS_ZONEMBR_DP:
                    proto_tree_add_string_format(tree,
                                                 hf_fcfzs_mbrid,
                                                 tvb, offset+4, 3, " ",
                                                 "0x%x",
                                                 tvb_get_ntoh24(tvb,
                                                         offset+4));
                    break;
                case FC_FZS_ZONEMBR_FCID:
                    proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb,
                                          offset+4, 4,
                                          tvb_fc_to_str(tvb, offset+4));
                    break;
                case FC_FZS_ZONEMBR_PWWN_LUN:
                    proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb,
                                          offset+4, 8,
                                          tvb_fcwwn_to_str(tvb, offset+4));
                    proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb,
                                        offset+8, 8, ENC_NA);
                    break;
                case FC_FZS_ZONEMBR_DP_LUN:
                    proto_tree_add_string_format(tree,
                                                 hf_fcfzs_mbrid,
                                                 tvb, offset+4, 3, " ",
                                                 "0x%x",
                                                 tvb_get_ntoh24(tvb,
                                                         offset+4));
                    proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb,
                                        offset+4, 8, ENC_NA);
                    break;
                case FC_FZS_ZONEMBR_FCID_LUN:
                    proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb,
                                          offset+4, 4,
                                          tvb_fc_to_str(tvb, offset+4));
                    proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb,
                                        offset+4, 8, ENC_NA);
                    break;
                default:
                    proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb,
                                          offset+4, 8,
                                          "Unknown member type format");
                }
                offset += 12;
            }
        }
    }
}
Example #9
0
static void
dissect_sdh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "SDH");
  col_clear(pinfo->cinfo,COL_INFO);

  if (tree) {
    proto_tree *sdh_tree;
    proto_item *sdh_item;

    int     level = get_sdh_level(tvb);

    guint32 a1;
    guint32 a2;
    guint8  j0;
    guint8  b1;
    guint8  e1;
    guint8  f1;
    guint8  d1;
    guint8  d2;
    guint8  d3;
    guint8  h1;
    guint8  h2;
    guint16 au;
    guint32 b2;
    guint8  k1;
    guint8  k2;
    guint8  d4;
    guint8  d5;
    guint8  d6;
    guint8  d7;
    guint8  d8;
    guint8  d9;
    guint8  d10;
    guint8  d11;
    guint8  d12;
    guint8  s1;
    guint8  m1;
    guint8  e2;
    guint8  j1;

    sdh_item = proto_tree_add_protocol_format(tree, proto_sdh, tvb, 0, -1, "SDH");
    sdh_tree = proto_item_add_subtree(sdh_item, ett_sdh);

    a1  = tvb_get_ntoh24(tvb, 0+(0*level*COLUMNS));
    a2  = tvb_get_ntoh24(tvb, 3+(0*level*COLUMNS));
    j0  = tvb_get_guint8(tvb, 6+(0*level*COLUMNS));
    b1  = tvb_get_guint8(tvb, 0+(1*level*COLUMNS));
    e1  = tvb_get_guint8(tvb, 3+(1*level*COLUMNS));
    f1  = tvb_get_guint8(tvb, 6+(1*level*COLUMNS));
    d1  = tvb_get_guint8(tvb, 0+(2*level*COLUMNS));
    d2  = tvb_get_guint8(tvb, 3+(2*level*COLUMNS));
    d3  = tvb_get_guint8(tvb, 6+(2*level*COLUMNS));
    h1  = tvb_get_guint8(tvb, 0+(3*level*COLUMNS));
    h2  = tvb_get_guint8(tvb, 3+(3*level*COLUMNS));
    au  = (h2 | ((0x03 & h1) << 8));
    b2  = 0;
    b2  = tvb_get_guint8(tvb, 0+(4*level*COLUMNS)) << 16;
    b2  = tvb_get_guint8(tvb, (1*level)+(4*level*COLUMNS)) << 8;
    b2  = tvb_get_guint8(tvb, (2*level)+(4*level*COLUMNS));
    k1  = tvb_get_guint8(tvb, 3+(4*level*COLUMNS));
    k2  = tvb_get_guint8(tvb, 6+(4*level*COLUMNS));
    d4  = tvb_get_guint8(tvb, 0+(5*level*COLUMNS));
    d5  = tvb_get_guint8(tvb, 3+(5*level*COLUMNS));
    d6  = tvb_get_guint8(tvb, 6+(5*level*COLUMNS));
    d7  = tvb_get_guint8(tvb, 0+(6*level*COLUMNS));
    d8  = tvb_get_guint8(tvb, 3+(6*level*COLUMNS));
    d9  = tvb_get_guint8(tvb, 6+(6*level*COLUMNS));
    d10 = tvb_get_guint8(tvb, 0+(7*level*COLUMNS));
    d11 = tvb_get_guint8(tvb, 3+(7*level*COLUMNS));
    d12 = tvb_get_guint8(tvb, 6+(7*level*COLUMNS));
    s1  = tvb_get_guint8(tvb, 0+(8*level*COLUMNS));
    m1  = tvb_get_guint8(tvb, 5+(8*level*COLUMNS));
    e2  = tvb_get_guint8(tvb, 6+(8*level*COLUMNS));

    j1 = tvb_get_guint8(tvb, au);

    proto_tree_add_uint_format(sdh_tree, hf_sdh_a1,  tvb, 0, 3, a1, "A1 %x", a1);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_a2,  tvb, 3, 3, a2, "A2 %x", a2);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_j0,  tvb, 6, 1, j0, "J0 %d", j0);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_b1,  tvb, 0+(1*level*COLUMNS), 1,  b1, "B1 %d",  b1);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_e1,  tvb, 3+(1*level*COLUMNS), 1,  e1, "E1 %d",  e1);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_f1,  tvb, 6+(1*level*COLUMNS), 1,  f1, "F1 %d",  f1);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d1,  tvb, 0+(2*level*COLUMNS), 1,  d1, "D1 %d",  d1);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d2,  tvb, 3+(2*level*COLUMNS), 1,  d2, "D2 %d",  d2);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d3,  tvb, 6+(2*level*COLUMNS), 1,  d3, "D3 %d",  d3);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_au,  tvb, 0+(3*level*COLUMNS), 9,  au, "AU pointer %d h1 %d, h2 %d", au, h1, h2);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_b2,  tvb, 0+(4*level*COLUMNS), 1,  b2, "B2 %d",  b2);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_k1,  tvb, 3+(4*level*COLUMNS), 1,  k1, "K1 %d",  k1);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_k2,  tvb, 6+(4*level*COLUMNS), 1,  k2, "K2 %d",  k2);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d4,  tvb, 0+(5*level*COLUMNS), 1,  d4, "D4 %d",  d4);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d5,  tvb, 3+(5*level*COLUMNS), 1,  d5, "D5 %d",  d5);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d6,  tvb, 6+(5*level*COLUMNS), 1,  d6, "D6 %d",  d6);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d7,  tvb, 0+(6*level*COLUMNS), 1,  d7, "D7 %d",  d7);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d8,  tvb, 3+(6*level*COLUMNS), 1,  d8, "D8 %d",  d8);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d9,  tvb, 6+(6*level*COLUMNS), 1,  d9, "D9 %d",  d9);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d10, tvb, 0+(7*level*COLUMNS), 1, d10, "D10 %d", d10);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d11, tvb, 3+(7*level*COLUMNS), 1, d11, "D11 %d", d11);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_d12, tvb, 6+(7*level*COLUMNS), 1, d12, "D12 %d", d12);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_s1,  tvb, 0+(8*level*COLUMNS), 1,  s1, "S1 %d",  s1);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_m1,  tvb, 5+(8*level*COLUMNS), 1,  m1, "M1 %d",  m1);
    proto_tree_add_uint_format(sdh_tree, hf_sdh_e2,  tvb, 6+(7*level*COLUMNS), 1,  e2, "E2 %d",  e2);

    proto_tree_add_uint_format(sdh_tree, hf_sdh_j1,  tvb, au, 1, j1, "J1 %d", j1);
  }

}
Example #10
0
static void
dissect_itdm_125usec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  tvbuff_t	*next_tvb;
  proto_item *itdm_item = NULL;
  proto_tree *itdm_tree = NULL;
  int offset;
  guint32 flowid;
  guint32 chanid;
  guint16 chloc1;
  guint16 chloc2;
  guint8 chcmd;
  guint8 actbit;
  guint8 ackbit;


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

  flowid = tvb_get_ntoh24(tvb, ITDM_FLOWID_OFFSET);
  chanid = tvb_get_ntoh24(tvb, ITDM_CHANID_OFFSET);
  chcmd  = tvb_get_guint8(tvb, ITDM_CHCMD_OFFSET);
  chloc1 = tvb_get_ntohs(tvb, ITDM_CHLOC1_OFFSET);
  actbit = (chcmd & 0x10) ? 1 : 0;
  ackbit = (chcmd & 0x20) ? 1 : 0;
  chcmd  = chcmd & 0x0f;

  col_add_fstr(pinfo->cinfo, COL_INFO,
      "Flow %d Chan %d ACT %d ACK %d %s",
      flowid, chanid, actbit, ackbit,
      val_to_str_const(chcmd, chcmd_vals, "Reserved"));
  if (chcmd == ITDM_CMD_NEW_CHAN ||
      chcmd == ITDM_CMD_CLOSE_CHAN ||
      chcmd == ITDM_CMD_CYCLIC_REAF)
  {
    col_append_fstr(pinfo->cinfo, COL_INFO,
        " Loc1 %d", chloc1);
  }
  else if (chcmd == ITDM_CMD_RELOC_CHAN)
  {
    chloc2 = tvb_get_ntohs(tvb, ITDM_CHLOC2_OFFSET);
    col_append_fstr(pinfo->cinfo, COL_INFO,
      " Loc1 %d Loc2 %d", chloc1, chloc2);
  }

  offset = 0;

  if (tree)
  {
	itdm_item = proto_tree_add_item(tree, proto_itdm, tvb, 0, -1, ENC_NA);
	itdm_tree = proto_item_add_subtree(itdm_item, ett_itdm);

	proto_tree_add_item(itdm_tree, hf_itdm_timestamp, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;
	proto_tree_add_item(itdm_tree, hf_itdm_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;
	proto_tree_add_item(itdm_tree, hf_itdm_sop_eop, tvb, offset, 1, ENC_BIG_ENDIAN);
	proto_tree_add_item(itdm_tree, hf_itdm_last_pack, tvb, offset, 1, ENC_BIG_ENDIAN);
	proto_tree_add_item(itdm_tree, hf_itdm_pktlen, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;
	proto_tree_add_item(itdm_tree, hf_itdm_chksum, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;
	proto_tree_add_item(itdm_tree, hf_itdm_uid, tvb, offset, 3, ENC_BIG_ENDIAN);
	offset += 3;
	proto_tree_add_item(itdm_tree, hf_itdm_ack, tvb, offset, 1, ENC_BIG_ENDIAN);
	proto_tree_add_item(itdm_tree, hf_itdm_act, tvb, offset, 1, ENC_BIG_ENDIAN);
	proto_tree_add_item(itdm_tree, hf_itdm_chcmd, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;
	proto_tree_add_item(itdm_tree, hf_itdm_chid, tvb, offset, 3, ENC_BIG_ENDIAN);
	offset += 3;
	if (chcmd == ITDM_CMD_PACKET_RATE)
	{
		proto_tree_add_item(itdm_tree, hf_itdm_pktrate, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
	}
	else
	{
		proto_tree_add_item(itdm_tree, hf_itdm_chloc1, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;
		if (chcmd == ITDM_CMD_CYCLIC_REAF ||
		    chcmd == ITDM_CMD_NEW_CHAN ||
		    chcmd == ITDM_CMD_CLOSE_CHAN)
		{
			proto_tree_add_item(itdm_tree, hf_itdm_cxnsize, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
		}
		else
		{
			proto_tree_add_item(itdm_tree, hf_itdm_chloc2, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
		}
	}
  }

  next_tvb = tvb_new_subset_remaining(tvb, offset);
  call_dissector(data_handle, next_tvb, pinfo, tree);
}
Example #11
0
static int
dissect_ppcap_source_address(tvbuff_t *tvb, packet_info *pinfo, proto_tree * ppcap_tree1, int offset, guint16 msg_len)
{
	int key1;
	proto_tree_add_item(ppcap_tree1, hf_ppcap_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	key1 = tvb_get_ntohs(tvb, offset);
	proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	if (key1 == 1)
	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;
		proto_tree_add_item(ppcap_tree1, hf_ppcap_spc, tvb, offset, 3, ENC_BIG_ENDIAN);
		/*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_opc = ep_alloc0(sizeof(mtp3_addr_pc_t));
		mtp3_addr_opc->pc = (guint32 )tvb_get_ntoh24(tvb, offset);
		mtp3_addr_opc->type = 1; /* ITU_STANDARD */
		mtp3_addr_opc->ni = 0;
		/*SET_ADDRESS(&pinfo->net_src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);*/
		SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);
		if (msg_len%4)
			msg_len = msg_len + (4 - (msg_len%4));

		offset += msg_len-1;
		return offset;
	}
	else if (key1 == 2)
	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_opc, tvb, offset, msg_len, ENC_BIG_ENDIAN);

		/*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_opc = ep_alloc0(sizeof(mtp3_addr_pc_t));
		mtp3_addr_opc->pc = tvb_get_ntohl(tvb, offset);
		mtp3_addr_opc->type = 1; /* ITU_STANDARD */
		mtp3_addr_opc->ni = 0;
		SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);
	}
	else if (key1 == 3)
	{
		if (msg_len%4 == 0)
		{

			proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_source_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset));
			TVB_SET_ADDRESS(&pinfo->net_src, AT_IPv4, tvb, offset, 4);
			COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src);
		}
		else
		{
			struct e_in6_addr value;
			tvb_get_ipv6(tvb, offset, &value);
			proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_source_ip_address2, tvb, offset, msg_len, (guint8*)&value);
			TVB_SET_ADDRESS(&pinfo->net_src, AT_IPv6, tvb, offset, 6);
			COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src);
		}
	}

	else if (key1 == 4)

	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_source_nodeid, tvb, offset, msg_len, ENC_BIG_ENDIAN|ENC_ASCII);
		TVB_SET_ADDRESS(&pinfo->net_src, AT_STRINGZ, tvb, offset, msg_len);
		COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src);
	}
	if (msg_len%4)
		msg_len = msg_len + (4 - (msg_len%4));
	offset += msg_len;
	return offset;
}
Example #12
0
/*
 * Dissect SNAP header; used elsewhere, e.g. in the Frame Relay dissector.
 */
void
dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
	     proto_tree *snap_tree, int control, int hf_oui, int hf_type, int hf_pid,
	     int bridge_pad)
{
	guint32		oui;
	guint16		etype;
	tvbuff_t	*next_tvb;
	oui_info_t	*oui_info;
	dissector_table_t subdissector_table;
	int		hf;
	int		mesh_header_len;

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

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

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

	switch (oui) {

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

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

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

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

		switch (etype) {

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

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

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

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

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

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

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

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

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

	default:
		/*
		 * Do we have information for this OUI?
		 */
		oui_info = get_snap_oui_info(oui);
		if (oui_info != NULL) {
			/*
			 * Yes - use it.
			 */
			hf = *oui_info->field_info->p_id;
			subdissector_table = oui_info->table;
		} else {
			/*
			 * No, use hf_pid for the PID and just dissect
			 * the payload as data.
			 */
			hf = hf_pid;
			subdissector_table = NULL;
		}
		if (tree) {
			proto_tree_add_uint(snap_tree, hf, tvb, offset+3, 2,
			    etype);
		}
		next_tvb = tvb_new_subset_remaining(tvb, offset+5);
		if (XDLC_IS_INFORMATION(control)) {
			if (subdissector_table != NULL) {
				/* do lookup with the subdissector table */
				if (dissector_try_uint(subdissector_table,
				    etype, next_tvb, pinfo, tree))
					break;
			}
		}
		call_dissector(data_handle, next_tvb, pinfo, tree);
		break;
	}
}
static void
dissect_fcfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

    /* Set up structures needed to add the protocol subtree and manage it */
    int offset = 0;
    proto_item *ti;
    proto_tree *fcfcs_tree = NULL;
    fc_ct_preamble cthdr;
    gboolean isreq = 1;
    conversation_t *conversation;
    fcfcs_conv_data_t *cdata;
    fcfcs_conv_key_t ckey, *req_key;
    int opcode,
        failed_opcode = 0;

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

    if (tree) {
        ti = proto_tree_add_protocol_format (tree, proto_fcfcs, tvb, 0,
                                             tvb_reported_length (tvb),
                                             "FCS");
        fcfcs_tree = proto_item_add_subtree (ti, ett_fcfcs);
    }

    tvb_memcpy (tvb, (guint8 *)&cthdr, offset, FCCT_PRMBL_SIZE);
    cthdr.revision = tvb_get_guint8 (tvb, offset);
    cthdr.in_id = tvb_get_ntoh24 (tvb, offset+1);
    cthdr.opcode = g_ntohs (cthdr.opcode);
    opcode = tvb_get_ntohs (tvb, offset+8);
    cthdr.maxres_size = g_ntohs (cthdr.maxres_size);

    if ((opcode != FCCT_MSG_ACC) && (opcode != FCCT_MSG_RJT)) {
        conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst,
                                          pinfo->ptype, pinfo->oxid,
                                          pinfo->rxid, NO_PORT2);
        if (!conversation) {
            conversation = conversation_new (pinfo->fd->num, &pinfo->src, &pinfo->dst,
                                             pinfo->ptype, pinfo->oxid,
                                             pinfo->rxid, NO_PORT2);
        }

        ckey.conv_idx = conversation->index;

        cdata = (fcfcs_conv_data_t *)g_hash_table_lookup (fcfcs_req_hash,
                &ckey);
        if (cdata) {
            /* Since we never free the memory used by an exchange, this maybe a
             * case of another request using the same exchange as a previous
             * req.
             */
            cdata->opcode = opcode;
        }
        else {
            req_key = se_alloc (sizeof(fcfcs_conv_key_t));
            req_key->conv_idx = conversation->index;

            cdata = se_alloc (sizeof(fcfcs_conv_data_t));
            cdata->opcode = opcode;

            g_hash_table_insert (fcfcs_req_hash, req_key, cdata);
        }
        if (check_col (pinfo->cinfo, COL_INFO)) {
            col_add_str (pinfo->cinfo, COL_INFO,
                         val_to_str (opcode, fc_fcs_opcode_abbrev_val, "0x%x"));
        }
    }
    else {
        /* Opcode is ACC or RJT */
        conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst,
                                          pinfo->ptype, pinfo->oxid,
                                          pinfo->rxid, NO_PORT2);
        isreq = 0;
        if (!conversation) {
            if (tree && (opcode == FCCT_MSG_ACC)) {
                if (check_col (pinfo->cinfo, COL_INFO)) {
                    col_add_str (pinfo->cinfo, COL_INFO,
                                 val_to_str (opcode, fc_fcs_opcode_abbrev_val,
                                             "0x%x"));
                }
                /* No record of what this accept is for. Can't decode */
                proto_tree_add_text (fcfcs_tree, tvb, 0, tvb_length (tvb),
                                     "No record of Exchg. Unable to decode MSG_ACC/RJT");
                return;
            }
        }
        else {
            ckey.conv_idx = conversation->index;

            cdata = (fcfcs_conv_data_t *)g_hash_table_lookup (fcfcs_req_hash,
                    &ckey);

            if (cdata != NULL) {
                if (opcode == FCCT_MSG_ACC)
                    opcode = cdata->opcode;
                else
                    failed_opcode = cdata->opcode;
            }

            if (check_col (pinfo->cinfo, COL_INFO)) {
                if (opcode != FCCT_MSG_RJT) {
                    col_add_fstr (pinfo->cinfo, COL_INFO, "MSG_ACC (%s)",
                                  val_to_str (opcode, fc_fcs_opcode_abbrev_val,
                                              "0x%x"));
                }
                else {
                    col_add_fstr (pinfo->cinfo, COL_INFO, "MSG_RJT (%s)",
                                  val_to_str (failed_opcode,
                                              fc_fcs_opcode_abbrev_val,
                                              "0x%x"));
                }
            }

            if (tree) {
                if ((cdata == NULL) && (opcode != FCCT_MSG_RJT)) {
                    /* No record of what this accept is for. Can't decode */
                    proto_tree_add_text (fcfcs_tree, tvb, 0, tvb_length (tvb),
                                         "No record of Exchg. Unable to decode MSG_ACC/RJT");
                    return;
                }
            }
        }
    }


    if (tree) {
        proto_tree_add_item (fcfcs_tree, hf_fcs_opcode, tvb, offset+8, 2, 0);
        proto_tree_add_item (fcfcs_tree, hf_fcs_maxres_size, tvb, offset+10,
                             2, 0);
    }

    switch (opcode) {
    case FCCT_MSG_RJT:
        dissect_fcfcs_rjt (tvb, fcfcs_tree);
        break;
    case FCFCS_GIEL:
        dissect_fcfcs_giel (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GIET:
        dissect_fcfcs_giet (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GDID:
        dissect_fcfcs_gdid (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GMID:
        dissect_fcfcs_gmid (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GFN:
        dissect_fcfcs_gfn (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GIELN:
        dissect_fcfcs_gieln (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GMAL:
        dissect_fcfcs_gmal (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GIEIL:
        dissect_fcfcs_gieil (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GPL:
        dissect_fcfcs_gpl (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GPT:
        dissect_fcfcs_gpt (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GPPN:
        dissect_fcfcs_gppn (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GAPNL:
        dissect_fcfcs_gapnl (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GPS:
        dissect_fcfcs_gps (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GPLNL:
        dissect_fcfcs_gplnl (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GPLT:
        dissect_fcfcs_gplt (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GPLML:
        dissect_fcfcs_gplml (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GNPL:
        dissect_fcfcs_gnpl (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GPNL:
        dissect_fcfcs_gpnl (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_RIELN:
        dissect_fcfcs_rieln (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_RPL:
        dissect_fcfcs_rpl (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_RPLN:
        dissect_fcfcs_rpln (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_RPLT:
        dissect_fcfcs_rplt (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_RPLM:
        dissect_fcfcs_rplm (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_DPL:
        dissect_fcfcs_dpl (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_DPLN:
        dissect_fcfcs_dpln (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_DPLML:
        dissect_fcfcs_dplml (tvb, fcfcs_tree, isreq);
        break;
    case FCFCS_GCAP:
        dissect_fcfcs_gcap (tvb, fcfcs_tree, isreq);
        break;
    default:
        call_dissector (data_handle, tvb, pinfo, fcfcs_tree);
        break;
    }
}
Example #14
0
/* Sub-vectors */
static int
sv_text(tvbuff_t *tvb, int svoff, packet_info *pinfo, proto_tree *tree)
{
	guint	sv_length, sv_id;
	guint16	beacon_type, ring;

	const char *beacon[] = {
		"Recovery mode set", "Signal loss error",
		"Streaming signal not Claim Token MAC frame",
		"Streaming signal, Claim Token MAC frame"
	};

	proto_tree	*sv_tree, *sv_subtree;
	proto_item	*sv_item, *len_item, *ti;

	guchar		errors[6];	/* isolating or non-isolating */

	sv_length = tvb_get_guint8(tvb, svoff+0);

	/* Check the SV length; it must be at least 2, to include
	   the subvector length and indicator. */
	if (sv_length < 2) {
		ti = proto_tree_add_text(tree, tvb, svoff+0, 1,
		    "Invalid subvector: length < 2");
		sv_tree = proto_item_add_subtree(ti, ett_tr_sv);
		len_item = proto_tree_add_uint(sv_tree, hf_trmac_sv_len, tvb, svoff+0, 1, sv_length);
		expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
		    "Subvector length is zero");
		return 0;	/* tells our caller to give up */
	}

	sv_item = proto_tree_add_text(tree, tvb, svoff+0, sv_length,
	    "Subvector: length %u", sv_length);
	sv_tree = proto_item_add_subtree(sv_item, ett_tr_sv);
	len_item = proto_tree_add_uint(sv_tree, hf_trmac_sv_len, tvb, svoff+0, 1, sv_length);
	sv_id = tvb_get_guint8(tvb, svoff+1);
	proto_tree_add_uint(sv_tree, hf_trmac_sv_id, tvb, svoff+1, 1, sv_id);
	proto_item_set_text(sv_item, "%s", val_to_str(sv_id, subvector_vs, "Unknown subvector ID 0x%02X"));

	switch(sv_id) {
		case 0x01: /* Beacon Type */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 4");
				break;
			}
			beacon_type = tvb_get_ntohs(tvb, svoff+2);
			if (beacon_type < array_length(beacon)) {
				proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
					"Beacon Type: %s", beacon[beacon_type] );
				proto_item_append_text(sv_item,
					": %s", beacon[beacon_type] );
			} else {
				proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
					"Beacon Type: Illegal value: %d", beacon_type );
				proto_item_append_text(sv_item,
					": Illegal value: %d", beacon_type );
			}
			break;

		case 0x02: /* Upstream Neighbor's Address */
			if (sv_length != 8) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 8");
				break;
			}
			proto_tree_add_item(sv_tree, hf_trmac_naun, tvb, svoff+2, sv_length-2, ENC_NA);
			proto_item_append_text(sv_item, ": %s",
					tvb_ether_to_str(tvb, svoff+2));
			break;

		case 0x03: /* Local Ring Number */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 4");
				break;
			}
			ring = tvb_get_ntohs(tvb, svoff+2);
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Local Ring Number: 0x%04X (%d)", ring, ring);
			proto_item_append_text(sv_item,
				": 0x%04X (%d)", ring, ring);
			break;

		case 0x04: /* Assign Physical Drop Number */
			if (sv_length != 6) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 6");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Assign Physical Drop Number: 0x%08X", tvb_get_ntohl(tvb, svoff+2) );
			proto_item_append_text(sv_item,
				": 0x%08X", tvb_get_ntohl(tvb, svoff+2) );
			break;

		case 0x05: /* Error Report Timer Value */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Error Report Timer Value: %d ms", 10 * tvb_get_ntohs(tvb, svoff+2) );
			proto_item_append_text(sv_item,
				": %d ms", 10 * tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x06: /* Authorized Function Classes */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Authorized Function Classes: %04X",  tvb_get_ntohs(tvb, svoff+2) );
			proto_item_append_text(sv_item,
				": %04X",  tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x07: /* Authorized Access Priority */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Authorized Access Priority: %04X",  tvb_get_ntohs(tvb, svoff+2) );
			proto_item_append_text(sv_item,
				": %04X",  tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x09: /* Correlator */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Correlator: %04X",  tvb_get_ntohs(tvb, svoff+2) );
			proto_item_append_text(sv_item,
				": %04X",  tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x0A: /* SA of Last AMP or SMP Frame */
			if (sv_length != 8) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 8");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"SA of Last AMP or SMP Frame: %s",
				tvb_ether_to_str(tvb, svoff+2));
			proto_item_append_text(sv_item,
				": %s",
				tvb_ether_to_str(tvb, svoff+2));
			break;

		case 0x0B: /* Physical Drop Number */
			if (sv_length != 6) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 6");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Physical Drop Number: 0x%08X", tvb_get_ntohl(tvb, svoff+2) );
			proto_item_append_text(sv_item,
				": 0x%08X", tvb_get_ntohl(tvb, svoff+2) );
			break;

		case 0x20: /* Response Code */
			if (sv_length != 4 && sv_length != 6) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 4 and != 6");
				break;
			}
			if (sv_length == 4) {
				proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
					"Response Code: 0x%04X 0x%02X 0x%02x",
					tvb_get_ntohs(tvb, svoff+2),
					tvb_get_guint8(tvb, svoff+4),
					tvb_get_guint8(tvb, svoff+5));
				proto_item_append_text(sv_item,
					": 0x%04X 0x%02X 0x%02x",
					tvb_get_ntohs(tvb, svoff+2),
					tvb_get_guint8(tvb, svoff+4),
					tvb_get_guint8(tvb, svoff+5));
			} else {
				proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
					"Response Code: 0x%04X 0x%02X 0x%06X",
					tvb_get_ntohs(tvb, svoff+2),
					tvb_get_guint8(tvb, svoff+4),
					tvb_get_ntoh24(tvb, svoff+5));
				proto_item_append_text(sv_item,
					": 0x%04X 0x%02X 0x%06X",
					tvb_get_ntohs(tvb, svoff+2),
					tvb_get_guint8(tvb, svoff+4),
					tvb_get_ntoh24(tvb, svoff+5));
			}
			break;

		case 0x21: /* Individual Address Count */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Individual Address Count: %u", tvb_get_ntohs(tvb, svoff+2) );
			proto_item_append_text(sv_item,
				": %u", tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x22: /* Product Instance ID */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Product Instance ID: ...");
			break;

		case 0x23: /* Ring Station Version Number */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Ring Station Version Number: ...");
			break;

		case 0x26: /* Wrap data */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Wrap Data: ... (%u bytes)", sv_length - 2);
			break;

		case 0x27: /* Frame Forward */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Frame Forward: ... (%d bytes)", sv_length - 2);
			break;

		case 0x28: /* Station Identifier */
			if (sv_length != 8) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 8");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Station Identifier: %s",
				tvb_ether_to_str(tvb, svoff+2));
			proto_item_append_text(sv_item,
				": %s",
				tvb_ether_to_str(tvb, svoff+2));
			break;

		case 0x29: /* Ring Station Status */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Ring Station Status: ...");
			break;

		case 0x2A: /* Transmit Status Code */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Transmit Status Code: %04X", tvb_get_ntohs(tvb, svoff+2) );
			proto_item_append_text(sv_item,
				": %04X", tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x2B: /* Group Address */
			if (sv_length != 6 && sv_length != 8) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 6 and != 8");
				break;
			}
			if (sv_length == 6) {
				proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
					"Group Address: %08X", tvb_get_ntohl(tvb, svoff+2) );
				proto_item_append_text(sv_item,
					": %08X", tvb_get_ntohl(tvb, svoff+2) );
			} else {
				proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
					"Group Address: %s",
					tvb_ether_to_str(tvb, svoff+2));
				proto_item_append_text(sv_item,
					": %s",
					tvb_ether_to_str(tvb, svoff+2));
			}
			break;

		case 0x2C: /* Functional Addresses */
			if (sv_length != 6) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 6");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Functional Addresses: %08X", tvb_get_ntohl(tvb, svoff+2) );
			proto_item_append_text(sv_item,
				": %08X", tvb_get_ntohl(tvb, svoff+2) );
			break;

		case 0x2D: /* Isolating Error Counts */
			if (sv_length != 8) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 8");
				break;
			}
			tvb_memcpy(tvb, errors, svoff+2, 6);
			ti = proto_tree_add_uint(sv_tree, hf_trmac_errors_iso, tvb, svoff+2, sv_length-2,
				errors[0] + errors[1] + errors[2] + errors[3] + errors[4]);
			sv_subtree = proto_item_add_subtree(ti, ett_tr_ierr_cnt);

			proto_tree_add_uint(sv_subtree, hf_trmac_errors_line, tvb, svoff+2, 1, errors[0]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_internal, tvb, svoff+3, 1, errors[1]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_burst, tvb, svoff+4, 1, errors[2]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_ac, tvb, svoff+5, 1, errors[3]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_abort, tvb, svoff+6, 1, errors[4]);

			break;

		case 0x2E: /* Non-Isolating Error Counts */
			if (sv_length != 8) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 8");
				break;
			}
			tvb_memcpy(tvb, errors, svoff+2, 6);
			ti = proto_tree_add_uint(sv_tree, hf_trmac_errors_noniso, tvb, svoff+2, sv_length-2,
				errors[0] + errors[1] + errors[2] + errors[3] + errors[4]);
			sv_subtree = proto_item_add_subtree(ti, ett_tr_nerr_cnt);

			proto_tree_add_uint(sv_subtree, hf_trmac_errors_lost, tvb, svoff+2, 1, errors[0]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_congestion, tvb, svoff+3, 1, errors[1]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_fc, tvb, svoff+4, 1, errors[2]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_freq, tvb, svoff+5, 1, errors[3]);
			proto_tree_add_uint(sv_subtree, hf_trmac_errors_token, tvb, svoff+6, 1, errors[4]);
			break;

		case 0x30: /* Error Code */
			if (sv_length != 4) {
				expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR,
				    "Subvector length is != 4");
				break;
			}
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Error Code: %04X", tvb_get_ntohs(tvb, svoff+2) );
			proto_item_append_text(sv_item,
				": %04X", tvb_get_ntohs(tvb, svoff+2) );
			break;

		default: /* Unknown */
			proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2,
				"Unknown Subvector");
			break;
	}
	return sv_length;
}
Example #15
0
/* WiMax MAC to MAC protocol dissector */
static void dissect_m2m(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item *ti = NULL;
	proto_item *m2m_item = NULL;
	proto_tree *m2m_tree = NULL;
	proto_tree *tlv_tree = NULL;
	gint burst_number = 0;
	gint length, offset = 0;
	gint tlv_count;
	gint tlv_type, tlv_len, tlv_offset, tlv_value;
	gint tlv_frag_type = 0;
	gint tlv_frag_number = 0;
	tlv_info_t m2m_tlv_info;
	gint hf;
	guint encoding;
	guint frame_number;
	int expected_len;

	/* display the M2M protocol name */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "WiMax");

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


	{	/* we are being asked for details */
		m2m_item = proto_tree_add_item(tree, proto_m2m, tvb, 0, -1, ENC_NA);
		m2m_tree = proto_item_add_subtree(m2m_item, ett_m2m);
		/* get the tvb reported length */
		length =  tvb_reported_length(tvb);
		/* add the size info */
        /*
		proto_item_append_text(m2m_item, " (%u bytes) - Packet Sequence Number,Number of TLVs", length);
        */
		proto_item_append_text(m2m_item, " (%u bytes)", length);
		/* display the sequence number */
		proto_tree_add_item(m2m_tree, hf_m2m_sequence_number, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;
		/* display the TLV count */
		proto_tree_add_item(m2m_tree, hf_m2m_tlv_count, tvb, offset, 2, ENC_BIG_ENDIAN);
		tlv_count = tvb_get_ntohs(tvb, offset);
		offset += 2;
		/* parses the TLVs within current packet */
		while ( tlv_count > 0)
		{	/* init MAC to MAC TLV information */
			init_tlv_info(&m2m_tlv_info, tvb, offset);
			/* get the TLV type */
			tlv_type = get_tlv_type(&m2m_tlv_info);
			/* get the TLV length */
			tlv_len = get_tlv_length(&m2m_tlv_info);
			if(tlv_type == -1 || tlv_len > 64000 || tlv_len < 1)
			{	/* invalid tlv info */
				col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "M2M TLV error");
				/* display the invalid TLV in HEX */
				proto_tree_add_item(m2m_tree, hf_wimax_invalid_tlv, tvb, offset, (length - offset), ENC_NA);
				break;
			}
			/* get the TLV value offset */
			tlv_offset = get_tlv_value_offset(&m2m_tlv_info);
			/* display TLV type */
			ti = proto_tree_add_protocol_format(m2m_tree, proto_m2m, tvb, offset, (tlv_len + tlv_offset), "%s", val_to_str(tlv_type, tlv_name, "Unknown TLV"));
			/* add TLV subtree */
			tlv_tree = proto_item_add_subtree(ti, ett_m2m_tlv);
			/* update the offset */
			offset += tlv_offset;
			/* add the size info */
			/* decode TLV content (TLV value) */
			expected_len = 0;
			hf = 0;
			encoding = ENC_NA;
			switch (tlv_type)
			{
				case TLV_PROTO_VER:
					/* get the protocol version */
					tlv_value = tvb_get_guint8( tvb, offset );
					/* add the description */
					proto_item_append_text(ti, ": %d", tlv_value);
					hf = hf_m2m_value_protocol_vers_uint8;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 1;
				break;

				case TLV_BURST_NUM:
					/* get the burst number */
					burst_number = tvb_get_guint8( tvb, offset );
					/* add the description */
					proto_item_append_text(ti, ": %d", burst_number);
					hf = hf_m2m_value_burst_num_uint8;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 1;
				break;

				case TLV_FRAG_TYPE:
					/* add the description */
					tlv_frag_type = tvb_get_guint8( tvb, offset );
					proto_item_append_text(ti, ": %s", val_to_str(tlv_frag_type, tlv_frag_type_name, "Unknown"));
					hf = hf_m2m_value_frag_type_uint8;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 1;
				break;

				case TLV_FRAG_NUM:
					/* get the fragment number */
					tlv_frag_number = tvb_get_guint8( tvb, offset );
					/* add the description */
					proto_item_append_text(ti, ": %d", tlv_frag_number);
					hf = hf_m2m_value_frag_num_uint8;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 1;
				break;

				case TLV_PDU_BURST:
					/* display PDU Burst length info */
					proto_item_append_text(ti, " (%u bytes)", tlv_len);
					/* decode and display the PDU Burst */
					pdu_burst_decoder(tree, tvb, offset, tlv_len, pinfo, burst_number, tlv_frag_type, tlv_frag_number);
					hf = hf_m2m_value_pdu_burst;
					encoding = ENC_NA;
				break;

				case TLV_FAST_FB:
					/* display the Fast Feedback Burst length info */
					proto_item_append_text(ti, " (%u bytes)", tlv_len);
					/* decode and display the Fast Feedback Burst */
					fast_feedback_burst_decoder(tree, tvb, offset, tlv_len, pinfo);
					hf = hf_m2m_value_fast_fb;
					encoding = ENC_NA;
				break;

				case TLV_FRAME_NUM:
					/* get the frame number */
					frame_number = tvb_get_ntoh24( tvb, offset );
					/* add the description */
					proto_tree_add_item(tlv_tree, hf_m2m_frame_number, tvb, offset, 3, ENC_BIG_ENDIAN);
					proto_item_append_text(ti, ": %d", frame_number);
				break;

				case TLV_FCH_BURST:
					/* add the description */
					tlv_value = tvb_get_ntoh24( tvb, offset );
					proto_item_append_text(ti, ": 0x%X", tlv_value);
					/* decode and display the TLV FCH burst */
					fch_burst_decoder(tree, tvb, offset, tlv_len, pinfo);
					hf = hf_m2m_value_fch_burst_uint24;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 3;
				break;

				case TLV_CDMA_CODE:
					/* add the description */
					tlv_value = tvb_get_ntoh24( tvb, offset );
					proto_item_append_text(ti, ": 0x%X", tlv_value);
					/* decode and display the CDMA Code */
					cdma_code_decoder(tree, tvb, offset, tlv_len, pinfo);
					hf = hf_m2m_value_cdma_code_uint24;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 3;
				break;

				case TLV_CRC16_STATUS:
					/* add the description */
					tlv_value = tvb_get_guint8( tvb, offset );
					proto_item_append_text(ti, ": %s", val_to_str(tlv_value, tlv_crc16_status, "Unknown"));
					hf = hf_m2m_value_crc16_status_uint8;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 1;
				break;

				case TLV_BURST_POWER:
					/* add the description */
					tlv_value = tvb_get_ntohs( tvb, offset );
					proto_item_append_text(ti, ": %d", tlv_value);
					hf = hf_m2m_value_burst_power_uint16;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 2;
				break;

				case TLV_BURST_CINR:
					/* add the description */
					tlv_value = tvb_get_ntohs( tvb, offset );
					proto_item_append_text(ti, ": 0x%X", tlv_value);
					hf = hf_m2m_value_burst_cinr_uint16;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 2;
				break;

				case TLV_PREAMBLE:
					/* add the description */
					tlv_value = tvb_get_ntohs( tvb, offset );
					proto_item_append_text(ti, ": 0x%X", tlv_value);
					hf = hf_m2m_value_preamble_uint16;
					encoding = ENC_BIG_ENDIAN;
					expected_len = 2;
				break;

				case TLV_HARQ_ACK_BURST:
					/* display the Burst length info */
					proto_item_append_text(ti, " (%u bytes)", tlv_len);
					/* decode and display the HARQ ACK Bursts */
					harq_ack_bursts_decoder(tree, tvb, offset, tlv_len, pinfo);
					hf = hf_m2m_value_harq_ack_burst_bytes;
					encoding = ENC_NA;
				break;

				case TLV_PHY_ATTRIBUTES:
					/* display the Burst length info */
					proto_item_append_text(ti, " (%u bytes)", tlv_len);
					/* decode and display the PDU Burst Physical Attributes */
					physical_attributes_decoder(tree, tvb, offset, tlv_len, pinfo);
					hf = hf_m2m_phy_attributes;
					encoding = ENC_NA;
				break;

				case TLV_EXTENDED_TLV:
					/* display the Burst length info */
					proto_item_append_text(ti, " (%u bytes)", tlv_len);
					/* decode and display the Extended TLV */
					extended_tlv_decoder(pinfo);
				break;

				default:
					/* update the info column */
					col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Unknown TLV Type");
				break;
			}
			/* expand the TLV detail */
			if (hf) {
				if (offset - tlv_offset == expected_len) {
					proto_tree_add_tlv(&m2m_tlv_info, tvb, offset - tlv_offset, pinfo, tlv_tree, hf, encoding);
				} else {
					expert_add_info_format(pinfo, NULL, &ei_m2m_unexpected_length, "Expected length %d, got %d.", expected_len, offset - tlv_offset);
				}
			}
			offset += tlv_len;
			/* update tlv_count */
			tlv_count--;
		}
	}
}
Example #16
0
/* Dissect a FEC header:
 * fec - ptr to the logical FEC packet representation to fill
 * hf - ptr to header fields array
 * ett - ptr to ett array
 * prefs - ptr to FEC prefs array
 * tvb - buffer
 * pinfo - packet info
 * tree - tree where to add FEC header subtree
 * offset - ptr to offset to use and update
 */
static int
dissect_fec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    proto_item          *ti;
    proto_tree          *fec_tree;
    guint                offset      = 0;
    fec_data_exchange_t *fec         = (fec_data_exchange_t*)data;
    guint8               encoding_id = 0;
    fec_packet_data_t   *packet_data = (fec_packet_data_t*)p_get_proto_data(wmem_file_scope(), pinfo, proto_rmt_fec, 0);

    if (fec != NULL)
    {
        encoding_id = fec->encoding_id;
    }

    /* Create the FEC subtree */
    ti = proto_tree_add_item(tree, proto_rmt_fec, tvb, offset, -1, ENC_NA);
    fec_tree = proto_item_add_subtree(ti, ett_main);

    proto_tree_add_uint(fec_tree, hf_encoding_id, tvb, offset, 0, encoding_id);

    if (encoding_id >= 128 && (packet_data != NULL))
        proto_tree_add_uint(fec_tree, hf_instance_id, tvb, offset, 0, packet_data->instance_id);

    switch (encoding_id)
    {
    case 0:
    case 1:
    case 130:
        proto_tree_add_item(fec_tree, hf_sbn, tvb, offset,   2, ENC_BIG_ENDIAN);
        proto_tree_add_item(fec_tree, hf_esi, tvb, offset+2, 2, ENC_BIG_ENDIAN);

        col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohs(tvb, offset));
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohs(tvb, offset+2));

        offset += 4;
        break;

    case 2:
    case 128:
    case 132:
        proto_tree_add_item(fec_tree, hf_sbn, tvb, offset,   4, ENC_BIG_ENDIAN);
        proto_tree_add_item(fec_tree, hf_esi, tvb, offset+4, 4, ENC_BIG_ENDIAN);

        col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohl(tvb, offset));
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohl(tvb, offset+4));

        offset += 8;
        break;

    case 3:
    case 4:
        proto_tree_add_item(fec_tree, hf_sbn_with_mask, tvb, offset, 4, ENC_BIG_ENDIAN);
        proto_tree_add_item(fec_tree, hf_esi_with_mask, tvb, offset, 4, ENC_BIG_ENDIAN);

        col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohl(tvb, offset) >> 20);
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohl(tvb, offset) & 0xfffff);

        offset += 4;
        break;

    case 6:
        proto_tree_add_item(fec_tree, hf_sbn, tvb, offset,   1, ENC_BIG_ENDIAN);
        proto_tree_add_item(fec_tree, hf_esi, tvb, offset+1, 3, ENC_BIG_ENDIAN);

        col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_guint8(tvb, offset));
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntoh24(tvb, offset+1));

        offset += 4;
        break;

    case 129:
        proto_tree_add_item(fec_tree, hf_sbn, tvb, offset,   4, ENC_BIG_ENDIAN);
        proto_tree_add_item(fec_tree, hf_sbl, tvb, offset+4, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(fec_tree, hf_esi, tvb, offset+6, 2, ENC_BIG_ENDIAN);

        col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohl(tvb, offset));
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohs(tvb, offset+6));

        offset += 8;
        break;
    }

    return offset;
}
Example #17
0
static int
dissect_ppcap_destination_address(tvbuff_t *tvb, packet_info * pinfo, proto_tree * ppcap_tree1, int offset, guint16 msg_len )
{
	int key2;

	proto_tree_add_item(ppcap_tree1, hf_ppcap_destreserved, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	key2 = tvb_get_ntohs(tvb, offset);
	proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN);
	offset += 2;

	if (key2 == 1)
	{
		ssn = tvb_get_guint8(tvb, offset);
		proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn1, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;

		proto_tree_add_item(ppcap_tree1, hf_ppcap_spc1, tvb, offset, 3, ENC_BIG_ENDIAN);

		/*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_dpc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t);
		mtp3_addr_dpc->pc = (guint32)tvb_get_ntoh24(tvb, offset);
		mtp3_addr_dpc->type = ITU_STANDARD;
		mtp3_addr_dpc->ni = 0;
                SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc);

		if (msg_len%4)
			msg_len = msg_len + (4 - (msg_len%4));

        offset += msg_len-1;
        return offset;

	}
	else if (key2 == 2)
	{
		proto_tree_add_item(ppcap_tree1, hf_ppcap_dpc, tvb, offset, 4, ENC_BIG_ENDIAN);

		/*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/
		mtp3_addr_dpc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t);
		mtp3_addr_dpc->pc = tvb_get_ntohl(tvb, offset);
		mtp3_addr_dpc->type = ITU_STANDARD;
		mtp3_addr_dpc->ni = 0;
        SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc);
	}
	else if (key2 == 3)
	{
		if (msg_len%4 == 0)
		{
			proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_destination_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset));
			TVB_SET_ADDRESS(&pinfo->net_dst, AT_IPv4, tvb, offset, 4);
			COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst);
		}
		else
		{
			struct e_in6_addr value;

			tvb_get_ipv6(tvb, offset,&value);
			proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_destination_ip_address2, tvb, offset, msg_len, (guint8*)&value);
			TVB_SET_ADDRESS(&pinfo->net_dst, AT_IPv6, tvb, offset, 6);
			COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst);
		}
	}

	else if (key2 == 4)
	{
		char *string;
		string = tvb_get_string(wmem_packet_scope(), tvb, offset, msg_len);
		proto_tree_add_string(ppcap_tree1, hf_ppcap_destination_nodeid, tvb, offset, msg_len, string);
		TVB_SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, tvb, offset, msg_len);
		COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst);
	}

	if (msg_len%4)
		msg_len = msg_len+(4-(msg_len%4));
		offset += msg_len;
	return offset;
}
Example #18
0
static void
dissect_ieee802a(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*ieee802a_tree = NULL;
	proto_item	*ti;
	tvbuff_t	*next_tvb;
	guint32		oui;
	guint16		pid;
	oui_info_t	*oui_info;
	dissector_table_t subdissector_table;
	int		hf;

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

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

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

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

	/*
	 * Do we have information for this OUI?
	 */
	if (oui_info_table != NULL &&
	    (oui_info = (oui_info_t *)g_hash_table_lookup(oui_info_table,
	      GUINT_TO_POINTER(oui))) != NULL) {
		/*
		 * Yes - use it.
		 */
		hf = *oui_info->field_info->p_id;
		subdissector_table = oui_info->table;
	} else {
		/*
		 * No, use hf_ieee802a_pid for the PID and just dissect
		 * the payload as data.
		 */
		hf = hf_ieee802a_pid;
		subdissector_table = NULL;
	}
	if (tree)
		proto_tree_add_uint(ieee802a_tree, hf, tvb, 3, 2, pid);
	next_tvb = tvb_new_subset_remaining(tvb, 5);
	if (subdissector_table != NULL) {
		/* do lookup with the subdissector table */
		if (dissector_try_uint(subdissector_table, pid, next_tvb,
		    pinfo, tree))
			return;
	}
	call_dissector(data_handle, next_tvb, pinfo, tree);
}
Example #19
0
proto_tree *add_protocol_subtree(tlv_info_t *self, gint idx, proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length _U_, const char *label)
{
    /* Declare local variables */
    proto_tree *tlv_tree;
    proto_item *tlv_item;
    gint tlv_value_length, tlv_val_offset;
    guint8 size_of_tlv_length_field;
    guint8 tlv_type;
    guint32 tlv_value;
    const gchar *hex_fmt;

    /* Make sure we're dealing with a valid TLV here */
    if (get_tlv_type(self) < 0)
        return tree;

    /* Retrieve the necessary TLV information */
    tlv_val_offset = get_tlv_value_offset(self);
    tlv_value_length = get_tlv_length(self);
    size_of_tlv_length_field = get_tlv_size_of_length(self);
    tlv_type = get_tlv_type(self);

    /* display the TLV name and display the value in hex. Highlight type, length, and value. */
    tlv_item = proto_tree_add_protocol_format(tree, hfindex, tvb, start, tlv_value_length+tlv_val_offset, "%s (%u byte(s))", label, tlv_value_length);
    tlv_tree = proto_item_add_subtree(tlv_item, ett_tlv[tlv_type]);

    proto_tree_add_uint(tlv_tree, hf_tlv_type, tvb, start, 1, tlv_type);
    if (size_of_tlv_length_field > 0) /* It is */
    {
        /* display the length of the length field TLV */
        proto_tree_add_uint(tlv_tree, hf_tlv_length_size, tvb, start+1, 1, size_of_tlv_length_field);
        /* display the TLV length */
        proto_tree_add_uint(tlv_tree, hf_tlv_length, tvb, start+2, size_of_tlv_length_field, tlv_value_length);
    } else { /* It is not */
        /* display the TLV length */
        proto_tree_add_uint(tlv_tree, hf_tlv_length, tvb, start+1, 1, tlv_value_length);
    }

    /* display the TLV value and make it a subtree */
    switch (tlv_value_length)
    {
    case 1:
        tlv_value = tvb_get_guint8(tvb, start+tlv_val_offset);
        hex_fmt = tlv_val_1byte;
        break;
    case 2:
        tlv_value = tvb_get_ntohs(tvb, start+tlv_val_offset);
        hex_fmt = tlv_val_2byte;
        break;
    case 3:
        tlv_value = tvb_get_ntoh24(tvb, start+tlv_val_offset);
        hex_fmt = tlv_val_3byte;
        break;
    case 4:
        tlv_value = tvb_get_ntohl(tvb, start+tlv_val_offset);
        hex_fmt = tlv_val_4byte;
        break;
    default:
        tlv_value = tvb_get_ntohl(tvb, start+tlv_val_offset);
        hex_fmt = tlv_val_5byte;
        break;
    }
    /* Show "TLV value: " */
    tlv_item = proto_tree_add_text(tlv_tree, tvb, start+tlv_val_offset, tlv_value_length, hex_fmt, label, tlv_value);
    tlv_tree = proto_item_add_subtree(tlv_item, idx);

    /* Return a pointer to the value level */
    return tlv_tree;
}