4 * Routines for IAX2 packet disassembly
5 * By Alastair Maw <asterisk@almaw.com>
6 * Copyright 2003 Alastair Maw
8 * IAX2 is a VoIP protocol for the open source PBX Asterisk. Please see
9 * http://www.asterisk.org for more information.
13 * Ethereal - Network traffic analyzer
14 * By Gerald Combs <gerald@ethereal.com>
15 * Copyright 1998 Gerald Combs
17 * This program is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2 of the License, or (at your
20 * option) any later version. This program is distributed in the hope
21 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
22 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
23 * PURPOSE. See the GNU General Public License for more details. You
24 * should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 #include <epan/circuit.h>
39 #include <epan/packet.h>
40 #include <epan/to_str.h>
42 #include "packet-iax2.h"
43 #include "iax2_codec_type.h"
45 #define IAX2_PORT 4569
46 #define PROTO_TAG_IAX2 "IAX2"
48 /* #define DEBUG_HASHING */
50 /* Ethereal ID of the IAX2 protocol */
51 static int proto_iax2 = -1;
53 /* The following hf_* variables are used to hold the ethereal IDs of
54 * our header fields; they are filled out when we call
55 * proto_register_field_array() in proto_register_iax2()
57 static int hf_iax2_packet_type = -1;
58 static int hf_iax2_retransmission = -1;
59 static int hf_iax2_scallno = -1;
60 static int hf_iax2_dcallno = -1;
61 static int hf_iax2_ts = -1;
62 static int hf_iax2_minits = -1;
63 static int hf_iax2_minividts = -1;
64 static int hf_iax2_minividmarker = -1;
65 static int hf_iax2_oseqno = -1;
66 static int hf_iax2_iseqno = -1;
67 static int hf_iax2_type = -1;
68 static int hf_iax2_csub = -1;
69 static int hf_iax2_cmd_csub = -1;
70 static int hf_iax2_iax_csub = -1;
71 static int hf_iax2_voice_csub = -1;
72 static int hf_iax2_voice_codec = -1;
73 static int hf_iax2_video_csub = -1;
74 static int hf_iax2_video_codec = -1;
75 static int hf_iax2_marker = -1;
77 static int hf_iax2_cap_g723_1 = -1;
78 static int hf_iax2_cap_gsm = -1;
79 static int hf_iax2_cap_ulaw = -1;
80 static int hf_iax2_cap_alaw = -1;
81 static int hf_iax2_cap_g726 = -1;
82 static int hf_iax2_cap_adpcm = -1;
83 static int hf_iax2_cap_slinear = -1;
84 static int hf_iax2_cap_lpc10 = -1;
85 static int hf_iax2_cap_g729a = -1;
86 static int hf_iax2_cap_speex = -1;
87 static int hf_iax2_cap_ilbc = -1;
88 static int hf_iax2_cap_jpeg = -1;
89 static int hf_iax2_cap_png = -1;
90 static int hf_iax2_cap_h261 = -1;
91 static int hf_iax2_cap_h263 = -1;
93 static int hf_IAX_IE_APPARENTADDR_SINFAMILY = -1;
94 static int hf_IAX_IE_APPARENTADDR_SINPORT = -1;
95 static int hf_IAX_IE_APPARENTADDR_SINADDR = -1;
96 static int hf_IAX_IE_APPARENTADDR_SINZERO = -1;
97 static int hf_IAX_IE_CALLED_NUMBER = -1;
98 static int hf_IAX_IE_CALLING_NUMBER = -1;
99 static int hf_IAX_IE_CALLING_ANI = -1;
100 static int hf_IAX_IE_CALLING_NAME = -1;
101 static int hf_IAX_IE_CALLED_CONTEXT = -1;
102 static int hf_IAX_IE_USERNAME = -1;
103 static int hf_IAX_IE_PASSWORD = -1;
104 static int hf_IAX_IE_CAPABILITY = -1;
105 static int hf_IAX_IE_FORMAT = -1;
106 static int hf_IAX_IE_LANGUAGE = -1;
107 static int hf_IAX_IE_VERSION = -1;
108 static int hf_IAX_IE_ADSICPE = -1;
109 static int hf_IAX_IE_DNID = -1;
110 static int hf_IAX_IE_AUTHMETHODS = -1;
111 static int hf_IAX_IE_CHALLENGE = -1;
112 static int hf_IAX_IE_MD5_RESULT = -1;
113 static int hf_IAX_IE_RSA_RESULT = -1;
114 static int hf_IAX_IE_REFRESH = -1;
115 static int hf_IAX_IE_DPSTATUS = -1;
116 static int hf_IAX_IE_CALLNO = -1;
117 static int hf_IAX_IE_CAUSE = -1;
118 static int hf_IAX_IE_IAX_UNKNOWN = -1;
119 static int hf_IAX_IE_MSGCOUNT = -1;
120 static int hf_IAX_IE_AUTOANSWER = -1;
121 static int hf_IAX_IE_MUSICONHOLD = -1;
122 static int hf_IAX_IE_TRANSFERID = -1;
123 static int hf_IAX_IE_RDNIS = -1;
124 static int hf_IAX_IE_PROVISIONING = -1;
125 static int hf_IAX_IE_AESPROVISIONING = -1;
126 static int hf_IAX_IE_DATETIME = -1;
127 static int hf_IAX_IE_DEVICETYPE = -1;
128 static int hf_IAX_IE_SERVICEIDENT = -1;
129 static int hf_IAX_IE_FIRMWAREVER = -1;
130 static int hf_IAX_IE_FWBLOCKDESC = -1;
131 static int hf_IAX_IE_FWBLOCKDATA = -1;
132 static int hf_IAX_IE_PROVVER = -1;
133 static int hf_IAX_IE_CALLINGPRES = -1;
134 static int hf_IAX_IE_CALLINGTON = -1;
135 static int hf_IAX_IE_CALLINGTNS = -1;
136 static int hf_IAX_IE_SAMPLINGRATE = -1;
137 static int hf_IAX_IE_CAUSECODE = -1;
138 static int hf_IAX_IE_ENCRYPTION = -1;
139 static int hf_IAX_IE_ENCKEY = -1;
140 static int hf_IAX_IE_CODEC_PREFS = -1;
141 static int hf_IAX_IE_RR_JITTER = -1;
142 static int hf_IAX_IE_RR_LOSS = -1;
143 static int hf_IAX_IE_RR_PKTS = -1;
144 static int hf_IAX_IE_RR_DELAY = -1;
145 static int hf_IAX_IE_RR_DROPPED = -1;
146 static int hf_IAX_IE_RR_OOO = -1;
148 static int hf_IAX_IE_DATAFORMAT = -1;
149 static int hf_IAX_IE_UNKNOWN_BYTE = -1;
150 static int hf_IAX_IE_UNKNOWN_I16 = -1;
151 static int hf_IAX_IE_UNKNOWN_I32 = -1;
152 static int hf_IAX_IE_UNKNOWN_BYTES = -1;
154 /* These are the ids of the subtrees that we may be creating */
155 static gint ett_iax2 = -1;
156 static gint ett_iax2_full_mini_subtree = -1;
157 static gint ett_iax2_type = -1; /* Frame-type specific subtree */
158 static gint ett_iax2_ie = -1; /* single IE */
159 static gint ett_iax2_codecs = -1; /* capabilities IE */
160 static gint ett_iax2_ies_apparent_addr = -1; /* apparent address IE */
162 static dissector_handle_t data_handle;
164 /* data-call subdissectors, AST_DATAFORMAT_* */
165 static dissector_table_t iax2_dataformat_dissector_table;
166 /* voice/video call subdissectors, AST_FORMAT_* */
167 static dissector_table_t iax2_codec_dissector_table;
169 /* IAX2 Full-frame types */
170 static const value_string iax_frame_types[] = {
183 /* Subclasses for IAX packets */
184 static const value_string iax_iax_subclasses[] = {
226 /* Subclassess for Control packets */
227 static const value_string iax_cmd_subclasses[] = {
236 {0xFF, "stop sounds"}, /* sent by app_dial, and not much else */
240 /* Information elements */
241 static const value_string iax_ies_type[] = {
242 {IAX_IE_CALLED_NUMBER, "Number/extension being called"},
243 {IAX_IE_CALLING_NUMBER, "Calling number"},
244 {IAX_IE_CALLING_ANI, "Calling number ANI for billing"},
245 {IAX_IE_CALLING_NAME, "Name of caller"},
246 {IAX_IE_CALLED_CONTEXT, "Context for number"},
247 {IAX_IE_USERNAME, "Username (peer or user) for authentication"},
248 {IAX_IE_PASSWORD, "Password for authentication"},
249 {IAX_IE_CAPABILITY, "Actual codec capability"},
250 {IAX_IE_FORMAT, "Desired codec format"},
251 {IAX_IE_LANGUAGE, "Desired language"},
252 {IAX_IE_VERSION, "Protocol version"},
253 {IAX_IE_ADSICPE, "CPE ADSI capability"},
254 {IAX_IE_DNID, "Originally dialed DNID"},
255 {IAX_IE_AUTHMETHODS, "Authentication method(s)"},
256 {IAX_IE_CHALLENGE, "Challenge data for MD5/RSA"},
257 {IAX_IE_MD5_RESULT, "MD5 challenge result"},
258 {IAX_IE_RSA_RESULT, "RSA challenge result"},
259 {IAX_IE_APPARENT_ADDR, "Apparent address of peer"},
260 {IAX_IE_REFRESH, "When to refresh registration"},
261 {IAX_IE_DPSTATUS, "Dialplan status"},
262 {IAX_IE_CALLNO, "Call number of peer"},
263 {IAX_IE_CAUSE, "Cause"},
264 {IAX_IE_IAX_UNKNOWN, "Unknown IAX command"},
265 {IAX_IE_MSGCOUNT, "How many messages waiting"},
266 {IAX_IE_AUTOANSWER, "Request auto-answering"},
267 {IAX_IE_MUSICONHOLD, "Request musiconhold with QUELCH"},
268 {IAX_IE_TRANSFERID, "Transfer Request Identifier"},
269 {IAX_IE_RDNIS, "Referring DNIS"},
270 {IAX_IE_PROVISIONING, "Provisioning info"},
271 {IAX_IE_AESPROVISIONING, "AES Provisioning info"},
272 {IAX_IE_DATETIME,"Date/Time"},
273 {IAX_IE_DEVICETYPE, "Device type"},
274 {IAX_IE_SERVICEIDENT, "Service Identifier"},
275 {IAX_IE_FIRMWAREVER, "Firmware revision"},
276 {IAX_IE_FWBLOCKDESC, "Firmware block description"},
277 {IAX_IE_FWBLOCKDATA, "Firmware block of data"},
278 {IAX_IE_PROVVER, "Provisioning version"},
279 {IAX_IE_CALLINGPRES, "Calling presentation"},
280 {IAX_IE_CALLINGTON, "Calling type of number"},
281 {IAX_IE_CALLINGTNS, "Calling transit network select"},
282 {IAX_IE_SAMPLINGRATE, "Supported sampling rates"},
283 {IAX_IE_CAUSECODE, "Hangup cause"},
284 {IAX_IE_ENCRYPTION, "Encryption format"},
285 {IAX_IE_ENCKEY, "Raw encryption key"},
286 {IAX_IE_CODEC_PREFS, "Codec preferences"},
287 {IAX_IE_RR_JITTER, "Received jitter"},
288 {IAX_IE_RR_LOSS, "Received loss"},
289 {IAX_IE_RR_PKTS, "Received frames"},
290 {IAX_IE_RR_DELAY, "Max playout delay in ms for received frames"},
291 {IAX_IE_RR_DROPPED, "Dropped frames"},
292 {IAX_IE_RR_OOO, "Frames received out of order"},
293 {IAX_IE_DATAFORMAT, "Data call format"},
297 static const value_string codec_types[] = {
298 {AST_FORMAT_G723_1, "G.723.1 compression"},
299 {AST_FORMAT_GSM, "GSM compression"},
300 {AST_FORMAT_ULAW, "Raw mu-law data (G.711)"},
301 {AST_FORMAT_ALAW, "Raw A-law data (G.711)"},
302 {AST_FORMAT_G726, "ADPCM (G.726, 32kbps)"},
303 {AST_FORMAT_ADPCM, "ADPCM (IMA)"},
304 {AST_FORMAT_SLINEAR, "Raw 16-bit Signed Linear (8000 Hz) PCM"},
305 {AST_FORMAT_LPC10, "LPC10, 180 samples/frame"},
306 {AST_FORMAT_G729A, "G.729a Audio"},
307 {AST_FORMAT_SPEEX, "SpeeX Free Compression"},
308 {AST_FORMAT_ILBC, "iLBC Free Compression"},
309 {AST_FORMAT_JPEG, "JPEG Images"},
310 {AST_FORMAT_PNG, "PNG Images"},
311 {AST_FORMAT_H261, "H.261 Video"},
312 {AST_FORMAT_H263, "H.263 Video"},
316 static const value_string iax_dataformats[] = {
317 {AST_DATAFORMAT_NULL, "N/A (analogue call?)"},
318 {AST_DATAFORMAT_V110, "ITU-T V.110 rate adaption"},
319 {AST_DATAFORMAT_H223_H245,"ITU-T H.223/H.245"},
324 IAX2_MINI_VOICE_PACKET,
326 IAX2_MINI_VIDEO_PACKET,
330 static const value_string iax_packet_types[] = {
331 {IAX2_FULL_PACKET, "Full packet"},
332 {IAX2_MINI_VOICE_PACKET, "Mini voice packet"},
333 {IAX2_MINI_VIDEO_PACKET, "Mini video packet"},
334 {IAX2_META_PACKET, "Meta packet"},
338 static const value_string iax_causecodes[] = {
339 {AST_CAUSE_UNALLOCATED, "Unallocated"},
340 {AST_CAUSE_NO_ROUTE_TRANSIT_NET, "No route transit net"},
341 {AST_CAUSE_NO_ROUTE_DESTINATION, "No route to destination"},
342 {AST_CAUSE_CHANNEL_UNACCEPTABLE, "Channel unacceptable"},
343 {AST_CAUSE_CALL_AWARDED_DELIVERED, "Call awarded delivered"},
344 {AST_CAUSE_NORMAL_CLEARING, "Normal clearing"},
345 {AST_CAUSE_USER_BUSY, "User busy"},
346 {AST_CAUSE_NO_USER_RESPONSE, "No user response"},
347 {AST_CAUSE_NO_ANSWER, "No answer"},
348 {AST_CAUSE_CALL_REJECTED, "Call rejected"},
349 {AST_CAUSE_NUMBER_CHANGED, "Number changed"},
350 {AST_CAUSE_DESTINATION_OUT_OF_ORDER, "Destination out of order"},
351 {AST_CAUSE_INVALID_NUMBER_FORMAT, "Invalid number format"},
352 {AST_CAUSE_FACILITY_REJECTED, "Facility rejected"},
353 {AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "Response to status inquiry"},
354 {AST_CAUSE_NORMAL_UNSPECIFIED, "Normal unspecified"},
355 {AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "Normal circuit congestion"},
356 {AST_CAUSE_NETWORK_OUT_OF_ORDER, "Network out of order"},
357 {AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "Normal temporary failure"},
358 {AST_CAUSE_SWITCH_CONGESTION, "Switch congestion"},
359 {AST_CAUSE_ACCESS_INFO_DISCARDED, "Access info discarded"},
360 {AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "Requested channel unavailable"},
361 {AST_CAUSE_PRE_EMPTED, "Preempted"},
362 {AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "Facility not subscribed"},
363 {AST_CAUSE_OUTGOING_CALL_BARRED, "Outgoing call barred"},
364 {AST_CAUSE_INCOMING_CALL_BARRED, "Incoming call barred"},
365 {AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "Bearer capability not authorized"},
366 {AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "Bearer capability not available"},
367 {AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "Bearer capability not implemented"},
368 {AST_CAUSE_CHAN_NOT_IMPLEMENTED, "Channel not implemented"},
369 {AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "Facility not implemented"},
370 {AST_CAUSE_INVALID_CALL_REFERENCE, "Invalid call reference"},
371 {AST_CAUSE_INCOMPATIBLE_DESTINATION, "Incompatible destination"},
372 {AST_CAUSE_INVALID_MSG_UNSPECIFIED, "Invalid message unspecified"},
373 {AST_CAUSE_MANDATORY_IE_MISSING, "Mandatory IE missing"},
374 {AST_CAUSE_MESSAGE_TYPE_NONEXIST, "Message type nonexistent"},
375 {AST_CAUSE_WRONG_MESSAGE, "Wrong message"},
376 {AST_CAUSE_IE_NONEXIST, "IE nonexistent"},
377 {AST_CAUSE_INVALID_IE_CONTENTS, "Invalid IE contents"},
378 {AST_CAUSE_WRONG_CALL_STATE, "Wrong call state"},
379 {AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "Recovery on timer expire"},
380 {AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "Mandatory IE length error"},
381 {AST_CAUSE_PROTOCOL_ERROR, "Protocol error"},
382 {AST_CAUSE_INTERWORKING, "Interworking"},
387 /* ************************************************************************* */
389 /* In order to track IAX calls, we have a hash table which maps
390 * {addr,port type,port,call} to a unique circuit id.
392 * Each call has two such circuits associated with it (a forward and a
393 * reverse circuit, where 'forward' is defined as the direction the NEW
394 * packet went in), and we maintain an iax_call_data structure for each
395 * call, attached to both circuits with circuit_add_proto_data.
397 * Because {addr,port type,port,call} quadruplets can be reused
398 * (Asterisk reuses call numbers), circuit ids aren't unique to
399 * individual calls and we treat NEW packets somewhat specially. When we
400 * get such a packet, we see if there are any calls with a matching
401 * circuit id, and make sure that its circuits are marked as ended
402 * before that packet.
404 * A second complication is that we only know one quadruplet at the time
405 * the NEW packet is processed: there is therefore cunningness in
406 * iax_lookup_circuit_details() to look for replies to NEW packets and
407 * create the reverse circuit.
411 /* start with a hash of {addr,port type,port,call}->{id} */
421 static GHashTable *iax_circuit_hashtab = NULL;
422 static GMemChunk *iax_circuit_keys = NULL;
423 static GMemChunk *iax_circuit_vals = NULL;
424 static guint circuitcount = 0;
426 /* the number of keys and values to reserve space for in each memory chunk.
427 We assume we won't be tracking many calls at once so this is quite low.
429 #define IAX_INIT_PACKET_COUNT 10
432 static gchar *key_to_str( const iax_circuit_key *key )
435 static gchar *strp, str[3][80];
443 /* why doesn't address_to_str take a const pointer?
444 cast the warnings into oblivion. */
446 sprintf(strp,"{%s:%i,%i}",
447 address_to_str((address *)&key->addr),
455 static gint iax_circuit_equal(gconstpointer v, gconstpointer w)
457 const iax_circuit_key *v1 = (const iax_circuit_key *)v;
458 const iax_circuit_key *v2 = (const iax_circuit_key *)w;
461 result = ( ADDRESSES_EQUAL(&(v1->addr), &(v2->addr)) &&
462 v1->ptype == v2->ptype &&
463 v1->port == v2->port &&
464 v1->callno== v2->callno);
466 g_message( "+++ Comparing for equality: %s, %s: %u",key_to_str(v1), key_to_str(v2), result);
472 static guint iax_circuit_hash (gconstpointer v)
474 const iax_circuit_key *key = (const iax_circuit_key *)v;
479 for (i = 0; i < key->addr.len; i++)
480 hash_val += (guint)(key->addr.data[i]);
482 hash_val += (guint)(key->ptype);
483 hash_val += (guint)(key->port);
484 hash_val += (guint)(key->callno);
487 g_message( "+++ Hashing key: %s, result %#x", key_to_str(key), hash_val );
490 return (guint) hash_val;
493 static guint iax_circuit_lookup(const address *address,
499 guint32 *circuit_id_p;
507 g_message( "+++ looking up key: %s", key_to_str(&key));
510 circuit_id_p = g_hash_table_lookup( iax_circuit_hashtab, &key);
511 if( ! circuit_id_p ) {
512 iax_circuit_key *new_key;
514 new_key = g_mem_chunk_alloc(iax_circuit_keys);
515 COPY_ADDRESS(&new_key->addr, address);
516 new_key->ptype = ptype;
517 new_key->port = port;
518 new_key->callno = callno;
520 circuit_id_p = g_mem_chunk_alloc(iax_circuit_vals);
521 *circuit_id_p = ++circuitcount;
523 g_hash_table_insert(iax_circuit_hashtab, new_key, circuit_id_p);
527 g_message( "+++ Id: %u", *circuit_id_p );
530 return *circuit_id_p;
534 /* ************************************************************************* */
537 /* This is our per-call data structure, which is attached to both the
538 * forward and reverse circuits.
540 typedef struct iax_call_data {
541 /* For this data, src and dst are relative to the original direction under
542 which this call is stored. Obviously if the reversed flag is set true by
543 iax_find_call, src and dst are reversed relative to the direction the
544 actual source and destination of the data.
546 if the codec changes mid-call, we update it here; because we store a codec
547 number with each packet too, we handle going back to earlier packets
551 iax_dataformat_t dataformat;
552 guint32 src_codec, dst_codec;
553 guint32 src_vformat, dst_vformat;
555 guint forward_circuit_id;
556 guint reverse_circuit_id;
561 static guint callcount = 0;
563 static GMemChunk *iax_call_datas = NULL;
565 static void iax_init_hash( void )
567 if (iax_circuit_hashtab)
568 g_hash_table_destroy(iax_circuit_hashtab);
570 if (iax_circuit_keys)
571 g_mem_chunk_destroy(iax_circuit_keys);
572 if (iax_circuit_vals)
573 g_mem_chunk_destroy(iax_circuit_vals);
575 g_mem_chunk_destroy(iax_call_datas);
577 iax_circuit_hashtab = g_hash_table_new(iax_circuit_hash, iax_circuit_equal);
579 iax_circuit_keys = g_mem_chunk_create(iax_circuit_key,
580 2*IAX_INIT_PACKET_COUNT,
582 iax_circuit_vals = g_mem_chunk_create(iax_circuit_key,
583 2*IAX_INIT_PACKET_COUNT,
586 iax_call_datas = g_mem_chunk_create(iax_call_data,
587 IAX_INIT_PACKET_COUNT,
594 static iax_call_data *iax_lookup_circuit_details_from_dest( guint src_circuit_id,
595 guint dst_circuit_id,
597 gboolean *reversed_p,
598 circuit_t **circuit_p)
600 circuit_t *dst_circuit;
601 iax_call_data * iax_call;
602 gboolean reversed = FALSE;
604 dst_circuit = find_circuit( CT_IAX2,
610 g_message( "++ destination circuit not found, must have missed NEW packet" );
620 g_message( "++ found destination circuit" );
623 iax_call = (iax_call_data *)circuit_get_proto_data(dst_circuit,proto_iax2);
625 /* there's no way we can create a CT_IAX2 circuit without adding
626 iax call data to it; assert this */
627 DISSECTOR_ASSERT(iax_call);
629 if( dst_circuit_id == iax_call -> forward_circuit_id ) {
631 g_message( "++ destination circuit matches forward_circuit_id of call, "
632 "therefore packet is reversed" );
637 if( iax_call -> reverse_circuit_id == 0 ) {
638 circuit_t *rev_circuit;
640 /* we are going in the reverse direction, and this call
641 doesn't have a reverse circuit associated with it.
644 g_message( "++ reverse_circuit_id of call is zero, need to create a "
645 "new reverse circuit for this call" );
648 iax_call -> reverse_circuit_id = src_circuit_id;
649 rev_circuit = circuit_new(CT_IAX2,
652 circuit_add_proto_data(rev_circuit, proto_iax2, iax_call);
654 /* we should have already set up a subdissector for the forward
655 * circuit. we'll need to copy it to the reverse circuit. */
656 circuit_set_dissector(rev_circuit, circuit_get_dissector(dst_circuit));
658 g_message( "++ done" );
660 } else if( iax_call -> reverse_circuit_id != src_circuit_id ) {
661 g_warning( "IAX Packet %u from circuit ids %u->%u"
662 "conflicts with earlier call with circuit ids %u->%u",
664 src_circuit_id,dst_circuit_id,
665 iax_call->forward_circuit_id,
666 iax_call->reverse_circuit_id);
673 } else if ( dst_circuit_id == iax_call -> reverse_circuit_id ) {
675 g_message( "++ destination circuit matches reverse_circuit_id of call, "
676 "therefore packet is forward" );
680 if( iax_call -> forward_circuit_id != src_circuit_id ) {
681 g_warning( "IAX Packet %u from circuit ids %u->%u"
682 "conflicts with earlier call with circuit ids %u->%u",
684 src_circuit_id,dst_circuit_id,
685 iax_call->forward_circuit_id,
686 iax_call->reverse_circuit_id);
694 DISSECTOR_ASSERT_NOT_REACHED();
699 /* by now we've created a new circuit if one was necessary, or
700 bailed out if it looks like a conflict, and we should be able
701 to look up the source circuit without issue */
702 *circuit_p = find_circuit( CT_IAX2,
705 DISSECTOR_ASSERT(*circuit_p);
709 *reversed_p = reversed;
715 /* looks up a circuit_t and an iax_call for this packet */
716 static iax_call_data *iax_lookup_circuit_details( packet_info *pinfo,
719 gboolean *reversed_p,
720 circuit_t **circuit_p)
722 gboolean reversed = FALSE;
723 iax_call_data *iax_call = NULL;
724 guint src_circuit_id;
725 circuit_t *src_circuit = NULL;
728 g_message( "++ iax_lookup_circuit_details: Looking up circuit for frame %u, "
729 "from {%s:%u:%u} to {%s:%u:%u}", pinfo->fd->num,
730 address_to_str(&pinfo->src),pinfo->srcport,scallno,
731 address_to_str(&pinfo->dst),pinfo->destport,dcallno);
735 src_circuit_id = iax_circuit_lookup(&pinfo->src,pinfo->ptype,
736 pinfo->srcport,scallno);
739 /* the most reliable indicator of call is the destination callno, if
742 guint dst_circuit_id;
744 g_message( "++ dcallno non-zero, looking up destination circuit" );
747 dst_circuit_id = iax_circuit_lookup(&pinfo->dst,pinfo->ptype,
748 pinfo->destport,dcallno);
750 iax_call = iax_lookup_circuit_details_from_dest(src_circuit_id, dst_circuit_id, pinfo->fd->num, &reversed, &src_circuit);
753 /* in all other circumstances, the source circuit should already
754 * exist: its absense indicates that we missed the all-important NEW
758 src_circuit = find_circuit( CT_IAX2,
763 iax_call = (iax_call_data *)circuit_get_proto_data(src_circuit,proto_iax2);
765 /* there's no way we can create a CT_IAX2 circuit without adding
766 iax call data to it; assert this */
767 DISSECTOR_ASSERT(iax_call);
769 if( src_circuit_id == iax_call -> forward_circuit_id )
771 else if ( src_circuit_id == iax_call -> reverse_circuit_id )
774 /* there's also no way we can attach an iax_call_data to a circuit
775 without the circuit being either the forward or reverse circuit
776 for that call; assert this too.
778 DISSECTOR_ASSERT_NOT_REACHED();
783 if(src_circuit && iax_call) {
784 /* info for subdissectors. We always pass on the forward circuit,
785 * and steal the p2p_dir flag to indicate the direction */
786 pinfo -> ctype = CT_IAX2;
787 pinfo -> circuit_id = (guint32)iax_call->forward_circuit_id;
788 pinfo -> p2p_dir = reversed?P2P_DIR_RECV:P2P_DIR_SENT;
792 *reversed_p = reversed;
795 *circuit_p = src_circuit;
799 g_message( "++ Found call for packet: id %u, reversed=%c", iax_call->callno, reversed?'1':'0' );
801 g_message( "++ Call not found. Must have missed the NEW packet?" );
809 /* handles a NEW packet by creating a new iax call and forward circuit.
810 the reverse circuit is not created until the ACK is received and
811 is created by iax_lookup_circuit_details. */
812 static iax_call_data *iax_new_circuit_details( packet_info *pinfo,
814 circuit_t **circuit_p)
821 g_message( "+ new_circuit: Handling NEW packet, frame %u", pinfo->fd->num );
824 circuit_id = iax_circuit_lookup(&pinfo->src,pinfo->ptype,
825 pinfo->srcport,scallno);
827 circuit = circuit_new(CT_IAX2,
833 call = g_mem_chunk_alloc(iax_call_datas);
834 call -> dataformat = 0;
835 call -> src_codec = 0;
836 call -> dst_codec = 0;
837 call -> forward_circuit_id = circuit_id;
838 call -> reverse_circuit_id = 0;
839 call -> callno = ++callcount;
842 g_message( "+ new_circuit: Added new circuit for new call %u", call -> callno );
845 circuit_add_proto_data( circuit, proto_iax2, call );
848 *circuit_p = circuit;
854 /* ************************************************************************* */
856 /* per-packet data */
857 typedef struct iax_packet_data {
858 iax_call_data *call_data;
862 static GMemChunk *iax_packets = NULL;
864 static iax_packet_data *iax_new_packet_data(iax_call_data *call)
866 iax_packet_data *p = g_mem_chunk_alloc(iax_packets);
873 /* ************************************************************************* */
875 static guint32 dissect_fullpacket (tvbuff_t * tvb, guint32 offset,
878 proto_tree * iax2_tree,
879 proto_tree * main_tree);
882 static guint32 dissect_minipacket (tvbuff_t * tvb, guint32 offset,
885 proto_tree * iax2_tree,
886 proto_tree * main_tree);
888 static guint32 dissect_minivideopacket (tvbuff_t * tvb, guint32 offset,
891 proto_tree * iax2_tree,
892 proto_tree * main_tree);
894 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
895 packet_info *pinfo, proto_tree *tree,
896 guint32 ts, gboolean video,
897 iax_packet_data *iax_packet);
902 dissect_iax2 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
904 proto_item *iax2_item = NULL;
905 proto_tree *iax2_tree = NULL;
906 proto_tree *full_mini_subtree = NULL;
907 guint32 offset = 0, len;
912 /* set up the protocol and info fields in the summary pane */
913 if (check_col (pinfo->cinfo, COL_PROTOCOL))
915 col_set_str (pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_IAX2);
917 if (check_col (pinfo->cinfo, COL_INFO))
919 col_clear (pinfo->cinfo, COL_INFO);
922 /* add the 'iax2' tree to the main tree */
925 iax2_item = proto_tree_add_item (tree, proto_iax2, tvb, offset, -1, FALSE);
926 iax2_tree = proto_item_add_subtree (iax2_item, ett_iax2);
929 stmp = tvb_get_ntohs(tvb, offset);
931 /* starting with 0x0000 indicates either a mini video packet or a 'meta'
932 * packet, whatever that means */
934 stmp = tvb_get_ntohs(tvb, offset);
935 if( stmp & 0x8000 ) {
936 /* mini video packet */
937 type = IAX2_MINI_VIDEO_PACKET;
938 scallno = stmp & 0x7FFF;
942 type = IAX2_META_PACKET;
945 /* The source call/fullpacket flag is common to both mini and full packets */
946 scallno = tvb_get_ntohs(tvb, offset);
948 if( scallno & 0x8000 )
949 type = IAX2_FULL_PACKET;
951 type = IAX2_MINI_VOICE_PACKET;
957 proto_item *full_mini_base;
959 full_mini_base = proto_tree_add_uint(iax2_tree, hf_iax2_packet_type, tvb, 0, offset, type);
960 full_mini_subtree = proto_item_add_subtree(full_mini_base, ett_iax2_full_mini_subtree);
963 proto_tree_add_item (full_mini_subtree, hf_iax2_scallno, tvb, offset-2, 2, FALSE);
967 case IAX2_FULL_PACKET:
968 len = dissect_fullpacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
970 case IAX2_MINI_VOICE_PACKET:
971 len = dissect_minipacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
973 case IAX2_MINI_VIDEO_PACKET:
974 len = dissect_minivideopacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
976 case IAX2_META_PACKET:
977 /* not implemented yet */
984 /* update the 'length' of the main IAX2 header field so that it covers just the headers,
985 not the audio data. */
986 proto_item_set_len(iax2_item, len);
990 /* dissect the information elements in an IAX frame. Returns the updated offset */
991 static guint32 dissect_ies (tvbuff_t * tvb, guint32 offset,
992 proto_tree * iax_tree,
993 iax_call_data *iax_call_data )
995 proto_tree *sockaddr_tree = NULL;
996 proto_item *sockaddr_item = 0;
999 while (offset < tvb_reported_length (tvb)) {
1001 int ies_type = tvb_get_guint8(tvb, offset);
1002 int ies_len = tvb_get_guint8(tvb, offset + 1);
1006 proto_tree *ies_tree;
1008 ti = proto_tree_add_text(iax_tree, tvb, offset, ies_len+2,
1009 "Information Element: %s (0x%02X)",
1010 val_to_str(ies_type, iax_ies_type,
1011 "Unknown information element"),
1015 ies_tree = proto_item_add_subtree(ti, ett_iax2_ie);
1017 proto_tree_add_text(ies_tree, tvb, offset, 1, "IE id: %s (0x%02X)",
1018 val_to_str(ies_type, iax_ies_type, "Unknown"),
1021 proto_tree_add_text(ies_tree, tvb, offset+1, 1, "Length: %u",ies_len);
1025 case IAX_IE_CALLED_NUMBER:
1026 proto_tree_add_item (ies_tree, hf_IAX_IE_CALLED_NUMBER, tvb,
1027 offset + 2, ies_len, FALSE);
1029 case IAX_IE_CALLING_NUMBER:
1030 proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_NUMBER,
1031 tvb, offset + 2, ies_len, FALSE);
1033 case IAX_IE_CALLING_ANI:
1034 proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_ANI, tvb,
1035 offset + 2, ies_len, FALSE);
1037 case IAX_IE_CALLING_NAME:
1038 proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_NAME, tvb,
1039 offset + 2, ies_len, FALSE);
1041 case IAX_IE_CALLED_CONTEXT:
1042 proto_tree_add_item (ies_tree, hf_IAX_IE_CALLED_CONTEXT,
1043 tvb, offset + 2, ies_len, FALSE);
1045 case IAX_IE_USERNAME:
1046 proto_tree_add_item (ies_tree, hf_IAX_IE_USERNAME, tvb,
1047 offset + 2, ies_len, FALSE);
1049 case IAX_IE_PASSWORD:
1050 proto_tree_add_item (ies_tree, hf_IAX_IE_PASSWORD, tvb,
1051 offset + 2, ies_len, FALSE);
1053 case IAX_IE_LANGUAGE:
1054 proto_tree_add_item (ies_tree, hf_IAX_IE_LANGUAGE, tvb,
1055 offset + 2, ies_len, FALSE);
1058 proto_tree_add_item (ies_tree, hf_IAX_IE_DNID, tvb,
1059 offset + 2, ies_len, FALSE);
1061 case IAX_IE_CHALLENGE:
1062 proto_tree_add_item (ies_tree, hf_IAX_IE_CHALLENGE, tvb,
1063 offset + 2, ies_len, FALSE);
1065 case IAX_IE_MD5_RESULT:
1066 proto_tree_add_item (ies_tree, hf_IAX_IE_MD5_RESULT, tvb,
1067 offset + 2, ies_len, FALSE);
1069 case IAX_IE_RSA_RESULT:
1070 proto_tree_add_item (ies_tree, hf_IAX_IE_RSA_RESULT, tvb,
1071 offset + 2, ies_len, FALSE);
1074 proto_tree_add_item (ies_tree, hf_IAX_IE_RDNIS, tvb,
1075 offset + 2, ies_len, FALSE);
1077 case IAX_IE_CAPABILITY:
1079 proto_tree *codec_tree;
1080 proto_item *codec_base;
1082 if (ies_len != 4) THROW(ReportedBoundsError);
1084 proto_tree_add_item (ies_tree, hf_IAX_IE_CAPABILITY,
1085 tvb, offset + 2, ies_len, FALSE);
1087 proto_item_add_subtree (codec_base, ett_iax2_codecs);
1089 proto_tree_add_item(codec_tree, hf_iax2_cap_g723_1, tvb, offset + 2, ies_len, FALSE );
1090 proto_tree_add_item(codec_tree, hf_iax2_cap_gsm, tvb, offset + 2, ies_len, FALSE );
1091 proto_tree_add_item(codec_tree, hf_iax2_cap_ulaw, tvb, offset + 2, ies_len, FALSE );
1092 proto_tree_add_item(codec_tree, hf_iax2_cap_alaw, tvb, offset + 2, ies_len, FALSE );
1093 proto_tree_add_item(codec_tree, hf_iax2_cap_g726, tvb, offset + 2, ies_len, FALSE );
1094 proto_tree_add_item(codec_tree, hf_iax2_cap_adpcm, tvb, offset + 2, ies_len, FALSE );
1095 proto_tree_add_item(codec_tree, hf_iax2_cap_slinear, tvb, offset + 2, ies_len, FALSE );
1096 proto_tree_add_item(codec_tree, hf_iax2_cap_lpc10, tvb, offset + 2, ies_len, FALSE );
1097 proto_tree_add_item(codec_tree, hf_iax2_cap_g729a, tvb, offset + 2, ies_len, FALSE );
1098 proto_tree_add_item(codec_tree, hf_iax2_cap_speex, tvb, offset + 2, ies_len, FALSE );
1099 proto_tree_add_item(codec_tree, hf_iax2_cap_ilbc, tvb, offset + 2, ies_len, FALSE );
1100 proto_tree_add_item(codec_tree, hf_iax2_cap_jpeg, tvb, offset + 2, ies_len, FALSE );
1101 proto_tree_add_item(codec_tree, hf_iax2_cap_png, tvb, offset + 2, ies_len, FALSE );
1102 proto_tree_add_item(codec_tree, hf_iax2_cap_h261, tvb, offset + 2, ies_len, FALSE );
1103 proto_tree_add_item(codec_tree, hf_iax2_cap_h263, tvb, offset + 2, ies_len, FALSE );
1107 if (ies_len != 4) THROW(ReportedBoundsError);
1108 proto_tree_add_item (ies_tree, hf_IAX_IE_FORMAT, tvb,
1109 offset + 2, ies_len, FALSE);
1111 case IAX_IE_VERSION:
1112 if (ies_len != 2) THROW(ReportedBoundsError);
1113 proto_tree_add_item (ies_tree, hf_IAX_IE_VERSION, tvb,
1114 offset + 2, ies_len, FALSE);
1116 case IAX_IE_ADSICPE:
1117 if (ies_len != 2) THROW(ReportedBoundsError);
1118 proto_tree_add_item (ies_tree, hf_IAX_IE_ADSICPE, tvb,
1119 offset + 2, ies_len, FALSE);
1121 case IAX_IE_AUTHMETHODS:
1122 if (ies_len != 2) THROW(ReportedBoundsError);
1123 proto_tree_add_item (ies_tree, hf_IAX_IE_AUTHMETHODS, tvb,
1124 offset + 2, ies_len, FALSE);
1126 case IAX_IE_APPARENT_ADDR:
1127 sockaddr_item = proto_tree_add_text(ies_tree, tvb, offset + 2, 16, "Apparent Address");
1128 sockaddr_tree = proto_item_add_subtree(sockaddr_item, ett_iax2_ies_apparent_addr);
1129 proto_tree_add_item(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINADDR, tvb, offset + 6, 4, FALSE);
1130 proto_tree_add_item(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINPORT, tvb, offset + 4, 2, FALSE);
1132 case IAX_IE_REFRESH:
1133 if (ies_len != 2) THROW(ReportedBoundsError);
1134 proto_tree_add_item (ies_tree, hf_IAX_IE_REFRESH, tvb,
1135 offset + 2, ies_len, FALSE);
1137 case IAX_IE_DPSTATUS:
1138 if (ies_len != 2) THROW(ReportedBoundsError);
1139 proto_tree_add_item (ies_tree, hf_IAX_IE_DPSTATUS, tvb,
1140 offset + 2, ies_len, FALSE);
1143 if (ies_len != 2) THROW(ReportedBoundsError);
1144 proto_tree_add_item (ies_tree, hf_IAX_IE_CALLNO, tvb,
1145 offset + 2, ies_len, FALSE);
1148 proto_tree_add_item (ies_tree, hf_IAX_IE_CAUSE, tvb,
1149 offset + 2, ies_len, FALSE);
1151 case IAX_IE_IAX_UNKNOWN:
1152 proto_tree_add_item (ies_tree, hf_IAX_IE_IAX_UNKNOWN, tvb,
1153 offset + 2, ies_len, FALSE);
1155 case IAX_IE_MSGCOUNT:
1156 if (ies_len != 2) THROW(ReportedBoundsError);
1157 proto_tree_add_item (ies_tree, hf_IAX_IE_MSGCOUNT, tvb,
1158 offset + 2, ies_len, FALSE);
1160 case IAX_IE_AUTOANSWER:
1161 proto_tree_add_item (ies_tree, hf_IAX_IE_AUTOANSWER, tvb,
1162 offset + 2, ies_len, FALSE);
1164 case IAX_IE_MUSICONHOLD:
1165 proto_tree_add_item (ies_tree, hf_IAX_IE_MUSICONHOLD, tvb,
1166 offset + 2, ies_len, FALSE);
1168 case IAX_IE_TRANSFERID:
1169 if (ies_len != 4) THROW(ReportedBoundsError);
1170 proto_tree_add_item (ies_tree, hf_IAX_IE_TRANSFERID, tvb,
1171 offset + 2, ies_len, FALSE);
1173 case IAX_IE_PROVISIONING:
1174 proto_tree_add_item (ies_tree, hf_IAX_IE_PROVISIONING, tvb,
1175 offset +2, ies_len, FALSE);
1177 case IAX_IE_AESPROVISIONING:
1178 proto_tree_add_item (ies_tree, hf_IAX_IE_AESPROVISIONING, tvb,
1179 offset +2, ies_len, FALSE);
1181 case IAX_IE_DATETIME:
1182 if (ies_len != 2) THROW(ReportedBoundsError);
1183 proto_tree_add_item (ies_tree, hf_IAX_IE_DATETIME, tvb,
1184 offset +2, ies_len, FALSE);
1186 case IAX_IE_DEVICETYPE:
1187 proto_tree_add_item (ies_tree, hf_IAX_IE_DEVICETYPE, tvb,
1188 offset +2, ies_len, FALSE);
1190 case IAX_IE_SERVICEIDENT:
1191 proto_tree_add_item (ies_tree, hf_IAX_IE_SERVICEIDENT, tvb,
1192 offset +2, ies_len, FALSE);
1194 case IAX_IE_FIRMWAREVER:
1195 if (ies_len != 2) THROW(ReportedBoundsError);
1196 proto_tree_add_item (ies_tree, hf_IAX_IE_FIRMWAREVER, tvb,
1197 offset +2, ies_len, FALSE);
1199 case IAX_IE_FWBLOCKDESC:
1200 if (ies_len != 4) THROW(ReportedBoundsError);
1201 proto_tree_add_item (ies_tree, hf_IAX_IE_FWBLOCKDESC, tvb,
1202 offset +2, ies_len, FALSE);
1204 case IAX_IE_FWBLOCKDATA:
1205 proto_tree_add_item (ies_tree, hf_IAX_IE_FWBLOCKDATA, tvb,
1206 offset +2, ies_len, FALSE);
1208 case IAX_IE_PROVVER:
1209 if (ies_len != 4) THROW(ReportedBoundsError);
1210 proto_tree_add_item (ies_tree, hf_IAX_IE_PROVVER, tvb,
1211 offset +2, ies_len, FALSE);
1213 case IAX_IE_CALLINGPRES:
1214 if (ies_len != 1) THROW(ReportedBoundsError);
1215 proto_tree_add_item (ies_tree, hf_IAX_IE_CALLINGPRES, tvb,
1216 offset +2, ies_len, FALSE);
1218 case IAX_IE_CALLINGTON:
1219 if (ies_len != 1) THROW(ReportedBoundsError);
1220 proto_tree_add_item (ies_tree, hf_IAX_IE_CALLINGTON, tvb,
1221 offset +2, ies_len, FALSE);
1223 case IAX_IE_CALLINGTNS:
1224 if (ies_len != 2) THROW(ReportedBoundsError);
1225 proto_tree_add_item (ies_tree, hf_IAX_IE_CALLINGTNS, tvb,
1226 offset +2, ies_len, FALSE);
1228 case IAX_IE_SAMPLINGRATE:
1229 if (ies_len != 2) THROW(ReportedBoundsError);
1230 proto_tree_add_item (ies_tree, hf_IAX_IE_SAMPLINGRATE, tvb,
1231 offset +2, ies_len, FALSE);
1233 case IAX_IE_CAUSECODE:
1234 if (ies_len != 1) THROW(ReportedBoundsError);
1235 proto_tree_add_item (ies_tree, hf_IAX_IE_CAUSECODE, tvb,
1236 offset +2, ies_len, FALSE);
1238 case IAX_IE_ENCRYPTION:
1239 if (ies_len != 2) THROW(ReportedBoundsError);
1240 proto_tree_add_item (ies_tree, hf_IAX_IE_ENCRYPTION, tvb,
1241 offset +2, ies_len, FALSE);
1244 proto_tree_add_item (ies_tree, hf_IAX_IE_ENCKEY, tvb,
1245 offset +2, ies_len, FALSE);
1247 case IAX_IE_CODEC_PREFS:
1248 proto_tree_add_item (ies_tree, hf_IAX_IE_CODEC_PREFS, tvb,
1249 offset +2, ies_len, FALSE);
1251 case IAX_IE_RR_JITTER:
1252 if (ies_len != 4) THROW(ReportedBoundsError);
1253 proto_tree_add_item (ies_tree, hf_IAX_IE_RR_JITTER, tvb,
1254 offset +2, ies_len, FALSE);
1256 case IAX_IE_RR_LOSS:
1257 if (ies_len != 4) THROW(ReportedBoundsError);
1258 proto_tree_add_item (ies_tree, hf_IAX_IE_RR_LOSS, tvb,
1259 offset +2, ies_len, FALSE);
1261 case IAX_IE_RR_PKTS:
1262 if (ies_len != 4) THROW(ReportedBoundsError);
1263 proto_tree_add_item (ies_tree, hf_IAX_IE_RR_PKTS, tvb,
1264 offset +2, ies_len, FALSE);
1266 case IAX_IE_RR_DELAY:
1267 if (ies_len != 2) THROW(ReportedBoundsError);
1268 proto_tree_add_item (ies_tree, hf_IAX_IE_RR_DELAY, tvb,
1269 offset +2, ies_len, FALSE);
1271 case IAX_IE_RR_DROPPED:
1272 if (ies_len != 4) THROW(ReportedBoundsError);
1273 proto_tree_add_item (ies_tree, hf_IAX_IE_RR_DROPPED, tvb,
1274 offset +2, ies_len, FALSE);
1277 if (ies_len != 4) THROW(ReportedBoundsError);
1278 proto_tree_add_item (ies_tree, hf_IAX_IE_RR_OOO, tvb,
1279 offset +2, ies_len, FALSE);
1282 case IAX_IE_DATAFORMAT:
1283 if (ies_len != 4) THROW(ReportedBoundsError);
1284 proto_tree_add_item (ies_tree, hf_IAX_IE_DATAFORMAT, tvb,
1285 offset + 2, ies_len, FALSE);
1288 iax_call_data -> dataformat = tvb_get_ntohl(tvb, offset+2);
1296 proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_BYTE, tvb, offset+2, ies_len, FALSE );
1300 proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_I16, tvb, offset+2, ies_len, FALSE );
1304 proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_I32, tvb, offset+2, ies_len, FALSE );
1308 proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_BYTES, tvb, offset+2, ies_len, FALSE );
1313 offset += ies_len + 2;
1318 static guint32 uncompress_subclass(guint8 csub)
1320 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
1322 /* special case for 'compressed' -1 */
1326 return 1 << (csub & 0x1F);
1329 return (guint32)csub;
1334 dissect_fullpacket (tvbuff_t * tvb, guint32 offset,
1336 packet_info * pinfo, proto_tree * iax2_tree,
1337 proto_tree * main_tree)
1339 guint32 retransmission = 0;
1346 proto_tree *packet_type_tree = NULL;
1347 iax_call_data *iax_call;
1348 iax_packet_data *iax_packet;
1350 gboolean rtp_marker;
1355 * remove the top bit for retransmission detection
1357 dcallno = tvb_get_ntohs(tvb, offset);
1358 retransmission = dcallno & 0x8000;
1359 dcallno = dcallno & 0x7FFF;
1360 ts = tvb_get_ntohl(tvb, offset+2);
1361 type = tvb_get_guint8(tvb, offset + 8);
1362 csub = tvb_get_guint8(tvb, offset + 9);
1364 /* see if we've seen this packet before */
1365 iax_packet = (iax_packet_data *)p_get_proto_data(pinfo->fd,proto_iax2);
1367 /* if not, find or create an iax_call info structure for this IAX session. */
1369 if( type == AST_FRAME_IAX && csub == IAX_COMMAND_NEW ) {
1370 /* NEW packets start a new call */
1371 iax_call = iax_new_circuit_details(pinfo,scallno,&circuit);
1374 iax_call = iax_lookup_circuit_details(pinfo, scallno, dcallno,
1375 &reversed, &circuit);
1378 iax_packet = iax_new_packet_data(iax_call);
1379 p_add_proto_data(pinfo->fd,proto_iax2,iax_packet);
1381 iax_call = iax_packet->call_data;
1384 * XXX - the code needs to set "circuit" and "reversed" somehow here,
1385 * by determining them based on values in "iax_call" or "iax_packet".
1386 * I leave that as an exercise for somebody who wants to maintain
1394 proto_item *packet_type_base;
1396 proto_tree_add_item (iax2_tree, hf_iax2_dcallno, tvb, offset, 2, FALSE );
1397 proto_tree_add_boolean(iax2_tree, hf_iax2_retransmission, tvb, offset, 2, FALSE );
1399 proto_tree_add_uint (iax2_tree, hf_iax2_ts, tvb, offset+2, 4, ts);
1401 proto_tree_add_item (iax2_tree, hf_iax2_oseqno, tvb, offset+6, 1,
1404 proto_tree_add_item (iax2_tree, hf_iax2_iseqno, tvb, offset+7, 1,
1406 packet_type_base = proto_tree_add_uint (iax2_tree, hf_iax2_type, tvb,
1409 /* add the type-specific subtree */
1410 packet_type_tree = proto_item_add_subtree (packet_type_base, ett_iax2_type);
1413 /* add frame type to info line */
1414 if (check_col (pinfo->cinfo, COL_INFO)) {
1415 col_add_fstr (pinfo->cinfo, COL_INFO, "%s, source call# %d, timestamp %ums",
1416 val_to_str (type, iax_frame_types, "Unknown (0x%02x)"),
1422 /* add the subclass */
1423 proto_tree_add_uint (packet_type_tree, hf_iax2_iax_csub, tvb,
1427 if (check_col (pinfo->cinfo, COL_INFO))
1428 col_append_fstr (pinfo->cinfo, COL_INFO, " %s",
1429 val_to_str (csub, iax_iax_subclasses, "unknown (0x%02x)"));
1431 if (offset < tvb_reported_length (tvb)) {
1432 offset += dissect_ies(tvb, offset, packet_type_tree, iax_call);
1435 if( csub == IAX_COMMAND_NEW && circuit && iax_call ) {
1436 /* if this is a data call, set up a subdissector for the circuit */
1437 dissector_handle_t s;
1438 s = dissector_get_port_handle(iax2_dataformat_dissector_table, iax_call -> dataformat );
1439 circuit_set_dissector( circuit, s );
1443 case AST_FRAME_DTMF:
1444 proto_tree_add_text (packet_type_tree, tvb, offset+9, 1, "DTMF digit: %c", csub);
1447 if (check_col (pinfo->cinfo, COL_INFO))
1448 col_append_fstr (pinfo->cinfo, COL_INFO, " digit %c", csub );
1451 case AST_FRAME_CONTROL:
1452 /* add the subclass */
1453 proto_tree_add_uint (packet_type_tree, hf_iax2_cmd_csub, tvb,
1457 if (check_col (pinfo->cinfo, COL_INFO))
1458 col_append_fstr (pinfo->cinfo, COL_INFO, " %s",
1459 val_to_str (csub, iax_cmd_subclasses, "unknown (0x%02x)"));
1462 case AST_FRAME_VOICE:
1464 iax_packet -> codec = codec = uncompress_subclass(csub);
1466 if( packet_type_tree ) {
1467 proto_tree_add_item (packet_type_tree, hf_iax2_voice_csub, tvb, offset+9, 1, FALSE);
1468 proto_tree_add_uint (packet_type_tree, hf_iax2_voice_codec, tvb, offset+9, 1, codec);
1475 iax_call->dst_codec = codec;
1477 iax_call->src_codec = codec;
1481 dissect_payload(tvb, offset, pinfo, main_tree, ts, FALSE,iax_packet);
1484 case AST_FRAME_VIDEO:
1485 /* bit 6 of the csub is used to represent the rtp 'marker' bit */
1486 rtp_marker = csub & 0x40 ? TRUE:FALSE;
1487 iax_packet -> codec = codec = uncompress_subclass((guint8) (csub & ~40));
1489 if( packet_type_tree ) {
1490 proto_tree_add_item (packet_type_tree, hf_iax2_video_csub, tvb, offset+9, 1, FALSE);
1491 proto_tree_add_item (packet_type_tree, hf_iax2_marker, tvb, offset+9, 1, FALSE);
1492 proto_tree_add_uint (packet_type_tree, hf_iax2_video_codec, tvb, offset+9, 1, codec);
1499 iax_call->dst_vformat = codec;
1501 iax_call->src_vformat = codec;
1505 if( rtp_marker && check_col (pinfo->cinfo, COL_INFO))
1506 col_append_fstr (pinfo->cinfo, COL_INFO, ", Mark" );
1509 dissect_payload(tvb, offset, pinfo, main_tree, ts, TRUE, iax_packet);
1514 proto_tree_add_uint (packet_type_tree, hf_iax2_csub, tvb, offset+9,
1518 if (check_col (pinfo->cinfo, COL_INFO))
1519 col_append_fstr (pinfo->cinfo, COL_INFO, " subclass %d", csub );
1526 static iax_packet_data *iax2_get_packet_data_for_minipacket(packet_info * pinfo,
1530 /* see if we've seen this packet before */
1531 iax_packet_data *p = (iax_packet_data *)p_get_proto_data(pinfo->fd,proto_iax2);
1534 /* if not, find or create an iax_call info structure for this IAX session. */
1537 iax_call_data *iax_call;
1539 iax_call = iax_lookup_circuit_details(pinfo, scallno, 0, &reversed, &circuit);
1541 p = iax_new_packet_data(iax_call);
1542 p_add_proto_data(pinfo->fd,proto_iax2,p);
1544 /* set the codec for this frame to be whatever the last full frame used */
1547 p->codec = reversed ? iax_call -> dst_vformat : iax_call -> src_vformat;
1549 p->codec = reversed ? iax_call -> dst_codec : iax_call -> src_codec;
1556 static guint32 dissect_minivideopacket (tvbuff_t * tvb, guint32 offset,
1557 guint16 scallno, packet_info * pinfo,
1558 proto_tree * iax2_tree, proto_tree *main_tree)
1561 iax_packet_data *iax_packet;
1562 gboolean rtp_marker;
1564 ts = tvb_get_ntohs(tvb, offset);
1566 /* bit 15 of the ts is used to represent the rtp 'marker' bit */
1567 rtp_marker = ts & 0x8000 ? TRUE:FALSE;
1572 proto_tree_add_item (iax2_tree, hf_iax2_minividts, tvb, offset, 2, FALSE);
1573 proto_tree_add_item (iax2_tree, hf_iax2_minividmarker, tvb, offset, 2, FALSE);
1578 iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, TRUE);
1580 if (check_col (pinfo->cinfo, COL_INFO))
1581 col_add_fstr (pinfo->cinfo, COL_INFO,
1582 "Mini video packet, source call# %d, timestamp %ums%s",
1583 scallno, ts, rtp_marker?", Mark":"");
1586 dissect_payload(tvb, offset, pinfo, main_tree, ts, TRUE, iax_packet);
1592 dissect_minipacket (tvbuff_t * tvb, guint32 offset, guint16 scallno, packet_info * pinfo, proto_tree * iax2_tree,
1593 proto_tree *main_tree)
1596 iax_packet_data *iax_packet;
1598 ts = tvb_get_ntohs(tvb, offset);
1600 iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, FALSE);
1602 proto_tree_add_uint (iax2_tree, hf_iax2_minits, tvb, offset, 2,
1606 if (check_col (pinfo->cinfo, COL_INFO))
1607 col_add_fstr (pinfo->cinfo, COL_INFO,
1608 "Mini packet, source call# %d, timestamp %ums",
1612 /* XXX fix the timestamp logic */
1613 dissect_payload(tvb, offset, pinfo, main_tree, ts, FALSE, iax_packet);
1619 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
1620 packet_info *pinfo, proto_tree *tree,
1621 guint32 ts, gboolean video,
1622 iax_packet_data *iax_packet)
1624 gboolean out_of_order = FALSE;
1626 guint32 codec = iax_packet -> codec;
1627 iax_call_data *iax_call = iax_packet -> call_data;
1629 /* keep compiler quiet */
1632 if( offset >= tvb_reported_length (tvb)) {
1633 if (check_col (pinfo->cinfo, COL_INFO))
1634 col_append_fstr (pinfo->cinfo, COL_INFO, ", empty frame" );
1638 sub_tvb = tvb_new_subset(tvb, offset, -1, -1 );
1640 /* XXX shouldn't pass through out-of-order packets. */
1642 if (check_col (pinfo->cinfo, COL_INFO)) {
1643 if( !video && iax_call && iax_call -> dataformat != 0 ) {
1644 col_append_fstr (pinfo->cinfo, COL_INFO, ", data, format %s",
1645 val_to_str (iax_call -> dataformat,
1646 iax_dataformats, "unknown (0x%02x)"));
1649 col_append_fstr (pinfo->cinfo, COL_INFO, " (out-of-order packet)");
1651 col_append_fstr (pinfo->cinfo, COL_INFO, ", %s",
1652 val_to_str (codec, codec_types, "unknown (0x%02x)"));
1656 /* pass the rest of the block to a subdissector */
1657 if( !video && try_circuit_dissector(pinfo->ctype, pinfo->circuit_id, pinfo->fd->num,
1658 sub_tvb, pinfo, tree))
1661 if( codec != 0 && dissector_try_port(iax2_codec_dissector_table, codec, sub_tvb, pinfo, tree ))
1664 /* we don't know how to dissect our data: dissect it as data */
1665 call_dissector(data_handle,sub_tvb, pinfo, tree);
1672 /* called at the start of a capture. We should clear out our static, per-capture
1677 iax_init_protocol(void)
1682 g_mem_chunk_destroy(iax_packets);
1683 iax_packets = g_mem_chunk_create(iax_packet_data,128,G_ALLOC_ONLY);
1688 proto_register_iax2 (void)
1690 /* we use this for displaying which codecs are supported */
1691 static const true_false_string supported_strings = {
1696 /* A header field is something you can search/filter on.
1698 * We create a structure to register our fields. It consists of an
1699 * array of hf_register_info structures, each of which are of the format
1700 * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
1703 static hf_register_info hf[] = {
1705 {&hf_iax2_packet_type,
1706 {"Packet type", "iax2.type", FT_UINT8, BASE_DEC, VALS(iax_packet_types), 0,
1707 "Full/minivoice/minivideo/meta packet",
1712 {"Source call", "iax2.src_call", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
1713 "src_call holds the number of this call at the packet source pbx",
1716 /* FIXME could this be turned into a FRAMENUM field? */
1718 {"Destination call", "iax2.dst_call", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
1719 "dst_call holds the number of this call at the packet destination",
1722 {&hf_iax2_retransmission,
1723 {"Retransmission", "iax2.retransmission", FT_BOOLEAN, 16,
1725 "retransmission is set if this packet is a retransmission of an earlier "
1726 "failed packet", HFILL}},
1729 {"Timestamp", "iax2.timestamp", FT_UINT32, BASE_DEC, NULL, 0x0,
1730 "timestamp is the time, in ms after the start of this call, at which "
1731 "this packet was transmitted",
1735 {"Timestamp", "iax2.timestamp", FT_UINT16, BASE_DEC, NULL, 0x0,
1736 "timestamp is the time, in ms after the start of this call, at which "
1737 "this packet was transmitted",
1740 {&hf_iax2_minividts,
1741 {"Timestamp", "iax2.timestamp", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
1742 "timestamp is the time, in ms after the start of this call, at which "
1743 "this packet was transmitted",
1746 {&hf_iax2_minividmarker,
1747 {"Marker", "iax2.video.marker", FT_UINT16, BASE_DEC, NULL, 0x8000,
1748 "RTP end-of-frame marker",
1752 {"Outbound seq.no.", "iax2.oseqno", FT_UINT16, BASE_DEC, NULL,
1754 "oseqno is the sequence no of this packet. The first packet has "
1755 "oseqno==0, and subsequent packets increment the oseqno by 1",
1759 {"Inbound seq.no.", "iax2.iseqno", FT_UINT16, BASE_DEC, NULL, 0x0,
1760 "iseqno is the sequence no of the last successfully recieved packet",
1764 {"Type", "iax2.type", FT_UINT8, BASE_DEC, VALS (iax_frame_types),
1766 "For full IAX2 frames, type is the type of frame",
1770 {"Sub-class", "iax2.subclass", FT_UINT8, BASE_DEC, NULL, 0x0,
1775 {"Control subclass", "iax2.control.subclass", FT_UINT8, BASE_DEC,
1776 VALS (iax_cmd_subclasses), 0x0,
1777 "This gives the command number for a Control packet.", HFILL}},
1780 {"IAX type", "iax2.iax.subclass", FT_UINT8, BASE_DEC,
1781 VALS (iax_iax_subclasses),
1783 "IAX type gives the command number for IAX signalling packets", HFILL}},
1785 {&hf_iax2_voice_csub,
1786 {"Sub-class", "iax2.voice.subclass", FT_UINT8, BASE_DEC, NULL, 0x0,
1790 {&hf_iax2_voice_codec,
1791 {"CODEC", "iax2.voice.codec", FT_UINT32, BASE_HEX, VALS (codec_types),
1793 "CODEC gives the codec used to encode audio data", HFILL}},
1795 {&hf_iax2_video_csub,
1796 {"Subclass (compressed codec no)", "iax2.video.subclass", FT_UINT8, BASE_DEC, NULL, 0xBF,
1797 "Subclass (compressed codec no)",
1801 {"Marker", "iax2.video.marker", FT_BOOLEAN, 8, NULL, 0x40,
1802 "RTP end-of-frame marker",
1805 {&hf_iax2_video_codec,
1806 {"CODEC", "iax2.video.codec", FT_UINT32, BASE_HEX, VALS (codec_types), 0,
1807 "The codec used to encode video data", HFILL}},
1810 * Decoding for the ies
1813 {&hf_IAX_IE_APPARENTADDR_SINFAMILY,
1814 {"Family", "iax2.iax.app_addr.sinfamily", FT_UINT16, BASE_DEC, NULL, 0, "Family", HFILL }},
1815 {&hf_IAX_IE_APPARENTADDR_SINPORT,
1816 {"Port", "iax2.iax.app_addr.sinport", FT_UINT16, BASE_DEC, NULL, 0, "Port", HFILL }},
1817 {&hf_IAX_IE_APPARENTADDR_SINADDR,
1818 {"Address", "iax2.iax.app_addr.sinaddr", FT_IPv4, BASE_HEX, NULL, 0, "Address", HFILL }},
1819 {&hf_IAX_IE_APPARENTADDR_SINZERO,
1820 {"Zero", "iax2.iax.app_addr.sinzero", FT_BYTES, BASE_HEX, NULL, 0, "Zero", HFILL }},
1822 {&hf_IAX_IE_CALLED_NUMBER,
1823 {"Number/extension being called", "iax2.iax.called_number",
1825 BASE_NONE, NULL, 0x0, "", HFILL}},
1827 {&hf_IAX_IE_CALLING_NUMBER,
1828 {"Calling number", "iax2.iax.calling_number", FT_STRING,
1832 {&hf_IAX_IE_CALLING_ANI,
1833 {"Calling number ANI for billing", "iax2.iax.calling_ani",
1835 BASE_NONE, NULL, 0x0, "", HFILL}},
1837 {&hf_IAX_IE_CALLING_NAME,
1838 {"Name of caller", "iax2.iax.calling_name", FT_STRING, BASE_NONE,
1842 {&hf_IAX_IE_CALLED_CONTEXT,
1843 {"Context for number", "iax2.iax.called_context", FT_STRING,
1845 NULL, 0x0, "", HFILL}},
1847 {&hf_IAX_IE_USERNAME,
1848 {"Username (peer or user) for authentication",
1849 "iax2.iax.username",
1850 FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1852 {&hf_IAX_IE_PASSWORD,
1853 {"Password for authentication", "iax2.iax.password", FT_STRING,
1854 BASE_NONE, NULL, 0x0, "", HFILL}},
1856 {&hf_IAX_IE_CAPABILITY,
1857 {"Actual codec capability", "iax2.iax.capability", FT_UINT32,
1859 NULL, 0x0, "", HFILL}},
1862 {"Desired codec format", "iax2.iax.format", FT_UINT32, BASE_HEX,
1863 VALS (codec_types), 0x0, "", HFILL}},
1865 {&hf_IAX_IE_LANGUAGE,
1866 {"Desired language", "iax2.iax.language", FT_STRING, BASE_NONE,
1870 {&hf_IAX_IE_VERSION,
1871 {"Protocol version", "iax2.iax.version", FT_UINT16, BASE_HEX, NULL,
1875 {&hf_IAX_IE_ADSICPE,
1876 {"CPE ADSI capability", "iax2.iax.cpe_adsi", FT_UINT16, BASE_HEX,
1881 {"Originally dialed DNID", "iax2.iax.dnid", FT_STRING, BASE_NONE,
1885 {&hf_IAX_IE_AUTHMETHODS,
1886 {"Authentication method(s)", "iax2.iax.auth.methods", FT_UINT16,
1888 NULL, 0x0, "", HFILL}},
1890 {&hf_IAX_IE_CHALLENGE,
1891 {"Challenge data for MD5/RSA", "iax2.iax.auth.challenge",
1893 BASE_NONE, NULL, 0x0, "", HFILL}},
1895 {&hf_IAX_IE_MD5_RESULT,
1896 {"MD5 challenge result", "iax2.iax.auth.md5", FT_STRING,
1900 {&hf_IAX_IE_RSA_RESULT,
1901 {"RSA challenge result", "iax2.iax.auth.rsa", FT_STRING,
1905 {&hf_IAX_IE_REFRESH,
1906 {"When to refresh registration", "iax2.iax.refresh", FT_INT16,
1908 NULL, 0x0, "", HFILL}},
1910 {&hf_IAX_IE_DPSTATUS,
1911 {"Dialplan status", "iax2.iax.dialplan_status", FT_UINT16,
1916 {"Call number of peer", "iax2.iax.call_no", FT_INT16, BASE_DEC,
1921 {"Cause", "iax2.iax.cause", FT_STRING, BASE_NONE, NULL, 0x0, "",
1924 {&hf_IAX_IE_IAX_UNKNOWN,
1925 {"Unknown IAX command", "iax2.iax.iax_unknown", FT_BYTES,
1929 {&hf_IAX_IE_MSGCOUNT,
1930 {"How many messages waiting", "iax2.iax.msg_count", FT_INT16,
1932 NULL, 0x0, "", HFILL}},
1934 {&hf_IAX_IE_AUTOANSWER,
1935 {"Request auto-answering", "iax2.iax.autoanswer", FT_NONE,
1937 NULL, 0x0, "", HFILL}},
1939 {&hf_IAX_IE_MUSICONHOLD,
1940 {"Request musiconhold with QUELCH", "iax2.iax.moh", FT_NONE,
1942 NULL, 0x0, "", HFILL}},
1944 {&hf_IAX_IE_TRANSFERID,
1945 {"Transfer Request Identifier", "iax2.iax.transferid", FT_UINT32,
1946 BASE_HEX, NULL, 0x0, "", HFILL}},
1949 {"Referring DNIS", "iax2.iax.rdnis", FT_STRING, BASE_NONE, NULL,
1953 {&hf_IAX_IE_PROVISIONING,
1954 {"Provisioning info","iax2.iax.provisioning", FT_STRING, BASE_NONE,
1955 NULL, 0x0, "", HFILL}},
1957 {&hf_IAX_IE_AESPROVISIONING,
1958 {"AES Provisioning info","iax2.iax.aesprovisioning", FT_STRING, BASE_NONE,
1959 NULL, 0x0, "", HFILL}},
1961 {&hf_IAX_IE_DATETIME,
1962 {"Date/Time", "iax2.iax.datetime", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1964 {&hf_IAX_IE_DEVICETYPE,
1965 {"Device type", "iax2.iax.devicetype", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1967 {&hf_IAX_IE_SERVICEIDENT,
1968 {"Service identifier", "iax2.iax.serviceident", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1970 {&hf_IAX_IE_FIRMWAREVER,
1971 {"Firmware version", "iax2.iax.firmwarever", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
1973 {&hf_IAX_IE_FWBLOCKDESC,
1974 {"Firmware block description", "iax2.iax.fwblockdesc", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
1976 {&hf_IAX_IE_FWBLOCKDATA,
1977 {"Firmware block of data", "iax2.iax.fwblockdata", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1979 {&hf_IAX_IE_PROVVER,
1980 {"Provisioning version", "iax2.iax.provver", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
1982 {&hf_IAX_IE_CALLINGPRES,
1983 {"Calling presentation", "iax2.iax.callingpres", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},
1985 {&hf_IAX_IE_CALLINGTON,
1986 {"Calling type of number", "iax2.iax.callington", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},
1988 {&hf_IAX_IE_CALLINGTNS,
1989 {"Calling transit network select", "iax2.iax.callingtns", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
1991 {&hf_IAX_IE_SAMPLINGRATE,
1992 {"Supported sampling rates", "iax2.iax.samplingrate", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
1994 {&hf_IAX_IE_CAUSECODE,
1995 {"Hangup cause", "iax2.iax.causecode", FT_UINT8, BASE_HEX, VALS(iax_causecodes),
1998 {&hf_IAX_IE_ENCRYPTION,
1999 {"Encryption format", "iax2.iax.encryption", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
2002 {"Encryption key", "iax2.iax.enckey", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
2004 {&hf_IAX_IE_CODEC_PREFS,
2005 {"Codec negotiation", "iax2.iax.codecprefs", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
2007 {&hf_IAX_IE_RR_JITTER,
2008 {"Received jitter (as in RFC1889)", "iax2.iax.rrjitter", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2010 {&hf_IAX_IE_RR_LOSS,
2011 {"Received loss (high byte loss pct, low 24 bits loss count, as in rfc1889)", "iax2.iax.rrloss",
2012 FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2014 {&hf_IAX_IE_RR_PKTS,
2015 {"Total frames received", "iax2.iax.rrpkts", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2017 {&hf_IAX_IE_RR_DELAY,
2018 {"Max playout delay in ms for received frames", "iax2.iax.rrdelay", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
2020 {&hf_IAX_IE_RR_DROPPED,
2021 {"Dropped frames (presumably by jitterbuffer)", "iax2.iax.rrdropped", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2024 {"Frame received out of order", "iax2.iax.rrooo", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2026 {&hf_IAX_IE_DATAFORMAT,
2027 {"Data call format", "iax2.iax.dataformat", FT_UINT32, BASE_HEX,
2028 VALS(iax_dataformats), 0x0, "", HFILL}},
2030 {&hf_IAX_IE_UNKNOWN_BYTE,
2031 {"data", "iax2.iax.unknowndata", FT_UINT8, BASE_HEX, NULL,
2032 0x0, "Raw data for unknown IEs",
2034 {&hf_IAX_IE_UNKNOWN_I16,
2035 {"data", "iax2.iax.unknowndata", FT_UINT16, BASE_HEX, NULL,
2036 0x0, "Raw data for unknown IEs",
2038 {&hf_IAX_IE_UNKNOWN_I32,
2039 {"data", "iax2.iax.unknowndata", FT_UINT32, BASE_HEX, NULL,
2040 0x0, "Raw data for unknown IEs",
2042 {&hf_IAX_IE_UNKNOWN_BYTES,
2043 {"data", "iax2.iax.unknowndata", FT_BYTES, BASE_NONE, NULL,
2044 0x0, "Raw data for unknown IEs",
2048 {&hf_iax2_cap_g723_1,
2049 {"G.723.1 compression", "iax2.cap.g723_1", FT_BOOLEAN, 32,
2050 TFS(&supported_strings), AST_FORMAT_G723_1,
2051 "G.723.1 compression", HFILL }},
2054 {"GSM compression", "iax2.cap.gsm", FT_BOOLEAN, 32,
2055 TFS(&supported_strings), AST_FORMAT_GSM,
2056 "GSM compression", HFILL }},
2059 {"Raw mu-law data (G.711)", "iax2.cap.ulaw",FT_BOOLEAN, 32,
2060 TFS(&supported_strings), AST_FORMAT_ULAW,
2061 "Raw mu-law data (G.711)", HFILL }},
2064 {"Raw A-law data (G.711)", "iax2.cap.alaw",FT_BOOLEAN, 32,
2065 TFS(&supported_strings), AST_FORMAT_ALAW,
2066 "Raw A-law data (G.711)", HFILL }},
2069 {"G.726 compression", "iax2.cap.g726",FT_BOOLEAN, 32,
2070 TFS(&supported_strings), AST_FORMAT_G726,
2071 "G.726 compression", HFILL }},
2073 {&hf_iax2_cap_adpcm,
2074 {"ADPCM", "iax2.cap.adpcm", FT_BOOLEAN, 32,
2075 TFS(&supported_strings), AST_FORMAT_ADPCM,
2078 {&hf_iax2_cap_slinear,
2079 {"Raw 16-bit Signed Linear (8000 Hz) PCM", "iax2.cap.slinear",
2080 FT_BOOLEAN, 32, TFS(&supported_strings), AST_FORMAT_SLINEAR,
2081 "Raw 16-bit Signed Linear (8000 Hz) PCM", HFILL }},
2083 {&hf_iax2_cap_lpc10,
2084 {"LPC10, 180 samples/frame", "iax2.cap.lpc10", FT_BOOLEAN, 32,
2085 TFS(&supported_strings), AST_FORMAT_LPC10,
2086 "LPC10, 180 samples/frame", HFILL }},
2088 {&hf_iax2_cap_g729a,
2089 {"G.729a Audio", "iax2.cap.g729a", FT_BOOLEAN, 32,
2090 TFS(&supported_strings), AST_FORMAT_G729A,
2091 "G.729a Audio", HFILL }},
2093 {&hf_iax2_cap_speex,
2094 {"SPEEX Audio", "iax2.cap.speex", FT_BOOLEAN, 32,
2095 TFS(&supported_strings), AST_FORMAT_SPEEX,
2096 "SPEEX Audio", HFILL }},
2099 {"iLBC Free compressed Audio", "iax2.cap.ilbc", FT_BOOLEAN, 32,
2100 TFS(&supported_strings), AST_FORMAT_ILBC,
2101 "iLBC Free compressed Audio", HFILL }},
2104 {"JPEG images", "iax2.cap.jpeg", FT_BOOLEAN, 32,
2105 TFS(&supported_strings), AST_FORMAT_JPEG,
2106 "JPEG images", HFILL }},
2109 {"PNG images", "iax2.cap.png", FT_BOOLEAN, 32,
2110 TFS(&supported_strings), AST_FORMAT_PNG,
2111 "PNG images", HFILL }},
2114 {"H.261 video", "iax2.cap.h261", FT_BOOLEAN, 32,
2115 TFS(&supported_strings), AST_FORMAT_H261,
2116 "H.261 video", HFILL }},
2119 {"H.263 video", "iax2.cap.h263", FT_BOOLEAN, 32,
2120 TFS(&supported_strings), AST_FORMAT_H263,
2121 "H.263 video", HFILL }}
2124 static gint *ett[] = {
2126 &ett_iax2_full_mini_subtree,
2130 &ett_iax2_ies_apparent_addr
2134 proto_register_protocol ("Inter-Asterisk eXchange v2", "IAX2", "iax2");
2135 proto_register_field_array (proto_iax2, hf, array_length (hf));
2136 proto_register_subtree_array (ett, array_length (ett));
2138 register_dissector("iax2", dissect_iax2, proto_iax2);
2140 iax2_codec_dissector_table = register_dissector_table(
2141 "iax2.codec","IAX codec number", FT_UINT32, BASE_HEX);
2142 iax2_dataformat_dissector_table = register_dissector_table(
2143 "iax2.dataformat","IAX dataformat number", FT_UINT32, BASE_HEX);
2145 /* register our init routine to be called at the start of a capture,
2146 to clear out our hash tables etc */
2147 register_init_routine(&iax_init_protocol);
2151 proto_reg_handoff_iax2 (void)
2153 dissector_add("udp.port", IAX2_PORT, find_dissector("iax2"));
2154 dissector_add("iax2.dataformat", AST_DATAFORMAT_V110, find_dissector("v110"));
2155 data_handle = find_dissector("data");
2160 * This sets up the indentation style for this file in emacs.