示例#1
0
/*
 * Dissect ASCII TPKT-encapsulated data in a TCP stream.
 */
void
dissect_asciitpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
		  dissector_handle_t subdissector_handle)
{
    proto_item *ti = NULL;
    proto_tree *tpkt_tree = NULL;
    volatile int offset = 0;
    int length_remaining;
    int data_len;
    volatile int mgcp_packet_len = 0;
    int mgcp_version = 0;
    int mgcp_reserved = 0;
    volatile int length;
    tvbuff_t *volatile next_tvb;
    const char *saved_proto;
    guint8 string[4];
    void *pd_save;

    /*
     * If we're reassembling segmented TPKT PDUs, empty the COL_INFO
     * column, so subdissectors can append information
     * without having to worry about emptying the column.
     *
     * We use "col_add_str()" because the subdissector
     * might be appending information to the column, in
     * which case we'd have to zero the buffer out explicitly
     * anyway.
     */
    if (tpkt_desegment)
        col_set_str(pinfo->cinfo, COL_INFO, "");

    while (tvb_reported_length_remaining(tvb, offset) != 0) {
        /*
         * Is the first byte of this putative TPKT header
         * a valid TPKT version number, i.e. 3?
         */
        if (tvb_get_guint8(tvb, offset) != 48) {
            /*
             * No, so don't assume this is a TPKT header;
             * we might be in the middle of TPKT data,
             * so don't get the length and don't try to
             * do reassembly.
             */
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
            col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
            if (tree) {
                ti = proto_tree_add_item(tree, proto_tpkt, tvb,
                    offset, -1, ENC_NA);
                tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
                proto_item_set_text(ti, "TPKT");

                proto_tree_add_text(tpkt_tree, tvb, offset, -1,
                    "Continuation data");
            }
            return;
        }

        length_remaining = tvb_captured_length_remaining(tvb, offset);

        /*
         * Get the length from the TPKT header.
         */

        tvb_memcpy(tvb, (guint8 *)string, offset, 2);
        mgcp_version = parseVersionText(string);
        tvb_memcpy(tvb, (guint8 *)string, offset +2, 2);
        mgcp_reserved = parseReservedText(string);
        tvb_memcpy(tvb, (guint8 *)string, offset + 4, 4);
        mgcp_packet_len = parseLengthText(string);
        data_len = mgcp_packet_len;

        /*
         * Dissect the TPKT header.
         * Save and restore "pinfo->current_proto".
         */
        saved_proto = pinfo->current_proto;
        pinfo->current_proto = "TPKT";

        col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
        /*
         * Don't add the TPKT header information if we're
         * reassembling segmented TPKT PDUs or if this
         * PDU isn't reassembled.
         *
         * XXX - the first is so that subdissectors can append
         * information without getting TPKT stuff in the middle;
         * why the second?
         */
        if (!tpkt_desegment && !pinfo->fragmented) {
            col_add_fstr(pinfo->cinfo, COL_INFO,
                "TPKT Data length = %u", data_len);
        }

        if (tree) {
            ti = proto_tree_add_item(tree, proto_tpkt, tvb,
                offset, 8, ENC_NA);
            tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
            proto_item_set_text(ti, "TPKT");

            /* Version */
            proto_tree_add_uint(tpkt_tree, hf_tpkt_version, tvb,
                            offset, 2, mgcp_version);

            /* Reserved octet*/
            proto_tree_add_uint(tpkt_tree, hf_tpkt_reserved, tvb,
                            offset + 2, 2, mgcp_reserved);

            /* Length */
            proto_tree_add_uint(tpkt_tree, hf_tpkt_length, tvb,
                            offset + 4, 4, mgcp_packet_len);
        }
        pinfo->current_proto = saved_proto;

        /* Skip the TPKT header. */
        offset += TEXT_LAYER_LENGTH;
        length = length_remaining - TEXT_LAYER_LENGTH;
        if (length > data_len)
            length = data_len;

        next_tvb = tvb_new_subset(tvb, offset,length, data_len);

        /*
         * Call the subdissector.
         *
         * If it gets an error that means there's no point in
         * dissecting any more TPKT messages, rethrow the
         * exception in question.
         *
         * If it gets any other error, report it and continue, as that
         * means that TPKT message got an error, but that doesn't mean
         * we should stop dissecting TPKT messages within this frame
         * or chunk of reassembled data.
         */
	pd_save = pinfo->private_data;
        TRY {
            call_dissector(subdissector_handle, next_tvb, pinfo,
                tree);
        }
        CATCH_NONFATAL_ERRORS {
	    /*  Restore the private_data structure in case one of the
	     *  called dissectors modified it (and, due to the exception,
	     *  was unable to restore it).
	     */
	    pinfo->private_data = pd_save;

            show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
        }
        ENDTRY;

        /*
         * Skip the payload.
         */
        offset += data_len;
    }
}
/*
 * Dissect ASCII TPKT-encapsulated data in a TCP stream.
 */
