Fix up a bunch of arguments to "dissect_ber_identifier()" to match its
[obnox/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.
10  *
11  * $Id$
12  *
13  * Ethereal - Network traffic analyzer
14  * By Gerald Combs <gerald@ethereal.com>
15  * Copyright 1998 Gerald Combs
16  * 
17  * This program is free software; you can redistribute it and/or modify it
18  * under the terms of the GNU General Public License as published by the
19  * Free Software Foundation; either version 2 of the License, or (at your
20  * option) any later version. This program is distributed in the hope
21  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
22  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
23  * PURPOSE.  See the GNU General Public License for more details. You
24  * should have received a copy of the GNU General Public License along
25  * with this program; if not, write to the Free Software Foundation, Inc., 
26  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  *
28  */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <glib.h>
37
38 #include <epan/circuit.h>
39 #include <epan/packet.h>
40 #include <epan/to_str.h>
41
42 #include "packet-iax2.h"
43 #include "iax2_codec_type.h"
44
45 #define IAX2_PORT               4569
46 #define PROTO_TAG_IAX2          "IAX2"
47
48 /* #define DEBUG_HASHING */
49
50 /* Ethereal ID of the IAX2 protocol */
51 static int proto_iax2 = -1;
52
53 /* The following hf_* variables are used to hold the ethereal IDs of
54  * our header fields; they are filled out when we call
55  * proto_register_field_array() in proto_register_iax2()
56  */
57 static int hf_iax2_packet_type = -1;
58 static int hf_iax2_retransmission = -1;
59 static int hf_iax2_scallno = -1;
60 static int hf_iax2_dcallno = -1;
61 static int hf_iax2_ts = -1;
62 static int hf_iax2_minits = -1;
63 static int hf_iax2_minividts = -1;
64 static int hf_iax2_minividmarker = -1;
65 static int hf_iax2_oseqno = -1;
66 static int hf_iax2_iseqno = -1;
67 static int hf_iax2_type = -1;
68 static int hf_iax2_csub = -1;
69 static int hf_iax2_cmd_csub = -1;
70 static int hf_iax2_iax_csub = -1;
71 static int hf_iax2_voice_csub = -1;
72 static int hf_iax2_voice_codec = -1;
73 static int hf_iax2_video_csub = -1;
74 static int hf_iax2_video_codec = -1;
75 static int hf_iax2_marker = -1;
76
77 static int hf_iax2_cap_g723_1 = -1;
78 static int hf_iax2_cap_gsm = -1;
79 static int hf_iax2_cap_ulaw = -1;
80 static int hf_iax2_cap_alaw = -1;
81 static int hf_iax2_cap_g726 = -1;
82 static int hf_iax2_cap_adpcm = -1;
83 static int hf_iax2_cap_slinear = -1;
84 static int hf_iax2_cap_lpc10 = -1;
85 static int hf_iax2_cap_g729a = -1;
86 static int hf_iax2_cap_speex = -1;
87 static int hf_iax2_cap_ilbc = -1;
88 static int hf_iax2_cap_jpeg = -1;
89 static int hf_iax2_cap_png = -1;
90 static int hf_iax2_cap_h261 = -1;
91 static int hf_iax2_cap_h263 = -1;
92
93 static int hf_IAX_IE_APPARENTADDR_SINFAMILY = -1;
94 static int hf_IAX_IE_APPARENTADDR_SINPORT = -1;
95 static int hf_IAX_IE_APPARENTADDR_SINADDR = -1;
96 static int hf_IAX_IE_APPARENTADDR_SINZERO = -1;           
97 static int hf_IAX_IE_CALLED_NUMBER = -1;
98 static int hf_IAX_IE_CALLING_NUMBER = -1;
99 static int hf_IAX_IE_CALLING_ANI = -1;
100 static int hf_IAX_IE_CALLING_NAME = -1;
101 static int hf_IAX_IE_CALLED_CONTEXT = -1;
102 static int hf_IAX_IE_USERNAME = -1;
103 static int hf_IAX_IE_PASSWORD = -1;
104 static int hf_IAX_IE_CAPABILITY = -1;
105 static int hf_IAX_IE_FORMAT = -1;
106 static int hf_IAX_IE_LANGUAGE = -1;
107 static int hf_IAX_IE_VERSION = -1;
108 static int hf_IAX_IE_ADSICPE = -1;
109 static int hf_IAX_IE_DNID = -1;
110 static int hf_IAX_IE_AUTHMETHODS = -1;
111 static int hf_IAX_IE_CHALLENGE = -1;
112 static int hf_IAX_IE_MD5_RESULT = -1;
113 static int hf_IAX_IE_RSA_RESULT = -1;
114 static int hf_IAX_IE_REFRESH = -1;
115 static int hf_IAX_IE_DPSTATUS = -1;
116 static int hf_IAX_IE_CALLNO = -1;
117 static int hf_IAX_IE_CAUSE = -1;
118 static int hf_IAX_IE_IAX_UNKNOWN = -1;
119 static int hf_IAX_IE_MSGCOUNT = -1;
120 static int hf_IAX_IE_AUTOANSWER = -1;
121 static int hf_IAX_IE_MUSICONHOLD = -1;
122 static int hf_IAX_IE_TRANSFERID = -1;
123 static int hf_IAX_IE_RDNIS = -1;
124 static int hf_IAX_IE_PROVISIONING = -1;
125 static int hf_IAX_IE_AESPROVISIONING = -1;
126 static int hf_IAX_IE_DATETIME = -1;
127 static int hf_IAX_IE_DEVICETYPE = -1;
128 static int hf_IAX_IE_SERVICEIDENT = -1;
129 static int hf_IAX_IE_FIRMWAREVER = -1;
130 static int hf_IAX_IE_FWBLOCKDESC = -1;
131 static int hf_IAX_IE_FWBLOCKDATA = -1;
132 static int hf_IAX_IE_PROVVER = -1;
133 static int hf_IAX_IE_CALLINGPRES = -1;
134 static int hf_IAX_IE_CALLINGTON = -1;
135 static int hf_IAX_IE_CALLINGTNS = -1;
136 static int hf_IAX_IE_SAMPLINGRATE = -1;
137 static int hf_IAX_IE_CAUSECODE = -1;
138 static int hf_IAX_IE_ENCRYPTION = -1;
139 static int hf_IAX_IE_ENCKEY = -1;
140 static int hf_IAX_IE_CODEC_PREFS = -1;
141 static int hf_IAX_IE_RR_JITTER = -1;
142 static int hf_IAX_IE_RR_LOSS = -1;
143 static int hf_IAX_IE_RR_PKTS = -1;
144 static int hf_IAX_IE_RR_DELAY = -1;
145 static int hf_IAX_IE_RR_DROPPED = -1;
146 static int hf_IAX_IE_RR_OOO = -1;
147
148 static int hf_IAX_IE_DATAFORMAT = -1;
149 static int hf_IAX_IE_UNKNOWN_BYTE = -1;
150 static int hf_IAX_IE_UNKNOWN_I16 = -1;
151 static int hf_IAX_IE_UNKNOWN_I32 = -1;
152 static int hf_IAX_IE_UNKNOWN_BYTES = -1;
153
154 /* These are the ids of the subtrees that we may be creating */
155 static gint ett_iax2 = -1;
156 static gint ett_iax2_full_mini_subtree = -1;
157 static gint ett_iax2_type = -1;         /* Frame-type specific subtree */
158 static gint ett_iax2_ie = -1;           /* single IE */
159 static gint ett_iax2_codecs = -1;       /* capabilities IE */
160 static gint ett_iax2_ies_apparent_addr = -1; /* apparent address IE */
161
162 static dissector_handle_t data_handle;
163
164 /* data-call subdissectors, AST_DATAFORMAT_* */
165 static dissector_table_t iax2_dataformat_dissector_table;
166 /* voice/video call subdissectors, AST_FORMAT_* */
167 static dissector_table_t iax2_codec_dissector_table;
168
169 /* IAX2 Full-frame types */
170 static const value_string iax_frame_types[] = {
171   {0, "(0?)"},
172   {1, "DTMF"},
173   {2, "Voice"},
174   {3, "Video"},
175   {4, "Control"},
176   {5, "NULL"},
177   {6, "IAX"},
178   {7, "Text"},
179   {8, "Image"},
180   {0,NULL}
181 };
182
183 /* Subclasses for IAX packets */
184 static const value_string iax_iax_subclasses[] = {
185   {0, "(0?)"},
186   {1, "NEW"},
187   {2, "PING"},
188   {3, "PONG"},
189   {4, "ACK"},
190   {5, "HANGUP"},
191   {6, "REJECT"},
192   {7, "ACCEPT"},
193   {8, "AUTHREQ"},
194   {9, "AUTHREP"},
195   {10, "INVAL"},
196   {11, "LAGRQ"},
197   {12, "LAGRP"},
198   {13, "REGREQ"},
199   {14, "REGAUTH"},
200   {15, "REGACK"},
201   {16, "REGREJ"},
202   {17, "REGREL"},
203   {18, "VNAK"},
204   {19, "DPREQ"},
205   {20, "DPREP"},
206   {21, "DIAL"},
207   {22, "TXREQ"},
208   {23, "TXCNT"},
209   {24, "TXACC"},
210   {25, "TXREADY"},
211   {26, "TXREL"},
212   {27, "TXREJ"},
213   {28, "QUELCH"},
214   {29, "UNQULCH"},
215   {30, "POKE"},
216   {31, "PAGE"},
217   {32, "MWI"},
218   {33, "UNSUPPORTED"},
219   {34, "TRANSFER"},
220   {35, "PROVISION"},
221   {36, "FWDOWNL"},
222   {37, "FWDATA"},
223   {0,NULL}
224 };
225
226 /* Subclassess for Control packets */
227 static const value_string iax_cmd_subclasses[] = {
228   {0, "(0?)"},
229   {1, "HANGUP"},
230   {2, "RING"},
231   {3, "RINGING"},
232   {4, "ANSWER"},
233   {5, "BUSY"},
234   {6, "TKOFFHK"},
235   {7, "OFFHOOK"},
236   {0xFF, "stop sounds"}, /* sent by app_dial, and not much else */
237   {0,NULL}
238 };
239
240 /* Information elements */
241 static const value_string iax_ies_type[] = {
242   {IAX_IE_CALLED_NUMBER, "Number/extension being called"},
243   {IAX_IE_CALLING_NUMBER, "Calling number"},
244   {IAX_IE_CALLING_ANI, "Calling number ANI for billing"},
245   {IAX_IE_CALLING_NAME, "Name of caller"},
246   {IAX_IE_CALLED_CONTEXT, "Context for number"},
247   {IAX_IE_USERNAME, "Username (peer or user) for authentication"},
248   {IAX_IE_PASSWORD, "Password for authentication"},
249   {IAX_IE_CAPABILITY, "Actual codec capability"},
250   {IAX_IE_FORMAT, "Desired codec format"},
251   {IAX_IE_LANGUAGE, "Desired language"},
252   {IAX_IE_VERSION, "Protocol version"},
253   {IAX_IE_ADSICPE, "CPE ADSI capability"},
254   {IAX_IE_DNID, "Originally dialed DNID"},
255   {IAX_IE_AUTHMETHODS, "Authentication method(s)"},
256   {IAX_IE_CHALLENGE, "Challenge data for MD5/RSA"},
257   {IAX_IE_MD5_RESULT, "MD5 challenge result"},
258   {IAX_IE_RSA_RESULT, "RSA challenge result"},
259   {IAX_IE_APPARENT_ADDR, "Apparent address of peer"},
260   {IAX_IE_REFRESH, "When to refresh registration"},
261   {IAX_IE_DPSTATUS, "Dialplan status"},
262   {IAX_IE_CALLNO, "Call number of peer"},
263   {IAX_IE_CAUSE, "Cause"},
264   {IAX_IE_IAX_UNKNOWN, "Unknown IAX command"},
265   {IAX_IE_MSGCOUNT, "How many messages waiting"},
266   {IAX_IE_AUTOANSWER, "Request auto-answering"},
267   {IAX_IE_MUSICONHOLD, "Request musiconhold with QUELCH"},
268   {IAX_IE_TRANSFERID, "Transfer Request Identifier"},
269   {IAX_IE_RDNIS, "Referring DNIS"},
270   {IAX_IE_PROVISIONING, "Provisioning info"},
271   {IAX_IE_AESPROVISIONING, "AES Provisioning info"},
272   {IAX_IE_DATETIME,"Date/Time"},
273   {IAX_IE_DEVICETYPE, "Device type"},
274   {IAX_IE_SERVICEIDENT, "Service Identifier"},
275   {IAX_IE_FIRMWAREVER, "Firmware revision"},
276   {IAX_IE_FWBLOCKDESC, "Firmware block description"},
277   {IAX_IE_FWBLOCKDATA, "Firmware block of data"},
278   {IAX_IE_PROVVER, "Provisioning version"},
279   {IAX_IE_CALLINGPRES, "Calling presentation"},
280   {IAX_IE_CALLINGTON, "Calling type of number"},
281   {IAX_IE_CALLINGTNS, "Calling transit network select"},
282   {IAX_IE_SAMPLINGRATE, "Supported sampling rates"},
283   {IAX_IE_CAUSECODE, "Hangup cause"},
284   {IAX_IE_ENCRYPTION, "Encryption format"},
285   {IAX_IE_ENCKEY, "Raw encryption key"},
286   {IAX_IE_CODEC_PREFS, "Codec preferences"},
287   {IAX_IE_RR_JITTER, "Received jitter"},
288   {IAX_IE_RR_LOSS, "Received loss"},
289   {IAX_IE_RR_PKTS, "Received frames"},
290   {IAX_IE_RR_DELAY, "Max playout delay in ms for received frames"},
291   {IAX_IE_RR_DROPPED, "Dropped frames"},
292   {IAX_IE_RR_OOO, "Frames received out of order"},
293   {IAX_IE_DATAFORMAT, "Data call format"},
294   {0,NULL}
295 };
296
297 static const value_string codec_types[] = {
298   {AST_FORMAT_G723_1, "G.723.1 compression"},
299   {AST_FORMAT_GSM, "GSM compression"},
300   {AST_FORMAT_ULAW, "Raw mu-law data (G.711)"},
301   {AST_FORMAT_ALAW, "Raw A-law data (G.711)"},
302   {AST_FORMAT_G726, "ADPCM (G.726, 32kbps)"},
303   {AST_FORMAT_ADPCM, "ADPCM (IMA)"},
304   {AST_FORMAT_SLINEAR, "Raw 16-bit Signed Linear (8000 Hz) PCM"},
305   {AST_FORMAT_LPC10, "LPC10, 180 samples/frame"},
306   {AST_FORMAT_G729A, "G.729a Audio"},
307   {AST_FORMAT_SPEEX, "SpeeX Free Compression"},
308   {AST_FORMAT_ILBC, "iLBC Free Compression"},
309   {AST_FORMAT_JPEG, "JPEG Images"},
310   {AST_FORMAT_PNG, "PNG Images"},
311   {AST_FORMAT_H261, "H.261 Video"},
312   {AST_FORMAT_H263, "H.263 Video"},
313   {0,NULL}
314 };
315
316 static const value_string iax_dataformats[] = {
317   {AST_DATAFORMAT_NULL, "N/A (analogue call?)"},
318   {AST_DATAFORMAT_V110, "ITU-T V.110 rate adaption"},
319   {AST_DATAFORMAT_H223_H245,"ITU-T H.223/H.245"},
320   {0,NULL}
321 };
322
323 typedef enum {
324   IAX2_MINI_VOICE_PACKET,
325   IAX2_FULL_PACKET,
326   IAX2_MINI_VIDEO_PACKET,
327   IAX2_META_PACKET
328 } packet_type;
329
330 static const value_string iax_packet_types[] = {
331   {IAX2_FULL_PACKET, "Full packet"},
332   {IAX2_MINI_VOICE_PACKET, "Mini voice packet"},
333   {IAX2_MINI_VIDEO_PACKET, "Mini video packet"},
334   {IAX2_META_PACKET, "Meta packet"},
335   {0,NULL}
336 };
337   
338 static const value_string iax_causecodes[] = {
339   {AST_CAUSE_UNALLOCATED, "Unallocated"},
340   {AST_CAUSE_NO_ROUTE_TRANSIT_NET, "No route transit net"},
341   {AST_CAUSE_NO_ROUTE_DESTINATION, "No route to destination"},
342   {AST_CAUSE_CHANNEL_UNACCEPTABLE, "Channel unacceptable"},
343   {AST_CAUSE_CALL_AWARDED_DELIVERED, "Call awarded delivered"},
344   {AST_CAUSE_NORMAL_CLEARING, "Normal clearing"},
345   {AST_CAUSE_USER_BUSY, "User busy"},
346   {AST_CAUSE_NO_USER_RESPONSE, "No user response"},
347   {AST_CAUSE_NO_ANSWER, "No answer"},
348   {AST_CAUSE_CALL_REJECTED, "Call rejected"},
349   {AST_CAUSE_NUMBER_CHANGED, "Number changed"},
350   {AST_CAUSE_DESTINATION_OUT_OF_ORDER, "Destination out of order"},
351   {AST_CAUSE_INVALID_NUMBER_FORMAT, "Invalid number format"},
352   {AST_CAUSE_FACILITY_REJECTED, "Facility rejected"},
353   {AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "Response to status inquiry"},
354   {AST_CAUSE_NORMAL_UNSPECIFIED, "Normal unspecified"},
355   {AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "Normal circuit congestion"},
356   {AST_CAUSE_NETWORK_OUT_OF_ORDER, "Network out of order"},
357   {AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "Normal temporary failure"},
358   {AST_CAUSE_SWITCH_CONGESTION, "Switch congestion"},
359   {AST_CAUSE_ACCESS_INFO_DISCARDED, "Access info discarded"},
360   {AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "Requested channel unavailable"},
361   {AST_CAUSE_PRE_EMPTED, "Preempted"},
362   {AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "Facility not subscribed"},
363   {AST_CAUSE_OUTGOING_CALL_BARRED, "Outgoing call barred"},
364   {AST_CAUSE_INCOMING_CALL_BARRED, "Incoming call barred"},
365   {AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "Bearer capability not authorized"},
366   {AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "Bearer capability not available"},
367   {AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "Bearer capability not implemented"},
368   {AST_CAUSE_CHAN_NOT_IMPLEMENTED, "Channel not implemented"},
369   {AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "Facility not implemented"},
370   {AST_CAUSE_INVALID_CALL_REFERENCE, "Invalid call reference"},
371   {AST_CAUSE_INCOMPATIBLE_DESTINATION, "Incompatible destination"},
372   {AST_CAUSE_INVALID_MSG_UNSPECIFIED, "Invalid message unspecified"},
373   {AST_CAUSE_MANDATORY_IE_MISSING, "Mandatory IE missing"},
374   {AST_CAUSE_MESSAGE_TYPE_NONEXIST, "Message type nonexistent"},
375   {AST_CAUSE_WRONG_MESSAGE, "Wrong message"},
376   {AST_CAUSE_IE_NONEXIST, "IE nonexistent"},
377   {AST_CAUSE_INVALID_IE_CONTENTS, "Invalid IE contents"},
378   {AST_CAUSE_WRONG_CALL_STATE, "Wrong call state"},
379   {AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "Recovery on timer expire"},
380   {AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "Mandatory IE length error"},
381   {AST_CAUSE_PROTOCOL_ERROR, "Protocol error"},
382   {AST_CAUSE_INTERWORKING, "Interworking"},
383   {0, NULL}
384 };
385
386
387 /* ************************************************************************* */
388
389 /* In order to track IAX calls, we have a hash table which maps
390  * {addr,port type,port,call} to a unique circuit id.
391  *
392  * Each call has two such circuits associated with it (a forward and a
393  * reverse circuit, where 'forward' is defined as the direction the NEW
394  * packet went in), and we maintain an iax_call_data structure for each
395  * call, attached to both circuits with circuit_add_proto_data.
396  *
397  * Because {addr,port type,port,call} quadruplets can be reused
398  * (Asterisk reuses call numbers), circuit ids aren't unique to
399  * individual calls and we treat NEW packets somewhat specially. When we
400  * get such a packet, we see if there are any calls with a matching
401  * circuit id, and make sure that its circuits are marked as ended
402  * before that packet.
403  *
404  * A second complication is that we only know one quadruplet at the time
405  * the NEW packet is processed: there is therefore cunningness in
406  * iax_lookup_circuit_details() to look for replies to NEW packets and
407  * create the reverse circuit.
408  */
409
410
411 /* start with a hash of {addr,port type,port,call}->{id} */
412
413 typedef struct {
414   address addr;
415   port_type ptype;
416   guint32 port;
417   guint32 callno;
418 } iax_circuit_key;
419
420 /* tables */
421 static GHashTable *iax_circuit_hashtab = NULL;
422 static GMemChunk *iax_circuit_keys = NULL;
423 static GMemChunk *iax_circuit_vals = NULL;
424 static guint circuitcount = 0;
425
426 /* the number of keys and values to reserve space for in each memory chunk.
427    We assume we won't be tracking many calls at once so this is quite low.
428 */
429 #define IAX_INIT_PACKET_COUNT 10
430
431 #ifdef DEBUG_HASHING
432 static gchar *key_to_str( const iax_circuit_key *key )
433 {
434   static int i=0;
435   static gchar *strp, str[3][80];
436
437   i++;
438   if(i>=3){
439     i=0;
440   }
441   strp=str[i];
442
443   /* why doesn't address_to_str take a const pointer?
444      cast the warnings into oblivion. */
445
446   sprintf(strp,"{%s:%i,%i}",
447           address_to_str((address *)&key->addr),
448           key->port,
449           key->callno);
450   return strp;
451 }
452 #endif
453
454 /* Hash Functions */
455 static gint iax_circuit_equal(gconstpointer v, gconstpointer w)
456 {
457   const iax_circuit_key *v1 = (const iax_circuit_key *)v;
458   const iax_circuit_key *v2 = (const iax_circuit_key *)w;
459   gint result;
460
461   result = ( ADDRESSES_EQUAL(&(v1->addr), &(v2->addr)) &&
462              v1->ptype == v2->ptype &&
463              v1->port  == v2->port &&
464              v1->callno== v2->callno);
465 #ifdef DEBUG_HASHING
466   g_message( "+++ Comparing for equality: %s, %s: %u",key_to_str(v1), key_to_str(v2), result);
467 #endif
468
469   return result;;
470 }
471
472 static guint iax_circuit_hash (gconstpointer v)
473 {
474   const iax_circuit_key *key = (const iax_circuit_key *)v;
475   guint hash_val;
476   int i;
477
478   hash_val = 0;
479   for (i = 0; i < key->addr.len; i++)
480     hash_val += (guint)(key->addr.data[i]);
481
482   hash_val += (guint)(key->ptype);
483   hash_val += (guint)(key->port);
484   hash_val += (guint)(key->callno);
485
486 #ifdef DEBUG_HASHING
487   g_message( "+++ Hashing key: %s, result %#x", key_to_str(key), hash_val );
488 #endif
489   
490   return (guint) hash_val;
491 }
492
493 static guint iax_circuit_lookup(const address *address,
494                                 port_type ptype,
495                                 guint32 port,
496                                 guint32 callno)
497 {
498   iax_circuit_key key;
499   guint32 *circuit_id_p;
500
501   key.addr = *address;
502   key.ptype = ptype;
503   key.port = port;
504   key.callno = callno;
505
506 #ifdef DEBUG_HASHING
507   g_message( "+++ looking up key: %s", key_to_str(&key));
508 #endif
509   
510   circuit_id_p = g_hash_table_lookup( iax_circuit_hashtab, &key);
511   if( ! circuit_id_p ) {
512     iax_circuit_key *new_key;
513
514     new_key = g_mem_chunk_alloc(iax_circuit_keys);
515     COPY_ADDRESS(&new_key->addr, address);
516     new_key->ptype = ptype;
517     new_key->port = port;
518     new_key->callno = callno;
519
520     circuit_id_p = g_mem_chunk_alloc(iax_circuit_vals);
521     *circuit_id_p = ++circuitcount;
522
523     g_hash_table_insert(iax_circuit_hashtab, new_key, circuit_id_p);
524   }
525
526 #ifdef DEBUG_HASHING
527     g_message( "+++ Id: %u", *circuit_id_p );
528 #endif
529
530   return *circuit_id_p;
531 }
532
533
534 /* ************************************************************************* */
535
536
537 /* This is our per-call data structure, which is attached to both the
538  * forward and reverse circuits.
539  */
540 typedef struct iax_call_data {
541   /* For this data, src and dst are relative to the original direction under
542      which this call is stored. Obviously if the reversed flag is set true by
543      iax_find_call, src and dst are reversed relative to the direction the
544      actual source and destination of the data.
545
546      if the codec changes mid-call, we update it here; because we store a codec
547      number with each packet too, we handle going back to earlier packets
548      without problem.
549   */
550
551   iax_dataformat_t dataformat;
552   guint32 src_codec, dst_codec;
553   guint32 src_vformat, dst_vformat;
554
555   guint forward_circuit_id;
556   guint reverse_circuit_id;
557
558   guint callno;
559 } iax_call_data;
560
561 static guint callcount = 0;
562
563 static GMemChunk *iax_call_datas = NULL;
564
565 static void iax_init_hash( void )
566 {
567   if (iax_circuit_hashtab)
568     g_hash_table_destroy(iax_circuit_hashtab);
569
570   if (iax_circuit_keys)
571     g_mem_chunk_destroy(iax_circuit_keys);
572   if (iax_circuit_vals)
573     g_mem_chunk_destroy(iax_circuit_vals);
574   if (iax_call_datas)
575     g_mem_chunk_destroy(iax_call_datas);
576
577   iax_circuit_hashtab = g_hash_table_new(iax_circuit_hash, iax_circuit_equal);
578
579   iax_circuit_keys = g_mem_chunk_create(iax_circuit_key,
580                                         2*IAX_INIT_PACKET_COUNT,
581                                         G_ALLOC_ONLY);
582   iax_circuit_vals = g_mem_chunk_create(iax_circuit_key,
583                                         2*IAX_INIT_PACKET_COUNT,
584                                         G_ALLOC_ONLY);
585
586   iax_call_datas = g_mem_chunk_create(iax_call_data,
587                                       IAX_INIT_PACKET_COUNT,
588                                       G_ALLOC_ONLY);
589   circuitcount = 0;
590   callcount = 0;
591 }
592
593
594 static iax_call_data *iax_lookup_circuit_details_from_dest( guint src_circuit_id,
595                                                             guint dst_circuit_id,
596                                                             guint framenum,
597                                                             gboolean *reversed_p,
598                                                             circuit_t **circuit_p)
599 {
600   circuit_t *dst_circuit;
601   iax_call_data * iax_call;
602   gboolean reversed = FALSE;
603   
604   dst_circuit = find_circuit( CT_IAX2,
605                               dst_circuit_id,
606                               framenum );
607
608   if( !dst_circuit ) {
609 #ifdef DEBUG_HASHING
610     g_message( "++ destination circuit not found, must have missed NEW packet" );
611 #endif
612     if( reversed_p )
613       *reversed_p = FALSE;
614     if( circuit_p )
615       *circuit_p = NULL;
616     return NULL;
617   }
618
619 #ifdef DEBUG_HASHING
620   g_message( "++ found destination circuit" );
621 #endif
622       
623   iax_call = (iax_call_data *)circuit_get_proto_data(dst_circuit,proto_iax2);
624
625   /* there's no way we can create a CT_IAX2 circuit without adding
626      iax call data to it; assert this */
627   DISSECTOR_ASSERT(iax_call);
628   
629   if( dst_circuit_id == iax_call -> forward_circuit_id ) {
630 #ifdef DEBUG_HASHING
631     g_message( "++ destination circuit matches forward_circuit_id of call, "
632                "therefore packet is reversed" );
633 #endif
634
635     reversed = TRUE;
636
637     if( iax_call -> reverse_circuit_id == 0 ) {
638       circuit_t *rev_circuit;
639       
640       /* we are going in the reverse direction, and this call
641          doesn't have a reverse circuit associated with it.
642          create one now. */
643 #ifdef DEBUG_HASHING
644       g_message( "++ reverse_circuit_id of call is zero, need to create a "
645                  "new reverse circuit for this call" );
646 #endif
647
648       iax_call -> reverse_circuit_id = src_circuit_id;
649       rev_circuit = circuit_new(CT_IAX2,
650                                 src_circuit_id,
651                                 framenum );
652       circuit_add_proto_data(rev_circuit, proto_iax2, iax_call);
653         
654       /* we should have already set up a subdissector for the forward
655        * circuit. we'll need to copy it to the reverse circuit. */
656       circuit_set_dissector(rev_circuit, circuit_get_dissector(dst_circuit));
657 #ifdef DEBUG_HASHING
658       g_message( "++ done" );
659 #endif
660     } else if( iax_call -> reverse_circuit_id != src_circuit_id ) {
661       g_warning( "IAX Packet %u from circuit ids %u->%u"
662                  "conflicts with earlier call with circuit ids %u->%u",
663                  framenum,
664                  src_circuit_id,dst_circuit_id,
665                  iax_call->forward_circuit_id,
666                  iax_call->reverse_circuit_id);
667       if( reversed_p )
668         *reversed_p = FALSE;
669       if( circuit_p )
670         *circuit_p = NULL;
671       return NULL;
672     }
673   } else if ( dst_circuit_id == iax_call -> reverse_circuit_id ) {
674 #ifdef DEBUG_HASHING
675     g_message( "++ destination circuit matches reverse_circuit_id of call, "
676                "therefore packet is forward" );
677 #endif
678
679     reversed = FALSE;
680     if( iax_call -> forward_circuit_id != src_circuit_id ) {
681       g_warning( "IAX Packet %u from circuit ids %u->%u"
682                  "conflicts with earlier call with circuit ids %u->%u",
683                  framenum,
684                  src_circuit_id,dst_circuit_id,
685                  iax_call->forward_circuit_id,
686                  iax_call->reverse_circuit_id);
687       if( reversed_p )
688         *reversed_p = FALSE;
689       if( circuit_p )
690         *circuit_p = NULL;
691       return NULL;
692     }
693   } else {
694     DISSECTOR_ASSERT_NOT_REACHED();
695   }
696
697
698   if( circuit_p ) {
699     /* by now we've created a new circuit if one was necessary, or
700        bailed out if it looks like a conflict, and we should be able
701        to look up the source circuit without issue */
702     *circuit_p = find_circuit( CT_IAX2, 
703                                src_circuit_id,
704                                framenum );
705     DISSECTOR_ASSERT(*circuit_p);
706   }
707
708   if( reversed_p )
709     *reversed_p = reversed;
710
711   return iax_call;
712 }
713
714   
715   /* looks up a circuit_t and an iax_call for this packet */
716 static iax_call_data *iax_lookup_circuit_details( packet_info *pinfo, 
717                                                  guint32 scallno,
718                                                  guint32 dcallno,
719                                                  gboolean *reversed_p,
720                                                  circuit_t **circuit_p)
721 {
722   gboolean reversed = FALSE;
723   iax_call_data *iax_call = NULL;
724   guint src_circuit_id;
725   circuit_t *src_circuit = NULL;
726
727 #ifdef DEBUG_HASHING
728   g_message( "++ iax_lookup_circuit_details: Looking up circuit for frame %u, "
729              "from {%s:%u:%u} to {%s:%u:%u}", pinfo->fd->num,
730              address_to_str(&pinfo->src),pinfo->srcport,scallno,
731              address_to_str(&pinfo->dst),pinfo->destport,dcallno);
732 #endif
733
734
735   src_circuit_id = iax_circuit_lookup(&pinfo->src,pinfo->ptype,
736                                       pinfo->srcport,scallno);
737
738
739   /* the most reliable indicator of call is the destination callno, if
740      we have one */
741   if( dcallno != 0 ) {
742     guint dst_circuit_id;
743 #ifdef DEBUG_HASHING
744     g_message( "++ dcallno non-zero, looking up destination circuit" );
745 #endif
746
747     dst_circuit_id = iax_circuit_lookup(&pinfo->dst,pinfo->ptype,
748                                         pinfo->destport,dcallno);
749
750     iax_call = iax_lookup_circuit_details_from_dest(src_circuit_id, dst_circuit_id, pinfo->fd->num, &reversed, &src_circuit);
751   } else {
752
753     /* in all other circumstances, the source circuit should already
754      * exist: its absense indicates that we missed the all-important NEW
755      * packet.
756      */
757
758     src_circuit = find_circuit( CT_IAX2,
759                             src_circuit_id,
760                             pinfo->fd->num );
761
762     if( src_circuit ) {
763       iax_call = (iax_call_data *)circuit_get_proto_data(src_circuit,proto_iax2);
764
765       /* there's no way we can create a CT_IAX2 circuit without adding
766          iax call data to it; assert this */
767       DISSECTOR_ASSERT(iax_call);
768
769       if( src_circuit_id == iax_call -> forward_circuit_id )
770         reversed = FALSE;
771       else if ( src_circuit_id == iax_call -> reverse_circuit_id )
772         reversed = TRUE;
773       else {
774         /* there's also no way we can attach an iax_call_data to a circuit
775            without the circuit being either the forward or reverse circuit
776            for that call; assert this too.
777         */
778         DISSECTOR_ASSERT_NOT_REACHED();
779       }
780     }
781   }
782
783   if(src_circuit && iax_call) {
784     /* info for subdissectors. We always pass on the forward circuit,
785      * and steal the p2p_dir flag to indicate the direction */
786     pinfo -> ctype = CT_IAX2;
787     pinfo -> circuit_id = (guint32)iax_call->forward_circuit_id;
788     pinfo -> p2p_dir = reversed?P2P_DIR_RECV:P2P_DIR_SENT;
789   }
790
791   if(reversed_p)
792     *reversed_p = reversed;
793
794   if(circuit_p)
795     *circuit_p = src_circuit;
796
797 #ifdef DEBUG_HASHING
798   if( iax_call ) {
799     g_message( "++ Found call for packet: id %u, reversed=%c", iax_call->callno, reversed?'1':'0' );
800   } else {
801     g_message( "++ Call not found. Must have missed the NEW packet?" );
802   }
803 #endif
804   
805   return iax_call;
806 }
807
808
809 /* handles a NEW packet by creating a new iax call and forward circuit.
810    the reverse circuit is not created until the ACK is received and
811    is created by iax_lookup_circuit_details. */
812 static iax_call_data *iax_new_circuit_details( packet_info *pinfo, 
813                                               guint32 scallno,
814                                               circuit_t **circuit_p)
815 {
816   circuit_t *circuit;
817   iax_call_data *call;
818   guint circuit_id;
819     
820 #ifdef DEBUG_HASHING
821   g_message( "+ new_circuit: Handling NEW packet, frame %u", pinfo->fd->num );
822 #endif
823   
824     circuit_id = iax_circuit_lookup(&pinfo->src,pinfo->ptype,
825                                     pinfo->srcport,scallno);
826     
827     circuit = circuit_new(CT_IAX2,
828                           circuit_id,
829                           pinfo->fd->num );
830
831     
832
833     call = g_mem_chunk_alloc(iax_call_datas);
834     call -> dataformat = 0;
835     call -> src_codec = 0;
836     call -> dst_codec = 0;
837     call -> forward_circuit_id = circuit_id;
838     call -> reverse_circuit_id = 0;
839     call -> callno = ++callcount;
840
841 #ifdef DEBUG_HASHING
842     g_message( "+ new_circuit: Added new circuit for new call %u", call -> callno );
843 #endif
844
845     circuit_add_proto_data( circuit, proto_iax2, call );
846
847   if( circuit_p )
848     *circuit_p = circuit;
849
850   return call;
851 }
852     
853
854 /* ************************************************************************* */
855
856 /* per-packet data */
857 typedef struct iax_packet_data {
858   iax_call_data *call_data;
859   guint32 codec;
860 } iax_packet_data;
861
862 static GMemChunk *iax_packets = NULL;
863
864 static iax_packet_data *iax_new_packet_data(iax_call_data *call)
865 {
866   iax_packet_data *p = g_mem_chunk_alloc(iax_packets);
867   p->call_data=call;
868   p->codec=0;
869   return p;
870 }
871
872
873 /* ************************************************************************* */
874
875 static guint32 dissect_fullpacket (tvbuff_t * tvb, guint32 offset,
876                                 guint16 scallno,
877                                 packet_info * pinfo,
878                                 proto_tree * iax2_tree,
879                                 proto_tree * main_tree);
880
881
882 static guint32 dissect_minipacket (tvbuff_t * tvb, guint32 offset, 
883                                 guint16 scallno,
884                                 packet_info * pinfo,
885                                 proto_tree * iax2_tree,
886                                 proto_tree * main_tree);
887
888 static guint32 dissect_minivideopacket (tvbuff_t * tvb, guint32 offset, 
889                                         guint16 scallno,
890                                         packet_info * pinfo,
891                                         proto_tree * iax2_tree,
892                                         proto_tree * main_tree);
893
894 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
895                             packet_info *pinfo, proto_tree *tree,
896                             guint32 ts, gboolean video,
897                             iax_packet_data *iax_packet);
898
899
900
901 static void
902 dissect_iax2 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
903 {
904   proto_item *iax2_item = NULL;
905   proto_tree *iax2_tree = NULL;
906   proto_tree *full_mini_subtree = NULL;
907   guint32 offset = 0, len;
908   guint16 scallno = 0;
909   guint16 stmp;
910   packet_type type;
911
912   /* set up the protocol and info fields in the summary pane */
913   if (check_col (pinfo->cinfo, COL_PROTOCOL))
914     {
915       col_set_str (pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_IAX2);
916     }
917   if (check_col (pinfo->cinfo, COL_INFO))
918     {
919       col_clear (pinfo->cinfo, COL_INFO);
920     }
921
922   /* add the 'iax2' tree to the main tree */
923   if (tree)
924     {
925       iax2_item = proto_tree_add_item (tree, proto_iax2, tvb, offset, -1, FALSE);
926       iax2_tree = proto_item_add_subtree (iax2_item, ett_iax2);
927     }
928
929   stmp = tvb_get_ntohs(tvb, offset);
930   if( stmp == 0 ) {
931     /* starting with 0x0000 indicates either a mini video packet or a 'meta'
932      * packet, whatever that means */
933     offset+=2;
934     stmp = tvb_get_ntohs(tvb, offset);
935     if( stmp & 0x8000 ) {
936       /* mini video packet */
937       type = IAX2_MINI_VIDEO_PACKET;
938       scallno = stmp & 0x7FFF;
939       offset += 2;
940     }
941     else {
942       type = IAX2_META_PACKET;
943     }
944   } else {
945     /* The source call/fullpacket flag is common to both mini and full packets */
946     scallno = tvb_get_ntohs(tvb, offset);
947     offset += 2;
948     if( scallno & 0x8000 )
949       type = IAX2_FULL_PACKET;
950     else {
951       type = IAX2_MINI_VOICE_PACKET;
952     }
953     scallno &= 0x7FFF;
954   }
955
956   if( tree ) {
957     proto_item *full_mini_base;
958
959     full_mini_base = proto_tree_add_uint(iax2_tree, hf_iax2_packet_type, tvb, 0, offset, type);
960     full_mini_subtree = proto_item_add_subtree(full_mini_base, ett_iax2_full_mini_subtree);
961
962     if( scallno != 0 )
963       proto_tree_add_item (full_mini_subtree, hf_iax2_scallno, tvb, offset-2, 2, FALSE);
964   }
965
966   switch( type ) {
967     case IAX2_FULL_PACKET:
968       len = dissect_fullpacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
969       break;
970     case IAX2_MINI_VOICE_PACKET:
971       len = dissect_minipacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
972       break;
973     case IAX2_MINI_VIDEO_PACKET:
974       len = dissect_minivideopacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
975       break;
976     case IAX2_META_PACKET:
977       /* not implemented yet */
978       len = 0;
979       break;
980     default:
981       len = 0;
982   }
983
984   /* update the 'length' of the main IAX2 header field so that it covers just the headers,
985      not the audio data. */
986   proto_item_set_len(iax2_item, len);
987 }
988
989
990 /* dissect the information elements in an IAX frame. Returns the updated offset */
991 static guint32 dissect_ies (tvbuff_t * tvb, guint32 offset,
992                             proto_tree * iax_tree,
993                             iax_call_data *iax_call_data )
994 {
995   proto_tree *sockaddr_tree = NULL;
996   proto_item *sockaddr_item = 0;
997
998
999   while (offset < tvb_reported_length (tvb)) {
1000
1001     int ies_type = tvb_get_guint8(tvb, offset);
1002     int ies_len = tvb_get_guint8(tvb, offset + 1);
1003
1004     if( iax_tree ) {
1005       proto_item *ti;
1006       proto_tree *ies_tree;
1007
1008       ti = proto_tree_add_text(iax_tree, tvb, offset, ies_len+2,
1009                                "Information Element: %s (0x%02X)",
1010                                val_to_str(ies_type, iax_ies_type, 
1011                                           "Unknown information element"),
1012                                ies_type);
1013
1014
1015       ies_tree = proto_item_add_subtree(ti, ett_iax2_ie);
1016       
1017       proto_tree_add_text(ies_tree, tvb, offset, 1, "IE id: %s (0x%02X)",
1018                           val_to_str(ies_type, iax_ies_type, "Unknown"),
1019                           ies_type);
1020
1021       proto_tree_add_text(ies_tree, tvb, offset+1, 1, "Length: %u",ies_len);
1022
1023
1024       switch (ies_type) {
1025             case IAX_IE_CALLED_NUMBER:
1026               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLED_NUMBER, tvb,
1027                                    offset + 2, ies_len, FALSE);
1028               break;
1029             case IAX_IE_CALLING_NUMBER:
1030               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_NUMBER,
1031                                    tvb, offset + 2, ies_len, FALSE);
1032               break;
1033             case IAX_IE_CALLING_ANI:
1034               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_ANI, tvb,
1035                                    offset + 2, ies_len, FALSE);
1036               break;
1037             case IAX_IE_CALLING_NAME:
1038               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_NAME, tvb,
1039                                    offset + 2, ies_len, FALSE);
1040               break;
1041             case IAX_IE_CALLED_CONTEXT:
1042               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLED_CONTEXT,
1043                                    tvb, offset + 2, ies_len, FALSE);
1044               break;
1045             case IAX_IE_USERNAME:
1046               proto_tree_add_item (ies_tree, hf_IAX_IE_USERNAME, tvb,
1047                                    offset + 2, ies_len, FALSE);
1048               break;
1049             case IAX_IE_PASSWORD:
1050               proto_tree_add_item (ies_tree, hf_IAX_IE_PASSWORD, tvb,
1051                                    offset + 2, ies_len, FALSE);
1052               break;
1053             case IAX_IE_LANGUAGE:
1054               proto_tree_add_item (ies_tree, hf_IAX_IE_LANGUAGE, tvb,
1055                                    offset + 2, ies_len, FALSE);
1056               break;
1057             case IAX_IE_DNID:
1058               proto_tree_add_item (ies_tree, hf_IAX_IE_DNID, tvb,
1059                                    offset + 2, ies_len, FALSE);
1060               break;
1061             case IAX_IE_CHALLENGE:
1062               proto_tree_add_item (ies_tree, hf_IAX_IE_CHALLENGE, tvb,
1063                                    offset + 2, ies_len, FALSE);
1064               break;
1065             case IAX_IE_MD5_RESULT:
1066               proto_tree_add_item (ies_tree, hf_IAX_IE_MD5_RESULT, tvb,
1067                                    offset + 2, ies_len, FALSE);
1068               break;
1069             case IAX_IE_RSA_RESULT:
1070               proto_tree_add_item (ies_tree, hf_IAX_IE_RSA_RESULT, tvb,
1071                                    offset + 2, ies_len, FALSE);
1072               break;
1073             case IAX_IE_RDNIS:
1074               proto_tree_add_item (ies_tree, hf_IAX_IE_RDNIS, tvb,
1075                                    offset + 2, ies_len, FALSE);
1076               break;
1077             case IAX_IE_CAPABILITY:
1078             {
1079               proto_tree *codec_tree;
1080               proto_item *codec_base;
1081
1082               if (ies_len != 4) THROW(ReportedBoundsError);
1083               codec_base =
1084                 proto_tree_add_item (ies_tree, hf_IAX_IE_CAPABILITY,
1085                                      tvb, offset + 2, ies_len, FALSE);
1086               codec_tree =
1087                 proto_item_add_subtree (codec_base, ett_iax2_codecs);
1088               
1089               proto_tree_add_item(codec_tree, hf_iax2_cap_g723_1, tvb, offset + 2, ies_len, FALSE );
1090               proto_tree_add_item(codec_tree, hf_iax2_cap_gsm, tvb, offset + 2, ies_len, FALSE );
1091               proto_tree_add_item(codec_tree, hf_iax2_cap_ulaw, tvb, offset + 2, ies_len, FALSE );
1092               proto_tree_add_item(codec_tree, hf_iax2_cap_alaw, tvb, offset + 2, ies_len, FALSE );
1093               proto_tree_add_item(codec_tree, hf_iax2_cap_g726, tvb, offset + 2, ies_len, FALSE );
1094               proto_tree_add_item(codec_tree, hf_iax2_cap_adpcm, tvb, offset + 2, ies_len, FALSE );
1095               proto_tree_add_item(codec_tree, hf_iax2_cap_slinear, tvb, offset + 2, ies_len, FALSE );
1096               proto_tree_add_item(codec_tree, hf_iax2_cap_lpc10, tvb, offset + 2, ies_len, FALSE );
1097               proto_tree_add_item(codec_tree, hf_iax2_cap_g729a, tvb, offset + 2, ies_len, FALSE );
1098               proto_tree_add_item(codec_tree, hf_iax2_cap_speex, tvb, offset + 2, ies_len, FALSE );
1099               proto_tree_add_item(codec_tree, hf_iax2_cap_ilbc, tvb, offset + 2, ies_len, FALSE );
1100               proto_tree_add_item(codec_tree, hf_iax2_cap_jpeg, tvb, offset + 2, ies_len, FALSE );
1101               proto_tree_add_item(codec_tree, hf_iax2_cap_png, tvb, offset + 2, ies_len, FALSE );
1102               proto_tree_add_item(codec_tree, hf_iax2_cap_h261, tvb, offset + 2, ies_len, FALSE );
1103               proto_tree_add_item(codec_tree, hf_iax2_cap_h263, tvb, offset + 2, ies_len, FALSE );
1104               break;
1105             }
1106             case IAX_IE_FORMAT:
1107               if (ies_len != 4) THROW(ReportedBoundsError);
1108               proto_tree_add_item (ies_tree, hf_IAX_IE_FORMAT, tvb,
1109                                    offset + 2, ies_len, FALSE);
1110               break;
1111             case IAX_IE_VERSION:
1112               if (ies_len != 2) THROW(ReportedBoundsError);
1113               proto_tree_add_item (ies_tree, hf_IAX_IE_VERSION, tvb,
1114                                    offset + 2, ies_len, FALSE);
1115               break;
1116             case IAX_IE_ADSICPE:
1117               if (ies_len != 2) THROW(ReportedBoundsError);
1118               proto_tree_add_item (ies_tree, hf_IAX_IE_ADSICPE, tvb,
1119                                    offset + 2, ies_len, FALSE);
1120               break;
1121             case IAX_IE_AUTHMETHODS:
1122               if (ies_len != 2) THROW(ReportedBoundsError);
1123               proto_tree_add_item (ies_tree, hf_IAX_IE_AUTHMETHODS, tvb,
1124                                    offset + 2, ies_len, FALSE);
1125               break;
1126             case IAX_IE_APPARENT_ADDR:
1127               sockaddr_item = proto_tree_add_text(ies_tree, tvb, offset + 2, 16, "Apparent Address");
1128               sockaddr_tree = proto_item_add_subtree(sockaddr_item, ett_iax2_ies_apparent_addr);
1129               proto_tree_add_item(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINADDR, tvb, offset + 6, 4, FALSE);
1130               proto_tree_add_item(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINPORT, tvb, offset + 4, 2, FALSE);
1131               break;
1132             case IAX_IE_REFRESH:
1133               if (ies_len != 2) THROW(ReportedBoundsError);
1134               proto_tree_add_item (ies_tree, hf_IAX_IE_REFRESH, tvb,
1135                                    offset + 2, ies_len, FALSE);
1136               break;
1137             case IAX_IE_DPSTATUS:
1138               if (ies_len != 2) THROW(ReportedBoundsError);
1139               proto_tree_add_item (ies_tree, hf_IAX_IE_DPSTATUS, tvb,
1140                                    offset + 2, ies_len, FALSE);
1141               break;
1142             case IAX_IE_CALLNO:
1143               if (ies_len != 2) THROW(ReportedBoundsError);
1144               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLNO, tvb,
1145                                    offset + 2, ies_len, FALSE);
1146               break;
1147             case IAX_IE_CAUSE:
1148               proto_tree_add_item (ies_tree, hf_IAX_IE_CAUSE, tvb,
1149                                    offset + 2, ies_len, FALSE);
1150               break;
1151             case IAX_IE_IAX_UNKNOWN:
1152               proto_tree_add_item (ies_tree, hf_IAX_IE_IAX_UNKNOWN, tvb,
1153                                    offset + 2, ies_len, FALSE);
1154               break;
1155             case IAX_IE_MSGCOUNT:
1156               if (ies_len != 2) THROW(ReportedBoundsError);
1157               proto_tree_add_item (ies_tree, hf_IAX_IE_MSGCOUNT, tvb,
1158                                    offset + 2, ies_len, FALSE);
1159               break;
1160             case IAX_IE_AUTOANSWER:
1161               proto_tree_add_item (ies_tree, hf_IAX_IE_AUTOANSWER, tvb,
1162                                    offset + 2, ies_len, FALSE);
1163               break;
1164             case IAX_IE_MUSICONHOLD:
1165               proto_tree_add_item (ies_tree, hf_IAX_IE_MUSICONHOLD, tvb,
1166                                    offset + 2, ies_len, FALSE);
1167               break;
1168             case IAX_IE_TRANSFERID:
1169               if (ies_len != 4) THROW(ReportedBoundsError);
1170               proto_tree_add_item (ies_tree, hf_IAX_IE_TRANSFERID, tvb,
1171                                    offset + 2, ies_len, FALSE);
1172               break;
1173             case IAX_IE_PROVISIONING:
1174               proto_tree_add_item (ies_tree, hf_IAX_IE_PROVISIONING, tvb,
1175                                   offset +2, ies_len, FALSE);
1176               break;
1177             case IAX_IE_AESPROVISIONING:
1178               proto_tree_add_item (ies_tree, hf_IAX_IE_AESPROVISIONING, tvb,
1179                                   offset +2, ies_len, FALSE);
1180               break;
1181             case IAX_IE_DATETIME:
1182               if (ies_len != 2) THROW(ReportedBoundsError);
1183               proto_tree_add_item (ies_tree, hf_IAX_IE_DATETIME, tvb,
1184                                   offset +2, ies_len, FALSE);
1185               break;
1186             case IAX_IE_DEVICETYPE:
1187               proto_tree_add_item (ies_tree, hf_IAX_IE_DEVICETYPE, tvb,
1188                                   offset +2, ies_len, FALSE);
1189               break;
1190             case IAX_IE_SERVICEIDENT:
1191               proto_tree_add_item (ies_tree, hf_IAX_IE_SERVICEIDENT, tvb,
1192                                   offset +2, ies_len, FALSE);
1193               break;
1194             case IAX_IE_FIRMWAREVER:
1195               if (ies_len != 2) THROW(ReportedBoundsError);
1196               proto_tree_add_item (ies_tree, hf_IAX_IE_FIRMWAREVER, tvb,
1197                                   offset +2, ies_len, FALSE);
1198               break;
1199             case IAX_IE_FWBLOCKDESC:
1200               if (ies_len != 4) THROW(ReportedBoundsError);
1201               proto_tree_add_item (ies_tree, hf_IAX_IE_FWBLOCKDESC, tvb,
1202                                   offset +2, ies_len, FALSE);
1203               break;
1204             case IAX_IE_FWBLOCKDATA:
1205               proto_tree_add_item (ies_tree, hf_IAX_IE_FWBLOCKDATA, tvb,
1206                                   offset +2, ies_len, FALSE);
1207               break;
1208             case IAX_IE_PROVVER:
1209               if (ies_len != 4) THROW(ReportedBoundsError);
1210               proto_tree_add_item (ies_tree, hf_IAX_IE_PROVVER, tvb,
1211                                   offset +2, ies_len, FALSE);
1212               break;
1213             case IAX_IE_CALLINGPRES:
1214               if (ies_len != 1) THROW(ReportedBoundsError);
1215               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLINGPRES, tvb,
1216                                   offset +2, ies_len, FALSE);
1217               break;
1218             case IAX_IE_CALLINGTON:
1219               if (ies_len != 1) THROW(ReportedBoundsError);
1220               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLINGTON, tvb,
1221                                   offset +2, ies_len, FALSE);
1222               break;
1223             case IAX_IE_CALLINGTNS:
1224               if (ies_len != 2) THROW(ReportedBoundsError);
1225               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLINGTNS, tvb,
1226                                   offset +2, ies_len, FALSE);
1227               break;
1228             case IAX_IE_SAMPLINGRATE:
1229               if (ies_len != 2) THROW(ReportedBoundsError);
1230               proto_tree_add_item (ies_tree, hf_IAX_IE_SAMPLINGRATE, tvb,
1231                                   offset +2, ies_len, FALSE);
1232               break;
1233             case IAX_IE_CAUSECODE:
1234               if (ies_len != 1) THROW(ReportedBoundsError);
1235               proto_tree_add_item (ies_tree, hf_IAX_IE_CAUSECODE, tvb,
1236                                    offset +2, ies_len, FALSE);
1237               break;
1238             case IAX_IE_ENCRYPTION:
1239               if (ies_len != 2) THROW(ReportedBoundsError);
1240               proto_tree_add_item (ies_tree, hf_IAX_IE_ENCRYPTION, tvb,
1241                                   offset +2, ies_len, FALSE);
1242               break;
1243             case IAX_IE_ENCKEY:
1244               proto_tree_add_item (ies_tree, hf_IAX_IE_ENCKEY, tvb,
1245                                   offset +2, ies_len, FALSE);
1246               break;
1247             case IAX_IE_CODEC_PREFS:
1248               proto_tree_add_item (ies_tree, hf_IAX_IE_CODEC_PREFS, tvb,
1249                                   offset +2, ies_len, FALSE);
1250               break;
1251             case IAX_IE_RR_JITTER:
1252               if (ies_len != 4) THROW(ReportedBoundsError);
1253               proto_tree_add_item (ies_tree, hf_IAX_IE_RR_JITTER, tvb,
1254                                   offset +2, ies_len, FALSE);
1255               break;
1256             case IAX_IE_RR_LOSS:
1257               if (ies_len != 4) THROW(ReportedBoundsError);
1258               proto_tree_add_item (ies_tree, hf_IAX_IE_RR_LOSS, tvb,
1259                                   offset +2, ies_len, FALSE);
1260               break;
1261             case IAX_IE_RR_PKTS:
1262               if (ies_len != 4) THROW(ReportedBoundsError);
1263               proto_tree_add_item (ies_tree, hf_IAX_IE_RR_PKTS, tvb,
1264                                   offset +2, ies_len, FALSE);
1265               break;
1266             case IAX_IE_RR_DELAY:
1267               if (ies_len != 2) THROW(ReportedBoundsError);
1268               proto_tree_add_item (ies_tree, hf_IAX_IE_RR_DELAY, tvb,
1269                                   offset +2, ies_len, FALSE);
1270               break;
1271             case IAX_IE_RR_DROPPED:
1272               if (ies_len != 4) THROW(ReportedBoundsError);
1273               proto_tree_add_item (ies_tree, hf_IAX_IE_RR_DROPPED, tvb,
1274                                   offset +2, ies_len, FALSE);
1275               break;
1276             case IAX_IE_RR_OOO:
1277               if (ies_len != 4) THROW(ReportedBoundsError);
1278               proto_tree_add_item (ies_tree, hf_IAX_IE_RR_OOO, tvb,
1279                                   offset +2, ies_len, FALSE);
1280               break;
1281               
1282       case IAX_IE_DATAFORMAT:
1283         if (ies_len != 4) THROW(ReportedBoundsError);
1284         proto_tree_add_item (ies_tree, hf_IAX_IE_DATAFORMAT, tvb,
1285                              offset + 2, ies_len, FALSE);
1286
1287         if( iax_call_data )
1288           iax_call_data -> dataformat = tvb_get_ntohl(tvb, offset+2);
1289             
1290         break;
1291
1292       default:
1293       {
1294         switch(ies_len) {
1295         case 1:
1296           proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_BYTE, tvb, offset+2, ies_len, FALSE );
1297           break;
1298           
1299         case 2:
1300           proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_I16, tvb, offset+2, ies_len, FALSE );
1301           break;
1302         
1303         case 4:
1304           proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_I32, tvb, offset+2, ies_len, FALSE );
1305           break;
1306
1307         default:
1308           proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_BYTES, tvb, offset+2, ies_len, FALSE );
1309         }
1310       }
1311       }
1312     }
1313     offset += ies_len + 2;
1314   }
1315   return offset;
1316 }
1317
1318 static guint32 uncompress_subclass(guint8 csub)
1319 {
1320   /* If the SC_LOG flag is set, return 2^csub otherwise csub */
1321   if (csub & 0x80) {
1322     /* special case for 'compressed' -1 */
1323     if (csub == 0xff)
1324       return (guint32)-1;
1325     else
1326       return 1 << (csub & 0x1F);
1327   }
1328   else
1329     return (guint32)csub;
1330 }
1331
1332
1333 static guint32
1334 dissect_fullpacket (tvbuff_t * tvb, guint32 offset, 
1335                     guint16 scallno,
1336                     packet_info * pinfo, proto_tree * iax2_tree,
1337                     proto_tree * main_tree)
1338 {
1339   guint32 retransmission = 0;
1340   guint16 dcallno;
1341   guint32 ts;
1342   guint8 type;
1343   guint8 csub;
1344   guint32 codec;
1345
1346   proto_tree *packet_type_tree = NULL;
1347   iax_call_data *iax_call;
1348   iax_packet_data *iax_packet;
1349   gboolean reversed;
1350   gboolean rtp_marker;
1351
1352   circuit_t *circuit;
1353
1354   /*
1355    * remove the top bit for retransmission detection 
1356    */
1357   dcallno = tvb_get_ntohs(tvb, offset);
1358   retransmission = dcallno & 0x8000;
1359   dcallno = dcallno & 0x7FFF;
1360   ts = tvb_get_ntohl(tvb, offset+2);
1361   type = tvb_get_guint8(tvb, offset + 8);
1362   csub = tvb_get_guint8(tvb, offset + 9);
1363
1364   /* see if we've seen this packet before */
1365   iax_packet = (iax_packet_data *)p_get_proto_data(pinfo->fd,proto_iax2);
1366   if( !iax_packet ) {
1367     /* if not, find or create an iax_call info structure for this IAX session. */
1368
1369     if( type == AST_FRAME_IAX && csub == IAX_COMMAND_NEW ) {
1370       /* NEW packets start a new call */
1371       iax_call = iax_new_circuit_details(pinfo,scallno,&circuit);
1372       reversed = FALSE;
1373     } else {
1374       iax_call = iax_lookup_circuit_details(pinfo, scallno, dcallno,
1375                                        &reversed, &circuit);
1376     }
1377
1378     iax_packet = iax_new_packet_data(iax_call);
1379     p_add_proto_data(pinfo->fd,proto_iax2,iax_packet);
1380   } else {
1381     iax_call = iax_packet->call_data;
1382
1383     /*
1384      * XXX - the code needs to set "circuit" and "reversed" somehow here,
1385      * by determining them based on values in "iax_call" or "iax_packet".
1386      * I leave that as an exercise for somebody who wants to maintain
1387      * this code.
1388      */
1389     circuit = NULL;
1390     reversed = FALSE;
1391   }
1392    
1393   if( iax2_tree ) {
1394       proto_item *packet_type_base;
1395
1396       proto_tree_add_item (iax2_tree, hf_iax2_dcallno, tvb, offset, 2, FALSE );
1397       proto_tree_add_boolean(iax2_tree, hf_iax2_retransmission, tvb, offset, 2, FALSE );
1398
1399       proto_tree_add_uint (iax2_tree, hf_iax2_ts, tvb, offset+2, 4, ts);
1400
1401       proto_tree_add_item (iax2_tree, hf_iax2_oseqno, tvb, offset+6, 1,
1402                            FALSE);
1403
1404       proto_tree_add_item (iax2_tree, hf_iax2_iseqno, tvb, offset+7, 1,
1405                            FALSE);
1406       packet_type_base = proto_tree_add_uint (iax2_tree, hf_iax2_type, tvb,
1407                                               offset+8, 1, type);
1408
1409       /* add the type-specific subtree */
1410       packet_type_tree = proto_item_add_subtree (packet_type_base, ett_iax2_type);
1411   }
1412
1413   /* add frame type to info line */
1414   if (check_col (pinfo->cinfo, COL_INFO)) {
1415     col_add_fstr (pinfo->cinfo, COL_INFO, "%s, source call# %d, timestamp %ums",
1416                   val_to_str (type, iax_frame_types, "Unknown (0x%02x)"),
1417                   scallno, ts);
1418   }
1419
1420   switch( type ) {
1421   case AST_FRAME_IAX:
1422     /* add the subclass */
1423     proto_tree_add_uint (packet_type_tree, hf_iax2_iax_csub, tvb,
1424                            offset+9, 1, csub);
1425     offset += 10;
1426
1427     if (check_col (pinfo->cinfo, COL_INFO))
1428       col_append_fstr (pinfo->cinfo, COL_INFO, " %s", 
1429                     val_to_str (csub, iax_iax_subclasses, "unknown (0x%02x)"));
1430
1431     if (offset < tvb_reported_length (tvb)) {
1432       offset += dissect_ies(tvb, offset, packet_type_tree, iax_call);
1433     }
1434
1435     if( csub == IAX_COMMAND_NEW && circuit && iax_call ) {
1436       /* if this is a data call, set up a subdissector for the circuit */
1437       dissector_handle_t s;
1438       s = dissector_get_port_handle(iax2_dataformat_dissector_table, iax_call -> dataformat );
1439       circuit_set_dissector( circuit, s );
1440     }
1441     break;
1442
1443   case AST_FRAME_DTMF:
1444     proto_tree_add_text (packet_type_tree, tvb, offset+9, 1, "DTMF digit: %c", csub);
1445     offset += 10;
1446
1447     if (check_col (pinfo->cinfo, COL_INFO))
1448       col_append_fstr (pinfo->cinfo, COL_INFO, " digit %c", csub );
1449     break;
1450
1451   case AST_FRAME_CONTROL:
1452     /* add the subclass */
1453     proto_tree_add_uint (packet_type_tree, hf_iax2_cmd_csub, tvb,
1454                          offset+9, 1, csub);
1455     offset += 10;
1456
1457     if (check_col (pinfo->cinfo, COL_INFO))
1458       col_append_fstr (pinfo->cinfo, COL_INFO, " %s",
1459                     val_to_str (csub, iax_cmd_subclasses, "unknown (0x%02x)"));
1460     break;
1461
1462   case AST_FRAME_VOICE:
1463     /* add the codec */
1464     iax_packet -> codec = codec = uncompress_subclass(csub);
1465
1466     if( packet_type_tree ) {
1467       proto_tree_add_item (packet_type_tree, hf_iax2_voice_csub, tvb, offset+9, 1, FALSE);
1468       proto_tree_add_uint (packet_type_tree, hf_iax2_voice_codec, tvb, offset+9, 1, codec);
1469     }
1470
1471     offset += 10;
1472
1473     if( iax_call ) {
1474       if( reversed ) {
1475         iax_call->dst_codec = codec;
1476       } else {
1477         iax_call->src_codec = codec;
1478       }
1479     }
1480
1481     dissect_payload(tvb, offset, pinfo, main_tree, ts, FALSE,iax_packet);
1482     break;
1483
1484   case AST_FRAME_VIDEO:
1485     /* bit 6 of the csub is used to represent the rtp 'marker' bit */
1486     rtp_marker = csub & 0x40 ? TRUE:FALSE;
1487     iax_packet -> codec = codec = uncompress_subclass((guint8) (csub & ~40));
1488
1489     if( packet_type_tree ) {
1490       proto_tree_add_item (packet_type_tree, hf_iax2_video_csub, tvb, offset+9, 1, FALSE);
1491       proto_tree_add_item (packet_type_tree, hf_iax2_marker, tvb, offset+9, 1, FALSE);
1492       proto_tree_add_uint (packet_type_tree, hf_iax2_video_codec, tvb, offset+9, 1, codec);
1493     }
1494
1495     offset += 10;
1496
1497     if( iax_call ) {
1498       if( reversed ) {
1499         iax_call->dst_vformat = codec;
1500       } else {
1501         iax_call->src_vformat = codec;
1502       }
1503     }
1504
1505     if( rtp_marker && check_col (pinfo->cinfo, COL_INFO))
1506       col_append_fstr (pinfo->cinfo, COL_INFO, ", Mark" );
1507
1508
1509     dissect_payload(tvb, offset, pinfo, main_tree, ts, TRUE, iax_packet);
1510     break;
1511
1512
1513   default:
1514     proto_tree_add_uint (packet_type_tree, hf_iax2_csub, tvb, offset+9,
1515                          1, csub);
1516     offset += 10;
1517
1518     if (check_col (pinfo->cinfo, COL_INFO))
1519       col_append_fstr (pinfo->cinfo, COL_INFO, " subclass %d", csub );
1520     break;
1521   }
1522
1523   return offset;
1524 }
1525
1526 static iax_packet_data *iax2_get_packet_data_for_minipacket(packet_info * pinfo,
1527                                                             guint16 scallno,
1528                                                             gboolean video)
1529 {
1530   /* see if we've seen this packet before */
1531   iax_packet_data *p = (iax_packet_data *)p_get_proto_data(pinfo->fd,proto_iax2);
1532
1533   if( !p ) {
1534     /* if not, find or create an iax_call info structure for this IAX session. */
1535     gboolean reversed;
1536     circuit_t *circuit;
1537     iax_call_data *iax_call;
1538
1539     iax_call = iax_lookup_circuit_details(pinfo, scallno, 0, &reversed, &circuit);
1540
1541     p = iax_new_packet_data(iax_call);
1542     p_add_proto_data(pinfo->fd,proto_iax2,p);
1543
1544     /* set the codec for this frame to be whatever the last full frame used */
1545     if( iax_call ) {
1546      if( video ) 
1547         p->codec = reversed ? iax_call -> dst_vformat : iax_call -> src_vformat;
1548       else 
1549         p->codec = reversed ? iax_call -> dst_codec : iax_call -> src_codec;
1550     }
1551   }
1552   return p;
1553 }
1554
1555
1556 static guint32 dissect_minivideopacket (tvbuff_t * tvb, guint32 offset,
1557                                         guint16 scallno, packet_info * pinfo,
1558                                         proto_tree * iax2_tree, proto_tree *main_tree)
1559 {
1560   guint32 ts;
1561   iax_packet_data *iax_packet;
1562   gboolean rtp_marker;
1563
1564   ts = tvb_get_ntohs(tvb, offset);
1565
1566   /* bit 15 of the ts is used to represent the rtp 'marker' bit */
1567   rtp_marker = ts & 0x8000 ? TRUE:FALSE;
1568   ts &= ~0x8000;
1569
1570
1571   if( iax2_tree ) {
1572     proto_tree_add_item (iax2_tree, hf_iax2_minividts, tvb, offset, 2, FALSE);
1573     proto_tree_add_item (iax2_tree, hf_iax2_minividmarker, tvb, offset, 2, FALSE);
1574   }
1575
1576   offset += 2;
1577   
1578   iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, TRUE);
1579   
1580   if (check_col (pinfo->cinfo, COL_INFO))
1581       col_add_fstr (pinfo->cinfo, COL_INFO, 
1582                     "Mini video packet, source call# %d, timestamp %ums%s",
1583                     scallno, ts, rtp_marker?", Mark":"");
1584
1585
1586   dissect_payload(tvb, offset, pinfo, main_tree, ts, TRUE, iax_packet);
1587
1588   return offset;
1589 }
1590
1591 static guint32
1592 dissect_minipacket (tvbuff_t * tvb, guint32 offset, guint16 scallno, packet_info * pinfo, proto_tree * iax2_tree,
1593                     proto_tree *main_tree)
1594 {
1595   guint32 ts;
1596   iax_packet_data *iax_packet;
1597
1598   ts = tvb_get_ntohs(tvb, offset);
1599
1600   iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, FALSE);
1601   
1602   proto_tree_add_uint (iax2_tree, hf_iax2_minits, tvb, offset, 2,
1603                        ts);
1604   offset += 2;
1605   
1606   if (check_col (pinfo->cinfo, COL_INFO))
1607       col_add_fstr (pinfo->cinfo, COL_INFO, 
1608                     "Mini packet, source call# %d, timestamp %ums",
1609                     scallno, ts);
1610
1611
1612   /* XXX fix the timestamp logic */
1613   dissect_payload(tvb, offset, pinfo, main_tree, ts, FALSE, iax_packet);
1614
1615
1616   return offset;
1617 }
1618
1619 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
1620                             packet_info *pinfo, proto_tree *tree,
1621                             guint32 ts, gboolean video,
1622                             iax_packet_data *iax_packet)
1623 {
1624   gboolean out_of_order = FALSE;
1625   tvbuff_t *sub_tvb;
1626   guint32 codec = iax_packet -> codec;
1627   iax_call_data *iax_call = iax_packet -> call_data;
1628
1629   /* keep compiler quiet */
1630   ts = ts;
1631
1632   if( offset >= tvb_reported_length (tvb)) {
1633     if (check_col (pinfo->cinfo, COL_INFO))
1634       col_append_fstr (pinfo->cinfo, COL_INFO, ", empty frame" );
1635     return;
1636   }
1637
1638   sub_tvb = tvb_new_subset(tvb, offset, -1, -1 );
1639
1640   /* XXX shouldn't pass through out-of-order packets. */
1641
1642   if (check_col (pinfo->cinfo, COL_INFO)) {
1643     if( !video && iax_call && iax_call -> dataformat != 0 ) {
1644       col_append_fstr (pinfo->cinfo, COL_INFO, ", data, format %s",
1645                        val_to_str (iax_call -> dataformat, 
1646                                    iax_dataformats, "unknown (0x%02x)"));
1647
1648       if( out_of_order )
1649         col_append_fstr (pinfo->cinfo, COL_INFO, " (out-of-order packet)");
1650     } else {
1651       col_append_fstr (pinfo->cinfo, COL_INFO, ", %s",
1652                        val_to_str (codec, codec_types, "unknown (0x%02x)"));
1653     }
1654   }
1655
1656   /* pass the rest of the block to a subdissector */
1657   if( !video && try_circuit_dissector(pinfo->ctype, pinfo->circuit_id, pinfo->fd->num,
1658                             sub_tvb, pinfo, tree))
1659     return;
1660
1661   if( codec != 0 && dissector_try_port(iax2_codec_dissector_table, codec, sub_tvb, pinfo, tree ))
1662     return;
1663   
1664   /* we don't know how to dissect our data: dissect it as data */
1665   call_dissector(data_handle,sub_tvb, pinfo, tree);
1666 }
1667
1668 /*
1669  * Init routines
1670  */
1671
1672 /* called at the start of a capture. We should clear out our static, per-capture
1673  * data.
1674  */
1675
1676 static void
1677 iax_init_protocol(void)
1678 {
1679   iax_init_hash();
1680
1681   if (iax_packets)
1682     g_mem_chunk_destroy(iax_packets);
1683   iax_packets = g_mem_chunk_create(iax_packet_data,128,G_ALLOC_ONLY);
1684 }
1685
1686
1687 void
1688 proto_register_iax2 (void)
1689 {
1690   /* we use this for displaying which codecs are supported */
1691   static const true_false_string supported_strings = {
1692     "Supported",
1693     "Not supported"
1694   };
1695
1696   /* A header field is something you can search/filter on.
1697    * 
1698    * We create a structure to register our fields. It consists of an
1699    * array of hf_register_info structures, each of which are of the format
1700    * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
1701    */
1702    
1703   static hf_register_info hf[] = {
1704
1705     {&hf_iax2_packet_type,
1706      {"Packet type", "iax2.type", FT_UINT8, BASE_DEC, VALS(iax_packet_types), 0,
1707       "Full/minivoice/minivideo/meta packet",
1708       HFILL}},
1709
1710
1711     {&hf_iax2_scallno,
1712      {"Source call", "iax2.src_call", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
1713       "src_call holds the number of this call at the packet source pbx",
1714       HFILL}},
1715
1716     /* FIXME could this be turned into a FRAMENUM field? */
1717     {&hf_iax2_dcallno,
1718      {"Destination call", "iax2.dst_call", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
1719       "dst_call holds the number of this call at the packet destination",
1720       HFILL}},
1721
1722     {&hf_iax2_retransmission,
1723      {"Retransmission", "iax2.retransmission", FT_BOOLEAN, 16,
1724       NULL, 0x8000,
1725       "retransmission is set if this packet is a retransmission of an earlier "
1726       "failed packet", HFILL}},
1727
1728     {&hf_iax2_ts,
1729      {"Timestamp", "iax2.timestamp", FT_UINT32, BASE_DEC, NULL, 0x0,
1730       "timestamp is the time, in ms after the start of this call, at which "
1731       "this packet was transmitted",
1732       HFILL}},
1733
1734     {&hf_iax2_minits,
1735      {"Timestamp", "iax2.timestamp", FT_UINT16, BASE_DEC, NULL, 0x0,
1736       "timestamp is the time, in ms after the start of this call, at which "
1737       "this packet was transmitted",
1738       HFILL}},
1739
1740     {&hf_iax2_minividts,
1741      {"Timestamp", "iax2.timestamp", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
1742       "timestamp is the time, in ms after the start of this call, at which "
1743       "this packet was transmitted",
1744       HFILL}},
1745
1746     {&hf_iax2_minividmarker,
1747      {"Marker", "iax2.video.marker", FT_UINT16, BASE_DEC, NULL, 0x8000,
1748       "RTP end-of-frame marker",
1749       HFILL}},
1750
1751     {&hf_iax2_oseqno,
1752      {"Outbound seq.no.", "iax2.oseqno", FT_UINT16, BASE_DEC, NULL,
1753       0x0, 
1754       "oseqno is the sequence no of this packet. The first packet has "
1755       "oseqno==0, and subsequent packets increment the oseqno by 1",
1756       HFILL}},
1757
1758     {&hf_iax2_iseqno,
1759      {"Inbound seq.no.", "iax2.iseqno", FT_UINT16, BASE_DEC, NULL, 0x0,
1760       "iseqno is the sequence no of the last successfully recieved packet",
1761       HFILL}},
1762
1763     {&hf_iax2_type,
1764      {"Type", "iax2.type", FT_UINT8, BASE_DEC, VALS (iax_frame_types),
1765       0x0,
1766       "For full IAX2 frames, type is the type of frame",
1767       HFILL}},
1768
1769     {&hf_iax2_csub,
1770      {"Sub-class", "iax2.subclass", FT_UINT8, BASE_DEC, NULL, 0x0, 
1771       "subclass",
1772       HFILL}},
1773
1774     {&hf_iax2_cmd_csub,
1775      {"Control subclass", "iax2.control.subclass", FT_UINT8, BASE_DEC,
1776       VALS (iax_cmd_subclasses), 0x0, 
1777       "This gives the command number for a Control packet.", HFILL}},
1778
1779     {&hf_iax2_iax_csub,
1780      {"IAX type", "iax2.iax.subclass", FT_UINT8, BASE_DEC,
1781       VALS (iax_iax_subclasses),
1782       0x0, 
1783       "IAX type gives the command number for IAX signalling packets", HFILL}},
1784
1785     {&hf_iax2_voice_csub,
1786      {"Sub-class", "iax2.voice.subclass", FT_UINT8, BASE_DEC, NULL, 0x0, 
1787       "subclass",
1788       HFILL}},
1789
1790     {&hf_iax2_voice_codec,
1791      {"CODEC", "iax2.voice.codec", FT_UINT32, BASE_HEX, VALS (codec_types),
1792       0x0, 
1793       "CODEC gives the codec used to encode audio data", HFILL}},
1794
1795     {&hf_iax2_video_csub,
1796      {"Subclass (compressed codec no)", "iax2.video.subclass", FT_UINT8, BASE_DEC, NULL, 0xBF, 
1797       "Subclass (compressed codec no)",
1798       HFILL}},
1799     
1800     {&hf_iax2_marker,
1801      {"Marker", "iax2.video.marker", FT_BOOLEAN, 8, NULL, 0x40,
1802       "RTP end-of-frame marker",
1803       HFILL}},
1804
1805     {&hf_iax2_video_codec,
1806      {"CODEC", "iax2.video.codec", FT_UINT32, BASE_HEX, VALS (codec_types), 0, 
1807       "The codec used to encode video data", HFILL}},
1808     
1809     /*
1810      * Decoding for the ies
1811      */
1812
1813     {&hf_IAX_IE_APPARENTADDR_SINFAMILY,
1814      {"Family", "iax2.iax.app_addr.sinfamily", FT_UINT16, BASE_DEC, NULL, 0, "Family", HFILL }},
1815     {&hf_IAX_IE_APPARENTADDR_SINPORT,
1816      {"Port", "iax2.iax.app_addr.sinport", FT_UINT16, BASE_DEC, NULL, 0, "Port", HFILL }},
1817     {&hf_IAX_IE_APPARENTADDR_SINADDR,
1818      {"Address", "iax2.iax.app_addr.sinaddr", FT_IPv4, BASE_HEX, NULL, 0, "Address", HFILL }},
1819     {&hf_IAX_IE_APPARENTADDR_SINZERO,
1820      {"Zero", "iax2.iax.app_addr.sinzero", FT_BYTES, BASE_HEX, NULL, 0, "Zero", HFILL }},
1821
1822     {&hf_IAX_IE_CALLED_NUMBER,
1823      {"Number/extension being called", "iax2.iax.called_number",
1824       FT_STRING,
1825       BASE_NONE, NULL, 0x0, "", HFILL}},
1826
1827     {&hf_IAX_IE_CALLING_NUMBER,
1828      {"Calling number", "iax2.iax.calling_number", FT_STRING,
1829       BASE_NONE, NULL,
1830       0x0, "", HFILL}},
1831
1832     {&hf_IAX_IE_CALLING_ANI,
1833      {"Calling number ANI for billing", "iax2.iax.calling_ani",
1834       FT_STRING,
1835       BASE_NONE, NULL, 0x0, "", HFILL}},
1836
1837     {&hf_IAX_IE_CALLING_NAME,
1838      {"Name of caller", "iax2.iax.calling_name", FT_STRING, BASE_NONE,
1839       NULL,
1840       0x0, "", HFILL}},
1841
1842     {&hf_IAX_IE_CALLED_CONTEXT,
1843      {"Context for number", "iax2.iax.called_context", FT_STRING,
1844       BASE_NONE,
1845       NULL, 0x0, "", HFILL}},
1846
1847     {&hf_IAX_IE_USERNAME,
1848      {"Username (peer or user) for authentication",
1849       "iax2.iax.username",
1850       FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1851
1852     {&hf_IAX_IE_PASSWORD,
1853      {"Password for authentication", "iax2.iax.password", FT_STRING,
1854       BASE_NONE, NULL, 0x0, "", HFILL}},
1855
1856     {&hf_IAX_IE_CAPABILITY,
1857      {"Actual codec capability", "iax2.iax.capability", FT_UINT32,
1858       BASE_HEX,
1859       NULL, 0x0, "", HFILL}},
1860
1861     {&hf_IAX_IE_FORMAT,
1862      {"Desired codec format", "iax2.iax.format", FT_UINT32, BASE_HEX,
1863       VALS (codec_types), 0x0, "", HFILL}},
1864
1865     {&hf_IAX_IE_LANGUAGE,
1866      {"Desired language", "iax2.iax.language", FT_STRING, BASE_NONE,
1867       NULL,
1868       0x0, "", HFILL}},
1869
1870     {&hf_IAX_IE_VERSION,
1871      {"Protocol version", "iax2.iax.version", FT_UINT16, BASE_HEX, NULL,
1872       0x0,
1873       "", HFILL}},
1874
1875     {&hf_IAX_IE_ADSICPE,
1876      {"CPE ADSI capability", "iax2.iax.cpe_adsi", FT_UINT16, BASE_HEX,
1877       NULL,
1878       0x0, "", HFILL}},
1879
1880     {&hf_IAX_IE_DNID,
1881      {"Originally dialed DNID", "iax2.iax.dnid", FT_STRING, BASE_NONE,
1882       NULL,
1883       0x0, "", HFILL}},
1884
1885     {&hf_IAX_IE_AUTHMETHODS,
1886      {"Authentication method(s)", "iax2.iax.auth.methods", FT_UINT16,
1887       BASE_HEX,
1888       NULL, 0x0, "", HFILL}},
1889
1890     {&hf_IAX_IE_CHALLENGE,
1891      {"Challenge data for MD5/RSA", "iax2.iax.auth.challenge",
1892       FT_STRING,
1893       BASE_NONE, NULL, 0x0, "", HFILL}},
1894
1895     {&hf_IAX_IE_MD5_RESULT,
1896      {"MD5 challenge result", "iax2.iax.auth.md5", FT_STRING,
1897       BASE_NONE, NULL,
1898       0x0, "", HFILL}},
1899
1900     {&hf_IAX_IE_RSA_RESULT,
1901      {"RSA challenge result", "iax2.iax.auth.rsa", FT_STRING,
1902       BASE_NONE, NULL,
1903       0x0, "", HFILL}},
1904
1905     {&hf_IAX_IE_REFRESH,
1906      {"When to refresh registration", "iax2.iax.refresh", FT_INT16,
1907       BASE_DEC,
1908       NULL, 0x0, "", HFILL}},
1909
1910     {&hf_IAX_IE_DPSTATUS,
1911      {"Dialplan status", "iax2.iax.dialplan_status", FT_UINT16,
1912       BASE_HEX, NULL,
1913       0x0, "", HFILL}},
1914
1915     {&hf_IAX_IE_CALLNO,
1916      {"Call number of peer", "iax2.iax.call_no", FT_INT16, BASE_DEC,
1917       NULL,
1918       0x0, "", HFILL}},
1919
1920     {&hf_IAX_IE_CAUSE,
1921      {"Cause", "iax2.iax.cause", FT_STRING, BASE_NONE, NULL, 0x0, "",
1922       HFILL}},
1923
1924     {&hf_IAX_IE_IAX_UNKNOWN,
1925      {"Unknown IAX command", "iax2.iax.iax_unknown", FT_BYTES,
1926       BASE_HEX, NULL,
1927       0x0, "", HFILL}},
1928
1929     {&hf_IAX_IE_MSGCOUNT,
1930      {"How many messages waiting", "iax2.iax.msg_count", FT_INT16,
1931       BASE_DEC,
1932       NULL, 0x0, "", HFILL}},
1933
1934     {&hf_IAX_IE_AUTOANSWER,
1935      {"Request auto-answering", "iax2.iax.autoanswer", FT_NONE,
1936       BASE_NONE,
1937       NULL, 0x0, "", HFILL}},
1938
1939     {&hf_IAX_IE_MUSICONHOLD,
1940      {"Request musiconhold with QUELCH", "iax2.iax.moh", FT_NONE,
1941       BASE_NONE,
1942       NULL, 0x0, "", HFILL}},
1943
1944     {&hf_IAX_IE_TRANSFERID,
1945      {"Transfer Request Identifier", "iax2.iax.transferid", FT_UINT32,
1946       BASE_HEX, NULL, 0x0, "", HFILL}},
1947
1948     {&hf_IAX_IE_RDNIS,
1949      {"Referring DNIS", "iax2.iax.rdnis", FT_STRING, BASE_NONE, NULL,
1950       0x0, "",
1951       HFILL}},
1952
1953     {&hf_IAX_IE_PROVISIONING,
1954      {"Provisioning info","iax2.iax.provisioning", FT_STRING, BASE_NONE,
1955        NULL, 0x0, "", HFILL}},
1956
1957     {&hf_IAX_IE_AESPROVISIONING,
1958      {"AES Provisioning info","iax2.iax.aesprovisioning", FT_STRING, BASE_NONE,
1959        NULL, 0x0, "", HFILL}},
1960
1961     {&hf_IAX_IE_DATETIME,
1962      {"Date/Time", "iax2.iax.datetime", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1963
1964     {&hf_IAX_IE_DEVICETYPE,
1965      {"Device type", "iax2.iax.devicetype", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1966
1967     {&hf_IAX_IE_SERVICEIDENT,
1968      {"Service identifier", "iax2.iax.serviceident", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1969
1970     {&hf_IAX_IE_FIRMWAREVER,
1971      {"Firmware version", "iax2.iax.firmwarever", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
1972
1973     {&hf_IAX_IE_FWBLOCKDESC,
1974      {"Firmware block description", "iax2.iax.fwblockdesc", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
1975
1976     {&hf_IAX_IE_FWBLOCKDATA,
1977      {"Firmware block of data", "iax2.iax.fwblockdata", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1978
1979     {&hf_IAX_IE_PROVVER,
1980      {"Provisioning version", "iax2.iax.provver", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
1981
1982     {&hf_IAX_IE_CALLINGPRES,
1983      {"Calling presentation", "iax2.iax.callingpres", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},
1984
1985     {&hf_IAX_IE_CALLINGTON,
1986      {"Calling type of number", "iax2.iax.callington", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},
1987
1988     {&hf_IAX_IE_CALLINGTNS,
1989      {"Calling transit network select", "iax2.iax.callingtns", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
1990
1991     {&hf_IAX_IE_SAMPLINGRATE,
1992      {"Supported sampling rates", "iax2.iax.samplingrate", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
1993
1994     {&hf_IAX_IE_CAUSECODE,
1995      {"Hangup cause", "iax2.iax.causecode", FT_UINT8, BASE_HEX, VALS(iax_causecodes),
1996        0x0, "", HFILL}},
1997
1998     {&hf_IAX_IE_ENCRYPTION,
1999      {"Encryption format", "iax2.iax.encryption", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
2000
2001     {&hf_IAX_IE_ENCKEY,
2002      {"Encryption key", "iax2.iax.enckey", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
2003
2004     {&hf_IAX_IE_CODEC_PREFS,
2005      {"Codec negotiation", "iax2.iax.codecprefs", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
2006
2007     {&hf_IAX_IE_RR_JITTER,
2008      {"Received jitter (as in RFC1889)", "iax2.iax.rrjitter", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2009
2010     {&hf_IAX_IE_RR_LOSS,
2011      {"Received loss (high byte loss pct, low 24 bits loss count, as in rfc1889)", "iax2.iax.rrloss",
2012        FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2013
2014     {&hf_IAX_IE_RR_PKTS,
2015      {"Total frames received", "iax2.iax.rrpkts", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2016
2017     {&hf_IAX_IE_RR_DELAY,
2018      {"Max playout delay in ms for received frames", "iax2.iax.rrdelay", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
2019
2020     {&hf_IAX_IE_RR_DROPPED,
2021      {"Dropped frames (presumably by jitterbuffer)", "iax2.iax.rrdropped", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2022
2023     {&hf_IAX_IE_RR_OOO,
2024      {"Frame received out of order", "iax2.iax.rrooo", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2025
2026     {&hf_IAX_IE_DATAFORMAT,
2027      {"Data call format", "iax2.iax.dataformat", FT_UINT32, BASE_HEX,
2028       VALS(iax_dataformats), 0x0, "", HFILL}},
2029
2030     {&hf_IAX_IE_UNKNOWN_BYTE,
2031      {"data", "iax2.iax.unknowndata", FT_UINT8, BASE_HEX, NULL,
2032       0x0, "Raw data for unknown IEs",
2033       HFILL}},
2034     {&hf_IAX_IE_UNKNOWN_I16,
2035      {"data", "iax2.iax.unknowndata", FT_UINT16, BASE_HEX, NULL,
2036       0x0, "Raw data for unknown IEs",
2037       HFILL}},
2038     {&hf_IAX_IE_UNKNOWN_I32,
2039      {"data", "iax2.iax.unknowndata", FT_UINT32, BASE_HEX, NULL,
2040       0x0, "Raw data for unknown IEs",
2041       HFILL}},
2042     {&hf_IAX_IE_UNKNOWN_BYTES,
2043      {"data", "iax2.iax.unknowndata", FT_BYTES, BASE_NONE, NULL,
2044       0x0, "Raw data for unknown IEs",
2045       HFILL}},
2046
2047     /* capablilites */
2048     {&hf_iax2_cap_g723_1,
2049      {"G.723.1 compression", "iax2.cap.g723_1", FT_BOOLEAN, 32,
2050       TFS(&supported_strings), AST_FORMAT_G723_1,
2051       "G.723.1 compression", HFILL }},
2052
2053     {&hf_iax2_cap_gsm,
2054      {"GSM compression", "iax2.cap.gsm", FT_BOOLEAN, 32,
2055        TFS(&supported_strings), AST_FORMAT_GSM, 
2056       "GSM compression", HFILL }},
2057
2058     {&hf_iax2_cap_ulaw,
2059      {"Raw mu-law data (G.711)", "iax2.cap.ulaw",FT_BOOLEAN, 32,
2060       TFS(&supported_strings), AST_FORMAT_ULAW,
2061       "Raw mu-law data (G.711)", HFILL }},
2062
2063      {&hf_iax2_cap_alaw,
2064       {"Raw A-law data (G.711)", "iax2.cap.alaw",FT_BOOLEAN, 32,
2065        TFS(&supported_strings), AST_FORMAT_ALAW,
2066        "Raw A-law data (G.711)", HFILL }},
2067
2068     {&hf_iax2_cap_g726,
2069      {"G.726 compression", "iax2.cap.g726",FT_BOOLEAN, 32,
2070       TFS(&supported_strings), AST_FORMAT_G726,
2071       "G.726 compression", HFILL }},
2072
2073     {&hf_iax2_cap_adpcm,
2074      {"ADPCM", "iax2.cap.adpcm", FT_BOOLEAN, 32,
2075       TFS(&supported_strings), AST_FORMAT_ADPCM,
2076       "ADPCM", HFILL }},
2077     
2078     {&hf_iax2_cap_slinear,
2079      {"Raw 16-bit Signed Linear (8000 Hz) PCM", "iax2.cap.slinear", 
2080       FT_BOOLEAN, 32, TFS(&supported_strings), AST_FORMAT_SLINEAR, 
2081       "Raw 16-bit Signed Linear (8000 Hz) PCM", HFILL }},
2082
2083     {&hf_iax2_cap_lpc10,
2084      {"LPC10, 180 samples/frame", "iax2.cap.lpc10", FT_BOOLEAN, 32,
2085       TFS(&supported_strings), AST_FORMAT_LPC10,
2086       "LPC10, 180 samples/frame", HFILL }},
2087
2088     {&hf_iax2_cap_g729a,
2089      {"G.729a Audio", "iax2.cap.g729a", FT_BOOLEAN, 32,
2090       TFS(&supported_strings), AST_FORMAT_G729A,
2091       "G.729a Audio", HFILL }},
2092
2093     {&hf_iax2_cap_speex,
2094      {"SPEEX Audio", "iax2.cap.speex", FT_BOOLEAN, 32,
2095       TFS(&supported_strings), AST_FORMAT_SPEEX,
2096       "SPEEX Audio", HFILL }},
2097
2098     {&hf_iax2_cap_ilbc,
2099      {"iLBC Free compressed Audio", "iax2.cap.ilbc", FT_BOOLEAN, 32,
2100       TFS(&supported_strings), AST_FORMAT_ILBC,
2101       "iLBC Free compressed Audio", HFILL }},
2102
2103     {&hf_iax2_cap_jpeg,
2104      {"JPEG images", "iax2.cap.jpeg", FT_BOOLEAN, 32,
2105       TFS(&supported_strings), AST_FORMAT_JPEG,
2106       "JPEG images", HFILL }},
2107
2108     {&hf_iax2_cap_png,
2109      {"PNG images", "iax2.cap.png", FT_BOOLEAN, 32,
2110       TFS(&supported_strings), AST_FORMAT_PNG,
2111       "PNG images", HFILL }},
2112
2113     {&hf_iax2_cap_h261,
2114      {"H.261 video", "iax2.cap.h261", FT_BOOLEAN, 32,
2115       TFS(&supported_strings), AST_FORMAT_H261,
2116       "H.261 video", HFILL }},
2117
2118     {&hf_iax2_cap_h263,
2119      {"H.263 video", "iax2.cap.h263", FT_BOOLEAN, 32,
2120       TFS(&supported_strings), AST_FORMAT_H263,
2121       "H.263 video", HFILL }}
2122   };
2123
2124   static gint *ett[] = {
2125     &ett_iax2,
2126     &ett_iax2_full_mini_subtree,
2127     &ett_iax2_type,
2128     &ett_iax2_ie,
2129     &ett_iax2_codecs,
2130     &ett_iax2_ies_apparent_addr
2131   };
2132
2133   proto_iax2 =
2134     proto_register_protocol ("Inter-Asterisk eXchange v2", "IAX2", "iax2");
2135   proto_register_field_array (proto_iax2, hf, array_length (hf));
2136   proto_register_subtree_array (ett, array_length (ett));
2137
2138   register_dissector("iax2", dissect_iax2, proto_iax2);
2139
2140   iax2_codec_dissector_table = register_dissector_table(
2141     "iax2.codec","IAX codec number", FT_UINT32, BASE_HEX);
2142   iax2_dataformat_dissector_table = register_dissector_table(
2143     "iax2.dataformat","IAX dataformat number", FT_UINT32, BASE_HEX);
2144   
2145   /* register our init routine to be called at the start of a capture,
2146      to clear out our hash tables etc */
2147   register_init_routine(&iax_init_protocol);
2148 }
2149
2150 void
2151 proto_reg_handoff_iax2 (void)
2152 {
2153   dissector_add("udp.port", IAX2_PORT, find_dissector("iax2"));
2154   dissector_add("iax2.dataformat", AST_DATAFORMAT_V110, find_dissector("v110"));
2155   data_handle = find_dissector("data");
2156 }
2157
2158
2159 /* 
2160  * This sets up the indentation style for this file in emacs.
2161  *
2162  * Local Variables:
2163  * c-basic-offset: 2
2164  * End:
2165  */