Fixup: tvb_get_string(z) -> tvb_get_string(z)_enc
[metze/wireshark/wip.git] / epan / dissectors / packet-iax2.c
1  /*
2  * packet-iax2.c
3  *
4  * Routines for IAX2 packet disassembly
5  * By Alastair Maw <asterisk@almaw.com>
6  * Copyright 2003 Alastair Maw
7  *
8  * IAX2 is a VoIP protocol for the open source PBX Asterisk. Please see
9  * http://www.asterisk.org for more information; see RFC 5456 for the
10  * protocol.
11  *
12  * Wireshark - Network traffic analyzer
13  * By Gerald Combs <gerald@wireshark.org>
14  * Copyright 1998 Gerald Combs
15  *
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29  */
30
31 #include "config.h"
32
33 #include <string.h>
34
35 #include <glib.h>
36
37 #include <epan/circuit.h>
38 #include <epan/packet.h>
39 #include <epan/exceptions.h>
40 #include <epan/to_str.h>
41 #include <epan/wmem/wmem.h>
42 #include <epan/reassemble.h>
43 #include <epan/expert.h>
44 #include <epan/aftypes.h>
45 #include <epan/tap.h>
46 #include <epan/tap-voip.h>
47
48 #include "packet-iax2.h"
49 #include <epan/iax2_codec_type.h>
50
51 void proto_register_iax2(void);
52 void proto_reg_handoff_iax2(void);
53
54 #define IAX2_PORT               4569
55 #define PROTO_TAG_IAX2          "IAX2"
56
57 /* enough to hold any address in an address_t */
58 #define MAX_ADDRESS 16
59
60 /* the maximum number of transfers (of each end) we can deal with per call,
61  * plus one */
62 #define IAX_MAX_TRANSFERS 2
63
64 /* #define DEBUG_HASHING */
65 /* #define DEBUG_DESEGMENT */
66
67 /* Wireshark ID of the IAX2 protocol */
68 static int proto_iax2 = -1;
69
70 /* tap register id */
71 static int iax2_tap = -1;
72
73 /* protocol tap info */
74 static iax2_info_t ii_arr[1];
75 static iax2_info_t *iax2_info = ii_arr;
76
77 /* The following hf_* variables are used to hold the wireshark IDs of
78  * our header fields; they are filled out when we call
79  * proto_register_field_array() in proto_register_iax2()
80  */
81 static int hf_iax2_packet_type = -1;
82 static int hf_iax2_retransmission = -1;
83 static int hf_iax2_callno = -1;
84 static int hf_iax2_scallno = -1;
85 static int hf_iax2_dcallno = -1;
86 static int hf_iax2_ts = -1;
87 static int hf_iax2_minits = -1;
88 static int hf_iax2_minividts = -1;
89 static int hf_iax2_absts = -1;
90 static int hf_iax2_lateness = -1;
91 static int hf_iax2_minividmarker = -1;
92 static int hf_iax2_oseqno = -1;
93 static int hf_iax2_iseqno = -1;
94 static int hf_iax2_type = -1;
95 static int hf_iax2_csub = -1;
96 static int hf_iax2_dtmf_csub = -1;
97 static int hf_iax2_cmd_csub = -1;
98 static int hf_iax2_iax_csub = -1;
99 static int hf_iax2_voice_csub = -1;
100 static int hf_iax2_voice_codec = -1;
101 static int hf_iax2_video_csub = -1;
102 static int hf_iax2_video_codec = -1;
103 static int hf_iax2_marker = -1;
104 static int hf_iax2_modem_csub = -1;
105 static int hf_iax2_text_csub = -1;
106 static int hf_iax2_text_text = -1;
107 static int hf_iax2_html_csub = -1;
108 static int hf_iax2_html_url = -1;
109 static int hf_iax2_trunk_metacmd = -1;
110 static int hf_iax2_trunk_cmddata = -1;
111 static int hf_iax2_trunk_cmddata_ts = -1;
112 static int hf_iax2_trunk_ts = -1;
113 static int hf_iax2_trunk_ncalls = -1;
114 static int hf_iax2_trunk_call_len = -1;
115 static int hf_iax2_trunk_call_scallno = -1;
116 static int hf_iax2_trunk_call_ts = -1;
117 static int hf_iax2_trunk_call_data = -1;
118
119 static int hf_iax2_cap_g723_1 = -1;
120 static int hf_iax2_cap_gsm = -1;
121 static int hf_iax2_cap_ulaw = -1;
122 static int hf_iax2_cap_alaw = -1;
123 static int hf_iax2_cap_g726_aal2 = -1;
124 static int hf_iax2_cap_adpcm = -1;
125 static int hf_iax2_cap_slinear = -1;
126 static int hf_iax2_cap_lpc10 = -1;
127 static int hf_iax2_cap_g729a = -1;
128 static int hf_iax2_cap_speex = -1;
129 static int hf_iax2_cap_ilbc = -1;
130 static int hf_iax2_cap_g726 = -1;
131 static int hf_iax2_cap_g722 = -1;
132 static int hf_iax2_cap_siren7 = -1;
133 static int hf_iax2_cap_siren14 = -1;
134 static int hf_iax2_cap_slinear16 = -1;
135 static int hf_iax2_cap_jpeg = -1;
136 static int hf_iax2_cap_png = -1;
137 static int hf_iax2_cap_h261 = -1;
138 static int hf_iax2_cap_h263 = -1;
139 static int hf_iax2_cap_h263_plus = -1;
140 static int hf_iax2_cap_h264 = -1;
141 static int hf_iax2_cap_mpeg4 = -1;
142
143 static int hf_iax2_fragments = -1;
144 static int hf_iax2_fragment = -1;
145 static int hf_iax2_fragment_overlap = -1;
146 static int hf_iax2_fragment_overlap_conflict = -1;
147 static int hf_iax2_fragment_multiple_tails = -1;
148 static int hf_iax2_fragment_too_long_fragment = -1;
149 static int hf_iax2_fragment_error = -1;
150 static int hf_iax2_fragment_count = -1;
151 static int hf_iax2_reassembled_in = -1;
152 static int hf_iax2_reassembled_length = -1;
153
154
155 /* hf_iax2_ies is an array of header fields, one per potential Information
156  * Element. It's done this way (rather than having separate variables for each
157  * IE) to make the dissection of information elements clearer and more
158  * orthogonal.
159  *
160  * To add the ability to dissect a new information element, just add an
161  * appropriate entry to hf[] in proto_register_iax2(); dissect_ies() will then
162  * pick it up automatically.
163  */
164 #define NUM_HF_IAX2_IES 256
165 static int hf_iax2_ies[NUM_HF_IAX2_IES];
166 static int hf_iax2_ie_datetime = -1;
167 static int hf_IAX_IE_APPARENTADDR_SINFAMILY = -1;
168 static int hf_IAX_IE_APPARENTADDR_SINPORT = -1;
169 static int hf_IAX_IE_APPARENTADDR_SINADDR = -1;
170 static int hf_IAX_IE_UNKNOWN_BYTE = -1;
171 static int hf_IAX_IE_UNKNOWN_I16 = -1;
172 static int hf_IAX_IE_UNKNOWN_I32 = -1;
173 static int hf_IAX_IE_UNKNOWN_BYTES = -1;
174
175 /* These are the ids of the subtrees that we may be creating */
176 static gint ett_iax2 = -1;
177 static gint ett_iax2_full_mini_subtree = -1;
178 static gint ett_iax2_type = -1;              /* Frame-type specific subtree */
179 static gint ett_iax2_ie = -1;                /* single IE */
180 static gint ett_iax2_codecs = -1;            /* capabilities IE */
181 static gint ett_iax2_ies_apparent_addr = -1; /* apparent address IE */
182 static gint ett_iax2_fragment = -1;
183 static gint ett_iax2_fragments = -1;
184 static gint ett_iax2_trunk_cmddata = -1;
185 static gint ett_iax2_trunk_call = -1;
186
187 static expert_field ei_iax_too_many_transfers = EI_INIT;
188 static expert_field ei_iax_circuit_id_conflict = EI_INIT;
189 static expert_field ei_iax_peer_address_unsupported = EI_INIT;
190
191 static const fragment_items iax2_fragment_items = {
192   &ett_iax2_fragment,
193   &ett_iax2_fragments,
194   &hf_iax2_fragments,
195   &hf_iax2_fragment,
196   &hf_iax2_fragment_overlap,
197   &hf_iax2_fragment_overlap_conflict,
198   &hf_iax2_fragment_multiple_tails,
199   &hf_iax2_fragment_too_long_fragment,
200   &hf_iax2_fragment_error,
201   &hf_iax2_fragment_count,
202   &hf_iax2_reassembled_in,
203   &hf_iax2_reassembled_length,
204   /* Reassembled data field */
205   NULL,
206   "iax2 fragments"
207 };
208
209 static dissector_handle_t data_handle;
210
211 /* data-call subdissectors, AST_DATAFORMAT_* */
212 static dissector_table_t iax2_dataformat_dissector_table;
213 /* voice/video call subdissectors, AST_FORMAT_* */
214 static dissector_table_t iax2_codec_dissector_table;
215
216
217 /* IAX2 Meta trunk packet Command data flags */
218 #define IAX2_TRUNK_TS 1
219
220 /* IAX2 Full-frame types */
221 static const value_string iax_frame_types[] = {
222   {0,                    "(0?)"},
223   {AST_FRAME_DTMF_END,   "DTMF End"},
224   {AST_FRAME_VOICE,      "Voice"},
225   {AST_FRAME_VIDEO,      "Video"},
226   {AST_FRAME_CONTROL,    "Control"},
227   {AST_FRAME_NULL,       "NULL"},
228   {AST_FRAME_IAX,        "IAX"},
229   {AST_FRAME_TEXT,       "Text"},
230   {AST_FRAME_IMAGE,      "Image"},
231   {AST_FRAME_HTML,       "HTML"},
232   {AST_FRAME_CNG,        "Comfort Noise"},
233   {AST_FRAME_MODEM,      "Modem"},
234   {AST_FRAME_DTMF_BEGIN, "DTMF Begin"},
235   {0, NULL}
236 };
237 static value_string_ext iax_frame_types_ext = VALUE_STRING_EXT_INIT(iax_frame_types);
238
239 /* Subclasses for IAX packets */
240 static const value_string iax_iax_subclasses[] = {
241   { 0, "(0?)"},
242   { 1, "NEW"},
243   { 2, "PING"},
244   { 3, "PONG"},
245   { 4, "ACK"},
246   { 5, "HANGUP"},
247   { 6, "REJECT"},
248   { 7, "ACCEPT"},
249   { 8, "AUTHREQ"},
250   { 9, "AUTHREP"},
251   {10, "INVAL"},
252   {11, "LAGRQ"},
253   {12, "LAGRP"},
254   {13, "REGREQ"},
255   {14, "REGAUTH"},
256   {15, "REGACK"},
257   {16, "REGREJ"},
258   {17, "REGREL"},
259   {18, "VNAK"},
260   {19, "DPREQ"},
261   {20, "DPREP"},
262   {21, "DIAL"},
263   {22, "TXREQ"},
264   {23, "TXCNT"},
265   {24, "TXACC"},
266   {25, "TXREADY"},
267   {26, "TXREL"},
268   {27, "TXREJ"},
269   {28, "QUELCH"},
270   {29, "UNQULCH"},
271   {30, "POKE"},
272   {31, "PAGE"},
273   {32, "MWI"},
274   {33, "UNSUPPORTED"},
275   {34, "TRANSFER"},
276   {35, "PROVISION"},
277   {36, "FWDOWNL"},
278   {37, "FWDATA"},
279   {38, "TXMEDIA"},
280   {39, "RTKEY"},
281   {40, "CALLTOKEN"},
282   {0, NULL}
283 };
284 static value_string_ext iax_iax_subclasses_ext = VALUE_STRING_EXT_INIT(iax_iax_subclasses);
285
286 /* Subclasses for Control packets */
287 static const value_string iax_cmd_subclasses[] = {
288   {0, "(0?)"},
289   {1, "HANGUP"},
290   {2, "RING"},
291   {3, "RINGING"},
292   {4, "ANSWER"},
293   {5, "BUSY"},
294   {6, "TKOFFHK"},
295   {7, "OFFHOOK"},
296   {0xFF, "stop sounds"}, /* sent by app_dial, and not much else */
297   {0, NULL}
298 };
299 static value_string_ext iax_cmd_subclasses_ext = VALUE_STRING_EXT_INIT(iax_cmd_subclasses);
300
301 /* IAX2 to tap-voip call state mapping for command frames */
302 static const voip_call_state tap_cmd_voip_state[] = {
303   VOIP_NO_STATE,
304   VOIP_COMPLETED, /*HANGUP*/
305   VOIP_RINGING,   /*RING*/
306   VOIP_RINGING,   /*RINGING*/
307   VOIP_IN_CALL,   /*ANSWER*/
308   VOIP_REJECTED,  /*BUSY*/
309   VOIP_UNKNOWN,   /*TKOFFHK*/
310   VOIP_UNKNOWN    /*OFFHOOK*/
311 };
312 #define NUM_TAP_CMD_VOIP_STATES array_length(tap_cmd_voip_state)
313
314 /* IAX2 to tap-voip call state mapping for IAX frames */
315 static const voip_call_state tap_iax_voip_state[] = {
316   VOIP_NO_STATE,
317   VOIP_CALL_SETUP, /*NEW*/
318   VOIP_NO_STATE,
319   VOIP_NO_STATE,
320   VOIP_COMPLETED,  /*HANGUP*/
321   VOIP_REJECTED,   /*REJECT*/
322   VOIP_RINGING,    /*ACCEPT*/
323   VOIP_NO_STATE,
324   VOIP_NO_STATE,
325   VOIP_NO_STATE,
326   VOIP_NO_STATE,
327   VOIP_NO_STATE,
328   VOIP_NO_STATE,
329   VOIP_NO_STATE,
330   VOIP_NO_STATE,
331   VOIP_NO_STATE,
332   VOIP_NO_STATE,
333   VOIP_NO_STATE,
334   VOIP_NO_STATE,
335   VOIP_NO_STATE,
336   VOIP_NO_STATE,
337   VOIP_CALL_SETUP, /*DIAL*/
338   VOIP_NO_STATE,
339   VOIP_NO_STATE,
340   VOIP_NO_STATE,
341   VOIP_NO_STATE,
342   VOIP_NO_STATE,
343   VOIP_NO_STATE,
344   VOIP_NO_STATE,
345   VOIP_NO_STATE,
346   VOIP_NO_STATE,
347   VOIP_NO_STATE,
348   VOIP_NO_STATE,
349   VOIP_NO_STATE,
350   VOIP_NO_STATE,
351   VOIP_NO_STATE,
352   VOIP_NO_STATE,
353   VOIP_NO_STATE
354 };
355
356 #define NUM_TAP_IAX_VOIP_STATES array_length(tap_iax_voip_state)
357
358 /* Subclasses for Modem packets */
359 static const value_string iax_modem_subclasses[] = {
360   {0, "(0?)"},
361   {1, "T.38"},
362   {2, "V.150"},
363   {0, NULL}
364 };
365
366 /* Subclasses for Text packets */
367 static const value_string iax_text_subclasses[] = {
368   {0, "Text"},
369   {0, NULL}
370 };
371
372 /* Subclasses for HTML packets */
373 static const value_string iax_html_subclasses[] = {
374   {0x01, "Sending a URL"},
375   {0x02, "Data frame"},
376   {0x04, "Beginning frame"},
377   {0x08, "End frame"},
378   {0x10, "Load is complete"},
379   {0x11, "Peer does not support HTML"},
380   {0x12, "Link URL"},
381   {0x13, "Unlink URL"},
382   {0x14, "Reject Link URL"},
383   {0, NULL}
384 };
385
386
387 /* Information elements */
388 static const value_string iax_ies_type[] = {
389   {IAX_IE_CALLED_NUMBER,   "Number/extension being called"},
390   {IAX_IE_CALLING_NUMBER,  "Calling number"},
391   {IAX_IE_CALLING_ANI,     "Calling number ANI for billing"},
392   {IAX_IE_CALLING_NAME,    "Name of caller"},
393   {IAX_IE_CALLED_CONTEXT,  "Context for number"},
394   {IAX_IE_USERNAME,        "Username (peer or user) for authentication"},
395   {IAX_IE_PASSWORD,        "Password for authentication"},
396   {IAX_IE_CAPABILITY,      "Actual codec capability"},
397   {IAX_IE_FORMAT,          "Desired codec format"},
398   {IAX_IE_LANGUAGE,        "Desired language"},
399   {IAX_IE_VERSION,         "Protocol version"},
400   {IAX_IE_ADSICPE,         "CPE ADSI capability"},
401   {IAX_IE_DNID,            "Originally dialed DNID"},
402   {IAX_IE_AUTHMETHODS,     "Authentication method(s)"},
403   {IAX_IE_CHALLENGE,       "Challenge data for MD5/RSA"},
404   {IAX_IE_MD5_RESULT,      "MD5 challenge result"},
405   {IAX_IE_RSA_RESULT,      "RSA challenge result"},
406   {IAX_IE_APPARENT_ADDR,   "Apparent address of peer"},
407   {IAX_IE_REFRESH,         "When to refresh registration"},
408   {IAX_IE_DPSTATUS,        "Dialplan status"},
409   {IAX_IE_CALLNO,          "Call number of peer"},
410   {IAX_IE_CAUSE,           "Cause"},
411   {IAX_IE_IAX_UNKNOWN,     "Unknown IAX command"},
412   {IAX_IE_MSGCOUNT,        "How many messages waiting"},
413   {IAX_IE_AUTOANSWER,      "Request auto-answering"},
414   {IAX_IE_MUSICONHOLD,     "Request musiconhold with QUELCH"},
415   {IAX_IE_TRANSFERID,      "Transfer Request Identifier"},
416   {IAX_IE_RDNIS,           "Referring DNIS"},
417   {IAX_IE_PROVISIONING,    "Provisioning info"},
418   {IAX_IE_AESPROVISIONING, "AES Provisioning info"},
419   {IAX_IE_DATETIME,        "Date/Time"},
420   {IAX_IE_DEVICETYPE,      "Device type"},
421   {IAX_IE_SERVICEIDENT,    "Service Identifier"},
422   {IAX_IE_FIRMWAREVER,     "Firmware revision"},
423   {IAX_IE_FWBLOCKDESC,     "Firmware block description"},
424   {IAX_IE_FWBLOCKDATA,     "Firmware block of data"},
425   {IAX_IE_PROVVER,         "Provisioning version"},
426   {IAX_IE_CALLINGPRES,     "Calling presentation"},
427   {IAX_IE_CALLINGTON,      "Calling type of number"},
428   {IAX_IE_CALLINGTNS,      "Calling transit network select"},
429   {IAX_IE_SAMPLINGRATE,    "Supported sampling rates"},
430   {IAX_IE_CAUSECODE,       "Hangup cause"},
431   {IAX_IE_ENCRYPTION,      "Encryption format"},
432   {IAX_IE_ENCKEY,          "Raw encryption key"},
433   {IAX_IE_CODEC_PREFS,     "Codec preferences"},
434   {IAX_IE_RR_JITTER,       "Received jitter"},
435   {IAX_IE_RR_LOSS,         "Received loss"},
436   {IAX_IE_RR_PKTS,         "Received frames"},
437   {IAX_IE_RR_DELAY,        "Max playout delay in ms for received frames"},
438   {IAX_IE_RR_DROPPED,      "Dropped frames"},
439   {IAX_IE_RR_OOO,          "Frames received out of order"},
440   {IAX_IE_VARIABLE,        "IAX2 variable"},
441   {IAX_IE_OSPTOKEN,        "OSP Token"},
442   {IAX_IE_CALLTOKEN,       "Call Token"},
443   {IAX_IE_CAPABILITY2,     "64-bit codec capability"},
444   {IAX_IE_FORMAT2,         "64-bit codec format"},
445   {IAX_IE_DATAFORMAT,      "Data call format"},
446   {0, NULL}
447 };
448 static value_string_ext iax_ies_type_ext = VALUE_STRING_EXT_INIT(iax_ies_type);
449
450 static const value_string codec_types[] = {
451   {AST_FORMAT_G723_1,    "G.723.1 compression"},
452   {AST_FORMAT_GSM,       "GSM compression"},
453   {AST_FORMAT_ULAW,      "Raw mu-law data (G.711)"},
454   {AST_FORMAT_ALAW,      "Raw A-law data (G.711)"},
455   {AST_FORMAT_G726_AAL2, "ADPCM (G.726, 32kbps)"},
456   {AST_FORMAT_ADPCM,     "ADPCM (IMA)"},
457   {AST_FORMAT_SLINEAR,   "Raw 16-bit Signed Linear (8000 Hz) PCM"},
458   {AST_FORMAT_LPC10,     "LPC10, 180 samples/frame"},
459   {AST_FORMAT_G729A,     "G.729a Audio"},
460   {AST_FORMAT_SPEEX,     "SpeeX Free Compression"},
461   {AST_FORMAT_ILBC,      "iLBC Free Compression"},
462   {AST_FORMAT_G726,      "G.726 compression"},
463   {AST_FORMAT_G722,      "G.722 wideband"},
464   {AST_FORMAT_SIREN7,    "G.722.1 32k wideband (aka Siren7)"},
465   {AST_FORMAT_SIREN14,   "G.722.1 Annex C 48k wideband (aka Siren14)"},
466   {AST_FORMAT_SLINEAR16, "Raw 16kHz signed linear audio"},
467   {AST_FORMAT_JPEG,      "JPEG Images"},
468   {AST_FORMAT_PNG,       "PNG Images"},
469   {AST_FORMAT_H261,      "H.261 Video"},
470   {AST_FORMAT_H263,      "H.263 Video"},
471   {AST_FORMAT_H263_PLUS, "H.263+ Video"},
472   {AST_FORMAT_H264,      "H.264 Video"},
473   {AST_FORMAT_MP4_VIDEO, "MPEG4 Video"},
474   {0, NULL}
475 };
476 static value_string_ext codec_types_ext = VALUE_STRING_EXT_INIT(codec_types);
477
478 static const value_string iax_dataformats[] = {
479   {AST_DATAFORMAT_NULL,      "N/A (analogue call?)"},
480   {AST_DATAFORMAT_V110,      "ITU-T V.110 rate adaption"},
481   {AST_DATAFORMAT_H223_H245, "ITU-T H.223/H.245"},
482   {0, NULL}
483 };
484
485
486 static const value_string iax_packet_types[] = {
487   {IAX2_FULL_PACKET,       "Full packet"},
488   {IAX2_MINI_VOICE_PACKET, "Mini voice packet"},
489   {IAX2_MINI_VIDEO_PACKET, "Mini video packet"},
490   {IAX2_TRUNK_PACKET,      "Trunk packet"},
491   {0, NULL}
492 };
493
494 static const value_string iax_causecodes[] = {
495   {AST_CAUSE_UNALLOCATED,                   "Unallocated"},
496   {AST_CAUSE_NO_ROUTE_TRANSIT_NET,          "No route transit net"},
497   {AST_CAUSE_NO_ROUTE_DESTINATION,          "No route to destination"},
498   {AST_CAUSE_MISDIALLED_TRUNK_PREFIX,       "Misdialled trunk prefix"},
499   {AST_CAUSE_CHANNEL_UNACCEPTABLE,          "Channel unacceptable"},
500   {AST_CAUSE_CALL_AWARDED_DELIVERED,        "Call awarded delivered"},
501   {AST_CAUSE_PRE_EMPTED,                    "Preempted"},
502   {AST_CAUSE_NUMBER_PORTED_NOT_HERE,        "Number ported not here"},
503   {AST_CAUSE_NORMAL_CLEARING,               "Normal clearing"},
504   {AST_CAUSE_USER_BUSY,                     "User busy"},
505   {AST_CAUSE_NO_USER_RESPONSE,              "No user response"},
506   {AST_CAUSE_NO_ANSWER,                     "No answer"},
507   {AST_CAUSE_SUBSCRIBER_ABSENT,             "Subscriber absent"},
508   {AST_CAUSE_CALL_REJECTED,                 "Call rejected"},
509   {AST_CAUSE_NUMBER_CHANGED,                "Number changed"},
510   {AST_CAUSE_REDIRECTED_TO_NEW_DESTINATION, "Redirected to new destination"},
511   {AST_CAUSE_ANSWERED_ELSEWHERE,            "Answered elsewhere"},
512   {AST_CAUSE_DESTINATION_OUT_OF_ORDER,      "Destination out of order"},
513   {AST_CAUSE_INVALID_NUMBER_FORMAT,         "Invalid number format"},
514   {AST_CAUSE_FACILITY_REJECTED,             "Facility rejected"},
515   {AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY,    "Response to status inquiry"},
516   {AST_CAUSE_NORMAL_UNSPECIFIED,            "Normal unspecified"},
517   {AST_CAUSE_NORMAL_CIRCUIT_CONGESTION,     "Normal circuit congestion"},
518   {AST_CAUSE_NETWORK_OUT_OF_ORDER,          "Network out of order"},
519   {AST_CAUSE_NORMAL_TEMPORARY_FAILURE,      "Normal temporary failure"},
520   {AST_CAUSE_SWITCH_CONGESTION,             "Switch congestion"},
521   {AST_CAUSE_ACCESS_INFO_DISCARDED,         "Access info discarded"},
522   {AST_CAUSE_REQUESTED_CHAN_UNAVAIL,        "Requested channel unavailable"},
523   {AST_CAUSE_FACILITY_NOT_SUBSCRIBED,       "Facility not subscribed"},
524   {AST_CAUSE_OUTGOING_CALL_BARRED,          "Outgoing call barred"},
525   {AST_CAUSE_INCOMING_CALL_BARRED,          "Incoming call barred"},
526   {AST_CAUSE_BEARERCAPABILITY_NOTAUTH,      "Bearer capability not authorized"},
527   {AST_CAUSE_BEARERCAPABILITY_NOTAVAIL,     "Bearer capability not available"},
528   {AST_CAUSE_BEARERCAPABILITY_NOTIMPL,      "Bearer capability not implemented"},
529   {AST_CAUSE_CHAN_NOT_IMPLEMENTED,          "Channel not implemented"},
530   {AST_CAUSE_FACILITY_NOT_IMPLEMENTED,      "Facility not implemented"},
531   {AST_CAUSE_INVALID_CALL_REFERENCE,        "Invalid call reference"},
532   {AST_CAUSE_INCOMPATIBLE_DESTINATION,      "Incompatible destination"},
533   {AST_CAUSE_INVALID_MSG_UNSPECIFIED,       "Invalid message unspecified"},
534   {AST_CAUSE_MANDATORY_IE_MISSING,          "Mandatory IE missing"},
535   {AST_CAUSE_MESSAGE_TYPE_NONEXIST,         "Message type nonexistent"},
536   {AST_CAUSE_WRONG_MESSAGE,                 "Wrong message"},
537   {AST_CAUSE_IE_NONEXIST,                   "IE nonexistent"},
538   {AST_CAUSE_INVALID_IE_CONTENTS,           "Invalid IE contents"},
539   {AST_CAUSE_WRONG_CALL_STATE,              "Wrong call state"},
540   {AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE,      "Recovery on timer expire"},
541   {AST_CAUSE_MANDATORY_IE_LENGTH_ERROR,     "Mandatory IE length error"},
542   {AST_CAUSE_PROTOCOL_ERROR,                "Protocol error"},
543   {AST_CAUSE_INTERWORKING,                  "Interworking"},
544   {0, NULL}
545 };
546 static value_string_ext iax_causecodes_ext = VALUE_STRING_EXT_INIT(iax_causecodes);
547
548 /* ************************************************************************* */
549
550 /* In order to track IAX calls, we have a hash table which maps
551  * {addr,port type,port,call} to a unique circuit id.
552  *
553  * Each call has two such circuits associated with it (a forward and a
554  * reverse circuit, where 'forward' is defined as the direction the NEW
555  * packet went in), and we maintain an iax_call_data structure for each
556  * call, attached to both circuits with circuit_add_proto_data.
557  *
558  * Because {addr,port type,port,call} quadruplets can be reused
559  * (Asterisk reuses call numbers), circuit ids aren't unique to
560  * individual calls and we treat NEW packets somewhat specially. When we
561  * get such a packet, we see if there are any calls with a matching
562  * circuit id, and make sure that its circuits are marked as ended
563  * before that packet.
564  *
565  * A second complication is that we only know one quadruplet at the time
566  * the NEW packet is processed: there is therefore cunningness in
567  * iax_lookup_circuit_details() to look for replies to NEW packets and
568  * create the reverse circuit.
569  */
570
571
572 /* start with a hash of {addr,port type,port,call}->{id} */
573
574 typedef struct {
575   address   addr;
576   port_type ptype;
577   guint32   port;
578   guint32   callno;
579
580   /* this is where addr->data points to. it's put in here for easy freeing */
581   guint8 address_data[MAX_ADDRESS];
582 } iax_circuit_key;
583
584 /* tables */
585 static GHashTable *iax_fid_table       = NULL;
586 static reassembly_table iax_reassembly_table;
587
588 static GHashTable *iax_circuit_hashtab = NULL;
589 static guint circuitcount = 0;
590
591 /* the number of keys and values to reserve space for in each memory chunk.
592    We assume we won't be tracking many calls at once so this is quite low.
593 */
594 #define IAX_INIT_PACKET_COUNT 10
595
596 #ifdef DEBUG_HASHING
597 static gchar *key_to_str( const iax_circuit_key *key )
598 {
599   static int    i = 0;
600   static gchar *strp, str[3][80];
601
602   i++;
603   if (i >= 3) {
604     i = 0;
605   }
606   strp = str[i];
607
608   /* why doesn't ep_address_to_str take a const pointer?
609      cast the warnings into oblivion. */
610
611   /* XXX - is this a case for wmem_packet_scope()? */
612   g_snprintf(strp, 80, "{%s:%i,%i}",
613              ep_address_to_str((address *)&key->addr),
614              key->port,
615              key->callno);
616   return strp;
617 }
618 #endif
619
620 /* Hash Functions */
621 static gint iax_circuit_equal(gconstpointer v, gconstpointer w)
622 {
623   const iax_circuit_key *v1 = (const iax_circuit_key *)v;
624   const iax_circuit_key *v2 = (const iax_circuit_key *)w;
625   gint result;
626
627   result = (ADDRESSES_EQUAL(&(v1->addr), &(v2->addr)) &&
628             v1->ptype == v2->ptype &&
629             v1->port  == v2->port  &&
630             v1->callno== v2->callno);
631 #ifdef DEBUG_HASHING
632   g_debug("+++ Comparing for equality: %s, %s: %u", key_to_str(v1), key_to_str(v2), result);
633 #endif
634
635   return result;
636 }
637
638 static guint iax_circuit_hash(gconstpointer v)
639 {
640   const iax_circuit_key *key = (const iax_circuit_key *)v;
641   guint                  hash_val;
642
643   hash_val = 0;
644   ADD_ADDRESS_TO_HASH(hash_val, &key->addr);
645   hash_val += (guint)(key->ptype);
646   hash_val += (guint)(key->port);
647   hash_val += (guint)(key->callno);
648
649 #ifdef DEBUG_HASHING
650   g_debug("+++ Hashing key: %s, result %#x", key_to_str(key), hash_val);
651 #endif
652
653   return (guint)hash_val;
654 }
655
656 /* Find, or create, a circuit for the given
657    {address,porttype,port,call} quadruplet
658 */
659 static guint iax_circuit_lookup(const address *address_p,
660                                 port_type ptype,
661                                 guint32 port,
662                                 guint32 callno)
663 {
664   iax_circuit_key  key;
665   guint32         *circuit_id_p;
666
667   key.addr   = *address_p;
668   key.ptype  = ptype;
669   key.port   = port;
670   key.callno = callno;
671
672   circuit_id_p = (guint32 *)g_hash_table_lookup(iax_circuit_hashtab, &key);
673   if (! circuit_id_p) {
674     iax_circuit_key *new_key;
675
676     new_key = wmem_new(wmem_file_scope(), iax_circuit_key);
677     new_key->addr.type = address_p->type;
678     new_key->addr.len  = MIN(address_p->len, MAX_ADDRESS);
679     new_key->addr.data = new_key->address_data;
680     memcpy(new_key->address_data, address_p->data, new_key->addr.len);
681     new_key->ptype     = ptype;
682     new_key->port      = port;
683     new_key->callno    = callno;
684
685     circuit_id_p  = (guint32 *)wmem_new(wmem_file_scope(), iax_circuit_key);
686     *circuit_id_p = ++circuitcount;
687
688     g_hash_table_insert(iax_circuit_hashtab, new_key, circuit_id_p);
689
690 #ifdef DEBUG_HASHING
691     g_debug("Created new circuit id %u for node %s", *circuit_id_p, key_to_str(new_key));
692 #endif
693   }
694
695   return *circuit_id_p;
696 }
697
698
699 /* ************************************************************************* */
700
701 typedef struct {
702   guint32     current_frag_id; /* invalid unless current_frag_bytes > 0 */
703   guint32     current_frag_bytes;
704   guint32     current_frag_minlen;
705 } iax_call_dirdata;
706
707 /* This is our per-call data structure, which is attached to both the
708  * forward and reverse circuits.
709  */
710 typedef struct iax_call_data {
711   /* For this data, src and dst are relative to the original direction under
712      which this call is stored. Obviously if the reversed flag is set true by
713      iax_find_call, src and dst are reversed relative to the direction the
714      actual source and destination of the data.
715
716      if the codec changes mid-call, we update it here; because we store a codec
717      number with each packet too, we handle going back to earlier packets
718      without problem.
719   */
720
721   iax_dataformat_t dataformat;
722   guint32          src_codec, dst_codec;
723   guint32          src_vformat, dst_vformat;
724
725   /* when a transfer takes place, we'll get a new circuit id; we assume that we
726      don't try to transfer more than IAX_MAX_TRANSFERS times in a call */
727   guint forward_circuit_ids[IAX_MAX_TRANSFERS];
728   guint reverse_circuit_ids[IAX_MAX_TRANSFERS];
729   guint n_forward_circuit_ids;
730   guint n_reverse_circuit_ids;
731
732   /* this is the subdissector for the call */
733   dissector_handle_t subdissector;
734
735   /* the absolute start time of the call */
736   nstime_t start_time;
737
738   iax_call_dirdata dirdata[2];
739 } iax_call_data;
740
741 static void iax_init_hash( void )
742 {
743   if (iax_circuit_hashtab)
744     g_hash_table_destroy(iax_circuit_hashtab);
745   iax_circuit_hashtab = g_hash_table_new(iax_circuit_hash, iax_circuit_equal);
746   circuitcount = 0;
747
748   if (iax_fid_table)
749     g_hash_table_destroy(iax_fid_table);
750   iax_fid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
751
752   reassembly_table_init(&iax_reassembly_table,
753                         &addresses_reassembly_table_functions);
754 }
755
756
757
758 /* creates a new CT_IAX2 circuit with a specified circuit id for a call
759  *
760  * typically a call has up to three associated circuits: an original source, an
761  * original destination, and the result of a transfer.
762  *
763  * For each endpoint, a CT_IAX2 circuit is created and added to the call_data
764  * by this function
765  *
766  * 'reversed' should be true if this end is the one which would have _received_
767  * the NEW packet, or it is an endpoint to which the 'destination' is being
768  * transferred.
769  *
770  */
771 static circuit_t *iax2_new_circuit_for_call(packet_info *pinfo, proto_item * item,
772                                             guint circuit_id, guint framenum,
773                                             iax_call_data *iax_call, gboolean reversed)
774 {
775   circuit_t *res;
776
777   if(!iax_call){
778     return NULL;
779   }
780   if ((reversed && iax_call->n_reverse_circuit_ids >= IAX_MAX_TRANSFERS) ||
781       (! reversed && iax_call->n_forward_circuit_ids >= IAX_MAX_TRANSFERS)) {
782     expert_add_info(pinfo, item, &ei_iax_too_many_transfers);
783     return NULL;
784   }
785
786   res = circuit_new(CT_IAX2,
787                     circuit_id,
788                     framenum);
789
790   circuit_add_proto_data(res, proto_iax2, iax_call);
791
792   if (reversed)
793     iax_call -> reverse_circuit_ids[iax_call->n_reverse_circuit_ids++] = circuit_id;
794   else
795     iax_call -> forward_circuit_ids[iax_call->n_forward_circuit_ids++] = circuit_id;
796
797   return res;
798 }
799
800
801 /* returns true if this circuit id is a "forward" circuit for this call: ie, it
802  * is the point which _sent_ the original 'NEW' packet, or a point to which that
803  * end was subsequently transferred */
804 static gboolean is_forward_circuit(guint circuit_id,
805                                    const iax_call_data *iax_call)
806 {
807   guint i;
808   for(i=0; i<iax_call->n_forward_circuit_ids; i++) {
809     if (circuit_id == iax_call->forward_circuit_ids[i])
810       return TRUE;
811   }
812   return FALSE;
813 }
814
815 /* returns true if this circuit id is a "reverse" circuit for this call: ie, it
816  * is the point which _received_ the original 'NEW' packet, or a point to which that
817  * end was subsequently transferred */
818 static gboolean is_reverse_circuit(guint circuit_id,
819                                    const iax_call_data *iax_call)
820 {
821   guint i;
822   for(i=0; i<iax_call->n_reverse_circuit_ids; i++){
823     if (circuit_id == iax_call->reverse_circuit_ids[i])
824       return TRUE;
825   }
826   return FALSE;
827 }
828
829
830 static iax_call_data *iax_lookup_call_from_dest(packet_info *pinfo, proto_item * item,
831                                                  guint src_circuit_id,
832                                                  guint dst_circuit_id,
833                                                  guint framenum,
834                                                  gboolean *reversed_p)
835 {
836   circuit_t     *dst_circuit;
837   iax_call_data *iax_call;
838   gboolean       reversed = FALSE;
839
840   dst_circuit = find_circuit(CT_IAX2,
841                              dst_circuit_id,
842                              framenum);
843
844   if (!dst_circuit) {
845 #ifdef DEBUG_HASHING
846     g_debug("++ destination circuit not found, must have missed NEW packet");
847 #endif
848     if (reversed_p)
849       *reversed_p = FALSE;
850     return NULL;
851   }
852
853 #ifdef DEBUG_HASHING
854   g_debug("++ found destination circuit");
855 #endif
856
857   iax_call = (iax_call_data *)circuit_get_proto_data(dst_circuit, proto_iax2);
858
859   /* there's no way we can create a CT_IAX2 circuit without adding
860      iax call data to it; assert this */
861   DISSECTOR_ASSERT(iax_call);
862
863   if (is_forward_circuit(dst_circuit_id, iax_call)) {
864 #ifdef DEBUG_HASHING
865     g_debug("++ destination circuit matches forward_circuit_id of call, "
866              "therefore packet is reversed");
867 #endif
868
869     reversed = TRUE;
870
871     if (iax_call -> n_reverse_circuit_ids == 0) {
872       /* we are going in the reverse direction, and this call
873          doesn't have a reverse circuit associated with it.
874          create one now. */
875 #ifdef DEBUG_HASHING
876       g_debug("++ reverse_circuit_id of call is zero, need to create a "
877               "new reverse circuit for this call");
878 #endif
879
880       iax2_new_circuit_for_call(pinfo, item, src_circuit_id, framenum, iax_call, TRUE);
881 #ifdef DEBUG_HASHING
882       g_debug("++ done");
883 #endif
884     } else if (!is_reverse_circuit(src_circuit_id, iax_call)) {
885       expert_add_info_format(pinfo, item, &ei_iax_circuit_id_conflict,
886                 "IAX Packet %u from circuit ids %u->%u conflicts with earlier call with circuit ids %u->%u",
887                 framenum,
888                 src_circuit_id, dst_circuit_id,
889                 iax_call->forward_circuit_ids[0],
890                 iax_call->reverse_circuit_ids[0]);
891       return NULL;
892     }
893   } else if (is_reverse_circuit(dst_circuit_id, iax_call)) {
894 #ifdef DEBUG_HASHING
895     g_debug("++ destination circuit matches reverse_circuit_id of call, "
896             "therefore packet is forward");
897 #endif
898
899     reversed = FALSE;
900     if (!is_forward_circuit(src_circuit_id, iax_call)) {
901       expert_add_info_format(pinfo, item, &ei_iax_circuit_id_conflict,
902                 "IAX Packet %u from circuit ids %u->%u conflicts with earlier call with circuit ids %u->%u",
903                 framenum,
904                 src_circuit_id, dst_circuit_id,
905                 iax_call->forward_circuit_ids[0],
906                 iax_call->reverse_circuit_ids[0]);
907       if (reversed_p)
908         *reversed_p = FALSE;
909       return NULL;
910     }
911   } else {
912     DISSECTOR_ASSERT_NOT_REACHED();
913   }
914
915   if (reversed_p)
916     *reversed_p = reversed;
917
918   return iax_call;
919 }
920
921
922 /* looks up an iax_call for this packet */
923 static iax_call_data *iax_lookup_call( packet_info *pinfo,
924                                        guint32 scallno,
925                                        guint32 dcallno,
926                                        gboolean *reversed_p)
927 {
928   gboolean       reversed = FALSE;
929   iax_call_data *iax_call = NULL;
930   guint          src_circuit_id;
931
932 #ifdef DEBUG_HASHING
933   g_debug("++ iax_lookup_circuit_details: Looking up circuit for frame %u, "
934           "from {%s:%u:%u} to {%s:%u:%u}", pinfo->fd->num,
935           ep_address_to_str(&pinfo->src), pinfo->srcport, scallno,
936           ep_address_to_str(&pinfo->dst), pinfo->destport, dcallno);
937 #endif
938
939
940   src_circuit_id = iax_circuit_lookup(&pinfo->src, pinfo->ptype,
941                                       pinfo->srcport, scallno);
942
943
944   /* the most reliable indicator of call is the destination callno, if
945      we have one */
946   if (dcallno != 0) {
947     guint dst_circuit_id;
948 #ifdef DEBUG_HASHING
949     g_debug("++ dcallno non-zero, looking up destination circuit");
950 #endif
951
952     dst_circuit_id = iax_circuit_lookup(&pinfo->dst, pinfo->ptype,
953                                         pinfo->destport, dcallno);
954
955     iax_call = iax_lookup_call_from_dest(pinfo, NULL, src_circuit_id, dst_circuit_id,
956                                          pinfo->fd->num, &reversed);
957   } else {
958     circuit_t *src_circuit;
959
960     /* in all other circumstances, the source circuit should already
961      * exist: its absence indicates that we missed the all-important NEW
962      * packet.
963      */
964
965     src_circuit = find_circuit(CT_IAX2,
966                                src_circuit_id,
967                                pinfo->fd->num);
968
969     if (src_circuit) {
970       iax_call = (iax_call_data *)circuit_get_proto_data(src_circuit, proto_iax2);
971
972       /* there's no way we can create a CT_IAX2 circuit without adding
973          iax call data to it; assert this */
974       DISSECTOR_ASSERT(iax_call);
975
976       if (is_forward_circuit(src_circuit_id, iax_call))
977         reversed = FALSE;
978       else if (is_reverse_circuit(src_circuit_id, iax_call))
979         reversed = TRUE;
980       else {
981         /* there's also no way we can attach an iax_call_data to a circuit
982            without the circuit being either the forward or reverse circuit
983            for that call; assert this too.
984         */
985         DISSECTOR_ASSERT_NOT_REACHED();
986       }
987     }
988   }
989
990   if (reversed_p)
991     *reversed_p = reversed;
992
993 #ifdef DEBUG_HASHING
994   if (iax_call) {
995     g_debug("++ Found call for packet: id %u, reversed=%c", iax_call->forward_circuit_ids[0], reversed?'1':'0');
996   } else {
997     g_debug("++ Call not found. Must have missed the NEW packet?");
998   }
999 #endif
1000
1001   return iax_call;
1002 }
1003
1004 /* initialize the per-direction parts of an iax_call_data structure */
1005 static void init_dir_data(iax_call_dirdata *dirdata)
1006 {
1007   dirdata -> current_frag_bytes=0;
1008   dirdata -> current_frag_minlen=0;
1009 }
1010
1011
1012 /* handles a NEW packet by creating a new iax call and forward circuit.
1013    the reverse circuit is not created until the ACK is received and
1014    is created by iax_lookup_circuit_details. */
1015 static iax_call_data *iax_new_call( packet_info *pinfo,
1016                                     guint32 scallno)
1017 {
1018   iax_call_data         *call;
1019   guint                  circuit_id;
1020   static const nstime_t  millisecond = {0, 1000000};
1021
1022 #ifdef DEBUG_HASHING
1023   g_debug("+ new_circuit: Handling NEW packet, frame %u", pinfo->fd->num);
1024 #endif
1025
1026   circuit_id = iax_circuit_lookup(&pinfo->src, pinfo->ptype,
1027                                   pinfo->srcport, scallno);
1028
1029   call = wmem_new(wmem_file_scope(), iax_call_data);
1030   call -> dataformat = AST_DATAFORMAT_NULL;
1031   call -> src_codec = 0;
1032   call -> dst_codec = 0;
1033   call -> n_forward_circuit_ids = 0;
1034   call -> n_reverse_circuit_ids = 0;
1035   call -> subdissector = NULL;
1036   call -> start_time = pinfo->fd->abs_ts;
1037   nstime_delta(&call -> start_time, &call -> start_time, &millisecond);
1038   init_dir_data(&call->dirdata[0]);
1039   init_dir_data(&call->dirdata[1]);
1040
1041   iax2_new_circuit_for_call(pinfo, NULL, circuit_id, pinfo->fd->num, call, FALSE);
1042
1043   return call;
1044 }
1045
1046
1047 /* ************************************************************************* */
1048
1049 /* per-packet data */
1050 typedef struct iax_packet_data {
1051   gboolean       first_time; /* we're dissecting this packet for the first time; so
1052                               * things like codec and transfer requests should be
1053                               * propagated into the call data */
1054   iax_call_data *call_data;
1055   guint32        codec;
1056   gboolean       reversed;
1057   nstime_t       abstime;    /* the absolute time of this packet, based on its
1058                               * timestamp and the NEW packet's time (-1 if unknown) */
1059 } iax_packet_data;
1060
1061 static iax_packet_data *iax_new_packet_data(iax_call_data *call, gboolean reversed)
1062 {
1063   iax_packet_data *p = wmem_new(wmem_file_scope(), iax_packet_data);
1064   p->first_time    = TRUE;
1065   p->call_data     = call;
1066   p->codec         = 0;
1067   p->reversed      = reversed;
1068   p->abstime.secs  = -1;
1069   p->abstime.nsecs = -1;
1070   return p;
1071 }
1072
1073 static void  iax2_populate_pinfo_from_packet_data(packet_info *pinfo, const iax_packet_data *p)
1074 {
1075   /* info for subdissectors. We always pass on the original forward circuit,
1076    * and steal the p2p_dir flag to indicate the direction */
1077   if (p->call_data == NULL) {
1078      /* if we missed the NEW packet for this call, call_data will be null. it's
1079       * tbd what the best thing to do here is. */
1080     pinfo -> ctype = CT_NONE;
1081   } else {
1082     pinfo -> ctype = CT_IAX2;
1083     pinfo -> circuit_id = (guint32)p->call_data->forward_circuit_ids[0];
1084     pinfo -> p2p_dir = p->reversed?P2P_DIR_RECV:P2P_DIR_SENT;
1085
1086     col_set_str(pinfo->cinfo, COL_IF_DIR, p->reversed ? "rev" : "fwd");
1087   }
1088 }
1089
1090
1091 /* ************************************************************************* */
1092
1093 /* this is passed up from the IE dissector to the main dissector */
1094 typedef struct
1095 {
1096   address   peer_address;
1097   port_type peer_ptype;
1098   guint32   peer_port;
1099   guint32   peer_callno;
1100   guint32   dataformat;
1101 } iax2_ie_data;
1102
1103
1104 static guint32 dissect_fullpacket(tvbuff_t *tvb, guint32 offset,
1105                                   guint16 scallno,
1106                                   packet_info *pinfo,
1107                                   proto_tree *iax2_tree,
1108                                   proto_tree *main_tree);
1109
1110
1111 static guint32 dissect_minipacket(tvbuff_t *tvb, guint32 offset,
1112                                   guint16 scallno,
1113                                   packet_info *pinfo,
1114                                   proto_tree *iax2_tree,
1115                                   proto_tree *main_tree);
1116
1117 static guint32 dissect_minivideopacket(tvbuff_t *tvb, guint32 offset,
1118                                        guint16 scallno,
1119                                        packet_info *pinfo,
1120                                        proto_tree *iax2_tree,
1121                                        proto_tree *main_tree);
1122
1123 static guint32 dissect_trunkpacket(tvbuff_t *tvb, guint32 offset,
1124                                    guint16 scallno,
1125                                    packet_info *pinfo,
1126                                    proto_tree *iax2_tree,
1127                                    proto_tree *main_tree);
1128
1129 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
1130                             packet_info *pinfo, proto_tree *iax2_tree,
1131                             proto_tree *tree, guint32 ts, gboolean video,
1132                             iax_packet_data *iax_packet);
1133
1134
1135
1136 static void
1137 dissect_iax2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1138 {
1139   proto_item  *iax2_item;
1140   proto_tree  *iax2_tree;
1141   proto_tree  *full_mini_subtree = NULL;
1142   guint32      offset            = 0, len;
1143   guint16      scallno           = 0;
1144   guint16      stmp;
1145   packet_type  type;
1146   proto_item *full_mini_base;
1147
1148   /* set up the protocol and info fields in the summary pane */
1149   col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_IAX2);
1150   col_clear(pinfo->cinfo, COL_INFO);
1151
1152   /* add the 'iax2' tree to the main tree */
1153   iax2_item = proto_tree_add_item(tree, proto_iax2, tvb, offset, -1, ENC_NA);
1154   iax2_tree = proto_item_add_subtree(iax2_item, ett_iax2);
1155
1156   stmp = tvb_get_ntohs(tvb, offset);
1157   if (stmp == 0) {
1158     /* starting with 0x0000 indicates meta packet which can be either a mini
1159      * video packet or a trunk packet */
1160     offset+=2;
1161     stmp = tvb_get_ntohs(tvb, offset);
1162     if (stmp & 0x8000) {
1163       /* mini video packet */
1164       type = IAX2_MINI_VIDEO_PACKET;
1165       scallno = stmp & 0x7FFF;
1166       offset += 2;
1167     }
1168     else {
1169       type = IAX2_TRUNK_PACKET;
1170     }
1171   } else {
1172     /* The source call/fullpacket flag is common to both mini and full packets */
1173     scallno = tvb_get_ntohs(tvb, offset);
1174     offset += 2;
1175     if (scallno & 0x8000)
1176       type = IAX2_FULL_PACKET;
1177     else {
1178       type = IAX2_MINI_VOICE_PACKET;
1179     }
1180     scallno &= 0x7FFF;
1181   }
1182
1183   full_mini_base = proto_tree_add_uint(iax2_tree, hf_iax2_packet_type, tvb, 0, offset, type);
1184   full_mini_subtree = proto_item_add_subtree(full_mini_base, ett_iax2_full_mini_subtree);
1185
1186   if (scallno != 0)
1187     proto_tree_add_item(full_mini_subtree, hf_iax2_scallno, tvb, offset-2, 2, ENC_BIG_ENDIAN);
1188
1189   iax2_info->ptype = type;
1190   iax2_info->scallno = 0;
1191   iax2_info->dcallno = 0;
1192   iax2_info->ftype = 0;
1193   iax2_info->csub = 0;
1194   iax2_info->payload_len = 0;
1195   iax2_info->timestamp = 0;
1196   iax2_info->callState = VOIP_NO_STATE;
1197   iax2_info->messageName = NULL;
1198   iax2_info->callingParty = NULL;
1199   iax2_info->calledParty = NULL;
1200   iax2_info->payload_data = NULL;
1201
1202   switch (type) {
1203     case IAX2_FULL_PACKET:
1204       len = dissect_fullpacket(tvb, offset, scallno, pinfo, full_mini_subtree, tree);
1205       break;
1206     case IAX2_MINI_VOICE_PACKET:
1207       iax2_info->messageName = "MINI_VOICE_PACKET";
1208       len = dissect_minipacket(tvb, offset, scallno, pinfo, full_mini_subtree, tree);
1209       break;
1210     case IAX2_MINI_VIDEO_PACKET:
1211       iax2_info->messageName = "MINI_VIDEO_PACKET";
1212       len = dissect_minivideopacket(tvb, offset, scallno, pinfo, full_mini_subtree, tree);
1213       break;
1214     case IAX2_TRUNK_PACKET:
1215       iax2_info->messageName = "TRUNK_PACKET";
1216       len = dissect_trunkpacket(tvb, offset, scallno, pinfo, full_mini_subtree, tree);
1217       break;
1218     default:
1219       len = 0;
1220   }
1221
1222   /* update the 'length' of the main IAX2 header field so that it covers just the headers,
1223      not the audio data. */
1224   proto_item_set_len(iax2_item, len);
1225   tap_queue_packet(iax2_tap, pinfo, iax2_info);
1226 }
1227
1228 static proto_item *dissect_datetime_ie(tvbuff_t *tvb, guint32 offset, proto_tree *ies_tree)
1229 {
1230   struct tm tm;
1231   guint32   ie_val;
1232   nstime_t  datetime;
1233
1234   proto_tree_add_item(ies_tree, hf_iax2_ies[IAX_IE_DATETIME], tvb, offset + 2, 4, ENC_BIG_ENDIAN);
1235   ie_val = tvb_get_ntohl(tvb, offset+2);
1236
1237   /* who's crazy idea for a time encoding was this? */
1238   tm.tm_sec  = (ie_val       & 0x1f) << 1;
1239   tm.tm_min  = (ie_val>>5)   & 0x3f;
1240   tm.tm_hour = (ie_val>>11)  & 0x1f;
1241   tm.tm_mday = (ie_val>>16)  & 0x1f;
1242   tm.tm_mon  = ((ie_val>>21) & 0x0f) - 1;
1243   tm.tm_year = ((ie_val>>25) & 0x7f) + 100;
1244   tm.tm_isdst= -1; /* there's no info on whether DST was in force; assume it's
1245                     * the same as currently */
1246
1247   datetime.secs = mktime(&tm);
1248   datetime.nsecs = 0;
1249   return proto_tree_add_time(ies_tree, hf_iax2_ie_datetime, tvb, offset+2, 4, &datetime);
1250 }
1251
1252
1253 /* dissect the information elements in an IAX frame. Returns the updated offset */
1254 static guint32 dissect_ies(tvbuff_t *tvb, packet_info *pinfo, guint32 offset,
1255                            proto_tree *iax_tree, proto_item * iax_item,
1256                            iax2_ie_data *ie_data)
1257 {
1258   DISSECTOR_ASSERT(ie_data);
1259
1260   while (offset < tvb_reported_length(tvb)) {
1261
1262     int     ies_type = tvb_get_guint8(tvb, offset);
1263     int     ies_len  = tvb_get_guint8(tvb, offset + 1);
1264     guint16 apparent_addr_family;
1265
1266     /* do non-tree-dependent stuff first */
1267     switch (ies_type) {
1268       case IAX_IE_DATAFORMAT:
1269         if (ies_len != 4) THROW(ReportedBoundsError);
1270         ie_data -> dataformat = tvb_get_ntohl(tvb, offset+2);
1271         break;
1272
1273       case IAX_IE_CALLED_NUMBER:
1274         iax2_info->calledParty = wmem_strdup(wmem_packet_scope(), tvb_format_text(tvb, offset+2, ies_len));
1275         break;
1276       case IAX_IE_CALLING_NUMBER:
1277         iax2_info->callingParty = wmem_strdup(wmem_packet_scope(), tvb_format_text(tvb, offset+2, ies_len));
1278         break;
1279
1280       case IAX_IE_APPARENT_ADDR:
1281         /* The IAX2 I-D says that the "apparent address" structure
1282            "is the same as the linux struct sockaddr_in", without
1283            bothering to note that the address family field is in
1284            *host* byte order in that structure (the I-D seems to be
1285            assuming that "everything is a Vax^Wx86 or x86-64" with
1286            the address family field being little-endian).
1287
1288            This means the address family values are the Linux
1289            address family values. */
1290         apparent_addr_family = tvb_get_letohs(tvb, offset+2);
1291         switch (apparent_addr_family) {
1292           case LINUX_AF_INET:
1293             /* IAX is always over UDP */
1294             ie_data->peer_ptype = PT_UDP;
1295             ie_data->peer_port = tvb_get_ntohs(tvb, offset+4);
1296
1297             /* the ip address is big-endian, but then so is peer_address.data */
1298             TVB_SET_ADDRESS(&ie_data->peer_address, AT_IPv4, tvb, offset+6, 4);
1299             break;
1300
1301           default:
1302             expert_add_info_format(pinfo, iax_item, &ei_iax_peer_address_unsupported,
1303                 "Not supported in IAX dissector: peer address family of %u", apparent_addr_family);
1304             break;
1305         }
1306         break;
1307     }
1308
1309
1310     /* the rest of this stuff only needs doing if we have an iax_tree */
1311
1312     if (iax_tree && ies_type < NUM_HF_IAX2_IES) {
1313       proto_item *ti, *ie_item = NULL;
1314       proto_tree *ies_tree;
1315       int ie_hf = hf_iax2_ies[ies_type];
1316
1317       ti = proto_tree_add_text(iax_tree, tvb, offset, ies_len+2, " ");
1318
1319       ies_tree = proto_item_add_subtree(ti, ett_iax2_ie);
1320
1321       proto_tree_add_text(ies_tree, tvb, offset, 1, "IE id: %s (0x%02X)",
1322                           val_to_str_ext_const(ies_type, &iax_ies_type_ext, "Unknown"),
1323                           ies_type);
1324
1325       proto_tree_add_text(ies_tree, tvb, offset + 1, 1, "Length: %u", ies_len);
1326
1327
1328       /* hf_iax2_ies[] is an array, indexed by IE number, of header-fields, one
1329          per IE. Apart from a couple of special cases which require more
1330          complex decoding, we can just look up an entry from the array, and add
1331          the relevant item, although the encoding value used depends on the
1332          type of the item.
1333       */
1334
1335       switch (ies_type) {
1336         case IAX_IE_DATETIME:
1337           ie_item = dissect_datetime_ie(tvb, offset, ies_tree);
1338           break;
1339
1340
1341         case IAX_IE_CAPABILITY:
1342         {
1343           proto_tree *codec_tree;
1344
1345           if (ies_len != 4) THROW(ReportedBoundsError);
1346
1347           ie_item =
1348             proto_tree_add_item(ies_tree, ie_hf,
1349                                 tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1350           codec_tree =
1351             proto_item_add_subtree(ie_item, ett_iax2_codecs);
1352
1353           proto_tree_add_item(codec_tree, hf_iax2_cap_g723_1,    tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1354           proto_tree_add_item(codec_tree, hf_iax2_cap_gsm,       tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1355           proto_tree_add_item(codec_tree, hf_iax2_cap_ulaw,      tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1356           proto_tree_add_item(codec_tree, hf_iax2_cap_alaw,      tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1357           proto_tree_add_item(codec_tree, hf_iax2_cap_g726_aal2, tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1358           proto_tree_add_item(codec_tree, hf_iax2_cap_adpcm,     tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1359           proto_tree_add_item(codec_tree, hf_iax2_cap_slinear,   tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1360           proto_tree_add_item(codec_tree, hf_iax2_cap_lpc10,     tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1361           proto_tree_add_item(codec_tree, hf_iax2_cap_g729a,     tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1362           proto_tree_add_item(codec_tree, hf_iax2_cap_speex,     tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1363           proto_tree_add_item(codec_tree, hf_iax2_cap_ilbc,      tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1364           proto_tree_add_item(codec_tree, hf_iax2_cap_g726,      tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1365           proto_tree_add_item(codec_tree, hf_iax2_cap_g722,      tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1366           proto_tree_add_item(codec_tree, hf_iax2_cap_siren7,    tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1367           proto_tree_add_item(codec_tree, hf_iax2_cap_siren14,   tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1368           proto_tree_add_item(codec_tree, hf_iax2_cap_slinear16, tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1369           proto_tree_add_item(codec_tree, hf_iax2_cap_jpeg,      tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1370           proto_tree_add_item(codec_tree, hf_iax2_cap_png,       tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1371           proto_tree_add_item(codec_tree, hf_iax2_cap_h261,      tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1372           proto_tree_add_item(codec_tree, hf_iax2_cap_h263,      tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1373           proto_tree_add_item(codec_tree, hf_iax2_cap_h263_plus, tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1374           proto_tree_add_item(codec_tree, hf_iax2_cap_h264,      tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1375           proto_tree_add_item(codec_tree, hf_iax2_cap_mpeg4,     tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1376           break;
1377         }
1378
1379         case IAX_IE_APPARENT_ADDR:
1380         {
1381           proto_tree *sockaddr_tree = NULL;
1382
1383           ie_item = proto_tree_add_text(ies_tree, tvb, offset + 2, 16, "Apparent Address");
1384           sockaddr_tree = proto_item_add_subtree(ie_item, ett_iax2_ies_apparent_addr);
1385
1386           /* The IAX2 I-D says that the "apparent address" structure
1387              "is the same as the linux struct sockaddr_in", without
1388              bothering to note that the address family field is in
1389              *host* byte order in that structure (the I-D seems to be
1390              assuming that "everything is a Vax^Wx86 or x86-64" with
1391              the address family field being little-endian).
1392
1393              This means the address family values are the Linux
1394              address family values. */
1395           apparent_addr_family = tvb_get_letohs(tvb, offset+2);
1396           proto_tree_add_uint(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINFAMILY, tvb, offset + 2, 2, apparent_addr_family);
1397
1398           switch (apparent_addr_family) {
1399             case LINUX_AF_INET:
1400             {
1401               guint32 addr;
1402               proto_tree_add_uint(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINPORT, tvb, offset + 4, 2, ie_data->peer_port);
1403               memcpy(&addr, ie_data->peer_address.data, 4);
1404               proto_tree_add_ipv4(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINADDR, tvb, offset + 6, 4, addr);
1405               break;
1406             }
1407           }
1408           break;
1409         }
1410
1411         default:
1412           if (ie_hf != -1) {
1413             /* throw an error if the IE isn't the expected length */
1414             enum ftenum type = proto_registrar_get_nth(ie_hf)->type;
1415             gint explen = ftype_length(type);
1416             if (explen != 0 && ies_len != explen)
1417               THROW(ReportedBoundsError);
1418             switch (type) {
1419             case FT_UINT8:
1420             case FT_UINT16:
1421             case FT_UINT24:
1422             case FT_UINT32:
1423             case FT_UINT64:
1424             case FT_INT8:
1425             case FT_INT16:
1426             case FT_INT24:
1427             case FT_INT32:
1428             case FT_INT64:
1429             case FT_BOOLEAN:
1430             case FT_IPv4:
1431                 ie_item = proto_tree_add_item(ies_tree, ie_hf, tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1432                 break;
1433
1434             case FT_BYTES:
1435             case FT_NONE:
1436                 ie_item = proto_tree_add_item(ies_tree, ie_hf, tvb, offset + 2, ies_len, ENC_NA);
1437                 break;
1438
1439             case FT_STRING:
1440             case FT_STRINGZ:
1441                 ie_item = proto_tree_add_item(ies_tree, ie_hf, tvb, offset + 2, ies_len, ENC_UTF_8|ENC_NA);
1442                 break;
1443
1444             default:
1445                 DISSECTOR_ASSERT_NOT_REACHED();
1446                 break;
1447             }
1448           } else {
1449             /* we don't understand this ie: add a generic one */
1450             guint32       value;
1451             const guint8 *ptr;
1452             const gchar  *ie_name = val_to_str_ext_const(ies_type, &iax_ies_type_ext, "Unknown");
1453
1454             switch (ies_len) {
1455               case 1:
1456                 value = tvb_get_guint8(tvb, offset + 2);
1457                 ie_item =
1458                   proto_tree_add_uint_format(ies_tree, hf_IAX_IE_UNKNOWN_BYTE,
1459                                              tvb, offset+2, 1, value,
1460                                              "%s: %#02x", ie_name, value);
1461                 break;
1462
1463               case 2:
1464                 value = tvb_get_ntohs(tvb, offset + 2);
1465                 ie_item =
1466                   proto_tree_add_uint_format(ies_tree, hf_IAX_IE_UNKNOWN_I16,
1467                                              tvb, offset+2, 2, value,
1468                                              "%s: %#04x", ie_name, value);
1469                 break;
1470
1471               case 4:
1472                 value = tvb_get_ntohl(tvb, offset + 2);
1473                 ie_item =
1474                   proto_tree_add_uint_format(ies_tree, hf_IAX_IE_UNKNOWN_I32,
1475                                              tvb, offset+2, 4, value,
1476                                              "%s: %#08x", ie_name, value);
1477                 break;
1478
1479               default:
1480                 ptr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 2, ies_len, ENC_ASCII);
1481                 ie_item =
1482                   proto_tree_add_string_format(ies_tree, hf_IAX_IE_UNKNOWN_BYTES,
1483                                                tvb, offset+2, ies_len, ptr,
1484                                                "%s: %s", ie_name, ptr);
1485                 break;
1486             }
1487           }
1488           break;
1489       }
1490
1491       /* by now, we *really* ought to have added an item */
1492       DISSECTOR_ASSERT(ie_item != NULL);
1493
1494       /* Retrieve the text from the item we added, and append it to the main IE
1495        * item */
1496       if (!PROTO_ITEM_IS_HIDDEN(ti)) {
1497         field_info *ie_finfo = PITEM_FINFO(ie_item);
1498
1499         /* if the representation of the item has already been set, use that;
1500            else we have to allocate a block to put the text into */
1501         if (ie_finfo && ie_finfo->rep != NULL)
1502           proto_item_set_text(ti, "Information Element: %s",
1503                               ie_finfo->rep->representation);
1504         else {
1505           guint8 *ie_val = NULL;
1506           ie_val = (guint8 *)wmem_alloc(wmem_packet_scope(), ITEM_LABEL_LENGTH);
1507           proto_item_fill_label(ie_finfo, ie_val);
1508           proto_item_set_text(ti, "Information Element: %s",
1509                               ie_val);
1510         }
1511       }
1512     }
1513
1514     offset += ies_len + 2;
1515   }
1516   return offset;
1517 }
1518
1519 static guint32 uncompress_subclass(guint8 csub)
1520 {
1521   /* If the SC_LOG flag is set, return 2^csub otherwise csub */
1522   if (csub & 0x80) {
1523     /* special case for 'compressed' -1 */
1524     if (csub == 0xff)
1525       return (guint32)-1;
1526     else
1527       return 1 << (csub & 0x1F);
1528   }
1529   else
1530     return (guint32)csub;
1531 }
1532
1533 /* returns the new offset */
1534 static guint32 dissect_iax2_command(tvbuff_t *tvb, guint32 offset,
1535                                     packet_info *pinfo, proto_tree *tree,
1536                                     iax_packet_data *iax_packet)
1537 {
1538   guint8         csub = tvb_get_guint8(tvb, offset);
1539   guint8         address_data[MAX_ADDRESS];
1540   proto_item*    ti;
1541   iax2_ie_data   ie_data;
1542   iax_call_data *iax_call;
1543
1544   ie_data.peer_address.type = AT_NONE;
1545   ie_data.peer_address.len  = 0;
1546   ie_data.peer_address.data = address_data;
1547   ie_data.peer_ptype        = PT_NONE;
1548   ie_data.peer_port         = 0;
1549   ie_data.peer_callno       = 0;
1550   ie_data.dataformat        = (guint32)-1;
1551   iax_call                  = iax_packet -> call_data;
1552
1553   /* add the subclass */
1554   ti = proto_tree_add_uint(tree, hf_iax2_iax_csub, tvb, offset, 1, csub);
1555   offset++;
1556
1557   col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1558                      val_to_str_ext(csub, &iax_iax_subclasses_ext, "unknown (0x%02x)"));
1559
1560   if (offset >= tvb_reported_length(tvb))
1561     return offset;
1562
1563   offset = dissect_ies(tvb, pinfo, offset, tree, ti, &ie_data);
1564
1565   /* if this is a data call, set up a subdissector for the circuit */
1566   if (iax_call && ie_data.dataformat != (guint32)-1 && iax_call -> subdissector == NULL) {
1567     iax_call -> subdissector = dissector_get_uint_handle(iax2_dataformat_dissector_table, ie_data.dataformat);
1568     iax_call -> dataformat = (iax_dataformat_t)ie_data.dataformat;
1569   }
1570
1571   /* if this is a transfer request, record it in the call data */
1572   if (csub == IAX_COMMAND_TXREQ && iax_packet -> first_time) {
1573     if (ie_data.peer_address.type != AT_NONE && ie_data.peer_callno != 0) {
1574       guint tx_circuit = iax_circuit_lookup(&ie_data.peer_address,
1575                                             ie_data.peer_ptype,
1576                                             ie_data.peer_port,
1577                                             ie_data.peer_callno);
1578
1579       iax2_new_circuit_for_call(pinfo, NULL, tx_circuit, pinfo->fd->num, iax_call, iax_packet->reversed);
1580     }
1581   }
1582
1583   return offset;
1584 }
1585
1586 static void iax2_add_ts_fields(packet_info *pinfo, proto_tree *iax2_tree, iax_packet_data *iax_packet, guint16 shortts)
1587 {
1588   guint32     longts =shortts;
1589   nstime_t    ts;
1590   proto_item *item;
1591
1592   if (iax_packet->call_data == NULL) {
1593     /* no call info for this frame; perhaps we missed the NEW packet */
1594     return;
1595   }
1596
1597   if (iax_packet->abstime.secs == -1) {
1598     time_t start_secs = iax_packet->call_data->start_time.secs;
1599     gint32 abs_secs = (gint32)(start_secs + longts/1000);
1600
1601     /* deal with short timestamps by assuming that packets are never more than
1602      * 16 seconds late */
1603     while(abs_secs < pinfo->fd->abs_ts.secs - 16) {
1604       longts += 32768;
1605       abs_secs = (gint32)(start_secs + longts/1000);
1606     }
1607
1608     iax_packet->abstime.secs=abs_secs;
1609     iax_packet->abstime.nsecs=iax_packet->call_data->start_time.nsecs + (longts % 1000) * 1000000;
1610     if (iax_packet->abstime.nsecs >= 1000000000) {
1611       iax_packet->abstime.nsecs -= 1000000000;
1612       iax_packet->abstime.secs ++;
1613     }
1614   }
1615   iax2_info->timestamp = longts;
1616
1617   if (iax2_tree) {
1618     item = proto_tree_add_time(iax2_tree, hf_iax2_absts, NULL, 0, 0, &iax_packet->abstime);
1619     PROTO_ITEM_SET_GENERATED(item);
1620
1621     ts  = pinfo->fd->abs_ts;
1622     nstime_delta(&ts, &ts, &iax_packet->abstime);
1623
1624     item = proto_tree_add_time(iax2_tree, hf_iax2_lateness, NULL, 0, 0, &ts);
1625     PROTO_ITEM_SET_GENERATED(item);
1626   }
1627 }
1628
1629 /* returns the new offset */
1630 static guint32
1631 dissect_fullpacket(tvbuff_t *tvb, guint32 offset,
1632                    guint16 scallno,
1633                    packet_info *pinfo, proto_tree *iax2_tree,
1634                    proto_tree *main_tree)
1635 {
1636   guint16 dcallno;
1637   guint32 ts;
1638   guint8  type;
1639   guint8  csub;
1640   guint32 codec;
1641
1642   proto_tree      *packet_type_tree = NULL;
1643   iax_call_data   *iax_call;
1644   iax_packet_data *iax_packet;
1645   gboolean         reversed;
1646   gboolean         rtp_marker;
1647
1648   /*
1649    * remove the top bit for retransmission detection
1650    */
1651   dcallno = tvb_get_ntohs(tvb, offset) & 0x7FFF;
1652   ts = tvb_get_ntohl(tvb, offset + 2);
1653   type = tvb_get_guint8(tvb, offset + 8);
1654   csub = tvb_get_guint8(tvb, offset + 9);
1655   iax2_info->ftype   = type;
1656   iax2_info->csub    = csub;
1657   iax2_info->scallno = scallno;
1658   iax2_info->dcallno = dcallno;
1659
1660   /* see if we've seen this packet before */
1661   iax_packet = (iax_packet_data *)p_get_proto_data(wmem_file_scope(), pinfo, proto_iax2, 0);
1662   if (!iax_packet) {
1663     /* if not, find or create an iax_call info structure for this IAX session. */
1664
1665     if (type == AST_FRAME_IAX && csub == IAX_COMMAND_NEW) {
1666       /* NEW packets start a new call */
1667       iax_call = iax_new_call(pinfo, scallno);
1668       reversed = FALSE;
1669     } else {
1670       iax_call = iax_lookup_call(pinfo, scallno, dcallno,
1671                                  &reversed);
1672     }
1673
1674     iax_packet = iax_new_packet_data(iax_call, reversed);
1675     p_add_proto_data(wmem_file_scope(), pinfo, proto_iax2, 0, iax_packet);
1676   } else {
1677     iax_call = iax_packet->call_data;
1678     reversed = iax_packet->reversed;
1679   }
1680
1681   iax2_populate_pinfo_from_packet_data(pinfo, iax_packet);
1682
1683   if (iax2_tree) {
1684       proto_item *packet_type_base;
1685
1686       proto_tree_add_item(iax2_tree, hf_iax2_dcallno, tvb, offset, 2, ENC_BIG_ENDIAN);
1687
1688       proto_tree_add_item(iax2_tree, hf_iax2_retransmission, tvb, offset, 2, ENC_BIG_ENDIAN);
1689
1690       if (iax_call) {
1691         proto_item *item =
1692           proto_tree_add_uint(iax2_tree, hf_iax2_callno, tvb, 0, 4,
1693                               iax_call->forward_circuit_ids[0]);
1694         PROTO_ITEM_SET_GENERATED(item);
1695       }
1696
1697       proto_tree_add_uint(iax2_tree, hf_iax2_ts, tvb, offset+2, 4, ts);
1698       iax2_add_ts_fields(pinfo, iax2_tree, iax_packet, (guint16)ts);
1699
1700       proto_tree_add_item(iax2_tree, hf_iax2_oseqno, tvb, offset+6, 1,
1701                           ENC_BIG_ENDIAN);
1702
1703       proto_tree_add_item(iax2_tree, hf_iax2_iseqno, tvb, offset+7, 1,
1704                           ENC_BIG_ENDIAN);
1705       packet_type_base = proto_tree_add_uint(iax2_tree, hf_iax2_type, tvb,
1706                                              offset+8, 1, type);
1707
1708       /* add the type-specific subtree */
1709       packet_type_tree = proto_item_add_subtree(packet_type_base, ett_iax2_type);
1710   } else {
1711     iax2_add_ts_fields(pinfo, iax2_tree, iax_packet, (guint16)ts);
1712   }
1713
1714
1715   /* add frame type to info line */
1716   col_add_fstr(pinfo->cinfo, COL_INFO, "%s, source call# %d, timestamp %ums",
1717                  val_to_str_ext(type, &iax_frame_types_ext, "Unknown (0x%02x)"),
1718                  scallno, ts);
1719
1720   iax2_info->messageName = val_to_str_ext(type, &iax_frame_types_ext, "Unknown (0x%02x)");
1721
1722   switch (type) {
1723   case AST_FRAME_IAX:
1724     offset=dissect_iax2_command(tvb, offset+9, pinfo, packet_type_tree, iax_packet);
1725     iax2_info->messageName = val_to_str_ext(csub, &iax_iax_subclasses_ext, "unknown (0x%02x)");
1726     if (csub < NUM_TAP_IAX_VOIP_STATES) iax2_info->callState = tap_iax_voip_state[csub];
1727     break;
1728
1729   case AST_FRAME_DTMF_BEGIN:
1730   case AST_FRAME_DTMF_END:
1731     proto_tree_add_item(packet_type_tree, hf_iax2_dtmf_csub, tvb, offset+9, 1, ENC_ASCII|ENC_NA);
1732     offset += 10;
1733
1734     col_append_fstr(pinfo->cinfo, COL_INFO, " digit %c", csub);
1735     break;
1736
1737   case AST_FRAME_CONTROL:
1738     /* add the subclass */
1739     proto_tree_add_uint(packet_type_tree, hf_iax2_cmd_csub, tvb,
1740                          offset+9, 1, csub);
1741     offset += 10;
1742
1743     col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1744                       val_to_str_ext(csub, &iax_cmd_subclasses_ext, "unknown (0x%02x)"));
1745     iax2_info->messageName = val_to_str_ext (csub, &iax_cmd_subclasses_ext, "unknown (0x%02x)");
1746     if (csub < NUM_TAP_CMD_VOIP_STATES) iax2_info->callState = tap_cmd_voip_state[csub];
1747     break;
1748
1749   case AST_FRAME_VOICE:
1750     /* add the codec */
1751     iax_packet -> codec = codec = uncompress_subclass(csub);
1752
1753     if (packet_type_tree) {
1754       proto_item *item;
1755       proto_tree_add_item(packet_type_tree, hf_iax2_voice_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1756       item = proto_tree_add_uint(packet_type_tree, hf_iax2_voice_codec, tvb, offset+9, 1, codec);
1757       PROTO_ITEM_SET_GENERATED(item);
1758     }
1759
1760     offset += 10;
1761
1762     if (iax_call) {
1763       if (reversed) {
1764         iax_call->dst_codec = codec;
1765       } else {
1766         iax_call->src_codec = codec;
1767       }
1768     }
1769
1770     dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, FALSE, iax_packet);
1771     break;
1772
1773   case AST_FRAME_VIDEO:
1774     /* bit 6 of the csub is used to represent the rtp 'marker' bit */
1775     rtp_marker = csub & 0x40 ? TRUE:FALSE;
1776     iax_packet -> codec = codec = uncompress_subclass((guint8)(csub & ~40));
1777
1778     if (packet_type_tree) {
1779       proto_item *item;
1780       proto_tree_add_item(packet_type_tree, hf_iax2_video_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1781       proto_tree_add_item(packet_type_tree, hf_iax2_marker, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1782       item = proto_tree_add_uint(packet_type_tree, hf_iax2_video_codec, tvb, offset+9, 1, codec);
1783       PROTO_ITEM_SET_GENERATED(item);
1784     }
1785
1786     offset += 10;
1787
1788     if (iax_call && iax_packet -> first_time) {
1789       if (reversed) {
1790         iax_call->dst_vformat = codec;
1791       } else {
1792         iax_call->src_vformat = codec;
1793       }
1794     }
1795
1796     if (rtp_marker)
1797       col_append_str(pinfo->cinfo, COL_INFO, ", Mark");
1798
1799
1800     dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, TRUE, iax_packet);
1801     break;
1802
1803   case AST_FRAME_MODEM:
1804     proto_tree_add_item(packet_type_tree, hf_iax2_modem_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1805     offset += 10;
1806
1807     col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1808                       val_to_str(csub, iax_modem_subclasses, "unknown (0x%02x)"));
1809     break;
1810
1811   case AST_FRAME_TEXT:
1812     proto_tree_add_item(packet_type_tree, hf_iax2_text_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1813     offset += 10;
1814
1815     {
1816       int textlen = tvb_captured_length_remaining(tvb, offset);
1817       if (textlen > 0)
1818       {
1819         proto_tree_add_item(packet_type_tree, hf_iax2_text_text, tvb, offset, textlen, ENC_UTF_8|ENC_NA);
1820         offset += textlen;
1821       }
1822     }
1823     break;
1824
1825   case AST_FRAME_HTML:
1826     proto_tree_add_item(packet_type_tree, hf_iax2_html_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1827     offset += 10;
1828
1829     if (csub == 0x01)
1830     {
1831       int urllen = tvb_captured_length_remaining(tvb, offset);
1832       if (urllen > 0)
1833       {
1834         proto_item *pi = proto_tree_add_item(packet_type_tree, hf_iax2_html_url, tvb, offset, urllen, ENC_UTF_8|ENC_NA);
1835         PROTO_ITEM_SET_URL(pi);
1836         offset += urllen;
1837       }
1838     }
1839     break;
1840
1841   case AST_FRAME_CNG:
1842   default:
1843     proto_tree_add_uint(packet_type_tree, hf_iax2_csub, tvb, offset+9,
1844                         1, csub);
1845     offset += 10;
1846
1847     col_append_fstr(pinfo->cinfo, COL_INFO, " subclass %d", csub);
1848     break;
1849   }
1850
1851   /* next time we come to parse this packet, don't propagate the codec into the
1852    * call_data */
1853   iax_packet->first_time = FALSE;
1854
1855   return offset;
1856 }
1857
1858 static iax_packet_data *iax2_get_packet_data_for_minipacket(packet_info *pinfo,
1859                                                             guint16 scallno,
1860                                                             gboolean video)
1861 {
1862   /* see if we've seen this packet before */
1863   iax_packet_data *p = (iax_packet_data *)p_get_proto_data(wmem_file_scope(), pinfo, proto_iax2, 0);
1864
1865   if (!p) {
1866     /* if not, find or create an iax_call info structure for this IAX session. */
1867     gboolean reversed;
1868     iax_call_data *iax_call;
1869
1870     iax_call = iax_lookup_call(pinfo, scallno, 0, &reversed);
1871
1872     p = iax_new_packet_data(iax_call, reversed);
1873     p_add_proto_data(wmem_file_scope(), pinfo, proto_iax2, 0, p);
1874
1875     /* set the codec for this frame to be whatever the last full frame used */
1876     if (iax_call) {
1877      if (video)
1878         p->codec = reversed ? iax_call -> dst_vformat : iax_call -> src_vformat;
1879       else
1880         p->codec = reversed ? iax_call -> dst_codec : iax_call -> src_codec;
1881     }
1882   }
1883
1884   iax2_populate_pinfo_from_packet_data(pinfo, p);
1885   return p;
1886 }
1887
1888
1889 static guint32 dissect_minivideopacket(tvbuff_t *tvb, guint32 offset,
1890                                        guint16 scallno, packet_info *pinfo,
1891                                        proto_tree *iax2_tree, proto_tree *main_tree)
1892 {
1893   guint32          ts;
1894   iax_packet_data *iax_packet;
1895   gboolean         rtp_marker;
1896   proto_item      *item;
1897
1898   ts = tvb_get_ntohs(tvb, offset);
1899
1900   /* bit 15 of the ts is used to represent the rtp 'marker' bit */
1901   rtp_marker = ts & 0x8000 ? TRUE:FALSE;
1902   ts &= ~0x8000;
1903
1904   iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, TRUE);
1905
1906   if (iax2_tree) {
1907     if (iax_packet->call_data) {
1908       item =
1909         proto_tree_add_uint(iax2_tree, hf_iax2_callno, tvb, 0, 4,
1910                             iax_packet->call_data->forward_circuit_ids[0]);
1911       PROTO_ITEM_SET_GENERATED(item);
1912     }
1913
1914     proto_tree_add_item(iax2_tree, hf_iax2_minividts, tvb, offset, 2, ENC_BIG_ENDIAN);
1915     iax2_add_ts_fields(pinfo, iax2_tree, iax_packet, (guint16)ts);
1916     proto_tree_add_item(iax2_tree, hf_iax2_minividmarker, tvb, offset, 2, ENC_BIG_ENDIAN);
1917   } else {
1918     iax2_add_ts_fields(pinfo, iax2_tree, iax_packet, (guint16)ts);
1919   }
1920
1921   offset += 2;
1922
1923   col_add_fstr(pinfo->cinfo, COL_INFO,
1924                    "Mini video packet, source call# %d, timestamp %ums%s",
1925                    scallno, ts, rtp_marker?", Mark":"");
1926
1927
1928   dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, TRUE, iax_packet);
1929
1930   /* next time we come to parse this packet, don't propagate the codec into the
1931    * call_data */
1932   iax_packet->first_time = FALSE;
1933
1934   return offset;
1935 }
1936
1937 static guint32 dissect_minipacket(tvbuff_t *tvb, guint32 offset, guint16 scallno,
1938                                   packet_info *pinfo, proto_tree *iax2_tree,
1939                                   proto_tree *main_tree)
1940 {
1941   guint32          ts;
1942   iax_packet_data *iax_packet;
1943   proto_item      *item;
1944
1945   ts = tvb_get_ntohs(tvb, offset);
1946
1947   iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, FALSE);
1948
1949   if (iax2_tree) {
1950     if (iax_packet->call_data) {
1951       item = proto_tree_add_uint(iax2_tree, hf_iax2_callno, tvb, 0, 4,
1952                                  iax_packet->call_data->forward_circuit_ids[0]);
1953       PROTO_ITEM_SET_GENERATED(item);
1954     }
1955
1956     proto_tree_add_uint(iax2_tree, hf_iax2_minits, tvb, offset, 2, ts);
1957     iax2_add_ts_fields(pinfo, iax2_tree, iax_packet, (guint16)ts);
1958   } else {
1959     iax2_add_ts_fields(pinfo, iax2_tree, iax_packet, (guint16)ts);
1960   }
1961
1962
1963   offset += 2;
1964
1965   col_add_fstr(pinfo->cinfo, COL_INFO,
1966                     "Mini packet, source call# %d, timestamp %ums",
1967                     scallno, ts);
1968
1969
1970   /* XXX fix the timestamp logic */
1971   dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, FALSE, iax_packet);
1972
1973
1974   /* next time we come to parse this packet, don't propagate the codec into the
1975    * call_data */
1976   iax_packet->first_time = FALSE;
1977
1978   return offset;
1979 }
1980
1981
1982 static guint32 dissect_trunkcall_ts(tvbuff_t *tvb, guint32 offset, proto_tree *iax2_tree, guint16 *scallno)
1983 {
1984   proto_item *call_item;
1985   proto_tree *call_tree;
1986   guint16     datalen, rlen, ts;
1987   /*
1988    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1989    |     Data Length (in octets)   |R|     Source Call Number      |
1990    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1991    |           time-stamp          |                               |
1992    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
1993    |                                       Data                    |
1994    :                                                               :
1995    |                                                               |
1996    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1997    */
1998   datalen = tvb_get_ntohs(tvb, offset);
1999   *scallno = tvb_get_ntohs(tvb, offset + 2);
2000   ts = tvb_get_ntohs(tvb, offset + 4);
2001
2002   rlen = MIN(tvb_length(tvb) - offset - 6, datalen);
2003
2004   if (iax2_tree) {
2005     call_item = proto_tree_add_text(iax2_tree, tvb, offset, rlen + 6, "Trunk call from %u, ts: %u", *scallno, ts);
2006     call_tree = proto_item_add_subtree(call_item, ett_iax2_trunk_call);
2007
2008     proto_tree_add_item(call_tree, hf_iax2_trunk_call_len, tvb, offset, 2, ENC_BIG_ENDIAN);
2009     proto_tree_add_item(call_tree, hf_iax2_trunk_call_scallno, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2010     proto_tree_add_item(call_tree, hf_iax2_trunk_call_ts, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
2011     proto_tree_add_item(call_tree, hf_iax2_trunk_call_data, tvb, offset + 6, rlen, ENC_NA);
2012   }
2013   offset += 6 + rlen;
2014
2015   return offset;
2016 }
2017
2018 static guint32 dissect_trunkcall_nots(tvbuff_t *tvb, guint32 offset, proto_tree *iax2_tree, guint16 *scallno)
2019 {
2020   proto_item *call_item;
2021   proto_tree *call_tree;
2022   guint16     datalen, rlen;
2023   /*
2024    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2025    |R|      Source Call Number     |     Data Length (in octets)   |
2026    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2027    |                                                               |
2028    :                             Data                              :
2029    |                                                               |
2030    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2031    */
2032   *scallno = tvb_get_ntohs(tvb, offset);
2033   datalen = tvb_get_ntohs(tvb, offset + 2);
2034
2035   rlen = MIN(tvb_length(tvb) - offset - 4, datalen);
2036
2037   if (iax2_tree) {
2038     call_item = proto_tree_add_text(iax2_tree, tvb, offset, rlen + 6, "Trunk call from %u", *scallno);
2039     call_tree = proto_item_add_subtree(call_item, ett_iax2_trunk_call);
2040
2041     proto_tree_add_item(call_tree, hf_iax2_trunk_call_scallno, tvb, offset, 2, ENC_BIG_ENDIAN);
2042     proto_tree_add_item(call_tree, hf_iax2_trunk_call_len, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2043     proto_tree_add_item(call_tree, hf_iax2_trunk_call_data, tvb, offset + 4, rlen, ENC_NA);
2044   }
2045   offset += 4 + rlen;
2046
2047   return offset;
2048 }
2049
2050 typedef struct _call_list {
2051   guint16            scallno;
2052   struct _call_list *next;
2053 } call_list;
2054
2055 static call_list *call_list_append(call_list *list, guint16 scallno)
2056 {
2057   call_list *node = wmem_new0(wmem_packet_scope(), call_list);
2058
2059   node->scallno = scallno;
2060
2061   if (list) {
2062     call_list *cur = list;
2063     while (cur->next) {
2064       cur = cur->next;
2065     }
2066     cur->next = node;
2067     return list;
2068   } else {
2069     return node;
2070   }
2071 }
2072
2073 static gboolean call_list_find(call_list *list, guint16 scallno)
2074 {
2075   for (; list; list = list->next) {
2076     if (list->scallno == scallno) {
2077       return TRUE;
2078     }
2079   }
2080   return FALSE;
2081 }
2082
2083 static guint call_list_length(call_list *list)
2084 {
2085   guint count = 0;
2086   for (; list; list = list->next) {
2087     count++;
2088   }
2089   return count;
2090 }
2091
2092 static guint32 dissect_trunkpacket(tvbuff_t *tvb, guint32 offset,
2093                                    guint16 scallno_param _U_, packet_info *pinfo,
2094                                    proto_tree *iax2_tree, proto_tree *main_tree _U_)
2095 {
2096   guint8      cmddata, trunkts;
2097   guint       nframes    = 0, ncalls = 0;
2098   proto_item *cd, *nc    = NULL;
2099   proto_tree *field_tree = NULL;
2100   call_list  *calls      = NULL;
2101   /*iax_packet_data *iax_packet;*/
2102
2103   cmddata = tvb_get_guint8(tvb, offset + 1);
2104   trunkts = cmddata & IAX2_TRUNK_TS;
2105
2106   /* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1   */
2107   /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
2108   /* |F|         Meta Indicator      |V|Meta Command | Cmd Data (0)  | */
2109   /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
2110   /* |                            time-stamp                         | */
2111   /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
2112
2113   if (iax2_tree) {
2114     /* Meta Command */
2115     proto_tree_add_item(iax2_tree, hf_iax2_trunk_metacmd, tvb, offset, 1, ENC_BIG_ENDIAN);
2116
2117     /* Command data */
2118     cd = proto_tree_add_uint(iax2_tree, hf_iax2_trunk_cmddata, tvb, offset + 1, 1, cmddata);
2119     field_tree = proto_item_add_subtree(cd, ett_iax2_trunk_cmddata);
2120     if (trunkts)
2121       proto_item_append_text(cd, " (trunk timestamps)");
2122
2123     /* CD -> Trunk timestamp */
2124     proto_tree_add_boolean(field_tree, hf_iax2_trunk_cmddata_ts, tvb, offset + 1, 1, cmddata);
2125
2126     /* Timestamp */
2127     proto_tree_add_item(iax2_tree, hf_iax2_trunk_ts, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
2128   }
2129
2130   offset += 6;
2131
2132   if (trunkts) {
2133     /* Trunk calls with timestamp */
2134     while(tvb_length_remaining(tvb, offset) >= 6) {
2135       guint16 scallno;
2136       offset = dissect_trunkcall_ts(tvb, offset, iax2_tree, &scallno);
2137       if (!call_list_find(calls, scallno)) {
2138         calls = call_list_append(calls, scallno);
2139       }
2140       nframes++;
2141     }
2142   }
2143   else {
2144     /* Trunk calls without timestamp */
2145     while(tvb_length_remaining(tvb, offset) >= 4) {
2146       guint16 scallno;
2147       offset = dissect_trunkcall_nots(tvb, offset, iax2_tree, &scallno);
2148       if (!call_list_find(calls, scallno)) {
2149         calls = call_list_append(calls, scallno);
2150       }
2151       nframes++;
2152     }
2153   }
2154
2155   ncalls = call_list_length(calls);
2156
2157   if (iax2_tree) {
2158     /* number of items */
2159     nc = proto_tree_add_uint(iax2_tree, hf_iax2_trunk_ncalls, NULL, 0, 0, ncalls);
2160     PROTO_ITEM_SET_GENERATED(nc);
2161   }
2162
2163   col_add_fstr(pinfo->cinfo, COL_INFO, "Trunk packet with %d media frame%s for %d call%s",
2164                nframes, plurality(nframes, "", "s"),
2165                ncalls, plurality(ncalls, "", "s"));
2166
2167   return offset;
2168 }
2169
2170
2171 static void process_iax_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2172                               gboolean video, iax_packet_data *iax_packet)
2173 {
2174   guint32        codec    = iax_packet -> codec;
2175   iax_call_data *iax_call = iax_packet -> call_data;
2176
2177 #ifdef DEBUG_DESEGMENT
2178   g_debug("calling process_iax_pdu; len = %u", tvb_reported_length(tvb));
2179 #endif
2180
2181   if (!video && iax_call && iax_call->subdissector) {
2182     call_dissector(iax_call->subdissector, tvb, pinfo, tree);
2183   } else if (codec != 0 && dissector_try_uint(iax2_codec_dissector_table, codec, tvb, pinfo, tree)) {
2184     /* codec dissector handled our data */
2185   } else {
2186     /* we don't know how to dissect our data: dissect it as data */
2187     call_dissector(data_handle, tvb, pinfo, tree);
2188   }
2189
2190 #ifdef DEBUG_DESEGMENT
2191   g_debug("called process_iax_pdu; pinfo->desegment_len=%u; pinfo->desegment_offset=%u",
2192             pinfo->desegment_len, pinfo->desegment_offset);
2193 #endif
2194 }
2195
2196 static void desegment_iax(tvbuff_t *tvb, packet_info *pinfo, proto_tree *iax2_tree,
2197                           proto_tree *tree, gboolean video, iax_packet_data *iax_packet)
2198 {
2199
2200   iax_call_data    *iax_call       = iax_packet -> call_data;
2201   iax_call_dirdata *dirdata;
2202   gpointer          value          = NULL;
2203   guint32           frag_offset    = 0;
2204   fragment_head    *fd_head;
2205   gboolean          must_desegment = FALSE;
2206
2207   DISSECTOR_ASSERT(iax_call);
2208
2209   pinfo->can_desegment    = 2;
2210   pinfo->desegment_offset = 0;
2211   pinfo->desegment_len    = 0;
2212
2213 #ifdef DEBUG_DESEGMENT
2214   g_debug("dissecting packet %u", pinfo->fd->num);
2215 #endif
2216
2217   dirdata = &(iax_call->dirdata[!!(iax_packet->reversed)]);
2218
2219   if ((!pinfo->fd->flags.visited && (dirdata->current_frag_bytes > 0)) ||
2220      ((value = g_hash_table_lookup(iax_fid_table, GUINT_TO_POINTER(pinfo->fd->num))) != NULL)) {
2221
2222     /* then we are continuing an already-started pdu */
2223     guint32 fid;
2224     guint32 frag_len = tvb_reported_length(tvb);
2225     gboolean complete;
2226
2227 #ifdef DEBUG_DESEGMENT
2228     g_debug("visited: %i; c_f_b: %u; hash: %u->%u", pinfo->fd->flags.visited?1:0,
2229             dirdata->current_frag_bytes, pinfo->fd->num, dirdata->current_frag_id);
2230 #endif
2231
2232     if (!pinfo->fd->flags.visited) {
2233       guint32 tot_len;
2234       fid = dirdata->current_frag_id;
2235       tot_len                      = dirdata->current_frag_minlen;
2236       DISSECTOR_ASSERT(g_hash_table_lookup(iax_fid_table, GUINT_TO_POINTER(pinfo->fd->num)) == NULL);
2237       g_hash_table_insert(iax_fid_table, GUINT_TO_POINTER(pinfo->fd->num), GUINT_TO_POINTER(fid));
2238       frag_offset                  = dirdata->current_frag_bytes;
2239       dirdata->current_frag_bytes += frag_len;
2240       complete                     = dirdata->current_frag_bytes > tot_len;
2241 #ifdef DEBUG_DESEGMENT
2242       g_debug("hash: %u->%u; frag_offset: %u; c_f_b: %u; totlen: %u",
2243               pinfo->fd->num, fid, frag_offset, dirdata->current_frag_bytes, tot_len);
2244 #endif
2245     } else {
2246       fid = GPOINTER_TO_UINT(value);
2247       /* these values are unused by fragment_add if pinfo->fd->flags.visited */
2248       dirdata->current_frag_bytes = 0;
2249       complete = FALSE;
2250     }
2251
2252     /* fragment_add checks for already-added */
2253     fd_head = fragment_add(&iax_reassembly_table, tvb, 0, pinfo, fid, NULL,
2254                            frag_offset,
2255                            frag_len, !complete);
2256
2257     if (fd_head && (pinfo->fd->num == fd_head->reassembled_in)) {
2258       gint32 old_len;
2259       tvbuff_t *next_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
2260       add_new_data_source(pinfo, next_tvb, "Reassembled IAX2");
2261
2262       process_iax_pdu(next_tvb, pinfo, tree, video, iax_packet);
2263
2264       /* calculate the amount of data which was available to the higher-level
2265          dissector before we added this segment; if the returned offset is
2266          within that section, the higher-level dissector was unable to find any
2267          pdus; if it's after that, it found one or more complete PDUs.
2268       */
2269       old_len = (gint32)(tvb_reported_length(next_tvb) - frag_len);
2270       if (pinfo->desegment_len &&
2271           (pinfo->desegment_offset < old_len)) {
2272         /* oops, it wasn't actually complete */
2273         fragment_set_partial_reassembly(&iax_reassembly_table, pinfo, fid, NULL);
2274         if (pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
2275           /* only one more byte should be enough for a retry */
2276           dirdata->current_frag_minlen = fd_head->datalen + 1;
2277         } else {
2278           dirdata->current_frag_minlen = fd_head->datalen + pinfo->desegment_len;
2279         }
2280       } else {
2281         /* we successfully dissected some data; create the proto tree items for
2282          * the fragments, and flag any remaining data for desegmentation */
2283
2284         proto_item *iax_tree_item, *frag_tree_item;
2285         /* this nargery is to insert the fragment tree into the main tree
2286          * between the IAX protocol entry and the subdissector entry */
2287         show_fragment_tree(fd_head, &iax2_fragment_items, tree, pinfo, next_tvb, &frag_tree_item);
2288         iax_tree_item = proto_item_get_parent(proto_tree_get_parent(iax2_tree));
2289         if (frag_tree_item && iax_tree_item)
2290           proto_tree_move_item(tree, iax_tree_item, frag_tree_item);
2291
2292         dirdata->current_frag_minlen = dirdata->current_frag_id = dirdata->current_frag_bytes = 0;
2293
2294         if (pinfo->desegment_len) {
2295           /* there's a bit of data left to desegment */
2296           must_desegment = TRUE;
2297           /* make desegment_offset relative to our tvb */
2298           pinfo->desegment_offset -= old_len;
2299         }
2300
2301         /* don't add a 'reassembled in' item for this pdu */
2302         fd_head = NULL;
2303       }
2304     }
2305   } else {
2306     /* This segment was not found in our table, so it doesn't
2307        contain a continuation of a higher-level PDU.
2308        Call the normal subdissector.
2309     */
2310
2311     process_iax_pdu(tvb, pinfo, tree, video, iax_packet);
2312
2313     if (pinfo->desegment_len) {
2314       /* the higher-level dissector has asked for some more data - ie,
2315          the end of this segment does not coincide with the end of a
2316          higher-level PDU. */
2317       must_desegment = TRUE;
2318     }
2319
2320     fd_head = NULL;
2321   }
2322
2323   /* must_desegment is set if the end of this segment (or the whole of it)
2324    * contained the start of a higher-level PDU; we must add whatever is left of
2325    * this segment (after pinfo->desegment_offset) to a fragment table for disassembly. */
2326   if (must_desegment) {
2327     guint32 fid = pinfo->fd->num; /* a new fragment id */
2328     guint32 deseg_offset = pinfo->desegment_offset;
2329     guint32 frag_len = tvb_reported_length_remaining(tvb, deseg_offset);
2330     dirdata->current_frag_id = fid;
2331     dirdata->current_frag_bytes = frag_len;
2332
2333     if (pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
2334       /* only one more byte should be enough for a retry */
2335       dirdata->current_frag_minlen = frag_len + 1;
2336     } else {
2337       dirdata->current_frag_minlen = frag_len + pinfo->desegment_len;
2338     }
2339
2340     fd_head = fragment_add(&iax_reassembly_table,
2341                            tvb, deseg_offset, pinfo, fid, NULL,
2342                            0, frag_len, TRUE);
2343 #ifdef DEBUG_DESEGMENT
2344     g_debug("Start offset of undissected bytes: %u; "
2345             "Bytes remaining in this segment: %u; min required bytes: %u\n",
2346             deseg_offset, frag_len, frag_len + pinfo->desegment_len);
2347 #endif
2348   }
2349
2350   /* add a 'reassembled in' item if necessary */
2351   if (fd_head != NULL) {
2352     guint32 deseg_offset = pinfo->desegment_offset;
2353     if (fd_head->reassembled_in != 0 &&
2354         !(fd_head->flags & FD_PARTIAL_REASSEMBLY)) {
2355       proto_item *iax_tree_item;
2356       iax_tree_item = proto_tree_add_uint(tree, hf_iax2_reassembled_in,
2357                                           tvb, deseg_offset, tvb_reported_length_remaining(tvb, deseg_offset),
2358                                           fd_head->reassembled_in);
2359       PROTO_ITEM_SET_GENERATED(iax_tree_item);
2360     } else {
2361       /* this fragment is never reassembled */
2362       proto_tree_add_text(tree, tvb, deseg_offset, -1,
2363                           "IAX2 fragment, unfinished");
2364     }
2365
2366     if (pinfo->desegment_offset == 0) {
2367       col_set_str(pinfo->cinfo, COL_PROTOCOL, "IAX2");
2368       col_set_str(pinfo->cinfo, COL_INFO, "[IAX2 segment of a reassembled PDU]");
2369     }
2370   }
2371
2372   pinfo->can_desegment = 0;
2373   pinfo->desegment_offset = 0;
2374   pinfo->desegment_len = 0;
2375 }
2376
2377 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
2378                             packet_info *pinfo, proto_tree *iax2_tree,
2379                             proto_tree *tree, guint32 ts _U_, gboolean video,
2380                             iax_packet_data *iax_packet)
2381 {
2382 #if 0
2383   gboolean       out_of_order = FALSE;
2384 #endif
2385   tvbuff_t      *sub_tvb;
2386   guint32        codec        = iax_packet -> codec;
2387   guint32        nbytes;
2388   iax_call_data *iax_call     = iax_packet -> call_data;
2389
2390   if (offset >= tvb_reported_length(tvb)) {
2391     col_append_str(pinfo->cinfo, COL_INFO, ", empty frame");
2392     return;
2393   }
2394
2395   sub_tvb = tvb_new_subset_remaining(tvb, offset);
2396
2397   /* XXX shouldn't pass through out-of-order packets. */
2398
2399   if (!video && iax_call && iax_call -> dataformat != 0) {
2400       col_append_fstr(pinfo->cinfo, COL_INFO, ", data, format %s",
2401                       val_to_str(iax_call -> dataformat,
2402                                  iax_dataformats, "unknown (0x%02x)"));
2403 #if 0
2404       if (out_of_order)
2405         col_append_str(pinfo->cinfo, COL_INFO, " (out-of-order packet)");
2406 #endif
2407   } else {
2408       col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
2409                       val_to_str_ext(codec, &codec_types_ext, "unknown (0x%02x)"));
2410   }
2411
2412   nbytes = tvb_reported_length(sub_tvb);
2413   proto_tree_add_text(iax2_tree, sub_tvb, 0, -1,
2414                       "IAX2 payload (%u byte%s)", nbytes,
2415                       plurality(nbytes, "", "s"));
2416
2417   iax2_info->payload_len = nbytes;
2418   iax2_info->payload_data = tvb_get_ptr(sub_tvb, 0, -1);
2419
2420   /* pass the rest of the block to a subdissector */
2421   if (iax_packet->call_data)
2422     desegment_iax(sub_tvb, pinfo, iax2_tree, tree, video, iax_packet);
2423   else
2424     process_iax_pdu(sub_tvb, pinfo, tree, video, iax_packet);
2425 }
2426
2427 /*
2428  * Init routines
2429  */
2430
2431 /* called at the start of a capture. We should clear out our static, per-capture
2432  * data.
2433  */
2434
2435 static void
2436 iax_init_protocol(void)
2437 {
2438   iax_init_hash();
2439 }
2440
2441
2442 void
2443 proto_register_iax2(void)
2444 {
2445   /* A header field is something you can search/filter on.
2446    *
2447    * We create a structure to register our fields. It consists of an
2448    * array of hf_register_info structures, each of which are of the format
2449    * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
2450    */
2451
2452   static hf_register_info hf[] = {
2453
2454     {&hf_iax2_packet_type,
2455      {"Packet type", "iax2.packet_type",
2456       FT_UINT8, BASE_DEC, VALS(iax_packet_types), 0,
2457       "Full/minivoice/minivideo/trunk packet",
2458       HFILL}},
2459
2460     {&hf_iax2_callno,
2461      {"Call identifier", "iax2.call",
2462       FT_UINT32, BASE_DEC, NULL, 0,
2463       "This is the identifier Wireshark assigns to identify this call."
2464       " It does not correspond to any real field in the protocol",
2465       HFILL }},
2466
2467     {&hf_iax2_scallno,
2468      {"Source call", "iax2.src_call",
2469       FT_UINT16, BASE_DEC, NULL, 0x7FFF,
2470       "src_call holds the number of this call at the packet source pbx",
2471       HFILL}},
2472
2473     /* FIXME could this be turned into a FRAMENUM field? */
2474     {&hf_iax2_dcallno,
2475      {"Destination call", "iax2.dst_call",
2476       FT_UINT16, BASE_DEC, NULL, 0x7FFF,
2477       "dst_call holds the number of this call at the packet destination",
2478       HFILL}},
2479
2480     {&hf_iax2_retransmission,
2481      {"Retransmission", "iax2.retransmission",
2482       FT_BOOLEAN, 16, NULL, 0x8000,
2483       "retransmission is set if this packet is a retransmission of an earlier failed packet",
2484       HFILL}},
2485
2486     {&hf_iax2_ts,
2487      {"Timestamp", "iax2.timestamp",
2488       FT_UINT32, BASE_DEC, NULL, 0x0,
2489       "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2490       HFILL}},
2491
2492     {&hf_iax2_minits,
2493      {"Timestamp", "iax2.timestamp",
2494       FT_UINT16, BASE_DEC, NULL, 0x0,
2495       "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2496       HFILL}},
2497
2498     {&hf_iax2_minividts,
2499      {"Timestamp", "iax2.timestamp",
2500       FT_UINT16, BASE_DEC, NULL, 0x7FFF,
2501       "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2502       HFILL}},
2503
2504     {&hf_iax2_absts,
2505      {"Absolute Time", "iax2.abstime",
2506       FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
2507       "The absolute time of this packet (calculated by adding the IAX timestamp to  the start time of this call)",
2508       HFILL}},
2509
2510     {&hf_iax2_lateness,
2511      {"Lateness", "iax2.lateness",
2512       FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2513       "The lateness of this packet compared to its timestamp",
2514       HFILL}},
2515
2516     {&hf_iax2_minividmarker,
2517      {"Marker", "iax2.video.marker",
2518       FT_UINT16, BASE_DEC, NULL, 0x8000,
2519       "RTP end-of-frame marker",
2520       HFILL}},
2521
2522     {&hf_iax2_oseqno,
2523      {"Outbound seq.no.", "iax2.oseqno",
2524       FT_UINT16, BASE_DEC, NULL, 0x0,
2525       "oseqno is the sequence no of this packet. The first packet has oseqno==0,"
2526       " and subsequent packets increment the oseqno by 1",
2527       HFILL}},
2528
2529     {&hf_iax2_iseqno,
2530      {"Inbound seq.no.", "iax2.iseqno",
2531       FT_UINT16, BASE_DEC, NULL, 0x0,
2532       "iseqno is the sequence no of the last successfully received packet",
2533       HFILL}},
2534
2535     {&hf_iax2_type,
2536      {"Type", "iax2.type",
2537       FT_UINT8, BASE_DEC | BASE_EXT_STRING, &iax_frame_types_ext, 0x0,
2538       "For full IAX2 frames, type is the type of frame",
2539       HFILL}},
2540
2541     {&hf_iax2_csub,
2542      {"Unknown subclass", "iax2.subclass",
2543       FT_UINT8, BASE_DEC, NULL, 0x0,
2544       "Subclass of unknown type of full IAX2 frame",
2545       HFILL}},
2546
2547     {&hf_iax2_dtmf_csub,
2548      {"DTMF subclass (digit)", "iax2.dtmf.subclass",
2549       FT_STRINGZ, BASE_NONE, NULL, 0x0,
2550       "DTMF subclass gives the DTMF digit",
2551       HFILL}},
2552
2553     {&hf_iax2_cmd_csub,
2554      {"Control subclass", "iax2.control.subclass",
2555       FT_UINT8, BASE_DEC | BASE_EXT_STRING, &iax_cmd_subclasses_ext, 0x0,
2556       "This gives the command number for a Control packet.",
2557       HFILL}},
2558
2559     {&hf_iax2_iax_csub,
2560      {"IAX subclass", "iax2.iax.subclass",
2561       FT_UINT8, BASE_DEC | BASE_EXT_STRING, &iax_iax_subclasses_ext, 0x0,
2562       "IAX subclass gives the command number for IAX signaling packets",
2563       HFILL}},
2564
2565     {&hf_iax2_voice_csub,
2566      {"Voice Subclass (compressed codec no)", "iax2.voice.subclass",
2567       FT_UINT8, BASE_DEC, NULL, 0x0,
2568       NULL, HFILL}},
2569
2570     {&hf_iax2_voice_codec,
2571      {"CODEC", "iax2.voice.codec",
2572       FT_UINT32, BASE_HEX | BASE_EXT_STRING, &codec_types_ext, 0x0,
2573       "CODEC gives the codec used to encode audio data",
2574       HFILL}},
2575
2576     {&hf_iax2_video_csub,
2577      {"Video Subclass (compressed codec no)", "iax2.video.subclass",
2578       FT_UINT8, BASE_DEC, NULL, 0xBF,
2579       NULL, HFILL}},
2580
2581     {&hf_iax2_marker,
2582      {"Marker", "iax2.video.marker",
2583       FT_BOOLEAN, 8, NULL, 0x40,
2584       "RTP end-of-frame marker",
2585       HFILL}},
2586
2587     {&hf_iax2_video_codec,
2588      {"CODEC", "iax2.video.codec",
2589       FT_UINT32, BASE_HEX | BASE_EXT_STRING, &codec_types_ext, 0,
2590       "The codec used to encode video data",
2591       HFILL}},
2592
2593     {&hf_iax2_modem_csub,
2594      {"Modem subclass", "iax2.modem.subclass",
2595       FT_UINT8, BASE_DEC, VALS(iax_modem_subclasses), 0x0,
2596       "Modem subclass gives the type of modem",
2597       HFILL}},
2598
2599     {&hf_iax2_text_csub,
2600      {"Text subclass", "iax2.text.subclass",
2601       FT_UINT8, BASE_DEC, VALS(iax_text_subclasses), 0x0,
2602       NULL,
2603       HFILL}},
2604
2605     {&hf_iax2_text_text,
2606      {"Text", "iax2.text.text",
2607       FT_STRING, BASE_NONE, NULL, 0x0,
2608       NULL,
2609       HFILL}},
2610
2611     {&hf_iax2_html_csub,
2612      {"HTML subclass", "iax2.html.subclass",
2613       FT_UINT8, BASE_DEC, VALS(iax_html_subclasses), 0x0,
2614       NULL,
2615       HFILL}},
2616
2617     {&hf_iax2_html_url,
2618      {"HTML URL", "iax2.html.url",
2619       FT_STRING, BASE_NONE, NULL, 0x0,
2620       NULL,
2621       HFILL}},
2622
2623     {&hf_iax2_trunk_ts,
2624      {"Timestamp", "iax2.timestamp",
2625       FT_UINT32, BASE_DEC, NULL, 0x0,
2626       "timestamp is the time, in ms after the start of Command data this call,"
2627       " at which this trunk packet was transmitted",
2628       HFILL}},
2629
2630     {&hf_iax2_trunk_metacmd,
2631      {"Meta command", "iax2.trunk.metacmd",
2632       FT_UINT8, BASE_DEC, NULL, 0x7F,
2633       "Meta command indicates whether or not the Meta Frame is a trunk.",
2634       HFILL}},
2635
2636     {&hf_iax2_trunk_cmddata,
2637      {"Command data", "iax2.trunk.cmddata",
2638       FT_UINT8, BASE_HEX, NULL, 0x0,
2639       "Flags for options that apply to a trunked call",
2640       HFILL}},
2641
2642     {&hf_iax2_trunk_cmddata_ts,
2643      {"Trunk timestamps", "iax2.trunk.cmddata.ts",
2644       FT_BOOLEAN, 8, NULL, IAX2_TRUNK_TS,
2645       "True: calls do each include their own timestamp",
2646       HFILL}},
2647
2648     {&hf_iax2_trunk_call_len,
2649      {"Data length", "iax2.trunk.call.len",
2650       FT_UINT16, BASE_DEC, NULL, 0x0,
2651       "Trunk call data length in octets",
2652       HFILL}},
2653
2654     {&hf_iax2_trunk_call_scallno,
2655      {"Source call number", "iax2.trunk.call.scallno",
2656       FT_UINT16, BASE_DEC, NULL, 0x7FFF,
2657       "Trunk call source call number",
2658       HFILL}},
2659
2660     {&hf_iax2_trunk_call_ts,
2661      {"Timestamp", "iax2.trunk.call.ts",
2662       FT_UINT16, BASE_DEC, NULL, 0x0,
2663       "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2664       HFILL}},
2665
2666     {&hf_iax2_trunk_call_data,
2667      {"Data", "iax2.trunk.call.payload",
2668       FT_BYTES, BASE_NONE, NULL, 0x0,
2669       "Payload carried by this trunked packet.",
2670       HFILL}},
2671
2672     {&hf_iax2_trunk_ncalls,
2673      {"Number of calls", "iax2.trunk.ncalls",
2674       FT_UINT16, BASE_DEC, NULL, 0x0,
2675       "Number of calls in this trunk packet",
2676       HFILL}},
2677
2678     /*
2679      * Decoding for the ies
2680      */
2681
2682     {&hf_IAX_IE_APPARENTADDR_SINFAMILY,
2683      {"Family", "iax2.iax.app_addr.sinfamily",
2684       FT_UINT16, BASE_DEC, NULL, 0,
2685       NULL, HFILL }},
2686
2687     {&hf_IAX_IE_APPARENTADDR_SINPORT,
2688      {"Port", "iax2.iax.app_addr.sinport",
2689       FT_UINT16, BASE_DEC, NULL, 0,
2690       NULL, HFILL }},
2691
2692     {&hf_IAX_IE_APPARENTADDR_SINADDR,
2693      {"Address", "iax2.iax.app_addr.sinaddr",
2694       FT_IPv4, BASE_NONE, NULL, 0,
2695       NULL, HFILL }},
2696
2697     {&hf_iax2_ies[IAX_IE_CALLED_NUMBER],
2698      {"Number/extension being called", "iax2.iax.called_number",
2699       FT_STRING,
2700       BASE_NONE, NULL, 0x0, NULL, HFILL}},
2701
2702     {&hf_iax2_ies[IAX_IE_CALLING_NUMBER],
2703      {"Calling number", "iax2.iax.calling_number",
2704       FT_STRING, BASE_NONE, NULL, 0x0,
2705       NULL, HFILL}},
2706
2707
2708     {&hf_iax2_ies[IAX_IE_CALLING_ANI],
2709      {"Calling number ANI for billing", "iax2.iax.calling_ani",
2710       FT_STRING, BASE_NONE, NULL, 0x0,
2711       NULL, HFILL}},
2712
2713     {&hf_iax2_ies[IAX_IE_CALLING_NAME],
2714      {"Name of caller", "iax2.iax.calling_name",
2715       FT_STRING, BASE_NONE, NULL, 0x0,
2716       NULL, HFILL}},
2717
2718     {&hf_iax2_ies[IAX_IE_CALLED_CONTEXT],
2719      {"Context for number", "iax2.iax.called_context",
2720       FT_STRING, BASE_NONE, NULL, 0x0,
2721       NULL, HFILL}},
2722
2723     {&hf_iax2_ies[IAX_IE_USERNAME],
2724      {"Username (peer or user) for authentication", "iax2.iax.username",
2725       FT_STRING, BASE_NONE, NULL, 0x0,
2726       NULL, HFILL}},
2727
2728     {&hf_iax2_ies[IAX_IE_PASSWORD],
2729      {"Password for authentication", "iax2.iax.password",
2730       FT_STRING, BASE_NONE, NULL, 0x0,
2731       NULL, HFILL}},
2732
2733     {&hf_iax2_ies[IAX_IE_CAPABILITY],
2734      {"Actual codec capability", "iax2.iax.capability",
2735       FT_UINT32, BASE_HEX, NULL, 0x0,
2736       NULL, HFILL}},
2737
2738     {&hf_iax2_ies[IAX_IE_FORMAT],
2739      {"Desired codec format", "iax2.iax.format",
2740       FT_UINT32, BASE_HEX | BASE_EXT_STRING, &codec_types_ext, 0x0,
2741       NULL, HFILL}},
2742
2743     {&hf_iax2_ies[IAX_IE_LANGUAGE],
2744      {"Desired language", "iax2.iax.language",
2745       FT_STRING, BASE_NONE, NULL, 0x0,
2746       NULL, HFILL}},
2747
2748     {&hf_iax2_ies[IAX_IE_VERSION],
2749      {"Protocol version", "iax2.iax.version",
2750       FT_UINT16, BASE_HEX, NULL, 0x0,
2751       NULL, HFILL}},
2752
2753     {&hf_iax2_ies[IAX_IE_ADSICPE],
2754      {"CPE ADSI capability", "iax2.iax.cpe_adsi",
2755       FT_UINT16, BASE_HEX, NULL, 0x0,
2756       NULL, HFILL}},
2757
2758     {&hf_iax2_ies[IAX_IE_DNID],
2759      {"Originally dialed DNID", "iax2.iax.dnid",
2760       FT_STRING, BASE_NONE, NULL, 0x0,
2761       NULL, HFILL}},
2762
2763     {&hf_iax2_ies[IAX_IE_AUTHMETHODS],
2764      {"Authentication method(s)", "iax2.iax.auth.methods",
2765       FT_UINT16, BASE_HEX, NULL, 0x0,
2766       NULL, HFILL}},
2767
2768     {&hf_iax2_ies[IAX_IE_CHALLENGE],
2769      {"Challenge data for MD5/RSA", "iax2.iax.auth.challenge",
2770       FT_STRING, BASE_NONE, NULL, 0x0,
2771       NULL, HFILL}},
2772
2773     {&hf_iax2_ies[IAX_IE_MD5_RESULT],
2774      {"MD5 challenge result", "iax2.iax.auth.md5",
2775       FT_STRING, BASE_NONE, NULL, 0x0,
2776       NULL, HFILL}},
2777
2778     {&hf_iax2_ies[IAX_IE_RSA_RESULT],
2779      {"RSA challenge result", "iax2.iax.auth.rsa",
2780       FT_STRING, BASE_NONE, NULL, 0x0,
2781       NULL, HFILL}},
2782
2783     {&hf_iax2_ies[IAX_IE_REFRESH],
2784      {"When to refresh registration", "iax2.iax.refresh",
2785       FT_INT16, BASE_DEC, NULL, 0x0,
2786       NULL, HFILL}},
2787
2788     {&hf_iax2_ies[IAX_IE_DPSTATUS],
2789      {"Dialplan status", "iax2.iax.dialplan_status",
2790       FT_UINT16, BASE_HEX, NULL, 0x0,
2791       NULL, HFILL}},
2792
2793     {&hf_iax2_ies[IAX_IE_CALLNO],
2794      {"Call number of peer", "iax2.iax.call_no",
2795       FT_UINT16, BASE_DEC, NULL, 0x0,
2796       NULL, HFILL}},
2797
2798     {&hf_iax2_ies[IAX_IE_CAUSE],
2799      {"Cause", "iax2.iax.cause",
2800       FT_STRING, BASE_NONE, NULL, 0x0,
2801       NULL, HFILL}},
2802
2803     {&hf_iax2_ies[IAX_IE_IAX_UNKNOWN],
2804      {"Unknown IAX command", "iax2.iax.iax_unknown",
2805       FT_BYTES, BASE_NONE, NULL, 0x0,
2806       NULL, HFILL}},
2807
2808     {&hf_iax2_ies[IAX_IE_MSGCOUNT],
2809      {"How many messages waiting", "iax2.iax.msg_count",
2810       FT_INT16, BASE_DEC, NULL, 0x0,
2811       NULL, HFILL}},
2812
2813     {&hf_iax2_ies[IAX_IE_AUTOANSWER],
2814      {"Request auto-answering", "iax2.iax.autoanswer",
2815       FT_NONE, BASE_NONE, NULL, 0x0,
2816       NULL, HFILL}},
2817
2818     {&hf_iax2_ies[IAX_IE_MUSICONHOLD],
2819      {"Request musiconhold with QUELCH", "iax2.iax.moh",
2820       FT_NONE, BASE_NONE, NULL, 0x0,
2821       NULL, HFILL}},
2822
2823     {&hf_iax2_ies[IAX_IE_TRANSFERID],
2824      {"Transfer Request Identifier", "iax2.iax.transferid",
2825       FT_UINT32, BASE_HEX, NULL, 0x0,
2826       NULL, HFILL}},
2827
2828     {&hf_iax2_ies[IAX_IE_RDNIS],
2829      {"Referring DNIS", "iax2.iax.rdnis",
2830       FT_STRING, BASE_NONE, NULL, 0x0,
2831       NULL, HFILL}},
2832
2833     {&hf_iax2_ies[IAX_IE_PROVISIONING],
2834      {"Provisioning info", "iax2.iax.provisioning",
2835       FT_STRING, BASE_NONE, NULL, 0x0,
2836       NULL, HFILL}},
2837
2838     {&hf_iax2_ies[IAX_IE_AESPROVISIONING],
2839      {"AES Provisioning info", "iax2.iax.aesprovisioning",
2840       FT_STRING, BASE_NONE, NULL, 0x0,
2841       NULL, HFILL}},
2842
2843     {&hf_iax2_ies[IAX_IE_DATETIME],
2844      {"Date/Time", "iax2.iax.datetime.raw",
2845       FT_UINT32, BASE_DEC, NULL, 0x0,
2846       NULL, HFILL}},
2847
2848     {&hf_iax2_ie_datetime,
2849      {"Date/Time", "iax2.iax.datetime",
2850       FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
2851       NULL, HFILL }},
2852
2853     {&hf_iax2_ies[IAX_IE_DEVICETYPE],
2854      {"Device type", "iax2.iax.devicetype",
2855       FT_STRING, BASE_NONE, NULL, 0x0,
2856       NULL, HFILL}},
2857
2858     {&hf_iax2_ies[IAX_IE_SERVICEIDENT],
2859      {"Service identifier", "iax2.iax.serviceident",
2860       FT_STRING, BASE_NONE, NULL, 0x0,
2861       NULL, HFILL}},
2862
2863     {&hf_iax2_ies[IAX_IE_FIRMWAREVER],
2864      {"Firmware version", "iax2.iax.firmwarever",
2865       FT_UINT16, BASE_HEX, NULL, 0x0,
2866       NULL, HFILL}},
2867
2868     {&hf_iax2_ies[IAX_IE_FWBLOCKDESC],
2869      {"Firmware block description", "iax2.iax.fwblockdesc",
2870       FT_UINT32, BASE_HEX, NULL, 0x0,
2871       NULL, HFILL}},
2872
2873     {&hf_iax2_ies[IAX_IE_FWBLOCKDATA],
2874      {"Firmware block of data", "iax2.iax.fwblockdata",
2875       FT_STRING, BASE_NONE, NULL, 0x0,
2876       NULL, HFILL}},
2877
2878     {&hf_iax2_ies[IAX_IE_PROVVER],
2879      {"Provisioning version", "iax2.iax.provver",
2880       FT_UINT32, BASE_HEX, NULL, 0x0,
2881       NULL, HFILL}},
2882
2883     {&hf_iax2_ies[IAX_IE_CALLINGPRES],
2884      {"Calling presentation", "iax2.iax.callingpres",
2885       FT_UINT8, BASE_HEX, NULL, 0x0,
2886       NULL, HFILL}},
2887
2888     {&hf_iax2_ies[IAX_IE_CALLINGTON],
2889      {"Calling type of number", "iax2.iax.callington",
2890       FT_UINT8, BASE_HEX, NULL, 0x0,
2891       NULL, HFILL}},
2892
2893     {&hf_iax2_ies[IAX_IE_CALLINGTNS],
2894      {"Calling transit network select", "iax2.iax.callingtns",
2895       FT_UINT16, BASE_HEX, NULL, 0x0,
2896       NULL, HFILL}},
2897
2898     {&hf_iax2_ies[IAX_IE_SAMPLINGRATE],
2899      {"Supported sampling rates", "iax2.iax.samplingrate",
2900       FT_UINT16, BASE_HEX, NULL, 0x0,
2901       NULL, HFILL}},
2902
2903     {&hf_iax2_ies[IAX_IE_CAUSECODE],
2904      {"Hangup cause", "iax2.iax.causecode",
2905       FT_UINT8, BASE_HEX | BASE_EXT_STRING, &iax_causecodes_ext, 0x0,
2906       NULL, HFILL}},
2907
2908     {&hf_iax2_ies[IAX_IE_ENCRYPTION],
2909      {"Encryption format", "iax2.iax.encryption",
2910       FT_UINT16, BASE_HEX, NULL, 0x0,
2911       NULL, HFILL}},
2912
2913     {&hf_iax2_ies[IAX_IE_ENCKEY],
2914      {"Encryption key", "iax2.iax.enckey",
2915       FT_STRING, BASE_NONE, NULL, 0x0,
2916       NULL, HFILL}},
2917
2918     {&hf_iax2_ies[IAX_IE_CODEC_PREFS],
2919      {"Codec negotiation", "iax2.iax.codecprefs",
2920       FT_STRING, BASE_NONE, NULL, 0x0,
2921       NULL, HFILL}},
2922
2923     {&hf_iax2_ies[IAX_IE_RR_JITTER],
2924      {"Received jitter (as in RFC1889)", "iax2.iax.rrjitter",
2925       FT_UINT32, BASE_HEX, NULL, 0x0,
2926       NULL, HFILL}},
2927
2928     {&hf_iax2_ies[IAX_IE_RR_LOSS],
2929      {"Received loss (high byte loss pct, low 24 bits loss count, as in rfc1889)", "iax2.iax.rrloss",
2930        FT_UINT32, BASE_HEX, NULL, 0x0,
2931       NULL, HFILL}},
2932
2933     {&hf_iax2_ies[IAX_IE_RR_PKTS],
2934      {"Total frames received", "iax2.iax.rrpkts",
2935       FT_UINT32, BASE_HEX, NULL, 0x0,
2936       NULL, HFILL}},
2937
2938     {&hf_iax2_ies[IAX_IE_RR_DELAY],
2939      {"Max playout delay in ms for received frames", "iax2.iax.rrdelay",
2940       FT_UINT16, BASE_HEX, NULL, 0x0,
2941       NULL, HFILL}},
2942
2943     {&hf_iax2_ies[IAX_IE_RR_DROPPED],
2944      {"Dropped frames (presumably by jitterbuffer)", "iax2.iax.rrdropped",
2945       FT_UINT32, BASE_HEX, NULL, 0x0,
2946       NULL, HFILL}},
2947
2948     {&hf_iax2_ies[IAX_IE_RR_OOO],
2949      {"Frame received out of order", "iax2.iax.rrooo",
2950       FT_UINT32, BASE_HEX, NULL, 0x0,
2951       NULL, HFILL}},
2952
2953     {&hf_iax2_ies[IAX_IE_DATAFORMAT],
2954      {"Data call format", "iax2.iax.dataformat",
2955       FT_UINT32, BASE_HEX, VALS(iax_dataformats), 0x0,
2956       NULL, HFILL}},
2957
2958     {&hf_IAX_IE_UNKNOWN_BYTE,
2959      {"Unknown", "iax2.iax.unknownbyte",
2960       FT_UINT8, BASE_HEX, NULL, 0x0,
2961       "Raw data for unknown IEs", HFILL}},
2962
2963     {&hf_IAX_IE_UNKNOWN_I16,
2964      {"Unknown", "iax2.iax.unknownshort",
2965       FT_UINT16, BASE_HEX, NULL, 0x0,
2966       "Raw data for unknown IEs", HFILL}},
2967
2968     {&hf_IAX_IE_UNKNOWN_I32,
2969      {"Unknown", "iax2.iax.unknownlong",
2970       FT_UINT32, BASE_HEX, NULL, 0x0,
2971       "Raw data for unknown IEs", HFILL}},
2972
2973     {&hf_IAX_IE_UNKNOWN_BYTES,
2974      {"Unknown", "iax2.iax.unknownstring",
2975       FT_STRING, BASE_NONE, NULL, 0x0,
2976       "Raw data for unknown IEs", HFILL}},
2977
2978     /* capabilities */
2979     {&hf_iax2_cap_g723_1,
2980      {"G.723.1 compression", "iax2.cap.g723_1",
2981       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_G723_1,
2982       NULL, HFILL }},
2983
2984     {&hf_iax2_cap_gsm,
2985      {"GSM compression", "iax2.cap.gsm",
2986       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_GSM,
2987       NULL, HFILL }},
2988
2989     {&hf_iax2_cap_ulaw,
2990      {"Raw mu-law data (G.711)", "iax2.cap.ulaw",
2991       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_ULAW,
2992       NULL, HFILL }},
2993
2994      {&hf_iax2_cap_alaw,
2995       {"Raw A-law data (G.711)", "iax2.cap.alaw",
2996        FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_ALAW,
2997        NULL, HFILL } },
2998
2999     {&hf_iax2_cap_g726_aal2,
3000      {"G.726 compression (AAL2 packing)", "iax2.cap.g726_aal2",
3001       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_G726_AAL2,
3002       NULL, HFILL }},
3003
3004     {&hf_iax2_cap_adpcm,
3005      {"ADPCM", "iax2.cap.adpcm",
3006       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_ADPCM,
3007       NULL, HFILL }},
3008
3009     {&hf_iax2_cap_slinear,
3010      {"Raw 16-bit Signed Linear (8000 Hz) PCM", "iax2.cap.slinear",
3011       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_SLINEAR,
3012       NULL, HFILL }},
3013
3014     {&hf_iax2_cap_lpc10,
3015      {"LPC10, 180 samples/frame",
3016       "iax2.cap.lpc10", FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported),
3017       AST_FORMAT_LPC10, NULL, HFILL }},
3018
3019     {&hf_iax2_cap_g729a,
3020      {"G.729a Audio", "iax2.cap.g729a",
3021       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_G729A,
3022       NULL, HFILL }},
3023
3024     {&hf_iax2_cap_speex,
3025      {"SPEEX Audio", "iax2.cap.speex",
3026       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_SPEEX,
3027       NULL, HFILL }},
3028
3029     {&hf_iax2_cap_ilbc,
3030      {"iLBC Free compressed Audio", "iax2.cap.ilbc",
3031       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_ILBC,
3032       NULL, HFILL }},
3033
3034     {&hf_iax2_cap_g726,
3035      {"ADPCM (G.726, 32kbps, RFC3551 codeword packing)", "iax2.cap.g726",
3036       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_G726,
3037       NULL, HFILL }},
3038
3039     {&hf_iax2_cap_g722,
3040      {"G.722 wideband audio", "iax2.cap.g722",
3041       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_G722,
3042       NULL, HFILL }},
3043
3044     {&hf_iax2_cap_siren7,
3045      {"G.722.1 (also known as Siren7, 32kbps assumed)", "iax2.cap.siren7",
3046       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_SIREN7,
3047       NULL, HFILL }},
3048
3049     {&hf_iax2_cap_siren14,
3050      {"G.722.1 Annex C (also known as Siren14, 48kbps assumed)", "iax2.cap.siren14",
3051       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_SIREN14,
3052       NULL, HFILL }},
3053
3054     {&hf_iax2_cap_slinear16,
3055      {"Raw 16-bit Signed Linear (16000 Hz) PCM", "iax2.cap.slinear16",
3056       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_SLINEAR16,
3057       NULL, HFILL }},
3058
3059     {&hf_iax2_cap_jpeg,
3060      {"JPEG images", "iax2.cap.jpeg",
3061       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_JPEG,
3062       NULL, HFILL }},
3063
3064     {&hf_iax2_cap_png,
3065      {"PNG images", "iax2.cap.png",
3066       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_PNG,
3067       NULL, HFILL }},
3068
3069     {&hf_iax2_cap_h261,
3070      {"H.261 video", "iax2.cap.h261",
3071       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_H261,
3072       NULL, HFILL }},
3073
3074     {&hf_iax2_cap_h263,
3075      {"H.263 video", "iax2.cap.h263",
3076       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_H263,
3077       NULL, HFILL }},
3078
3079     {&hf_iax2_cap_h263_plus,
3080      {"H.263+ video", "iax2.cap.h263_plus",
3081       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_H263_PLUS,
3082       NULL, HFILL }},
3083
3084     {&hf_iax2_cap_h264,
3085      {"H.264 video", "iax2.cap.h264",
3086       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_H264,
3087       NULL, HFILL }},
3088
3089     {&hf_iax2_cap_mpeg4,
3090      {"MPEG4 video", "iax2.cap.mpeg4",
3091       FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), AST_FORMAT_MP4_VIDEO,
3092       NULL, HFILL }},
3093
3094     /* reassembly stuff */
3095     {&hf_iax2_fragments,
3096      {"IAX2 Fragments", "iax2.fragments",
3097       FT_NONE, BASE_NONE, NULL, 0x0,
3098       NULL, HFILL }},
3099
3100     {&hf_iax2_fragment,
3101      {"IAX2 Fragment data", "iax2.fragment",
3102       FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3103       NULL, HFILL }},
3104
3105     {&hf_iax2_fragment_overlap,
3106      {"Fragment overlap", "iax2.fragment.overlap",
3107       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3108       "Fragment overlaps with other fragments", HFILL }},
3109
3110     {&hf_iax2_fragment_overlap_conflict,
3111      {"Conflicting data in fragment overlap", "iax2.fragment.overlap.conflict",
3112       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3113       "Overlapping fragments contained conflicting data", HFILL }},
3114
3115     {&hf_iax2_fragment_multiple_tails,
3116      {"Multiple tail fragments found", "iax2.fragment.multipletails",
3117       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3118       "Several tails were found when defragmenting the packet", HFILL }},
3119
3120     {&hf_iax2_fragment_too_long_fragment,
3121      {"Fragment too long", "iax2.fragment.toolongfragment",
3122       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3123       "Fragment contained data past end of packet", HFILL }},
3124
3125     {&hf_iax2_fragment_error,
3126      {"Defragmentation error", "iax2.fragment.error",
3127       FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3128       "Defragmentation error due to illegal fragments", HFILL }},
3129
3130     {&hf_iax2_fragment_count,
3131      {"Fragment count", "iax2.fragment.count",
3132       FT_UINT32, BASE_DEC, NULL, 0x0,
3133       NULL, HFILL }},
3134
3135     {&hf_iax2_reassembled_in,
3136      {"IAX2 fragment, reassembled in frame", "iax2.reassembled_in",
3137       FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3138       "This IAX2 packet is reassembled in this frame", HFILL }},
3139
3140     {&hf_iax2_reassembled_length,
3141      {"Reassembled IAX2 length", "iax2.reassembled.length",
3142       FT_UINT32, BASE_DEC, NULL, 0x0,
3143       "The total length of the reassembled payload", HFILL }}
3144   };
3145
3146   static gint *ett[] = {
3147     &ett_iax2,
3148     &ett_iax2_full_mini_subtree,
3149     &ett_iax2_type,
3150     &ett_iax2_ie,
3151     &ett_iax2_codecs,
3152     &ett_iax2_ies_apparent_addr,
3153     &ett_iax2_fragment,
3154     &ett_iax2_fragments,
3155     &ett_iax2_trunk_cmddata,
3156     &ett_iax2_trunk_call
3157   };
3158
3159   static ei_register_info ei[] = {
3160     { &ei_iax_too_many_transfers, { "iax2.too_many_transfers", PI_PROTOCOL, PI_WARN, "Too many transfers for iax_call", EXPFILL }},
3161     { &ei_iax_circuit_id_conflict, { "iax2.circuit_id_conflict", PI_PROTOCOL, PI_WARN, "Circuit ID conflict", EXPFILL }},
3162     { &ei_iax_peer_address_unsupported, { "iax2.peer_address_unsupported", PI_PROTOCOL, PI_WARN, "Peer address unsupported", EXPFILL }},
3163   };
3164
3165   expert_module_t* expert_iax;
3166
3167   /* initialize the hf_iax2_ies[] array to -1 */
3168   memset(hf_iax2_ies, 0xff, sizeof(hf_iax2_ies));
3169
3170   proto_iax2 =
3171     proto_register_protocol("Inter-Asterisk eXchange v2", "IAX2", "iax2");
3172   proto_register_field_array(proto_iax2, hf, array_length(hf));
3173   proto_register_subtree_array(ett, array_length(ett));
3174   expert_iax = expert_register_protocol(proto_iax2);
3175   expert_register_field_array(expert_iax, ei, array_length(ei));
3176
3177   register_dissector("iax2", dissect_iax2, proto_iax2);
3178
3179   iax2_codec_dissector_table = register_dissector_table(
3180     "iax2.codec", "IAX codec number", FT_UINT32, BASE_HEX);
3181   iax2_dataformat_dissector_table = register_dissector_table(
3182     "iax2.dataformat", "IAX dataformat number", FT_UINT32, BASE_HEX);
3183
3184   /* register our init routine to be called at the start of a capture,
3185      to clear out our hash tables etc */
3186   register_init_routine(&iax_init_protocol);
3187   iax2_tap = register_tap("IAX2");
3188 }
3189
3190 void
3191 proto_reg_handoff_iax2(void)
3192 {
3193   dissector_handle_t v110_handle;
3194
3195   dissector_add_uint("udp.port", IAX2_PORT, find_dissector("iax2"));
3196   v110_handle =  find_dissector("v110");
3197   if (v110_handle)
3198     dissector_add_uint("iax2.dataformat", AST_DATAFORMAT_V110, v110_handle);
3199   data_handle = find_dissector("data");
3200 }
3201
3202 /*
3203  * Editor modelines
3204  *
3205  * Local Variables:
3206  * c-basic-offset: 2
3207  * tab-width: 8
3208  * indent-tabs-mode: nil
3209  * End:
3210  *
3211  * ex: set shiftwidth=2 tabstop=8 expandtab:
3212  * :indentSize=2:tabSize=8:noTabs=true:
3213  */