Add an additional "protocol index" argument to "{old_}dissector_add()",
[obnox/wireshark/wip.git] / plugins / gryphon / packet-gryphon.c
index 725dc6b7878f00af564aa38996c3d9dc7b25bd6b..0c9fb493ba50edb0020677ffd1b964c112814987 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-gryphon.c
  * Routines for Gryphon protocol packet disassembly
  *
- * $Id: packet-gryphon.c,v 1.9 2000/05/11 08:18:09 gram Exp $
+ * $Id: packet-gryphon.c,v 1.19 2001/01/09 06:32:08 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Steve Limkemann <stevelim@dgtech.com>
 #include <ctype.h>
 #include <time.h>
 
-#include <glib.h>
+#include <gmodule.h>
 #ifdef HAVE_NETINET_IN_H
 # include <netinet/in.h>
 #endif
 #include "packet.h"
-#include "dfilter.h"
 #include "packet-gryphon.h"
 
-DLLEXPORT const gchar version[] = VERSION;
-DLLEXPORT const gchar desc[] = "DG Gryphon Protocol";
-DLLEXPORT const gchar protocol[] = "tcp";
-DLLEXPORT const gchar filter_string[] = "tcp.port == 7000";
+G_MODULE_EXPORT const gchar version[] = VERSION;
 
 #ifndef G_HAVE_GINT64
 #error "Sorry, this won't compile without 64-bit integer support"
@@ -87,12 +83,12 @@ static gint ett_gryphon_pgm_options = -1;
 
 
 
