The function pointer in a "per_choice_t" or a "per_sequence_t" is to a
[obnox/wireshark/wip.git] / packet-iax2.c
1 /*
2  * packet-iax2.c
3  *
4  * Routines for IAX2 packet disassembly
5  * By Alastair Maw <asterisk@almaw.com>
6  * Copyright 2003 Alastair Maw
7  *
8  * IAX2 is a VoIP protocol for the open source PBX Asterisk. Please see
9  * http://www.asterisk.org for more information.
10  *
11  * $Id: packet-iax2.c,v 1.6 2004/05/15 21:26:09 guy Exp $
12  *
13  * Ethereal - Network traffic analyzer
14  * By Gerald Combs <gerald@ethereal.com>
15  * Copyright 1998 Gerald Combs
16  * 
17  * This program is free software; you can redistribute it and/or modify it
18  * under the terms of the GNU General Public License as published by the
19  * Free Software Foundation; either version 2 of the License, or (at your
20  * option) any later version. This program is distributed in the hope
21  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
22  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
23  * PURPOSE.  See the GNU General Public License for more details. You
24  * should have received a copy of the GNU General Public License along
25  * with this program; if not, write to the Free Software Foundation, Inc., 
26  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  *
28  */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <glib.h>
37 #include <epan/packet.h>
38
39 #include "packet-iax2.h"
40
41 #define IAX2_PORT               4569
42 #define PROTO_TAG_IAX2  "IAX2"
43
44 static int proto_iax2 = -1;
45
46 static int hf_iax2_retransmission = -1;
47 static int hf_iax2_scallno = -1;
48 static int hf_iax2_dcallno = -1;
49 static int hf_iax2_ts = -1;
50 static int hf_iax2_minits = -1;
51 static int hf_iax2_voicedata = -1;
52 static int hf_iax2_oseqno = -1;
53 static int hf_iax2_iseqno = -1;
54 static int hf_iax2_type = -1;
55 static int hf_iax2_csub = -1;
56 static int hf_iax2_cmd_csub = -1;
57 static int hf_iax2_iax_csub = -1;
58 static int hf_iax2_voice_csub = -1;
59 static int hf_iax2_ies = -1;
60
61 static int hf_IAX_IE_APPARENTADDR_SINFAMILY = -1;
62 static int hf_IAX_IE_APPARENTADDR_SINPORT = -1;
63 static int hf_IAX_IE_APPARENTADDR_SINADDR = -1;
64 static int hf_IAX_IE_APPARENTADDR_SINZERO = -1;           
65 static int hf_IAX_IE_CALLED_NUMBER = -1;
66 static int hf_IAX_IE_CALLING_NUMBER = -1;
67 static int hf_IAX_IE_CALLING_ANI = -1;
68 static int hf_IAX_IE_CALLING_NAME = -1;
69 static int hf_IAX_IE_CALLED_CONTEXT = -1;
70 static int hf_IAX_IE_USERNAME = -1;
71 static int hf_IAX_IE_PASSWORD = -1;
72 static int hf_IAX_IE_CAPABILITY = -1;
73 static int hf_IAX_IE_FORMAT = -1;
74 static int hf_IAX_IE_LANGUAGE = -1;
75 static int hf_IAX_IE_VERSION = -1;
76 static int hf_IAX_IE_ADSICPE = -1;
77 static int hf_IAX_IE_DNID = -1;
78 static int hf_IAX_IE_AUTHMETHODS = -1;
79 static int hf_IAX_IE_CHALLENGE = -1;
80 static int hf_IAX_IE_MD5_RESULT = -1;
81 static int hf_IAX_IE_RSA_RESULT = -1;
82 static int hf_IAX_IE_REFRESH = -1;
83 static int hf_IAX_IE_DPSTATUS = -1;
84 static int hf_IAX_IE_CALLNO = -1;
85 static int hf_IAX_IE_CAUSE = -1;
86 static int hf_IAX_IE_IAX_UNKNOWN = -1;
87 static int hf_IAX_IE_MSGCOUNT = -1;
88 static int hf_IAX_IE_AUTOANSWER = -1;
89 static int hf_IAX_IE_MUSICONHOLD = -1;
90 static int hf_IAX_IE_TRANSFERID = -1;
91 static int hf_IAX_IE_RDNIS = -1;
92
93
94
95 static gint ett_iax2 = -1;
96 static gint ett_iax2_ies = -1;
97 static gint ett_iax2_codecs = -1;
98 static gint ett_iax2_ies_apparent_addr = -1;
99
100 static const value_string iax_frame_types[] = {
101   {0, "(0?)"},
102   {1, "DTMF"},
103   {2, "Voice"},
104   {3, "Video"},
105   {4, "Control"},
106   {5, "NULL"},
107   {6, "IAX"},
108   {7, "Text"},
109   {8, "Image"}
110 };
111 static const value_string iax_iax_subclasses[] = {
112   {0, "(0?)"},
113   {1, "NEW"},
114   {2, "PING"},
115   {3, "PONG"},
116   {4, "ACK"},
117   {5, "HANGUP"},
118   {6, "REJECT"},
119   {7, "ACCEPT"},
120   {8, "AUTHREQ"},
121   {9, "AUTHREP"},
122   {10, "INVAL"},
123   {11, "LAGRQ"},
124   {12, "LAGRP"},
125   {13, "REGREQ"},
126   {14, "REGAUTH"},
127   {15, "REGACK"},
128   {16, "REGREJ"},
129   {17, "REGREL"},
130   {18, "VNAK"},
131   {19, "DPREQ"},
132   {20, "DPREP"},
133   {21, "DIAL"},
134   {22, "TXREQ"},
135   {23, "TXCNT"},
136   {24, "TXACC"},
137   {25, "TXREADY"},
138   {26, "TXREL"},
139   {27, "TXREJ"},
140   {28, "QUELCH"},
141   {29, "UNQULCH"},
142   {30, "POKE"},
143   {31, "PAGE"},
144   {32, "MWI"},
145   {33, "UNSUPPORTED"},
146   {34, "TRANSFER"}
147 };
148 static const value_string iax_cmd_subclasses[] = {
149   {0, "(0?)"},
150   {1, "HANGUP"},
151   {2, "RING"},
152   {3, "RINGING"},
153   {4, "ANSWER"},
154   {5, "BUSY"},
155   {6, "TKOFFHK"},
156   {7, "OFFHOOK"}
157 };
158
159 static const value_string iax_ies_type[] = {
160   {IAX_IE_CALLED_NUMBER, "Number/extension being called"},
161   {IAX_IE_CALLING_NUMBER, "Calling number"},
162   {IAX_IE_CALLING_ANI, "Calling number ANI for billing"},
163   {IAX_IE_CALLING_NAME, "Name of caller"},
164   {IAX_IE_CALLED_CONTEXT, "Context for number"},
165   {IAX_IE_USERNAME, "Username (peer or user) for authentication"},
166   {IAX_IE_PASSWORD, "Password for authentication"},
167   {IAX_IE_CAPABILITY, "Actual codec capability"},
168   {IAX_IE_FORMAT, "Desired codec format"},
169   {IAX_IE_LANGUAGE, "Desired language"},
170   {IAX_IE_VERSION, "Protocol version"},
171   {IAX_IE_ADSICPE, "CPE ADSI capability"},
172   {IAX_IE_DNID, "Originally dialed DNID"},
173   {IAX_IE_AUTHMETHODS, "Authentication method(s)"},
174   {IAX_IE_CHALLENGE, "Challenge data for MD5/RSA"},
175   {IAX_IE_MD5_RESULT, "MD5 challenge result"},
176   {IAX_IE_RSA_RESULT, "RSA challenge result"},
177   {IAX_IE_APPARENT_ADDR, "Apparent address of peer"},
178   {IAX_IE_REFRESH, "When to refresh registration"},
179   {IAX_IE_DPSTATUS, "Dialplan status"},
180   {IAX_IE_CALLNO, "Call number of peer"},
181   {IAX_IE_CAUSE, "Cause"},
182   {IAX_IE_IAX_UNKNOWN, "Unknown IAX command"},
183   {IAX_IE_MSGCOUNT, "How many messages waiting"},
184   {IAX_IE_AUTOANSWER, "Request auto-answering"},
185   {IAX_IE_MUSICONHOLD, "Request musiconhold with QUELCH"},
186   {IAX_IE_TRANSFERID, "Transfer Request Identifier"},
187   {IAX_IE_RDNIS, "Referring DNIS"}
188 };
189
190 static const value_string codec_types[] = {
191   {AST_FORMAT_G723_1, "G.723.1 compression"},
192   {AST_FORMAT_GSM, "GSM compression"},
193   {AST_FORMAT_ULAW, "Raw mu-law data (G.711)"},
194   {AST_FORMAT_ALAW, "Raw A-law data (G.711)"},
195   {AST_FORMAT_G726, "ADPCM (G.726, 32kbps)"},
196   {AST_FORMAT_ADPCM, "ADPCM (IMA)"},
197   {AST_FORMAT_SLINEAR, "Raw 16-bit Signed Linear (8000 Hz) PCM"},
198   {AST_FORMAT_LPC10, "LPC10, 180 samples/frame"},
199   {AST_FORMAT_G729A, "G.729a Audio"},
200   {AST_FORMAT_SPEEX, "SpeeX Free Compression"},
201   {AST_FORMAT_ILBC, "iLBC Free Compression"},
202   {AST_FORMAT_JPEG, "JPEG Images"},
203   {AST_FORMAT_PNG, "PNG Images"},
204   {AST_FORMAT_H261, "H.261 Video"},
205   {AST_FORMAT_H263, "H.263 Video"}
206 };
207
208 static void
209 dissect_iax2 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
210 {
211   proto_tree *iax2_tree = NULL, *ies_tree = NULL, *codec_tree = NULL, *sockaddr_tree = NULL;
212   proto_item *ti = 0, *ies_base = 0, *codec_base = 0, *sockaddr_item = 0;
213   guint32 offset = 0, codecs = 0, i = 0, mask = 0, retransmission = 0;
214   guint16 scallno;
215   guint16 dcallno;
216   guint32 ts;
217   guint8 type;
218   guint8 csub;
219
220   if (check_col (pinfo->cinfo, COL_PROTOCOL))
221     {
222       col_set_str (pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_IAX2);
223     }
224   if (check_col (pinfo->cinfo, COL_INFO))
225     {
226       col_clear (pinfo->cinfo, COL_INFO);
227     }
228
229   if (tree)
230     {
231       ti = proto_tree_add_item (tree, proto_iax2, tvb, offset, -1, FALSE);
232       iax2_tree = proto_item_add_subtree (ti, ett_iax2);
233     }
234
235   scallno = tvb_get_ntohs(tvb, offset);
236   if (scallno & 0x8000)
237     {
238       /*
239        * remove the top bit for header type detection 
240        */
241       scallno = scallno & 0x7FFF;
242       proto_tree_add_uint (iax2_tree, hf_iax2_scallno, tvb, offset, 2,
243                            scallno);
244
245       /*
246        * remove the top bit for retransmission detection 
247        */
248       dcallno = tvb_get_ntohs(tvb, offset + 2);
249       retransmission = dcallno & 0x8000;
250       dcallno = dcallno & 0x7FFF;
251       proto_tree_add_uint (iax2_tree, hf_iax2_dcallno, tvb, offset + 2, 2,
252                            dcallno);
253       proto_tree_add_boolean (iax2_tree, hf_iax2_retransmission, tvb,
254                               offset + 2, 2, retransmission);
255
256       ts = tvb_get_ntohl(tvb, offset + 4);
257       proto_tree_add_uint (iax2_tree, hf_iax2_ts, tvb, offset + 4, 4, ts);
258       proto_tree_add_item (iax2_tree, hf_iax2_oseqno, tvb, offset + 8, 1,
259                            FALSE);
260       proto_tree_add_item (iax2_tree, hf_iax2_iseqno, tvb, offset + 9, 1,
261                            FALSE);
262       type = tvb_get_guint8(tvb, offset + 10);
263       proto_tree_add_uint (iax2_tree, hf_iax2_type, tvb, offset + 10, 1,
264                            type);
265
266       csub = tvb_get_guint8(tvb, offset + 11);
267       if (type == AST_FRAME_IAX)
268         {
269           proto_tree_add_uint (iax2_tree, hf_iax2_iax_csub, tvb,
270                                offset + 11, 1, csub);
271           if (check_col (pinfo->cinfo, COL_INFO))
272             {
273               col_add_fstr (pinfo->cinfo, COL_INFO,
274                             "%s %s, source call# %d, timestamp %ums",
275                             val_to_str (type, iax_frame_types,
276                                         "Unknown (0x%02x)"),
277                             val_to_str (csub, iax_iax_subclasses,
278                                         "unknown (0x%02x)"), scallno,
279                             ts);
280             }
281
282         }
283       else if (type == AST_FRAME_DTMF)
284         {
285           proto_tree_add_text (iax2_tree, tvb, offset + 11, 1, "DTMF digit: %c", csub);
286           if (check_col (pinfo->cinfo, COL_INFO))
287             {
288               col_add_fstr (pinfo->cinfo, COL_INFO,
289                             "%s digit %c, source call# %d, timestamp %ums",
290                             val_to_str (type, iax_frame_types,
291                                         "Unknown (0x%02x)"), csub,
292                             scallno, ts);
293             }
294
295         }
296       else if (type == AST_FRAME_CONTROL)
297         {
298           proto_tree_add_uint (iax2_tree, hf_iax2_cmd_csub, tvb,
299                                offset + 11, 1, csub);
300           if (check_col (pinfo->cinfo, COL_INFO))
301             {
302               col_add_fstr (pinfo->cinfo, COL_INFO,
303                             "%s %s, source call# %d, timestamp %ums",
304                             val_to_str (type, iax_frame_types,
305                                         "Unknown (0x%02x)"),
306                             val_to_str (csub, iax_cmd_subclasses,
307                                         "unknown (0x%02x)"), scallno,
308                             ts);
309             }
310
311         }
312       else if (type == AST_FRAME_VOICE)
313         {
314           proto_tree_add_uint (iax2_tree, hf_iax2_voice_csub, tvb,
315                                offset + 11, 1, csub);
316           if (check_col (pinfo->cinfo, COL_INFO))
317             {
318               col_add_fstr (pinfo->cinfo, COL_INFO,
319                             "%s codec %s, source call# %d, timestamp %ums",
320                             val_to_str (type, iax_frame_types,
321                                         "Unknown (0x%02x)"),
322                             val_to_str (csub, codec_types,
323                                         "unknown (0x%02x)"), scallno,
324                             ts);
325             }
326         }
327       else
328         {
329           proto_tree_add_uint (iax2_tree, hf_iax2_csub, tvb, offset + 11,
330                                1, csub);
331           if (check_col (pinfo->cinfo, COL_INFO))
332             {
333               col_add_fstr (pinfo->cinfo, COL_INFO,
334                             "%s subclass %d, source call# %d, timestamp %ums",
335                             val_to_str (type, iax_frame_types,
336                                         "Unknown (0x%02x)"), csub,
337                             scallno, ts);
338             }
339         }
340       offset += 12;
341
342       if (type == AST_FRAME_IAX && (offset < tvb_reported_length (tvb)))
343         {
344           ies_base =
345             proto_tree_add_item (iax2_tree, hf_iax2_ies, tvb, offset,
346                                  -1, FALSE);
347           ies_tree = proto_item_add_subtree (ies_base, ett_iax2_ies);
348         }
349
350       while (type == AST_FRAME_IAX && offset < tvb_reported_length (tvb))
351         {
352           int ies_type = tvb_get_guint8(tvb, offset);
353           int ies_len = tvb_get_guint8(tvb, offset + 1);
354           switch (ies_type)
355             {
356             case IAX_IE_CALLED_NUMBER:
357               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLED_NUMBER, tvb,
358                                    offset + 2, ies_len, FALSE);
359               break;
360             case IAX_IE_CALLING_NUMBER:
361               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_NUMBER,
362                                    tvb, offset + 2, ies_len, FALSE);
363               break;
364             case IAX_IE_CALLING_ANI:
365               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_ANI, tvb,
366                                    offset + 2, ies_len, FALSE);
367               break;
368             case IAX_IE_CALLING_NAME:
369               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLING_NAME, tvb,
370                                    offset + 2, ies_len, FALSE);
371               break;
372             case IAX_IE_CALLED_CONTEXT:
373               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLED_CONTEXT,
374                                    tvb, offset + 2, ies_len, FALSE);
375               break;
376             case IAX_IE_USERNAME:
377               proto_tree_add_item (ies_tree, hf_IAX_IE_USERNAME, tvb,
378                                    offset + 2, ies_len, FALSE);
379               break;
380             case IAX_IE_PASSWORD:
381               proto_tree_add_item (ies_tree, hf_IAX_IE_PASSWORD, tvb,
382                                    offset + 2, ies_len, FALSE);
383               break;
384             case IAX_IE_LANGUAGE:
385               proto_tree_add_item (ies_tree, hf_IAX_IE_LANGUAGE, tvb,
386                                    offset + 2, ies_len, FALSE);
387               break;
388             case IAX_IE_DNID:
389               proto_tree_add_item (ies_tree, hf_IAX_IE_DNID, tvb,
390                                    offset + 2, ies_len, FALSE);
391               break;
392             case IAX_IE_CHALLENGE:
393               proto_tree_add_item (ies_tree, hf_IAX_IE_CHALLENGE, tvb,
394                                    offset + 2, ies_len, FALSE);
395               break;
396             case IAX_IE_MD5_RESULT:
397               proto_tree_add_item (ies_tree, hf_IAX_IE_MD5_RESULT, tvb,
398                                    offset + 2, ies_len, FALSE);
399               break;
400             case IAX_IE_RSA_RESULT:
401               proto_tree_add_item (ies_tree, hf_IAX_IE_RSA_RESULT, tvb,
402                                    offset + 2, ies_len, FALSE);
403               break;
404             case IAX_IE_RDNIS:
405               proto_tree_add_item (ies_tree, hf_IAX_IE_RDNIS, tvb,
406                                    offset + 2, ies_len, FALSE);
407               break;
408             case IAX_IE_CAPABILITY:
409               codec_base =
410                 proto_tree_add_item (ies_tree, hf_IAX_IE_CAPABILITY,
411                                      tvb, offset + 2, ies_len, FALSE);
412               codec_tree =
413                 proto_item_add_subtree (codec_base, ett_iax2_codecs);
414
415               codecs = tvb_get_ntohl (tvb, offset + 2);
416               for (i = 0; i < 8; i++)
417                 {
418                   mask = (1 << i);
419                   if (codecs & mask)
420                     proto_tree_add_text (codec_tree, tvb, offset + 2, 4,
421                                          "Supported: %s",
422                                          val_to_str (mask, codec_types,
423                                                      "unknown"));
424                 }
425               for (i = 0; i < 8; i++)
426                 {
427                   mask = (1 << i);
428                   if (!(codecs & mask))
429                     proto_tree_add_text (codec_tree, tvb, offset + 2, 4,
430                                          "Unsupported: %s",
431                                          val_to_str (mask, codec_types,
432                                                      "unknown"));
433                 }
434
435               break;
436             case IAX_IE_FORMAT:
437               proto_tree_add_item (ies_tree, hf_IAX_IE_FORMAT, tvb,
438                                    offset + 2, ies_len, FALSE);
439               break;
440             case IAX_IE_VERSION:
441               proto_tree_add_item (ies_tree, hf_IAX_IE_VERSION, tvb,
442                                    offset + 2, ies_len, FALSE);
443               break;
444             case IAX_IE_ADSICPE:
445               proto_tree_add_item (ies_tree, hf_IAX_IE_ADSICPE, tvb,
446                                    offset + 2, ies_len, FALSE);
447               break;
448             case IAX_IE_AUTHMETHODS:
449               proto_tree_add_item (ies_tree, hf_IAX_IE_AUTHMETHODS, tvb,
450                                    offset + 2, ies_len, FALSE);
451               break;
452             case IAX_IE_APPARENT_ADDR:
453               sockaddr_item = proto_tree_add_text(ies_tree, tvb, offset + 2, 16, "Apparent Address");
454               sockaddr_tree = proto_item_add_subtree(sockaddr_item, ett_iax2_ies_apparent_addr);
455               proto_tree_add_item(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINADDR, tvb, offset + 6, 4, FALSE);
456               proto_tree_add_item(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINPORT, tvb, offset + 4, 2, FALSE);
457               break;
458             case IAX_IE_REFRESH:
459               proto_tree_add_item (ies_tree, hf_IAX_IE_REFRESH, tvb,
460                                    offset + 2, ies_len, FALSE);
461               break;
462             case IAX_IE_DPSTATUS:
463               proto_tree_add_item (ies_tree, hf_IAX_IE_DPSTATUS, tvb,
464                                    offset + 2, ies_len, FALSE);
465               break;
466             case IAX_IE_CALLNO:
467               proto_tree_add_item (ies_tree, hf_IAX_IE_CALLNO, tvb,
468                                    offset + 2, ies_len, FALSE);
469               break;
470             case IAX_IE_CAUSE:
471               proto_tree_add_item (ies_tree, hf_IAX_IE_CAUSE, tvb,
472                                    offset + 2, ies_len, FALSE);
473               break;
474             case IAX_IE_IAX_UNKNOWN:
475               proto_tree_add_item (ies_tree, hf_IAX_IE_IAX_UNKNOWN, tvb,
476                                    offset + 2, ies_len, FALSE);
477               break;
478             case IAX_IE_MSGCOUNT:
479               proto_tree_add_item (ies_tree, hf_IAX_IE_MSGCOUNT, tvb,
480                                    offset + 2, ies_len, FALSE);
481               break;
482             case IAX_IE_AUTOANSWER:
483               proto_tree_add_item (ies_tree, hf_IAX_IE_AUTOANSWER, tvb,
484                                    offset + 2, ies_len, FALSE);
485               break;
486             case IAX_IE_MUSICONHOLD:
487               proto_tree_add_item (ies_tree, hf_IAX_IE_MUSICONHOLD, tvb,
488                                    offset + 2, ies_len, FALSE);
489               break;
490             case IAX_IE_TRANSFERID:
491               proto_tree_add_item (ies_tree, hf_IAX_IE_TRANSFERID, tvb,
492                                    offset + 2, ies_len, FALSE);
493               break;
494             }
495           offset += ies_len + 2;
496         }
497
498     }
499   else
500     {
501       proto_tree_add_uint (iax2_tree, hf_iax2_scallno, tvb, offset, 2,
502                            scallno);
503       ts = tvb_get_ntohs(tvb, offset + 2);
504       proto_tree_add_uint (iax2_tree, hf_iax2_minits, tvb, offset + 2, 2,
505                            ts);
506       if (check_col (pinfo->cinfo, COL_INFO))
507         {
508           col_add_fstr (pinfo->cinfo, COL_INFO,
509                         "Voice frame (mini header), source call# %d, timestamp %ums",
510                         scallno, ts);
511         }
512       proto_tree_add_item (iax2_tree, hf_iax2_voicedata, tvb, offset + 4,
513                            -1, FALSE);
514     }
515
516 }                               /* dissect_iax2 */
517
518 void
519 proto_register_iax2 (void)
520 {
521   static hf_register_info hf[] = {
522     {&hf_iax2_scallno,
523      {"Source call", "iax2.src_call", FT_UINT16, BASE_DEC, NULL, 0x0,
524       "",
525       HFILL}},
526     {&hf_iax2_dcallno,
527      {"Destination call", "iax2.dst_call", FT_UINT16, BASE_DEC, NULL,
528       0x0, "",
529       HFILL}},
530     {&hf_iax2_retransmission,
531      {"Retransmission", "iax2.retransmission", FT_BOOLEAN, BASE_NONE,
532       NULL,
533       0x0, "", HFILL}},
534     {&hf_iax2_ts,
535      {"Timestamp", "iax2.timestamp", FT_UINT32, BASE_DEC, NULL, 0x0,
536       "",
537       HFILL}},
538     {&hf_iax2_minits,
539      {"Timestamp", "iax2.timestamp", FT_UINT16, BASE_DEC, NULL, 0x0,
540       "",
541       HFILL}},
542     {&hf_iax2_voicedata,
543      {"Voice data", "iax2.voicedata", FT_BYTES, BASE_NONE, NULL, 0x0,
544       "",
545       HFILL}},
546     {&hf_iax2_oseqno,
547      {"Outbound seq.no.", "iax2.oseqno", FT_UINT16, BASE_DEC, NULL,
548       0x0, "",
549       HFILL}},
550     {&hf_iax2_iseqno,
551      {"Inbound seq.no.", "iax2.iseqno", FT_UINT16, BASE_DEC, NULL, 0x0,
552       "",
553       HFILL}},
554     {&hf_iax2_type,
555      {"Type", "iax2.type", FT_UINT8, BASE_DEC, VALS (iax_frame_types),
556       0x0, "",
557       HFILL}},
558     {&hf_iax2_csub,
559      {"Sub-class", "iax2.subclass", FT_UINT8, BASE_DEC, NULL, 0x0, "",
560       HFILL}},
561     {&hf_iax2_cmd_csub,
562      {"Control type", "iax2.control", FT_UINT8, BASE_DEC,
563       VALS (iax_cmd_subclasses), 0x0, "", HFILL}},
564     {&hf_iax2_voice_csub,
565      {"CODEC", "iax2.voice", FT_UINT8, BASE_DEC, VALS (codec_types),
566       0x0, "", HFILL}},
567     {&hf_iax2_iax_csub,
568      {"IAX type", "iax2.iax", FT_UINT8, BASE_DEC,
569       VALS (iax_iax_subclasses),
570       0x0, "", HFILL}},
571     {&hf_iax2_ies,
572      {"Information elements", "iax2.ies", FT_BYTES, BASE_NONE, NULL,
573       0x0, "", HFILL}},
574         {&hf_IAX_IE_APPARENTADDR_SINFAMILY,
575      {"Family", "iax2.ies.app_addr.sinfamily", FT_UINT16, BASE_DEC, NULL, 0, "Family", HFILL }},
576         {&hf_IAX_IE_APPARENTADDR_SINPORT,
577      {"Port", "iax2.ies.app_addr.sinport", FT_UINT16, BASE_DEC, NULL, 0, "Port", HFILL }},
578         {&hf_IAX_IE_APPARENTADDR_SINADDR,
579      {"Address", "iax2.ies.app_addr.sinaddr", FT_IPv4, BASE_HEX, NULL, 0, "Address", HFILL }},
580         {&hf_IAX_IE_APPARENTADDR_SINZERO,
581      {"Zero", "iax2.ies.app_addr.sinzero", FT_BYTES, BASE_HEX, NULL, 0, "Zero", HFILL }},
582     {&hf_IAX_IE_CALLED_NUMBER,
583      {"Number/extension being called", "iax2.ies.called_number",
584       FT_STRING,
585       BASE_NONE, NULL, 0x0, "", HFILL}},
586     {&hf_IAX_IE_CALLING_NUMBER,
587      {"Calling number", "iax2.ies.calling_number", FT_STRING,
588       BASE_NONE, NULL,
589       0x0, "", HFILL}},
590     {&hf_IAX_IE_CALLING_ANI,
591      {"Calling number ANI for billing", "iax2.ies.calling_ani",
592       FT_STRING,
593       BASE_NONE, NULL, 0x0, "", HFILL}},
594     {&hf_IAX_IE_CALLING_NAME,
595      {"Name of caller", "iax2.ies.calling_name", FT_STRING, BASE_NONE,
596       NULL,
597       0x0, "", HFILL}},
598     {&hf_IAX_IE_CALLED_CONTEXT,
599      {"Context for number", "iax2.ies.called_context", FT_STRING,
600       BASE_NONE,
601       NULL, 0x0, "", HFILL}},
602     {&hf_IAX_IE_USERNAME,
603      {"Username (peer or user) for authentication",
604       "iax2.ies.username",
605       FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
606     {&hf_IAX_IE_PASSWORD,
607      {"Password for authentication", "iax2.ies.password", FT_STRING,
608       BASE_NONE, NULL, 0x0, "", HFILL}},
609     {&hf_IAX_IE_CAPABILITY,
610      {"Actual codec capability", "iax2.ies.capability", FT_UINT32,
611       BASE_HEX,
612       NULL, 0x0, "", HFILL}},
613     {&hf_IAX_IE_FORMAT,
614      {"Desired codec format", "iax2.ies.format", FT_UINT32, BASE_HEX,
615       VALS (codec_types), 0x0, "", HFILL}},
616     {&hf_IAX_IE_LANGUAGE,
617      {"Desired language", "iax2.ies.language", FT_STRING, BASE_NONE,
618       NULL,
619       0x0, "", HFILL}},
620     {&hf_IAX_IE_VERSION,
621      {"Protocol version", "iax2.ies.version", FT_INT16, BASE_HEX, NULL,
622       0x0,
623       "", HFILL}},
624     {&hf_IAX_IE_ADSICPE,
625      {"CPE ADSI capability", "iax2.ies.cpe_adsi", FT_INT16, BASE_HEX,
626       NULL,
627       0x0, "", HFILL}},
628     {&hf_IAX_IE_DNID,
629      {"Originally dialed DNID", "iax2.ies.dnid", FT_STRING, BASE_NONE,
630       NULL,
631       0x0, "", HFILL}},
632     {&hf_IAX_IE_AUTHMETHODS,
633      {"Authentication method(s)", "iax2.ies.auth.methods", FT_INT16,
634       BASE_HEX,
635       NULL, 0x0, "", HFILL}},
636     {&hf_IAX_IE_CHALLENGE,
637      {"Challenge data for MD5/RSA", "iax2.ies.auth.challenge",
638       FT_STRING,
639       BASE_NONE, NULL, 0x0, "", HFILL}},
640     {&hf_IAX_IE_MD5_RESULT,
641      {"MD5 challenge result", "iax2.ies.auth.md5", FT_STRING,
642       BASE_NONE, NULL,
643       0x0, "", HFILL}},
644     {&hf_IAX_IE_RSA_RESULT,
645      {"RSA challenge result", "iax2.ies.auth.rsa", FT_STRING,
646       BASE_NONE, NULL,
647       0x0, "", HFILL}},
648     {&hf_IAX_IE_REFRESH,
649      {"When to refresh registration", "iax2.ies.refresh", FT_INT16,
650       BASE_DEC,
651       NULL, 0x0, "", HFILL}},
652     {&hf_IAX_IE_DPSTATUS,
653      {"Dialplan status", "iax2.ies.dialplan_status", FT_INT16,
654       BASE_HEX, NULL,
655       0x0, "", HFILL}},
656     {&hf_IAX_IE_CALLNO,
657      {"Call number of peer", "iax2.ies.call_no", FT_INT16, BASE_DEC,
658       NULL,
659       0x0, "", HFILL}},
660     {&hf_IAX_IE_CAUSE,
661      {"Cause", "iax2.ies.cause", FT_STRING, BASE_NONE, NULL, 0x0, "",
662       HFILL}},
663     {&hf_IAX_IE_IAX_UNKNOWN,
664      {"Unknown IAX command", "iax2.ies.iax_unknown", FT_BYTES,
665       BASE_HEX, NULL,
666       0x0, "", HFILL}},
667     {&hf_IAX_IE_MSGCOUNT,
668      {"How many messages waiting", "iax2.ies.msg_count", FT_INT16,
669       BASE_DEC,
670       NULL, 0x0, "", HFILL}},
671     {&hf_IAX_IE_AUTOANSWER,
672      {"Request auto-answering", "iax2.ies.autoanswer", FT_NONE,
673       BASE_NONE,
674       NULL, 0x0, "", HFILL}},
675     {&hf_IAX_IE_MUSICONHOLD,
676      {"Request musiconhold with QUELCH", "iax2.ies.moh", FT_NONE,
677       BASE_NONE,
678       NULL, 0x0, "", HFILL}},
679     {&hf_IAX_IE_TRANSFERID,
680      {"Transfer Request Identifier", "iax2.ies.transferid", FT_INT32,
681       BASE_HEX, NULL, 0x0, "", HFILL}},
682     {&hf_IAX_IE_RDNIS,
683      {"Referring DNIS", "iax2.ies.rdnis", FT_STRING, BASE_NONE, NULL,
684       0x0, "",
685       HFILL}}
686   };
687
688   static gint *ett[] = {
689     &ett_iax2,
690     &ett_iax2_ies,
691     &ett_iax2_codecs,
692         &ett_iax2_ies_apparent_addr
693   };
694
695   proto_iax2 =
696     proto_register_protocol ("IAX2", "Inter-Asterisk eXchange v2", "iax2");
697   proto_register_field_array (proto_iax2, hf, array_length (hf));
698   proto_register_subtree_array (ett, array_length (ett));
699
700 }
701
702 void
703 proto_reg_handoff_iax2 (void)
704 {
705
706   dissector_handle_t iax2_handle = NULL;
707
708   iax2_handle = create_dissector_handle (dissect_iax2, proto_iax2);
709
710   dissector_add ("udp.port", IAX2_PORT, iax2_handle);
711 }