2 * Routines for Gryphon protocol packet disassembly
3 * By Steve Limkemann <stevelim@dgtech.com>
4 * Copyright 1998 Steve Limkemann
6 * $Id: packet-gryphon.c,v 1.38 2003/09/05 07:44:46 jmayer Exp $
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;
88 /* desegmentation of Gryphon */
89 static gboolean gryphon_desegment = TRUE;
91 static void dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo,
92 proto_tree *tree, gboolean is_msgresp_add);
93 static int decode_command(tvbuff_t*, int, int, proto_tree*);
94 static int decode_response(tvbuff_t*, int, int, proto_tree*);
95 static int decode_data(tvbuff_t*, int, proto_tree*);
96 static int decode_event(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 resp_blm_data(tvbuff_t*, int, proto_tree*);
116 static int resp_blm_stat(tvbuff_t*, int, proto_tree*);
117 static int cmd_addresp(tvbuff_t*, int, proto_tree*);
118 static int resp_addresp(tvbuff_t*, int, proto_tree*);
119 static int cmd_modresp(tvbuff_t*, int, proto_tree*);
120 static int resp_resphan(tvbuff_t*, int, proto_tree*);
121 static int resp_sched(tvbuff_t*, int, proto_tree*);
122 static int cmd_desc(tvbuff_t*, int, proto_tree*);
123 static int resp_desc(tvbuff_t*, int, proto_tree*);
124 static int cmd_upload(tvbuff_t*, int, proto_tree*);
125 static int cmd_delete(tvbuff_t*, int, proto_tree*);
126 static int cmd_list(tvbuff_t*, int, proto_tree*);
127 static int resp_list(tvbuff_t*, int, proto_tree*);
128 static int cmd_start(tvbuff_t*, int, proto_tree*);
129 static int resp_start(tvbuff_t*, int, proto_tree*);
130 static int resp_status(tvbuff_t*, int, proto_tree*);
131 static int cmd_options(tvbuff_t*, int, proto_tree*);
132 static int cmd_files(tvbuff_t*, int, proto_tree*);
133 static int resp_files(tvbuff_t*, int, proto_tree*);
134 static int eventnum(tvbuff_t*, int, proto_tree*);
135 static int speed(tvbuff_t*, int, proto_tree*);
136 static int filter_block(tvbuff_t*, int, proto_tree*);
137 static int blm_mode(tvbuff_t*, int, proto_tree*);
138 static int cmd_usdt(tvbuff_t*, int, proto_tree*);
140 static char *frame_type[] = {
144 "Network (vehicle) data",
151 * Length of the frame header.
153 #define FRAME_HEADER_LEN 8
156 get_gryphon_pdu_len(tvbuff_t *tvb, int offset)
162 * Get the length of the Gryphon packet, and then get the length as
163 * padded to a 4-byte boundary.
165 plen = tvb_get_ntohs(tvb, offset + 4);
166 padded_len = plen + 3 - (plen + 3) % 4;
169 * That length doesn't include the fixed-length part of the header;
172 return padded_len + FRAME_HEADER_LEN;
176 dissect_gryphon_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
178 dissect_gryphon_message(tvb, pinfo, tree, FALSE);
182 dissect_gryphon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
184 tcp_dissect_pdus(tvb, pinfo, tree, gryphon_desegment, FRAME_HEADER_LEN,
185 get_gryphon_pdu_len, dissect_gryphon_pdu);
188 static const value_string src_dest[] = {
190 {SD_SERVER, "Server"},
191 {SD_CLIENT, "Client"},
192 {SD_SCHED, "Scheduler"},
193 {SD_SCRIPT, "Script Processor"},
194 {SD_PGM, "Program Loader"},
195 {SD_USDT, "USDT Server"},
196 {SD_BLM, "Bus Load Monitoring"},
197 {SD_FLIGHT, "Flight Recorder"},
198 {SD_RESP, "Message Responder"},
203 dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
204 gboolean is_msgresp_add)
207 proto_tree *gryphon_tree;
209 proto_tree *header_tree, *body_tree, *localTree;
210 proto_item *header_item, *body_item, *localItem;
211 int start_offset, msgend;
213 unsigned int src, dest, i, frmtyp;
216 if (!is_msgresp_add) {
217 if (check_col(pinfo->cinfo, COL_PROTOCOL))
218 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Gryphon");
219 if (check_col(pinfo->cinfo, COL_INFO))
220 col_clear(pinfo->cinfo, COL_INFO);
223 if (!is_msgresp_add) {
224 ti = proto_tree_add_item(tree, proto_gryphon, tvb, 0, -1, FALSE);
225 gryphon_tree = proto_item_add_subtree(ti, ett_gryphon);
229 src = tvb_get_guint8(tvb, offset + 0);
230 dest = tvb_get_guint8(tvb, offset + 2);
231 msglen = tvb_get_ntohs(tvb, offset + 4);
232 flags = tvb_get_guint8(tvb, offset + 6);
233 frmtyp = flags & ~RESPONSE_FLAGS;
235 if (!is_msgresp_add) {
237 * This tvbuff includes padding to make its length a multiple
238 * of 4 bytes; set it to the actual length.
240 set_actual_length(tvb, msglen + FRAME_HEADER_LEN);
242 if (check_col(pinfo->cinfo, COL_INFO)) {
244 * Indicate what kind of message this is.
246 if (frmtyp >= SIZEOF (frame_type))
247 col_set_str(pinfo->cinfo, COL_INFO, "- Invalid -");
249 col_set_str(pinfo->cinfo, COL_INFO, frame_type[frmtyp]);
256 if (frmtyp >= SIZEOF (frame_type)) {
258 * Unknown message type.
260 proto_tree_add_text(gryphon_tree, tvb, offset, msglen, "Data");
264 header_item = proto_tree_add_text(gryphon_tree, tvb, offset, MSG_HDR_SZ, "Header");
265 header_tree = proto_item_add_subtree(header_item, ett_gryphon_header);
266 proto_tree_add_text(header_tree, tvb, offset, 2,
267 "Source: %s, channel %u",
268 val_to_str(src, src_dest, "Unknown (0x%02x)"),
269 tvb_get_guint8(tvb, offset + 1));
270 proto_tree_add_uint_hidden(header_tree, hf_gryph_src, tvb,
272 proto_tree_add_uint_hidden(header_tree, hf_gryph_srcchan, tvb,
273 offset+1, 1, tvb_get_guint8(tvb, offset + 1));
275 proto_tree_add_text(header_tree, tvb, offset+2, 2,
276 "Destination: %s, channel %u",
277 val_to_str(dest, src_dest, "Unknown (0x%02x)"),
278 tvb_get_guint8(tvb, offset + 3));
279 proto_tree_add_uint_hidden(header_tree, hf_gryph_dest, tvb,
281 proto_tree_add_uint_hidden(header_tree, hf_gryph_destchan, tvb,
282 offset+3, 1, tvb_get_guint8(tvb, offset + 3));
284 proto_tree_add_text(header_tree, tvb, offset+4, 2,
285 "Data length: %u bytes", msglen);
286 proto_tree_add_text(header_tree, tvb, offset+6, 1,
287 "Frame type: %s", frame_type[frmtyp]);
288 if (is_msgresp_add) {
289 localItem = proto_tree_add_text(header_tree, tvb, offset+6, 1, "Flags");
290 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
291 proto_tree_add_text(localTree, tvb, offset+6, 1, "%s",
292 decode_boolean_bitfield(flags, DONT_WAIT_FOR_RESP, 8,
293 "Don't wait for response",
294 "Wait for response"));
295 proto_tree_add_text(localTree, tvb, offset+6, 1, "%s",
296 decode_boolean_bitfield(flags, WAIT_FOR_PREV_RESP, 8,
297 "Wait for previous responses",
298 "Don't wait for previous responses"));
300 proto_tree_add_text(header_tree, tvb, offset+7, 1, "reserved");
302 proto_tree_add_uint_hidden(header_tree, hf_gryph_type, tvb,
303 offset+6, 1, frmtyp);
304 msgpad = 3 - (msglen + 3) % 4;
305 msgend = offset + msglen + msgpad + MSG_HDR_SZ;
307 body_item = proto_tree_add_text(gryphon_tree, tvb, offset + MSG_HDR_SZ,
308 msglen + msgpad, "Body");
309 body_tree = proto_item_add_subtree(body_item, ett_gryphon_body);
311 start_offset = offset;
312 offset += MSG_HDR_SZ;
315 offset = decode_command(tvb, offset, dest, body_tree);
318 offset = decode_response(tvb, offset, src, body_tree);
321 offset = decode_data(tvb, offset, body_tree);
324 offset = decode_event(tvb, offset, body_tree);
333 if (offset < msgend - msgpad) {
334 i = msgend - msgpad - offset;
335 proto_tree_add_text(gryphon_tree, tvb, offset, i, "Data");
338 if (offset < msgend) {
340 proto_tree_add_text(gryphon_tree, tvb, offset, i, "padding");
346 static const val_str_dsp cmds[] = {
347 {CMD_INIT, "Initialize", cmd_init, NULL},
348 {CMD_GET_STAT, "Get status", NULL, NULL},
349 {CMD_GET_CONFIG, "Get configuration", NULL, resp_config},
350 {CMD_EVENT_ENABLE, "Enable event", eventnum, NULL},
351 {CMD_EVENT_DISABLE, "Disable event", eventnum, NULL},
352 {CMD_GET_TIME, "Get time", NULL, resp_time},
353 {CMD_GET_RXDROP, "Get number of dropped RX messages", NULL, NULL},
354 {CMD_RESET_RXDROP, "Clear number of dropped RX messages", NULL, NULL},
355 {CMD_BCAST_ON, "Set broadcasts on", NULL, NULL},
356 {CMD_BCAST_OFF, "Set broadcasts off", NULL, NULL},
357 {CMD_CARD_SET_SPEED, "Set channel baud rate", speed, NULL},
358 {CMD_CARD_GET_SPEED, "Get channel baud rate", NULL, speed},
359 {CMD_CARD_SET_FILTER, "Set filter (deprecated)", cmd_setfilt, NULL},
360 {CMD_CARD_GET_FILTER, "Get filter", resp_addfilt, cmd_addfilt},
361 {CMD_CARD_TX, "Transmit message", decode_data, NULL},
362 {CMD_CARD_TX_LOOP_ON, "Set transmit loopback on", NULL, NULL},
363 {CMD_CARD_TX_LOOP_OFF, "Set transmit loopback off", NULL, NULL},
364 {CMD_CARD_IOCTL, "IOCTL pass-through", cmd_ioctl, NULL},
365 {CMD_CARD_ADD_FILTER, "Add a filter", cmd_addfilt, resp_addfilt},
366 {CMD_CARD_MODIFY_FILTER, "Modify a filter", cmd_modfilt, NULL},
367 {CMD_CARD_GET_FILTER_HANDLES, "Get filter handles", NULL, resp_filthan},
368 {CMD_CARD_SET_DEFAULT_FILTER, "Set default filter", dfiltmode, NULL},
369 {CMD_CARD_GET_DEFAULT_FILTER, "Get default filter mode", NULL, dfiltmode},
370 {CMD_CARD_SET_FILTER_MODE, "Set filter mode", filtmode, NULL},
371 {CMD_CARD_GET_FILTER_MODE, "Get filter mode", NULL, filtmode},
372 {CMD_CARD_GET_EVNAMES, "Get event names", NULL, resp_events},
373 {CMD_CARD_GET_SPEEDS, "Get defined speeds", NULL, resp_getspeeds},
374 {CMD_SERVER_REG, "Register with server", cmd_register, resp_register},
375 {CMD_SERVER_SET_SORT, "Set the sorting behavior", cmd_sort, NULL},
376 {CMD_SERVER_SET_OPT, "Set the type of optimization", cmd_optimize, NULL},
377 {CMD_BLM_SET_MODE, "Set Bus Load Monitoring mode", blm_mode, NULL},
378 {CMD_BLM_GET_MODE, "Get Bus Load Monitoring mode", NULL, blm_mode},
379 {CMD_BLM_GET_DATA, "Get Bus Load data", NULL, resp_blm_data},
380 {CMD_BLM_GET_STATS, "Get Bus Load statistics", NULL, resp_blm_stat},
381 {CMD_FLIGHT_GET_CONFIG, "Get flight recorder channel info", NULL, NULL},
382 {CMD_FLIGHT_START_MON, "Start flight recorder monitoring", NULL, NULL},
383 {CMD_FLIGHT_STOP_MON, "Stop flight recorder monitoring", NULL, NULL},
384 {CMD_MSGRESP_ADD, "Add response message", cmd_addresp, resp_addresp},
385 {CMD_MSGRESP_GET, "Get response message", resp_addresp, cmd_addresp},
386 {CMD_MSGRESP_MODIFY, "Modify response message state", cmd_modresp, NULL},
387 {CMD_MSGRESP_GET_HANDLES, "Get response message handles", NULL, resp_resphan},
388 {CMD_PGM_DESC, "Describe program to to uploaded", cmd_desc, resp_desc},
389 {CMD_PGM_UPLOAD, "Upload a program to the Gryphon", cmd_upload, NULL},
390 {CMD_PGM_DELETE, "Delete an uploaded program", cmd_delete, NULL},
391 {CMD_PGM_LIST, "Get a list of uploaded programs", cmd_list, resp_list},
392 {CMD_PGM_START, "Start an uploaded program", cmd_start, resp_start},
393 {CMD_PGM_STOP, "Stop an uploaded program", resp_start, NULL},
394 {CMD_PGM_STATUS, "Get status of an uploaded program", cmd_delete, resp_status},
395 {CMD_PGM_OPTIONS, "Set program upload options", cmd_options, resp_status},
396 {CMD_PGM_FILES, "Get a list of files & directories", cmd_files, resp_files},
397 {CMD_SCHED_TX, "Schedule transmission of messages", cmd_sched, resp_sched},
398 {CMD_SCHED_KILL_TX, "Stop and destroy a message transmission", NULL, NULL},
399 {CMD_SCHED_STOP_TX, "Kill a message transmission (deprecated)", NULL, NULL},
400 {CMD_USDT_IOCTL, "Register/Unregister with USDT server", cmd_usdt, NULL},
401 {-1, "- unknown -", NULL, NULL},
404 static const value_string responses[] = {
405 {RESP_OK, "OK - no error"},
406 {RESP_UNKNOWN_ERR, "Unknown error"},
407 {RESP_UNKNOWN_CMD, "Unrecognised command"},
408 {RESP_UNSUPPORTED, "Unsupported command"},
409 {RESP_INVAL_CHAN, "Invalid channel specified"},
410 {RESP_INVAL_DST, "Invalid destination"},
411 {RESP_INVAL_PARAM, "Invalid parameter(s)"},
412 {RESP_INVAL_MSG, "Invalid message"},
413 {RESP_INVAL_LEN, "Invalid length field"},
414 {RESP_TX_FAIL, "Transmit failed"},
415 {RESP_RX_FAIL, "Receive failed"},
416 {RESP_AUTH_FAIL, "Authorization failed"},
417 {RESP_MEM_ALLOC_ERR, "Memory allocation error"},
418 {RESP_TIMEOUT, "Command timed out"},
419 {RESP_UNAVAILABLE, "Unavailable"},
420 {RESP_BUF_FULL, "Buffer full"},
421 {RESP_NO_SUCH_JOB, "No such job"},
425 static const value_string filter_data_types[] = {
426 {FILTER_DATA_TYPE_HEADER_FRAME, "frame header"},
427 {FILTER_DATA_TYPE_HEADER, "data message header"},
428 {FILTER_DATA_TYPE_DATA, "data message data"},
429 {FILTER_DATA_TYPE_EXTRA_DATA, "data message extra data"},
430 {FILTER_EVENT_TYPE_HEADER, "event message header"},
431 {FILTER_EVENT_TYPE_DATA, "event message"},
435 static const value_string operators[] = {
436 {BIT_FIELD_CHECK, "Bit field check"},
437 {SVALUE_GT, "Greater than (signed)"},
438 {SVALUE_GE, "Greater than or equal to (signed)"},
439 {SVALUE_LT, "Less than (signed)"},
440 {SVALUE_LE, "Less than or equal to (signed)"},
441 {VALUE_EQ, "Equal to"},
442 {VALUE_NE, "Not equal to"},
443 {UVALUE_GT, "Greater than (unsigned)"},
444 {UVALUE_GE, "Greater than or equal to (unsigned)"},
445 {UVALUE_LT, "Less than (unsigned)"},
446 {UVALUE_LE, "Less than or equal to (unsigned)"},
447 {DIG_LOW_TO_HIGH, "Digital, low to high transistion"},
448 {DIG_HIGH_TO_LOW, "Digital, high to low transistion"},
449 {DIG_TRANSITION, "Digital, change of state"},
453 static const value_string modes[] = {
454 {FILTER_OFF_PASS_ALL, "Filter off, pass all messages"},
455 {FILTER_OFF_BLOCK_ALL, "Filter off, block all messages"},
456 {FILTER_ON, "Filter on"},
460 static const value_string dmodes[] = {
461 {DEFAULT_FILTER_BLOCK, "Block"},
462 {DEFAULT_FILTER_PASS, "Pass"},
466 static const value_string filtacts[] = {
467 {DELETE_FILTER, "Delete"},
468 {ACTIVATE_FILTER, "Activate"},
469 {DEACTIVATE_FILTER, "Deactivate"},
473 static const value_string ioctls[] = {
474 {GINIT, "GINIT: Initialize"},
475 {GLOOPON, "GLOOPON: Loop on"},
476 {GLOOPOFF, "GLOOPOFF: Loop off"},
477 {GGETHWTYPE, "GGETHWTYPE: Get hardware type"},
478 {GGETREG, "GGETREG: Get register"},
479 {GSETREG, "GSETREG: Set register"},
480 {GGETRXCOUNT, "GGETRXCOUNT: Get the receive message counter"},
481 {GSETRXCOUNT, "GSETRXCOUNT: Set the receive message counter"},
482 {GGETTXCOUNT, "GGETTXCOUNT: Get the transmit message counter"},
483 {GSETTXCOUNT, "GSETTXCOUNT: Set the transmit message counter"},
484 {GGETRXDROP, "GGETRXDROP: Get the number of dropped receive messages"},
485 {GSETRXDROP, "GSETRXDROP: Set the number of dropped receive messages"},
486 {GGETTXDROP, "GGETTXDROP: Get the number of dropped transmit messages"},
487 {GSETTXDROP, "GSETTXDROP: Set the number of dropped transmit messages"},
488 {GGETRXBAD, "GGETRXBAD: Get the number of bad receive messages"},
489 {GGETTXBAD, "GGETTXBAD: Get the number of bad transmit messages"},
490 {GGETCOUNTS, "GGETCOUNTS: Get total message counter"},
491 {GGETBLMON, "GGETBLMON: Get bus load monitoring status"},
492 {GSETBLMON, "GSETBLMON: Set bus load monitoring status (turn on/off)"},
493 {GGETERRLEV, "GGETERRLEV: Get error level"},
494 {GSETERRLEV, "GSETERRLEV: Set error level"},
495 {GGETBITRATE, "GGETBITRATE: Get bit rate"},
496 {GGETRAM, "GGETRAM: Read value from RAM"},
497 {GSETRAM, "GSETRAM: Write value to RAM"},
498 {GCANGETBTRS, "GCANGETBTRS: Read CAN bit timing registers"},
499 {GCANSETBTRS, "GCANSETBTRS: Write CAN bit timing registers"},
500 {GCANGETBC, "GCANGETBC: Read CAN byte count"},
501 {GCANSETBC, "GCANSETBC: Write CAN byte count"},
502 {GCANGETMODE, "GCANGETMODE"},
503 {GCANSETMODE, "GCANSETMODE"},
504 {GCANGETTRANS, "GCANGETTRANS"},
505 {GCANSETTRANS, "GCANSETTRANS"},
506 {GCANSENDERR, "GCANSENDERR"},
507 {GCANRGETOBJ, "GCANRGETOBJ"},
508 {GCANRSETSTDID, "GCANRSETSTDID"},
509 {GCANRSETEXTID, "GCANRSETEXTID"},
510 {GCANRSETDATA, "GCANRSETDATA"},
511 {GCANRENABLE, "GCANRENABLE"},
512 {GCANRDISABLE, "GCANRDISABLE"},
513 {GCANRGETMASKS, "GCANRGETMASKS"},
514 {GCANRSETMASKS, "GCANRSETMASKS"},
515 {GCANSWGETMODE, "GCANSWGETMODE"},
516 {GCANSWSETMODE, "GCANSWSETMODE"},
517 {GDLCGETFOURX, "GDLCGETFOURX"},
518 {GDLCSETFOURX, "GDLCSETFOURX"},
519 {GDLCGETLOAD, "GDLCGETLOAD"},
520 {GDLCSETLOAD, "GDLCSETLOAD"},
521 {GDLCSENDBREAK, "GDLCSENDBREAK"},
522 {GDLCABORTTX, "GDLCABORTTX"},
523 {GDLCGETHDRMODE, "DLCGETHDRMODE"},
524 {GDLCSETHDRMODE, "GDLCSETHDRMODE"},
525 {GHONSLEEP, "GHONSLEEP"},
526 {GHONSILENCE, "GHONSILENCE"},
527 {GKWPSETPTIMES, "GKWPSETPTIMES"},
528 {GKWPSETWTIMES, "GKWPSETWTIMES"},
529 {GKWPDOWAKEUP, "GKWPDOWAKEUP"},
530 {GKWPGETBITTIME, "GKWPGETBITTIME"},
531 {GKWPSETBITTIME, "GKWPSETBITTIME"},
532 {GKWPSETNODEADDR, "GKWPSETNODEADDR"},
533 {GKWPGETNODETYPE, "GKWPGETNODETYPE"},
534 {GKWPSETNODETYPE, "GKWPSETNODETYPE"},
535 {GKWPSETWAKETYPE, "GKWPSETWAKETYPE"},
536 {GKWPSETTARGADDR, "GKWPSETTARGADDR"},
537 {GKWPSETKEYBYTES, "GKWPSETKEYBYTES"},
538 {GKWPSETSTARTREQ, "GKWPSETSTARTREQ"},
539 {GKWPSETSTARTRESP, "GKWPSETSTARTRESP"},
540 {GKWPSETPROTOCOL, "GKWPSETPROTOCOL"},
541 {GKWPGETLASTKEYBYTES, "GKWPGETLASTKEYBYTES"},
542 {GKWPSETLASTKEYBYTES, "GKWPSETLASTKEYBYTES"},
543 {GSCPGETBBR, "GSCPGETBBR"},
544 {GSCPSETBBR, "GSCPSETBBR"},
545 {GSCPGETID, "GSCPGETID"},
546 {GSCPSETID, "GSCPSETID"},
547 {GSCPADDFUNCID, "GSCPADDFUNCID"},
548 {GSCPCLRFUNCID, "GSCPCLRFUNCID"},
549 {GUBPGETBITRATE, "GUBPGETBITRATE"},
550 {GUBPSETBITRATE, "GUBPSETBITRATE"},
551 {GUBPGETINTERBYTE, "GUBPGETINTERBYTE"},
552 {GUBPSETINTERBYTE, "GUBPSETINTERBYTE"},
553 {GUBPGETNACKMODE, "GUBPGETNACKMODE"},
554 {GUBPSETNACKMODE, "GUBPSETNACKMODE"},
560 decode_command(tvbuff_t *tvb, int offset, int dst, proto_tree *pt)
562 int cmd, padding, msglen;
567 msglen = tvb_reported_length_remaining(tvb, offset);
568 cmd = tvb_get_guint8(tvb, offset);
569 proto_tree_add_uint_hidden(pt, hf_gryph_cmd, tvb, offset, 1, cmd);
573 for (i = 0; i < SIZEOF(cmds); i++) {
574 if (cmds[i].value == cmd)
577 if (i >= SIZEOF(cmds) && dst >= SD_KNOWN) {
578 cmd = (cmd & 0xFF) + SD_CARD * 256;
579 for (i = 0; i < SIZEOF(cmds); i++) {
580 if (cmds[i].value == cmd)
584 if (i >= SIZEOF(cmds))
585 i = SIZEOF(cmds) - 1;
587 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
591 if (cmds[i].cmd_fnct && msglen > 0) {
592 padding = 3 - (msglen + 3) % 4;
593 ti = proto_tree_add_text(pt, tvb, offset, -1, "Data: (%d bytes)", msglen);
594 ft = proto_item_add_subtree(ti, ett_gryphon_command_data);
595 offset = (*(cmds[i].cmd_fnct)) (tvb, offset, ft);
601 decode_response(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
604 unsigned int i, resp;
608 msglen = tvb_reported_length_remaining(tvb, offset);
609 cmd = tvb_get_guint8(tvb, offset);
613 for (i = 0; i < SIZEOF(cmds); i++) {
614 if (cmds[i].value == cmd)
617 if (i >= SIZEOF(cmds) && src >= SD_KNOWN) {
618 cmd = (cmd & 0xFF) + SD_CARD * 256;
619 for (i = 0; i < SIZEOF(cmds); i++) {
620 if (cmds[i].value == cmd)
624 if (i >= SIZEOF(cmds))
625 i = SIZEOF(cmds) - 1;
626 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
630 resp = tvb_get_ntohl (tvb, offset);
631 proto_tree_add_text (pt, tvb, offset, 4, "Status: %s",
632 val_to_str(resp, responses, "Unknown (0x%08x)"));
636 if (cmds[i].rsp_fnct && msglen > 0) {
637 ti = proto_tree_add_text(pt, tvb, offset, msglen, "Data: (%d bytes)", msglen);
638 ft = proto_item_add_subtree(ti, ett_gryphon_response_data);
639 offset = (*(cmds[i].rsp_fnct)) (tvb, offset, ft);
645 decode_data(tvbuff_t *tvb, int offset, proto_tree *pt)
647 proto_item *item, *item1;
648 proto_tree *tree, *tree1;
649 int hdrsize, datasize, extrasize, hdrbits, msgsize, padding, mode;
650 int hours, minutes, seconds, fraction;
651 unsigned long timestamp;
653 hdrsize = tvb_get_guint8(tvb, offset+0);
654 hdrbits = tvb_get_guint8(tvb, offset+1);
655 datasize = tvb_get_ntohs(tvb, offset+2);
656 extrasize = tvb_get_guint8(tvb, offset+4);
657 padding = 3 - (hdrsize + datasize + extrasize + 3) % 4;
658 msgsize = hdrsize + datasize + extrasize + padding + 16;
660 item = proto_tree_add_text(pt, tvb, offset, 16, "Message header");
661 tree = proto_item_add_subtree (item, ett_gryphon_data_header);
662 proto_tree_add_text(tree, tvb, offset, 2, "Header length: %d bytes, %d bits", hdrsize, hdrbits);
663 proto_tree_add_text(tree, tvb, offset+2, 2, "Data length: %d bytes", datasize);
664 proto_tree_add_text(tree, tvb, offset+4, 1, "Extra data length: %d bytes", extrasize);
665 mode = tvb_get_guint8(tvb, offset+5);
666 item1 = proto_tree_add_text(tree, tvb, offset+5, 1, "Mode: %d", mode);
668 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
670 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
671 decode_boolean_bitfield(mode, 0x80, 8,
672 "Transmitted message", NULL));
675 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
676 decode_boolean_bitfield(mode, 0x40, 8,
677 "Received message", NULL));
680 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
681 decode_boolean_bitfield(mode, 0x20, 8,
682 "Local message", NULL));
685 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
686 decode_boolean_bitfield(mode, 0x10, 8,
687 "Remote message", NULL));
690 proto_tree_add_text(tree1, tvb, offset+5, 1, "%s",
691 decode_boolean_bitfield(mode, 0x01, 8,
692 "Internal message", NULL));
695 proto_tree_add_text(tree, tvb, offset+6, 1, "Priority: %u",
696 tvb_get_guint8(tvb, offset+6));
697 proto_tree_add_text(tree, tvb, offset+7, 1, "Error status: %u",
698 tvb_get_guint8(tvb, offset+7));
699 timestamp = tvb_get_ntohl(tvb, offset+8);
700 hours = timestamp /(100000 * 60 *60);
701 minutes = (timestamp / (100000 * 60)) % 60;
702 seconds = (timestamp / 100000) % 60;
703 fraction = timestamp % 100000;
704 proto_tree_add_text(tree, tvb, offset+8, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
705 proto_tree_add_text(tree, tvb, offset+12, 1, "Context: %u",
706 tvb_get_guint8(tvb, offset+12));
707 proto_tree_add_text(tree, tvb, offset+13, 3, "reserved:");
709 item = proto_tree_add_text(pt, tvb, offset, msgsize-16-padding, "Message Body");
710 tree = proto_item_add_subtree (item, ett_gryphon_data_body);
712 proto_tree_add_text(tree, tvb, offset, hdrsize, "Header");
716 proto_tree_add_text(tree, tvb, offset, datasize, "Data");
720 proto_tree_add_text(tree, tvb, offset, extrasize, "Extra data");
724 proto_tree_add_text(pt, tvb, offset, padding, "padding");
731 decode_event(tvbuff_t *tvb, int offset, proto_tree *pt)
734 int hours, minutes, seconds, fraction, padding, length;
735 unsigned long timestamp;
738 msglen = tvb_reported_length_remaining(tvb, offset);
739 padding = 3 - (msglen + 3) % 4;
740 msgend = offset + msglen;
741 proto_tree_add_text(pt, tvb, offset, 1, "Event ID: %u",
742 tvb_get_guint8(tvb, offset));
743 proto_tree_add_text(pt, tvb, offset+1, 1, "Event context: %u",
744 tvb_get_guint8(tvb, offset+1));
745 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
747 timestamp = tvb_get_ntohl(tvb, offset);
748 hours = timestamp /(100000 * 60 *60);
749 minutes = (timestamp / (100000 * 60)) % 60;
750 seconds = (timestamp / 100000) % 60;
751 fraction = timestamp % 100000;
752 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
754 if (offset < msgend) {
755 length = msgend - offset;
756 proto_tree_add_text (pt, tvb, offset, length, "Data (%d bytes)", length);
760 proto_tree_add_text(pt, tvb, offset, padding, "padding");
767 cmd_init(tvbuff_t *tvb, int offset, proto_tree *pt)
771 if (tvb_get_guint8(tvb, offset) == 0)
772 ptr = "Always initialize";
774 ptr = "Initialize if not previously initialized";
775 proto_tree_add_text(pt, tvb, offset, 1, "Mode: %s", ptr);
776 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
782 eventnum(tvbuff_t *tvb, int offset, proto_tree *pt)
784 guint8 event = tvb_get_guint8(tvb, offset);
787 proto_tree_add_text(pt, tvb, offset, 1, "Event number: %u", event);
789 proto_tree_add_text(pt, tvb, offset, 1, "Event numbers: All");
790 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
796 resp_time(tvbuff_t *tvb, int offset, proto_tree *pt)
798 int hours, minutes, seconds, fraction;
803 unsigned int timestamp;
804 unsigned char date[45];
806 ts.lng[1] = tvb_get_ntohl(tvb, offset);
807 ts.lng[0] = tvb_get_ntohl(tvb, offset + 4);
808 timestamp = ts.lnglng / 100000L;
809 strncpy (date, ctime((time_t*)×tamp), sizeof(date));
810 date[strlen(date)-1] = 0x00;
811 proto_tree_add_text(pt, tvb, offset, 8, "Date/Time: %s", date);
812 timestamp = ts.lng[0];
813 hours = timestamp /(100000 * 60 *60);
814 minutes = (timestamp / (100000 * 60)) % 60;
815 seconds = (timestamp / 100000) % 60;
816 fraction = timestamp % 100000;
817 proto_tree_add_text(pt, tvb, offset+4, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
823 cmd_setfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
825 int flag = tvb_get_ntohl(tvb, offset);
827 unsigned char mode[30];
829 length = tvb_get_guint8(tvb, offset+4) + tvb_get_guint8(tvb, offset+5)
830 + tvb_get_ntohs(tvb, offset+6);
832 strcpy (mode, "Pass");
834 strcpy (mode, "Block");
836 strcat (mode, " all");
837 proto_tree_add_text(pt, tvb, offset, 4, "Pass/Block flag: %s", mode);
838 proto_tree_add_text(pt, tvb, offset+4, 4, "Length of Pattern & Mask: %d", length);
841 proto_tree_add_text(pt, tvb, offset, length * 2, "discarded data");
842 offset += length * 2;
844 padding = 3 - (length * 2 + 3) % 4;
846 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
853 cmd_ioctl(tvbuff_t *tvb, int offset, proto_tree *pt)
858 msglen = tvb_reported_length_remaining(tvb, offset);
859 ioctl = tvb_get_ntohl(tvb, offset);
860 proto_tree_add_text(pt, tvb, offset, 4, "IOCTL: %s",
861 val_to_str(ioctl, ioctls, "Unknown (0x%08x)"));
865 proto_tree_add_text(pt, tvb, offset, msglen, "Data");
872 cmd_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
877 int blocks, i, length;
879 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags");
880 tree = proto_item_add_subtree (item, ett_gryphon_flags);
881 flags = tvb_get_guint8(tvb, offset);
882 proto_tree_add_text(tree, tvb, offset, 1, "%s",
883 decode_boolean_bitfield(flags, FILTER_PASS_FLAG, 8,
884 "Conforming messages are passed",
885 "Conforming messages are blocked"));
886 proto_tree_add_text(tree, tvb, offset, 1, "%s",
887 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
888 "The filter is active", "The filter is inactive"));
890 blocks = tvb_get_guint8(tvb, offset);
891 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
892 proto_tree_add_text(pt, tvb, offset+1, 6, "reserved");
894 for (i = 1; i <= blocks; i++) {
895 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
896 length += 3 - (length + 3) % 4;
897 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
898 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
899 offset = filter_block(tvb, offset, tree);
905 resp_addfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
907 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
908 tvb_get_guint8(tvb, offset));
909 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
915 cmd_modfilt(tvbuff_t *tvb, int offset, proto_tree *pt)
917 guint8 filter_handle;
918 unsigned char action;
920 filter_handle = tvb_get_guint8(tvb, offset);
922 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
925 proto_tree_add_text(pt, tvb, offset, 1, "Filter handles: all");
926 action = tvb_get_guint8(tvb, offset + 1);
927 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s filter",
928 val_to_str(action, filtacts, "Unknown (%u)"));
929 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
935 resp_filthan(tvbuff_t *tvb, int offset, proto_tree *pt)
937 int handles = tvb_get_guint8(tvb, offset);
940 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter handles: %d", handles);
941 for (i = 1; i <= handles; i++){
942 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
943 tvb_get_guint8(tvb, offset+i));
945 padding = 3 - (handles + 1 + 3) % 4;
947 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
948 offset += 1+handles+padding;
953 dfiltmode(tvbuff_t *tvb, int offset, proto_tree *pt)
957 mode = tvb_get_guint8(tvb, offset);
958 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
959 val_to_str(mode, dmodes, "Unknown (%u)"));
960 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
966 filtmode(tvbuff_t *tvb, int offset, proto_tree *pt)
970 mode = tvb_get_guint8(tvb, offset);
971 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s",
972 val_to_str(mode, dmodes, "Unknown (%u)"));
973 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
979 resp_events(tvbuff_t *tvb, int offset, proto_tree *pt)
986 msglen = tvb_reported_length_remaining(tvb, offset);
988 while (msglen != 0) {
989 item = proto_tree_add_text(pt, tvb, offset, 20, "Event %d:", i);
990 tree = proto_item_add_subtree (item, ett_gryphon_cmd_events_data);
991 proto_tree_add_text(tree, tvb, offset, 1, "Event ID: %u",
992 tvb_get_guint8(tvb, offset));
993 proto_tree_add_text(tree, tvb, offset+1, 19, "Event name: %.19s",
994 tvb_get_ptr(tvb, offset+1, 19));
1003 cmd_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1005 proto_tree_add_text(pt, tvb, offset, 16, "Username: %.16s",
1006 tvb_get_ptr(tvb, offset, 16));
1008 proto_tree_add_text(pt, tvb, offset, 32, "Password: %.32s",
1009 tvb_get_ptr(tvb, offset, 32));
1015 resp_register(tvbuff_t *tvb, int offset, proto_tree *pt)
1017 proto_tree_add_text(pt, tvb, offset, 1, "Client ID: %u",
1018 tvb_get_guint8(tvb, offset));
1019 proto_tree_add_text(pt, tvb, offset+1, 1, "Privileges: %u",
1020 tvb_get_guint8(tvb, offset+1));
1021 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1028 resp_getspeeds(tvbuff_t *tvb, int offset, proto_tree *pt)
1034 proto_tree_add_text(pt, tvb, offset, 4, "Set Speed IOCTL");
1035 proto_tree_add_text(pt, tvb, offset+4, 4, "Get Speed IOCTL");
1036 size = tvb_get_guint8(tvb, offset+8);
1037 proto_tree_add_text(pt, tvb, offset+8, 1, "Speed data size is %d bytes", size);
1038 number = tvb_get_guint8(tvb, offset+9);
1039 proto_tree_add_text(pt, tvb, offset+9, 1, "There are %d preset speeds", number);
1041 for (index = 0; index < number; index++) {
1042 proto_tree_add_text(pt, tvb, offset, size, "Data for preset %d",
1050 cmd_sort(tvbuff_t *tvb, int offset, proto_tree *pt)
1054 which = tvb_get_guint8(tvb, offset) ?
1055 "Sort into blocks of up to 16 messages" :
1056 "Do not sort messages";
1057 proto_tree_add_text(pt, tvb, offset, 1, "Set sorting: %s", which);
1063 cmd_optimize(tvbuff_t *tvb, int offset, proto_tree *pt)
1067 which = tvb_get_guint8(tvb, offset) ?
1068 "Optimize for latency (Nagle algorithm disabled)" :
1069 "Optimize for throughput (Nagle algorithm enabled)";
1070 proto_tree_add_text(pt, tvb, offset, 1, "Set optimization: %s", which);
1076 resp_config(tvbuff_t *tvb, int offset, proto_tree *pt)
1084 static const value_string protocol_types[] = {
1085 {GDUMMY * 256 + GDGDMARKONE, "Dummy device driver"},
1086 {GCAN * 256 + G82527, "CAN, 82527 subtype"},
1087 {GCAN * 256 + GSJA1000, "CAN, SJA1000 subtype"},
1088 {GCAN * 256 + G82527SW, "CAN, 82527 single wire subtype"},
1089 {GJ1850 * 256 + GHBCCPAIR, "J1850, HBCC subtype"},
1090 {GJ1850 * 256 + GDLC, "J1850, GM DLC subtype"},
1091 {GJ1850 * 256 + GCHRYSLER, "J1850, Chrysler subtype"},
1092 {GJ1850 * 256 + GDEHC12, "J1850, DE HC12 KWP/BDLC subtype"},
1093 {GKWP2000 * 256 + GDEHC12KWP, "Keyword protocol 2000"},
1094 {GHONDA * 256 + GDGHC08, "Honda UART, DG HC08 subtype"},
1095 {GFORDUBP * 256 + GDGUBP08, "Ford UBP, DG HC08 subtype"},
1099 proto_tree_add_text(pt, tvb, offset, 20, "Device name: %.20s",
1100 tvb_get_ptr(tvb, offset, 20));
1103 proto_tree_add_text(pt, tvb, offset, 8, "Device version: %.8s",
1104 tvb_get_ptr(tvb, offset, 8));
1107 proto_tree_add_text(pt, tvb, offset, 20, "Device serial number: %.20s",
1108 tvb_get_ptr(tvb, offset, 20));
1111 devices = tvb_get_guint8(tvb, offset);
1112 proto_tree_add_text(pt, tvb, offset, 1, "Number of channels: %d", devices);
1113 proto_tree_add_text(pt, tvb, offset+1, 15, "reserved");
1115 for (i = 1; i <= devices; i++) {
1116 ti = proto_tree_add_text(pt, tvb, offset, 80, "Channel %d:", i);
1117 ft = proto_item_add_subtree(ti, ett_gryphon_cmd_config_device);
1118 proto_tree_add_text(ft, tvb, offset, 20, "Driver name: %.20s",
1119 tvb_get_ptr(tvb, offset, 20));
1122 proto_tree_add_text(ft, tvb, offset, 8, "Driver version: %.8s",
1123 tvb_get_ptr(tvb, offset, 8));
1126 proto_tree_add_text(ft, tvb, offset, 24, "Device security string: %.24s",
1127 tvb_get_ptr(tvb, offset, 24));
1130 proto_tree_add_text(ft, tvb, offset, 20, "Hardware serial number: %.20s",
1131 tvb_get_ptr(tvb, offset, 20));
1134 x = tvb_get_ntohs(tvb, offset);
1135 proto_tree_add_text(ft, tvb, offset, 2, "Protocol type & subtype: %s",
1136 val_to_str(x, protocol_types, "Unknown (0x%04x)"));
1139 proto_tree_add_text(ft, tvb, offset, 1, "Channel ID: %u",
1140 tvb_get_guint8(tvb, offset));
1141 proto_tree_add_text(ft, tvb, offset+1, 5, "reserved");
1148 cmd_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1151 proto_item *item, *item1;
1152 proto_tree *tree, *tree1;
1154 unsigned int i, x, length;
1155 unsigned char def_chan = tvb_get_guint8(tvb, offset-9);
1157 msglen = tvb_reported_length_remaining(tvb, offset);
1158 x = tvb_get_ntohl(tvb, offset);
1159 if (x == 0xFFFFFFFF)
1160 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: infinite");
1162 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: %u", x);
1165 x = tvb_get_ntohl(tvb, offset);
1166 item = proto_tree_add_text(pt, tvb, offset, 4, "Flags: 0x%08x", x);
1167 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1168 proto_tree_add_text(tree, tvb, offset, 4, "%s",
1169 decode_boolean_bitfield(x, 0x01, 32,
1170 "Critical scheduler", "Normal scheduler"));
1174 while (msglen > 0) {
1175 length = 16 + tvb_get_guint8(tvb, offset+16) +
1176 tvb_get_ntohs(tvb, offset+18) + tvb_get_guint8(tvb, offset+20) + 16;
1177 length += 3 - (length + 3) % 4;
1178 item = proto_tree_add_text(pt, tvb, offset, length, "Message %d", i);
1179 tree = proto_item_add_subtree (item, ett_gryphon_cmd_sched_data);
1180 x = tvb_get_ntohl(tvb, offset);
1181 proto_tree_add_text(tree, tvb, offset, 4, "Sleep: %u milliseconds", x);
1184 x = tvb_get_ntohl(tvb, offset);
1185 proto_tree_add_text(tree, tvb, offset, 4, "Transmit count: %u", x);
1188 x = tvb_get_ntohl(tvb, offset);
1189 proto_tree_add_text(tree, tvb, offset, 4, "Transmit period: %u milliseconds", x);
1192 proto_tree_add_text(tree, tvb, offset, 2, "reserved flags");
1193 x = tvb_get_guint8(tvb, offset+2);
1196 proto_tree_add_text(tree, tvb, offset+2, 1, "Channel: %u", x);
1197 proto_tree_add_text(tree, tvb, offset+3, 1, "reserved");
1200 item1 = proto_tree_add_text(tree, tvb, offset, length, "Message");
1201 tree1 = proto_item_add_subtree (item1, ett_gryphon_cmd_sched_cmd);
1202 save_offset = offset;
1203 offset = decode_data(tvb, offset, tree1);
1204 msglen -= offset - save_offset;
1211 resp_blm_data(tvbuff_t *tvb, int offset, proto_tree *pt)
1214 int hours, minutes, seconds, fraction, x, fract;
1215 unsigned long timestamp;
1216 static char *fields[] = {
1217 "Bus load average: %d.%02d%%",
1218 "Current bus load: %d.%02d%%",
1219 "Peak bus load: %d.%02d%%",
1220 "Historic peak bus load: %d.%02d%%"
1223 timestamp = tvb_get_ntohl(tvb, offset);
1224 hours = timestamp /(100000 * 60 *60);
1225 minutes = (timestamp / (100000 * 60)) % 60;
1226 seconds = (timestamp / 100000) % 60;
1227 fraction = timestamp % 100000;
1228 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
1230 for (i = 0; i < SIZEOF(fields); i++){
1231 x = tvb_get_ntohs(tvb, offset);
1234 proto_tree_add_text(pt, tvb, offset, 2, fields[i], x, fract);
1241 resp_blm_stat(tvbuff_t *tvb, int offset, proto_tree *pt)
1245 "Receive frame count: %u",
1246 "Transmit frame count: %u",
1247 "Receive dropped frame count: %u",
1248 "Transmit dropped frame count: %u",
1249 "Receive error count: %u",
1250 "Transmit error count: %u",
1253 offset = resp_blm_data(tvb, offset, pt);
1254 for (i = 0; i < SIZEOF(fields); i++){
1255 x = tvb_get_ntohl(tvb, offset);
1256 proto_tree_add_text(pt, tvb, offset, 4, fields[i], x);
1262 static const value_string action_vals[] = {
1263 { FR_RESP_AFTER_EVENT, "Send response(s) for each conforming message" },
1264 { FR_RESP_AFTER_PERIOD, "Send response(s) after the specified period expires following a conforming message" },
1265 { FR_IGNORE_DURING_PER, "Send response(s) for a conforming message and ignore\nfurther messages until the specified period expires" },
1269 static const value_string deact_on_event_vals[] = {
1270 { FR_DEACT_ON_EVENT,
1271 "Deactivate this response for a conforming message" },
1272 { FR_DELETE|FR_DEACT_ON_EVENT,
1273 "Delete this response for a conforming message" },
1278 static const value_string deact_after_per_vals[] = {
1279 { FR_DEACT_AFTER_PER,
1280 "Deactivate this response after the specified period following a conforming message" },
1281 { FR_DELETE|FR_DEACT_AFTER_PER,
1282 "Delete this response after the specified period following a conforming message" },
1288 cmd_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1293 int blocks, responses, old_handle, i, msglen, length;
1294 int action, actionType, actionValue;
1298 flags = tvb_get_guint8(tvb, offset);
1299 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1300 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1301 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1302 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1303 "The response is active", "The response is inactive"));
1305 blocks = tvb_get_guint8(tvb, offset);
1306 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1308 responses = tvb_get_guint8(tvb, offset);
1309 proto_tree_add_text(pt, tvb, offset, 1, "Number of response blocks = %d", responses);
1311 old_handle = tvb_get_guint8(tvb, offset);
1312 proto_tree_add_text(pt, tvb, offset, 1, "Old handle = %d", old_handle);
1314 action = tvb_get_guint8(tvb, offset);
1315 item = proto_tree_add_text(pt, tvb, offset, 1, "Action: %s",
1316 val_to_str(action & 0x07, action_vals, "Unknown (%u)"));
1317 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1318 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1319 decode_enumerated_bitfield(action, 0x07, 8, action_vals, "%s"));
1320 actionValue = tvb_get_ntohs(tvb, offset+2);
1322 if (action & FR_PERIOD_MSGS) {
1327 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1328 decode_boolean_bitfield(action, FR_PERIOD_MSGS, 8,
1329 "The period is in frames", "The period is in 0.01 seconds"));
1331 if (action & FR_DEACT_ON_EVENT) {
1332 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1333 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_ON_EVENT, 8,
1334 deact_on_event_vals, "%s"));
1336 if (action & FR_DEACT_AFTER_PER) {
1337 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1338 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_AFTER_PER, 8,
1339 deact_after_per_vals, "%s"));
1342 proto_tree_add_text(pt, tvb, offset, 1, "reserved");
1345 if (actionType == 1) {
1346 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d messages", actionValue);
1348 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d.%02d seconds", actionValue/100, actionValue%100);
1352 for (i = 1; i <= blocks; i++) {
1353 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1354 length += 3 - (length + 3) % 4;
1355 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1356 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1357 offset = filter_block(tvb, offset, tree);
1359 for (i = 1; i <= responses; i++) {
1360 msglen = tvb_get_ntohs(tvb, offset+4) + 8;
1361 length = msglen + 3 - (msglen + 3) % 4;
1362 item = proto_tree_add_text(pt, tvb, offset, length, "Response block %d", i);
1363 tree = proto_item_add_subtree (item, ett_gryphon_cmd_response_block);
1364 next_tvb = tvb_new_subset(tvb, offset, msglen, msglen);
1365 dissect_gryphon_message(next_tvb, NULL, tree, TRUE);
1372 resp_addresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1374 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1375 tvb_get_guint8(tvb, offset));
1376 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1382 cmd_modresp(tvbuff_t *tvb, int offset, proto_tree *pt)
1384 unsigned char action;
1385 unsigned char dest = tvb_get_guint8(tvb, offset-5);
1388 resp_handle = tvb_get_guint8(tvb, offset);
1390 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1393 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all on channel %hd", dest);
1395 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all");
1396 action = tvb_get_guint8(tvb, offset+1);
1397 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s response",
1398 val_to_str(action, filtacts, "Unknown (%u)"));
1399 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1405 resp_resphan(tvbuff_t *tvb, int offset, proto_tree *pt)
1407 int handles = tvb_get_guint8(tvb, offset);
1410 proto_tree_add_text(pt, tvb, offset, 1, "Number of response handles: %d", handles);
1411 for (i = 1; i <= handles; i++){
1412 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1413 tvb_get_guint8(tvb, offset+i));
1415 padding = 3 - (handles + 1 + 3) % 4;
1417 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1418 offset += 1+handles+padding;
1423 resp_sched(tvbuff_t *tvb, int offset, proto_tree *pt)
1425 unsigned int id = tvb_get_ntohl(tvb, offset);
1427 proto_tree_add_text(pt, tvb, offset, 4, "Transmit schedule ID: %u", id);
1433 cmd_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1435 proto_tree_add_text(pt, tvb, offset, 4, "Program size: %u bytes",
1436 tvb_get_ntohl(tvb, offset));
1438 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1439 tvb_get_ptr(tvb, offset, 32));
1441 proto_tree_add_text(pt, tvb, offset, 80, "Program description: %.80s",
1442 tvb_get_ptr(tvb, offset, 80));
1448 resp_desc(tvbuff_t *tvb, int offset, proto_tree *pt)
1454 flags = tvb_get_guint8(tvb, offset);
1455 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1456 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1457 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1458 decode_boolean_bitfield(flags, 0x01, 8,
1459 "The program is already present",
1460 "The program is not present"));
1461 proto_tree_add_text(pt, tvb, offset+1, 1, "Handle: %u",
1462 tvb_get_guint8(tvb, offset+1));
1463 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1469 cmd_upload(tvbuff_t *tvb, int offset, proto_tree *pt)
1472 unsigned int length;
1474 msglen = tvb_reported_length_remaining(tvb, offset);
1475 proto_tree_add_text(pt, tvb, offset, 2, "Block number: %u",
1476 tvb_get_ntohs(tvb, offset));
1479 proto_tree_add_text(pt, tvb, offset+2, 1, "Handle: %u",
1480 tvb_get_guint8(tvb, offset+2));
1484 proto_tree_add_text(pt, tvb, offset, length, "Data (%u bytes)", length);
1486 length = 3 - (length + 3) % 4;
1488 proto_tree_add_text(pt, tvb, offset, length, "padding");
1495 cmd_delete(tvbuff_t *tvb, int offset, proto_tree *pt)
1497 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1498 tvb_get_ptr(tvb, offset, 32));
1504 cmd_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1506 proto_tree_add_text(pt, tvb, offset, 1, "Block number: %u",
1507 tvb_get_guint8(tvb, offset));
1508 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1514 resp_list(tvbuff_t *tvb, int offset, proto_tree *pt)
1518 unsigned int i, count;
1520 count = tvb_get_guint8(tvb, offset);
1521 proto_tree_add_text(pt, tvb, offset, 1, "Number of programs in this response: %u", count);
1522 proto_tree_add_text(pt, tvb, offset+1, 1, "reserved");
1524 proto_tree_add_text(pt, tvb, offset, 2, "Number of remaining programs: %u",
1525 tvb_get_ntohs(tvb, offset));
1527 for (i = 1; i <= count; i++) {
1528 item = proto_tree_add_text(pt, tvb, offset, 112, "Program %u", i);
1529 tree = proto_item_add_subtree (item, ett_gryphon_pgm_list);
1530 proto_tree_add_text(tree, tvb, offset, 32, "Name: %.32s",
1531 tvb_get_ptr(tvb, offset, 32));
1533 proto_tree_add_text(tree, tvb, offset, 80, "Description: %.80s",
1534 tvb_get_ptr(tvb, offset, 80));
1541 cmd_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1546 offset = cmd_delete(tvb, offset, pt); /* decode the name */
1547 string = tvb_get_stringz(tvb, offset, &length);
1548 proto_tree_add_text(pt, tvb, offset, length, "Arguments: %s", string);
1551 length = 3 - (length + 3) % 4;
1553 proto_tree_add_text(pt, tvb, offset, length, "padding");
1560 resp_start(tvbuff_t *tvb, int offset, proto_tree *pt)
1562 proto_tree_add_text(pt, tvb, offset, 1, "Channel (Client) number: %u",
1563 tvb_get_guint8(tvb, offset));
1564 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1570 resp_status(tvbuff_t *tvb, int offset, proto_tree *pt)
1574 unsigned int i, copies, length;
1576 copies = tvb_get_guint8(tvb, offset);
1577 item = proto_tree_add_text(pt, tvb, offset, 1, "Number of running copies: %u", copies);
1578 tree = proto_item_add_subtree (item, ett_gryphon_pgm_status);
1581 for (i = 1; i <= copies; i++) {
1582 proto_tree_add_text(tree, tvb, offset, 1, "Program %u channel (client) number %u",
1583 i, tvb_get_guint8(tvb, offset));
1587 length = 3 - (copies + 1 + 3) % 4;
1589 proto_tree_add_text(pt, tvb, offset, length, "padding");
1596 cmd_options(tvbuff_t *tvb, int offset, proto_tree *pt)
1601 unsigned int i, size, padding, option, option_length, option_value;
1602 unsigned char *string, *string1;
1604 msglen = tvb_reported_length_remaining(tvb, offset);
1605 item = proto_tree_add_text(pt, tvb, offset, 1, "Handle: %u",
1606 tvb_get_guint8(tvb, offset));
1607 item = proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1610 for (i = 1; msglen > 0; i++) {
1611 option_length = tvb_get_guint8(tvb, offset+1);
1612 size = option_length + 2;
1613 padding = 3 - ((size + 3) %4);
1614 item = proto_tree_add_text(pt, tvb, offset, size + padding, "Option number %u", i);
1615 tree = proto_item_add_subtree (item, ett_gryphon_pgm_options);
1616 option = tvb_get_guint8(tvb, offset);
1617 switch (option_length) {
1619 option_value = tvb_get_guint8(tvb, offset+2);
1622 option_value = tvb_get_ntohs(tvb, offset+2);
1625 option_value = tvb_get_ntohl(tvb, offset+2);
1630 string = "unknown option";
1631 string1 = "unknown option data";
1634 string = "Type of data in the file";
1635 switch (option_value) {
1637 string1 = "Binary - Don't modify";
1640 string1 = "ASCII - Remove CR's";
1645 string = "Type of file";
1646 switch (option_value) {
1648 string1 = "Executable";
1656 proto_tree_add_text(tree, tvb, offset, 1, "%s", string);
1657 proto_tree_add_text(tree, tvb, offset+2, option_length, "%s", string1);
1659 proto_tree_add_text(tree, tvb, offset+option_length+2, padding, "padding");
1660 offset += size + padding;
1661 msglen -= size + padding;
1667 cmd_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1672 msglen = tvb_reported_length_remaining(tvb, offset);
1673 if (tvb_get_guint8(tvb, offset) == 0)
1674 which = "First group of names";
1676 which = "Subsequent group of names";
1678 proto_tree_add_text(pt, tvb, offset, 1, "%s", which);
1679 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "Directory: %.*s",
1680 msglen-1, tvb_get_ptr(tvb, offset+1, msglen-1));
1686 resp_files(tvbuff_t *tvb, int offset, proto_tree *pt)
1691 msglen = tvb_reported_length_remaining(tvb, offset);
1692 flag = tvb_get_guint8(tvb, offset) ? "Yes": "No";
1693 proto_tree_add_text(pt, tvb, offset, 1, "More filenames to return: %s", flag);
1694 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "File and directory names");
1700 cmd_usdt(tvbuff_t *tvb, int offset, proto_tree *pt)
1703 guint8 assemble_flag;
1705 if (tvb_get_guint8(tvb, offset))
1706 desc = "Register with gusdt";
1708 desc = "Unregister with gusdt";
1709 proto_tree_add_text(pt, tvb, offset, 1, "%s", desc);
1711 if (tvb_get_guint8(tvb, offset+1))
1712 desc = "Echo long transmit messages back to the client";
1714 desc = "Do not echo long transmit messages back to the client";
1715 proto_tree_add_text(pt, tvb, offset+1, 1, "%s", desc);
1717 assemble_flag = tvb_get_guint8(tvb, offset+2);
1718 if (assemble_flag == 2)
1719 desc = "Assemble long received messages but do not send them to the client";
1720 else if (assemble_flag)
1721 desc = "Assemble long received messages and send them to the client";
1723 desc = "Do not assemble long received messages on behalf of the client";
1724 proto_tree_add_text(pt, tvb, offset+2, 1, "%s", desc);
1731 speed(tvbuff_t *tvb, int offset, proto_tree *pt)
1733 proto_tree_add_text(pt, tvb, offset, 1, "Baud rate index: %u",
1734 tvb_get_guint8(tvb, offset));
1735 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1741 filter_block(tvbuff_t *tvb, int offset, proto_tree *pt)
1743 unsigned int type, operator;
1744 int length, padding;
1746 proto_tree_add_text(pt, tvb, offset, 2, "Filter field starts at byte %u",
1747 tvb_get_ntohs(tvb, offset));
1748 length = tvb_get_ntohs(tvb, offset+2);
1749 proto_tree_add_text(pt, tvb, offset+2, 2, "Filter field is %d bytes long", length);
1750 type = tvb_get_guint8(tvb, offset+4);
1751 proto_tree_add_text(pt, tvb, offset+4, 1, "Filtering on %s",
1752 val_to_str(type, filter_data_types, "Unknown (0x%02x)"));
1754 operator = tvb_get_guint8(tvb, offset+5);
1755 proto_tree_add_text(pt, tvb, offset+5, 1, "Type of comparison: %s",
1756 val_to_str(operator, operators, "Unknown (%u)"));
1757 proto_tree_add_text(pt, tvb, offset+6, 2, "reserved");
1760 if (operator == BIT_FIELD_CHECK) {
1761 proto_tree_add_text(pt, tvb, offset, length, "Pattern");
1762 proto_tree_add_text(pt, tvb, offset+length, length, "Mask");
1766 proto_tree_add_text(pt, tvb, offset, 1, "Value: %u",
1767 tvb_get_guint8(tvb, offset));
1770 proto_tree_add_text(pt, tvb, offset, 2, "Value: %u",
1771 tvb_get_ntohs(tvb, offset));
1774 proto_tree_add_text(pt, tvb, offset, 4, "Value: %u",
1775 tvb_get_ntohl(tvb, offset));
1778 proto_tree_add_text(pt, tvb, offset, length, "Value");
1781 offset += length * 2;
1782 padding = 3 - (length * 2 + 3) % 4;
1784 proto_tree_add_text(pt, tvb, offset, padding, "padding");
1791 blm_mode(tvbuff_t *tvb, int offset, proto_tree *pt)
1793 char *mode, line[50];
1796 x = tvb_get_ntohl(tvb, offset);
1797 y = tvb_get_ntohl(tvb, offset+4);
1801 sprintf (line, "reserved");
1804 mode = "Average over time";
1807 sprintf (line, "Averaging period: %d.%03d seconds", seconds, y);
1810 mode = "Average over frame count";
1811 sprintf (line, "Averaging period: %d frames", y);
1814 mode = "- unknown -";
1815 sprintf (line, "reserved");
1817 proto_tree_add_text(pt, tvb, offset, 4, "Mode: %s", mode);
1819 proto_tree_add_text(pt, tvb, offset, 4, line, NULL);
1825 proto_register_gryphon(void)
1827 static hf_register_info hf[] = {
1829 { "Source", "gryph.src", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
1831 { &hf_gryph_srcchan,
1832 { "Source channel", "gryph.srcchan", FT_UINT8, BASE_DEC, NULL, 0x0,
1835 { "Destination", "gryph.dest", FT_UINT8, BASE_HEX, VALS(src_dest), 0x0,
1837 { &hf_gryph_destchan,
1838 { "Destination channel", "gryph.dstchan", FT_UINT8, BASE_DEC, NULL, 0x0,
1841 { "Frame type", "gryph.type", FT_UINT8, BASE_DEC, NULL, 0x0,
1844 { "Command", "gryph.cmd.cmd", FT_UINT8, BASE_DEC, NULL, 0x0,
1848 static gint *ett[] = {
1850 &ett_gryphon_header,
1852 &ett_gryphon_command_data,
1853 &ett_gryphon_response_data,
1854 &ett_gryphon_data_header,
1856 &ett_gryphon_data_body,
1857 &ett_gryphon_cmd_filter_block,
1858 &ett_gryphon_cmd_events_data,
1859 &ett_gryphon_cmd_config_device,
1860 &ett_gryphon_cmd_sched_data,
1861 &ett_gryphon_cmd_sched_cmd,
1862 &ett_gryphon_cmd_response_block,
1863 &ett_gryphon_pgm_list,
1864 &ett_gryphon_pgm_status,
1865 &ett_gryphon_pgm_options,
1867 module_t *gryphon_module;
1869 proto_gryphon = proto_register_protocol("DG Gryphon Protocol",
1872 proto_register_field_array(proto_gryphon, hf, array_length(hf));
1873 proto_register_subtree_array(ett, array_length(ett));
1875 gryphon_module = prefs_register_protocol(proto_gryphon, NULL);
1876 prefs_register_bool_preference(gryphon_module, "desegment",
1877 "Desegment all Gryphon messages spanning multiple TCP segments",
1878 "Whether the Gryphon dissector should desegment all messages spanning multiple TCP segments",
1879 &gryphon_desegment);
1883 proto_reg_handoff_gryphon(void)
1885 dissector_handle_t gryphon_handle;
1887 gryphon_handle = create_dissector_handle(dissect_gryphon, proto_gryphon);
1888 dissector_add("tcp.port", 7000, gryphon_handle);
1891 /* Start the functions we need for the plugin stuff */
1892 G_MODULE_EXPORT void
1893 plugin_reg_handoff(void){
1894 proto_reg_handoff_gryphon();
1897 G_MODULE_EXPORT void
1898 plugin_init(plugin_address_table_t *pat
1899 #ifndef PLUGINS_NEED_ADDRESS_TABLE
1903 /* initialise the table of pointers needed in Win32 DLLs */
1904 plugin_address_table_init(pat);
1905 /* register the new protocol, protocol fields, and subtrees */
1906 if (proto_gryphon == -1) { /* execute protocol initialization only once */
1907 proto_register_gryphon();
1910 /* End the functions we need for plugin stuff */