Remove a bunch of duplicate semicolons.
[obnox/wireshark/wip.git] / packet-m2pa.c
1 /* packet-m2pa.c
2  * Routines for MTP2 Peer Adaptation Layer dissection
3  * It is hopefully (needs testing) compliant to
4  * http://www.ietf.org/internet-drafts/draft-ietf-sigtran-m2pa-02.txt
5  * http://www.ietf.org/internet-drafts/draft-ietf-sigtran-m2pa-09.txt
6  *
7  * Copyright 2001, 2002, Jeff Morriss <jeff.morriss[AT]ulticom.com>,
8  * updated by Michael Tuexen <tuexen [AT] fh-muenster.de>
9  *
10  * $Id: packet-m2pa.c,v 1.22 2003/09/04 14:32:34 tuexen Exp $
11  *
12  * Ethereal - Network traffic analyzer
13  * By Gerald Combs <gerald@ethereal.com>
14  * Copyright 1998 Gerald Combs
15  *
16  * Copied from packet-m3ua.c
17  *
18  * This program is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU General Public License
20  * as published by the Free Software Foundation; either version 2
21  * of the License, or (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31  */
32
33
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <epan/packet.h>
39 #include "prefs.h"
40 #include "sctpppids.h"
41
42 #define NETWORK_BYTE_ORDER          FALSE
43 #define SCTP_PORT_M2PA              3565
44
45 static int global_sctp_port       = SCTP_PORT_M2PA;
46 static int sctp_port              = 0;
47
48 void proto_reg_handoff_m2pa(void);
49
50 static int proto_m2pa      = -1;
51 static module_t *m2pa_module;
52
53 static int hf_version      = -1;
54 static int hf_spare        = -1;
55 static int hf_v2_type      = -1;
56 static int hf_v8_type      = -1;
57 static int hf_class        = -1;
58 static int hf_length       = -1;
59 static int hf_unused       = -1;
60 static int hf_bsn          = -1;
61 static int hf_fsn          = -1;
62 static int hf_v2_status    = -1;
63 static int hf_v8_status    = -1;
64 static int hf_v2_li_spare  = -1;
65 static int hf_v8_li_spare  = -1;
66 static int hf_v2_li_prio   = -1;
67 static int hf_v8_li_prio   = -1;
68 static int hf_filler       = -1;
69 static int hf_unknown_data = -1;
70
71 static gint ett_m2pa       = -1;
72 static gint ett_m2pa_li    = -1;
73
74 static int mtp3_proto_id;
75 static dissector_handle_t mtp3_handle;
76
77 typedef enum {
78   M2PA_V2 = 1,
79   M2PA_V9 = 2
80 } Version_Type;
81
82 static Version_Type m2pa_version = M2PA_V9;
83
84 #define VERSION_LENGTH         1
85 #define SPARE_LENGTH           1
86 #define CLASS_LENGTH           1
87 #define V2_TYPE_LENGTH         2
88 #define V8_TYPE_LENGTH         1
89 #define LENGTH_LENGTH          4
90 #define UNUSED_LENGTH          1
91 #define BSN_LENGTH             3
92 #define FSN_LENGTH             3
93
94 #define V2_HEADER_LENGTH        (VERSION_LENGTH + SPARE_LENGTH + \
95                                 V2_TYPE_LENGTH + LENGTH_LENGTH)
96                                 
97 #define V8_HEADER_LENGTH        (VERSION_LENGTH + SPARE_LENGTH + \
98                                 CLASS_LENGTH + V8_TYPE_LENGTH + LENGTH_LENGTH + \
99                                 UNUSED_LENGTH + BSN_LENGTH + UNUSED_LENGTH + \
100                                 FSN_LENGTH)
101
102 #define HEADER_OFFSET          0
103 #define VERSION_OFFSET         HEADER_OFFSET
104 #define SPARE_OFFSET           (VERSION_OFFSET + VERSION_LENGTH)
105 #define CLASS_OFFSET           (SPARE_OFFSET + SPARE_LENGTH)
106 #define V2_TYPE_OFFSET         (SPARE_OFFSET + SPARE_LENGTH)
107 #define V8_TYPE_OFFSET         (CLASS_OFFSET + CLASS_LENGTH)
108 #define V8_LENGTH_OFFSET       (V8_TYPE_OFFSET + V8_TYPE_LENGTH)
109 #define V2_LENGTH_OFFSET       (V2_TYPE_OFFSET + V2_TYPE_LENGTH)
110 #define FIRST_UNUSED_OFFSET    (V8_LENGTH_OFFSET + LENGTH_LENGTH)
111 #define BSN_OFFSET             (FIRST_UNUSED_OFFSET + UNUSED_LENGTH)
112 #define SECOND_UNUSED_OFFSET   (BSN_OFFSET + BSN_LENGTH)
113 #define FSN_OFFSET             (SECOND_UNUSED_OFFSET + UNUSED_LENGTH)
114
115 static const value_string protocol_version_values[] = {
116   { 1,      "Release 1" },
117   { 0,      NULL } };
118
119 static const value_string message_class_values[] = {
120   { 0xb,    "M2PA" },
121   { 0,      NULL } };
122   
123 #define V2_USER_DATA_TYPE   0x0601
124 #define V2_LINK_STATUS_TYPE 0x0602
125
126 static const value_string v2_message_type_values[] = {
127   { V2_USER_DATA_TYPE,   "User Data" },
128   { V2_LINK_STATUS_TYPE, "Link Status" },
129   { 0,                   NULL } };
130
131 #define V8_USER_DATA_TYPE   0x0001
132 #define V8_LINK_STATUS_TYPE 0x0002
133
134 static const value_string v8_message_type_values[] = {
135   { V8_USER_DATA_TYPE,   "User Data" },
136   { V8_LINK_STATUS_TYPE, "Link Status" },
137   { 0,                   NULL } };
138
139 static void
140 dissect_v2_header(tvbuff_t *header_tvb, packet_info *pinfo, proto_tree *m2pa_tree)
141 {
142   guint16 message_type;
143   
144   message_type  = tvb_get_ntohs(header_tvb, V2_TYPE_OFFSET);
145
146   if (check_col(pinfo->cinfo, COL_INFO))
147     col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(message_type, v2_message_type_values, "reserved"));
148
149   if (m2pa_tree) {
150     proto_tree_add_item(m2pa_tree, hf_version, header_tvb, VERSION_OFFSET,       VERSION_LENGTH, NETWORK_BYTE_ORDER);
151     proto_tree_add_item(m2pa_tree, hf_spare,   header_tvb, SPARE_OFFSET,         SPARE_LENGTH,   NETWORK_BYTE_ORDER);
152     proto_tree_add_item(m2pa_tree, hf_v2_type, header_tvb, V2_TYPE_OFFSET,       V2_TYPE_LENGTH, NETWORK_BYTE_ORDER);
153     proto_tree_add_item(m2pa_tree, hf_length,  header_tvb, V2_LENGTH_OFFSET,     LENGTH_LENGTH,  NETWORK_BYTE_ORDER);
154   }
155 }
156
157 static void
158 dissect_v8_header(tvbuff_t *header_tvb, packet_info *pinfo, proto_tree *m2pa_tree)
159 {
160   guint8 message_type;
161   
162   message_type  = tvb_get_guint8(header_tvb, V8_TYPE_OFFSET);
163
164   if (check_col(pinfo->cinfo, COL_INFO))
165     col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(message_type, v8_message_type_values, "Unknown"));
166
167   if (m2pa_tree) {
168     proto_tree_add_item(m2pa_tree, hf_version, header_tvb, VERSION_OFFSET,       VERSION_LENGTH, NETWORK_BYTE_ORDER);
169     proto_tree_add_item(m2pa_tree, hf_spare,   header_tvb, SPARE_OFFSET,         SPARE_LENGTH,   NETWORK_BYTE_ORDER);
170     proto_tree_add_item(m2pa_tree, hf_class,   header_tvb, CLASS_OFFSET,         CLASS_LENGTH,   NETWORK_BYTE_ORDER);
171     proto_tree_add_item(m2pa_tree, hf_v8_type, header_tvb, V8_TYPE_OFFSET,       V8_TYPE_LENGTH, NETWORK_BYTE_ORDER);
172     proto_tree_add_item(m2pa_tree, hf_length,  header_tvb, V8_LENGTH_OFFSET,     LENGTH_LENGTH,  NETWORK_BYTE_ORDER);
173     proto_tree_add_item(m2pa_tree, hf_unused,  header_tvb, FIRST_UNUSED_OFFSET,  UNUSED_LENGTH,  NETWORK_BYTE_ORDER);
174     proto_tree_add_item(m2pa_tree, hf_bsn,     header_tvb, BSN_OFFSET,           BSN_LENGTH,     NETWORK_BYTE_ORDER);
175     proto_tree_add_item(m2pa_tree, hf_unused,  header_tvb, SECOND_UNUSED_OFFSET, UNUSED_LENGTH,  NETWORK_BYTE_ORDER);
176     proto_tree_add_item(m2pa_tree, hf_fsn,     header_tvb, FSN_OFFSET,           FSN_LENGTH,     NETWORK_BYTE_ORDER);
177   }
178 }
179
180 #define LI_OFFSET           0
181 #define LI_LENGTH           1
182 #define MTP3_OFFSET         (LI_OFFSET + LI_LENGTH)
183
184 #define V2_LI_SPARE_MASK    0xfc
185 #define V2_LI_PRIORITY_MASK 0x3
186
187 static void
188 dissect_v2_user_data_message(tvbuff_t *message_data_tvb, packet_info *pinfo, proto_item *m2pa_item, proto_tree *m2pa_tree, proto_tree *tree)
189 {
190   proto_item *m2pa_li_item;
191   proto_tree *m2pa_li_tree;
192   tvbuff_t *payload_tvb;
193
194   if (tvb_length(message_data_tvb) > 0) {
195     if (m2pa_tree) {
196       m2pa_li_item = proto_tree_add_text(m2pa_tree, message_data_tvb, LI_OFFSET, LI_LENGTH, "Length Indicator");
197       m2pa_li_tree = proto_item_add_subtree(m2pa_li_item, ett_m2pa_li);
198
199       proto_tree_add_item(m2pa_li_tree, hf_v2_li_spare, message_data_tvb, LI_OFFSET, LI_LENGTH, NETWORK_BYTE_ORDER);
200       proto_tree_add_item(m2pa_li_tree, hf_v2_li_prio,  message_data_tvb, LI_OFFSET, LI_LENGTH, NETWORK_BYTE_ORDER);
201
202       /* Re-adjust length of M2PA item since it will be dissected as MTP3 */
203       proto_item_set_len(m2pa_item, V2_HEADER_LENGTH + LI_LENGTH);
204      }
205   }
206
207   payload_tvb = tvb_new_subset(message_data_tvb, MTP3_OFFSET, -1, -1);
208   call_dissector(mtp3_handle, payload_tvb, pinfo, tree);
209 }
210
211 #define V8_LI_SPARE_MASK         0x3f
212 #define V8_LI_PRIORITY_MASK      0xc0
213
214 static void
215 dissect_v8_user_data_message(tvbuff_t *message_data_tvb, packet_info *pinfo, proto_item *m2pa_item, proto_tree *m2pa_tree, proto_tree *tree)
216 {
217   proto_item *m2pa_li_item;
218   proto_tree *m2pa_li_tree;
219   tvbuff_t *payload_tvb;
220
221   if (tvb_length(message_data_tvb) > 0) {
222     if (m2pa_tree) {
223       m2pa_li_item = proto_tree_add_text(m2pa_tree, message_data_tvb, LI_OFFSET, LI_LENGTH, "Length Indicator");
224       m2pa_li_tree = proto_item_add_subtree(m2pa_li_item, ett_m2pa_li);
225       proto_tree_add_item(m2pa_li_tree, hf_v8_li_prio,  message_data_tvb, LI_OFFSET, LI_LENGTH, NETWORK_BYTE_ORDER);
226       proto_tree_add_item(m2pa_li_tree, hf_v8_li_spare, message_data_tvb, LI_OFFSET, LI_LENGTH, NETWORK_BYTE_ORDER);
227
228         /* Re-adjust length of M2PA item since it will be dissected as MTP3 */
229       proto_item_set_len(m2pa_item, V8_HEADER_LENGTH + LI_LENGTH);
230     }
231
232     payload_tvb = tvb_new_subset(message_data_tvb, MTP3_OFFSET, -1, -1);
233     call_dissector(mtp3_handle, payload_tvb, pinfo, tree);
234   }
235 }
236
237 static const value_string v2_link_status_values[] = {
238   { 1, "In Service" },
239   { 2, "Processor Outage" },
240   { 3, "Processor Outage Ended" },
241   { 4, "Busy" },
242   { 5, "Busy Ended" },
243   { 0, NULL } };
244
245 #define STATUS_LENGTH    4
246 #define STATUS_OFFSET    0
247 #define FILLER_OFFSET    (STATUS_OFFSET + STATUS_LENGTH)
248
249 static void
250 dissect_v2_link_status_message(tvbuff_t *message_data_tvb, proto_tree *m2pa_tree)
251 {
252  if (m2pa_tree)
253     proto_tree_add_item(m2pa_tree, hf_v2_status, message_data_tvb, STATUS_OFFSET, STATUS_LENGTH, NETWORK_BYTE_ORDER);
254 }
255
256 static const value_string v8_link_status_values[] = {
257   { 1, "Alignment" },
258   { 2, "Proving Normal" },
259   { 3, "Proving Emergency" },
260   { 4, "Ready" },
261   { 5, "Processor Outage" },
262   { 6, "Processor Outage Ended" },
263   { 7, "Busy" },
264   { 8, "Busy Ended" },
265   { 9, "Out of Service" },
266   { 0, NULL } };
267
268 static void
269 dissect_v8_link_status_message(tvbuff_t *message_data_tvb, proto_tree *m2pa_tree)
270 {
271   guint16 filler_length;
272
273   filler_length = tvb_length(message_data_tvb) - STATUS_LENGTH;
274   
275   proto_tree_add_item(m2pa_tree, hf_v8_status, message_data_tvb, STATUS_OFFSET, STATUS_LENGTH, NETWORK_BYTE_ORDER);
276   if (filler_length > 0)
277       proto_tree_add_item(m2pa_tree, hf_filler, message_data_tvb, FILLER_OFFSET, filler_length, NETWORK_BYTE_ORDER);
278 }
279
280 static void
281 dissect_unknown_message(tvbuff_t *message_data_tvb, proto_tree *m2pa_tree)
282 {
283   guint length;
284    
285   length = tvb_length(message_data_tvb);
286   if ((m2pa_tree) && (length > 0))
287     proto_tree_add_item(m2pa_tree, hf_unknown_data, message_data_tvb, 0, length, NETWORK_BYTE_ORDER);
288 }
289
290 #define V2_MESSAGE_DATA_OFFSET (HEADER_OFFSET + V2_HEADER_LENGTH)
291
292 static void
293 dissect_v2_message_data(tvbuff_t *message_tvb, packet_info *pinfo, proto_item *m2pa_item, proto_tree *m2pa_tree, proto_tree *tree)
294 {
295   guint32 message_data_length;
296   guint16 type;
297   tvbuff_t *message_data_tvb;
298
299   message_data_length = tvb_get_ntohl(message_tvb,  V2_LENGTH_OFFSET);
300   message_data_tvb    = tvb_new_subset(message_tvb, V2_MESSAGE_DATA_OFFSET, message_data_length, message_data_length);
301   type                = tvb_get_ntohs(message_tvb, V2_TYPE_OFFSET);
302
303   switch(type) {
304   case V2_USER_DATA_TYPE:
305     dissect_v2_user_data_message(message_data_tvb, pinfo, m2pa_item, m2pa_tree, tree);
306     break;
307   case V2_LINK_STATUS_TYPE:
308     dissect_v2_link_status_message(message_data_tvb, m2pa_tree);
309     break;
310   default:
311     dissect_unknown_message(message_data_tvb, m2pa_tree);
312   }
313 }
314
315 #define V8_MESSAGE_DATA_OFFSET (HEADER_OFFSET + V8_HEADER_LENGTH)
316
317 static void
318 dissect_v8_message_data(tvbuff_t *message_tvb, packet_info *pinfo, proto_item *m2pa_item, proto_tree *m2pa_tree, proto_tree *tree)
319 {
320   guint32 message_data_length;
321   guint8 type;
322   tvbuff_t *message_data_tvb;
323
324   message_data_length = tvb_get_ntohl(message_tvb, V8_LENGTH_OFFSET) - V8_HEADER_LENGTH;
325   message_data_tvb    = tvb_new_subset(message_tvb, V8_MESSAGE_DATA_OFFSET, message_data_length, message_data_length);
326   type                = tvb_get_guint8(message_tvb, V8_TYPE_OFFSET);
327
328
329   switch(type) {
330   case V8_USER_DATA_TYPE:
331     dissect_v8_user_data_message(message_data_tvb, pinfo, m2pa_item, m2pa_tree, tree);
332     break;
333   case V8_LINK_STATUS_TYPE:
334     dissect_v8_link_status_message(message_data_tvb, m2pa_tree);
335     break;
336   default:
337     dissect_unknown_message(message_data_tvb, m2pa_tree);
338   }
339 }
340
341 static void
342 dissect_v2_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_item *m2pa_item, proto_tree *m2pa_tree, proto_tree *tree)
343 {
344   dissect_v2_header(message_tvb, pinfo, m2pa_tree);
345   dissect_v2_message_data(message_tvb, pinfo, m2pa_item, m2pa_tree, tree);
346 }
347
348 static void
349 dissect_v8_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_item *m2pa_item, proto_tree *m2pa_tree, proto_tree *tree)
350 {
351   dissect_v8_header(message_tvb, pinfo, m2pa_tree);
352   dissect_v8_message_data(message_tvb, pinfo, m2pa_item, m2pa_tree, tree);
353 }
354
355 static void
356 dissect_m2pa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
357 {
358   proto_item *m2pa_item;
359   proto_tree *m2pa_tree;
360
361   if (check_col(pinfo->cinfo, COL_PROTOCOL))
362     switch(m2pa_version) {
363     case M2PA_V2:
364       col_set_str(pinfo->cinfo, COL_PROTOCOL, "M2PA (ID 02)");
365       break;
366     case M2PA_V9:
367       col_set_str(pinfo->cinfo, COL_PROTOCOL, "M2PA (ID 09)");
368       break;
369     };      
370
371   if (tree) {
372     m2pa_item = proto_tree_add_item(tree, proto_m2pa, tvb, 0, -1, FALSE);
373     m2pa_tree = proto_item_add_subtree(m2pa_item, ett_m2pa);
374   } else {
375     m2pa_item = NULL;
376     m2pa_tree = NULL;
377   }
378
379   switch(m2pa_version) {
380     case M2PA_V2:
381       dissect_v2_message(tvb, pinfo, m2pa_item, m2pa_tree, tree);
382       break;
383     case M2PA_V9:
384       dissect_v8_message(tvb, pinfo, m2pa_item, m2pa_tree, tree);
385       break;
386   };      
387 }
388
389 void
390 proto_register_m2pa(void)
391 {
392   static hf_register_info hf[] = 
393   { { &hf_version,      { "Version",        "m2pa.version",      FT_UINT8,  BASE_DEC,  VALS(protocol_version_values), 0x0,                 "", HFILL} },
394     { &hf_spare,        { "Spare",          "m2pa.spare",        FT_UINT8,  BASE_HEX,  NULL,                          0x0,                 "", HFILL} },
395     { &hf_v2_type,      { "Message Type",   "m2pa.type",         FT_UINT16, BASE_HEX,  VALS(v2_message_type_values),  0x0,                 "", HFILL} },
396     { &hf_v8_type,      { "Message Type",   "m2pa.type",         FT_UINT8,  BASE_DEC,  VALS(v8_message_type_values),  0x0,                 "", HFILL} },
397     { &hf_class,        { "Message Class",  "m2pa.class",        FT_UINT8,  BASE_DEC,  VALS(message_class_values),    0x0,                 "", HFILL} },
398     { &hf_length,       { "Message length", "m2pa.length",       FT_UINT32, BASE_DEC,  NULL,                          0x0,                 "", HFILL} },
399     { &hf_unused,       { "Unused",         "m2pa.unused",       FT_UINT8,  BASE_DEC,  NULL,                          0x0,                 "", HFILL} },
400     { &hf_bsn,          { "BSN",            "m2pa.bsn",          FT_UINT24, BASE_DEC,  NULL,                          0x0,                 "", HFILL} },
401     { &hf_fsn,          { "FSN",            "m2pa.fsn",          FT_UINT24, BASE_DEC,  NULL,                          0x0,                 "", HFILL} },
402     { &hf_v2_li_spare,  { "Spare",          "m2pa.li_spare",     FT_UINT8,  BASE_DEC,  NULL,                          V2_LI_SPARE_MASK,    "", HFILL} },
403     { &hf_v8_li_spare,  { "Spare",          "m2pa.li_spare",     FT_UINT8,  BASE_HEX,  NULL,                          V8_LI_SPARE_MASK,    "", HFILL} },
404     { &hf_v2_li_prio,   { "Priority",       "m2pa.li_priority",  FT_UINT8,  BASE_DEC,  NULL,                          V2_LI_PRIORITY_MASK, "", HFILL} },
405     { &hf_v8_li_prio,   { "Priority",       "m2pa.li_priority",  FT_UINT8,  BASE_HEX,  NULL,                          V8_LI_PRIORITY_MASK, "", HFILL} },
406     { &hf_v2_status,    { "Link Status",    "m2pa.status",       FT_UINT32, BASE_DEC,  VALS(v2_link_status_values),   0x0,                 "", HFILL} },
407     { &hf_v8_status,    { "Link Status",    "m2pa.status",       FT_UINT32, BASE_DEC,  VALS(v8_link_status_values),   0x0,                 "", HFILL} },
408     { &hf_filler,       { "Filler",         "m2pa.filler",       FT_BYTES,  BASE_NONE, NULL,                          0x0,                 "", HFILL} },
409     { &hf_unknown_data, { "Unknown Data",   "m2pa.unknown_data", FT_BYTES,  BASE_NONE, NULL,                          0x0,                 "", HFILL} }
410   };
411
412   static gint *ett[] = {
413     &ett_m2pa,
414     &ett_m2pa_li
415   };
416
417   static enum_val_t m2pa_version_options[] = {
418     { "Internet Draft version 2", M2PA_V2 },
419     { "Internet Draft version 9", M2PA_V9 },
420     { NULL, 0 }
421   };
422
423   proto_m2pa = proto_register_protocol("MTP2 Peer Adaptation Layer", "M2PA", "m2pa");
424
425   proto_register_field_array(proto_m2pa, hf, array_length(hf));
426   proto_register_subtree_array(ett, array_length(ett));
427
428   m2pa_module = prefs_register_protocol(proto_m2pa, proto_reg_handoff_m2pa);
429
430   prefs_register_enum_preference(m2pa_module, "version", "M2PA version", "Version used by Ethereal", (gint *)&m2pa_version, m2pa_version_options, FALSE);
431   prefs_register_uint_preference(m2pa_module, "port", "M2PA SCTP Port", "Set the port for M2PA messages (Default of 3565)", 10, &global_sctp_port);
432 }
433
434 void
435 proto_reg_handoff_m2pa(void)
436 {
437   static int prefs_initialized = FALSE;
438   static dissector_handle_t m2pa_handle;
439
440   /* Port preferences code shamelessly copied from packet-beep.c */
441   if (!prefs_initialized) {
442     mtp3_handle   = find_dissector("mtp3");
443     mtp3_proto_id = proto_get_id_by_filter_name("mtp3");
444     m2pa_handle   = create_dissector_handle(dissect_m2pa, proto_m2pa);
445
446     dissector_add("sctp.ppi", M2PA_PAYLOAD_PROTOCOL_ID, m2pa_handle);
447
448     prefs_initialized = TRUE;
449
450   } else {
451
452     dissector_delete("sctp.port", sctp_port, m2pa_handle);
453
454   }
455
456   /* Set our port number for future use */
457   sctp_port = global_sctp_port;
458
459   dissector_add("sctp.port", sctp_port, m2pa_handle);
460 }