Bill Meier:
[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 #include <epan/emem.h>
42 #include <epan/reassemble.h>
43
44 #include "packet-iax2.h"
45 #include <epan/iax2_codec_type.h>
46
47 #define IAX2_PORT               4569
48 #define PROTO_TAG_IAX2          "IAX2"
49
50 /* enough to hold any address in an address_t */
51 #define MAX_ADDRESS 16
52
53 /* the maximum number of transfers (of each end) we can deal with per call,
54  * plus one */
55 #define IAX_MAX_TRANSFERS 2
56
57 /* #define DEBUG_HASHING */
58 /* #define DEBUG_DESEGMENT */
59
60 /* Ethereal ID of the IAX2 protocol */
61 static int proto_iax2 = -1;
62
63 /* The following hf_* variables are used to hold the ethereal IDs of
64  * our header fields; they are filled out when we call
65  * proto_register_field_array() in proto_register_iax2()
66  */
67 static int hf_iax2_packet_type = -1;
68 static int hf_iax2_retransmission = -1;
69 static int hf_iax2_callno = -1;
70 static int hf_iax2_scallno = -1;
71 static int hf_iax2_dcallno = -1;
72 static int hf_iax2_ts = -1;
73 static int hf_iax2_minits = -1;
74 static int hf_iax2_minividts = -1;
75 static int hf_iax2_absts = -1;
76 static int hf_iax2_lateness = -1;
77 static int hf_iax2_minividmarker = -1;
78 static int hf_iax2_oseqno = -1;
79 static int hf_iax2_iseqno = -1;
80 static int hf_iax2_type = -1;
81 static int hf_iax2_csub = -1;
82 static int hf_iax2_dtmf_csub = -1;
83 static int hf_iax2_cmd_csub = -1;
84 static int hf_iax2_iax_csub = -1;
85 static int hf_iax2_voice_csub = -1;
86 static int hf_iax2_voice_codec = -1;
87 static int hf_iax2_video_csub = -1;
88 static int hf_iax2_video_codec = -1;
89 static int hf_iax2_marker = -1;
90
91 static int hf_iax2_cap_g723_1 = -1;
92 static int hf_iax2_cap_gsm = -1;
93 static int hf_iax2_cap_ulaw = -1;
94 static int hf_iax2_cap_alaw = -1;
95 static int hf_iax2_cap_g726 = -1;
96 static int hf_iax2_cap_adpcm = -1;
97 static int hf_iax2_cap_slinear = -1;
98 static int hf_iax2_cap_lpc10 = -1;
99 static int hf_iax2_cap_g729a = -1;
100 static int hf_iax2_cap_speex = -1;
101 static int hf_iax2_cap_ilbc = -1;
102 static int hf_iax2_cap_jpeg = -1;
103 static int hf_iax2_cap_png = -1;
104 static int hf_iax2_cap_h261 = -1;
105 static int hf_iax2_cap_h263 = -1;
106
107 static int hf_iax2_fragments = -1;
108 static int hf_iax2_fragment = -1;
109 static int hf_iax2_fragment_overlap = -1;
110 static int hf_iax2_fragment_overlap_conflict = -1;
111 static int hf_iax2_fragment_multiple_tails = -1;
112 static int hf_iax2_fragment_too_long_fragment = -1;
113 static int hf_iax2_fragment_error = -1;
114 static int hf_iax2_reassembled_in = -1;
115
116
117 /* hf_iax2_ies is an array of header fields, one per potential Information
118  * Element. It's done this way (rather than having separate variables for each
119  * IE) to make the dissection of information elements clearer and more
120  * orthoganal.
121  *
122  * To add the ability to dissect a new information element, just add an
123  * appropriate entry to hf[] in proto_register_iax2(); dissect_ies() will then
124  * pick it up automatically.
125  */
126 static int hf_iax2_ies[256];
127 static int hf_iax2_ie_datetime = -1;
128 static int hf_IAX_IE_APPARENTADDR_SINFAMILY = -1;
129 static int hf_IAX_IE_APPARENTADDR_SINPORT = -1;
130 static int hf_IAX_IE_APPARENTADDR_SINADDR = -1;
131 static int hf_IAX_IE_UNKNOWN_BYTE = -1;
132 static int hf_IAX_IE_UNKNOWN_I16 = -1;
133 static int hf_IAX_IE_UNKNOWN_I32 = -1;
134 static int hf_IAX_IE_UNKNOWN_BYTES = -1;
135
136 /* These are the ids of the subtrees that we may be creating */
137 static gint ett_iax2 = -1;
138 static gint ett_iax2_full_mini_subtree = -1;
139 static gint ett_iax2_type = -1;         /* Frame-type specific subtree */
140 static gint ett_iax2_ie = -1;           /* single IE */
141 static gint ett_iax2_codecs = -1;       /* capabilities IE */
142 static gint ett_iax2_ies_apparent_addr = -1; /* apparent address IE */
143 static gint ett_iax2_fragment = -1;
144 static gint ett_iax2_fragments = -1;
145
146 static const fragment_items iax2_fragment_items = {
147   &ett_iax2_fragment,
148   &ett_iax2_fragments,
149   &hf_iax2_fragments,
150   &hf_iax2_fragment,
151   &hf_iax2_fragment_overlap,
152   &hf_iax2_fragment_overlap_conflict,
153   &hf_iax2_fragment_multiple_tails,
154   &hf_iax2_fragment_too_long_fragment,
155   &hf_iax2_fragment_error,
156   &hf_iax2_reassembled_in,
157   "iax2 fragments"
158 };
159
160 static dissector_handle_t data_handle;
161
162 /* data-call subdissectors, AST_DATAFORMAT_* */
163 static dissector_table_t iax2_dataformat_dissector_table;
164 /* voice/video call subdissectors, AST_FORMAT_* */
165 static dissector_table_t iax2_codec_dissector_table;
166
167 /* IAX2 Full-frame types */
168 static const value_string iax_frame_types[] = {
169   {0, "(0?)"},
170   {1, "DTMF"},
171   {2, "Voice"},
172   {3, "Video"},
173   {4, "Control"},
174   {5, "NULL"},
175   {6, "IAX"},
176   {7, "Text"},
177   {8, "Image"},
178   {0,NULL}
179 };
180
181 /* Subclasses for IAX packets */
182 static const value_string iax_iax_subclasses[] = {
183   {0, "(0?)"},
184   {1, "NEW"},
185   {2, "PING"},
186   {3, "PONG"},
187   {4, "ACK"},
188   {5, "HANGUP"},
189   {6, "REJECT"},
190   {7, "ACCEPT"},
191   {8, "AUTHREQ"},
192   {9, "AUTHREP"},
193   {10, "INVAL"},
194   {11, "LAGRQ"},
195   {12, "LAGRP"},
196   {13, "REGREQ"},
197   {14, "REGAUTH"},
198   {15, "REGACK"},
199   {16, "REGREJ"},
200   {17, "REGREL"},
201   {18, "VNAK"},
202   {19, "DPREQ"},
203   {20, "DPREP"},
204   {21, "DIAL"},
205   {22, "TXREQ"},
206   {23, "TXCNT"},
207   {24, "TXACC"},
208   {25, "TXREADY"},
209   {26, "TXREL"},
210   {27, "TXREJ"},
211   {28, "QUELCH"},
212   {29, "UNQULCH"},
213   {30, "POKE"},
214   {31, "PAGE"},
215   {32, "MWI"},
216   {33, "UNSUPPORTED"},
217   {34, "TRANSFER"},
218   {35, "PROVISION"},
219   {36, "FWDOWNL"},
220   {37, "FWDATA"},
221   {0,NULL}
222 };
223
224 /* Subclassess for Control packets */
225 static const value_string iax_cmd_subclasses[] = {
226   {0, "(0?)"},
227   {1, "HANGUP"},
228   {2, "RING"},
229   {3, "RINGING"},
230   {4, "ANSWER"},
231   {5, "BUSY"},
232   {6, "TKOFFHK"},
233   {7, "OFFHOOK"},
234   {0xFF, "stop sounds"}, /* sent by app_dial, and not much else */
235   {0,NULL}
236 };
237
238 /* Information elements */
239 static const value_string iax_ies_type[] = {
240   {IAX_IE_CALLED_NUMBER, "Number/extension being called"},
241   {IAX_IE_CALLING_NUMBER, "Calling number"},
242   {IAX_IE_CALLING_ANI, "Calling number ANI for billing"},
243   {IAX_IE_CALLING_NAME, "Name of caller"},
244   {IAX_IE_CALLED_CONTEXT, "Context for number"},
245   {IAX_IE_USERNAME, "Username (peer or user) for authentication"},
246   {IAX_IE_PASSWORD, "Password for authentication"},
247   {IAX_IE_CAPABILITY, "Actual codec capability"},
248   {IAX_IE_FORMAT, "Desired codec format"},
249   {IAX_IE_LANGUAGE, "Desired language"},
250   {IAX_IE_VERSION, "Protocol version"},
251   {IAX_IE_ADSICPE, "CPE ADSI capability"},
252   {IAX_IE_DNID, "Originally dialed DNID"},
253   {IAX_IE_AUTHMETHODS, "Authentication method(s)"},
254   {IAX_IE_CHALLENGE, "Challenge data for MD5/RSA"},
255   {IAX_IE_MD5_RESULT, "MD5 challenge result"},
256   {IAX_IE_RSA_RESULT, "RSA challenge result"},
257   {IAX_IE_APPARENT_ADDR, "Apparent address of peer"},
258   {IAX_IE_REFRESH, "When to refresh registration"},
259   {IAX_IE_DPSTATUS, "Dialplan status"},
260   {IAX_IE_CALLNO, "Call number of peer"},
261   {IAX_IE_CAUSE, "Cause"},
262   {IAX_IE_IAX_UNKNOWN, "Unknown IAX command"},
263   {IAX_IE_MSGCOUNT, "How many messages waiting"},
264   {IAX_IE_AUTOANSWER, "Request auto-answering"},
265   {IAX_IE_MUSICONHOLD, "Request musiconhold with QUELCH"},
266   {IAX_IE_TRANSFERID, "Transfer Request Identifier"},
267   {IAX_IE_RDNIS, "Referring DNIS"},
268   {IAX_IE_PROVISIONING, "Provisioning info"},
269   {IAX_IE_AESPROVISIONING, "AES Provisioning info"},
270   {IAX_IE_DATETIME,"Date/Time"},
271   {IAX_IE_DEVICETYPE, "Device type"},
272   {IAX_IE_SERVICEIDENT, "Service Identifier"},
273   {IAX_IE_FIRMWAREVER, "Firmware revision"},
274   {IAX_IE_FWBLOCKDESC, "Firmware block description"},
275   {IAX_IE_FWBLOCKDATA, "Firmware block of data"},
276   {IAX_IE_PROVVER, "Provisioning version"},
277   {IAX_IE_CALLINGPRES, "Calling presentation"},
278   {IAX_IE_CALLINGTON, "Calling type of number"},
279   {IAX_IE_CALLINGTNS, "Calling transit network select"},
280   {IAX_IE_SAMPLINGRATE, "Supported sampling rates"},
281   {IAX_IE_CAUSECODE, "Hangup cause"},
282   {IAX_IE_ENCRYPTION, "Encryption format"},
283   {IAX_IE_ENCKEY, "Raw encryption key"},
284   {IAX_IE_CODEC_PREFS, "Codec preferences"},
285   {IAX_IE_RR_JITTER, "Received jitter"},
286   {IAX_IE_RR_LOSS, "Received loss"},
287   {IAX_IE_RR_PKTS, "Received frames"},
288   {IAX_IE_RR_DELAY, "Max playout delay in ms for received frames"},
289   {IAX_IE_RR_DROPPED, "Dropped frames"},
290   {IAX_IE_RR_OOO, "Frames received out of order"},
291   {IAX_IE_DATAFORMAT, "Data call format"},
292   {0,NULL}
293 };
294
295 static const value_string codec_types[] = {
296   {AST_FORMAT_G723_1, "G.723.1 compression"},
297   {AST_FORMAT_GSM, "GSM compression"},
298   {AST_FORMAT_ULAW, "Raw mu-law data (G.711)"},
299   {AST_FORMAT_ALAW, "Raw A-law data (G.711)"},
300   {AST_FORMAT_G726, "ADPCM (G.726, 32kbps)"},
301   {AST_FORMAT_ADPCM, "ADPCM (IMA)"},
302   {AST_FORMAT_SLINEAR, "Raw 16-bit Signed Linear (8000 Hz) PCM"},
303   {AST_FORMAT_LPC10, "LPC10, 180 samples/frame"},
304   {AST_FORMAT_G729A, "G.729a Audio"},
305   {AST_FORMAT_SPEEX, "SpeeX Free Compression"},
306   {AST_FORMAT_ILBC, "iLBC Free Compression"},
307   {AST_FORMAT_JPEG, "JPEG Images"},
308   {AST_FORMAT_PNG, "PNG Images"},
309   {AST_FORMAT_H261, "H.261 Video"},
310   {AST_FORMAT_H263, "H.263 Video"},
311   {0,NULL}
312 };
313
314 static const value_string iax_dataformats[] = {
315   {AST_DATAFORMAT_NULL, "N/A (analogue call?)"},
316   {AST_DATAFORMAT_V110, "ITU-T V.110 rate adaption"},
317   {AST_DATAFORMAT_H223_H245,"ITU-T H.223/H.245"},
318   {0,NULL}
319 };
320
321 typedef enum {
322   IAX2_MINI_VOICE_PACKET,
323   IAX2_FULL_PACKET,
324   IAX2_MINI_VIDEO_PACKET,
325   IAX2_META_PACKET
326 } packet_type;
327
328 static const value_string iax_packet_types[] = {
329   {IAX2_FULL_PACKET, "Full packet"},
330   {IAX2_MINI_VOICE_PACKET, "Mini voice packet"},
331   {IAX2_MINI_VIDEO_PACKET, "Mini video packet"},
332   {IAX2_META_PACKET, "Meta packet"},
333   {0,NULL}
334 };
335   
336 static const value_string iax_causecodes[] = {
337   {AST_CAUSE_UNALLOCATED, "Unallocated"},
338   {AST_CAUSE_NO_ROUTE_TRANSIT_NET, "No route transit net"},
339   {AST_CAUSE_NO_ROUTE_DESTINATION, "No route to destination"},
340   {AST_CAUSE_CHANNEL_UNACCEPTABLE, "Channel unacceptable"},
341   {AST_CAUSE_CALL_AWARDED_DELIVERED, "Call awarded delivered"},
342   {AST_CAUSE_NORMAL_CLEARING, "Normal clearing"},
343   {AST_CAUSE_USER_BUSY, "User busy"},
344   {AST_CAUSE_NO_USER_RESPONSE, "No user response"},
345   {AST_CAUSE_NO_ANSWER, "No answer"},
346   {AST_CAUSE_CALL_REJECTED, "Call rejected"},
347   {AST_CAUSE_NUMBER_CHANGED, "Number changed"},
348   {AST_CAUSE_DESTINATION_OUT_OF_ORDER, "Destination out of order"},
349   {AST_CAUSE_INVALID_NUMBER_FORMAT, "Invalid number format"},
350   {AST_CAUSE_FACILITY_REJECTED, "Facility rejected"},
351   {AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "Response to status inquiry"},
352   {AST_CAUSE_NORMAL_UNSPECIFIED, "Normal unspecified"},
353   {AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "Normal circuit congestion"},
354   {AST_CAUSE_NETWORK_OUT_OF_ORDER, "Network out of order"},
355   {AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "Normal temporary failure"},
356   {AST_CAUSE_SWITCH_CONGESTION, "Switch congestion"},
357   {AST_CAUSE_ACCESS_INFO_DISCARDED, "Access info discarded"},
358   {AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "Requested channel unavailable"},
359   {AST_CAUSE_PRE_EMPTED, "Preempted"},
360   {AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "Facility not subscribed"},
361   {AST_CAUSE_OUTGOING_CALL_BARRED, "Outgoing call barred"},
362   {AST_CAUSE_INCOMING_CALL_BARRED, "Incoming call barred"},
363   {AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "Bearer capability not authorized"},
364   {AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "Bearer capability not available"},
365   {AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "Bearer capability not implemented"},
366   {AST_CAUSE_CHAN_NOT_IMPLEMENTED, "Channel not implemented"},
367   {AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "Facility not implemented"},
368   {AST_CAUSE_INVALID_CALL_REFERENCE, "Invalid call reference"},
369   {AST_CAUSE_INCOMPATIBLE_DESTINATION, "Incompatible destination"},
370   {AST_CAUSE_INVALID_MSG_UNSPECIFIED, "Invalid message unspecified"},
371   {AST_CAUSE_MANDATORY_IE_MISSING, "Mandatory IE missing"},
372   {AST_CAUSE_MESSAGE_TYPE_NONEXIST, "Message type nonexistent"},
373   {AST_CAUSE_WRONG_MESSAGE, "Wrong message"},
374   {AST_CAUSE_IE_NONEXIST, "IE nonexistent"},
375   {AST_CAUSE_INVALID_IE_CONTENTS, "Invalid IE contents"},
376   {AST_CAUSE_WRONG_CALL_STATE, "Wrong call state"},
377   {AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "Recovery on timer expire"},
378   {AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "Mandatory IE length error"},
379   {AST_CAUSE_PROTOCOL_ERROR, "Protocol error"},
380   {AST_CAUSE_INTERWORKING, "Interworking"},
381   {0, NULL}
382 };
383
384
385 /* ************************************************************************* */
386
387 /* In order to track IAX calls, we have a hash table which maps
388  * {addr,port type,port,call} to a unique circuit id.
389  *
390  * Each call has two such circuits associated with it (a forward and a
391  * reverse circuit, where 'forward' is defined as the direction the NEW
392  * packet went in), and we maintain an iax_call_data structure for each
393  * call, attached to both circuits with circuit_add_proto_data.
394  *
395  * Because {addr,port type,port,call} quadruplets can be reused
396  * (Asterisk reuses call numbers), circuit ids aren't unique to
397  * individual calls and we treat NEW packets somewhat specially. When we
398  * get such a packet, we see if there are any calls with a matching
399  * circuit id, and make sure that its circuits are marked as ended
400  * before that packet.
401  *
402  * A second complication is that we only know one quadruplet at the time
403  * the NEW packet is processed: there is therefore cunningness in
404  * iax_lookup_circuit_details() to look for replies to NEW packets and
405  * create the reverse circuit.
406  */
407
408
409 /* start with a hash of {addr,port type,port,call}->{id} */
410
411 typedef struct {
412   address addr;
413   port_type ptype;
414   guint32 port;
415   guint32 callno;
416
417   /* this is where addr->data points to. it's put in here for easy freeing */
418   guint8 address_data[MAX_ADDRESS];
419 } iax_circuit_key;
420
421 /* tables */
422 static GHashTable *iax_circuit_hashtab = NULL;
423 static guint circuitcount = 0;
424
425 /* the number of keys and values to reserve space for in each memory chunk.
426    We assume we won't be tracking many calls at once so this is quite low.
427 */
428 #define IAX_INIT_PACKET_COUNT 10
429
430 #ifdef DEBUG_HASHING
431 static gchar *key_to_str( const iax_circuit_key *key )
432 {
433   static int i=0;
434   static gchar *strp, str[3][80];
435
436   i++;
437   if(i>=3){
438     i=0;
439   }
440   strp=str[i];
441
442   /* why doesn't address_to_str take a const pointer?
443      cast the warnings into oblivion. */
444
445   /* XXX - is this a case for ep_alloc? */
446   g_snprintf(strp, 80, "{%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_debug( "+++ 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_debug( "+++ Hashing key: %s, result %#x", key_to_str(key), hash_val );
488 #endif
489   
490   return (guint) hash_val;
491 }
492
493 /* Find, or create, a circuit for the given
494    {address,porttype,port,call} quadruplet
495 */
496 static guint iax_circuit_lookup(const address *address,
497                                 port_type ptype,
498                                 guint32 port,
499                                 guint32 callno)
500 {
501   iax_circuit_key key;
502   guint32 *circuit_id_p;
503
504   key.addr = *address;
505   key.ptype = ptype;
506   key.port = port;
507   key.callno = callno;
508
509   circuit_id_p = g_hash_table_lookup( iax_circuit_hashtab, &key);
510   if( ! circuit_id_p ) {
511     iax_circuit_key *new_key;
512
513     new_key = se_alloc(sizeof(iax_circuit_key));
514     new_key->addr.type = address->type;
515     new_key->addr.len = MIN(address->len,MAX_ADDRESS);
516     new_key->addr.data = new_key->address_data;
517     memmove(new_key->address_data,address->data,new_key->addr.len);
518     new_key->ptype = ptype;
519     new_key->port = port;
520     new_key->callno = callno;
521
522     circuit_id_p = se_alloc(sizeof(iax_circuit_key));
523     *circuit_id_p = ++circuitcount;
524
525     g_hash_table_insert(iax_circuit_hashtab, new_key, circuit_id_p);
526
527 #ifdef DEBUG_HASHING
528     g_debug("Created new circuit id %u for node %s", *circuit_id_p, key_to_str(new_key));
529 #endif
530   }
531
532   return *circuit_id_p;
533 }
534
535
536 /* ************************************************************************* */
537
538 typedef struct {
539   guint32     current_frag_id; /* invalid unless current_frag_bytes > 0 */
540   guint32     current_frag_bytes;
541   guint32     current_frag_minlen;
542 } iax_call_dirdata;
543
544 /* This is our per-call data structure, which is attached to both the
545  * forward and reverse circuits.
546  */
547 typedef struct iax_call_data {
548   /* For this data, src and dst are relative to the original direction under
549      which this call is stored. Obviously if the reversed flag is set true by
550      iax_find_call, src and dst are reversed relative to the direction the
551      actual source and destination of the data.
552
553      if the codec changes mid-call, we update it here; because we store a codec
554      number with each packet too, we handle going back to earlier packets
555      without problem.
556   */
557
558   iax_dataformat_t dataformat;
559   guint32 src_codec, dst_codec;
560   guint32 src_vformat, dst_vformat;
561
562   /* when a transfer takes place, we'll get a new circuit id; we assume that we
563      don't try to transfer more than IAX_MAX_TRANSFERS times in a call */
564   guint forward_circuit_ids[IAX_MAX_TRANSFERS];
565   guint reverse_circuit_ids[IAX_MAX_TRANSFERS];
566   guint n_forward_circuit_ids;
567   guint n_reverse_circuit_ids;
568
569   /* this is the subdissector for the call */
570   dissector_handle_t subdissector;
571
572   /* the absolute start time of the call */
573   nstime_t start_time;
574
575   GHashTable *fid_table;
576   GHashTable *fragment_table;
577   iax_call_dirdata dirdata[2];
578 } iax_call_data;
579
580 static void iax_init_hash( void )
581 {
582   if (iax_circuit_hashtab)
583     g_hash_table_destroy(iax_circuit_hashtab);
584
585   iax_circuit_hashtab = g_hash_table_new(iax_circuit_hash, iax_circuit_equal);
586
587   circuitcount = 0;
588 }
589
590
591
592 /* creates a new CT_IAX2 circuit with a specified circuit id for a call
593  *
594  * typically a call has up to three associated circuits: an original source, an
595  * original destination, and the result of a transfer.
596  *
597  * For each endpoint, a CT_IAX2 circuit is created and added to the call_data
598  * by this function
599  *
600  * 'reversed' should be true if this end is the one which would have _received_
601  * the NEW packet, or it is an endpoint to which the 'destination' is being
602  * transferred.
603  *
604  */
605 static circuit_t *iax2_new_circuit_for_call(guint circuit_id, guint framenum, iax_call_data *iax_call,
606                                             gboolean reversed)
607 {
608   circuit_t *res;
609   
610   if(( reversed && iax_call->n_reverse_circuit_ids >= IAX_MAX_TRANSFERS) ||
611      ( !reversed && iax_call->n_forward_circuit_ids >= IAX_MAX_TRANSFERS)) {
612     g_warning("Too many transfers for iax_call");
613     return NULL;
614   }
615   
616   res = circuit_new(CT_IAX2,
617                     circuit_id,
618                     framenum );
619
620   circuit_add_proto_data(res, proto_iax2, iax_call);
621         
622   if( reversed )
623     iax_call -> reverse_circuit_ids[iax_call->n_reverse_circuit_ids++] = circuit_id;
624   else
625     iax_call -> forward_circuit_ids[iax_call->n_forward_circuit_ids++] = circuit_id;
626
627   return res;
628 }
629
630
631 /* returns true if this circuit id is a "forward" circuit for this call: ie, it
632  * is the point which _sent_ the original 'NEW' packet, or a point to which that
633  * end was subsequently transferred */
634 static gboolean is_forward_circuit(guint circuit_id,
635                                    const iax_call_data *iax_call)
636 {
637   guint i;
638   for(i=0;i<iax_call->n_forward_circuit_ids;i++){
639     if(circuit_id == iax_call->forward_circuit_ids[i])
640       return TRUE;
641   }
642   return FALSE;
643 }
644
645 /* returns true if this circuit id is a "reverse" circuit for this call: ie, it
646  * is the point which _received_ the original 'NEW' packet, or a point to which that
647  * end was subsequently transferred */
648 static gboolean is_reverse_circuit(guint circuit_id,
649                                    const iax_call_data *iax_call)
650 {
651   guint i;
652   for(i=0;i<iax_call->n_reverse_circuit_ids;i++){
653     if(circuit_id == iax_call->reverse_circuit_ids[i])
654       return TRUE;
655   }
656   return FALSE;
657 }
658
659
660 static iax_call_data *iax_lookup_call_from_dest( guint src_circuit_id,
661                                                  guint dst_circuit_id,
662                                                  guint framenum,
663                                                  gboolean *reversed_p)
664 {
665   circuit_t *dst_circuit;
666   iax_call_data * iax_call;
667   gboolean reversed = FALSE;
668   
669   dst_circuit = find_circuit( CT_IAX2,
670                               dst_circuit_id,
671                               framenum );
672
673   if( !dst_circuit ) {
674 #ifdef DEBUG_HASHING
675     g_debug( "++ destination circuit not found, must have missed NEW packet" );
676 #endif
677     if( reversed_p )
678       *reversed_p = FALSE;
679     return NULL;
680   }
681
682 #ifdef DEBUG_HASHING
683   g_debug( "++ found destination circuit" );
684 #endif
685       
686   iax_call = (iax_call_data *)circuit_get_proto_data(dst_circuit,proto_iax2);
687
688   /* there's no way we can create a CT_IAX2 circuit without adding
689      iax call data to it; assert this */
690   DISSECTOR_ASSERT(iax_call);
691
692   if( is_forward_circuit(dst_circuit_id, iax_call )) {
693 #ifdef DEBUG_HASHING
694     g_debug( "++ destination circuit matches forward_circuit_id of call, "
695                "therefore packet is reversed" );
696 #endif
697
698     reversed = TRUE;
699
700     if( iax_call -> n_reverse_circuit_ids == 0 ) {
701       /* we are going in the reverse direction, and this call
702          doesn't have a reverse circuit associated with it.
703          create one now. */
704 #ifdef DEBUG_HASHING
705       g_debug( "++ reverse_circuit_id of call is zero, need to create a "
706                  "new reverse circuit for this call" );
707 #endif
708
709       iax2_new_circuit_for_call( src_circuit_id, framenum, iax_call, TRUE );
710 #ifdef DEBUG_HASHING
711       g_debug( "++ done" );
712 #endif
713     } else if( !is_reverse_circuit(src_circuit_id, iax_call )) {
714       g_warning( "IAX Packet %u from circuit ids %u->%u "
715                  "conflicts with earlier call with circuit ids %u->%u",
716                  framenum,
717                  src_circuit_id,dst_circuit_id,
718                  iax_call->forward_circuit_ids[0],
719                  iax_call->reverse_circuit_ids[0]);
720       return NULL;
721     }
722   } else if ( is_reverse_circuit(dst_circuit_id, iax_call)) {
723 #ifdef DEBUG_HASHING
724     g_debug( "++ destination circuit matches reverse_circuit_id of call, "
725                "therefore packet is forward" );
726 #endif
727
728     reversed = FALSE;
729     if( !is_forward_circuit(src_circuit_id, iax_call)) {
730       g_warning( "IAX Packet %u from circuit ids %u->%u "
731                  "conflicts with earlier call with circuit ids %u->%u",
732                  framenum,
733                  src_circuit_id,dst_circuit_id,
734                  iax_call->forward_circuit_ids[0],
735                  iax_call->reverse_circuit_ids[0]);
736       if( reversed_p )
737         *reversed_p = FALSE;
738       return NULL;
739     }
740   } else {
741     DISSECTOR_ASSERT_NOT_REACHED();
742   }
743
744   if( reversed_p )
745     *reversed_p = reversed;
746
747   return iax_call;
748 }
749
750   
751 /* looks up an iax_call for this packet */
752 static iax_call_data *iax_lookup_call( packet_info *pinfo, 
753                                        guint32 scallno,
754                                        guint32 dcallno,
755                                        gboolean *reversed_p)
756 {
757   gboolean reversed = FALSE;
758   iax_call_data *iax_call = NULL;
759   guint src_circuit_id;
760
761 #ifdef DEBUG_HASHING
762   g_debug( "++ iax_lookup_circuit_details: Looking up circuit for frame %u, "
763              "from {%s:%u:%u} to {%s:%u:%u}", pinfo->fd->num,
764              address_to_str(&pinfo->src),pinfo->srcport,scallno,
765              address_to_str(&pinfo->dst),pinfo->destport,dcallno);
766 #endif
767
768
769   src_circuit_id = iax_circuit_lookup(&pinfo->src,pinfo->ptype,
770                                       pinfo->srcport,scallno);
771
772
773   /* the most reliable indicator of call is the destination callno, if
774      we have one */
775   if( dcallno != 0 ) {
776     guint dst_circuit_id;
777 #ifdef DEBUG_HASHING
778     g_debug( "++ dcallno non-zero, looking up destination circuit" );
779 #endif
780
781     dst_circuit_id = iax_circuit_lookup(&pinfo->dst,pinfo->ptype,
782                                         pinfo->destport,dcallno);
783
784     iax_call = iax_lookup_call_from_dest(src_circuit_id, dst_circuit_id,
785                                          pinfo->fd->num, &reversed);
786   } else {
787     circuit_t *src_circuit;
788
789     /* in all other circumstances, the source circuit should already
790      * exist: its absense indicates that we missed the all-important NEW
791      * packet.
792      */
793
794     src_circuit = find_circuit( CT_IAX2,
795                             src_circuit_id,
796                             pinfo->fd->num );
797
798     if( src_circuit ) {
799       iax_call = (iax_call_data *)circuit_get_proto_data(src_circuit,proto_iax2);
800
801       /* there's no way we can create a CT_IAX2 circuit without adding
802          iax call data to it; assert this */
803       DISSECTOR_ASSERT(iax_call);
804
805       if( is_forward_circuit(src_circuit_id,iax_call))
806         reversed = FALSE;
807       else if(is_reverse_circuit(src_circuit_id,iax_call))
808         reversed = TRUE;
809       else {
810         /* there's also no way we can attach an iax_call_data to a circuit
811            without the circuit being either the forward or reverse circuit
812            for that call; assert this too.
813         */
814         DISSECTOR_ASSERT_NOT_REACHED();
815       }
816     }
817   }
818
819   if(reversed_p)
820     *reversed_p = reversed;
821
822 #ifdef DEBUG_HASHING
823   if( iax_call ) {
824     g_debug( "++ Found call for packet: id %u, reversed=%c", iax_call->forward_circuit_ids[0], reversed?'1':'0' );
825   } else {
826     g_debug( "++ Call not found. Must have missed the NEW packet?" );
827   }
828 #endif
829   
830   return iax_call;
831 }
832
833 /* initialise the per-direction parts of an iax_call_data structure */
834 static void init_dir_data(iax_call_dirdata *dirdata)
835 {
836   dirdata -> current_frag_bytes=0;
837   dirdata -> current_frag_minlen=0;
838 }
839
840
841 /* handles a NEW packet by creating a new iax call and forward circuit.
842    the reverse circuit is not created until the ACK is received and
843    is created by iax_lookup_circuit_details. */
844 static iax_call_data *iax_new_call( packet_info *pinfo, 
845                                     guint32 scallno)
846 {
847   iax_call_data *call;
848   guint circuit_id;
849   static const nstime_t millisecond = {0, 1000000};
850     
851 #ifdef DEBUG_HASHING
852   g_debug( "+ new_circuit: Handling NEW packet, frame %u", pinfo->fd->num );
853 #endif
854   
855   circuit_id = iax_circuit_lookup(&pinfo->src,pinfo->ptype,
856                                   pinfo->srcport,scallno);
857     
858   call = se_alloc(sizeof(iax_call_data));
859   call -> dataformat = 0;
860   call -> src_codec = 0;
861   call -> dst_codec = 0;
862   call -> n_forward_circuit_ids = 0;
863   call -> n_reverse_circuit_ids = 0;
864   call -> subdissector = NULL;
865   call -> start_time = pinfo->fd->abs_ts;
866   nstime_delta(&call -> start_time, &call -> start_time, &millisecond);
867   call -> fid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
868   init_dir_data(&call->dirdata[0]);
869   init_dir_data(&call->dirdata[1]);
870   call->fragment_table = NULL;
871   fragment_table_init(&(call->fragment_table));
872
873   iax2_new_circuit_for_call(circuit_id,pinfo->fd->num,call,FALSE);
874
875   return call;
876 }
877     
878
879 /* ************************************************************************* */
880
881 /* per-packet data */
882 typedef struct iax_packet_data {
883   gboolean first_time; /* we're dissecting this packet for the first time; so
884                           things like codec and transfer requests should be
885                           propogated into the call data */
886   iax_call_data *call_data;
887   guint32 codec;
888   gboolean reversed;
889   nstime_t abstime;    /* the absolute time of this packet, based on its
890                         * timestamp and the NEW packet's time (-1 if unknown) */
891 } iax_packet_data;
892
893 static iax_packet_data *iax_new_packet_data(iax_call_data *call, gboolean reversed)
894 {
895   iax_packet_data *p = se_alloc(sizeof(iax_packet_data));
896   p->first_time=TRUE;
897   p->call_data=call;
898   p->codec=0;
899   p->reversed=reversed;
900   p->abstime.secs=-1;
901   p->abstime.nsecs=-1;
902   return p;
903 }
904
905 static void  iax2_populate_pinfo_from_packet_data(packet_info *pinfo, const iax_packet_data * p)
906 {
907   /* info for subdissectors. We always pass on the original forward circuit,
908    * and steal the p2p_dir flag to indicate the direction */
909   if( p->call_data == NULL ) {
910      /* if we missed the NEW packet for this call, call_data will be null. it's
911       * tbd what the best thing to do here is. */
912     pinfo -> ctype = CT_NONE;
913   } else {
914     pinfo -> ctype = CT_IAX2;
915     pinfo -> circuit_id = (guint32)p->call_data->forward_circuit_ids[0];
916     pinfo -> p2p_dir = p->reversed?P2P_DIR_RECV:P2P_DIR_SENT;
917
918     if (check_col (pinfo->cinfo, COL_CIRCUIT_ID)) {
919       col_set_str (pinfo->cinfo, COL_CIRCUIT_ID, "" );
920       col_add_fstr(pinfo->cinfo, COL_CIRCUIT_ID, "%u", pinfo->circuit_id);
921     }
922     if (check_col (pinfo->cinfo, COL_IF_DIR))
923       col_set_str (pinfo->cinfo, COL_IF_DIR, p->reversed ? "rev" : "fwd" );
924   }
925 }
926
927
928 /* ************************************************************************* */
929
930 /* this is passed up from the IE dissector to the main dissector */
931 typedef struct
932 {
933   address peer_address;
934   port_type peer_ptype;
935   guint32 peer_port;
936   guint32 peer_callno;
937   guint32 dataformat;
938 } iax2_ie_data;
939
940
941 static guint32 dissect_fullpacket (tvbuff_t * tvb, guint32 offset,
942                                 guint16 scallno,
943                                 packet_info * pinfo,
944                                 proto_tree * iax2_tree,
945                                 proto_tree * main_tree);
946
947
948 static guint32 dissect_minipacket (tvbuff_t * tvb, guint32 offset, 
949                                 guint16 scallno,
950                                 packet_info * pinfo,
951                                 proto_tree * iax2_tree,
952                                 proto_tree * main_tree);
953
954 static guint32 dissect_minivideopacket (tvbuff_t * tvb, guint32 offset, 
955                                         guint16 scallno,
956                                         packet_info * pinfo,
957                                         proto_tree * iax2_tree,
958                                         proto_tree * main_tree);
959
960 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
961                             packet_info *pinfo, proto_tree *iax2_tree,
962                             proto_tree *tree, guint32 ts, gboolean video,
963                             iax_packet_data *iax_packet);
964
965
966
967 static void
968 dissect_iax2 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
969 {
970   proto_item *iax2_item = NULL;
971   proto_tree *iax2_tree = NULL;
972   proto_tree *full_mini_subtree = NULL;
973   guint32 offset = 0, len;
974   guint16 scallno = 0;
975   guint16 stmp;
976   packet_type type;
977
978   /* set up the protocol and info fields in the summary pane */
979   if (check_col (pinfo->cinfo, COL_PROTOCOL))
980     {
981       col_set_str (pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_IAX2);
982     }
983   if (check_col (pinfo->cinfo, COL_INFO))
984     {
985       col_clear (pinfo->cinfo, COL_INFO);
986     }
987
988   /* add the 'iax2' tree to the main tree */
989   if (tree)
990     {
991       iax2_item = proto_tree_add_item (tree, proto_iax2, tvb, offset, -1, FALSE);
992       iax2_tree = proto_item_add_subtree (iax2_item, ett_iax2);
993     }
994
995   stmp = tvb_get_ntohs(tvb, offset);
996   if( stmp == 0 ) {
997     /* starting with 0x0000 indicates either a mini video packet or a 'meta'
998      * packet, whatever that means */
999     offset+=2;
1000     stmp = tvb_get_ntohs(tvb, offset);
1001     if( stmp & 0x8000 ) {
1002       /* mini video packet */
1003       type = IAX2_MINI_VIDEO_PACKET;
1004       scallno = stmp & 0x7FFF;
1005       offset += 2;
1006     }
1007     else {
1008       type = IAX2_META_PACKET;
1009     }
1010   } else {
1011     /* The source call/fullpacket flag is common to both mini and full packets */
1012     scallno = tvb_get_ntohs(tvb, offset);
1013     offset += 2;
1014     if( scallno & 0x8000 )
1015       type = IAX2_FULL_PACKET;
1016     else {
1017       type = IAX2_MINI_VOICE_PACKET;
1018     }
1019     scallno &= 0x7FFF;
1020   }
1021
1022   if( tree ) {
1023     proto_item *full_mini_base;
1024
1025     full_mini_base = proto_tree_add_uint(iax2_tree, hf_iax2_packet_type, tvb, 0, offset, type);
1026     full_mini_subtree = proto_item_add_subtree(full_mini_base, ett_iax2_full_mini_subtree);
1027
1028     if( scallno != 0 )
1029       proto_tree_add_item (full_mini_subtree, hf_iax2_scallno, tvb, offset-2, 2, FALSE);
1030   }
1031
1032   switch( type ) {
1033     case IAX2_FULL_PACKET:
1034       len = dissect_fullpacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
1035       break;
1036     case IAX2_MINI_VOICE_PACKET:
1037       len = dissect_minipacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
1038       break;
1039     case IAX2_MINI_VIDEO_PACKET:
1040       len = dissect_minivideopacket( tvb, offset, scallno, pinfo, full_mini_subtree, tree );
1041       break;
1042     case IAX2_META_PACKET:
1043       /* not implemented yet */
1044       len = 0;
1045       break;
1046     default:
1047       len = 0;
1048   }
1049
1050   /* update the 'length' of the main IAX2 header field so that it covers just the headers,
1051      not the audio data. */
1052   proto_item_set_len(iax2_item, len);
1053 }
1054
1055 static proto_item *dissect_datetime_ie(tvbuff_t *tvb, guint32 offset, proto_tree *ies_tree)
1056 {
1057   struct tm tm;
1058   guint32 ie_val;
1059   nstime_t datetime;
1060     
1061   proto_tree_add_item (ies_tree, hf_iax2_ies[IAX_IE_DATETIME], tvb, offset + 2, 4, FALSE);
1062   ie_val = tvb_get_ntohl(tvb, offset+2);
1063
1064   /* who's crazy idea for a time encoding was this? */
1065   tm.tm_sec  = (ie_val & 0x1f) << 1;
1066   tm.tm_min  = (ie_val>>5) & 0x3f;
1067   tm.tm_hour = (ie_val>>11) & 0x1f;
1068   tm.tm_mday = (ie_val>>16) & 0x1f;
1069   tm.tm_mon  = ((ie_val>>21) & 0xf) - 1;
1070   tm.tm_year = ((ie_val>>25) & 0x7f) + 100;
1071   tm.tm_isdst= -1; /* there's no info on whether DST was in force; assume it's
1072                     * the same as currently */
1073
1074   datetime.secs = mktime(&tm);
1075   datetime.nsecs = 0;
1076   return proto_tree_add_time (ies_tree, hf_iax2_ie_datetime, tvb, offset+2, 4, &datetime);
1077 }
1078   
1079
1080 /* dissect the information elements in an IAX frame. Returns the updated offset */
1081 static guint32 dissect_ies (tvbuff_t * tvb, guint32 offset,
1082                             proto_tree * iax_tree,
1083                             iax2_ie_data *ie_data)
1084 {
1085   DISSECTOR_ASSERT(ie_data);
1086   
1087   while (offset < tvb_reported_length (tvb)) {
1088
1089     int ies_type = tvb_get_guint8(tvb, offset);
1090     int ies_len = tvb_get_guint8(tvb, offset + 1);
1091
1092     if( iax_tree ) {
1093       proto_item *ti, *ie_item = NULL;
1094       proto_tree *ies_tree;
1095       int ie_hf = hf_iax2_ies[ies_type];
1096
1097       ti = proto_tree_add_text(iax_tree, tvb, offset, ies_len+2, " " );
1098
1099       ies_tree = proto_item_add_subtree(ti, ett_iax2_ie);
1100       
1101       proto_tree_add_text(ies_tree, tvb, offset, 1, "IE id: %s (0x%02X)",
1102                           val_to_str(ies_type, iax_ies_type, "Unknown"),
1103                           ies_type);
1104
1105       proto_tree_add_text(ies_tree, tvb, offset+1, 1, "Length: %u",ies_len);
1106
1107
1108       /* hf_iax2_ies[] is an array, indexed by IE number, of header-fields, one
1109          per IE. Apart from a couple of special cases which require more
1110          complex decoding, we can just look up an entry from the array, and add
1111          the relevant item.
1112       */
1113          
1114       switch (ies_type) {
1115         case IAX_IE_DATETIME:
1116           ie_item = dissect_datetime_ie(tvb,offset,ies_tree);
1117           break;
1118
1119         
1120         case IAX_IE_CAPABILITY:
1121         {
1122           proto_tree *codec_tree;
1123
1124           if (ies_len != 4) THROW(ReportedBoundsError);
1125
1126           ie_item =
1127             proto_tree_add_item (ies_tree, ie_hf,
1128                                  tvb, offset + 2, ies_len, FALSE);
1129           codec_tree =
1130             proto_item_add_subtree (ie_item, ett_iax2_codecs);
1131               
1132           proto_tree_add_item(codec_tree, hf_iax2_cap_g723_1, tvb, offset + 2, ies_len, FALSE );
1133           proto_tree_add_item(codec_tree, hf_iax2_cap_gsm, tvb, offset + 2, ies_len, FALSE );
1134           proto_tree_add_item(codec_tree, hf_iax2_cap_ulaw, tvb, offset + 2, ies_len, FALSE );
1135           proto_tree_add_item(codec_tree, hf_iax2_cap_alaw, tvb, offset + 2, ies_len, FALSE );
1136           proto_tree_add_item(codec_tree, hf_iax2_cap_g726, tvb, offset + 2, ies_len, FALSE );
1137           proto_tree_add_item(codec_tree, hf_iax2_cap_adpcm, tvb, offset + 2, ies_len, FALSE );
1138           proto_tree_add_item(codec_tree, hf_iax2_cap_slinear, tvb, offset + 2, ies_len, FALSE );
1139           proto_tree_add_item(codec_tree, hf_iax2_cap_lpc10, tvb, offset + 2, ies_len, FALSE );
1140           proto_tree_add_item(codec_tree, hf_iax2_cap_g729a, tvb, offset + 2, ies_len, FALSE );
1141           proto_tree_add_item(codec_tree, hf_iax2_cap_speex, tvb, offset + 2, ies_len, FALSE );
1142           proto_tree_add_item(codec_tree, hf_iax2_cap_ilbc, tvb, offset + 2, ies_len, FALSE );
1143           proto_tree_add_item(codec_tree, hf_iax2_cap_jpeg, tvb, offset + 2, ies_len, FALSE );
1144           proto_tree_add_item(codec_tree, hf_iax2_cap_png, tvb, offset + 2, ies_len, FALSE );
1145           proto_tree_add_item(codec_tree, hf_iax2_cap_h261, tvb, offset + 2, ies_len, FALSE );
1146           proto_tree_add_item(codec_tree, hf_iax2_cap_h263, tvb, offset + 2, ies_len, FALSE );
1147           break;
1148         }
1149
1150         case IAX_IE_APPARENT_ADDR:
1151         {
1152           proto_tree *sockaddr_tree = NULL;
1153           guint16 family;
1154
1155           ie_item = proto_tree_add_text(ies_tree, tvb, offset + 2, 16, "Apparent Address");
1156           sockaddr_tree = proto_item_add_subtree(ie_item, ett_iax2_ies_apparent_addr);
1157
1158           /* the family is little-endian. That's probably broken, given
1159              everything else is big-endian, but that's not our fault.
1160           */
1161           family = tvb_get_letohs(tvb, offset+2);
1162           proto_tree_add_uint(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINFAMILY, tvb, offset + 2, 2, family);
1163               
1164           switch( family ) {
1165             /* these come from linux/socket.h */
1166             case 2: /* AF_INET */
1167             {
1168               guint32 addr;
1169               
1170               /* IAX is always over UDP */
1171               ie_data->peer_ptype = PT_UDP;
1172               ie_data->peer_port = tvb_get_ntohs(tvb, offset+4);
1173               proto_tree_add_uint(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINPORT, tvb, offset + 4, 2, ie_data->peer_port);
1174               /* the ip address is big-endian, but then so is address.data */
1175               SET_ADDRESS(&ie_data->peer_address,AT_IPv4,4,tvb_get_ptr(tvb,offset+6,4));
1176               memcpy(&addr, ie_data->peer_address.data, 4);
1177               proto_tree_add_ipv4(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINADDR, tvb, offset + 6, 4, addr);
1178               break;
1179             }
1180
1181             default:
1182               g_warning("Not supported in IAX dissector: peer address family of %u", family);
1183               break;
1184           }
1185           break;
1186         }
1187               
1188         case IAX_IE_DATAFORMAT:
1189           if (ies_len != 4) THROW(ReportedBoundsError);
1190           ie_item = proto_tree_add_item (ies_tree, ie_hf, tvb,
1191                                offset + 2, ies_len, FALSE);
1192           ie_data -> dataformat = tvb_get_ntohl(tvb, offset+2);
1193           break;
1194
1195         default:
1196           if( ie_hf != -1 ) {
1197             /* throw an error if the IE isn't the expected length */
1198             gint explen = ftype_length(proto_registrar_get_nth(ie_hf)->type);
1199             if(explen != 0 && ies_len != explen)
1200               THROW(ReportedBoundsError);
1201             ie_item = proto_tree_add_item(ies_tree, ie_hf, tvb, offset + 2, ies_len, FALSE);
1202           } else {
1203             /* we don't understand this ie: add a generic one */
1204             guint32 value;
1205             const guint8 *ptr;
1206             const guint8 *ie_name = val_to_str(ies_type, iax_ies_type, "Unknown");
1207           
1208             switch(ies_len) {
1209               case 1:
1210                 value = tvb_get_guint8(tvb, offset + 2);
1211                 ie_item =
1212                   proto_tree_add_uint_format(ies_tree, hf_IAX_IE_UNKNOWN_BYTE,
1213                                              tvb, offset+2, 1, value,
1214                                              "%s: %#02x", ie_name, value );
1215                 break;
1216           
1217               case 2:
1218                 value = tvb_get_ntohs(tvb, offset + 2);
1219                 ie_item =
1220                   proto_tree_add_uint_format(ies_tree, hf_IAX_IE_UNKNOWN_I16,
1221                                              tvb, offset+2, 2, value,
1222                                              "%s: %#04x", ie_name, value );
1223                 break;
1224         
1225               case 4:
1226                 value = tvb_get_ntohl(tvb, offset + 2);
1227                 ie_item =
1228                   proto_tree_add_uint_format(ies_tree, hf_IAX_IE_UNKNOWN_I32,
1229                                              tvb, offset+2, 4, value,
1230                                              "%s: %#08x", ie_name, value );
1231                 break;
1232
1233               default:
1234                 ptr = tvb_get_ptr(tvb, offset + 2, ies_len);
1235                 ie_item =
1236                   proto_tree_add_string_format(ies_tree, hf_IAX_IE_UNKNOWN_BYTES,
1237                                                tvb, offset+2, ies_len, ptr,
1238                                                "%s: %s", ie_name, ptr );
1239                 break;
1240             }
1241           }
1242           break;
1243       }
1244
1245       /* by now, we *really* ought to have added an item */
1246       DISSECTOR_ASSERT(ie_item != NULL);
1247
1248       /* Retrieve the text from the item we added, and append it to the main IE
1249        * item */
1250       if(!PROTO_ITEM_IS_HIDDEN(ti)) {
1251         field_info *ie_finfo = PITEM_FINFO(ie_item);
1252         
1253         /* if the representation of the item has already been set, use that;
1254            else we have to allocate a block to put the text into */
1255         if( ie_finfo -> rep != NULL ) 
1256           proto_item_set_text(ti, "Information Element: %s",
1257                               ie_finfo->rep->representation);
1258         else {
1259           guint8 *ie_val = NULL;
1260           ie_val = g_malloc(ITEM_LABEL_LENGTH);
1261           proto_item_fill_label(ie_finfo, ie_val);
1262           proto_item_set_text(ti, "Information Element: %s",
1263                               ie_val);
1264           g_free(ie_val);
1265         }
1266       }
1267     }
1268
1269     offset += ies_len + 2;
1270   }
1271   return offset;
1272 }
1273
1274 static guint32 uncompress_subclass(guint8 csub)
1275 {
1276   /* If the SC_LOG flag is set, return 2^csub otherwise csub */
1277   if (csub & 0x80) {
1278     /* special case for 'compressed' -1 */
1279     if (csub == 0xff)
1280       return (guint32)-1;
1281     else
1282       return 1 << (csub & 0x1F);
1283   }
1284   else
1285     return (guint32)csub;
1286 }
1287
1288 /* returns the new offset */
1289 static guint32 dissect_iax2_command(tvbuff_t * tvb, guint32 offset,
1290                                     packet_info * pinfo, proto_tree *tree,
1291                                     iax_packet_data *iax_packet)
1292 {
1293   guint8 csub = tvb_get_guint8(tvb, offset);
1294   guint8 address_data[MAX_ADDRESS];
1295   iax2_ie_data ie_data;
1296   iax_call_data *iax_call;
1297
1298   ie_data.peer_address.type = AT_NONE;
1299   ie_data.peer_address.len = 0;
1300   ie_data.peer_address.data = address_data;
1301   ie_data.peer_ptype = 0;
1302   ie_data.peer_port = 0;
1303   ie_data.peer_callno = 0;
1304   ie_data.dataformat = (guint32)-1;
1305   iax_call = iax_packet -> call_data;
1306   
1307   /* add the subclass */
1308   proto_tree_add_uint (tree, hf_iax2_iax_csub, tvb, offset, 1, csub);
1309   offset++;
1310
1311   if (check_col (pinfo->cinfo, COL_INFO))
1312     col_append_fstr (pinfo->cinfo, COL_INFO, " %s", 
1313                      val_to_str (csub, iax_iax_subclasses, "unknown (0x%02x)"));
1314
1315   if (offset >= tvb_reported_length (tvb))
1316     return offset;
1317   
1318   offset += dissect_ies(tvb, offset, tree, &ie_data);
1319
1320   /* if this is a data call, set up a subdissector for the circuit */
1321   if(iax_call && ie_data.dataformat != (guint32)-1 && iax_call -> subdissector == NULL) {
1322     iax_call -> subdissector = dissector_get_port_handle(iax2_dataformat_dissector_table, ie_data.dataformat );
1323     iax_call -> dataformat = ie_data.dataformat;
1324   }
1325
1326   /* if this is a transfer request, record it in the call data */
1327   if( csub == IAX_COMMAND_TXREQ && iax_packet -> first_time ) {
1328     if( ie_data.peer_address.type != AT_NONE && ie_data.peer_callno != 0 ) {
1329       guint tx_circuit = iax_circuit_lookup(&ie_data.peer_address,
1330                                             ie_data.peer_ptype,
1331                                             ie_data.peer_port,
1332                                             ie_data.peer_callno);
1333
1334 #if 0
1335       g_debug("found transfer request for call %u->%u, to new id %u",
1336                 iax_call->forward_circuit_ids[0],
1337                 iax_call->reverse_circuit_ids[0],
1338                 tx_circuit);
1339 #endif
1340       
1341       iax2_new_circuit_for_call(tx_circuit,pinfo->fd->num,iax_call,iax_packet->reversed);
1342     }
1343   }
1344   
1345   return offset;
1346 }
1347
1348 static void iax2_add_ts_fields(packet_info * pinfo, proto_tree * iax2_tree, iax_packet_data *iax_packet, guint16 shortts)
1349 {
1350   guint32 longts = shortts;
1351   nstime_t ts;
1352   proto_item *item;
1353     
1354   if(iax_packet->call_data == NULL) {
1355     /* no call info for this frame; perhaps we missed the NEW packet */
1356     return;
1357   }
1358
1359   if(iax_packet->abstime.secs == -1) {
1360     time_t start_secs = iax_packet->call_data->start_time.secs;
1361     gint32 abs_secs = start_secs + longts/1000;
1362
1363     /* deal with short timestamps by assuming that packets are never more than
1364      * 16 seconds late */
1365     while(abs_secs < pinfo->fd->abs_ts.secs - 16) {
1366       longts += 32768;
1367       abs_secs = start_secs + longts/1000;
1368     }
1369
1370     iax_packet->abstime.secs=abs_secs;
1371     iax_packet->abstime.nsecs=iax_packet->call_data->start_time.nsecs + (longts % 1000) * 1000000;
1372     if(iax_packet->abstime.nsecs >= 1000000000) {
1373       iax_packet->abstime.nsecs -= 1000000000;
1374       iax_packet->abstime.secs ++;
1375     }
1376   }
1377   
1378   item = proto_tree_add_time(iax2_tree, hf_iax2_absts, NULL, 0, 0, &iax_packet->abstime);
1379   PROTO_ITEM_SET_GENERATED(item);
1380
1381   ts  = pinfo->fd->abs_ts;
1382   nstime_delta(&ts, &ts, &iax_packet->abstime);
1383   
1384   item = proto_tree_add_time(iax2_tree, hf_iax2_lateness, NULL, 0, 0, &ts);
1385   PROTO_ITEM_SET_GENERATED(item);
1386 }
1387
1388 /* returns the new offset */
1389 static guint32
1390 dissect_fullpacket (tvbuff_t * tvb, guint32 offset, 
1391                     guint16 scallno,
1392                     packet_info * pinfo, proto_tree * iax2_tree,
1393                     proto_tree * main_tree)
1394 {
1395   guint32 retransmission = 0;
1396   guint16 dcallno;
1397   guint32 ts;
1398   guint8 type;
1399   guint8 csub;
1400   guint32 codec;
1401
1402   proto_tree *packet_type_tree = NULL;
1403   iax_call_data *iax_call;
1404   iax_packet_data *iax_packet;
1405   gboolean reversed;
1406   gboolean rtp_marker;
1407
1408   /*
1409    * remove the top bit for retransmission detection 
1410    */
1411   dcallno = tvb_get_ntohs(tvb, offset);
1412   retransmission = dcallno & 0x8000;
1413   dcallno = dcallno & 0x7FFF;
1414   ts = tvb_get_ntohl(tvb, offset+2);
1415   type = tvb_get_guint8(tvb, offset + 8);
1416   csub = tvb_get_guint8(tvb, offset + 9);
1417
1418   /* see if we've seen this packet before */
1419   iax_packet = (iax_packet_data *)p_get_proto_data(pinfo->fd,proto_iax2);
1420   if( !iax_packet ) {
1421     /* if not, find or create an iax_call info structure for this IAX session. */
1422
1423     if( type == AST_FRAME_IAX && csub == IAX_COMMAND_NEW ) {
1424       /* NEW packets start a new call */
1425       iax_call = iax_new_call(pinfo,scallno);
1426       reversed = FALSE;
1427     } else {
1428       iax_call = iax_lookup_call(pinfo, scallno, dcallno,
1429                                  &reversed);
1430     }
1431
1432     iax_packet = iax_new_packet_data(iax_call, reversed);
1433     p_add_proto_data(pinfo->fd,proto_iax2,iax_packet);
1434   } else {
1435     iax_call = iax_packet->call_data;
1436     reversed = iax_packet->reversed;
1437   }
1438
1439   iax2_populate_pinfo_from_packet_data(pinfo, iax_packet);
1440   
1441   if( iax2_tree ) {
1442       proto_item *packet_type_base;
1443
1444       proto_tree_add_item (iax2_tree, hf_iax2_dcallno, tvb, offset, 2, FALSE );
1445
1446       proto_tree_add_boolean(iax2_tree, hf_iax2_retransmission, tvb, offset, 2, FALSE );
1447
1448       if( iax_call ) {
1449         proto_item *item = 
1450           proto_tree_add_uint (iax2_tree, hf_iax2_callno, tvb, 0, 4,
1451                              iax_call->forward_circuit_ids[0] );
1452         PROTO_ITEM_SET_GENERATED(item);
1453       }
1454
1455       proto_tree_add_uint (iax2_tree, hf_iax2_ts, tvb, offset+2, 4, ts);
1456       iax2_add_ts_fields(pinfo, iax2_tree, iax_packet, (guint16)ts);
1457
1458       proto_tree_add_item (iax2_tree, hf_iax2_oseqno, tvb, offset+6, 1,
1459                            FALSE);
1460
1461       proto_tree_add_item (iax2_tree, hf_iax2_iseqno, tvb, offset+7, 1,
1462                            FALSE);
1463       packet_type_base = proto_tree_add_uint (iax2_tree, hf_iax2_type, tvb,
1464                                               offset+8, 1, type);
1465
1466       /* add the type-specific subtree */
1467       packet_type_tree = proto_item_add_subtree (packet_type_base, ett_iax2_type);
1468   }
1469
1470   /* add frame type to info line */
1471   if (check_col (pinfo->cinfo, COL_INFO)) {
1472     col_add_fstr (pinfo->cinfo, COL_INFO, "%s, source call# %d, timestamp %ums",
1473                   val_to_str (type, iax_frame_types, "Unknown (0x%02x)"),
1474                   scallno, ts);
1475   }
1476
1477   switch( type ) {
1478   case AST_FRAME_IAX:
1479     offset=dissect_iax2_command(tvb,offset+9,pinfo,packet_type_tree,iax_packet);
1480     break;
1481     
1482   case AST_FRAME_DTMF:
1483     proto_tree_add_item (packet_type_tree, hf_iax2_dtmf_csub, tvb, offset+9, 1, FALSE);
1484     offset += 10;
1485
1486     if (check_col (pinfo->cinfo, COL_INFO))
1487       col_append_fstr (pinfo->cinfo, COL_INFO, " digit %c", csub );
1488     break;
1489
1490   case AST_FRAME_CONTROL:
1491     /* add the subclass */
1492     proto_tree_add_uint (packet_type_tree, hf_iax2_cmd_csub, tvb,
1493                          offset+9, 1, csub);
1494     offset += 10;
1495
1496     if (check_col (pinfo->cinfo, COL_INFO))
1497       col_append_fstr (pinfo->cinfo, COL_INFO, " %s",
1498                     val_to_str (csub, iax_cmd_subclasses, "unknown (0x%02x)"));
1499     break;
1500
1501   case AST_FRAME_VOICE:
1502     /* add the codec */
1503     iax_packet -> codec = codec = uncompress_subclass(csub);
1504
1505     if( packet_type_tree ) {
1506       proto_item *item;
1507       proto_tree_add_item (packet_type_tree, hf_iax2_voice_csub, tvb, offset+9, 1, FALSE);
1508       item = proto_tree_add_uint (packet_type_tree, hf_iax2_voice_codec, tvb, offset+9, 1, codec);
1509       PROTO_ITEM_SET_GENERATED(item);
1510     }
1511
1512     offset += 10;
1513
1514     if( iax_call ) {
1515       if( reversed ) {
1516         iax_call->dst_codec = codec;
1517       } else {
1518         iax_call->src_codec = codec;
1519       }
1520     }
1521
1522     dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, FALSE,iax_packet);
1523     break;
1524
1525   case AST_FRAME_VIDEO:
1526     /* bit 6 of the csub is used to represent the rtp 'marker' bit */
1527     rtp_marker = csub & 0x40 ? TRUE:FALSE;
1528     iax_packet -> codec = codec = uncompress_subclass((guint8) (csub & ~40));
1529
1530     if( packet_type_tree ) {
1531       proto_item *item;
1532       proto_tree_add_item (packet_type_tree, hf_iax2_video_csub, tvb, offset+9, 1, FALSE);
1533       proto_tree_add_item (packet_type_tree, hf_iax2_marker, tvb, offset+9, 1, FALSE);
1534       item = proto_tree_add_uint (packet_type_tree, hf_iax2_video_codec, tvb, offset+9, 1, codec);
1535       PROTO_ITEM_SET_GENERATED(item);
1536     }
1537
1538     offset += 10;
1539
1540     if( iax_call && iax_packet -> first_time ) {
1541       if( reversed ) {
1542         iax_call->dst_vformat = codec;
1543       } else {
1544         iax_call->src_vformat = codec;
1545       }
1546     }
1547
1548     if( rtp_marker && check_col (pinfo->cinfo, COL_INFO))
1549       col_append_fstr (pinfo->cinfo, COL_INFO, ", Mark" );
1550
1551
1552     dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, TRUE, iax_packet);
1553     break;
1554
1555
1556   default:
1557     proto_tree_add_uint (packet_type_tree, hf_iax2_csub, tvb, offset+9,
1558                          1, csub);
1559     offset += 10;
1560
1561     if (check_col (pinfo->cinfo, COL_INFO))
1562       col_append_fstr (pinfo->cinfo, COL_INFO, " subclass %d", csub );
1563     break;
1564   }
1565
1566   /* next time we come to parse this packet, don't propogate the codec into the
1567    * call_data */
1568   iax_packet->first_time = FALSE;
1569   
1570   return offset;
1571 }
1572
1573 static iax_packet_data *iax2_get_packet_data_for_minipacket(packet_info * pinfo,
1574                                                             guint16 scallno,
1575                                                             gboolean video)
1576 {
1577   /* see if we've seen this packet before */
1578   iax_packet_data *p = (iax_packet_data *)p_get_proto_data(pinfo->fd,proto_iax2);
1579
1580   if( !p ) {
1581     /* if not, find or create an iax_call info structure for this IAX session. */
1582     gboolean reversed;
1583     iax_call_data *iax_call;
1584
1585     iax_call = iax_lookup_call(pinfo, scallno, 0, &reversed);
1586
1587     p = iax_new_packet_data(iax_call,reversed);
1588     p_add_proto_data(pinfo->fd,proto_iax2,p);
1589
1590     /* set the codec for this frame to be whatever the last full frame used */
1591     if( iax_call ) {
1592      if( video ) 
1593         p->codec = reversed ? iax_call -> dst_vformat : iax_call -> src_vformat;
1594       else 
1595         p->codec = reversed ? iax_call -> dst_codec : iax_call -> src_codec;
1596     }
1597   }
1598
1599   iax2_populate_pinfo_from_packet_data(pinfo, p);
1600   return p;
1601 }
1602
1603
1604 static guint32 dissect_minivideopacket (tvbuff_t * tvb, guint32 offset,
1605                                         guint16 scallno, packet_info * pinfo,
1606                                         proto_tree * iax2_tree, proto_tree *main_tree)
1607 {
1608   guint32 ts;
1609   iax_packet_data *iax_packet;
1610   gboolean rtp_marker;
1611   proto_item *item;
1612
1613   ts = tvb_get_ntohs(tvb, offset);
1614
1615   /* bit 15 of the ts is used to represent the rtp 'marker' bit */
1616   rtp_marker = ts & 0x8000 ? TRUE:FALSE;
1617   ts &= ~0x8000;
1618
1619   iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, TRUE);
1620
1621   if( iax2_tree ) {
1622     if( iax_packet->call_data ) {
1623       item = 
1624         proto_tree_add_uint (iax2_tree, hf_iax2_callno, tvb, 0, 4,
1625                                     iax_packet->call_data->forward_circuit_ids[0] );
1626       PROTO_ITEM_SET_GENERATED(item);
1627     }
1628
1629     proto_tree_add_item (iax2_tree, hf_iax2_minividts, tvb, offset, 2, FALSE);
1630     iax2_add_ts_fields(pinfo, iax2_tree, iax_packet, (guint16)ts);
1631     proto_tree_add_item (iax2_tree, hf_iax2_minividmarker, tvb, offset, 2, FALSE);
1632   }
1633
1634   offset += 2;
1635   
1636   if (check_col (pinfo->cinfo, COL_INFO))
1637       col_add_fstr (pinfo->cinfo, COL_INFO, 
1638                     "Mini video packet, source call# %d, timestamp %ums%s",
1639                     scallno, ts, rtp_marker?", Mark":"");
1640
1641
1642   dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, TRUE, iax_packet);
1643
1644   /* next time we come to parse this packet, don't propogate the codec into the
1645    * call_data */
1646   iax_packet->first_time = FALSE;
1647   
1648   return offset;
1649 }
1650
1651 static guint32
1652 dissect_minipacket (tvbuff_t * tvb, guint32 offset, guint16 scallno, packet_info * pinfo, proto_tree * iax2_tree,
1653                     proto_tree *main_tree)
1654 {
1655   guint32 ts;
1656   iax_packet_data *iax_packet;
1657   proto_item *item;
1658
1659   ts = tvb_get_ntohs(tvb, offset);
1660
1661   iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, FALSE);
1662
1663   if( iax2_tree ) {
1664     if( iax_packet->call_data ) {
1665       item = proto_tree_add_uint (iax2_tree, hf_iax2_callno, tvb, 0, 4,
1666                                   iax_packet->call_data->forward_circuit_ids[0] );
1667       PROTO_ITEM_SET_GENERATED(item);
1668     }
1669
1670     proto_tree_add_uint (iax2_tree, hf_iax2_minits, tvb, offset, 2, ts);
1671     iax2_add_ts_fields(pinfo, iax2_tree, iax_packet,(guint16)ts);
1672   }
1673   
1674   offset += 2;
1675   
1676   if (check_col (pinfo->cinfo, COL_INFO))
1677       col_add_fstr (pinfo->cinfo, COL_INFO, 
1678                     "Mini packet, source call# %d, timestamp %ums",
1679                     scallno, ts);
1680
1681
1682   /* XXX fix the timestamp logic */
1683   dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, FALSE, iax_packet);
1684
1685
1686   /* next time we come to parse this packet, don't propogate the codec into the
1687    * call_data */
1688   iax_packet->first_time = FALSE;
1689   
1690   return offset;
1691 }
1692
1693 static void process_iax_pdu( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1694                               gboolean video, iax_packet_data *iax_packet )
1695 {
1696   guint32 codec = iax_packet -> codec;
1697   iax_call_data *iax_call = iax_packet -> call_data;
1698
1699 #ifdef DEBUG_DESEGMENT
1700   g_debug("calling process_iax_pdu; len = %u", tvb_reported_length(tvb));
1701 #endif
1702
1703   if( !video && iax_call && iax_call->subdissector ) {
1704     call_dissector(iax_call->subdissector, tvb, pinfo, tree);
1705   }else if( codec != 0 && dissector_try_port(iax2_codec_dissector_table, codec, tvb, pinfo, tree )) {
1706     /* codec dissector handled our data */
1707   }else {
1708     /* we don't know how to dissect our data: dissect it as data */
1709     call_dissector(data_handle,tvb, pinfo, tree);
1710   }
1711
1712 #ifdef DEBUG_DESEGMENT
1713   g_debug("called process_iax_pdu; pinfo->desegment_len=%u; pinfo->desegment_offset=%u",
1714             pinfo->desegment_len, pinfo->desegment_offset);
1715 #endif
1716 }
1717
1718 static void desegment_iax(tvbuff_t *tvb, packet_info *pinfo, proto_tree *iax2_tree,
1719                           proto_tree *tree, gboolean video, iax_packet_data *iax_packet )
1720 {
1721
1722   iax_call_data *iax_call = iax_packet -> call_data;
1723   iax_call_dirdata *dirdata;
1724   gpointer value;
1725   guint32 frag_offset;
1726   fragment_data *fd_head;
1727   gboolean must_desegment = FALSE;
1728
1729   DISSECTOR_ASSERT(iax_call);
1730   
1731   pinfo->can_desegment = 2;
1732   pinfo->desegment_offset = 0;
1733   pinfo->desegment_len = 0;
1734
1735 #ifdef DEBUG_DESEGMENT
1736   g_debug("dissecting packet %u", pinfo->fd->num);
1737 #endif
1738   
1739   dirdata = &(iax_call->dirdata[!!(iax_packet->reversed)]);
1740
1741   if((!pinfo->fd->flags.visited && dirdata->current_frag_bytes > 0) ||
1742      (value = g_hash_table_lookup(iax_call->fid_table,
1743                                   GUINT_TO_POINTER(pinfo->fd->num))) != NULL ) {
1744     /* then we are continuing an already-started pdu */
1745     guint32 fid;
1746     guint32 frag_len = tvb_reported_length( tvb );
1747     gboolean complete;
1748
1749 #ifdef DEBUG_DESEGMENT
1750     g_debug("visited: %i; c_f_b: %u; hash: %u->%u", pinfo->fd->flags.visited?1:0,
1751             dirdata->current_frag_bytes, pinfo->fd->num, fid);
1752 #endif
1753
1754     if(!pinfo->fd->flags.visited) {
1755       guint32 tot_len;
1756       fid = dirdata->current_frag_id;
1757       tot_len                      = dirdata->current_frag_minlen;
1758       g_hash_table_insert( iax_call->fid_table, GUINT_TO_POINTER(pinfo->fd->num), GUINT_TO_POINTER(fid) );
1759       frag_offset                  = dirdata->current_frag_bytes;
1760       dirdata->current_frag_bytes += frag_len;
1761       complete                     = dirdata->current_frag_bytes > tot_len;
1762 #ifdef DEBUG_DESEGMENT
1763       g_debug("hash: %u->%u; frag_offset: %u; c_f_b: %u; totlen: %u",
1764               pinfo->fd->num, fid, frag_offset, dirdata->current_frag_bytes, tot_len );
1765 #endif
1766     } else {
1767       fid = GPOINTER_TO_UINT(value);
1768       /* these values are unused by fragment_add if pinfo->fd->flags.visited */
1769       dirdata->current_frag_bytes = 0;
1770       complete = FALSE;
1771     }
1772
1773     /* fragment_add checks for already-added */
1774     fd_head = fragment_add( tvb, 0, pinfo, fid,
1775                             iax_call->fragment_table,
1776                             frag_offset,
1777                             frag_len, !complete );
1778     
1779     if(fd_head && (pinfo->fd->num == fd_head->reassembled_in)) {
1780       gint32 old_len;
1781       tvbuff_t *next_tvb = tvb_new_real_data(fd_head->data, fd_head->datalen, fd_head->datalen);
1782       tvb_set_child_real_data_tvbuff(tvb, next_tvb); 
1783       add_new_data_source(pinfo, next_tvb, "Reassembled IAX2");
1784
1785       process_iax_pdu(next_tvb,pinfo,tree,video,iax_packet);
1786
1787       /* calculate the amount of data which was available to the higher-level
1788          dissector before we added this segment; if the returned offset is
1789          within that section, the higher-level dissector was unable to find any
1790          pdus; if it's after that, it found one or more complete PDUs.
1791       */
1792       old_len = (gint32)(tvb_reported_length(next_tvb) - tvb_reported_length(tvb));
1793       if( pinfo->desegment_len &&
1794           pinfo->desegment_offset < old_len ) {
1795         /* oops, it wasn't actually complete */
1796         fragment_set_partial_reassembly(pinfo, fid, iax_call->fragment_table);
1797         dirdata->current_frag_minlen = fd_head->datalen + pinfo->desegment_len;
1798       } else {
1799         /* we successfully dissected some data; create the proto tree items for
1800          * the fragments, and flag any remaining data for desegmentation */
1801
1802         proto_item *iax_tree_item, *frag_tree_item;
1803         /* this nargery is to insert the fragment tree into the main tree
1804          * between the IAX protocol entry and the subdissector entry */
1805         show_fragment_tree(fd_head, &iax2_fragment_items, tree, pinfo, next_tvb, &frag_tree_item);
1806         iax_tree_item = proto_item_get_parent( proto_tree_get_parent( iax2_tree ));
1807         if( frag_tree_item && iax_tree_item )
1808           proto_tree_move_item( tree, iax_tree_item, frag_tree_item );
1809
1810         dirdata->current_frag_minlen = dirdata->current_frag_id = dirdata->current_frag_bytes = 0;
1811
1812         if( pinfo->desegment_len ) {
1813           /* there's a bit of data left to desegment */
1814           must_desegment = TRUE;
1815           /* make desegment_offset relative to our tvb */
1816           pinfo->desegment_offset -= old_len;
1817         }
1818
1819         /* don't add a 'reassembled in' item for this pdu */
1820         fd_head = NULL;
1821       }
1822     }
1823   } else {
1824     /* This segment was not found in our table, so it doesn't
1825        contain a continuation of a higher-level PDU.
1826        Call the normal subdissector.
1827     */
1828
1829     process_iax_pdu(tvb,pinfo,tree,video,iax_packet);
1830     
1831     if(pinfo->desegment_len) {
1832       /* the higher-level dissector has asked for some more data - ie,
1833          the end of this segment does not coincide with the end of a
1834          higher-level PDU. */
1835       must_desegment = TRUE;
1836     }
1837
1838     fd_head = NULL;
1839   }
1840
1841   /* must_desegment is set if the end of this segment (or the whole of it)
1842    * contained the start of a higher-level PDU; we must add whatever is left of
1843    * this segment (after pinfo->desegment_offset) to a fragment table for disassembly. */
1844   if(must_desegment) {
1845       guint32 fid = pinfo->fd->num; /* a new fragment id */
1846       guint32 deseg_offset = pinfo->desegment_offset;
1847       guint32 frag_len = tvb_reported_length_remaining(tvb,deseg_offset);
1848       dirdata->current_frag_id = fid;
1849       dirdata->current_frag_bytes = frag_len;
1850       dirdata->current_frag_minlen = frag_len + pinfo->desegment_len;
1851       fd_head = fragment_add(tvb, deseg_offset, pinfo, fid,
1852                              iax_call->fragment_table,
1853                              0, frag_len, TRUE );
1854 #ifdef DEBUG_DESEGMENT
1855       g_debug("Start offset of undissected bytes: %u; "
1856               "Bytes remaining in this segment: %u; min required bytes: %u\n",
1857               deseg_offset, frag_len, frag_len + pinfo->desegment_len);
1858 #endif
1859   }
1860
1861   /* add a 'reassembled in' item if necessary */
1862   if( fd_head != NULL ) {
1863       guint32 deseg_offset = pinfo->desegment_offset;
1864       if( fd_head->reassembled_in != 0 &&
1865           !(fd_head->flags & FD_PARTIAL_REASSEMBLY) ) {
1866         proto_item *iax_tree_item;
1867         iax_tree_item = proto_tree_add_uint( tree, hf_iax2_reassembled_in,
1868                                              tvb, deseg_offset, tvb_reported_length_remaining(tvb,deseg_offset),
1869                                              fd_head->reassembled_in);
1870         PROTO_ITEM_SET_GENERATED(iax_tree_item);
1871       } else {
1872         /* this fragment is never reassembled */
1873         proto_tree_add_text( tree, tvb, deseg_offset, -1,
1874                              "IAX2 fragment, unfinished");
1875       }
1876
1877     if( pinfo->desegment_offset == 0 ) {
1878       if (check_col(pinfo->cinfo, COL_PROTOCOL)){
1879         col_set_str(pinfo->cinfo, COL_PROTOCOL, "IAX2");
1880       }
1881       if (check_col(pinfo->cinfo, COL_INFO)){
1882         col_set_str(pinfo->cinfo, COL_INFO, "[IAX2 segment of a reassembled PDU]");
1883       }
1884     }
1885   }
1886
1887   pinfo->can_desegment = 0;
1888   pinfo->desegment_offset = 0;
1889   pinfo->desegment_len = 0;
1890 }
1891
1892 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
1893                             packet_info *pinfo, proto_tree *iax2_tree,
1894                             proto_tree *tree, guint32 ts, gboolean video,
1895                             iax_packet_data *iax_packet)
1896 {
1897   gboolean out_of_order = FALSE;
1898   tvbuff_t *sub_tvb;
1899   guint32 codec = iax_packet -> codec;
1900   guint32 nbytes;
1901   iax_call_data *iax_call = iax_packet -> call_data;
1902
1903   /* keep compiler quiet */
1904   ts = ts;
1905
1906   if( offset >= tvb_reported_length (tvb)) {
1907     if (check_col (pinfo->cinfo, COL_INFO))
1908       col_append_fstr (pinfo->cinfo, COL_INFO, ", empty frame" );
1909     return;
1910   }
1911
1912   sub_tvb = tvb_new_subset(tvb, offset, -1, -1 );
1913
1914   /* XXX shouldn't pass through out-of-order packets. */
1915
1916   if (check_col (pinfo->cinfo, COL_INFO)) {
1917     if( !video && iax_call && iax_call -> dataformat != 0 ) {
1918       col_append_fstr (pinfo->cinfo, COL_INFO, ", data, format %s",
1919                        val_to_str (iax_call -> dataformat, 
1920                                    iax_dataformats, "unknown (0x%02x)"));
1921
1922       if( out_of_order )
1923         col_append_fstr (pinfo->cinfo, COL_INFO, " (out-of-order packet)");
1924     } else {
1925       col_append_fstr (pinfo->cinfo, COL_INFO, ", %s",
1926                        val_to_str (codec, codec_types, "unknown (0x%02x)"));
1927     }
1928   }
1929
1930   nbytes = tvb_reported_length(sub_tvb);
1931   proto_tree_add_text( iax2_tree, sub_tvb, 0, -1,
1932       "IAX2 payload (%u byte%s)", nbytes,
1933       plurality( nbytes, "", "s" ));
1934
1935   /* pass the rest of the block to a subdissector */
1936   if(iax_packet->call_data)
1937     desegment_iax( sub_tvb, pinfo, iax2_tree, tree, video, iax_packet );
1938   else
1939     process_iax_pdu(sub_tvb,pinfo,tree,video,iax_packet);
1940 }
1941
1942 /*
1943  * Init routines
1944  */
1945
1946 /* called at the start of a capture. We should clear out our static, per-capture
1947  * data.
1948  */
1949
1950 static void
1951 iax_init_protocol(void)
1952 {
1953   iax_init_hash();
1954
1955 }
1956
1957
1958 void
1959 proto_register_iax2 (void)
1960 {
1961   /* we use this for displaying which codecs are supported */
1962   static const true_false_string supported_strings = {
1963     "Supported",
1964     "Not supported"
1965   };
1966
1967   /* A header field is something you can search/filter on.
1968    * 
1969    * We create a structure to register our fields. It consists of an
1970    * array of hf_register_info structures, each of which are of the format
1971    * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
1972    */
1973    
1974   static hf_register_info hf[] = {
1975
1976     {&hf_iax2_packet_type,
1977      {"Packet type", "iax2.packet_type", FT_UINT8, BASE_DEC, VALS(iax_packet_types), 0,
1978       "Full/minivoice/minivideo/meta packet",
1979       HFILL}},
1980
1981     {&hf_iax2_callno,
1982      {"Call identifier", "iax2.call", FT_UINT32, BASE_DEC, NULL, 0,
1983       "This is the identifier Ethereal assigns to identify this call. It does "
1984       "not correspond to any real field in the protocol", HFILL }},
1985
1986     {&hf_iax2_scallno,
1987      {"Source call", "iax2.src_call", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
1988       "src_call holds the number of this call at the packet source pbx",
1989       HFILL}},
1990
1991     /* FIXME could this be turned into a FRAMENUM field? */
1992     {&hf_iax2_dcallno,
1993      {"Destination call", "iax2.dst_call", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
1994       "dst_call holds the number of this call at the packet destination",
1995       HFILL}},
1996
1997     {&hf_iax2_retransmission,
1998      {"Retransmission", "iax2.retransmission", FT_BOOLEAN, 16,
1999       NULL, 0x8000,
2000       "retransmission is set if this packet is a retransmission of an earlier "
2001       "failed packet", HFILL}},
2002
2003     {&hf_iax2_ts,
2004      {"Timestamp", "iax2.timestamp", FT_UINT32, BASE_DEC, NULL, 0x0,
2005       "timestamp is the time, in ms after the start of this call, at which "
2006       "this packet was transmitted",
2007       HFILL}},
2008
2009     {&hf_iax2_minits,
2010      {"Timestamp", "iax2.timestamp", FT_UINT16, BASE_DEC, NULL, 0x0,
2011       "timestamp is the time, in ms after the start of this call, at which "
2012       "this packet was transmitted",
2013       HFILL}},
2014
2015     {&hf_iax2_minividts,
2016      {"Timestamp", "iax2.timestamp", FT_UINT16, BASE_DEC, NULL, 0x7FFF,
2017       "timestamp is the time, in ms after the start of this call, at which "
2018       "this packet was transmitted",
2019       HFILL}},
2020
2021     {&hf_iax2_absts,
2022      {"Absolute Time", "iax2.abstime", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
2023       "The absoulte time of this packet (calculated by adding the IAX timestamp to "
2024       " the start time of this call)",
2025       HFILL}},
2026
2027     {&hf_iax2_lateness,
2028      {"Lateness", "iax2.lateness", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2029       "The lateness of this packet compared to its timestamp",
2030       HFILL}},
2031
2032     {&hf_iax2_minividmarker,
2033      {"Marker", "iax2.video.marker", FT_UINT16, BASE_DEC, NULL, 0x8000,
2034       "RTP end-of-frame marker",
2035       HFILL}},
2036
2037     {&hf_iax2_oseqno,
2038      {"Outbound seq.no.", "iax2.oseqno", FT_UINT16, BASE_DEC, NULL,
2039       0x0, 
2040       "oseqno is the sequence no of this packet. The first packet has "
2041       "oseqno==0, and subsequent packets increment the oseqno by 1",
2042       HFILL}},
2043
2044     {&hf_iax2_iseqno,
2045      {"Inbound seq.no.", "iax2.iseqno", FT_UINT16, BASE_DEC, NULL, 0x0,
2046       "iseqno is the sequence no of the last successfully received packet",
2047       HFILL}},
2048
2049     {&hf_iax2_type,
2050      {"Type", "iax2.type", FT_UINT8, BASE_DEC, VALS (iax_frame_types),
2051       0x0,
2052       "For full IAX2 frames, type is the type of frame",
2053       HFILL}},
2054
2055     {&hf_iax2_csub,
2056      {"Unknown subclass", "iax2.subclass", FT_UINT8, BASE_DEC, NULL, 0x0, 
2057       "Subclass of unknown type of full IAX2 frame",
2058       HFILL}},
2059
2060     {&hf_iax2_dtmf_csub,
2061      {"DTMF subclass (digit)", "iax2.dtmf.subclass", FT_STRINGZ, BASE_NONE, NULL, 0x0,
2062       "DTMF subclass gives the DTMF digit",
2063       HFILL}},
2064
2065     {&hf_iax2_cmd_csub,
2066      {"Control subclass", "iax2.control.subclass", FT_UINT8, BASE_DEC,
2067       VALS (iax_cmd_subclasses), 0x0, 
2068       "This gives the command number for a Control packet.", HFILL}},
2069
2070     {&hf_iax2_iax_csub,
2071      {"IAX subclass", "iax2.iax.subclass", FT_UINT8, BASE_DEC,
2072       VALS (iax_iax_subclasses),
2073       0x0, 
2074       "IAX subclass gives the command number for IAX signalling packets", HFILL}},
2075
2076     {&hf_iax2_voice_csub,
2077      {"Voice Subclass (compressed codec no)", "iax2.voice.subclass", FT_UINT8, BASE_DEC, NULL, 0x0, 
2078       "Voice Subclass (compressed codec no)",
2079       HFILL}},
2080
2081     {&hf_iax2_voice_codec,
2082      {"CODEC", "iax2.voice.codec", FT_UINT32, BASE_HEX, VALS (codec_types),
2083       0x0, 
2084       "CODEC gives the codec used to encode audio data", HFILL}},
2085
2086     {&hf_iax2_video_csub,
2087      {"Video Subclass (compressed codec no)", "iax2.video.subclass", FT_UINT8, BASE_DEC, NULL, 0xBF, 
2088       "Video Subclass (compressed codec no)",
2089       HFILL}},
2090     
2091     {&hf_iax2_marker,
2092      {"Marker", "iax2.video.marker", FT_BOOLEAN, 8, NULL, 0x40,
2093       "RTP end-of-frame marker",
2094       HFILL}},
2095
2096     {&hf_iax2_video_codec,
2097      {"CODEC", "iax2.video.codec", FT_UINT32, BASE_HEX, VALS (codec_types), 0, 
2098       "The codec used to encode video data", HFILL}},
2099     
2100     /*
2101      * Decoding for the ies
2102      */
2103
2104     {&hf_IAX_IE_APPARENTADDR_SINFAMILY,
2105      {"Family", "iax2.iax.app_addr.sinfamily", FT_UINT16, BASE_DEC, NULL, 0, "Family", HFILL }},
2106     {&hf_IAX_IE_APPARENTADDR_SINPORT,
2107      {"Port", "iax2.iax.app_addr.sinport", FT_UINT16, BASE_DEC, NULL, 0, "Port", HFILL }},
2108     {&hf_IAX_IE_APPARENTADDR_SINADDR,
2109      {"Address", "iax2.iax.app_addr.sinaddr", FT_IPv4, BASE_HEX, NULL, 0, "Address", HFILL }},
2110     
2111     {&hf_iax2_ies[IAX_IE_CALLED_NUMBER],
2112      {"Number/extension being called", "iax2.iax.called_number",
2113       FT_STRING,
2114       BASE_NONE, NULL, 0x0, "", HFILL}},
2115
2116     {&hf_iax2_ies[IAX_IE_CALLING_NUMBER],
2117      {"Calling number", "iax2.iax.calling_number", FT_STRING,
2118       BASE_NONE, NULL,
2119       0x0, "", HFILL}},
2120
2121     {&hf_iax2_ies[IAX_IE_CALLING_ANI],
2122      {"Calling number ANI for billing", "iax2.iax.calling_ani",
2123       FT_STRING,
2124       BASE_NONE, NULL, 0x0, "", HFILL}},
2125
2126     {&hf_iax2_ies[IAX_IE_CALLING_NAME],
2127      {"Name of caller", "iax2.iax.calling_name", FT_STRING, BASE_NONE,
2128       NULL,
2129       0x0, "", HFILL}},
2130
2131     {&hf_iax2_ies[IAX_IE_CALLED_CONTEXT],
2132      {"Context for number", "iax2.iax.called_context", FT_STRING,
2133       BASE_NONE,
2134       NULL, 0x0, "", HFILL}},
2135
2136     {&hf_iax2_ies[IAX_IE_USERNAME],
2137      {"Username (peer or user) for authentication",
2138       "iax2.iax.username",
2139       FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
2140
2141     {&hf_iax2_ies[IAX_IE_PASSWORD],
2142      {"Password for authentication", "iax2.iax.password", FT_STRING,
2143       BASE_NONE, NULL, 0x0, "", HFILL}},
2144
2145     {&hf_iax2_ies[IAX_IE_CAPABILITY],
2146      {"Actual codec capability", "iax2.iax.capability", FT_UINT32,
2147       BASE_HEX,
2148       NULL, 0x0, "", HFILL}},
2149
2150     {&hf_iax2_ies[IAX_IE_FORMAT],
2151      {"Desired codec format", "iax2.iax.format", FT_UINT32, BASE_HEX,
2152       VALS (codec_types), 0x0, "", HFILL}},
2153
2154     {&hf_iax2_ies[IAX_IE_LANGUAGE],
2155      {"Desired language", "iax2.iax.language", FT_STRING, BASE_NONE,
2156       NULL,
2157       0x0, "", HFILL}},
2158
2159     {&hf_iax2_ies[IAX_IE_VERSION],
2160      {"Protocol version", "iax2.iax.version", FT_UINT16, BASE_HEX, NULL,
2161       0x0,
2162       "", HFILL}},
2163
2164     {&hf_iax2_ies[IAX_IE_ADSICPE],
2165      {"CPE ADSI capability", "iax2.iax.cpe_adsi", FT_UINT16, BASE_HEX,
2166       NULL,
2167       0x0, "", HFILL}},
2168
2169     {&hf_iax2_ies[IAX_IE_DNID],
2170      {"Originally dialed DNID", "iax2.iax.dnid", FT_STRING, BASE_NONE,
2171       NULL,
2172       0x0, "", HFILL}},
2173
2174     {&hf_iax2_ies[IAX_IE_AUTHMETHODS],
2175      {"Authentication method(s)", "iax2.iax.auth.methods", FT_UINT16,
2176       BASE_HEX,
2177       NULL, 0x0, "", HFILL}},
2178
2179     {&hf_iax2_ies[IAX_IE_CHALLENGE],
2180      {"Challenge data for MD5/RSA", "iax2.iax.auth.challenge",
2181       FT_STRING,
2182       BASE_NONE, NULL, 0x0, "", HFILL}},
2183
2184     {&hf_iax2_ies[IAX_IE_MD5_RESULT],
2185      {"MD5 challenge result", "iax2.iax.auth.md5", FT_STRING,
2186       BASE_NONE, NULL,
2187       0x0, "", HFILL}},
2188
2189     {&hf_iax2_ies[IAX_IE_RSA_RESULT],
2190      {"RSA challenge result", "iax2.iax.auth.rsa", FT_STRING,
2191       BASE_NONE, NULL,
2192       0x0, "", HFILL}},
2193
2194     {&hf_iax2_ies[IAX_IE_REFRESH],
2195      {"When to refresh registration", "iax2.iax.refresh", FT_INT16,
2196       BASE_DEC,
2197       NULL, 0x0, "", HFILL}},
2198
2199     {&hf_iax2_ies[IAX_IE_DPSTATUS],
2200      {"Dialplan status", "iax2.iax.dialplan_status", FT_UINT16,
2201       BASE_HEX, NULL,
2202       0x0, "", HFILL}},
2203
2204     {&hf_iax2_ies[IAX_IE_CALLNO],
2205      {"Call number of peer", "iax2.iax.call_no", FT_UINT16, BASE_DEC,
2206       NULL,
2207       0x0, "", HFILL}},
2208
2209     {&hf_iax2_ies[IAX_IE_CAUSE],
2210      {"Cause", "iax2.iax.cause", FT_STRING, BASE_NONE, NULL, 0x0, "",
2211       HFILL}},
2212
2213     {&hf_iax2_ies[IAX_IE_IAX_UNKNOWN],
2214      {"Unknown IAX command", "iax2.iax.iax_unknown", FT_BYTES,
2215       BASE_HEX, NULL,
2216       0x0, "", HFILL}},
2217
2218     {&hf_iax2_ies[IAX_IE_MSGCOUNT],
2219      {"How many messages waiting", "iax2.iax.msg_count", FT_INT16,
2220       BASE_DEC,
2221       NULL, 0x0, "", HFILL}},
2222
2223     {&hf_iax2_ies[IAX_IE_AUTOANSWER],
2224      {"Request auto-answering", "iax2.iax.autoanswer", FT_NONE,
2225       BASE_NONE,
2226       NULL, 0x0, "", HFILL}},
2227
2228     {&hf_iax2_ies[IAX_IE_MUSICONHOLD],
2229      {"Request musiconhold with QUELCH", "iax2.iax.moh", FT_NONE,
2230       BASE_NONE,
2231       NULL, 0x0, "", HFILL}},
2232
2233     {&hf_iax2_ies[IAX_IE_TRANSFERID],
2234      {"Transfer Request Identifier", "iax2.iax.transferid", FT_UINT32,
2235       BASE_HEX, NULL, 0x0, "", HFILL}},
2236
2237     {&hf_iax2_ies[IAX_IE_RDNIS],
2238      {"Referring DNIS", "iax2.iax.rdnis", FT_STRING, BASE_NONE, NULL,
2239       0x0, "",
2240       HFILL}},
2241
2242     {&hf_iax2_ies[IAX_IE_PROVISIONING],
2243      {"Provisioning info","iax2.iax.provisioning", FT_STRING, BASE_NONE,
2244        NULL, 0x0, "", HFILL}},
2245
2246     {&hf_iax2_ies[IAX_IE_AESPROVISIONING],
2247      {"AES Provisioning info","iax2.iax.aesprovisioning", FT_STRING, BASE_NONE,
2248        NULL, 0x0, "", HFILL}},
2249
2250     {&hf_iax2_ies[IAX_IE_DATETIME],
2251      {"Date/Time", "iax2.iax.datetime.raw", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
2252
2253     {&hf_iax2_ie_datetime,
2254      {"Date/Time", "iax2.iax.datetime", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0, "", HFILL }},
2255
2256     {&hf_iax2_ies[IAX_IE_DEVICETYPE],
2257      {"Device type", "iax2.iax.devicetype", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
2258
2259     {&hf_iax2_ies[IAX_IE_SERVICEIDENT],
2260      {"Service identifier", "iax2.iax.serviceident", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
2261
2262     {&hf_iax2_ies[IAX_IE_FIRMWAREVER],
2263      {"Firmware version", "iax2.iax.firmwarever", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
2264
2265     {&hf_iax2_ies[IAX_IE_FWBLOCKDESC],
2266      {"Firmware block description", "iax2.iax.fwblockdesc", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2267
2268     {&hf_iax2_ies[IAX_IE_FWBLOCKDATA],
2269      {"Firmware block of data", "iax2.iax.fwblockdata", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
2270
2271     {&hf_iax2_ies[IAX_IE_PROVVER],
2272      {"Provisioning version", "iax2.iax.provver", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2273
2274     {&hf_iax2_ies[IAX_IE_CALLINGPRES],
2275      {"Calling presentation", "iax2.iax.callingpres", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},
2276
2277     {&hf_iax2_ies[IAX_IE_CALLINGTON],
2278      {"Calling type of number", "iax2.iax.callington", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL}},
2279
2280     {&hf_iax2_ies[IAX_IE_CALLINGTNS],
2281      {"Calling transit network select", "iax2.iax.callingtns", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
2282
2283     {&hf_iax2_ies[IAX_IE_SAMPLINGRATE],
2284      {"Supported sampling rates", "iax2.iax.samplingrate", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
2285
2286     {&hf_iax2_ies[IAX_IE_CAUSECODE],
2287      {"Hangup cause", "iax2.iax.causecode", FT_UINT8, BASE_HEX, VALS(iax_causecodes),
2288        0x0, "", HFILL}},
2289
2290     {&hf_iax2_ies[IAX_IE_ENCRYPTION],
2291      {"Encryption format", "iax2.iax.encryption", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
2292
2293     {&hf_iax2_ies[IAX_IE_ENCKEY],
2294      {"Encryption key", "iax2.iax.enckey", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
2295
2296     {&hf_iax2_ies[IAX_IE_CODEC_PREFS],
2297      {"Codec negotiation", "iax2.iax.codecprefs", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
2298
2299     {&hf_iax2_ies[IAX_IE_RR_JITTER],
2300      {"Received jitter (as in RFC1889)", "iax2.iax.rrjitter", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2301
2302     {&hf_iax2_ies[IAX_IE_RR_LOSS],
2303      {"Received loss (high byte loss pct, low 24 bits loss count, as in rfc1889)", "iax2.iax.rrloss",
2304        FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2305
2306     {&hf_iax2_ies[IAX_IE_RR_PKTS],
2307      {"Total frames received", "iax2.iax.rrpkts", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2308
2309     {&hf_iax2_ies[IAX_IE_RR_DELAY],
2310      {"Max playout delay in ms for received frames", "iax2.iax.rrdelay", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL}},
2311
2312     {&hf_iax2_ies[IAX_IE_RR_DROPPED],
2313      {"Dropped frames (presumably by jitterbuffer)", "iax2.iax.rrdropped", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2314
2315     {&hf_iax2_ies[IAX_IE_RR_OOO],
2316      {"Frame received out of order", "iax2.iax.rrooo", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
2317
2318     {&hf_iax2_ies[IAX_IE_DATAFORMAT],
2319      {"Data call format", "iax2.iax.dataformat", FT_UINT32, BASE_HEX,
2320       VALS(iax_dataformats), 0x0, "", HFILL}},
2321
2322     {&hf_IAX_IE_UNKNOWN_BYTE,
2323      {"Unknown", "iax2.iax.unknownbyte", FT_UINT8, BASE_HEX, NULL,
2324       0x0, "Raw data for unknown IEs",
2325       HFILL}},
2326     {&hf_IAX_IE_UNKNOWN_I16,
2327      {"Unknown", "iax2.iax.unknownshort", FT_UINT16, BASE_HEX, NULL,
2328       0x0, "Raw data for unknown IEs",
2329       HFILL}},
2330     {&hf_IAX_IE_UNKNOWN_I32,
2331      {"Unknown", "iax2.iax.unknownlong", FT_UINT32, BASE_HEX, NULL,
2332       0x0, "Raw data for unknown IEs",
2333       HFILL}},
2334     {&hf_IAX_IE_UNKNOWN_BYTES,
2335      {"Unknown", "iax2.iax.unknownstring", FT_STRING, BASE_NONE, NULL,
2336       0x0, "Raw data for unknown IEs",
2337       HFILL}},
2338
2339     /* capablilites */
2340     {&hf_iax2_cap_g723_1,
2341      {"G.723.1 compression", "iax2.cap.g723_1", FT_BOOLEAN, 32,
2342       TFS(&supported_strings), AST_FORMAT_G723_1,
2343       "G.723.1 compression", HFILL }},
2344
2345     {&hf_iax2_cap_gsm,
2346      {"GSM compression", "iax2.cap.gsm", FT_BOOLEAN, 32,
2347        TFS(&supported_strings), AST_FORMAT_GSM, 
2348       "GSM compression", HFILL }},
2349
2350     {&hf_iax2_cap_ulaw,
2351      {"Raw mu-law data (G.711)", "iax2.cap.ulaw",FT_BOOLEAN, 32,
2352       TFS(&supported_strings), AST_FORMAT_ULAW,
2353       "Raw mu-law data (G.711)", HFILL }},
2354
2355      {&hf_iax2_cap_alaw,
2356       {"Raw A-law data (G.711)", "iax2.cap.alaw",FT_BOOLEAN, 32,
2357        TFS(&supported_strings), AST_FORMAT_ALAW,
2358        "Raw A-law data (G.711)", HFILL }},
2359
2360     {&hf_iax2_cap_g726,
2361      {"G.726 compression", "iax2.cap.g726",FT_BOOLEAN, 32,
2362       TFS(&supported_strings), AST_FORMAT_G726,
2363       "G.726 compression", HFILL }},
2364
2365     {&hf_iax2_cap_adpcm,
2366      {"ADPCM", "iax2.cap.adpcm", FT_BOOLEAN, 32,
2367       TFS(&supported_strings), AST_FORMAT_ADPCM,
2368       "ADPCM", HFILL }},
2369     
2370     {&hf_iax2_cap_slinear,
2371      {"Raw 16-bit Signed Linear (8000 Hz) PCM", "iax2.cap.slinear", 
2372       FT_BOOLEAN, 32, TFS(&supported_strings), AST_FORMAT_SLINEAR, 
2373       "Raw 16-bit Signed Linear (8000 Hz) PCM", HFILL }},
2374
2375     {&hf_iax2_cap_lpc10,
2376      {"LPC10, 180 samples/frame", "iax2.cap.lpc10", FT_BOOLEAN, 32,
2377       TFS(&supported_strings), AST_FORMAT_LPC10,
2378       "LPC10, 180 samples/frame", HFILL }},
2379
2380     {&hf_iax2_cap_g729a,
2381      {"G.729a Audio", "iax2.cap.g729a", FT_BOOLEAN, 32,
2382       TFS(&supported_strings), AST_FORMAT_G729A,
2383       "G.729a Audio", HFILL }},
2384
2385     {&hf_iax2_cap_speex,
2386      {"SPEEX Audio", "iax2.cap.speex", FT_BOOLEAN, 32,
2387       TFS(&supported_strings), AST_FORMAT_SPEEX,
2388       "SPEEX Audio", HFILL }},
2389
2390     {&hf_iax2_cap_ilbc,
2391      {"iLBC Free compressed Audio", "iax2.cap.ilbc", FT_BOOLEAN, 32,
2392       TFS(&supported_strings), AST_FORMAT_ILBC,
2393       "iLBC Free compressed Audio", HFILL }},
2394
2395     {&hf_iax2_cap_jpeg,
2396      {"JPEG images", "iax2.cap.jpeg", FT_BOOLEAN, 32,
2397       TFS(&supported_strings), AST_FORMAT_JPEG,
2398       "JPEG images", HFILL }},
2399
2400     {&hf_iax2_cap_png,
2401      {"PNG images", "iax2.cap.png", FT_BOOLEAN, 32,
2402       TFS(&supported_strings), AST_FORMAT_PNG,
2403       "PNG images", HFILL }},
2404
2405     {&hf_iax2_cap_h261,
2406      {"H.261 video", "iax2.cap.h261", FT_BOOLEAN, 32,
2407       TFS(&supported_strings), AST_FORMAT_H261,
2408       "H.261 video", HFILL }},
2409
2410     {&hf_iax2_cap_h263,
2411      {"H.263 video", "iax2.cap.h263", FT_BOOLEAN, 32,
2412       TFS(&supported_strings), AST_FORMAT_H263,
2413       "H.263 video", HFILL }},
2414
2415     /* reassembly stuff */
2416     {&hf_iax2_fragments,
2417      {"IAX2 Fragments", "iax2.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
2418       "IAX2 Fragments", HFILL }},
2419
2420     {&hf_iax2_fragment,
2421      {"IAX2 Fragment data", "iax2.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2422       "IAX2 Fragment data", HFILL }},
2423
2424     {&hf_iax2_fragment_overlap,
2425      {"Fragment overlap", "iax2.fragment.overlap", FT_BOOLEAN, BASE_NONE,
2426       NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
2427
2428     {&hf_iax2_fragment_overlap_conflict,
2429      {"Conflicting data in fragment overlap", "iax2.fragment.overlap.conflict",
2430       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2431       "Overlapping fragments contained conflicting data", HFILL }},
2432
2433     {&hf_iax2_fragment_multiple_tails,
2434      {"Multiple tail fragments found", "iax2.fragment.multipletails",
2435       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2436       "Several tails were found when defragmenting the packet", HFILL }},
2437
2438     {&hf_iax2_fragment_too_long_fragment,
2439      {"Fragment too long", "iax2.fragment.toolongfragment",
2440       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2441       "Fragment contained data past end of packet", HFILL }},
2442
2443     {&hf_iax2_fragment_error,
2444      {"Defragmentation error", "iax2.fragment.error",
2445       FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2446       "Defragmentation error due to illegal fragments", HFILL }},
2447
2448     {&hf_iax2_reassembled_in,
2449      {"IAX2 fragment, reassembled in frame", "iax2.reassembled_in",
2450       FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2451       "This IAX2 packet is reassembled in this frame", HFILL }}
2452   };
2453
2454   static gint *ett[] = {
2455     &ett_iax2,
2456     &ett_iax2_full_mini_subtree,
2457     &ett_iax2_type,
2458     &ett_iax2_ie,
2459     &ett_iax2_codecs,
2460     &ett_iax2_ies_apparent_addr,
2461     &ett_iax2_fragment,
2462     &ett_iax2_fragments
2463   };
2464
2465   /* initialise the hf_iax2_ies[] array to -1 */
2466   memset(hf_iax2_ies,0xff,sizeof(hf_iax2_ies));
2467
2468   proto_iax2 =
2469     proto_register_protocol ("Inter-Asterisk eXchange v2", "IAX2", "iax2");
2470   proto_register_field_array (proto_iax2, hf, array_length (hf));
2471   proto_register_subtree_array (ett, array_length (ett));
2472
2473   register_dissector("iax2", dissect_iax2, proto_iax2);
2474
2475   iax2_codec_dissector_table = register_dissector_table(
2476     "iax2.codec","IAX codec number", FT_UINT32, BASE_HEX);
2477   iax2_dataformat_dissector_table = register_dissector_table(
2478     "iax2.dataformat","IAX dataformat number", FT_UINT32, BASE_HEX);
2479   
2480   /* register our init routine to be called at the start of a capture,
2481      to clear out our hash tables etc */
2482   register_init_routine(&iax_init_protocol);
2483 }
2484
2485 void
2486 proto_reg_handoff_iax2 (void)
2487 {
2488   dissector_add("udp.port", IAX2_PORT, find_dissector("iax2"));
2489   dissector_add("iax2.dataformat", AST_DATAFORMAT_V110, find_dissector("v110"));
2490   data_handle = find_dissector("data");
2491 }
2492
2493
2494 /* 
2495  * This sets up the indentation style for this file in emacs.
2496  *
2497  * Local Variables:
2498  * c-basic-offset: 2
2499  * End:
2500  *
2501  * .. And for vim:
2502  * vim:set ts=8 sts=2 sw=2 noet:
2503  */