Remaining ADDRESS macro to address function conversions
[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 static dissector_handle_t data_handle;
51
52 static void uadecode(e_ua_direction  direction,
53                      proto_tree     *tree,
54                      packet_info    *pinfo,
55                      tvbuff_t       *tvb,
56                      gint            offset,
57                      gint            opcode,
58                      gint            length)
59 {
60     switch (opcode & 0x7f) /* suppression of the CP bit */
61     {
62     case 0x15:
63     case 0x16:
64         {
65             call_dissector(noe_handle,
66                            tvb_new_subset_length(tvb, offset, length),
67                            pinfo,
68                            tree);
69             break;
70         }
71     case 0x00:
72     case 0x01:
73     case 0x02:
74     case 0x03:
75     case 0x04:
76     case 0x05:
77     case 0x06:
78     case 0x07:  /* Only UA NOE */
79     case 0x08:  /* Only UA NOE */
80     case 0x09:
81     case 0x0A:
82     case 0x0B:
83     case 0x0C:
84     case 0x0D:
85     case 0x0E:
86     case 0x0F:
87     case 0x11:
88     case 0x12:
89     case 0x13:
90     case 0x14:
91     case 0x17:
92     case 0x18:
93     case 0x1F:  /* case 0x9F */
94     case 0x20:
95     case 0x21:
96     case 0x22:
97     case 0x23:
98     case 0x24:  /* Only IP NOE */
99     case 0x25:  /* Only IP NOE */
100     case 0x26:
101     case 0x27:
102     case 0x28:
103     case 0x29:
104     case 0x2A:
105     case 0x2B:  /* Only UA NOE */
106     case 0x2C:
107     case 0x2D:
108     case 0x2E:
109     case 0x30:
110     case 0x31:
111     case 0x32:  /* Only UA NOE */
112     case 0x33:
113     case 0x35:
114     case 0x36:  /* IP Phone */
115     case 0x38:
116     case 0x39:
117     case 0x3A:
118     case 0x3B:
119     case 0x3C:
120     case 0x3D:
121     case 0x3E:
122     case 0x3F:
123     case 0x40:
124     case 0x41:
125     case 0x42:
126     case 0x43:
127     case 0x44:
128     case 0x45:
129     case 0x46:
130     case 0x47:
131     case 0x48:
132     case 0x49:
133     case 0x4A:
134     case 0x4B:
135     case 0x4C:
136     case 0x4D:
137     case 0x4E:
138     case 0x4F:
139     case 0x50:  /* Only UA NOE */
140         {
141             call_dissector_with_data(ua3g_handle,
142                        tvb_new_subset_length(tvb, offset, length),
143                        pinfo,
144                        tree, &direction);
145             break;
146         }
147     default:
148         {
149             /* add text to the frame "INFO" column */
150             col_append_fstr(pinfo->cinfo, COL_INFO, " - UA3G Message ERR: Opcode (0x%02x) Unknown", tvb_get_guint8(tvb, (offset + 2)));
151
152             call_dissector(data_handle,
153                            tvb_new_subset_length(tvb, offset, length),
154                            pinfo,
155                            tree);
156             break;
157         }
158     }
159 }
160
161
162
163 /*-----------------------------------------------------------------------------
164   UA DISSECTOR
165   ---------------------------------------------------------------------------*/
166 static void _dissect_ua_msg(tvbuff_t       *tvb,
167                             packet_info    *pinfo,
168                             proto_tree     *tree,
169                             e_ua_direction  direction)
170 {
171     gint        offset = 0;
172     proto_item *ua_msg_item;
173     proto_tree *ua_msg_tree;
174
175     ua_msg_item = proto_tree_add_protocol_format(tree, proto_ua_msg, tvb, 0, -1,
176         "Universal Alcatel Protocol, %s",
177         ((direction == SYS_TO_TERM) ?
178         "System -> Terminal" : "Terminal -> System"));
179
180     ua_msg_tree = proto_item_add_subtree(ua_msg_item, ett_ua_msg);
181
182     while (tvb_offset_exists(tvb, offset))
183     {
184         gint length;
185         gint opcode;
186
187         length = tvb_get_letohs(tvb, offset) + 2;
188         opcode = tvb_get_guint8(tvb, offset+2);
189
190         /* RTP/RTCP conversation setup */
191         if (setup_conversations_enabled && (opcode==0x13) && (tvb_get_guint8(tvb, offset+3)==0x01))
192         {
193             address remote_rtp_addr;
194             guint32 remote_rtp_port;
195             gint    suboffset;
196
197             remote_rtp_addr.data = NULL;
198             remote_rtp_port = 0;
199
200             /* StartRTP */
201             suboffset = offset + 5;
202
203             while (suboffset < offset+length)
204             {
205                 switch (tvb_get_guint8(tvb, suboffset))
206                 {
207                 case 0x00: /* local port */
208                     {
209                     /*local_rtp_port = tvb_get_ntohs(tvb, suboffset+2);*/
210                     break;
211                     }
212                 case 0x01: /* remote IP */
213                     {
214                     set_address_tvb(&remote_rtp_addr, AT_IPv4, 4, tvb, suboffset+2);
215                     break;
216                     }
217                 case 0x02: /* remote port */
218                     {
219                     remote_rtp_port = tvb_get_ntohs(tvb, suboffset+2);
220                     break;
221                     }
222                 }
223
224             suboffset += tvb_get_guint8(tvb, suboffset+1) + 2;
225             }
226
227             if ((remote_rtp_addr.data != NULL) && (remote_rtp_port != 0))
228             {
229                 rtp_add_address(pinfo, &remote_rtp_addr, remote_rtp_port, 0,
230                         "UA", pinfo->fd->num, 0, NULL);
231                 rtcp_add_address(pinfo, &remote_rtp_addr, remote_rtp_port+1, 0,
232                          "UA", pinfo->fd->num);
233             }
234         }
235
236         uadecode(direction, ua_msg_tree, pinfo, tvb, offset, opcode, length);
237
238         offset += length;
239     }
240 }
241
242
243 static void dissect_ua_sys_to_term(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
244 {
245     _dissect_ua_msg(tvb, pinfo, tree, SYS_TO_TERM);
246 }
247
248 static void dissect_ua_term_to_sys(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
249 {
250     _dissect_ua_msg(tvb, pinfo, tree, TERM_TO_SYS);
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("noe");
308     ua3g_handle = find_dissector("ua3g");
309     data_handle = find_dissector("data");
310
311 }
312
313 /*
314  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
315  *
316  * Local variables:
317  * c-basic-offset: 4
318  * tab-width: 8
319  * indent-tabs-mode: nil
320  * End:
321  *
322  * vi: set shiftwidth=4 tabstop=8 expandtab:
323  * :indentSize=4:tabSize=8:noTabs=true:
324  */