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 <epan/dissectors/packet-tcp.h>
45 #include "plugins/plugin_api_defs.h"
48 G_MODULE_EXPORT const gchar version[] = VERSION;
54 * http://www.dgtech.com/gryphon/docs/html/
57 static int proto_gryphon = -1;
59 static int hf_gryph_src = -1;
60 static int hf_gryph_srcchan = -1;
61 static int hf_gryph_dest = -1;
62 static int hf_gryph_destchan= -1;
63 static int hf_gryph_type = -1;
64 static int hf_gryph_cmd = -1;
66 static gint ett_gryphon = -1;
67 static gint ett_gryphon_header = -1;
68 static gint ett_gryphon_body = -1;
69 static gint ett_gryphon_command_data = -1;
70 static gint ett_gryphon_response_data = -1;
71 static gint ett_gryphon_data_header = -1;
72 static gint ett_gryphon_flags = -1;
73 static gint ett_gryphon_data_body = -1;
74 static gint ett_gryphon_cmd_filter_block = -1;
75 static gint ett_gryphon_cmd_events_data = -1;
76 static gint ett_gryphon_cmd_config_device = -1;
77 static gint ett_gryphon_cmd_sched_data = -1;
78 static gint ett_gryphon_cmd_sched_cmd = -1;
79 static gint ett_gryphon_cmd_response_block = -1;
80 static gint ett_gryphon_pgm_list = -1;
81 static gint ett_gryphon_pgm_status = -1;
82 static gint ett_gryphon_pgm_options = -1;
83 static gint ett_gryphon_valid_headers = -1;
84 static gint ett_gryphon_usdt_data = -1;
85 static gint ett_gryphon_digital_data = -1;
87 /* desegmentation of Gryphon */
88 static gboolean gryphon_desegment = TRUE;
90 static void dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo,
91 proto_tree *tree, gboolean is_msgresp_add);
92 static int decode_command(tvbuff_t*, int, int, proto_tree*);
93 static int decode_response(tvbuff_t*, int, int, proto_tree*);
94 static int decode_data(tvbuff_t*, int, proto_tree*);
95 static int decode_event(tvbuff_t*, int, proto_tree*);
96 static int decode_misc(tvbuff_t*, int, proto_tree*);
97 static int cmd_init(tvbuff_t*, int, proto_tree*);
98 static int resp_time(tvbuff_t*, int, proto_tree*);
99 static int cmd_setfilt(tvbuff_t*, int, proto_tree*);
100 static int cmd_ioctl(tvbuff_t*, int, proto_tree*);
101 static int cmd_addfilt(tvbuff_t*, int, proto_tree*);
102 static int resp_addfilt(tvbuff_t*, int, proto_tree*);
103 static int cmd_modfilt(tvbuff_t*, int, proto_tree*);
104 static int resp_filthan(tvbuff_t*, int, proto_tree*);
105 static int dfiltmode(tvbuff_t*, int, proto_tree*);
106 static int filtmode(tvbuff_t*, int, proto_tree*);
107 static int resp_events(tvbuff_t*, int, proto_tree*);
108 static int cmd_register(tvbuff_t*, int, proto_tree*);
109 static int resp_register(tvbuff_t*, int, proto_tree*);
110 static int resp_getspeeds(tvbuff_t*, int, proto_tree*);
111 static int cmd_sort(tvbuff_t*, int, proto_tree*);
112 static int cmd_optimize(tvbuff_t*, int, proto_tree*);
113 static int resp_config(tvbuff_t*, int, proto_tree*);
114 static int cmd_sched(tvbuff_t*, int, proto_tree*);
115 static int cmd_sched_rep(tvbuff_t*, int, proto_tree*);
116 static int resp_blm_data(tvbuff_t*, int, proto_tree*);
117 static int resp_blm_stat(tvbuff_t*, int, proto_tree*);
118 static int cmd_addresp(tvbuff_t*, int, proto_tree*);
119 static int resp_addresp(tvbuff_t*, int, proto_tree*);
120 static int cmd_modresp(tvbuff_t*, int, proto_tree*);
121 static int resp_resphan(tvbuff_t*, int, proto_tree*);
122 static int resp_sched(tvbuff_t*, int, proto_tree*);
123 static int cmd_desc(tvbuff_t*, int, proto_tree*);
124 static int resp_desc(tvbuff_t*, int, proto_tree*);
125 static int cmd_upload(tvbuff_t*, int, proto_tree*);
126 static int cmd_delete(tvbuff_t*, int, proto_tree*);
127 static int cmd_list(tvbuff_t*, int, proto_tree*);
128 static int resp_list(tvbuff_t*, int, proto_tree*);
129 static int cmd_start(tvbuff_t*, int, proto_tree*);
130 static int resp_start(tvbuff_t*, int, proto_tree*);
131 static int resp_status(tvbuff_t*, int, proto_tree*);
132 static int cmd_options(tvbuff_t*, int, proto_tree*);
133 static int cmd_files(tvbuff_t*, int, proto_tree*);
134 static int resp_files(tvbuff_t*, int, proto_tree*);
135 static int eventnum(tvbuff_t*, int, proto_tree*);
136 static int speed(tvbuff_t*, int, proto_tree*);
137 static int filter_block(tvbuff_t*, int, proto_tree*);
138 static int blm_mode(tvbuff_t*, int, proto_tree*);
139 static int cmd_usdt(tvbuff_t*, int, proto_tree*);
140 static int cmd_bits_in(tvbuff_t*, int, proto_tree*);
141 static int cmd_bits_out(tvbuff_t*, int, proto_tree*);
142 static int cmd_init_strat(tvbuff_t*, int, proto_tree*);
144 static char *frame_type[] = {
148 "Network (vehicle) data",
155 * Length of the frame header.
157 #define FRAME_HEADER_LEN 8
160 get_gryphon_pdu_len(tvbuff_t *tvb, int offset)
166 * Get the length of the Gryphon packet, and then get the length as
167 * padded to a 4-byte boundary.
169 plen = tvb_get_ntohs(tvb, offset + 4);
170 padded_len = plen + 3 - (plen + 3) % 4;
173 * That length doesn't include the fixed-length part of the header;
176 return padded_len + FRAME_HEADER_LEN;
180 dissect_gryphon_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
182 dissect_gryphon_message(tvb, pinfo, tree, FALSE);
186 dissect_gryphon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
188 tcp_dissect_pdus(tvb, pinfo, tree, gryphon_desegment, FRAME_HEADER_LEN,
189 get_gryphon_pdu_len, dissect_gryphon_pdu);
192 static const value_string src_dest[] = {
194 {SD_SERVER, "Server"},
195 {SD_CLIENT, "Client"},
196 {SD_SCHED, "Scheduler"},
197 {SD_SCRIPT, "Script Processor"},
198 {SD_PGM, "Program Loader"},
199 {SD_USDT, "USDT Server"},
200 {SD_BLM, "Bus Load Monitoring"},
201 {SD_FLIGHT, "Flight Recorder"},
202 {SD_RESP, "Message Responder"},
203 {SD_IOPWR, "I/O and power"},
204 {SD_UTIL, "Utility/Miscellaneous"},
209 dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
210 gboolean is_msgresp_add)
213 proto_tree *gryphon_tree;
215 proto_tree *header_tree, *body_tree, *localTree;
216 proto_item *header_item, *body_item, *localItem;
217 int start_offset, msgend;
219 unsigned int src, dest, i, frmtyp;
222 if (!is_msgresp_add) {
223 if (check_col(pinfo->cinfo, COL_PROTOCOL))
224 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Gryphon");
225 if (check_col(pinfo->cinfo, COL_INFO))
226 col_clear(pinfo->cinfo, COL_INFO);
229 if (!is_msgresp_add) {
230 ti = proto_tree_add_item(tree, proto_gryphon, tvb, 0, -1, FALSE);
231 gryphon_tree = proto_item_add_subtree(ti, ett_gryphon);
235 src = tvb_get_guint8(tvb, offset + 0);
236 dest = tvb_get_guint8(tvb, offset + 2);
237 msglen = tvb_get_ntohs(tvb, offset + 4);
238 flags = tvb_get_guint8(tvb, offset + 6);
239 frmtyp = flags & ~RESPONSE_FLAGS;
241 if (!is_msgresp_add) {
243 * This tvbuff includes padding to make its length a multiple
244 * of 4 bytes; set it to the actual length.
246 set_actual_length(tvb, msglen + FRAME_HEADER_LEN);
248 if (check_col(pinfo->cinfo, COL_INFO)) {
250 * Indicate what kind of message this is.
252 if (frmtyp >= SIZEOF (frame_type))
253 col_set_str(pinfo->cinfo, COL_INFO, "- Invalid -");
255 col_set_str(pinfo->cinfo, COL_INFO, frame_type[frmtyp]);
262 if (frmtyp >= SIZEOF (frame_type)) {
264 * Unknown message type.
266 proto_tree_add_text(gryphon_tree, tvb, offset, msglen, "Data");
270 header_item = proto_tree_add_text(gryphon_tree, tvb, offset, MSG_HDR_SZ, "Header");
271 header_tree = proto_item_add_subtree(header_item, ett_gryphon_header);
272 proto_tree_add_text(header_tree, tvb, offset, 2,
273 "Source: %s, channel %u",
274 val_to_str(src, src_dest, "Unknown (0x%02x)"),
275 tvb_get_guint8(tvb, offset + 1));
276 proto_tree_add_uint_hidden(header_tree, hf_gryph_src, tvb,
278 proto_tree_add_uint_hidden(header_tree, hf_gryph_srcchan, tvb,
279 offset+1, 1, tvb_get_guint8(tvb, offset + 1));
281 proto_tree_add_text(header_tree, tvb, offset+2, 2,
282 "Destination: %s, channel %u",
283 val_to_str(dest, src_dest, "Unknown (0x%02x)"),
284 tvb_get_guint8(tvb, offset + 3));
285 proto_tree_add_uint_hidden(header_tree, hf_gryph_dest, tvb,
287 proto_tree_add_uint_hidden(header_tree, hf_gryph_destchan, tvb,
288 offset+3, 1, tvb_get_guint8(tvb, offset + 3));
290 proto_tree_add_text(header_tree, tvb, offset+4, 2,
291 "Data length: %u byte%s", msglen, msglen == 1 ? "" : "s");
292 proto_tree_add_text(header_tree, tvb, offset+6, 1,
293 "Frame type: %s", frame_type[frmtyp]);
294 if (is_msgresp_add) {
295 localItem = proto_tree_add_text(header_tree, tvb, offset+6, 1, "Flags");
296 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
297 proto_tree_add_text(localTree, tvb, offset+6, 1, "%s",
298 decode_boolean_bitfield(flags, DONT_WAIT_FOR_RESP, 8,
299 "Don't wait for response",
300 "Wait for response"));
301 proto_tree_add_text(localTree, tvb, offset+6, 1, "%s",
302 decode_boolean_bitfield(flags, WAIT_FOR_PREV_RESP, 8,
303 "Wait for previous responses",
304 "Don't wait for previous responses"));
306 proto_tree_add_text(header_tree, tvb, offset+7, 1, "reserved");
308 proto_tree_add_uint_hidden(header_tree, hf_gryph_type, tvb,
309 offset+6, 1, frmtyp);
310 msgpad = 3 - (msglen + 3) % 4;
311 msgend = offset + msglen + msgpad + MSG_HDR_SZ;
313 body_item = proto_tree_add_text(gryphon_tree, tvb, offset + MSG_HDR_SZ,
314 msglen + msgpad, "Body");
315 body_tree = proto_item_add_subtree(body_item, ett_gryphon_body);
317 start_offset = offset;
318 offset += MSG_HDR_SZ;
321 offset = decode_command(tvb, offset, dest, body_tree);
324 offset = decode_response(tvb, offset, src, body_tree);
327 offset = decode_data(tvb, offset, body_tree);
330 offset = decode_event(tvb, offset, body_tree);
333 offset = decode_misc (tvb, offset, body_tree);
340 if (offset < msgend - msgpad) {
341 i = msgend - msgpad - offset;
342 proto_tree_add_text(gryphon_tree, tvb, offset, i, "Data");
345 if (offset < msgend) {
347 proto_tree_add_text(gryphon_tree, tvb, offset, i, "padding");
353 static const val_str_dsp cmds[] = {
354 {CMD_INIT, "Initialize", cmd_init, NULL},
355 {CMD_GET_STAT, "Get status", NULL, NULL},
356 {CMD_GET_CONFIG, "Get configuration", NULL, resp_config},
357 {CMD_EVENT_ENABLE, "Enable event", eventnum, NULL},
358 {CMD_EVENT_DISABLE, "Disable event", eventnum, NULL},
359 {CMD_GET_TIME, "Get time", NULL, resp_time},
360 {CMD_SET_TIME, "Set time", resp_time, NULL},
361 {CMD_GET_RXDROP, "Get number of dropped RX messages", NULL, NULL},
362 {CMD_RESET_RXDROP, "Clear number of dropped RX messages", NULL, NULL},
363 {CMD_BCAST_ON, "Set broadcasts on", NULL, NULL},
364 {CMD_BCAST_OFF, "Set broadcasts off", NULL, NULL},
365 {CMD_CARD_SET_SPEED, "Set channel baud rate", speed, NULL},
366 {CMD_CARD_GET_SPEED, "Get channel baud rate", NULL, speed},
367 {CMD_CARD_SET_FILTER, "Set filter (deprecated)", cmd_setfilt, NULL},
368 {CMD_CARD_GET_FILTER, "Get filter", resp_addfilt, cmd_addfilt},
369 {CMD_CARD_TX, "Transmit message", decode_data, NULL},
370 {CMD_CARD_TX_LOOP_ON, "Set transmit loopback on", NULL, NULL},
371 {CMD_CARD_TX_LOOP_OFF, "Set transmit loopback off", NULL, NULL},
372 {CMD_CARD_IOCTL, "IOCTL pass-through", cmd_ioctl, NULL},
373 {CMD_CARD_ADD_FILTER, "Add a filter", cmd_addfilt, resp_addfilt},
374 {CMD_CARD_MODIFY_FILTER, "Modify a filter", cmd_modfilt, NULL},
375 {CMD_CARD_GET_FILTER_HANDLES, "Get filter handles", NULL, resp_filthan},
376 {CMD_CARD_SET_DEFAULT_FILTER, "Set default filter", dfiltmode, NULL},
377 {CMD_CARD_GET_DEFAULT_FILTER, "Get default filter mode", NULL, dfiltmode},
378 {CMD_CARD_SET_FILTER_MODE, "Set filter mode", filtmode, NULL},
379 {CMD_CARD_GET_FILTER_MODE, "Get filter mode", NULL, filtmode},
380 {CMD_CARD_GET_EVNAMES, "Get event names", NULL, resp_events},
381 {CMD_CARD_GET_SPEEDS, "Get defined speeds", NULL, resp_getspeeds},
382 {CMD_SERVER_REG, "Register with server", cmd_register, resp_register},
383 {CMD_SERVER_SET_SORT, "Set the sorting behavior", cmd_sort, NULL},
384 {CMD_SERVER_SET_OPT, "Set the type of optimization", cmd_optimize, NULL},
385 {CMD_BLM_SET_MODE, "Set Bus Load Monitoring mode", blm_mode, NULL},
386 {CMD_BLM_GET_MODE, "Get Bus Load Monitoring mode", NULL, blm_mode},
387 {CMD_BLM_GET_DATA, "Get Bus Load data", NULL, resp_blm_data},
388 {CMD_BLM_GET_STATS, "Get Bus Load statistics", NULL, resp_blm_stat},
389 {CMD_FLIGHT_GET_CONFIG, "Get flight recorder channel info", NULL, NULL},
390 {CMD_FLIGHT_START_MON, "Start flight recorder monitoring", NULL, NULL},
391 {CMD_FLIGHT_STOP_MON, "Stop flight recorder monitoring", NULL, NULL},
392 {CMD_MSGRESP_ADD, "Add response message", cmd_addresp, resp_addresp},
393 {CMD_MSGRESP_GET, "Get response message", resp_addresp, cmd_addresp},
394 {CMD_MSGRESP_MODIFY, "Modify response message state", cmd_modresp, NULL},
395 {CMD_MSGRESP_GET_HANDLES, "Get response message handles", NULL, resp_resphan},
396 {CMD_PGM_DESC, "Describe program to to uploaded", cmd_desc, resp_desc},
397 {CMD_PGM_UPLOAD, "Upload a program to the Gryphon", cmd_upload, NULL},
398 {CMD_PGM_DELETE, "Delete an uploaded program", cmd_delete, NULL},
399 {CMD_PGM_LIST, "Get a list of uploaded programs", cmd_list, resp_list},
400 {CMD_PGM_START, "Start an uploaded program", cmd_start, resp_start},
401 {CMD_PGM_START2, "Start an uploaded program", NULL, resp_start},
402 {CMD_PGM_STOP, "Stop an uploaded program", resp_start, NULL},
403 {CMD_PGM_STATUS, "Get status of an uploaded program", cmd_delete, resp_status},
404 {CMD_PGM_OPTIONS, "Set program upload options", cmd_options, resp_status},
405 {CMD_PGM_FILES, "Get a list of files & directories", cmd_files, resp_files},
406 {CMD_SCHED_TX, "Schedule transmission of messages", cmd_sched, resp_sched},
407 {CMD_SCHED_KILL_TX, "Stop and destroy a message transmission", resp_sched, NULL},
408 {CMD_SCHED_STOP_TX, "Kill a message transmission (deprecated)", resp_sched, NULL},
409 {CMD_SCHED_MSG_REPLACE, "Replace a scheduled message", cmd_sched_rep, NULL},
410 {CMD_USDT_IOCTL, "Register/Unregister with USDT server", cmd_usdt, NULL},
411 {CMD_USDT_REGISTER, "Register/Unregister with USDT server", cmd_usdt, NULL},
412 {CMD_USDT_SET_FUNCTIONAL, "Set IDs to use extended addressing", cmd_usdt, NULL},
413 {CMD_IOPWR_GETINP, "Read current digital inputs", NULL, cmd_bits_in},
414 {CMD_IOPWR_GETLATCH, "Read latched digital inputs", NULL, cmd_bits_in},
415 {CMD_IOPWR_CLRLATCH, "Read & clear latched digital inputs", cmd_bits_in, cmd_bits_in},
416 {CMD_IOPWR_GETOUT, "Read digital outputs", NULL, cmd_bits_out},
417 {CMD_IOPWR_SETOUT, "Write digital outputs", cmd_bits_out, NULL},
418 {CMD_IOPWR_SETBIT, "Set indicated output bits", cmd_bits_out, NULL},
419 {CMD_IOPWR_CLRBIT, "Clear indicated output bits", cmd_bits_out, NULL},
420 {CMD_IOPWR_GETPOWER, "Read digital inputs at power on time", NULL, cmd_bits_in},
421 {CMD_UTIL_SET_INIT_STRATEGY, "Set initialization strategy", cmd_init_strat, NULL},
422 {CMD_UTIL_GET_INIT_STRATEGY, "Get initialization strategy", NULL, cmd_init_strat},
423 {-1, "- unknown -", NULL, NULL},
426 static const value_string responses[] = {
427 {RESP_OK, "OK - no error"},
428 {RESP_UNKNOWN_ERR, "Unknown error"},
429 {RESP_UNKNOWN_CMD, "Unrecognised command"},
430 {RESP_UNSUPPORTED, "Unsupported command"},
431 {RESP_INVAL_CHAN, "Invalid channel specified"},
432 {RESP_INVAL_DST, "Invalid destination"},
433 {RESP_INVAL_PARAM, "Invalid parameter(s)"},
434 {RESP_INVAL_MSG, "Invalid message"},
435 {RESP_INVAL_LEN, "Invalid length field"},
436 {RESP_TX_FAIL, "Transmit failed"},
437 {RESP_RX_FAIL, "Receive failed"},
438 {RESP_AUTH_FAIL, "Authorization failed"},
439 {RESP_MEM_ALLOC_ERR, "Memory allocation error"},
440 {RESP_TIMEOUT, "Command timed out"},
441 {RESP_UNAVAILABLE, "Unavailable"},
442 {RESP_BUF_FULL, "Buffer full"},
443 {RESP_NO_SUCH_JOB, "No such job"},
447 static const value_string filter_data_types[] = {
448 {FILTER_DATA_TYPE_HEADER_FRAME, "frame header"},
449 {FILTER_DATA_TYPE_HEADER, "data message header"},
450 {FILTER_DATA_TYPE_DATA, "data message data"},
451 {FILTER_DATA_TYPE_EXTRA_DATA, "data message extra data"},
452 {FILTER_EVENT_TYPE_HEADER, "event message header"},
453 {FILTER_EVENT_TYPE_DATA, "event message"},
457 static const value_string operators[] = {
458 {BIT_FIELD_CHECK, "Bit field check"},
459 {SVALUE_GT, "Greater than (signed)"},
460 {SVALUE_GE, "Greater than or equal to (signed)"},
461 {SVALUE_LT, "Less than (signed)"},
462 {SVALUE_LE, "Less than or equal to (signed)"},
463 {VALUE_EQ, "Equal to"},
464 {VALUE_NE, "Not equal to"},
465 {UVALUE_GT, "Greater than (unsigned)"},
466 {UVALUE_GE, "Greater than or equal to (unsigned)"},
467 {UVALUE_LT, "Less than (unsigned)"},
468 {UVALUE_LE, "Less than or equal to (unsigned)"},
469 {DIG_LOW_TO_HIGH, "Digital, low to high transistion"},
470 {DIG_HIGH_TO_LOW, "Digital, high to low transistion"},
471 {DIG_TRANSITION, "Digital, change of state"},
475 static const value_string modes[] = {
476 {FILTER_OFF_PASS_ALL, "Filter off, pass all messages"},
477 {FILTER_OFF_BLOCK_ALL, "Filter off, block all messages"},
478 {FILTER_ON, "Filter on"},
482 static const value_string dmodes[] = {
483 {DEFAULT_FILTER_BLOCK, "Block"},
484 {DEFAULT_FILTER_PASS, "Pass"},
488 static const value_string filtacts[] = {
489 {DELETE_FILTER, "Delete"},
490 {ACTIVATE_FILTER, "Activate"},
491 {DEACTIVATE_FILTER, "Deactivate"},
495 static const value_string ioctls[] = {
496 {GINIT, "GINIT: Initialize"},
497 {GLOOPON, "GLOOPON: Loop on"},
498 {GLOOPOFF, "GLOOPOFF: Loop off"},
499 {GGETHWTYPE, "GGETHWTYPE: Get hardware type"},
500 {GGETREG, "GGETREG: Get register"},
501 {GSETREG, "GSETREG: Set register"},
502 {GGETRXCOUNT, "GGETRXCOUNT: Get the receive message counter"},
503 {GSETRXCOUNT, "GSETRXCOUNT: Set the receive message counter"},
504 {GGETTXCOUNT, "GGETTXCOUNT: Get the transmit message counter"},
505 {GSETTXCOUNT, "GSETTXCOUNT: Set the transmit message counter"},
506 {GGETRXDROP, "GGETRXDROP: Get the number of dropped receive messages"},
507 {GSETRXDROP, "GSETRXDROP: Set the number of dropped receive messages"},
508 {GGETTXDROP, "GGETTXDROP: Get the number of dropped transmit messages"},
509 {GSETTXDROP, "GSETTXDROP: Set the number of dropped transmit messages"},
510 {GGETRXBAD, "GGETRXBAD: Get the number of bad receive messages"},
511 {GGETTXBAD, "GGETTXBAD: Get the number of bad transmit messages"},
512 {GGETCOUNTS, "GGETCOUNTS: Get total message counter"},
513 {GGETBLMON, "GGETBLMON: Get bus load monitoring status"},
514 {GSETBLMON, "GSETBLMON: Set bus load monitoring status (turn on/off)"},
515 {GGETERRLEV, "GGETERRLEV: Get error level"},
516 {GSETERRLEV, "GSETERRLEV: Set error level"},
517 {GGETBITRATE, "GGETBITRATE: Get bit rate"},
518 {GGETRAM, "GGETRAM: Read value from RAM"},
519 {GSETRAM, "GSETRAM: Write value to RAM"},
520 {GCANGETBTRS, "GCANGETBTRS: Read CAN bit timing registers"},
521 {GCANSETBTRS, "GCANSETBTRS: Write CAN bit timing registers"},
522 {GCANGETBC, "GCANGETBC: Read CAN bus configuration register"},
523 {GCANSETBC, "GCANSETBC: Write CAN bus configuration register"},
524 {GCANGETMODE, "GCANGETMODE"},
525 {GCANSETMODE, "GCANSETMODE"},
526 {GCANGETTRANS, "GCANGETTRANS"},
527 {GCANSETTRANS, "GCANSETTRANS"},
528 {GCANSENDERR, "GCANSENDERR"},
529 {GCANRGETOBJ, "GCANRGETOBJ"},
530 {GCANRSETSTDID, "GCANRSETSTDID"},
531 {GCANRSETEXTID, "GCANRSETEXTID"},
532 {GCANRSETDATA, "GCANRSETDATA"},
533 {GCANRENABLE, "GCANRENABLE"},
534 {GCANRDISABLE, "GCANRDISABLE"},
535 {GCANRGETMASKS, "GCANRGETMASKS"},
536 {GCANRSETMASKS, "GCANRSETMASKS"},
537 {GCANSWGETMODE, "GCANSWGETMODE"},
538 {GCANSWSETMODE, "GCANSWSETMODE"},
539 {GDLCGETFOURX, "GDLCGETFOURX"},
540 {GDLCSETFOURX, "GDLCSETFOURX"},
541 {GDLCGETLOAD, "GDLCGETLOAD"},
542 {GDLCSETLOAD, "GDLCSETLOAD"},
543 {GDLCSENDBREAK, "GDLCSENDBREAK"},
544 {GDLCABORTTX, "GDLCABORTTX"},
545 {GDLCGETHDRMODE, "DLCGETHDRMODE"},
546 {GDLCSETHDRMODE, "GDLCSETHDRMODE"},
547 {GHONSLEEP, "GHONSLEEP"},
548 {GHONSILENCE, "GHONSILENCE"},
549 {GKWPSETPTIMES, "GKWPSETPTIMES"},
550 {GKWPSETWTIMES, "GKWPSETWTIMES"},
551 {GKWPDOWAKEUP, "GKWPDOWAKEUP"},
552 {GKWPGETBITTIME, "GKWPGETBITTIME"},
553 {GKWPSETBITTIME, "GKWPSETBITTIME"},
554 {GKWPSETNODEADDR, "GKWPSETNODEADDR"},
555 {GKWPGETNODETYPE, "GKWPGETNODETYPE"},
556 {GKWPSETNODETYPE, "GKWPSETNODETYPE"},
557 {GKWPSETWAKETYPE, "GKWPSETWAKETYPE"},
558 {GKWPSETTARGADDR, "GKWPSETTARGADDR"},
559 {GKWPSETKEYBYTES, "GKWPSETKEYBYTES"},
560 {GKWPSETSTARTREQ, "GKWPSETSTARTREQ"},
561 {GKWPSETSTARTRESP, "GKWPSETSTARTRESP"},
562 {GKWPSETPROTOCOL, "GKWPSETPROTOCOL"},
563 {GKWPGETLASTKEYBYTES, "GKWPGETLASTKEYBYTES"},
564 {GKWPSETLASTKEYBYTES, "GKWPSETLASTKEYBYTES"},
565 {GSCPGETBBR, "GSCPGETBBR"},
566 {GSCPSETBBR, "GSCPSETBBR"},
567 {GSCPGETID, "GSCPGETID"},
568 {GSCPSETID, "GSCPSETID"},
569 {GSCPADDFUNCID, "GSCPADDFUNCID"},
570 {GSCPCLRFUNCID, "GSCPCLRFUNCID"},
571 {GUBPGETBITRATE, "GUBPGETBITRATE"},
572 {GUBPSETBITRATE, "GUBPSETBITRATE"},
573 {GUBPGETINTERBYTE, "GUBPGETINTERBYTE"},
574 {GUBPSETINTERBYTE, "GUBPSETINTERBYTE"},
575 {GUBPGETNACKMODE, "GUBPGETNACKMODE"},
576 {GUBPSETNACKMODE, "GUBPSETNACKMODE"},
577 {GUBPGETRETRYDELAY, "GUBPGETRETRYDELAY"},
578 {GUBPSETRETRYDELAY, "GUBPSETRETRYDELAY"},
579 {GRESETHC08, "GRESETHC08: Reset the HC08 processor"},
580 {GTESTHC08COP, "GTESTHC08COP: Stop updating the HC08 watchdog timer"},
581 {GSJAGETLISTEN, "GSJAGETLISTEN"},
582 {GSJASETLISTEN, "GSJASETLISTEN"},
583 {GSJAGETSELFTEST, "GSJAGETSELFTEST"},
584 {GSJASETSELFTEST, "GSJASETSELFTEST"},
585 {GSJAGETXMITONCE, "GSJAGETXMITONCE"},
586 {GSJASETXMITONCE, "GSJASETXMITONCE"},
587 {GSJAGETTRIGSTATE, "GSJAGETTRIGSTATE"},
588 {GSJASETTRIGCTRL, "GSJASETTRIGCTRL"},
589 {GSJAGETTRIGCTRL, "GSJAGETTRIGCTRL"},
590 {GSJAGETOUTSTATE, "GSJAGETOUTSTATE"},
591 {GSJASETOUTSTATE, "GSJASETOUTSTATE"},
592 {GSJAGETFILTER, "GSJAGETFILTER"},
593 {GSJASETFILTER, "GSJASETFILTER"},
594 {GSJAGETMASK, "GSJAGETMASK"},
595 {GSJASETMASK, "GSJASETMASK"},
596 {GSJAGETINTTERM, "GSJAGETINTTERM"},
597 {GSJASETINTTERM, "GSJASETINTTERM"},
598 {GSJAGETFTTRANS, "GSJAGETFTTRANS"},
599 {GSJASETFTTRANS, "GSJASETFTTRANS"},
600 {GSJAGETFTERROR, "GSJAGETFTERROR"},
601 {GLINGETBITRATE, "GLINGETBITRATE: Get the current bit rate"},
602 {GLINSETBITRATE, "GLINSETBITRATE: Set the bit rate"},
603 {GLINGETBRKSPACE, "GLINGETBRKSPACE"},
604 {GLINSETBRKSPACE, "GLINSETBRKSPACE"},
605 {GLINGETBRKMARK, "GLINGETBRKMARK"},
606 {GLINSETBRKMARK, "GLINSETBRKMARK"},
607 {GLINGETIDDELAY, "GLINGETIDDELAY"},
608 {GLINSETIDDELAY, "GLINSETIDDELAY"},
609 {GLINGETRESPDELAY, "GLINGETRESPDELAY"},
610 {GLINSETRESPDELAY, "GLINSETRESPDELAY"},
611 {GLINGETINTERBYTE, "GLINGETINTERBYTE"},
612 {GLINSETINTERBYTE, "GLINSETINTERBYTE"},
613 {GLINGETWAKEUPDELAY, "GLINGETWAKEUPDELAY"},
614 {GLINSETWAKEUPDELAY, "GLINSETWAKEUPDELAY"},
615 {GLINGETWAKEUPTIMEOUT, "GLINGETWAKEUPTIMEOUT"},
616 {GLINSETWAKEUPTIMEOUT, "GLINSETWAKEUPTIMEOUT"},
617 {GLINGETWUTIMOUT3BR, "GLINGETWUTIMOUT3BR"},
618 {GLINSETWUTIMOUT3BR, "GLINSETWUTIMOUT3BR"},
619 {GLINSENDWAKEUP, "GLINSENDWAKEUP"},
620 {GLINGETMODE, "GLINGETMODE"},
621 {GLINSETMODE, "GLINSETMODE"},
622 {GINPGETINP, "GINPGETINP: Read current digital inputs"},
623 {GINPGETLATCH, "GINPGETLATCH: Read latched digital inputs"},
624 {GINPCLRLATCH, "GINPCLRLATCH: Read and clear latched digital inputs"},
625 {GOUTGET, "GOUTGET: Read digital outputs"},
626 {GOUTSET, "GOUTSET: Write digital outputs"},
627 {GOUTSETBIT, "GOUTSETBIT: Set digital output bits"},
628 {GOUTCLEARBIT, "GOUTCLEARBIT"},
629 {GPWRGETWHICH, "GPWRGETWHICH"},
630 {GPWROFF, "GPWROFF"},
631 {GPWROFFRESET, "GPWROFFRESET"},
632 {GPWRRESET, "GPWRRESET"},
641 decode_command(tvbuff_t *tvb, int offset, int dst, proto_tree *pt)
643 int cmd, padding, msglen;
648 msglen = tvb_reported_length_remaining(tvb, offset);
649 cmd = tvb_get_guint8(tvb, offset);
650 proto_tree_add_uint_hidden(pt, hf_gryph_cmd, tvb, offset, 1, cmd);
654 for (i = 0; i < SIZEOF(cmds); i++) {
655 if (cmds[i].value == cmd)
658 if (i >= SIZEOF(cmds) && dst >= SD_KNOWN) {
659 cmd = (cmd & 0xFF) + SD_CARD * 256;
660 for (i = 0; i < SIZEOF(cmds); i++) {
661 if (cmds[i].value == cmd)
665 if (i >= SIZEOF(cmds))
666 i = SIZEOF(cmds) - 1;
668 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
672 if (cmds[i].cmd_fnct && msglen > 0) {
673 padding = 3 - (msglen + 3) % 4;
674 ti = proto_tree_add_text(pt, tvb, offset, -1, "Data: (%d byte%s)",
675 msglen, msglen == 1 ? "" : "s");
676 ft = proto_item_add_subtree(ti, ett_gryphon_command_data);
677 offset = (*(cmds[i].cmd_fnct)) (tvb, offset, ft);
683 decode_response(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
686 unsigned int i, resp;
690 msglen = tvb_reported_length_remaining(tvb, offset);
691 cmd = tvb_get_guint8(tvb, offset);
695 for (i = 0; i < SIZEOF(cmds); i++) {
696 if (cmds[i].value == cmd)
699 if (i >= SIZEOF(cmds) && src >= SD_KNOWN) {
700 cmd = (cmd & 0xFF) + SD_CARD * 256;
701 for (i = 0; i < SIZEOF(cmds); i++) {
702 if (cmds[i].value == cmd)
706 if (i >= SIZEOF(cmds))
707 i = SIZEOF(cmds) - 1;
708 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
712 resp = tvb_get_ntohl (tvb, offset);
713 proto_tree_add_text (pt, tvb, offset, 4, "Status: %s",
714 val_to_str(resp, responses, "Unknown (0x%08x)"));
718 if (cmds[i].rsp_fnct && msglen > 0) {
719 ti = proto_tree_add_text(pt, tvb, offset, msglen, "Data: (%d byte%s)",
720 msglen, msglen == 1 ? "" : "s");
721 ft = proto_item_add_subtree(ti, ett_gryphon_response_data);
722 offset = (*(cmds[i].rsp_fnct)) (tvb, offset, ft);
728 decode_data(tvbuff_t *tvb, int offset, proto_tree *pt)
730 proto_item *item, *item1;
731 proto_tree *tree, *tree1;
732 int hdrsize, datasize, extrasize, hdrbits, msgsize, padding, mode;
733 int hours, minutes, seconds, fraction;
734 unsigned long timestamp;
736 hdrsize = tvb_get_guint8(tvb, offset+0);
737 hdrbits = tvb_get_guint8(tvb, offset+1);
738 datasize = tvb_get_ntohs(tvb, offset+2);
739 extrasize = tvb_get_guint8(tvb, offset+4);
740 padding = 3 - (hdrsize + datasize + extrasize + 3) % 4;
741 msgsize = hdrsize + datasize + extrasize + padding + 16;
743 item = proto_tree_add_text(pt, tvb, offset, 16, "Message header");
744 tree = proto_item_add_subtree (item, ett_gryphon_data_header);
745 proto_tree_add_text(tree, tvb, offset, 2, "Header length: %d byte%s, %d bits",
746 hdrsize, plurality(hdrsize, "", "s"), hdrbits);
747 proto_tree_add_text(tree, tvb, offset+2, 2, "Data length: %d byte%s",
748 datasize, plurality(datasize, "", "s"));
749 proto_tree_add_text(tree, tvb, offset+4, 1, "Extra data length: %d byte%s",
750 extrasize, plurality(extrasize, "", "s"));
751 mode = tvb_get_guint8(tvb, offset+5);
752 item1 = proto_tree_add_text(tree, tvb, offset+5, 1, "Mode: %d", mode);
754 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
756 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
757 decode_boolean_bitfield(mode, 0x80, 8,
758 "Transmitted message", NULL));
761 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
762 decode_boolean_bitfield(mode, 0x40, 8,
763 "Received message", NULL));
766 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
767 decode_boolean_bitfield(mode, 0x20, 8,
768 "Local message", NULL));
771 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
772 decode_boolean_bitfield(mode, 0x10, 8,
773 "Remote message", NULL));
776 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
777 decode_boolean_bitfield(mode, 0x01, 8,
778 "Internal message", NULL));
781 proto_tree_add_text(tree, tvb, offset+6, 1, "Priority: %u",
782 tvb_get_guint8(tvb, offset+6));
783 proto_tree_add_text(tree, tvb, offset+7, 1, "Error status: %u",
784 tvb_get_guint8(tvb, offset+7));
785 timestamp = tvb_get_ntohl(tvb, offset+8);
786 hours = timestamp /(100000 * 60 *60);
787 minutes = (timestamp / (100000 * 60)) % 60;
788 seconds = (timestamp / 100000) % 60;
789 fraction = timestamp % 100000;
790 proto_tree_add_text(tree, tvb, offset+8, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
791 proto_tree_add_text(tree, tvb, offset+12, 1, "Context: %u",
792 tvb_get_guint8(tvb, offset+12));
793 proto_tree_add_text(tree, tvb, offset+13, 3, "reserved:");
795 item = proto_tree_add_text(pt, tvb, offset, msgsize-16-padding, "Message Body");
796 tree = proto_item_add_subtree (item, ett_gryphon_data_body);
798 proto_tree_add_text(tree, tvb, offset, hdrsize, "Header");
802 proto_tree_add_text(tree, tvb, offset, datasize, "Data");
806 proto_tree_add_text(tree, tvb, offset, extrasize, "Extra data");
810 proto_tree_add_text(pt, tvb, offset, padding, "padding");
817 decode_event(tvbuff_t *tvb, int offset, proto_tree *pt)
820 int hours, minutes, seconds, fraction, padding, length;
821 unsigned long timestamp;
824 msglen = tvb_reported_length_remaining(tvb, offset);
825 padding = 3 - (msglen + 3) % 4;
826 msgend = offset + msglen;
827 proto_tree_add_text(pt, tvb, offset, 1, "Event ID: %u",
828 tvb_get_guint8(tvb, offset));
829 proto_tree_add_text(pt, tvb, offset+1, 1, "Event context: %u",
830 tvb_get_guint8(tvb, offset+1));
831 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
833 timestamp = tvb_get_ntohl(tvb, offset);
834 hours = timestamp /(100000 * 60 *60);
835 minutes = (timestamp / (100000 * 60)) % 60;
836 seconds = (timestamp / 100000) % 60;
837 fraction = timestamp % 100000;
838 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
840 if (offset < msgend) {
841 length = msgend - offset;
842 proto_tree_add_text (pt, tvb, offset, length, "Data (%d byte%s)",
843 length, length == 1 ? "" : "s");
847 proto_tree_add_text(pt, tvb, offset, padding, "padding");
854 decode_misc (tvbuff_t *tvb, int offset, proto_tree *pt)
859 unsigned char local_data[LENGTH+1];
861 msglen = tvb_reported_length_remaining(tvb, offset);
862 padding = 3 - (msglen + 3) % 4;
863 length = tvb_get_nstringz0(tvb, offset, LENGTH, local_data);
864 proto_tree_add_text(pt, tvb, offset, msglen, "Data: %s", local_data);
867 proto_tree_add_text (pt, tvb, offset, padding, "padding");
874 cmd_init(tvbuff_t *tvb, int offset, proto_tree *pt)
878 if (tvb_get_guint8(tvb, offset) == 0)
879 ptr = "Always initialize";
881 ptr = "Initialize if not previously initialized";
882 proto_tree_add_text(pt, tvb, offset, 1, "Mode: %s", ptr);
883 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
889 eventnum(tvbuff_t *tvb, int offset, proto_tree *pt)
891 guint8 event = tvb_get_guint8(tvb, offset);
894 proto_tree_add_text(pt, tvb, offset, 1, "Event number: %u", event);
896 proto_tree_add_text(pt, tvb, offset, 1, "Event numbers: All");
897 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
903 resp_time(tvbuff_t *tvb, int offset, proto_tree *pt)
908 static const char *mon_names[12] = {
923 ts = tvb_get_ntoh64(tvb, offset);
924 timestamp = (time_t) (ts / 100000);
925 tmp = localtime(×tamp);
926 proto_tree_add_text(pt, tvb, offset, 8,
927 "Date/Time: %s %d, %d %02d:%02d:%02d.%05u",
928 mon_names[tmp->tm_mon],
934 (guint) (ts % 100000));
940 cmd_setfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
942 int flag = tvb_get_ntohl(tvb, offset);
946 length = tvb_get_guint8(tvb, offset+4) + tvb_get_guint8(tvb, offset+5)
947 + tvb_get_ntohs(tvb, offset+6);
949 strcpy (mode, "Pass");
951 strcpy (mode, "Block");
953 strcat (mode, " all");
954 proto_tree_add_text(pt, tvb, offset, 4, "Pass/Block flag: %s", mode);
955 proto_tree_add_text(pt, tvb, offset+4, 4, "Length of Pattern & Mask: %d", length);
958 proto_tree_add_text(pt, tvb, offset, length * 2, "discarded data");
959 offset += length * 2;
961 padding = 3 - (length * 2 + 3) % 4;
963 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
970 cmd_ioctl(tvbuff_t *tvb, int offset, proto_tree *pt)
975 msglen = tvb_reported_length_remaining(tvb, offset);
976 ioctl = tvb_get_ntohl(tvb, offset);
977 proto_tree_add_text(pt, tvb, offset, 4, "IOCTL: %s",
978 val_to_str(ioctl, ioctls, "Unknown (0x%08x)"));
982 proto_tree_add_text(pt, tvb, offset, msglen, "Data");
989 cmd_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
994 int blocks, i, length;
996 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags");
997 tree = proto_item_add_subtree (item, ett_gryphon_flags);
998 flags = tvb_get_guint8(tvb, offset);
999 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1000 decode_boolean_bitfield(flags, FILTER_PASS_FLAG, 8,
1001 "Conforming messages are passed",
1002 "Conforming messages are blocked"));
1003 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1004 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1005 "The filter is active", "The filter is inactive"));
1007 blocks = tvb_get_guint8(tvb, offset);
1008 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1009 proto_tree_add_text(pt, tvb, offset+1, 6, "reserved");
1011 for (i = 1; i <= blocks; i++) {
1012 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1013 length += 3 - (length + 3) % 4;
1014 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1015 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1016 offset = filter_block(tvb, offset, tree);
1022 resp_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
1024 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
1025 tvb_get_guint8(tvb, offset));
1026 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1032 cmd_modfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
1034 guint8 filter_handle;
1035 unsigned char action;
1037 filter_handle = tvb_get_guint8(tvb, offset);
1039 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
1042 proto_tree_add_text(pt, tvb, offset, 1, "Filter handles: all");
1043 action = tvb_get_guint8(tvb, offset + 1);
1044 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s filter",
1045 val_to_str(action, filtacts, "Unknown (%u)"));
1046 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1052 resp_filthan(tvbuff_t *tvb, int offset, proto_tree *pt)
1054 int handles = tvb_get_guint8(tvb, offset);
1057 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter handles: %d", handles);
1058 for (i = 1; i <= handles; i++){
1059 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1060 tvb_get_guint8(tvb, offset+i));
1062 padding = 3 - (handles + 1 + 3) % 4;
1064 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1065 offset += 1+handles+padding;
1070 dfiltmode(tvbuff_t *tvb, int offset, proto_tree *pt)
1074 mode = tvb_get_guint8(tvb, offset);
1075 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
1076 val_to_str(mode, dmodes, "Unknown (%u)"));
1077 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1083 filtmode(tvbuff_t *tvb, int offset, proto_tree *pt)
1087 mode = tvb_get_guint8(tvb, offset);
1088 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
1089 val_to_str(mode, modes, "Unknown (%u)"));
1090 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1096 resp_events(tvbuff_t *tvb, int offset, proto_tree *pt)
1103 msglen = tvb_reported_length_remaining(tvb, offset);
1105 while (msglen != 0) {
1106 item = proto_tree_add_text(pt, tvb, offset, 20, "Event %d:", i);
1107 tree = proto_item_add_subtree (item, ett_gryphon_cmd_events_data);
1108 proto_tree_add_text(tree, tvb, offset, 1, "Event ID: %u",
1109 tvb_get_guint8(tvb, offset));
1110 proto_tree_add_text(tree, tvb, offset+1, 19, "Event name: %.19s",
1111 tvb_get_ptr(tvb, offset+1, 19));
1120 cmd_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1122 proto_tree_add_text(pt, tvb, offset, 16, "Username: %.16s",
1123 tvb_get_ptr(tvb, offset, 16));
1125 proto_tree_add_text(pt, tvb, offset, 32, "Password: %.32s",
1126 tvb_get_ptr(tvb, offset, 32));
1132 resp_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1134 proto_tree_add_text(pt, tvb, offset, 1, "Client ID: %u",
1135 tvb_get_guint8(tvb, offset));
1136 proto_tree_add_text(pt, tvb, offset+1, 1, "Privileges: %u",
1137 tvb_get_guint8(tvb, offset+1));
1138 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1145 resp_getspeeds(tvbuff_t *tvb, int offset, proto_tree *pt)
1151 proto_tree_add_text(pt, tvb, offset, 4, "Set Speed IOCTL");
1152 proto_tree_add_text(pt, tvb, offset+4, 4, "Get Speed IOCTL");
1153 size = tvb_get_guint8(tvb, offset+8);
1154 proto_tree_add_text(pt, tvb, offset+8, 1, "Speed data size is %d byte%s",
1155 size, size == 1 ? "" : "s");
1156 number = tvb_get_guint8(tvb, offset+9);
1157 proto_tree_add_text(pt, tvb, offset+9, 1, "There %s %d preset speed%s",
1158 number == 1 ? "is" : "are", number, number == 1 ? "" : "s");
1160 for (index = 0; index < number; index++) {
1161 proto_tree_add_text(pt, tvb, offset, size, "Data for preset %d",
1169 cmd_sort(tvbuff_t *tvb, int offset, proto_tree *pt)
1173 which = tvb_get_guint8(tvb, offset) ?
1174 "Sort into blocks of up to 16 messages" :
1175 "Do not sort messages";
1176 proto_tree_add_text(pt, tvb, offset, 1, "Set sorting: %s", which);
1182 cmd_optimize(tvbuff_t *tvb, int offset, proto_tree *pt)
1186 which = tvb_get_guint8(tvb, offset) ?
1187 "Optimize for latency (Nagle algorithm disabled)" :
1188 "Optimize for throughput (Nagle algorithm enabled)";
1189 proto_tree_add_text(pt, tvb, offset, 1, "Set optimization: %s", which);
1195 resp_config(tvbuff_t *tvb, int offset, proto_tree *pt)
1197 proto_item *ti, *item;
1198 proto_tree *ft, *tree;
1203 static const value_string protocol_types[] = {
1204 {GDUMMY * 256 + GDGDMARKONE, "Dummy device driver"},
1205 {GCAN * 256 + G82527, "CAN, 82527 subtype"},
1206 {GCAN * 256 + GSJA1000, "CAN, SJA1000 subtype"},
1207 {GCAN * 256 + G82527SW, "CAN, 82527 single wire subtype"},
1208 {GCAN * 256 + G82527ISO11992, "CAN, 82527 ISO11992 subtype"},
1209 {GCAN * 256 + G82527_SINGLECHAN, "CAN, Fiber Optic 82527 subtype"},
1210 {GCAN * 256 + G82527SW_SINGLECHAN, "CAN, Fiber Optic 82527 single wire subtype"},
1211 {GCAN * 256 + G82527ISO11992_SINGLECHAN, "CAN, Fiber Optic ISO11992 subtype"},
1212 {GCAN * 256 + GSJA1000FT, "CAN, SJA1000 Fault Tolerant subtype"},
1213 {GCAN * 256 + GSJA1000C, "CAN, SJA1000 onboard subtype"},
1214 {GCAN * 256 + GSJA1000FT_FO, "CAN, SJA1000 Fiber Optic Fault Tolerant subtype"},
1215 {GJ1850 * 256 + GHBCCPAIR, "J1850, HBCC subtype"},
1216 {GJ1850 * 256 + GDLC, "J1850, GM DLC subtype"},
1217 {GJ1850 * 256 + GCHRYSLER, "J1850, Chrysler subtype"},
1218 {GJ1850 * 256 + GDEHC12, "J1850, DE HC12 KWP/BDLC subtype"},
1219 {GKWP2000 * 256 + GDEHC12KWP, "Keyword protocol 2000/ISO 9141"},
1220 {GHONDA * 256 + GDGHC08, "Honda UART, DG HC08 subtype"},
1221 {GFORDUBP * 256 + GDGUBP08, "Ford UBP, DG HC08 subtype"},
1222 {GSCI * 256 + G16550SCI, "Chrysler SCI, UART subtype"},
1223 {GCCD * 256 + G16550CDP68HC68, "Chrysler C2D, UART / CDP68HC68S1 subtype"},
1224 {GLIN * 256 + GDGLIN08, "LIN, DG HC08 subtype"},
1228 proto_tree_add_text(pt, tvb, offset, 20, "Device name: %.20s",
1229 tvb_get_ptr(tvb, offset, 20));
1232 proto_tree_add_text(pt, tvb, offset, 8, "Device version: %.8s",
1233 tvb_get_ptr(tvb, offset, 8));
1236 proto_tree_add_text(pt, tvb, offset, 20, "Device serial number: %.20s",
1237 tvb_get_ptr(tvb, offset, 20));
1240 devices = tvb_get_guint8(tvb, offset);
1241 proto_tree_add_text(pt, tvb, offset, 1, "Number of channels: %d", devices);
1242 proto_tree_add_text(pt, tvb, offset+1, 11, "Name & version extension: %.11s",
1243 tvb_get_ptr(tvb, offset+1, 11));
1244 proto_tree_add_text(pt, tvb, offset+12, 4, "reserved");
1246 for (i = 1; i <= devices; i++) {
1247 ti = proto_tree_add_text(pt, tvb, offset, 80, "Channel %d:", i);
1248 ft = proto_item_add_subtree(ti, ett_gryphon_cmd_config_device);
1249 proto_tree_add_text(ft, tvb, offset, 20, "Driver name: %.20s",
1250 tvb_get_ptr(tvb, offset, 20));
1253 proto_tree_add_text(ft, tvb, offset, 8, "Driver version: %.8s",
1254 tvb_get_ptr(tvb, offset, 8));
1257 proto_tree_add_text(ft, tvb, offset, 16, "Device security string: %.16s",
1258 tvb_get_ptr(tvb, offset, 16));
1261 x = tvb_get_ntohl (tvb, offset);
1263 item = proto_tree_add_text(ft, tvb, offset, 4, "Valid Header lengths");
1264 tree = proto_item_add_subtree (item, ett_gryphon_valid_headers);
1265 for (j = 0; ; j++) {
1267 proto_tree_add_text(tree, tvb, offset, 4, "%d byte%s", j,
1276 x = tvb_get_ntohs (tvb, offset);
1277 proto_tree_add_text(ft, tvb, offset, 2, "Maximum data length = %d byte%s",
1278 x, x == 1 ? "" : "s");
1281 x = tvb_get_ntohs (tvb, offset);
1282 proto_tree_add_text(ft, tvb, offset, 2, "Minimum data length = %d byte%s",
1283 x, x == 1 ? "" : "s");
1286 proto_tree_add_text(ft, tvb, offset, 20, "Hardware serial number: %.20s",
1287 tvb_get_ptr(tvb, offset, 20));
1290 x = tvb_get_ntohs(tvb, offset);
1291 proto_tree_add_text(ft, tvb, offset, 2, "Protocol type & subtype: %s",
1292 val_to_str(x, protocol_types, "Unknown (0x%04x)"));
1295 proto_tree_add_text(ft, tvb, offset, 1, "Channel ID: %u",
1296 tvb_get_guint8(tvb, offset));
1299 proto_tree_add_text(ft, tvb, offset, 1, "Card slot number: %u",
1300 tvb_get_guint8(tvb, offset));
1303 x = tvb_get_ntohs (tvb, offset);
1304 proto_tree_add_text(ft, tvb, offset, 2, "Maximum extra data = %d byte%s",
1305 x, x == 1 ? "" : "s");
1308 x = tvb_get_ntohs (tvb, offset);
1309 proto_tree_add_text(ft, tvb, offset, 2, "Minimum extra data = %d byte%s",
1310 x, x == 1 ? "" : "s");
1318 cmd_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1321 proto_item *item, *item1;
1322 proto_tree *tree, *tree1;
1324 unsigned int i, x, length;
1325 unsigned char def_chan = tvb_get_guint8(tvb, offset-9);
1327 msglen = tvb_reported_length_remaining(tvb, offset);
1328 x = tvb_get_ntohl(tvb, offset);
1329 if (x == 0xFFFFFFFF)
1330 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: \"infinite\"");
1332 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: %u", x);
1335 x = tvb_get_ntohl(tvb, offset);
1336 item = proto_tree_add_text(pt, tvb, offset, 4, "Flags: 0x%08x", x);
1337 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1338 proto_tree_add_text(tree, tvb, offset, 4, "%s",
1339 decode_boolean_bitfield(x, 0x01, 32,
1340 "Critical scheduler", "Normal scheduler"));
1344 while (msglen > 0) {
1345 length = 16 + tvb_get_guint8(tvb, offset+16) +
1346 tvb_get_ntohs(tvb, offset+18) + tvb_get_guint8(tvb, offset+20) + 16;
1347 length += 3 - (length + 3) % 4;
1348 item = proto_tree_add_text(pt, tvb, offset, length, "Message %d", i);
1349 tree = proto_item_add_subtree (item, ett_gryphon_cmd_sched_data);
1350 x = tvb_get_ntohl(tvb, offset);
1351 proto_tree_add_text(tree, tvb, offset, 4, "Sleep: %u milliseconds", x);
1354 x = tvb_get_ntohl(tvb, offset);
1355 proto_tree_add_text(tree, tvb, offset, 4, "Transmit count: %u", x);
1358 x = tvb_get_ntohl(tvb, offset);
1359 proto_tree_add_text(tree, tvb, offset, 4, "Transmit period: %u milliseconds", x);
1362 x = tvb_get_ntohs(tvb, offset);
1363 item1 = proto_tree_add_text(tree, tvb, offset, 2, "Flags");
1364 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
1365 proto_tree_add_text(tree1, tvb, offset, 2, "%s%s",
1366 decode_boolean_bitfield(x, 1, 16, "S", "Do not s"),
1367 "kip the last \"Transmit period\"");
1369 proto_tree_add_text(tree1, tvb, offset, 2, "%s%s",
1370 decode_boolean_bitfield(x, 2, 16, "S", "Do not s"),
1371 "kip the first \"Sleep\" value");
1373 x = tvb_get_guint8(tvb, offset+2);
1376 proto_tree_add_text(tree, tvb, offset+2, 1, "Channel: %u", x);
1377 proto_tree_add_text(tree, tvb, offset+3, 1, "reserved");
1380 item1 = proto_tree_add_text(tree, tvb, offset, length, "Message");
1381 tree1 = proto_item_add_subtree (item1, ett_gryphon_cmd_sched_cmd);
1382 save_offset = offset;
1383 offset = decode_data(tvb, offset, tree1);
1384 msglen -= offset - save_offset;
1391 cmd_sched_rep(tvbuff_t *tvb, int offset, proto_tree *pt)
1399 msglen = tvb_reported_length_remaining(tvb, offset);
1400 x = tvb_get_ntohl(tvb, offset);
1405 proto_tree_add_text(pt, tvb, offset, 4, "%s schedule ID: %u", type, x);
1408 x= tvb_get_guint8(tvb, offset);
1409 item = proto_tree_add_text(pt, tvb, offset, 1, "Message index: %d", x);
1410 item = proto_tree_add_text(pt, tvb, offset + 1, 3, "reserved");
1413 save_offset = offset;
1414 offset = decode_data(tvb, offset, pt);
1415 msglen -= offset - save_offset;
1420 resp_blm_data(tvbuff_t *tvb, int offset, proto_tree *pt)
1423 int hours, minutes, seconds, fraction, x, fract;
1424 unsigned long timestamp;
1425 static char *fields[] = {
1426 "Bus load average: %d.%02d%%",
1427 "Current bus load: %d.%02d%%",
1428 "Peak bus load: %d.%02d%%",
1429 "Historic peak bus load: %d.%02d%%"
1432 timestamp = tvb_get_ntohl(tvb, offset);
1433 hours = timestamp /(100000 * 60 *60);
1434 minutes = (timestamp / (100000 * 60)) % 60;
1435 seconds = (timestamp / 100000) % 60;
1436 fraction = timestamp % 100000;
1437 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
1439 for (i = 0; i < SIZEOF(fields); i++){
1440 x = tvb_get_ntohs(tvb, offset);
1443 proto_tree_add_text(pt, tvb, offset, 2, fields[i], x, fract);
1450 resp_blm_stat(tvbuff_t *tvb, int offset, proto_tree *pt)
1454 "Receive frame count: %u",
1455 "Transmit frame count: %u",
1456 "Receive dropped frame count: %u",
1457 "Transmit dropped frame count: %u",
1458 "Receive error count: %u",
1459 "Transmit error count: %u",
1462 offset = resp_blm_data(tvb, offset, pt);
1463 for (i = 0; i < SIZEOF(fields); i++){
1464 x = tvb_get_ntohl(tvb, offset);
1465 proto_tree_add_text(pt, tvb, offset, 4, fields[i], x);
1471 static const value_string action_vals[] = {
1472 { FR_RESP_AFTER_EVENT, "Send response(s) for each conforming message" },
1473 { FR_RESP_AFTER_PERIOD, "Send response(s) after the specified period expires following a conforming message" },
1474 { FR_IGNORE_DURING_PER, "Send response(s) for a conforming message and ignore\nfurther messages until the specified period expires" },
1478 static const value_string deact_on_event_vals[] = {
1479 { FR_DEACT_ON_EVENT,
1480 "Deactivate this response for a conforming message" },
1481 { FR_DELETE|FR_DEACT_ON_EVENT,
1482 "Delete this response for a conforming message" },
1487 static const value_string deact_after_per_vals[] = {
1488 { FR_DEACT_AFTER_PER,
1489 "Deactivate this response after the specified period following a conforming message" },
1490 { FR_DELETE|FR_DEACT_AFTER_PER,
1491 "Delete this response after the specified period following a conforming message" },
1497 cmd_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1502 int blocks, responses, old_handle, i, msglen, length;
1503 int action, actionType, actionValue;
1507 flags = tvb_get_guint8(tvb, offset);
1508 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1509 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1510 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1511 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1512 "The response is active", "The response is inactive"));
1514 blocks = tvb_get_guint8(tvb, offset);
1515 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1517 responses = tvb_get_guint8(tvb, offset);
1518 proto_tree_add_text(pt, tvb, offset, 1, "Number of response blocks = %d", responses);
1520 old_handle = tvb_get_guint8(tvb, offset);
1521 proto_tree_add_text(pt, tvb, offset, 1, "Old handle = %d", old_handle);
1523 action = tvb_get_guint8(tvb, offset);
1524 item = proto_tree_add_text(pt, tvb, offset, 1, "Action: %s",
1525 val_to_str(action & 0x07, action_vals, "Unknown (%u)"));
1526 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1527 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1528 decode_enumerated_bitfield(action, 0x07, 8, action_vals, "%s"));
1529 actionValue = tvb_get_ntohs(tvb, offset+2);
1531 if (action & FR_PERIOD_MSGS) {
1536 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1537 decode_boolean_bitfield(action, FR_PERIOD_MSGS, 8,
1538 "The period is in frames", "The period is in 0.01 seconds"));
1540 if (action & FR_DEACT_ON_EVENT) {
1541 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1542 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_ON_EVENT, 8,
1543 deact_on_event_vals, "%s"));
1545 if (action & FR_DEACT_AFTER_PER) {
1546 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1547 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_AFTER_PER, 8,
1548 deact_after_per_vals, "%s"));
1551 proto_tree_add_text(pt, tvb, offset, 1, "reserved");
1554 if (actionType == 1) {
1555 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d messages", actionValue);
1557 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d.%02d seconds", actionValue/100, actionValue%100);
1561 for (i = 1; i <= blocks; i++) {
1562 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1563 length += 3 - (length + 3) % 4;
1564 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1565 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1566 offset = filter_block(tvb, offset, tree);
1568 for (i = 1; i <= responses; i++) {
1569 msglen = tvb_get_ntohs(tvb, offset+4) + 8;
1570 length = msglen + 3 - (msglen + 3) % 4;
1571 item = proto_tree_add_text(pt, tvb, offset, length, "Response block %d", i);
1572 tree = proto_item_add_subtree (item, ett_gryphon_cmd_response_block);
1573 next_tvb = tvb_new_subset(tvb, offset, msglen, msglen);
1574 dissect_gryphon_message(next_tvb, NULL, tree, TRUE);
1581 resp_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1583 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1584 tvb_get_guint8(tvb, offset));
1585 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1591 cmd_modresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1593 unsigned char action;
1594 unsigned char dest = tvb_get_guint8(tvb, offset-5);
1597 resp_handle = tvb_get_guint8(tvb, offset);
1599 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1602 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all on channel %hd", dest);
1604 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all");
1605 action = tvb_get_guint8(tvb, offset+1);
1606 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s response",
1607 val_to_str(action, filtacts, "Unknown (%u)"));
1608 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1614 resp_resphan(tvbuff_t *tvb, int offset, proto_tree *pt)
1616 int handles = tvb_get_guint8(tvb, offset);
1619 proto_tree_add_text(pt, tvb, offset, 1, "Number of response handles: %d", handles);
1620 for (i = 1; i <= handles; i++){
1621 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1622 tvb_get_guint8(tvb, offset+i));
1624 padding = 3 - (handles + 1 + 3) % 4;
1626 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1627 offset += 1+handles+padding;
1632 resp_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1634 unsigned int id = tvb_get_ntohl(tvb, offset);
1636 proto_tree_add_text(pt, tvb, offset, 4, "Transmit schedule ID: %u", id);
1642 cmd_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1644 proto_tree_add_text(pt, tvb, offset, 4, "Program size: %u bytes",
1645 tvb_get_ntohl(tvb, offset));
1647 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1648 tvb_get_ptr(tvb, offset, 32));
1650 proto_tree_add_text(pt, tvb, offset, 80, "Program description: %.80s",
1651 tvb_get_ptr(tvb, offset, 80));
1657 resp_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1663 flags = tvb_get_guint8(tvb, offset);
1664 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1665 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1666 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1667 decode_boolean_bitfield(flags, 0x01, 8,
1668 "The program is already present",
1669 "The program is not present"));
1670 proto_tree_add_text(pt, tvb, offset+1, 1, "Handle: %u",
1671 tvb_get_guint8(tvb, offset+1));
1672 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1678 cmd_upload(tvbuff_t *tvb, int offset, proto_tree *pt)
1681 unsigned int length;
1683 msglen = tvb_reported_length_remaining(tvb, offset);
1684 proto_tree_add_text(pt, tvb, offset, 2, "Block number: %u",
1685 tvb_get_ntohs(tvb, offset));
1686 proto_tree_add_text(pt, tvb, offset+2, 1, "Handle: %u",
1687 tvb_get_guint8(tvb, offset+2));
1691 proto_tree_add_text(pt, tvb, offset, length, "Data (%u byte%s)",
1692 length, length == 1 ? "" : "s");
1694 length = 3 - (length + 3) % 4;
1696 proto_tree_add_text(pt, tvb, offset, length, "padding");
1703 cmd_delete(tvbuff_t *tvb, int offset, proto_tree *pt)
1705 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1706 tvb_get_ptr(tvb, offset, 32));
1712 cmd_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1714 proto_tree_add_text(pt, tvb, offset, 1, "Block number: %u",
1715 tvb_get_guint8(tvb, offset));
1716 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1722 resp_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1726 unsigned int i, count;
1728 count = tvb_get_guint8(tvb, offset);
1729 proto_tree_add_text(pt, tvb, offset, 1, "Number of programs in this response: %u", count);
1730 proto_tree_add_text(pt, tvb, offset+1, 1, "reserved");
1732 proto_tree_add_text(pt, tvb, offset, 2, "Number of remaining programs: %u",
1733 tvb_get_ntohs(tvb, offset));
1735 for (i = 1; i <= count; i++) {
1736 item = proto_tree_add_text(pt, tvb, offset, 112, "Program %u", i);
1737 tree = proto_item_add_subtree (item, ett_gryphon_pgm_list);
1738 proto_tree_add_text(tree, tvb, offset, 32, "Name: %.32s",
1739 tvb_get_ptr(tvb, offset, 32));
1741 proto_tree_add_text(tree, tvb, offset, 80, "Description: %.80s",
1742 tvb_get_ptr(tvb, offset, 80));
1749 cmd_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1754 int hdr_stuff = offset;
1756 msglen = tvb_reported_length_remaining(tvb, offset);
1757 offset = cmd_delete(tvb, offset, pt); /* decode the name */
1758 if (offset < msglen + hdr_stuff) {
1759 string = tvb_get_stringz(tvb, offset, &length);
1761 proto_tree_add_text(pt, tvb, offset, length, "Arguments: %s", string);
1763 length = 3 - (length + 3) % 4;
1765 proto_tree_add_text(pt, tvb, offset, length, "padding");
1775 resp_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1779 msglen = tvb_reported_length_remaining(tvb, offset);
1781 proto_tree_add_text(pt, tvb, offset, 1, "Channel (Client) number: %u",
1782 tvb_get_guint8(tvb, offset));
1783 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1790 resp_status(tvbuff_t *tvb, int offset, proto_tree *pt)
1794 unsigned int i, copies, length;
1796 copies = tvb_get_guint8(tvb, offset);
1797 item = proto_tree_add_text(pt, tvb, offset, 1, "Number of running copies: %u", copies);
1798 tree = proto_item_add_subtree (item, ett_gryphon_pgm_status);
1801 for (i = 1; i <= copies; i++) {
1802 proto_tree_add_text(tree, tvb, offset, 1, "Program %u channel (client) number %u",
1803 i, tvb_get_guint8(tvb, offset));
1807 length = 3 - (copies + 1 + 3) % 4;
1809 proto_tree_add_text(pt, tvb, offset, length, "padding");
1816 cmd_options(tvbuff_t *tvb, int offset, proto_tree *pt)
1821 unsigned int i, size, padding, option, option_length, option_value;
1822 char *string, *string1;
1824 msglen = tvb_reported_length_remaining(tvb, offset);
1825 item = proto_tree_add_text(pt, tvb, offset, 1, "Handle: %u",
1826 tvb_get_guint8(tvb, offset));
1827 item = proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1830 for (i = 1; msglen > 0; i++) {
1831 option_length = tvb_get_guint8(tvb, offset+1);
1832 size = option_length + 2;
1833 padding = 3 - ((size + 3) %4);
1834 item = proto_tree_add_text(pt, tvb, offset, size + padding, "Option number %u", i);
1835 tree = proto_item_add_subtree (item, ett_gryphon_pgm_options);
1836 option = tvb_get_guint8(tvb, offset);
1837 switch (option_length) {
1839 option_value = tvb_get_guint8(tvb, offset+2);
1842 option_value = tvb_get_ntohs(tvb, offset+2);
1845 option_value = tvb_get_ntohl(tvb, offset+2);
1850 string = "unknown option";
1851 string1 = "unknown option data";
1854 string = "Type of data in the file";
1855 switch (option_value) {
1857 string1 = "Binary - Don't modify";
1860 string1 = "ASCII - Remove CR's";
1865 string = "Type of file";
1866 switch (option_value) {
1868 string1 = "Executable";
1876 proto_tree_add_text(tree, tvb, offset, 1, "%s", string);
1877 proto_tree_add_text(tree, tvb, offset+2, option_length, "%s", string1);
1879 proto_tree_add_text(tree, tvb, offset+option_length+2, padding, "padding");
1880 offset += size + padding;
1881 msglen -= size + padding;
1887 cmd_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1892 msglen = tvb_reported_length_remaining(tvb, offset);
1893 if (tvb_get_guint8(tvb, offset) == 0)
1894 which = "First group of names";
1896 which = "Subsequent group of names";
1898 proto_tree_add_text(pt, tvb, offset, 1, "%s", which);
1899 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "Directory: %.*s",
1900 msglen-1, tvb_get_ptr(tvb, offset+1, msglen-1));
1906 resp_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1911 msglen = tvb_reported_length_remaining(tvb, offset);
1912 flag = tvb_get_guint8(tvb, offset) ? "Yes": "No";
1913 proto_tree_add_text(pt, tvb, offset, 1, "More filenames to return: %s", flag);
1914 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "File and directory names");
1920 cmd_usdt(tvbuff_t *tvb, int offset, proto_tree *pt)
1922 int ids, id, remain, size, i, j, bytes;
1925 proto_tree *localTree;
1926 proto_item *localItem;
1927 gchar *actions[] = {"Use 11 bit headers only",
1928 "Use 29 bit headers only",
1929 "Use both 11 & 29 bit headers",
1931 gchar *xmit_opts[] = {"Pad messages with less than 8 data bytes with 0x00's",
1932 "Pad messages with less than 8 data bytes with 0xFF's",
1933 "Do not pad messages with less than 8 data bytes",
1935 gchar *recv_opts[] = {"Do not verify the integrity of long received messages and do not send them to the client",
1936 "Verify the integrity of long received messages and send them to the client",
1937 "Verify the integrity of long received messages but do not send them to the client",
1939 gchar *block_desc[] = {"USDT request", "USDT response", "UUDT response"};
1941 flags = tvb_get_guint8(tvb, offset);
1946 proto_tree_add_text(pt, tvb, offset, 1, "%segister with gusdt", desc);
1949 localItem = proto_tree_add_text(pt, tvb, offset, 1, "Action flags");
1950 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1951 proto_tree_add_text(localTree, tvb, offset, 1, "%s%s",
1952 decode_boolean_bitfield (flags, 1, 8,
1953 "R", "Unr"), "egister with gusdt");
1954 proto_tree_add_text(localTree, tvb, offset, 1, "%s = %s",
1955 decode_numeric_bitfield (flags, 6, 8, "%d"),
1956 actions[(flags >> 1) & 3]);
1958 flags = tvb_get_guint8(tvb, offset+1);
1959 localItem = proto_tree_add_text(pt, tvb, offset+1, 1, "Transmit options");
1960 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1961 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s%s",
1962 decode_boolean_bitfield (flags, 1, 8,
1964 "cho long transmit messages back to the client");
1965 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s = %s",
1966 decode_numeric_bitfield (flags, 6, 8, "%d"),
1967 xmit_opts[(flags >> 1) & 3]);
1968 proto_tree_add_text(localTree, tvb, offset+1, 1, "%s%s",
1969 decode_boolean_bitfield (flags, 8, 8,
1971 "end a USDT_DONE event when the last frame of a multi-frame USDT message is transmitted");
1973 flags = tvb_get_guint8(tvb, offset+2);
1974 localItem = proto_tree_add_text(pt, tvb, offset+2, 1, "Receive options");
1975 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
1976 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s = %s",
1977 decode_numeric_bitfield (flags, 3, 8, "%d"),
1978 recv_opts[flags & 3]);
1979 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s%s",
1980 decode_boolean_bitfield (flags, 4, 8,
1982 "end a USDT_FIRSTFRAME event when the first frame of a multi-frame USDT message is received");
1983 proto_tree_add_text(localTree, tvb, offset+2, 1, "%s%s",
1984 decode_boolean_bitfield (flags, 8, 8,
1986 "end a USDT_LASTFRAME event when the last frame of a multi-frame USDT message is received");
1988 if ((ids = tvb_get_guint8(tvb, offset+3))) {
1989 localItem = proto_tree_add_text(pt, tvb, offset+3, 1, "Using extended addressing for %d ID%s",
1990 ids, ids == 1?"":"s");
1992 localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data);
1994 id = tvb_get_ntohl (tvb, offset);
1995 proto_tree_add_text (localTree, tvb, offset, 4, "%04X", id);
2000 proto_tree_add_text(pt, tvb, offset+3, 1, "Using extended addressing for the single, internally defined, ID");
2003 for (i = 0; i < 2; i++) {
2004 bytes = tvb_reported_length_remaining (tvb, offset);
2007 localItem = proto_tree_add_text(pt, tvb, offset, 16, "%s block of USDT/UUDT IDs", i==0?"First":"Second");
2008 localTree = proto_item_add_subtree (localItem, ett_gryphon_usdt_data);
2009 size = tvb_get_ntohl (tvb, offset);
2011 proto_tree_add_text (localTree, tvb, offset, 16, "No IDs in the block");
2013 } else if (size == 1) {
2014 proto_tree_add_text (localTree, tvb, offset, 4, "1 ID in the block");
2016 for (j = 0; j < 3; j++){
2017 id = tvb_get_ntohl (tvb, offset);
2018 proto_tree_add_text (localTree, tvb, offset, 4,
2019 "%s ID: %04X", block_desc[j], id);
2023 proto_tree_add_text (localTree, tvb, offset, 4, "%d IDs in the block", size);
2025 for (j = 0; j < 3; j++){
2026 id = tvb_get_ntohl (tvb, offset);
2027 proto_tree_add_text (localTree, tvb, offset, 4,
2028 "%s IDs from %04X through %04X", block_desc[j], id, id+size-1);
2034 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
2038 if ((remain = tvb_reported_length_remaining(tvb, offset))) {
2039 proto_tree_add_text(pt, tvb, offset, remain, "%d ignored byte%s",
2040 remain, remain == 1 ? "" : "s");
2048 cmd_bits_in (tvbuff_t *tvb, int offset, proto_tree *pt)
2053 int msglen, mask, value;
2054 char *decode[] = {"Input 1", "Input 2", "Input 3", "Pushbutton"};
2056 msglen = tvb_reported_length_remaining(tvb, offset);
2057 value = tvb_get_guint8(tvb, offset);
2059 item = proto_tree_add_text(pt, tvb, offset, 1, "Digital values set");
2060 tree = proto_item_add_subtree (item, ett_gryphon_digital_data);
2061 for (i = 0, mask = 1; i < SIZEOF (decode); mask <<= 1, i++) {
2063 proto_tree_add_text(tree, tvb, offset, 1, "%s is set",
2068 proto_tree_add_text(pt, tvb, offset, 1, "No digital values are set");
2077 cmd_bits_out (tvbuff_t *tvb, int offset, proto_tree *pt)
2082 int msglen, mask, value;
2083 char *decode[] = {"Output 1", "Output 2"};
2085 msglen = tvb_reported_length_remaining(tvb, offset);
2086 value = tvb_get_guint8(tvb, offset);
2088 item = proto_tree_add_text(pt, tvb, offset, 1, "Digital values set");
2089 tree = proto_item_add_subtree (item, ett_gryphon_digital_data);
2090 for (i = 0, mask = 1; i < SIZEOF (decode); mask <<= 1, i++) {
2092 proto_tree_add_text(tree, tvb, offset, 1, "%s is set",
2097 proto_tree_add_text(pt, tvb, offset, 1, "No digital values are set");
2106 cmd_init_strat (tvbuff_t *tvb, int offset, proto_tree *pt)
2111 msglen = tvb_reported_length_remaining(tvb, offset);
2112 proto_tree_add_text(pt, tvb, offset, 4, "Reset Limit = %u messages",
2113 tvb_get_ntohl(tvb, offset));
2116 for (index = 1; msglen; index++, offset++, msglen--) {
2117 value = tvb_get_guint8(tvb, offset);
2120 proto_tree_add_text(pt, tvb, offset, 1, "Delay %d = %.2f seconds",
2123 proto_tree_add_text(pt, tvb, offset, 1, "Delay %d = infinite",
2131 speed(tvbuff_t *tvb, int offset, proto_tree *pt)
2133 proto_tree_add_text(pt, tvb, offset, 1, "Baud rate index: %u",
2134 tvb_get_guint8(tvb, offset));
2135 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
2141 filter_block(tvbuff_t *tvb, int offset, proto_tree *pt)
2143 unsigned int type, operator;
2144 int length, padding;
2146 proto_tree_add_text(pt, tvb, offset, 2, "Filter field starts at byte %u",
2147 tvb_get_ntohs(tvb, offset));
2148 length = tvb_get_ntohs(tvb, offset+2);
2149 proto_tree_add_text(pt, tvb, offset+2, 2, "Filter field is %d byte%s long",
2150 length, length == 1 ? "" : "s");
2151 type = tvb_get_guint8(tvb, offset+4);
2152 proto_tree_add_text(pt, tvb, offset+4, 1, "Filtering on %s",
2153 val_to_str(type, filter_data_types, "Unknown (0x%02x)"));
2155 operator = tvb_get_guint8(tvb, offset+5);
2156 proto_tree_add_text(pt, tvb, offset+5, 1, "Type of comparison: %s",
2157 val_to_str(operator, operators, "Unknown (%u)"));
2158 proto_tree_add_text(pt, tvb, offset+6, 2, "reserved");
2161 if (operator == BIT_FIELD_CHECK) {
2162 proto_tree_add_text(pt, tvb, offset, length, "Pattern");
2163 proto_tree_add_text(pt, tvb, offset+length, length, "Mask");
2167 proto_tree_add_text(pt, tvb, offset, 1, "Value: %u",
2168 tvb_get_guint8(tvb, offset));
2171 proto_tree_add_text(pt, tvb, offset, 2, "Value: %u",
2172 tvb_get_ntohs(tvb, offset));
2175 proto_tree_add_text(pt, tvb, offset, 4, "Value: %u",
2176 tvb_get_ntohl(tvb, offset));
2179 proto_tree_add_text(pt, tvb, offset, length, "Value");
2182 offset += length * 2;
2183 padding = 3 - (length * 2 + 3) % 4;
2185 proto_tree_add_text(pt, tvb, offset, padding, "padding");
2192 blm_mode(tvbuff_t *tvb, int offset, proto_tree *pt)
2194 char *mode, line[50];
2197 x = tvb_get_ntohl(tvb, offset);
2198 y = tvb_get_ntohl(tvb, offset+4);
2202 sprintf (line, "reserved");
2205 mode = "Average over time";
2208 sprintf (line, "Averaging period: %d.%03d seconds", seconds, y);
2211 mode = "Average over frame count";
2212 sprintf (line, "Averaging period: %d frames", y);
2215 mode = "- unknown -";
2216 sprintf (line, "reserved");
2218 proto_tree_add_text(pt, tvb, offset, 4, "Mode: %s", mode);
2220 proto_tree_add_text(pt, tvb, offset, 4, line, NULL);
2226 proto_register_gryphon(void)
2228 static hf_register_info hf[] = {
2230 { "Source", "gryph.src", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
2232 { &hf_gryph_srcchan,
2233 { "Source channel", "gryph.srcchan", FT_UINT8, BASE_DEC, NULL, 0x0,
2236 { "Destination", "gryph.dest", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
2238 { &hf_gryph_destchan,
2239 { "Destination channel", "gryph.dstchan", FT_UINT8, BASE_DEC, NULL, 0x0,
2242 { "Frame type", "gryph.type", FT_UINT8, BASE_DEC, NULL, 0x0,
2245 { "Command", "gryph.cmd.cmd", FT_UINT8, BASE_DEC, NULL, 0x0,
2249 static gint *ett[] = {
2251 &ett_gryphon_header,
2253 &ett_gryphon_command_data,
2254 &ett_gryphon_response_data,
2255 &ett_gryphon_data_header,
2257 &ett_gryphon_data_body,
2258 &ett_gryphon_cmd_filter_block,
2259 &ett_gryphon_cmd_events_data,
2260 &ett_gryphon_cmd_config_device,
2261 &ett_gryphon_cmd_sched_data,
2262 &ett_gryphon_cmd_sched_cmd,
2263 &ett_gryphon_cmd_response_block,
2264 &ett_gryphon_pgm_list,
2265 &ett_gryphon_pgm_status,
2266 &ett_gryphon_pgm_options,
2267 &ett_gryphon_valid_headers,
2268 &ett_gryphon_usdt_data,
2269 &ett_gryphon_digital_data,
2271 module_t *gryphon_module;
2273 proto_gryphon = proto_register_protocol("DG Gryphon Protocol",
2276 proto_register_field_array(proto_gryphon, hf, array_length(hf));
2277 proto_register_subtree_array(ett, array_length(ett));
2279 gryphon_module = prefs_register_protocol(proto_gryphon, NULL);
2280 prefs_register_bool_preference(gryphon_module, "desegment",
2281 "Desegment all Gryphon messages spanning multiple TCP segments",
2282 "Whether the Gryphon dissector should desegment all messages spanning multiple TCP segments",
2283 &gryphon_desegment);
2287 proto_reg_handoff_gryphon(void)
2289 dissector_handle_t gryphon_handle;
2291 gryphon_handle = create_dissector_handle(dissect_gryphon, proto_gryphon);
2292 dissector_add("tcp.port", 7000, gryphon_handle);
2295 /* Start the functions we need for the plugin stuff */
2297 #ifndef ENABLE_STATIC
2299 G_MODULE_EXPORT void
2300 plugin_reg_handoff(void){
2301 proto_reg_handoff_gryphon();
2304 G_MODULE_EXPORT void
2305 plugin_init(plugin_address_table_t *pat
2306 #ifndef PLUGINS_NEED_ADDRESS_TABLE
2310 /* initialise the table of pointers needed in Win32 DLLs */
2311 plugin_address_table_init(pat);
2312 /* register the new protocol, protocol fields, and subtrees */
2313 if (proto_gryphon == -1) { /* execute protocol initialization only once */
2314 proto_register_gryphon();
2320 /* End the functions we need for plugin stuff */