Wireshark-dev: [Wireshark-dev] How to call a dissector from the llc dissector?
From: Florian FAVIER <florian_favier@xxxxxxxxxx>
Date: Wed, 20 May 2009 14:19:51 +0200

Hello,

We are now writing a new dissector for the Asterix protocol, and we would like to call it when the LLC dissector is running.
The condition is when the third byte of LLC is equal to 0x03, we have to call our dissector.
We tried this in the dissect_llc function :

dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree    *llc_tree = NULL;
    proto_item    *ti = NULL;
    int        is_snap;
    guint16        control;
    int        llc_header_len;
    guint8        dsap, ssap, format;
    tvbuff_t    *next_tvb;
    int cmd;

    if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLC");
    }
    if (check_col(pinfo->cinfo, COL_INFO)) {
        col_clear(pinfo->cinfo, COL_INFO);
    }

    dsap = tvb_get_guint8(tvb, 0);
    if (tree) {
        ti = proto_tree_add_item(tree, proto_llc, tvb, 0, -1, FALSE);
        llc_tree = proto_item_add_subtree(ti, ett_llc);
        proto_tree_add_uint(llc_tree, hf_llc_dsap, tvb, 0,
            1, dsap & SAP_MASK);
        proto_tree_add_boolean(llc_tree, hf_llc_dsap_ig, tvb, 0,
            1, dsap & DSAP_GI_BIT);
    } else
        llc_tree = NULL;

    ssap = tvb_get_guint8(tvb, 1);
    if (tree) {
        proto_tree_add_uint(llc_tree, hf_llc_ssap, tvb, 1,
            1, ssap & SAP_MASK);
        proto_tree_add_boolean(llc_tree, hf_llc_ssap_cr, tvb, 1,
            1, ssap & SSAP_CR_BIT);
    } else
        llc_tree = NULL;


/****added***********/
    cmd = tvb_get_guint8(tvb, 2);
    if (cmd==0x03) call_dissector(asterix_handle, 3, pinfo, tree);    //asterix_handle = find_dissector("asterix");

/****************/


    is_snap = (dsap == SAP_SNAP) && (ssap == SAP_SNAP);
    llc_header_len = 2;    /* DSAP + SSAP */

    /*
     * XXX - the page referred to in the comment above about the
     * Command/Response bit also implies that LLC Type 2 always
     * uses extended operation, so we don't need to determine
     * whether it's basic or extended operation; is that the case?
     */
    control = dissect_xdlc_control(tvb, 2, pinfo, llc_tree,
                hf_llc_ctrl, ett_llc_ctrl,
                &llc_cf_items, &llc_cf_items_ext,
                NULL, NULL, ssap & SSAP_CR_BIT, TRUE, FALSE);
    llc_header_len += XDLC_CONTROL_LEN(control, TRUE);
    if (is_snap)
        llc_header_len += 5;    /* 3 bytes of OUI, 2 bytes of protocol ID */

    if (tree)
        proto_item_set_len(ti, llc_header_len);

    if (is_snap) {
        dissect_snap(tvb, 3, pinfo, tree, llc_tree, control,
            hf_llc_oui, hf_llc_type, hf_llc_pid, 2);
    }
    else {
        if (check_col(pinfo->cinfo, COL_INFO)) {
            col_append_fstr(pinfo->cinfo, COL_INFO,
                "; DSAP %s %s, SSAP %s %s",
                val_to_str(dsap & SAP_MASK, sap_vals, "0x%02x"),
                dsap & DSAP_GI_BIT ?
                  "Group" : "Individual",
                val_to_str(ssap & SAP_MASK, sap_vals, "0x%02x"),
                ssap & SSAP_CR_BIT ?
                  "Response" : "Command"
            );
        }

        if (tvb_length_remaining(tvb, llc_header_len) > 0) {
            next_tvb = tvb_new_subset(tvb, llc_header_len, -1, -1);
            if (XDLC_IS_INFORMATION(control)) {
                /*
                 * Non-SNAP I or UI frame.
                 * Try the regular LLC subdissector table
                 * with the DSAP.
                 */
                if (!dissector_try_port(subdissector_table,
                    dsap, next_tvb, pinfo, tree)) {
                    call_dissector(data_handle, next_tvb,
                        pinfo, tree);
                }
            } else if ((control & (XDLC_U_MODIFIER_MASK|XDLC_U))
                == (XDLC_XID|XDLC_U)) {
                /*
                 * Non-SNAP XID frame.
                 * Test for LLC basic format first
                 */
                format = tvb_get_guint8(next_tvb, 0);
                if (format == 0x81) {
                    dissect_basicxid(next_tvb, pinfo, tree);
                } else {
                /*
                 * Try the XID LLC subdissector table
                 * with the DSAP.
                 */
                    if (!dissector_try_port(
                    xid_subdissector_table, dsap, next_tvb,
                    pinfo, tree)) {
                        call_dissector(data_handle,
                        next_tvb, pinfo, tree);
                    }
                }
            } else {
                call_dissector(data_handle, next_tvb, pinfo,
                    tree);
            }
        }
    }
}


but we encountered a segfault.

Should we forbid our asterix dissector to be called at any time, and only by llc? Maybe there is a concurrency problem.

Thanks
Florian



Discutez sur Messenger où que vous soyez ! Mettez Messenger sur votre mobile !