For proto_tree_add_item(..., proto_xxx, ...)use ENC_NA as the encoding arg.
[obnox/wireshark/wip.git] / epan / dissectors / packet-lge_monitor.c
1 /* packet-lge_monitor.c
2  * Routines for LGE Monitor packet dissection
3  * Copyright 2006, Anders Broman <anders.broman[at]ericsson.com>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24  *
25  * LGE Monitor is a trace tool from Nortel.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <glib.h>
33
34 #include <epan/packet.h>
35 #include <epan/prefs.h>
36
37
38 /* Initialize the protocol and registered fields */
39 static int proto_lge_monitor            = -1;
40
41 static int hf_lge_monitor_dir = -1;
42 static int hf_lge_monitor_prot = -1;
43 static int hf_lge_monitor_length = -1;
44
45 /* Initialize the subtree pointers */
46 static int ett_lge_monitor = -1;
47
48
49 static guint LGEMonitorUDPPort = 0;
50 static dissector_handle_t mtp3_handle, m3ua_handle, sccp_handle, sctp_handle;
51
52 static const value_string lge_monitor_dir_vals[] = {
53         { 0x00, "TX(Transmit Message Signaling Unit)" },
54         { 0x01, "RX(Receive Message Signaling Unit)" },
55         { 0,    NULL }
56 };
57
58 static const value_string lge_monitor_prot_vals[] = {
59         { 0x00, "MTP-3(Message Transfer Part 3)" },
60         { 0x01, "SCCP(Signaling Connection Control Part)"},
61         { 0x02, "SCTP(Stream Control Transmission Protocol)"},
62         { 0x03, "M3UA(MTP-3 User Adaptation)"},
63         { 0,    NULL }
64 };
65
66 #define LGEMON_PROTO_HEADER_LENGTH 12
67
68 /* Code to actually dissect the packets */
69 static void
70 dissect_lge_monitor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
71 {
72         int offset = 0;
73         guint32 lge_monitor_proto_id;
74         tvbuff_t* next_tvb = NULL;
75
76 /* Set up structures needed to add the protocol subtree and manage it */
77         proto_item *ti;
78         proto_tree *lge_monitor_tree;
79
80 /* Make entries in Protocol column and Info column on summary display */
81         col_set_str(pinfo->cinfo, COL_PROTOCOL, "LGE Monitor");
82
83         ti = proto_tree_add_item(tree, proto_lge_monitor, tvb, 0, LGEMON_PROTO_HEADER_LENGTH, ENC_NA);
84         lge_monitor_tree = proto_item_add_subtree(ti, ett_lge_monitor);
85
86         proto_tree_add_text(lge_monitor_tree, tvb, offset, LGEMON_PROTO_HEADER_LENGTH, "LGE Monitor PDU");
87         proto_tree_add_item(lge_monitor_tree, hf_lge_monitor_dir, tvb, offset, 4, ENC_BIG_ENDIAN);
88         offset = offset +4;
89         lge_monitor_proto_id = tvb_get_ntohl(tvb,offset);
90         proto_tree_add_item(lge_monitor_tree, hf_lge_monitor_prot, tvb, offset, 4, ENC_BIG_ENDIAN);
91         offset = offset +4;
92         proto_tree_add_item(lge_monitor_tree, hf_lge_monitor_length, tvb, offset, 4, ENC_BIG_ENDIAN);
93         offset = offset +4;
94
95         next_tvb = tvb_new_subset_remaining(tvb, offset);
96
97         switch (lge_monitor_proto_id){
98         case 0: /* MTP3 */
99                 call_dissector(mtp3_handle, next_tvb, pinfo, tree);
100                 break;
101         case 1: /* SCCP */
102                 call_dissector(sccp_handle, next_tvb, pinfo, tree);
103                 break;
104         case 2: /* SCTP */
105                 call_dissector(sctp_handle, next_tvb, pinfo, tree);
106                 return;
107         case 3: /* M3UA */
108                 call_dissector(m3ua_handle, next_tvb, pinfo, tree);
109                 return;
110         default:
111                 proto_tree_add_text(lge_monitor_tree, tvb, offset, -1, "LGE Monitor data");
112                 break;
113         }
114         return;
115 }
116
117
118 void
119 proto_reg_handoff_lge_monitor(void)
120 {
121         static dissector_handle_t lge_monitor_handle;
122         static guint saved_udp_port;
123         static gboolean lge_monitor_prefs_initialized = FALSE;
124
125         if (!lge_monitor_prefs_initialized) {
126                 lge_monitor_handle = create_dissector_handle(dissect_lge_monitor, proto_lge_monitor);
127                 dissector_add_handle("udp.port", lge_monitor_handle);  /* for 'decode-as' */
128                 mtp3_handle  = find_dissector("mtp3");
129                 m3ua_handle  = find_dissector("m3ua");
130                 sccp_handle  = find_dissector("sccp");
131                 sctp_handle  = find_dissector("sctp");
132                 lge_monitor_prefs_initialized = TRUE;
133           }
134         else {
135                 if (saved_udp_port != 0) {
136                         dissector_delete_uint("udp.port", saved_udp_port, lge_monitor_handle);
137                 }
138         }
139
140         if (LGEMonitorUDPPort != 0) {
141                 dissector_add_uint("udp.port", LGEMonitorUDPPort, lge_monitor_handle);
142         }
143         saved_udp_port = LGEMonitorUDPPort;
144 }
145
146 void
147 proto_register_lge_monitor(void)
148 {
149
150         module_t *lge_monitor_module;
151
152 /* Setup list of header fields  */
153         static hf_register_info hf[] = {
154                 { &hf_lge_monitor_dir,
155                         { "Direction",           "lge_monitor.dir",
156                         FT_UINT32, BASE_DEC, VALS(lge_monitor_dir_vals), 0x0,
157                         NULL, HFILL }
158                 },
159                 { &hf_lge_monitor_prot,
160                         { "Protocol Identifier",           "lge_monitor.prot",
161                         FT_UINT32, BASE_DEC, VALS(lge_monitor_prot_vals), 0x0,
162                         NULL, HFILL }
163                 },
164                 { &hf_lge_monitor_length,
165                         { "Payload Length",           "lge_monitor.length",
166                         FT_UINT32, BASE_DEC, NULL, 0x0,
167                         NULL, HFILL }
168                 },
169         };
170
171 /* Setup protocol subtree array */
172         static gint *ett[] = {
173                 &ett_lge_monitor,
174         };
175
176 /* Register the protocol name and description */
177         proto_lge_monitor = proto_register_protocol("LGE Monitor","LGE_Monitor", "lge_monitor");
178
179 /* Required function calls to register the header fields and subtrees used */
180         proto_register_field_array(proto_lge_monitor, hf, array_length(hf));
181         proto_register_subtree_array(ett, array_length(ett));
182         /* Register a configuration option for port */
183
184
185         lge_monitor_module = prefs_register_protocol(proto_lge_monitor, proto_reg_handoff_lge_monitor);
186
187         prefs_register_uint_preference(lge_monitor_module, "udp.port",
188                                                                    "LGE Monitor UDP Port",
189                                                                    "Set UDP port for LGE Monitor messages",
190                                                                    10,
191                                                                    &LGEMonitorUDPPort);
192
193 }
194
195