Don't capitalize "Filter" in "Display Filter" in the "Find" dialog box,
[obnox/wireshark/wip.git] / packet-rtps.c
1 /* packet-rtps.c
2  * Routines for Real-Time Publish-Subscribe Protocol (RTPS) dissection
3  *
4  * Copyright 2003, LUKAS POKORNY <maskis@seznam.cz>
5  *                 PETR SMOLIK   <petr.smolik@wo.cz>
6  *                 ZDENEK SEBEK  <sebek@fel.cvut.cz>
7  * 
8  * Czech Technical University in Prague 
9  *  Faculty of Electrical Engineering <www.fel.cvut.cz>
10  *  Department of Control Engineering <dce.felk.cvut.cz>                
11  *                   
12  * version: 2004/04/15 9:40:45
13  * dedication to Kj :]
14  *
15  * $Id: packet-rtps.c,v 1.9 2004/04/19 22:41:19 guy Exp $
16  *
17  * Ethereal - Network traffic analyzer
18  * By Gerald Combs <gerald@ethereal.com>
19  * Copyright 1998 Gerald Combs
20  *
21  * Copied from packet-udp.c, packet-tftp.c, packet-x25.c
22  *
23  * This program is free software; you can redistribute it and/or
24  * modify it under the terms of the GNU General Public License
25  * as published by the Free Software Foundation; either version 2
26  * of the License, or (at your option) any later version.
27  *
28  * This program is distributed in the hope that it will be useful,
29  * but WITHOUT ANY WARRANTY; without even the implied warranty of
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31  * GNU General Public License for more details.
32  *
33  * You should have received a copy of the GNU General Public License
34  * along with this program; if not, write to the Free Software
35  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36  *
37  * *********************************************************************** */
38
39 #ifdef HAVE_CONFIG_H
40 # include "config.h"
41 #endif
42
43 #ifdef NEED_SNPRINTF_H
44 # include "snprintf.h"
45 #endif
46
47 #include  <stdio.h>
48 #include  <stdlib.h>
49 #include  <string.h>
50 #include  <glib.h>
51 #include  <epan/packet.h>
52 #include  <epan/resolv.h>
53 #include  <epan/conversation.h>
54
55
56 /* *********************************************************************** *
57    RTPS protocol was developed by Real Time Innovation, Inc.
58
59    Protocol specifikation and documenation you can find on these addresses:
60
61    http://www.rti.com/
62
63    http://www.rti.com/products/ndds/literature.html
64
65    http://www.schneider-electric.com.au/Products/Automation/TF_RealTime/
66          /technical%20library/specifications/WireProtocolExternal.pdf
67
68
69  * *********************************************************************** */
70
71
72
73 /* redefine types because of definitions in 'packet-rtps.h' */
74 /*
75 #define  u_int8_t           guint8
76 #define  int8_t             gint8
77
78 #define  u_int16_t          guint16
79 #define  int16_t            gint16
80
81 #define  u_int32_t          guint32
82 #define  int32_t            gint32
83 */
84
85 #include "packet-rtps.h"
86
87 /* number of APP_KIND byte in packet header */
88 #define  APP_KIND_BYTE          15
89
90
91 /*  definitions of flags */
92 #define    FLAG_E      0x01
93 #define    FLAG_F      0x02
94 #define    FLAG_I      0x02
95 #define    FLAG_M      0x02
96 #define    FLAG_P      0x02
97 #define    FLAG_A      0x04
98 #define    FLAG_H      0x08
99
100
101 /*  submessageId's ranges  */
102 #define  SUBMSG_ID_MIN     PAD
103 #define  SUBMSG_ID_MAX     INFO_DST
104
105 /*  Vendor specific submessageId's ranges */
106 #define  VENDOR_SUBMSG_ID_MIN      0x80
107 #define  VENDOR_SUBMSG_ID_MAX      0xff
108
109 /* *********************************************************************** */
110
111
112 /*  initialize the protocol and registered fields  */
113 static int proto_rtps                    = -1;
114 static int hf_rtps_submessage_id         = -1;
115 static int hf_rtps_submessage_flags      = -1;
116 static int hf_rtps_octets_to_next_header = -1;
117 static int hf_rtps_parameter_id          = -1;
118 static int hf_rtps_parameter_length      = -1;
119 static int hf_rtps_issue_data            = -1;
120
121 /*  Initialize the subtree pointers */
122 static gint ett_rtps                     = -1;
123 static gint ett_rtps_submessage          = -1;
124 static gint ett_rtps_bitmap              = -1;
125 static gint ett_rtps_parameter_sequence  = -1;
126 static gint ett_rtps_parameter           = -1;
127
128 /*  Functions declarations */
129 static void dissect_PAD(tvbuff_t *tvb,gint offset,guint8 flags,
130                         int next_submsg_offset,
131                         proto_tree *rtps_submessage_tree);
132 static void dissect_VAR(tvbuff_t *tvb,gint offset,guint8 flags,
133                         gboolean little_endian,int next_submsg_offset,
134                         proto_tree *rtps_submessage_tree);
135 static void dissect_ISSUE(tvbuff_t *tvb,gint offset,guint8 flags,
136                         gboolean little_endian,int next_submsg_offset,
137                         proto_tree *rtps_submessage_tree);
138 static void dissect_ACK(tvbuff_t *tvb,gint offset,guint8 flags,
139                         gboolean little_endian,int next_submsg_offset,
140                         proto_tree *rtps_submessage_tree);
141 static void dissect_HEARTBEAT(tvbuff_t *tvb,gint offset,guint8 flags,
142                         gboolean little_endian,int next_submsg_offset,
143                         proto_tree *rtps_submessage_tree);
144 static void dissect_GAP(tvbuff_t *tvb,gint offset,guint8 flags,
145                         gboolean little_endian,int next_submsg_offset,
146                         proto_tree *rtps_submessage_tree);
147 static void dissect_INFO_TS(tvbuff_t *tvb,gint offset,guint8 flags,
148                         gboolean little_endian,int next_submsg_offset,
149                         proto_tree *rtps_submessage_tree);
150 static void dissect_INFO_SRC(tvbuff_t *tvb,gint offset,guint8 flags,
151                         gboolean little_endian,int next_submsg_offset,
152                         proto_tree *rtps_submessage_tree);
153 static void dissect_INFO_REPLY(tvbuff_t *tvb,gint offset,guint8 flags,
154                         gboolean little_endian,int next_submsg_offset,
155                         proto_tree *rtps_submessage_tree);
156 static void dissect_INFO_DST(tvbuff_t *tvb,gint offset,guint8 flags,
157                         int next_submsg_offset,
158                         proto_tree *rtps_submessage_tree);
159
160 static guint16  get_guint16(tvbuff_t *tvb, gint offset, gboolean little_endian);
161 static guint32  get_guint32(tvbuff_t *tvb, gint offset, gboolean little_endian);
162
163 static char *protocol_version_to_string(gint offset,tvbuff_t *tvb,char *buff);
164 static char *vendor_id_to_string(gint offset, tvbuff_t *tvb, char *buff);
165
166 static char *host_id_to_string(gint offset,tvbuff_t *tvb, char buff[]);
167 static char *app_id_to_string(gint offset,tvbuff_t *tvb,char buff[]);
168 static char *object_id_to_string(gint offset, tvbuff_t *tvb, char buff[]);
169
170 static char *IP_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]);
171 static char *port_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]);
172 static char *get_NtpTime(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[]);
173
174 static void  get_bitmap(tvbuff_t *tvb, gint *p_offset, gboolean little_endian,
175                         gint next_submsg, proto_tree *tree);
176
177 static void  get_parameter_sequence(tvbuff_t *tvb, gint *p_offset,
178                                     gboolean little_endian,
179                                     gint next_submsg_offset, proto_tree *tree);
180
181 static gint  seq_nr_to_string( gint offset, gboolean little_endian, tvbuff_t *tvb,
182                              SequenceNumber *p_seqNumber);
183
184 static const value_string submessage_id_vals[] = {
185   { PAD, "PAD" },
186   { VAR, "VAR" },
187   { ISSUE, "ISSUE" },
188   { ACK, "ACK" },
189   { HEARTBEAT, "HEARTBEAT" },
190   { GAP, "GAP" },
191   { INFO_TS, "INFO_TS" },
192   { INFO_SRC, "INFO_SRC" },
193   { INFO_REPLY, "INFO_REPLY" },
194   { INFO_DST, "INFO_DST" },
195   { APP_QUIT, "APP_QUIT" },
196   { 0, NULL }
197 };
198
199 static const value_string parameter_id_vals[] = {
200   { PID_PAD, "PID_PAD" },
201   { PID_SENTINEL, "PID_SENTINEL" },
202   { PID_EXPIRATION_TIME, "PID_EXPIRATION_TIME" },
203   { PID_PERSISTENCE, "PID_PERSISTENCE" },
204   { PID_MINIMUM_SEPARATION, "PID_MINIMUM_SEPARATION" },
205   { PID_TOPIC, "PID_TOPIC" },
206   { PID_STRENGTH, "PID_STRENGTH" },
207   { PID_TYPE_NAME, "PID_TYPE_NAME" },
208   { PID_TYPE_CHECKSUM, "PID_TYPE_CHECKSUM" },
209   { RTPS_PID_TYPE2_NAME, "RTPS_PID_TYPE2_NAME" },
210   { RTPS_PID_TYPE2_CHECKSUM, "RTPS_PID_TYPE2_CHECKSUM" },
211   { PID_METATRAFFIC_MULTICAST_IPADDRESS, "PID_METATRAFFIC_MULTICAST_IPADDRESS" },
212   { PID_APP_IPADDRESS, "PID_APP_IPADDRESS" },
213   { PID_METATRAFFIC_UNICAST_PORT, "PID_METATRAFFIC_UNICAST_PORT" },
214   { PID_USERDATA_UNICAST_PORT, "PID_USERDATA_UNICAST_PORT" },
215   { PID_IS_RELIABLE, "PID_IS_RELIABLE" },
216   { PID_EXPECTS_ACK, "PID_EXPECTS_ACK" },
217   { PID_USERDATA_MULTICAST_IPADDRESS, "PID_USERDATA_MULTICAST_IPADDRESS" },
218   { PID_MANAGER_KEY, "PID_MANAGER_KEY" },
219   { PID_SEND_QUEUE_SIZE, "PID_SEND_QUEUE_SIZE" },
220   { PID_RELIABILITY_ENABLED, "PID_RELIABILITY_ENABLED" },
221   { PID_PROTOCOL_VERSION, "PID_PROTOCOL_VERSION" },
222   { PID_VENDOR_ID, "PID_VENDOR_ID" },
223   { PID_VARGAPPS_SEQUENCE_NUMBER_LAST, "PID_VARGAPPS_SEQUENCE_NUMBER_LAST" },
224   { PID_RECV_QUEUE_SIZE, "PID_RECV_QUEUE_SIZE" },
225   { PID_RELIABILITY_OFFERED, "PID_RELIABILITY_OFFERED" },
226   { PID_RELIABILITY_REQUESTED, "PID_RELIABILITY_REQUESTED" },
227   { 0, NULL }
228 };
229
230 /* *********************************************************************** */
231
232
233 /* *********************************************************************** *
234  *                                                                         *
235  *                  Code to actually dissect the packets                   *
236  *                                                                         *
237  * *********************************************************************** */
238
239 static gboolean
240 dissect_rtps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
241 {
242   proto_item       *ti;
243   proto_tree       *rtps_tree=NULL;
244   gint             offset = 0;
245   gint             appKind;
246   proto_tree       *rtps_submessage_tree;
247   guint8           submessageId;
248   guint8           flags;
249   gboolean         little_endian;
250   int              next_submsg;
251   int              count_msg_type[11];
252   char             buff[200], buff_tmp[30];/* buffers */
253
254   /*  offset is the byte offset of 'tvb' at which the new tvbuff
255       should start.  The first byte is the 0th byte.             */
256
257   /* --- making disition if protocol is RTPS protocol --- */
258   if (!tvb_bytes_exist(tvb, offset, 4)) return FALSE;
259   if (tvb_get_guint8(tvb,offset++) != 'R') return FALSE;
260   if (tvb_get_guint8(tvb,offset++) != 'T') return FALSE;
261   if (tvb_get_guint8(tvb,offset++) != 'P') return FALSE;
262   if (tvb_get_guint8(tvb,offset++) != 'S') return FALSE;
263
264   /* --- Make entries in Protocol column ---*/
265   if (check_col(pinfo->cinfo, COL_PROTOCOL))
266    col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTPS");
267
268   if (check_col(pinfo->cinfo, COL_INFO))
269    col_clear(pinfo->cinfo, COL_INFO);
270
271   memset(count_msg_type, 0, sizeof(count_msg_type));
272
273   if (tree) {
274
275    /* create display subtree for the protocol */
276    ti = proto_tree_add_item(tree, proto_rtps, tvb, 0, -1, FALSE);
277    rtps_tree = proto_item_add_subtree(ti, ett_rtps);
278
279    /*  Protocol Version */
280    proto_tree_add_text(rtps_tree, tvb, offset, 2,
281                        "Protocol  RTPS, version %s",
282                        protocol_version_to_string(offset, tvb, buff));
283    offset +=2;
284
285    /*  Vendor Id  */
286    proto_tree_add_text(rtps_tree, tvb, offset, 2,
287                        "VendorId: %s",
288                        vendor_id_to_string(offset, tvb, buff));
289    offset +=2;
290
291    /*  Host Id  */
292    proto_tree_add_text(rtps_tree, tvb, offset, 4,
293                        "HostId:   %s",
294                        host_id_to_string(offset,tvb,buff));
295    offset +=4;
296
297    /*  App Id  */
298    proto_tree_add_text(rtps_tree, tvb, offset, 4,
299                        "App ID:   %s",
300                        app_id_to_string(offset, tvb, buff));
301
302   }
303
304   /*  offset behind RTPS's Header */
305   offset=16;
306
307   while (tvb_reported_length_remaining(tvb, offset) > 0) {
308     submessageId = tvb_get_guint8(tvb, offset);
309     if (submessageId & 0x80) {
310       ti = proto_tree_add_text(tree, tvb, offset, -1, "Submessage: %s",
311                                val_to_str(submessageId, submessage_id_vals,
312                                           "Vendor-specific (0x%02X)"));
313     } else {
314       ti = proto_tree_add_text(tree, tvb, offset, -1, "Submessage: %s",
315                                val_to_str(submessageId, submessage_id_vals,
316                                           "Unknown (0x%02X)"));
317     }
318     rtps_submessage_tree = proto_item_add_subtree(ti, ett_rtps_submessage);
319     if (submessageId & 0x80) {
320       proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_submessage_id,
321                                  tvb, offset, 1, submessageId,
322                                  "Submessage Id: Vendor-specific (0x%02x)",
323                                  submessageId);
324     } else {
325       proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_id,
326                           tvb, offset, 1, submessageId);
327     }
328
329     flags = tvb_get_guint8(tvb, offset + 1);
330     /*  E flag |XXXX|HAPE| => masks with 000000001b = 1  */
331     if ((flags & FLAG_E) != 0)      little_endian = TRUE;
332       else                          little_endian = FALSE;
333
334     next_submsg  = get_guint16(tvb, offset + 2, little_endian);
335     proto_item_set_len(ti, next_submsg);
336
337     switch (submessageId)
338     {
339       case PAD:
340         if (tree)
341           dissect_PAD(tvb, offset + 1, flags, next_submsg,
342                       rtps_submessage_tree);
343         count_msg_type[0]++;
344         break;
345       case VAR:
346         if (tree)
347           dissect_VAR(tvb, offset + 1, flags, little_endian, next_submsg,
348                       rtps_submessage_tree);
349         count_msg_type[1]++;
350         break;
351       case ISSUE:
352         if (tree)
353           dissect_ISSUE(tvb, offset + 1, flags, little_endian, next_submsg,
354                         rtps_submessage_tree);
355         count_msg_type[2]++;
356         break;
357       case ACK:
358         if (tree)
359           dissect_ACK(tvb, offset + 1, flags, little_endian, next_submsg,
360                       rtps_submessage_tree);
361         count_msg_type[3]++;
362         break;
363       case HEARTBEAT:
364         if (tree)
365           dissect_HEARTBEAT(tvb, offset + 1, flags, little_endian, next_submsg,
366                             rtps_submessage_tree);
367         count_msg_type[4]++;
368         break;
369       case GAP:
370         if (tree)
371           dissect_GAP(tvb, offset + 1, flags, little_endian, next_submsg,
372                       rtps_submessage_tree);
373         count_msg_type[5]++;
374         break;
375       case INFO_TS:
376         if (tree)
377           dissect_INFO_TS(tvb, offset + 1, flags, little_endian, next_submsg,
378                           rtps_submessage_tree);
379         count_msg_type[6]++;
380         break;
381       case INFO_SRC:
382         if (tree)
383           dissect_INFO_SRC(tvb, offset + 1, flags, little_endian, next_submsg,
384                            rtps_submessage_tree);
385         count_msg_type[7]++;
386         break;
387       case INFO_REPLY:
388         if (tree)
389           dissect_INFO_REPLY(tvb, offset + 1, flags, little_endian, next_submsg,
390                              rtps_submessage_tree);
391         count_msg_type[8]++;
392         break;
393       case INFO_DST:
394         if (tree)
395           dissect_INFO_DST(tvb, offset + 1, flags, next_submsg,
396                            rtps_submessage_tree);
397         count_msg_type[9]++;
398         break;
399       default:
400         if (tree) {
401           proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
402                               tvb, offset + 1, 1, flags);
403           proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
404                               tvb, offset + 2, 2, next_submsg);
405         }
406         break;
407      }
408
409      /* next submessage's offset */
410      offset += next_submsg+4;
411
412   }
413
414   /* --- and Info column on summary display ---*/
415
416   if (check_col(pinfo->cinfo, COL_INFO))
417   {
418     appKind = tvb_get_guint8(tvb, APP_KIND_BYTE);
419
420     if (appKind == MANAGEDAPPLICATION ) {sprintf(buff,"App: ");}
421     if (appKind == MANAGER)             {sprintf(buff,"Man: ");}
422     if (appKind == AID_UNKNOWN)         {sprintf(buff,"Unknown:");}
423
424     if (appKind != MANAGEDAPPLICATION  && appKind != MANAGER &&
425         appKind != AID_UNKNOWN)         {sprintf(buff,"ERROR in APP type");}
426
427    /* -- counts of submessages - for Information Frame */
428    if (count_msg_type[0]>0) {
429        sprintf(buff_tmp,"PAD(%d) ",count_msg_type[0]);
430        strcat(buff,buff_tmp);
431    }
432
433    if (count_msg_type[1]>0) {
434        sprintf(buff_tmp,"VAR(%d) ",count_msg_type[1]);
435        strcat(buff,buff_tmp);
436    }
437
438    if (count_msg_type[2]>0) {
439        sprintf(buff_tmp,"ISSUE(%d) ",count_msg_type[2]);
440        strcat(buff,buff_tmp);
441    }
442
443    if (count_msg_type[3]>0) {
444        sprintf(buff_tmp,"ACK(%d) ",count_msg_type[3]);
445        strcat(buff,buff_tmp);
446    }
447
448    if (count_msg_type[4]>0) {
449        sprintf(buff_tmp,"HEARTBEAT(%d) ",count_msg_type[4]);
450        strcat(buff,buff_tmp);
451    }
452
453    if (count_msg_type[5]>0) {
454        sprintf(buff_tmp,"GAP(%d) ",count_msg_type[5]);
455        strcat(buff,buff_tmp);
456    }
457
458    if (count_msg_type[6]>0) {
459        sprintf(buff_tmp,"INFO_TS(%d) ",count_msg_type[6]);
460        strcat(buff,buff_tmp);
461    }
462
463    if (count_msg_type[7]>0) {
464        sprintf(buff_tmp, "INFO_SRC(%d) ",count_msg_type[7]);
465        strcat(buff,buff_tmp);
466    }
467
468    if (count_msg_type[8]>0) {
469        sprintf(buff_tmp,"INFO_REPLY(%d) ",count_msg_type[8]);
470        strcat(buff,buff_tmp);
471    }
472
473    if (count_msg_type[9]>0) {
474        sprintf(buff_tmp,"INFO_DST(%d) ",count_msg_type[9]);
475        strcat(buff,buff_tmp);
476    }
477
478    if (count_msg_type[10]>0) {
479        sprintf(buff_tmp,"vendor specific(%d) ",count_msg_type[10]);
480        strcat(buff,buff_tmp);
481    }
482
483    col_add_fstr(pinfo->cinfo, COL_INFO, buff);
484
485   }
486
487
488   return TRUE;
489
490 }  /* end dissect_rtps(...) */
491
492 /* *********************************************************************** */
493
494
495 /* *********************************************************************** *
496  *                                                                         *
497  *                        get 16 bit from the stream                       *
498  *                                                                         *
499  * *********************************************************************** */
500
501 static guint16  get_guint16(tvbuff_t *tvb, gint offset, gboolean little_endian)
502 {
503   guint16   value;
504
505   if (little_endian)
506     value = tvb_get_letohs(tvb, offset);
507   else
508     value = tvb_get_ntohs(tvb, offset);
509
510   return(value);
511 }
512
513 /* *********************************************************************** */
514
515
516 /* *********************************************************************** *
517  *                                                                         *
518  *                          get 32 bit from the stream                     *
519  *                                                                         *
520  * *********************************************************************** */
521
522 static guint32  get_guint32(tvbuff_t *tvb, gint offset, gboolean little_endian)
523 {
524   guint32     value;
525
526   if (little_endian)
527     value = tvb_get_letohl(tvb, offset);
528   else
529     value = tvb_get_ntohl(tvb, offset);
530
531   return(value);
532 }
533
534 /* *********************************************************************** */
535
536
537 /* *********************************************************************** *
538  *                                                                         *
539  *                               get Protocol version                      *
540  *                                                                         *
541  * *********************************************************************** */
542
543 static char *
544 protocol_version_to_string(gint offset,tvbuff_t *tvb,char *buff)
545 {
546   guint8            major, minor;
547
548   /* protocol verzion = major.minor */
549    major = tvb_get_guint8(tvb, offset);
550    minor = tvb_get_guint8(tvb, (offset+1));
551
552    sprintf(buff,"%d.%d", major, minor);
553    return(buff);
554
555 }
556
557 /* *********************************************************************** */
558
559
560 /* *********************************************************************** *
561  *                                                                         *
562  *                               get Vendor Id                             *
563  *                                                                         *
564  * *********************************************************************** */
565
566 static char *
567 vendor_id_to_string(gint offset, tvbuff_t *tvb, char *buff)
568 {
569   guint8              major, minor;
570   VendorId            vendorId_rti;
571
572   VENDOR_ID_RTI(vendorId_rti);
573
574   major = tvb_get_guint8(tvb, offset);
575   minor = tvb_get_guint8(tvb, (offset+1));
576
577   if (major == vendorId_rti.major &&
578       minor == vendorId_rti.minor)
579   { sprintf(buff,"Real-Time Innovations,Inc.,CA,USA");
580     return(buff); }
581
582   sprintf(buff,"Vendor unknown");
583   return(buff);
584 }
585
586 /* *********************************************************************** */
587
588
589 /* *********************************************************************** *
590  *                                                                         *
591  *                               get IP Address                            *
592  *                                                                         *
593  * *********************************************************************** */
594
595 static char *
596 IP_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[])
597 {
598   IPAddress         ip;
599   guint8  a = 0, b = 0, c = 0, d = 0; /* IP Adresss = a.b.c.d */
600
601   ip = get_guint32(tvb, offset, little_endian);
602      /* get_guint32() - reads + endian conversion */
603   a = (ip >> 24);
604   b = (ip >> 16) & 0xff;
605   c = (ip >>  8) & 0xff;
606   d =  ip & 0xff;
607
608   sprintf(buff,"%d.%d.%d.%d", a, b, c, d);
609   return(buff);
610 }
611
612 /* *********************************************************************** */
613
614
615 /* *********************************************************************** *
616  *                                                                         *
617  *                               get Port                                  *
618  *                                                                         *
619  * *********************************************************************** */
620
621 static char *
622 port_to_string(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[])
623 {
624   Port port = get_guint32(tvb, offset, little_endian);
625             /* get_guint32() - reads + endian conversion */
626
627   if (port == PORT_INVALID)
628     sprintf(buff,"PORT_INVALID");
629   else
630     sprintf(buff,"0x%X",port);
631
632   return(buff);
633 }
634
635 /* *********************************************************************** */
636
637
638 /* *********************************************************************** *
639  *                                                                         *
640  *                                get NTP Time                             *
641  *                                                                         *
642  * *********************************************************************** */
643
644 static char *
645 get_NtpTime(gint offset,tvbuff_t *tvb,gboolean little_endian,char buff[])
646 {
647   NtpTime         ntpTime;
648   float           time;
649
650   /* get_guint32() - reads + endian conversion */
651   ntpTime.seconds  =  get_guint32(tvb, offset, little_endian);
652   ntpTime.fraction =  get_guint32(tvb, (offset + 4), little_endian);
653   time = (float) ntpTime.seconds + (ntpTime.fraction / 2^(32));
654
655   sprintf(buff,"%f", time);
656   return(buff);
657 }
658
659 /* *********************************************************************** */
660
661
662 /* *********************************************************************** *
663  *                                                                         *
664  *                                get Host Id                              *
665  *                                                                         *
666  * *********************************************************************** */
667
668 static char *
669 host_id_to_string(gint offset,tvbuff_t *tvb, char buff[])
670 {
671   guint32       hostId = tvb_get_ntohl(tvb, offset);
672   /* get_ntohl() automaticaly convert data to BIG ENDIAN */
673
674   sprintf(buff,"0x%X", hostId);
675   return(buff);
676 }
677
678 /* *********************************************************************** */
679
680
681 /* *********************************************************************** *
682  *                                                                         *
683  *                                get AppID                                *
684  *                                                                         *
685  * *********************************************************************** */
686
687 static char *
688 app_id_to_string(gint offset,tvbuff_t *tvb,char buff[])
689 {
690   guint32        appId = tvb_get_ntohl(tvb, offset);
691   /* get_ntohl() automaticaly convert data to BIG ENDIAN */
692
693   /* Instance Id */
694   guint32        instanceId = (appId >> 8);
695   /* applicatin Kind */
696   guint8         appKind    = (appId & 0xff);
697
698   if (appKind == MANAGEDAPPLICATION)
699   {
700     sprintf(buff,"Managed App, InstanceId: 0x%X",instanceId);
701     return(buff);
702   }
703
704   if (appKind == MANAGER)
705   {
706     sprintf(buff,"Manager, InstanceId: 0x%X",instanceId);
707     return(buff);
708   }
709
710   sprintf(buff,"Unknown");
711   return(buff);
712
713 }
714
715 /* *********************************************************************** */
716
717
718 /* *********************************************************************** *
719  *                                                                         *
720  *                         get Object_Id (32 bit)                          *
721  *                                                                         *
722  * *********************************************************************** */
723
724 static char *
725 object_id_to_string(gint offset, tvbuff_t *tvb, char buff[])
726 {
727   guint32        objectId = tvb_get_ntohl(tvb, offset);
728   /* get_ntohl() automaticaly convert data to BIG ENDIAN */
729
730   if (objectId == OID_UNKNOWN)      { sprintf(buff,"Unknown ObjectId");
731                                       return(buff);}
732   if (objectId == OID_APP)          { sprintf(buff,"applicationSelf");
733                                       return(buff);}
734   if (objectId == OID_WRITE_APPSELF){ sprintf(buff,"writerApplicationSelf");
735                                       return(buff);}
736   if (objectId == OID_WRITE_APP)    { sprintf(buff,"writerApplications");
737                                       return(buff);}
738   if (objectId == OID_READ_APP)     { sprintf(buff,"readerApplications");
739                                       return(buff);}
740   if (objectId == OID_WRITE_MGR)    { sprintf(buff,"writerManagers");
741                                       return(buff);}
742   if (objectId == OID_READ_MGR)     { sprintf(buff,"readerManagers ");
743                                       return(buff);}
744   if (objectId == OID_WRITE_PUBL)   { sprintf(buff,"writerPublications");
745                                       return(buff);}
746   if (objectId == OID_READ_PUBL)    { sprintf(buff,"readerPublications");
747                                       return(buff);}
748   if (objectId == OID_WRITE_SUBS)   { sprintf(buff,"writerSubscriptions");
749                                       return(buff);}
750   if (objectId == OID_READ_SUBS)    { sprintf(buff,"readerSubscriptions");
751                                       return(buff);}
752
753   /* nothing from the possibilites above */
754   sprintf(buff,"instanceId: 0x%X, objKind: 0x%X",
755                (objectId >> 8),(objectId & 0xff));
756   return(buff);
757
758 /* for the future
759 //Kind
760 #define OID_APPLICATION      0x01
761 #define OID_CSTWRITER        0x02
762 #define OID_PUBLICATION      0x03
763 #define OID_SUBSCRIPTION     0x04
764 #define OID_CSTREADER        0x07
765 //
766 #define OID_USEROBJ          0x00
767 #define OID_RESUSEROBJ       0x40
768 #define OID_METAOBJ          0x80
769 #define OID_RESMETAOBJ       0xC0
770 */
771 }
772
773 /* *********************************************************************** */
774
775
776 /* *********************************************************************** *
777  *                                                                         *
778  *                      get Sequence Number (64 bit)                       *
779  *                                                                         *
780  * *********************************************************************** */
781
782 static gint
783 seq_nr_to_string(gint offset, gboolean little_endian, tvbuff_t *tvb,
784                  SequenceNumber *p_seqNumber)
785 {
786    p_seqNumber->high = get_guint32(tvb, offset, little_endian);
787    p_seqNumber->low  = get_guint32(tvb, offset + 4, little_endian);
788
789    return(1);
790 }
791
792 /* *********************************************************************** */
793
794
795 /* *********************************************************************** *
796  *                                                                         *
797  *                                get_Bitmap                               *
798  *                                                                         *
799  * *********************************************************************** */
800
801 static void
802 get_bitmap(tvbuff_t *tvb, gint *p_offset, gboolean little_endian,
803            gint next_submsg, proto_tree *tree)
804 {
805   proto_item             *ti;
806   proto_tree             *rtps_bitmap_tree;
807   gint                    i = 0;
808   gint                    offset = *p_offset;
809   SequenceNumber          sequenceNumber;
810   guint32                 num_bits;
811   guint                   num_longs;
812
813   /* making subtree for the bitmap */
814   ti = proto_tree_add_text(tree,tvb,offset,(next_submsg-offset),"Bitmap");
815   rtps_bitmap_tree = proto_item_add_subtree(ti, ett_rtps_bitmap);
816
817   /* SekvenceNumber bitmapBase */
818   seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
819   proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 8,
820                       "bitmapBase:  0x%X%X",
821                       sequenceNumber.high, sequenceNumber.low);
822   offset +=8;
823
824   num_bits = get_guint32(tvb, offset, little_endian);
825   proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 4,
826                       "numBits:     %u",
827                       num_bits);
828   offset += 4;
829
830   if (num_bits+31 < num_bits)
831     num_longs = UINT_MAX; /* overflow */
832   else
833     num_longs = (num_bits+31)/32;
834   while (num_longs != 0)
835   {
836     if (next_submsg-offset < 4)
837     {
838       proto_tree_add_text(rtps_bitmap_tree, tvb, offset, next_submsg-offset,
839                           "bitmap[%d]:   < 4 bytes remain in message", i);
840       offset = next_submsg;
841       break;
842     }
843     proto_tree_add_text(rtps_bitmap_tree, tvb, offset, 4,
844                         "bitmap[%d]:   0x%08X",
845                         i, get_guint32(tvb, offset, little_endian));
846     offset +=4;
847     ++i;
848     --num_longs;
849   }  /* end while */
850
851   *p_offset = offset;
852 }
853
854 /* *********************************************************************** */
855
856
857 /* *********************************************************************** *
858  *                                                                         *
859  *                          dissect submessage: PAD                        *
860  *                                                                         *
861  *           (this submessage has no meaning and it is always valid)       *
862  * *********************************************************************** */
863
864 static void
865 dissect_PAD(tvbuff_t *tvb, gint offset, guint8 flags,
866             int next_submsg_offset, proto_tree *rtps_submessage_tree)
867 {
868   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
869                       tvb, offset, 1, flags);
870   offset += 1;
871
872   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
873                       tvb, offset, 2, next_submsg_offset);
874   offset +=2;
875   next_submsg_offset += offset;
876 }
877
878 /* *********************************************************************** */
879
880
881 /* *********************************************************************** *
882  *                                                                         *
883  *                          dissect submessage: VAR                        *
884  *                                                                         *
885  * *********************************************************************** */
886
887 static void
888 dissect_VAR(tvbuff_t *tvb, gint offset, guint8 flags, gboolean little_endian,
889             int next_submsg_offset, proto_tree *rtps_submessage_tree)
890 {
891   int                min_len;
892   char               buff[200];
893   SequenceNumber     writerSeqNumber;
894
895   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
896                       tvb, offset, 1, flags);
897   offset +=1;
898
899   min_len = 20;
900   if ((flags & FLAG_H) != 0)
901     min_len += 8;
902   if ((flags & FLAG_P) != 0)
903     min_len += 4;
904   if (next_submsg_offset < min_len)
905   {
906     proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
907                                tvb, offset, 2, next_submsg_offset,
908                                "Octets to next header: %u (bogus, must be >= %u)",
909                                next_submsg_offset, min_len);
910     return;
911   }
912   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
913                       tvb, offset, 2, next_submsg_offset);
914   offset +=2;
915   next_submsg_offset += offset;
916
917   /*  readerObjectId*/
918   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
919                       "Reader Object ID:   %s ",
920                        object_id_to_string(offset, tvb, buff));
921   offset +=4;
922
923   /*  writerObjectId*/
924   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
925                       "Writer Object ID:   %s ",
926                       object_id_to_string(offset, tvb, buff));
927   offset+=4;
928
929   /*  H flag |XXXX|HAPE| => masks with 00001000b = 8 */
930   if ((flags & FLAG_H) != 0)
931   {
932     /*  HostId */
933     proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
934                         "Host ID:            %s",
935                         host_id_to_string(offset,tvb,buff));
936     offset+=4;
937
938     /*  App Id  */
939     proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
940                         "App ID:             %s",
941                         app_id_to_string(offset, tvb, buff));
942     offset +=4;
943   }
944
945   /* Object Id */
946   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
947                       "Object ID:          %s ",
948                       object_id_to_string(offset, tvb, buff));
949   offset +=4;
950
951   /*  WriterSequence Number */
952   seq_nr_to_string(offset, little_endian, tvb, &writerSeqNumber);
953   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
954                       "WriterSeqNumber:    0x%X%X",
955                       writerSeqNumber.high, writerSeqNumber.low);
956   offset +=8;
957
958   /*  P flag |XXXX|HAPE| => masks with 00000010b = 2 */
959   if ((flags & FLAG_P) != 0)
960   {
961     get_parameter_sequence(tvb, &offset, little_endian, next_submsg_offset,
962                            rtps_submessage_tree);
963   }
964 }
965
966 /* *********************************************************************** */
967
968 /* *********************************************************************** *
969  *                                                                         *
970  *                            get_ParameterSequence                        *
971  *                                                                         *
972  * *********************************************************************** */
973
974
975 static void
976 get_parameter_sequence(tvbuff_t *tvb, gint *p_offset, gboolean little_endian,
977                        gint next_submsg_offset, proto_tree *tree)
978 {
979   proto_item             *ti;
980   proto_tree             *rtps_parameter_sequence_tree;
981   proto_tree             *rtps_parameter_tree;
982   gint                    offset = *p_offset;
983   guint16                 parameter, param_length;
984   gint                    str_length;
985   SequenceNumber          seqNumber;
986   char                    buff_tmp[MAX_PATHNAME];
987   int                     i;
988   char                    sep;
989
990   ti = proto_tree_add_text(tree, tvb, offset, (next_submsg_offset - offset),
991                       "Parameters:");
992   rtps_parameter_sequence_tree = proto_item_add_subtree(ti,
993                                                         ett_rtps_parameter_sequence);
994   for (;;)
995   {
996     if (next_submsg_offset-offset < 2)
997     {
998       proto_tree_add_text(rtps_parameter_sequence_tree, tvb, offset,
999                           next_submsg_offset-offset,
1000                           "Parameter: < 2 bytes remain in message");
1001       offset = next_submsg_offset;
1002       break;
1003     }
1004     parameter    = get_guint16(tvb, offset, little_endian);
1005     ti = proto_tree_add_text(rtps_parameter_sequence_tree, tvb, offset, 2,
1006                              "%s",
1007                              val_to_str(parameter, parameter_id_vals,
1008                                         "Unknown parameter (0x%04X)"));
1009     rtps_parameter_tree = proto_item_add_subtree(ti, ett_rtps_parameter);
1010     proto_tree_add_uint(rtps_parameter_tree, hf_rtps_parameter_id,
1011                         tvb, offset, 2, parameter);
1012     offset +=2;
1013     if (next_submsg_offset-offset < 2)
1014     {
1015       proto_tree_add_text(rtps_parameter_tree, tvb, offset,
1016                           next_submsg_offset-offset,
1017                           "Parameter length: < 2 bytes remain in message");
1018       offset = next_submsg_offset;
1019       proto_item_set_end(ti, tvb, offset);
1020       break;
1021     }
1022     param_length = get_guint16(tvb, offset, little_endian);
1023     proto_tree_add_uint(rtps_parameter_tree, hf_rtps_parameter_length,
1024                         tvb, offset, 2, param_length);
1025     offset +=2;
1026
1027     if (parameter == PID_SENTINEL) {
1028       proto_item_set_end(ti, tvb, offset);
1029       break;
1030     }
1031
1032     if (next_submsg_offset-offset < param_length)
1033     {
1034       proto_tree_add_text(rtps_parameter_tree, tvb, offset,
1035                           next_submsg_offset-offset,
1036                           "Parameter value: < %u bytes remain in message",
1037                           param_length);
1038       offset = next_submsg_offset;
1039       proto_item_set_end(ti, tvb, offset);
1040       break;
1041     }
1042     proto_item_set_end(ti, tvb, offset + param_length);
1043
1044     switch (parameter)
1045     {
1046       case PID_PAD:
1047         proto_item_append_text(ti, ": -");
1048         proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1049                             "Padding");
1050         break;
1051
1052       case PID_EXPIRATION_TIME:
1053         if (param_length < 8)
1054         {
1055           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1056                               "Bad parameter: length < 8");
1057         }
1058         else
1059         {
1060           char *ntp_time_str;
1061
1062           ntp_time_str = get_NtpTime(offset, tvb, little_endian,buff_tmp);
1063           proto_item_append_text(ti, ": %s", ntp_time_str);
1064           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1065                               "Expiration time: %s", ntp_time_str);
1066         }
1067         break;
1068
1069       case PID_PERSISTENCE:
1070         if (param_length < 8)
1071         {
1072           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1073                               "Bad parameter: length < 8");
1074         }
1075         else
1076         {
1077           char *ntp_time_str;
1078
1079           ntp_time_str = get_NtpTime(offset, tvb, little_endian,buff_tmp);
1080           proto_item_append_text(ti, ": %s", ntp_time_str);
1081           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1082                               "Persistence: %s", ntp_time_str);
1083         }
1084         break;
1085
1086       case PID_MINIMUM_SEPARATION:
1087         if (param_length < 8)
1088         {
1089           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1090                               "Bad parameter: length < 8");
1091         }
1092         else
1093         {
1094           char *ntp_time_str;
1095
1096           ntp_time_str = get_NtpTime(offset, tvb, little_endian,buff_tmp);
1097           proto_item_append_text(ti, ": %s", ntp_time_str);
1098           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1099                               "Minimum separation: %s", ntp_time_str);
1100         }
1101         break;
1102
1103       case PID_TOPIC: /* --- ?? funguje spravne ?? */
1104         str_length = tvb_strnlen(tvb, offset, param_length);
1105         if (str_length == -1)
1106         {
1107           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1108                               "Bad parameter: Terminating zero missing");
1109         }
1110         else
1111         {
1112           char *str;
1113
1114           str = tvb_format_text(tvb, offset, str_length);
1115           proto_item_append_text(ti, ": %s", str);
1116           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1117                               "Topic: %s", str);
1118         }
1119         break;   
1120
1121       case PID_STRENGTH:
1122         if (param_length < 4)
1123         {
1124           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1125                               "Bad parameter: length < 4");
1126         }
1127         else
1128         {
1129           guint32 strength;
1130
1131           strength = get_guint32(tvb, offset, little_endian);
1132           proto_item_append_text(ti, ": 0x%X", strength);
1133           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1134                               "Strength: 0x%X", strength);
1135         }
1136         break;
1137
1138       case PID_TYPE_NAME: /* --- ?? funguje spravne ?? */
1139         str_length = tvb_strnlen(tvb, offset, param_length);
1140         if (str_length == -1)
1141         {
1142           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1143                               "Bad parameter: Terminating zero missing");
1144         }
1145         else
1146         {
1147           char *str;
1148
1149           str = tvb_format_text(tvb, offset, str_length);
1150           proto_item_append_text(ti, ": %s", str);
1151           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1152                               "Type name: %s", str);
1153         }
1154         break;   
1155
1156       case PID_TYPE_CHECKSUM:
1157         /* nacitam jako UNSIGNED - nemuze to byt i zaporne cislo?? */
1158         if (param_length < 4)
1159         {
1160           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1161                               "Bad parameter: length < 4");
1162         }
1163         else
1164         {
1165           guint32 checksum;
1166
1167           checksum = get_guint32(tvb, offset, little_endian);
1168           proto_item_append_text(ti, ": 0x%X", checksum);
1169           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1170                               "Checksum: 0x%X", checksum);
1171         }
1172         break;
1173
1174       case RTPS_PID_TYPE2_NAME:
1175         proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1176                             "Parameter data");
1177         break;
1178                           
1179       case RTPS_PID_TYPE2_CHECKSUM:
1180         proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1181                             "Parameter data");
1182         break;
1183
1184       case PID_METATRAFFIC_MULTICAST_IPADDRESS:
1185         i = 0;
1186         sep = ':';
1187         while (param_length >= 4)
1188         {
1189           char *ip_string;
1190
1191           ip_string = IP_to_string(offset, tvb, little_endian,buff_tmp);
1192           proto_item_append_text(ti, "%c %s", sep, ip_string);
1193           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1194                               "Address[%d]: %s", i, ip_string);
1195           ++i;
1196           offset +=4;
1197           sep = ',';
1198         }
1199         offset += param_length;
1200         break;
1201
1202       case PID_APP_IPADDRESS:
1203         i = 0;
1204         sep = ':';
1205         while (param_length >= 4)
1206         {
1207           char *ip_string;
1208
1209           ip_string = IP_to_string(offset, tvb, little_endian,buff_tmp);
1210           proto_item_append_text(ti, "%c %s", sep, ip_string);
1211           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1212                               "Address[%d]: %s", i, ip_string);
1213           ++i;
1214           offset +=4;
1215           sep = ',';
1216         }
1217         offset += param_length;
1218         break;
1219
1220       case PID_METATRAFFIC_UNICAST_PORT:
1221         if (param_length < 4)
1222         {
1223           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1224                               "Bad parameter: length < 4");
1225         }
1226         else
1227         {
1228           char *port_str;
1229
1230           port_str = port_to_string(offset, tvb, little_endian,buff_tmp);
1231           proto_item_append_text(ti, ": %s", port_str);
1232           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1233                               "Port: %s", port_str);
1234         }
1235         break;
1236
1237       case PID_USERDATA_UNICAST_PORT:
1238         if (param_length < 4)
1239         {
1240           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1241                               "Bad parameter: length < 4");
1242         }
1243         else
1244         {
1245           char *port_str;
1246
1247           port_str = port_to_string(offset, tvb, little_endian,buff_tmp);
1248           proto_item_append_text(ti, ": %s", port_str);
1249           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1250                               "Port: %s", port_str);
1251         }
1252         break;
1253
1254       case PID_EXPECTS_ACK:
1255         if (param_length < 1)
1256         {
1257           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1258                               "Bad parameter: length < 1");
1259         }
1260         else
1261         {
1262           if (tvb_get_guint8(tvb, offset) == 0)
1263           {
1264             proto_item_append_text(ti, ": No");
1265             proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1266                                 "ACK expected: No");
1267           }
1268           else
1269           {
1270             proto_item_append_text(ti, ": Yes");
1271             proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1272                                 "ACK expected: Yes");
1273           }
1274         }
1275         break;
1276
1277       case PID_USERDATA_MULTICAST_IPADDRESS:
1278         i = 0;
1279         sep = ':';
1280         while (param_length >= 4)
1281         {
1282           char *ip_string;
1283
1284           ip_string = IP_to_string(offset, tvb, little_endian,buff_tmp);
1285           proto_item_append_text(ti, "%c %s", sep, ip_string);
1286           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1287                               "Address[%d]: %s", i, ip_string);
1288           ++i;
1289           offset +=4;
1290         }
1291         offset += param_length;
1292         break;
1293
1294       case PID_MANAGER_KEY:
1295         i = 0;
1296         sep = ':';
1297         while (param_length >= 4)
1298         {
1299           guint32 manager_key;
1300
1301           manager_key = get_guint32(tvb, offset, little_endian);
1302           proto_item_append_text(ti, "%c 0x%X", sep, manager_key);
1303           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1304                               "Key[%d]: 0x%X", i, manager_key);
1305           ++i;
1306           offset +=4;
1307           sep = ',';
1308         }
1309         offset += param_length;
1310         break;
1311
1312       case PID_SEND_QUEUE_SIZE:
1313         if (param_length < 4)
1314         {
1315           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1316                               "Bad parameter: length < 4");
1317         }
1318         else
1319         {
1320           guint32 send_queue_size;
1321
1322           send_queue_size = get_guint32(tvb, offset, little_endian);
1323           proto_item_append_text(ti, ": %u", send_queue_size);
1324           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1325                               "Send queue size: %u", send_queue_size);
1326         }
1327         break;
1328
1329       case PID_PROTOCOL_VERSION:
1330         if (param_length < 2)
1331         {
1332           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1333                               "Bad parameter: length < 2");
1334         }
1335         else
1336         {
1337           char *protocol_version_str;
1338
1339           protocol_version_str = protocol_version_to_string(offset, tvb, buff_tmp);
1340           proto_item_append_text(ti, ": %s", protocol_version_str);
1341           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1342                               "Protocol version: %s", protocol_version_str);
1343         }
1344         break;
1345
1346       case PID_VENDOR_ID:
1347         if (param_length < 2)
1348         {
1349           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1350                               "Bad parameter: length < 2");
1351         }
1352         else
1353         {
1354           char *vendor_id_str;
1355
1356           vendor_id_str = vendor_id_to_string(offset, tvb, buff_tmp);
1357           proto_item_append_text(ti, ": %s", vendor_id_str);
1358           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1359                               "Vendor ID: %s", vendor_id_str);
1360         }
1361         break;
1362
1363       case PID_VARGAPPS_SEQUENCE_NUMBER_LAST:
1364         if (param_length < 8)
1365         {
1366           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1367                               "Bad parameter: length < 8");
1368         }
1369         else
1370         {
1371           seq_nr_to_string(offset, little_endian, tvb, &seqNumber);
1372           proto_item_append_text(ti, ": 0x%X%X",
1373                                  seqNumber.high, seqNumber.low);
1374           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1375                               "Sequence number: 0x%X%X",
1376                               seqNumber.high, seqNumber.low);
1377         }
1378         break;
1379
1380       case PID_RECV_QUEUE_SIZE:
1381         if (param_length < 4)
1382         {
1383           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1384                               "Bad parameter: length < 4");
1385         }
1386         else
1387         {
1388           guint32 recv_queue_size;
1389
1390           recv_queue_size = get_guint32(tvb, offset, little_endian);
1391           proto_item_append_text(ti, ": %u", recv_queue_size);
1392           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1393                               "Receive queue size: %u", recv_queue_size);
1394         }
1395         break;
1396
1397       case PID_RELIABILITY_OFFERED:
1398         if (param_length < 4)
1399         {
1400           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1401                               "Bad parameter: length < 4");
1402         }
1403         else
1404         {
1405           guint32 reliability_offered;
1406
1407           reliability_offered = get_guint32(tvb, offset, little_endian);
1408           proto_item_append_text(ti, ": 0x%X", reliability_offered);
1409           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1410                               "Reliability offered: 0x%X", reliability_offered);
1411         }
1412         break;
1413
1414       case PID_RELIABILITY_REQUESTED:
1415         if (param_length < 4)
1416         {
1417           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1418                               "Bad parameter: length < 4");
1419         }
1420         else
1421         {
1422           guint32 reliability_requested;
1423
1424           reliability_requested = get_guint32(tvb, offset, little_endian);
1425           proto_item_append_text(ti, ": 0x%X", reliability_requested);
1426           proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1427                               "Reliability requested: 0x%X", reliability_requested);
1428         }
1429         break;
1430
1431       default:
1432         proto_tree_add_text(rtps_parameter_tree, tvb, offset, param_length,
1433                             "Unknown parameter value");
1434         break;
1435     }   /* end switch */
1436
1437     offset += param_length;
1438   }
1439
1440   *p_offset = offset;
1441 }
1442
1443 /* *********************************************************************** */
1444
1445
1446 /* *********************************************************************** *
1447  *                                                                         *
1448  *                  subdissector for submessage: ISSUE                     *
1449  *                                                                         *
1450  * *********************************************************************** */
1451  /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1452 static void
1453 dissect_ISSUE(tvbuff_t *tvb, gint offset, guint8 flags,
1454               gboolean little_endian, int next_submsg_offset,
1455               proto_tree *rtps_submessage_tree)
1456 {
1457   int                       min_len;
1458   char                      buff[40];
1459   SequenceNumber            sequenceNumber;      /*  type struct  */
1460
1461   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1462                       tvb, offset, 1, flags);
1463   offset +=1;
1464
1465   min_len = 16;
1466   if ((flags & FLAG_P) != 0)
1467     min_len += 4;
1468   if (next_submsg_offset < min_len)
1469   {
1470     proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1471                                tvb, offset, 2, next_submsg_offset,
1472                                "Octets to next header: %u (bogus, must be >= %u)",
1473                                next_submsg_offset, min_len);
1474     return;
1475   }
1476   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1477                       tvb, offset, 2, next_submsg_offset);
1478   offset +=2;
1479   next_submsg_offset += offset;
1480
1481   /*  Reader Object ID  */
1482   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1483                       "Reader Object ID: %s ",
1484                       object_id_to_string(offset, tvb, buff));
1485   offset +=4;
1486
1487   /*  Writer Object ID */
1488   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1489                       "Writer Object ID: %s ",
1490                       object_id_to_string(offset, tvb, buff));
1491   offset +=4;
1492
1493   /*  Sequence Number */
1494   seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1495   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1496                       "firstSeqNumber:   0x%X%X",
1497                       sequenceNumber.high, sequenceNumber.low);
1498   offset += 8;
1499
1500   /*  Parameters */
1501 /* *********************************************************************** *
1502  *              - for future extension of the protocol - in                *
1503  *                implementation of RTPS 1.0 can ignore the content        *
1504  * *********************************************************************** */
1505
1506   /* -- P flag |XXXX|HAPE| => masks with 00000010b = 2 */
1507   if ((flags & FLAG_P) != 0)
1508   {
1509     get_parameter_sequence(tvb, &offset, little_endian, next_submsg_offset,
1510                            rtps_submessage_tree);
1511   }
1512
1513   /*  Issue Data */
1514   proto_tree_add_item(rtps_submessage_tree, hf_rtps_issue_data, tvb,
1515                       offset, (next_submsg_offset - offset), FALSE);
1516
1517 }
1518
1519 /* *********************************************************************** */
1520
1521
1522 /* *********************************************************************** *
1523  *                                                                         *
1524  *                  subdissector for submessage: ACK                       *
1525  *                                                                         *
1526  * *********************************************************************** */
1527  /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1528 static void
1529 dissect_ACK(tvbuff_t *tvb, gint offset, guint8 flags,
1530             gboolean little_endian, int next_submsg_offset,
1531             proto_tree *rtps_submessage_tree)
1532 {
1533   char                    buff[40];
1534
1535   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1536                       tvb, offset, 1, flags);
1537   offset +=1;
1538
1539   if (next_submsg_offset < 20)
1540   {
1541     proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1542                                tvb, offset, 2, next_submsg_offset,
1543                                "Octets to next header: %u (bogus, must be >= 20)",
1544                                next_submsg_offset);
1545     return;
1546   }
1547   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1548                       tvb, offset, 2, next_submsg_offset);
1549   offset +=2;
1550   next_submsg_offset += offset;
1551
1552   /*  Reader Object ID  */
1553   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1554                       "Reader Object ID:   %s ",
1555                       object_id_to_string(offset, tvb, buff));
1556   offset +=4;
1557
1558   /*  Writer Object ID  */
1559   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1560                       "Writer Object ID:   %s ",
1561                       object_id_to_string(offset, tvb, buff));
1562   offset +=4;
1563
1564   get_bitmap(tvb,&offset,little_endian,next_submsg_offset,rtps_submessage_tree);
1565
1566 }
1567
1568 /* *********************************************************************** */
1569
1570
1571 /* *********************************************************************** *
1572  *                                                                         *
1573  *                subdissector for submessage: HEARTBEAT                   *
1574  *                                                                         *
1575  * *********************************************************************** */
1576  /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1577 static void
1578 dissect_HEARTBEAT(tvbuff_t *tvb, gint offset, guint8 flags,
1579                   gboolean little_endian, int next_submsg_offset,
1580                   proto_tree *rtps_submessage_tree)
1581 {
1582   char                buff[40];
1583   SequenceNumber     sequenceNumber;      /* type struct  */
1584
1585   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1586                       tvb, offset, 1, flags);
1587   offset +=1;
1588
1589   if (next_submsg_offset < 24)
1590   {
1591     proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1592                                tvb, offset, 2, next_submsg_offset,
1593                                "Octets to next header: %u (bogus, must be >= 24)",
1594                                next_submsg_offset);
1595     return;
1596   }
1597   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1598                       tvb, offset, 2, next_submsg_offset);
1599   offset +=2;
1600   next_submsg_offset += offset;
1601
1602   /* Reader Object ID */
1603   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1604                       "Reader Object ID:   %s ",
1605                       object_id_to_string(offset, tvb, buff));
1606   offset +=4;
1607
1608   /* Writer Object ID */
1609   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1610                       "Writer Object ID:   %s ",
1611                           object_id_to_string(offset, tvb, buff));
1612   offset +=4;
1613
1614   /*  firstSeqNumber */
1615   seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1616   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1617                       "firstSeqNumber:     0x%X%X",
1618                       sequenceNumber.high, sequenceNumber.low);
1619   offset +=8;
1620
1621   /* lastSeqNumber */
1622   seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1623   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1624                       "lastSeqNumber:      0x%X%X",
1625                       sequenceNumber.high, sequenceNumber.low);
1626   offset +=8;
1627
1628 }
1629
1630 /* *********************************************************************** */
1631
1632
1633 /* *********************************************************************** *
1634  *                                                                         *
1635  *                   subdissector for submessage: GAP                      *
1636  *                                                                         *
1637  * *********************************************************************** */
1638  /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1639 static void
1640 dissect_GAP(tvbuff_t *tvb, gint offset, guint8 flags,
1641             gboolean little_endian, int next_submsg_offset,
1642             proto_tree *rtps_submessage_tree)
1643 {
1644   char                    buff[40];
1645   SequenceNumber          sequenceNumber;      /* type struct  */
1646
1647   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1648                       tvb, offset, 1, flags);
1649   offset +=1;
1650
1651   if (next_submsg_offset < 28)
1652   {
1653     proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1654                                tvb, offset, 2, next_submsg_offset,
1655                                "Octets to next header: %u (bogus, must be >= 28)",
1656                                next_submsg_offset);
1657     return;
1658   }
1659   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1660                       tvb, offset, 2, next_submsg_offset);
1661   offset +=2;
1662   next_submsg_offset += offset;
1663
1664   /*  Reader Object ID  */
1665   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1666                       "Reader Object ID:          %s ",
1667                       object_id_to_string(offset, tvb, buff));
1668   offset +=4;
1669
1670   /*  Writer Object ID  */
1671   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1672                       "Writer Object ID:          %s ",
1673                       object_id_to_string(offset, tvb, buff));
1674   offset +=4;
1675
1676   /*  Sequence Number */
1677   seq_nr_to_string(offset, little_endian, tvb, &sequenceNumber);
1678   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1679                       "firstSeqNumber:   0x%X%X",
1680                       sequenceNumber.high, sequenceNumber.low);
1681   offset +=8;
1682
1683   get_bitmap(tvb,&offset,little_endian,next_submsg_offset,rtps_submessage_tree);
1684
1685 }
1686
1687 /* *********************************************************************** */
1688
1689
1690 /* *********************************************************************** *
1691  *                                                                         *
1692  *                subdissector for submessage: INFO_TS                     *
1693  *                                                                         *
1694  * *********************************************************************** */
1695  /* hotovo 12.01.04 - JEN OTESTOVAT :] */
1696
1697 static void
1698 dissect_INFO_TS(tvbuff_t *tvb, gint offset, guint8 flags,
1699                 gboolean little_endian, int next_submsg_offset,
1700                 proto_tree *rtps_submessage_tree)
1701 {
1702   char                     buff[10];
1703
1704   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1705                       tvb, offset, 1, flags);
1706   offset +=1;
1707
1708   /*   npTimestamp - valid if flag I = 1         *
1709    *   |XXXX|XXIE| => masks with 00000010b = 2   */
1710   if ((flags & FLAG_I) != 0)
1711   {
1712     if (next_submsg_offset < 8)
1713     {
1714       proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1715                                  tvb, offset, 2, next_submsg_offset,
1716                                  "Octets to next header: %u (bogus, must be >= 8)",
1717                                  next_submsg_offset);
1718       return;
1719     }
1720   }
1721   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1722                       tvb, offset, 2, next_submsg_offset);
1723   offset +=2;
1724   next_submsg_offset += offset;
1725
1726   /*   npTimestamp - valid if flag I = 1         *
1727    *   |XXXX|XXIE| => masks with 00000010b = 2   */
1728   if ((flags & FLAG_I) != 0)
1729   {
1730     proto_tree_add_text(rtps_submessage_tree, tvb, offset, 8,
1731                         "ntpTimestamp: %s (sec)",
1732                         get_NtpTime(offset, tvb, little_endian,buff));
1733     offset +=8;
1734   }
1735
1736 }
1737
1738 /* *********************************************************************** */
1739
1740
1741 /* *********************************************************************** *
1742  *                                                                         *
1743  *               subdissector for submessage: INFO_SRC                     *
1744  *                                                                         *
1745  * *********************************************************************** */
1746 /* hotovo 12.01.04 JEN OTESTOVAT :] */
1747 static void
1748 dissect_INFO_SRC(tvbuff_t *tvb, gint offset, guint8 flags,
1749                  gboolean little_endian, int next_submsg_offset,
1750                  proto_tree *rtps_submessage_tree)
1751 {
1752   char                    buff[200];
1753
1754   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1755                       tvb, offset, 1, flags);
1756   offset +=1;
1757
1758   if (next_submsg_offset < 16)
1759   {
1760     proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1761                                tvb, offset, 2, next_submsg_offset,
1762                                "Octets to next header: %u (bogus, must be >= 16)",
1763                                next_submsg_offset);
1764     return;
1765   }
1766   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1767                       tvb, offset, 2, next_submsg_offset);
1768   offset +=2;
1769   next_submsg_offset += offset;
1770
1771   /*  IPAddress */
1772   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1773                       "appIP address: %s",
1774                       IP_to_string(offset, tvb, little_endian,buff));
1775   offset +=4;
1776
1777   /*  Protocol Version */
1778   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
1779                       "Protocol  RTPS  version %s -new",
1780                       protocol_version_to_string(offset, tvb, buff));
1781   offset +=2;
1782
1783   /*  Vendor Id */
1784   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 2,
1785                       "VendorId: %s -new",
1786                       vendor_id_to_string(offset, tvb, buff));
1787   offset +=2;
1788
1789   /*  Host Id */
1790   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1791                       "Host ID:            %s",
1792                       host_id_to_string(offset,tvb,buff));
1793   offset+=4;
1794
1795   /*  App Id */
1796   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1797                       "App ID:             %s-new",
1798                       app_id_to_string(offset, tvb, buff));
1799   offset +=4;
1800
1801 }
1802
1803 /* *********************************************************************** */
1804
1805
1806 /* *********************************************************************** *
1807  *                                                                         *
1808  *               subdissector for submessage: INFO_REPLY                   *
1809  *                                                                         *
1810  * *********************************************************************** */
1811  /* hotovo 11.01.04 :] */
1812 static void
1813 dissect_INFO_REPLY(tvbuff_t *tvb, gint offset, guint8 flags,
1814                    gboolean little_endian, int next_submsg_offset,
1815                    proto_tree *rtps_submessage_tree)
1816 {
1817   int                     min_len;
1818   char                    buff_ip[10], buff_port[10];
1819
1820   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1821                       tvb, offset, 1, flags);
1822   offset +=1;
1823
1824  /*  'multicastReplyAdress' and 'multicastReplyPort' are    *
1825   *   parts of submessage INFO REPLY which are available    *
1826   *   only when FLAG  M=1  flags: XXXX XXME                 */
1827
1828   if ((flags & FLAG_M) != 0)
1829     min_len = 16;
1830   else
1831     min_len = 8;
1832   if (next_submsg_offset < min_len)
1833   {
1834     proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1835                                tvb, offset, 2, next_submsg_offset,
1836                                "Octets to next header: %u (bogus, must be >= %u)",
1837                                next_submsg_offset, min_len);
1838     return;
1839   }
1840   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1841                       tvb, offset, 2, next_submsg_offset);
1842   offset +=2;
1843   next_submsg_offset += offset;
1844
1845   /* Unicat Reply IPAddress */
1846   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1847                       "Unicast Reply IP Adress: %s",
1848                       IP_to_string(offset, tvb, little_endian,buff_ip));
1849   offset +=4;
1850
1851
1852   /* Unicast Reply Port */
1853   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1854                       "Unicast Reply IP Port: %s",
1855                       port_to_string(offset, tvb, little_endian,buff_port));
1856   offset +=4;
1857
1858
1859  /*  'multicastReplyAdress' and 'multicastReplyPort' are    *
1860   *   parts of submessage INFO REPLY which are available    *
1861   *   only when FLAG  M=1  flags: XXXX XXME                 */
1862
1863   if ((flags & FLAG_M) != 0)
1864   {
1865     /* Multicast Reply IPAddress */
1866     proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1867                         "Multicast Reply IP Adress: %s",
1868                         IP_to_string(offset, tvb, little_endian,buff_ip));
1869     offset +=4;
1870
1871     /* Multicast Reply Port */
1872     proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1873                         "Multicast Reply IP Port: %s",
1874                         port_to_string(offset, tvb, little_endian,buff_port));
1875     offset +=4;
1876
1877   }
1878 }
1879
1880 /* *********************************************************************** */
1881
1882
1883 /* *********************************************************************** *
1884  *                                                                         *
1885  *                 subdissector for submessage: INFO_DST                   *
1886  *                                                                         *
1887  * *********************************************************************** */
1888  /* HOTOVO 12.01.04 - JEN OTESOVAT :]*/
1889 static void
1890 dissect_INFO_DST(tvbuff_t *tvb, gint offset, guint8 flags,
1891                  int next_submsg_offset,
1892                  proto_tree *rtps_submessage_tree)
1893 {
1894   char                    buff[200];
1895
1896   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_submessage_flags,
1897                       tvb, offset, 1, flags);
1898   offset +=1;
1899
1900   if (next_submsg_offset < 8)
1901   {
1902     proto_tree_add_uint_format(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1903                                tvb, offset, 2, next_submsg_offset,
1904                                "Octets to next header: %u (bogus, must be >= 8)",
1905                                next_submsg_offset);
1906     return;
1907   }
1908   proto_tree_add_uint(rtps_submessage_tree, hf_rtps_octets_to_next_header,
1909                       tvb, offset, 2, next_submsg_offset);
1910   offset +=2;
1911   next_submsg_offset += offset;
1912
1913   /*  Host Id */
1914   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1915                       "Host ID:            %s",
1916                       host_id_to_string(offset,tvb,buff));
1917   offset+=4;
1918
1919   /*  App Id */
1920   proto_tree_add_text(rtps_submessage_tree, tvb, offset, 4,
1921                       "App ID:             %s-new",
1922                       app_id_to_string(offset, tvb, buff));
1923   offset +=4;
1924
1925 }
1926
1927 /* *********************************************************************** *
1928  *                                                                         *
1929  *                       Register the protocol with Ethereal               *
1930  *                                                                         *
1931  * *********************************************************************** */
1932
1933 void proto_register_rtps(void)
1934 {
1935   static hf_register_info hf[] = {
1936
1937     { &hf_rtps_submessage_id,
1938       { "Submessage Id", "rtps.submessage_id",
1939          FT_UINT8, BASE_HEX, VALS(submessage_id_vals), 0x0,
1940         "Submessage flags", HFILL }},
1941
1942     { &hf_rtps_submessage_flags,
1943       { "Submessage flags", "rtps.submessage_flags",
1944          FT_UINT8, BASE_HEX, NULL, 0x0,
1945         "Submessage flags", HFILL }},
1946
1947     { &hf_rtps_octets_to_next_header,
1948       { "Octets to next header", "rtps.octets_to_next_header",
1949          FT_UINT16, BASE_DEC, NULL, 0x0,
1950         "Octets to next header", HFILL }},
1951
1952     { &hf_rtps_parameter_id,
1953       { "Parameter Id", "rtps.parameter_id",
1954          FT_UINT16, BASE_HEX, VALS(parameter_id_vals), 0x0,
1955         "Parameter Id", HFILL }},
1956
1957     { &hf_rtps_parameter_length,
1958       { "Parameter Length", "rtps.parameter_length",
1959          FT_UINT16, BASE_DEC, NULL, 0x0,
1960         "Parameter Length", HFILL }},
1961
1962     { &hf_rtps_issue_data,
1963       { "User Data", "rtps.issue_data",
1964          FT_BYTES, BASE_HEX, NULL, 0x0,
1965         "Issue Data", HFILL }},
1966   };
1967
1968   static gint *ett[] = {
1969     &ett_rtps,
1970     &ett_rtps_submessage,
1971     &ett_rtps_bitmap,
1972     &ett_rtps_parameter_sequence,
1973     &ett_rtps_parameter,
1974   };
1975
1976   proto_rtps = proto_register_protocol("Real-Time Publish-Subscribe Wire Protocol",
1977                                        "RTPS", "rtps");
1978   proto_register_field_array(proto_rtps, hf, array_length(hf));
1979   proto_register_subtree_array(ett, array_length(ett));
1980
1981 }
1982
1983
1984 void
1985 proto_reg_handoff_rtps(void)
1986 {
1987  heur_dissector_add("udp", dissect_rtps, proto_rtps);
1988 }
1989