2 * Routines for RTnet packet disassembly
6 * Copyright (c) 2003 by Erwin Rol <erwin@erwinrol.com>
7 * Copyright (c) 2004 by Jan Kiszka <jan.kiszka@web.de>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1999 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include "moduleinfo.h"
43 #include <epan/packet.h>
44 #include <epan/addr_resolv.h>
45 #include <epan/etypes.h>
46 #include <epan/strutil.h>
51 * http://www.rts.uni-hannover.de/rtnet/
54 #define RTMAC_TYPE_TDMA 0x0001 /* since version 2 */
55 #define RTMAC_TYPE_TDMA_V1 0x9031 /* first TDMA version */
57 static const value_string rtmac_type_vals[] = {
58 { RTMAC_TYPE_TDMA, "TDMA" },
59 { RTMAC_TYPE_TDMA_V1, "TDMA-V1" },
63 #define RTMAC_FLAG_TUNNEL 0x01
64 #define RTMAC_FLAGS_RES 0xFE
66 #define RTCFG_MSG_S1_CONFIG 0x0
67 #define RTCFG_MSG_ANN_NEW 0x1
68 #define RTCFG_MSG_ANN_REPLY 0x2
69 #define RTCFG_MSG_S2_CONFIG 0x3
70 #define RTCFG_MSG_S2_FRAG 0x4
71 #define RTCFG_MSG_ACK 0x5
72 #define RTCFG_MSG_READY 0x6
73 #define RTCFG_MSG_HBEAT 0x7
74 #define RTCFG_MSG_DEAD_STN 0x8
76 static const value_string rtcfg_msg_vals[] = {
77 { RTCFG_MSG_S1_CONFIG, "Stage 1 Config" },
78 { RTCFG_MSG_ANN_NEW, "New Announce" },
79 { RTCFG_MSG_ANN_REPLY, "Reply Announce" },
80 { RTCFG_MSG_S2_CONFIG, "Stage 2 Config" },
81 { RTCFG_MSG_S2_FRAG, "Stage 2 Fragment" },
82 { RTCFG_MSG_ACK, "Acknowledge" },
83 { RTCFG_MSG_READY, "Ready" },
84 { RTCFG_MSG_HBEAT, "Heartbeat" },
85 { RTCFG_MSG_DEAD_STN, "Dead Station" },
89 #define RTCFG_ADDRESS_TYPE_MAC 0x00
90 #define RTCFG_ADDRESS_TYPE_IP 0x01
92 static const value_string rtcfg_address_type_vals[] = {
93 { RTCFG_ADDRESS_TYPE_MAC, "MAC" },
94 { RTCFG_ADDRESS_TYPE_IP, "IP" },
98 #define TDMA_V1_MSG_NOTIFY_MASTER 0x10
99 #define TDMA_V1_MSG_REQUEST_TEST 0x11
100 #define TDMA_V1_MSG_ACK_TEST 0x12
101 #define TDMA_V1_MSG_REQUEST_CONF 0x13
102 #define TDMA_V1_MSG_ACK_CONF 0x14
103 #define TDMA_V1_MSG_ACK_ACK_CONF 0x15
104 #define TDMA_V1_MSG_STATION_LIST 0x16
105 #define TDMA_V1_MSG_REQUEST_CHANGE_OFFSET 0x17
106 #define TDMA_V1_MSG_START_OF_FRAME 0x18
108 static const value_string tdma_v1_msg_vals[] = {
109 { TDMA_V1_MSG_NOTIFY_MASTER, "Notify Master" },
110 { TDMA_V1_MSG_REQUEST_TEST, "Request Test" },
111 { TDMA_V1_MSG_ACK_TEST, "Acknowledge Test" },
112 { TDMA_V1_MSG_REQUEST_CONF, "Request Config" },
113 { TDMA_V1_MSG_ACK_CONF, "Acknowledge Config" },
114 { TDMA_V1_MSG_ACK_ACK_CONF, "Ack Ack Config" },
115 { TDMA_V1_MSG_STATION_LIST, "Station List" },
116 { TDMA_V1_MSG_REQUEST_CHANGE_OFFSET, "Request Change Offset" },
117 { TDMA_V1_MSG_START_OF_FRAME, "Start of Frame" },
121 #define TDMA_MSG_SYNC 0x0000
122 #define TDMA_MSG_CAL_REQUEST 0x0010
123 #define TDMA_MSG_CAL_REPLY 0x0011
125 static const value_string tdma_msg_vals[] = {
126 { TDMA_MSG_SYNC, "Synchronisation" },
127 { TDMA_MSG_CAL_REQUEST, "Request Calibration" },
128 { TDMA_MSG_CAL_REPLY, "Reply Calibration" },
132 static dissector_table_t ethertype_table;
133 static dissector_handle_t data_handle;
135 /* Define the rtnet proto */
136 static int proto_rtmac = -1;
137 static int proto_tdma = -1;
138 static int proto_rtcfg = -1;
141 static int hf_rtmac_header_type = -1;
142 static int hf_rtmac_header_ver = -1;
143 static int hf_rtmac_header_flags = -1;
144 static int hf_rtmac_header_flags_tunnel = -1;
145 static int hf_rtmac_header_flags_res = -1;
146 static int hf_rtmac_header_res_v1 = -1;
150 static int hf_rtcfg_vers_id = -1;
151 static int hf_rtcfg_vers = -1;
152 static int hf_rtcfg_id = -1;
153 static int hf_rtcfg_address_type = -1;
154 static int hf_rtcfg_client_ip_address = -1;
155 static int hf_rtcfg_server_ip_address = -1;
156 static int hf_rtcfg_burst_rate = -1;
157 static int hf_rtcfg_padding = -1;
158 static int hf_rtcfg_s1_config_length = -1;
159 static int hf_rtcfg_config_data = -1;
160 static int hf_rtcfg_client_flags = -1;
161 static int hf_rtcfg_client_flags_available = -1;
162 static int hf_rtcfg_client_flags_ready = -1;
163 static int hf_rtcfg_client_flags_res = -1;
164 static int hf_rtcfg_server_flags = -1;
165 static int hf_rtcfg_server_flags_res0 = -1;
166 static int hf_rtcfg_server_flags_ready = -1;
167 static int hf_rtcfg_server_flags_res2 = -1;
168 static int hf_rtcfg_active_stations = -1;
169 static int hf_rtcfg_heartbeat_period = -1;
170 static int hf_rtcfg_s2_config_length = -1;
171 static int hf_rtcfg_config_offset = -1;
172 static int hf_rtcfg_ack_length = -1;
173 static int hf_rtcfg_client_hw_address = -1;
177 static int hf_tdma_v1_msg = -1;
179 /* TDMA REQUEST_CONF */
180 static int hf_tdma_v1_msg_request_conf_station = -1;
181 static int hf_tdma_v1_msg_request_conf_padding = -1;
182 static int hf_tdma_v1_msg_request_conf_mtu = -1;
183 static int hf_tdma_v1_msg_request_conf_cycle = -1;
186 static int hf_tdma_v1_msg_ack_conf_station = -1;
187 static int hf_tdma_v1_msg_ack_conf_padding = -1;
188 static int hf_tdma_v1_msg_ack_conf_mtu = -1;
189 static int hf_tdma_v1_msg_ack_conf_cycle = -1;
191 /* TDMA ACK_ACK_CONF */
192 static int hf_tdma_v1_msg_ack_ack_conf_station = -1;
193 static int hf_tdma_v1_msg_ack_ack_conf_padding = -1;
195 /* TDMA REQUEST_TEST */
196 static int hf_tdma_v1_msg_request_test_counter = -1;
197 static int hf_tdma_v1_msg_request_test_tx = -1;
200 static int hf_tdma_v1_msg_ack_test_counter = -1;
201 static int hf_tdma_v1_msg_ack_test_tx = -1;
203 /* TDMA STATION_LIST */
204 static int hf_tdma_v1_msg_station_list_nr_stations = -1;
205 static int hf_tdma_v1_msg_station_list_padding = -1;
207 static int hf_tdma_v1_msg_station_list_ip = -1;
208 static int hf_tdma_v1_msg_station_list_nr = -1;
210 /* TDMA CHANGE_OFFSET */
211 static int hf_tdma_v1_msg_request_change_offset_offset = -1;
213 /* TDMA START_OF_FRAME */
214 static int hf_tdma_v1_msg_start_of_frame_timestamp = -1;
217 /* TDMA since version 2 */
218 static int hf_tdma_ver = -1;
219 static int hf_tdma_id = -1;
222 static int hf_tdma_sync_cycle = -1;
223 static int hf_tdma_sync_xmit_stamp = -1;
224 static int hf_tdma_sync_sched_xmit = -1;
226 /* TDMA Request Calibration */
227 static int hf_tdma_req_cal_xmit_stamp = -1;
228 static int hf_tdma_req_cal_rpl_cycle = -1;
229 static int hf_tdma_req_cal_rpl_slot = -1;
231 /* TDMA Reply Calibration */
232 static int hf_tdma_rpl_cal_req_stamp = -1;
233 static int hf_tdma_rpl_cal_rcv_stamp = -1;
234 static int hf_tdma_rpl_cal_xmit_stamp = -1;
237 /* Define the tree for rtnet */
238 static int ett_rtmac = -1;
239 static int ett_rtmac_flags = -1;
240 static int ett_tdma = -1;
241 static int ett_rtcfg = -1;
244 dissect_rtnet_tdma_notify_master(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_)
250 dissect_rtnet_tdma_request_test(tvbuff_t *tvb, guint offset, proto_tree *tree)
252 proto_tree_add_item(tree, hf_tdma_v1_msg_request_test_counter, tvb,
256 proto_tree_add_item(tree, hf_tdma_v1_msg_request_test_tx, tvb,
264 dissect_rtnet_tdma_ack_test(tvbuff_t *tvb, guint offset, proto_tree *tree)
266 proto_tree_add_item(tree, hf_tdma_v1_msg_ack_test_counter, tvb,
270 proto_tree_add_item(tree, hf_tdma_v1_msg_ack_test_tx, tvb,
278 dissect_rtnet_tdma_request_conf(tvbuff_t *tvb, guint offset, proto_tree *tree)
280 proto_tree_add_item(tree, hf_tdma_v1_msg_request_conf_station, tvb,
284 proto_tree_add_item(tree, hf_tdma_v1_msg_request_conf_padding, tvb,
288 proto_tree_add_item(tree, hf_tdma_v1_msg_request_conf_mtu, tvb,
292 proto_tree_add_item(tree, hf_tdma_v1_msg_request_conf_cycle, tvb,
301 dissect_rtnet_tdma_ack_conf(tvbuff_t *tvb, guint offset, proto_tree *tree)
303 proto_tree_add_item(tree, hf_tdma_v1_msg_ack_conf_station, tvb,
307 proto_tree_add_item(tree, hf_tdma_v1_msg_ack_conf_padding, tvb,
311 proto_tree_add_item(tree, hf_tdma_v1_msg_ack_conf_mtu, tvb,
315 proto_tree_add_item(tree, hf_tdma_v1_msg_ack_conf_cycle, tvb,
323 dissect_rtnet_tdma_ack_ack_conf(tvbuff_t *tvb, guint offset, proto_tree *tree) {
325 proto_tree_add_item(tree, hf_tdma_v1_msg_ack_ack_conf_station, tvb,
330 proto_tree_add_item(tree, hf_tdma_v1_msg_ack_ack_conf_padding, tvb,
338 dissect_rtnet_tdma_station_list(tvbuff_t *tvb, guint offset, proto_tree *tree)
343 nr_stations = tvb_get_guint8(tvb, offset);
344 proto_tree_add_uint(tree, hf_tdma_v1_msg_station_list_nr_stations, tvb,
345 offset, 1, nr_stations);
349 proto_tree_add_item(tree, hf_tdma_v1_msg_station_list_padding, tvb,
354 for( i = 0; i < nr_stations; i++ )
356 proto_tree_add_item(tree, hf_tdma_v1_msg_station_list_ip, tvb,
361 proto_tree_add_item(tree, hf_tdma_v1_msg_station_list_nr, tvb,
366 proto_tree_add_item(tree, hf_tdma_v1_msg_station_list_padding, tvb,
375 dissect_rtnet_tdma_request_change_offset(tvbuff_t *tvb, guint offset, proto_tree *tree)
377 proto_tree_add_item(tree, hf_tdma_v1_msg_request_change_offset_offset, tvb,
386 dissect_rtnet_tdma_start_of_frame(tvbuff_t *tvb, guint offset, proto_tree *tree)
388 proto_tree_add_item(tree, hf_tdma_v1_msg_start_of_frame_timestamp, tvb,
396 dissect_rtnet_tdma_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *root) {
402 msg = tvb_get_ntohl(tvb, offset);
404 /* Set the protocol column */
405 if (check_col(pinfo->cinfo,COL_PROTOCOL)){
406 col_set_str(pinfo->cinfo,COL_PROTOCOL,"TDMA-V1");
409 /* set the info column */
410 if (check_col(pinfo->cinfo, COL_INFO)) {
411 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
412 val_to_str(msg, tdma_v1_msg_vals, "Unknown (0x%04x)"));
416 ti = proto_tree_add_item(root, proto_tdma, tvb, 0, -1, FALSE);
417 tree = proto_item_add_subtree(ti, ett_tdma);
419 proto_item_append_text(ti, ", Version 1, %s",
420 val_to_str(msg, tdma_v1_msg_vals, "Unknown (0x%04x)"));
422 proto_tree_add_item(tree, hf_tdma_v1_msg, tvb,
427 case TDMA_V1_MSG_NOTIFY_MASTER:
428 dissect_rtnet_tdma_notify_master(tvb, offset, tree);
431 case TDMA_V1_MSG_REQUEST_TEST:
432 dissect_rtnet_tdma_request_test(tvb, offset, tree);
435 case TDMA_V1_MSG_ACK_TEST:
436 dissect_rtnet_tdma_ack_test(tvb, offset, tree);
439 case TDMA_V1_MSG_REQUEST_CONF:
440 dissect_rtnet_tdma_request_conf(tvb, offset, tree);
443 case TDMA_V1_MSG_ACK_CONF:
444 dissect_rtnet_tdma_ack_conf(tvb, offset, tree);
447 case TDMA_V1_MSG_ACK_ACK_CONF:
448 dissect_rtnet_tdma_ack_ack_conf(tvb, offset, tree);
451 case TDMA_V1_MSG_STATION_LIST:
452 dissect_rtnet_tdma_station_list (tvb, offset, tree);
455 case TDMA_V1_MSG_REQUEST_CHANGE_OFFSET:
456 dissect_rtnet_tdma_request_change_offset(tvb, offset, tree);
459 case TDMA_V1_MSG_START_OF_FRAME:
460 dissect_rtnet_tdma_start_of_frame(tvb, offset, tree);
470 dissect_tdma_sync(tvbuff_t *tvb, guint offset, proto_tree *tree) {
474 proto_tree_add_item(tree, hf_tdma_sync_cycle, tvb, offset, 4, FALSE);
477 ti = proto_tree_add_item(tree, hf_tdma_sync_xmit_stamp, tvb, offset, 8, FALSE);
478 time = tvb_get_ntoh64(tvb, offset) - tvb_get_ntoh64(tvb, offset+8);
479 proto_item_append_text(ti, " (%s%" G_GINT64_MODIFIER "d)", (time > 0) ? "+" : "", time);
482 proto_tree_add_item(tree, hf_tdma_sync_sched_xmit, tvb, offset, 8, FALSE);
486 dissect_tdma_request_cal(tvbuff_t *tvb, guint offset, proto_tree *tree) {
488 proto_tree_add_item(tree, hf_tdma_req_cal_xmit_stamp, tvb, offset, 8, FALSE);
491 proto_tree_add_item(tree, hf_tdma_req_cal_rpl_cycle, tvb, offset, 4, FALSE);
494 proto_tree_add_item(tree, hf_tdma_req_cal_rpl_slot, tvb, offset, 8, FALSE);
498 dissect_tdma_reply_cal(tvbuff_t *tvb, guint offset, proto_tree *tree) {
502 proto_tree_add_item(tree, hf_tdma_rpl_cal_req_stamp, tvb, offset, 8, FALSE);
505 proto_tree_add_item(tree, hf_tdma_rpl_cal_rcv_stamp, tvb, offset, 8, FALSE);
507 time = tvb_get_ntoh64(tvb, offset+8) - tvb_get_ntoh64(tvb, offset);
510 ti = proto_tree_add_item(tree, hf_tdma_rpl_cal_xmit_stamp, tvb, offset, 8, FALSE);
511 proto_item_append_text(ti, " (%s%" G_GINT64_MODIFIER "d)", (time > 0) ? "+" : "", time);
515 dissect_rtnet_tdma(tvbuff_t *tvb, packet_info *pinfo, proto_tree *root) {
521 msg = tvb_get_ntohs(tvb, 2);
523 /* Set the protocol column */
524 if (check_col(pinfo->cinfo,COL_PROTOCOL)){
525 col_set_str(pinfo->cinfo,COL_PROTOCOL,"TDMA");
528 /* Set the info column */
529 if (check_col(pinfo->cinfo, COL_INFO)) {
530 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
531 val_to_str(msg, tdma_msg_vals, "Unknown (0x%04x)"));
535 ti = proto_tree_add_item(root, proto_tdma, tvb, 0, -1, FALSE);
536 tree = proto_item_add_subtree(ti, ett_tdma);
538 proto_item_append_text(ti, ", %s", val_to_str(msg, tdma_msg_vals, "Unknown (0x%04x)"));
540 proto_tree_add_item(tree, hf_tdma_ver, tvb, offset, 2, FALSE);
543 proto_tree_add_item(tree, hf_tdma_id, tvb, offset, 2, FALSE);
548 dissect_tdma_sync(tvb, offset, tree);
551 case TDMA_MSG_CAL_REQUEST:
552 dissect_tdma_request_cal(tvb, offset, tree);
555 case TDMA_MSG_CAL_REPLY:
556 dissect_tdma_reply_cal(tvb, offset, tree);
566 dissect_rtmac(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
571 proto_tree *ti=NULL, *rtmac_tree=NULL;
573 dissector_handle_t dissector=NULL;
574 const gchar *type_str=NULL;
576 /* Read the header */
577 type = tvb_get_ntohs(tvb, offset);
578 ver = tvb_get_guint8(tvb, offset+2);
579 flags = tvb_get_guint8(tvb, offset+3);
582 type_str = match_strval(type, rtmac_type_vals);
584 dissector = dissector_get_port_handle(ethertype_table, type);
587 if (flags & RTMAC_FLAG_TUNNEL) {
588 dissector = dissector_get_port_handle(ethertype_table, type);
592 dissector = data_handle;
595 ti = proto_tree_add_item(tree, proto_rtmac, tvb, offset, 4, FALSE);
596 rtmac_tree = proto_item_add_subtree(ti, ett_rtmac);
597 proto_item_append_text(ti, ", Version %d", ver);
600 /* Set the protocol column */
601 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
602 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTmac");
605 /* set the info column */
606 if (check_col(pinfo->cinfo, COL_INFO)) {
607 col_clear(pinfo->cinfo,COL_INFO);
608 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown (0x%04x)",type);
614 if (dissector != data_handle)
615 type_str = dissector_handle_get_short_name(dissector);
617 type_str = "Unknown";
620 if (!(flags & RTMAC_FLAG_TUNNEL))
621 type_str = val_to_str(type, rtmac_type_vals, "Unknown");
623 if (dissector != data_handle)
624 type_str = dissector_handle_get_short_name(dissector);
626 type_str = "Unknown";
629 proto_tree_add_string_format(rtmac_tree, hf_rtmac_header_type, tvb, offset, 2,
630 type_str, "Type: %s (0x%04x)", type_str, type);
633 proto_tree_add_item(rtmac_tree, hf_rtmac_header_ver, tvb, offset, 1, FALSE);
637 proto_tree_add_item(rtmac_tree, hf_rtmac_header_res_v1, tvb, offset, 1, FALSE);
639 item = proto_tree_add_item(rtmac_tree, hf_rtmac_header_flags, tvb, offset, 1, FALSE);
640 ti = proto_item_add_subtree(item, ett_rtmac_flags);
641 proto_tree_add_item(ti, hf_rtmac_header_flags_res, tvb, offset, 1, FALSE);
642 proto_tree_add_item(ti, hf_rtmac_header_flags_tunnel, tvb, offset, 1, FALSE);
649 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
653 case RTMAC_TYPE_TDMA_V1:
654 dissect_rtnet_tdma_v1(next_tvb, pinfo, tree);
658 call_dissector(dissector, next_tvb, pinfo, tree);
662 if (flags & RTMAC_FLAG_TUNNEL)
663 call_dissector(dissector, next_tvb, pinfo, tree);
666 case RTMAC_TYPE_TDMA:
667 dissect_rtnet_tdma(next_tvb, pinfo, tree);
671 call_dissector(data_handle, next_tvb, pinfo, tree);
677 dissect_rtcfg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
679 proto_tree *vers_id_tree, *vers_id_item, *flags_tree, *flags_item;
682 guint32 config_length,len;
683 proto_tree *ti=NULL,*rtcfg_tree=NULL;
686 /* Set the protocol column */
687 if(check_col(pinfo->cinfo,COL_PROTOCOL)){
688 col_set_str(pinfo->cinfo,COL_PROTOCOL,"RTcfg");
691 /* Clear out stuff in the info column */
692 if(check_col(pinfo->cinfo,COL_INFO)){
693 col_clear(pinfo->cinfo,COL_INFO);
697 ti = proto_tree_add_item(tree, proto_rtcfg, tvb, offset, -1, FALSE);
698 rtcfg_tree = proto_item_add_subtree(ti, ett_rtcfg);
701 vers_id = tvb_get_guint8(tvb, offset);
703 if (check_col(pinfo->cinfo, COL_INFO)) {
704 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
705 val_to_str(vers_id, rtcfg_msg_vals, "Unknown (0x%04x)"));
710 vers_id_item = proto_tree_add_uint(rtcfg_tree, hf_rtcfg_vers_id, tvb,
713 vers_id_tree=proto_item_add_subtree(vers_id_item, ett_rtcfg);
714 proto_tree_add_item(vers_id_tree, hf_rtcfg_vers, tvb, offset, 1, FALSE);
715 proto_tree_add_item(vers_id_tree, hf_rtcfg_id, tvb, offset, 1, FALSE);
718 proto_item_append_text(ti, ", Version %d, %s",
720 val_to_str(vers_id, rtcfg_msg_vals, "Unknown (0x%04x)"));
722 switch( vers_id & 0x1f )
724 case RTCFG_MSG_S1_CONFIG:
725 address_type = tvb_get_guint8(tvb, offset);
726 proto_tree_add_item( rtcfg_tree, hf_rtcfg_address_type, tvb, offset, 1, FALSE );
729 switch( address_type )
731 case RTCFG_ADDRESS_TYPE_MAC:
735 case RTCFG_ADDRESS_TYPE_IP:
736 proto_tree_add_item( rtcfg_tree, hf_rtcfg_client_ip_address, tvb, offset, 4, FALSE );
739 proto_tree_add_item( rtcfg_tree, hf_rtcfg_server_ip_address, tvb, offset, 4, FALSE );
745 proto_tree_add_item( rtcfg_tree, hf_rtcfg_burst_rate, tvb, offset, 1, FALSE );
748 config_length = tvb_get_ntohs( tvb, offset );
749 proto_tree_add_item( rtcfg_tree, hf_rtcfg_s1_config_length, tvb, offset, 2, FALSE );
752 if( config_length > 0 ) {
753 proto_tree_add_item( rtcfg_tree, hf_rtcfg_config_data, tvb, offset, config_length, FALSE );
754 offset += config_length;
759 case RTCFG_MSG_ANN_NEW:
760 address_type = tvb_get_guint8(tvb, offset);
761 proto_tree_add_item( rtcfg_tree, hf_rtcfg_address_type, tvb, offset, 1, FALSE );
764 switch( address_type )
766 case RTCFG_ADDRESS_TYPE_MAC:
770 case RTCFG_ADDRESS_TYPE_IP:
771 proto_tree_add_item( rtcfg_tree, hf_rtcfg_client_ip_address, tvb, offset, 4, FALSE );
776 flags_item = proto_tree_add_item(rtcfg_tree, hf_rtcfg_client_flags, tvb,
779 flags_tree=proto_item_add_subtree(flags_item, ett_rtcfg);
780 proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_available, tvb, offset, 1, FALSE);
781 proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_ready, tvb, offset, 1, FALSE);
782 proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_res, tvb, offset, 1, FALSE);
785 proto_tree_add_item( rtcfg_tree, hf_rtcfg_burst_rate, tvb, offset, 1, FALSE );
790 case RTCFG_MSG_ANN_REPLY:
791 address_type = tvb_get_guint8(tvb, offset);
792 proto_tree_add_item( rtcfg_tree, hf_rtcfg_address_type, tvb, offset, 1, FALSE );
795 switch( address_type )
797 case RTCFG_ADDRESS_TYPE_MAC:
801 case RTCFG_ADDRESS_TYPE_IP:
802 proto_tree_add_item( rtcfg_tree, hf_rtcfg_client_ip_address, tvb, offset, 4, FALSE );
807 flags_item = proto_tree_add_item(rtcfg_tree, hf_rtcfg_client_flags, tvb,
810 flags_tree=proto_item_add_subtree(flags_item, ett_rtcfg);
811 proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_available, tvb, offset, 1, FALSE);
812 proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_ready, tvb, offset, 1, FALSE);
813 proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_res, tvb, offset, 1, FALSE);
816 proto_tree_add_item( rtcfg_tree, hf_rtcfg_padding, tvb, offset, 1, FALSE );
821 case RTCFG_MSG_S2_CONFIG:
822 flags_item = proto_tree_add_item(rtcfg_tree, hf_rtcfg_server_flags, tvb,
825 flags_tree=proto_item_add_subtree(flags_item, ett_rtcfg);
826 proto_tree_add_item(flags_tree, hf_rtcfg_server_flags_res0, tvb, offset, 1, FALSE);
827 proto_tree_add_item(flags_tree, hf_rtcfg_server_flags_ready, tvb, offset, 1, FALSE);
828 proto_tree_add_item(flags_tree, hf_rtcfg_server_flags_res2, tvb, offset, 1, FALSE);
831 proto_tree_add_item( rtcfg_tree, hf_rtcfg_active_stations, tvb, offset, 4, FALSE );
834 proto_tree_add_item( rtcfg_tree, hf_rtcfg_heartbeat_period, tvb, offset, 2, FALSE );
837 config_length = tvb_get_ntohl( tvb, offset );
838 proto_tree_add_item( rtcfg_tree, hf_rtcfg_s2_config_length, tvb, offset, 4, FALSE );
841 if( config_length > 0 ) {
842 len = tvb_reported_length_remaining(tvb, offset);
843 proto_tree_add_item( rtcfg_tree, hf_rtcfg_config_data, tvb, offset, len, FALSE );
849 case RTCFG_MSG_S2_FRAG:
850 proto_tree_add_item( rtcfg_tree, hf_rtcfg_config_offset, tvb, offset, 4, FALSE );
853 len = tvb_reported_length_remaining(tvb, offset);
854 proto_tree_add_item( rtcfg_tree, hf_rtcfg_config_data, tvb, offset, len, FALSE );
859 proto_tree_add_item( rtcfg_tree, hf_rtcfg_ack_length, tvb, offset, 4, FALSE );
864 case RTCFG_MSG_READY:
867 case RTCFG_MSG_HBEAT:
870 case RTCFG_MSG_DEAD_STN:
871 address_type = tvb_get_guint8(tvb, offset);
872 proto_tree_add_item( rtcfg_tree, hf_rtcfg_address_type, tvb, offset, 1, FALSE );
875 switch( address_type )
877 case RTCFG_ADDRESS_TYPE_MAC:
881 case RTCFG_ADDRESS_TYPE_IP:
882 proto_tree_add_item( rtcfg_tree, hf_rtcfg_client_ip_address, tvb, offset, 4, FALSE );
887 switch (pinfo->fd->lnk_t) {
888 case WTAP_ENCAP_ETHERNET:
889 haddr = tvb_get_ptr(tvb, offset, 6);
890 proto_tree_add_bytes_format( rtcfg_tree, hf_rtcfg_client_hw_address, tvb, offset, 32,
891 haddr, "Client Hardware Address: %02X:%02X:%02X:%02X:%02X:%02X",
892 *haddr, *(haddr+1), *(haddr+2),
893 *(haddr+3), *(haddr+4), *(haddr+5) );
897 proto_tree_add_item( rtcfg_tree, hf_rtcfg_client_hw_address, tvb, offset, 32, FALSE );
909 proto_register_rtmac(void) {
910 static const true_false_string rtnet_flags_set_truth = {
915 static hf_register_info hf_array_rtmac[] = {
918 { &hf_rtmac_header_type,
921 FT_STRING, BASE_NONE, NULL, 0x0,
922 "RTmac Type", HFILL }},
924 { &hf_rtmac_header_ver,
927 FT_UINT16, BASE_DEC, NULL, 0x0,
928 "RTmac Version", HFILL }},
930 { &hf_rtmac_header_flags,
932 "rtmac.header.flags",
933 FT_UINT8, BASE_HEX, NULL, 0x0,
934 "RTmac Flags", HFILL }},
936 { &hf_rtmac_header_flags_tunnel,
938 "rtmac.header.flags.tunnel",
939 FT_BOOLEAN, 8, TFS(&rtnet_flags_set_truth), RTMAC_FLAG_TUNNEL,
940 "RTmac Tunnelling Flag", HFILL }},
942 { &hf_rtmac_header_flags_res,
944 "rtmac.header.flags.res",
945 FT_UINT8, BASE_HEX, NULL, RTMAC_FLAGS_RES,
946 "RTmac Reserved Flags", HFILL }},
948 { &hf_rtmac_header_res_v1,
951 FT_UINT8, BASE_HEX, NULL, 0x0,
952 "RTmac Reserved", HFILL }},
955 static hf_register_info hf_array_tdma[] = {
961 FT_UINT32, BASE_HEX, VALS(tdma_v1_msg_vals), 0x0,
962 "TDMA-V1 Message", HFILL }},
964 /* TDMA request conf */
966 { &hf_tdma_v1_msg_request_conf_station,
968 "tdma-v1.msg.request_conf.station",
969 FT_UINT8, BASE_DEC, NULL, 0x0,
970 "TDMA Station", HFILL }},
972 { &hf_tdma_v1_msg_request_conf_padding,
974 "tdma-v1.msg.request_conf.padding",
975 FT_UINT8, BASE_HEX, NULL, 0x0,
976 "TDMA Padding", HFILL }},
978 { &hf_tdma_v1_msg_request_conf_mtu,
980 "tdma-v1.msg.request_conf.mtu",
981 FT_UINT8, BASE_DEC, NULL, 0x0,
982 "TDMA MTU", HFILL }},
984 { &hf_tdma_v1_msg_request_conf_cycle,
986 "tdma-v1.msg.request_conf.cycle",
987 FT_UINT8, BASE_DEC, NULL, 0x0,
988 "TDMA Cycle", HFILL }},
992 { &hf_tdma_v1_msg_ack_conf_station,
994 "tdma-v1.msg.ack_conf.station",
995 FT_UINT8, BASE_DEC, NULL, 0x0,
996 "TDMA Station", HFILL }},
998 { &hf_tdma_v1_msg_ack_conf_padding,
1000 "tdma-v1.msg.ack_conf.padding",
1001 FT_UINT8, BASE_HEX, NULL, 0x0,
1002 "TDMA PAdding", HFILL }},
1004 { &hf_tdma_v1_msg_ack_conf_mtu,
1006 "tdma-v1.msg.ack_conf.mtu",
1007 FT_UINT8, BASE_DEC, NULL, 0x0,
1008 "TDMA MTU", HFILL }},
1010 { &hf_tdma_v1_msg_ack_conf_cycle,
1012 "tdma-v1.msg.ack_conf.cycle",
1013 FT_UINT8, BASE_DEC, NULL, 0x0,
1014 "TDMA Cycle", HFILL }},
1016 /* TDMA ack ack conf */
1018 { &hf_tdma_v1_msg_ack_ack_conf_station,
1020 "tdma-v1.msg.ack_ack_conf.station",
1021 FT_UINT8, BASE_DEC, NULL, 0x0,
1022 "TDMA Station", HFILL }},
1024 { &hf_tdma_v1_msg_ack_ack_conf_padding,
1026 "tdma-v1.msg.ack_ack_conf.padding",
1027 FT_BYTES, BASE_HEX, NULL, 0x0,
1028 "TDMA Padding", HFILL }},
1030 /* TDMA request test */
1032 { &hf_tdma_v1_msg_request_test_counter,
1034 "tdma-v1.msg.request_test.counter",
1035 FT_UINT32, BASE_DEC, NULL, 0x0,
1036 "TDMA Counter", HFILL }},
1038 { &hf_tdma_v1_msg_request_test_tx,
1040 "tdma-v1.msg.request_test.tx",
1041 FT_UINT64, BASE_DEC, NULL, 0x0,
1042 "TDMA TX", HFILL }},
1046 { &hf_tdma_v1_msg_ack_test_counter,
1048 "tdma-v1.msg.ack_test.counter",
1049 FT_UINT32, BASE_DEC, NULL, 0x0,
1050 "TDMA Counter", HFILL }},
1052 { &hf_tdma_v1_msg_ack_test_tx,
1054 "tdma-v1.msg.ack_test.tx",
1055 FT_UINT64, BASE_DEC, NULL, 0x0,
1056 "TDMA TX", HFILL }},
1060 { &hf_tdma_v1_msg_request_change_offset_offset,
1062 "tdma-v1.msg.request_change_offset.offset",
1063 FT_UINT32, BASE_DEC, NULL, 0x0,
1064 "TDMA Offset", HFILL }},
1066 /* TDMA start of frame */
1069 { &hf_tdma_v1_msg_start_of_frame_timestamp,
1071 "tdma-v1.msg.start_of_frame.timestamp",
1072 FT_UINT64, BASE_DEC, NULL, 0x0,
1073 "TDMA Timestamp", HFILL }},
1075 /* TDMA station list */
1077 { &hf_tdma_v1_msg_station_list_nr_stations,
1079 "tdma-v1.msg.station_list.nr_stations",
1080 FT_UINT8, BASE_DEC, NULL, 0x0,
1081 "TDMA Nr. Stations", HFILL }},
1083 { &hf_tdma_v1_msg_station_list_nr,
1085 "tdma-v1.msg.station_list.nr",
1086 FT_UINT8, BASE_DEC, NULL, 0x0,
1087 "TDMA Station Number", HFILL }},
1089 { &hf_tdma_v1_msg_station_list_ip,
1091 "tdma-v1.msg.station_list.ip",
1092 FT_IPv4, BASE_DEC, NULL, 0x0,
1093 "TDMA Station IP", HFILL }},
1095 { &hf_tdma_v1_msg_station_list_padding,
1097 "tdma-v1.msg.station_list.padding",
1098 FT_BYTES, BASE_HEX, NULL, 0x0,
1099 "TDMA Padding", HFILL }},
1102 /* TDMA since version 2 */
1107 FT_UINT16, BASE_HEX, NULL, 0x0,
1108 "TDMA Version", HFILL }},
1113 FT_UINT16, BASE_HEX, VALS(tdma_msg_vals), 0x0,
1114 "TDMA Message ID", HFILL }},
1118 { &hf_tdma_sync_cycle,
1121 FT_UINT32, BASE_DEC, NULL, 0x0,
1122 "TDMA Sync Cycle Number", HFILL }},
1124 { &hf_tdma_sync_xmit_stamp,
1125 { "Transmission Time Stamp",
1126 "tdma.sync.xmit_stamp",
1127 FT_UINT64, BASE_DEC, NULL, 0x0,
1128 "TDMA Sync Transmission Time Stamp", HFILL }},
1130 { &hf_tdma_sync_sched_xmit,
1131 { "Scheduled Transmission Time",
1132 "tdma.sync.sched_xmit",
1133 FT_UINT64, BASE_DEC, NULL, 0x0,
1134 "TDMA Sync Scheduled Transmission Time", HFILL }},
1136 /* TDMA request calibration */
1138 { &hf_tdma_req_cal_xmit_stamp,
1139 { "Transmission Time Stamp",
1140 "tdma.req_cal.xmit_stamp",
1141 FT_UINT64, BASE_DEC, NULL, 0x0,
1142 "TDMA Request Calibration Transmission Time Stamp", HFILL }},
1144 { &hf_tdma_req_cal_rpl_cycle,
1145 { "Reply Cycle Number",
1146 "tdma.req_cal.rpl_cycle",
1147 FT_UINT32, BASE_DEC, NULL, 0x0,
1148 "TDMA Request Calibration Reply Cycle Number", HFILL }},
1150 { &hf_tdma_req_cal_rpl_slot,
1151 { "Reply Slot Offset",
1152 "tdma.req_cal.rpl_slot",
1153 FT_UINT64, BASE_DEC, NULL, 0x0,
1154 "TDMA Request Calibration Reply Slot Offset", HFILL }},
1156 /* TDMA reply calibration */
1158 { &hf_tdma_rpl_cal_req_stamp,
1159 { "Request Transmission Time",
1160 "tdma.rpl_cal.req_stamp",
1161 FT_UINT64, BASE_DEC, NULL, 0x0,
1162 "TDMA Reply Calibration Request Transmission Time", HFILL }},
1164 { &hf_tdma_rpl_cal_rcv_stamp,
1165 { "Reception Time Stamp",
1166 "tdma.rpl_cal.rcv_stamp",
1167 FT_UINT64, BASE_DEC, NULL, 0x0,
1168 "TDMA Reply Calibration Reception Time Stamp", HFILL }},
1170 { &hf_tdma_rpl_cal_xmit_stamp,
1171 { "Transmission Time Stamp",
1172 "tdma.rpl_cal.xmit_stamp",
1173 FT_UINT64, BASE_DEC, NULL, 0x0,
1174 "TDMA Reply Calibration Transmission Time Stamp", HFILL }},
1177 static gint *ett_array_rtmac[] = {
1182 static gint *ett_array_tdma[] = {
1186 proto_rtmac = proto_register_protocol("Real-Time Media Access Control", "RTmac", "rtmac");
1187 proto_register_field_array(proto_rtmac, hf_array_rtmac, array_length(hf_array_rtmac));
1188 proto_register_subtree_array(ett_array_rtmac, array_length(ett_array_rtmac));
1190 proto_tdma = proto_register_protocol("TDMA RTmac Discipline", "TDMA", "tdma");
1191 proto_register_field_array(proto_rtmac, hf_array_tdma, array_length(hf_array_tdma));
1192 proto_register_subtree_array(ett_array_tdma, array_length(ett_array_tdma));
1197 proto_register_rtcfg(void) {
1198 static hf_register_info hf[] = {
1199 { &hf_rtcfg_vers_id,
1202 FT_UINT8, BASE_HEX, NULL, 0x0,
1203 "RTcfg Version and ID", HFILL }},
1208 FT_UINT8, BASE_DEC, NULL, 0xe0,
1209 "RTcfg Version", HFILL }},
1214 FT_UINT8, BASE_HEX, VALS(rtcfg_msg_vals), 0x1f,
1215 "RTcfg ID", HFILL }},
1217 { &hf_rtcfg_address_type,
1219 "rtcfg.address_type",
1220 FT_UINT8, BASE_DEC, VALS(rtcfg_address_type_vals), 0x00,
1221 "RTcfg Address Type", HFILL }},
1223 { &hf_rtcfg_client_ip_address,
1224 { "Client IP Address",
1225 "rtcfg.client_ip_address",
1226 FT_IPv4, BASE_DEC, NULL, 0x0,
1227 "RTcfg Client IP Address", HFILL }},
1229 { &hf_rtcfg_server_ip_address,
1230 { "Server IP Address",
1231 "rtcfg.server_ip_address",
1232 FT_IPv4, BASE_DEC, NULL, 0x0,
1233 "RTcfg Server IP Address", HFILL }},
1235 { &hf_rtcfg_burst_rate,
1236 { "Stage 2 Burst Rate",
1238 FT_UINT8, BASE_DEC, NULL, 0x00,
1239 "RTcfg Stage 2 Burst Rate", HFILL }},
1241 { &hf_rtcfg_s1_config_length,
1242 { "Stage 1 Config Length",
1243 "rtcfg.s1_config_length",
1244 FT_UINT16, BASE_DEC, NULL, 0x00,
1245 "RTcfg Stage 1 Config Length", HFILL }},
1247 { &hf_rtcfg_config_data,
1249 "rtcfg.config_data",
1250 FT_BYTES, BASE_DEC, NULL, 0x00,
1251 "RTcfg Config Data", HFILL }},
1253 { &hf_rtcfg_padding,
1256 FT_UINT8, BASE_DEC, NULL, 0x00,
1257 "RTcfg Padding", HFILL }},
1259 { &hf_rtcfg_client_flags,
1261 "rtcfg.client_flags",
1262 FT_UINT8, BASE_HEX, NULL, 0x00,
1263 "RTcfg Client Flags", HFILL }},
1265 { &hf_rtcfg_client_flags_available,
1267 "rtcfg.client_flags.available",
1268 FT_UINT8, BASE_DEC, NULL, 0x01,
1269 "Request Available", HFILL }},
1271 { &hf_rtcfg_client_flags_ready,
1273 "rtcfg.client_flags.ready",
1274 FT_UINT8, BASE_DEC, NULL, 0x02,
1275 "Client Ready", HFILL }},
1277 { &hf_rtcfg_client_flags_res,
1279 "rtcfg.client_flags.res",
1280 FT_UINT8, BASE_HEX, NULL, 0xfc,
1281 "Reserved", HFILL }},
1283 { &hf_rtcfg_server_flags,
1285 "rtcfg.server_flags",
1286 FT_UINT8, BASE_HEX, NULL, 0x00,
1287 "RTcfg Server Flags", HFILL }},
1289 { &hf_rtcfg_server_flags_res0,
1291 "rtcfg.server_flags.res0",
1292 FT_UINT8, BASE_HEX, NULL, 0x01,
1293 "Reserved", HFILL }},
1295 { &hf_rtcfg_server_flags_ready,
1297 "rtcfg.server_flags.ready",
1298 FT_UINT8, BASE_DEC, NULL, 0x02,
1299 "Server Ready", HFILL }},
1301 { &hf_rtcfg_server_flags_res2,
1303 "rtcfg.server_flags.res2",
1304 FT_UINT8, BASE_HEX, NULL, 0xfc,
1305 "Reserved", HFILL }},
1307 { &hf_rtcfg_active_stations,
1308 { "Active Stations",
1309 "rtcfg.active_stations",
1310 FT_UINT32, BASE_DEC, NULL, 0x00,
1311 "RTcfg Active Stations", HFILL }},
1313 { &hf_rtcfg_heartbeat_period,
1314 { "Heartbeat Period",
1315 "rtcfg.hearbeat_period",
1316 FT_UINT16, BASE_DEC, NULL, 0x00,
1317 "RTcfg Heartbeat Period", HFILL }},
1319 { &hf_rtcfg_s2_config_length,
1320 { "Stage 2 Config Length",
1321 "rtcfg.s2_config_length",
1322 FT_UINT32, BASE_DEC, NULL, 0x00,
1323 "RTcfg Stage 2 Config Length", HFILL }},
1325 { &hf_rtcfg_config_offset,
1327 "rtcfg.config_offset",
1328 FT_UINT32, BASE_DEC, NULL, 0x00,
1329 "RTcfg Config Offset", HFILL }},
1331 { &hf_rtcfg_ack_length,
1334 FT_UINT32, BASE_DEC, NULL, 0x00,
1335 "RTcfg Ack Length", HFILL }},
1337 { &hf_rtcfg_client_hw_address,
1338 { "Client Hardware Address",
1339 "rtcfg.client_ip_address",
1340 FT_BYTES, BASE_NONE, NULL, 0x00,
1341 "RTcfg Client Hardware Address", HFILL }}
1344 static gint *ett[] = {
1348 proto_rtcfg = proto_register_protocol("RTcfg","RTcfg","rtcfg");
1349 proto_register_field_array(proto_rtcfg,hf,array_length(hf));
1350 proto_register_subtree_array(ett,array_length(ett));
1353 /* The registration hand-off routing */
1356 proto_reg_handoff_rtmac(void) {
1357 dissector_handle_t rtmac_handle;
1359 rtmac_handle = create_dissector_handle(dissect_rtmac, proto_rtmac);
1360 dissector_add("ethertype", ETHERTYPE_RTMAC, rtmac_handle);
1361 ethertype_table = find_dissector_table("ethertype");
1365 proto_reg_handoff_rtcfg(void) {
1366 dissector_handle_t rtcfg_handle;
1368 data_handle = find_dissector("data");
1369 rtcfg_handle = create_dissector_handle(dissect_rtcfg, proto_rtcfg);
1370 dissector_add("ethertype", ETHERTYPE_RTCFG, rtcfg_handle);