void
dissect_asciitpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    dissector_handle_t subdissector_handle)
{
    proto_item *ti = NULL;
    proto_tree *tpkt_tree = NULL;
    volatile int offset = 0;
    int length_remaining;
    int data_len;
    int mgcp_packet_len = 0;
    int mgcp_version = 0;
    int mgcp_reserved = 0;
    volatile int length;
    tvbuff_t *volatile next_tvb;
    const char *saved_proto;
    guint8 string[4];
    /*
     * If we're reassembling segmented TPKT PDUs, empty the COL_INFO
     * column, so subdissectors can append information
     * without having to worry about emptying the column.
     *
     * We use "col_add_str()" because the subdissector
     * might be appending information to the column, in
     * which case we'd have to zero the buffer out explicitly
     * anyway.
     */
    if (tpkt_desegment && check_col(pinfo->cinfo, COL_INFO))
        col_add_str(pinfo->cinfo, COL_INFO, "");

    while (tvb_reported_length_remaining(tvb, offset) != 0) {
        /*
         * Is the first byte of this putative TPKT header
         * a valid TPKT version number, i.e. 3?
         */
        if (tvb_get_guint8(tvb, offset) != 48) {
            /*
             * No, so don't assume this is a TPKT header;
             * we might be in the middle of TPKT data,
             * so don't get the length and don't try to
             * do reassembly.
             */
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
            col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
            if (tree) {
                ti = proto_tree_add_item(tree, proto_tpkt, tvb,
                    offset, -1, FALSE);
                tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
                proto_item_set_text(ti, "TPKT");

                proto_tree_add_text(tpkt_tree, tvb, offset, -1,
                    "Continuation data");
            }
            return;
        }

        length_remaining = tvb_length_remaining(tvb, offset);

        /*
         * Get the length from the TPKT header.
         */

        tvb_memcpy(tvb, (guint8 *)string, offset, 2);
        mgcp_version = parseVersionText(string);
        tvb_memcpy(tvb, (guint8 *)string, offset +2, 2);
        mgcp_reserved = parseReservedText(string);
        tvb_memcpy(tvb, (guint8 *)string, offset + 4, 4);
        mgcp_packet_len = parseLengthText(string);
        data_len = mgcp_packet_len;

        /*
         * Dissect the TPKT header.
         * Save and restore "pinfo->current_proto".
         */
        saved_proto = pinfo->current_proto;
        pinfo->current_proto = "TPKT";

        col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
        /*
         * Don't add the TPKT header information if we're
         * reassembling segmented TPKT PDUs or if this
         * PDU isn't reassembled.
         *
         * XXX - the first is so that subdissectors can append
         * information without getting TPKT stuff in the middle;
         * why the second?
         */
        if (!tpkt_desegment && !pinfo->fragmented
            && check_col(pinfo->cinfo, COL_INFO)) {
            col_add_fstr(pinfo->cinfo, COL_INFO,
                "TPKT Data length = %u", data_len);
        }

        if (tree) {
            ti = proto_tree_add_item(tree, proto_tpkt, tvb,
                offset, 8, FALSE);
            tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
            proto_item_set_text(ti, "TPKT");

            /* Version */
            proto_tree_add_uint(tpkt_tree, hf_tpkt_version, tvb,
                            offset, 2, mgcp_version);

            /* Reserved octet*/
            proto_tree_add_uint(tpkt_tree, hf_tpkt_reserved, tvb,
                            offset + 2, 2, mgcp_reserved);

            /* Length */
            proto_tree_add_uint(tpkt_tree, hf_tpkt_length, tvb,
                            offset + 4, 4, mgcp_packet_len);
        }
        pinfo->current_proto = saved_proto;

        /* Skip the TPKT header. */
        offset += TEXT_LAYER_LENGTH;
        length = length_remaining - TEXT_LAYER_LENGTH;
        if (length > data_len)
            length = data_len;

        next_tvb = tvb_new_subset(tvb, offset,length, data_len);

        /*
         * Call the subdissector.
         *
         * Catch the ReportedBoundsError exception; if this
         * particular message happens to get a ReportedBoundsError
         * exception, that doesn't mean that we should stop
         * dissecting TPKT messages within this frame or chunk
         * of reassembled data.
         *
         * If it gets a BoundsError, we can stop, as there's nothing
         * more to see, so we just re-throw it.
         */

        TRY {
            call_dissector(subdissector_handle, next_tvb, pinfo,
                tree);
        }
        CATCH(BoundsError) {
            RETHROW;
        }
        CATCH(ReportedBoundsError) {
            show_reported_bounds_error(tvb, pinfo, tree);
        }
        ENDTRY;

        /*
         * Skip the payload.
         */
        offset += data_len;
    }
}