From Marc Petit-Huguenin via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id...
[obnox/wireshark/wip.git] / epan / dissectors / packet-reload.c
1 /* packet-reload.c
2  * Routines forREsource LOcation And Discovery (RELOAD) Base Protocol
3  * Author: Stephane Bryant <sbryant@glycon.org>
4  * Copyright 2010 Stonyfish Inc.
5  *
6  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25  *
26  * Please refer to the following specs for protocol detail:
27  * - draft-ietf-p2psip-base-13
28  */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <epan/conversation.h>
35 #include <epan/prefs.h>
36 #include <epan/reassemble.h>
37 #include <epan/expert.h>
38 #include <epan/asn1.h>
39 #include <epan/dissectors/packet-x509af.h>
40 #include <packet-tcp.h>
41 #include <packet-ssl-utils.h>
42
43 /* Initialize the protocol and registered fields */
44 static int proto_reload = -1;
45
46 static gboolean reload_defragment = TRUE;
47 static guint reload_nodeid_length = 16;
48
49 static int hf_reload_response_in = -1;
50 static int hf_reload_response_to = -1;
51 static int hf_reload_time = -1;
52 static int hf_reload_duplicate = -1;
53 static int hf_reload_token = -1;
54 static int hf_reload_forwarding = -1;
55 static int hf_reload_overlay = -1;
56 static int hf_reload_configuration_sequence = -1;
57 static int hf_reload_version = -1;
58 static int hf_reload_ttl = -1;
59 static int hf_reload_fragment_flag = -1;
60 static int hf_reload_fragment_fragmented = -1;
61 static int hf_reload_fragment_last_fragment = -1;
62 static int hf_reload_fragment_reserved = -1;
63 static int hf_reload_fragment_offset = -1;
64 static int hf_reload_length = -1;
65 static int hf_reload_trans_id = -1;
66 static int hf_reload_max_response_length = -1;
67 static int hf_reload_via_list_length = -1;
68 static int hf_reload_destination_list_length = -1;
69 static int hf_reload_options_length = -1;
70 static int hf_reload_via_list = -1;
71 static int hf_reload_destination = -1;
72 static int hf_reload_destination_compressed = -1;
73 static int hf_reload_destination_type = -1;
74 static int hf_reload_destination_length = -1;
75 static int hf_reload_nodeid = -1;
76 static int hf_reload_resource_id = -1;
77 static int hf_reload_destination_data_compressed_id = -1;
78 static int hf_reload_destination_list = -1;
79 static int hf_reload_forwarding_option = -1;
80 static int hf_reload_forwarding_option_type = -1;
81 static int hf_reload_forwarding_option_flags = -1;
82 static int hf_reload_forwarding_option_flag_response_copy = -1;
83 static int hf_reload_forwarding_option_flag_destination_critical = -1;
84 static int hf_reload_forwarding_option_flag_forward_critical = -1;
85 static int hf_reload_forwarding_option_length = -1;
86 static int hf_reload_forwarding_option_data = -1;
87 static int hf_reload_forwarding_option_directresponseforwarding = -1;
88 static int hf_reload_attachreqans = -1;
89 static int hf_reload_ufrag = -1;
90 static int hf_reload_password = -1;
91 static int hf_reload_role = -1;
92 static int hf_reload_sendupdate = -1;
93 static int hf_reload_icecandidates = -1;
94 static int hf_reload_icecandidates_length = -1;
95 static int hf_reload_icecandidate = -1;
96 static int hf_reload_icecandidate_srflx_addr = -1;
97 static int hf_reload_icecandidate_prflx_addr = -1;
98 static int hf_reload_icecandidate_relay_addr = -1;
99 static int hf_reload_icecandidate_foundation = -1;
100 static int hf_reload_icecandidate_priority = -1;
101 static int hf_reload_icecandidate_type = -1;
102 static int hf_reload_overlaylink_type = -1;
103 static int hf_reload_icecandidate_extensions_length = -1;
104 static int hf_reload_iceextension = -1;
105 static int hf_reload_iceextension_name = -1;
106 static int hf_reload_iceextension_value = -1;
107 static int hf_reload_ipaddressport = -1;
108 static int hf_reload_ipaddressport_type = -1;
109 static int hf_reload_ipaddressport_length = -1;
110 static int hf_reload_ipv4addr = -1;
111 static int hf_reload_port = -1;
112 static int hf_reload_ipv6addr = -1;
113 static int hf_reload_message_contents = -1;
114 static int hf_reload_message_code = -1;
115 static int hf_reload_message_body = -1;
116 static int hf_reload_message_extensions_length = -1;
117 static int hf_reload_message_extension = -1;
118 static int hf_reload_message_extension_type = -1;
119 static int hf_reload_message_extension_critical = -1;
120 static int hf_reload_message_extension_content = -1;
121 static int hf_reload_error_response = -1;
122 static int hf_reload_error_response_code = -1;
123 static int hf_reload_error_response_info = -1;
124 static int hf_reload_security_block = -1;
125 static int hf_reload_certificates_length = -1;
126 static int hf_reload_certificates = -1;
127 static int hf_reload_certificate_type = -1;
128 static int hf_reload_certificate = -1;
129 static int hf_reload_signature = -1;
130 static int hf_reload_hash_algorithm = -1;
131 static int hf_reload_signature_algorithm = -1;
132 static int hf_reload_signature_identity = -1;
133 static int hf_reload_signature_identity_type = -1;
134 static int hf_reload_signature_identity_length = -1;
135 static int hf_reload_signature_identity_value = -1;
136 static int hf_reload_signature_identity_value_certificate_hash = -1;
137 static int hf_reload_signature_value = -1;
138 static int hf_reload_opaque_length_uint8 = -1;
139 static int hf_reload_opaque_length_uint16 = -1;
140 static int hf_reload_opaque_length_uint32 = -1;
141 static int hf_reload_opaque_data = -1;
142 static int hf_reload_routequeryreq = -1;
143 static int hf_reload_overlay_specific = -1;
144 static int hf_reload_probereq = -1;
145 static int hf_reload_probe_information_type = -1;
146 static int hf_reload_probe_information = -1;
147 static int hf_reload_responsible_set = -1;
148 static int hf_reload_num_resources = -1;
149 static int hf_reload_uptime = -1;
150 static int hf_reload_probeans = -1;
151 static int hf_reload_appattach = -1;
152 static int hf_reload_application = -1;
153 static int hf_reload_ping_response_id = -1;
154 static int hf_reload_ping_time = -1;
155 static int hf_reload_storeddata = -1;
156 static int hf_reload_storeddata_length = -1;
157 static int hf_reload_storeddata_storage_time =  -1;
158 static int hf_reload_storeddata_lifetime = -1;
159 static int hf_reload_kinddata = -1;
160 static int hf_reload_kindid = -1;
161 static int hf_reload_kinddata_generation_counter = -1;
162 static int hf_reload_kinddata_values_length = -1;
163 static int hf_reload_storereq = -1;
164 static int hf_reload_store_replica_num = -1;
165 static int hf_reload_store_kind_data_length = -1;
166 static int hf_reload_storeans_kind_responses = -1;
167 static int hf_reload_storeans_kind_responses_length = -1;
168 static int hf_reload_storekindresponse = -1;
169 static int hf_reload_storekindresponse_replicas = -1;
170 static int hf_reload_storeddataspecifiers = -1;
171 static int hf_reload_fetchans = -1;
172 static int hf_reload_kind_responses_length = -1;
173 static int hf_reload_statans = -1;
174 static int hf_reload_findreq_kinds_length = -1;
175 static int hf_reload_findkinddata = -1;
176 static int hf_reload_findans_results_length = -1;
177 static int hf_reload_fragments = -1;
178 static int hf_reload_fragment = -1;
179 static int hf_reload_fragment_overlap = -1;
180 static int hf_reload_fragment_overlap_conflict = -1;
181 static int hf_reload_fragment_multiple_tails = -1;
182 static int hf_reload_fragment_too_long_fragment = -1;
183 static int hf_reload_fragment_error = -1;
184 static int hf_reload_fragment_count = -1;
185 static int hf_reload_reassembled_in = -1;
186 static int hf_reload_reassembled_length = -1;
187 static int hf_reload_configupdatereq = -1;
188 static int hf_reload_configupdatereq_type = -1;
189 static int hf_reload_configupdatereq_length = -1;
190 static int hf_reload_configupdatereq_configdata = -1;
191 static int hf_reload_configupdatereq_kinds = -1;
192 static int hf_reload_padding = -1;
193
194
195 static dissector_handle_t data_handle;
196
197 /* Structure containing transaction specific information */
198 typedef struct _reload_transaction_t {
199   guint32 req_frame;
200   guint32 rep_frame;
201   nstime_t req_time;
202 } reload_transaction_t;
203
204 /* Structure containing conversation specific information */
205 typedef struct _reload_conv_info_t {
206   emem_tree_t *transaction_pdus;
207 } reload_conv_info_t;
208
209
210 /* RELOAD Message classes = (message_code & 0x1) (response = request +1) */
211 #define REQUEST         0x0001
212 #define RESPONSE        0x0000
213
214 #define ERROR           0xffff
215
216 /* RELOAD Message Methods = (message_code +1) & 0xfffe*/
217 #define METHOD_INVALID           0
218 #define METHOD_PROBE             2
219 #define METHOD_ATTACH            4
220 #define METHOD_STORE             8
221 #define METHOD_FETCH            10
222 #define METHOD_REMOVE           12
223 #define METHOD_FIND             14
224 #define METHOD_JOIN             16
225 #define METHOD_LEAVE            18
226 #define METHOD_UPDATE           20
227 #define METHOD_ROUTEQUERY       22
228 #define METHOD_PING             24
229 #define METHOD_STAT             26
230 #define METHOD_APPATTACH        30
231 #define METHOD_CONFIGUPDATE     34
232
233
234 /* RELOAD Destinationtype */
235 #define DESTINATIONTYPE_RESERVED            0
236 #define DESTINATIONTYPE_NODE                1
237 #define DESTINATIONTYPE_RESOURCE            2
238 #define DESTINATIONTYPE_COMPRESSED          3
239
240 /* RELOAD forwarding option type */
241 #define OPTIONTYPE_DIRECTRESPONSEFORWARDING  1
242
243 /* RELOAD CandTypes */
244 #define CANDTYPE_RESERVED        0
245 #define CANDTYPE_HOST            1
246 #define CANDTYPE_SRFLX           2
247 #define CANDTYPE_PRFLX           3
248 #define CANDTYPE_RELAY           4
249
250 /* IpAddressPort types */
251 #define IPADDRESSPORTTYPE_RESERVED 0
252 #define IPADDRESSPORTTYPE_IPV4     1
253 #define IPADDRESSPORTTYPE_IPV6     2
254
255 /* OverlayLink types */
256 #define OVERLAYLINKTYPE_RESERVEDOVERLAYLINK                             0
257 #define OVERLAYLINKTYPE_DTLS_UDP_SR                                     1
258 #define OVERLAYLINKTYPE_DTLS_UDP_SR_NO_ICE                              3
259 #define OVERLAYLINKTYPE_TLS_TCP_FH_NO_ICE                               4
260
261 #define ERRORCODE_INVALID                                               0
262 #define ERRORCODE_UNUSED                                                1
263 #define ERRORCODE_FORBIDDEN                                             2
264 #define ERRORCODE_NOTFOUND                                              3
265 #define ERRORCODE_REQUESTTIMEOUT                                        4
266 #define ERRORCODE_GENERATIONCOUNTERTOOLOW                               5
267 #define ERRORCODE_INCOMPATIBLEWITHOVERLAY                               6
268 #define ERRORCODE_UNSUPPORTEDFORWARDINGOPTION                           7
269 #define ERRORCODE_DATATOOLARGE                                          8
270 #define ERRORCODE_DATATOOOLD                                            9
271 #define ERRORCODE_TTLEXCEEDED                                           10
272 #define ERRORCODE_MESSAGETOOLARGE                                       11
273 #define ERRORCODE_UNKNOWNKIND                                           12
274 #define ERRORCODE_UNKNOWNEXTENSION                                      13
275 #define ERRORCODE_RESPONSETOOLARGE                                      14
276 #define ERRORCODE_CONFIGTOOOLD                                          15
277 #define ERRORCODE_CONFIGTOONEW                                          16
278
279 /* Certificate types */
280 #define CERTIFICATETYPE_X509                                            0
281
282 #define SIGNATUREIDENTITYTYPE_RESERVED                                  0
283 #define SIGNATUREIDENTITYTYPE_CERTHASH                                  1
284
285 /* Probe information type */
286 #define PROBEINFORMATIONTYPE_RESERVED                                   0
287 #define PROBEINFORMATIONTYPE_RESPONSIBLESET                             1
288 #define PROBEINFORMATIONTYPE_NUMRESOURCES                               2
289 #define PROBEINFORMATIONTYPE_UPTIME                                     3
290
291 /* Data Kind ID */
292 #define DATAKINDID_INVALID                                              0
293 #define DATAKINDID_TURNSERVICE                                          2
294 #define DATAKINDID_CERTIFICATE_BY_NODE                                  4
295 #define DATAKINDID_CERTIFICATE_BY_USER                                  6
296
297 /* Message Extension Type */
298 #define MESSAGEEXTENSIONTYPE_RESERVED                                   0
299
300 /* Config Update Type */
301 #define CONFIGUPDATETYPE_RESERVED                                       0
302 #define CONFIGUPDATETYPE_CONFIG                                         1
303 #define CONFIGUPDATETYPE_KIND                                           2
304
305 /* Initialize the subtree pointers */
306 static gint ett_reload = -1;
307 static gint ett_reload_forwarding = -1;
308 static gint ett_reload_message = -1;
309 static gint ett_reload_security=-1;
310 static gint ett_reload_fragment_flag=-1;
311 static gint ett_reload_destination = -1;
312 static gint ett_reload_via_list = -1;
313 static gint ett_reload_destination_list = -1;
314 static gint ett_reload_forwarding_option = -1;
315 static gint ett_reload_forwarding_option_flags = -1;
316 static gint ett_reload_forwarding_option_directresponseforwarding = -1;
317 static gint ett_reload_attachreqans = -1;
318 static gint ett_reload_icecandidates = -1;
319 static gint ett_reload_icecandidate = -1;
320 static gint ett_reload_icecandidate_computed_address = -1;
321 static gint ett_reload_iceextension = -1;
322 static gint ett_reload_ipaddressport = -1;
323 static gint ett_reload_message_contents = -1;
324 static gint ett_reload_message_extension = -1;
325 static gint ett_reload_error_response = -1;
326 static gint ett_reload_security_block = -1;
327 static gint ett_reload_certificate = -1;
328 static gint ett_reload_signature = -1;
329 static gint ett_reload_signature_identity = -1;
330 static gint ett_reload_signature_identity_value = -1;
331 static gint ett_reload_opaque = -1;
332 static gint ett_reload_message_body = -1;
333 static gint ett_reload_routequeryreq = -1;
334 static gint ett_reload_probereq = -1;
335 static gint ett_reload_probe_information = -1;
336 static gint ett_reload_probeans = -1;
337 static gint ett_reload_appattach = -1;
338 static gint ett_reload_storeddata = -1;
339 static gint ett_reload_kinddata = -1;
340 static gint ett_reload_storereq = -1;
341 static gint ett_reload_storeans_kind_responses = -1;
342 static gint ett_reload_storekindresponse = -1;
343 static gint ett_reload_fetchans = -1;
344 static gint ett_reload_statans = -1;
345 static gint ett_reload_findkinddata = -1;
346 static gint ett_reload_fragments = -1;
347 static gint ett_reload_fragment  = -1;
348 static gint ett_reload_configupdatereq = -1;
349 static gint ett_reload_storekindresponse_replicas = -1;
350
351 static const fragment_items reload_frag_items = {
352   &ett_reload_fragment,
353   &ett_reload_fragments,
354   &hf_reload_fragments,
355   &hf_reload_fragment,
356   &hf_reload_fragment_overlap,
357   &hf_reload_fragment_overlap_conflict,
358   &hf_reload_fragment_multiple_tails,
359   &hf_reload_fragment_too_long_fragment,
360   &hf_reload_fragment_error,
361   &hf_reload_fragment_count,
362   &hf_reload_reassembled_in,
363   &hf_reload_reassembled_length,
364   "RELOAD fragments"
365 };
366
367
368 #define MSG_LENGH_OFFSET                16
369 #define MIN_HDR_LENGTH                  38      /* Forwarding header till options_length member (included) */
370
371 #define RELOAD_TOKEN                    0xd2454c4f
372
373 #define IS_REQUEST(code)                (code & 0x0001)
374 #define MSGCODE_TO_METHOD(code)         ((code + 1) & 0xfffe)
375 #define MSGCODE_TO_CLASS(code)          (code & 0x0001)
376
377
378 static const value_string classes[] = {
379   {REQUEST,                                     "Request"},
380   {RESPONSE,                                    "Answer"},
381   {0x00, NULL}
382 };
383
384 static const value_string methods[] = {
385   {METHOD_INVALID,                              "invalid"},
386   {METHOD_PROBE,                                "Probe"},
387   {METHOD_ATTACH,                               "Attach"},
388   {METHOD_STORE,                                "Store"},
389   {METHOD_FETCH,                                "Fetch"},
390   {METHOD_REMOVE,                               "Remove"},
391   {METHOD_FIND,                                 "Find"},
392   {METHOD_JOIN,                                 "Join"},
393   {METHOD_LEAVE,                                "Leave"},
394   {METHOD_UPDATE,                               "Update"},
395   {METHOD_ROUTEQUERY,                           "RouteQuery"},
396   {METHOD_PING,                                 "Ping"},
397   {METHOD_STAT,                                 "Stat"},
398   {METHOD_APPATTACH,                            "AppAttach"},
399   {METHOD_CONFIGUPDATE,                         "ConfigUpdate"},
400   {0x00, NULL}
401 };
402
403 static const value_string destinationtypes[] = {
404   {DESTINATIONTYPE_RESERVED,                    "reserved"},
405   {DESTINATIONTYPE_NODE,                        "Node"},
406   {DESTINATIONTYPE_RESOURCE,                    "Resource"},
407   {DESTINATIONTYPE_COMPRESSED,                  "Compressed"},
408   {0x00, NULL}
409 };
410
411 static const value_string forwardingoptiontypes[] = {
412   {OPTIONTYPE_DIRECTRESPONSEFORWARDING,         "directResponseForwarding"},
413   {0x00, NULL}
414 };
415
416 static const value_string candtypes[] = {
417   {CANDTYPE_RESERVED,                           "reserved"},
418   {CANDTYPE_HOST,                               "host"},
419   {CANDTYPE_SRFLX,                              "srflx"},
420   {CANDTYPE_PRFLX,                              "prflx"},
421   {CANDTYPE_RELAY,                              "relay"},
422   {0x00, NULL}
423 };
424
425 static const value_string ipaddressporttypes [] = {
426   {IPADDRESSPORTTYPE_RESERVED,                  "reserved"},
427   {IPADDRESSPORTTYPE_IPV4,                      "IPV4"},
428   {IPADDRESSPORTTYPE_IPV6,                      "IPV6"},
429   {0x00, NULL}
430 };
431
432 static const value_string overlaylinktypes [] ={
433   {OVERLAYLINKTYPE_RESERVEDOVERLAYLINK,         "reserved"},
434   {OVERLAYLINKTYPE_DTLS_UDP_SR,                 "DTLS-UDP-SR"},
435   {OVERLAYLINKTYPE_DTLS_UDP_SR_NO_ICE,          "DTLS-UDP-SR-NO-ICE"},
436   {OVERLAYLINKTYPE_TLS_TCP_FH_NO_ICE,           "TLS-TCP-FH-NO-ICE"},
437   {0x00, NULL}
438 };
439
440 static const value_string errorcodes [] ={
441   {ERRORCODE_INVALID,                           "invalid"},
442   {ERRORCODE_UNUSED,                            "Unused"},
443   {ERRORCODE_FORBIDDEN,                         "Forbidden"},
444   {ERRORCODE_NOTFOUND,                          "Not Found"},
445   {ERRORCODE_REQUESTTIMEOUT,                    "Request Timeout"},
446   {ERRORCODE_GENERATIONCOUNTERTOOLOW,           "Generation Counter Too Low"},
447   {ERRORCODE_INCOMPATIBLEWITHOVERLAY,           "Incompatible with Overlay"},
448   {ERRORCODE_UNSUPPORTEDFORWARDINGOPTION,       "Unsupported Forwarding Option"},
449   {ERRORCODE_DATATOOLARGE,                      "Data Too Large"},
450   {ERRORCODE_DATATOOOLD,                        "Data Too Old"},
451   {ERRORCODE_TTLEXCEEDED,                       "TTL Exceeded"},
452   {ERRORCODE_MESSAGETOOLARGE,                   "Message Too Large"},
453   {ERRORCODE_UNKNOWNKIND,                       "Unknown Kind"},
454   {ERRORCODE_UNKNOWNEXTENSION,                  "Unknown Extension"},
455   {ERRORCODE_RESPONSETOOLARGE,                  "Response Too Large"},
456   {ERRORCODE_CONFIGTOOOLD,                      "Config Too Old"},
457   {ERRORCODE_CONFIGTOONEW,                      "Config Too New"},
458   {0x00, NULL}
459 };
460
461 static const value_string certificatetypes[] = {
462   {CERTIFICATETYPE_X509,                        "X509"},
463   {0x00, NULL}
464 };
465
466 static const value_string signatureidentitytypes[] = {
467   {SIGNATUREIDENTITYTYPE_RESERVED,              "reserved"},
468   {SIGNATUREIDENTITYTYPE_CERTHASH,              "CERT_HASH"},
469   {0x00, NULL}
470 };
471
472 static const value_string probeinformationtypes[] = {
473   {PROBEINFORMATIONTYPE_RESERVED,               "reserved"},
474   {PROBEINFORMATIONTYPE_RESPONSIBLESET,         "responsible_set"},
475   {PROBEINFORMATIONTYPE_NUMRESOURCES,           "num_resources"},
476   {PROBEINFORMATIONTYPE_UPTIME,                 "uptime"},
477   {0x00, NULL}
478 };
479
480 static const value_string datakindids[] = {
481   {DATAKINDID_INVALID,                          "invalid"},
482   {DATAKINDID_TURNSERVICE,                      "TURN-SERVICE"},
483   {DATAKINDID_CERTIFICATE_BY_NODE,              "CERTIFICATE_BY_NODE"},
484   {DATAKINDID_CERTIFICATE_BY_USER,              "CERTIFICATE_BY_USER"},
485   {0x00, NULL}
486 };
487
488 static const value_string messageextensiontypes[] = {
489   {MESSAGEEXTENSIONTYPE_RESERVED,               "reserved"},
490   {0x00, NULL}
491 };
492
493 static const value_string configupdatetypes[] = {
494   {CONFIGUPDATETYPE_RESERVED,                   "reserved"},
495   {CONFIGUPDATETYPE_CONFIG,                     "config"},
496   {CONFIGUPDATETYPE_KIND,                       "kind"},
497   {0x00, NULL}
498 };
499 /*
500  * defragmentation of IPv4
501  */
502 static GHashTable *reload_fragment_table = NULL;
503 static GHashTable *reload_reassembled_table = NULL;
504
505 static void
506 reload_defragment_init(void)
507 {
508   fragment_table_init(&reload_fragment_table);
509   reassembled_table_init(&reload_reassembled_table);
510 }
511
512
513 static guint
514 get_reload_message_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
515 {
516   guint32 length = tvb_get_ntohl(tvb, offset + MSG_LENGH_OFFSET);
517   return length;
518 }
519
520 static int
521 get_opaque_length(tvbuff_t *tvb, guint16 offset, guint16 length_size)
522 {
523   int length = -1;
524
525   switch (length_size) {
526   case 1:
527     length = (gint32)tvb_get_guint8(tvb,offset);
528     break;
529   case 2:
530     length = (gint32)tvb_get_ntohs(tvb, offset);
531     break;
532   case 4:
533     length = (gint32)tvb_get_ntohl(tvb, offset);
534     break;
535
536   default:
537     break;
538   }
539
540   return length;
541 }
542
543 static int
544 dissect_opaque(tvbuff_t *tvb, packet_info *pinfo,proto_tree *tree, int anchor_index, guint16 offset, guint16 length_size, gint32 max_field_length)
545 {
546   proto_tree *opaque_tree;
547   proto_item *ti_anchor;
548   gint length_index = -1;
549   gint32 length = -1;
550
551   switch (length_size) {
552   case 1:
553     length_index = hf_reload_opaque_length_uint8;
554     length = (gint32)tvb_get_guint8(tvb,offset);
555     break;
556   case 2:
557     length_index = hf_reload_opaque_length_uint16;
558     length = (gint32)tvb_get_ntohs(tvb, offset);
559     break;
560   case 3:
561     length_index = hf_reload_opaque_length_uint32;
562     length = ((gint32) (tvb_get_ntohs(tvb, offset) <<8) + (tvb_get_guint8(tvb, offset+2)));
563     break;
564   case 4:
565     length_index = hf_reload_opaque_length_uint32;
566     length = (gint32)tvb_get_ntohl(tvb, offset);
567     break;
568
569   default:
570     break;
571   }
572
573   if (length_index < 0) return 0;
574
575   ti_anchor = proto_tree_add_item(tree, anchor_index, tvb, offset, length_size + length, FALSE);
576
577   if (max_field_length > 0) {
578     if ((length + length_size) > max_field_length) {
579       expert_add_info_format(pinfo, ti_anchor, PI_PROTOCOL, PI_ERROR, "computed length > max_field length");
580       length = max_field_length - length_size;
581     }
582   }
583
584   opaque_tree = proto_item_add_subtree(ti_anchor, ett_reload_opaque);
585   proto_tree_add_uint(opaque_tree, length_index, tvb, offset, length_size, (guint)length);
586   proto_tree_add_item(opaque_tree, hf_reload_opaque_data, tvb, offset + length_size, length, FALSE);
587
588   return (length_size + length);
589 }
590
591 static int
592 dissect_destination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
593 {
594   guint8 destination_length;
595   guint8 destination_type;
596
597   destination_type = tvb_get_guint8(tvb,offset);
598
599   if (destination_type & 0x80) {
600     /* simple compressed case */
601     destination_length = 2;
602     proto_tree_add_item(tree, hf_reload_destination_compressed, tvb, offset, 2, FALSE);
603     return 2;
604   }
605   else {
606     /* normal case */
607     proto_tree *destination_tree;
608     proto_item *ti_destination;
609
610     destination_length = tvb_get_guint8(tvb,offset+1);
611     ti_destination = proto_tree_add_item(tree, hf_reload_destination, tvb, offset, 2+destination_length, FALSE);
612     destination_tree = proto_item_add_subtree(ti_destination, ett_reload_destination);
613     proto_item_append_text(ti_destination, " (%s)", val_to_str(destination_type, destinationtypes, "Unknown"));
614
615     proto_tree_add_item(destination_tree, hf_reload_destination_type, tvb, offset, 1, FALSE);
616     proto_tree_add_uint(destination_tree, hf_reload_destination_length, tvb, offset+1, 1, destination_length);
617     if (2 + destination_length > length) {
618       expert_add_info_format(pinfo, ti_destination, PI_PROTOCOL, PI_ERROR, "Truncated destination field");
619       return length;
620     }
621     switch(destination_type) {
622     case DESTINATIONTYPE_NODE:
623       {
624         proto_item *ti_nodeid;
625         guint nodeid_length = destination_length;
626         /* We don't know the node ID. Just assume that all the data is part of it */
627         if (nodeid_length < reload_nodeid_length) {
628           expert_add_info_format(pinfo, ti_destination, PI_PROTOCOL, PI_ERROR, "truncated node id");
629         }
630         else {
631           nodeid_length = reload_nodeid_length;
632         }
633         ti_nodeid = proto_tree_add_item(destination_tree, hf_reload_nodeid, tvb, offset+ 2, nodeid_length, FALSE);
634         if ((nodeid_length < 16) || (nodeid_length > 20)) {
635           expert_add_info_format(pinfo, ti_nodeid, PI_PROTOCOL, PI_ERROR, "node id length is not in the correct range");
636         }
637       }
638       break;
639
640     case DESTINATIONTYPE_RESOURCE:
641       dissect_opaque(tvb, pinfo, destination_tree, hf_reload_resource_id, offset +2, 1, destination_length);
642       break;
643
644     case DESTINATIONTYPE_COMPRESSED:
645       dissect_opaque(tvb, pinfo, destination_tree, hf_reload_destination_data_compressed_id, offset+2, 1, destination_length);
646       break;
647     default:
648       break;
649     }
650   }
651   return (2+destination_length);
652 }
653
654
655 static int
656 dissect_destination_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *list_tree, guint16 offset, guint16 length)
657 {
658   gint local_offset = 0;
659   gint local_increment;
660   while (local_offset +2 <= length) {
661     local_increment = dissect_destination(tvb, pinfo, list_tree, offset + local_offset, length-local_offset);
662     if (local_increment == 0) break;
663     local_offset += local_increment;
664   }
665   return local_offset;
666 }
667
668 static int
669 dissect_probe_information(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
670 {
671   proto_item *ti_probe_information;
672   proto_tree *probe_information_tree;
673   guint8 type;
674   guint8 probe_length;
675
676   type = tvb_get_guint8(tvb, offset);
677   probe_length = tvb_get_guint8(tvb, offset + 1);
678
679   if (probe_length + 2 > length) {
680     ti_probe_information = proto_tree_add_item(tree, hf_reload_probe_information, tvb, offset, length, FALSE);
681     expert_add_info_format(pinfo, ti_probe_information, PI_PROTOCOL, PI_ERROR, "Truncated probe information");
682     return length;
683   }
684   ti_probe_information = proto_tree_add_item(tree, hf_reload_probe_information, tvb, offset, 2 + probe_length, FALSE);
685   probe_information_tree = proto_item_add_subtree(ti_probe_information, ett_reload_probe_information);
686
687   proto_tree_add_item(probe_information_tree, hf_reload_probe_information_type, tvb, offset, 1, FALSE);
688   proto_tree_add_uint(probe_information_tree, hf_reload_opaque_length_uint8, tvb, offset + 1, 1, probe_length);
689
690   switch(type) {
691   case   PROBEINFORMATIONTYPE_RESPONSIBLESET:
692     if (probe_length < 4) {
693       expert_add_info_format(pinfo, ti_probe_information, PI_PROTOCOL, PI_ERROR, "Truncated Responsible Set Info");
694       return 2 + probe_length;
695     }
696     proto_tree_add_item(probe_information_tree, hf_reload_responsible_set, tvb, offset + 2, 4, FALSE);
697     break;
698   case PROBEINFORMATIONTYPE_NUMRESOURCES:
699     if (probe_length < 4) {
700       expert_add_info_format(pinfo, ti_probe_information, PI_PROTOCOL, PI_ERROR, "Truncated Num Resource Info");
701       return 2 + probe_length;
702     }
703     proto_tree_add_item(probe_information_tree, hf_reload_num_resources, tvb, offset + 2, 4, FALSE);
704     break;
705   case PROBEINFORMATIONTYPE_UPTIME:
706     if (probe_length < 4) {
707       expert_add_info_format(pinfo, ti_probe_information, PI_PROTOCOL, PI_ERROR, "Truncated Uptime Info");
708       return 2 + probe_length;
709     }
710     proto_tree_add_item(probe_information_tree, hf_reload_uptime, tvb, offset + 2, 4, FALSE);
711     break;
712   default:
713     break;
714   }
715
716   return probe_length + 2;
717 }
718
719
720
721 static int
722 dissect_ipaddressport(tvbuff_t *tvb, proto_tree *tree, guint16 offset)
723 {
724   proto_item *ti_ipaddressport;
725   proto_tree *ipaddressport_tree;
726   guint8 ipaddressport_type;
727   guint8 ipaddressport_length;
728
729   ipaddressport_length = tvb_get_guint8(tvb, offset+1);
730   ti_ipaddressport = proto_tree_add_item(tree, hf_reload_ipaddressport, tvb, offset, ipaddressport_length+2, FALSE);
731   ipaddressport_type = tvb_get_guint8(tvb, offset);
732   proto_item_append_text(ti_ipaddressport, " %s ", val_to_str(ipaddressport_type, ipaddressporttypes,"Unknown Type"));
733   ipaddressport_tree = proto_item_add_subtree(ti_ipaddressport, ett_reload_ipaddressport);
734   proto_tree_add_item(ipaddressport_tree, hf_reload_ipaddressport_type, tvb, offset, 1, FALSE);
735   offset +=1;
736   proto_tree_add_uint(ipaddressport_tree, hf_reload_ipaddressport_length, tvb, offset, 1, ipaddressport_length);
737   offset +=1;
738   switch (ipaddressport_type) {
739   case IPADDRESSPORTTYPE_IPV4:
740     proto_tree_add_item(ipaddressport_tree, hf_reload_ipv4addr, tvb, offset, 4, FALSE);
741     proto_tree_add_item(ipaddressport_tree, hf_reload_port, tvb, offset + 4, 2, FALSE);
742     break;
743
744   case IPADDRESSPORTTYPE_IPV6:
745     proto_tree_add_item(ipaddressport_tree, hf_reload_ipv6addr, tvb, offset, 16, FALSE);
746     proto_tree_add_item(ipaddressport_tree, hf_reload_port, tvb, offset + 16, 2, FALSE);
747     break;
748
749   default:
750     break;
751   }
752
753   return (int) (2 + ipaddressport_length);
754 }
755
756 static int
757 dissect_icecandidates(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
758 {
759   proto_item *ti_icecandidates;
760   proto_tree *icecandidates_tree;
761   guint16 icecandidates_offset = 0;
762   guint16 icecandidates_length;
763   guint16 local_offset = 0;
764
765   icecandidates_length = tvb_get_ntohs(tvb, offset);
766   /* Precalculate the length of the icecandidate list */
767   if (2+icecandidates_length > length) {
768     ti_icecandidates = proto_tree_add_item(tree, hf_reload_icecandidates, tvb, offset, length, FALSE);
769     expert_add_info_format(pinfo, ti_icecandidates, PI_PROTOCOL, PI_ERROR, "Truncated Ice candidates");
770     return length;
771   }
772
773   ti_icecandidates = proto_tree_add_item(tree, hf_reload_icecandidates, tvb, offset, 2+icecandidates_length, FALSE);
774   icecandidates_tree = proto_item_add_subtree(ti_icecandidates, ett_reload_icecandidates);
775   proto_tree_add_uint(icecandidates_tree, hf_reload_icecandidates_length, tvb, offset+local_offset, 2, icecandidates_length);
776   local_offset += 2;
777   while (icecandidates_offset < icecandidates_length) {
778     proto_item *ti_icecandidate;
779     proto_tree *icecandidate_tree;
780     guint8 ipaddressport_length;
781     guint8 computed_ipaddressport_length;
782     guint16 iceextensions_length;
783     guint8 foundation_length;
784     guint8 candtype;
785     guint16 icecandidate_offset = 0;
786     /* compute the length */
787     ipaddressport_length = tvb_get_guint8(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset+1);
788     icecandidate_offset += 2 + ipaddressport_length;
789     icecandidate_offset += 1;/* OverlayLink */
790     foundation_length = tvb_get_guint8(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset);
791     icecandidate_offset += 1 + foundation_length;
792     icecandidate_offset += 4;/* priority */
793     candtype = tvb_get_guint8(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset);
794     icecandidate_offset += 1;/* candType */
795     computed_ipaddressport_length = 0;
796     switch (candtype) {
797     case CANDTYPE_HOST:
798       break;
799     case CANDTYPE_SRFLX:
800     case CANDTYPE_PRFLX:
801     case CANDTYPE_RELAY:
802       /* IpAddressPort */
803       computed_ipaddressport_length = tvb_get_guint8(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset+1);
804       icecandidate_offset += computed_ipaddressport_length+2;
805       break;
806     default:
807       break;
808     }
809
810     iceextensions_length = tvb_get_ntohs(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset);
811     icecandidate_offset += iceextensions_length + 2;
812
813     /* icecandidate_offset is now equal to the length of this icecandicate */
814     if (icecandidates_offset + icecandidate_offset > icecandidates_length) {
815       expert_add_info_format(pinfo, ti_icecandidates, PI_PROTOCOL, PI_ERROR, "Truncated ice candidate");
816       break;
817     }
818     ti_icecandidate = proto_tree_add_item(icecandidates_tree, hf_reload_icecandidate, tvb, offset+local_offset+ icecandidates_offset, icecandidate_offset, FALSE);
819     icecandidate_tree = proto_item_add_subtree(ti_icecandidate, ett_reload_icecandidate);
820     /* parse from start */
821     icecandidate_offset = 0;
822     dissect_ipaddressport(tvb, icecandidate_tree, offset+local_offset+icecandidates_offset+icecandidate_offset);
823     icecandidate_offset += 2 + ipaddressport_length;
824
825     proto_tree_add_item(icecandidate_tree, hf_reload_overlaylink_type, tvb,
826                         offset+local_offset+icecandidates_offset+icecandidate_offset, 1, FALSE);
827
828     icecandidate_offset += 1;
829     icecandidate_offset += dissect_opaque(tvb, pinfo,icecandidate_tree,  hf_reload_icecandidate_foundation,offset+local_offset+icecandidates_offset + icecandidate_offset, 1, -1);
830
831     {
832       guint32 priority;
833
834       priority = tvb_get_ntohl(tvb, offset+local_offset + icecandidates_offset);
835       proto_tree_add_item(icecandidate_tree, hf_reload_icecandidate_priority, tvb, offset+local_offset + icecandidates_offset, 4, FALSE);
836       icecandidate_offset += 4;
837       proto_tree_add_item(icecandidate_tree, hf_reload_icecandidate_type, tvb,
838                           offset+local_offset+icecandidates_offset+icecandidate_offset, 1, FALSE);
839       proto_item_append_text(ti_icecandidate, ": %s, priority=%d", val_to_str(candtype, candtypes, "Unknown"), priority);
840     }
841     icecandidate_offset += 1;
842     {
843       int item_index = -1;
844       switch (candtype) {
845       case CANDTYPE_HOST:
846         break;
847       case CANDTYPE_SRFLX:
848         item_index = hf_reload_icecandidate_srflx_addr;
849         break;
850       case CANDTYPE_PRFLX:
851         item_index = hf_reload_icecandidate_prflx_addr;
852         break;
853       case CANDTYPE_RELAY:
854         item_index = hf_reload_icecandidate_relay_addr;
855         break;
856
857       default:
858         break;
859       }
860       if (item_index != -1) {
861         proto_item *ti_computed_address;
862         proto_tree *computed_address_tree;
863         ti_computed_address =
864           proto_tree_add_item(icecandidate_tree, item_index, tvb,
865                               offset+local_offset+icecandidates_offset+icecandidate_offset, computed_ipaddressport_length + 2, FALSE);
866         computed_address_tree = proto_item_add_subtree(ti_computed_address, ett_reload_icecandidate_computed_address);
867         dissect_ipaddressport(tvb, computed_address_tree,
868                               offset+local_offset+icecandidates_offset+icecandidate_offset);
869         icecandidate_offset += computed_ipaddressport_length + 2;
870       }
871     }
872     /* Ice extensions */
873     {
874       guint16 iceextensions_offset = 0;
875       proto_item *ti_iceextension, *ti_iceextensions_length;
876       proto_tree *iceextension_tree;
877       guint16 iceextension_name_length;
878       guint16 iceextension_value_length;
879       ti_iceextensions_length =
880         proto_tree_add_uint(icecandidate_tree, hf_reload_icecandidate_extensions_length, tvb,
881                             offset+local_offset+icecandidates_offset+icecandidate_offset, 2,
882                             iceextensions_length);
883       icecandidate_offset += 2;
884       while (iceextensions_offset < iceextensions_length) {
885         iceextension_name_length =
886           tvb_get_ntohs(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset+iceextensions_offset);
887         iceextension_value_length =
888           tvb_get_ntohs(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset+iceextensions_offset+iceextension_name_length + 2);
889         if ((iceextensions_offset + 4 + iceextension_name_length + iceextension_value_length) > iceextensions_length) {
890           expert_add_info_format(pinfo, ti_iceextensions_length, PI_PROTOCOL, PI_ERROR, "Truncated ice extension");
891           break;
892         }
893         ti_iceextension =
894           proto_tree_add_item(icecandidate_tree, hf_reload_iceextension, tvb,
895                               offset+local_offset + icecandidates_offset + icecandidate_offset + iceextensions_offset, 4 + iceextension_name_length + iceextension_value_length, FALSE);
896         iceextension_tree = proto_item_add_subtree(ti_iceextension, ett_reload_iceextension);
897         proto_tree_add_item(iceextension_tree, hf_reload_iceextension_name, tvb,
898                             offset+local_offset+ icecandidates_offset + icecandidate_offset + iceextensions_offset, 2 + iceextension_name_length, FALSE);
899         proto_tree_add_item(iceextension_tree, hf_reload_iceextension_value, tvb,
900                             offset+local_offset + icecandidates_offset + icecandidate_offset + iceextensions_offset +2 + iceextension_name_length, 2 + iceextension_value_length, FALSE);
901         iceextensions_offset += 4 + iceextension_name_length + iceextension_value_length;
902       }
903     }
904     icecandidate_offset += iceextensions_length;
905     icecandidates_offset += icecandidate_offset;
906   }
907   return (2 + icecandidates_length);
908 }
909
910 static int
911 dissect_attachreqans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
912 {
913   proto_item *ti_attachreqans;
914   proto_tree *attachreqans_tree;
915   guint8 ufrag_length;
916   guint8 password_length;
917   guint8 role_length;
918   guint16 icecandidates_length;
919   guint16 local_offset = 0;
920
921   /* variable length structures: must 1st compute the length ... */
922   ufrag_length = tvb_get_guint8(tvb,offset+local_offset);
923   local_offset += 1;
924   if (local_offset + ufrag_length > length) {
925     ti_attachreqans = proto_tree_add_item(tree, hf_reload_attachreqans, tvb, offset, length, FALSE);
926     expert_add_info_format(pinfo, ti_attachreqans, PI_PROTOCOL, PI_ERROR, "Truncated attach_reqans");
927     return length;
928   }
929   local_offset += ufrag_length;
930   password_length = tvb_get_guint8(tvb,offset+local_offset);
931   local_offset += 1;
932   if (local_offset + password_length > length) {
933     ti_attachreqans = proto_tree_add_item(tree, hf_reload_attachreqans, tvb, offset, length, FALSE);
934     expert_add_info_format(pinfo, ti_attachreqans, PI_PROTOCOL, PI_ERROR, "Truncated attach_reqans");
935     return length;
936   }
937   local_offset += password_length;
938   role_length = tvb_get_guint8(tvb,offset+local_offset);
939   local_offset += 1;
940   if (local_offset + role_length > length) {
941     ti_attachreqans = proto_tree_add_item(tree, hf_reload_attachreqans, tvb, offset, length, FALSE);
942     expert_add_info_format(pinfo, ti_attachreqans, PI_PROTOCOL, PI_ERROR, "Truncated attach_reqans");
943     return length;
944   }
945   local_offset += role_length;
946   icecandidates_length = tvb_get_ntohs(tvb, offset+local_offset);
947   local_offset += 2;
948   if (local_offset +icecandidates_length > length) {
949     ti_attachreqans = proto_tree_add_item(tree, hf_reload_attachreqans, tvb, offset, length, FALSE);
950     expert_add_info_format(pinfo, ti_attachreqans, PI_PROTOCOL, PI_ERROR, "Truncated attach_reqans");
951     return length;
952   }
953   local_offset += icecandidates_length;
954
955   ti_attachreqans = proto_tree_add_item(tree, hf_reload_attachreqans, tvb, offset, local_offset, FALSE);
956   attachreqans_tree  = proto_item_add_subtree(ti_attachreqans, ett_reload_attachreqans);
957
958   /* restart parsing, field by field */
959   local_offset = 0;
960   local_offset += dissect_opaque(tvb, pinfo,attachreqans_tree, hf_reload_ufrag,offset+local_offset, 1, -1);
961   local_offset += dissect_opaque(tvb, pinfo,attachreqans_tree, hf_reload_password,offset+local_offset, 1, -1);
962   local_offset += dissect_opaque(tvb, pinfo,attachreqans_tree, hf_reload_role,offset+local_offset, 1, -1);
963   local_offset += dissect_icecandidates(tvb, pinfo, attachreqans_tree, offset + local_offset, 2+icecandidates_length);
964
965   proto_tree_add_item(attachreqans_tree, hf_reload_sendupdate, tvb, offset+local_offset, 1, FALSE);
966   local_offset += 1;
967
968   return local_offset;
969 }
970
971 static int
972 dissect_storeddata(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
973 {
974   proto_item *ti_storeddata;
975   proto_item *storeddata_tree;
976   guint32 storeddata_length;
977   guint32 local_offset = 0;
978
979   storeddata_length = tvb_get_ntohl(tvb, offset);
980   local_offset += 4;
981
982   if (storeddata_length + 4 > length) {
983     ti_storeddata = proto_tree_add_item(tree, hf_reload_storeddata, tvb, offset, length, FALSE);
984     expert_add_info_format(pinfo, ti_storeddata, PI_PROTOCOL, PI_ERROR, "Truncated storeddata");
985     return length;
986   }
987
988   local_offset = 0;
989   ti_storeddata = proto_tree_add_item(tree, hf_reload_storeddata, tvb, offset, 4 + storeddata_length, FALSE);
990   storeddata_tree = proto_item_add_subtree(ti_storeddata, ett_reload_storeddata);
991
992   proto_tree_add_uint(storeddata_tree, hf_reload_storeddata_length, tvb, offset + local_offset, 4, storeddata_length);
993   local_offset += 4;
994   proto_tree_add_item(storeddata_tree, hf_reload_storeddata_storage_time, tvb, offset + local_offset, 8, FALSE);
995   local_offset += 8;
996   proto_tree_add_item(storeddata_tree, hf_reload_storeddata_lifetime, tvb, offset + local_offset, 4, FALSE);
997   /* Can not parse the value and signature fields, as we do not know what is the data model for
998      a given kind id */
999   return (storeddata_length + 4);
1000 }
1001
1002 static int
1003 dissect_kinddata(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
1004 {
1005   proto_item *ti_kinddata;
1006   proto_item *kinddata_tree;
1007   guint32 values_length;
1008   guint32 local_offset = 0;
1009
1010   values_length = tvb_get_ntohl(tvb, offset + 4 + 8);
1011   if (12 + values_length > length) {
1012     ti_kinddata = proto_tree_add_item(tree, hf_reload_kinddata, tvb, offset, length, FALSE);
1013     expert_add_info_format(pinfo, ti_kinddata, PI_PROTOCOL, PI_ERROR, "Truncated kind data");
1014     return length;
1015   }
1016   ti_kinddata = proto_tree_add_item(tree, hf_reload_kinddata, tvb, offset, 12+values_length, FALSE);
1017   kinddata_tree = proto_item_add_subtree(ti_kinddata, ett_reload_kinddata);
1018
1019   proto_tree_add_item(kinddata_tree, hf_reload_kindid, tvb, offset+local_offset, 4, FALSE);
1020   local_offset += 4;
1021   proto_tree_add_item(kinddata_tree, hf_reload_kinddata_generation_counter, tvb, offset+local_offset, 8, FALSE);
1022   local_offset += 8;
1023   proto_tree_add_uint(kinddata_tree, hf_reload_kinddata_values_length, tvb, offset +local_offset, 4, values_length);
1024   local_offset += 4;
1025   {
1026     guint32 values_offset = 0;
1027     guint32 values_increment;
1028     while (values_offset < values_length) {
1029       values_increment = dissect_storeddata(tvb, pinfo, kinddata_tree, offset+local_offset+values_offset, values_length - values_offset);
1030       if (values_increment == 0) {
1031         break;
1032       }
1033       values_offset += values_increment;
1034     }
1035   }
1036   local_offset += values_length;
1037   return local_offset;
1038 }
1039
1040 static int
1041 dissect_storereq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
1042 {
1043   proto_item * ti_storereq;
1044   proto_tree * storereq_tree;
1045   guint32 local_offset = 0;
1046   guint32 kind_data_length;
1047
1048
1049   local_offset += get_opaque_length(tvb, offset, 1) + 1; /* resource id length */
1050   if (local_offset > length) {
1051     ti_storereq = proto_tree_add_item(tree, hf_reload_storereq, tvb, offset, length, FALSE);
1052     expert_add_info_format(pinfo, ti_storereq, PI_PROTOCOL, PI_ERROR, "Truncated storereq: resource too long");
1053     return length;
1054   }
1055
1056   local_offset += 1; /* replica_num */
1057   if (local_offset > length) {
1058     ti_storereq = proto_tree_add_item(tree, hf_reload_storereq, tvb, offset, length, FALSE);
1059     expert_add_info_format(pinfo, ti_storereq, PI_PROTOCOL, PI_ERROR, "Truncated storereq: no room for replica_number");
1060     return length;
1061   }
1062
1063   kind_data_length = tvb_get_ntohl(tvb, offset + local_offset);
1064   local_offset += 4;
1065   if (local_offset + kind_data_length > length) {
1066     ti_storereq = proto_tree_add_item(tree, hf_reload_storereq, tvb, offset, length, FALSE);
1067     expert_add_info_format(pinfo, ti_storereq, PI_PROTOCOL, PI_ERROR, "Truncated storereq: kind_date too long");
1068     return length;
1069   }
1070   local_offset += kind_data_length;
1071
1072   ti_storereq = proto_tree_add_item(tree, hf_reload_storereq, tvb, offset, local_offset, FALSE);
1073   storereq_tree = proto_item_add_subtree(ti_storereq, ett_reload_storereq);
1074
1075   /* Parse from start */
1076   local_offset = 0;
1077   local_offset += dissect_opaque(tvb, pinfo, storereq_tree, hf_reload_resource_id, offset +local_offset, 1, length);
1078   proto_tree_add_item(storereq_tree, hf_reload_store_replica_num, tvb, offset + local_offset, 1, FALSE);
1079   local_offset += 1;
1080   proto_tree_add_item(storereq_tree, hf_reload_store_kind_data_length, tvb, offset + local_offset, 4, FALSE);
1081   local_offset += 4;
1082   {
1083     guint32 kind_data_offset = 0;
1084     guint32 kind_data_increment;
1085     while (kind_data_offset < kind_data_length) {
1086       kind_data_increment = dissect_kinddata(tvb, pinfo, storereq_tree, offset+local_offset+kind_data_offset, kind_data_length - kind_data_offset);
1087       if (kind_data_increment == 0) {
1088         break;
1089       }
1090       kind_data_offset += kind_data_increment;
1091     }
1092   }
1093   local_offset += kind_data_length;
1094
1095   return local_offset;
1096 }
1097
1098 static int
1099 dissect_fetchans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
1100 {
1101   proto_item *ti_fetchans;
1102   proto_tree *fetchans_tree;
1103   guint32 kind_responses_length;
1104   guint32 kind_responses_offset = 0;
1105
1106   kind_responses_length = tvb_get_ntohl(tvb, offset);
1107   if (4 + kind_responses_length > length) {
1108     ti_fetchans = proto_tree_add_item(tree, hf_reload_fetchans, tvb, offset, length, FALSE);
1109     expert_add_info_format(pinfo, ti_fetchans, PI_PROTOCOL, PI_ERROR, "Truncated storereq");
1110     return length;
1111   }
1112   ti_fetchans = proto_tree_add_item(tree, hf_reload_fetchans, tvb, offset, 4 + kind_responses_length, FALSE);
1113   fetchans_tree = proto_item_add_subtree(ti_fetchans, ett_reload_fetchans);
1114
1115   proto_tree_add_uint(fetchans_tree, hf_reload_kind_responses_length, tvb, offset, 4, FALSE);
1116
1117   while (kind_responses_offset < kind_responses_length) {
1118     guint32 kind_responses_increment;
1119     kind_responses_increment = dissect_kinddata(tvb, pinfo, fetchans_tree, offset + 4 + kind_responses_offset, kind_responses_length - kind_responses_offset);
1120     if (kind_responses_increment == 0) {
1121       break;
1122     }
1123     kind_responses_offset += kind_responses_increment;
1124   }
1125
1126   return 4 + kind_responses_length;
1127 }
1128
1129
1130 static int
1131 dissect_statans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
1132 {
1133   proto_item *ti_statans;
1134   proto_tree *statans_tree;
1135   guint32 kind_responses_length;
1136   guint32 kind_responses_offset = 0;
1137
1138   kind_responses_length = tvb_get_ntohl(tvb, offset);
1139   if (4 + kind_responses_length > length) {
1140     ti_statans = proto_tree_add_item(tree, hf_reload_statans, tvb, offset, length, FALSE);
1141     expert_add_info_format(pinfo, ti_statans, PI_PROTOCOL, PI_ERROR, "Truncated statans");
1142     return length;
1143   }
1144   ti_statans = proto_tree_add_item(tree, hf_reload_statans, tvb, offset, 4 + kind_responses_length, FALSE);
1145   statans_tree = proto_item_add_subtree(ti_statans, ett_reload_statans);
1146
1147   proto_tree_add_uint(statans_tree, hf_reload_kind_responses_length, tvb, offset, 4, FALSE);
1148
1149   while (kind_responses_offset < kind_responses_length) {
1150     /* assume metadata is a form of stored data */
1151     guint32 kind_responses_increment;
1152     kind_responses_increment = dissect_kinddata(tvb, pinfo, statans_tree, offset + 4 + kind_responses_offset, kind_responses_length - kind_responses_offset);
1153     if (kind_responses_increment == 0) {
1154       break;
1155     }
1156     kind_responses_offset += kind_responses_increment;
1157   }
1158
1159   return 4 + kind_responses_length;
1160 }
1161
1162 static int
1163 dissect_reload_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1164 {
1165   proto_item *ti;
1166   proto_tree *reload_tree;
1167   guint32 relo_token;
1168   guint effective_length;
1169   guint msg_length;
1170   guint16 offset;
1171   conversation_t *conversation;
1172   reload_conv_info_t *reload_info;
1173   reload_transaction_t * reload_trans;
1174   emem_tree_key_t transaction_id_key[2];
1175   guint32 transaction_id[2];
1176   guint16 options_length;
1177   guint16 via_list_length;
1178   guint16 destination_list_length;
1179   guint16 message_code;
1180   guint16 error_code = 0;
1181   guint32 forwarding_length;
1182   proto_tree *reload_forwarding_tree;
1183   const char *msg_class_str;
1184   const char *msg_method_str = NULL;
1185   gboolean fragmented = FALSE;
1186   gboolean last_fragment = FALSE;
1187   fragment_data *reload_fd_head = NULL;
1188   gboolean save_fragmented;
1189   guint32 fragment = 0;
1190   gboolean update_col_info = TRUE;
1191
1192   offset = 0;
1193   effective_length = tvb_length(tvb);
1194
1195   /* First, make sure we have enough data to do the check. */
1196   if (effective_length < MIN_HDR_LENGTH)
1197     return 0;
1198
1199   /*
1200    * First check if the frame is really meant for us.
1201    */
1202   relo_token = tvb_get_ntohl(tvb,0);
1203
1204   if (relo_token != RELOAD_TOKEN) {
1205     return 0;
1206   }
1207
1208   msg_length = get_reload_message_length(pinfo, tvb, offset);
1209
1210   if (effective_length < msg_length) {
1211     /* The effective length is too small for the packet */
1212     expert_add_info_format(pinfo, NULL, PI_PROTOCOL, PI_ERROR, "Truncated RELOAD packet");
1213     return 0;
1214   }
1215
1216   /* The message seems to be a valid reLOAD message! */
1217
1218   col_set_str(pinfo->cinfo, COL_PROTOCOL, "RELOAD");
1219   col_clear(pinfo->cinfo, COL_INFO);
1220
1221   /* Create the transaction key which may be used to track the conversation */
1222   transaction_id[0] = tvb_get_ntohl(tvb, 20);
1223   transaction_id[1] = tvb_get_ntohl(tvb, 24);
1224
1225   transaction_id_key[0].length = 2;
1226   transaction_id_key[0].key =  transaction_id;
1227   transaction_id_key[1].length = 0;
1228   transaction_id_key[1].key = NULL;
1229
1230   via_list_length = tvb_get_ntohs(tvb, 32);
1231   destination_list_length = tvb_get_ntohs(tvb, 34);
1232   options_length = tvb_get_ntohs(tvb, 36);
1233
1234   forwarding_length = MIN_HDR_LENGTH + (via_list_length + destination_list_length + options_length);
1235
1236   message_code = tvb_get_ntohs(tvb, forwarding_length);
1237
1238   /* Do we already have a conversation ? */
1239   conversation = find_or_create_conversation(pinfo);
1240
1241   /*
1242    * Do we already have a state structure for this conv
1243    */
1244   reload_info = conversation_get_proto_data(conversation, proto_reload);
1245   if (!reload_info) {
1246     /* No.  Attach that information to the conversation, and add
1247      * it to the list of information structures.
1248      */
1249     reload_info = se_alloc(sizeof(reload_conv_info_t));
1250     reload_info->transaction_pdus = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "reload_transaction_pdus");
1251     conversation_add_proto_data(conversation, proto_reload, reload_info);
1252   }
1253
1254   if (!pinfo->fd->flags.visited) {
1255     if ((reload_trans =
1256          se_tree_lookup32_array(reload_info->transaction_pdus, transaction_id_key)) == NULL) {
1257       reload_trans = se_alloc(sizeof(reload_transaction_t));
1258       reload_trans->req_frame = 0;
1259       reload_trans->rep_frame = 0;
1260       reload_trans->req_time = pinfo->fd->abs_ts;
1261       se_tree_insert32_array(reload_info->transaction_pdus, transaction_id_key, (void *)reload_trans);
1262     }
1263
1264     /* check whether the message is a request or a response */
1265
1266     if (IS_REQUEST(message_code) && (message_code != ERROR)) {
1267       /* This is a request */
1268       if (reload_trans->req_frame == 0) {
1269         reload_trans->req_frame = pinfo->fd->num;
1270       }
1271     }
1272     else {
1273       /* This is a catch-all for all non-request messages */
1274       if (reload_trans->rep_frame == 0) {
1275         reload_trans->rep_frame = pinfo->fd->num;
1276       }
1277     }
1278   }
1279   else {
1280     reload_trans=se_tree_lookup32_array(reload_info->transaction_pdus, transaction_id_key);
1281   }
1282
1283   if (!reload_trans) {
1284     /* create a "fake" pana_trans structure */
1285     reload_trans = ep_alloc(sizeof(reload_transaction_t));
1286     reload_trans->req_frame = 0;
1287     reload_trans->rep_frame = 0;
1288     reload_trans->req_time = pinfo->fd->abs_ts;
1289   }
1290
1291   ti = proto_tree_add_item(tree, proto_reload, tvb, 0, -1, FALSE);
1292
1293   if (message_code == ERROR) {
1294     error_code = tvb_get_ntohs(tvb, forwarding_length + 2);
1295     msg_class_str = "ERROR Response";
1296     col_add_fstr(pinfo->cinfo, COL_INFO, " %s %s", msg_class_str, val_to_str(error_code, errorcodes, "Unknown"));
1297     proto_item_append_text(ti, ": %s %s", msg_class_str, val_to_str(error_code, errorcodes, "Unknown"));
1298   }
1299   else {
1300     msg_class_str = match_strval(MSGCODE_TO_CLASS(message_code), classes);
1301     msg_method_str = match_strval(MSGCODE_TO_METHOD(message_code), methods);
1302
1303     if (msg_method_str == NULL)
1304       msg_method_str = "Unknown";
1305
1306     col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
1307                  msg_method_str, msg_class_str);
1308     proto_item_append_text(ti, ": %s %s", msg_method_str, msg_class_str);
1309   }
1310
1311   reload_tree = proto_item_add_subtree(ti, ett_reload);
1312
1313   /* Retransmission control */
1314   if (IS_REQUEST(message_code) && (message_code != ERROR)) {
1315     if (reload_trans->req_frame != pinfo->fd->num) {
1316       proto_item *it;
1317       it = proto_tree_add_uint(reload_tree, hf_reload_duplicate, tvb, 0, 0, reload_trans->req_frame);
1318       PROTO_ITEM_SET_GENERATED(it);
1319     }
1320     if (reload_trans->rep_frame) {
1321       proto_item *it;
1322       it = proto_tree_add_uint(reload_tree, hf_reload_response_in, tvb, 0, 0, reload_trans->rep_frame);
1323       PROTO_ITEM_SET_GENERATED(it);
1324     }
1325   }
1326   else {
1327     /* This is a response */
1328     if (reload_trans->rep_frame != pinfo->fd->num) {
1329       proto_item *it;
1330       it = proto_tree_add_uint(reload_tree, hf_reload_duplicate, tvb, 0, 0, reload_trans->rep_frame);
1331       PROTO_ITEM_SET_GENERATED(it);
1332     }
1333
1334     if (reload_trans->req_frame) {
1335       proto_item *it;
1336       nstime_t ns;
1337
1338       it = proto_tree_add_uint(reload_tree, hf_reload_response_to, tvb, 0, 0, reload_trans->req_frame);
1339       PROTO_ITEM_SET_GENERATED(it);
1340
1341       nstime_delta(&ns, &pinfo->fd->abs_ts, &reload_trans->req_time);
1342       it = proto_tree_add_time(reload_tree, hf_reload_time, tvb, 0, 0, &ns);
1343       PROTO_ITEM_SET_GENERATED(it);
1344     }
1345   }
1346
1347   /*
1348    * Message dissection
1349    */
1350
1351   /*
1352    * Forwarding Header
1353    */
1354   ti = proto_tree_add_item(reload_tree, hf_reload_forwarding, tvb, 0, forwarding_length, FALSE);
1355   reload_forwarding_tree = proto_item_add_subtree(ti, ett_reload_forwarding);
1356
1357   proto_tree_add_uint(reload_forwarding_tree, hf_reload_token, tvb, 0, 4, relo_token);
1358   proto_tree_add_item(reload_forwarding_tree, hf_reload_overlay, tvb, 4, 4, FALSE);
1359   proto_tree_add_item(reload_forwarding_tree, hf_reload_configuration_sequence, tvb, 8, 2, FALSE);
1360   {
1361     guint8 version =
1362       tvb_get_guint8(tvb,10);
1363     proto_tree_add_uint_format_value(reload_forwarding_tree, hf_reload_version, tvb, 10, 1,
1364                                      version, "%u.%u", (version & 0xF0)>>4, (version & 0xF));
1365   }
1366   proto_tree_add_item(reload_forwarding_tree, hf_reload_ttl, tvb, 11, 1, FALSE);
1367   {
1368     proto_item *ti_fragment;
1369     proto_tree *fragment_tree;
1370     guint32 bit_offset;
1371
1372     fragment = tvb_get_ntohl(tvb,12);
1373
1374     ti_fragment = proto_tree_add_uint(reload_forwarding_tree, hf_reload_fragment_flag, tvb, 12, 4, fragment);
1375     fragment_tree = proto_item_add_subtree(ti_fragment, ett_reload_fragment_flag);
1376     bit_offset = (12) * 8;
1377
1378     if (fragment & 0x80000000) {
1379       proto_item_append_text(ti_fragment, " (Fragment)");
1380       fragmented = TRUE;
1381     }
1382     if (fragment & 0x40000000) {
1383       proto_item_append_text(ti_fragment, " (Last)");
1384       last_fragment = TRUE;
1385     }
1386     proto_tree_add_bits_item(fragment_tree, hf_reload_fragment_fragmented, tvb, bit_offset, 1, FALSE);
1387     proto_tree_add_bits_item(fragment_tree, hf_reload_fragment_last_fragment, tvb, bit_offset+1, 1, FALSE);
1388     proto_tree_add_bits_item(fragment_tree, hf_reload_fragment_reserved, tvb, bit_offset+2, 6, FALSE);
1389     fragment = fragment & 0x00ffffff;
1390     proto_tree_add_uint(fragment_tree, hf_reload_fragment_offset, tvb, 13, 3, fragment);
1391   }
1392
1393   /* msg_length is already parsed */
1394   proto_tree_add_uint(reload_forwarding_tree, hf_reload_length, tvb, 16, 4, msg_length);
1395   proto_tree_add_item(reload_forwarding_tree, hf_reload_trans_id, tvb, 20, 8, FALSE);
1396   proto_tree_add_item(reload_forwarding_tree, hf_reload_max_response_length, tvb, 28, 4, FALSE);
1397   /* variable lengths fields lengths are already parsed */
1398   proto_tree_add_uint(reload_forwarding_tree, hf_reload_via_list_length, tvb, 32, 2, via_list_length);
1399   proto_tree_add_uint(reload_forwarding_tree, hf_reload_destination_list_length, tvb, 34, 2, destination_list_length);
1400   proto_tree_add_uint(reload_forwarding_tree, hf_reload_options_length, tvb, 36, 2, options_length);
1401
1402   offset += MIN_HDR_LENGTH;
1403
1404   if (((guint)offset + via_list_length) > msg_length) {
1405     expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_ERROR, "Truncated RELOAD packet");
1406     return MIN_HDR_LENGTH;
1407   }
1408
1409   if (via_list_length > 0) {
1410     proto_item *ti_vialist;
1411     proto_tree *vialist_tree;
1412     ti_vialist = proto_tree_add_item(reload_forwarding_tree, hf_reload_via_list, tvb, offset, via_list_length, FALSE);
1413     vialist_tree = proto_item_add_subtree(ti_vialist, ett_reload_via_list);
1414
1415     dissect_destination_list(tvb, pinfo, vialist_tree, offset, via_list_length);
1416   }
1417   offset += via_list_length;
1418
1419   if (((guint)offset + destination_list_length) > msg_length) {
1420     expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_ERROR, "Truncated RELOAD packet");
1421     return offset;
1422   }
1423
1424   if (destination_list_length > 0) {
1425     proto_item *ti_destination_list;
1426     proto_tree *destination_list_tree;
1427     ti_destination_list = proto_tree_add_item(reload_forwarding_tree, hf_reload_destination_list, tvb, offset, destination_list_length, FALSE);
1428     destination_list_tree = proto_item_add_subtree(ti_destination_list, ett_reload_destination_list);
1429
1430     dissect_destination_list(tvb, pinfo, destination_list_tree, offset, destination_list_length);
1431   }
1432   offset += destination_list_length;
1433
1434   if (((guint)offset + options_length) > msg_length) {
1435     expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_ERROR, "Truncated RELOAD packet");
1436     return offset;
1437   }
1438
1439   if (options_length > 0) {
1440     guint16 local_offset = 0;
1441     while ((local_offset +4) <= options_length) {
1442       proto_item *ti_option;
1443       guint8 option_type = tvb_get_guint8(tvb,offset+local_offset);
1444       guint8 option_flags = tvb_get_guint8(tvb, offset+local_offset + 1);
1445       guint16 option_length = tvb_get_ntohs(tvb, offset+local_offset + 2);
1446       proto_tree *option_tree;
1447
1448       ti_option = proto_tree_add_item(reload_forwarding_tree, hf_reload_forwarding_option, tvb, offset+local_offset, option_length + 4, FALSE);
1449       proto_item_append_text(ti_option, " type=%s, flags=%02x, length=%d", val_to_str(option_type, forwardingoptiontypes, "Unknown"), option_flags, option_length);
1450
1451       option_tree = proto_item_add_subtree(ti_option, ett_reload_forwarding_option);
1452       proto_tree_add_item(option_tree, hf_reload_forwarding_option_type, tvb, offset+local_offset, 1, FALSE);
1453       {
1454         proto_item *ti_flags;
1455         proto_tree *flags_tree;
1456         guint32 bit_offset;
1457         ti_flags = proto_tree_add_uint(option_tree, hf_reload_forwarding_option_flags, tvb, offset+local_offset+1, 1, option_flags);
1458         flags_tree = proto_item_add_subtree(ti_flags, ett_reload_forwarding_option_flags);
1459         bit_offset = 8*(offset+local_offset+1);
1460         proto_tree_add_bits_item(flags_tree, hf_reload_forwarding_option_flag_response_copy, tvb, bit_offset+5, 1, FALSE);
1461         proto_tree_add_bits_item(flags_tree, hf_reload_forwarding_option_flag_destination_critical, tvb, bit_offset+6, 1, FALSE);
1462         proto_tree_add_bits_item(flags_tree, hf_reload_forwarding_option_flag_forward_critical, tvb, bit_offset+7, 1, FALSE);
1463       }
1464       proto_tree_add_uint(option_tree, hf_reload_forwarding_option_length, tvb, offset+local_offset+2, 2, option_length);
1465       local_offset += 4;
1466       if (local_offset + option_length > options_length) {
1467         expert_add_info_format(pinfo, ti_option, PI_PROTOCOL, PI_ERROR, "Bad option len");
1468         break;
1469       }
1470
1471       switch (option_type) {
1472       case OPTIONTYPE_DIRECTRESPONSEFORWARDING:
1473         {
1474           proto_item *ti_directresponseforwarding;
1475           proto_tree *directresponseforwarding_tree;
1476           guint16 option_offset = 0;
1477           ti_directresponseforwarding = proto_tree_add_item(option_tree, hf_reload_forwarding_option_directresponseforwarding, tvb, offset+local_offset, option_length, FALSE);
1478           directresponseforwarding_tree = proto_item_add_subtree(ti_directresponseforwarding, ett_reload_forwarding_option_directresponseforwarding);
1479           /* Connection_information handling */
1480           option_offset += dissect_attachreqans(tvb, pinfo, directresponseforwarding_tree, offset + local_offset + option_offset, option_length);
1481           /* requesting node */
1482           {
1483             guint nodeid_length = (guint) (option_length - option_offset);
1484             proto_item *ti_nodeid;
1485             if (reload_nodeid_length > nodeid_length) {
1486               expert_add_info_format(pinfo, ti_directresponseforwarding, PI_PROTOCOL, PI_ERROR, "nodeid length truncated");
1487             }
1488             else {
1489               nodeid_length = reload_nodeid_length;
1490             }
1491             ti_nodeid = proto_tree_add_item(option_tree, hf_reload_nodeid, tvb, offset+local_offset+option_offset, nodeid_length, FALSE);
1492             if ((nodeid_length < 16) || (nodeid_length > 20)) {
1493               expert_add_info_format(pinfo, ti_nodeid, PI_PROTOCOL, PI_ERROR, "node id length is not in the correct range");
1494             }
1495           }
1496         }
1497         break;
1498
1499       default:
1500         proto_tree_add_item(option_tree, hf_reload_forwarding_option_data, tvb, offset+local_offset, option_length, FALSE);
1501         break;
1502       }
1503       local_offset += option_length;
1504     }
1505   }
1506   offset += options_length;
1507
1508   save_fragmented = pinfo->fragmented;
1509   if ((reload_defragment) && ((fragmented != FALSE) && !((fragment == 0) && (last_fragment)))) {
1510     tvbuff_t   *next_tvb = NULL;
1511
1512     pinfo->fragmented = TRUE;
1513     if (tvb_bytes_exist(tvb, offset, msg_length - offset)) {
1514       fragment_add_check(tvb, offset, pinfo,
1515                          transaction_id[0]^transaction_id[1],
1516                          reload_fragment_table,
1517                          reload_reassembled_table,
1518                          fragment,
1519                          msg_length - offset,
1520                          !last_fragment);
1521
1522       next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled RELOAD",
1523                                           reload_fd_head, &reload_frag_items, &update_col_info, reload_tree);
1524     }
1525     if (next_tvb == NULL) {
1526       /* Just show this as a fragment. */
1527       col_add_fstr(pinfo->cinfo, COL_INFO, "Fragmented RELOAD protocol (trans id=%x%x off=%u)",
1528                    transaction_id[0],transaction_id[1], fragment);
1529       if (reload_fd_head && reload_fd_head->reassembled_in != pinfo->fd->num) {
1530         col_append_fstr(pinfo->cinfo, COL_INFO, " [Reassembled in #%u]",
1531                         reload_fd_head->reassembled_in);
1532       }
1533       call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1534       pinfo->fragmented = save_fragmented;
1535       return effective_length;
1536     }
1537     tvb = next_tvb;
1538     offset = 0;
1539   }
1540   else {
1541     pinfo->fragmented = FALSE;
1542   }
1543
1544
1545
1546   /* Message Contents */
1547   {
1548     guint32 message_body_length;
1549     guint32 extensions_length;
1550     proto_item *ti_message_contents;
1551     proto_tree *message_contents_tree;
1552
1553     message_body_length = tvb_get_ntohl(tvb, offset + 2);
1554     extensions_length = tvb_get_ntohl(tvb, offset + 2 + 4 + message_body_length);
1555     if (forwarding_length + 2 + 4 + message_body_length + 4 + extensions_length > msg_length) {
1556       ti_message_contents = proto_tree_add_item(reload_tree, hf_reload_message_contents, tvb, offset, (msg_length - forwarding_length), FALSE);
1557       expert_add_info_format(pinfo, ti_message_contents, PI_PROTOCOL, PI_ERROR, "truncated message contents");
1558       return msg_length;
1559     }
1560
1561     ti_message_contents = proto_tree_add_item(reload_tree, hf_reload_message_contents, tvb, offset, 2 + 4 + message_body_length + 4 + extensions_length, FALSE);
1562     message_contents_tree = proto_item_add_subtree(ti_message_contents, ett_reload_message_contents);
1563
1564     if (message_code != ERROR) {
1565       proto_item *ti_message_body;
1566       proto_tree *message_body_tree;
1567
1568       /* message_code was already parsed */
1569       proto_tree_add_uint_format_value(message_contents_tree, hf_reload_message_code, tvb,
1570                                        offset, 2,
1571                                        message_code,
1572                                        "%s-%s", msg_method_str, msg_class_str);
1573       offset += 2;
1574       /* Message body */
1575       ti_message_body = proto_tree_add_item(message_contents_tree, hf_reload_message_body, tvb, offset, 4 + message_body_length, FALSE);
1576       message_body_tree = proto_item_add_subtree(ti_message_body, ett_reload_message_body);
1577       proto_tree_add_uint(message_body_tree, hf_reload_opaque_length_uint32, tvb, offset, 4, message_body_length);
1578       offset +=4;
1579
1580       switch(MSGCODE_TO_METHOD(message_code)) {
1581       case METHOD_ROUTEQUERY:
1582         {
1583           if (IS_REQUEST(message_code)) {
1584             {
1585               proto_item * ti_routequeryreq;
1586               proto_tree * routequeryreq_tree;
1587               int destination_length;
1588               ti_routequeryreq = proto_tree_add_item(message_body_tree, hf_reload_routequeryreq, tvb, offset, message_body_length, FALSE);
1589               routequeryreq_tree = proto_item_add_subtree(ti_routequeryreq, ett_reload_routequeryreq);
1590               proto_tree_add_item(routequeryreq_tree, hf_reload_sendupdate, tvb, offset, 1, FALSE);
1591               destination_length = dissect_destination(tvb, pinfo, routequeryreq_tree, offset + 1, message_body_length - 1 - 2);
1592               dissect_opaque(tvb, pinfo, routequeryreq_tree, hf_reload_overlay_specific, offset + 1 + destination_length, 2, (message_body_length - 1 - destination_length));
1593             }
1594           }
1595           /* Answer is entirely Overlay-specific */
1596         }
1597         break;
1598
1599       case METHOD_PROBE:
1600         {
1601           if (IS_REQUEST(message_code)) {
1602             proto_item * ti_probereq;
1603             proto_tree * probereq_tree;
1604             guint8 info_list_length = 0;
1605             ti_probereq = proto_tree_add_item(message_body_tree, hf_reload_probereq, tvb, offset, message_body_length, FALSE);
1606             probereq_tree = proto_item_add_subtree(ti_probereq, ett_reload_probereq);
1607             info_list_length = tvb_get_guint8(tvb, offset);
1608
1609             proto_tree_add_uint(probereq_tree, hf_reload_opaque_length_uint8, tvb, offset, 1, info_list_length);
1610
1611             if (info_list_length > message_body_length - 1) {
1612               expert_add_info_format(pinfo, ti_probereq, PI_PROTOCOL, PI_ERROR, "requested info list too long for field size");
1613               info_list_length = message_body_length - 1;
1614             }
1615             {
1616               int probe_offset = 0;
1617               while (probe_offset < info_list_length) {
1618                 proto_tree_add_item(probereq_tree, hf_reload_probe_information_type, tvb, offset + 1 + probe_offset, 1, FALSE);
1619                 probe_offset += 1;
1620               }
1621             }
1622           }
1623           else {
1624             /* response */
1625             proto_item * ti_probeans;
1626             proto_tree * probeans_tree;
1627             guint16 info_list_length = 0;
1628
1629             ti_probeans = proto_tree_add_item(message_body_tree, hf_reload_probeans, tvb, offset, message_body_length, FALSE);
1630             probeans_tree = proto_item_add_subtree(ti_probeans, ett_reload_probeans);
1631             info_list_length = tvb_get_ntohs(tvb, offset);
1632
1633             proto_tree_add_uint(probeans_tree, hf_reload_opaque_length_uint16, tvb, offset, 2, info_list_length);
1634
1635             if (info_list_length > message_body_length - 2) {
1636               expert_add_info_format(pinfo, ti_probeans, PI_PROTOCOL, PI_ERROR, "requested info list too long for field size");
1637               info_list_length = message_body_length - 2;
1638             }
1639             {
1640               int probe_offset = 0;
1641               int probe_increment;
1642               while (probe_offset < info_list_length) {
1643                 probe_increment = dissect_probe_information(tvb, pinfo, probeans_tree, offset + 2 + probe_offset, info_list_length - probe_offset);
1644                 if (probe_increment == 0) {
1645                   break;
1646                 }
1647               probe_offset += probe_increment;
1648               }
1649             }
1650           }
1651         }
1652         break;
1653
1654       case METHOD_ATTACH:
1655         {
1656           dissect_attachreqans(tvb, pinfo, message_body_tree, offset, message_body_length);
1657         }
1658         break;
1659
1660       case METHOD_APPATTACH:
1661         {
1662           /* Parse AppAttachReq/Ans */
1663
1664           {
1665             guint16 local_offset = 0;
1666             proto_item *ti_appattach;
1667             proto_tree *appattach_tree;
1668             ti_appattach = proto_tree_add_item(message_body_tree, hf_reload_appattach, tvb, offset+local_offset, message_body_length, FALSE);
1669             appattach_tree  = proto_item_add_subtree(ti_appattach, ett_reload_appattach);
1670             local_offset += dissect_opaque(tvb, pinfo,appattach_tree, hf_reload_ufrag,offset+local_offset, 1, message_body_length-local_offset);
1671             local_offset += dissect_opaque(tvb, pinfo,appattach_tree, hf_reload_password,offset+local_offset, 1, message_body_length-local_offset);
1672             proto_tree_add_item(appattach_tree, hf_reload_application, tvb, offset+local_offset, 2, FALSE);
1673             local_offset += 2;
1674             local_offset += dissect_opaque(tvb, pinfo,appattach_tree, hf_reload_role,offset+local_offset, 1, message_body_length-local_offset);
1675             dissect_icecandidates(tvb, pinfo, appattach_tree, offset+local_offset, message_body_length-local_offset);
1676           }
1677         }
1678         break;
1679
1680       case METHOD_PING:
1681         {
1682           if (IS_REQUEST(message_code)) {
1683             dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_padding, offset, 2, message_body_length);
1684           }
1685           else {
1686             if (message_body_length < 16) {
1687               expert_add_info_format(pinfo, ti_message_contents, PI_PROTOCOL, PI_ERROR, "Truncated ping Answer");
1688             }
1689             else {
1690               proto_tree_add_item(message_body_tree, hf_reload_ping_response_id, tvb, offset, 8, FALSE);
1691               proto_tree_add_item(message_body_tree, hf_reload_ping_time, tvb, offset + 8, 8, FALSE);
1692             }
1693           }
1694         }
1695         break;
1696
1697       case METHOD_CONFIGUPDATE:
1698         {
1699           if (IS_REQUEST(message_code)) {
1700             guint16 local_offset = 0;
1701             proto_item *ti_configupdate;
1702             proto_tree *configupdate_tree;
1703             guint8 configupdate_type;
1704             guint32 configupdate_length;
1705             ti_configupdate = proto_tree_add_item(message_body_tree, hf_reload_configupdatereq, tvb, offset+local_offset, message_body_length, FALSE);
1706             configupdate_tree  = proto_item_add_subtree(ti_configupdate, ett_reload_configupdatereq);
1707             configupdate_type = tvb_get_guint8(tvb, offset + local_offset);
1708             proto_tree_add_uint(configupdate_tree, hf_reload_configupdatereq_type, tvb, offset+local_offset, 1, configupdate_type);
1709             local_offset += 1;
1710             configupdate_length = tvb_get_ntohl(tvb, offset + local_offset);
1711             proto_tree_add_uint(configupdate_tree, hf_reload_configupdatereq_length, tvb,  offset + local_offset, 4, configupdate_length);
1712             if (5 + configupdate_length > message_body_length) {
1713               expert_add_info_format(pinfo, ti_configupdate, PI_PROTOCOL, PI_ERROR, "Truncated ConfigUpdateReq");
1714               break;
1715             }
1716             local_offset += 4;
1717             switch(configupdate_type) {
1718             case CONFIGUPDATETYPE_CONFIG:
1719               local_offset +=
1720                 dissect_opaque(tvb, pinfo, configupdate_tree, hf_reload_configupdatereq_configdata,
1721                                offset + local_offset, 3, configupdate_length);
1722
1723               break;
1724
1725             case CONFIGUPDATETYPE_KIND:
1726               local_offset +=
1727                 dissect_opaque(tvb, pinfo, configupdate_tree, hf_reload_configupdatereq_kinds,
1728                                offset + local_offset, 3, configupdate_length);
1729               break;
1730             }
1731
1732           }
1733           break;
1734         }
1735
1736       case METHOD_STORE:
1737         {
1738           if (IS_REQUEST(message_code)) {
1739             dissect_storereq(tvb, pinfo, message_body_tree, offset, message_body_length);
1740           }
1741           else {
1742             guint16 storeans_kind_responses_length;
1743             guint32 local_offset = 0;
1744             proto_item *ti_storeans_kind_responses;
1745             proto_tree *storeans_kind_responses_tree;
1746             ti_storeans_kind_responses = proto_tree_add_item(message_body_tree, hf_reload_storeans_kind_responses, tvb, offset, message_body_length, FALSE);
1747             storeans_kind_responses_tree = proto_item_add_subtree(ti_storeans_kind_responses, ett_reload_storeans_kind_responses);
1748             storeans_kind_responses_length = tvb_get_ntohs(tvb, offset);
1749             proto_tree_add_uint(storeans_kind_responses_tree, hf_reload_storeans_kind_responses_length, tvb, offset, 2, storeans_kind_responses_length);
1750             if ((guint32)storeans_kind_responses_length + 2 > message_body_length) {
1751               expert_add_info_format(pinfo, ti_storeans_kind_responses, PI_PROTOCOL, PI_ERROR, "Truncated StoreAns");
1752               break;
1753             }
1754             while (local_offset + 4 + 8 + 2< storeans_kind_responses_length) {
1755               proto_item *ti_storekindresponse;
1756               proto_tree *storekindresponse_tree;
1757               guint16 replicas_length;
1758               replicas_length = tvb_get_ntohs(tvb, offset + 2 + local_offset +4 + 8);
1759               if (local_offset + 4/*kindId*/ + 8/*generationcounter*/ + 2 +replicas_length > storeans_kind_responses_length) {
1760                 expert_add_info_format(pinfo, ti_storeans_kind_responses, PI_PROTOCOL, PI_ERROR, "Truncated StoreKindResponse");
1761                 break;
1762               }
1763               ti_storekindresponse =
1764               proto_tree_add_item(storeans_kind_responses_tree, hf_reload_storekindresponse, tvb, offset+2+local_offset, 4+ 8 + 2 + replicas_length, FALSE);
1765               storekindresponse_tree = proto_item_add_subtree(ti_storekindresponse, ett_reload_storekindresponse);
1766               proto_tree_add_item(storekindresponse_tree, hf_reload_kindid, tvb, offset+2+local_offset, 4, FALSE);
1767               local_offset += 4;
1768               proto_tree_add_item(storekindresponse_tree, hf_reload_kinddata_generation_counter, tvb, offset+2+local_offset, 8, FALSE);
1769               local_offset += 8;
1770               {
1771                 guint16 replicas_length;
1772                 proto_item *ti_replicas;
1773                 proto_tree *replicas_tree;
1774                 guint16 replicas_offset = 0;
1775                 replicas_length = tvb_get_ntohs(tvb, offset + 2 + local_offset);
1776                 ti_replicas = proto_tree_add_item(storekindresponse_tree, hf_reload_storekindresponse_replicas, tvb,
1777                                                   offset+2+local_offset, 2 + replicas_length, FALSE);
1778                 replicas_tree = proto_item_add_subtree(storekindresponse_tree, ett_reload_storekindresponse_replicas);
1779                 proto_tree_add_uint(replicas_tree, hf_reload_opaque_length_uint16, tvb, offset + 2+local_offset, 2, replicas_length);
1780                 local_offset +=2;
1781                 while (replicas_offset < replicas_length) {
1782                   if ((replicas_offset + reload_nodeid_length) > replicas_length) {
1783                     expert_add_info_format(pinfo, ti_replicas, PI_PROTOCOL, PI_ERROR, "Truncated NodeId");
1784                     break;
1785                   }
1786                   proto_tree_add_item(replicas_tree, hf_reload_nodeid, tvb, offset+2+local_offset+replicas_offset,
1787                                       reload_nodeid_length, FALSE);
1788                   replicas_offset += reload_nodeid_length;
1789                 }
1790                 local_offset += replicas_length;
1791               }
1792             }
1793           }
1794         }
1795         break;
1796
1797       case METHOD_FETCH:
1798         {
1799           if (IS_REQUEST(message_code)) {
1800             guint16 fetch_offset = 0;
1801             fetch_offset += dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_resource_id, offset, 1, message_body_length);
1802             fetch_offset += dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_storeddataspecifiers, offset + fetch_offset,
1803                                            2, message_body_length - fetch_offset);
1804           }
1805           else {
1806             /* response */
1807             dissect_fetchans(tvb, pinfo, message_body_tree, offset, message_body_length);
1808           }
1809         }
1810         break;
1811
1812       case METHOD_STAT:
1813         {
1814           if (IS_REQUEST(message_code)) {
1815             guint16 stat_offset = 0;
1816             stat_offset += dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_resource_id, offset, 1, message_body_length);
1817             stat_offset += dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_storeddataspecifiers, offset + stat_offset,
1818                                           2, message_body_length - stat_offset);
1819           }
1820           else {
1821             dissect_statans(tvb, pinfo, message_body_tree, offset, message_body_length);
1822           }
1823
1824         }
1825         break;
1826
1827       case METHOD_FIND:
1828         {
1829           if (IS_REQUEST(message_code)) {
1830             guint32 find_offset = 0;
1831             guint8 kinds_length;
1832             find_offset += dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_resource_id, offset, 1, message_body_length);
1833             kinds_length = tvb_get_guint8(tvb, offset + find_offset);
1834             if (find_offset + 1 + kinds_length > message_body_length) {
1835               expert_add_info_format(pinfo, ti_message_body, PI_PROTOCOL, PI_ERROR, "Truncated FindRequest");
1836               break;
1837             }
1838             proto_tree_add_uint(message_body_tree, hf_reload_findreq_kinds_length, tvb, offset + find_offset, 1, kinds_length);
1839             find_offset += 1;
1840             {
1841               guint8 kinds_offset = 0;
1842               while (kinds_offset < kinds_length) {
1843                 proto_tree_add_item(message_body_tree, hf_reload_kindid, tvb, offset+find_offset+kinds_offset, 4, FALSE);
1844
1845                 kinds_offset += 4;
1846               }
1847             }
1848           }
1849           else {
1850             guint16 results_length;
1851
1852             results_length = tvb_get_ntohs(tvb, offset);
1853             if ((guint32)results_length + 2 > message_body_length) {
1854               expert_add_info_format(pinfo, ti_message_body, PI_PROTOCOL, PI_ERROR, "Truncated FindAnswer");
1855               break;
1856             }
1857             proto_tree_add_uint(message_body_tree, hf_reload_findans_results_length, tvb, offset, 2, results_length);
1858             {
1859               guint16 results_offset = 0;
1860               while (results_offset < results_length) {
1861                 proto_item *ti_findkinddata;
1862                 proto_tree *findkinddata_tree;
1863                 guint16 findkinddata_length;
1864                 findkinddata_length = 4/*kind id */ + 1 + get_opaque_length(tvb,offset + 2 + results_offset + 4, 1)/* resourceId */;
1865                 if (results_offset + findkinddata_length > results_length) {
1866                   ti_findkinddata = proto_tree_add_item(message_body_tree, hf_reload_findkinddata, tvb, offset + results_offset, results_length - results_offset, FALSE);
1867                   expert_add_info_format(pinfo, ti_findkinddata, PI_PROTOCOL, PI_ERROR, "Truncated FindKindData");
1868                   break;
1869                 }
1870                 ti_findkinddata = proto_tree_add_item(message_body_tree, hf_reload_findkinddata, tvb, offset + 2 + results_offset, findkinddata_length, FALSE);
1871                 findkinddata_tree = proto_item_add_subtree(ti_findkinddata, ett_reload_findkinddata);
1872
1873                 proto_tree_add_item(findkinddata_tree, hf_reload_kindid, tvb, offset + 2 + results_offset, 4, FALSE);
1874                 dissect_opaque(tvb, pinfo, findkinddata_tree, hf_reload_resource_id, offset + 2 + results_offset + 4, 1, results_length - 4 - results_offset);
1875
1876                 results_offset += findkinddata_length;
1877               }
1878             }
1879           }
1880         }
1881         break;
1882
1883       case METHOD_LEAVE:
1884       case METHOD_JOIN:
1885         {
1886           if (IS_REQUEST(message_code)) {
1887             proto_tree_add_item(message_body_tree, hf_reload_nodeid, tvb, offset, reload_nodeid_length, FALSE);
1888             dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_overlay_specific, offset + reload_nodeid_length, 2,
1889                            message_body_length - reload_nodeid_length);
1890           }
1891           else {
1892             dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_overlay_specific, offset, 2, message_body_length);
1893           }
1894         }
1895         break;
1896
1897       default:
1898         break;
1899       }
1900     }
1901     else {
1902       /* Error Response */
1903       guint16 error_length;
1904       proto_item *ti_message_body;
1905       proto_tree *message_body_tree;
1906       proto_item *ti_error;
1907       proto_tree *error_tree;
1908
1909       /* message_code was already parsed */
1910       proto_tree_add_uint_format_value(message_contents_tree, hf_reload_message_code, tvb, offset, 2, message_code, "ERROR Response");
1911       offset += 2;
1912
1913       /* Message body */
1914       ti_message_body = proto_tree_add_item(message_contents_tree, hf_reload_message_body, tvb, offset, 4 + message_body_length, FALSE);
1915       message_body_tree = proto_item_add_subtree(ti_message_body, ett_reload_message_body);
1916       proto_tree_add_uint(message_body_tree, hf_reload_opaque_length_uint32, tvb, offset, 4, message_body_length);
1917       offset +=4;
1918
1919       error_length = tvb_get_ntohs(tvb, offset + 2);
1920       if ((guint)offset + 2 + 2 + error_length > msg_length) {
1921         expert_add_info_format(pinfo, ti_message_body, PI_PROTOCOL, PI_ERROR, "truncated error message");
1922         return msg_length;
1923       }
1924
1925       ti_error = proto_tree_add_item(message_body_tree, hf_reload_error_response, tvb, offset, 2 + 2 + error_length, FALSE);
1926       error_tree = proto_item_add_subtree(ti_error, ett_reload_error_response);
1927       proto_tree_add_item(error_tree, hf_reload_error_response_code, tvb, offset, 2, FALSE);
1928       dissect_opaque(tvb, pinfo, error_tree, hf_reload_error_response_info, offset+2, 2, -1);
1929       proto_item_append_text(error_tree, ": %s (%s)", val_to_str(error_code, errorcodes, "Unknown"), tvb_get_ephemeral_string(tvb, offset+4, error_length));
1930     }
1931     offset += message_body_length;
1932     {
1933       proto_tree *extension_tree;
1934       guint16 extension_offset = 0;
1935
1936       proto_tree_add_item(message_contents_tree, hf_reload_message_extensions_length, tvb, offset, 4, FALSE);
1937       offset += 4;
1938       while (extension_offset < extensions_length) {
1939         proto_item *ti_extension;
1940         guint32 extension_content_length = tvb_get_ntohl(tvb, offset + extension_offset + 3);
1941         if ((extension_offset + 3 + 4 + extension_content_length) > extensions_length) {
1942           expert_add_info_format(pinfo, ti_message_contents, PI_PROTOCOL, PI_ERROR, "truncated message extensions");
1943           break;
1944         }
1945         ti_extension = proto_tree_add_item(message_contents_tree, hf_reload_message_extension, tvb, offset+ extension_offset, 3 + 4 + extension_content_length, FALSE);
1946         extension_tree = proto_item_add_subtree(ti_extension, ett_reload_message_extension);
1947         proto_tree_add_item(extension_tree, hf_reload_message_extension_type, tvb, offset+ extension_offset, 2, FALSE);
1948         proto_tree_add_item(extension_tree, hf_reload_message_extension_critical, tvb, offset+ extension_offset + 2, 1, FALSE);
1949           dissect_opaque(tvb, pinfo, extension_tree, hf_reload_message_extension_content, offset + extension_offset + 3, 4, -1);
1950           extension_offset += 3 + 4 + extension_content_length;
1951       }
1952     }
1953     offset += extensions_length;
1954   }
1955
1956   /* Security Block */
1957   {
1958     proto_item *ti_security_block;
1959     proto_tree *security_block_tree;
1960     guint16 certificates_length;
1961     guint16 signatureidentityvalue_length;
1962     guint16 signaturevalue_length;
1963     guint16 security_block_offset = 0;
1964
1965     certificates_length = tvb_get_ntohs(tvb, offset);
1966     security_block_offset += 2 + certificates_length;
1967     security_block_offset += 2; /* SignatureAndHashAlgorithm     algorithm; */
1968     security_block_offset += 1; /* SignerIdentityType     identity_type; */
1969     signatureidentityvalue_length = tvb_get_ntohs(tvb, offset +security_block_offset);
1970     security_block_offset += 2;
1971     security_block_offset += signatureidentityvalue_length;
1972     signaturevalue_length = tvb_get_ntohs(tvb, offset +security_block_offset);
1973     security_block_offset += 2;
1974     security_block_offset += signaturevalue_length;
1975
1976     ti_security_block = proto_tree_add_item(reload_tree, hf_reload_security_block, tvb, offset,
1977                                             security_block_offset, FALSE);
1978     security_block_tree = proto_item_add_subtree(ti_security_block, ett_reload_security_block);
1979     /* start parsing from the beginning */
1980     security_block_offset = 0;
1981     proto_tree_add_uint(security_block_tree, hf_reload_certificates_length, tvb, offset, 2, certificates_length);
1982     security_block_offset += 2;
1983     /* certificates */
1984     {
1985       guint16 certificate_offset = 0;
1986       while (certificate_offset < certificates_length) {
1987         proto_item *ti_certificate;
1988         proto_tree *certificate_tree;
1989         guint16 certificate_length;
1990
1991         certificate_length = tvb_get_ntohs(tvb, offset + security_block_offset + certificate_offset + 1);
1992         if (certificate_offset + 1 + 2 + certificate_length > certificates_length) {
1993           expert_add_info_format(pinfo, ti_security_block, PI_PROTOCOL, PI_ERROR, "truncated certificate");
1994           break;
1995         }
1996         ti_certificate = proto_tree_add_item(security_block_tree,
1997                                              hf_reload_certificates, tvb, offset + security_block_offset + certificate_offset,
1998                                              1 + 2 + certificate_length,
1999                                              FALSE);
2000         certificate_tree = proto_item_add_subtree(ti_certificate, ett_reload_certificate);
2001
2002         proto_tree_add_item(certificate_tree, hf_reload_certificate_type, tvb,
2003                             offset + security_block_offset + certificate_offset, 1, FALSE);
2004         switch (tvb_get_guint8(tvb, offset + security_block_offset + certificate_offset)) {
2005           case CERTIFICATETYPE_X509: {
2006             asn1_ctx_t asn1_ctx;
2007
2008             asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2009             dissect_x509af_Certificate(FALSE, tvb, offset + security_block_offset + certificate_offset + 1 + 2, &asn1_ctx,
2010                                        certificate_tree, hf_reload_certificate);
2011           }
2012           break;
2013
2014           default:
2015             dissect_opaque(tvb, pinfo, certificate_tree, hf_reload_certificate, offset + security_block_offset + certificate_offset + 1,
2016                            2, -1);
2017         }
2018         certificate_offset += 1 + 2 + certificate_length;
2019       }
2020     }
2021     security_block_offset += certificates_length;
2022
2023     /* Signature */
2024     {
2025       proto_item *ti_signature;
2026       proto_tree *signature_tree;
2027
2028       ti_signature = proto_tree_add_item(security_block_tree,
2029                                          hf_reload_signature, tvb, offset+security_block_offset ,
2030                                          2 +/* SignatureAndHashAlgorithm */
2031                                          1 + 2 + signatureidentityvalue_length +/* SignatureIdenty length*/
2032                                          2 + signaturevalue_length,
2033                                          FALSE);
2034       signature_tree = proto_item_add_subtree(ti_signature, ett_reload_signature);
2035       proto_tree_add_item(signature_tree, hf_reload_hash_algorithm, tvb,
2036                                  offset + security_block_offset, 1, FALSE);
2037       security_block_offset += 1;
2038       proto_tree_add_item(signature_tree, hf_reload_signature_algorithm, tvb,
2039                                  offset + security_block_offset, 1, FALSE);
2040       security_block_offset += 1;
2041       /* SignatureIdentity */
2042       {
2043         proto_item *ti_signatureidentity;
2044         proto_tree *signatureidentity_tree;
2045         guint8 identity_type;
2046         ti_signatureidentity = proto_tree_add_item(signature_tree,
2047                                                    hf_reload_signature_identity,
2048                                                    tvb, offset+security_block_offset,
2049                                                    1 + 2 + signatureidentityvalue_length,
2050                                                    FALSE);
2051         signatureidentity_tree = proto_item_add_subtree(ti_signatureidentity, ett_reload_signature_identity);
2052         identity_type = tvb_get_guint8(tvb, offset + security_block_offset);
2053         proto_tree_add_item(signatureidentity_tree, hf_reload_signature_identity_type, tvb,
2054                             offset + security_block_offset, 1, FALSE);
2055         security_block_offset += 1;
2056         proto_tree_add_uint(signatureidentity_tree, hf_reload_signature_identity_length, tvb,
2057                             offset + security_block_offset, 2, signatureidentityvalue_length);
2058         security_block_offset += 2;
2059         {
2060           guint16 signatureidentityvalue_offset = 0;
2061           while (signatureidentityvalue_offset < signatureidentityvalue_length) {
2062             proto_item *ti_signatureidentityvalue;
2063             proto_tree *signatureidentityvalue_tree;
2064             if (identity_type == SIGNATUREIDENTITYTYPE_CERTHASH) {
2065               guint8 certificate_hash_length;
2066
2067               certificate_hash_length = tvb_get_guint8(tvb, offset + security_block_offset + signatureidentityvalue_offset + 1);
2068               if (signatureidentityvalue_offset + 1 + 1 + certificate_hash_length > signatureidentityvalue_length) {
2069                 expert_add_info_format(pinfo, ti_signatureidentity, PI_PROTOCOL, PI_ERROR, "truncated signature identity value");
2070                 break;
2071               }
2072               ti_signatureidentityvalue= proto_tree_add_item(signatureidentity_tree,
2073                                                              hf_reload_signature_identity_value,
2074                                                              tvb, offset + security_block_offset + signatureidentityvalue_offset,
2075                                                              1 + 1 + certificate_hash_length,
2076                                                              FALSE);
2077               signatureidentityvalue_tree = proto_item_add_subtree(ti_signatureidentityvalue, ett_reload_signature_identity_value);
2078               proto_tree_add_item(signatureidentityvalue_tree, hf_reload_hash_algorithm, tvb,
2079                                   offset + security_block_offset +signatureidentityvalue_offset, 1, FALSE);
2080               dissect_opaque(tvb, pinfo, signatureidentityvalue_tree, hf_reload_signature_identity_value_certificate_hash, offset + security_block_offset + signatureidentityvalue_offset+1, 1, -1);
2081               signatureidentityvalue_offset += 1 + 1 + certificate_hash_length;
2082             }
2083             else {
2084               expert_add_info_format(pinfo, ti_signatureidentity, PI_PROTOCOL, PI_ERROR, "Unknown identity type");
2085               break;
2086             }
2087           }
2088         }
2089         security_block_offset += signatureidentityvalue_length;
2090       }
2091       dissect_opaque(tvb, pinfo, signature_tree, hf_reload_signature_value, offset + security_block_offset, 2, -1);
2092     }
2093   }
2094
2095
2096   return msg_length;
2097 }
2098
2099 static int
2100 dissect_reload_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2101 {
2102   return dissect_reload_message(tvb, pinfo, tree);
2103 }
2104
2105 static void
2106 dissect_reload_message_no_return(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2107 {
2108   dissect_reload_message(tvb, pinfo, tree);
2109 }
2110
2111 static void
2112 dissect_reload_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2113 {
2114   tcp_dissect_pdus(tvb, pinfo, tree, TRUE, MIN_HDR_LENGTH,
2115                    get_reload_message_length, dissect_reload_message_no_return);
2116 }
2117
2118 static gboolean
2119 dissect_reload_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2120 {
2121   if (dissect_reload_message(tvb, pinfo, tree) == 0) {
2122     /*
2123      * It wasn't a valid RELOAD message, and wasn't
2124      * dissected as such.
2125      */
2126     return FALSE;
2127   }
2128   return TRUE;
2129 }
2130
2131 void
2132 proto_register_reload(void)
2133 {
2134   module_t *reload_module;
2135   static hf_register_info hf[] = {
2136     { &hf_reload_response_in,
2137       { "Response In",  "reload.response-in", FT_FRAMENUM,
2138         BASE_NONE, NULL, 0x0, "The response to this RELOAD Request is in this frame", HFILL }
2139     },
2140     { &hf_reload_response_to,
2141       { "Request In", "reload.response-to", FT_FRAMENUM,
2142         BASE_NONE, NULL, 0x0, "This is a response to the RELOAD Request in this frame", HFILL }
2143     },
2144     { &hf_reload_time,
2145       { "Time", "reload.time", FT_RELATIVE_TIME,
2146         BASE_NONE, NULL, 0x0, "The time between the Request and the Response", HFILL }
2147     },
2148     { &hf_reload_duplicate,
2149       { "Duplicated original message in", "reload.duplicate", FT_FRAMENUM,
2150         BASE_NONE, NULL, 0x0, "This is a duplicate of RELOAD message in this frame", HFILL }
2151     },
2152     { &hf_reload_forwarding,
2153       { "Forwarding Header",    "reload.forwarding",  FT_NONE,
2154         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2155     },
2156     { &hf_reload_token,
2157       { "RELOAD token", "reload.forwarding.token",  FT_UINT32,
2158         BASE_HEX, NULL, 0x0,  NULL, HFILL }
2159     },
2160     { &hf_reload_overlay,
2161       { "Overlay",  "reload.forwarding.overlay",  FT_UINT32,
2162         BASE_HEX, NULL, 0x0,  NULL, HFILL }
2163     },
2164     { &hf_reload_configuration_sequence,
2165       { "Configuration Sequence", "reload.forwarding.configuration_sequence", FT_UINT16,
2166         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2167     },
2168     { &hf_reload_version,
2169       { "Version",  "reload.forwarding.version",  FT_UINT8,
2170         BASE_HEX, NULL, 0x0,  NULL, HFILL }
2171     },
2172     { &hf_reload_ttl,
2173       { "TTL",  "reload.forwarding.ttl",  FT_UINT8,
2174         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2175     },
2176     { &hf_reload_fragment_flag,
2177       { "Fragment", "reload.forwarding.fragment", FT_UINT32,
2178         BASE_HEX, NULL, 0x0,  NULL, HFILL }
2179     },
2180     { &hf_reload_fragment_fragmented,
2181       { "Fragmented Bit", "reload.forwarding.fragment.fragmented", FT_BOOLEAN, 1, TFS(&tfs_set_notset), 0x0,
2182         NULL, HFILL }
2183     },
2184     { &hf_reload_fragment_last_fragment,
2185       { "Last fragment bit", "reload.forwarding.fragment.last", FT_BOOLEAN, 1, TFS(&tfs_set_notset), 0x0,
2186         NULL, HFILL }
2187     },
2188     { &hf_reload_fragment_reserved,
2189       { "Reserved", "reload.forwarding.fragment.reserved", FT_BOOLEAN, 1, NULL, 0x0,
2190         NULL, HFILL }
2191     },
2192     { &hf_reload_fragment_offset,
2193       { "Fragment offset","reload.forwarding.fragment.offset",  FT_UINT32,
2194         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2195     },
2196     { &hf_reload_length,
2197       { "Length", "reload.forwarding.length", FT_UINT32,
2198         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2199     },
2200     { &hf_reload_trans_id,
2201       { "Transaction ID", "reload.forwarding.trans_id", FT_UINT64,
2202         BASE_HEX, NULL, 0x0,  NULL, HFILL }
2203     },
2204     { &hf_reload_max_response_length,
2205       { "Max response length",  "reload.forwarding.max_response_length",  FT_UINT32,
2206         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2207     },
2208     { &hf_reload_via_list_length,
2209       { "Via-list length",  "reload.forwarding.via_list.length",  FT_UINT16,
2210         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2211     },
2212     { &hf_reload_destination_list_length,
2213       { "Destination list length",  "reload.forwarding.destination_list.length",  FT_UINT16,
2214         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2215     },
2216     { &hf_reload_options_length,
2217       { "Options length", "reload.forwarding.options.length", FT_UINT16,
2218         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2219     },
2220     { &hf_reload_via_list,
2221       { "via list",   "reload.forwarding.via_list", FT_NONE,
2222         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2223     },
2224     { &hf_reload_destination,
2225       { "Destination",    "reload.forwarding.destination",  FT_NONE,
2226         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2227     },
2228     { &hf_reload_destination_compressed,
2229       { "Destination (compressed)", "reload.forwarding.destination.compressed_id",  FT_UINT16,
2230         BASE_HEX, NULL,   0x0,  NULL, HFILL }
2231     },
2232     { &hf_reload_destination_type,
2233       { "Destination type",    "reload.forwarding.destination.type",  FT_UINT8,
2234         BASE_HEX, VALS(destinationtypes), 0x0,  NULL, HFILL }
2235     },
2236     { &hf_reload_destination_length,
2237       { "Destination length",   "reload.forwarding.destination.length", FT_UINT8,
2238         BASE_DEC, NULL,   0x0,  NULL, HFILL }
2239     },
2240     { &hf_reload_nodeid,
2241       { "node id",    "reload.nodeid", FT_BYTES,
2242         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2243     },
2244     { &hf_reload_resource_id,
2245       { "resource id",    "reload.resource_id", FT_NONE,
2246         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2247     },
2248     { &hf_reload_destination_data_compressed_id,
2249       { "compressed id",    "reload.destination.data.compressed_id",  FT_BYTES,
2250         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2251     },
2252     { &hf_reload_destination_list,
2253       { "destination list",   "reload.forwarding.destination_list", FT_NONE,
2254         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2255     },
2256     { &hf_reload_forwarding_option,
2257       { "forwarding option",    "reload.forwarding.option", FT_NONE,
2258         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2259     },
2260     { &hf_reload_forwarding_option_type,
2261       { "forwarding option type", "reload.forwarding.option.type",  FT_UINT8,
2262         BASE_DEC, VALS(forwardingoptiontypes),  0x0,  NULL, HFILL }
2263     },
2264     { &hf_reload_forwarding_option_flags,
2265       { "forwarding option flags",  "reload.forwarding.option.flags", FT_UINT8,
2266         BASE_HEX, NULL, 0x0,  NULL, HFILL }
2267     },
2268     { &hf_reload_forwarding_option_length,
2269       { "forwarding option length", "forwarding.option.length", FT_UINT16,
2270         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2271     },
2272     { &hf_reload_forwarding_option_data,
2273       { "forwarding option data", "reload.forwarding.option.data",  FT_BYTES,
2274         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2275     },
2276     { &hf_reload_forwarding_option_flag_response_copy,
2277       { "Response Copy", "reload.forwarding.option.flag.response_copy", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x0,
2278         NULL, HFILL }
2279     },
2280     { &hf_reload_forwarding_option_flag_destination_critical,
2281       { "Response destination critical", "reload.forwarding.option.flags.destination_critical", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x0,
2282         NULL, HFILL }
2283     },
2284     { &hf_reload_forwarding_option_flag_forward_critical,
2285       { "Forward Critical", "reload.forwarding.option.flags.forward_critical", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x0,
2286         NULL, HFILL }
2287     },
2288     { &hf_reload_forwarding_option_directresponseforwarding,
2289       { "Direct Response Forwarding", "reload.forwarding.option.direct_response_forwarding",  FT_NONE,
2290         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2291     },
2292     { &hf_reload_attachreqans,
2293       { "AttachReqAns", "reload.attachreqans",  FT_NONE,
2294         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2295     },
2296     { &hf_reload_ufrag,
2297       { "ufrag",  "reload.ufrag", FT_BYTES,
2298         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2299     },
2300     { &hf_reload_password,
2301       { "password", "reload.password",  FT_BYTES,
2302         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2303     },
2304     { &hf_reload_role,
2305       { "Role", "reload.role",  FT_BYTES,
2306         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2307     },
2308     { &hf_reload_icecandidates,
2309       { "ice candidates",   "reload.icecandidates", FT_NONE,
2310         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2311     },
2312     { &hf_reload_icecandidates_length,
2313       { "ice candidates length",  "reload.icecandidates.length",  FT_UINT16,
2314         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2315     },
2316     { &hf_reload_icecandidate,
2317       { "ice candidate",    "reload.icecandidate",  FT_NONE,
2318         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2319     },
2320     { &hf_reload_icecandidate_relay_addr,
2321       { "relay address",    "reload.icecandidate.relay_addr", FT_NONE,
2322         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2323     },
2324     { &hf_reload_icecandidate_srflx_addr,
2325       { "srflx address",    "reload.icecandidate.srflx_addr", FT_NONE,
2326         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2327     },
2328     { &hf_reload_icecandidate_prflx_addr,
2329       { "prfkx address",    "reload.icecandidate.prflx_addr", FT_NONE,
2330         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2331     },
2332     { &hf_reload_ipaddressport,
2333       { "Ip Address Port",    "reload.ipaddressport", FT_NONE,
2334         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2335     },
2336     { &hf_reload_ipaddressport_type,
2337       { "Ip Address-Port Type", "reload.ipaddressport.type",  FT_UINT8,
2338         BASE_HEX, VALS(ipaddressporttypes), 0x0,  NULL, HFILL }
2339     },
2340     { &hf_reload_ipaddressport_length,
2341       { "Ip Address-Port Length", "reload.ipaddressport.length",  FT_UINT8,
2342         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2343     },
2344     { &hf_reload_ipv4addr,
2345       { "Ipv4 Address", "reload.ipv4addr",  FT_IPv4,
2346         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2347     },
2348     { &hf_reload_ipv6addr,
2349       { "Ipv6 Address", "reload.ipv6addr",  FT_IPv6,
2350         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2351     },
2352     { &hf_reload_port,
2353       { "port", "reload.port",  FT_UINT16,
2354         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2355     },
2356     { &hf_reload_overlaylink_type,
2357       { "Overlay Link Type",  "reload.overlaylink.type",  FT_UINT8,
2358         BASE_DEC, VALS(overlaylinktypes), 0x0,  NULL, HFILL }
2359     },
2360     { &hf_reload_icecandidate_foundation,
2361       { "Ice Candidate foundation", "reload.icecandidate.foundation", FT_BYTES,
2362         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2363     },
2364     { &hf_reload_icecandidate_priority,
2365       { "Ice Candidate Priority", "reload.icecandidate.priority", FT_UINT32,
2366         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2367     },
2368     { &hf_reload_icecandidate_type,
2369       { "Ice Candidate type", "reload.icecandidate.type", FT_UINT8,
2370         BASE_DEC, VALS(candtypes),  0x0,  NULL, HFILL }
2371     },
2372     { &hf_reload_icecandidate_extensions_length,
2373       { "Ice Candidate Extensions Length",  "reload.icecandidate.extensions_length",  FT_UINT16,
2374         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2375     },
2376     { &hf_reload_iceextension,
2377       { "ice Extension",    "reload.iceextension",  FT_NONE,
2378         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2379     },
2380     { &hf_reload_iceextension_name,
2381       { "Ice Extension Name", "reload.iceextension.name", FT_BYTES,
2382         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2383     },
2384     { &hf_reload_iceextension_value,
2385       { "Ice Extension Value",  "reload.iceextension.value",  FT_BYTES,
2386         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2387     },
2388     { &hf_reload_sendupdate,
2389       { "SendUpdate", "reload.sendupdate",  FT_BOOLEAN,
2390         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2391     },
2392     { &hf_reload_message_contents,
2393       { "message contents",   "reload.message.contents",  FT_NONE,
2394         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2395     },
2396     { &hf_reload_message_code,
2397       { "Message Code", "reload.message.code",  FT_UINT16,
2398         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2399     },
2400     { &hf_reload_message_body,
2401       { "Message Body", "reload.message.body",  FT_BYTES,
2402         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2403     },
2404     { &hf_reload_message_extensions_length,
2405       { "Message extensions length",  "reload.message.extensions.length", FT_UINT16,
2406         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2407     },
2408     { &hf_reload_message_extension,
2409       { "message extension",    "reload.message_extension", FT_NONE,
2410         BASE_NONE,  NULL,   0x0,  NULL, HFILL }
2411     },
2412     { &hf_reload_message_extension_type,
2413       { "Message extension type", "reload.message_extension.type",  FT_UINT16,
2414         BASE_DEC, VALS(messageextensiontypes), 0x0,  NULL, HFILL }
2415     },
2416     { &hf_reload_message_extension_critical,
2417       { "Message extension critical", "reload.message_extension.critical",  FT_BOOLEAN,
2418         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2419     },
2420     { &hf_reload_message_extension_content,
2421       { "Message extension content",  "reload.message_extension.content", FT_BYTES,
2422         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2423     },
2424     { &hf_reload_error_response,
2425       { "error response", "reload.error_response",  FT_NONE,
2426         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2427     },
2428     { &hf_reload_error_response_code,
2429       { "error code", "reload.error_response.code", FT_UINT16,
2430         BASE_DEC, VALS(errorcodes), 0x0,  NULL, HFILL }
2431     },
2432     { &hf_reload_error_response_info,
2433       { "error info", "reload.error_response_info", FT_BYTES,
2434         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2435     },
2436     { &hf_reload_security_block,
2437       { "Security Block", "reload.security_block",  FT_NONE,
2438         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2439     },
2440     { &hf_reload_certificates_length,
2441       { "Certificates Length",  "reload.certificates.length", FT_UINT16,
2442         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2443     },
2444     { &hf_reload_certificates,
2445       { "Certificates",  "reload.certificates", FT_NONE,
2446         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2447     },
2448     { &hf_reload_certificate_type,
2449       { "Certificate Type", "reload.certificate.type",  FT_UINT8,
2450         BASE_DEC, VALS(certificatetypes), 0x0,  NULL, HFILL }
2451     },
2452     { &hf_reload_certificate,
2453       { "Certificate", "reload.certificate",  FT_NONE,
2454         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2455     },
2456     { &hf_reload_signature,
2457       { "Signature",  "reload.signature", FT_NONE,
2458         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2459     },
2460     { &hf_reload_hash_algorithm,
2461       { "Hash Algorithm", "reload.hash_algorithm",  FT_UINT8,
2462         BASE_DEC, VALS(tls_hash_algorithm), 0x0,  NULL, HFILL }
2463     },
2464     { &hf_reload_signature_algorithm,
2465       { "Signature Algorithm",  "reload.signature_algorithm", FT_UINT8,
2466         BASE_DEC, VALS(tls_signature_algorithm),  0x0,  NULL, HFILL }
2467     },
2468     { &hf_reload_signature_identity,
2469       { "Signature Identity", "reload.signature.identity",  FT_NONE,
2470         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2471     },
2472     { &hf_reload_signature_identity_type,
2473       { "Signature Identity Type",  "reload.signature.identity.type", FT_UINT8,
2474         BASE_DEC, VALS(signatureidentitytypes), 0x0,  NULL, HFILL }
2475     },
2476     { &hf_reload_signature_identity_length,
2477       { "Signature Identity Length",  "reload.signature.identity.length", FT_UINT16,
2478         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2479     },
2480     { &hf_reload_signature_identity_value,
2481       { "Signature Identity Value", "reload.signature.identity.value",  FT_NONE,
2482         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2483     },
2484     { &hf_reload_signature_identity_value_certificate_hash,
2485       { "Signature Identity Value Certificate Hash",  "reload.signature.identity.value.certificate_hash", FT_BYTES,
2486         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2487     },
2488     { &hf_reload_signature_value,
2489       { "Signature Value",  "reload.signature.value.",  FT_BYTES,
2490         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2491     },
2492     { &hf_reload_opaque_length_uint8,
2493       { "length", "reload.opaque.length.8", FT_UINT8,
2494         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2495     },
2496     { &hf_reload_opaque_length_uint16,
2497       { "length", "reload.opaque.length.6", FT_UINT16,
2498         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2499     },
2500     { &hf_reload_opaque_length_uint32,
2501       { "length", "reload.opaque.length.32",  FT_UINT32,
2502         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2503     },
2504     { &hf_reload_opaque_data,
2505       { "data", "reload.opaque.length.8", FT_BYTES,
2506         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2507     },
2508     { &hf_reload_routequeryreq,
2509       { "RouteQueryReq",  "reload.routequeryreq", FT_NONE,
2510         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2511     },
2512     { &hf_reload_overlay_specific,
2513       { "Overlay Specific Data",  "reload.overlay.specific.data", FT_NONE,
2514         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2515     },
2516     { &hf_reload_probereq,
2517       { "ProbeReq", "reload.probereq",  FT_NONE,
2518         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2519     },
2520     { &hf_reload_probe_information,
2521       { "Probe Information",  "reload.probe_information", FT_NONE,
2522         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2523     },
2524     { &hf_reload_probe_information_type,
2525       { "Probe Information Type", "reload.probe_information.type", FT_UINT8,
2526         BASE_HEX, VALS(probeinformationtypes),  0x0,  NULL, HFILL }
2527     },
2528     { &hf_reload_responsible_set,
2529       { "Responsible Set",  "reload.responsible_set", FT_UINT32,
2530         BASE_HEX, NULL, 0x0,  NULL, HFILL }
2531     },
2532     { &hf_reload_num_resources,
2533       { "Num Resources",  "reload.num_resources", FT_UINT32,
2534         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2535     },
2536     { &hf_reload_uptime,
2537       { "Uptime", "reload.uptime", FT_UINT32,
2538         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2539     },
2540     { &hf_reload_probeans,
2541       { "Probe Ans",  "reload.probeans", FT_NONE,
2542         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2543     },
2544     { &hf_reload_appattach,
2545       { "App Attach Req/Ans", "reload.appattach", FT_NONE,
2546         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2547     },
2548     { &hf_reload_application,
2549       { "Application", "reload.application", FT_UINT16,
2550         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2551     },
2552     { &hf_reload_ping_response_id,
2553       { "Ping Response Id", "reload.ping.response_id",  FT_UINT64,
2554         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2555     },
2556     { &hf_reload_ping_time,
2557       { "Ping Time",  "reload.ping.time", FT_UINT64,
2558         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2559     },
2560     { &hf_reload_storeddata,
2561       { "Stored Data",  "reload.storeddata", FT_NONE,
2562         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2563     },
2564     { &hf_reload_storeddata_length,
2565       { "Stored Data length", "reload.storeddata.length", FT_UINT32,
2566         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2567     },
2568     { &hf_reload_storeddata_storage_time,
2569       { "Stored Data storage time", "reload.storeddata.storage_time", FT_UINT64,
2570         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2571     },
2572     { &hf_reload_storeddata_lifetime,
2573       { "Stored Lifetime",  "reload.storeddata.lifetime", FT_UINT32,
2574         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2575     },
2576     { &hf_reload_kinddata,
2577       { "Kind Data",  "reload.kinddata", FT_NONE,
2578         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2579     },
2580     { &hf_reload_kindid,
2581       { "Kind Id",  "reload.kindid",  FT_UINT32,
2582         BASE_DEC, VALS(datakindids),  0x0,  NULL, HFILL }
2583     },
2584     { &hf_reload_kinddata_generation_counter,
2585       { "Generation Counter", "reload.kinddata.generation_counter", FT_UINT64,
2586         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2587     },
2588     { &hf_reload_kinddata_values_length,
2589       { "Values Length",  "reload.kinddata.values_length",  FT_UINT32,
2590         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2591     },
2592     { &hf_reload_storereq,
2593       { "StoreReq", "reload.storereq", FT_NONE,
2594         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2595     },
2596     { &hf_reload_store_replica_num,
2597       { "replica num",  "reload.store.replica_num", FT_UINT8,
2598         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2599     },
2600     { &hf_reload_store_kind_data_length,
2601       { "StoreReq Kind Data Length",  "reload.store.kind_data.length",  FT_UINT32,
2602         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2603     },
2604     { &hf_reload_storeans_kind_responses,
2605       { "Kind Responses", "reload.storeans.kind_responses", FT_NONE,
2606         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2607     },
2608     { &hf_reload_storeans_kind_responses_length,
2609       { "Kind Responses Length", "reload.storeans.kind_responses.length", FT_UINT16,
2610         BASE_DEC,  NULL, 0x0,  NULL, HFILL }
2611     },
2612     { &hf_reload_storekindresponse,
2613       { "Store Kind Response", "reload.storekindresponse", FT_NONE,
2614         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2615     },
2616     { &hf_reload_storekindresponse_replicas,
2617       { "Store Kind Response Replicas", "reload.storekindresponse.replicas", FT_NONE,
2618         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2619     },
2620     { &hf_reload_storeddataspecifiers,
2621       { "StoredDataSpecifiers", "reload.storeddataspecifiers", FT_NONE,
2622         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2623     },
2624     { &hf_reload_fetchans,
2625       { "FetchAns", "reload.fetchans", FT_NONE,
2626         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2627     },
2628     { &hf_reload_kind_responses_length,
2629       { "Kind Responses Length", "reload.fetchans.kind_responses.length", FT_UINT32,
2630         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2631     },
2632     { &hf_reload_statans,
2633       { "StatAns",  "reload.statans", FT_NONE,
2634         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2635     },
2636     { &hf_reload_findreq_kinds_length,
2637       { "Kinds Length", "reload.findreq.kindslength", FT_UINT8,
2638         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2639     },
2640     { &hf_reload_findans_results_length,
2641       { "Results Length", "reload.findans.resultsslength", FT_UINT16,
2642         BASE_DEC, NULL, 0x0,  NULL, HFILL }
2643     },
2644     { &hf_reload_findkinddata,
2645       { "FindKindData", "reload.findkinddata", FT_NONE,
2646         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2647     },
2648     { &hf_reload_fragment_overlap,
2649       { "Fragment overlap", "reload.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2650         "Fragment overlaps with other fragments", HFILL }},
2651
2652     { &hf_reload_fragment_overlap_conflict,
2653       { "Conflicting data in fragment overlap", "reload.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2654         "Overlapping fragments contained conflicting data", HFILL }},
2655
2656     { &hf_reload_fragment_multiple_tails,
2657       { "Multiple tail fragments found",  "reload.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2658         "Several tails were found when defragmenting the packet", HFILL }},
2659
2660     { &hf_reload_fragment_too_long_fragment,
2661       { "Fragment too long",  "reload.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2662         "Fragment contained data past end of packet", HFILL }},
2663
2664     { &hf_reload_fragment_error,
2665       { "Defragmentation error", "reload.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2666         "Defragmentation error due to illegal fragments", HFILL }},
2667
2668     { &hf_reload_fragment_count,
2669       { "Fragment count", "reload.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
2670         NULL, HFILL}},
2671
2672     { &hf_reload_fragment,
2673       { "RELOAD Fragment", "reload.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2674         NULL, HFILL }},
2675
2676     { &hf_reload_fragments,
2677       { "RELOAD Fragments", "reload.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2678         NULL, HFILL }},
2679
2680     { &hf_reload_reassembled_in,
2681       { "Reassembled RELOAD in frame", "reload.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2682         "This RELOAD packet is reassembled in this frame", HFILL }},
2683
2684     { &hf_reload_reassembled_length,
2685       { "Reassembled RELOAD length", "reload.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
2686         "The total length of the reassembled payload", HFILL}},
2687
2688     { &hf_reload_configupdatereq,
2689       { "ConfigUpdate Req",  "reload.configupdatereq.",  FT_BYTES,
2690         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2691     },
2692
2693     { &hf_reload_configupdatereq_type,
2694       { "ConfigUpdate Req Type", "reload.configupdatereq.type", FT_UINT8,
2695         BASE_DEC, VALS(configupdatetypes),  0x0,  NULL, HFILL }
2696     },
2697
2698     { &hf_reload_configupdatereq_length,
2699       { "ConfigUpdate Req Length", "reload.configupdatereq.length", FT_UINT32,
2700         BASE_DEC, NULL,  0x0,  NULL, HFILL }
2701     },
2702
2703     { &hf_reload_configupdatereq_configdata,
2704       { "ConfigUpdate Req Config Data",  "reload.configupdatereq.config_data",  FT_NONE,
2705         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2706     },
2707
2708     { &hf_reload_configupdatereq_kinds,
2709       { "ConfigUpdate Req Kinds",  "reload.configupdatereq.kinds",  FT_NONE,
2710         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2711     },
2712
2713     { &hf_reload_padding,
2714       { "padding",  "reload.padding",  FT_NONE,
2715         BASE_NONE,  NULL, 0x0,  NULL, HFILL }
2716     },
2717
2718   };
2719
2720   /* Setup protocol subtree array */
2721   static gint *ett[] = {
2722     &ett_reload,
2723     &ett_reload_forwarding,
2724     &ett_reload_message,
2725     &ett_reload_security,
2726     &ett_reload_fragment_flag,
2727     &ett_reload_destination,
2728     &ett_reload_via_list,
2729     &ett_reload_destination_list,
2730     &ett_reload_forwarding_option,
2731     &ett_reload_forwarding_option_flags,
2732     &ett_reload_forwarding_option_directresponseforwarding,
2733     &ett_reload_attachreqans,
2734     &ett_reload_icecandidates,
2735     &ett_reload_icecandidate,
2736     &ett_reload_icecandidate_computed_address,
2737     &ett_reload_iceextension,
2738     &ett_reload_ipaddressport,
2739     &ett_reload_message_contents,
2740     &ett_reload_message_extension,
2741     &ett_reload_error_response,
2742     &ett_reload_security_block,
2743     &ett_reload_certificate,
2744     &ett_reload_signature,
2745     &ett_reload_signature_identity,
2746     &ett_reload_signature_identity_value,
2747     &ett_reload_opaque,
2748     &ett_reload_message_body,
2749     &ett_reload_routequeryreq,
2750     &ett_reload_probereq,
2751     &ett_reload_probe_information,
2752     &ett_reload_probeans,
2753     &ett_reload_appattach,
2754     &ett_reload_storeddata,
2755     &ett_reload_kinddata,
2756     &ett_reload_storereq,
2757     &ett_reload_storeans_kind_responses,
2758     &ett_reload_storekindresponse,
2759     &ett_reload_fetchans,
2760     &ett_reload_statans,
2761     &ett_reload_findkinddata,
2762     &ett_reload_fragments,
2763     &ett_reload_fragment,
2764     &ett_reload_configupdatereq,
2765     &ett_reload_storekindresponse_replicas,
2766   };
2767
2768   /* Register the protocol name and description */
2769   proto_reload = proto_register_protocol("REsource LOcation And Discovery", "RELOAD", "reload");
2770   register_dissector("reload", dissect_reload_message_no_return, proto_reload);
2771   /* Required function calls to register the header fields and subtrees used */
2772   proto_register_field_array(proto_reload, hf, array_length(hf));
2773   proto_register_subtree_array(ett, array_length(ett));
2774
2775   reload_module = prefs_register_protocol(proto_reload, NULL);
2776   prefs_register_bool_preference(reload_module, "defragment",
2777                                  "Reassemble fragmented reload datagrams",
2778                                  "Whether fragmented RELOAD datagrams should be reassembled",
2779                                  &reload_defragment);
2780   prefs_register_uint_preference(reload_module, "nodeid_length",
2781                                  "NodeId Length",
2782                                  "Length of the NodeId as defined in the overlay.",
2783                                  10,
2784                                  &reload_nodeid_length);
2785
2786
2787   register_init_routine(reload_defragment_init);
2788 }
2789
2790 void
2791 proto_reg_handoff_reload(void)
2792 {
2793
2794   dissector_handle_t reload_tcp_handle;
2795   dissector_handle_t reload_udp_handle;
2796
2797   reload_tcp_handle = create_dissector_handle(dissect_reload_tcp, proto_reload);
2798   reload_udp_handle = new_create_dissector_handle(dissect_reload_udp, proto_reload);
2799
2800   data_handle = find_dissector("data");
2801
2802   heur_dissector_add("udp", dissect_reload_heur, proto_reload);
2803   heur_dissector_add("tcp", dissect_reload_heur, proto_reload);
2804
2805 }
2806
2807 /*
2808  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2809  *
2810  * Local variables:
2811  * c-basic-offset: 2
2812  * tab-width: 2
2813  * indent-tabs-mode: nil
2814  * End:
2815  *
2816  * vi: set shiftwidth=2 tabstop=2 expandtab
2817  * :indentSize=2:tabSize=2:noTabs=true:
2818  */