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