Wireshark-dev: [Wireshark-dev] A Wireshark dissector generator for both C and Lua

From: Richard Sharpe <realrichardsharpe@xxxxxxxxx>
Date: Sat, 27 Oct 2018 20:36:13 -0700
Hi folks,

I have updated my dissector generator and it can now generate
dissectors in C and Lua.

I also now include a jar file of all the class files so you do not
have to build the dissector generator, you can simply type:

    java -jar WiresharkGenerator.jar -l some-proto-file

and it will spit out a Lua dissector for your protocol.

You do need to install the Antlr4 runtime, however.

You can find it at: https://gitlab.com/realrichardsharpe/wireshark-generator.git

This is example protocol file was developed for Graham Bloice's little
protocol (but uses Ethernet frames not TCP/IP):

-----------grahams.proto-----------------------
endian = big;  # Default

enum funcs_enum:uint8 {
    20 = CONNECT:        "connect",
    21 = CONNECT_ACK:    "connect_ack",
    40 = REQUEST_DATA:   "request_data",
    41 = REQUEST_REPLY:  "request_reply",
    60 = DISCONNECT:     "disconnect",
    61 = DISCONNECT_ACK: "disconnect_ack",
    default = "Reserved"
};

enum data_enum:uint8 {
    0 = READ_SHORT:  "read short",
    1 = READ_LONG:   "read long",
    2 = READ_STRING: "read string",
    default = "Reserved"
};

struct request_reply_data {
    data_enum "Data id";
    switch ("Data id") {
    case READ_SHORT:
       uint16_le  "Data Short";   # Handles le and be entries explicitly
    case READ_LONG:
       uint32_le  "Data Long";
    case READ_STRING:
       string  "Data String"[15];
    default:
       # REMAINING is a special variable meaning the rest of the tvb
       byte "Unknown request data"[REMAINING];
    };
};

struct header {
    funcs_enum Function;
    uint16 Length;
};

struct grahams_proto_pdu {
    header Header;
    switch (Header/Function) {   # Reach into the struct for this
    case CONNECT:
        uint32 id;
    case CONNECT_ACK:
        uint32 id;
    case DISCONNECT:
        uint32 id;
    case DISCONNECT_ACK:
        uint32 id;
    case REQUEST_DATA:
        data_enum "Data id";
    case REQUEST_REPLY:
        request_reply_data Data;
    default:
        byte "Unknown function data"[REMAINING];
    };

# If there is any rubbish at the end, insert an unknown data entry
    switch (REMAINING) {
    case 0:
        void;
    default:
        byte "Unknown data at end"[REMAINING];
    };
};

protoDetails = { "Graham's Protocol", "grahams_proto", "grahamp" };
dissectorEntry grahams_proto = grahams_proto_pdu;
dissectorTable["ethertype", "0x893C"] = grahams_proto;
---------------------------------------------------

Things I would like to improve:

1. I need to add a way for users to insert things into the Info field.
2. I want to allow switch statements to contain switch statements.
3. I want to also generate code to generate packets conforming to the spec.

The reason for item 2 is that users could then specify things like:

switch (Header/Function) {
case CONNECT:
    switch (Header/Length) {
    case 7:
        void;
    default:
        exception("error", "A CONNECT request length must be 7");
    };
};

And this would allow the user to easily insert protocol verification code.

I will be giving a presentation about this at SharkFest Europe.

-- 
Regards,
Richard Sharpe
(何以解憂?唯有杜康。--曹操)(传说杜康是酒的发明者)