Wireshark-dev: Re: [Wireshark-dev] Single TCP segment having multiple PDUs not working
From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Fri, 28 Sep 2007 14:53:12 -0700

On Sep 27, 2007, at 6:43 PM, Zongjun wrote:

I am using asn1 BER encoding at the sending side.

So does LDAP, and its dissector uses tcp_dissect_pdus().

The LDAP dissector is a bit complicated, as the LDAP packets use SASL and have an extra non-BER header; however, for non-SASL packets, what the LDAP dissector does is:

        /* check if it is a normal BER encoded LDAP packet
         * i.e. first byte is 0x30 followed by a length that is
         * <64k
         * (no ldap PDUs are ever >64kb? )
         */
        if(tvb_get_guint8(tvb, 0)!=0x30){
                goto this_was_not_normal_ldap;
        }

        /* check that length makes sense */
        offset=get_ber_length(tvb, 1, &ldap_len, &ind);

/* dont check ind since indefinite length is never used for ldap (famous last words)*/
        if(ldap_len<2){
                goto this_was_not_normal_ldap;
        }

tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_normal_ldap_pdu_len, dissect_normal_ldap_pdu);

where get_normal_ldap_pdu_len() is

static guint
get_normal_ldap_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
{
        guint32 len;
        gboolean ind;
        int data_offset;

        /* normal ldap is tag+len bytes plus the length
         * offset is where the tag is
         * offset+1 is where length starts
         */
        data_offset=get_ber_length(tvb, offset+1, &len, &ind);
        return len+data_offset-offset;
}

and dissect_normal_ldap_pdu() is

static void
dissect_normal_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
        dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
        return;
}

If your protocol uses ASN.1 in such a way that a message is something that has a standard BER length, that should work for you.