Don't do any Decode As stuff for dissector tables not used with Decode As.
[metze/wireshark/wip.git] / epan / dissectors / packet-ua.c
1 /* packet-ua.c
2  * Routines for UA/UDP (Universal Alcatel over UDP) packet dissection.
3  * Copyright 2012, Alcatel-Lucent Enterprise <lars.ruoff@alcatel-lucent.com>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include "config.h"
25
26 #include <epan/packet.h>
27 #include <epan/prefs.h>
28
29 #include "packet-rtp.h"
30 #include "packet-rtcp.h"
31 #include "packet-uaudp.h"
32
33 void proto_register_ua_msg(void);
34 void proto_reg_handoff_ua_msg(void);
35 /*-----------------------------------------------------------------------------
36   GLOBALS
37   ---------------------------------------------------------------------------*/
38
39 #if 0
40 static dissector_table_t ua_opcode_dissector_table;
41 #endif
42
43 static int  proto_ua_msg        = -1;
44 static gint ett_ua_msg          = -1;
45
46 static gboolean setup_conversations_enabled = TRUE;
47
48 static dissector_handle_t noe_handle;
49 static dissector_handle_t ua3g_handle;
50
51 static void uadecode(e_ua_direction  direction,
52                      proto_tree     *tree,
53                      packet_info    *pinfo,
54                      tvbuff_t       *tvb,
55                      gint            offset,
56                      gint            opcode,
57                      gint            length)
58 {
59     switch (opcode & 0x7f) /* suppression of the CP bit */
60     {
61     case 0x15:
62     case 0x16:
63         {
64             call_dissector(noe_handle,
65                            tvb_new_subset_length(tvb, offset, length),
66                            pinfo,
67                            tree);
68             break;
69         }
70     case 0x00:
71     case 0x01:
72     case 0x02:
73     case 0x03:
74     case 0x04:
75     case 0x05:
76     case 0x06:
77     case 0x07:  /* Only UA NOE */
78     case 0x08:  /* Only UA NOE */
79     case 0x09:
80     case 0x0A:
81     case 0x0B:
82     case 0x0C:
83     case 0x0D:
84     case 0x0E:
85     case 0x0F:
86     case 0x11:
87     case 0x12:
88     case 0x13:
89     case 0x14:
90     case 0x17:
91     case 0x18:
92     case 0x1F:  /* case 0x9F */
93     case 0x20:
94     case 0x21:
95     case 0x22:
96     case 0x23:
97     case 0x24:  /* Only IP NOE */
98     case 0x25:  /* Only IP NOE */
99     case 0x26:
100     case 0x27:
101     case 0x28:
102     case 0x29:
103     case 0x2A:
104     case 0x2B:  /* Only UA NOE */
105     case 0x2C:
106     case 0x2D:
107     case 0x2E:
108     case 0x30:
109     case 0x31:
110     case 0x32:  /* Only UA NOE */
111     case 0x33:
112     case 0x35:
113     case 0x36:  /* IP Phone */
114     case 0x38:
115     case 0x39:
116     case 0x3A:
117     case 0x3B:
118     case 0x3C:
119     case 0x3D:
120     case 0x3E:
121     case 0x3F:
122     case 0x40:
123     case 0x41:
124     case 0x42:
125     case 0x43:
126     case 0x44:
127     case 0x45:
128     case 0x46:
129     case 0x47:
130     case 0x48:
131     case 0x49:
132     case 0x4A:
133     case 0x4B:
134     case 0x4C:
135     case 0x4D:
136     case 0x4E:
137     case 0x4F:
138     case 0x50:  /* Only UA NOE */
139         {
140             call_dissector_with_data(ua3g_handle,
141                        tvb_new_subset_length(tvb, offset, length),
142                        pinfo,
143                        tree, &direction);
144             break;
145         }
146     default:
147         {
148             /* add text to the frame "INFO" column */
149             col_append_fstr(pinfo->cinfo, COL_INFO, " - UA3G Message ERR: Opcode (0x%02x) Unknown", tvb_get_guint8(tvb, (offset + 2)));
150
151             call_data_dissector(tvb_new_subset_length(tvb, offset, length),
152                            pinfo,
153                            tree);
154             break;
155         }
156     }
157 }
158
159
160
161 /*-----------------------------------------------------------------------------
162   UA DISSECTOR
163   ---------------------------------------------------------------------------*/
164 static void _dissect_ua_msg(tvbuff_t       *tvb,
165                             packet_info    *pinfo,
166                             proto_tree     *tree,
167                             e_ua_direction  direction)
168 {
169     gint        offset = 0;
170     proto_item *ua_msg_item;
171     proto_tree *ua_msg_tree;
172
173     ua_msg_item = proto_tree_add_protocol_format(tree, proto_ua_msg, tvb, 0, -1,
174         "Universal Alcatel Protocol, %s",
175         ((direction == SYS_TO_TERM) ?
176         "System -> Terminal" : "Terminal -> System"));
177
178     ua_msg_tree = proto_item_add_subtree(ua_msg_item, ett_ua_msg);
179
180     while (tvb_offset_exists(tvb, offset))
181     {
182         gint length;
183         gint opcode;
184
185         length = tvb_get_letohs(tvb, offset) + 2;
186         opcode = tvb_get_guint8(tvb, offset+2);
187
188         /* RTP/RTCP conversation setup */
189         if (setup_conversations_enabled && (opcode==0x13) && (tvb_get_guint8(tvb, offset+3)==0x01))
190         {
191             address remote_rtp_addr;
192             guint32 remote_rtp_port;
193             gint    suboffset;
194
195             remote_rtp_addr.data = NULL;
196             remote_rtp_port = 0;
197
198             /* StartRTP */
199             suboffset = offset + 5;
200
201             while (suboffset < offset+length)
202             {
203                 switch (tvb_get_guint8(tvb, suboffset))
204                 {
205                 case 0x00: /* local port */
206                     {
207                     /*local_rtp_port = tvb_get_ntohs(tvb, suboffset+2);*/
208                     break;
209                     }
210                 case 0x01: /* remote IP */
211                     {
212                     set_address_tvb(&remote_rtp_addr, AT_IPv4, 4, tvb, suboffset+2);
213                     break;
214                     }
215                 case 0x02: /* remote port */
216                     {
217                     remote_rtp_port = tvb_get_ntohs(tvb, suboffset+2);
218                     break;
219                     }
220                 }
221
222             suboffset += tvb_get_guint8(tvb, suboffset+1) + 2;
223             }
224
225             if ((remote_rtp_addr.data != NULL) && (remote_rtp_port != 0))
226             {
227                 rtp_add_address(pinfo, &remote_rtp_addr, remote_rtp_port, 0,
228                         "UA", pinfo->num, 0, NULL);
229                 rtcp_add_address(pinfo, &remote_rtp_addr, remote_rtp_port+1, 0,
230                          "UA", pinfo->num);
231             }
232         }
233
234         uadecode(direction, ua_msg_tree, pinfo, tvb, offset, opcode, length);
235
236         offset += length;
237     }
238 }
239
240
241 static int dissect_ua_sys_to_term(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
242 {
243     _dissect_ua_msg(tvb, pinfo, tree, SYS_TO_TERM);
244     return tvb_captured_length(tvb);
245 }
246
247 static int dissect_ua_term_to_sys(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
248 {
249     _dissect_ua_msg(tvb, pinfo, tree, TERM_TO_SYS);
250     return tvb_captured_length(tvb);
251 }
252
253
254 /*-----------------------------------------------------------------------------
255   DISSECTORS REGISTRATION FUNCTIONS
256   ---------------------------------------------------------------------------*/
257
258 void proto_register_ua_msg(void)
259 {
260     module_t *ua_msg_module;
261
262     static gint *ett[] =
263     {
264         &ett_ua_msg,
265     };
266
267     /* UA dissector registration */
268     proto_ua_msg = proto_register_protocol("Universal Alcatel Protocol", "UA", "ua");
269
270     register_dissector("ua_sys_to_term", dissect_ua_sys_to_term, proto_ua_msg);
271     register_dissector("ua_term_to_sys", dissect_ua_term_to_sys, proto_ua_msg);
272
273     /* Common subtree array registration */
274     proto_register_subtree_array(ett, array_length(ett));
275
276     /* Register preferences */
277     ua_msg_module = prefs_register_protocol(proto_ua_msg, NULL);
278
279     prefs_register_bool_preference(ua_msg_module, "setup_conversations",
280         "Setup RTP/RTCP conversations on Start RTP",
281         "Setup RTP/RTCP conversations when parsing Start RTP messages",
282         &setup_conversations_enabled);
283 }
284
285 void proto_reg_handoff_ua_msg(void)
286 {
287 #if 0  /* Future */
288     dissector_handle_t handle_ua_msg;
289
290     /* hooking of UA on UAUDP */
291     /* XXX: The following is NG since the same 'pattern' is added twice */
292     handle_ua_msg = find_dissector("ua_sys_to_term");
293     dissector_add_uint("uaudp.opcode", UAUDP_DATA, handle_ua_msg);
294
295     handle_ua_msg = find_dissector("ua_term_to_sys");
296     dissector_add_uint("uaudp.opcode", UAUDP_DATA, handle_ua_msg);
297
298     /* For hooking dissectors to UA */
299     ua_opcode_dissector_table =
300         register_dissector_table("ua.opcode",
301                                  "ua.opcode",
302                                  FT_UINT8,
303                                  BASE_HEX);
304
305
306 #endif
307     noe_handle  = find_dissector_add_dependency("noe", proto_ua_msg);
308     ua3g_handle = find_dissector_add_dependency("ua3g", proto_ua_msg);
309
310 }
311
312 /*
313  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
314  *
315  * Local variables:
316  * c-basic-offset: 4
317  * tab-width: 8
318  * indent-tabs-mode: nil
319  * End:
320  *
321  * vi: set shiftwidth=4 tabstop=8 expandtab:
322  * :indentSize=4:tabSize=8:noTabs=true:
323  */