/* 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"
-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[] = {"",
{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) {
/*
* 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;
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,
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)
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;
proto_tree_add_text(gryphon_tree, NullTVB, offset, i, "padding");
BUMP (offset, data, i);
}
-/* data = dataend;*/
}
}
{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},
{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},
};
{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 -"},
};
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;
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);
}
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);
}
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
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;
{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 -"},
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);
}
}
}
}
+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) {
BUMP (*offset, *data, 4);
}
-DLLEXPORT void
+G_MODULE_EXPORT void
plugin_init(plugin_address_table_t *pat)
{
static hf_register_info hf[] = {
&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);
}