Esempio n. 1
0
/* Code to actually dissect the packets */
static void
dissect_ipa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

	int offset = 0;

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

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

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

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

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

		next_tvb = tvb_new_subset(tvb, offset+3, len, len);

		switch (msg_type) {
		case ABISIP_RSL:
			/* hand this off to the standard A-bis RSL dissector */
			call_dissector(sub_handles[SUB_RSL], next_tvb, pinfo, tree);
			break;
		case ABISIP_OML:
			/* hand this off to the standard A-bis OML dissector */
			if (sub_handles[SUB_OML])
				call_dissector(sub_handles[SUB_OML], next_tvb,
						 pinfo, tree);
			break;
		case ABISIP_IPACCESS:
			dissect_ipaccess(next_tvb, pinfo, tree);
			break;
		case AIP_SCCP:
			/* hand this off to the standard SCCP dissector */
			call_dissector(sub_handles[SUB_SCCP], next_tvb, pinfo, tree);
			break;
		}
		offset += len + 3;
	}
}
/* Code to actually dissect the packets */
static void
dissect_ipa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    gint remaining;
    gint header_length = 3;
    int offset = 0;

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

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

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

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

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

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

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

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