-DLLEXPORT void
-dissector(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+static void
+dissect_gryphon(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
 {
 
-    proto_tree     *gryphon_tree, *header_tree, *body_tree;
-    proto_item     *ti, *header_item, *body_item;
+    proto_tree     *gryphon_tree, *header_tree, *body_tree, *localTree;
+    proto_item     *ti, *header_item, *body_item, *localItem;
     const u_char    *data, *dataend, *msgend;
     int                    src, msglen, msgpad, dest, frmtyp, i, end_of_frame;
     static const u_char *frame_type[] = {"",
@@ -114,7 +110,9 @@ dissector(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
            {SD_FLIGHT,         "Flight Recorder"},
            {SD_RESP,           "Message Responder"},
            {-1,                "- unknown -"},
-           };                                 
+           };                         
+
+    OLD_CHECK_DISPLAY_AS_DATA(proto_gryphon, pd, offset, fd, tree);
 
     data = &pd[offset];
     if (fd) {
@@ -136,12 +134,16 @@ dissector(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
        /*
         * Indicate what kind of message this is.
         */
-       col_add_str (fd, COL_INFO, frame_type[data[6]]);
+       frmtyp = data[6] & ~RESPONSE_FLAGS;
+       if (frmtyp >= SIZEOF (frame_type))
+           col_add_str (fd, COL_INFO, "- Invalid -");
+       else
+           col_add_str (fd, COL_INFO, frame_type[frmtyp]);
     }
     if (tree) {
        if (fd) {
            ti = proto_tree_add_item(tree, proto_gryphon, NullTVB, offset,
-                   end_of_frame, NULL);
+                   end_of_frame, FALSE);
            gryphon_tree = proto_item_add_subtree(ti, ett_gryphon);
        } else
            gryphon_tree = tree;
@@ -149,7 +151,13 @@ dissector(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
        while (data < dataend) {
            src = data[0];
            dest = data[2];
-           frmtyp = data[6];
+           frmtyp = data[6] & ~RESPONSE_FLAGS;
+           if (frmtyp >= SIZEOF (frame_type)) {
+               i = dataend - data;
+               proto_tree_add_text(gryphon_tree, NullTVB, offset, i, "Data");
+               BUMP (offset, data, i);
+               continue;
+           }
            msglen = pntohs ((unsigned short *)&data[4]);
 
            header_item = proto_tree_add_text(gryphon_tree, NullTVB, offset,
@@ -164,8 +172,8 @@ dissector(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
                i = SIZEOF(src_dest) - 1;
            proto_tree_add_text(header_tree, NullTVB, offset, 2,
                    "Source: %s, channel %hd", src_dest[i].strptr, data[1]);
-           proto_tree_add_item_hidden(header_tree, hf_gryph_src, NullTVB, offset, 1, src);
-           proto_tree_add_item_hidden(header_tree, hf_gryph_srcchan, NullTVB, offset+1, 1, data[1]);
+           proto_tree_add_uint_hidden(header_tree, hf_gryph_src, NullTVB, offset, 1, src);
+           proto_tree_add_uint_hidden(header_tree, hf_gryph_srcchan, NullTVB, offset+1, 1, data[1]);
 
            for (i = 0; i < SIZEOF(src_dest); i++) {
                if (src_dest[i].value == dest)
@@ -175,16 +183,34 @@ dissector(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
                i = SIZEOF(src_dest) - 1;
            proto_tree_add_text(header_tree, NullTVB, offset+2, 2,
                    "Destination: %s, channel %hd", src_dest[i].strptr, data[3]);
-           proto_tree_add_item_hidden(header_tree, hf_gryph_dest, NullTVB, offset+2, 1, dest);
-           proto_tree_add_item_hidden(header_tree, hf_gryph_destchan, NullTVB, offset+3, 1, data[3]);
+           proto_tree_add_uint_hidden(header_tree, hf_gryph_dest, NullTVB, offset+2, 1, dest);
+           proto_tree_add_uint_hidden(header_tree, hf_gryph_destchan, NullTVB, offset+3, 1, data[3]);
 
            proto_tree_add_text(header_tree, NullTVB, offset+4, 2,
                    "Data length: %d bytes", msglen);
            proto_tree_add_text(header_tree, NullTVB, offset+6, 1,
                    "Frame type: %s", frame_type[frmtyp]);
+           if (!fd) {
+               localItem = proto_tree_add_text(header_tree, NullTVB, offset+6, 1, "Flags");
+               localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
+               if (data[6] & DONT_WAIT_FOR_RESP) {
+                   proto_tree_add_text(localTree, NullTVB, offset+6, 1,
+                           "1... .... = Don't wait for response");
+               } else {
+                   proto_tree_add_text(localTree, NullTVB, offset+6, 1,
+                           "0... .... = Wait for response");
+               }
+               if (data[6] & WAIT_FOR_PREV_RESP) {
+                   proto_tree_add_text(localTree, NullTVB, offset+6, 1,
+                           ".1.. .... = Wait for previous responses");
+               } else {
+                   proto_tree_add_text(localTree, NullTVB, offset+6, 1,
+                           ".0.. .... = Don't wait for previous responses");
+               }
+           }
            proto_tree_add_text(header_tree, NullTVB, offset+7, 1, "reserved");
 
-           proto_tree_add_item_hidden(header_tree, hf_gryph_type, NullTVB, offset+6, 1, frmtyp);
+           proto_tree_add_uint_hidden(header_tree, hf_gryph_type, NullTVB, offset+6, 1, frmtyp);
            msgpad = 3 - (msglen + 3) % 4;
            msgend = data + msglen + msgpad + MSG_HDR_SZ;
 
@@ -224,7 +250,6 @@ dissector(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
                proto_tree_add_text(gryphon_tree, NullTVB, offset, i, "padding");
                BUMP (offset, data, i);
            }
-/*         data = dataend;*/
        }
 
    }
@@ -258,8 +283,10 @@ static const val_str_dsp cmds[] = {
        {CMD_CARD_SET_FILTER_MODE, "Set filter mode", filtmode, NULL},
        {CMD_CARD_GET_FILTER_MODE, "Get filter mode", NULL, filtmode},
        {CMD_CARD_GET_EVNAMES,  "Get event names", NULL, resp_events},
-       {CMD_CARD_GET_SPEEDS,   "Get defined speeds", NULL, NULL},
+       {CMD_CARD_GET_SPEEDS,   "Get defined speeds", NULL, resp_getspeeds},
        {CMD_SERVER_REG,        "Register with server", cmd_register, resp_register},
+       {CMD_SERVER_SET_SORT,   "Set the sorting behavior", cmd_sort, NULL},
+       {CMD_SERVER_SET_OPT,    "Set the type of optimization", cmd_optimize, NULL},
        {CMD_BLM_SET_MODE,      "Set Bus Load Monitoring mode", blm_mode, NULL},
        {CMD_BLM_GET_MODE,      "Get Bus Load Monitoring mode", NULL, blm_mode},
        {CMD_BLM_GET_DATA,      "Get Bus Load data", NULL, resp_blm_data},
@@ -279,9 +306,11 @@ static const val_str_dsp cmds[] = {
        {CMD_PGM_STOP,          "Stop an uploaded program", resp_start, NULL},
        {CMD_PGM_STATUS,        "Get status of an uploaded program", cmd_delete, resp_status},
        {CMD_PGM_OPTIONS,       "Set program upload options", cmd_options, resp_status},
+       {CMD_PGM_FILES,         "Get a list of files & directories", cmd_files, resp_files},
        {CMD_SCHED_TX,          "Schedule transmission of messages", cmd_sched, resp_sched},
        {CMD_SCHED_KILL_TX,     "Stop and destroy a message transmission", NULL, NULL},
        {CMD_SCHED_STOP_TX,     "Kill a message transmission (deprecated)", NULL, NULL},
+       {CMD_USDT_IOCTL,        "Register/Unregister with USDT server", cmd_usdt, NULL},
        {-1,                    "- unknown -", NULL, NULL},
         };
 
@@ -311,6 +340,8 @@ static const value_string filter_data_types[] = {
        {FILTER_DATA_TYPE_HEADER,       "data message header"},
        {FILTER_DATA_TYPE_DATA,         "data message data"},
        {FILTER_DATA_TYPE_EXTRA_DATA,   "data message extra data"},
+       {FILTER_EVENT_TYPE_HEADER,      "event message header"},
+       {FILTER_EVENT_TYPE_DATA,        "event message"},
        {-1,                            "- unknown -"},
        };
 
@@ -441,12 +472,12 @@ static const value_string ioctls[] = {
 void
 decode_command (int dst, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
 {
-    int            cmd, i;
+    int            cmd, i, padding;
     proto_tree     *ft;
     proto_item     *ti;
 
     cmd = (*data)[0];
-    proto_tree_add_item_hidden(pt, hf_gryph_cmd, NullTVB, *offset, 1, cmd);
+    proto_tree_add_uint_hidden(pt, hf_gryph_cmd, NullTVB, *offset, 1, cmd);
     if (cmd > 0x3F)
        cmd += dst * 256;
 
@@ -467,8 +498,10 @@ decode_command (int dst, const u_char **data, const u_char *dataend, int *offset
     proto_tree_add_text (pt, NullTVB, *offset, 4, "Command: %s", cmds[i].strptr);
     BUMP (*offset, *data, 4);
 
-    if (cmds[i].cmd_fnct && dataend - *data) {
-       ti = proto_tree_add_text(pt, NullTVB, *offset, dataend - *data, "Data: (%d bytes)", dataend - *data);
+/*  if (cmds[i].cmd_fnct && dataend - *data) { */
+    if (cmds[i].cmd_fnct && msglen > 4) {
+       padding = 3 - (msglen + 3) % 4;
+       ti = proto_tree_add_text(pt, NullTVB, *offset, msglen-4, "Data: (%d bytes)", msglen-4);
        ft = proto_item_add_subtree(ti, ett_gryphon_command_data);
        (*(cmds[i].cmd_fnct)) (dst, data, dataend, offset, msglen, ft);
     }
@@ -512,7 +545,7 @@ decode_response (int src, const u_char **data, const u_char *dataend, int *offse
     BUMP (*offset, *data, 4);
 
     if (cmds[i].rsp_fnct) {
-    ti = proto_tree_add_text(pt, NullTVB, *offset, dataend - *data, "Data: (%d bytes)", dataend - *data);
+    ti = proto_tree_add_text(pt, NullTVB, *offset, msglen-8, "Data: (%d bytes)", msglen-8);
     ft = proto_item_add_subtree(ti, ett_gryphon_response_data);
        (*(cmds[i].rsp_fnct)) (src, data, dataend, offset, msglen, ft);
     }
@@ -714,8 +747,10 @@ cmd_ioctl (int src, const u_char **data, const u_char *dataend, int *offset, int
        i = SIZEOF(ioctls) - 1;
     proto_tree_add_text(pt, NullTVB, *offset, 4, "IOCTL: %s", ioctls[i].strptr);
     BUMP (*offset, *data, 4);
-    proto_tree_add_text(pt, NullTVB, *offset, dataend - *data, "Data");
-    BUMP (*offset, *data, dataend - *data);
+    if (msglen > 8) {
+      proto_tree_add_text(pt, NullTVB, *offset, msglen-8, "Data");
+      BUMP (*offset, *data, msglen-8);
+    }
 }
 
 void
@@ -875,6 +910,49 @@ resp_register (int src, const u_char **data, const u_char *dataend, int *offset,
     BUMP (*offset, *data, 4);
 }
 
+
+void
+resp_getspeeds (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
+    int number = (*data)[9];
+    int size = (*data)[8];
+    int index;
+    
+    proto_tree_add_text(pt, NullTVB, *offset, 4, "Set Speed IOCTL");
+    proto_tree_add_text(pt, NullTVB, *offset+4, 4, "Get Speed IOCTL");
+    proto_tree_add_text(pt, NullTVB, *offset+8, 1, "Speed data size is %d bytes", size);
+    proto_tree_add_text(pt, NullTVB, *offset+9, 1, "There are %d preset speeds", number);
+    BUMP (*offset, *data, 10);
+    for (index = 0; index < number; index++) {
+       proto_tree_add_text(pt, NullTVB, *offset, size, "Data for preset %d", index+1);
+       BUMP (*offset, *data, size);
+    }
+}
+
+
+
+void
+cmd_sort (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
+{
+    char       *which;
+    
+    which = (*data)[0] ? "Sort into blocks of up to 16 messages" :
+           "Do not sort messages";
+    proto_tree_add_text(pt, NullTVB, *offset, 1, "Set sorting: %s", which);
+    BUMP (*offset, *data, 1);
+}
+
+void
+
+cmd_optimize (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
+{
+    char       *which;
+    
+    which = (*data)[0] ? "Optimize for latency (Nagle algorithm disabled)" :
+           "Optimize for throughput (Nagle algorithm enabled)";
+    proto_tree_add_text(pt, NullTVB, *offset, 1, "Set optimization: %s", which);
+    BUMP (*offset, *data, 1);
+}
+
 void
 resp_config (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
     proto_item *ti;
@@ -892,7 +970,7 @@ resp_config (int src, const u_char **data, const u_char *dataend, int *offset, i
        {GJ1850 * 256 + GDLC,           "J1850, GM DLC subtype"},
        {GJ1850 * 256 + GCHRYSLER,      "J1850, Chrysler subtype"},
        {GJ1850 * 256 + GDEHC12,        "J1850, DE HC12 KWP/BDLC subtype"},
-       {GKWP2000,                      "Keyword protocol 2000"},
+       {GKWP2000 * 256 + GDEHC12KWP,   "Keyword protocol 2000"},
        {GHONDA * 256 + GDGHC08,        "Honda UART, DG HC08 subtype"},
        {GFORDUBP * 256 + GDGUBP08,     "Ford UBP, DG HC08 subtype"},
        {-1,                            "- unknown -"},
@@ -1148,7 +1226,7 @@ cmd_addresp (int src, const u_char **data, const u_char *dataend, int *offset, i
        length += 3 - (length + 3) % 4;
        item = proto_tree_add_text(pt, NullTVB, *offset, length, "Response block %d", i);
        tree = proto_item_add_subtree (item, ett_gryphon_cmd_response_block);
-       dissector((*data)-*offset, *offset, NULL, tree);
+       dissect_gryphon((*data)-*offset, *offset, NULL, tree);
        BUMP (*offset, *data, length);
     }
 }
@@ -1426,6 +1504,64 @@ cmd_options (int src, const u_char **data, const u_char *dataend, int *offset, i
     }
 }
 
+void
+cmd_files (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
+    u_char  *which, dir[256];
+    int     len;
+    
+    if ((*data)[0] == 0)
+       which = "First group of names";
+    else
+       which = "Subsequent group of names";
+    
+    msglen -= 4;
+    len = msglen > 255 ? 255: msglen;
+    memset (dir, 0, 256);
+    strncpy (dir, (*data)+1, len);
+    proto_tree_add_text(pt, NullTVB, *offset, 1, "%s", which);
+    proto_tree_add_text(pt, NullTVB, *offset+1, msglen-1, "Directory: %s", dir);
+    BUMP (*offset, *data, msglen);
+}
+
+void
+resp_files (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
+    u_char     *flag;
+    
+    msglen -= 8;
+    flag = (*data)[0] ? "Yes": "No";
+    proto_tree_add_text(pt, NullTVB, *offset, 1, "More filenames to return: %s", flag);
+    proto_tree_add_text(pt, NullTVB, *offset+1, msglen-1, "File and directory names");
+    BUMP (*offset, *data, msglen);
+}
+
+void
+cmd_usdt (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
+{
+    u_char  *desc;
+    
+    if ((*data)[0])
+       desc = "Register with gusdt";
+    else
+       desc = "Unregister with gusdt";
+    proto_tree_add_text(pt, NullTVB, *offset, 1, "%s", desc);
+    
+    if ((*data)[1])
+       desc = "Echo long transmit messages back to the client";
+    else
+       desc = "Do not echo long transmit messages back to the client";
+    proto_tree_add_text(pt, NullTVB, (*offset)+1, 1, "%s", desc);
+    
+    if ((*data)[2] == 2)
+       desc = "Assemble long received messages but do not send them to the client";
+    else if ((*data)[2])
+       desc = "Assemble long received messages and send them to the client";
+    else
+       desc = "Do not assemble long received messages on behalf of the client";
+    proto_tree_add_text(pt, NullTVB, (*offset)+2, 1, "%s", desc);
+    
+    BUMP (*offset, *data, 4);
+}
+
 void
 speed (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
     
@@ -1520,7 +1656,7 @@ blm_mode (int src, const u_char **data, const u_char *dataend, int *offset, int
     BUMP (*offset, *data, 4);
 }
 
-DLLEXPORT void
+G_MODULE_EXPORT void
 plugin_init(plugin_address_table_t *pat)
 {
     static hf_register_info hf[] = {
@@ -1564,9 +1700,21 @@ plugin_init(plugin_address_table_t *pat)
        &ett_gryphon_pgm_options,
     };
     plugin_address_table_init(pat);
-    dfilter_cleanup();
-    proto_gryphon = proto_register_protocol("DG Gryphon Protocol", "gryphon");
-    proto_register_field_array(proto_gryphon, hf, array_length(hf));
-    proto_register_subtree_array(ett, array_length(ett));
-    dfilter_init();
+    if (proto_gryphon == -1) {
+       /* first activation */
+       proto_gryphon = proto_register_protocol("DG Gryphon Protocol",
+                                               "Gryphon",
+                                               "gryphon");
+       proto_register_field_array(proto_gryphon, hf, array_length(hf));
+       proto_register_subtree_array(ett, array_length(ett));
+    } else {
+       /* do nothing, this is in fact a re-activation with possibly 
+          a new filter */
+    }
+}
+
+G_MODULE_EXPORT void
+plugin_reg_handoff(void)
+{
+    old_dissector_add("tcp.port", 7000, &dissect_gryphon, proto_gryphon);
 }