1 /* packet-rpki-rtr.c
2  * Routines for RPKI-Router Protocol dissection (RFC6810)
3  * Copyright 2013, Alexis La Goutte <alexis.lagoutte at gmail dot com>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10 
11  * The information used comes from:
12  * RFC6810: The Resource Public Key Infrastructure (RPKI) to Router Protocol
13  */
14 
15 #include "config.h"
16 
17 #include <epan/packet.h>
18 #include <epan/prefs.h>
19 #include "packet-tcp.h"
20 #include "packet-tls.h"
21 #include <epan/expert.h>
22 #include <epan/asn1.h>
23 #include "packet-x509af.h"
24 
25 void proto_register_rpkirtr(void);
26 void proto_reg_handoff_rpkirtr(void);
27 
28 static int proto_rpkirtr = -1;
29 static int hf_rpkirtr_version = -1;
30 static int hf_rpkirtr_pdu_type = -1;
31 static int hf_rpkirtr_reserved = -1;
32 static int hf_rpkirtr_session_id = -1;
33 static int hf_rpkirtr_length = -1;
34 static int hf_rpkirtr_serial_number = -1;
35 static int hf_rpkirtr_flags = -1;
36 static int hf_rpkirtr_flags_aw = -1;
37 static int hf_rpkirtr_flags_rk = -1;
38 static int hf_rpkirtr_prefix_length = -1;
39 static int hf_rpkirtr_max_length = -1;
40 static int hf_rpkirtr_ipv4_prefix = -1;
41 static int hf_rpkirtr_ipv6_prefix = -1;
42 static int hf_rpkirtr_as_number = -1;
43 static int hf_rpkirtr_error_code = -1;
44 static int hf_rpkirtr_length_pdu = -1;
45 static int hf_rpkirtr_error_pdu = -1;
46 static int hf_rpkirtr_length_text = -1;
47 static int hf_rpkirtr_error_text = -1;
48 static int hf_rpkirtr_refresh_interval = -1;
49 static int hf_rpkirtr_retry_interval = -1;
50 static int hf_rpkirtr_expire_interval = -1;
51 static int hf_rpkirtr_subject_key_identifier = -1;
52 static int hf_rpkirtr_subject_public_key_info = -1;
53 
54 #define RPKI_RTR_TCP_PORT 323
55 #define RPKI_RTR_TLS_PORT 324
56 static guint g_port_rpkirtr_tls = RPKI_RTR_TLS_PORT;
57 
58 static gint ett_rpkirtr = -1;
59 static gint ett_flags   = -1;
60 static gint ett_flags_nd = -1;
61 
62 static expert_field ei_rpkirtr_wrong_version_router_key = EI_INIT;
63 static expert_field ei_rpkirtr_bad_length = EI_INIT;
64 
65 static dissector_handle_t rpkirtr_handle;
66 
67 
68 /* http://www.iana.org/assignments/rpki/rpki.xml#rpki-rtr-pdu */
69 #define RPKI_RTR_SERIAL_NOTIFY_PDU   0
70 #define RPKI_RTR_SERIAL_QUERY_PDU    1
71 #define RPKI_RTR_RESET_QUERY_PDU     2
72 #define RPKI_RTR_CACHE_RESPONSE_PDU  3
73 #define RPKI_RTR_IPV4_PREFIX_PDU     4
74 #define RPKI_RTR_IPV6_PREFIX_PDU     6
75 #define RPKI_RTR_END_OF_DATA_PDU     7
76 #define RPKI_RTR_CACHE_RESET_PDU     8
77 #define RPKI_RTR_ROUTER_KEY          9
78 #define RPKI_RTR_ERROR_REPORT_PDU   10
79 
80 static const value_string rtr_pdu_type_vals[] = {
81     { RPKI_RTR_SERIAL_NOTIFY_PDU,  "Serial Notify" },
82     { RPKI_RTR_SERIAL_QUERY_PDU,   "Serial Query" },
83     { RPKI_RTR_RESET_QUERY_PDU,    "Reset Query" },
84     { RPKI_RTR_CACHE_RESPONSE_PDU, "Cache Response" },
85     { RPKI_RTR_IPV4_PREFIX_PDU,    "IPv4 Prefix" },
86     { RPKI_RTR_IPV6_PREFIX_PDU,    "IPv6 Prefix" },
87     { RPKI_RTR_END_OF_DATA_PDU,    "End of Data" },
88     { RPKI_RTR_CACHE_RESET_PDU,    "Cache Reset" },
89     { RPKI_RTR_ROUTER_KEY,         "Router Key" },
90     { RPKI_RTR_ERROR_REPORT_PDU,   "Error Report" },
91     { 0, NULL }
92 };
93 
94 /* http://www.iana.org/assignments/rpki/rpki.xml#rpki-rtr-error */
95 static const value_string rtr_error_code_vals[] = {
96     { 0, "Corrupt Data" },
97     { 1, "Internal Error" },
98     { 2, "No Data Available" },
99     { 3, "Invalid Request" },
100     { 4, "Unsupported Protocol Version" },
101     { 5, "Unsupported PDU Type" },
102     { 6, "Withdrawal of Unknown Record" },
103     { 7, "Duplicate Announcement Received" },
104     { 8, "Unexpected Protocol Version" },
105     { 0, NULL }
106 };
107 
108 static const true_false_string tfs_flag_type_aw = {
109     "Announcement",
110     "Withdrawal"
111 };
112 
113 static const true_false_string tfs_flag_type_rk = {
114     "New Router Key",
115     "Delete Router Key"
116 };
117 
118 static guint
get_rpkirtr_pdu_len(packet_info * pinfo _U_,tvbuff_t * tvb,int offset,void * data _U_)119 get_rpkirtr_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
120 {
121   guint32 plen;
122 
123   /*
124   * Get the length of the RPKI-RTR packet.
125   */
126   plen = tvb_get_ntohl(tvb, offset+4);
127 
128   return plen;
129 }
130 
131 
dissect_rpkirtr_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)132 static int dissect_rpkirtr_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
133 {
134 
135     proto_item *ti = NULL, *ti_flags, *ti_type;
136     proto_tree *rpkirtr_tree = NULL, *flags_tree = NULL;
137     int offset = 0;
138     guint8 pdu_type, version;
139     guint length;
140 
141     while (tvb_reported_length_remaining(tvb, offset) > 0) {
142 
143         ti = proto_tree_add_item(tree, proto_rpkirtr, tvb, 0, -1, ENC_NA);
144 
145         rpkirtr_tree = proto_item_add_subtree(ti, ett_rpkirtr);
146 
147         proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_version, tvb, offset, 1, ENC_BIG_ENDIAN);
148         version = tvb_get_guint8(tvb, offset);
149         offset += 1;
150 
151         ti_type = proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN);
152         pdu_type = tvb_get_guint8(tvb, offset);
153         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(pdu_type, rtr_pdu_type_vals, "Unknown (%d)"));
154         proto_item_append_text(ti, " (%s)", val_to_str(pdu_type, rtr_pdu_type_vals, "Unknown %d"));
155         offset += 1;
156 
157         length = tvb_get_ntohl(tvb, offset);
158 
159         switch (pdu_type) {
160             case RPKI_RTR_SERIAL_NOTIFY_PDU: /* Serial Notify (0) */
161             case RPKI_RTR_SERIAL_QUERY_PDU:  /* Serial Query (1)  */
162                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_session_id,       tvb, offset, 2, ENC_BIG_ENDIAN);
163                 offset += 2;
164                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_length,           tvb, offset, 4, ENC_BIG_ENDIAN);
165                 /* TODO: Add check length ? */
166                 offset += 4;
167                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_serial_number,    tvb, offset, 4, ENC_BIG_ENDIAN);
168                 offset += 4;
169                 break;
170             case RPKI_RTR_RESET_QUERY_PDU:  /* Reset Query (2) */
171             case RPKI_RTR_CACHE_RESET_PDU:  /* Cache Reset (8) */
172                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_reserved,         tvb, offset, 2, ENC_NA);
173                 offset += 2;
174                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_length,           tvb, offset, 4, ENC_BIG_ENDIAN);
175                 /* TODO: Add check length ? */
176                 offset += 4;
177                 break;
178             case RPKI_RTR_CACHE_RESPONSE_PDU:  /* Cache Response (3) */
179                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_session_id,       tvb, offset, 2, ENC_BIG_ENDIAN);
180                 offset += 2;
181                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_length,           tvb, offset, 4, ENC_BIG_ENDIAN);
182                 /* TODO: Add check length ? */
183                 offset += 4;
184                 break;
185             case RPKI_RTR_IPV4_PREFIX_PDU: /* IPv4 Prefix (4) */
186                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_reserved,         tvb, offset, 2, ENC_NA);
187                 offset += 2;
188                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_length,           tvb, offset, 4, ENC_BIG_ENDIAN);
189                 /* TODO: Add check length ? */
190                 offset += 4;
191                 ti_flags = proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
192                 flags_tree = proto_item_add_subtree(ti_flags, ett_flags);
193                 proto_tree_add_item(flags_tree, hf_rpkirtr_flags_aw,           tvb, offset, 1, ENC_BIG_ENDIAN);
194                 offset += 1;
195                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_prefix_length,    tvb, offset, 1, ENC_BIG_ENDIAN);
196                 offset += 1;
197                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_max_length,       tvb, offset, 1, ENC_BIG_ENDIAN);
198                 offset += 1;
199                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_reserved,         tvb, offset, 1, ENC_NA);
200                 offset += 1;
201                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_ipv4_prefix,      tvb, offset, 4, ENC_BIG_ENDIAN);
202                 offset += 4;
203                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_as_number,        tvb, offset, 4, ENC_BIG_ENDIAN);
204                 offset += 4;
205                 break;
206             case RPKI_RTR_IPV6_PREFIX_PDU: /* IPv6 Prefix (6) */
207                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_reserved,         tvb, offset, 2, ENC_NA);
208                 offset += 2;
209                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_length,           tvb, offset, 4, ENC_BIG_ENDIAN);
210                 /* TODO: Add check length ? */
211                 offset += 4;
212                 ti_flags = proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
213                 flags_tree = proto_item_add_subtree(ti_flags, ett_flags);
214                 proto_tree_add_item(flags_tree, hf_rpkirtr_flags_aw,           tvb, offset, 1, ENC_BIG_ENDIAN);
215                 offset += 1;
216                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_prefix_length,    tvb, offset, 1, ENC_BIG_ENDIAN);
217                 offset += 1;
218                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_max_length,       tvb, offset, 1, ENC_BIG_ENDIAN);
219                 offset += 1;
220                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_reserved,         tvb, offset, 1, ENC_NA);
221                 offset += 1;
222                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_ipv6_prefix,      tvb, offset, 16, ENC_NA);
223                 offset += 16;
224                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_as_number,        tvb, offset, 4, ENC_BIG_ENDIAN);
225                 offset += 4;
226                 break;
227             case RPKI_RTR_END_OF_DATA_PDU: /* End Of Data (7) */
228                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_session_id,       tvb, offset, 2, ENC_BIG_ENDIAN);
229                 offset += 2;
230                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_length,           tvb, offset, 4, ENC_BIG_ENDIAN);
231                 /* TODO: Add check length ? */
232                 offset += 4;
233                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_serial_number,    tvb, offset, 4, ENC_BIG_ENDIAN);
234                 offset += 4;
235 
236                 if (version >= 1){
237                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_refresh_interval, tvb, offset, 4, ENC_BIG_ENDIAN);
238                 offset += 4;
239 
240                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_retry_interval,   tvb, offset, 4, ENC_BIG_ENDIAN);
241                 offset += 4;
242 
243                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_expire_interval,  tvb, offset, 4, ENC_BIG_ENDIAN);
244                 offset += 4;
245                 }
246                 break;
247 
248             case RPKI_RTR_ROUTER_KEY: /* Router Key (9) */
249                 if(version < 1){
250                     /* Error about wrong version... */
251                     expert_add_info(pinfo, ti_type, &ei_rpkirtr_wrong_version_router_key);
252                 } else {
253                     asn1_ctx_t asn1_ctx;
254 
255                     ti_flags = proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
256                     flags_tree = proto_item_add_subtree(ti_flags, ett_flags_nd);
257                     proto_tree_add_item(flags_tree, hf_rpkirtr_flags_rk,           tvb, offset, 1, ENC_BIG_ENDIAN);
258                     offset += 1;
259                     proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_reserved,         tvb, offset, 2, ENC_NA);
260                     offset += 1;
261                     proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_length,           tvb, offset, 4, ENC_BIG_ENDIAN);
262                     /* TODO: Add check length ? */
263                     offset += 4;
264                     proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_subject_key_identifier, tvb, offset, 20, ENC_NA);
265                     offset += 20;
266 
267                     proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_as_number, tvb, offset, 4, ENC_BIG_ENDIAN);
268                     offset += 4;
269                     asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
270                     offset = dissect_x509af_SubjectPublicKeyInfo(FALSE, tvb, offset, &asn1_ctx, rpkirtr_tree, hf_rpkirtr_subject_public_key_info);
271 
272                 }
273                 break;
274             case RPKI_RTR_ERROR_REPORT_PDU: /* Error Report (10) */
275             {
276                 guint32 len_pdu, len_text;
277                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_error_code,       tvb, offset, 2, ENC_BIG_ENDIAN);
278                 offset += 2;
279                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_length,           tvb, offset, 4, ENC_BIG_ENDIAN);
280                 /* TODO: Add check length ? */
281                 offset += 4;
282                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_length_pdu,       tvb, offset, 4, ENC_BIG_ENDIAN);
283                 len_pdu =                                                      tvb_get_ntohl(tvb, offset);
284                 offset += 4;
285                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_error_pdu,        tvb, offset, len_pdu, ENC_NA);
286                 offset +=  len_pdu;
287                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_length_text,      tvb, offset, 4, ENC_BIG_ENDIAN);
288                 len_text =                                                     tvb_get_ntohl(tvb, offset);
289                 offset += 4;
290                 proto_tree_add_item(rpkirtr_tree, hf_rpkirtr_error_text,   tvb, offset, len_text, ENC_ASCII|ENC_NA);
291                 offset += len_text;
292             }
293             break;
294             default:
295                 /* No default ? At least sanity check the length*/
296                 if (length > tvb_reported_length(tvb)) {
297                     expert_add_info(pinfo, ti_type, &ei_rpkirtr_bad_length);
298                     return tvb_reported_length(tvb);
299                 }
300 
301                 offset += length;
302                 break;
303         }
304     }
305 
306     return tvb_reported_length(tvb);
307 }
308 
309 static int
dissect_rpkirtr(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)310 dissect_rpkirtr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
311 {
312     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RPKI-RTR");
313     col_clear(pinfo->cinfo, COL_INFO);
314 
315     tcp_dissect_pdus(tvb, pinfo, tree, 1, 8, get_rpkirtr_pdu_len, dissect_rpkirtr_pdu, data);
316     return tvb_reported_length(tvb);
317 }
318 
319 void
proto_register_rpkirtr(void)320 proto_register_rpkirtr(void)
321 {
322     module_t *rpkirtr_module;
323 
324     static hf_register_info hf[] = {
325         { &hf_rpkirtr_version,
326             { "Version", "rpki-rtr.version",
327             FT_UINT8, BASE_DEC, NULL, 0x0,
328             "Denoting the version of this protocol (currently 0)", HFILL }
329         },
330         { &hf_rpkirtr_pdu_type,
331             { "PDU Type", "rpki-rtr.pdu_type",
332             FT_UINT8, BASE_DEC, VALS(rtr_pdu_type_vals), 0x0,
333             "Denoting the type of the PDU", HFILL }
334         },
335         { &hf_rpkirtr_reserved,
336             { "Reserved", "rpki-rtr.reserved",
337             FT_BYTES, BASE_NONE, NULL, 0x0,
338             "Must be zero", HFILL }
339         },
340         { &hf_rpkirtr_session_id,
341             { "Session ID", "rpki-rtr.session_id",
342             FT_UINT16, BASE_DEC, NULL, 0x0,
343             NULL, HFILL }
344         },
345         { &hf_rpkirtr_length,
346             { "Length", "rpki-rtr.length",
347             FT_UINT32, BASE_DEC, NULL, 0x0,
348             "Value the count of the bytes in the entire PDU, including the eight bytes of header that end with the length field", HFILL }
349         },
350         { &hf_rpkirtr_serial_number,
351             { "Serial Number", "rpki-rtr.serial_number",
352             FT_UINT32, BASE_DEC, NULL, 0x0,
353             NULL, HFILL }
354         },
355         { &hf_rpkirtr_flags,
356             { "Flags", "rpki-rtr.flags",
357             FT_UINT8, BASE_HEX, NULL, 0x0,
358             NULL, HFILL }
359         },
360         { &hf_rpkirtr_flags_aw,
361             { "Flag AW", "rpki-rtr.flags.aw",
362             FT_BOOLEAN, 8, TFS(&tfs_flag_type_aw), 0x01,
363             NULL, HFILL }
364         },
365         { &hf_rpkirtr_flags_rk,
366             { "Flag Router Key", "rpki-rtr.flags.rk",
367             FT_BOOLEAN, 8, TFS(&tfs_flag_type_rk), 0x01,
368             NULL, HFILL }
369         },
370         { &hf_rpkirtr_prefix_length,
371             { "Prefix Length", "rpki-rtr.prefix_length",
372             FT_UINT8, BASE_DEC, NULL, 0x0,
373             "Denoting the shortest prefix allowed for the prefix", HFILL }
374         },
375         { &hf_rpkirtr_max_length,
376             { "Max length", "rpki-rtr.max_length",
377             FT_UINT8, BASE_DEC, NULL, 0x0,
378             "Denoting the longest prefix allowed by the prefix.  This MUST NOT be less than the Prefix Length element", HFILL }
379         },
380         { &hf_rpkirtr_ipv4_prefix,
381             { "IPv4 Prefix", "rpki-rtr.ipv4_prefix",
382             FT_IPv4, BASE_NONE, NULL, 0x0,
383             "The IPv4 prefix of the ROA", HFILL }
384         },
385         { &hf_rpkirtr_ipv6_prefix,
386             { "IPv6 Prefix", "rpki-rtr.ipv6_prefix",
387             FT_IPv6, BASE_NONE, NULL, 0x0,
388             "The IPv6 prefix of the ROA", HFILL }
389         },
390         { &hf_rpkirtr_as_number,
391             { "AS Number", "rpki-rtr.as_number",
392             FT_UINT32, BASE_DEC, NULL, 0x0,
393             "Autonomous System Number allowed to announce this prefix", HFILL }
394         },
395         { &hf_rpkirtr_error_code,
396             { "Error Code", "rpki-rtr.error_code",
397             FT_UINT16, BASE_DEC, VALS(rtr_error_code_vals), 0x0,
398             NULL, HFILL }
399         },
400         { &hf_rpkirtr_length_pdu,
401             { "Length of Encapsulated PDU", "rpki-rtr.length_pdu",
402             FT_UINT32, BASE_DEC, NULL, 0x0,
403             NULL, HFILL }
404         },
405         { &hf_rpkirtr_error_pdu,
406             { "Erroneous PDU", "rpki-rtr.error_pdu",
407             FT_BYTES, BASE_NONE, NULL, 0x0,
408             NULL, HFILL }
409         },
410         { &hf_rpkirtr_length_text,
411             { "Length of text", "rpki-rtr.length_text",
412             FT_UINT32, BASE_DEC, NULL, 0x0,
413             NULL, HFILL }
414         },
415         { &hf_rpkirtr_error_text,
416             { "Erroneous Text", "rpki-rtr.error_text",
417             FT_STRING, BASE_NONE, NULL, 0x0,
418             NULL, HFILL }
419         },
420         { &hf_rpkirtr_refresh_interval,
421             { "Refresh Interval", "rpki-rtr.refresh_interval",
422             FT_UINT32, BASE_DEC, NULL, 0x0,
423             NULL, HFILL }
424         },
425         { &hf_rpkirtr_retry_interval,
426             { "Retry Interval", "rpki-rtr.retry_interval",
427             FT_UINT32, BASE_DEC, NULL, 0x0,
428             NULL, HFILL }
429         },
430         { &hf_rpkirtr_expire_interval,
431             { "Expire Interval", "rpki-rtr.expire_interval",
432             FT_UINT32, BASE_DEC, NULL, 0x0,
433             NULL, HFILL }
434         },
435         { &hf_rpkirtr_subject_key_identifier,
436             { "Subject Key Identifier", "rpki-rtr.subject_key_identifier",
437             FT_BYTES, BASE_NONE, NULL, 0x0,
438             NULL, HFILL }
439         },
440         { &hf_rpkirtr_subject_public_key_info,
441             { "Subject Public Key Info", "rpki-rtr.subject_public_key_info",
442             FT_NONE, BASE_NONE, NULL, 0x0,
443             NULL, HFILL }
444         }
445     };
446 
447     static gint *ett[] = {
448         &ett_rpkirtr,
449         &ett_flags,
450         &ett_flags_nd
451     };
452 
453     static ei_register_info ei[] = {
454         { &ei_rpkirtr_wrong_version_router_key, { "rpkirtr.router_key.wrong_version", PI_MALFORMED, PI_WARN, "Wrong version for Router Key type", EXPFILL }},
455         { &ei_rpkirtr_bad_length, { "rpkirtr.bad_length", PI_MALFORMED, PI_ERROR, "Invalid length field", EXPFILL }},
456     };
457 
458     expert_module_t *expert_rpkirtr;
459 
460     proto_rpkirtr = proto_register_protocol("RPKI-Router Protocol",
461         "RPKI-Router Protocol", "rpkirtr");
462 
463     proto_register_field_array(proto_rpkirtr, hf, array_length(hf));
464     proto_register_subtree_array(ett, array_length(ett));
465 
466     rpkirtr_module = prefs_register_protocol(proto_rpkirtr,
467         proto_reg_handoff_rpkirtr);
468 
469     prefs_register_uint_preference(rpkirtr_module, "tcp.rpkirtr_tls.port", "RPKI-RTR TCP TLS Port",
470          "RPKI-Router Protocol TCP TLS port if other than the default",
471          10, &g_port_rpkirtr_tls);
472 
473     expert_rpkirtr = expert_register_protocol(proto_rpkirtr);
474     expert_register_field_array(expert_rpkirtr, ei, array_length(ei));
475     rpkirtr_handle = register_dissector("rpkirtr", dissect_rpkirtr, proto_rpkirtr);
476 }
477 
478 
479 void
proto_reg_handoff_rpkirtr(void)480 proto_reg_handoff_rpkirtr(void)
481 {
482     static gboolean initialized = FALSE;
483     static int rpki_rtr_tls_port;
484 
485     if (!initialized) {
486         dissector_add_uint_with_preference("tcp.port", RPKI_RTR_TCP_PORT, rpkirtr_handle);
487         initialized = TRUE;
488     } else {
489         ssl_dissector_delete(rpki_rtr_tls_port, rpkirtr_handle);
490     }
491 
492     rpki_rtr_tls_port = g_port_rpkirtr_tls;
493     ssl_dissector_add(rpki_rtr_tls_port, rpkirtr_handle);
494 }
495 
496 
497 /*
498  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
499  *
500  * Local variables:
501  * c-basic-offset: 4
502  * tab-width: 8
503  * indent-tabs-mode: nil
504  * End:
505  *
506  * vi: set shiftwidth=4 tabstop=8 expandtab:
507  * :indentSize=4:tabSize=8:noTabs=true:
508  */
509