16.9. Simple ASN.1-Based Dissector
Prev | Chapter 16. Creating ASN.1 Dissectors | Next

## 16.9. Simple ASN.1-Based Dissector

The following snippets show the different files that make up a dissector for a “FOO” protocol dissector.

README.txt.

            FOO protocol dissector
            ----------------------

    This trivial dissector is an example for the struggling dissector developer (me included)
    of how to create a dissector for a protocol that is encapsulated in UDP packets
    for a specific port, and the packet data is ASN1 PER encoded.

    The thing that took me a while to figure out was that in order to see my packet
    dissected on the detail pane, I had to:
    1. Tell the compiler which block in the ASN1 definition is a PDU definition by adding
       FOO-MESSAGE under the #.PDU directive in the foo.cnf file
    2. Add a call to dissect_FOO_MESSAGE_PDU() function in the dissect_foo() function in the
       packet-foo-template.c file.

    To build and test it:
    1. in foo directory, run make
    2. run make copy_files
    3. add packet-foo.c and packet-foo.h to epan/dissectors/Makefile.common
    4. run top level make

    CAVEAT: Makefile.nmake was not tested .

    You can take it from here :-)

            --00--

foo.asn.

    -- FOO PROTOCOL
    --

    FOO-PROTOCOL DEFINITIONS AUTOMATIC TAGS ::=
    BEGIN

    -- General definitions

    MessageId       ::= INTEGER (0..65535)
    FlowId          ::= INTEGER (0..65535)

    MessageData     ::= SEQUENCE {
        name        OCTET STRING(SIZE(10)),
        value       OCTET STRING(SIZE(10))
    }

    FOO-MESSAGE ::= SEQUENCE {
        messageId           MessageId,
        flowId              FlowId,
        messageData        MessageData
    }

    END

foo.cnf.

    # foo.cnf
    # FOO conformation file

    # $Id$

    #.MODULE_IMPORT

    #.EXPORTS

    #.PDU
    FOO-MESSAGE

    #.NO_EMIT

    #.TYPE_RENAME

    #.FIELD_RENAME

    #.END

packet-foo-template.h.

    /* packet-foo.h
     * Routines for foo packet dissection
     *
     * Wireshark - Network traffic analyzer
     * By Gerald Combs <gerald@wireshark.org>
     * Copyright 1998 Gerald Combs
     *
     * SPDX-License-Identifier: GPL-2.0-or-later
     */

    #ifndef PACKET_FOO_H
    #define PACKET_FOO_H

    #endif  /* PACKET_FOO_H */

packet-foo-template.c.

    /* packet-foo.c
     * Routines for FOO packet dissection
     *
     * Wireshark - Network traffic analyzer
     * By Gerald Combs <gerald@wireshark.org>
     * Copyright 1998 Gerald Combs
     *
     * SPDX-License-Identifier: GPL-2.0-or-later
     */

    #include "config.h"

    #include <glib.h>
    #include <epan/packet.h>
    #include <epan/conversation.h>

    #include <stdio.h>
    #include <string.h>

    #include "packet-per.h"
    #include "packet-foo.h"

    #define PNAME  "FOO Protocol"
    #define PSNAME "FOO"
    #define PFNAME "foo"
    #define FOO_PORT 5001    /* UDP port */
    static dissector_handle_t foo_handle;

    void proto_reg_handoff_foo(void);
    void proto_register_foo(void);

    /* Initialize the protocol and registered fields */
    static int proto_foo;
    static int global_foo_port = FOO_PORT;

    #include "packet-foo-hf.c"

    /* Initialize the subtree pointers */
    static int ett_foo;

    #include "packet-foo-ett.c"

    #include "packet-foo-fn.c"

    static void
    dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
    {
            proto_item      *foo_item = NULL;
            proto_tree      *foo_tree = NULL;
            int                     offset = 0;

            /* make entry in the Protocol column on summary display */
            if (check_col(pinfo->cinfo, COL_PROTOCOL))
                    col_set_str(pinfo->cinfo, COL_PROTOCOL, PNAME);

        /* create the foo protocol tree */
        if (tree) {
            foo_item = proto_tree_add_item(tree, proto_foo, tvb, 0, -1, ENC_NA);
            foo_tree = proto_item_add_subtree(foo_item, ett_foo);

            dissect_FOO_MESSAGE_PDU(tvb, pinfo, foo_tree);
        }
    }
    /*--- proto_register_foo -------------------------------------------*/
    void proto_register_foo(void) {

      /* List of fields */
      static hf_register_info hf[] = {

    #include "packet-foo-hfarr.c"
      };

      /* List of subtrees */
      static int *ett[] = {
                      &ett_foo,
    #include "packet-foo-ettarr.c"
      };

      /* Register protocol */
      proto_foo = proto_register_protocol(PNAME, PSNAME, PFNAME);
      /* Register fields and subtrees */
      proto_register_field_array(proto_foo, hf, array_length(hf));
      proto_register_subtree_array(ett, array_length(ett));

    }

    /*--- proto_reg_handoff_foo ---------------------------------------*/
    void
    proto_reg_handoff_foo(void)
    {
        static bool inited = false;

        if( !inited ) {

            foo_handle = create_dissector_handle(dissect_foo,
                                                         proto_foo);
            dissector_add("udp.port", global_foo_port, foo_handle);

            inited = true;
        }

    }

CMakeLists.txt.

    set( PROTOCOL_NAME foo )

    set( PROTO_OPT )

    set( EXT_ASN_FILE_LIST
    )

    set( ASN_FILE_LIST
    	Foo.asn
    )

    set( EXTRA_DIST
    	${ASN_FILE_LIST}
    	packet-${PROTOCOL_NAME}-template.c
    	${PROTOCOL_NAME}.cnf
    )

    set( SRC_FILES
    	${EXTRA_DIST}
    	${EXT_ASN_FILE_LIST}
    )

    set( A2W_FLAGS  )

    ASN2WRS()

Prev | Up | Next
16.8. Hints For Using Asn2wrs | Home | 16.10. Conformance (.cnf) Files