removed some gcc warnings (hopefully)
[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_DATAFORMAT = -1;
125 static int hf_IAX_IE_UNKNOWN_BYTE = -1;
126 static int hf_IAX_IE_UNKNOWN_I16 = -1;
127 static int hf_IAX_IE_UNKNOWN_I32 = -1;
128 static int hf_IAX_IE_UNKNOWN_BYTES = -1;
129
130 /* These are the ids of the subtrees that we may be creating */
131 static gint ett_iax2 = -1;
132 static gint ett_iax2_full_mini_subtree = -1;
133 static gint ett_iax2_type = -1;         /* Frame-type specific subtree */
134 static gint ett_iax2_ie = -1;           /* single IE */
135 static gint ett_iax2_codecs = -1;       /* capabilities IE */
136 static gint ett_iax2_ies_apparent_addr = -1; /* apparent address IE */
137
138 static dissector_handle_t data_handle;
139
140 /* data-call subdissectors, AST_DATAFORMAT_* */
141 static dissector_table_t iax2_dataformat_dissector_table;
142 /* voice/video call subdissectors, AST_FORMAT_* */
143 static dissector_table_t iax2_codec_dissector_table;
144
145 /* IAX2 Full-frame types */
146 static const value_string iax_frame_types[] = {
147   {0, "(0?)"},
148   {1, "DTMF"},
149   {2, "Voice"},
150   {3, "Video"},
151   {4, "Control"},
152   {5, "NULL"},
153   {6, "IAX"},
154   {7, "Text"},
155   {8, "Image"},
156   {0,NULL}
157 };
158
159 /* Subclasses for IAX packets */
160 static const value_string iax_iax_subclasses[] = {
161   {0, "(0?)"},
162   {1, "NEW"},
163   {2, "PING"},
164   {3, "PONG"},
165   {4, "ACK"},
166   {5, "HANGUP"},
167   {6, "REJECT"},
168   {7, "ACCEPT"},
169   {8, "AUTHREQ"},
170   {9, "AUTHREP"},
171   {10, "INVAL"},
172   {11, "LAGRQ"},
173   {12, "LAGRP"},
174   {13, "REGREQ"},
175   {14, "REGAUTH"},
176   {15, "REGACK"},
177   {16, "REGREJ"},
178   {17, "REGREL"},
179   {18, "VNAK"},
180   {19, "DPREQ"},
181   {20, "DPREP"},
182   {21, "DIAL"},
183   {22, "TXREQ"},
184   {23, "TXCNT"},
185   {24, "TXACC"},
186   {25, "TXREADY"},
187   {26, "TXREL"},
188   {27, "TXREJ"},
189   {28, "QUELCH"},
190   {29, "UNQULCH"},
191   {30, "POKE"},
192   {31, "PAGE"},
193   {32, "MWI"},
194   {33, "UNSUPPORTED"},
195   {34, "TRANSFER"},
196   {0,NULL}
197 };
198
199 /* Subclassess for Control packets */
200 static const value_string iax_cmd_subclasses[] = {
201   {0, "(0?)"},
202   {1, "HANGUP"},
203   {2, "RING"},
204   {3, "RINGING"},
205   {4, "ANSWER"},
206   {5, "BUSY"},
207   {6, "TKOFFHK"},
208   {7, "OFFHOOK"},
209   {0xFF, "stop sounds"}, /* sent by app_dial, and not much else */
210   {0,NULL}
211 };
212
213 /* Information elements */
214 static const value_string iax_ies_type[] = {
215   {IAX_IE_CALLED_NUMBER, "Number/extension being called"},
216   {IAX_IE_CALLING_NUMBER, "Calling number"},
217   {IAX_IE_CALLING_ANI, "Calling number ANI for billing"},
218   {IAX_IE_CALLING_NAME, "Name of caller"},
219   {IAX_IE_CALLED_CONTEXT, "Context for number"},
220   {IAX_IE_USERNAME, "Username (peer or user) for authentication"},
221   {IAX_IE_PASSWORD, "Password for authentication"},
222   {IAX_IE_CAPABILITY, "Actual codec capability"},
223   {IAX_IE_FORMAT, "Desired codec format"},
224   {IAX_IE_LANGUAGE, "Desired language"},
225   {IAX_IE_VERSION, "Protocol version"},
226   {IAX_IE_ADSICPE, "CPE ADSI capability"},
227   {IAX_IE_DNID, "Originally dialed DNID"},
228   {IAX_IE_AUTHMETHODS, "Authentication method(s)"},
229   {IAX_IE_CHALLENGE, "Challenge data for MD5/RSA"},
230   {IAX_IE_MD5_RESULT, "MD5 challenge result"},
231   {IAX_IE_RSA_RESULT, "RSA challenge result"},
232   {IAX_IE_APPARENT_ADDR, "Apparent address of peer"},
233   {IAX_IE_REFRESH, "When to refresh registration"},
234   {IAX_IE_DPSTATUS, "Dialplan status"},
235   {IAX_IE_CALLNO, "Call number of peer"},
236   {IAX_IE_CAUSE, "Cause"},
237   {IAX_IE_IAX_UNKNOWN, "Unknown IAX command"},
238   {IAX_IE_MSGCOUNT, "How many messages waiting"},
239   {IAX_IE_AUTOANSWER, "Request auto-answering"},
240   {IAX_IE_MUSICONHOLD, "Request musiconhold with QUELCH"},
241   {IAX_IE_TRANSFERID, "Transfer Request Identifier"},
242   {IAX_IE_RDNIS, "Referring DNIS"},
243   {IAX_IE_PROVISIONING, "Provisioning info"},
244   {IAX_IE_AESPROVISIONING, "AES Provisioning info"},
245   {IAX_IE_DATETIME,"Date/Time"},
246   {IAX_IE_DATAFORMAT, "Data call format"},
247   {0,NULL}
248 };
249
250 static const value_string codec_types[] = {
251   {AST_FORMAT_G723_1, "G.723.1 compression"},
252   {AST_FORMAT_GSM, "GSM compression"},
253   {AST_FORMAT_ULAW, "Raw mu-law data (G.711)"},
254   {AST_FORMAT_ALAW, "Raw A-law data (G.711)"},
255   {AST_FORMAT_G726, "ADPCM (G.726, 32kbps)"},
256   {AST_FORMAT_ADPCM, "ADPCM (IMA)"},
257   {AST_FORMAT_SLINEAR, "Raw 16-bit Signed Linear (8000 Hz) PCM"},
258   {AST_FORMAT_LPC10, "LPC10, 180 samples/frame"},
259   {AST_FORMAT_G729A, "G.729a Audio"},
260   {AST_FORMAT_SPEEX, "SpeeX Free Compression"},
261   {AST_FORMAT_ILBC, "iLBC Free Compression"},
262   {AST_FORMAT_JPEG, "JPEG Images"},
263   {AST_FORMAT_PNG, "PNG Images"},
264   {AST_FORMAT_H261, "H.261 Video"},
265   {AST_FORMAT_H263, "H.263 Video"},
266   {0,NULL}
267 };
268
269 static const value_string iax_dataformats[] = {
270   {AST_DATAFORMAT_NULL, "N/A (analogue call?)"},
271   {AST_DATAFORMAT_V110, "ITU-T V.110 rate adaption"},
272   {AST_DATAFORMAT_H223_H245,"ITU-T H.223/H.245"},
273   {0,NULL}
274 };
275
276 typedef enum {
277   IAX2_MINI_VOICE_PACKET,
278   IAX2_FULL_PACKET,
279   IAX2_MINI_VIDEO_PACKET,
280   IAX2_META_PACKET
281 } packet_type;
282
283 static const value_string iax_packet_types[] = {
284   {IAX2_FULL_PACKET, "Full packet"},
285   {IAX2_MINI_VOICE_PACKET, "Mini voice packet"},
286   {IAX2_MINI_VIDEO_PACKET, "Mini video packet"},
287   {IAX2_META_PACKET, "Meta packet"},
288   {0,NULL}
289 };
290   
291
292 /* ************************************************************************* */
293
294 /* In order to track IAX calls, we have a hash table which maps
295  * {addr,port type,port,call} to a unique circuit id.
296  *
297  * Each call has two such circuits associated with it (a forward and a
298  * reverse circuit, where 'forward' is defined as the direction the NEW
299  * packet went in), and we maintain an iax_call_data structure for each
300  * call, attached to both circuits with circuit_add_proto_data.
301  *
302  * Because {addr,port type,port,call} quadruplets can be reused
303  * (Asterisk reuses call numbers), circuit ids aren't unique to
304  * individual calls and we treat NEW packets somewhat specially. When we
305  * get such a packet, we see if there are any calls with a matching
306  * circuit id, and make sure that its circuits are marked as ended
307  * before that packet.
308  *
309  * A second complication is that we only know one quadruplet at the time
310  * the NEW packet is processed: there is therefore cunningness in
311  * iax_lookup_circuit_details() to look for replies to NEW packets and
312  * create the reverse circuit.
313  */
314
315
316 /* start with a hash of {addr,port type,port,call}->{id} */
317
318 typedef struct {
319   address addr;
320   port_type ptype;
321   guint32 port;
322   guint32 callno;
323 } iax_circuit_key;
324
325 /* tables */
326 static GHashTable *iax_circuit_hashtab = NULL;
327 static GMemChunk *iax_circuit_keys = NULL;
328 static GMemChunk *iax_circuit_vals = NULL;
329 static guint circuitcount = 0;
330
331 /* the number of keys and values to reserve space for in each memory chunk.
332    We assume we won't be tracking many calls at once so this is quite low.
333 */
334 #define IAX_INIT_PACKET_COUNT 10
335
336 #ifdef DEBUG_HASHING
337 static gchar *key_to_str( const iax_circuit_key *key )
338 {
339   static int i=0;
340   static gchar *strp, str[3][80];
341
342   i++;
343   if(i>=3){
344     i=0;
345   }
346   strp=str[i];
347
348   /* why doesn't address_to_str take a const pointer?
349      cast the warnings into oblivion. */
350
351   sprintf(strp,"{%s:%i,%i}",
352           address_to_str((address *)&key->addr),
353           key->port,
354           key->callno);
355   return strp;
356 }
357 #endif
358
359 /* Hash Functions */
360 static gint iax_circuit_equal(gconstpointer v, gconstpointer w)
361 {
362   const iax_circuit_key *v1 = (const iax_circuit_key *)v;
363   const iax_circuit_key *v2 = (const iax_circuit_key *)w;
364   gint result;
365
366   result = ( ADDRESSES_EQUAL(&(v1->addr), &(v2->addr)) &&
367              v1->ptype == v2->ptype &&
368              v1->port  == v2->port &&
369              v1->callno== v2->callno);
370 #ifdef DEBUG_HASHING
371   g_message( "+++ Comparing for equality: %s, %s: %u",key_to_str(v1), key_to_str(v2), result);
372 #endif
373
374   return result;;
375 }
376
377 static guint iax_circuit_hash (gconstpointer v)
378 {
379   const iax_circuit_key *key = (const iax_circuit_key *)v;
380   guint hash_val;
381   int i;
382
383   hash_val = 0;
384   for (i = 0; i < key->addr.len; i++)
385     hash_val += (guint)(key->addr.data[i]);
386
387   hash_val += (guint)(key->ptype);
388   hash_val += (guint)(key->port);
389   hash_val += (guint)(key->callno);
390
391 #ifdef DEBUG_HASHING
392   g_message( "+++ Hashing key: %s, result %#x", key_to_str(key), hash_val );
393 #endif
394   
395   return (guint) hash_val;
396 }
397
398 static guint iax_circuit_lookup(const address *address,
399                                 port_type ptype,
400                                 guint32 port,
401                                 guint32 callno)
402 {
403   iax_circuit_key key;
404   guint32 *circuit_id_p;
405
406   key.addr = *address;
407   key.ptype = ptype;
408   key.port = port;
409   key.callno = callno;
410
411 #ifdef DEBUG_HASHING
412   g_message( "+++ looking up key: %s", key_to_str(&key));
413 #endif
414   
415   circuit_id_p = g_hash_table_lookup( iax_circuit_hashtab, &key);
416   if( ! circuit_id_p ) {
417     iax_circuit_key *new_key;
418
419     new_key = g_mem_chunk_alloc(iax_circuit_keys);
420     COPY_ADDRESS(&new_key->addr, address);
421     new_key->ptype = ptype;
422     new_key->port = port;
423     new_key->callno = callno;
424
425     circuit_id_p = g_mem_chunk_alloc(iax_circuit_vals);
426     *circuit_id_p = ++circuitcount;
427
428     g_hash_table_insert(iax_circuit_hashtab, new_key, circuit_id_p);
429   }
430
431 #ifdef DEBUG_HASHING
432     g_message( "+++ Id: %u", *circuit_id_p );
433 #endif
434
435   return *circuit_id_p;
436 }
437
438
439 /* ************************************************************************* */
440
441
442 /* This is our per-call data structure, which is attached to both the
443  * forward and reverse circuits.
444  */
445 typedef struct iax_call_data {
446   /* For this data, src and dst are relative to the original direction under
447      which this call is stored. Obviously if the reversed flag is set true by
448      iax_find_call, src and dst are reversed relative to the direction the
449      actual source and destination of the data.
450
451      if the codec changes mid-call, we update it here; because we store a codec
452      number with each packet too, we handle going back to earlier packets
453      without problem.
454   */
455
456   iax_dataformat_t dataformat;
457   guint32 src_codec, dst_codec;
458   guint32 src_vformat, dst_vformat;
459
460   guint forward_circuit_id;
461   guint reverse_circuit_id;
462
463   guint callno;
464 } iax_call_data;
465
466 static guint callcount = 0;
467
468 static GMemChunk *iax_call_datas = NULL;
469
470 static void iax_init_hash( void )
471 {
472   if (iax_circuit_hashtab)
473     g_hash_table_destroy(iax_circuit_hashtab);
474
475   if (iax_circuit_keys)
476     g_mem_chunk_destroy(iax_circuit_keys);
477   if (iax_circuit_vals)
478     g_mem_chunk_destroy(iax_circuit_vals);
479   if (iax_call_datas)
480     g_mem_chunk_destroy(iax_call_datas);
481
482   iax_circuit_hashtab = g_hash_table_new(iax_circuit_hash, iax_circuit_equal);
483
484   iax_circuit_keys = g_mem_chunk_create(iax_circuit_key,
485                                         2*IAX_INIT_PACKET_COUNT,
486                                         G_ALLOC_ONLY);
487   iax_circuit_vals = g_mem_chunk_create(iax_circuit_key,
488                                         2*IAX_INIT_PACKET_COUNT,
489                                         G_ALLOC_ONLY);
490
491   iax_call_datas = g_mem_chunk_create(iax_call_data,
492                                       IAX_INIT_PACKET_COUNT,
493                                       G_ALLOC_ONLY);
494   circuitcount = 0;
495   callcount = 0;
496 }
497
498
499 static iax_call_data *iax_lookup_circuit_details_from_dest( guint src_circuit_id,
500                                                             guint dst_circuit_id,
501                                                             guint framenum,
502                                                             gboolean *reversed_p,
503                                                             circuit_t **circuit_p)
504 {
505   circuit_t *dst_circuit;
506   iax_call_data * iax_call;
507   gboolean reversed = FALSE;
508   
509   dst_circuit = find_circuit( CT_IAX2,
510                               dst_circuit_id,
511                               framenum );
512
513   if( !dst_circuit ) {
514 #ifdef DEBUG_HASHING
515     g_message( "++ destination circuit not found, must have missed NEW packet" );
516 #endif
517     return NULL;
518   }
519
520 #ifdef DEBUG_HASHING
521   g_message( "++ found destination circuit" );
522 #endif
523       
524   iax_call = (iax_call_data *)circuit_get_proto_data(dst_circuit,proto_iax2);
525
526   /* there's no way we can create a CT_IAX2 circuit without adding
527      iax call data to it; assert this */
528   g_assert(iax_call);
529   
530   if( dst_circuit_id == iax_call -> forward_circuit_id ) {
531 #ifdef DEBUG_HASHING
532     g_message( "++ destination circuit matches forward_circuit_id of call, "
533                "therefore packet is reversed" );
534 #endif
535
536     reversed = TRUE;
537
538     if( iax_call -> reverse_circuit_id == 0 ) {
539       circuit_t *rev_circuit;
540       
541       /* we are going in the reverse direction, and this call
542          doesn't have a reverse circuit associated with it.
543          create one now. */
544 #ifdef DEBUG_HASHING
545       g_message( "++ reverse_circuit_id of call is zero, need to create a "
546                  "new reverse circuit for this call" );
547 #endif
548
549       iax_call -> reverse_circuit_id = src_circuit_id;
550       rev_circuit = circuit_new(CT_IAX2,
551                                 src_circuit_id,
552                                 framenum );
553       circuit_add_proto_data(rev_circuit, proto_iax2, iax_call);
554         
555       /* we should have already set up a subdissector for the forward
556        * circuit. we'll need to copy it to the reverse circuit. */
557       circuit_set_dissector(rev_circuit, circuit_get_dissector(dst_circuit));
558 #ifdef DEBUG_HASHING
559       g_message( "++ done" );
560 #endif
561     } else if( iax_call -> reverse_circuit_id != src_circuit_id ) {
562       g_warning( "IAX Packet %u from circuit ids %u->%u"
563                  "conflicts with earlier call with circuit ids %u->%u",
564                  framenum,
565                  src_circuit_id,dst_circuit_id,
566                  iax_call->forward_circuit_id,
567                  iax_call->reverse_circuit_id);
568       return NULL;
569     }
570   } else if ( dst_circuit_id == iax_call -> reverse_circuit_id ) {
571 #ifdef DEBUG_HASHING
572     g_message( "++ destination circuit matches reverse_circuit_id of call, "
573                "therefore packet is forward" );
574 #endif
575
576     reversed = FALSE;
577     if( iax_call -> forward_circuit_id != src_circuit_id ) {
578       g_warning( "IAX Packet %u from circuit ids %u->%u"
579                  "conflicts with earlier call with circuit ids %u->%u",
580                  framenum,
581                  src_circuit_id,dst_circuit_id,
582                  iax_call->forward_circuit_id,
583                  iax_call->reverse_circuit_id);
584       return NULL;
585     }
586   } else {
587     g_assert_not_reached();
588   }
589
590
591   if( circuit_p ) {
592     /* by now we've created a new circuit if one was necessary, or
593        bailed out if it looks like a conflict, and we should be able
594        to look up the source circuit without issue */
595     *circuit_p = find_circuit( CT_IAX2, 
596                                src_circuit_id,
597                                framenum );
598     g_assert(*circuit_p);
599   }
600
601   if( reversed_p )
602     *reversed_p = reversed;
603
604   return iax_call;
605 }
606
607   
608   /* looks up a circuit_t and an iax_call for this packet */
609 static iax_call_data *iax_lookup_circuit_details( packet_info *pinfo, 
610                                                  guint32 scallno,
611                                                  guint32 dcallno,
612                                                  gboolean *reversed_p,
613                                                  circuit_t **circuit_p)
614 {
615   gboolean reversed = FALSE;
616   iax_call_data *iax_call = NULL;
617   guint src_circuit_id;
618   circuit_t *src_circuit = NULL;
619
620 #ifdef DEBUG_HASHING
621   g_message( "++ iax_lookup_circuit_details: Looking up circuit for frame %u, "
622              "from {%s:%u:%u} to {%s:%u:%u}", pinfo->fd->num,
623              address_to_str(&pinfo->src),pinfo->srcport,scallno,
624              address_to_str(&pinfo->dst),pinfo->destport,dcallno);
625 #endif
626
627
628   src_circuit_id = iax_circuit_lookup(&pinfo->src,pinfo->ptype,
629                                       pinfo->srcport,scallno);
630
631
632   /* the most reliable indicator of call is the destination callno, if
633      we have one */
634   if( dcallno != 0 ) {
635     guint dst_circuit_id;
636 #ifdef DEBUG_HASHING
637     g_message( "++ dcallno non-zero, looking up destination circuit" );
638 #endif
639
640     dst_circuit_id = iax_circuit_lookup(&pinfo->dst,pinfo->ptype,
641                                         pinfo->destport,dcallno);
642
643     iax_call = iax_lookup_circuit_details_from_dest(src_circuit_id, dst_circuit_id, pinfo->fd->num, &reversed, &src_circuit);
644   } else {
645
646     /* in all other circumstances, the source circuit should already
647      * exist: its absense indicates that we missed the all-important NEW
648      * packet.
649      */
650
651     src_circuit = find_circuit( CT_IAX2,
652                             src_circuit_id,
653                             pinfo->fd->num );
654
655     if( src_circuit ) {
656       iax_call = (iax_call_data *)circuit_get_proto_data(src_circuit,proto_iax2);
657
658       /* there's no way we can create a CT_IAX2 circuit without adding
659          iax call data to it; assert this */
660       g_assert(iax_call);
661
662       if( src_circuit_id == iax_call -> forward_circuit_id )
663         reversed = FALSE;
664       else if ( src_circuit_id == iax_call -> reverse_circuit_id )
665         reversed = TRUE;
666       else {
667         /* there's also no way we can attach an iax_call_data to a circuit
668            without the circuit being either the forward or reverse circuit
669            for that call; assert this too.
670         */
671         g_assert_not_reached();
672       }
673     }
674   }
675
676   if(src_circuit && iax_call) {
677     /* info for subdissectors. We always pass on the forward circuit,
678      * and steal the p2p_dir flag to indicate the direction */
679     pinfo -> ctype = CT_IAX2;
680     pinfo -> circuit_id = (guint32)iax_call->forward_circuit_id;
681     pinfo -> p2p_dir = reversed?P2P_DIR_RECV:P2P_DIR_SENT;
682   }
683
684   if(reversed_p)
685     *reversed_p = reversed;
686
687   if(circuit_p)
688     *circuit_p = src_circuit;
689
690 #ifdef DEBUG_HASHING
691   if( iax_call ) {
692     g_message( "++ Found call for packet: id %u, reversed=%c", iax_call->callno, reversed?'1':'0' );
693   } else {
694     g_message( "++ Call not found. Must have missed the NEW packet?" );
695   }
696 #endif
697   
698   return iax_call;
699 }
700
701
702 /* handles a NEW packet by creating a new iax call and forward circuit.
703    the reverse circuit is not created until the ACK is received and
704    is created by iax_lookup_circuit_details. */
705 static iax_call_data *iax_new_circuit_details( packet_info *pinfo, 
706                                               guint32 scallno,
707                                               circuit_t **circuit_p)
708 {
709   circuit_t *circuit;
710   iax_call_data *call;
711   guint circuit_id;
712     
713 #ifdef DEBUG_HASHING
714   g_message( "+ new_circuit: Handling NEW packet, frame %u", pinfo->fd->num );
715 #endif
716   
717     circuit_id = iax_circuit_lookup(&pinfo->src,pinfo->ptype,
718                                     pinfo->srcport,scallno);
719     
720     circuit = circuit_new(CT_IAX2,
721                           circuit_id,
722                           pinfo->fd->num );
723
724     
725
726     call = g_mem_chunk_alloc(iax_call_datas);
727     call -> dataformat = 0;
728     call -> src_codec = 0;
729     call -> dst_codec = 0;
730     call -> forward_circuit_id = circuit_id;
731     call -> reverse_circuit_id = 0;
732     call -> callno = ++callcount;
733
734 #ifdef DEBUG_HASHING
735     g_message( "+ new_circuit: Added new circuit for new call %u", call -> callno );
736 #endif
737
738     circuit_add_proto_data( circuit, proto_iax2, call );
739
740   if( circuit_p )
741     *circuit_p = circuit;
742
743   return call;
744 }
745     
746
747 /* ************************************************************************* */
748
749 /* per-packet data */
750 typedef struct iax_packet_data {
751   iax_call_data *call_data;
752   guint32 codec;
753 } iax_packet_data;
754
755 static GMemChunk *iax_packets = NULL;
756
757 static iax_packet_data *iax_new_packet_data(iax_call_data *call)
758 {
759   iax_packet_data *p = g_mem_chunk_alloc(iax_packets);
760   p->call_data=call;
761   p->codec=0;
762   return p;
763 }
764
765
766 /* ************************************************************************* */
767
768 static guint32 dissect_fullpacket (tvbuff_t * tvb, guint32 offset,
769                                 guint16 scallno,
770                                 packet_info * pinfo,
771                                 proto_tree * iax2_tree,
772                                 proto_tree * main_tree);
773
774
775 static guint32 dissect_minipacket (tvbuff_t * tvb, guint32 offset, 
776                                 guint16 scallno,
777                                 packet_info * pinfo,
778                                 proto_tree * iax2_tree,
779                                 proto_tree * main_tree);
780
781 static guint32 dissect_minivideopacket (tvbuff_t * tvb, guint32 offset, 
782                                         guint16 scallno,
783                                         packet_info * pinfo,
784                                         proto_tree * iax2_tree,
785                                         proto_tree * main_tree);
786
787 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
788                             packet_info *pinfo, proto_tree *tree,
789                             guint32 ts, gboolean video,
790                             iax_packet_data *iax_packet);
791
792
793
794 static void
795 dissect_iax2 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
796 {
797   proto_item *iax2_item = NULL;
798   proto_tree *iax2_tree = NULL;
799   proto_tree *full_mini_subtree = NULL;
800   guint32 offset = 0, len;
801   guint16 scallno = 0;
802   guint16 stmp;
803   packet_type type;
804
805   /* set up the protocol and info fields in the summary pane */
806   if (check_col (pinfo->cinfo, COL_PROTOCOL))
807     {
808       col_set_str (pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_IAX2);
809     }
810   if (check_col (pinfo->cinfo, COL_INFO))
811     {
812       col_clear (pinfo->cinfo, COL_INFO);
813     }
814
815   /* add the 'iax2' tree to the main tree */
816   if (tree)
817     {
818       iax2_item = proto_tree_add_item (tree, proto_iax2, tvb, offset, -1, FALSE);
819       iax2_tree = proto_item_add_subtree (iax2_item, ett_iax2);
820     }
821
822   stmp = tvb_get_ntohs(tvb, offset);
823   if( stmp == 0 ) {
824     /* starting with 0x0000 indicates either a mini video packet or a 'meta'
825      * packet, whatever that means */
826     offset+=2;
827     stmp = tvb_get_ntohs(tvb, offset);
828     if( stmp & 0x8000 ) {
829       /* mini video packet */
830       type = IAX2_MINI_VIDEO_PACKET;
831       scallno = stmp & 0x7FFF;
832       offset += 2;
833     }
834     else {
835       type = IAX2_META_PACKET;
836     }
837   } else {
838     /* The source call/fullpacket flag is common to both mini and full packets */
839     scallno = tvb_get_ntohs(tvb, offset);
840     offset += 2;
841     if( scallno & 0x8000 )
842       type = IAX2_FULL_PACKET;
843     else {
844       type = IAX2_MINI_VOICE_PACKET;
845     }
846     scallno &= 0x7FFF;
847   }
848
849   if( tree ) {
850     proto_item *full_mini_base;
851
852     full_mini_base = proto_tree_add_uint(iax2_tree, hf_iax2_packet_type, tvb, 0, offset, type);
853     full_mini_subtree = proto_item_add_subtree(full_mini_base, ett_iax2_full_mini_subtree);
854
855     if( scallno != 0 )
856       proto_tree_add_item (full_mini_subtree, hf_iax2_scallno, tvb, offset-2, 2, FALSE);
857   }
858
859   switch( type ) {
860     case IAX2_FULL_PACKET:
861       len = dissect_fullpacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
862       break;
863     case IAX2_MINI_VOICE_PACKET:
864       len = dissect_minipacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
865       break;
866     case IAX2_MINI_VIDEO_PACKET:
867       len = dissect_minivideopacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
868       break;
869     case IAX2_META_PACKET:
870       /* not implemented yet */
871       len = 0;
872       break;
873     default:
874       len = 0;
875   }
876
877   /* update the 'length' of the main IAX2 header field so that it covers just the headers,
878      not the audio data. */
879   proto_item_set_len(iax2_item, len);
880 }
881
882
883 /* dissect the information elements in an IAX frame. Returns the updated offset */
884 static guint32 dissect_ies (tvbuff_t * tvb, guint32 offset,
885                             proto_tree * iax_tree,
886                             iax_call_data *iax_call_data )
887 {
888   proto_tree *sockaddr_tree = NULL;
889   proto_item *sockaddr_item = 0;
890
891
892   while (offset < tvb_reported_length (tvb)) {
893
894     int ies_type = tvb_get_guint8(tvb, offset);
895     int ies_len = tvb_get_guint8(tvb, offset + 1);
896
897     if( iax_tree ) {
898       proto_item *ti;
899       proto_tree *ies_tree;
900
901       ti = proto_tree_add_text(iax_tree, tvb, offset, ies_len+2,
902                                "Information Element: %s (0x%02X)",
903                                val_to_str(ies_type, iax_ies_type, 
904                                           "Unknown information element"),
905                                ies_type);
906
907
908       ies_tree = proto_item_add_subtree(ti, ett_iax2_ie);
909       
910       proto_tree_add_text(ies_tree, tvb, offset, 1, "IE id: %s (0x%02X)",
911                           val_to_str(ies_type, iax_ies_type, "Unknown"),
912                           ies_type);
913
914       proto_tree_add_text(ies_tree, tvb, offset+1, 1, "Length: %u",ies_len);
915
916
917       switch (ies_type) {
918             case IAX_IE_CALLED_NUMBER:
919               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLED_NUMBER, tvb,
920                                    offset + 2, ies_len, FALSE);
921               break;
922             case IAX_IE_CALLING_NUMBER:
923               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_NUMBER,
924                                    tvb, offset + 2, ies_len, FALSE);
925               break;
926             case IAX_IE_CALLING_ANI:
927               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_ANI, tvb,
928                                    offset + 2, ies_len, FALSE);
929               break;
930             case IAX_IE_CALLING_NAME:
931               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_NAME, tvb,
932                                    offset + 2, ies_len, FALSE);
933               break;
934             case IAX_IE_CALLED_CONTEXT:
935               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLED_CONTEXT,
936                                    tvb, offset + 2, ies_len, FALSE);
937               break;
938             case IAX_IE_USERNAME:
939               proto_tree_add_item (ies_tree, hf_IAX_IE_USERNAME, tvb,
940                                    offset + 2, ies_len, FALSE);
941               break;
942             case IAX_IE_PASSWORD:
943               proto_tree_add_item (ies_tree, hf_IAX_IE_PASSWORD, tvb,
944                                    offset + 2, ies_len, FALSE);
945               break;
946             case IAX_IE_LANGUAGE:
947               proto_tree_add_item (ies_tree, hf_IAX_IE_LANGUAGE, tvb,
948                                    offset + 2, ies_len, FALSE);
949               break;
950             case IAX_IE_DNID:
951               proto_tree_add_item (ies_tree, hf_IAX_IE_DNID, tvb,
952                                    offset + 2, ies_len, FALSE);
953               break;
954             case IAX_IE_CHALLENGE:
955               proto_tree_add_item (ies_tree, hf_IAX_IE_CHALLENGE, tvb,
956                                    offset + 2, ies_len, FALSE);
957               break;
958             case IAX_IE_MD5_RESULT:
959               proto_tree_add_item (ies_tree, hf_IAX_IE_MD5_RESULT, tvb,
960                                    offset + 2, ies_len, FALSE);
961               break;
962             case IAX_IE_RSA_RESULT:
963               proto_tree_add_item (ies_tree, hf_IAX_IE_RSA_RESULT, tvb,
964                                    offset + 2, ies_len, FALSE);
965               break;
966             case IAX_IE_RDNIS:
967               proto_tree_add_item (ies_tree, hf_IAX_IE_RDNIS, tvb,
968                                    offset + 2, ies_len, FALSE);
969               break;
970             case IAX_IE_CAPABILITY:
971             {
972               proto_tree *codec_tree;
973               proto_item *codec_base;
974
975               codec_base =
976                 proto_tree_add_item (ies_tree, hf_IAX_IE_CAPABILITY,
977                                      tvb, offset + 2, ies_len, FALSE);
978               codec_tree =
979                 proto_item_add_subtree (codec_base, ett_iax2_codecs);
980               
981               proto_tree_add_item(codec_tree, hf_iax2_cap_g723_1, tvb, offset + 2, ies_len, FALSE );
982               proto_tree_add_item(codec_tree, hf_iax2_cap_gsm, tvb, offset + 2, ies_len, FALSE );
983               proto_tree_add_item(codec_tree, hf_iax2_cap_ulaw, tvb, offset + 2, ies_len, FALSE );
984               proto_tree_add_item(codec_tree, hf_iax2_cap_alaw, tvb, offset + 2, ies_len, FALSE );
985               proto_tree_add_item(codec_tree, hf_iax2_cap_g726, tvb, offset + 2, ies_len, FALSE );
986               proto_tree_add_item(codec_tree, hf_iax2_cap_adpcm, tvb, offset + 2, ies_len, FALSE );
987               proto_tree_add_item(codec_tree, hf_iax2_cap_slinear, tvb, offset + 2, ies_len, FALSE );
988               proto_tree_add_item(codec_tree, hf_iax2_cap_lpc10, tvb, offset + 2, ies_len, FALSE );
989               proto_tree_add_item(codec_tree, hf_iax2_cap_g729a, tvb, offset + 2, ies_len, FALSE );
990               proto_tree_add_item(codec_tree, hf_iax2_cap_speex, tvb, offset + 2, ies_len, FALSE );
991               proto_tree_add_item(codec_tree, hf_iax2_cap_ilbc, tvb, offset + 2, ies_len, FALSE );
992               proto_tree_add_item(codec_tree, hf_iax2_cap_jpeg, tvb, offset + 2, ies_len, FALSE );
993               proto_tree_add_item(codec_tree, hf_iax2_cap_png, tvb, offset + 2, ies_len, FALSE );
994               proto_tree_add_item(codec_tree, hf_iax2_cap_h261, tvb, offset + 2, ies_len, FALSE );
995               proto_tree_add_item(codec_tree, hf_iax2_cap_h263, tvb, offset + 2, ies_len, FALSE );
996               break;
997             }
998             case IAX_IE_FORMAT:
999               proto_tree_add_item (ies_tree, hf_IAX_IE_FORMAT, tvb,
1000                                    offset + 2, ies_len, FALSE);
1001               break;
1002             case IAX_IE_VERSION:
1003               proto_tree_add_item (ies_tree, hf_IAX_IE_VERSION, tvb,
1004                                    offset + 2, ies_len, FALSE);
1005               break;
1006             case IAX_IE_ADSICPE:
1007               proto_tree_add_item (ies_tree, hf_IAX_IE_ADSICPE, tvb,
1008                                    offset + 2, ies_len, FALSE);
1009               break;
1010             case IAX_IE_AUTHMETHODS:
1011               proto_tree_add_item (ies_tree, hf_IAX_IE_AUTHMETHODS, tvb,
1012                                    offset + 2, ies_len, FALSE);
1013               break;
1014             case IAX_IE_APPARENT_ADDR:
1015               sockaddr_item = proto_tree_add_text(ies_tree, tvb, offset + 2, 16, "Apparent Address");
1016               sockaddr_tree = proto_item_add_subtree(sockaddr_item, ett_iax2_ies_apparent_addr);
1017               proto_tree_add_item(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINADDR, tvb, offset + 6, 4, FALSE);
1018               proto_tree_add_item(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINPORT, tvb, offset + 4, 2, FALSE);
1019               break;
1020             case IAX_IE_REFRESH:
1021               proto_tree_add_item (ies_tree, hf_IAX_IE_REFRESH, tvb,
1022                                    offset + 2, ies_len, FALSE);
1023               break;
1024             case IAX_IE_DPSTATUS:
1025               proto_tree_add_item (ies_tree, hf_IAX_IE_DPSTATUS, tvb,
1026                                    offset + 2, ies_len, FALSE);
1027               break;
1028             case IAX_IE_CALLNO:
1029               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLNO, tvb,
1030                                    offset + 2, ies_len, FALSE);
1031               break;
1032             case IAX_IE_CAUSE:
1033               proto_tree_add_item (ies_tree, hf_IAX_IE_CAUSE, tvb,
1034                                    offset + 2, ies_len, FALSE);
1035               break;
1036             case IAX_IE_IAX_UNKNOWN:
1037               proto_tree_add_item (ies_tree, hf_IAX_IE_IAX_UNKNOWN, tvb,
1038                                    offset + 2, ies_len, FALSE);
1039               break;
1040             case IAX_IE_MSGCOUNT:
1041               proto_tree_add_item (ies_tree, hf_IAX_IE_MSGCOUNT, tvb,
1042                                    offset + 2, ies_len, FALSE);
1043               break;
1044             case IAX_IE_AUTOANSWER:
1045               proto_tree_add_item (ies_tree, hf_IAX_IE_AUTOANSWER, tvb,
1046                                    offset + 2, ies_len, FALSE);
1047               break;
1048             case IAX_IE_MUSICONHOLD:
1049               proto_tree_add_item (ies_tree, hf_IAX_IE_MUSICONHOLD, tvb,
1050                                    offset + 2, ies_len, FALSE);
1051               break;
1052             case IAX_IE_TRANSFERID:
1053               proto_tree_add_item (ies_tree, hf_IAX_IE_TRANSFERID, tvb,
1054                                    offset + 2, ies_len, FALSE);
1055               break;
1056               
1057       case IAX_IE_DATAFORMAT:
1058         proto_tree_add_item (ies_tree, hf_IAX_IE_DATAFORMAT, tvb,
1059                              offset + 2, ies_len, FALSE);
1060
1061         if( iax_call_data )
1062           iax_call_data -> dataformat = tvb_get_ntohl(tvb, offset+2);
1063             
1064         break;
1065
1066       default:
1067       {
1068         switch(ies_len) {
1069         case 1:
1070           proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_BYTE, tvb, offset+2, ies_len, FALSE );
1071           break;
1072           
1073         case 2:
1074           proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_I16, tvb, offset+2, ies_len, FALSE );
1075           break;
1076         
1077         case 4:
1078           proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_I32, tvb, offset+2, ies_len, FALSE );
1079           break;
1080
1081         default:
1082           proto_tree_add_item( ies_tree, hf_IAX_IE_UNKNOWN_BYTES, tvb, offset+2, ies_len, FALSE );
1083         }
1084       }
1085       }
1086     }
1087     offset += ies_len + 2;
1088   }
1089   return offset;
1090 }
1091
1092 static guint32 uncompress_subclass(guint8 csub)
1093 {
1094   /* If the SC_LOG flag is set, return 2^csub otherwise csub */
1095   if (csub & 0x80) {
1096     /* special case for 'compressed' -1 */
1097     if (csub == 0xff)
1098       return (guint32)-1;
1099     else
1100       return 1 << (csub & 0x1F);
1101   }
1102   else
1103     return (guint32)csub;
1104 }
1105
1106
1107 static guint32
1108 dissect_fullpacket (tvbuff_t * tvb, guint32 offset, 
1109                     guint16 scallno,
1110                     packet_info * pinfo, proto_tree * iax2_tree,
1111                     proto_tree * main_tree)
1112 {
1113   guint32 retransmission = 0;
1114   guint16 dcallno;
1115   guint32 ts;
1116   guint8 type;
1117   guint8 csub;
1118   guint32 codec;
1119
1120   proto_tree *packet_type_tree = NULL;
1121   iax_call_data *iax_call;
1122   iax_packet_data *iax_packet;
1123   gboolean reversed;
1124   gboolean rtp_marker;
1125
1126   circuit_t *circuit;
1127
1128       /*
1129        * remove the top bit for retransmission detection 
1130        */
1131       dcallno = tvb_get_ntohs(tvb, offset);
1132       retransmission = dcallno & 0x8000;
1133       dcallno = dcallno & 0x7FFF;
1134       ts = tvb_get_ntohl(tvb, offset+2);
1135       type = tvb_get_guint8(tvb, offset + 8);
1136       csub = tvb_get_guint8(tvb, offset + 9);
1137
1138   /* see if we've seen this packet before */
1139   iax_packet = (iax_packet_data *)p_get_proto_data(pinfo->fd,proto_iax2);
1140   if( !iax_packet ) {
1141     /* if not, find or create an iax_call info structure for this IAX session. */
1142
1143     if( type == AST_FRAME_IAX && csub == IAX_COMMAND_NEW ) {
1144       /* NEW packets start a new call */
1145       iax_call = iax_new_circuit_details(pinfo,scallno,&circuit);
1146       reversed = FALSE;
1147     } else {
1148       iax_call = iax_lookup_circuit_details(pinfo, scallno, dcallno,
1149                                        &reversed, &circuit);
1150     }
1151
1152     iax_packet = iax_new_packet_data(iax_call);
1153     p_add_proto_data(pinfo->fd,proto_iax2,iax_packet);
1154   } else {
1155     iax_call = iax_packet->call_data;
1156   }
1157    
1158   if( iax2_tree ) {
1159       proto_item *packet_type_base;
1160
1161       proto_tree_add_item (iax2_tree, hf_iax2_dcallno, tvb, offset, 2, FALSE );
1162       proto_tree_add_boolean(iax2_tree, hf_iax2_retransmission, tvb, offset, 2, FALSE );
1163
1164       proto_tree_add_uint (iax2_tree, hf_iax2_ts, tvb, offset+2, 4, ts);
1165
1166       proto_tree_add_item (iax2_tree, hf_iax2_oseqno, tvb, offset+6, 1,
1167                            FALSE);
1168
1169       proto_tree_add_item (iax2_tree, hf_iax2_iseqno, tvb, offset+7, 1,
1170                            FALSE);
1171       packet_type_base = proto_tree_add_uint (iax2_tree, hf_iax2_type, tvb,
1172                                               offset+8, 1, type);
1173
1174       /* add the type-specific subtree */
1175       packet_type_tree = proto_item_add_subtree (packet_type_base, ett_iax2_type);
1176   }
1177
1178   /* add frame type to info line */
1179   if (check_col (pinfo->cinfo, COL_INFO)) {
1180     col_add_fstr (pinfo->cinfo, COL_INFO, "%s, source call# %d, timestamp %ums",
1181                   val_to_str (type, iax_frame_types, "Unknown (0x%02x)"),
1182                   scallno, ts);
1183   }
1184
1185   switch( type ) {
1186   case AST_FRAME_IAX:
1187     /* add the subclass */
1188     proto_tree_add_uint (packet_type_tree, hf_iax2_iax_csub, tvb,
1189                            offset+9, 1, csub);
1190     offset += 10;
1191
1192     if (check_col (pinfo->cinfo, COL_INFO))
1193       col_append_fstr (pinfo->cinfo, COL_INFO, " %s", 
1194                     val_to_str (csub, iax_iax_subclasses, "unknown (0x%02x)"));
1195
1196     if (offset < tvb_reported_length (tvb)) {
1197       offset += dissect_ies(tvb, offset, packet_type_tree, iax_call);
1198     }
1199
1200     if( csub == IAX_COMMAND_NEW && circuit && iax_call ) {
1201       /* if this is a data call, set up a subdissector for the circuit */
1202       dissector_handle_t s;
1203       s = dissector_get_port_handle(iax2_dataformat_dissector_table, iax_call -> dataformat );
1204       circuit_set_dissector( circuit, s );
1205     }
1206     break;
1207
1208   case AST_FRAME_DTMF:
1209     proto_tree_add_text (packet_type_tree, tvb, offset+9, 1, "DTMF digit: %c", csub);
1210     offset += 10;
1211
1212     if (check_col (pinfo->cinfo, COL_INFO))
1213       col_append_fstr (pinfo->cinfo, COL_INFO, " digit %c", csub );
1214     break;
1215
1216   case AST_FRAME_CONTROL:
1217     /* add the subclass */
1218     proto_tree_add_uint (packet_type_tree, hf_iax2_cmd_csub, tvb,
1219                          offset+9, 1, csub);
1220     offset += 10;
1221
1222     if (check_col (pinfo->cinfo, COL_INFO))
1223       col_append_fstr (pinfo->cinfo, COL_INFO, " %s",
1224                     val_to_str (csub, iax_cmd_subclasses, "unknown (0x%02x)"));
1225     break;
1226
1227   case AST_FRAME_VOICE:
1228     /* add the codec */
1229     iax_packet -> codec = codec = uncompress_subclass(csub);
1230
1231     if( packet_type_tree ) {
1232       proto_tree_add_item (packet_type_tree, hf_iax2_voice_csub, tvb, offset+9, 1, FALSE);
1233       proto_tree_add_uint (packet_type_tree, hf_iax2_voice_codec, tvb, offset+9, 1, codec);
1234     }
1235
1236     offset += 10;
1237
1238     if( iax_call ) {
1239       if( reversed ) {
1240         iax_call->dst_codec = codec;
1241       } else {
1242         iax_call->src_codec = codec;
1243       }
1244     }
1245
1246     dissect_payload(tvb, offset, pinfo, main_tree, ts, FALSE,iax_packet);
1247     break;
1248
1249   case AST_FRAME_VIDEO:
1250     /* bit 6 of the csub is used to represent the rtp 'marker' bit */
1251     rtp_marker = csub & 0x40 ? TRUE:FALSE;
1252     iax_packet -> codec = codec = uncompress_subclass((guint8) (csub & ~40));
1253
1254     if( packet_type_tree ) {
1255       proto_tree_add_item (packet_type_tree, hf_iax2_video_csub, tvb, offset+9, 1, FALSE);
1256       proto_tree_add_item (packet_type_tree, hf_iax2_marker, tvb, offset+9, 1, FALSE);
1257       proto_tree_add_uint (packet_type_tree, hf_iax2_video_codec, tvb, offset+9, 1, codec);
1258     }
1259
1260     offset += 10;
1261
1262     if( iax_call ) {
1263       if( reversed ) {
1264         iax_call->dst_vformat = codec;
1265       } else {
1266         iax_call->src_vformat = codec;
1267       }
1268     }
1269
1270     if( rtp_marker && check_col (pinfo->cinfo, COL_INFO))
1271       col_append_fstr (pinfo->cinfo, COL_INFO, ", Mark" );
1272
1273
1274     dissect_payload(tvb, offset, pinfo, main_tree, ts, TRUE, iax_packet);
1275     break;
1276
1277
1278   default:
1279     proto_tree_add_uint (packet_type_tree, hf_iax2_csub, tvb, offset+9,
1280                          1, csub);
1281     offset += 10;
1282
1283     if (check_col (pinfo->cinfo, COL_INFO))
1284       col_append_fstr (pinfo->cinfo, COL_INFO, " subclass %d", csub );
1285     break;
1286   }
1287
1288   return offset;
1289 }
1290
1291 static iax_packet_data *iax2_get_packet_data_for_minipacket(packet_info * pinfo,
1292                                                             guint16 scallno,
1293                                                             gboolean video)
1294 {
1295   /* see if we've seen this packet before */
1296   iax_packet_data *p = (iax_packet_data *)p_get_proto_data(pinfo->fd,proto_iax2);
1297
1298   if( !p ) {
1299     /* if not, find or create an iax_call info structure for this IAX session. */
1300     gboolean reversed;
1301     circuit_t *circuit;
1302     iax_call_data *iax_call;
1303
1304     iax_call = iax_lookup_circuit_details(pinfo, scallno, 0, &reversed, &circuit);
1305
1306     p = iax_new_packet_data(iax_call);
1307     p_add_proto_data(pinfo->fd,proto_iax2,p);
1308
1309     /* set the codec for this frame to be whatever the last full frame used */
1310     if( iax_call ) {
1311      if( video ) 
1312         p->codec = reversed ? iax_call -> dst_vformat : iax_call -> src_vformat;
1313       else 
1314         p->codec = reversed ? iax_call -> dst_codec : iax_call -> src_codec;
1315     }
1316   }
1317   return p;
1318 }
1319
1320
1321 static guint32 dissect_minivideopacket (tvbuff_t * tvb, guint32 offset,
1322                                         guint16 scallno, packet_info * pinfo,
1323                                         proto_tree * iax2_tree, proto_tree *main_tree)
1324 {
1325   guint32 ts;
1326   iax_packet_data *iax_packet;
1327   gboolean rtp_marker;
1328
1329   ts = tvb_get_ntohs(tvb, offset);
1330
1331   /* bit 15 of the ts is used to represent the rtp 'marker' bit */
1332   rtp_marker = ts & 0x8000 ? TRUE:FALSE;
1333   ts &= ~0x8000;
1334
1335
1336   if( iax2_tree ) {
1337     proto_tree_add_item (iax2_tree, hf_iax2_minividts, tvb, offset, 2, FALSE);
1338     proto_tree_add_item (iax2_tree, hf_iax2_minividmarker, tvb, offset, 2, FALSE);
1339   }
1340
1341   offset += 2;
1342   
1343   iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, TRUE);
1344   
1345   if (check_col (pinfo->cinfo, COL_INFO))
1346       col_add_fstr (pinfo->cinfo, COL_INFO, 
1347                     "Mini video packet, source call# %d, timestamp %ums%s",
1348                     scallno, ts, rtp_marker?", Mark":"");
1349
1350
1351   dissect_payload(tvb, offset, pinfo, main_tree, ts, TRUE, iax_packet);
1352
1353   return offset;
1354 }
1355
1356 static guint32
1357 dissect_minipacket (tvbuff_t * tvb, guint32 offset, guint16 scallno, packet_info * pinfo, proto_tree * iax2_tree,
1358                     proto_tree *main_tree)
1359 {
1360   guint32 ts;
1361   iax_packet_data *iax_packet;
1362
1363   ts = tvb_get_ntohs(tvb, offset);
1364
1365   iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, FALSE);
1366   
1367   proto_tree_add_uint (iax2_tree, hf_iax2_minits, tvb, offset, 2,
1368                        ts);
1369   offset += 2;
1370   
1371   if (check_col (pinfo->cinfo, COL_INFO))
1372       col_add_fstr (pinfo->cinfo, COL_INFO, 
1373                     "Mini packet, source call# %d, timestamp %ums",
1374                     scallno, ts);
1375
1376
1377   /* XXX fix the timestamp logic */
1378   dissect_payload(tvb, offset, pinfo, main_tree, ts, FALSE, iax_packet);
1379
1380
1381   return offset;
1382 }
1383
1384 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
1385                             packet_info *pinfo, proto_tree *tree,
1386                             guint32 ts, gboolean video,
1387                             iax_packet_data *iax_packet)
1388 {
1389   gboolean out_of_order = FALSE;
1390   tvbuff_t *sub_tvb;
1391   guint32 codec = iax_packet -> codec;
1392   iax_call_data *iax_call = iax_packet -> call_data;
1393
1394   /* keep compiler quiet */
1395   ts = ts;
1396
1397   if( offset >= tvb_reported_length (tvb)) {
1398     if (check_col (pinfo->cinfo, COL_INFO))
1399       col_append_fstr (pinfo->cinfo, COL_INFO, ", empty frame" );
1400     return;
1401   }
1402
1403   sub_tvb = tvb_new_subset(tvb, offset, -1, -1 );
1404
1405   /* XXX shouldn't pass through out-of-order packets. */
1406
1407   if (check_col (pinfo->cinfo, COL_INFO)) {
1408     if( !video && iax_call && iax_call -> dataformat != 0 ) {
1409       col_append_fstr (pinfo->cinfo, COL_INFO, ", data, format %s",
1410                        val_to_str (iax_call -> dataformat, 
1411                                    iax_dataformats, "unknown (0x%02x)"));
1412
1413       if( out_of_order )
1414         col_append_fstr (pinfo->cinfo, COL_INFO, " (out-of-order packet)");
1415     } else {
1416       col_append_fstr (pinfo->cinfo, COL_INFO, ", %s",
1417                        val_to_str (codec, codec_types, "unknown (0x%02x)"));
1418     }
1419   }
1420
1421   /* pass the rest of the block to a subdissector */
1422   if( !video && try_circuit_dissector(pinfo->ctype, pinfo->circuit_id, pinfo->fd->num,
1423                             sub_tvb, pinfo, tree))
1424     return;
1425
1426   if( codec != 0 && dissector_try_port(iax2_codec_dissector_table, codec, sub_tvb, pinfo, tree ))
1427     return;
1428   
1429   /* we don't know how to dissect our data: dissect it as data */
1430   call_dissector(data_handle,sub_tvb, pinfo, tree);
1431 }
1432
1433 /*
1434  * Init routines
1435  */
1436
1437 /* called at the start of a capture. We should clear out our static, per-capture
1438  * data.
1439  */
1440
1441 static void
1442 iax_init_protocol(void)
1443 {
1444   iax_init_hash();
1445
1446   if (iax_packets)
1447     g_mem_chunk_destroy(iax_packets);
1448   iax_packets = g_mem_chunk_create(iax_packet_data,128,G_ALLOC_ONLY);
1449 }
1450
1451
1452 void
1453 proto_register_iax2 (void)
1454 {
1455   /* we use this for displaying which codecs are supported */
1456   static const true_false_string supported_strings = {
1457     "Supported",
1458     "Not supported"
1459   };
1460
1461   /* A header field is something you can search/filter on.
1462    * 
1463    * We create a structure to register our fields. It consists of an
1464    * array of hf_register_info structures, each of which are of the format
1465    * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
1466    */
1467    
1468   static hf_register_info hf[] = {
1469
1470     {&hf_iax2_packet_type,
1471      {"Packet type", "iax2.type", FT_UINT8, BASE_DEC, VALS(iax_packet_types), 0,
1472       "Full/minivoice/minivideo/meta packet",
1473       HFILL}},
1474
1475
1476     {&hf_iax2_scallno,
1477      {"Source call", "iax2.src_call", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
1478       "src_call holds the number of this call at the packet source pbx",
1479       HFILL}},
1480
1481     /* FIXME could this be turned into a FRAMENUM field? */
1482     {&hf_iax2_dcallno,
1483      {"Destination call", "iax2.dst_call", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
1484       "dst_call holds the number of this call at the packet destination",
1485       HFILL}},
1486
1487     {&hf_iax2_retransmission,
1488      {"Retransmission", "iax2.retransmission", FT_BOOLEAN, 16,
1489       NULL, 0x8000,
1490       "retransmission is set if this packet is a retransmission of an earlier "
1491       "failed packet", HFILL}},
1492
1493     {&hf_iax2_ts,
1494      {"Timestamp", "iax2.timestamp", FT_UINT32, BASE_DEC, NULL, 0x0,
1495       "timestamp is the time, in ms after the start of this call, at which "
1496       "this packet was transmitted",
1497       HFILL}},
1498
1499     {&hf_iax2_minits,
1500      {"Timestamp", "iax2.timestamp", FT_UINT16, BASE_DEC, NULL, 0x0,
1501       "timestamp is the time, in ms after the start of this call, at which "
1502       "this packet was transmitted",
1503       HFILL}},
1504
1505     {&hf_iax2_minividts,
1506      {"Timestamp", "iax2.timestamp", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
1507       "timestamp is the time, in ms after the start of this call, at which "
1508       "this packet was transmitted",
1509       HFILL}},
1510
1511     {&hf_iax2_minividmarker,
1512      {"Marker", "iax2.video.marker", FT_UINT16, BASE_DEC, NULL, 0x8000,
1513       "RTP end-of-frame marker",
1514       HFILL}},
1515
1516     {&hf_iax2_oseqno,
1517      {"Outbound seq.no.", "iax2.oseqno", FT_UINT16, BASE_DEC, NULL,
1518       0x0, 
1519       "oseqno is the sequence no of this packet. The first packet has "
1520       "oseqno==0, and subsequent packets increment the oseqno by 1",
1521       HFILL}},
1522
1523     {&hf_iax2_iseqno,
1524      {"Inbound seq.no.", "iax2.iseqno", FT_UINT16, BASE_DEC, NULL, 0x0,
1525       "iseqno is the sequence no of the last successfully recieved packet",
1526       HFILL}},
1527
1528     {&hf_iax2_type,
1529      {"Type", "iax2.type", FT_UINT8, BASE_DEC, VALS (iax_frame_types),
1530       0x0,
1531       "For full IAX2 frames, type is the type of frame",
1532       HFILL}},
1533
1534     {&hf_iax2_csub,
1535      {"Sub-class", "iax2.subclass", FT_UINT8, BASE_DEC, NULL, 0x0, 
1536       "subclass",
1537       HFILL}},
1538
1539     {&hf_iax2_cmd_csub,
1540      {"Control subclass", "iax2.control.subclass", FT_UINT8, BASE_DEC,
1541       VALS (iax_cmd_subclasses), 0x0, 
1542       "This gives the command number for a Control packet.", HFILL}},
1543
1544     {&hf_iax2_iax_csub,
1545      {"IAX type", "iax2.iax.subclass", FT_UINT8, BASE_DEC,
1546       VALS (iax_iax_subclasses),
1547       0x0, 
1548       "IAX type gives the command number for IAX signalling packets", HFILL}},
1549
1550     {&hf_iax2_voice_csub,
1551      {"Sub-class", "iax2.voice.subclass", FT_UINT8, BASE_DEC, NULL, 0x0, 
1552       "subclass",
1553       HFILL}},
1554
1555     {&hf_iax2_voice_codec,
1556      {"CODEC", "iax2.voice.codec", FT_UINT32, BASE_HEX, VALS (codec_types),
1557       0x0, 
1558       "CODEC gives the codec used to encode audio data", HFILL}},
1559
1560     {&hf_iax2_video_csub,
1561      {"Subclass (compressed codec no)", "iax2.video.subclass", FT_UINT8, BASE_DEC, NULL, 0xBF, 
1562       "Subclass (compressed codec no)",
1563       HFILL}},
1564     
1565     {&hf_iax2_marker,
1566      {"Marker", "iax2.video.marker", FT_BOOLEAN, 8, NULL, 0x40,
1567       "RTP end-of-frame marker",
1568       HFILL}},
1569
1570     {&hf_iax2_video_codec,
1571      {"CODEC", "iax2.video.codec", FT_UINT32, BASE_HEX, VALS (codec_types), 0, 
1572       "The codec used to encode video data", HFILL}},
1573     
1574     /*
1575      * Decoding for the ies
1576      */
1577
1578     {&hf_IAX_IE_APPARENTADDR_SINFAMILY,
1579      {"Family", "iax2.iax.app_addr.sinfamily", FT_UINT16, BASE_DEC, NULL, 0, "Family", HFILL }},
1580     {&hf_IAX_IE_APPARENTADDR_SINPORT,
1581      {"Port", "iax2.iax.app_addr.sinport", FT_UINT16, BASE_DEC, NULL, 0, "Port", HFILL }},
1582     {&hf_IAX_IE_APPARENTADDR_SINADDR,
1583      {"Address", "iax2.iax.app_addr.sinaddr", FT_IPv4, BASE_HEX, NULL, 0, "Address", HFILL }},
1584     {&hf_IAX_IE_APPARENTADDR_SINZERO,
1585      {"Zero", "iax2.iax.app_addr.sinzero", FT_BYTES, BASE_HEX, NULL, 0, "Zero", HFILL }},
1586
1587     {&hf_IAX_IE_CALLED_NUMBER,
1588      {"Number/extension being called", "iax2.iax.called_number",
1589       FT_STRING,
1590       BASE_NONE, NULL, 0x0, "", HFILL}},
1591
1592     {&hf_IAX_IE_CALLING_NUMBER,
1593      {"Calling number", "iax2.iax.calling_number", FT_STRING,
1594       BASE_NONE, NULL,
1595       0x0, "", HFILL}},
1596
1597     {&hf_IAX_IE_CALLING_ANI,
1598      {"Calling number ANI for billing", "iax2.iax.calling_ani",
1599       FT_STRING,
1600       BASE_NONE, NULL, 0x0, "", HFILL}},
1601
1602     {&hf_IAX_IE_CALLING_NAME,
1603      {"Name of caller", "iax2.iax.calling_name", FT_STRING, BASE_NONE,
1604       NULL,
1605       0x0, "", HFILL}},
1606
1607     {&hf_IAX_IE_CALLED_CONTEXT,
1608      {"Context for number", "iax2.iax.called_context", FT_STRING,
1609       BASE_NONE,
1610       NULL, 0x0, "", HFILL}},
1611
1612     {&hf_IAX_IE_USERNAME,
1613      {"Username (peer or user) for authentication",
1614       "iax2.iax.username",
1615       FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1616
1617     {&hf_IAX_IE_PASSWORD,
1618      {"Password for authentication", "iax2.iax.password", FT_STRING,
1619       BASE_NONE, NULL, 0x0, "", HFILL}},
1620
1621     {&hf_IAX_IE_CAPABILITY,
1622      {"Actual codec capability", "iax2.iax.capability", FT_UINT32,
1623       BASE_HEX,
1624       NULL, 0x0, "", HFILL}},
1625
1626     {&hf_IAX_IE_FORMAT,
1627      {"Desired codec format", "iax2.iax.format", FT_UINT32, BASE_HEX,
1628       VALS (codec_types), 0x0, "", HFILL}},
1629
1630     {&hf_IAX_IE_LANGUAGE,
1631      {"Desired language", "iax2.iax.language", FT_STRING, BASE_NONE,
1632       NULL,
1633       0x0, "", HFILL}},
1634
1635     {&hf_IAX_IE_VERSION,
1636      {"Protocol version", "iax2.iax.version", FT_UINT16, BASE_HEX, NULL,
1637       0x0,
1638       "", HFILL}},
1639
1640     {&hf_IAX_IE_ADSICPE,
1641      {"CPE ADSI capability", "iax2.iax.cpe_adsi", FT_UINT16, BASE_HEX,
1642       NULL,
1643       0x0, "", HFILL}},
1644
1645     {&hf_IAX_IE_DNID,
1646      {"Originally dialed DNID", "iax2.iax.dnid", FT_STRING, BASE_NONE,
1647       NULL,
1648       0x0, "", HFILL}},
1649
1650     {&hf_IAX_IE_AUTHMETHODS,
1651      {"Authentication method(s)", "iax2.iax.auth.methods", FT_UINT16,
1652       BASE_HEX,
1653       NULL, 0x0, "", HFILL}},
1654
1655     {&hf_IAX_IE_CHALLENGE,
1656      {"Challenge data for MD5/RSA", "iax2.iax.auth.challenge",
1657       FT_STRING,
1658       BASE_NONE, NULL, 0x0, "", HFILL}},
1659
1660     {&hf_IAX_IE_MD5_RESULT,
1661      {"MD5 challenge result", "iax2.iax.auth.md5", FT_STRING,
1662       BASE_NONE, NULL,
1663       0x0, "", HFILL}},
1664
1665     {&hf_IAX_IE_RSA_RESULT,
1666      {"RSA challenge result", "iax2.iax.auth.rsa", FT_STRING,
1667       BASE_NONE, NULL,
1668       0x0, "", HFILL}},
1669
1670     {&hf_IAX_IE_REFRESH,
1671      {"When to refresh registration", "iax2.iax.refresh", FT_INT16,
1672       BASE_DEC,
1673       NULL, 0x0, "", HFILL}},
1674
1675     {&hf_IAX_IE_DPSTATUS,
1676      {"Dialplan status", "iax2.iax.dialplan_status", FT_UINT16,
1677       BASE_HEX, NULL,
1678       0x0, "", HFILL}},
1679
1680     {&hf_IAX_IE_CALLNO,
1681      {"Call number of peer", "iax2.iax.call_no", FT_INT16, BASE_DEC,
1682       NULL,
1683       0x0, "", HFILL}},
1684
1685     {&hf_IAX_IE_CAUSE,
1686      {"Cause", "iax2.iax.cause", FT_STRING, BASE_NONE, NULL, 0x0, "",
1687       HFILL}},
1688
1689     {&hf_IAX_IE_IAX_UNKNOWN,
1690      {"Unknown IAX command", "iax2.iax.iax_unknown", FT_BYTES,
1691       BASE_HEX, NULL,
1692       0x0, "", HFILL}},
1693
1694     {&hf_IAX_IE_MSGCOUNT,
1695      {"How many messages waiting", "iax2.iax.msg_count", FT_INT16,
1696       BASE_DEC,
1697       NULL, 0x0, "", HFILL}},
1698
1699     {&hf_IAX_IE_AUTOANSWER,
1700      {"Request auto-answering", "iax2.iax.autoanswer", FT_NONE,
1701       BASE_NONE,
1702       NULL, 0x0, "", HFILL}},
1703
1704     {&hf_IAX_IE_MUSICONHOLD,
1705      {"Request musiconhold with QUELCH", "iax2.iax.moh", FT_NONE,
1706       BASE_NONE,
1707       NULL, 0x0, "", HFILL}},
1708
1709     {&hf_IAX_IE_TRANSFERID,
1710      {"Transfer Request Identifier", "iax2.iax.transferid", FT_UINT32,
1711       BASE_HEX, NULL, 0x0, "", HFILL}},
1712
1713     {&hf_IAX_IE_RDNIS,
1714      {"Referring DNIS", "iax2.iax.rdnis", FT_STRING, BASE_NONE, NULL,
1715       0x0, "",
1716       HFILL}},
1717
1718     {&hf_IAX_IE_DATAFORMAT,
1719      {"Data call format", "iax2.iax.dataformat", FT_UINT32, BASE_HEX,
1720       VALS(iax_dataformats), 0x0, "", HFILL}},
1721
1722     {&hf_IAX_IE_UNKNOWN_BYTE,
1723      {"data", "iax2.iax.unknowndata", FT_UINT8, BASE_HEX, NULL,
1724       0x0, "Raw data for unknown IEs",
1725       HFILL}},
1726     {&hf_IAX_IE_UNKNOWN_I16,
1727      {"data", "iax2.iax.unknowndata", FT_UINT16, BASE_HEX, NULL,
1728       0x0, "Raw data for unknown IEs",
1729       HFILL}},
1730     {&hf_IAX_IE_UNKNOWN_I32,
1731      {"data", "iax2.iax.unknowndata", FT_UINT32, BASE_HEX, NULL,
1732       0x0, "Raw data for unknown IEs",
1733       HFILL}},
1734     {&hf_IAX_IE_UNKNOWN_BYTES,
1735      {"data", "iax2.iax.unknowndata", FT_BYTES, BASE_NONE, NULL,
1736       0x0, "Raw data for unknown IEs",
1737       HFILL}},
1738
1739     /* capablilites */
1740     {&hf_iax2_cap_g723_1,
1741      {"G.723.1 compression", "iax2.cap.g723_1", FT_BOOLEAN, 32,
1742       TFS(&supported_strings), AST_FORMAT_G723_1,
1743       "G.723.1 compression", HFILL }},
1744
1745     {&hf_iax2_cap_gsm,
1746      {"GSM compression", "iax2.cap.gsm", FT_BOOLEAN, 32,
1747        TFS(&supported_strings), AST_FORMAT_GSM, 
1748       "GSM compression", HFILL }},
1749
1750     {&hf_iax2_cap_ulaw,
1751      {"Raw mu-law data (G.711)", "iax2.cap.ulaw",FT_BOOLEAN, 32,
1752       TFS(&supported_strings), AST_FORMAT_ULAW,
1753       "Raw mu-law data (G.711)", HFILL }},
1754
1755      {&hf_iax2_cap_alaw,
1756       {"Raw A-law data (G.711)", "iax2.cap.alaw",FT_BOOLEAN, 32,
1757        TFS(&supported_strings), AST_FORMAT_ALAW,
1758        "Raw A-law data (G.711)", HFILL }},
1759
1760     {&hf_iax2_cap_g726,
1761      {"G.726 compression", "iax2.cap.g726",FT_BOOLEAN, 32,
1762       TFS(&supported_strings), AST_FORMAT_G726,
1763       "G.726 compression", HFILL }},
1764
1765     {&hf_iax2_cap_adpcm,
1766      {"ADPCM", "iax2.cap.adpcm", FT_BOOLEAN, 32,
1767       TFS(&supported_strings), AST_FORMAT_ADPCM,
1768       "ADPCM", HFILL }},
1769     
1770     {&hf_iax2_cap_slinear,
1771      {"Raw 16-bit Signed Linear (8000 Hz) PCM", "iax2.cap.slinear", 
1772       FT_BOOLEAN, 32, TFS(&supported_strings), AST_FORMAT_SLINEAR, 
1773       "Raw 16-bit Signed Linear (8000 Hz) PCM", HFILL }},
1774
1775     {&hf_iax2_cap_lpc10,
1776      {"LPC10, 180 samples/frame", "iax2.cap.lpc10", FT_BOOLEAN, 32,
1777       TFS(&supported_strings), AST_FORMAT_LPC10,
1778       "LPC10, 180 samples/frame", HFILL }},
1779
1780     {&hf_iax2_cap_g729a,
1781      {"G.729a Audio", "iax2.cap.g729a", FT_BOOLEAN, 32,
1782       TFS(&supported_strings), AST_FORMAT_G729A,
1783       "G.729a Audio", HFILL }},
1784
1785     {&hf_iax2_cap_speex,
1786      {"SPEEX Audio", "iax2.cap.speex", FT_BOOLEAN, 32,
1787       TFS(&supported_strings), AST_FORMAT_SPEEX,
1788       "SPEEX Audio", HFILL }},
1789
1790     {&hf_iax2_cap_ilbc,
1791      {"iLBC Free compressed Audio", "iax2.cap.ilbc", FT_BOOLEAN, 32,
1792       TFS(&supported_strings), AST_FORMAT_ILBC,
1793       "iLBC Free compressed Audio", HFILL }},
1794
1795     {&hf_iax2_cap_jpeg,
1796      {"JPEG images", "iax2.cap.jpeg", FT_BOOLEAN, 32,
1797       TFS(&supported_strings), AST_FORMAT_JPEG,
1798       "JPEG images", HFILL }},
1799
1800     {&hf_iax2_cap_png,
1801      {"PNG images", "iax2.cap.png", FT_BOOLEAN, 32,
1802       TFS(&supported_strings), AST_FORMAT_PNG,
1803       "PNG images", HFILL }},
1804
1805     {&hf_iax2_cap_h261,
1806      {"H.261 video", "iax2.cap.h261", FT_BOOLEAN, 32,
1807       TFS(&supported_strings), AST_FORMAT_H261,
1808       "H.261 video", HFILL }},
1809
1810     {&hf_iax2_cap_h263,
1811      {"H.263 video", "iax2.cap.h263", FT_BOOLEAN, 32,
1812       TFS(&supported_strings), AST_FORMAT_H263,
1813       "H.263 video", HFILL }}
1814   };
1815
1816   static gint *ett[] = {
1817     &ett_iax2,
1818     &ett_iax2_full_mini_subtree,
1819     &ett_iax2_type,
1820     &ett_iax2_ie,
1821     &ett_iax2_codecs,
1822     &ett_iax2_ies_apparent_addr
1823   };
1824
1825   proto_iax2 =
1826     proto_register_protocol ("Inter-Asterisk eXchange v2", "IAX2", "iax2");
1827   proto_register_field_array (proto_iax2, hf, array_length (hf));
1828   proto_register_subtree_array (ett, array_length (ett));
1829
1830   register_dissector("iax2", dissect_iax2, proto_iax2);
1831
1832   iax2_codec_dissector_table = register_dissector_table(
1833     "iax2.codec","IAX codec number", FT_UINT32, BASE_HEX);
1834   iax2_dataformat_dissector_table = register_dissector_table(
1835     "iax2.dataformat","IAX dataformat number", FT_UINT32, BASE_HEX);
1836   
1837   /* register our init routine to be called at the start of a capture,
1838      to clear out our hash tables etc */
1839   register_init_routine(&iax_init_protocol);
1840 }
1841
1842 void
1843 proto_reg_handoff_iax2 (void)
1844 {
1845   dissector_add("udp.port", IAX2_PORT, find_dissector("iax2"));
1846   dissector_add("iax2.dataformat", AST_DATAFORMAT_V110, find_dissector("v110"));
1847   data_handle = find_dissector("data");
1848 }
1849
1850
1851 /* 
1852  * This sets up the indentation style for this file in emacs.
1853  *
1854  * Local Variables:
1855  * c-basic-offset: 2
1856  * End:
1857  */