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.30 2002/05/01 06:15:44 guy 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"
35 #ifdef HAVE_SYS_TYPES_H
36 #include <sys/types.h>
44 #ifdef HAVE_NETINET_IN_H
45 # include <netinet/in.h>
47 #include <epan/packet.h>
48 #include "packet-gryphon.h"
49 #include "packet-frame.h"
52 #include "plugins/plugin_api_defs.h"
54 #ifndef __ETHEREAL_STATIC__
55 G_MODULE_EXPORT const gchar version[] = VERSION;
59 #error "Sorry, this won't compile without 64-bit integer support"
65 * http://www.dgtech.com/gryphon/docs/html/
68 static int proto_gryphon = -1;
70 static int hf_gryph_src = -1;
71 static int hf_gryph_srcchan = -1;
72 static int hf_gryph_dest = -1;
73 static int hf_gryph_destchan= -1;
74 static int hf_gryph_type = -1;
75 static int hf_gryph_cmd = -1;
77 static gint ett_gryphon = -1;
78 static gint ett_gryphon_header = -1;
79 static gint ett_gryphon_body = -1;
80 static gint ett_gryphon_command_data = -1;
81 static gint ett_gryphon_response_data = -1;
82 static gint ett_gryphon_data_header = -1;
83 static gint ett_gryphon_flags = -1;
84 static gint ett_gryphon_data_body = -1;
85 static gint ett_gryphon_cmd_filter_block = -1;
86 static gint ett_gryphon_cmd_events_data = -1;
87 static gint ett_gryphon_cmd_config_device = -1;
88 static gint ett_gryphon_cmd_sched_data = -1;
89 static gint ett_gryphon_cmd_sched_cmd = -1;
90 static gint ett_gryphon_cmd_response_block = -1;
91 static gint ett_gryphon_pgm_list = -1;
92 static gint ett_gryphon_pgm_status = -1;
93 static gint ett_gryphon_pgm_options = -1;
95 /* desegmentation of Gryphon */
96 static gboolean gryphon_desegment = TRUE;
98 static void dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo,
99 proto_tree *tree, gboolean is_msgresp_add);
100 static int decode_command(tvbuff_t*, int, int, proto_tree*);
101 static int decode_response(tvbuff_t*, int, int, proto_tree*);
102 static int decode_data(tvbuff_t*, int, int, proto_tree*);
103 static int decode_event(tvbuff_t*, int, int, proto_tree*);
104 static int cmd_init(tvbuff_t*, int, int, proto_tree*);
105 static int resp_time(tvbuff_t*, int, int, proto_tree*);
106 static int cmd_setfilt(tvbuff_t*, int, int, proto_tree*);
107 static int cmd_ioctl(tvbuff_t*, int, int, proto_tree*);
108 static int cmd_addfilt(tvbuff_t*, int, int, proto_tree*);
109 static int resp_addfilt(tvbuff_t*, int, int, proto_tree*);
110 static int cmd_modfilt(tvbuff_t*, int, int, proto_tree*);
111 static int resp_filthan(tvbuff_t*, int, int, proto_tree*);
112 static int dfiltmode(tvbuff_t*, int, int, proto_tree*);
113 static int filtmode(tvbuff_t*, int, int, proto_tree*);
114 static int resp_events(tvbuff_t*, int, int, proto_tree*);
115 static int cmd_register(tvbuff_t*, int, int, proto_tree*);
116 static int resp_register(tvbuff_t*, int, int, proto_tree*);
117 static int resp_getspeeds(tvbuff_t*, int, int, proto_tree*);
118 static int cmd_sort(tvbuff_t*, int, int, proto_tree*);
119 static int cmd_optimize(tvbuff_t*, int, int, proto_tree*);
120 static int resp_config(tvbuff_t*, int, int, proto_tree*);
121 static int cmd_sched(tvbuff_t*, int, int, proto_tree*);
122 static int resp_blm_data(tvbuff_t*, int, int, proto_tree*);
123 static int resp_blm_stat(tvbuff_t*, int, int, proto_tree*);
124 static int cmd_addresp(tvbuff_t*, int, int, proto_tree*);
125 static int resp_addresp(tvbuff_t*, int, int, proto_tree*);
126 static int cmd_modresp(tvbuff_t*, int, int, proto_tree*);
127 static int resp_resphan(tvbuff_t*, int, int, proto_tree*);
128 static int resp_sched(tvbuff_t*, int, int, proto_tree*);
129 static int cmd_desc(tvbuff_t*, int, int, proto_tree*);
130 static int resp_desc(tvbuff_t*, int, int, proto_tree*);
131 static int cmd_upload(tvbuff_t*, int, int, proto_tree*);
132 static int cmd_delete(tvbuff_t*, int, int, proto_tree*);
133 static int cmd_list(tvbuff_t*, int, int, proto_tree*);
134 static int resp_list(tvbuff_t*, int, int, proto_tree*);
135 static int cmd_start(tvbuff_t*, int, int, proto_tree*);
136 static int resp_start(tvbuff_t*, int, int, proto_tree*);
137 static int resp_status(tvbuff_t*, int, int, proto_tree*);
138 static int cmd_options(tvbuff_t*, int, int, proto_tree*);
139 static int cmd_files(tvbuff_t*, int, int, proto_tree*);
140 static int resp_files(tvbuff_t*, int, int, proto_tree*);
141 static int eventnum(tvbuff_t*, int, int, proto_tree*);
142 static int speed(tvbuff_t*, int, int, proto_tree*);
143 static int filter_block(tvbuff_t*, int, int, proto_tree*);
144 static int blm_mode(tvbuff_t*, int, int, proto_tree*);
145 static int cmd_usdt(tvbuff_t*, int, int, proto_tree*);
147 static char *frame_type[] = {
151 "Network (vehicle) data",
158 dissect_gryphon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
160 volatile int offset = 0;
161 int length_remaining;
168 while (tvb_reported_length_remaining(tvb, offset) != 0) {
169 length_remaining = tvb_length_remaining(tvb, offset);
172 * Can we do reassembly?
174 if (gryphon_desegment && pinfo->can_desegment) {
176 * Yes - is the Gryphon header split across segment boundaries?
178 if (length_remaining < 8) {
180 * Yes. Tell the TCP dissector where the data for
181 * this message starts in the data it handed us,
182 * and how many more bytes we need, and return.
184 pinfo->desegment_offset = offset;
185 pinfo->desegment_len = 8 - length_remaining;
191 * Get the length of the Gryphon packet, and then
192 * get the length as padded to a 4-byte boundary.
194 plen = tvb_get_ntohs(tvb, offset + 4);
195 padded_len = plen + 3 - (plen + 3) % 4;
198 * Can we do reassembly?
200 if (gryphon_desegment && pinfo->can_desegment) {
202 * Yes - is the Gryphon packet split across segment boundaries?
204 if (length_remaining < padded_len + 8) {
206 * Yes. Tell the TCP dissector where the data for
207 * this message starts in the data it handed us,
208 * and how many more bytes we need, and return.
210 pinfo->desegment_offset = offset;
211 pinfo->desegment_len = (padded_len + 8) - length_remaining;
217 * Construct a tvbuff containing the amount of the payload
218 * we have available. Make its reported length the
219 * amount of data in the Gryphon packet.
221 * XXX - if reassembly isn't enabled. the subdissector
222 * will throw a BoundsError exception, rather than a
223 * ReportedBoundsError exception. We really want
224 * a tvbuff where the length is "length", the reported
225 * length is "plen + 8", and the "if the snapshot length
226 * were infinite" length is the minimum of the
227 * reported length of the tvbuff handed to us and "plen+8",
228 * with a new type of exception thrown if the offset is
229 * within the reported length but beyond that third length,
230 * with that exception getting the "Unreassembled Packet"
233 length = length_remaining;
234 if (length > plen + 8)
236 next_tvb = tvb_new_subset(tvb, offset, length, plen + 8);
239 * Dissect the Gryphon packet.
241 * Catch the ReportedBoundsError exception; if this
242 * particular message happens to get a ReportedBoundsError
243 * exception, that doesn't mean that we should stop
244 * dissecting Gryphon messages within this frame or
245 * chunk of reassembled data.
247 * If it gets a BoundsError, we can stop, as there's nothing
248 * more to see, so we just re-throw it.
251 dissect_gryphon_message(next_tvb, pinfo, tree, FALSE);
256 CATCH(ReportedBoundsError) {
257 show_reported_bounds_error(tvb, pinfo, tree);
262 * Skip the Gryphon header and the payload.
264 offset += padded_len + 8;
269 dissect_gryphon_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
270 gboolean is_msgresp_add)
273 proto_tree *gryphon_tree;
275 proto_tree *header_tree, *body_tree, *localTree;
276 proto_item *header_item, *body_item, *localItem;
277 int start_offset, msgend;
279 unsigned int src, dest, i, frmtyp;
281 static const value_string src_dest[] = {
283 {SD_SERVER, "Server"},
284 {SD_CLIENT, "Client"},
285 {SD_SCHED, "Scheduler"},
286 {SD_SCRIPT, "Script Processor"},
287 {SD_PGM, "Program Loader"},
288 {SD_USDT, "USDT Server"},
289 {SD_BLM, "Bus Load Monitoring"},
290 {SD_FLIGHT, "Flight Recorder"},
291 {SD_RESP, "Message Responder"},
295 if (!is_msgresp_add) {
296 if (check_col(pinfo->cinfo, COL_PROTOCOL))
297 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Gryphon");
298 if (check_col(pinfo->cinfo, COL_INFO))
299 col_clear(pinfo->cinfo, COL_INFO);
302 if (!is_msgresp_add) {
303 ti = proto_tree_add_item(tree, proto_gryphon, tvb, 0, -1, FALSE);
304 gryphon_tree = proto_item_add_subtree(ti, ett_gryphon);
308 src = tvb_get_guint8(tvb, offset + 0);
309 dest = tvb_get_guint8(tvb, offset + 2);
310 msglen = tvb_get_ntohs(tvb, offset + 4);
311 flags = tvb_get_guint8(tvb, offset + 6);
312 frmtyp = flags & ~RESPONSE_FLAGS;
314 if (!is_msgresp_add) {
315 if (check_col(pinfo->cinfo, COL_INFO)) {
317 * Indicate what kind of message this is.
319 if (frmtyp >= SIZEOF (frame_type))
320 col_set_str(pinfo->cinfo, COL_INFO, "- Invalid -");
322 col_set_str(pinfo->cinfo, COL_INFO, frame_type[frmtyp]);
329 if (frmtyp >= SIZEOF (frame_type)) {
331 * Unknown message type.
333 proto_tree_add_text(gryphon_tree, tvb, offset, msglen, "Data");
337 header_item = proto_tree_add_text(gryphon_tree, tvb, offset, MSG_HDR_SZ, "Header");
338 header_tree = proto_item_add_subtree(header_item, ett_gryphon_header);
339 for (i = 0; i < SIZEOF(src_dest); i++) {
340 if (src_dest[i].value == src)
343 if (i >= SIZEOF(src_dest))
344 i = SIZEOF(src_dest) - 1;
345 proto_tree_add_text(header_tree, tvb, offset, 2,
346 "Source: %s, channel %u", src_dest[i].strptr,
347 tvb_get_guint8(tvb, offset + 1));
348 proto_tree_add_uint_hidden(header_tree, hf_gryph_src, tvb,
350 proto_tree_add_uint_hidden(header_tree, hf_gryph_srcchan, tvb,
351 offset+1, 1, tvb_get_guint8(tvb, offset + 1));
353 for (i = 0; i < SIZEOF(src_dest); i++) {
354 if (src_dest[i].value == dest)
357 if (i >= SIZEOF(src_dest))
358 i = SIZEOF(src_dest) - 1;
359 proto_tree_add_text(header_tree, tvb, offset+2, 2,
360 "Destination: %s, channel %u", src_dest[i].strptr,
361 tvb_get_guint8(tvb, offset + 3));
362 proto_tree_add_uint_hidden(header_tree, hf_gryph_dest, tvb,
364 proto_tree_add_uint_hidden(header_tree, hf_gryph_destchan, tvb,
365 offset+3, 1, tvb_get_guint8(tvb, offset + 3));
367 proto_tree_add_text(header_tree, tvb, offset+4, 2,
368 "Data length: %u bytes", msglen);
369 proto_tree_add_text(header_tree, tvb, offset+6, 1,
370 "Frame type: %s", frame_type[frmtyp]);
371 if (is_msgresp_add) {
372 localItem = proto_tree_add_text(header_tree, tvb, offset+6, 1, "Flags");
373 localTree = proto_item_add_subtree (localItem, ett_gryphon_flags);
374 if (flags & DONT_WAIT_FOR_RESP) {
375 proto_tree_add_text(localTree, tvb, offset+6, 1,
376 "1... .... = Don't wait for response");
378 proto_tree_add_text(localTree, tvb, offset+6, 1,
379 "0... .... = Wait for response");
381 if (flags & WAIT_FOR_PREV_RESP) {
382 proto_tree_add_text(localTree, tvb, offset+6, 1,
383 ".1.. .... = Wait for previous responses");
385 proto_tree_add_text(localTree, tvb, offset+6, 1,
386 ".0.. .... = Don't wait for previous responses");
389 proto_tree_add_text(header_tree, tvb, offset+7, 1, "reserved");
391 proto_tree_add_uint_hidden(header_tree, hf_gryph_type, tvb,
392 offset+6, 1, frmtyp);
393 msgpad = 3 - (msglen + 3) % 4;
394 msgend = offset + msglen + msgpad + MSG_HDR_SZ;
396 body_item = proto_tree_add_text(gryphon_tree, tvb, offset + MSG_HDR_SZ,
397 msglen + msgpad, "Body");
398 body_tree = proto_item_add_subtree(body_item, ett_gryphon_body);
400 start_offset = offset;
401 offset += MSG_HDR_SZ;
404 offset = decode_command(tvb, offset, dest, body_tree);
407 offset = decode_response(tvb, offset, src, body_tree);
410 offset = decode_data(tvb, offset, src, body_tree);
413 offset = decode_event(tvb, offset, src, body_tree);
422 if (offset < msgend - msgpad) {
423 i = msgend - msgpad - offset;
424 proto_tree_add_text(gryphon_tree, tvb, offset, i, "Data");
427 if (offset < msgend) {
429 proto_tree_add_text(gryphon_tree, tvb, offset, i, "padding");
435 static const val_str_dsp cmds[] = {
436 {CMD_INIT, "Initialize", cmd_init, NULL},
437 {CMD_GET_STAT, "Get status", NULL, NULL},
438 {CMD_GET_CONFIG, "Get configuration", NULL, resp_config},
439 {CMD_EVENT_ENABLE, "Enable event", eventnum, NULL},
440 {CMD_EVENT_DISABLE, "Disable event", eventnum, NULL},
441 {CMD_GET_TIME, "Get time", NULL, resp_time},
442 {CMD_GET_RXDROP, "Get number of dropped RX messages", NULL, NULL},
443 {CMD_RESET_RXDROP, "Clear number of dropped RX messages", NULL, NULL},
444 {CMD_BCAST_ON, "Set broadcasts on", NULL, NULL},
445 {CMD_BCAST_OFF, "Set broadcasts off", NULL, NULL},
446 {CMD_CARD_SET_SPEED, "Set channel baud rate", speed, NULL},
447 {CMD_CARD_GET_SPEED, "Get channel baud rate", NULL, speed},
448 {CMD_CARD_SET_FILTER, "Set filter (deprecated)", cmd_setfilt, NULL},
449 {CMD_CARD_GET_FILTER, "Get filter", resp_addfilt, cmd_addfilt},
450 {CMD_CARD_TX, "Transmit message", decode_data, NULL},
451 {CMD_CARD_TX_LOOP_ON, "Set transmit loopback on", NULL, NULL},
452 {CMD_CARD_TX_LOOP_OFF, "Set transmit loopback off", NULL, NULL},
453 {CMD_CARD_IOCTL, "IOCTL pass-through", cmd_ioctl, NULL},
454 {CMD_CARD_ADD_FILTER, "Add a filter", cmd_addfilt, resp_addfilt},
455 {CMD_CARD_MODIFY_FILTER, "Modify a filter", cmd_modfilt, NULL},
456 {CMD_CARD_GET_FILTER_HANDLES, "Get filter handles", NULL, resp_filthan},
457 {CMD_CARD_SET_DEFAULT_FILTER, "Set default filter", dfiltmode, NULL},
458 {CMD_CARD_GET_DEFAULT_FILTER, "Get default filter mode", NULL, dfiltmode},
459 {CMD_CARD_SET_FILTER_MODE, "Set filter mode", filtmode, NULL},
460 {CMD_CARD_GET_FILTER_MODE, "Get filter mode", NULL, filtmode},
461 {CMD_CARD_GET_EVNAMES, "Get event names", NULL, resp_events},
462 {CMD_CARD_GET_SPEEDS, "Get defined speeds", NULL, resp_getspeeds},
463 {CMD_SERVER_REG, "Register with server", cmd_register, resp_register},
464 {CMD_SERVER_SET_SORT, "Set the sorting behavior", cmd_sort, NULL},
465 {CMD_SERVER_SET_OPT, "Set the type of optimization", cmd_optimize, NULL},
466 {CMD_BLM_SET_MODE, "Set Bus Load Monitoring mode", blm_mode, NULL},
467 {CMD_BLM_GET_MODE, "Get Bus Load Monitoring mode", NULL, blm_mode},
468 {CMD_BLM_GET_DATA, "Get Bus Load data", NULL, resp_blm_data},
469 {CMD_BLM_GET_STATS, "Get Bus Load statistics", NULL, resp_blm_stat},
470 {CMD_FLIGHT_GET_CONFIG, "Get flight recorder channel info", NULL, NULL},
471 {CMD_FLIGHT_START_MON, "Start flight recorder monitoring", NULL, NULL},
472 {CMD_FLIGHT_STOP_MON, "Stop flight recorder monitoring", NULL, NULL},
473 {CMD_MSGRESP_ADD, "Add response message", cmd_addresp, resp_addresp},
474 {CMD_MSGRESP_GET, "Get response message", resp_addresp, cmd_addresp},
475 {CMD_MSGRESP_MODIFY, "Modify response message state", cmd_modresp, NULL},
476 {CMD_MSGRESP_GET_HANDLES, "Get response message handles", NULL, resp_resphan},
477 {CMD_PGM_DESC, "Describe program to to uploaded", cmd_desc, resp_desc},
478 {CMD_PGM_UPLOAD, "Upload a program to the Gryphon", cmd_upload, NULL},
479 {CMD_PGM_DELETE, "Delete an uploaded program", cmd_delete, NULL},
480 {CMD_PGM_LIST, "Get a list of uploaded programs", cmd_list, resp_list},
481 {CMD_PGM_START, "Start an uploaded program", cmd_start, resp_start},
482 {CMD_PGM_STOP, "Stop an uploaded program", resp_start, NULL},
483 {CMD_PGM_STATUS, "Get status of an uploaded program", cmd_delete, resp_status},
484 {CMD_PGM_OPTIONS, "Set program upload options", cmd_options, resp_status},
485 {CMD_PGM_FILES, "Get a list of files & directories", cmd_files, resp_files},
486 {CMD_SCHED_TX, "Schedule transmission of messages", cmd_sched, resp_sched},
487 {CMD_SCHED_KILL_TX, "Stop and destroy a message transmission", NULL, NULL},
488 {CMD_SCHED_STOP_TX, "Kill a message transmission (deprecated)", NULL, NULL},
489 {CMD_USDT_IOCTL, "Register/Unregister with USDT server", cmd_usdt, NULL},
490 {-1, "- unknown -", NULL, NULL},
493 static const value_string responses[] = {
494 {RESP_OK, "OK - no error"},
495 {RESP_UNKNOWN_ERR, "Unknown error"},
496 {RESP_UNKNOWN_CMD, "Unrecognised command"},
497 {RESP_UNSUPPORTED, "Unsupported command"},
498 {RESP_INVAL_CHAN, "Invalid channel specified"},
499 {RESP_INVAL_DST, "Invalid destination"},
500 {RESP_INVAL_PARAM, "Invalid parameter(s)"},
501 {RESP_INVAL_MSG, "Invalid message"},
502 {RESP_INVAL_LEN, "Invalid length field"},
503 {RESP_TX_FAIL, "Transmit failed"},
504 {RESP_RX_FAIL, "Receive failed"},
505 {RESP_AUTH_FAIL, "Authorization failed"},
506 {RESP_MEM_ALLOC_ERR, "Memory allocation error"},
507 {RESP_TIMEOUT, "Command timed out"},
508 {RESP_UNAVAILABLE, "Unavailable"},
509 {RESP_BUF_FULL, "Buffer full"},
510 {RESP_NO_SUCH_JOB, "No such job"},
514 static const value_string filter_data_types[] = {
515 {FILTER_DATA_TYPE_HEADER_FRAME, "frame header"},
516 {FILTER_DATA_TYPE_HEADER, "data message header"},
517 {FILTER_DATA_TYPE_DATA, "data message data"},
518 {FILTER_DATA_TYPE_EXTRA_DATA, "data message extra data"},
519 {FILTER_EVENT_TYPE_HEADER, "event message header"},
520 {FILTER_EVENT_TYPE_DATA, "event message"},
524 static const value_string operators[] = {
525 {BIT_FIELD_CHECK, "Bit field check"},
526 {SVALUE_GT, "Greater than (signed)"},
527 {SVALUE_GE, "Greater than or equal to (signed)"},
528 {SVALUE_LT, "Less than (signed)"},
529 {SVALUE_LE, "Less than or equal to (signed)"},
530 {VALUE_EQ, "Equal to"},
531 {VALUE_NE, "Not equal to"},
532 {UVALUE_GT, "Greater than (unsigned)"},
533 {UVALUE_GE, "Greater than or equal to (unsigned)"},
534 {UVALUE_LT, "Less than (unsigned)"},
535 {UVALUE_LE, "Less than or equal to (unsigned)"},
536 {DIG_LOW_TO_HIGH, "Digital, low to high transistion"},
537 {DIG_HIGH_TO_LOW, "Digital, high to low transistion"},
538 {DIG_TRANSITION, "Digital, change of state"},
542 static const value_string modes[] = {
543 {FILTER_OFF_PASS_ALL, "Filter off, pass all messages"},
544 {FILTER_OFF_BLOCK_ALL, "Filter off, block all messages"},
545 {FILTER_ON, "Filter on"},
549 static const value_string dmodes[] = {
550 {DEFAULT_FILTER_BLOCK, "Block"},
551 {DEFAULT_FILTER_PASS, "Pass"},
555 static const value_string filtacts[] = {
556 {DELETE_FILTER, "Delete"},
557 {ACTIVATE_FILTER, "Activate"},
558 {DEACTIVATE_FILTER, "Deactivate"},
562 static const value_string ioctls[] = {
563 {GINIT, "GINIT: Initialize"},
564 {GLOOPON, "GLOOPON: Loop on"},
565 {GLOOPOFF, "GLOOPOFF: Loop off"},
566 {GGETHWTYPE, "GGETHWTYPE: Get hardware type"},
567 {GGETREG, "GGETREG: Get register"},
568 {GSETREG, "GSETREG: Set register"},
569 {GGETRXCOUNT, "GGETRXCOUNT: Get the receive message counter"},
570 {GSETRXCOUNT, "GSETRXCOUNT: Set the receive message counter"},
571 {GGETTXCOUNT, "GGETTXCOUNT: Get the transmit message counter"},
572 {GSETTXCOUNT, "GSETTXCOUNT: Set the transmit message counter"},
573 {GGETRXDROP, "GGETRXDROP: Get the number of dropped receive messages"},
574 {GSETRXDROP, "GSETRXDROP: Set the number of dropped receive messages"},
575 {GGETTXDROP, "GGETTXDROP: Get the number of dropped transmit messages"},
576 {GSETTXDROP, "GSETTXDROP: Set the number of dropped transmit messages"},
577 {GGETRXBAD, "GGETRXBAD: Get the number of bad receive messages"},
578 {GGETTXBAD, "GGETTXBAD: Get the number of bad transmit messages"},
579 {GGETCOUNTS, "GGETCOUNTS: Get total message counter"},
580 {GGETBLMON, "GGETBLMON: Get bus load monitoring status"},
581 {GSETBLMON, "GSETBLMON: Set bus load monitoring status (turn on/off)"},
582 {GGETERRLEV, "GGETERRLEV: Get error level"},
583 {GSETERRLEV, "GSETERRLEV: Set error level"},
584 {GGETBITRATE, "GGETBITRATE: Get bit rate"},
585 {GGETRAM, "GGETRAM: Read value from RAM"},
586 {GSETRAM, "GSETRAM: Write value to RAM"},
587 {GCANGETBTRS, "GCANGETBTRS: Read CAN bit timing registers"},
588 {GCANSETBTRS, "GCANSETBTRS: Write CAN bit timing registers"},
589 {GCANGETBC, "GCANGETBC: Read CAN byte count"},
590 {GCANSETBC, "GCANSETBC: Write CAN byte count"},
591 {GCANGETMODE, "GCANGETMODE"},
592 {GCANSETMODE, "GCANSETMODE"},
593 {GCANGETTRANS, "GCANGETTRANS"},
594 {GCANSETTRANS, "GCANSETTRANS"},
595 {GCANSENDERR, "GCANSENDERR"},
596 {GCANRGETOBJ, "GCANRGETOBJ"},
597 {GCANRSETSTDID, "GCANRSETSTDID"},
598 {GCANRSETEXTID, "GCANRSETEXTID"},
599 {GCANRSETDATA, "GCANRSETDATA"},
600 {GCANRENABLE, "GCANRENABLE"},
601 {GCANRDISABLE, "GCANRDISABLE"},
602 {GCANRGETMASKS, "GCANRGETMASKS"},
603 {GCANRSETMASKS, "GCANRSETMASKS"},
604 {GCANSWGETMODE, "GCANSWGETMODE"},
605 {GCANSWSETMODE, "GCANSWSETMODE"},
606 {GDLCGETFOURX, "GDLCGETFOURX"},
607 {GDLCSETFOURX, "GDLCSETFOURX"},
608 {GDLCGETLOAD, "GDLCGETLOAD"},
609 {GDLCSETLOAD, "GDLCSETLOAD"},
610 {GDLCSENDBREAK, "GDLCSENDBREAK"},
611 {GDLCABORTTX, "GDLCABORTTX"},
612 {GDLCGETHDRMODE, "DLCGETHDRMODE"},
613 {GDLCSETHDRMODE, "GDLCSETHDRMODE"},
614 {GHONSLEEP, "GHONSLEEP"},
615 {GHONSILENCE, "GHONSILENCE"},
616 {GKWPSETPTIMES, "GKWPSETPTIMES"},
617 {GKWPSETWTIMES, "GKWPSETWTIMES"},
618 {GKWPDOWAKEUP, "GKWPDOWAKEUP"},
619 {GKWPGETBITTIME, "GKWPGETBITTIME"},
620 {GKWPSETBITTIME, "GKWPSETBITTIME"},
621 {GKWPSETNODEADDR, "GKWPSETNODEADDR"},
622 {GKWPGETNODETYPE, "GKWPGETNODETYPE"},
623 {GKWPSETNODETYPE, "GKWPSETNODETYPE"},
624 {GKWPSETWAKETYPE, "GKWPSETWAKETYPE"},
625 {GKWPSETTARGADDR, "GKWPSETTARGADDR"},
626 {GKWPSETKEYBYTES, "GKWPSETKEYBYTES"},
627 {GKWPSETSTARTREQ, "GKWPSETSTARTREQ"},
628 {GKWPSETSTARTRESP, "GKWPSETSTARTRESP"},
629 {GKWPSETPROTOCOL, "GKWPSETPROTOCOL"},
630 {GKWPGETLASTKEYBYTES, "GKWPGETLASTKEYBYTES"},
631 {GKWPSETLASTKEYBYTES, "GKWPSETLASTKEYBYTES"},
632 {GSCPGETBBR, "GSCPGETBBR"},
633 {GSCPSETBBR, "GSCPSETBBR"},
634 {GSCPGETID, "GSCPGETID"},
635 {GSCPSETID, "GSCPSETID"},
636 {GSCPADDFUNCID, "GSCPADDFUNCID"},
637 {GSCPCLRFUNCID, "GSCPCLRFUNCID"},
638 {GUBPGETBITRATE, "GUBPGETBITRATE"},
639 {GUBPSETBITRATE, "GUBPSETBITRATE"},
640 {GUBPGETINTERBYTE, "GUBPGETINTERBYTE"},
641 {GUBPSETINTERBYTE, "GUBPSETINTERBYTE"},
642 {GUBPGETNACKMODE, "GUBPGETNACKMODE"},
643 {GUBPSETNACKMODE, "GUBPSETNACKMODE"},
649 decode_command(tvbuff_t *tvb, int offset, int dst, proto_tree *pt)
651 int cmd, padding, msglen;
656 msglen = tvb_reported_length_remaining(tvb, offset);
657 cmd = tvb_get_guint8(tvb, offset);
658 proto_tree_add_uint_hidden(pt, hf_gryph_cmd, tvb, offset, 1, cmd);
662 for (i = 0; i < SIZEOF(cmds); i++) {
663 if (cmds[i].value == cmd)
666 if (i >= SIZEOF(cmds) && dst >= SD_KNOWN) {
667 cmd = (cmd & 0xFF) + SD_CARD * 256;
668 for (i = 0; i < SIZEOF(cmds); i++) {
669 if (cmds[i].value == cmd)
673 if (i >= SIZEOF(cmds))
674 i = SIZEOF(cmds) - 1;
676 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
680 if (cmds[i].cmd_fnct && msglen > 0) {
681 padding = 3 - (msglen + 3) % 4;
682 ti = proto_tree_add_text(pt, tvb, offset, -1, "Data: (%d bytes)", msglen);
683 ft = proto_item_add_subtree(ti, ett_gryphon_command_data);
684 offset = (*(cmds[i].cmd_fnct)) (tvb, offset, dst, ft);
690 decode_response(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
693 unsigned int i, j, resp;
697 msglen = tvb_reported_length_remaining(tvb, offset);
698 cmd = tvb_get_guint8(tvb, offset);
702 for (i = 0; i < SIZEOF(cmds); i++) {
703 if (cmds[i].value == cmd)
706 if (i >= SIZEOF(cmds) && src >= SD_KNOWN) {
707 cmd = (cmd & 0xFF) + SD_CARD * 256;
708 for (i = 0; i < SIZEOF(cmds); i++) {
709 if (cmds[i].value == cmd)
713 if (i >= SIZEOF(cmds))
714 i = SIZEOF(cmds) - 1;
715 proto_tree_add_text (pt, tvb, offset, 4, "Command: %s", cmds[i].strptr);
719 resp = tvb_get_ntohl (tvb, offset);
720 for (j = 0; j < SIZEOF(responses); j++) {
721 if (responses[j].value == resp)
724 if (j >= SIZEOF(responses))
725 j = SIZEOF(responses) - 1;
726 proto_tree_add_text (pt, tvb, offset, 4, "Status: %s", responses[j].strptr);
730 if (cmds[i].rsp_fnct && msglen > 0) {
731 ti = proto_tree_add_text(pt, tvb, offset, msglen, "Data: (%d bytes)", msglen);
732 ft = proto_item_add_subtree(ti, ett_gryphon_response_data);
733 offset = (*(cmds[i].rsp_fnct)) (tvb, offset, src, ft);
739 decode_data(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
741 proto_item *item, *item1;
742 proto_tree *tree, *tree1;
743 int hdrsize, datasize, extrasize, hdrbits, msgsize, padding, mode;
744 int hours, minutes, seconds, fraction;
745 unsigned long timestamp;
747 hdrsize = tvb_get_guint8(tvb, offset+0);
748 hdrbits = tvb_get_guint8(tvb, offset+1);
749 datasize = tvb_get_ntohs(tvb, offset+2);
750 extrasize = tvb_get_guint8(tvb, offset+4);
751 padding = 3 - (hdrsize + datasize + extrasize + 3) % 4;
752 msgsize = hdrsize + datasize + extrasize + padding + 16;
754 item = proto_tree_add_text(pt, tvb, offset, 16, "Message header");
755 tree = proto_item_add_subtree (item, ett_gryphon_data_header);
756 proto_tree_add_text(tree, tvb, offset, 2, "Header length: %d bytes, %d bits", hdrsize, hdrbits);
757 proto_tree_add_text(tree, tvb, offset+2, 2, "Data length: %d bytes", datasize);
758 proto_tree_add_text(tree, tvb, offset+4, 1, "Extra data length: %d bytes", extrasize);
759 mode = tvb_get_guint8(tvb, offset+5);
760 item1 = proto_tree_add_text(tree, tvb, offset+5, 1, "Mode: %d", mode);
762 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
764 proto_tree_add_text(tree1, tvb, offset+5, 1, "1... .... = Transmitted message");
766 proto_tree_add_text(tree1, tvb, offset+5, 1, ".1.. .... = Received message");
768 proto_tree_add_text(tree1, tvb, offset+5, 1, "..1. .... = Local message");
770 proto_tree_add_text(tree1, tvb, offset+5, 1, "...1 .... = Remote message");
772 proto_tree_add_text(tree1, tvb, offset+5, 1, ".... ...1 = Internal message");
774 proto_tree_add_text(tree, tvb, offset+6, 1, "Priority: %u",
775 tvb_get_guint8(tvb, offset+6));
776 proto_tree_add_text(tree, tvb, offset+7, 1, "Error status: %u",
777 tvb_get_guint8(tvb, offset+7));
778 timestamp = tvb_get_ntohl(tvb, offset+8);
779 hours = timestamp /(100000 * 60 *60);
780 minutes = (timestamp / (100000 * 60)) % 60;
781 seconds = (timestamp / 100000) % 60;
782 fraction = timestamp % 100000;
783 proto_tree_add_text(tree, tvb, offset+8, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
784 proto_tree_add_text(tree, tvb, offset+12, 1, "Context: %u",
785 tvb_get_guint8(tvb, offset+12));
786 proto_tree_add_text(tree, tvb, offset+13, 3, "reserved:");
788 item = proto_tree_add_text(pt, tvb, offset, msgsize-16-padding, "Message Body");
789 tree = proto_item_add_subtree (item, ett_gryphon_data_body);
791 proto_tree_add_text(tree, tvb, offset, hdrsize, "Header");
795 proto_tree_add_text(tree, tvb, offset, datasize, "Data");
799 proto_tree_add_text(tree, tvb, offset, extrasize, "Extra data");
803 proto_tree_add_text(pt, tvb, offset, padding, "padding");
810 decode_event(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
813 int hours, minutes, seconds, fraction, padding, length;
814 unsigned long timestamp;
817 msglen = tvb_reported_length_remaining(tvb, offset);
818 padding = 3 - (msglen + 3) % 4;
819 msgend = offset + msglen;
820 proto_tree_add_text(pt, tvb, offset, 1, "Event ID: %u",
821 tvb_get_guint8(tvb, offset));
822 proto_tree_add_text(pt, tvb, offset+1, 1, "Event context: %u",
823 tvb_get_guint8(tvb, offset+1));
824 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
826 timestamp = tvb_get_ntohl(tvb, offset);
827 hours = timestamp /(100000 * 60 *60);
828 minutes = (timestamp / (100000 * 60)) % 60;
829 seconds = (timestamp / 100000) % 60;
830 fraction = timestamp % 100000;
831 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
833 if (offset < msgend) {
834 length = msgend - offset;
835 proto_tree_add_text (pt, tvb, offset, length, "Data (%d bytes)", length);
839 proto_tree_add_text(pt, tvb, offset, padding, "padding");
846 cmd_init(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
850 if (tvb_get_guint8(tvb, offset) == 0)
851 ptr = "Always initialize";
853 ptr = "Initialize if not previously initialized";
854 proto_tree_add_text(pt, tvb, offset, 1, "Mode: %s", ptr);
855 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
861 eventnum(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
863 guint8 event = tvb_get_guint8(tvb, offset);
866 proto_tree_add_text(pt, tvb, offset, 1, "Event number: %u", event);
868 proto_tree_add_text(pt, tvb, offset, 1, "Event numbers: All");
869 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
875 resp_time(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
877 int hours, minutes, seconds, fraction;
882 unsigned int timestamp;
883 unsigned char date[45];
885 ts.lng[1] = tvb_get_ntohl(tvb, offset);
886 ts.lng[0] = tvb_get_ntohl(tvb, offset + 4);
887 timestamp = ts.lnglng / 100000L;
888 strncpy (date, ctime((time_t*)×tamp), sizeof(date));
889 date[strlen(date)-1] = 0x00;
890 proto_tree_add_text(pt, tvb, offset, 8, "Date/Time: %s", date);
891 timestamp = ts.lng[0];
892 hours = timestamp /(100000 * 60 *60);
893 minutes = (timestamp / (100000 * 60)) % 60;
894 seconds = (timestamp / 100000) % 60;
895 fraction = timestamp % 100000;
896 proto_tree_add_text(pt, tvb, offset+4, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
902 cmd_setfilt(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
904 int flag = tvb_get_ntohl(tvb, offset);
906 unsigned char mode[30];
908 length = tvb_get_guint8(tvb, offset+4) + tvb_get_guint8(tvb, offset+5)
909 + tvb_get_ntohs(tvb, offset+6);
911 strcpy (mode, "Pass");
913 strcpy (mode, "Block");
915 strcat (mode, " all");
916 proto_tree_add_text(pt, tvb, offset, 4, "Pass/Block flag: %s", mode);
917 proto_tree_add_text(pt, tvb, offset+4, 4, "Length of Pattern & Mask: %d", length);
920 proto_tree_add_text(pt, tvb, offset, length * 2, "discarded data");
921 offset += length * 2;
923 padding = 3 - (length * 2 + 3) % 4;
925 proto_tree_add_text(pt, tvb, offset+1, 3, "padding");
932 cmd_ioctl(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
935 unsigned int ioctl, i;
937 msglen = tvb_reported_length_remaining(tvb, offset);
938 ioctl = tvb_get_ntohl(tvb, offset);
939 for (i = 0; i < SIZEOF(ioctls); i++) {
940 if (ioctls[i].value == ioctl)
943 if (i >= SIZEOF(ioctls))
944 i = SIZEOF(ioctls) - 1;
945 proto_tree_add_text(pt, tvb, offset, 4, "IOCTL: %s", ioctls[i].strptr);
949 proto_tree_add_text(pt, tvb, offset, msglen, "Data");
956 cmd_addfilt(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
961 int blocks, i, length;
963 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags");
964 tree = proto_item_add_subtree (item, ett_gryphon_flags);
965 flags = tvb_get_guint8(tvb, offset);
966 proto_tree_add_text(tree, tvb, offset, 1, "%s",
967 decode_boolean_bitfield(flags, FILTER_PASS_FLAG, 8,
968 "Conforming messages are passed",
969 "Conforming messages are blocked"));
970 proto_tree_add_text(tree, tvb, offset, 1, "%s",
971 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
972 "The filter is active", "The filter is inactive"));
974 blocks = tvb_get_guint8(tvb, offset);
975 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
976 proto_tree_add_text(pt, tvb, offset+1, 6, "reserved");
978 for (i = 1; i <= blocks; i++) {
979 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
980 length += 3 - (length + 3) % 4;
981 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
982 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
983 offset = filter_block(tvb, offset, src, tree);
989 resp_addfilt(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
991 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
992 tvb_get_guint8(tvb, offset));
993 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
999 cmd_modfilt(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1001 guint8 filter_handle;
1002 unsigned char action, i;
1004 filter_handle = tvb_get_guint8(tvb, offset);
1006 proto_tree_add_text(pt, tvb, offset, 1, "Filter handle: %u",
1009 proto_tree_add_text(pt, tvb, offset, 1, "Filter handles: all");
1010 action = tvb_get_guint8(tvb, offset + 1);
1011 for (i = 0; i < SIZEOF(filtacts); i++) {
1012 if (filtacts[i].value == action)
1015 if (i >= SIZEOF(filtacts))
1016 i = SIZEOF(filtacts) - 1;
1017 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s filter", filtacts[i].strptr);
1018 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1024 resp_filthan(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1026 int handles = tvb_get_guint8(tvb, offset);
1029 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter handles: %d", handles);
1030 for (i = 1; i <= handles; i++){
1031 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1032 tvb_get_guint8(tvb, offset+i));
1034 padding = 3 - (handles + 1 + 3) % 4;
1036 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1037 offset += 1+handles+padding;
1042 dfiltmode(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1047 mode = tvb_get_guint8(tvb, offset);
1048 for (i = 0; i < SIZEOF(modes); i++) {
1049 if (dmodes[i].value == mode)
1052 if (i >= SIZEOF(dmodes))
1053 i = SIZEOF(dmodes) - 1;
1054 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s", dmodes[i].strptr);
1055 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1061 filtmode(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1066 mode = tvb_get_guint8(tvb, offset);
1067 for (i = 0; i < SIZEOF(modes); i++) {
1068 if (modes[i].value == mode)
1071 if (i >= SIZEOF(modes))
1072 i = SIZEOF(modes) - 1;
1073 proto_tree_add_text(pt, tvb, offset, 1, "Filter mode: %s", modes[i].strptr);
1074 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1080 resp_events(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1087 msglen = tvb_reported_length_remaining(tvb, offset);
1089 while (msglen != 0) {
1090 item = proto_tree_add_text(pt, tvb, offset, 20, "Event %d:", i);
1091 tree = proto_item_add_subtree (item, ett_gryphon_cmd_events_data);
1092 proto_tree_add_text(tree, tvb, offset, 1, "Event ID: %u",
1093 tvb_get_guint8(tvb, offset));
1094 proto_tree_add_text(tree, tvb, offset+1, 19, "Event name: %.19s",
1095 tvb_get_ptr(tvb, offset+1, 19));
1104 cmd_register(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1106 proto_tree_add_text(pt, tvb, offset, 16, "Username: %.16s",
1107 tvb_get_ptr(tvb, offset, 16));
1109 proto_tree_add_text(pt, tvb, offset, 32, "Password: %.32s",
1110 tvb_get_ptr(tvb, offset, 32));
1116 resp_register(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1118 proto_tree_add_text(pt, tvb, offset, 1, "Client ID: %u",
1119 tvb_get_guint8(tvb, offset));
1120 proto_tree_add_text(pt, tvb, offset+1, 1, "Privileges: %u",
1121 tvb_get_guint8(tvb, offset+1));
1122 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1129 resp_getspeeds(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1135 proto_tree_add_text(pt, tvb, offset, 4, "Set Speed IOCTL");
1136 proto_tree_add_text(pt, tvb, offset+4, 4, "Get Speed IOCTL");
1137 size = tvb_get_guint8(tvb, offset+8);
1138 proto_tree_add_text(pt, tvb, offset+8, 1, "Speed data size is %d bytes", size);
1139 number = tvb_get_guint8(tvb, offset+9);
1140 proto_tree_add_text(pt, tvb, offset+9, 1, "There are %d preset speeds", number);
1142 for (index = 0; index < number; index++) {
1143 proto_tree_add_text(pt, tvb, offset, size, "Data for preset %d",
1151 cmd_sort(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1155 which = tvb_get_guint8(tvb, offset) ?
1156 "Sort into blocks of up to 16 messages" :
1157 "Do not sort messages";
1158 proto_tree_add_text(pt, tvb, offset, 1, "Set sorting: %s", which);
1164 cmd_optimize(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1168 which = tvb_get_guint8(tvb, offset) ?
1169 "Optimize for latency (Nagle algorithm disabled)" :
1170 "Optimize for throughput (Nagle algorithm enabled)";
1171 proto_tree_add_text(pt, tvb, offset, 1, "Set optimization: %s", which);
1177 resp_config(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1185 static const value_string protocol_types[] = {
1186 {GDUMMY * 256 + GDGDMARKONE, "Dummy device driver"},
1187 {GCAN * 256 + G82527, "CAN, 82527 subtype"},
1188 {GCAN * 256 + GSJA1000, "CAN, SJA1000 subtype"},
1189 {GCAN * 256 + G82527SW, "CAN, 82527 single wire subtype"},
1190 {GJ1850 * 256 + GHBCCPAIR, "J1850, HBCC subtype"},
1191 {GJ1850 * 256 + GDLC, "J1850, GM DLC subtype"},
1192 {GJ1850 * 256 + GCHRYSLER, "J1850, Chrysler subtype"},
1193 {GJ1850 * 256 + GDEHC12, "J1850, DE HC12 KWP/BDLC subtype"},
1194 {GKWP2000 * 256 + GDEHC12KWP, "Keyword protocol 2000"},
1195 {GHONDA * 256 + GDGHC08, "Honda UART, DG HC08 subtype"},
1196 {GFORDUBP * 256 + GDGUBP08, "Ford UBP, DG HC08 subtype"},
1197 {-1, "- unknown -"},
1200 proto_tree_add_text(pt, tvb, offset, 20, "Device name: %.20s",
1201 tvb_get_ptr(tvb, offset, 20));
1204 proto_tree_add_text(pt, tvb, offset, 8, "Device version: %.8s",
1205 tvb_get_ptr(tvb, offset, 8));
1208 proto_tree_add_text(pt, tvb, offset, 20, "Device serial number: %.20s",
1209 tvb_get_ptr(tvb, offset, 20));
1212 devices = tvb_get_guint8(tvb, offset);
1213 proto_tree_add_text(pt, tvb, offset, 1, "Number of channels: %d", devices);
1214 proto_tree_add_text(pt, tvb, offset+1, 15, "reserved");
1216 for (i = 1; i <= devices; i++) {
1217 ti = proto_tree_add_text(pt, tvb, offset, 80, "Channel %d:", i);
1218 ft = proto_item_add_subtree(ti, ett_gryphon_cmd_config_device);
1219 proto_tree_add_text(ft, tvb, offset, 20, "Driver name: %.20s",
1220 tvb_get_ptr(tvb, offset, 20));
1223 proto_tree_add_text(ft, tvb, offset, 8, "Driver version: %.8s",
1224 tvb_get_ptr(tvb, offset, 8));
1227 proto_tree_add_text(ft, tvb, offset, 24, "Device security string: %.24s",
1228 tvb_get_ptr(tvb, offset, 24));
1231 proto_tree_add_text(ft, tvb, offset, 20, "Hardware serial number: %.20s",
1232 tvb_get_ptr(tvb, offset, 20));
1235 x = tvb_get_ntohs(tvb, offset);
1236 for (j = 0; j < SIZEOF(protocol_types); j++) {
1237 if (protocol_types[j].value == x)
1240 if (j >= SIZEOF(protocol_types))
1241 j = SIZEOF(protocol_types) -1;
1242 proto_tree_add_text(ft, tvb, offset, 2, "Protocol type & subtype: %s", protocol_types[j].strptr);
1245 proto_tree_add_text(ft, tvb, offset, 1, "Channel ID: %u",
1246 tvb_get_guint8(tvb, offset));
1247 proto_tree_add_text(ft, tvb, offset+1, 5, "reserved");
1254 cmd_sched(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1257 proto_item *item, *item1;
1258 proto_tree *tree, *tree1;
1260 unsigned int i, x, length;
1261 unsigned char def_chan = tvb_get_guint8(tvb, offset-9);
1263 msglen = tvb_reported_length_remaining(tvb, offset);
1264 x = tvb_get_ntohl(tvb, offset);
1265 if (x == 0xFFFFFFFF)
1266 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: infinite");
1268 proto_tree_add_text(pt, tvb, offset, 4, "Number of iterations: %u", x);
1271 x = tvb_get_ntohl(tvb, offset);
1272 item = proto_tree_add_text(pt, tvb, offset, 4, "Flags: 0x%08x", x);
1273 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1274 proto_tree_add_text(tree, tvb, offset, 4, "%s",
1275 decode_boolean_bitfield(x, 0x01, 32,
1276 "Critical scheduler", "Normal scheduler"));
1280 while (msglen > 0) {
1281 length = 16 + tvb_get_guint8(tvb, offset+16) +
1282 tvb_get_ntohs(tvb, offset+18) + tvb_get_guint8(tvb, offset+20) + 16;
1283 length += 3 - (length + 3) % 4;
1284 item = proto_tree_add_text(pt, tvb, offset, length, "Message %d", i);
1285 tree = proto_item_add_subtree (item, ett_gryphon_cmd_sched_data);
1286 x = tvb_get_ntohl(tvb, offset);
1287 proto_tree_add_text(tree, tvb, offset, 4, "Sleep: %u milliseconds", x);
1290 x = tvb_get_ntohl(tvb, offset);
1291 proto_tree_add_text(tree, tvb, offset, 4, "Transmit count: %u", x);
1294 x = tvb_get_ntohl(tvb, offset);
1295 proto_tree_add_text(tree, tvb, offset, 4, "Transmit period: %u milliseconds", x);
1298 proto_tree_add_text(tree, tvb, offset, 2, "reserved flags");
1299 x = tvb_get_guint8(tvb, offset+2);
1302 proto_tree_add_text(tree, tvb, offset+2, 1, "Channel: %u", x);
1303 proto_tree_add_text(tree, tvb, offset+3, 1, "reserved");
1306 item1 = proto_tree_add_text(tree, tvb, offset, length, "Message");
1307 tree1 = proto_item_add_subtree (item1, ett_gryphon_cmd_sched_cmd);
1308 save_offset = offset;
1309 offset = decode_data(tvb, offset, src, tree1);
1310 msglen -= offset - save_offset;
1317 resp_blm_data(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1320 int hours, minutes, seconds, fraction, x, fract;
1321 unsigned long timestamp;
1322 static char *fields[] = {
1323 "Bus load average: %d.%02d%%",
1324 "Current bus load: %d.%02d%%",
1325 "Peak bus load: %d.%02d%%",
1326 "Historic peak bus load: %d.%02d%%"
1329 timestamp = tvb_get_ntohl(tvb, offset);
1330 hours = timestamp /(100000 * 60 *60);
1331 minutes = (timestamp / (100000 * 60)) % 60;
1332 seconds = (timestamp / 100000) % 60;
1333 fraction = timestamp % 100000;
1334 proto_tree_add_text(pt, tvb, offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
1336 for (i = 0; i < SIZEOF(fields); i++){
1337 x = tvb_get_ntohs(tvb, offset);
1340 proto_tree_add_text(pt, tvb, offset, 2, fields[i], x, fract);
1347 resp_blm_stat(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1351 "Receive frame count: %u",
1352 "Transmit frame count: %u",
1353 "Receive dropped frame count: %u",
1354 "Transmit dropped frame count: %u",
1355 "Receive error count: %u",
1356 "Transmit error count: %u",
1359 offset = resp_blm_data(tvb, offset, src, pt);
1360 for (i = 0; i < SIZEOF(fields); i++){
1361 x = tvb_get_ntohl(tvb, offset);
1362 proto_tree_add_text(pt, tvb, offset, 4, fields[i], x);
1368 static const value_string action_vals[] = {
1369 { FR_RESP_AFTER_EVENT, "Send response(s) for each conforming message" },
1370 { FR_RESP_AFTER_PERIOD, "Send response(s) after the specified period expires following a conforming message" },
1371 { FR_IGNORE_DURING_PER, "Send response(s) for a conforming message and ignore\nfurther messages until the specified period expires" },
1375 static const value_string deact_on_event_vals[] = {
1376 { FR_DEACT_ON_EVENT,
1377 "Deactivate this response for a conforming message" },
1378 { FR_DELETE|FR_DEACT_ON_EVENT,
1379 "Delete this response for a conforming message" },
1384 static const value_string deact_after_per_vals[] = {
1385 { FR_DEACT_AFTER_PER,
1386 "Deactivate this response after the specified period following a conforming message" },
1387 { FR_DELETE|FR_DEACT_AFTER_PER,
1388 "Delete this response after the specified period following a conforming message" },
1394 cmd_addresp(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1399 int blocks, responses, old_handle, i, msglen, length;
1400 int action, actionType, actionValue;
1404 flags = tvb_get_guint8(tvb, offset);
1405 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1406 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1407 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1408 decode_boolean_bitfield(flags, FILTER_ACTIVE_FLAG, 8,
1409 "The response is active", "The response is inactive"));
1411 blocks = tvb_get_guint8(tvb, offset);
1412 proto_tree_add_text(pt, tvb, offset, 1, "Number of filter blocks = %d", blocks);
1414 responses = tvb_get_guint8(tvb, offset);
1415 proto_tree_add_text(pt, tvb, offset, 1, "Number of response blocks = %d", responses);
1417 old_handle = tvb_get_guint8(tvb, offset);
1418 proto_tree_add_text(pt, tvb, offset, 1, "Old handle = %d", old_handle);
1420 action = tvb_get_guint8(tvb, offset);
1421 item = proto_tree_add_text(pt, tvb, offset, 1, "Action: %s",
1422 val_to_str(action & 0x07, action_vals, "Unknown (%u)"));
1423 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1424 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1425 decode_enumerated_bitfield(action, 0x07, 8, action_vals, "%s"));
1426 actionValue = tvb_get_ntohs(tvb, offset+2);
1428 if (action & FR_PERIOD_MSGS) {
1433 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1434 decode_boolean_bitfield(action, FR_PERIOD_MSGS, 8,
1435 "The period is in frames", "The period is in 0.01 seconds"));
1437 if (action & FR_DEACT_ON_EVENT) {
1438 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1439 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_ON_EVENT, 8,
1440 deact_on_event_vals, "%s"));
1442 if (action & FR_DEACT_AFTER_PER) {
1443 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1444 decode_enumerated_bitfield(action, FR_DELETE|FR_DEACT_AFTER_PER, 8,
1445 deact_after_per_vals, "%s"));
1448 proto_tree_add_text(pt, tvb, offset, 1, "reserved");
1451 if (actionType == 1) {
1452 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d messages", actionValue);
1454 proto_tree_add_text(tree, tvb, offset, 2, "Period: %d.%02d seconds", actionValue/100, actionValue%100);
1458 for (i = 1; i <= blocks; i++) {
1459 length = tvb_get_ntohs(tvb, offset+2) * 2 + 8;
1460 length += 3 - (length + 3) % 4;
1461 item = proto_tree_add_text(pt, tvb, offset, length, "Filter block %d", i);
1462 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1463 offset = filter_block(tvb, offset, src, tree);
1465 for (i = 1; i <= responses; i++) {
1466 msglen = tvb_get_ntohs(tvb, offset+4) + 8;
1467 length = msglen + 3 - (msglen + 3) % 4;
1468 item = proto_tree_add_text(pt, tvb, offset, length, "Response block %d", i);
1469 tree = proto_item_add_subtree (item, ett_gryphon_cmd_response_block);
1470 next_tvb = tvb_new_subset(tvb, offset, msglen, msglen);
1471 dissect_gryphon_message(next_tvb, NULL, tree, TRUE);
1478 resp_addresp(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1480 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1481 tvb_get_guint8(tvb, offset));
1482 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1488 cmd_modresp(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1490 unsigned char action;
1491 unsigned char dest = tvb_get_guint8(tvb, offset-5);
1495 resp_handle = tvb_get_guint8(tvb, offset);
1497 proto_tree_add_text(pt, tvb, offset, 1, "Response handle: %u",
1500 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all on channel %hd", dest);
1502 proto_tree_add_text(pt, tvb, offset, 1, "Response handles: all");
1503 action = tvb_get_guint8(tvb, offset+1);
1504 for (i = 0; i < SIZEOF(filtacts); i++) {
1505 if (filtacts[i].value == action)
1508 if (i >= SIZEOF(filtacts))
1509 i = SIZEOF(filtacts) - 1;
1510 proto_tree_add_text(pt, tvb, offset+1, 1, "Action: %s response", filtacts[i].strptr);
1511 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1517 resp_resphan(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1519 int handles = tvb_get_guint8(tvb, offset);
1522 proto_tree_add_text(pt, tvb, offset, 1, "Number of response handles: %d", handles);
1523 for (i = 1; i <= handles; i++){
1524 proto_tree_add_text(pt, tvb, offset+i, 1, "Handle %d: %u", i,
1525 tvb_get_guint8(tvb, offset+i));
1527 padding = 3 - (handles + 1 + 3) % 4;
1529 proto_tree_add_text(pt, tvb, offset+1+handles, padding, "padding");
1530 offset += 1+handles+padding;
1535 resp_sched(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1537 unsigned int id = tvb_get_ntohl(tvb, offset);
1539 proto_tree_add_text(pt, tvb, offset, 4, "Transmit schedule ID: %u", id);
1545 cmd_desc(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1547 proto_tree_add_text(pt, tvb, offset, 4, "Program size: %u bytes",
1548 tvb_get_ntohl(tvb, offset));
1550 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1551 tvb_get_ptr(tvb, offset, 32));
1553 proto_tree_add_text(pt, tvb, offset, 80, "Program description: %.80s",
1554 tvb_get_ptr(tvb, offset, 80));
1560 resp_desc(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1566 flags = tvb_get_guint8(tvb, offset);
1567 item = proto_tree_add_text(pt, tvb, offset, 1, "Flags: 0x%02x", flags);
1568 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1569 proto_tree_add_text(tree, tvb, offset, 1, "%s",
1570 decode_boolean_bitfield(flags, 0x01, 8,
1571 "The program is already present",
1572 "The program is not present"));
1573 proto_tree_add_text(pt, tvb, offset+1, 1, "Handle: %u",
1574 tvb_get_guint8(tvb, offset+1));
1575 proto_tree_add_text(pt, tvb, offset+2, 2, "reserved");
1581 cmd_upload(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1584 unsigned int length;
1586 msglen = tvb_reported_length_remaining(tvb, offset);
1587 proto_tree_add_text(pt, tvb, offset, 2, "Block number: %u",
1588 tvb_get_ntohs(tvb, offset));
1591 proto_tree_add_text(pt, tvb, offset+2, 1, "Handle: %u",
1592 tvb_get_guint8(tvb, offset+2));
1596 proto_tree_add_text(pt, tvb, offset, length, "Data (%u bytes)", length);
1598 length = 3 - (length + 3) % 4;
1600 proto_tree_add_text(pt, tvb, offset, length, "padding");
1607 cmd_delete(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1609 proto_tree_add_text(pt, tvb, offset, 32, "Program name: %.32s",
1610 tvb_get_ptr(tvb, offset, 32));
1616 cmd_list(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1618 proto_tree_add_text(pt, tvb, offset, 1, "Block number: %u",
1619 tvb_get_guint8(tvb, offset));
1620 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1626 resp_list(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1630 unsigned int i, count;
1632 count = tvb_get_guint8(tvb, offset);
1633 proto_tree_add_text(pt, tvb, offset, 1, "Number of programs in this response: %u", count);
1634 proto_tree_add_text(pt, tvb, offset+1, 1, "reserved");
1636 proto_tree_add_text(pt, tvb, offset, 2, "Number of remaining programs: %u",
1637 tvb_get_ntohs(tvb, offset));
1639 for (i = 1; i <= count; i++) {
1640 item = proto_tree_add_text(pt, tvb, offset, 112, "Program %u", i);
1641 tree = proto_item_add_subtree (item, ett_gryphon_pgm_list);
1642 proto_tree_add_text(tree, tvb, offset, 32, "Name: %.32s",
1643 tvb_get_ptr(tvb, offset, 32));
1645 proto_tree_add_text(tree, tvb, offset, 80, "Description: %.80s",
1646 tvb_get_ptr(tvb, offset, 80));
1653 cmd_start(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1658 offset = cmd_delete(tvb, offset, src, pt);
1659 length = tvb_get_nstringz0(tvb, offset, 120, string) + 1;
1660 proto_tree_add_text(pt, tvb, offset, length, "Arguments: %s", string);
1662 length = 3 - (length + 3) % 4;
1664 proto_tree_add_text(pt, tvb, offset, length, "padding");
1671 resp_start(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1673 proto_tree_add_text(pt, tvb, offset, 1, "Channel (Client) number: %u",
1674 tvb_get_guint8(tvb, offset));
1675 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1681 resp_status(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1685 unsigned int i, copies, length;
1687 copies = tvb_get_guint8(tvb, offset);
1688 item = proto_tree_add_text(pt, tvb, offset, 1, "Number of running copies: %u", copies);
1689 tree = proto_item_add_subtree (item, ett_gryphon_pgm_status);
1692 for (i = 1; i <= copies; i++) {
1693 proto_tree_add_text(tree, tvb, offset, 1, "Program %u channel (client) number %u",
1694 i, tvb_get_guint8(tvb, offset));
1698 length = 3 - (copies + 1 + 3) % 4;
1700 proto_tree_add_text(pt, tvb, offset, length, "padding");
1707 cmd_options(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1712 unsigned int i, size, padding, option, option_length, option_value;
1713 unsigned char *string, *string1;
1715 msglen = tvb_reported_length_remaining(tvb, offset);
1716 item = proto_tree_add_text(pt, tvb, offset, 1, "Handle: %u",
1717 tvb_get_guint8(tvb, offset));
1718 item = proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1721 for (i = 1; msglen > 0; i++) {
1722 option_length = tvb_get_guint8(tvb, offset+1);
1723 size = option_length + 2;
1724 padding = 3 - ((size + 3) %4);
1725 item = proto_tree_add_text(pt, tvb, offset, size + padding, "Option number %u", i);
1726 tree = proto_item_add_subtree (item, ett_gryphon_pgm_options);
1727 option = tvb_get_guint8(tvb, offset);
1728 switch (option_length) {
1730 option_value = tvb_get_guint8(tvb, offset+2);
1733 option_value = tvb_get_ntohs(tvb, offset+2);
1736 option_value = tvb_get_ntohl(tvb, offset+2);
1741 string = "unknown option";
1742 string1 = "unknown option data";
1745 string = "Type of data in the file";
1746 switch (option_value) {
1748 string1 = "Binary - Don't modify";
1751 string1 = "ASCII - Remove CR's";
1756 string = "Type of file";
1757 switch (option_value) {
1759 string1 = "Executable";
1767 proto_tree_add_text(tree, tvb, offset, 1, "%s", string);
1768 proto_tree_add_text(tree, tvb, offset+2, option_length, "%s", string1);
1770 proto_tree_add_text(tree, tvb, offset+option_length+2, padding, "padding");
1771 offset += size + padding;
1772 msglen -= size + padding;
1778 cmd_files(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1783 msglen = tvb_reported_length_remaining(tvb, offset);
1784 if (tvb_get_guint8(tvb, offset) == 0)
1785 which = "First group of names";
1787 which = "Subsequent group of names";
1789 proto_tree_add_text(pt, tvb, offset, 1, "%s", which);
1790 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "Directory: %.*s",
1791 msglen-1, tvb_get_ptr(tvb, offset+1, msglen-1));
1797 resp_files(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1802 msglen = tvb_reported_length_remaining(tvb, offset);
1803 flag = tvb_get_guint8(tvb, offset) ? "Yes": "No";
1804 proto_tree_add_text(pt, tvb, offset, 1, "More filenames to return: %s", flag);
1805 proto_tree_add_text(pt, tvb, offset+1, msglen-1, "File and directory names");
1811 cmd_usdt(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1814 guint8 assemble_flag;
1816 if (tvb_get_guint8(tvb, offset))
1817 desc = "Register with gusdt";
1819 desc = "Unregister with gusdt";
1820 proto_tree_add_text(pt, tvb, offset, 1, "%s", desc);
1822 if (tvb_get_guint8(tvb, offset+1))
1823 desc = "Echo long transmit messages back to the client";
1825 desc = "Do not echo long transmit messages back to the client";
1826 proto_tree_add_text(pt, tvb, offset+1, 1, "%s", desc);
1828 assemble_flag = tvb_get_guint8(tvb, offset+2);
1829 if (assemble_flag == 2)
1830 desc = "Assemble long received messages but do not send them to the client";
1831 else if (assemble_flag)
1832 desc = "Assemble long received messages and send them to the client";
1834 desc = "Do not assemble long received messages on behalf of the client";
1835 proto_tree_add_text(pt, tvb, offset+2, 1, "%s", desc);
1842 speed(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1844 proto_tree_add_text(pt, tvb, offset, 1, "Baud rate index: %u",
1845 tvb_get_guint8(tvb, offset));
1846 proto_tree_add_text(pt, tvb, offset+1, 3, "reserved");
1852 filter_block(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1854 unsigned int type, operator, i;
1855 int length, padding;
1857 proto_tree_add_text(pt, tvb, offset, 2, "Filter field starts at byte %u",
1858 tvb_get_ntohs(tvb, offset));
1859 length = tvb_get_ntohs(tvb, offset+2);
1860 proto_tree_add_text(pt, tvb, offset+2, 2, "Filter field is %d bytes long", length);
1861 type = tvb_get_guint8(tvb, offset+4);
1862 for (i = 0; i < SIZEOF(filter_data_types); i++) {
1863 if (filter_data_types[i].value == type)
1866 if (i >= SIZEOF(filter_data_types))
1867 i = SIZEOF(filter_data_types) - 1;
1868 proto_tree_add_text(pt, tvb, offset+4, 1, "Filtering on %s", filter_data_types[i].strptr);
1870 operator = tvb_get_guint8(tvb, offset+5);
1871 for (i = 0; i < SIZEOF(operators); i++) {
1872 if (operators[i].value == operator)
1875 if (i >= SIZEOF(operators))
1876 i = SIZEOF(operators) - 1;
1877 proto_tree_add_text(pt, tvb, offset+5, 1, "Type of comparison: %s", operators[i].strptr);
1878 proto_tree_add_text(pt, tvb, offset+6, 2, "reserved");
1881 if (operator == BIT_FIELD_CHECK) {
1882 proto_tree_add_text(pt, tvb, offset, length, "Pattern");
1883 proto_tree_add_text(pt, tvb, offset+length, length, "Mask");
1887 proto_tree_add_text(pt, tvb, offset, 1, "Value: %u",
1888 tvb_get_guint8(tvb, offset));
1891 proto_tree_add_text(pt, tvb, offset, 2, "Value: %u",
1892 tvb_get_ntohs(tvb, offset));
1895 proto_tree_add_text(pt, tvb, offset, 4, "Value: %u",
1896 tvb_get_ntohl(tvb, offset));
1899 proto_tree_add_text(pt, tvb, offset, length, "Value");
1902 offset += length * 2;
1903 padding = 3 - (length * 2 + 3) % 4;
1905 proto_tree_add_text(pt, tvb, offset, padding, "padding");
1912 blm_mode(tvbuff_t *tvb, int offset, int src, proto_tree *pt)
1914 char *mode, line[50];
1917 x = tvb_get_ntohl(tvb, offset);
1918 y = tvb_get_ntohl(tvb, offset+4);
1922 sprintf (line, "reserved");
1925 mode = "Average over time";
1928 sprintf (line, "Averaging period: %d.%03d seconds", seconds, y);
1931 mode = "Average over frame count";
1932 sprintf (line, "Averaging period: %d frames", y);
1935 mode = "- unknown -";
1936 sprintf (line, "reserved");
1938 proto_tree_add_text(pt, tvb, offset, 4, "Mode: %s", mode);
1940 proto_tree_add_text(pt, tvb, offset, 4, line, NULL);
1946 proto_register_gryphon(void)
1948 static hf_register_info hf[] = {
1950 { "Source", "gryph.src", FT_UINT8, BASE_DEC, NULL, 0x0,
1952 { &hf_gryph_srcchan,
1953 { "Source channel", "gryph.srcchan", FT_UINT8, BASE_DEC, NULL, 0x0,
1956 { "Destination", "gryph.dest", FT_UINT8, BASE_DEC, NULL, 0x0,
1958 { &hf_gryph_destchan,
1959 { "Destination channel", "gryph.dstchan", FT_UINT8, BASE_DEC, NULL, 0x0,
1962 { "Frame type", "gryph.type", FT_UINT8, BASE_DEC, NULL, 0x0,
1965 { "Command", "gryph.cmd.cmd", FT_UINT8, BASE_DEC, NULL, 0x0,
1969 static gint *ett[] = {
1971 &ett_gryphon_header,
1973 &ett_gryphon_command_data,
1974 &ett_gryphon_response_data,
1975 &ett_gryphon_data_header,
1977 &ett_gryphon_data_body,
1978 &ett_gryphon_cmd_filter_block,
1979 &ett_gryphon_cmd_events_data,
1980 &ett_gryphon_cmd_config_device,
1981 &ett_gryphon_cmd_sched_data,
1982 &ett_gryphon_cmd_sched_cmd,
1983 &ett_gryphon_cmd_response_block,
1984 &ett_gryphon_pgm_list,
1985 &ett_gryphon_pgm_status,
1986 &ett_gryphon_pgm_options,
1988 module_t *gryphon_module;
1990 proto_gryphon = proto_register_protocol("DG Gryphon Protocol",
1993 proto_register_field_array(proto_gryphon, hf, array_length(hf));
1994 proto_register_subtree_array(ett, array_length(ett));
1996 gryphon_module = prefs_register_protocol(proto_gryphon, NULL);
1997 prefs_register_bool_preference(gryphon_module, "desegment",
1998 "Desegment all Gryphon messages spanning multiple TCP segments",
1999 "Whether the Gryphon dissector should desegment all messages spanning multiple TCP segments",
2000 &gryphon_desegment);
2004 proto_reg_handoff_gryphon(void)
2006 dissector_handle_t gryphon_handle;
2008 gryphon_handle = create_dissector_handle(dissect_gryphon, proto_gryphon);
2009 dissector_add("tcp.port", 7000, gryphon_handle);
2012 /* Start the functions we need for the plugin stuff */
2013 G_MODULE_EXPORT void
2014 plugin_reg_handoff(void){
2015 proto_reg_handoff_gryphon();
2018 G_MODULE_EXPORT void
2019 plugin_init(plugin_address_table_t *pat
2020 #ifndef PLUGINS_NEED_ADDRESS_TABLE
2024 /* initialise the table of pointers needed in Win32 DLLs */
2025 plugin_address_table_init(pat);
2026 /* register the new protocol, protocol fields, and subtrees */
2027 if (proto_gryphon == -1) { /* execute protocol initialization only once */
2028 proto_register_gryphon();
2031 /* End the functions we need for plugin stuff */