some compilers dont like unnamed unions and structs
[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 <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include <glib.h>
37
38 #include <epan/packet.h>
39 #include <epan/proto.h>
40
41 #include "prefs.h"
42
43
44 /* Initialize the protocol and registered fields */
45 static int proto_lge_monitor            = -1;
46
47 static int hf_lge_monitor_dir = -1;
48 static int hf_lge_monitor_prot = -1;
49 static int hf_lge_monitor_length = -1;
50
51 /* Initialize the subtree pointers */
52 static int ett_lge_monitor = -1;
53
54
55 static guint LGEMonitorUDPPort = 0;
56 static guint udp_port = 0;
57 static dissector_handle_t mtp3_handle, m3ua_handle, sccp_handle, sctp_handle;
58
59 static const value_string lge_monitor_dir_vals[] = {
60         { 0x00, "TX(Transmit Message Signaling Unit)" },
61         { 0x01, "RX(Receive Message Signaling Unit)" },
62         { 0,    NULL }
63 };
64
65 static const value_string lge_monitor_prot_vals[] = {
66         { 0x00, "MTP-3(Message Transfer Part 3)" },
67         { 0x01, "SCCP(Signaling Connection Control Part)"},
68         { 0x02, "SCTP(Stream Control Transmission Protocol)"},
69         { 0x03, "M3UA(MTP-3 User Adaptation)"},
70         { 0,    NULL }
71 };
72
73 #define LGEMON_PROTO_HEADER_LENGTH 12
74
75 /* Code to actually dissect the packets */
76 static void
77 dissect_lge_monitor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
78 {
79         int offset = 0;
80         guint32 lge_monitor_proto_id;
81         tvbuff_t* next_tvb = NULL;
82
83 /* Set up structures needed to add the protocol subtree and manage it */
84         proto_item *ti;
85         proto_tree *lge_monitor_tree;
86
87 /* Make entries in Protocol column and Info column on summary display */
88         if (check_col(pinfo->cinfo, COL_PROTOCOL)) 
89                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LGE Monitor");
90
91         ti = proto_tree_add_item(tree, proto_lge_monitor, tvb, 0, LGEMON_PROTO_HEADER_LENGTH, FALSE);
92         lge_monitor_tree = proto_item_add_subtree(ti, ett_lge_monitor);
93
94         proto_tree_add_text(lge_monitor_tree, tvb, offset, LGEMON_PROTO_HEADER_LENGTH, "LGE Monitor PDU");
95         proto_tree_add_item(lge_monitor_tree, hf_lge_monitor_dir, tvb, offset, 4, FALSE);
96         offset = offset +4;
97         lge_monitor_proto_id = tvb_get_ntohl(tvb,offset);
98         proto_tree_add_item(lge_monitor_tree, hf_lge_monitor_prot, tvb, offset, 4, FALSE);
99         offset = offset +4;
100         proto_tree_add_item(lge_monitor_tree, hf_lge_monitor_length, tvb, offset, 4, FALSE);
101         offset = offset +4;
102
103         next_tvb = tvb_new_subset(tvb, offset, -1, -1);
104
105         switch (lge_monitor_proto_id){
106         case 0: /* MTP3 */
107                 call_dissector(mtp3_handle, next_tvb, pinfo, tree);
108                 break;
109         case 1: /* SCCP */
110                 call_dissector(sccp_handle, next_tvb, pinfo, tree);
111                 break;
112         case 2: /* SCTP */
113                 call_dissector(sctp_handle, next_tvb, pinfo, tree);
114                 return;
115         case 3: /* M3UA */
116                 call_dissector(m3ua_handle, next_tvb, pinfo, tree);
117                 return;
118         default:
119                 proto_tree_add_text(lge_monitor_tree, tvb, offset, -1, "LGE Monitor data");
120                 break;
121         }
122         return;
123 }
124
125
126 void
127 proto_reg_handoff_lge_monitor(void)
128 {
129         dissector_handle_t lge_monitor_handle;
130         static int lge_monitor_prefs_initialized = FALSE;
131         
132         lge_monitor_handle = create_dissector_handle(dissect_lge_monitor, proto_lge_monitor);
133
134         if (!lge_monitor_prefs_initialized) {
135                 lge_monitor_prefs_initialized = TRUE;
136           }
137         else {
138                 dissector_delete("udp.port", udp_port, lge_monitor_handle);
139         }
140
141         udp_port = LGEMonitorUDPPort;
142         dissector_add("udp.port", LGEMonitorUDPPort, lge_monitor_handle);
143         mtp3_handle  = find_dissector("mtp3");
144         m3ua_handle  = find_dissector("m3ua");
145         sccp_handle  = find_dissector("sccp");
146         sctp_handle  = find_dissector("sctp");
147 }
148
149 void
150 proto_register_lge_monitor(void)
151 {                 
152
153         module_t *lge_monitor_module;
154
155 /* Setup list of header fields  */
156         static hf_register_info hf[] = {
157                 { &hf_lge_monitor_dir,
158                         { "Direction",           "lge_monitor.dir",
159                         FT_UINT32, BASE_DEC, VALS(lge_monitor_dir_vals), 0x0,          
160                         "Direction", HFILL }
161                 },
162                 { &hf_lge_monitor_prot,
163                         { "Protocol Identifier",           "lge_monitor.prot",
164                         FT_UINT32, BASE_DEC, VALS(lge_monitor_prot_vals), 0x0,          
165                         "Protocol Identifier", HFILL }
166                 },
167                 { &hf_lge_monitor_length,
168                         { "Payload Length",           "lge_monitor.length",
169                         FT_UINT32, BASE_DEC, NULL, 0x0,          
170                         "Payload Length", HFILL }
171                 },
172         };
173
174 /* Setup protocol subtree array */
175         static gint *ett[] = {
176                 &ett_lge_monitor,
177         };
178
179 /* Register the protocol name and description */
180         proto_lge_monitor = proto_register_protocol("LGE Monitor","LGE_Monitor", "lge_monitor");
181
182 /* Required function calls to register the header fields and subtrees used */
183         proto_register_field_array(proto_lge_monitor, hf, array_length(hf));
184         proto_register_subtree_array(ett, array_length(ett));
185         /* Register a configuration option for port */
186
187         
188         lge_monitor_module = prefs_register_protocol(proto_lge_monitor, proto_reg_handoff_lge_monitor);
189
190         prefs_register_uint_preference(lge_monitor_module, "udp.port",
191                                                                    "LGE Monitor UDP Port",
192                                                                    "Set UDP port for LGE Monitor messages",
193                                                                    10,
194                                                                    &LGEMonitorUDPPort);
195
196 }
197
198