2 * Routines for Gryphon protocol packet disassembly
3 * By Steve Limkemann <stevelim@dgtech.com>
4 * Copyright 1998 Steve Limkemann
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include "plugins/plugin_api.h"
33 #include "moduleinfo.h"
40 #include <epan/packet.h>
41 #include "packet-gryphon.h"
42 #include "packet-tcp.h"
45 #include "plugins/plugin_api_defs.h"
48 G_MODULE_EXPORT const gchar version[] = VERSION;
52 #error "Sorry, this won't compile without 64-bit integer support"
58 * http://www.dgtech.com/gryphon/docs/html/
61 static int proto_gryphon = -1;
63 static int hf_gryph_src = -1;
64 static int hf_gryph_srcchan = -1;
65 static int hf_gryph_dest = -1;
66 static int hf_gryph_destchan= -1;
67 static int hf_gryph_type = -1;
68 static int hf_gryph_cmd = -1;
70 static gint ett_gryphon = -1;
71 static gint ett_gryphon_header = -1;
72 static gint ett_gryphon_body = -1;
73 static gint ett_gryphon_command_data = -1;
74 static gint ett_gryphon_response_data = -1;
75 static gint ett_gryphon_data_header = -1;
76 static gint ett_gryphon_flags = -1;
77 static gint ett_gryphon_data_body = -1;
78 static gint ett_gryphon_cmd_filter_block = -1;
79 static gint ett_gryphon_cmd_events_data = -1;
80 static gint ett_gryphon_cmd_config_device = -1;
81 static gint ett_gryphon_cmd_sched_data = -1;
82 static gint ett_gryphon_cmd_sched_cmd = -1;
83 static gint ett_gryphon_cmd_response_block = -1;
84 static gint ett_gryphon_pgm_list = -1;
85 static gint ett_gryphon_pgm_status = -1;
86 static gint ett_gryphon_pgm_options = -1;
87 static gint ett_gryphon_valid_headers = -1;
88 static gint ett_gryphon_usdt_data = -1;
89 static gint ett_gryphon_digital_data = -1;
91 /* desegmentation of Gryphon */
92 static gboolean gryphon_desegment = TRUE;
94 static void dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo,
95 proto_tree *tree, gboolean is_msgresp_add);
96 static int decode_command(tvbuff_t*, int, int, proto_tree*);
97 static int decode_response(tvbuff_t*, int, int, proto_tree*);
98 static int decode_data(tvbuff_t*, int, proto_tree*);
99 static int decode_event(tvbuff_t*, int, proto_tree*);
100 static int decode_misc(tvbuff_t*, int, proto_tree*);
101 static int cmd_init(tvbuff_t*, int, proto_tree*);
102 static int resp_time(tvbuff_t*, int, proto_tree*);
103 static int cmd_setfilt(tvbuff_t*, int, proto_tree*);
104 static int cmd_ioctl(tvbuff_t*, int, proto_tree*);
105 static int cmd_addfilt(tvbuff_t*, int, proto_tree*);
106 static int resp_addfilt(tvbuff_t*, int, proto_tree*);
107 static int cmd_modfilt(tvbuff_t*, int, proto_tree*);
108 static int resp_filthan(tvbuff_t*, int, proto_tree*);
109 static int dfiltmode(tvbuff_t*, int, proto_tree*);
110 static int filtmode(tvbuff_t*, int, proto_tree*);
111 static int resp_events(tvbuff_t*, int, proto_tree*);
112 static int cmd_register(tvbuff_t*, int, proto_tree*);
113 static int resp_register(tvbuff_t*, int, proto_tree*);
114 static int resp_getspeeds(tvbuff_t*, int, proto_tree*);
115 static int cmd_sort(tvbuff_t*, int, proto_tree*);
116 static int cmd_optimize(tvbuff_t*, int, proto_tree*);
117 static int resp_config(tvbuff_t*, int, proto_tree*);
118 static int cmd_sched(tvbuff_t*, int, proto_tree*);
119 static int cmd_sched_rep(tvbuff_t*, int, proto_tree*);
120 static int resp_blm_data(tvbuff_t*, int, proto_tree*);
121 static int resp_blm_stat(tvbuff_t*, int, proto_tree*);
122 static int cmd_addresp(tvbuff_t*, int, proto_tree*);
123 static int resp_addresp(tvbuff_t*, int, proto_tree*);
124 static int cmd_modresp(tvbuff_t*, int, proto_tree*);
125 static int resp_resphan(tvbuff_t*, int, proto_tree*);
126 static int resp_sched(tvbuff_t*, int, proto_tree*);
127 static int cmd_desc(tvbuff_t*, int, proto_tree*);
128 static int resp_desc(tvbuff_t*, int, proto_tree*);
129 static int cmd_upload(tvbuff_t*, int, proto_tree*);
130 static int cmd_delete(tvbuff_t*, int, proto_tree*);
131 static int cmd_list(tvbuff_t*, int, proto_tree*);
132 static int resp_list(tvbuff_t*, int, proto_tree*);
133 static int cmd_start(tvbuff_t*, int, proto_tree*);
134 static int resp_start(tvbuff_t*, int, proto_tree*);
135 static int resp_status(tvbuff_t*, int, proto_tree*);
136 static int cmd_options(tvbuff_t*, int, proto_tree*);
137 static int cmd_files(tvbuff_t*, int, proto_tree*);
138 static int resp_files(tvbuff_t*, int, proto_tree*);
139 static int eventnum(tvbuff_t*, int, proto_tree*);
140 static int speed(tvbuff_t*, int, proto_tree*);
141 static int filter_block(tvbuff_t*, int, proto_tree*);
142 static int blm_mode(tvbuff_t*, int, proto_tree*);
143 static int cmd_usdt(tvbuff_t*, int, proto_tree*);
144 static int cmd_bits_in(tvbuff_t*, int, proto_tree*);
145 static int cmd_bits_out(tvbuff_t*, int, proto_tree*);
146 static int cmd_init_strat(tvbuff_t*, int, proto_tree*);
148 static char *frame_type[] = {
152 "Network (vehicle) data",
159 * Length of the frame header.
161 #define FRAME_HEADER_LEN 8
164 get_gryphon_pdu_len(tvbuff_t *tvb, int offset)
170 * Get the length of the Gryphon packet, and then get the length as
171 * padded to a 4-byte boundary.
173 plen = tvb_get_ntohs(tvb, offset + 4);
174 padded_len = plen + 3 - (plen + 3) % 4;
177 * That length doesn't include the fixed-length part of the header;
180 return padded_len + FRAME_HEADER_LEN;
184 dissect_gryphon_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
186 dissect_gryphon_message(tvb, pinfo, tree, FALSE);
190 dissect_gryphon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
192 tcp_dissect_pdus(tvb, pinfo, tree, gryphon_desegment, FRAME_HEADER_LEN,
193 get_gryphon_pdu_len, dissect_gryphon_pdu);
196 static const value_string src_dest[] = {
198 {SD_SERVER, "Server"},
199 {SD_CLIENT, "Client"},
200 {SD_SCHED, "Scheduler"},
201 {SD_SCRIPT, "Script Processor"},
202 {SD_PGM, "Program Loader"},
203 {SD_USDT, "USDT Server"},
204 {SD_BLM, "Bus Load Monitoring"},
205 {SD_FLIGHT, "Flight Recorder"},
206 {SD_RESP, "Message Responder"},
207 {SD_IOPWR, "I/O and power"},
208 {SD_UTIL, "Utility/Miscellaneous"},
213 dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
214 gboolean is_msgresp_add)
217 proto_tree *gryphon_tree;
219 proto_tree *header_tree, *body_tree, *localTree;
220 proto_item *header_item, *body_item, *localItem;
221 int start_offset, msgend;
223 unsigned int src, dest, i, frmtyp;
226 if (!is_msgresp_add) {
227 if (check_col(pinfo->cinfo, COL_PROTOCOL))
228 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Gryphon");
229 if (check_col(pinfo->cinfo, COL_INFO))
230 col_clear(pinfo->cinfo, COL_INFO);
233 if (!is_msgresp_add) {
234 ti = proto_tree_add_item(tree, proto_gryphon, tvb, 0, -1, FALSE);
235 gryphon_tree = proto_item_add_subtree(ti, ett_gryphon);
239 src = tvb_get_guint8(tvb, offset + 0);
240 dest = tvb_get_guint8(tvb, offset + 2);
241 msglen = tvb_get_ntohs(tvb, offset + 4);
242 flags = tvb_get_guint8(tvb, offset + 6);
243 frmtyp = flags & ~RESPONSE_FLAGS;
245 if (!is_msgresp_add) {
247 * This tvbuff includes padding to make its length a multiple
248 * of 4 bytes; set it to the actual length.
250 set_actual_length(tvb, msglen + FRAME_HEADER_LEN);
252 if (check_col(pinfo->cinfo, COL_INFO)) {
254 * Indicate what kind of message this is.
256 if (frmtyp >= SIZEOF (frame_type))
257 col_set_str(pinfo->cinfo, COL_INFO, "- Invalid -");
259 col_set_str(pinfo->cinfo, COL_INFO, frame_type[frmtyp]);
266 if (frmtyp >= SIZEOF (frame_type)) {
268 * Unknown message type.
270 proto_tree_add_text(gryphon_tree, tvb, offset, msglen, "Data");
274 header_item = proto_tree_add_text(gryphon_tree, tvb, offset, MSG_HDR_SZ, "Header");
275 header_tree = proto_item_add_subtree(header_item, ett_gryphon_header);
276 proto_tree_add_text(header_tree, tvb, offset, 2,
277 "Source: %s, channel %u",
278 val_to_str(src, src_dest, "Unknown (0x%02x)"),
279 tvb_get_guint8(tvb, offset + 1));
280 proto_tree_add_uint_hidden(header_tree, hf_gryph_src, tvb,
282 proto_tree_add_uint_hidden(header_tree, hf_gryph_srcchan, tvb,
283 offset+1, 1, tvb_get_guint8(tvb, offset + 1));
285 proto_tree_add_text(header_tree, tvb, offset+2, 2,
286 "Destination: %s, channel %u",
287 val_to_str(dest, src_dest, "Unknown (0x%02x)"),
288 tvb_get_guint8(tvb, offset + 3));
289 proto_tree_add_uint_hidden(header_tree, hf_gryph_dest, tvb,
291 proto_tree_add_uint_hidden(header_tree, hf_gryph_destchan, tvb,
292 offset+3, 1, tvb_get_guint8(tvb, offset + 3));
294 proto_tree_add_text(header_tree, tvb, offset+4, 2,
295 "Data length: %u byte%s", msglen, msglen == 1 ? "" : "s");
296 proto_tree_add_text(header_tree, tvb, offset+6, 1,
297 "Frame type: %s", frame_type[frmtyp]);
298 if (is_msgresp_add) {
299 localItem = proto_tree_add_text(header_tree, tvb, offset+6, 1, "Flags");
300 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
301 proto_tree_add_text(localTree, tvb, offset+6, 1, "%s",
302 decode_boolean_bitfield(flags, DONT_WAIT_FOR_RESP, 8,
303 "Don't wait for response",
304 "Wait for response"));
305 proto_tree_add_text(localTree, tvb, offset+6, 1, "%s",
306 decode_boolean_bitfield(flags, WAIT_FOR_PREV_RESP, 8,
307 "Wait for previous responses",
308 "Don't wait for previous responses"));
310 proto_tree_add_text(header_tree, tvb, offset+7, 1, "reserved");
312 proto_tree_add_uint_hidden(header_tree, hf_gryph_type, tvb,
313 offset+6, 1, frmtyp);
314 msgpad = 3 - (msglen + 3) % 4;
315 msgend = offset + msglen + msgpad + MSG_HDR_SZ;
317 body_item = proto_tree_add_text(gryphon_tree, tvb, offset + MSG_HDR_SZ,
318 msglen + msgpad, "Body");
319 body_tree = proto_item_add_subtree(body_item, ett_gryphon_body);
321 start_offset = offset;
322 offset += MSG_HDR_SZ;
325 offset = decode_command(tvb, offset, dest, body_tree);
328 offset = decode_response(tvb, offset, src, body_tree);
331 offset = decode_data(tvb, offset, body_tree);
334 offset = decode_event(tvb, offset, body_tree);
337 offset = decode_misc (tvb, offset, body_tree);
344 if (offset < msgend - msgpad) {
345 i = msgend - msgpad - offset;
346 proto_tree_add_text(gryphon_tree, tvb, offset, i, "Data");
349 if (offset < msgend) {
351 proto_tree_add_text(gryphon_tree, tvb, offset, i, "padding");
357 static const val_str_dsp cmds[] = {
358 {CMD_INIT, "Initialize", cmd_init, NULL},
359 {CMD_GET_STAT, "Get status", NULL, NULL},
360 {CMD_GET_CONFIG, "Get configuration", NULL, resp_config},
361 {CMD_EVENT_ENABLE, "Enable event", eventnum, NULL},
362 {CMD_EVENT_DISABLE, "Disable event", eventnum, NULL},
363 {CMD_GET_TIME, "Get time", NULL, resp_time},
364 {CMD_SET_TIME, "Set time", resp_time, NULL},
365 {CMD_GET_RXDROP, "Get number of dropped RX messages", NULL, NULL},
366 {CMD_RESET_RXDROP, "Clear number of dropped RX messages", NULL, NULL},
367 {CMD_BCAST_ON, "Set broadcasts on", NULL, NULL},
368 {CMD_BCAST_OFF, "Set broadcasts off", NULL, NULL},
369 {CMD_CARD_SET_SPEED, "Set channel baud rate", speed, NULL},
370 {CMD_CARD_GET_SPEED, "Get channel baud rate", NULL, speed},
371 {CMD_CARD_SET_FILTER, "Set filter (deprecated)", cmd_setfilt, NULL},
372 {CMD_CARD_GET_FILTER, "Get filter", resp_addfilt, cmd_addfilt},
373 {CMD_CARD_TX, "Transmit message", decode_data, NULL},
374 {CMD_CARD_TX_LOOP_ON, "Set transmit loopback on", NULL, NULL},
375 {CMD_CARD_TX_LOOP_OFF, "Set transmit loopback off", NULL, NULL},
376 {CMD_CARD_IOCTL, "IOCTL pass-through", cmd_ioctl, NULL},
377 {CMD_CARD_ADD_FILTER, "Add a filter", cmd_addfilt, resp_addfilt},
378 {CMD_CARD_MODIFY_FILTER, "Modify a filter", cmd_modfilt, NULL},
379 {CMD_CARD_GET_FILTER_HANDLES, "Get filter handles", NULL, resp_filthan},
380 {CMD_CARD_SET_DEFAULT_FILTER, "Set default filter", dfiltmode, NULL},
381 {CMD_CARD_GET_DEFAULT_FILTER, "Get default filter mode", NULL, dfiltmode},
382 {CMD_CARD_SET_FILTER_MODE, "Set filter mode", filtmode, NULL},
383 {CMD_CARD_GET_FILTER_MODE, "Get filter mode", NULL, filtmode},
384 {CMD_CARD_GET_EVNAMES, "Get event names", NULL, resp_events},
385 {CMD_CARD_GET_SPEEDS, "Get defined speeds", NULL, resp_getspeeds},
386 {CMD_SERVER_REG, "Register with server", cmd_register, resp_register},
387 {CMD_SERVER_SET_SORT, "Set the sorting behavior", cmd_sort, NULL},
388 {CMD_SERVER_SET_OPT, "Set the type of optimization", cmd_optimize, NULL},
389 {CMD_BLM_SET_MODE, "Set Bus Load Monitoring mode", blm_mode, NULL},
390 {CMD_BLM_GET_MODE, "Get Bus Load Monitoring mode", NULL, blm_mode},
391 {CMD_BLM_GET_DATA, "Get Bus Load data", NULL, resp_blm_data},
392 {CMD_BLM_GET_STATS, "Get Bus Load statistics", NULL, resp_blm_stat},
393 {CMD_FLIGHT_GET_CONFIG, "Get flight recorder channel info", NULL, NULL},
394 {CMD_FLIGHT_START_MON, "Start flight recorder monitoring", NULL, NULL},
395 {CMD_FLIGHT_STOP_MON, "Stop flight recorder monitoring", NULL, NULL},
396 {CMD_MSGRESP_ADD, "Add response message", cmd_addresp, resp_addresp},
397 {CMD_MSGRESP_GET, "Get response message", resp_addresp, cmd_addresp},
398 {CMD_MSGRESP_MODIFY, "Modify response message state", cmd_modresp, NULL},
399 {CMD_MSGRESP_GET_HANDLES, "Get response message handles", NULL, resp_resphan},
400 {CMD_PGM_DESC, "Describe program to to uploaded", cmd_desc, resp_desc},
401 {CMD_PGM_UPLOAD, "Upload a program to the Gryphon", cmd_upload, NULL},
402 {CMD_PGM_DELETE, "Delete an uploaded program", cmd_delete, NULL},
403 {CMD_PGM_LIST, "Get a list of uploaded programs", cmd_list, resp_list},
404 {CMD_PGM_START, "Start an uploaded program", cmd_start, resp_start},
405 {CMD_PGM_START2, "Start an uploaded program", NULL, resp_start},
406 {CMD_PGM_STOP, "Stop an uploaded program", resp_start, NULL},
407 {CMD_PGM_STATUS, "Get status of an uploaded program", cmd_delete, resp_status},
408 {CMD_PGM_OPTIONS, "Set program upload options", cmd_options, resp_status},
409 {CMD_PGM_FILES, "Get a list of files & directories", cmd_files, resp_files},
410 {CMD_SCHED_TX, "Schedule transmission of messages", cmd_sched, resp_sched},
411 {CMD_SCHED_KILL_TX, "Stop and destroy a message transmission", resp_sched, NULL},
412 {CMD_SCHED_STOP_TX, "Kill a message transmission (deprecated)", resp_sched, NULL},
413 {CMD_SCHED_MSG_REPLACE, "Replace a scheduled message", cmd_sched_rep, NULL},
414 {CMD_USDT_IOCTL, "Register/Unregister with USDT server", cmd_usdt, NULL},
415 {CMD_USDT_REGISTER, "Register/Unregister with USDT server", cmd_usdt, NULL},
416 {CMD_USDT_SET_FUNCTIONAL, "Set IDs to use extended addressing", cmd_usdt, NULL},
417 {CMD_IOPWR_GETINP, "Read current digital inputs", NULL, cmd_bits_in},
418 {CMD_IOPWR_GETLATCH, "Read latched digital inputs", NULL, cmd_bits_in},
419 {CMD_IOPWR_CLRLATCH, "Read & clear latched digital inputs", cmd_bits_in, cmd_bits_in},
420 {CMD_IOPWR_GETOUT, "Read digital outputs", NULL, cmd_bits_out},
421 {CMD_IOPWR_SETOUT, "Write digital outputs", cmd_bits_out, NULL},
422 {CMD_IOPWR_SETBIT, "Set indicated output bits", cmd_bits_out, NULL},
423 {CMD_IOPWR_CLRBIT, "Clear indicated output bits", cmd_bits_out, NULL},
424 {CMD_IOPWR_GETPOWER, "Read digital inputs at power on time", NULL, cmd_bits_in},
425 {CMD_UTIL_SET_INIT_STRATEGY, "Set initialization strategy", cmd_init_strat, NULL},
426 {CMD_UTIL_GET_INIT_STRATEGY, "Get initialization strategy", NULL, cmd_init_strat},
427 {-1, "- unknown -", NULL, NULL},
430 static const value_string responses[] = {
431 {RESP_OK, "OK - no error"},
432 {RESP_UNKNOWN_ERR, "Unknown error"},
433 {RESP_UNKNOWN_CMD, "Unrecognised command"},
434 {RESP_UNSUPPORTED, "Unsupported command"},
435 {RESP_INVAL_CHAN, "Invalid channel specified"},
436 {RESP_INVAL_DST, "Invalid destination"},
437 {RESP_INVAL_PARAM, "Invalid parameter(s)"},
438 {RESP_INVAL_MSG, "Invalid message"},
439 {RESP_INVAL_LEN, "Invalid length field"},
440 {RESP_TX_FAIL, "Transmit failed"},
441 {RESP_RX_FAIL, "Receive failed"},
442 {RESP_AUTH_FAIL, "Authorization failed"},
443 {RESP_MEM_ALLOC_ERR, "Memory allocation error"},
444 {RESP_TIMEOUT, "Command timed out"},
445 {RESP_UNAVAILABLE, "Unavailable"},
446 {RESP_BUF_FULL, "Buffer full"},
447 {RESP_NO_SUCH_JOB, "No such job"},
451 static const value_string filter_data_types[] = {
452 {FILTER_DATA_TYPE_HEADER_FRAME, "frame header"},
453 {FILTER_DATA_TYPE_HEADER, "data message header"},
454 {FILTER_DATA_TYPE_DATA, "data message data"},
455 {FILTER_DATA_TYPE_EXTRA_DATA, "data message extra data"},
456 {FILTER_EVENT_TYPE_HEADER, "event message header"},
457 {FILTER_EVENT_TYPE_DATA, "event message"},
461 static const value_string operators[] = {
462 {BIT_FIELD_CHECK, "Bit field check"},
463 {SVALUE_GT, "Greater than (signed)"},
464 {SVALUE_GE, "Greater than or equal to (signed)"},
465 {SVALUE_LT, "Less than (signed)"},
466 {SVALUE_LE, "Less than or equal to (signed)"},
467 {VALUE_EQ, "Equal to"},
468 {VALUE_NE, "Not equal to"},
469 {UVALUE_GT, "Greater than (unsigned)"},
470 {UVALUE_GE, "Greater than or equal to (unsigned)"},
471 {UVALUE_LT, "Less than (unsigned)"},
472 {UVALUE_LE, "Less than or equal to (unsigned)"},
473 {DIG_LOW_TO_HIGH, "Digital, low to high transistion"},
474 {DIG_HIGH_TO_LOW, "Digital, high to low transistion"},
475 {DIG_TRANSITION, "Digital, change of state"},
479 static const value_string modes[] = {
480 {FILTER_OFF_PASS_ALL, "Filter off, pass all messages"},
481 {FILTER_OFF_BLOCK_ALL, "Filter off, block all messages"},
482 {FILTER_ON, "Filter on"},
486 static const value_string dmodes[] = {
487 {DEFAULT_FILTER_BLOCK, "Block"},
488 {DEFAULT_FILTER_PASS, "Pass"},
492 static const value_string filtacts[] = {
493 {DELETE_FILTER, "Delete"},
494 {ACTIVATE_FILTER, "Activate"},
495 {DEACTIVATE_FILTER, "Deactivate"},
499 static const value_string ioctls[] = {
500 {GINIT, "GINIT: Initialize"},
501 {GLOOPON, "GLOOPON: Loop on"},
502 {GLOOPOFF, "GLOOPOFF: Loop off"},
503 {GGETHWTYPE, "GGETHWTYPE: Get hardware type"},
504 {GGETREG, "GGETREG: Get register"},
505 {GSETREG, "GSETREG: Set register"},
506 {GGETRXCOUNT, "GGETRXCOUNT: Get the receive message counter"},
507 {GSETRXCOUNT, "GSETRXCOUNT: Set the receive message counter"},
508 {GGETTXCOUNT, "GGETTXCOUNT: Get the transmit message counter"},
509 {GSETTXCOUNT, "GSETTXCOUNT: Set the transmit message counter"},
510 {GGETRXDROP, "GGETRXDROP: Get the number of dropped receive messages"},
511 {GSETRXDROP, "GSETRXDROP: Set the number of dropped receive messages"},
512 {GGETTXDROP, "GGETTXDROP: Get the number of dropped transmit messages"},
513 {GSETTXDROP, "GSETTXDROP: Set the number of dropped transmit messages"},
514 {GGETRXBAD, "GGETRXBAD: Get the number of bad receive messages"},
515 {GGETTXBAD, "GGETTXBAD: Get the number of bad transmit messages"},
516 {GGETCOUNTS, "GGETCOUNTS: Get total message counter"},
517 {GGETBLMON, "GGETBLMON: Get bus load monitoring status"},
518 {GSETBLMON, "GSETBLMON: Set bus load monitoring status (turn on/off)"},
519 {GGETERRLEV, "GGETERRLEV: Get error level"},
520 {GSETERRLEV, "GSETERRLEV: Set error level"},
521 {GGETBITRATE, "GGETBITRATE: Get bit rate"},
522 {GGETRAM, "GGETRAM: Read value from RAM"},
523 {GSETRAM, "GSETRAM: Write value to RAM"},
524 {GCANGETBTRS, "GCANGETBTRS: Read CAN bit timing registers"},
525 {GCANSETBTRS, "GCANSETBTRS: Write CAN bit timing registers"},
526 {GCANGETBC, "GCANGETBC: Read CAN bus configuration register"},
527 {GCANSETBC, "GCANSETBC: Write CAN bus configuration register"},
528 {GCANGETMODE, "GCANGETMODE"},
529 {GCANSETMODE, "GCANSETMODE"},
530 {GCANGETTRANS, "GCANGETTRANS"},
531 {GCANSETTRANS, "GCANSETTRANS"},
532 {GCANSENDERR, "GCANSENDERR"},
533 {GCANRGETOBJ, "GCANRGETOBJ"},
534 {GCANRSETSTDID, "GCANRSETSTDID"},
535 {GCANRSETEXTID, "GCANRSETEXTID"},
536 {GCANRSETDATA, "GCANRSETDATA"},
537 {GCANRENABLE, "GCANRENABLE"},
538 {GCANRDISABLE, "GCANRDISABLE"},
539 {GCANRGETMASKS, "GCANRGETMASKS"},
540 {GCANRSETMASKS, "GCANRSETMASKS"},
541 {GCANSWGETMODE, "GCANSWGETMODE"},
542 {GCANSWSETMODE, "GCANSWSETMODE"},
543 {GDLCGETFOURX, "GDLCGETFOURX"},
544 {GDLCSETFOURX, "GDLCSETFOURX"},
545 {GDLCGETLOAD, "GDLCGETLOAD"},
546 {GDLCSETLOAD, "GDLCSETLOAD"},
547 {GDLCSENDBREAK, "GDLCSENDBREAK"},
548 {GDLCABORTTX, "GDLCABORTTX"},
549 {GDLCGETHDRMODE, "DLCGETHDRMODE"},
550 {GDLCSETHDRMODE, "GDLCSETHDRMODE"},
551 {GHONSLEEP, "GHONSLEEP"},
552 {GHONSILENCE, "GHONSILENCE"},
553 {GKWPSETPTIMES, "GKWPSETPTIMES"},
554 {GKWPSETWTIMES, "GKWPSETWTIMES"},
555 {GKWPDOWAKEUP, "GKWPDOWAKEUP"},
556 {GKWPGETBITTIME, "GKWPGETBITTIME"},
557 {GKWPSETBITTIME, "GKWPSETBITTIME"},
558 {GKWPSETNODEADDR, "GKWPSETNODEADDR"},
559 {GKWPGETNODETYPE, "GKWPGETNODETYPE"},
560 {GKWPSETNODETYPE, "GKWPSETNODETYPE"},
561 {GKWPSETWAKETYPE, "GKWPSETWAKETYPE"},
562 {GKWPSETTARGADDR, "GKWPSETTARGADDR"},
563 {GKWPSETKEYBYTES, "GKWPSETKEYBYTES"},
564 {GKWPSETSTARTREQ, "GKWPSETSTARTREQ"},
565 {GKWPSETSTARTRESP, "GKWPSETSTARTRESP"},
566 {GKWPSETPROTOCOL, "GKWPSETPROTOCOL"},
567 {GKWPGETLASTKEYBYTES, "GKWPGETLASTKEYBYTES"},
568 {GKWPSETLASTKEYBYTES, "GKWPSETLASTKEYBYTES"},
569 {GSCPGETBBR, "GSCPGETBBR"},
570 {GSCPSETBBR, "GSCPSETBBR"},
571 {GSCPGETID, "GSCPGETID"},
572 {GSCPSETID, "GSCPSETID"},
573 {GSCPADDFUNCID, "GSCPADDFUNCID"},
574 {GSCPCLRFUNCID, "GSCPCLRFUNCID"},
575 {GUBPGETBITRATE, "GUBPGETBITRATE"},
576 {GUBPSETBITRATE, "GUBPSETBITRATE"},
577 {GUBPGETINTERBYTE, "GUBPGETINTERBYTE"},
578 {GUBPSETINTERBYTE, "GUBPSETINTERBYTE"},
579 {GUBPGETNACKMODE, "GUBPGETNACKMODE"},
580 {GUBPSETNACKMODE, "GUBPSETNACKMODE"},
581 {GUBPGETRETRYDELAY, "GUBPGETRETRYDELAY"},
582 {GUBPSETRETRYDELAY, "GUBPSETRETRYDELAY"},
583 {GRESETHC08, "GRESETHC08: Reset the HC08 processor"},
584 {GTESTHC08COP, "GTESTHC08COP: Stop updating the HC08 watchdog timer"},
585 {GSJAGETLISTEN, "GSJAGETLISTEN"},
586 {GSJASETLISTEN, "GSJASETLISTEN"},
587 {GSJAGETSELFTEST, "GSJAGETSELFTEST"},
588 {GSJASETSELFTEST, "GSJASETSELFTEST"},
589 {GSJAGETXMITONCE, "GSJAGETXMITONCE"},
590 {GSJASETXMITONCE, "GSJASETXMITONCE"},
591 {GSJAGETTRIGSTATE, "GSJAGETTRIGSTATE"},
592 {GSJASETTRIGCTRL, "GSJASETTRIGCTRL"},
593 {GSJAGETTRIGCTRL, "GSJAGETTRIGCTRL"},
594 {GSJAGETOUTSTATE, "GSJAGETOUTSTATE"},
595 {GSJASETOUTSTATE, "GSJASETOUTSTATE"},
596 {GSJAGETFILTER, "GSJAGETFILTER"},
597 {GSJASETFILTER, "GSJASETFILTER"},
598 {GSJAGETMASK, "GSJAGETMASK"},
599 {GSJASETMASK, "GSJASETMASK"},
600 {GSJAGETINTTERM, "GSJAGETINTTERM"},
601 {GSJASETINTTERM, "GSJASETINTTERM"},
602 {GSJAGETFTTRANS, "GSJAGETFTTRANS"},
603 {GSJASETFTTRANS, "GSJASETFTTRANS"},
604 {GSJAGETFTERROR, "GSJAGETFTERROR"},
605 {GLINGETBITRATE, "GLINGETBITRATE: Get the current bit rate"},
606 {GLINSETBITRATE, "GLINSETBITRATE: Set the bit rate"},
607 {GLINGETBRKSPACE, "GLINGETBRKSPACE"},
608 {GLINSETBRKSPACE, "GLINSETBRKSPACE"},
609 {GLINGETBRKMARK, "GLINGETBRKMARK"},
610 {GLINSETBRKMARK, "GLINSETBRKMARK"},
611 {GLINGETIDDELAY, "GLINGETIDDELAY"},
612 {GLINSETIDDELAY, "GLINSETIDDELAY"},
613 {GLINGETRESPDELAY, "GLINGETRESPDELAY"},
614 {GLINSETRESPDELAY, "GLINSETRESPDELAY"},
615 {GLINGETINTERBYTE, "GLINGETINTERBYTE"},
616 {GLINSETINTERBYTE, "GLINSETINTERBYTE"},
617 {GLINGETWAKEUPDELAY, "GLINGETWAKEUPDELAY"},
618 {GLINSETWAKEUPDELAY, "GLINSETWAKEUPDELAY"},
619 {GLINGETWAKEUPTIMEOUT, "GLINGETWAKEUPTIMEOUT"},
620 {GLINSETWAKEUPTIMEOUT, "GLINSETWAKEUPTIMEOUT"},
621 {GLINGETWUTIMOUT3BR, "GLINGETWUTIMOUT3BR"},
622 {GLINSETWUTIMOUT3BR, "GLINSETWUTIMOUT3BR"},
623 {GLINSENDWAKEUP, "GLINSENDWAKEUP"},
624 {GLINGETMODE, "GLINGETMODE"},
625 {GLINSETMODE, "GLINSETMODE"},
626 {GINPGETINP, "GINPGETINP: Read current digital inputs"},
627 {GINPGETLATCH, "GINPGETLATCH: Read latched digital inputs"},
628 {GINPCLRLATCH, "GINPCLRLATCH: Read and clear latched digital inputs"},
629 {GOUTGET, "GOUTGET: Read digital outputs"},
630 {GOUTSET, "GOUTSET: Write digital outputs"},
631 {GOUTSETBIT, "GOUTSETBIT: Set digital output bits"},
632 {GOUTCLEARBIT, "GOUTCLEARBIT"},
633 {GPWRGETWHICH, "GPWRGETWHICH"},
634 {GPWROFF, "GPWROFF"},
635 {GPWROFFRESET, "GPWROFFRESET"},
636 {GPWRRESET, "GPWRRESET"},
645 decode_command(tvbuff_t *tvb, int offset, int dst, proto_tree *pt)
647 int cmd, padding, msglen;
652 msglen = tvb_reported_length_remaining(tvb, offset);
653 cmd = tvb_get_guint8(tvb, offset);
654 proto_tree_add_uint_hidden(pt, hf_gryph_cmd, tvb, offset, 1, cmd);
658 for (i = 0; i < SIZEOF(cmds); i++) {
659 if (cmds[i].value == cmd)
662 if (i >= SIZEOF(cmds) && dst >= SD_KNOWN) {
663 cmd = (cmd & 0xFF) + SD_CARD * 256;
664 for (i = 0; i < SIZEOF(cmds); i++) {
665 if (cmds[i].value == cmd)
669 if (i >= SIZEOF(cmds))
670 i = SIZEOF(cmds) - 1;
672 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
676 if (cmds[i].cmd_fnct && msglen > 0) {
677 padding = 3 - (msglen + 3) % 4;
678 ti = proto_tree_add_text(pt, tvb, offset, -1, "Data: (%d byte%s)",
679 msglen, msglen == 1 ? "" : "s");
680 ft = proto_item_add_subtree(ti, ett_gryphon_command_data);
681 offset = (*(cmds[i].cmd_fnct)) (tvb, offset, ft);
687 decode_response(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
690 unsigned int i, resp;
694 msglen = tvb_reported_length_remaining(tvb, offset);
695 cmd = tvb_get_guint8(tvb, offset);
699 for (i = 0; i < SIZEOF(cmds); i++) {
700 if (cmds[i].value == cmd)
703 if (i >= SIZEOF(cmds) && src >= SD_KNOWN) {
704 cmd = (cmd & 0xFF) + SD_CARD * 256;
705 for (i = 0; i < SIZEOF(cmds); i++) {
706 if (cmds[i].value == cmd)
710 if (i >= SIZEOF(cmds))
711 i = SIZEOF(cmds) - 1;
712 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
716 resp = tvb_get_ntohl (tvb, offset);
717 proto_tree_add_text (pt, tvb, offset, 4, "Status: %s",
718 val_to_str(resp, responses, "Unknown (0x%08x)"));
722 if (cmds[i].rsp_fnct && msglen > 0) {
723 ti = proto_tree_add_text(pt, tvb, offset, msglen, "Data: (%d byte%s)",
724 msglen, msglen == 1 ? "" : "s");
725 ft = proto_item_add_subtree(ti, ett_gryphon_response_data);
726 offset = (*(cmds[i].rsp_fnct)) (tvb, offset, ft);
732 decode_data(tvbuff_t *tvb, int offset, proto_tree *pt)
734 proto_item *item, *item1;
735 proto_tree *tree, *tree1;
736 int hdrsize, datasize, extrasize, hdrbits, msgsize, padding, mode;
737 int hours, minutes, seconds, fraction;
738 unsigned long timestamp;
740 hdrsize = tvb_get_guint8(tvb, offset+0);
741 hdrbits = tvb_get_guint8(tvb, offset+1);
742 datasize = tvb_get_ntohs(tvb, offset+2);
743 extrasize = tvb_get_guint8(tvb, offset+4);
744 padding = 3 - (hdrsize + datasize + extrasize + 3) % 4;
745 msgsize = hdrsize + datasize + extrasize + padding + 16;
747 item = proto_tree_add_text(pt, tvb, offset, 16, "Message header");
748 tree = proto_item_add_subtree (item, ett_gryphon_data_header);
749 proto_tree_add_text(tree, tvb, offset, 2, "Header length: %d byte%s, %d bits",
750 hdrsize, plurality(hdrsize, "", "s"), hdrbits);
751 proto_tree_add_text(tree, tvb, offset+2, 2, "Data length: %d byte%s",
752 datasize, plurality(datasize, "", "s"));
753 proto_tree_add_text(tree, tvb, offset+4, 1, "Extra data length: %d byte%s",
754 extrasize, plurality(extrasize, "", "s"));
755 mode = tvb_get_guint8(tvb, offset+5);
756 item1 = proto_tree_add_text(tree, tvb, offset+5, 1, "Mode: %d", mode);
758 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
760 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
761 decode_boolean_bitfield(mode, 0x80, 8,
762 "Transmitted message", NULL));
765 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
766 decode_boolean_bitfield(mode, 0x40, 8,
767 "Received message", NULL));
770 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
771 decode_boolean_bitfield(mode, 0x20, 8,
772 "Local message", NULL));
775 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
776 decode_boolean_bitfield(mode, 0x10, 8,
777 "Remote message", NULL));
780 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
781 decode_boolean_bitfield(mode, 0x01, 8,
782 "Internal message", NULL));
785 proto_tree_add_text(tree, tvb, offset+6, 1, "Priority: %u",
786 tvb_get_guint8(tvb, offset+6));
787 proto_tree_add_text(tree, tvb, offset+7, 1, "Error status: %u",
788 tvb_get_guint8(tvb, offset+7));
789 timestamp = tvb_get_ntohl(tvb, offset+8);
790 hours = timestamp /(100000 * 60 *60);
791 minutes = (timestamp / (100000 * 60)) % 60;
792 seconds = (timestamp / 100000) % 60;
793 fraction = timestamp % 100000;
794 proto_tree_add_text(tree, tvb, offset+8, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
795 proto_tree_add_text(tree, tvb, offset+12, 1, "Context: %u",
796 tvb_get_guint8(tvb, offset+12));
797 proto_tree_add_text(tree, tvb, offset+13, 3, "reserved:");
799 item = proto_tree_add_text(pt, tvb, offset, msgsize-16-padding, "Message Body");
800 tree = proto_item_add_subtree (item, ett_gryphon_data_body);
802 proto_tree_add_text(tree, tvb, offset, hdrsize, "Header");
806 proto_tree_add_text(tree, tvb, offset, datasize, "Data");
810 proto_tree_add_text(tree, tvb, offset, extrasize, "Extra data");
814 proto_tree_add_text(pt, tvb, offset, padding, "padding");
821 decode_event(tvbuff_t *tvb, int offset, proto_tree *pt)
824 int hours, minutes, seconds, fraction, padding, length;
825 unsigned long timestamp;
828 msglen = tvb_reported_length_remaining(tvb, offset);
829 padding = 3 - (msglen + 3) % 4;
830 msgend = offset + msglen;
831 proto_tree_add_text(pt, tvb, offset, 1, "Event ID: %u",
832 tvb_get_guint8(tvb, offset));
833 proto_tree_add_text(pt, tvb, offset+1, 1, "Event context: %u",
834 tvb_get_guint8(tvb, offset+1));
835 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
837 timestamp = tvb_get_ntohl(tvb, offset);
838 hours = timestamp /(100000 * 60 *60);
839 minutes = (timestamp / (100000 * 60)) % 60;
840 seconds = (timestamp / 100000) % 60;
841 fraction = timestamp % 100000;
842 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
844 if (offset < msgend) {
845 length = msgend - offset;
846 proto_tree_add_text (pt, tvb, offset, length, "Data (%d byte%s)",
847 length, length == 1 ? "" : "s");
851 proto_tree_add_text(pt, tvb, offset, padding, "padding");
858 decode_misc (tvbuff_t *tvb, int offset, proto_tree *pt)
863 unsigned char local_data[LENGTH+1];
865 msglen = tvb_reported_length_remaining(tvb, offset);
866 padding = 3 - (msglen + 3) % 4;
867 length = tvb_get_nstringz0(tvb, offset, LENGTH, local_data);
868 proto_tree_add_text(pt, tvb, offset, msglen, "Data: %s", local_data);
871 proto_tree_add_text (pt, tvb, offset, padding, "padding");
878 cmd_init(tvbuff_t *tvb, int offset, proto_tree *pt)
882 if (tvb_get_guint8(tvb, offset) == 0)
883 ptr = "Always initialize";
885 ptr = "Initialize if not previously initialized";
886 proto_tree_add_text(pt, tvb, offset, 1, "Mode: %s", ptr);
887 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
893 eventnum(tvbuff_t *tvb, int offset, proto_tree *pt)
895 guint8 event = tvb_get_guint8(tvb, offset);
898 proto_tree_add_text(pt, tvb, offset, 1, "Event number: %u", event);
900 proto_tree_add_text(pt, tvb, offset, 1, "Event numbers: All");
901 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
907 resp_time(tvbuff_t *tvb, int offset, proto_tree *pt)
909 int hours, minutes, seconds, fraction;
917 /* XXX This code is neither Endianess independent, nor will it work
918 * on platforms that do not support the *optional* guin64 type
920 ts.lng[1] = tvb_get_ntohl(tvb, offset);
921 ts.lng[0] = tvb_get_ntohl(tvb, offset + 4);
922 timestamp = (time_t) (ts.lnglng / 100000L);
923 strncpy (date, ctime(×tamp), sizeof(date));
924 date[strlen(date)-1] = 0x00;
925 proto_tree_add_text(pt, tvb, offset, 8, "Date/Time: %s", date);
926 timestamp = ts.lng[0];
927 hours = timestamp /(100000 * 60 *60);
928 minutes = (timestamp / (100000 * 60)) % 60;
929 seconds = (timestamp / 100000) % 60;
930 fraction = timestamp % 100000;
931 proto_tree_add_text(pt, tvb, offset+4, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
937 cmd_setfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
939 int flag = tvb_get_ntohl(tvb, offset);
943 length = tvb_get_guint8(tvb, offset+4) + tvb_get_guint8(tvb, offset+5)
944 + tvb_get_ntohs(tvb, offset+6);
946 strcpy (mode, "Pass");
948 strcpy (mode, "Block");
950 strcat (mode, " all");
951 proto_tree_add_text(pt, tvb, offset, 4, "Pass/Block flag: %s", mode);
952 proto_tree_add_text(pt, tvb, offset+4, 4, "Length of Pattern & Mask: %d", length);
955 proto_tree_add_text(pt, tvb, offset, length * 2, "discarded data");
956 offset += length * 2;
958 padding = 3 - (length * 2 + 3) % 4;
960 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
967 cmd_ioctl(tvbuff_t *tvb, int offset, proto_tree *pt)
972 msglen = tvb_reported_length_remaining(tvb, offset);
973 ioctl = tvb_get_ntohl(tvb, offset);
974 proto_tree_add_text(pt, tvb, offset, 4, "IOCTL: %s",
975 val_to_str(ioctl, ioctls, "Unknown (0x%08x)"));
979 proto_tree_add_text(pt, tvb, offset, msglen, "Data");
986 cmd_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
991 int blocks, i, length;
993 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags");
994 tree = proto_item_add_subtree (item, ett_gryphon_flags);
995 flags = tvb_get_guint8(tvb, offset);
996 proto_tree_add_text(tree, tvb, offset, 1, "%s",
997 decode_boolean_bitfield(flags, FILTER_PASS_FLAG, 8,
998 "Conforming messages are passed",
999 "Conforming messages are blocked"));
1000 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1001 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1002 "The filter is active", "The filter is inactive"));
1004 blocks = tvb_get_guint8(tvb, offset);
1005 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1006 proto_tree_add_text(pt, tvb, offset+1, 6, "reserved");
1008 for (i = 1; i <= blocks; i++) {
1009 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1010 length += 3 - (length + 3) % 4;
1011 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1012 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1013 offset = filter_block(tvb, offset, tree);
1019 resp_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
1021 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
1022 tvb_get_guint8(tvb, offset));
1023 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1029 cmd_modfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
1031 guint8 filter_handle;
1032 unsigned char action;
1034 filter_handle = tvb_get_guint8(tvb, offset);
1036 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
1039 proto_tree_add_text(pt, tvb, offset, 1, "Filter handles: all");
1040 action = tvb_get_guint8(tvb, offset + 1);
1041 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s filter",
1042 val_to_str(action, filtacts, "Unknown (%u)"));
1043 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1049 resp_filthan(tvbuff_t *tvb, int offset, proto_tree *pt)
1051 int handles = tvb_get_guint8(tvb, offset);
1054 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter handles: %d", handles);
1055 for (i = 1; i <= handles; i++){
1056 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1057 tvb_get_guint8(tvb, offset+i));
1059 padding = 3 - (handles + 1 + 3) % 4;
1061 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1062 offset += 1+handles+padding;
1067 dfiltmode(tvbuff_t *tvb, int offset, proto_tree *pt)
1071 mode = tvb_get_guint8(tvb, offset);
1072 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
1073 val_to_str(mode, dmodes, "Unknown (%u)"));
1074 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1080 filtmode(tvbuff_t *tvb, int offset, proto_tree *pt)
1084 mode = tvb_get_guint8(tvb, offset);
1085 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
1086 val_to_str(mode, modes, "Unknown (%u)"));
1087 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1093 resp_events(tvbuff_t *tvb, int offset, proto_tree *pt)
1100 msglen = tvb_reported_length_remaining(tvb, offset);
1102 while (msglen != 0) {
1103 item = proto_tree_add_text(pt, tvb, offset, 20, "Event %d:", i);
1104 tree = proto_item_add_subtree (item, ett_gryphon_cmd_events_data);
1105 proto_tree_add_text(tree, tvb, offset, 1, "Event ID: %u",
1106 tvb_get_guint8(tvb, offset));
1107 proto_tree_add_text(tree, tvb, offset+1, 19, "Event name: %.19s",
1108 tvb_get_ptr(tvb, offset+1, 19));
1117 cmd_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1119 proto_tree_add_text(pt, tvb, offset, 16, "Username: %.16s",
1120 tvb_get_ptr(tvb, offset, 16));
1122 proto_tree_add_text(pt, tvb, offset, 32, "Password: %.32s",
1123 tvb_get_ptr(tvb, offset, 32));
1129 resp_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1131 proto_tree_add_text(pt, tvb, offset, 1, "Client ID: %u",
1132 tvb_get_guint8(tvb, offset));
1133 proto_tree_add_text(pt, tvb, offset+1, 1, "Privileges: %u",
1134 tvb_get_guint8(tvb, offset+1));
1135 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1142 resp_getspeeds(tvbuff_t *tvb, int offset, proto_tree *pt)
1148 proto_tree_add_text(pt, tvb, offset, 4, "Set Speed IOCTL");
1149 proto_tree_add_text(pt, tvb, offset+4, 4, "Get Speed IOCTL");
1150 size = tvb_get_guint8(tvb, offset+8);
1151 proto_tree_add_text(pt, tvb, offset+8, 1, "Speed data size is %d byte%s",
1152 size, size == 1 ? "" : "s");
1153 number = tvb_get_guint8(tvb, offset+9);
1154 proto_tree_add_text(pt, tvb, offset+9, 1, "There %s %d preset speed%s",
1155 number == 1 ? "is" : "are", number, number == 1 ? "" : "s");
1157 for (index = 0; index < number; index++) {
1158 proto_tree_add_text(pt, tvb, offset, size, "Data for preset %d",
1166 cmd_sort(tvbuff_t *tvb, int offset, proto_tree *pt)
1170 which = tvb_get_guint8(tvb, offset) ?
1171 "Sort into blocks of up to 16 messages" :
1172 "Do not sort messages";
1173 proto_tree_add_text(pt, tvb, offset, 1, "Set sorting: %s", which);
1179 cmd_optimize(tvbuff_t *tvb, int offset, proto_tree *pt)
1183 which = tvb_get_guint8(tvb, offset) ?
1184 "Optimize for latency (Nagle algorithm disabled)" :
1185 "Optimize for throughput (Nagle algorithm enabled)";
1186 proto_tree_add_text(pt, tvb, offset, 1, "Set optimization: %s", which);
1192 resp_config(tvbuff_t *tvb, int offset, proto_tree *pt)
1194 proto_item *ti, *item;
1195 proto_tree *ft, *tree;
1200 static const value_string protocol_types[] = {
1201 {GDUMMY * 256 + GDGDMARKONE, "Dummy device driver"},
1202 {GCAN * 256 + G82527, "CAN, 82527 subtype"},
1203 {GCAN * 256 + GSJA1000, "CAN, SJA1000 subtype"},
1204 {GCAN * 256 + G82527SW, "CAN, 82527 single wire subtype"},
1205 {GCAN * 256 + G82527ISO11992, "CAN, 82527 ISO11992 subtype"},
1206 {GCAN * 256 + G82527_SINGLECHAN, "CAN, Fiber Optic 82527 subtype"},
1207 {GCAN * 256 + G82527SW_SINGLECHAN, "CAN, Fiber Optic 82527 single wire subtype"},
1208 {GCAN * 256 + G82527ISO11992_SINGLECHAN, "CAN, Fiber Optic ISO11992 subtype"},
1209 {GCAN * 256 + GSJA1000FT, "CAN, SJA1000 Fault Tolerant subtype"},
1210 {GCAN * 256 + GSJA1000C, "CAN, SJA1000 onboard subtype"},
1211 {GCAN * 256 + GSJA1000FT_FO, "CAN, SJA1000 Fiber Optic Fault Tolerant subtype"},
1212 {GJ1850 * 256 + GHBCCPAIR, "J1850, HBCC subtype"},
1213 {GJ1850 * 256 + GDLC, "J1850, GM DLC subtype"},
1214 {GJ1850 * 256 + GCHRYSLER, "J1850, Chrysler subtype"},
1215 {GJ1850 * 256 + GDEHC12, "J1850, DE HC12 KWP/BDLC subtype"},
1216 {GKWP2000 * 256 + GDEHC12KWP, "Keyword protocol 2000/ISO 9141"},
1217 {GHONDA * 256 + GDGHC08, "Honda UART, DG HC08 subtype"},
1218 {GFORDUBP * 256 + GDGUBP08, "Ford UBP, DG HC08 subtype"},
1219 {GSCI * 256 + G16550SCI, "Chrysler SCI, UART subtype"},
1220 {GCCD * 256 + G16550CDP68HC68, "Chrysler C2D, UART / CDP68HC68S1 subtype"},
1221 {GLIN * 256 + GDGLIN08, "LIN, DG HC08 subtype"},
1225 proto_tree_add_text(pt, tvb, offset, 20, "Device name: %.20s",
1226 tvb_get_ptr(tvb, offset, 20));
1229 proto_tree_add_text(pt, tvb, offset, 8, "Device version: %.8s",
1230 tvb_get_ptr(tvb, offset, 8));
1233 proto_tree_add_text(pt, tvb, offset, 20, "Device serial number: %.20s",
1234 tvb_get_ptr(tvb, offset, 20));
1237 devices = tvb_get_guint8(tvb, offset);
1238 proto_tree_add_text(pt, tvb, offset, 1, "Number of channels: %d", devices);
1239 proto_tree_add_text(pt, tvb, offset+1, 11, "Name & version extension: %.11s",
1240 tvb_get_ptr(tvb, offset+1, 11));
1241 proto_tree_add_text(pt, tvb, offset+12, 4, "reserved");
1243 for (i = 1; i <= devices; i++) {
1244 ti = proto_tree_add_text(pt, tvb, offset, 80, "Channel %d:", i);
1245 ft = proto_item_add_subtree(ti, ett_gryphon_cmd_config_device);
1246 proto_tree_add_text(ft, tvb, offset, 20, "Driver name: %.20s",
1247 tvb_get_ptr(tvb, offset, 20));
1250 proto_tree_add_text(ft, tvb, offset, 8, "Driver version: %.8s",
1251 tvb_get_ptr(tvb, offset, 8));
1254 proto_tree_add_text(ft, tvb, offset, 16, "Device security string: %.16s",
1255 tvb_get_ptr(tvb, offset, 16));
1258 x = tvb_get_ntohl (tvb, offset);
1260 item = proto_tree_add_text(ft, tvb, offset, 4, "Valid Header lengths");
1261 tree = proto_item_add_subtree (item, ett_gryphon_valid_headers);
1262 for (j = 0; ; j++) {
1264 proto_tree_add_text(tree, tvb, offset, 4, "%d byte%s", j,
1273 x = tvb_get_ntohs (tvb, offset);
1274 proto_tree_add_text(ft, tvb, offset, 2, "Maximum data length = %d byte%s",
1275 x, x == 1 ? "" : "s");
1278 x = tvb_get_ntohs (tvb, offset);
1279 proto_tree_add_text(ft, tvb, offset, 2, "Minimum data length = %d byte%s",
1280 x, x == 1 ? "" : "s");
1283 proto_tree_add_text(ft, tvb, offset, 20, "Hardware serial number: %.20s",
1284 tvb_get_ptr(tvb, offset, 20));
1287 x = tvb_get_ntohs(tvb, offset);
1288 proto_tree_add_text(ft, tvb, offset, 2, "Protocol type & subtype: %s",
1289 val_to_str(x, protocol_types, "Unknown (0x%04x)"));
1292 proto_tree_add_text(ft, tvb, offset, 1, "Channel ID: %u",
1293 tvb_get_guint8(tvb, offset));
1296 proto_tree_add_text(ft, tvb, offset, 1, "Card slot number: %u",
1297 tvb_get_guint8(tvb, offset));
1300 x = tvb_get_ntohs (tvb, offset);
1301 proto_tree_add_text(ft, tvb, offset, 2, "Maximum extra data = %d byte%s",
1302 x, x == 1 ? "" : "s");
1305 x = tvb_get_ntohs (tvb, offset);
1306 proto_tree_add_text(ft, tvb, offset, 2, "Minimum extra data = %d byte%s",
1307 x, x == 1 ? "" : "s");
1315 cmd_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1318 proto_item *item, *item1;
1319 proto_tree *tree, *tree1;
1321 unsigned int i, x, length;
1322 unsigned char def_chan = tvb_get_guint8(tvb, offset-9);
1324 msglen = tvb_reported_length_remaining(tvb, offset);
1325 x = tvb_get_ntohl(tvb, offset);
1326 if (x == 0xFFFFFFFF)
1327 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: \"infinite\"");
1329 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: %u", x);
1332 x = tvb_get_ntohl(tvb, offset);
1333 item = proto_tree_add_text(pt, tvb, offset, 4, "Flags: 0x%08x", x);
1334 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1335 proto_tree_add_text(tree, tvb, offset, 4, "%s",
1336 decode_boolean_bitfield(x, 0x01, 32,
1337 "Critical scheduler", "Normal scheduler"));
1341 while (msglen > 0) {
1342 length = 16 + tvb_get_guint8(tvb, offset+16) +
1343 tvb_get_ntohs(tvb, offset+18) + tvb_get_guint8(tvb, offset+20) + 16;
1344 length += 3 - (length + 3) % 4;
1345 item = proto_tree_add_text(pt, tvb, offset, length, "Message %d", i);
1346 tree = proto_item_add_subtree (item, ett_gryphon_cmd_sched_data);
1347 x = tvb_get_ntohl(tvb, offset);
1348 proto_tree_add_text(tree, tvb, offset, 4, "Sleep: %u milliseconds", x);
1351 x = tvb_get_ntohl(tvb, offset);
1352 proto_tree_add_text(tree, tvb, offset, 4, "Transmit count: %u", x);
1355 x = tvb_get_ntohl(tvb, offset);
1356 proto_tree_add_text(tree, tvb, offset, 4, "Transmit period: %u milliseconds", x);
1359 x = tvb_get_ntohs(tvb, offset);
1360 item1 = proto_tree_add_text(tree, tvb, offset, 2, "Flags");
1361 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
1362 proto_tree_add_text(tree1, tvb, offset, 2, "%s%s",
1363 decode_boolean_bitfield(x, 1, 16, "S", "Do not s"),
1364 "kip the last \"Transmit period\"");
1366 proto_tree_add_text(tree1, tvb, offset, 2, "%s%s",
1367 decode_boolean_bitfield(x, 2, 16, "S", "Do not s"),
1368 "kip the first \"Sleep\" value");
1370 x = tvb_get_guint8(tvb, offset+2);
1373 proto_tree_add_text(tree, tvb, offset+2, 1, "Channel: %u", x);
1374 proto_tree_add_text(tree, tvb, offset+3, 1, "reserved");
1377 item1 = proto_tree_add_text(tree, tvb, offset, length, "Message");
1378 tree1 = proto_item_add_subtree (item1, ett_gryphon_cmd_sched_cmd);
1379 save_offset = offset;
1380 offset = decode_data(tvb, offset, tree1);
1381 msglen -= offset - save_offset;
1388 cmd_sched_rep(tvbuff_t *tvb, int offset, proto_tree *pt)
1396 msglen = tvb_reported_length_remaining(tvb, offset);
1397 x = tvb_get_ntohl(tvb, offset);
1402 proto_tree_add_text(pt, tvb, offset, 4, "%s schedule ID: %u", type, x);
1405 x= tvb_get_guint8(tvb, offset);
1406 item = proto_tree_add_text(pt, tvb, offset, 1, "Message index: %d", x);
1407 item = proto_tree_add_text(pt, tvb, offset + 1, 3, "reserved");
1410 save_offset = offset;
1411 offset = decode_data(tvb, offset, pt);
1412 msglen -= offset - save_offset;
1417 resp_blm_data(tvbuff_t *tvb, int offset, proto_tree *pt)
1420 int hours, minutes, seconds, fraction, x, fract;
1421 unsigned long timestamp;
1422 static char *fields[] = {
1423 "Bus load average: %d.%02d%%",
1424 "Current bus load: %d.%02d%%",
1425 "Peak bus load: %d.%02d%%",
1426 "Historic peak bus load: %d.%02d%%"
1429 timestamp = tvb_get_ntohl(tvb, offset);
1430 hours = timestamp /(100000 * 60 *60);
1431 minutes = (timestamp / (100000 * 60)) % 60;
1432 seconds = (timestamp / 100000) % 60;
1433 fraction = timestamp % 100000;
1434 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
1436 for (i = 0; i < SIZEOF(fields); i++){
1437 x = tvb_get_ntohs(tvb, offset);
1440 proto_tree_add_text(pt, tvb, offset, 2, fields[i], x, fract);
1447 resp_blm_stat(tvbuff_t *tvb, int offset, proto_tree *pt)
1451 "Receive frame count: %u",
1452 "Transmit frame count: %u",
1453 "Receive dropped frame count: %u",
1454 "Transmit dropped frame count: %u",
1455 "Receive error count: %u",
1456 "Transmit error count: %u",
1459 offset = resp_blm_data(tvb, offset, pt);
1460 for (i = 0; i < SIZEOF(fields); i++){
1461 x = tvb_get_ntohl(tvb, offset);
1462 proto_tree_add_text(pt, tvb, offset, 4, fields[i], x);
1468 static const value_string action_vals[] = {
1469 { FR_RESP_AFTER_EVENT, "Send response(s) for each conforming message" },
1470 { FR_RESP_AFTER_PERIOD, "Send response(s) after the specified period expires following a conforming message" },
1471 { FR_IGNORE_DURING_PER, "Send response(s) for a conforming message and ignore\nfurther messages until the specified period expires" },
1475 static const value_string deact_on_event_vals[] = {
1476 { FR_DEACT_ON_EVENT,
1477 "Deactivate this response for a conforming message" },
1478 { FR_DELETE|FR_DEACT_ON_EVENT,
1479 "Delete this response for a conforming message" },
1484 static const value_string deact_after_per_vals[] = {
1485 { FR_DEACT_AFTER_PER,
1486 "Deactivate this response after the specified period following a conforming message" },
1487 { FR_DELETE|FR_DEACT_AFTER_PER,
1488 "Delete this response after the specified period following a conforming message" },
1494 cmd_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1499 int blocks, responses, old_handle, i, msglen, length;
1500 int action, actionType, actionValue;
1504 flags = tvb_get_guint8(tvb, offset);
1505 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1506 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1507 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1508 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1509 "The response is active", "The response is inactive"));
1511 blocks = tvb_get_guint8(tvb, offset);
1512 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1514 responses = tvb_get_guint8(tvb, offset);
1515 proto_tree_add_text(pt, tvb, offset, 1, "Number of response blocks = %d", responses);
1517 old_handle = tvb_get_guint8(tvb, offset);
1518 proto_tree_add_text(pt, tvb, offset, 1, "Old handle = %d", old_handle);
1520 action = tvb_get_guint8(tvb, offset);
1521 item = proto_tree_add_text(pt, tvb, offset, 1, "Action: %s",
1522 val_to_str(action & 0x07, action_vals, "Unknown (%u)"));
1523 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1524 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1525 decode_enumerated_bitfield(action, 0x07, 8, action_vals, "%s"));
1526 actionValue = tvb_get_ntohs(tvb, offset+2);
1528 if (action & FR_PERIOD_MSGS) {
1533 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1534 decode_boolean_bitfield(action, FR_PERIOD_MSGS, 8,
1535 "The period is in frames", "The period is in 0.01 seconds"));
1537 if (action & FR_DEACT_ON_EVENT) {
1538 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1539 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_ON_EVENT, 8,
1540 deact_on_event_vals, "%s"));
1542 if (action & FR_DEACT_AFTER_PER) {
1543 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1544 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_AFTER_PER, 8,
1545 deact_after_per_vals, "%s"));
1548 proto_tree_add_text(pt, tvb, offset, 1, "reserved");
1551 if (actionType == 1) {
1552 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d messages", actionValue);
1554 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d.%02d seconds", actionValue/100, actionValue%100);
1558 for (i = 1; i <= blocks; i++) {
1559 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1560 length += 3 - (length + 3) % 4;
1561 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1562 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1563 offset = filter_block(tvb, offset, tree);
1565 for (i = 1; i <= responses; i++) {
1566 msglen = tvb_get_ntohs(tvb, offset+4) + 8;
1567 length = msglen + 3 - (msglen + 3) % 4;
1568 item = proto_tree_add_text(pt, tvb, offset, length, "Response block %d", i);
1569 tree = proto_item_add_subtree (item, ett_gryphon_cmd_response_block);
1570 next_tvb = tvb_new_subset(tvb, offset, msglen, msglen);
1571 dissect_gryphon_message(next_tvb, NULL, tree, TRUE);
1578 resp_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1580 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1581 tvb_get_guint8(tvb, offset));
1582 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1588 cmd_modresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1590 unsigned char action;
1591 unsigned char dest = tvb_get_guint8(tvb, offset-5);
1594 resp_handle = tvb_get_guint8(tvb, offset);
1596 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1599 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all on channel %hd", dest);
1601 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all");
1602 action = tvb_get_guint8(tvb, offset+1);
1603 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s response",
1604 val_to_str(action, filtacts, "Unknown (%u)"));
1605 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1611 resp_resphan(tvbuff_t *tvb, int offset, proto_tree *pt)
1613 int handles = tvb_get_guint8(tvb, offset);
1616 proto_tree_add_text(pt, tvb, offset, 1, "Number of response handles: %d", handles);
1617 for (i = 1; i <= handles; i++){
1618 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1619 tvb_get_guint8(tvb, offset+i));
1621 padding = 3 - (handles + 1 + 3) % 4;
1623 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1624 offset += 1+handles+padding;
1629 resp_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1631 unsigned int id = tvb_get_ntohl(tvb, offset);
1633 proto_tree_add_text(pt, tvb, offset, 4, "Transmit schedule ID: %u", id);
1639 cmd_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1641 proto_tree_add_text(pt, tvb, offset, 4, "Program size: %u bytes",
1642 tvb_get_ntohl(tvb, offset));
1644 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1645 tvb_get_ptr(tvb, offset, 32));
1647 proto_tree_add_text(pt, tvb, offset, 80, "Program description: %.80s",
1648 tvb_get_ptr(tvb, offset, 80));
1654 resp_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1660 flags = tvb_get_guint8(tvb, offset);
1661 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1662 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1663 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1664 decode_boolean_bitfield(flags, 0x01, 8,
1665 "The program is already present",
1666 "The program is not present"));
1667 proto_tree_add_text(pt, tvb, offset+1, 1, "Handle: %u",
1668 tvb_get_guint8(tvb, offset+1));
1669 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1675 cmd_upload(tvbuff_t *tvb, int offset, proto_tree *pt)
1678 unsigned int length;
1680 msglen = tvb_reported_length_remaining(tvb, offset);
1681 proto_tree_add_text(pt, tvb, offset, 2, "Block number: %u",
1682 tvb_get_ntohs(tvb, offset));
1683 proto_tree_add_text(pt, tvb, offset+2, 1, "Handle: %u",
1684 tvb_get_guint8(tvb, offset+2));
1688 proto_tree_add_text(pt, tvb, offset, length, "Data (%u byte%s)",
1689 length, length == 1 ? "" : "s");
1691 length = 3 - (length + 3) % 4;
1693 proto_tree_add_text(pt, tvb, offset, length, "padding");
1700 cmd_delete(tvbuff_t *tvb, int offset, proto_tree *pt)
1702 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1703 tvb_get_ptr(tvb, offset, 32));
1709 cmd_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1711 proto_tree_add_text(pt, tvb, offset, 1, "Block number: %u",
1712 tvb_get_guint8(tvb, offset));
1713 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1719 resp_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1723 unsigned int i, count;
1725 count = tvb_get_guint8(tvb, offset);
1726 proto_tree_add_text(pt, tvb, offset, 1, "Number of programs in this response: %u", count);
1727 proto_tree_add_text(pt, tvb, offset+1, 1, "reserved");
1729 proto_tree_add_text(pt, tvb, offset, 2, "Number of remaining programs: %u",
1730 tvb_get_ntohs(tvb, offset));
1732 for (i = 1; i <= count; i++) {
1733 item = proto_tree_add_text(pt, tvb, offset, 112, "Program %u", i);
1734 tree = proto_item_add_subtree (item, ett_gryphon_pgm_list);
1735 proto_tree_add_text(tree, tvb, offset, 32, "Name: %.32s",
1736 tvb_get_ptr(tvb, offset, 32));
1738 proto_tree_add_text(tree, tvb, offset, 80, "Description: %.80s",
1739 tvb_get_ptr(tvb, offset, 80));
1746 cmd_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1751 int hdr_stuff = offset;
1753 msglen = tvb_reported_length_remaining(tvb, offset);
1754 offset = cmd_delete(tvb, offset, pt); /* decode the name */
1755 if (offset < msglen + hdr_stuff) {
1756 string = tvb_get_stringz(tvb, offset, &length);
1758 proto_tree_add_text(pt, tvb, offset, length, "Arguments: %s", string);
1760 length = 3 - (length + 3) % 4;
1762 proto_tree_add_text(pt, tvb, offset, length, "padding");
1772 resp_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1776 msglen = tvb_reported_length_remaining(tvb, offset);
1778 proto_tree_add_text(pt, tvb, offset, 1, "Channel (Client) number: %u",
1779 tvb_get_guint8(tvb, offset));
1780 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1787 resp_status(tvbuff_t *tvb, int offset, proto_tree *pt)
1791 unsigned int i, copies, length;
1793 copies = tvb_get_guint8(tvb, offset);
1794 item = proto_tree_add_text(pt, tvb, offset, 1, "Number of running copies: %u", copies);
1795 tree = proto_item_add_subtree (item, ett_gryphon_pgm_status);
1798 for (i = 1; i <= copies; i++) {
1799 proto_tree_add_text(tree, tvb, offset, 1, "Program %u channel (client) number %u",
1800 i, tvb_get_guint8(tvb, offset));
1804 length = 3 - (copies + 1 + 3) % 4;
1806 proto_tree_add_text(pt, tvb, offset, length, "padding");
1813 cmd_options(tvbuff_t *tvb, int offset, proto_tree *pt)
1818 unsigned int i, size, padding, option, option_length, option_value;
1819 char *string, *string1;
1821 msglen = tvb_reported_length_remaining(tvb, offset);
1822 item = proto_tree_add_text(pt, tvb, offset, 1, "Handle: %u",
1823 tvb_get_guint8(tvb, offset));
1824 item = proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1827 for (i = 1; msglen > 0; i++) {
1828 option_length = tvb_get_guint8(tvb, offset+1);
1829 size = option_length + 2;
1830 padding = 3 - ((size + 3) %4);
1831 item = proto_tree_add_text(pt, tvb, offset, size + padding, "Option number %u", i);
1832 tree = proto_item_add_subtree (item, ett_gryphon_pgm_options);
1833 option = tvb_get_guint8(tvb, offset);
1834 switch (option_length) {
1836 option_value = tvb_get_guint8(tvb, offset+2);
1839 option_value = tvb_get_ntohs(tvb, offset+2);
1842 option_value = tvb_get_ntohl(tvb, offset+2);
1847 string = "unknown option";
1848 string1 = "unknown option data";
1851 string = "Type of data in the file";
1852 switch (option_value) {
1854 string1 = "Binary - Don't modify";
1857 string1 = "ASCII - Remove CR's";
1862 string = "Type of file";
1863 switch (option_value) {
1865 string1 = "Executable";
1873 proto_tree_add_text(tree, tvb, offset, 1, "%s", string);
1874 proto_tree_add_text(tree, tvb, offset+2, option_length, "%s", string1);
1876 proto_tree_add_text(tree, tvb, offset+option_length+2, padding, "padding");
1877 offset += size + padding;
1878 msglen -= size + padding;
1884 cmd_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1889 msglen = tvb_reported_length_remaining(tvb, offset);
1890 if (tvb_get_guint8(tvb, offset) == 0)
1891 which = "First group of names";
1893 which = "Subsequent group of names";
1895 proto_tree_add_text(pt, tvb, offset, 1, "%s", which);
1896 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "Directory: %.*s",
1897 msglen-1, tvb_get_ptr(tvb, offset+1, msglen-1));
1903 resp_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1908 msglen = tvb_reported_length_remaining(tvb, offset);
1909 flag = tvb_get_guint8(tvb, offset) ? "Yes": "No";
1910 proto_tree_add_text(pt, tvb, offset, 1, "More filenames to return: %s", flag);
1911 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "File and directory names");
1917 cmd_usdt(tvbuff_t *tvb, int offset, proto_tree *pt)
1919 int ids, id, remain, size, i, j, bytes;
1922 proto_tree *localTree;
1923 proto_item *localItem;
1924 gchar *actions[] = {"Use 11 bit headers only",
1925 "Use 29 bit headers only",
1926 "Use both 11 & 29 bit headers",
1928 gchar *xmit_opts[] = {"Pad messages with less than 8 data bytes with 0x00's",
1929 "Pad messages with less than 8 data bytes with 0xFF's",
1930 "Do not pad messages with less than 8 data bytes",
1932 gchar *recv_opts[] = {"Do not verify the integrity of long received messages and do not send them to the client",
1933 "Verify the integrity of long received messages and send them to the client",
1934 "Verify the integrity of long received messages but do not send them to the client",
1936 gchar *block_desc[] = {"USDT request", "USDT response", "UUDT response"};
1938 flags = tvb_get_guint8(tvb, offset);
1943 proto_tree_add_text(pt, tvb, offset, 1, "%segister with gusdt", desc);
1946 localItem = proto_tree_add_text(pt, tvb, offset, 1, "Action flags");
1947 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1948 proto_tree_add_text(localTree, tvb, offset, 1, "%s%s",
1949 decode_boolean_bitfield (flags, 1, 8,
1950 "R", "Unr"), "egister with gusdt");
1951 proto_tree_add_text(localTree, tvb, offset, 1, "%s = %s",
1952 decode_numeric_bitfield (flags, 6, 8, "%d"),
1953 actions[(flags >> 1) & 3]);
1955 flags = tvb_get_guint8(tvb, offset+1);
1956 localItem = proto_tree_add_text(pt, tvb, offset+1, 1, "Transmit options");
1957 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1958 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s%s",
1959 decode_boolean_bitfield (flags, 1, 8,
1961 "cho long transmit messages back to the client");
1962 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s = %s",
1963 decode_numeric_bitfield (flags, 6, 8, "%d"),
1964 xmit_opts[(flags >> 1) & 3]);
1965 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s%s",
1966 decode_boolean_bitfield (flags, 8, 8,
1968 "end a USDT_DONE event when the last frame of a multi-frame USDT message is transmitted");
1970 flags = tvb_get_guint8(tvb, offset+2);
1971 localItem = proto_tree_add_text(pt, tvb, offset+2, 1, "Receive options");
1972 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1973 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s = %s",
1974 decode_numeric_bitfield (flags, 3, 8, "%d"),
1975 recv_opts[flags & 3]);
1976 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s%s",
1977 decode_boolean_bitfield (flags, 4, 8,
1979 "end a USDT_FIRSTFRAME event when the first frame of a multi-frame USDT message is received");
1980 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s%s",
1981 decode_boolean_bitfield (flags, 8, 8,
1983 "end a USDT_LASTFRAME event when the last frame of a multi-frame USDT message is received");
1985 if ((ids = tvb_get_guint8(tvb, offset+3))) {
1986 localItem = proto_tree_add_text(pt, tvb, offset+3, 1, "Using extended addressing for %d ID%s",
1987 ids, ids == 1?"":"s");
1989 localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data);
1991 id = tvb_get_ntohl (tvb, offset);
1992 proto_tree_add_text (localTree, tvb, offset, 4, "%04X", id);
1997 proto_tree_add_text(pt, tvb, offset+3, 1, "Using extended addressing for the single, internally defined, ID");
2000 for (i = 0; i < 2; i++) {
2001 bytes = tvb_reported_length_remaining (tvb, offset);
2004 localItem = proto_tree_add_text(pt, tvb, offset, 16, "%s block of USDT/UUDT IDs", i==0?"First":"Second");
2005 localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data);
2006 size = tvb_get_ntohl (tvb, offset);
2008 proto_tree_add_text (localTree, tvb, offset, 16, "No IDs in the block");
2010 } else if (size == 1) {
2011 proto_tree_add_text (localTree, tvb, offset, 4, "1 ID in the block");
2013 for (j = 0; j < 3; j++){
2014 id = tvb_get_ntohl (tvb, offset);
2015 proto_tree_add_text (localTree, tvb, offset, 4,
2016 "%s ID: %04X", block_desc[j], id);
2020 proto_tree_add_text (localTree, tvb, offset, 4, "%d IDs in the block", size);
2022 for (j = 0; j < 3; j++){
2023 id = tvb_get_ntohl (tvb, offset);
2024 proto_tree_add_text (localTree, tvb, offset, 4,
2025 "%s IDs from %04X through %04X", block_desc[j], id, id+size-1);
2031 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
2035 if ((remain = tvb_reported_length_remaining(tvb, offset))) {
2036 proto_tree_add_text(pt, tvb, offset, remain, "%d ignored byte%s",
2037 remain, remain == 1 ? "" : "s");
2045 cmd_bits_in (tvbuff_t *tvb, int offset, proto_tree *pt)
2050 int msglen, mask, value;
2051 char *decode[] = {"Input 1", "Input 2", "Input 3", "Pushbutton"};
2053 msglen = tvb_reported_length_remaining(tvb, offset);
2054 value = tvb_get_guint8(tvb, offset);
2056 item = proto_tree_add_text(pt, tvb, offset, 1, "Digital values set");
2057 tree = proto_item_add_subtree (item, ett_gryphon_digital_data);
2058 for (i = 0, mask = 1; i < SIZEOF (decode); mask <<= 1, i++) {
2060 proto_tree_add_text(tree, tvb, offset, 1, "%s is set",
2065 proto_tree_add_text(pt, tvb, offset, 1, "No digital values are set");
2074 cmd_bits_out (tvbuff_t *tvb, int offset, proto_tree *pt)
2079 int msglen, mask, value;
2080 char *decode[] = {"Output 1", "Output 2"};
2082 msglen = tvb_reported_length_remaining(tvb, offset);
2083 value = tvb_get_guint8(tvb, offset);
2085 item = proto_tree_add_text(pt, tvb, offset, 1, "Digital values set");
2086 tree = proto_item_add_subtree (item, ett_gryphon_digital_data);
2087 for (i = 0, mask = 1; i < SIZEOF (decode); mask <<= 1, i++) {
2089 proto_tree_add_text(tree, tvb, offset, 1, "%s is set",
2094 proto_tree_add_text(pt, tvb, offset, 1, "No digital values are set");
2103 cmd_init_strat (tvbuff_t *tvb, int offset, proto_tree *pt)
2108 msglen = tvb_reported_length_remaining(tvb, offset);
2109 proto_tree_add_text(pt, tvb, offset, 4, "Reset Limit = %u messages",
2110 tvb_get_ntohl(tvb, offset));
2113 for (index = 1; msglen; index++, offset++, msglen--) {
2114 value = tvb_get_guint8(tvb, offset);
2117 proto_tree_add_text(pt, tvb, offset, 1, "Delay %d = %.2f seconds",
2120 proto_tree_add_text(pt, tvb, offset, 1, "Delay %d = infinite",
2128 speed(tvbuff_t *tvb, int offset, proto_tree *pt)
2130 proto_tree_add_text(pt, tvb, offset, 1, "Baud rate index: %u",
2131 tvb_get_guint8(tvb, offset));
2132 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
2138 filter_block(tvbuff_t *tvb, int offset, proto_tree *pt)
2140 unsigned int type, operator;
2141 int length, padding;
2143 proto_tree_add_text(pt, tvb, offset, 2, "Filter field starts at byte %u",
2144 tvb_get_ntohs(tvb, offset));
2145 length = tvb_get_ntohs(tvb, offset+2);
2146 proto_tree_add_text(pt, tvb, offset+2, 2, "Filter field is %d byte%s long",
2147 length, length == 1 ? "" : "s");
2148 type = tvb_get_guint8(tvb, offset+4);
2149 proto_tree_add_text(pt, tvb, offset+4, 1, "Filtering on %s",
2150 val_to_str(type, filter_data_types, "Unknown (0x%02x)"));
2152 operator = tvb_get_guint8(tvb, offset+5);
2153 proto_tree_add_text(pt, tvb, offset+5, 1, "Type of comparison: %s",
2154 val_to_str(operator, operators, "Unknown (%u)"));
2155 proto_tree_add_text(pt, tvb, offset+6, 2, "reserved");
2158 if (operator == BIT_FIELD_CHECK) {
2159 proto_tree_add_text(pt, tvb, offset, length, "Pattern");
2160 proto_tree_add_text(pt, tvb, offset+length, length, "Mask");
2164 proto_tree_add_text(pt, tvb, offset, 1, "Value: %u",
2165 tvb_get_guint8(tvb, offset));
2168 proto_tree_add_text(pt, tvb, offset, 2, "Value: %u",
2169 tvb_get_ntohs(tvb, offset));
2172 proto_tree_add_text(pt, tvb, offset, 4, "Value: %u",
2173 tvb_get_ntohl(tvb, offset));
2176 proto_tree_add_text(pt, tvb, offset, length, "Value");
2179 offset += length * 2;
2180 padding = 3 - (length * 2 + 3) % 4;
2182 proto_tree_add_text(pt, tvb, offset, padding, "padding");
2189 blm_mode(tvbuff_t *tvb, int offset, proto_tree *pt)
2191 char *mode, line[50];
2194 x = tvb_get_ntohl(tvb, offset);
2195 y = tvb_get_ntohl(tvb, offset+4);
2199 sprintf (line, "reserved");
2202 mode = "Average over time";
2205 sprintf (line, "Averaging period: %d.%03d seconds", seconds, y);
2208 mode = "Average over frame count";
2209 sprintf (line, "Averaging period: %d frames", y);
2212 mode = "- unknown -";
2213 sprintf (line, "reserved");
2215 proto_tree_add_text(pt, tvb, offset, 4, "Mode: %s", mode);
2217 proto_tree_add_text(pt, tvb, offset, 4, line, NULL);
2223 proto_register_gryphon(void)
2225 static hf_register_info hf[] = {
2227 { "Source", "gryph.src", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
2229 { &hf_gryph_srcchan,
2230 { "Source channel", "gryph.srcchan", FT_UINT8, BASE_DEC, NULL, 0x0,
2233 { "Destination", "gryph.dest", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
2235 { &hf_gryph_destchan,
2236 { "Destination channel", "gryph.dstchan", FT_UINT8, BASE_DEC, NULL, 0x0,
2239 { "Frame type", "gryph.type", FT_UINT8, BASE_DEC, NULL, 0x0,
2242 { "Command", "gryph.cmd.cmd", FT_UINT8, BASE_DEC, NULL, 0x0,
2246 static gint *ett[] = {
2248 &ett_gryphon_header,
2250 &ett_gryphon_command_data,
2251 &ett_gryphon_response_data,
2252 &ett_gryphon_data_header,
2254 &ett_gryphon_data_body,
2255 &ett_gryphon_cmd_filter_block,
2256 &ett_gryphon_cmd_events_data,
2257 &ett_gryphon_cmd_config_device,
2258 &ett_gryphon_cmd_sched_data,
2259 &ett_gryphon_cmd_sched_cmd,
2260 &ett_gryphon_cmd_response_block,
2261 &ett_gryphon_pgm_list,
2262 &ett_gryphon_pgm_status,
2263 &ett_gryphon_pgm_options,
2264 &ett_gryphon_valid_headers,
2265 &ett_gryphon_usdt_data,
2266 &ett_gryphon_digital_data,
2268 module_t *gryphon_module;
2270 proto_gryphon = proto_register_protocol("DG Gryphon Protocol",
2273 proto_register_field_array(proto_gryphon, hf, array_length(hf));
2274 proto_register_subtree_array(ett, array_length(ett));
2276 gryphon_module = prefs_register_protocol(proto_gryphon, NULL);
2277 prefs_register_bool_preference(gryphon_module, "desegment",
2278 "Desegment all Gryphon messages spanning multiple TCP segments",
2279 "Whether the Gryphon dissector should desegment all messages spanning multiple TCP segments",
2280 &gryphon_desegment);
2284 proto_reg_handoff_gryphon(void)
2286 dissector_handle_t gryphon_handle;
2288 gryphon_handle = create_dissector_handle(dissect_gryphon, proto_gryphon);
2289 dissector_add("tcp.port", 7000, gryphon_handle);
2292 /* Start the functions we need for the plugin stuff */
2294 #ifndef ENABLE_STATIC
2296 G_MODULE_EXPORT void
2297 plugin_reg_handoff(void){
2298 proto_reg_handoff_gryphon();
2301 G_MODULE_EXPORT void
2302 plugin_init(plugin_address_table_t *pat
2303 #ifndef PLUGINS_NEED_ADDRESS_TABLE
2307 /* initialise the table of pointers needed in Win32 DLLs */
2308 plugin_address_table_init(pat);
2309 /* register the new protocol, protocol fields, and subtrees */
2310 if (proto_gryphon == -1) { /* execute protocol initialization only once */
2311 proto_register_gryphon();
2317 /* End the functions we need for plugin stuff */