2 * Routines for UA/UDP (Universal Alcatel over UDP) packet dissection.
3 * Copyright 2012, Alcatel-Lucent Enterprise <lars.ruoff@alcatel-lucent.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "epan/packet.h"
31 #include "epan/prefs.h"
33 #include "epan/dissectors/packet-rtp.h"
34 #include "epan/dissectors/packet-rtcp.h"
36 #include "packet-uaudp.h"
38 /*-----------------------------------------------------------------------------
40 ---------------------------------------------------------------------------*/
43 static dissector_table_t ua_opcode_dissector_table
;
46 static int proto_ua_msg
= -1;
47 static gint ett_ua_msg
= -1;
49 static gboolean setup_conversations_enabled
= TRUE
;
51 static dissector_handle_t noe_handle
;
52 static dissector_handle_t ua3g_handle
;
54 static void uadecode(e_ua_direction direction
,
62 switch (opcode
& 0x7f) /* suppression of the CP bit */
67 call_dissector(noe_handle
,
68 tvb_new_subset(tvb
, offset
, length
, length
),
80 case 0x07: /* Only UA NOE */
81 case 0x08: /* Only UA NOE */
95 case 0x1F: /* case 0x9F */
100 case 0x24: /* Only IP NOE */
101 case 0x25: /* Only IP NOE */
107 case 0x2B: /* Only UA NOE */
113 case 0x32: /* Only UA NOE */
116 case 0x36: /* IP Phone */
141 case 0x50: /* Only UA NOE */
143 call_dissector_with_data(ua3g_handle
,
144 tvb_new_subset(tvb
, offset
, length
, length
),
146 tree
, (void*)direction
);
151 /* add text to the frame "INFO" column */
152 col_append_str(pinfo
->cinfo
, COL_INFO
, " - UA3G Message ERR: Opcode Unknown");
154 proto_tree_add_text(tree
,
158 "Opcode Unknown 0x%02x",
159 tvb_get_guint8(tvb
, (offset
+ 2)));
167 /*-----------------------------------------------------------------------------
169 ---------------------------------------------------------------------------*/
170 static void _dissect_ua_msg(tvbuff_t
*tvb
,
173 e_ua_direction direction
)
176 proto_item
*ua_msg_item
;
177 proto_tree
*ua_msg_tree
;
179 ua_msg_item
= proto_tree_add_protocol_format(tree
, proto_ua_msg
, tvb
, 0, -1,
180 "Universal Alcatel Protocol, %s",
181 ((direction
== SYS_TO_TERM
) ?
182 "System -> Terminal" : "Terminal -> System"));
184 ua_msg_tree
= proto_item_add_subtree(ua_msg_item
, ett_ua_msg
);
186 while (tvb_offset_exists(tvb
, offset
))
191 length
= tvb_get_letohs(tvb
, offset
) + 2;
192 opcode
= tvb_get_guint8(tvb
, offset
+2);
194 /* RTP/RTCP conversation setup */
195 if (setup_conversations_enabled
&& (opcode
==0x13) && (tvb_get_guint8(tvb
, offset
+3)==0x01))
197 address remote_rtp_addr
;
198 guint32 remote_rtp_port
;
201 remote_rtp_addr
.data
= NULL
;
205 suboffset
= offset
+ 5;
207 while (suboffset
< offset
+length
)
209 switch (tvb_get_guint8(tvb
, suboffset
))
211 case 0x00: /* local port */
213 /*local_rtp_port = tvb_get_ntohs(tvb, suboffset+2);*/
216 case 0x01: /* remote IP */
218 remote_rtp_addr
.type
= AT_IPv4
;
219 remote_rtp_addr
.len
= 4;
220 remote_rtp_addr
.data
= tvb_get_ptr(tvb
, suboffset
+2, 4);
223 case 0x02: /* remote port */
225 remote_rtp_port
= tvb_get_ntohs(tvb
, suboffset
+2);
230 suboffset
+= tvb_get_guint8(tvb
, suboffset
+1) + 2;
233 if ((remote_rtp_addr
.data
!= NULL
) && (remote_rtp_port
!= 0))
235 rtp_add_address(pinfo
, &remote_rtp_addr
, remote_rtp_port
, 0,
236 "UA", pinfo
->fd
->num
, 0, NULL
);
237 rtcp_add_address(pinfo
, &remote_rtp_addr
, remote_rtp_port
+1, 0,
238 "UA", pinfo
->fd
->num
);
242 uadecode(direction
, ua_msg_tree
, pinfo
, tvb
, offset
, opcode
, length
);
249 static void dissect_ua_sys_to_term(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
251 _dissect_ua_msg(tvb
, pinfo
, tree
, SYS_TO_TERM
);
254 static void dissect_ua_term_to_sys(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
256 _dissect_ua_msg(tvb
, pinfo
, tree
, TERM_TO_SYS
);
260 /*-----------------------------------------------------------------------------
261 DISSECTORS REGISTRATION FUNCTIONS
262 ---------------------------------------------------------------------------*/
264 void proto_register_ua_msg(void)
266 module_t
*ua_msg_module
;
273 /* UA dissector registration */
274 proto_ua_msg
= proto_register_protocol("Universal Alcatel Protocol", "UA", "ua");
276 register_dissector("ua_sys_to_term", dissect_ua_sys_to_term
, proto_ua_msg
);
277 register_dissector("ua_term_to_sys", dissect_ua_term_to_sys
, proto_ua_msg
);
279 /* Common subtree array registration */
280 proto_register_subtree_array(ett
, array_length(ett
));
282 /* Register preferences */
283 ua_msg_module
= prefs_register_protocol(proto_ua_msg
, NULL
);
285 prefs_register_bool_preference(ua_msg_module
, "setup_conversations",
286 "Setup RTP/RTCP conversations on Start RTP",
287 "Setup RTP/RTCP conversations when parsing Start RTP messages",
288 &setup_conversations_enabled
);
291 void proto_reg_handoff_ua_msg(void)
294 dissector_handle_t handle_ua_msg
;
296 /* hooking of UA on UAUDP */
297 /* XXX: The following is NG since the same 'pattern' is added twice */
298 handle_ua_msg
= find_dissector("ua_sys_to_term");
299 dissector_add_uint("uaudp.opcode", UAUDP_DATA
, handle_ua_msg
);
301 handle_ua_msg
= find_dissector("ua_term_to_sys");
302 dissector_add_uint("uaudp.opcode", UAUDP_DATA
, handle_ua_msg
);
304 /* For hooking dissectors to UA */
305 ua_opcode_dissector_table
=
306 register_dissector_table("ua.opcode",
313 noe_handle
= find_dissector("noe");
314 ua3g_handle
= find_dissector("ua3g");