Switch a bunch of dissectors over to using tvb_new_subset_remaining()
[obnox/wireshark/wip.git] / epan / dissectors / packet-mtp3mg.c
1 /* packet-mtp3mg.c
2  * Routines for Message Transfer Part Level 3 Management and Test dissection
3  *
4  * It is (hopefully) compliant to:
5  *   ANSI T1.111.4-1996
6  *   ITU-T Q.704 7/1996
7  *   ITU-T Q.707 7/1996 and ANSI T1.111.7-1996 (for SLT message formats)
8  *   portions of ITU-T Q.2210 7/1996 (for XCO/XCA message formats)
9  *   GF 001-9001 (Chinese ITU variant)
10  *   JT-Q704, JT-Q707v2, and NTT-Q704 (Japan)
11  *
12  *   Note that the division of the Japan SLS into the SLC and A/B bit is not
13  *   done.
14  *
15  * Copyright 2003, Jeff Morriss <jeff.morriss[AT]ulticom.com>
16  *
17  * $Id$
18  *
19  * Wireshark - Network traffic analyzer
20  * By Gerald Combs <gerald@wireshark.org>
21  * Copyright 1998 Gerald Combs
22  *
23  * Copied from packet-mtp3.c
24  *
25  * This program is free software; you can redistribute it and/or
26  * modify it under the terms of the GNU General Public License
27  * as published by the Free Software Foundation; either version 2
28  * of the License, or (at your option) any later version.
29  *
30  * This program is distributed in the hope that it will be useful,
31  * but WITHOUT ANY WARRANTY; without even the implied warranty of
32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33  * GNU General Public License for more details.
34  *
35  * You should have received a copy of the GNU General Public License
36  * along with this program; if not, write to the Free Software
37  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38  */
39
40 #ifdef HAVE_CONFIG_H
41 # include "config.h"
42 #endif
43
44 #include <glib.h>
45
46 #include <epan/packet.h>
47
48 #include <packet-mtp3.h>
49
50 /* MTP3 Service Indicators used by this dissector */
51 #define MTP3MG_SI 0
52 #define MTP3MG_ITU_TEST_SI 1
53 #define MTP3MG_ANSI_TEST_SI 2
54
55 #define H0H1_LENGTH 1
56 #define H0_MASK     0x0f
57 #define H1_MASK     0xf0
58 #define H1_SHIFT    4
59
60 #define H0_CHM 0x01
61 #define H0_ECM 0x02
62 #define H0_FCM 0x03
63 #define H0_TFM 0x04
64 #define H0_RSM 0x05
65 #define H0_MIM 0x06     /* not used in Japan */
66 #define H0_TRM 0x07     /* not used in Japan */
67 #define H0_DLM 0x08     /* not used in Japan */
68 #define H0_UFC 0x0a     /* not used in Japan */
69 static const value_string h0_message_type_values[] = {
70   { H0_CHM, "Changeover and changeback messages" },
71   { H0_ECM, "Emergency changeover messages" },
72   { H0_FCM, "Transfer-controlled and signalling route set congestion messages" },
73   { H0_TFM, "Transfer prohibited-allowed-restricted messages" },
74   { H0_RSM, "Signalling-route-set-test messages" },
75   { H0_MIM, "Management inhibit messages" },
76   { H0_TRM, "Traffic restart messages" },
77   { H0_DLM, "Signalling-data-link-connection messages" },
78   { H0_UFC, "User part flow control messages" },
79   { 0,      NULL } };
80
81 #define TEST_H0_SLT 0x1
82 static const value_string test_h0_message_type_values[] = {
83   { TEST_H0_SLT, "Test messages" },
84   { 0,           NULL } };
85
86 #define CHM_H1_COO 0x01
87 #define CHM_H1_COA 0x02
88 #define CHM_H1_XCO 0x03
89 #define CHM_H1_XCA 0x04
90 #define CHM_H1_CBD 0x05
91 #define CHM_H1_CBA 0x06
92 static const value_string chm_h1_message_type_values[] = {
93   { CHM_H1_COO, "Changeover-order signal" },
94   { CHM_H1_COA, "Changeover-ack signal" },
95   { CHM_H1_XCO, "Extended changeover-order signal" },
96   { CHM_H1_XCA, "Extended changeover-ack signal" },
97   { CHM_H1_CBD, "Changeback-declaration signal" },
98   { CHM_H1_CBA, "Changeback-ack signal" },
99   { 0,          NULL } };
100
101 /* Same as above but in acronym form (for the Info column) */
102 static const value_string chm_h1_message_type_acro_values[] = {
103   { CHM_H1_COO, "COO" },
104   { CHM_H1_COA, "COA" },
105   { CHM_H1_XCO, "XCO" },
106   { CHM_H1_XCA, "XCA" },
107   { CHM_H1_CBD, "CBD" },
108   { CHM_H1_CBA, "CBA" },
109   { 0,          NULL } };
110
111 #define ECM_H1_ECO 0x01
112 #define ECM_H1_ECA 0x02
113 static const value_string ecm_h1_message_type_values[] = {
114   { ECM_H1_ECO, "Emergency-changeover-order signal" },
115   { ECM_H1_ECA, "Emergency-changeover-ack signal" },
116   { 0,          NULL } };
117
118 /* Same as above but in acronym form (for the Info column) */
119 static const value_string ecm_h1_message_type_acro_values[] = {
120   { ECM_H1_ECO, "ECO" },
121   { ECM_H1_ECA, "ECA" },
122   { 0,          NULL } };
123
124 #define FCM_H1_RCT 0x01
125 #define FCM_H1_TFC 0x02
126 static const value_string fcm_h1_message_type_values[] = {
127   { FCM_H1_RCT, "Signalling-route-set-congestion-test signal" },
128   { FCM_H1_TFC, "Transfer-controlled signal" },
129   { 0,          NULL } };
130
131 /* Same as above but in acronym form (for the Info column) */
132 static const value_string fcm_h1_message_type_acro_values[] = {
133   { FCM_H1_RCT, "RCT" },
134   { FCM_H1_TFC, "TFC" },
135   { 0,          NULL } };
136
137 #define TFM_H1_TFP 0x01
138 #define TFM_H1_TCP 0x02 /* ANSI only */
139 #define TFM_H1_TFR 0x03
140 #define TFM_H1_TCR 0x04 /* ANSI only */
141 #define TFM_H1_TFA 0x05
142 #define TFM_H1_TCA 0x06 /* ANSI only */
143 static const value_string tfm_h1_message_type_values[] = {
144   { TFM_H1_TFP, "Transfer-prohibited signal" },
145   { TFM_H1_TCP, "Transfer-cluster-prohibited signal (ANSI only)" },
146   { TFM_H1_TFR, "Transfer-restricted signal" },
147   { TFM_H1_TCR, "Transfer-cluster-restricted signal (ANSI only)" },
148   { TFM_H1_TFA, "Transfer-allowed signal" },
149   { TFM_H1_TCA, "Transfer-cluster-allowed signal (ANSI only)" },
150   { 0,          NULL } };
151
152 /* Same as above but in acronym form (for the Info column) */
153 static const value_string tfm_h1_message_type_acro_values[] = {
154   { TFM_H1_TFP, "TFP" },
155   { TFM_H1_TCP, "TCP" },
156   { TFM_H1_TFR, "TFR" },
157   { TFM_H1_TCR, "TCR" },
158   { TFM_H1_TFA, "TFA" },
159   { TFM_H1_TCA, "TCA" },
160   { 0,          NULL } };
161
162 #define RSM_H1_RST 0x01
163 #define RSM_H1_RSR 0x02
164 #define RSM_H1_RCP 0x03 /* ANSI only */
165 #define RSM_H1_RCR 0x04 /* ANSI only */
166 static const value_string rsm_h1_message_type_values[] = {
167   { RSM_H1_RST, "Signalling-route-set-test prohibited signal" },
168   { RSM_H1_RSR, "Signalling-route-set-test restricted signal" },
169   { RSM_H1_RCP, "Signalling-route-set-test cluster-prohibited signal (ANSI only)" },
170   { RSM_H1_RCR, "Signalling-route-set-test cluster-restricted signal (ANSI only)" },
171   { 0,          NULL } };
172
173 /* Same as above but in acronym form (for the Info column) */
174 static const value_string rsm_h1_message_type_acro_values[] = {
175   { RSM_H1_RST, "RST" },
176   { RSM_H1_RSR, "RSR" },
177   { RSM_H1_RCP, "RCP" },
178   { RSM_H1_RCR, "RCR" },
179   { 0,          NULL } };
180
181 #define MIM_H1_LIN 0x01
182 #define MIM_H1_LUN 0x02
183 #define MIM_H1_LIA 0x03
184 #define MIM_H1_LUA 0x04
185 #define MIM_H1_LID 0x05
186 #define MIM_H1_LFU 0x06
187 #define MIM_H1_LLT 0x07 /* LLI in ANSI */
188 #define MIM_H1_LRT 0x08 /* LRI in ANSI */
189 static const value_string mim_h1_message_type_values[] = {
190   { MIM_H1_LIN, "Link inhibit signal" },
191   { MIM_H1_LUN, "Link uninhibit signal" },
192   { MIM_H1_LIA, "Link inhibit ack signal" },
193   { MIM_H1_LUA, "Link uninhibit ack signal" },
194   { MIM_H1_LID, "Link inhibit denied signal" },
195   { MIM_H1_LFU, "Link forced uninhibit signal" },
196   { MIM_H1_LLT, "Link local inhibit test signal" },
197   { MIM_H1_LRT, "Link remote inhibit test signal" },
198   { 0,          NULL } };
199
200 /* Same as above but in acronym form (for the Info column) */
201 static const value_string mim_h1_message_type_acro_values[] = {
202   { MIM_H1_LIN, "LIN" },
203   { MIM_H1_LUN, "LUN" },
204   { MIM_H1_LIA, "LIA" },
205   { MIM_H1_LUA, "LUA" },
206   { MIM_H1_LID, "LID" },
207   { MIM_H1_LFU, "LFU" },
208   { MIM_H1_LLT, "LLT (LLI)" },
209   { MIM_H1_LRT, "LRT (LRI)" },
210   { 0,          NULL } };
211
212 #define TRM_H1_TRA 0x01
213 #define TRM_H1_TRW 0x02 /* ANSI only */
214 static const value_string trm_h1_message_type_values[] = {
215   { TRM_H1_TRA, "Traffic-restart-allowed signal" },
216   { TRM_H1_TRW, "Traffic-restart-waiting signal (ANSI only)" },
217   { 0,          NULL } };
218
219 /* Same as above but in acronym form (for the Info column) */
220 static const value_string trm_h1_message_type_acro_values[] = {
221   { TRM_H1_TRA, "TRA" },
222   { TRM_H1_TRW, "TRW" },
223   { 0,          NULL } };
224
225 #define DLM_H1_DLC 0x01
226 #define DLM_H1_CSS 0x02
227 #define DLM_H1_CNS 0x03
228 #define DLM_H1_CNP 0x04
229 static const value_string dlm_h1_message_type_values[] = {
230   { DLM_H1_DLC, "Signalling-data-link-connection-order signal" },
231   { DLM_H1_CSS, "Connection-successful signal" },
232   { DLM_H1_CNS, "Connection-not-successful signal" },
233   { DLM_H1_CNP, "Connection-not-possible signal" },
234   { 0,          NULL } };
235
236 /* Same as above but in acronym form (for the Info column) */
237 static const value_string dlm_h1_message_type_acro_values[] = {
238   { DLM_H1_DLC, "DLC" },
239   { DLM_H1_CSS, "CSS" },
240   { DLM_H1_CNS, "CNS" },
241   { DLM_H1_CNP, "CNP" },
242   { 0,          NULL } };
243
244 #define UFC_H1_UPU 0x01
245 static const value_string ufc_h1_message_type_values[] = {
246   { UFC_H1_UPU, "User part unavailable signal" },
247   { 0,          NULL } };
248
249 /* Same as above but in acronym form (for the Info column) */
250 static const value_string ufc_h1_message_type_acro_values[] = {
251   { UFC_H1_UPU, "UPU" },
252   { 0,          NULL } };
253
254 static const value_string upu_cause_values[] = {
255   { 0x0, "Unknown" },
256   { 0x1, "Unequipped remote user" },
257   { 0x2, "Inaccessible remote user" },
258   { 0,   NULL } };
259
260 #define TEST_H1_SLTM 0x1
261 #define TEST_H1_SLTA 0x2
262 static const value_string test_h1_message_type_values[] = {
263   { TEST_H1_SLTM, "Signalling link test message" },
264   { TEST_H1_SLTA, "Signalling link test acknowledgement message" },
265   { 0,            NULL } };
266
267 /* Same as above but in acronym form (for the Info column) */
268 static const value_string test_h1_message_type_acro_values[] = {
269   { TEST_H1_SLTM, "SLTM" },
270   { TEST_H1_SLTA, "SLTA" },
271   { 0,            NULL } };
272
273 #define JAPAN_TEST_SRT 0x23
274 #define JAPAN_TEST_SRA 0x84
275 static const value_string japan_test_message_type_values[] = {
276   { JAPAN_TEST_SRT, "Signalling routing test message" },
277   { JAPAN_TEST_SRA, "Signalling routing test acknowledgement message" },
278   { 0,              NULL } };
279
280 /* Same as above but in acronym form (for the Info column) */
281 static const value_string japan_test_message_type_acro_values[] = {
282   { JAPAN_TEST_SRT, "SRT" },
283   { JAPAN_TEST_SRA, "SRA" },
284   { 0,              NULL } };
285
286 #define ANSI_COO_LENGTH    2
287 #define ANSI_COO_SLC_MASK  0x000f
288 #define ANSI_COO_FSN_MASK  0x07f0
289 #define ITU_COO_LENGTH     1
290 #define ITU_COO_FSN_MASK   0x007f
291 #define ANSI_XCO_LENGTH    4
292 #define ANSI_XCO_SLC_MASK  0x0000000f
293 #define ANSI_XCO_FSN_MASK  0x0ffffff0
294 #define ITU_XCO_LENGTH     3
295 #define ANSI_CBD_LENGTH    2
296 #define ANSI_CBD_SLC_MASK  0x000f
297 #define ANSI_CBD_CBC_MASK  0x0ff0
298 #define ITU_CBD_LENGTH     1
299 #define JAPAN_CBD_CBC_MASK 0x3
300
301 #define ANSI_ECO_LENGTH   1
302 #define ANSI_ECO_SLC_MASK 0x0f
303
304 #define ANSI_TFC_STATUS_LENGTH       1
305 #define ANSI_TFC_STATUS_OFFSET       ANSI_PC_LENGTH
306 #define ANSI_TFC_STATUS_MASK         0x03
307 #define ITU_TFC_STATUS_LENGTH        ITU_PC_LENGTH
308 #define ITU_TFC_STATUS_MASK          0xc000
309 #define JAPAN_TFC_SPARE_OFFSET        0
310 #define JAPAN_TFC_SPARE_LENGTH        1
311 #define JAPAN_TFC_APC_OFFSET          JAPAN_TFC_SPARE_LENGTH
312 #define JAPAN_TFC_STATUS_OFFSET       (JAPAN_TFC_SPARE_LENGTH + JAPAN_PC_LENGTH)
313 #define JAPAN_TFC_STATUS_LENGTH       1
314 #define JAPAN_TFC_STATUS_MASK         0x03
315 #define JAPAN_TFC_STATUS_SPARE_MASK   0xfc
316
317 #define JAPAN_TFM_COUNT_OFFSET 0
318 #define JAPAN_TFM_COUNT_LENGTH 1
319
320 #define ANSI_MIM_LENGTH   1
321 #define ANSI_MIM_SLC_MASK 0x0f
322
323 #define ANSI_DLC_LENGTH    3
324 #define ANSI_DLC_SLC_MASK  0x0000f
325 #define ANSI_DLC_LINK_MASK 0x3fff0
326 #define ITU_DLC_LENGTH     2
327 #define ITU_DLC_LINK_MASK  0x0fff
328
329 #define ANSI_UPU_USER_OFFSET ANSI_PC_LENGTH
330 #define UPU_USER_LENGTH      1
331 #define UPU_USER_MASK        0x0f
332 #define UPU_CAUSE_MASK       0xf0
333 #define ITU_UPU_USER_OFFSET  ITU_PC_LENGTH
334
335 #define TEST_LENGTH         1
336 #define TEST_LENGTH_MASK    0xf0
337 #define TEST_LENGTH_SHIFT   4
338 #define TEST_PATTERN_OFFSET TEST_LENGTH
339 #define ANSI_TEST_SLC_MASK  0x000f
340
341 #define JAPAN_SPARE_LENGTH 1
342 #define JAPAN_H0H1_OFFSET JAPAN_SPARE_LENGTH
343
344 #define JAPAN_TEST_SPARE_OFFSET   JAPAN_SPARE_LENGTH + H0H1_LENGTH
345 #define JAPAN_TEST_SPARE_LENGTH   1
346 #define JAPAN_TEST_PATTERN_OFFSET (JAPAN_TEST_SPARE_OFFSET + JAPAN_TEST_SPARE_LENGTH)
347 #define JAPAN_TEST_PATTERN_LENGTH 2
348 #define JAPAN_TEST_PATTERN 0x7711
349
350
351 /* This list is slightly different from that in packet-mtp3.c */
352 static const value_string service_indicator_code_vals[] = {
353         { 0x0,  "Spare" },
354         { 0x1,  "Spare"},
355         { 0x2,  "Spare" },
356         { 0x3,  "SCCP" },
357         { 0x4,  "TUP" },
358         { 0x5,  "ISUP" },
359         { 0x6,  "DUP (call and circuit related messages)" },
360         { 0x7,  "DUP (facility registration and cancellation message)" },
361         { 0x8,  "MTP testing user part" },
362         { 0x9,  "ISUP-b" },
363         { 0xa,  "ISUP-s" },
364         { 0xb,  "Spare" },
365         { 0xc,  "Spare" },
366         { 0xd,  "Spare" },
367         { 0xe,  "Spare" },
368         { 0xf,  "Spare" },
369         { 0,    NULL }
370 };
371
372 /* Initialize the protocol and registered fields */
373 static int proto_mtp3mg  = -1;
374 static int hf_mtp3mg_h0 = -1;
375 static int hf_mtp3mg_chm_h1 = -1;
376 static int hf_mtp3mg_ecm_h1 = -1;
377 static int hf_mtp3mg_fcm_h1 = -1;
378 static int hf_mtp3mg_tfm_h1 = -1;
379 static int hf_mtp3mg_rsm_h1 = -1;
380 static int hf_mtp3mg_mim_h1 = -1;
381 static int hf_mtp3mg_trm_h1 = -1;
382 static int hf_mtp3mg_dlm_h1 = -1;
383 static int hf_mtp3mg_ufc_h1 = -1;
384 static int hf_mtp3mg_coo_ansi_slc = -1;
385 static int hf_mtp3mg_coo_ansi_fsn = -1;
386 static int hf_mtp3mg_coo_itu_fsn = -1;
387 static int hf_mtp3mg_xco_ansi_slc = -1;
388 static int hf_mtp3mg_xco_ansi_fsn = -1;
389 static int hf_mtp3mg_xco_itu_fsn = -1;
390 static int hf_mtp3mg_cbd_ansi_slc = -1;
391 static int hf_mtp3mg_cbd_ansi_cbc = -1;
392 static int hf_mtp3mg_cbd_itu_cbc = -1;
393 static int hf_mtp3mg_cbd_japan_cbc = -1;
394 static int hf_mtp3mg_eco_ansi_slc = -1;
395 static int hf_mtp3mg_tfc_ansi_apc = -1;
396 static int hf_mtp3mg_tfc_apc_member = -1;
397 static int hf_mtp3mg_tfc_apc_cluster = -1;
398 static int hf_mtp3mg_tfc_apc_network = -1;
399 static int hf_mtp3mg_tfc_ansi_status = -1;
400 static int hf_mtp3mg_tfc_itu_apc = -1;
401 static int hf_mtp3mg_tfc_itu_status = -1;
402 static int hf_mtp3mg_tfc_chinese_apc = -1;
403 static int hf_mtp3mg_tfc_japan_spare = -1;
404 static int hf_mtp3mg_tfc_japan_apc = -1;
405 static int hf_mtp3mg_tfc_japan_status = -1;
406 static int hf_mtp3mg_tfc_japan_status_spare = -1;
407 static int hf_mtp3mg_tfm_ansi_apc = -1;
408 static int hf_mtp3mg_tfm_apc_member = -1;
409 static int hf_mtp3mg_tfm_apc_cluster = -1;
410 static int hf_mtp3mg_tfm_apc_network = -1;
411 static int hf_mtp3mg_tfm_itu_apc = -1;
412 static int hf_mtp3mg_tfm_chinese_apc = -1;
413 static int hf_mtp3mg_tfm_japan_count = -1;
414 static int hf_mtp3mg_tfm_japan_apc = -1;
415 static int hf_mtp3mg_tfm_japan_spare = -1;
416 static int hf_mtp3mg_rsm_ansi_apc = -1;
417 static int hf_mtp3mg_rsm_apc_member = -1;
418 static int hf_mtp3mg_rsm_apc_cluster = -1;
419 static int hf_mtp3mg_rsm_apc_network = -1;
420 static int hf_mtp3mg_rsm_itu_apc = -1;
421 static int hf_mtp3mg_rsm_chinese_apc = -1;
422 static int hf_mtp3mg_rsm_japan_count = -1;
423 static int hf_mtp3mg_rsm_japan_apc = -1;
424 static int hf_mtp3mg_rsm_japan_spare = -1;
425 static int hf_mtp3mg_mim_ansi_slc = -1;
426 static int hf_mtp3mg_dlc_ansi_slc = -1;
427 static int hf_mtp3mg_dlc_ansi_link = -1;
428 static int hf_mtp3mg_dlc_itu_link = -1;
429 static int hf_mtp3mg_upu_ansi_apc = -1;
430 static int hf_mtp3mg_upu_apc_member = -1;
431 static int hf_mtp3mg_upu_apc_cluster = -1;
432 static int hf_mtp3mg_upu_apc_network = -1;
433 static int hf_mtp3mg_upu_itu_apc = -1;
434 static int hf_mtp3mg_upu_chinese_apc = -1;
435 static int hf_mtp3mg_upu_japan_apc = -1;
436 static int hf_mtp3mg_upu_user = -1;
437 static int hf_mtp3mg_upu_cause = -1;
438 static int hf_mtp3test_h0 = -1;
439 static int hf_mtp3mg_test_h1 = -1;
440 static int hf_mtp3mg_test_ansi_slc = -1;
441 static int hf_mtp3mg_test_length = -1;
442 static int hf_mtp3mg_japan_test = -1;
443 static int hf_mtp3mg_japan_test_spare = -1;
444 static int hf_mtp3mg_japan_test_pattern = -1;
445 static int hf_mtp3mg_japan_spare = -1;
446
447 /* Initialize the subtree pointers */
448 static gint ett_mtp3mg = -1;
449 static gint ett_mtp3mg_fcm_apc = -1;
450 static gint ett_mtp3mg_tfm_apc = -1;
451 static gint ett_mtp3mg_rsm_apc = -1;
452 static gint ett_mtp3mg_upu_apc = -1;
453
454 static void
455 dissect_mtp3mg_unknown_message(tvbuff_t *tvb, proto_tree *tree)
456 {
457     guint8 message_length;
458
459     message_length = tvb_length(tvb);
460     proto_tree_add_text(tree, tvb, 0, message_length,
461                         "Unknown message (%u byte%s)", message_length,
462                         plurality(message_length, "", "s"));
463 }
464
465 static void
466 dissect_mtp3mg_chm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
467                    guint8 h1)
468 {
469     if (check_col(pinfo->cinfo, COL_INFO))
470         col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
471                      val_to_str(h1, chm_h1_message_type_acro_values, "Unknown"));
472
473     switch (h1)
474     {
475     case CHM_H1_COO:
476     case CHM_H1_COA:
477         if (mtp3_standard == ANSI_STANDARD)
478         {
479             proto_tree_add_item(tree, hf_mtp3mg_coo_ansi_slc, tvb, 0,
480                                 ANSI_COO_LENGTH, TRUE);
481             proto_tree_add_item(tree, hf_mtp3mg_coo_ansi_fsn, tvb, 0,
482                                 ANSI_COO_LENGTH, TRUE);
483         } else /* ITU_STANDARD, CHINESE_ITU_STANDARD, and JAPAN_STANDARD */ {
484             proto_tree_add_item(tree, hf_mtp3mg_coo_itu_fsn, tvb, 0,
485                                 ITU_COO_LENGTH, TRUE);
486         }
487         break;
488
489     case CHM_H1_XCO:
490     case CHM_H1_XCA:
491         if (mtp3_standard == ANSI_STANDARD)
492         {
493             proto_tree_add_item(tree, hf_mtp3mg_xco_ansi_slc, tvb, 0,
494                                 ANSI_XCO_LENGTH, TRUE);
495             proto_tree_add_item(tree, hf_mtp3mg_xco_ansi_fsn, tvb, 0,
496                                 ANSI_XCO_LENGTH, TRUE);
497         } else /* ITU_STANDARD, CHINESE_ITU_STANDARD, and JAPAN_STANDARD */ {
498             proto_tree_add_item(tree, hf_mtp3mg_xco_itu_fsn, tvb, 0,
499                                 ITU_XCO_LENGTH, TRUE);
500         }
501         break;
502
503     case CHM_H1_CBD:
504     case CHM_H1_CBA:
505         if (mtp3_standard == ANSI_STANDARD)
506         {
507             proto_tree_add_item(tree, hf_mtp3mg_cbd_ansi_slc, tvb, 0,
508                                 ANSI_CBD_LENGTH, TRUE);
509             proto_tree_add_item(tree, hf_mtp3mg_cbd_ansi_cbc, tvb, 0,
510                                 ANSI_CBD_LENGTH, TRUE);
511         } else if (mtp3_standard == JAPAN_STANDARD) {
512             proto_tree_add_item(tree, hf_mtp3mg_cbd_japan_cbc, tvb, 0,
513                                 ITU_CBD_LENGTH, TRUE);
514         } else /* ITU_STANDARD and CHINESE_ITU_STANDARD */ {
515             proto_tree_add_item(tree, hf_mtp3mg_cbd_itu_cbc, tvb, 0,
516                                 ITU_CBD_LENGTH, TRUE);
517         }
518         break;
519
520     default:
521         dissect_mtp3mg_unknown_message(tvb, tree);
522   }
523 }
524
525 static void
526 dissect_mtp3mg_ecm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
527                    guint8 h1)
528 {
529     if (check_col(pinfo->cinfo, COL_INFO))
530         col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
531                      val_to_str(h1, ecm_h1_message_type_acro_values, "Unknown"));
532
533     switch (h1)
534     {
535     case ECM_H1_ECO:
536     case ECM_H1_ECA:
537         if (mtp3_standard == ANSI_STANDARD)
538         {
539             proto_tree_add_item(tree, hf_mtp3mg_eco_ansi_slc, tvb, 0,
540                                 ANSI_ECO_LENGTH, TRUE);
541         }
542         /* else: nothing to dissect */
543         break;
544
545     default:
546         dissect_mtp3mg_unknown_message(tvb, tree);
547     }
548 }
549
550 static void
551 dissect_mtp3mg_fcm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
552                    guint8 h1)
553 {
554     proto_item *apc_item;
555
556     if (check_col(pinfo->cinfo, COL_INFO))
557         col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
558                      val_to_str(h1, fcm_h1_message_type_acro_values, "Unknown"));
559
560     switch (h1)
561     {
562     case FCM_H1_RCT:
563         /* nothing to dissect */
564         break;
565
566     case FCM_H1_TFC:
567         if (mtp3_standard == ITU_STANDARD)
568         {
569
570             apc_item = proto_tree_add_item(tree, hf_mtp3mg_tfc_itu_apc, tvb, 0,
571                                            ITU_PC_LENGTH, TRUE);
572
573             if (mtp3_pc_structured())
574             {
575                 guint32 apc;
576
577                 apc = tvb_get_letohs(tvb, 0) & ITU_PC_MASK;
578                 proto_item_append_text(apc_item, " (%s)", mtp3_pc_to_str(apc));
579             }
580
581             /* Congestion level is a national option */
582             proto_tree_add_item(tree, hf_mtp3mg_tfc_itu_status, tvb, 0,
583                                 ITU_TFC_STATUS_LENGTH, TRUE);
584
585
586
587         } else if (mtp3_standard == JAPAN_STANDARD) {
588
589             proto_tree_add_item(tree, hf_mtp3mg_tfc_japan_spare, tvb,
590                                 JAPAN_TFC_SPARE_OFFSET,
591                                 JAPAN_TFC_SPARE_LENGTH, TRUE);
592
593             apc_item = proto_tree_add_item(tree, hf_mtp3mg_tfc_japan_apc, tvb,
594                                            JAPAN_TFC_APC_OFFSET,
595                                            JAPAN_PC_LENGTH, TRUE);
596             if (mtp3_pc_structured())
597             {
598                 guint32 apc;
599
600                 apc = tvb_get_letohs(tvb, JAPAN_TFC_APC_OFFSET);
601                 proto_item_append_text(apc_item, " (%s)", mtp3_pc_to_str(apc));
602             }
603
604             proto_tree_add_item(tree, hf_mtp3mg_tfc_japan_status, tvb,
605                                 JAPAN_TFC_STATUS_OFFSET,
606                                 JAPAN_TFC_STATUS_LENGTH, TRUE);
607             proto_tree_add_item(tree, hf_mtp3mg_tfc_japan_status_spare, tvb,
608                                 JAPAN_TFC_STATUS_OFFSET,
609                                 JAPAN_TFC_STATUS_LENGTH, TRUE);
610
611         } else /* ANSI_STANDARD and CHINESE_ITU_STANDARD */ {
612
613             int *hf_apc_string;
614
615             if (mtp3_standard == ANSI_STANDARD) {
616
617                 hf_apc_string = &hf_mtp3mg_tfc_ansi_apc;
618
619             } else /* CHINESE_ITU_STANDARD */ {
620
621                 hf_apc_string = &hf_mtp3mg_tfc_chinese_apc;
622             }
623
624             dissect_mtp3_3byte_pc(tvb, 0, tree, ett_mtp3mg_fcm_apc,
625                                   *hf_apc_string, hf_mtp3mg_tfc_apc_network,
626                                   hf_mtp3mg_tfc_apc_cluster,
627                                   hf_mtp3mg_tfc_apc_member, 0, 0);
628
629             proto_tree_add_item(tree, hf_mtp3mg_tfc_ansi_status, tvb,
630                                 ANSI_TFC_STATUS_OFFSET, ANSI_TFC_STATUS_LENGTH,
631                                 TRUE);
632
633         }
634         break;
635
636     default:
637         dissect_mtp3mg_unknown_message(tvb, tree);
638     }
639 }
640
641 static void
642 dissect_mtp3mg_tfm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
643                    guint8 h1)
644 {
645     proto_item *apc_item;
646
647     if (check_col(pinfo->cinfo, COL_INFO))
648         col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
649                      val_to_str(h1, tfm_h1_message_type_acro_values, "Unknown"));
650
651     switch (h1)
652     {
653     case TFM_H1_TFP:
654     case TFM_H1_TCP:
655     case TFM_H1_TFR:
656     case TFM_H1_TCR:
657     case TFM_H1_TFA:
658     case TFM_H1_TCA:
659         if (mtp3_standard == ANSI_STANDARD)
660         {
661             dissect_mtp3_3byte_pc(tvb, 0, tree, ett_mtp3mg_tfm_apc,
662                                   hf_mtp3mg_tfm_ansi_apc,
663                                   hf_mtp3mg_tfm_apc_network,
664                                   hf_mtp3mg_tfm_apc_cluster,
665                                   hf_mtp3mg_tfm_apc_member, 0, 0);
666
667         } else if (mtp3_standard == JAPAN_STANDARD) {
668             guint8 count, i;
669             guint32 offset;
670
671             if (h1 == TFM_H1_TCP || h1 == TFM_H1_TCR || h1 == TFM_H1_TCA
672                 || h1 == TFM_H1_TFR)
673                 dissect_mtp3mg_unknown_message(tvb, tree);
674
675             proto_tree_add_item(tree, hf_mtp3mg_tfm_japan_count, tvb,
676                                 JAPAN_TFM_COUNT_OFFSET,
677                                 JAPAN_TFM_COUNT_LENGTH, TRUE);
678
679             count = tvb_get_guint8(tvb, JAPAN_TFM_COUNT_OFFSET);
680             offset = JAPAN_TFM_COUNT_LENGTH;
681             for (i = 0; i < count; i++)
682             {
683                 apc_item = proto_tree_add_item(tree, hf_mtp3mg_tfm_japan_apc, tvb,
684                                     offset, JAPAN_PC_LENGTH, TRUE);
685                 if (mtp3_pc_structured())
686                 {
687                     guint32 apc;
688
689                     apc = tvb_get_letohs(tvb, offset);
690                     proto_item_append_text(apc_item, " (%s)", mtp3_pc_to_str(apc));
691                 }
692                 offset += JAPAN_PC_LENGTH;
693                 proto_tree_add_item(tree, hf_mtp3mg_tfm_japan_spare, tvb,
694                                     offset, JAPAN_PC_LENGTH, TRUE);
695                 offset += JAPAN_PC_LENGTH;
696             }
697         } else /* ITU_STANDARD and CHINESE_ITU_STANDARD */ {
698
699             if (h1 == TFM_H1_TCP || h1 == TFM_H1_TCR || h1 == TFM_H1_TCA)
700                 dissect_mtp3mg_unknown_message(tvb, tree);
701             else if (mtp3_standard == ITU_STANDARD)
702             {
703                 apc_item = proto_tree_add_item(tree, hf_mtp3mg_tfm_itu_apc,
704                                                tvb, 0, ITU_PC_LENGTH, TRUE);
705                 if (mtp3_pc_structured())
706                 {
707                     guint32 apc;
708
709                     apc = tvb_get_letohs(tvb, 0) & ITU_PC_MASK;
710                     proto_item_append_text(apc_item, " (%s)", mtp3_pc_to_str(apc));
711                 }
712             }
713             else if (mtp3_standard == CHINESE_ITU_STANDARD)
714                 dissect_mtp3_3byte_pc(tvb, 0, tree, ett_mtp3mg_tfm_apc,
715                                       hf_mtp3mg_tfm_chinese_apc,
716                                       hf_mtp3mg_tfm_apc_network,
717                                       hf_mtp3mg_tfm_apc_cluster,
718                                       hf_mtp3mg_tfm_apc_member, 0, 0);
719         }
720         break;
721
722     default:
723         dissect_mtp3mg_unknown_message(tvb, tree);
724     }
725 }
726
727 static void
728 dissect_mtp3mg_rsm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
729                    guint8 h1)
730 {
731     proto_item *apc_item;
732
733     if (check_col(pinfo->cinfo, COL_INFO))
734         col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
735                      val_to_str(h1, rsm_h1_message_type_acro_values, "Unknown"));
736
737     switch (h1)
738     {
739     case RSM_H1_RST:
740     case RSM_H1_RSR:
741     case RSM_H1_RCP:
742     case RSM_H1_RCR:
743         if (mtp3_standard == ANSI_STANDARD)
744         {
745             dissect_mtp3_3byte_pc(tvb, 0, tree, ett_mtp3mg_rsm_apc,
746                                   hf_mtp3mg_rsm_ansi_apc,
747                                   hf_mtp3mg_rsm_apc_network,
748                                   hf_mtp3mg_rsm_apc_cluster,
749                                   hf_mtp3mg_rsm_apc_member, 0, 0);
750
751         } else if (mtp3_standard == JAPAN_STANDARD) {
752             if (h1 == RSM_H1_RST)
753             {
754                 guint32 offset;
755                 guint8 count, i;
756
757                 proto_tree_add_item(tree, hf_mtp3mg_rsm_japan_count, tvb,
758                                     JAPAN_TFM_COUNT_OFFSET,
759                                     JAPAN_TFM_COUNT_LENGTH, TRUE);
760
761                 count = tvb_get_guint8(tvb, JAPAN_TFM_COUNT_OFFSET);
762                 offset = JAPAN_TFM_COUNT_LENGTH;
763                 for (i = 0; i < count; i++)
764                 {
765                     apc_item = proto_tree_add_item(tree,
766                                                    hf_mtp3mg_rsm_japan_apc,
767                                                    tvb, offset,
768                                                    JAPAN_PC_LENGTH, TRUE);
769                     if (mtp3_pc_structured())
770                     {
771                         guint32 apc;
772
773                         apc = tvb_get_letohs(tvb, 0);
774                         proto_item_append_text(apc_item, " (%s)", mtp3_pc_to_str(apc));
775                     }
776                     offset += JAPAN_PC_LENGTH;
777                     proto_tree_add_item(tree, hf_mtp3mg_rsm_japan_spare, tvb,
778                                         offset, JAPAN_PC_LENGTH, TRUE);
779                     offset += JAPAN_PC_LENGTH;
780                 }
781             } else
782                 dissect_mtp3mg_unknown_message(tvb, tree);
783
784         } else /* ITU_STANDARD and CHINESE_ITU_STANDARD */ {
785
786             if (h1 == RSM_H1_RST || h1 == RSM_H1_RSR)
787             {
788                 if (mtp3_standard == ITU_STANDARD)
789                 {
790                     apc_item = proto_tree_add_item(tree, hf_mtp3mg_rsm_itu_apc,
791                                                    tvb, 0, ITU_PC_LENGTH, TRUE);
792                     if (mtp3_pc_structured())
793                     {
794                         guint32 apc;
795
796                         apc = tvb_get_letohs(tvb, 0) & ITU_PC_MASK;
797                         proto_item_append_text(apc_item, " (%s)", mtp3_pc_to_str(apc));
798                     }
799                 }
800                 else /* CHINESE_ITU_STANDARD */
801                     dissect_mtp3_3byte_pc(tvb, 0, tree, ett_mtp3mg_rsm_apc,
802                                           hf_mtp3mg_rsm_chinese_apc,
803                                           hf_mtp3mg_rsm_apc_network,
804                                           hf_mtp3mg_rsm_apc_cluster,
805                                           hf_mtp3mg_rsm_apc_member, 0, 0);
806             } else
807                 dissect_mtp3mg_unknown_message(tvb, tree);
808         }
809         break;
810
811     default:
812         dissect_mtp3mg_unknown_message(tvb, tree);
813     }
814 }
815
816 static void
817 dissect_mtp3mg_mim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
818                    guint8 h1)
819 {
820     if (check_col(pinfo->cinfo, COL_INFO))
821         col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
822                      val_to_str(h1, mim_h1_message_type_acro_values, "Unknown"));
823
824     switch (h1)
825     {
826     case MIM_H1_LIN:
827     case MIM_H1_LUN:
828     case MIM_H1_LIA:
829     case MIM_H1_LUA:
830     case MIM_H1_LID:
831     case MIM_H1_LFU:
832     case MIM_H1_LLT:
833     case MIM_H1_LRT:
834         if (mtp3_standard == ANSI_STANDARD)
835         {
836             proto_tree_add_item(tree, hf_mtp3mg_mim_ansi_slc, tvb, 0,
837                                 ANSI_MIM_LENGTH, TRUE);
838         }
839         /* else: nothing to dissect */
840         break;
841
842     default:
843         dissect_mtp3mg_unknown_message(tvb, tree);
844     }
845 }
846
847 static void
848 dissect_mtp3mg_trm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
849                    guint8 h1)
850 {
851     if (check_col(pinfo->cinfo, COL_INFO))
852         col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
853                      val_to_str(h1, trm_h1_message_type_acro_values, "Unknown"));
854
855     switch (h1)
856     {
857     case TRM_H1_TRA:
858         /* nothing to dissect */
859         break;
860     case TRM_H1_TRW:
861         if (mtp3_standard != ANSI_STANDARD)
862             dissect_mtp3mg_unknown_message(tvb, tree);
863         /* else: nothing to dissect */
864         break;
865
866     default:
867         dissect_mtp3mg_unknown_message(tvb, tree);
868     }
869 }
870
871 static void
872 dissect_mtp3mg_dlm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
873                    guint8 h1)
874 {
875     if (check_col(pinfo->cinfo, COL_INFO))
876         col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
877                      val_to_str(h1, dlm_h1_message_type_acro_values, "Unknown"));
878
879     switch (h1)
880     {
881     case DLM_H1_DLC:
882         if (mtp3_standard == ANSI_STANDARD)
883         {
884             proto_tree_add_item(tree, hf_mtp3mg_dlc_ansi_slc, tvb, 0,
885                                 ANSI_DLC_LENGTH, TRUE);
886             proto_tree_add_item(tree, hf_mtp3mg_dlc_ansi_link, tvb, 0,
887                                 ANSI_DLC_LENGTH, TRUE);
888         } else /* ITU_STANDARD and CHINESE_ITU_STANDARD */ {
889             proto_tree_add_item(tree, hf_mtp3mg_dlc_itu_link, tvb, 0,
890                                 ITU_DLC_LENGTH, TRUE);
891         }
892         break;
893     case DLM_H1_CSS:
894     case DLM_H1_CNS:
895     case DLM_H1_CNP:
896         /* nothing to dissect */
897         break;
898
899     default:
900         dissect_mtp3mg_unknown_message(tvb, tree);
901     }
902 }
903
904 static void
905 dissect_mtp3mg_ufc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
906                    guint8 h1)
907 {
908     proto_item *apc_item;
909
910     if (check_col(pinfo->cinfo, COL_INFO))
911         col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
912                      val_to_str(h1, ufc_h1_message_type_acro_values, "Unknown"));
913
914     switch (h1)
915     {
916     case UFC_H1_UPU:
917         if (mtp3_standard == ANSI_STANDARD
918             || mtp3_standard == CHINESE_ITU_STANDARD)
919         {
920             int *hf_apc;
921
922             if (mtp3_standard == ANSI_STANDARD)
923                 hf_apc = &hf_mtp3mg_upu_ansi_apc;
924             else /* CHINESE_ITU_STANDARD */
925                 hf_apc = &hf_mtp3mg_upu_chinese_apc;
926
927             dissect_mtp3_3byte_pc(tvb, 0, tree, ett_mtp3mg_upu_apc, *hf_apc,
928                                   hf_mtp3mg_rsm_apc_network,
929                                   hf_mtp3mg_rsm_apc_cluster,
930                                   hf_mtp3mg_rsm_apc_member, 0, 0);
931
932             proto_tree_add_item(tree, hf_mtp3mg_upu_user, tvb,
933                                 ANSI_UPU_USER_OFFSET, UPU_USER_LENGTH, TRUE);
934             proto_tree_add_item(tree, hf_mtp3mg_upu_cause, tvb,
935                                 ANSI_UPU_USER_OFFSET, UPU_USER_LENGTH, TRUE);
936         } else if (mtp3_standard == ITU_STANDARD) {
937
938             apc_item = proto_tree_add_item(tree, hf_mtp3mg_upu_itu_apc, tvb, 0,
939                                            ITU_PC_LENGTH, TRUE);
940             if (mtp3_pc_structured())
941             {
942                 guint32 apc;
943
944                 apc = tvb_get_letohs(tvb, 0) & ITU_PC_MASK;
945                 proto_item_append_text(apc_item, " (%s)", mtp3_pc_to_str(apc));
946             }
947
948             proto_tree_add_item(tree, hf_mtp3mg_upu_user, tvb,
949                                 ITU_UPU_USER_OFFSET, UPU_USER_LENGTH, TRUE);
950             proto_tree_add_item(tree, hf_mtp3mg_upu_cause, tvb,
951                                 ITU_UPU_USER_OFFSET, UPU_USER_LENGTH, TRUE);
952         } else { /* JAPAN_STANDARD */
953
954             apc_item = proto_tree_add_item(tree, hf_mtp3mg_upu_japan_apc, tvb,
955                                            0, JAPAN_PC_LENGTH, TRUE);
956             if (mtp3_pc_structured())
957             {
958                 guint32 apc;
959
960                 apc = tvb_get_letohs(tvb, 0);
961                 proto_item_append_text(apc_item, " (%s)", mtp3_pc_to_str(apc));
962             }
963
964             proto_tree_add_item(tree, hf_mtp3mg_upu_user, tvb,
965                                 ITU_UPU_USER_OFFSET, UPU_USER_LENGTH, TRUE);
966             proto_tree_add_item(tree, hf_mtp3mg_upu_cause, tvb,
967                                 ITU_UPU_USER_OFFSET, UPU_USER_LENGTH, TRUE);
968         }
969         break;
970
971     default:
972         dissect_mtp3mg_unknown_message(tvb, tree);
973     }
974 }
975
976 static void
977 dissect_mtp3mg_test(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
978                    guint8 h1)
979 {
980     guint8 length;
981
982     if (check_col(pinfo->cinfo, COL_INFO))
983         col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
984                      val_to_str(h1, test_h1_message_type_acro_values, "Unknown"));
985
986     switch (h1)
987     {
988     case TEST_H1_SLTM:
989     case TEST_H1_SLTA:
990         if (mtp3_standard == ANSI_STANDARD)
991         {
992             proto_tree_add_item(tree, hf_mtp3mg_test_ansi_slc, tvb, 0,
993                                 TEST_LENGTH, TRUE);
994         }
995
996         proto_tree_add_item(tree, hf_mtp3mg_test_length, tvb, 0, TEST_LENGTH,
997                             TRUE);
998
999         length = tvb_get_guint8(tvb, 0) >> TEST_LENGTH_SHIFT;
1000         proto_tree_add_text(tree, tvb, TEST_PATTERN_OFFSET, length,
1001                             "Test pattern (%u byte%s)", length,
1002                             plurality(length, "", "s"));
1003         break;
1004
1005     default:
1006         dissect_mtp3mg_unknown_message(tvb, tree);
1007     }
1008 }
1009
1010 static void
1011 dissect_mtp3mg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1012 {
1013
1014     guint8 h0, h1;
1015     tvbuff_t *payload_tvb;
1016
1017     /* Set up structures needed to add the protocol subtree and manage it */
1018     proto_item *mtp3mg_item = NULL;
1019     proto_tree *mtp3mg_tree = NULL;
1020
1021     /* Make entries in Protocol column on summary display */
1022     if (check_col(pinfo->cinfo, COL_PROTOCOL))
1023       switch(mtp3_standard) {
1024         case ITU_STANDARD:
1025           col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3MG (Int. ITU)");
1026           break;
1027         case ANSI_STANDARD:
1028           col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3MG (ANSI)");
1029           break;
1030         case CHINESE_ITU_STANDARD:
1031           col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3MG (Chin. ITU)");
1032           break;
1033         case JAPAN_STANDARD:
1034           col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3MG (Japan)");
1035           break;
1036       };
1037
1038     if (tree) {
1039         /* create display subtree for the protocol */
1040         mtp3mg_item = proto_tree_add_item(tree, proto_mtp3mg, tvb, 0, -1, TRUE);
1041         mtp3mg_tree = proto_item_add_subtree(mtp3mg_item, ett_mtp3mg);
1042     }
1043
1044     /*
1045      *  Dissect the message
1046      */
1047     if(pinfo->private_data == (void *)MTP3MG_ANSI_TEST_SI ||
1048        pinfo->private_data == (void *)MTP3MG_ITU_TEST_SI)
1049     {   /* Test messages */
1050
1051         if (mtp3_standard == JAPAN_STANDARD)
1052         {
1053             guint8 h0h1;
1054             guint16 test_pattern;
1055             proto_item *pattern_item;
1056
1057             proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_japan_spare, tvb, 0,
1058                                 JAPAN_SPARE_LENGTH, TRUE);
1059
1060             h0h1 = tvb_get_guint8(tvb, JAPAN_H0H1_OFFSET);
1061
1062             proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_japan_test, tvb,
1063                                 JAPAN_SPARE_LENGTH, H0H1_LENGTH, TRUE);
1064
1065             if (check_col(pinfo->cinfo, COL_INFO))
1066                 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ",
1067                              val_to_str(h0h1, japan_test_message_type_acro_values, "Unknown"));
1068
1069             switch (h0h1)
1070             {
1071             case JAPAN_TEST_SRT:
1072             case JAPAN_TEST_SRA:
1073                 proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_japan_test_spare,
1074                                     tvb, JAPAN_TEST_SPARE_OFFSET,
1075                                     JAPAN_TEST_SPARE_LENGTH, TRUE);
1076
1077                 test_pattern = tvb_get_letohl(tvb, JAPAN_TEST_PATTERN_OFFSET);
1078                 pattern_item = proto_tree_add_item(mtp3mg_tree,
1079                                                    hf_mtp3mg_japan_test_pattern,
1080                                                    tvb,
1081                                                    JAPAN_TEST_PATTERN_OFFSET,
1082                                                    JAPAN_TEST_PATTERN_LENGTH,
1083                                                    TRUE);
1084                 proto_item_append_text(pattern_item, " (%s)",
1085                                        test_pattern == JAPAN_TEST_PATTERN
1086                                        ? "correct" : "incorrect");
1087                 break;
1088
1089             default:
1090                 dissect_mtp3mg_unknown_message(tvb, mtp3mg_tree);
1091             }
1092
1093         } else { /* not JAPAN */
1094             proto_tree_add_item(mtp3mg_tree, hf_mtp3test_h0, tvb, 0, H0H1_LENGTH, TRUE);
1095             /* H1 is added below */
1096
1097             h0 = tvb_get_guint8(tvb, 0) & H0_MASK;
1098             h1 = (tvb_get_guint8(tvb, 0) & H1_MASK) >> H1_SHIFT;
1099
1100             payload_tvb = tvb_new_subset_remaining(tvb, H0H1_LENGTH);
1101
1102             switch (h0)
1103             {
1104             case TEST_H0_SLT:
1105                 proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_test_h1, tvb, 0,
1106                                     H0H1_LENGTH, TRUE);
1107                 dissect_mtp3mg_test(payload_tvb, pinfo, mtp3mg_tree, h1);
1108                 break;
1109
1110             default:
1111                 col_set_str(pinfo->cinfo, COL_INFO, "Unknown ");
1112
1113                 dissect_mtp3mg_unknown_message(tvb, mtp3mg_tree);
1114             } /* switch */
1115
1116         }
1117
1118     } else {    /* Real management messages */
1119
1120
1121         if (mtp3_standard == JAPAN_STANDARD)
1122         {
1123             proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_japan_spare, tvb, 0,
1124                                 JAPAN_SPARE_LENGTH, TRUE);
1125
1126             /*  Get a tvb w/o the spare byte--it makes for less code below */
1127             tvb = tvb_new_subset_remaining(tvb, JAPAN_SPARE_LENGTH);
1128         }
1129
1130         proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_h0, tvb, 0, H0H1_LENGTH,
1131                             TRUE);
1132         /* H1 is added below */
1133
1134         h0 = tvb_get_guint8(tvb, 0) & H0_MASK;
1135         h1 = (tvb_get_guint8(tvb, 0) & H1_MASK) >> H1_SHIFT;
1136
1137         payload_tvb = tvb_new_subset_remaining(tvb, H0H1_LENGTH);
1138
1139         switch (h0)
1140         {
1141         case H0_CHM:
1142             proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_chm_h1, tvb, 0,
1143                                 H0H1_LENGTH, TRUE);
1144             dissect_mtp3mg_chm(payload_tvb, pinfo, mtp3mg_tree, h1);
1145             break;
1146         case H0_ECM:
1147             proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_ecm_h1, tvb, 0,
1148                                 H0H1_LENGTH, TRUE);
1149             dissect_mtp3mg_ecm(payload_tvb, pinfo, mtp3mg_tree, h1);
1150             break;
1151         case H0_FCM:
1152             proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_fcm_h1, tvb, 0,
1153                                 H0H1_LENGTH, TRUE);
1154             dissect_mtp3mg_fcm(payload_tvb, pinfo, mtp3mg_tree, h1);
1155             break;
1156         case H0_TFM:
1157             proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_tfm_h1, tvb, 0,
1158                                 H0H1_LENGTH, TRUE);
1159             dissect_mtp3mg_tfm(payload_tvb, pinfo, mtp3mg_tree, h1);
1160             break;
1161         case H0_RSM:
1162             proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_rsm_h1, tvb, 0,
1163                                 H0H1_LENGTH, TRUE);
1164             dissect_mtp3mg_rsm(payload_tvb, pinfo, mtp3mg_tree, h1);
1165             break;
1166         case H0_MIM:
1167             if (mtp3_standard != JAPAN_STANDARD)
1168             {
1169                 proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_mim_h1, tvb, 0,
1170                                     H0H1_LENGTH, TRUE);
1171                 dissect_mtp3mg_mim(payload_tvb, pinfo, mtp3mg_tree, h1);
1172             } else
1173                 dissect_mtp3mg_unknown_message(tvb, mtp3mg_tree);
1174             break;
1175         case H0_TRM:
1176             if (mtp3_standard != JAPAN_STANDARD)
1177             {
1178                 proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_trm_h1, tvb, 0,
1179                                     H0H1_LENGTH, TRUE);
1180                 dissect_mtp3mg_trm(payload_tvb, pinfo, mtp3mg_tree, h1);
1181             } else
1182                 dissect_mtp3mg_unknown_message(tvb, mtp3mg_tree);
1183             break;
1184         case H0_DLM:
1185             if (mtp3_standard != JAPAN_STANDARD)
1186             {
1187                 proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_dlm_h1, tvb, 0,
1188                                     H0H1_LENGTH, TRUE);
1189                 dissect_mtp3mg_dlm(payload_tvb, pinfo, mtp3mg_tree, h1);
1190             } else
1191                 dissect_mtp3mg_unknown_message(tvb, mtp3mg_tree);
1192             break;
1193         case H0_UFC:
1194             if (mtp3_standard != JAPAN_STANDARD)
1195             {
1196                 proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_ufc_h1, tvb, 0,
1197                                     H0H1_LENGTH, TRUE);
1198                 dissect_mtp3mg_ufc(payload_tvb, pinfo, mtp3mg_tree, h1);
1199             } else
1200                 dissect_mtp3mg_unknown_message(tvb, mtp3mg_tree);
1201             break;
1202
1203         default:
1204             col_set_str(pinfo->cinfo, COL_INFO, "Unknown ");
1205
1206             dissect_mtp3mg_unknown_message(tvb, mtp3mg_tree);
1207         } /* switch */
1208     } /* else */
1209
1210 }
1211
1212 void
1213 proto_register_mtp3mg(void)
1214 {
1215
1216     /* Setup list of header fields  See Section 1.6.1 for details*/
1217     static hf_register_info hf[] = {
1218         { &hf_mtp3mg_h0,
1219             { "H0 (Message Group)", "mtp3mg.h0",
1220               FT_UINT8, BASE_HEX, VALS(h0_message_type_values), H0_MASK,
1221               "Message group identifier", HFILL }},
1222         { &hf_mtp3mg_chm_h1,
1223             { "H1 (Message)", "mtp3mg.h1",
1224               FT_UINT8, BASE_HEX, VALS(chm_h1_message_type_values), H1_MASK,
1225               "Message type", HFILL }},
1226         { &hf_mtp3mg_ecm_h1,
1227             { "H1 (Message)", "mtp3mg.h1",
1228               FT_UINT8, BASE_HEX, VALS(ecm_h1_message_type_values), H1_MASK,
1229               "Message type", HFILL }},
1230         { &hf_mtp3mg_fcm_h1,
1231             { "H1 (Message)", "mtp3mg.h1",
1232               FT_UINT8, BASE_HEX, VALS(fcm_h1_message_type_values), H1_MASK,
1233               "Message type", HFILL }},
1234         { &hf_mtp3mg_tfm_h1,
1235             { "H1 (Message)", "mtp3mg.h1",
1236               FT_UINT8, BASE_HEX, VALS(tfm_h1_message_type_values), H1_MASK,
1237               "Message type", HFILL }},
1238         { &hf_mtp3mg_rsm_h1,
1239             { "H1 (Message)", "mtp3mg.h1",
1240               FT_UINT8, BASE_HEX, VALS(rsm_h1_message_type_values), H1_MASK,
1241               "Message type", HFILL }},
1242         { &hf_mtp3mg_mim_h1,
1243             { "H1 (Message)", "mtp3mg.h1",
1244               FT_UINT8, BASE_HEX, VALS(mim_h1_message_type_values), H1_MASK,
1245               "Message type", HFILL }},
1246         { &hf_mtp3mg_trm_h1,
1247             { "H1 (Message)", "mtp3mg.h1",
1248               FT_UINT8, BASE_HEX, VALS(trm_h1_message_type_values), H1_MASK,
1249               "Message type", HFILL }},
1250         { &hf_mtp3mg_dlm_h1,
1251             { "H1 (Message)", "mtp3mg.h1",
1252               FT_UINT8, BASE_HEX, VALS(dlm_h1_message_type_values), H1_MASK,
1253               "Message type", HFILL }},
1254         { &hf_mtp3mg_ufc_h1,
1255             { "H1 (Message)", "mtp3mg.h1",
1256               FT_UINT8, BASE_HEX, VALS(ufc_h1_message_type_values), H1_MASK,
1257               "Message type", HFILL }},
1258         { &hf_mtp3mg_coo_ansi_slc,
1259             { "Signalling Link Code", "mtp3mg.slc",
1260               FT_UINT8, BASE_DEC, NULL, ANSI_COO_SLC_MASK,
1261               "SLC of affected link", HFILL }},
1262         { &hf_mtp3mg_coo_ansi_fsn,
1263             { "Forward Sequence Number", "mtp3mg.fsn",
1264               FT_UINT8, BASE_DEC, NULL, ANSI_COO_FSN_MASK,
1265               "Forward Sequence Number of last accepted message", HFILL }},
1266         { &hf_mtp3mg_coo_itu_fsn,
1267             { "Forward Sequence Number", "mtp3mg.fsn",
1268               FT_UINT8, BASE_DEC, NULL, ITU_COO_FSN_MASK,
1269               "Forward Sequence Number of last accepted message", HFILL }},
1270         { &hf_mtp3mg_xco_ansi_slc,
1271             { "Signalling Link Code", "mtp3mg.slc",
1272               FT_UINT32, BASE_DEC, NULL, ANSI_XCO_SLC_MASK,
1273               "SLC of affected link", HFILL }},
1274         { &hf_mtp3mg_xco_ansi_fsn,
1275             { "Forward Sequence Number", "mtp3mg.fsn",
1276               FT_UINT32, BASE_DEC, NULL, ANSI_XCO_FSN_MASK,
1277               "Forward Sequence Number of last accepted message", HFILL }},
1278         { &hf_mtp3mg_xco_itu_fsn,
1279             { "Forward Sequence Number", "mtp3mg.fsn",
1280               FT_UINT24, BASE_DEC, NULL, 0x0,
1281               "Forward Sequence Number of last accepted message", HFILL }},
1282         { &hf_mtp3mg_cbd_ansi_slc,
1283             { "Signalling Link Code", "mtp3mg.slc",
1284               FT_UINT16, BASE_DEC, NULL, ANSI_CBD_SLC_MASK,
1285               "SLC of affected link", HFILL }},
1286         { &hf_mtp3mg_cbd_ansi_cbc,
1287             { "Change Back Code", "mtp3mg.cbc",
1288               FT_UINT16, BASE_DEC, NULL, ANSI_CBD_CBC_MASK,
1289               NULL, HFILL }},
1290         { &hf_mtp3mg_cbd_itu_cbc,
1291             { "Change Back Code", "mtp3mg.cbc",
1292               FT_UINT8, BASE_DEC, NULL, 0x0,
1293               NULL, HFILL }},
1294         { &hf_mtp3mg_cbd_japan_cbc,
1295             { "Change Back Code", "mtp3mg.cbc",
1296               FT_UINT8, BASE_DEC, NULL, JAPAN_CBD_CBC_MASK,
1297               NULL, HFILL }},
1298         { &hf_mtp3mg_eco_ansi_slc,
1299             { "Signalling Link Code", "mtp3mg.slc",
1300               FT_UINT8, BASE_DEC, NULL, ANSI_ECO_SLC_MASK,
1301               "SLC of affected link", HFILL }},
1302         { &hf_mtp3mg_tfc_ansi_apc,
1303             { "Affected Point Code", "mtp3mg.ansi_apc",
1304               FT_STRING, BASE_NONE, NULL, 0x0,
1305               NULL, HFILL }},
1306         { &hf_mtp3mg_tfc_apc_member,
1307             { "Affected Point Code member", "mtp3mg.apc.member",
1308               FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
1309               NULL, HFILL }},
1310         { &hf_mtp3mg_tfc_apc_cluster,
1311             { "Affected Point Code cluster", "mtp3mg.apc.cluster",
1312               FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
1313               NULL, HFILL }},
1314         { &hf_mtp3mg_tfc_apc_network,
1315             { "Affected Point Code network", "mtp3mg.apc.network",
1316               FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
1317               NULL, HFILL }},
1318         { &hf_mtp3mg_tfc_ansi_status,
1319             { "Status", "mtp3mg.status",
1320               FT_UINT8, BASE_DEC, NULL, ANSI_TFC_STATUS_MASK,
1321               "Congestion status", HFILL }},
1322         { &hf_mtp3mg_tfc_itu_apc,
1323             { "Affected Point Code (ITU)", "mtp3mg.apc",
1324               FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
1325               NULL, HFILL }},
1326         { &hf_mtp3mg_tfc_itu_status,
1327             { "Status", "mtp3mg.status",
1328               FT_UINT8, BASE_DEC, NULL, ITU_TFC_STATUS_MASK,
1329               "Congestion status", HFILL }},
1330         { &hf_mtp3mg_tfc_chinese_apc,
1331             { "Affected Point Code", "mtp3mg.chinese_apc",
1332               FT_STRING, BASE_NONE, NULL, 0x0,
1333               NULL, HFILL }},
1334         { &hf_mtp3mg_tfc_japan_spare,
1335             { "TFC spare (Japan)", "mtp3mg.japan_spare",
1336               FT_UINT8, BASE_HEX, NULL, 0x0,
1337               NULL, HFILL }},
1338         { &hf_mtp3mg_tfc_japan_apc,
1339             { "Affected Point Code", "mtp3mg.japan_apc",
1340               FT_UINT16, BASE_DEC, NULL, 0x0,
1341               NULL, HFILL }},
1342         { &hf_mtp3mg_tfc_japan_status,
1343             { "Status", "mtp3mg.japan_status",
1344               FT_UINT8, BASE_DEC, NULL, JAPAN_TFC_STATUS_MASK,
1345               NULL, HFILL }},
1346         { &hf_mtp3mg_tfc_japan_status_spare,
1347             { "Spare (Japan)", "mtp3mg.japan_spare",
1348               FT_UINT8, BASE_HEX, NULL, JAPAN_TFC_STATUS_SPARE_MASK,
1349               NULL, HFILL }},
1350         { &hf_mtp3mg_tfm_ansi_apc,
1351             { "Affected Point Code", "mtp3mg.ansi_apc",
1352               FT_STRING, BASE_NONE, NULL, 0x0,
1353               NULL, HFILL }},
1354         { &hf_mtp3mg_tfm_apc_member,
1355             { "Affected Point Code member", "mtp3mg.apc.member",
1356               FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
1357               NULL, HFILL }},
1358         { &hf_mtp3mg_tfm_apc_cluster,
1359             { "Affected Point Code cluster", "mtp3mg.apc.cluster",
1360               FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
1361               NULL, HFILL }},
1362         { &hf_mtp3mg_tfm_apc_network,
1363             { "Affected Point Code network", "mtp3mg.apc.network",
1364               FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
1365               NULL, HFILL }},
1366         { &hf_mtp3mg_tfm_itu_apc,
1367             { "Affected Point Code (ITU)", "mtp3mg.apc",
1368               FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
1369               NULL, HFILL }},
1370         { &hf_mtp3mg_tfm_chinese_apc,
1371             { "Affected Point Code", "mtp3mg.chinese_apc",
1372               FT_STRING, BASE_NONE, NULL, 0x0,
1373               NULL, HFILL }},
1374         { &hf_mtp3mg_tfm_japan_count,
1375             { "Count of Affected Point Codes (Japan)", "mtp3mg.japan_count",
1376               FT_UINT8, BASE_DEC, NULL, 0x0,
1377               NULL, HFILL }},
1378         { &hf_mtp3mg_tfm_japan_apc,
1379             { "Affected Point Code", "mtp3mg.japan_apc",
1380               FT_UINT16, BASE_DEC, NULL, 0x0,
1381               NULL, HFILL }},
1382         { &hf_mtp3mg_tfm_japan_spare,
1383             { "Spare (Japan)", "mtp3mg.japan_spare",
1384               FT_UINT16, BASE_DEC, NULL, 0x0,
1385               NULL, HFILL }},
1386         { &hf_mtp3mg_rsm_ansi_apc,
1387             { "Affected Point Code", "mtp3mg.ansi_apc",
1388               FT_STRING, BASE_NONE, NULL, 0x0,
1389               NULL, HFILL }},
1390         { &hf_mtp3mg_rsm_apc_member,
1391             { "Affected Point Code member", "mtp3mg.apc.member",
1392               FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
1393               NULL, HFILL }},
1394         { &hf_mtp3mg_rsm_apc_cluster,
1395             { "Affected Point Code cluster", "mtp3mg.apc.cluster",
1396               FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
1397               NULL, HFILL }},
1398         { &hf_mtp3mg_rsm_apc_network,
1399             { "Affected Point Code network", "mtp3mg.apc.network",
1400               FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
1401               NULL, HFILL }},
1402         { &hf_mtp3mg_rsm_itu_apc,
1403             { "Affected Point Code (ITU)", "mtp3mg.apc",
1404               FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
1405               NULL, HFILL }},
1406         { &hf_mtp3mg_rsm_chinese_apc,
1407             { "Affected Point Code", "mtp3mg.chinese_apc",
1408               FT_STRING, BASE_NONE, NULL, 0x0,
1409               NULL, HFILL }},
1410         { &hf_mtp3mg_rsm_japan_count,
1411             { "Count of Affected Point Codes (Japan)", "mtp3mg.japan_count",
1412               FT_UINT8, BASE_DEC, NULL, 0x0,
1413               NULL, HFILL }},
1414         { &hf_mtp3mg_rsm_japan_apc,
1415             { "Affected Point Code", "mtp3mg.japan_apc",
1416               FT_UINT16, BASE_DEC, NULL, 0x0,
1417               NULL, HFILL }},
1418         { &hf_mtp3mg_rsm_japan_spare,
1419             { "Spare (Japan)", "mtp3mg.japan_spare",
1420               FT_UINT16, BASE_DEC, NULL, 0x0,
1421               NULL, HFILL }},
1422         { &hf_mtp3mg_mim_ansi_slc,
1423             { "Signalling Link Code", "mtp3mg.slc",
1424               FT_UINT8, BASE_DEC, NULL, ANSI_MIM_SLC_MASK,
1425               "SLC of affected link", HFILL }},
1426         { &hf_mtp3mg_dlc_ansi_slc,
1427             { "Signalling Link Code", "mtp3mg.slc",
1428               FT_UINT8, BASE_DEC, NULL, ANSI_DLC_SLC_MASK,
1429               "SLC of affected link", HFILL }},
1430         { &hf_mtp3mg_dlc_ansi_link,
1431             { "Link", "mtp3mg.link",
1432               FT_UINT8, BASE_DEC, NULL, ANSI_DLC_LINK_MASK,
1433               "CIC of BIC used to carry data", HFILL }},
1434         { &hf_mtp3mg_dlc_itu_link,
1435             { "Link", "mtp3mg.link",
1436               FT_UINT8, BASE_DEC, NULL, ITU_DLC_LINK_MASK,
1437               "CIC of BIC used to carry data", HFILL }},
1438         { &hf_mtp3mg_upu_ansi_apc,
1439             { "Affected Point Code", "mtp3mg.ansi_apc",
1440               FT_STRING, BASE_NONE, NULL, 0x0,
1441               NULL, HFILL }},
1442         { &hf_mtp3mg_upu_apc_member,
1443             { "Affected Point Code member", "mtp3mg.apc.member",
1444               FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
1445               NULL, HFILL }},
1446         { &hf_mtp3mg_upu_apc_cluster,
1447             { "Affected Point Code cluster", "mtp3mg.apc.cluster",
1448               FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
1449               NULL, HFILL }},
1450         { &hf_mtp3mg_upu_apc_network,
1451             { "Affected Point Code network", "mtp3mg.apc.network",
1452               FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
1453               NULL, HFILL }},
1454         { &hf_mtp3mg_upu_itu_apc,
1455             { "Affected Point Code", "mtp3mg.apc",
1456               FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
1457               NULL, HFILL }},
1458         { &hf_mtp3mg_upu_chinese_apc,
1459             { "Affected Point Code", "mtp3mg.chinese_apc",
1460               FT_STRING, BASE_NONE, NULL, 0x0,
1461               NULL, HFILL }},
1462         { &hf_mtp3mg_upu_japan_apc,
1463             { "Affected Point Code", "mtp3mg.apc",
1464               FT_UINT16, BASE_DEC, NULL, JAPAN_PC_MASK,
1465               NULL, HFILL }},
1466         { &hf_mtp3mg_upu_user,
1467             { "User", "mtp3mg.user",
1468               FT_UINT8, BASE_HEX, VALS(service_indicator_code_vals), UPU_USER_MASK,
1469               "Unavailable user part", HFILL }},
1470         { &hf_mtp3mg_upu_cause,
1471             { "Cause", "mtp3mg.cause",
1472               FT_UINT8, BASE_HEX, VALS(upu_cause_values), UPU_CAUSE_MASK,
1473               "Cause of user unavailability", HFILL }},
1474         { &hf_mtp3test_h0,
1475             { "H0 (Message Group)", "mtp3mg.test.h0",
1476               FT_UINT8, BASE_HEX, VALS(test_h0_message_type_values), H0_MASK,
1477               "Message group identifier", HFILL }},
1478         { &hf_mtp3mg_test_h1,
1479             { "H1 (Message)", "mtp3mg.test.h1",
1480               FT_UINT8, BASE_HEX, VALS(test_h1_message_type_values), H1_MASK,
1481               "SLT message type", HFILL }},
1482         { &hf_mtp3mg_test_length,
1483             { "Test length", "mtp3mg.test.length",
1484               FT_UINT8, BASE_DEC, NULL, H1_MASK,
1485               "Signalling link test pattern length", HFILL }},
1486         { &hf_mtp3mg_japan_test,
1487             { "Japan test message", "mtp3mg.test",
1488               FT_UINT8, BASE_HEX, VALS(japan_test_message_type_values), 0x0,
1489               "Japan test message type", HFILL }},
1490         { &hf_mtp3mg_japan_test_spare,
1491             { "Japan test message spare", "mtp3mg.test.spare",
1492               FT_UINT8, BASE_HEX, NULL, 0x0,
1493               NULL, HFILL }},
1494         { &hf_mtp3mg_japan_test_pattern,
1495             { "Japan test message pattern", "mtp3mg.test.pattern",
1496               FT_UINT16, BASE_HEX, NULL, 0x0,
1497               NULL, HFILL }},
1498         { &hf_mtp3mg_japan_spare,
1499             { "Japan management spare", "mtp3mg.spare",
1500               FT_UINT8, BASE_HEX, NULL, 0x0,
1501               NULL, HFILL }},
1502         { &hf_mtp3mg_test_ansi_slc,
1503             { "Signalling Link Code", "mtp3mg.slc",
1504               FT_UINT8, BASE_DEC, NULL, ANSI_TEST_SLC_MASK,
1505               "SLC of affected link", HFILL }}
1506   };
1507
1508     /* Setup protocol subtree array */
1509     static gint *ett[] = {
1510         &ett_mtp3mg,
1511         &ett_mtp3mg_fcm_apc,
1512         &ett_mtp3mg_tfm_apc,
1513         &ett_mtp3mg_rsm_apc,
1514         &ett_mtp3mg_upu_apc
1515     };
1516
1517     /* Register the protocol name and description */
1518     proto_mtp3mg = proto_register_protocol("Message Transfer Part Level 3 Management",
1519                                            "MTP3MG", "mtp3mg");
1520     register_dissector("mtp3mg", dissect_mtp3mg, proto_mtp3mg);
1521
1522     /* Required calls to register the header fields and subtrees used */
1523     proto_register_field_array(proto_mtp3mg, hf, array_length(hf));
1524     proto_register_subtree_array(ett, array_length(ett));
1525
1526 }
1527
1528 void
1529 proto_reg_handoff_mtp3mg(void)
1530 {
1531     dissector_handle_t mtp3mg_handle;
1532
1533     mtp3mg_handle = find_dissector("mtp3mg");
1534
1535     dissector_add("mtp3.service_indicator", MTP3MG_SI, mtp3mg_handle);
1536
1537     /*  SI 1 is unused in ANSI and SI 2 is unused in ITU, so it's okay for us
1538      *  to grab both (regardless of mtp3.standard setting) here.
1539      */
1540     dissector_add("mtp3.service_indicator", MTP3MG_ITU_TEST_SI, mtp3mg_handle);
1541     dissector_add("mtp3.service_indicator", MTP3MG_ANSI_TEST_SI, mtp3mg_handle);
1542 }
1543