730650acccdbb083021bb4ee1378b8b74c0e24c8
[obnox/wireshark/wip.git] / plugins / rtnet / packet-rtnet.c
1 /* packet-rtnet.c
2  * Routines for RTnet packet disassembly
3  *
4  * $Id$
5  *
6  * Copyright (c) 2003 by Erwin Rol <erwin@erwinrol.com>
7  * Copyright (c) 2004 by Jan Kiszka <jan.kiszka@web.de>
8  *
9  * Ethereal - Network traffic analyzer
10  * By Gerald Combs <gerald@ethereal.com>
11  * Copyright 1999 Gerald Combs
12  *
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.
17  *
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.
22  *
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.
26  */
27
28 /* Include files */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "plugins/plugin_api.h"
35
36 #include "moduleinfo.h"
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <gmodule.h>
41 #include <ctype.h>
42 #include <time.h>
43 #include <string.h>
44 #include <epan/packet.h>
45 #include <epan/addr_resolv.h>
46 #include "etypes.h"
47 #include <epan/strutil.h>
48
49 #include "plugins/plugin_api_defs.h"
50
51 /* Define version if we are not building ethereal statically */
52
53 #ifndef ENABLE_STATIC
54 G_MODULE_EXPORT const gchar version[] = VERSION;
55 #endif
56
57 /*
58  * See
59  *
60  *      http://www.rts.uni-hannover.de/rtnet/
61  */
62
63 #define RTMAC_TYPE_TDMA     0x0001 /* since version 2    */
64 #define RTMAC_TYPE_TDMA_V1  0x9031 /* first TDMA version */
65
66 static const value_string rtmac_type_vals[] = {
67   { RTMAC_TYPE_TDMA,    "TDMA" },
68   { RTMAC_TYPE_TDMA_V1, "TDMA-V1" },
69   { 0, NULL }
70 };
71
72 #define RTMAC_FLAG_TUNNEL   0x01
73 #define RTMAC_FLAGS_RES     0xFE
74
75 #define RTCFG_MSG_S1_CONFIG    0x0
76 #define RTCFG_MSG_ANN_NEW      0x1
77 #define RTCFG_MSG_ANN_REPLY    0x2
78 #define RTCFG_MSG_S2_CONFIG    0x3
79 #define RTCFG_MSG_S2_FRAG      0x4
80 #define RTCFG_MSG_ACK          0x5
81 #define RTCFG_MSG_READY        0x6
82 #define RTCFG_MSG_HBEAT        0x7
83 #define RTCFG_MSG_DEAD_STN     0x8
84
85 static const value_string rtcfg_msg_vals[] = {
86   { RTCFG_MSG_S1_CONFIG, "Stage 1 Config" },
87   { RTCFG_MSG_ANN_NEW,   "New Announce" },
88   { RTCFG_MSG_ANN_REPLY, "Reply Announce" },
89   { RTCFG_MSG_S2_CONFIG, "Stage 2 Config" },
90   { RTCFG_MSG_S2_FRAG,   "Stage 2 Fragment" },
91   { RTCFG_MSG_ACK,       "Acknowledge" },
92   { RTCFG_MSG_READY,     "Ready" },
93   { RTCFG_MSG_HBEAT,     "Heartbeat" },
94   { RTCFG_MSG_DEAD_STN,  "Dead Station" },
95   { 0, NULL }
96 };
97
98 #define RTCFG_ADDRESS_TYPE_MAC  0x00
99 #define RTCFG_ADDRESS_TYPE_IP   0x01
100
101 static const value_string rtcfg_address_type_vals[] = {
102   { RTCFG_ADDRESS_TYPE_MAC,    "MAC" },
103   { RTCFG_ADDRESS_TYPE_IP,     "IP" },
104   { 0, NULL }
105 };
106
107 #define TDMA_V1_MSG_NOTIFY_MASTER          0x10
108 #define TDMA_V1_MSG_REQUEST_TEST           0x11
109 #define TDMA_V1_MSG_ACK_TEST               0x12
110 #define TDMA_V1_MSG_REQUEST_CONF           0x13
111 #define TDMA_V1_MSG_ACK_CONF               0x14
112 #define TDMA_V1_MSG_ACK_ACK_CONF           0x15
113 #define TDMA_V1_MSG_STATION_LIST           0x16
114 #define TDMA_V1_MSG_REQUEST_CHANGE_OFFSET  0x17
115 #define TDMA_V1_MSG_START_OF_FRAME         0x18
116
117 static const value_string tdma_v1_msg_vals[] = {
118   { TDMA_V1_MSG_NOTIFY_MASTER,         "Notify Master" },
119   { TDMA_V1_MSG_REQUEST_TEST,          "Request Test" },
120   { TDMA_V1_MSG_ACK_TEST,              "Acknowledge Test" },
121   { TDMA_V1_MSG_REQUEST_CONF,          "Request Config" },
122   { TDMA_V1_MSG_ACK_CONF,              "Acknowledge Config" },
123   { TDMA_V1_MSG_ACK_ACK_CONF,          "Ack Ack Config" },
124   { TDMA_V1_MSG_STATION_LIST,          "Station List" },
125   { TDMA_V1_MSG_REQUEST_CHANGE_OFFSET, "Request Change Offset" },
126   { TDMA_V1_MSG_START_OF_FRAME,        "Start of Frame" },
127   { 0, NULL }
128 };
129
130 #define TDMA_MSG_SYNC           0x0000
131 #define TDMA_MSG_CAL_REQUEST    0x0010
132 #define TDMA_MSG_CAL_REPLY      0x0011
133
134 static const value_string tdma_msg_vals[] = {
135   { TDMA_MSG_SYNC,              "Synchronisation" },
136   { TDMA_MSG_CAL_REQUEST,       "Request Calibration" },
137   { TDMA_MSG_CAL_REPLY,         "Reply Calibration" },
138   { 0, NULL }
139 };
140
141 static dissector_table_t ethertype_table;
142 static dissector_handle_t data_handle;
143
144 void proto_reg_handoff_rtmac(void);
145 void proto_reg_handoff_rtcfg(void);
146
147 /* Define the rtnet proto */
148 static int proto_rtmac = -1;
149 static int proto_tdma = -1;
150 static int proto_rtcfg = -1;
151
152 /* RTmac Header */
153 static int hf_rtmac_header_type = -1;
154 static int hf_rtmac_header_ver = -1;
155 static int hf_rtmac_header_flags = -1;
156 static int hf_rtmac_header_flags_tunnel = -1;
157 static int hf_rtmac_header_flags_res = -1;
158 static int hf_rtmac_header_res_v1 = -1;
159
160
161 /* RTcfg */
162 static int hf_rtcfg_vers_id = -1;
163 static int hf_rtcfg_vers = -1;
164 static int hf_rtcfg_id = -1;
165 static int hf_rtcfg_address_type = -1;
166 static int hf_rtcfg_client_ip_address = -1;
167 static int hf_rtcfg_server_ip_address = -1;
168 static int hf_rtcfg_burst_rate = -1;
169 static int hf_rtcfg_padding = -1;
170 static int hf_rtcfg_s1_config_length = -1;
171 static int hf_rtcfg_config_data = -1;
172 static int hf_rtcfg_client_flags = -1;
173 static int hf_rtcfg_client_flags_available = -1;
174 static int hf_rtcfg_client_flags_ready = -1;
175 static int hf_rtcfg_client_flags_res = -1;
176 static int hf_rtcfg_server_flags = -1;
177 static int hf_rtcfg_server_flags_res0 = -1;
178 static int hf_rtcfg_server_flags_ready = -1;
179 static int hf_rtcfg_server_flags_res2 = -1;
180 static int hf_rtcfg_active_stations = -1;
181 static int hf_rtcfg_heartbeat_period = -1;
182 static int hf_rtcfg_s2_config_length = -1;
183 static int hf_rtcfg_config_offset = -1;
184 static int hf_rtcfg_ack_length = -1;
185 static int hf_rtcfg_client_hw_address = -1;
186
187
188 /* TDMA-V1 */
189 static int hf_tdma_v1_msg = -1;
190
191 /* TDMA REQUEST_CONF */
192 static int hf_tdma_v1_msg_request_conf_station = -1;
193 static int hf_tdma_v1_msg_request_conf_padding = -1;
194 static int hf_tdma_v1_msg_request_conf_mtu = -1;
195 static int hf_tdma_v1_msg_request_conf_cycle = -1;
196
197 /* TDMA ACK_CONF */
198 static int hf_tdma_v1_msg_ack_conf_station = -1;
199 static int hf_tdma_v1_msg_ack_conf_padding = -1;
200 static int hf_tdma_v1_msg_ack_conf_mtu = -1;
201 static int hf_tdma_v1_msg_ack_conf_cycle = -1;
202
203 /* TDMA ACK_ACK_CONF */
204 static int hf_tdma_v1_msg_ack_ack_conf_station = -1;
205 static int hf_tdma_v1_msg_ack_ack_conf_padding = -1;
206
207 /* TDMA REQUEST_TEST */
208 static int hf_tdma_v1_msg_request_test_counter = -1;
209 static int hf_tdma_v1_msg_request_test_tx = -1;
210
211 /* TDMA ACK_TEST */
212 static int hf_tdma_v1_msg_ack_test_counter = -1;
213 static int hf_tdma_v1_msg_ack_test_tx = -1;
214
215 /* TDMA STATION_LIST */
216 static int hf_tdma_v1_msg_station_list_nr_stations = -1;
217 static int hf_tdma_v1_msg_station_list_padding = -1;
218
219 static int hf_tdma_v1_msg_station_list_ip = -1;
220 static int hf_tdma_v1_msg_station_list_nr = -1;
221
222 /* TDMA CHANGE_OFFSET */
223 static int hf_tdma_v1_msg_request_change_offset_offset = -1;
224
225 /* TDMA START_OF_FRAME */
226 static int hf_tdma_v1_msg_start_of_frame_timestamp = -1;
227
228
229 /* TDMA since version 2 */
230 static int hf_tdma_ver = -1;
231 static int hf_tdma_id = -1;
232
233 /* TDMA Sync */
234 static int hf_tdma_sync_cycle = -1;
235 static int hf_tdma_sync_xmit_stamp = -1;
236 static int hf_tdma_sync_sched_xmit = -1;
237
238 /* TDMA Request Calibration */
239 static int hf_tdma_req_cal_xmit_stamp = -1;
240 static int hf_tdma_req_cal_rpl_cycle = -1;
241 static int hf_tdma_req_cal_rpl_slot = -1;
242
243 /* TDMA Reply Calibration */
244 static int hf_tdma_rpl_cal_req_stamp = -1;
245 static int hf_tdma_rpl_cal_rcv_stamp = -1;
246 static int hf_tdma_rpl_cal_xmit_stamp = -1;
247
248
249 /* Define the tree for rtnet */
250 static int ett_rtmac = -1;
251 static int ett_rtmac_flags = -1;
252 static int ett_tdma = -1;
253 static int ett_rtcfg = -1;
254
255 static guint
256 dissect_rtnet_tdma_notify_master(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_)
257 {
258   return offset;
259 }
260
261 static guint
262 dissect_rtnet_tdma_request_test(tvbuff_t *tvb, guint offset, proto_tree *tree)
263 {
264   proto_tree_add_item(tree, hf_tdma_v1_msg_request_test_counter, tvb,
265                        offset, 4, TRUE );
266   offset += 4;
267
268   proto_tree_add_item(tree, hf_tdma_v1_msg_request_test_tx, tvb,
269                        offset, 8, TRUE );
270   offset += 8;
271
272   return offset;
273 }
274
275 static guint
276 dissect_rtnet_tdma_ack_test(tvbuff_t *tvb, guint offset, proto_tree *tree)
277 {
278   proto_tree_add_item(tree, hf_tdma_v1_msg_ack_test_counter, tvb,
279                        offset, 4, TRUE );
280   offset += 4;
281
282   proto_tree_add_item(tree, hf_tdma_v1_msg_ack_test_tx, tvb,
283                        offset, 8, TRUE );
284   offset += 8;
285
286   return offset;
287 }
288
289 static guint
290 dissect_rtnet_tdma_request_conf(tvbuff_t *tvb, guint offset, proto_tree *tree)
291 {
292   proto_tree_add_item(tree, hf_tdma_v1_msg_request_conf_station, tvb,
293                        offset, 1, FALSE );
294   offset += 1;
295
296   proto_tree_add_item(tree, hf_tdma_v1_msg_request_conf_padding, tvb,
297                        offset, 1, FALSE );
298   offset += 1;
299
300   proto_tree_add_item(tree, hf_tdma_v1_msg_request_conf_mtu, tvb,
301                        offset, 2, FALSE );
302   offset += 2;
303
304   proto_tree_add_item(tree, hf_tdma_v1_msg_request_conf_cycle, tvb,
305                        offset, 4, FALSE );
306   offset += 4;
307
308   return offset;
309 }
310
311
312 static guint
313 dissect_rtnet_tdma_ack_conf(tvbuff_t *tvb, guint offset, proto_tree *tree)
314 {
315   proto_tree_add_item(tree, hf_tdma_v1_msg_ack_conf_station, tvb,
316                        offset, 1, FALSE );
317   offset += 1;
318
319   proto_tree_add_item(tree, hf_tdma_v1_msg_ack_conf_padding, tvb,
320                        offset, 1, FALSE );
321   offset += 1;
322
323   proto_tree_add_item(tree, hf_tdma_v1_msg_ack_conf_mtu, tvb,
324                        offset, 2, FALSE );
325   offset += 2;
326
327   proto_tree_add_item(tree, hf_tdma_v1_msg_ack_conf_cycle, tvb,
328                        offset, 4, FALSE );
329   offset += 4;
330
331   return offset;
332 }
333
334 static guint
335 dissect_rtnet_tdma_ack_ack_conf(tvbuff_t *tvb, guint offset, proto_tree *tree) {
336
337   proto_tree_add_item(tree, hf_tdma_v1_msg_ack_ack_conf_station, tvb,
338                        offset, 1, FALSE );
339
340   offset += 1;
341
342   proto_tree_add_item(tree, hf_tdma_v1_msg_ack_ack_conf_padding, tvb,
343                        offset, 3, FALSE );
344   offset += 3;
345
346   return offset;
347 }
348
349 static guint
350 dissect_rtnet_tdma_station_list(tvbuff_t *tvb, guint offset, proto_tree *tree)
351 {
352   guint8 nr_stations;
353   guint8 i;
354
355   nr_stations = tvb_get_guint8(tvb, offset);
356   proto_tree_add_uint(tree, hf_tdma_v1_msg_station_list_nr_stations, tvb,
357                       offset, 1, nr_stations);
358
359   offset += 1;
360
361   proto_tree_add_item(tree, hf_tdma_v1_msg_station_list_padding, tvb,
362                        offset, 3, FALSE );
363   offset += 3;
364
365
366   for( i = 0; i < nr_stations; i++ )
367   {
368     proto_tree_add_item(tree, hf_tdma_v1_msg_station_list_ip, tvb,
369                         offset, 4, FALSE );
370
371     offset += 4;
372
373     proto_tree_add_item(tree, hf_tdma_v1_msg_station_list_nr, tvb,
374                         offset, 1, FALSE );
375
376     offset += 1;
377
378     proto_tree_add_item(tree, hf_tdma_v1_msg_station_list_padding, tvb,
379                         offset, 3, FALSE );
380     offset += 3;
381   }
382
383   return offset;
384 }
385
386 static guint
387 dissect_rtnet_tdma_request_change_offset(tvbuff_t *tvb, guint offset, proto_tree *tree)
388 {
389   proto_tree_add_item(tree, hf_tdma_v1_msg_request_change_offset_offset, tvb,
390                        offset, 4, FALSE );
391
392   offset += 4;
393
394   return offset;
395 }
396
397 static guint
398 dissect_rtnet_tdma_start_of_frame(tvbuff_t *tvb, guint offset, proto_tree *tree)
399 {
400   proto_tree_add_item(tree, hf_tdma_v1_msg_start_of_frame_timestamp, tvb,
401                        offset, 8, FALSE );
402   offset += 8;
403
404   return offset;
405 }
406
407 static void
408 dissect_rtnet_tdma_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *root) {
409   guint offset = 0;
410   guint32 msg;
411   proto_tree *tree;
412   proto_item *ti;
413
414   msg = tvb_get_ntohl(tvb, offset);
415
416   /* Set the protocol column */
417   if (check_col(pinfo->cinfo,COL_PROTOCOL)){
418     col_set_str(pinfo->cinfo,COL_PROTOCOL,"TDMA-V1");
419   }
420
421   /* set the info column */
422   if (check_col(pinfo->cinfo, COL_INFO)) {
423     col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
424       val_to_str(msg, tdma_v1_msg_vals, "Unknown (0x%04x)"));
425   }
426
427   if (root) {
428     ti = proto_tree_add_item(root, proto_tdma, tvb, 0, -1, FALSE);
429     tree = proto_item_add_subtree(ti, ett_tdma);
430
431     proto_item_append_text(ti, ", Version 1, %s",
432       val_to_str(msg, tdma_v1_msg_vals, "Unknown (0x%04x)"));
433
434     proto_tree_add_item(tree, hf_tdma_v1_msg, tvb,
435                         offset, 4, FALSE);
436     offset += 4;
437
438     switch( msg ) {
439       case TDMA_V1_MSG_NOTIFY_MASTER:
440         dissect_rtnet_tdma_notify_master(tvb, offset, tree);
441         break;
442
443       case TDMA_V1_MSG_REQUEST_TEST:
444         dissect_rtnet_tdma_request_test(tvb, offset, tree);
445         break;
446
447       case TDMA_V1_MSG_ACK_TEST:
448         dissect_rtnet_tdma_ack_test(tvb, offset, tree);
449         break;
450
451       case TDMA_V1_MSG_REQUEST_CONF:
452         dissect_rtnet_tdma_request_conf(tvb, offset, tree);
453         break;
454
455       case TDMA_V1_MSG_ACK_CONF:
456         dissect_rtnet_tdma_ack_conf(tvb, offset, tree);
457         break;
458
459       case TDMA_V1_MSG_ACK_ACK_CONF:
460         dissect_rtnet_tdma_ack_ack_conf(tvb, offset, tree);
461         break;
462
463       case TDMA_V1_MSG_STATION_LIST:
464         dissect_rtnet_tdma_station_list (tvb, offset, tree);
465         break;
466
467       case TDMA_V1_MSG_REQUEST_CHANGE_OFFSET:
468         dissect_rtnet_tdma_request_change_offset(tvb, offset, tree);
469         break;
470
471       case TDMA_V1_MSG_START_OF_FRAME:
472         dissect_rtnet_tdma_start_of_frame(tvb, offset, tree);
473         break;
474
475       default:
476         break;
477     }
478   }
479 }
480
481 static void
482 dissect_tdma_sync(tvbuff_t *tvb, guint offset, proto_tree *tree) {
483   gint64 time;
484   proto_item *ti;
485
486   proto_tree_add_item(tree, hf_tdma_sync_cycle, tvb, offset, 4, FALSE);
487   offset += 4;
488
489   ti = proto_tree_add_item(tree, hf_tdma_sync_xmit_stamp, tvb, offset, 8, FALSE);
490   time = tvb_get_ntoh64(tvb, offset) - tvb_get_ntoh64(tvb, offset+8);
491   proto_item_append_text(ti, " (%s%" PRId64 ")", (time > 0) ? "+" : "", time);
492   offset += 8;
493
494   proto_tree_add_item(tree, hf_tdma_sync_sched_xmit, tvb, offset, 8, FALSE);
495 }
496
497 static void
498 dissect_tdma_request_cal(tvbuff_t *tvb, guint offset, proto_tree *tree) {
499
500   proto_tree_add_item(tree, hf_tdma_req_cal_xmit_stamp, tvb, offset, 8, FALSE);
501   offset += 8;
502
503   proto_tree_add_item(tree, hf_tdma_req_cal_rpl_cycle, tvb, offset, 4, FALSE);
504   offset += 4;
505
506   proto_tree_add_item(tree, hf_tdma_req_cal_rpl_slot, tvb, offset, 8, FALSE);
507 }
508
509 static void
510 dissect_tdma_reply_cal(tvbuff_t *tvb, guint offset, proto_tree *tree) {
511   gint64 time;
512   proto_item *ti;
513
514   proto_tree_add_item(tree, hf_tdma_rpl_cal_req_stamp, tvb, offset, 8, FALSE);
515   offset += 8;
516
517   proto_tree_add_item(tree, hf_tdma_rpl_cal_rcv_stamp, tvb, offset, 8, FALSE);
518
519   time = tvb_get_ntoh64(tvb, offset+8) - tvb_get_ntoh64(tvb, offset);
520   offset += 8;
521
522   ti = proto_tree_add_item(tree, hf_tdma_rpl_cal_xmit_stamp, tvb, offset, 8, FALSE);
523   proto_item_append_text(ti, " (%s%" PRId64 ")", (time > 0) ? "+" : "", time);
524 }
525
526 static void
527 dissect_rtnet_tdma(tvbuff_t *tvb, packet_info *pinfo, proto_tree *root) {
528   guint offset = 0;
529   guint16 msg;
530   proto_item *ti;
531   proto_tree *tree;
532
533   msg = tvb_get_ntohs(tvb, 2);
534
535   /* Set the protocol column */
536   if (check_col(pinfo->cinfo,COL_PROTOCOL)){
537     col_set_str(pinfo->cinfo,COL_PROTOCOL,"TDMA");
538   }
539
540   /* Set the info column */
541   if (check_col(pinfo->cinfo, COL_INFO)) {
542     col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
543                  val_to_str(msg, tdma_msg_vals, "Unknown (0x%04x)"));
544   }
545
546   if (root) {
547     ti = proto_tree_add_item(root, proto_tdma, tvb, 0, -1, FALSE);
548     tree = proto_item_add_subtree(ti, ett_tdma);
549
550     proto_item_append_text(ti, ", %s", val_to_str(msg, tdma_msg_vals, "Unknown (0x%04x)"));
551
552     proto_tree_add_item(tree, hf_tdma_ver, tvb, offset, 2, FALSE);
553     offset += 2;
554
555     proto_tree_add_item(tree, hf_tdma_id, tvb, offset, 2, FALSE);
556     offset += 2;
557
558     switch (msg) {
559       case TDMA_MSG_SYNC:
560         dissect_tdma_sync(tvb, offset, tree);
561         break;
562
563       case TDMA_MSG_CAL_REQUEST:
564         dissect_tdma_request_cal(tvb, offset, tree);
565         break;
566
567       case TDMA_MSG_CAL_REPLY:
568         dissect_tdma_reply_cal(tvb, offset, tree);
569         break;
570
571       default:
572         break;
573     }
574   }
575 }
576
577 static void
578 dissect_rtmac(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
579   gint offset = 0;
580   guint8 ver,flags;
581   guint16 type;
582   tvbuff_t *next_tvb;
583   proto_tree *ti=NULL, *rtmac_tree=NULL;
584   proto_item *item;
585   dissector_handle_t dissector=NULL;
586   gchar *type_str=NULL;
587
588   /* Read the header */
589   type = tvb_get_ntohs(tvb, offset);
590   ver = tvb_get_guint8(tvb, offset+2);
591   flags = tvb_get_guint8(tvb, offset+3);
592
593   if (ver == 1) {
594     type_str = match_strval(type, rtmac_type_vals);
595     if (!type_str) {
596       dissector = dissector_get_port_handle(ethertype_table, type);
597       if (!dissector)
598         dissector = data_handle;
599     }
600   } else {
601     if (flags & RTMAC_FLAG_TUNNEL) {
602       dissector = dissector_get_port_handle(ethertype_table, type);
603       if (!dissector)
604         dissector = data_handle;
605     }
606   }
607
608   if (tree) {
609     ti = proto_tree_add_item(tree, proto_rtmac, tvb, offset, 4, FALSE);
610     rtmac_tree = proto_item_add_subtree(ti, ett_rtmac);
611     proto_item_append_text(ti, ", Version %d", ver);
612   }
613
614   /* Set the protocol column */
615   if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
616     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTmac");
617   }
618
619   /* set the info column */
620   if (check_col(pinfo->cinfo, COL_INFO)) {
621     col_clear(pinfo->cinfo,COL_INFO);
622     col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown (0x%04x)",type);
623   }
624
625   if (rtmac_tree) {
626     if (ver == 1) {
627       if (!type_str) {
628         if (dissector != data_handle)
629           type_str = dissector_handle_get_short_name(dissector);
630         else
631           type_str = "Unknown";
632       }
633     } else {
634       if (!(flags & RTMAC_FLAG_TUNNEL)) {
635         type_str = match_strval(type, rtmac_type_vals);
636         if (!type_str)
637           type_str = "Unknown";
638       } else {
639         if (dissector != data_handle)
640           type_str = dissector_handle_get_short_name(dissector);
641         else
642           type_str = "Unknown";
643       }
644     }
645     proto_tree_add_string_format(rtmac_tree, hf_rtmac_header_type, tvb, offset, 2,
646                                  type_str, "Type: %s (0x%04x)", type_str, type);
647     offset += 2;
648
649     proto_tree_add_item(rtmac_tree, hf_rtmac_header_ver, tvb, offset, 1, FALSE);
650     offset += 1;
651
652     if (ver == 1)
653       proto_tree_add_item(rtmac_tree, hf_rtmac_header_res_v1, tvb, offset, 1, FALSE);
654     else {
655       item = proto_tree_add_item(rtmac_tree, hf_rtmac_header_flags, tvb, offset, 1, FALSE);
656       ti = proto_item_add_subtree(item, ett_rtmac_flags);
657       proto_tree_add_item(ti, hf_rtmac_header_flags_res, tvb, offset, 1, FALSE);
658       proto_tree_add_item(ti, hf_rtmac_header_flags_tunnel, tvb, offset, 1, FALSE);
659     }
660     offset += 1;
661   }
662   else
663     offset += 4;
664
665   next_tvb = tvb_new_subset(tvb, offset, -1, -1);
666
667   if (ver == 1)
668     switch (type) {
669       case RTMAC_TYPE_TDMA_V1:
670         dissect_rtnet_tdma_v1(next_tvb, pinfo, tree);
671         break;
672
673       default:
674         call_dissector(dissector, next_tvb, pinfo, tree);
675         break;
676     }
677   else
678     if (flags & RTMAC_FLAG_TUNNEL)
679       call_dissector(dissector, next_tvb, pinfo, tree);
680     else
681       switch (type) {
682         case RTMAC_TYPE_TDMA:
683           dissect_rtnet_tdma(next_tvb, pinfo, tree);
684           break;
685
686         default:
687           call_dissector(data_handle, next_tvb, pinfo, tree);
688           break;
689       }
690 }
691
692 static void
693 dissect_rtcfg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
694   gint offset = 0;
695   proto_tree *vers_id_tree, *vers_id_item, *flags_tree, *flags_item;
696   guint8 vers_id;
697   guint8 address_type;
698   guint32 config_length,len;
699   proto_tree *ti=NULL,*rtcfg_tree=NULL;
700   const guint8 *haddr;
701
702   /* Set the protocol column */
703   if(check_col(pinfo->cinfo,COL_PROTOCOL)){
704     col_set_str(pinfo->cinfo,COL_PROTOCOL,"RTcfg");
705   }
706
707   /* Clear out stuff in the info column */
708   if(check_col(pinfo->cinfo,COL_INFO)){
709     col_clear(pinfo->cinfo,COL_INFO);
710   }
711
712   if (tree) {
713     ti = proto_tree_add_item(tree, proto_rtcfg, tvb, offset, -1, FALSE);
714     rtcfg_tree = proto_item_add_subtree(ti, ett_rtcfg);
715   }
716
717   vers_id = tvb_get_guint8(tvb, offset);
718
719   if (check_col(pinfo->cinfo, COL_INFO)) {
720     col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
721            val_to_str(vers_id, rtcfg_msg_vals, "Unknown (0x%04x)"));
722   }
723
724   if( rtcfg_tree )
725   {
726     vers_id_item = proto_tree_add_uint(rtcfg_tree, hf_rtcfg_vers_id, tvb,
727                                        offset, 1, vers_id);
728
729     vers_id_tree=proto_item_add_subtree(vers_id_item, ett_rtcfg);
730     proto_tree_add_item(vers_id_tree, hf_rtcfg_vers, tvb, offset, 1, FALSE);
731     proto_tree_add_item(vers_id_tree, hf_rtcfg_id, tvb, offset, 1, FALSE);
732     offset += 1;
733
734     proto_item_append_text(ti, ", Version %d, %s",
735              (vers_id >> 5),
736              val_to_str(vers_id, rtcfg_msg_vals, "Unknown (0x%04x)"));
737
738     switch( vers_id & 0x1f )
739     {
740        case RTCFG_MSG_S1_CONFIG:
741          address_type = tvb_get_guint8(tvb, offset);
742          proto_tree_add_item( rtcfg_tree, hf_rtcfg_address_type, tvb, offset, 1, FALSE );
743          offset += 1;
744
745          switch( address_type )
746          {
747            case RTCFG_ADDRESS_TYPE_MAC:
748              /* nothing */
749              break;
750
751            case RTCFG_ADDRESS_TYPE_IP:
752              proto_tree_add_item( rtcfg_tree, hf_rtcfg_client_ip_address, tvb, offset, 4, FALSE );
753              offset += 4;
754
755              proto_tree_add_item( rtcfg_tree, hf_rtcfg_server_ip_address, tvb, offset, 4, FALSE );
756              offset += 4;
757
758              break;
759          }
760
761          proto_tree_add_item( rtcfg_tree, hf_rtcfg_burst_rate, tvb, offset, 1, FALSE );
762          offset += 1;
763
764          config_length = tvb_get_ntohs( tvb, offset );
765          proto_tree_add_item( rtcfg_tree, hf_rtcfg_s1_config_length, tvb, offset, 2, FALSE );
766          offset += 2;
767
768          if( config_length > 0 ) {
769            proto_tree_add_item( rtcfg_tree, hf_rtcfg_config_data, tvb, offset, config_length, FALSE );
770            offset += config_length;
771          }
772
773          break;
774
775        case RTCFG_MSG_ANN_NEW:
776          address_type = tvb_get_guint8(tvb, offset);
777          proto_tree_add_item( rtcfg_tree, hf_rtcfg_address_type, tvb, offset, 1, FALSE );
778          offset += 1;
779
780          switch( address_type )
781          {
782            case RTCFG_ADDRESS_TYPE_MAC:
783              /* nothing */
784              break;
785
786            case RTCFG_ADDRESS_TYPE_IP:
787              proto_tree_add_item( rtcfg_tree, hf_rtcfg_client_ip_address, tvb, offset, 4, FALSE );
788              offset += 4;
789              break;
790          }
791
792          flags_item = proto_tree_add_item(rtcfg_tree, hf_rtcfg_client_flags, tvb,
793                                           offset, 1, FALSE);
794
795          flags_tree=proto_item_add_subtree(flags_item, ett_rtcfg);
796          proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_available, tvb, offset, 1, FALSE);
797          proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_ready, tvb, offset, 1, FALSE);
798          proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_res, tvb, offset, 1, FALSE);
799          offset += 1;
800
801          proto_tree_add_item( rtcfg_tree, hf_rtcfg_burst_rate, tvb, offset, 1, FALSE );
802          offset += 1;
803
804          break;
805
806        case RTCFG_MSG_ANN_REPLY:
807          address_type = tvb_get_guint8(tvb, offset);
808          proto_tree_add_item( rtcfg_tree, hf_rtcfg_address_type, tvb, offset, 1, FALSE );
809          offset += 1;
810
811          switch( address_type )
812          {
813            case RTCFG_ADDRESS_TYPE_MAC:
814              /* nothing */
815              break;
816
817            case RTCFG_ADDRESS_TYPE_IP:
818              proto_tree_add_item( rtcfg_tree, hf_rtcfg_client_ip_address, tvb, offset, 4, FALSE );
819              offset += 4;
820              break;
821          }
822
823          flags_item = proto_tree_add_item(rtcfg_tree, hf_rtcfg_client_flags, tvb,
824                                           offset, 1, FALSE);
825
826          flags_tree=proto_item_add_subtree(flags_item, ett_rtcfg);
827          proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_available, tvb, offset, 1, FALSE);
828          proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_ready, tvb, offset, 1, FALSE);
829          proto_tree_add_item(flags_tree, hf_rtcfg_client_flags_res, tvb, offset, 1, FALSE);
830          offset += 1;
831
832          proto_tree_add_item( rtcfg_tree, hf_rtcfg_padding, tvb, offset, 1, FALSE );
833          offset += 1;
834
835          break;
836
837        case RTCFG_MSG_S2_CONFIG:
838          flags_item = proto_tree_add_item(rtcfg_tree, hf_rtcfg_server_flags, tvb,
839                                           offset, 1, FALSE);
840
841          flags_tree=proto_item_add_subtree(flags_item, ett_rtcfg);
842          proto_tree_add_item(flags_tree, hf_rtcfg_server_flags_res0, tvb, offset, 1, FALSE);
843          proto_tree_add_item(flags_tree, hf_rtcfg_server_flags_ready, tvb, offset, 1, FALSE);
844          proto_tree_add_item(flags_tree, hf_rtcfg_server_flags_res2, tvb, offset, 1, FALSE);
845          offset += 1;
846
847          proto_tree_add_item( rtcfg_tree, hf_rtcfg_active_stations, tvb, offset, 4, FALSE );
848          offset += 4;
849
850          proto_tree_add_item( rtcfg_tree, hf_rtcfg_heartbeat_period, tvb, offset, 2, FALSE );
851          offset += 2;
852
853          config_length = tvb_get_ntohl( tvb, offset );
854          proto_tree_add_item( rtcfg_tree, hf_rtcfg_s2_config_length, tvb, offset, 4, FALSE );
855          offset += 4;
856
857          if( config_length > 0 ) {
858            len = tvb_reported_length_remaining(tvb, offset);
859            proto_tree_add_item( rtcfg_tree, hf_rtcfg_config_data, tvb, offset, len, FALSE );
860            offset += len;
861          }
862
863          break;
864
865        case RTCFG_MSG_S2_FRAG:
866          proto_tree_add_item( rtcfg_tree, hf_rtcfg_config_offset, tvb, offset, 4, FALSE );
867          offset += 4;
868
869          len = tvb_reported_length_remaining(tvb, offset);
870          proto_tree_add_item( rtcfg_tree, hf_rtcfg_config_data, tvb, offset, len, FALSE );
871          offset += len;
872          break;
873
874        case RTCFG_MSG_ACK:
875          proto_tree_add_item( rtcfg_tree, hf_rtcfg_ack_length, tvb, offset, 4, FALSE );
876          offset += 4;
877
878          break;
879
880        case RTCFG_MSG_READY:
881          break;
882
883        case RTCFG_MSG_HBEAT:
884          break;
885
886        case RTCFG_MSG_DEAD_STN:
887          address_type = tvb_get_guint8(tvb, offset);
888          proto_tree_add_item( rtcfg_tree, hf_rtcfg_address_type, tvb, offset, 1, FALSE );
889          offset += 1;
890
891          switch( address_type )
892          {
893            case RTCFG_ADDRESS_TYPE_MAC:
894              /* nothing */
895              break;
896
897            case RTCFG_ADDRESS_TYPE_IP:
898              proto_tree_add_item( rtcfg_tree, hf_rtcfg_client_ip_address, tvb, offset, 4, FALSE );
899              offset += 4;
900              break;
901          }
902
903          switch (pinfo->fd->lnk_t) {
904            case WTAP_ENCAP_ETHERNET:
905              haddr = tvb_get_ptr(tvb, offset, 6);
906              proto_tree_add_bytes_format( rtcfg_tree, hf_rtcfg_client_hw_address, tvb, offset, 32,
907                                           haddr, "Client Hardware Address: %02X:%02X:%02X:%02X:%02X:%02X",
908                                           *haddr, *(haddr+1), *(haddr+2),
909                                           *(haddr+3), *(haddr+4), *(haddr+5) );
910              break;
911
912            default:
913              proto_tree_add_item( rtcfg_tree, hf_rtcfg_client_hw_address, tvb, offset, 32, FALSE );
914              break;
915          }
916          offset += 32;
917
918          break;
919
920     }
921   }
922 }
923
924 void
925 proto_register_rtmac(void) {
926   static const true_false_string rtnet_flags_set_truth = {
927     "Set",
928     "Not set"
929   };
930
931   static hf_register_info hf_array_rtmac[] = {
932
933     /* RTmac header */
934     { &hf_rtmac_header_type,
935       { "Type",
936         "rtmac.header.type",
937         FT_STRING, BASE_NONE, NULL, 0x0,
938         "RTmac Type", HFILL }},
939
940     { &hf_rtmac_header_ver,
941       { "Version",
942         "rtmac.header.ver",
943         FT_UINT16, BASE_DEC, NULL, 0x0,
944         "RTmac Version", HFILL }},
945
946     { &hf_rtmac_header_flags,
947       { "Flags",
948         "rtmac.header.flags",
949         FT_UINT8, BASE_HEX, NULL, 0x0,
950         "RTmac Flags", HFILL }},
951
952     { &hf_rtmac_header_flags_tunnel,
953       { "Tunnelling Flag",
954         "rtmac.header.flags.tunnel",
955         FT_BOOLEAN, 8, TFS(&rtnet_flags_set_truth), RTMAC_FLAG_TUNNEL,
956         "RTmac Tunnelling Flag", HFILL }},
957
958     { &hf_rtmac_header_flags_res,
959       { "Reserved Flags",
960         "rtmac.header.flags.res",
961         FT_UINT8, BASE_HEX, NULL, RTMAC_FLAGS_RES,
962         "RTmac Reserved Flags", HFILL }},
963
964     { &hf_rtmac_header_res_v1,
965       { "Reserved",
966         "rtmac.header.res",
967         FT_UINT8, BASE_HEX, NULL, 0x0,
968         "RTmac Reserved", HFILL }},
969   };
970
971   static hf_register_info hf_array_tdma[] = {
972
973     /* TDMA msg */
974     { &hf_tdma_v1_msg,
975       { "Message",
976         "tdma-v1.msg",
977         FT_UINT32, BASE_HEX, VALS(tdma_v1_msg_vals), 0x0,
978         "TDMA-V1 Message", HFILL }},
979
980     /* TDMA request conf */
981
982     { &hf_tdma_v1_msg_request_conf_station,
983       { "Station",
984         "tdma-v1.msg.request_conf.station",
985         FT_UINT8, BASE_DEC, NULL, 0x0,
986         "TDMA Station", HFILL }},
987
988     { &hf_tdma_v1_msg_request_conf_padding,
989       { "Padding",
990         "tdma-v1.msg.request_conf.padding",
991         FT_UINT8, BASE_HEX, NULL, 0x0,
992         "TDMA Padding", HFILL }},
993
994     { &hf_tdma_v1_msg_request_conf_mtu,
995       { "MTU",
996         "tdma-v1.msg.request_conf.mtu",
997         FT_UINT8, BASE_DEC, NULL, 0x0,
998         "TDMA MTU", HFILL }},
999
1000     { &hf_tdma_v1_msg_request_conf_cycle,
1001       { "Cycle",
1002         "tdma-v1.msg.request_conf.cycle",
1003         FT_UINT8, BASE_DEC, NULL, 0x0,
1004         "TDMA Cycle", HFILL }},
1005
1006     /* TDMA ack conf */
1007
1008     { &hf_tdma_v1_msg_ack_conf_station,
1009       { "Station",
1010         "tdma-v1.msg.ack_conf.station",
1011         FT_UINT8, BASE_DEC, NULL, 0x0,
1012         "TDMA Station", HFILL }},
1013
1014     { &hf_tdma_v1_msg_ack_conf_padding,
1015       { "Padding",
1016         "tdma-v1.msg.ack_conf.padding",
1017         FT_UINT8, BASE_HEX, NULL, 0x0,
1018         "TDMA PAdding", HFILL }},
1019
1020     { &hf_tdma_v1_msg_ack_conf_mtu,
1021       { "MTU",
1022         "tdma-v1.msg.ack_conf.mtu",
1023         FT_UINT8, BASE_DEC, NULL, 0x0,
1024         "TDMA MTU", HFILL }},
1025
1026     { &hf_tdma_v1_msg_ack_conf_cycle,
1027       { "Cycle",
1028         "tdma-v1.msg.ack_conf.cycle",
1029         FT_UINT8, BASE_DEC, NULL, 0x0,
1030         "TDMA Cycle", HFILL }},
1031
1032     /* TDMA ack ack conf */
1033
1034     { &hf_tdma_v1_msg_ack_ack_conf_station,
1035       { "Station",
1036         "tdma-v1.msg.ack_ack_conf.station",
1037         FT_UINT8, BASE_DEC, NULL, 0x0,
1038         "TDMA Station", HFILL }},
1039
1040     { &hf_tdma_v1_msg_ack_ack_conf_padding,
1041       { "Padding",
1042         "tdma-v1.msg.ack_ack_conf.padding",
1043         FT_BYTES, BASE_HEX, NULL, 0x0,
1044         "TDMA Padding", HFILL }},
1045
1046     /* TDMA request test */
1047
1048     { &hf_tdma_v1_msg_request_test_counter,
1049       { "Counter",
1050         "tdma-v1.msg.request_test.counter",
1051         FT_UINT32, BASE_DEC, NULL, 0x0,
1052         "TDMA Counter", HFILL }},
1053
1054     { &hf_tdma_v1_msg_request_test_tx,
1055       { "TX",
1056         "tdma-v1.msg.request_test.tx",
1057         FT_UINT64, BASE_DEC, NULL, 0x0,
1058         "TDMA TX", HFILL }},
1059
1060     /* TDMA ack test */
1061
1062     { &hf_tdma_v1_msg_ack_test_counter,
1063       { "Counter",
1064         "tdma-v1.msg.ack_test.counter",
1065         FT_UINT32, BASE_DEC, NULL, 0x0,
1066         "TDMA Counter", HFILL }},
1067
1068     { &hf_tdma_v1_msg_ack_test_tx,
1069       { "TX",
1070         "tdma-v1.msg.ack_test.tx",
1071         FT_UINT64, BASE_DEC, NULL, 0x0,
1072         "TDMA TX", HFILL }},
1073
1074     /* TDMA ack test */
1075
1076     { &hf_tdma_v1_msg_request_change_offset_offset,
1077       { "Offset",
1078         "tdma-v1.msg.request_change_offset.offset",
1079         FT_UINT32, BASE_DEC, NULL, 0x0,
1080         "TDMA Offset", HFILL }},
1081
1082     /* TDMA start of frame */
1083
1084
1085     { &hf_tdma_v1_msg_start_of_frame_timestamp,
1086       { "Timestamp",
1087         "tdma-v1.msg.start_of_frame.timestamp",
1088         FT_UINT64, BASE_DEC, NULL, 0x0,
1089         "TDMA Timestamp", HFILL }},
1090
1091     /* TDMA station list */
1092
1093     { &hf_tdma_v1_msg_station_list_nr_stations,
1094       { "Nr. Stations",
1095         "tdma-v1.msg.station_list.nr_stations",
1096         FT_UINT8, BASE_DEC, NULL, 0x0,
1097         "TDMA Nr. Stations", HFILL }},
1098
1099     { &hf_tdma_v1_msg_station_list_nr,
1100       { "Nr.",
1101         "tdma-v1.msg.station_list.nr",
1102         FT_UINT8, BASE_DEC, NULL, 0x0,
1103         "TDMA Station Number", HFILL }},
1104
1105     { &hf_tdma_v1_msg_station_list_ip,
1106       { "IP",
1107         "tdma-v1.msg.station_list.ip",
1108         FT_IPv4, BASE_DEC, NULL, 0x0,
1109         "TDMA Station IP", HFILL }},
1110
1111     { &hf_tdma_v1_msg_station_list_padding,
1112       { "Padding",
1113         "tdma-v1.msg.station_list.padding",
1114         FT_BYTES, BASE_HEX, NULL, 0x0,
1115         "TDMA Padding", HFILL }},
1116
1117
1118     /* TDMA since version 2 */
1119
1120     { &hf_tdma_ver,
1121       { "Version",
1122         "tdma.ver",
1123         FT_UINT16, BASE_HEX, NULL, 0x0,
1124         "TDMA Version", HFILL }},
1125
1126     { &hf_tdma_id,
1127       { "Message ID",
1128         "tdma.id",
1129         FT_UINT16, BASE_HEX, VALS(tdma_msg_vals), 0x0,
1130         "TDMA Message ID", HFILL }},
1131
1132     /* TDMA sync */
1133
1134     { &hf_tdma_sync_cycle,
1135       { "Cycle Number",
1136         "tdma.sync.cycle",
1137         FT_UINT32, BASE_DEC, NULL, 0x0,
1138         "TDMA Sync Cycle Number", HFILL }},
1139
1140     { &hf_tdma_sync_xmit_stamp,
1141       { "Transmission Time Stamp",
1142         "tdma.sync.xmit_stamp",
1143         FT_UINT64, BASE_DEC, NULL, 0x0,
1144         "TDMA Sync Transmission Time Stamp", HFILL }},
1145
1146     { &hf_tdma_sync_sched_xmit,
1147       { "Scheduled Transmission Time",
1148         "tdma.sync.sched_xmit",
1149         FT_UINT64, BASE_DEC, NULL, 0x0,
1150         "TDMA Sync Scheduled Transmission Time", HFILL }},
1151
1152     /* TDMA request calibration */
1153
1154     { &hf_tdma_req_cal_xmit_stamp,
1155       { "Transmission Time Stamp",
1156         "tdma.req_cal.xmit_stamp",
1157         FT_UINT64, BASE_DEC, NULL, 0x0,
1158         "TDMA Request Calibration Transmission Time Stamp", HFILL }},
1159
1160     { &hf_tdma_req_cal_rpl_cycle,
1161       { "Reply Cycle Number",
1162         "tdma.req_cal.rpl_cycle",
1163         FT_UINT32, BASE_DEC, NULL, 0x0,
1164         "TDMA Request Calibration Reply Cycle Number", HFILL }},
1165
1166     { &hf_tdma_req_cal_rpl_slot,
1167       { "Reply Slot Offset",
1168         "tdma.req_cal.rpl_slot",
1169         FT_UINT64, BASE_DEC, NULL, 0x0,
1170         "TDMA Request Calibration Reply Slot Offset", HFILL }},
1171
1172     /* TDMA reply calibration */
1173
1174     { &hf_tdma_rpl_cal_req_stamp,
1175       { "Request Transmission Time",
1176         "tdma.rpl_cal.req_stamp",
1177         FT_UINT64, BASE_DEC, NULL, 0x0,
1178         "TDMA Reply Calibration Request Transmission Time", HFILL }},
1179
1180     { &hf_tdma_rpl_cal_rcv_stamp,
1181       { "Reception Time Stamp",
1182         "tdma.rpl_cal.rcv_stamp",
1183         FT_UINT64, BASE_DEC, NULL, 0x0,
1184         "TDMA Reply Calibration Reception Time Stamp", HFILL }},
1185
1186     { &hf_tdma_rpl_cal_xmit_stamp,
1187       { "Transmission Time Stamp",
1188         "tdma.rpl_cal.xmit_stamp",
1189         FT_UINT64, BASE_DEC, NULL, 0x0,
1190         "TDMA Reply Calibration Transmission Time Stamp", HFILL }},
1191   };
1192
1193   static gint *ett_array_rtmac[] = {
1194     &ett_rtmac,
1195     &ett_rtmac_flags,
1196   };
1197
1198   static gint *ett_array_tdma[] = {
1199     &ett_tdma,
1200   };
1201
1202   proto_rtmac = proto_register_protocol("Real-Time Media Access Control", "RTmac", "rtmac");
1203   proto_register_field_array(proto_rtmac, hf_array_rtmac, array_length(hf_array_rtmac));
1204   proto_register_subtree_array(ett_array_rtmac, array_length(ett_array_rtmac));
1205
1206   proto_tdma = proto_register_protocol("TDMA RTmac Discipline", "TDMA", "tdma");
1207   proto_register_field_array(proto_rtmac, hf_array_tdma, array_length(hf_array_tdma));
1208   proto_register_subtree_array(ett_array_tdma, array_length(ett_array_tdma));
1209 }
1210
1211
1212 void
1213 proto_register_rtcfg(void) {
1214   static hf_register_info hf[] = {
1215     { &hf_rtcfg_vers_id,
1216       { "Version and ID",
1217         "rtcfg.vers_id",
1218         FT_UINT8, BASE_HEX, NULL, 0x0,
1219         "RTcfg Version and ID", HFILL }},
1220
1221     { &hf_rtcfg_vers,
1222       { "Version",
1223         "rtcfg.vers",
1224         FT_UINT8, BASE_DEC, NULL, 0xe0,
1225         "RTcfg Version", HFILL }},
1226
1227     { &hf_rtcfg_id,
1228       { "ID",
1229         "rtcfg.id",
1230         FT_UINT8, BASE_HEX, VALS(rtcfg_msg_vals), 0x1f,
1231         "RTcfg ID", HFILL }},
1232
1233     { &hf_rtcfg_address_type,
1234       { "Address Type",
1235         "rtcfg.address_type",
1236         FT_UINT8, BASE_DEC, VALS(rtcfg_address_type_vals), 0x00,
1237         "RTcfg Address Type", HFILL }},
1238
1239     { &hf_rtcfg_client_ip_address,
1240       { "Client IP Address",
1241         "rtcfg.client_ip_address",
1242         FT_IPv4, BASE_DEC, NULL, 0x0,
1243         "RTcfg Client IP Address", HFILL }},
1244
1245     { &hf_rtcfg_server_ip_address,
1246       { "Server IP Address",
1247         "rtcfg.server_ip_address",
1248         FT_IPv4, BASE_DEC, NULL, 0x0,
1249         "RTcfg Server IP Address", HFILL }},
1250
1251     { &hf_rtcfg_burst_rate,
1252       { "Stage 2 Burst Rate",
1253         "rtcfg.burst_rate",
1254         FT_UINT8, BASE_DEC, NULL, 0x00,
1255         "RTcfg Stage 2 Burst Rate", HFILL }},
1256
1257     { &hf_rtcfg_s1_config_length,
1258       { "Stage 1 Config Length",
1259         "rtcfg.s1_config_length",
1260         FT_UINT16, BASE_DEC, NULL, 0x00,
1261         "RTcfg Stage 1 Config Length", HFILL }},
1262
1263     { &hf_rtcfg_config_data,
1264       { "Config Data",
1265         "rtcfg.config_data",
1266         FT_BYTES, BASE_DEC, NULL, 0x00,
1267         "RTcfg Config Data", HFILL }},
1268
1269     { &hf_rtcfg_padding,
1270       { "Padding",
1271         "rtcfg.padding",
1272         FT_UINT8, BASE_DEC, NULL, 0x00,
1273         "RTcfg Padding", HFILL }},
1274
1275     { &hf_rtcfg_client_flags,
1276       { "Flags",
1277         "rtcfg.client_flags",
1278         FT_UINT8, BASE_HEX, NULL, 0x00,
1279         "RTcfg Client Flags", HFILL }},
1280
1281     { &hf_rtcfg_client_flags_available,
1282       { "Req. Available",
1283         "rtcfg.client_flags.available",
1284         FT_UINT8, BASE_DEC, NULL, 0x01,
1285         "Request Available", HFILL }},
1286
1287     { &hf_rtcfg_client_flags_ready,
1288       { "Client Ready",
1289         "rtcfg.client_flags.ready",
1290         FT_UINT8, BASE_DEC, NULL, 0x02,
1291         "Client Ready", HFILL }},
1292
1293     { &hf_rtcfg_client_flags_res,
1294       { "Reserved",
1295         "rtcfg.client_flags.res",
1296         FT_UINT8, BASE_HEX, NULL, 0xfc,
1297         "Reserved", HFILL }},
1298
1299     { &hf_rtcfg_server_flags,
1300       { "Flags",
1301         "rtcfg.server_flags",
1302         FT_UINT8, BASE_HEX, NULL, 0x00,
1303         "RTcfg Server Flags", HFILL }},
1304
1305     { &hf_rtcfg_server_flags_res0,
1306       { "Reserved",
1307         "rtcfg.server_flags.res0",
1308         FT_UINT8, BASE_HEX, NULL, 0x01,
1309         "Reserved", HFILL }},
1310
1311     { &hf_rtcfg_server_flags_ready,
1312       { "Server Ready",
1313         "rtcfg.server_flags.ready",
1314         FT_UINT8, BASE_DEC, NULL, 0x02,
1315         "Server Ready", HFILL }},
1316
1317     { &hf_rtcfg_server_flags_res2,
1318       { "Reserved",
1319         "rtcfg.server_flags.res2",
1320         FT_UINT8, BASE_HEX, NULL, 0xfc,
1321         "Reserved", HFILL }},
1322
1323     { &hf_rtcfg_active_stations,
1324       { "Active Stations",
1325         "rtcfg.active_stations",
1326         FT_UINT32, BASE_DEC, NULL, 0x00,
1327         "RTcfg Active Stations", HFILL }},
1328
1329     { &hf_rtcfg_heartbeat_period,
1330       { "Heartbeat Period",
1331         "rtcfg.hearbeat_period",
1332         FT_UINT16, BASE_DEC, NULL, 0x00,
1333         "RTcfg Heartbeat Period", HFILL }},
1334
1335     { &hf_rtcfg_s2_config_length,
1336       { "Stage 2 Config Length",
1337         "rtcfg.s2_config_length",
1338         FT_UINT32, BASE_DEC, NULL, 0x00,
1339         "RTcfg Stage 2 Config Length", HFILL }},
1340
1341     { &hf_rtcfg_config_offset,
1342       { "Config Offset",
1343         "rtcfg.config_offset",
1344         FT_UINT32, BASE_DEC, NULL, 0x00,
1345         "RTcfg Config Offset", HFILL }},
1346
1347     { &hf_rtcfg_ack_length,
1348       { "Ack Length",
1349         "rtcfg.ack_length",
1350         FT_UINT32, BASE_DEC, NULL, 0x00,
1351         "RTcfg Ack Length", HFILL }},
1352
1353     { &hf_rtcfg_client_hw_address,
1354       { "Client Hardware Address",
1355         "rtcfg.client_ip_address",
1356         FT_BYTES, BASE_NONE, NULL, 0x00,
1357         "RTcfg Client Hardware Address", HFILL }}
1358   };
1359
1360   static gint *ett[] = {
1361     &ett_rtcfg,
1362   };
1363
1364   proto_rtcfg = proto_register_protocol("RTcfg","RTcfg","rtcfg");
1365   proto_register_field_array(proto_rtcfg,hf,array_length(hf));
1366   proto_register_subtree_array(ett,array_length(ett));
1367 }
1368
1369 /* The registration hand-off routing */
1370
1371 void
1372 proto_reg_handoff_rtmac(void) {
1373   static int rtmac_initialized = FALSE;
1374   static dissector_handle_t rtmac_handle;
1375
1376   if( !rtmac_initialized ){
1377     rtmac_handle = create_dissector_handle(dissect_rtmac, proto_rtmac);
1378     rtmac_initialized = TRUE;
1379   } else {
1380     dissector_delete("ethertype",ETHERTYPE_RTMAC, rtmac_handle);
1381   }
1382
1383   dissector_add("ethertype", ETHERTYPE_RTMAC, rtmac_handle);
1384
1385
1386   ethertype_table = find_dissector_table("ethertype");
1387 }
1388
1389 void
1390 proto_reg_handoff_rtcfg(void) {
1391   static int rtcfg_initialized = FALSE;
1392   static dissector_handle_t rtcfg_handle;
1393
1394   if( !rtcfg_initialized ){
1395     rtcfg_handle = create_dissector_handle(dissect_rtcfg, proto_rtcfg);
1396     rtcfg_initialized = TRUE;
1397   } else {
1398     dissector_delete("ethertype",ETHERTYPE_RTCFG, rtcfg_handle);
1399   }
1400
1401   dissector_add("ethertype", ETHERTYPE_RTCFG, rtcfg_handle);
1402 }
1403
1404 /* Start the functions we need for the plugin stuff */
1405
1406 #ifndef ENABLE_STATIC
1407
1408 G_MODULE_EXPORT void
1409 plugin_reg_handoff(void){
1410   proto_reg_handoff_rtmac();
1411   proto_reg_handoff_rtcfg();
1412   data_handle = find_dissector("data");
1413 }
1414
1415 G_MODULE_EXPORT void
1416 plugin_init(plugin_address_table_t *pat
1417 #ifndef PLUGINS_NEED_ADDRESS_TABLE
1418 _U_
1419 #endif
1420 ){
1421   /* initialise the table of pointers needed in Win32 DLLs */
1422   plugin_address_table_init(pat);
1423   /* register the new protocol, protocol fields, and subtrees */
1424   if (proto_rtmac == -1) { /* execute protocol initialization only once */
1425     proto_register_rtmac();
1426   }
1427   if (proto_rtcfg == -1) { /* execute protocol initialization only once */
1428     proto_register_rtcfg();
1429   }
1430 }
1431
1432 #endif
1433
1434 /* End the functions we need for plugin stuff */
1435