2 * Routines for Gryphon protocol packet disassembly
4 * $Id: packet-gryphon.c,v 1.6 2000/02/07 17:23:53 gram Exp $
6 * Ethereal - Network traffic analyzer
7 * By Steve Limkemann <stevelim@dgtech.com>
8 * Copyright 1998 Steve Limkemann
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include "plugins/plugin_api.h"
34 #include "moduleinfo.h"
36 #ifdef HAVE_SYS_TYPES_H
37 #include <sys/types.h>
45 #ifdef HAVE_NETINET_IN_H
46 # include <netinet/in.h>
50 #include "packet-gryphon.h"
52 DLLEXPORT const gchar version[] = VERSION;
53 DLLEXPORT const gchar desc[] = "DG Gryphon Protocol";
54 DLLEXPORT const gchar protocol[] = "tcp";
55 DLLEXPORT const gchar filter_string[] = "tcp.port == 7000";
58 #error "Sorry, this won't compile without 64-bit integer support"
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;
91 dissector(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
94 proto_tree *gryphon_tree, *header_tree, *body_tree;
95 proto_item *ti, *header_item, *body_item;
96 const u_char *data, *dataend, *msgend;
97 int src, msglen, msgpad, dest, frmtyp, i, end_of_frame;
98 static const u_char *frame_type[] = {"",
101 "Network (vehicle) data",
105 static const value_string src_dest[] = {
107 {SD_SERVER, "Server"},
108 {SD_CLIENT, "Client"},
109 {SD_SCHED, "Scheduler"},
110 {SD_SCRIPT, "Script Processor"},
111 {SD_PGM, "Program Loader"},
112 {SD_USDT, "USDT Server"},
113 {SD_BLM, "Bus Load Monitoring"},
114 {SD_FLIGHT, "Flight Recorder"},
115 {SD_RESP, "Message Responder"},
121 end_of_frame = END_OF_FRAME;
124 end_of_frame = pntohs (data + 4) + 8;
125 end_of_frame += 3 - (end_of_frame + 3 ) % 4;
127 dataend = data + end_of_frame;
129 if (fd && check_col(fd, COL_PROTOCOL))
130 col_add_str(fd, COL_PROTOCOL, "Gryphon");
132 if (END_OF_FRAME < 8)
135 if (fd && check_col(fd, COL_INFO)) {
137 * Indicate what kind of message this is.
139 col_add_str (fd, COL_INFO, frame_type[data[6]]);
143 ti = proto_tree_add_item(tree, proto_gryphon, offset,
145 gryphon_tree = proto_item_add_subtree(ti, ett_gryphon);
149 while (data < dataend) {
153 msglen = pntohs ((unsigned short *)&data[4]);
155 header_item = proto_tree_add_text(gryphon_tree, offset,
156 MSG_HDR_SZ, "Header", NULL);
157 header_tree = proto_item_add_subtree(header_item,
159 for (i = 0; i < SIZEOF(src_dest); i++) {
160 if (src_dest[i].value == src)
163 if (i >= SIZEOF(src_dest))
164 i = SIZEOF(src_dest) - 1;
165 proto_tree_add_text(header_tree, offset, 2,
166 "Source: %s, channel %hd", src_dest[i].strptr, data[1]);
167 proto_tree_add_item_hidden(header_tree, hf_gryph_src, offset, 1, src);
168 proto_tree_add_item_hidden(header_tree, hf_gryph_srcchan, offset+1, 1, data[1]);
170 for (i = 0; i < SIZEOF(src_dest); i++) {
171 if (src_dest[i].value == dest)
174 if (i >= SIZEOF(src_dest))
175 i = SIZEOF(src_dest) - 1;
176 proto_tree_add_text(header_tree, offset+2, 2,
177 "Destination: %s, channel %hd", src_dest[i].strptr, data[3]);
178 proto_tree_add_item_hidden(header_tree, hf_gryph_dest, offset+2, 1, dest);
179 proto_tree_add_item_hidden(header_tree, hf_gryph_destchan, offset+3, 1, data[3]);
181 proto_tree_add_text(header_tree, offset+4, 2,
182 "Data length: %d bytes", msglen);
183 proto_tree_add_text(header_tree, offset+6, 1,
184 "Frame type: %s", frame_type[frmtyp]);
185 proto_tree_add_text(header_tree, offset+7, 1, "reserved", NULL);
187 proto_tree_add_item_hidden(header_tree, hf_gryph_type, offset+6, 1, frmtyp);
188 msgpad = 3 - (msglen + 3) % 4;
189 msgend = data + msglen + msgpad + MSG_HDR_SZ;
191 body_item = proto_tree_add_text(gryphon_tree, offset + MSG_HDR_SZ,
192 msglen + msgpad, "Body", NULL);
193 body_tree = proto_item_add_subtree(body_item, ett_gryphon_body);
195 offset += MSG_HDR_SZ;
199 decode_command (dest, &data, dataend, &offset, msglen, body_tree);
202 decode_response (src, &data, dataend, &offset, msglen, body_tree);
205 decode_data (src, &data, dataend, &offset, msglen, body_tree);
208 decode_event (src, &data, dataend, &offset, msglen, body_tree);
217 if (data < msgend - msgpad) {
218 i = msgend - msgpad - data;
219 proto_tree_add_text(gryphon_tree, offset, i, "Data", NULL);
220 BUMP (offset, data, i);
224 proto_tree_add_text(gryphon_tree, offset, i, "padding", NULL);
225 BUMP (offset, data, i);
234 static const val_str_dsp cmds[] = {
235 {CMD_INIT, "Initialize", cmd_init, NULL},
236 {CMD_GET_STAT, "Get status", NULL, NULL},
237 {CMD_GET_CONFIG, "Get configuration", NULL, resp_config},
238 {CMD_EVENT_ENABLE, "Enable event", eventnum, NULL},
239 {CMD_EVENT_DISABLE, "Disable event", eventnum, NULL},
240 {CMD_GET_TIME, "Get time", NULL, resp_time},
241 {CMD_GET_RXDROP, "Get number of dropped RX messages", NULL, NULL},
242 {CMD_RESET_RXDROP, "Clear number of dropped RX messages", NULL, NULL},
243 {CMD_BCAST_ON, "Set broadcasts on", NULL, NULL},
244 {CMD_BCAST_OFF, "Set broadcasts off", NULL, NULL},
245 {CMD_CARD_SET_SPEED, "Set channel baud rate", speed, NULL},
246 {CMD_CARD_GET_SPEED, "Get channel baud rate", NULL, speed},
247 {CMD_CARD_SET_FILTER, "Set filter (deprecated)", cmd_setfilt, NULL},
248 {CMD_CARD_GET_FILTER, "Get filter", resp_addfilt, cmd_addfilt},
249 {CMD_CARD_TX, "Transmit message", decode_data, NULL},
250 {CMD_CARD_TX_LOOP_ON, "Set transmit loopback on", NULL, NULL},
251 {CMD_CARD_TX_LOOP_OFF, "Set transmit loopback off", NULL, NULL},
252 {CMD_CARD_IOCTL, "IOCTL pass-through", cmd_ioctl, NULL},
253 {CMD_CARD_ADD_FILTER, "Add a filter", cmd_addfilt, resp_addfilt},
254 {CMD_CARD_MODIFY_FILTER, "Modify a filter", cmd_modfilt, NULL},
255 {CMD_CARD_GET_FILTER_HANDLES, "Get filter handles", NULL, resp_filthan},
256 {CMD_CARD_SET_DEFAULT_FILTER, "Set default filter", dfiltmode, NULL},
257 {CMD_CARD_GET_DEFAULT_FILTER, "Get default filter mode", NULL, dfiltmode},
258 {CMD_CARD_SET_FILTER_MODE, "Set filter mode", filtmode, NULL},
259 {CMD_CARD_GET_FILTER_MODE, "Get filter mode", NULL, filtmode},
260 {CMD_CARD_GET_EVNAMES, "Get event names", NULL, resp_events},
261 {CMD_CARD_GET_SPEEDS, "Get defined speeds", NULL, NULL},
262 {CMD_SERVER_REG, "Register with server", cmd_register, resp_register},
263 {CMD_BLM_SET_MODE, "Set Bus Load Monitoring mode", blm_mode, NULL},
264 {CMD_BLM_GET_MODE, "Get Bus Load Monitoring mode", NULL, blm_mode},
265 {CMD_BLM_GET_DATA, "Get Bus Load data", NULL, resp_blm_data},
266 {CMD_BLM_GET_STATS, "Get Bus Load statistics", NULL, resp_blm_stat},
267 {CMD_FLIGHT_GET_CONFIG, "Get flight recorder channel info", NULL, NULL},
268 {CMD_FLIGHT_START_MON, "Start flight recorder monitoring", NULL, NULL},
269 {CMD_FLIGHT_STOP_MON, "Stop flight recorder monitoring", NULL, NULL},
270 {CMD_MSGRESP_ADD, "Add response message", cmd_addresp, resp_addresp},
271 {CMD_MSGRESP_GET, "Get response message", resp_addresp, cmd_addresp},
272 {CMD_MSGRESP_MODIFY, "Modify response message state", cmd_modresp, NULL},
273 {CMD_MSGRESP_GET_HANDLES, "Get response message handles", NULL, resp_resphan},
274 {CMD_PGM_DESC, "Describe program to to uploaded", cmd_desc, resp_desc},
275 {CMD_PGM_UPLOAD, "Upload a program to the Gryphon", cmd_upload, NULL},
276 {CMD_PGM_DELETE, "Delete an uploaded program", cmd_delete, NULL},
277 {CMD_PGM_LIST, "Get a list of uploaded programs", cmd_list, resp_list},
278 {CMD_PGM_START, "Start an uploaded program", cmd_start, resp_start},
279 {CMD_PGM_STOP, "Stop an uploaded program", resp_start, NULL},
280 {CMD_PGM_STATUS, "Get status of an uploaded program", cmd_delete, resp_status},
281 {CMD_PGM_OPTIONS, "Set program upload options", cmd_options, resp_status},
282 {CMD_SCHED_TX, "Schedule transmission of messages", cmd_sched, resp_sched},
283 {CMD_SCHED_KILL_TX, "Stop and destroy a message transmission", NULL, NULL},
284 {CMD_SCHED_STOP_TX, "Kill a message transmission (deprecated)", NULL, NULL},
285 {-1, "- unknown -", NULL, NULL},
288 static const value_string responses[] = {
289 {RESP_OK, "OK - no error"},
290 {RESP_UNKNOWN_ERR, "Unknown error"},
291 {RESP_UNKNOWN_CMD, "Unrecognised command"},
292 {RESP_UNSUPPORTED, "Unsupported command"},
293 {RESP_INVAL_CHAN, "Invalid channel specified"},
294 {RESP_INVAL_DST, "Invalid destination"},
295 {RESP_INVAL_PARAM, "Invalid parameter(s)"},
296 {RESP_INVAL_MSG, "Invalid message"},
297 {RESP_INVAL_LEN, "Invalid length field"},
298 {RESP_TX_FAIL, "Transmit failed"},
299 {RESP_RX_FAIL, "Receive failed"},
300 {RESP_AUTH_FAIL, "Authorization failed"},
301 {RESP_MEM_ALLOC_ERR, "Memory allocation error"},
302 {RESP_TIMEOUT, "Command timed out"},
303 {RESP_UNAVAILABLE, "Unavailable"},
304 {RESP_BUF_FULL, "Buffer full"},
305 {RESP_NO_SUCH_JOB, "No such job"},
309 static const value_string filter_data_types[] = {
310 {FILTER_DATA_TYPE_HEADER_FRAME, "frame header"},
311 {FILTER_DATA_TYPE_HEADER, "data message header"},
312 {FILTER_DATA_TYPE_DATA, "data message data"},
313 {FILTER_DATA_TYPE_EXTRA_DATA, "data message extra data"},
317 static const value_string operators[] = {
318 {BIT_FIELD_CHECK, "Bit field check"},
319 {SVALUE_GT, "Greater than (signed)"},
320 {SVALUE_GE, "Greater than or equal to (signed)"},
321 {SVALUE_LT, "Less than (signed)"},
322 {SVALUE_LE, "Less than or equal to (signed)"},
323 {VALUE_EQ, "Equal to"},
324 {VALUE_NE, "Not equal to"},
325 {UVALUE_GT, "Greater than (unsigned)"},
326 {UVALUE_GE, "Greater than or equal to (unsigned)"},
327 {UVALUE_LT, "Less than (unsigned)"},
328 {UVALUE_LE, "Less than or equal to (unsigned)"},
329 {DIG_LOW_TO_HIGH, "Digital, low to high transistion"},
330 {DIG_HIGH_TO_LOW, "Digital, high to low transistion"},
331 {DIG_TRANSITION, "Digital, change of state"},
335 static const value_string modes[] = {
336 {FILTER_OFF_PASS_ALL, "Filter off, pass all messages"},
337 {FILTER_OFF_BLOCK_ALL, "Filter off, block all messages"},
338 {FILTER_ON, "Filter on"},
342 static const value_string dmodes[] = {
343 {DEFAULT_FILTER_BLOCK, "Block"},
344 {DEFAULT_FILTER_PASS, "Pass"},
348 static const value_string filtacts[] = {
349 {DELETE_FILTER, "Delete"},
350 {ACTIVATE_FILTER, "Activate"},
351 {DEACTIVATE_FILTER, "Deactivate"},
355 static const value_string ioctls[] = {
356 {GINIT, "GINIT: Initialize"},
357 {GLOOPON, "GLOOPON: Loop on"},
358 {GLOOPOFF, "GLOOPOFF: Loop off"},
359 {GGETHWTYPE, "GGETHWTYPE: Get hardware type"},
360 {GGETREG, "GGETREG: Get register"},
361 {GSETREG, "GSETREG: Set register"},
362 {GGETRXCOUNT, "GGETRXCOUNT: Get the receive message counter"},
363 {GSETRXCOUNT, "GSETRXCOUNT: Set the receive message counter"},
364 {GGETTXCOUNT, "GGETTXCOUNT: Get the transmit message counter"},
365 {GSETTXCOUNT, "GSETTXCOUNT: Set the transmit message counter"},
366 {GGETRXDROP, "GGETRXDROP: Get the number of dropped receive messages"},
367 {GSETRXDROP, "GSETRXDROP: Set the number of dropped receive messages"},
368 {GGETTXDROP, "GGETTXDROP: Get the number of dropped transmit messages"},
369 {GSETTXDROP, "GSETTXDROP: Set the number of dropped transmit messages"},
370 {GGETRXBAD, "GGETRXBAD: Get the number of bad receive messages"},
371 {GGETTXBAD, "GGETTXBAD: Get the number of bad transmit messages"},
372 {GGETCOUNTS, "GGETCOUNTS: Get total message counter"},
373 {GGETBLMON, "GGETBLMON: Get bus load monitoring status"},
374 {GSETBLMON, "GSETBLMON: Set bus load monitoring status (turn on/off)"},
375 {GGETERRLEV, "GGETERRLEV: Get error level"},
376 {GSETERRLEV, "GSETERRLEV: Set error level"},
377 {GGETBITRATE, "GGETBITRATE: Get bit rate"},
378 {GGETRAM, "GGETRAM: Read value from RAM"},
379 {GSETRAM, "GSETRAM: Write value to RAM"},
380 {GCANGETBTRS, "GCANGETBTRS: Read CAN bit timing registers"},
381 {GCANSETBTRS, "GCANSETBTRS: Write CAN bit timing registers"},
382 {GCANGETBC, "GCANGETBC: Read CAN byte count"},
383 {GCANSETBC, "GCANSETBC: Write CAN byte count"},
384 {GCANGETMODE, "GCANGETMODE"},
385 {GCANSETMODE, "GCANSETMODE"},
386 {GCANGETTRANS, "GCANGETTRANS"},
387 {GCANSETTRANS, "GCANSETTRANS"},
388 {GCANSENDERR, "GCANSENDERR"},
389 {GCANRGETOBJ, "GCANRGETOBJ"},
390 {GCANRSETSTDID, "GCANRSETSTDID"},
391 {GCANRSETEXTID, "GCANRSETEXTID"},
392 {GCANRSETDATA, "GCANRSETDATA"},
393 {GCANRENABLE, "GCANRENABLE"},
394 {GCANRDISABLE, "GCANRDISABLE"},
395 {GCANRGETMASKS, "GCANRGETMASKS"},
396 {GCANRSETMASKS, "GCANRSETMASKS"},
397 {GCANSWGETMODE, "GCANSWGETMODE"},
398 {GCANSWSETMODE, "GCANSWSETMODE"},
399 {GDLCGETFOURX, "GDLCGETFOURX"},
400 {GDLCSETFOURX, "GDLCSETFOURX"},
401 {GDLCGETLOAD, "GDLCGETLOAD"},
402 {GDLCSETLOAD, "GDLCSETLOAD"},
403 {GDLCSENDBREAK, "GDLCSENDBREAK"},
404 {GDLCABORTTX, "GDLCABORTTX"},
405 {GDLCGETHDRMODE, "DLCGETHDRMODE"},
406 {GDLCSETHDRMODE, "GDLCSETHDRMODE"},
407 {GHONSLEEP, "GHONSLEEP"},
408 {GHONSILENCE, "GHONSILENCE"},
409 {GKWPSETPTIMES, "GKWPSETPTIMES"},
410 {GKWPSETWTIMES, "GKWPSETWTIMES"},
411 {GKWPDOWAKEUP, "GKWPDOWAKEUP"},
412 {GKWPGETBITTIME, "GKWPGETBITTIME"},
413 {GKWPSETBITTIME, "GKWPSETBITTIME"},
414 {GKWPSETNODEADDR, "GKWPSETNODEADDR"},
415 {GKWPGETNODETYPE, "GKWPGETNODETYPE"},
416 {GKWPSETNODETYPE, "GKWPSETNODETYPE"},
417 {GKWPSETWAKETYPE, "GKWPSETWAKETYPE"},
418 {GKWPSETTARGADDR, "GKWPSETTARGADDR"},
419 {GKWPSETKEYBYTES, "GKWPSETKEYBYTES"},
420 {GKWPSETSTARTREQ, "GKWPSETSTARTREQ"},
421 {GKWPSETSTARTRESP, "GKWPSETSTARTRESP"},
422 {GKWPSETPROTOCOL, "GKWPSETPROTOCOL"},
423 {GKWPGETLASTKEYBYTES, "GKWPGETLASTKEYBYTES"},
424 {GKWPSETLASTKEYBYTES, "GKWPSETLASTKEYBYTES"},
425 {GSCPGETBBR, "GSCPGETBBR"},
426 {GSCPSETBBR, "GSCPSETBBR"},
427 {GSCPGETID, "GSCPGETID"},
428 {GSCPSETID, "GSCPSETID"},
429 {GSCPADDFUNCID, "GSCPADDFUNCID"},
430 {GSCPCLRFUNCID, "GSCPCLRFUNCID"},
431 {GUBPGETBITRATE, "GUBPGETBITRATE"},
432 {GUBPSETBITRATE, "GUBPSETBITRATE"},
433 {GUBPGETINTERBYTE, "GUBPGETINTERBYTE"},
434 {GUBPSETINTERBYTE, "GUBPSETINTERBYTE"},
435 {GUBPGETNACKMODE, "GUBPGETNACKMODE"},
436 {GUBPSETNACKMODE, "GUBPSETNACKMODE"},
442 decode_command (int dst, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
449 proto_tree_add_item_hidden(pt, hf_gryph_cmd, *offset, 1, cmd);
453 for (i = 0; i < SIZEOF(cmds); i++) {
454 if (cmds[i].value == cmd)
457 if (i >= SIZEOF(cmds) && dst >= SD_KNOWN) {
458 cmd = (cmd & 0xFF) + SD_CARD * 256;
459 for (i = 0; i < SIZEOF(cmds); i++) {
460 if (cmds[i].value == cmd)
464 if (i >= SIZEOF(cmds))
465 i = SIZEOF(cmds) - 1;
467 proto_tree_add_text (pt, *offset, 4, "Command: %s", cmds[i].strptr);
468 BUMP (*offset, *data, 4);
470 if (cmds[i].cmd_fnct && dataend - *data) {
471 pi = proto_tree_add_text(pt, *offset, dataend - *data, "Data: (%d bytes)", dataend - *data);
472 ft = proto_item_add_subtree(pi, ett_gryphon_command_data);
473 (*(cmds[i].cmd_fnct)) (dst, data, dataend, offset, msglen, ft);
478 decode_response (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
488 for (i = 0; i < SIZEOF(cmds); i++) {
489 if (cmds[i].value == cmd)
492 if (i >= SIZEOF(cmds) && src >= SD_KNOWN) {
493 cmd = (cmd & 0xFF) + SD_CARD * 256;
494 for (i = 0; i < SIZEOF(cmds); i++) {
495 if (cmds[i].value == cmd)
499 if (i >= SIZEOF(cmds))
500 i = SIZEOF(cmds) - 1;
501 proto_tree_add_text (pt, *offset, 4, "Command: %s", cmds[i].strptr);
502 BUMP (*offset, *data, 4);
504 resp = pntohl ((unsigned long *)data[0]);
505 for (j = 0; j < SIZEOF(responses); j++) {
506 if (responses[j].value == resp)
509 if (j >= SIZEOF(responses))
510 j = SIZEOF(responses) - 1;
511 proto_tree_add_text (pt, *offset, 4, "Status: %s", responses[j].strptr);
512 BUMP (*offset, *data, 4);
514 if (cmds[i].rsp_fnct) {
515 pi = proto_tree_add_text(pt, *offset, dataend - *data, "Data: (%d bytes)", dataend - *data);
516 ft = proto_item_add_subtree(pi, ett_gryphon_response_data);
517 (*(cmds[i].rsp_fnct)) (src, data, dataend, offset, msglen, ft);
522 decode_data (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
524 proto_item *item, *item1;
525 proto_tree *tree, *tree1;
526 int hdrsize, datasize, extrasize, hdrbits, msgsize, padding, mode;
527 int hours, minutes, seconds, fraction;
528 unsigned long timestamp;
530 hdrsize = (*data)[0];
531 hdrbits = (*data)[1];
532 datasize = pntohs ((unsigned short *)((*data)+2));
533 extrasize = (*data)[4];
534 padding = 3 - (hdrsize + datasize + extrasize + 3) % 4;
535 msgsize = hdrsize + datasize + extrasize + padding + 16;
537 item = proto_tree_add_text(pt, *offset, 16, "Message header", NULL);
538 tree = proto_item_add_subtree (item, ett_gryphon_data_header);
539 proto_tree_add_text(tree, *offset, 2, "Header length: %d bytes, %d bits", hdrsize, hdrbits);
540 proto_tree_add_text(tree, *offset+2, 2, "Data length: %d bytes", datasize);
541 proto_tree_add_text(tree, *offset+4, 1, "Extra data length: %d bytes", extrasize);
543 item1 = proto_tree_add_text(tree, *offset+5, 1, "Mode: %hd", mode);
545 tree1 = proto_item_add_subtree (item1, ett_gryphon_flags);
547 proto_tree_add_text(tree1, *offset+5, 1, "1... .... = Transmitted message", NULL);
549 proto_tree_add_text(tree1, *offset+5, 1, ".1.. .... = Received message", NULL);
551 proto_tree_add_text(tree1, *offset+5, 1, "..1. .... = Local message", NULL);
553 proto_tree_add_text(tree1, *offset+5, 1, "...1 .... = Remote message", NULL);
555 proto_tree_add_text(tree1, *offset+5, 1, ".... ...1 = Internal message", NULL);
557 proto_tree_add_text(tree, *offset+6, 1, "Priority: %d", (*data)[6]);
558 proto_tree_add_text(tree, *offset+7, 1, "Error status: %hd", (*data)[7]);
559 timestamp = pntohl ((unsigned long *)((*data)+8));
560 hours = timestamp /(100000 * 60 *60);
561 minutes = (timestamp / (100000 * 60)) % 60;
562 seconds = (timestamp / 100000) % 60;
563 fraction = timestamp % 100000;
564 proto_tree_add_text(tree, *offset+8, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
565 proto_tree_add_text(tree, *offset+12, 1, "Context: %hd", (*data)[12]);
566 proto_tree_add_text(tree, *offset+13, 3, "reserved:", NULL);
567 BUMP (*offset, *data, 16);
568 item = proto_tree_add_text(pt, *offset, msgsize-16-padding, "Message Body", NULL);
569 tree = proto_item_add_subtree (item, ett_gryphon_data_body);
571 proto_tree_add_text(tree, *offset, hdrsize, "Header", NULL);
572 BUMP (*offset, *data, hdrsize);
575 proto_tree_add_text(tree, *offset, datasize, "Data", NULL);
576 BUMP (*offset, *data, datasize);
579 proto_tree_add_text(tree, *offset, extrasize, "Extra data", NULL);
580 BUMP (*offset, *data, extrasize);
583 proto_tree_add_text(pt, *offset, padding, "padding", NULL);
584 BUMP (*offset, *data, padding);
589 decode_event (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
591 int hours, minutes, seconds, fraction, padding, length;
592 unsigned long timestamp;
593 const u_char *msgend;
595 padding = 3 - (msglen + 3) % 4;
596 msgend = *data + msglen;
597 proto_tree_add_text(pt, *offset, 1, "Event ID: %hd", **data);
598 proto_tree_add_text(pt, *offset+1, 1, "Event context: %hd", *((*data)+1));
599 proto_tree_add_text(pt, *offset+2, 2, "reserved", NULL);
600 BUMP (*offset, *data, 4);
601 timestamp = pntohl ((unsigned long *)(*data));
602 hours = timestamp /(100000 * 60 *60);
603 minutes = (timestamp / (100000 * 60)) % 60;
604 seconds = (timestamp / 100000) % 60;
605 fraction = timestamp % 100000;
606 proto_tree_add_text(pt, *offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
607 BUMP (*offset, *data, 4);
608 if (*data < msgend) {
609 length = msgend - *data;
610 proto_tree_add_text (pt, *offset, length, "Data (%d bytes)", length);
611 BUMP (*offset, *data, length);
614 proto_tree_add_text (pt, *offset, padding, "padding", NULL);
615 BUMP (*offset, *data, padding);
620 cmd_init (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
624 if (*data >= dataend)
627 ptr = "Always initialize";
629 ptr = "Initialize if not previously initialized";
630 proto_tree_add_text(pt, *offset, 1, "Mode: %s", ptr);
631 proto_tree_add_text(pt, *offset+1, 3, "reserved", NULL);
632 BUMP (*offset, *data, 4);
636 eventnum (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
638 unsigned char event = **data;
641 proto_tree_add_text(pt, *offset, 1, "Event number: %hd", event);
643 proto_tree_add_text(pt, *offset, 1, "Event numbers: All", NULL);
644 proto_tree_add_text(pt, *offset+1, 3, "padding", NULL);
645 BUMP (*offset, *data, 4);
649 resp_time (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
651 int hours, minutes, seconds, fraction;
656 unsigned int timestamp;
657 unsigned char date[45];
659 ts.lng[1] = pntohl ((unsigned int *)(*data));
660 ts.lng[0] = pntohl ((unsigned int *)((*data)+4));
661 timestamp = ts.lnglng / 100000L;
662 strncpy (date, ctime((time_t*)×tamp), sizeof(date));
663 date[strlen(date)-1] = 0x00;
664 proto_tree_add_text(pt, *offset, 8, "Date/Time: %s", date);
665 timestamp = ts.lng[0];
666 hours = timestamp /(100000 * 60 *60);
667 minutes = (timestamp / (100000 * 60)) % 60;
668 seconds = (timestamp / 100000) % 60;
669 fraction = timestamp % 100000;
670 proto_tree_add_text(pt, *offset+4, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
671 BUMP (*offset, *data, 8);
675 cmd_setfilt (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
677 int flag = pntohl ((unsigned int *)((*data)+4));
679 unsigned char mode[30];
681 length = *((*data)+4) + *((*data)+5) + pntohs ((unsigned short *)((*data)+6));
683 strcpy (mode, "Pass");
685 strcpy (mode, "Block");
687 strcat (mode, " all");
688 proto_tree_add_text(pt, *offset, 4, "Pass/Block flag: %s", mode);
689 proto_tree_add_text(pt, *offset+4, 4, "Length of Pattern & Mask: %d", length);
690 BUMP (*offset, *data, 8);
692 proto_tree_add_text(pt, *offset, length * 2, "discarded data", NULL);
693 BUMP (*offset, *data, length * 2);
695 padding = 3 - (length * 2 + 3) % 4;
697 proto_tree_add_text(pt, *offset+1, 3, "padding", NULL);
698 BUMP (*offset, *data, padding);
703 cmd_ioctl (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
708 ioctl = pntohl ((unsigned int *)(*data));
709 for (i = 0; i < SIZEOF(ioctls); i++) {
710 if (ioctls[i].value == ioctl)
713 if (i >= SIZEOF(ioctls))
714 i = SIZEOF(ioctls) - 1;
715 proto_tree_add_text(pt, *offset, 4, "IOCTL: %s", ioctls[i].strptr);
716 BUMP (*offset, *data, 4);
717 proto_tree_add_text(pt, *offset, dataend - *data, "Data", NULL);
718 BUMP (*offset, *data, dataend - *data);
722 cmd_addfilt (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
726 int blocks, i, length;
728 char pass[] = ".... ...1 = Conforming messages are passed";
729 char block[] = ".... ...0 = Conforming messages are blocked";
730 char active[] = ".... ..1. = The filter is active";
731 char inactive[] = ".... ..0. = The filter is inactive";
733 item = proto_tree_add_text(pt, *offset, 1, "Flags", NULL);
734 tree = proto_item_add_subtree (item, ett_gryphon_flags);
735 if (**data & FILTER_PASS_FLAG)
739 proto_tree_add_text(tree, *offset, 1, ptr, NULL);
740 if (**data & FILTER_ACTIVE_FLAG)
744 proto_tree_add_text(tree, *offset, 1, ptr, NULL);
745 BUMP (*offset, *data, 1);
747 proto_tree_add_text(pt, *offset, 1, "Number of filter blocks = %d", blocks);
748 proto_tree_add_text(pt, *offset+1, 6, "reserved", NULL);
749 BUMP (*offset, *data, 7);
750 for (i = 1; i <= blocks; i++) {
751 length = pntohs ((unsigned short *)((*data)+2)) * 2 + 8;
752 length += 3 - (length + 3) % 4;
753 item = proto_tree_add_text(pt, *offset, length, "Filter block %d", i);
754 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
755 filter_block (src, data, dataend, offset, msglen, tree);
760 resp_addfilt (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
762 proto_tree_add_text(pt, *offset, 1, "Filter handle: %hd", **data);
763 proto_tree_add_text(pt, *offset+1, 3, "reserved", NULL);
764 BUMP (*offset, *data, 4);
768 cmd_modfilt (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
770 unsigned char action;
774 proto_tree_add_text(pt, *offset, 1, "Filter handle: %hd", **data);
776 proto_tree_add_text(pt, *offset, 1, "Filter handles: all", NULL);
777 action = *((*data) + 1);
778 for (i = 0; i < SIZEOF(filtacts); i++) {
779 if (filtacts[i].value == action)
782 if (i >= SIZEOF(filtacts))
783 i = SIZEOF(filtacts) - 1;
784 proto_tree_add_text(pt, *offset+1, 1, "Action: %s filter", filtacts[i].strptr);
785 proto_tree_add_text(pt, *offset+2, 2, "reserved", NULL);
786 BUMP (*offset, *data, 4);
790 resp_filthan (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
792 int handles = **data;
795 proto_tree_add_text(pt, *offset, 1, "Number of filter handles: %d", handles);
796 for (i = 1; i <= handles; i++){
797 proto_tree_add_text(pt, *offset+i, 1, "Handle %d: %hd", i, *(*data+i));
799 padding = 3 - (handles + 1 + 3) % 4;
801 proto_tree_add_text(pt, *offset+1+handles, padding, "padding", NULL);
802 BUMP (*offset, *data, 1+handles+padding);
806 dfiltmode (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
811 for (i = 0; i < SIZEOF(modes); i++) {
812 if (dmodes[i].value == mode)
815 if (i >= SIZEOF(dmodes))
816 i = SIZEOF(dmodes) - 1;
817 proto_tree_add_text(pt, *offset, 1, "Filter mode: %s", dmodes[i].strptr);
818 proto_tree_add_text(pt, *offset+1, 3, "reserved", NULL);
819 BUMP (*offset, *data, 4);
823 filtmode (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
828 for (i = 0; i < SIZEOF(modes); i++) {
829 if (modes[i].value == mode)
832 if (i >= SIZEOF(modes))
833 i = SIZEOF(modes) - 1;
834 proto_tree_add_text(pt, *offset, 1, "Filter mode: %s", modes[i].strptr);
835 proto_tree_add_text(pt, *offset+1, 3, "reserved", NULL);
836 BUMP (*offset, *data, 4);
840 resp_events (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
846 while (*data < dataend) {
847 item = proto_tree_add_text(pt, *offset, 20, "Event %d:", i);
848 tree = proto_item_add_subtree (item, ett_gryphon_cmd_events_data);
849 proto_tree_add_text(tree, *offset, 1, "Event ID: %hd", **data);
850 proto_tree_add_text(tree, *offset+1, 19, "Event name: %s", (*data)+1);
851 BUMP (*offset, *data, 20);
857 cmd_register (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
861 MEMCPY (string, *data, 16);
862 proto_tree_add_text(pt, *offset, 16, "Username: %s", string);
863 BUMP (*offset, *data, 16);
864 MEMCPY (string, *data, 32);
865 proto_tree_add_text(pt, *offset, 32, "Password: %s", string);
866 BUMP (*offset, *data, 32);
870 resp_register (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
872 proto_tree_add_text(pt, *offset, 1, "Client ID: %hd", (*data)[0]);
873 proto_tree_add_text(pt, *offset+1, 1, "Privileges: %hd", (*data)[1]);
874 proto_tree_add_text(pt, *offset+2, 2, "reserved", NULL);
875 BUMP (*offset, *data, 4);
879 resp_config (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
886 static const value_string protocol_types[] = {
887 {GDUMMY * 256 + GDGDMARKONE, "Dummy device driver"},
888 {GCAN * 256 + G82527, "CAN, 82527 subtype"},
889 {GCAN * 256 + GSJA1000, "CAN, SJA1000 subtype"},
890 {GCAN * 256 + G82527SW, "CAN, 82527 single wire subtype"},
891 {GJ1850 * 256 + GHBCCPAIR, "J1850, HBCC subtype"},
892 {GJ1850 * 256 + GDLC, "J1850, GM DLC subtype"},
893 {GJ1850 * 256 + GCHRYSLER, "J1850, Chrysler subtype"},
894 {GJ1850 * 256 + GDEHC12, "J1850, DE HC12 KWP/BDLC subtype"},
895 {GKWP2000, "Keyword protocol 2000"},
896 {GHONDA * 256 + GDGHC08, "Honda UART, DG HC08 subtype"},
897 {GFORDUBP * 256 + GDGUBP08, "Ford UBP, DG HC08 subtype"},
904 MEMCPY (string, *data, 20);
905 proto_tree_add_text(pt, *offset, 20, "Device name: %s", string);
906 BUMP (*offset, *data, 20);
908 MEMCPY (string, *data, 8);
909 proto_tree_add_text(pt, *offset, 8, "Device version: %s", string);
910 BUMP (*offset, *data, 8);
912 MEMCPY (string, *data, 20);
913 proto_tree_add_text(pt, *offset, 20, "Device serial number: %s", string);
914 BUMP (*offset, *data, 20);
917 proto_tree_add_text(pt, *offset, 1, "Number of channels: %d", devices);
918 proto_tree_add_text(pt, *offset+1, 15, "reserved", NULL);
919 BUMP (*offset, *data, 16);
920 for (i = 1; i <= devices; i++) {
921 pi = proto_tree_add_text(pt, *offset, 80, "Channel %d:", i);
922 ft = proto_item_add_subtree(pi, ett_gryphon_cmd_config_device);
923 MEMCPY (string, *data, 20);
924 proto_tree_add_text(ft, *offset, 20, "Driver name: %s", string);
925 BUMP (*offset, *data, 20);
927 MEMCPY (string, *data, 8);
928 proto_tree_add_text(ft, *offset, 8, "Driver version: %s", string);
929 BUMP (*offset, *data, 8);
931 MEMCPY (string, *data, 24);
932 proto_tree_add_text(ft, *offset, 24, "device security string: %s", string);
933 BUMP (*offset, *data, 24);
935 MEMCPY (string, *data, 20);
936 proto_tree_add_text(ft, *offset, 20, "Hardware serial number: %s", string);
937 BUMP (*offset, *data, 20);
939 x = pntohs ((unsigned short *)*data);
940 for (j = 0; j < SIZEOF(protocol_types); j++) {
941 if (protocol_types[j].value == x)
944 if (j >= SIZEOF(protocol_types))
945 j = SIZEOF(protocol_types) -1;
946 proto_tree_add_text(ft, *offset, 2, "Protocol type & subtype: %s", protocol_types[j].strptr);
947 BUMP (*offset, *data, 2);
949 proto_tree_add_text(ft, *offset, 1, "Channel ID: %hd", **data);
950 proto_tree_add_text(ft, *offset+1, 5, "reserved", NULL);
951 BUMP (*offset, *data, 6);
956 cmd_sched (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
958 proto_item *item, *item1;
959 proto_tree *tree, *tree1;
960 unsigned int i, x, length;
961 unsigned char def_chan = *((*data)-9);
963 char crit[] = ".... ...1 = Critical scheduler";
964 char norm[] = ".... ...0 = Normal scheduler";
966 x = pntohl ((unsigned int *)*data);
968 proto_tree_add_text(pt, *offset, 4, "Number of iterations: infinite", NULL);
970 proto_tree_add_text(pt, *offset, 4, "Number of iterations: %d", x);
971 BUMP (*offset, *data, 4);
972 x = pntohl ((unsigned int *)*data);
973 item = proto_tree_add_text(pt, *offset, 4, "Flags", NULL);
974 tree = proto_item_add_subtree (item, ett_gryphon_flags);
975 ptr = x & 1 ? crit : norm;
976 proto_tree_add_text(tree, *offset, 4, ptr, NULL);
977 BUMP (*offset, *data, 4);
979 while (*data < dataend) {
980 length = 16 + (*data)[16] + pntohs ((unsigned short *)((*data)+18)) + (*data)[20] + 16;
981 length += 3 - (length + 3) % 4;
982 item = proto_tree_add_text(pt, *offset, length, "Message %d", i);
983 tree = proto_item_add_subtree (item, ett_gryphon_cmd_sched_data);
984 x = pntohl ((unsigned int *)*data);
985 proto_tree_add_text(tree, *offset, 4, "Sleep: %d milliseconds", x);
986 BUMP (*offset, *data, 4);
987 x = pntohl ((unsigned int *)*data);
988 proto_tree_add_text(tree, *offset, 4, "Transmit count: %d", x);
989 BUMP (*offset, *data, 4);
990 x = pntohl ((unsigned int *)*data);
991 proto_tree_add_text(tree, *offset, 4, "Transmit period: %d milliseconds", x);
992 BUMP (*offset, *data, 4);
993 proto_tree_add_text(tree, *offset, 2, "reserved flags", NULL);
997 proto_tree_add_text(tree, *offset+2, 1, "Channel: %d", x);
998 proto_tree_add_text(tree, *offset+3, 1, "reserved", NULL);
999 BUMP (*offset, *data, 4);
1000 item1 = proto_tree_add_text(tree, *offset, length, "Message", NULL);
1001 tree1 = proto_item_add_subtree (item1, ett_gryphon_cmd_sched_cmd);
1002 decode_data (src, data, dataend, offset, msglen, tree1);
1008 resp_blm_data (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
1010 int hours, minutes, seconds, fraction, i, x, fract;
1011 unsigned long timestamp;
1013 "Bus load average: %d.%02d%%",
1014 "Current bus load: %d.%02d%%",
1015 "Peak bus load: %d.%02d%%",
1016 "Historic peak bus load: %d.%02d%%"
1019 timestamp = pntohl ((unsigned long *)(*data));
1020 hours = timestamp /(100000 * 60 *60);
1021 minutes = (timestamp / (100000 * 60)) % 60;
1022 seconds = (timestamp / 100000) % 60;
1023 fraction = timestamp % 100000;
1024 proto_tree_add_text(pt, *offset, 4, "Timestamp: %d:%02d:%02d.%05d", hours, minutes, seconds, fraction);
1025 BUMP (*offset, *data, 4);
1026 for (i = 0; i < SIZEOF(fields); i++){
1027 x = pntohs ((unsigned short *)(*data));
1030 proto_tree_add_text(pt, *offset, 2, fields[i], x, fract);
1031 BUMP (*offset, *data, 2);
1036 resp_blm_stat (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
1040 "Receive frame count: %d",
1041 "Transmit frame count: %d",
1042 "Receive dropped frame count: %d",
1043 "Transmit dropped frame count: %d",
1044 "Receive error count: %d",
1045 "Transmit error count: %d",
1048 resp_blm_data (src, data, dataend, offset, msglen, pt);
1049 for (i = 0; i < SIZEOF(fields); i++){
1050 x = pntohl ((unsigned int *)(*data));
1051 proto_tree_add_text(pt, *offset, 4, fields[i], x);
1052 BUMP (*offset, *data, 4);
1057 cmd_addresp (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
1061 int blocks, responses, old_handle, i, length;
1062 int action, actionType, actionValue;
1064 char active[] = ".... ..1. = The response is active";
1065 char inactive[] = ".... ..0. = The response is inactive";
1068 item = proto_tree_add_text(pt, *offset, 1, "Flags", NULL);
1069 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1070 if (**data & FILTER_ACTIVE_FLAG)
1074 proto_tree_add_text(tree, *offset, 1, ptr, NULL);
1075 BUMP (*offset, *data, 1);
1077 proto_tree_add_text(pt, *offset, 1, "Number of filter blocks = %d", blocks);
1078 BUMP (*offset, *data, 1);
1080 proto_tree_add_text(pt, *offset, 1, "Number of response blocks = %d", responses);
1081 BUMP (*offset, *data, 1);
1082 old_handle = **data;
1083 proto_tree_add_text(pt, *offset, 1, "Old handle = %d", old_handle);
1084 BUMP (*offset, *data, 1);
1086 switch (action & 7) {
1087 case FR_RESP_AFTER_EVENT:
1088 ptr = "Send response(s) for each conforming message";
1090 case FR_RESP_AFTER_PERIOD:
1091 ptr = "Send response(s) after the specified period expires following a conforming message";
1093 case FR_IGNORE_DURING_PER:
1094 ptr = "Send response(s) for a conforming message and ignore\nfurther messages until the specified period expires";
1097 ptr = "- unknown -";
1099 item = proto_tree_add_text(pt, *offset, 1, "Action = %s", ptr);
1100 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1101 if (action & FR_DEACT_AFTER_PER && !(action & FR_DELETE)){
1102 proto_tree_add_text(tree, *offset, 1,
1103 "1.0. .... Deactivate this response after the specified period following a conforming message", NULL);
1105 if (action & FR_DEACT_ON_EVENT && !(action & FR_DELETE)){
1106 proto_tree_add_text(tree, *offset, 1,
1107 ".10. .... Deactivate this response for a conforming message", NULL);
1109 if (action & FR_DEACT_AFTER_PER && action & FR_DELETE){
1110 proto_tree_add_text(tree, *offset, 1,
1111 "1.1. .... Delete this response after the specified period following a conforming message", NULL);
1113 if (action & FR_DEACT_ON_EVENT && action & FR_DELETE){
1114 proto_tree_add_text(tree, *offset, 1,
1115 ".11. .... Delete this response for a conforming message", NULL);
1117 actionValue = pntohs ((unsigned short *)((*data)+2));
1119 if (action & FR_PERIOD_MSGS){
1120 ptr = "...1 .... The period is in frames";
1123 ptr = "...0 .... The period is in 0.01 seconds";
1126 proto_tree_add_text(tree, *offset, 1, ptr, NULL);
1128 BUMP (*offset, *data, 1);
1129 proto_tree_add_text(pt, *offset, 1, "reserved", NULL);
1130 BUMP (*offset, *data, 1);
1132 if (actionType == 1) {
1133 proto_tree_add_text(tree, *offset, 2, "Period: %d messages", actionValue);
1135 proto_tree_add_text(tree, *offset, 2, "Period: %d.%02d seconds", actionValue/100, actionValue%100);
1138 BUMP (*offset, *data, 2);
1139 for (i = 1; i <= blocks; i++) {
1140 length = pntohs ((unsigned short *)((*data)+2)) * 2 + 8;
1141 length += 3 - (length + 3) % 4;
1142 item = proto_tree_add_text(pt, *offset, length, "Filter block %d", i);
1143 tree = proto_item_add_subtree (item, ett_gryphon_cmd_filter_block);
1144 filter_block (src, data, dataend, offset, msglen, tree);
1146 for (i = 1; i <= responses; i++) {
1147 length = pntohs ((unsigned short *)((*data)+4)) + 8;
1148 length += 3 - (length + 3) % 4;
1149 item = proto_tree_add_text(pt, *offset, length, "Response block %d", i);
1150 tree = proto_item_add_subtree (item, ett_gryphon_cmd_response_block);
1151 dissector((*data)-*offset, *offset, NULL, tree);
1152 BUMP (*offset, *data, length);
1157 resp_addresp (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
1159 if (*data < dataend) {
1160 proto_tree_add_text(pt, *offset, 1, "Response handle: %hd", **data);
1161 proto_tree_add_text(pt, *offset+1, 3, "reserved", NULL);
1162 BUMP (*offset, *data, 4);
1167 cmd_modresp (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
1169 unsigned char action;
1170 unsigned char dest = *((*data)-5);
1174 proto_tree_add_text(pt, *offset, 1, "Response handle: %hd", **data);
1176 proto_tree_add_text(pt, *offset, 1, "Response handles: all on channel %hd", dest);
1178 proto_tree_add_text(pt, *offset, 1, "Response handles: all", NULL);
1179 action = *((*data) + 1);
1180 for (i = 0; i < SIZEOF(filtacts); i++) {
1181 if (filtacts[i].value == action)
1184 if (i >= SIZEOF(filtacts))
1185 i = SIZEOF(filtacts) - 1;
1186 proto_tree_add_text(pt, *offset+1, 1, "Action: %s response", filtacts[i].strptr);
1187 proto_tree_add_text(pt, *offset+2, 2, "reserved", NULL);
1188 BUMP (*offset, *data, 4);
1192 resp_resphan (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
1194 int handles = **data;
1197 proto_tree_add_text(pt, *offset, 1, "Number of response handles: %d", handles);
1198 for (i = 1; i <= handles; i++){
1199 proto_tree_add_text(pt, *offset+i, 1, "Handle %d: %hd", i, *(*data+i));
1201 padding = 3 - (handles + 1 + 3) % 4;
1203 proto_tree_add_text(pt, *offset+1+handles, padding, "padding", NULL);
1204 BUMP (*offset, *data, 1+handles+padding);
1208 resp_sched (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
1210 unsigned int id = pntohl ((unsigned int *)(*data));
1211 proto_tree_add_text(pt, *offset, 4, "Transmit schedule ID: %d", id);
1212 BUMP (*offset, *data, 4);
1216 cmd_desc (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
1220 proto_tree_add_text(pt, *offset, 4, "Program size: %d bytes", pntohl ((unsigned int *)(*data)));
1221 BUMP (*offset, *data, 4);
1222 strncpy (string, *data, 32);
1224 proto_tree_add_text(pt, *offset, 32, "Program name: %s", string);
1225 BUMP (*offset, *data, 32);
1226 strncpy (string, *data, 80);
1228 proto_tree_add_text(pt, *offset, 80, "Program description: %s", string);
1229 BUMP (*offset, *data, 80);
1233 resp_desc (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt)
1238 char missing[] = ".... ...0 = The program is not present";
1239 char present[] = ".... ...1 = The program is already present";
1241 item = proto_tree_add_text(pt, *offset, 1, "Flags", NULL);
1242 tree = proto_item_add_subtree (item, ett_gryphon_flags);
1247 proto_tree_add_text(tree, *offset, 1, ptr, NULL);
1248 proto_tree_add_text(pt, *offset+1, 1, "Handle: %hd", (*data)[1]);
1249 proto_tree_add_text(pt, *offset+2, 2, "reserved", NULL);
1250 BUMP (*offset, *data, 4);
1254 cmd_upload (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
1255 unsigned int length;
1257 proto_tree_add_text(pt, *offset, 2, "Block number: %d", pntohs ((unsigned short *)(*data)));
1258 BUMP (*offset, *data, 4);
1259 proto_tree_add_text(pt, *offset+2, 1, "Handle: %hd", (*data)[2]);
1260 BUMP (*offset, *data, 3);
1261 length = *data - dataend;
1262 proto_tree_add_text(pt, *offset, length, "Data (%d bytes)", length);
1263 BUMP (*offset, *data, length);
1264 length = 3 - (length + 3) % 4;
1266 proto_tree_add_text(pt, *offset, length, "padding", NULL);
1267 BUMP (*offset, *data, length);
1272 cmd_delete (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
1275 strncpy (string, *data, 32);
1277 proto_tree_add_text(pt, *offset, 32, "Program name: %s", string);
1278 BUMP (*offset, *data, 32);
1282 cmd_list (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
1284 proto_tree_add_text(pt, *offset, 1, "Block number: %hd", (*data)[0]);
1285 proto_tree_add_text(pt, *offset+1, 3, "reserved", NULL);
1286 BUMP (*offset, *data, 4);
1290 resp_list (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
1294 unsigned int i, count;
1297 proto_tree_add_text(pt, *offset, 1, "Number of programs in this response: %d", count);
1298 proto_tree_add_text(pt, *offset+1, 1, "reserved", NULL);
1299 BUMP (*offset, *data, 2);
1300 proto_tree_add_text(pt, *offset, 2, "Number of remaining programs: %d", pntohs ((unsigned short *)(*data)));
1301 BUMP (*offset, *data, 2);
1302 for (i = 1; i <= count; i++) {
1303 item = proto_tree_add_text(pt, *offset, 112, "Program %d", i);
1304 tree = proto_item_add_subtree (item, ett_gryphon_pgm_list);
1305 strncpy (string, *data, 32);
1307 proto_tree_add_text(tree, *offset, 32, "Name: %s", string);
1308 BUMP (*offset, *data, 32);
1309 strncpy (string, *data, 80);
1311 proto_tree_add_text(tree, *offset, 80, "Description: %s", string);
1312 BUMP (*offset, *data, 80);
1317 cmd_start (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
1319 unsigned int length;
1321 cmd_delete (src, data, dataend, offset, msglen, pt);
1322 strncpy (string, *data, 119);
1324 length = strlen (string) + 1;
1325 proto_tree_add_text(pt, *offset, length, "Arguments: %s", string);
1326 BUMP (*offset, *data, length);
1327 length = 3 - (length + 3) % 4;
1329 proto_tree_add_text(pt, *offset, length, "padding", NULL);
1330 BUMP (*offset, *data, length);
1335 resp_start (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
1337 proto_tree_add_text(pt, *offset, 1, "Channel (Client) number: %hd", (*data)[0]);
1338 proto_tree_add_text(pt, *offset+1, 3, "reserved", NULL);
1339 BUMP (*offset, *data, 4);
1343 resp_status (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
1346 unsigned int i, copies, length;
1348 copies = (*data)[0];
1349 item = proto_tree_add_text(pt, *offset, 1, "Number of running copies: %d", copies);
1350 tree = proto_item_add_subtree (item, ett_gryphon_pgm_status);
1351 BUMP (*offset, *data, 1);
1353 for (i = 1; i <= copies; i++) {
1354 proto_tree_add_text(tree, *offset, 1, "Program %d channel (client) number %hd", i, (*data)[0]);
1355 BUMP (*offset, *data, 1);
1358 length = 3 - (copies + 1 + 3) % 4;
1360 proto_tree_add_text(pt, *offset, length, "padding", NULL);
1361 BUMP (*offset, *data, length);
1366 cmd_options (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
1369 unsigned int i, size, padding, option, option_length, option_value;
1370 unsigned char *string, *string1;
1372 item = proto_tree_add_text(pt, *offset, 1, "Handle: %hd", **data);
1373 item = proto_tree_add_text(pt, *offset+1, 3, "reserved", NULL);
1374 BUMP (*offset, *data, 4);
1375 for (i = 1; *data <= dataend; i++) {
1376 size = (*data)[1] + 2;
1377 padding = 3 - ((size + 3) %4);
1378 item = proto_tree_add_text(pt, *offset, size + padding, "Option number %d", i);
1379 tree = proto_item_add_subtree (item, ett_gryphon_pgm_options);
1381 option_length = (*data)[1];
1382 switch (option_length) {
1384 option_value = (*data)[2];
1387 option_value = pntohs ((unsigned short *)((*data)+2));
1390 option_value = pntohl ((unsigned int *)((*data)+2));
1395 string = "unknown option";
1396 string1 = "unknown option data";
1399 string = "Type of data in the file";
1400 switch (option_value) {
1402 string1 = "Binary - Don't modify";
1405 string1 = "ASCII - Remove CR's";
1410 string = "Type of file";
1411 switch (option_value) {
1413 string1 = "Executable";
1421 proto_tree_add_text(tree, *offset, 1, "%s", string);
1422 proto_tree_add_text(tree, *offset+2, option_length, "%s", string1);
1424 proto_tree_add_text(tree, *offset+option_length+2, padding, "padding", NULL);
1425 BUMP (*offset, *data, size + padding);
1430 speed (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
1432 proto_tree_add_text(pt, *offset, 1, "Baud rate index: %hd", (*data)[0]);
1433 proto_tree_add_text(pt, *offset+1, 3, "reserved", NULL);
1434 BUMP (*offset, *data, 4);
1438 filter_block (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
1439 int length, type, i, operator, padding;
1441 proto_tree_add_text(pt, *offset, 2, "Filter field starts at byte %d", pntohs ((unsigned short *)(*data)));
1442 length = pntohs ((unsigned short *)((*data)+2));
1443 proto_tree_add_text(pt, *offset+2, 2, "Filter field is %d bytes long", length);
1444 type = *((*data)+4);
1445 for (i = 0; i < SIZEOF(filter_data_types); i++) {
1446 if (filter_data_types[i].value == type)
1449 if (i >= SIZEOF(filter_data_types))
1450 i = SIZEOF(filter_data_types) - 1;
1451 proto_tree_add_text(pt, *offset+4, 1, "Filtering on %s", filter_data_types[i].strptr);
1453 operator = *((*data)+5);
1454 for (i = 0; i < SIZEOF(operators); i++) {
1455 if (operators[i].value == operator)
1458 if (i >= SIZEOF(operators))
1459 i = SIZEOF(operators) - 1;
1460 proto_tree_add_text(pt, *offset+5, 1, "Type of comparison: %s", operators[i].strptr);
1461 proto_tree_add_text(pt, *offset+6, 2, "reserved" ,NULL);
1462 BUMP (*offset, *data, 8);
1464 if (operator == BIT_FIELD_CHECK) {
1465 proto_tree_add_text(pt, *offset, length, "Pattern" ,NULL);
1466 proto_tree_add_text(pt, *offset+length, length, "Mask" ,NULL);
1470 proto_tree_add_text(pt, *offset, 1, "Value: %hd", **data);
1473 proto_tree_add_text(pt, *offset, 2, "Value: %d", pntohs ((unsigned short *)(*data)));
1476 proto_tree_add_text(pt, *offset, 4, "Value: %dl", pntohl ((unsigned long *)(*data)));
1479 proto_tree_add_text(pt, *offset, length, "Value", NULL);
1482 BUMP (*offset, *data, length * 2);
1483 padding = 3 - (length * 2 + 3) % 4;
1485 proto_tree_add_text(pt, *offset, padding, "padding", NULL);
1486 BUMP (*offset, *data, padding);
1491 blm_mode (int src, const u_char **data, const u_char *dataend, int *offset, int msglen, proto_tree *pt) {
1493 char *mode, line[50];
1496 x = pntohl ((unsigned long *)(*data));
1497 y = pntohl ((unsigned long *)((*data)+4));
1501 sprintf (line, "reserved");
1504 mode = "Average over time";
1507 sprintf (line, "Averaging period: %d.%03d seconds", seconds, y);
1510 mode = "Average over frame count";
1511 sprintf (line, "Averaging period: %d frames", y);
1514 mode = "- unknown -";
1515 sprintf (line, "reserved");
1517 proto_tree_add_text(pt, *offset, 4, "Mode: %s", mode);
1518 BUMP (*offset, *data, 4);
1519 proto_tree_add_text(pt, *offset, 4, line, NULL);
1520 BUMP (*offset, *data, 4);
1524 plugin_init(plugin_address_table_t *pat)
1526 static hf_register_info hf[] = {
1528 { "Source", "gryph.src", FT_UINT8, BASE_DEC, NULL, 0x0,
1530 { &hf_gryph_srcchan,
1531 { "Source channel", "gryph.srcchan", FT_UINT8, BASE_DEC, NULL, 0x0,
1534 { "Destination", "gryph.dest", FT_UINT8, BASE_DEC, NULL, 0x0,
1536 { &hf_gryph_destchan,
1537 { "Destination channel", "gryph.dstchan", FT_UINT8, BASE_DEC, NULL, 0x0,
1540 { "Frame type", "gryph.type", FT_UINT8, BASE_DEC, NULL, 0x0,
1543 { "Command", "gryph.cmd.cmd", FT_UINT8, BASE_DEC, NULL, 0x0,
1547 static gint *ett[] = {
1549 &ett_gryphon_header,
1551 &ett_gryphon_command_data,
1552 &ett_gryphon_response_data,
1553 &ett_gryphon_data_header,
1555 &ett_gryphon_data_body,
1556 &ett_gryphon_cmd_filter_block,
1557 &ett_gryphon_cmd_events_data,
1558 &ett_gryphon_cmd_config_device,
1559 &ett_gryphon_cmd_sched_data,
1560 &ett_gryphon_cmd_sched_cmd,
1561 &ett_gryphon_cmd_response_block,
1562 &ett_gryphon_pgm_list,
1563 &ett_gryphon_pgm_status,
1564 &ett_gryphon_pgm_options,
1566 plugin_address_table_init(pat);
1568 proto_gryphon = proto_register_protocol("DG Gryphon Protocol", "gryphon");
1569 proto_register_field_array(proto_gryphon, hf, array_length(hf));
1570 proto_register_subtree_array(ett, array_length(ett));