Ethereal-dev: [Ethereal-dev] IAX2 VoIP packet dissector
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Alastair Maw <me@xxxxxxxxx>
Date: Fri, 02 Jan 2004 19:12:13 +0000
This is my first go at a packet dissector, so be gentle...Please find attached a dissector for the IAX2 protocol, which I hope you good folk might include in the next release. :)
There's a screenshot at http://almaw.com/ethereal-iax2/ should you be interested (although the source there is a little older than the attached).
IAX2 is used by Asterisk, which is a very nice bit of GPL'd PBX/VoIP software. For more information, http://www.asterisk.org.
Best regards, Alastair Maw
Index: Makefile.am =================================================================== RCS file: /cvsroot/ethereal/Makefile.am,v retrieving revision 1.682 diff -u -u -r1.682 Makefile.am --- Makefile.am 30 Dec 2003 17:14:14 -0000 1.682 +++ Makefile.am 2 Jan 2004 18:26:12 -0000 @@ -256,6 +256,7 @@ packet-http.c \ packet-hyperscsi.c \ packet-iapp.c \ + packet-iax2.c \ packet-ib.c \ packet-icap.c \ packet-icmpv6.c\ Index: Makefile.nmake =================================================================== RCS file: /cvsroot/ethereal/Makefile.nmake,v retrieving revision 1.382 diff -u -u -r1.382 Makefile.nmake --- Makefile.nmake 30 Dec 2003 22:18:03 -0000 1.382 +++ Makefile.nmake 2 Jan 2004 18:26:12 -0000 @@ -196,6 +196,7 @@ packet-http.c \ packet-hyperscsi.c \ packet-iapp.c \ + packet-iax2.c \ packet-ib.c \ packet-icap.c \ packet-icmpv6.c\
/* packet-iax2.c * * Routines for IAX2 packet disassembly * By Alastair Maw <asterisk@xxxxxxxxx> * Copyright 2003 Alastair Maw * * IAX2 is a VoIP protocol for the open source PBX Asterisk. * Please see http://www.asterisk.org for more information. * * $Id: packet-iax2.c,v 1.3 2004/01/02 16:28:18 almaw Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@xxxxxxxxxxxx> * Copyright 1998 Gerald Combs * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #include <string.h> #include <glib.h> #include <epan/packet.h> #include <arpa/inet.h> #include "packet-iax2.h" #define IAX2_PORT 4569 #define PROTO_TAG_IAX2 "IAX2" static int proto_iax2 = -1; static int hf_iax2_retransmission = -1; static int hf_iax2_scallno = -1; static int hf_iax2_dcallno = -1; static int hf_iax2_ts = -1; static int hf_iax2_minits = -1; static int hf_iax2_voicedata = -1; static int hf_iax2_oseqno = -1; static int hf_iax2_iseqno = -1; static int hf_iax2_type = -1; static int hf_iax2_csub = -1; static int hf_iax2_dtmf_csub = -1; static int hf_iax2_cmd_csub = -1; static int hf_iax2_iax_csub = -1; static int hf_iax2_voice_csub = -1; static int hf_iax2_ies = -1; static int hf_IAX_IE_CALLED_NUMBER = -1; static int hf_IAX_IE_CALLING_NUMBER = -1; static int hf_IAX_IE_CALLING_ANI = -1; static int hf_IAX_IE_CALLING_NAME = -1; static int hf_IAX_IE_CALLED_CONTEXT = -1; static int hf_IAX_IE_USERNAME = -1; static int hf_IAX_IE_PASSWORD = -1; static int hf_IAX_IE_CAPABILITY = -1; static int hf_IAX_IE_FORMAT = -1; static int hf_IAX_IE_LANGUAGE = -1; static int hf_IAX_IE_VERSION = -1; static int hf_IAX_IE_ADSICPE = -1; static int hf_IAX_IE_DNID = -1; static int hf_IAX_IE_AUTHMETHODS = -1; static int hf_IAX_IE_CHALLENGE = -1; static int hf_IAX_IE_MD5_RESULT = -1; static int hf_IAX_IE_RSA_RESULT = -1; static int hf_IAX_IE_APPARENT_ADDR = -1; static int hf_IAX_IE_REFRESH = -1; static int hf_IAX_IE_DPSTATUS = -1; static int hf_IAX_IE_CALLNO = -1; static int hf_IAX_IE_CAUSE = -1; static int hf_IAX_IE_IAX_UNKNOWN = -1; static int hf_IAX_IE_MSGCOUNT = -1; static int hf_IAX_IE_AUTOANSWER = -1; static int hf_IAX_IE_MUSICONHOLD = -1; static int hf_IAX_IE_TRANSFERID = -1; static int hf_IAX_IE_RDNIS = -1; static gint ett_iax2 = -1; static gint ett_iax2_ies = -1; static gint ett_iax2_codecs = -1; static const value_string iax_frame_types[] = { {0, "(0?)"}, {1, "DTMF"}, {2, "Voice"}, {3, "Video"}, {4, "Control"}, {5, "NULL"}, {6, "IAX"}, {7, "Text"}, {8, "Image"} }; static const value_string iax_iax_subclasses[] = { {0, "(0?)"}, {1, "NEW"}, {2, "PING"}, {3, "PONG"}, {4, "ACK"}, {5, "HANGUP"}, {6, "REJECT"}, {7, "ACCEPT"}, {8, "AUTHREQ"}, {9, "AUTHREP"}, {10, "INVAL"}, {11, "LAGRQ"}, {12, "LAGRP"}, {13, "REGREQ"}, {14, "REGAUTH"}, {15, "REGACK"}, {16, "REGREJ"}, {17, "REGREL"}, {18, "VNAK"}, {19, "DPREQ"}, {20, "DPREP"}, {21, "DIAL"}, {22, "TXREQ"}, {23, "TXCNT"}, {24, "TXACC"}, {25, "TXREADY"}, {26, "TXREL"}, {27, "TXREJ"}, {28, "QUELCH"}, {29, "UNQULCH"}, {30, "POKE"}, {31, "PAGE"}, {32, "MWI"}, {33, "UNSUPPORTED"}, {34, "TRANSFER"} }; static const value_string iax_cmd_subclasses[] = { {0, "(0?)"}, {1, "HANGUP"}, {2, "RING"}, {3, "RINGING"}, {4, "ANSWER"}, {5, "BUSY"}, {6, "TKOFFHK"}, {7, "OFFHOOK"} }; static const value_string iax_ies_type[] = { {IAX_IE_CALLED_NUMBER, "Number/extension being called"}, {IAX_IE_CALLING_NUMBER, "Calling number"}, {IAX_IE_CALLING_ANI, "Calling number ANI for billing"}, {IAX_IE_CALLING_NAME, "Name of caller"}, {IAX_IE_CALLED_CONTEXT, "Context for number"}, {IAX_IE_USERNAME, "Username (peer or user) for authentication"}, {IAX_IE_PASSWORD, "Password for authentication"}, {IAX_IE_CAPABILITY, "Actual codec capability"}, {IAX_IE_FORMAT, "Desired codec format"}, {IAX_IE_LANGUAGE, "Desired language"}, {IAX_IE_VERSION, "Protocol version"}, {IAX_IE_ADSICPE, "CPE ADSI capability"}, {IAX_IE_DNID, "Originally dialed DNID"}, {IAX_IE_AUTHMETHODS, "Authentication method(s)"}, {IAX_IE_CHALLENGE, "Challenge data for MD5/RSA"}, {IAX_IE_MD5_RESULT, "MD5 challenge result"}, {IAX_IE_RSA_RESULT, "RSA challenge result"}, {IAX_IE_APPARENT_ADDR, "Apparent address of peer"}, {IAX_IE_REFRESH, "When to refresh registration"}, {IAX_IE_DPSTATUS, "Dialplan status"}, {IAX_IE_CALLNO, "Call number of peer"}, {IAX_IE_CAUSE, "Cause"}, {IAX_IE_IAX_UNKNOWN, "Unknown IAX command"}, {IAX_IE_MSGCOUNT, "How many messages waiting"}, {IAX_IE_AUTOANSWER, "Request auto-answering"}, {IAX_IE_MUSICONHOLD, "Request musiconhold with QUELCH"}, {IAX_IE_TRANSFERID, "Transfer Request Identifier"}, {IAX_IE_RDNIS, "Referring DNIS"} }; static const value_string codec_types[] = { {AST_FORMAT_G723_1, "G.723.1 compression"}, {AST_FORMAT_GSM, "GSM compression"}, {AST_FORMAT_ULAW, "Raw mu-law data (G.711)"}, {AST_FORMAT_ALAW, "Raw A-law data (G.711)"}, {AST_FORMAT_MP3, "MPEG-2 layer 3"}, {AST_FORMAT_ADPCM, "ADPCM (whose?)"}, {AST_FORMAT_SLINEAR,"Raw 16-bit Signed Linear (8000 Hz) PCM"}, {AST_FORMAT_LPC10, "LPC10, 180 samples/frame"}, {AST_FORMAT_G729A, "G.729a Audio"} }; static void dissect_iax2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { char buffer[150]; proto_tree *iax2_tree = NULL, *ies_tree = NULL, *codec_tree = NULL; proto_item *ti = 0, *ies_base = 0, *codec_base = 0; unsigned int offset = 0, codecs = 0, i = 0, mask = 0; const char *data = tvb_get_ptr(tvb, offset, -1); struct sockaddr_in * addr; guint16 scallno; guint16 dcallno; if (check_col(pinfo->cinfo, COL_PROTOCOL)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_IAX2); } if (tree) { ti = proto_tree_add_item(tree, proto_iax2, tvb, offset, -1, FALSE); iax2_tree = proto_item_add_subtree(ti, ett_iax2); } if (g_ntohs(*data) & 0x8000) { struct ast_iax2_full_hdr *h = (struct ast_iax2_full_hdr*)data; int retransmission = g_ntohs(h->dcallno) & 0x8000; /* remove the top bits for retransmission/header type detection */ scallno = g_ntohs(h->scallno) & 0x7FFF; dcallno = g_ntohs(h->dcallno) & 0x7FFF; proto_tree_add_boolean(iax2_tree, hf_iax2_retransmission, tvb, offset+2, 1, retransmission); proto_tree_add_uint(iax2_tree, hf_iax2_scallno, tvb, offset, 2, scallno); proto_tree_add_uint(iax2_tree, hf_iax2_dcallno, tvb, offset+2, 2, dcallno); proto_tree_add_item(iax2_tree, hf_iax2_ts, tvb, offset+4, 4, FALSE); proto_tree_add_item(iax2_tree, hf_iax2_oseqno, tvb, offset+8, 1, FALSE); proto_tree_add_item(iax2_tree, hf_iax2_iseqno, tvb, offset+9, 1, FALSE); proto_tree_add_item(iax2_tree, hf_iax2_type, tvb, offset+10, 1, FALSE); if (h->type == AST_FRAME_IAX) { proto_tree_add_item(iax2_tree, hf_iax2_iax_csub, tvb, offset+11, 1, FALSE); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s, source call# %d, timestamp %ums", val_to_str(h->type, iax_frame_types, "Unknown (0x%02x)"), val_to_str(h->csub, iax_iax_subclasses, "unknown (0x%02x)"), scallno, g_ntohl(h->ts)); } } else if (h->type == AST_FRAME_DTMF) { proto_tree_add_item(iax2_tree, hf_iax2_dtmf_csub, tvb, offset+11, 1, FALSE); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%s digit %c, source call# %d, timestamp %ums", val_to_str(h->type, iax_frame_types, "Unknown (0x%02x)"), h->csub, scallno, g_ntohl(h->ts)); } } else if (h->type == AST_FRAME_CONTROL) { proto_tree_add_item(iax2_tree, hf_iax2_cmd_csub, tvb, offset+11, 1, FALSE); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s, source call# %d, timestamp %ums", val_to_str(h->type, iax_frame_types, "Unknown (0x%02x)"), val_to_str(h->csub, iax_cmd_subclasses, "unknown (0x%02x)"), scallno, g_ntohl(h->ts)); } } else if (h->type == AST_FRAME_VOICE) { proto_tree_add_item(iax2_tree, hf_iax2_voice_csub, tvb, offset+11, 1, FALSE); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%s codec %s, source call# %d, timestamp %ums", val_to_str(h->type, iax_frame_types, "Unknown (0x%02x)"), val_to_str(h->csub, codec_types, "unknown (0x%02x)"), scallno, g_ntohl(h->ts)); } } else { proto_tree_add_item(iax2_tree, hf_iax2_csub, tvb, offset+11, 1, FALSE); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%s subclass %d, source call# %d, timestamp %ums", val_to_str(h->type, iax_frame_types, "Unknown (0x%02x)"), h->csub, scallno, g_ntohl(h->ts)); } } offset += 12; if (h->type == AST_FRAME_IAX && (offset < tvb_reported_length(tvb))) { ies_base = proto_tree_add_item(iax2_tree, hf_iax2_ies, tvb, offset, -1, FALSE); ies_tree = proto_item_add_subtree(ies_base, ett_iax2_ies); } while(h->type == AST_FRAME_IAX && offset < tvb_reported_length(tvb)) { int ies_type = data[offset]; int ies_len = data[offset + 1]; switch (ies_type) { case IAX_IE_CALLED_NUMBER: proto_tree_add_item(ies_tree, hf_IAX_IE_CALLED_NUMBER, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_CALLING_NUMBER: proto_tree_add_item(ies_tree, hf_IAX_IE_CALLING_NUMBER, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_CALLING_ANI: proto_tree_add_item(ies_tree, hf_IAX_IE_CALLING_ANI, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_CALLING_NAME: proto_tree_add_item(ies_tree, hf_IAX_IE_CALLING_NAME, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_CALLED_CONTEXT: proto_tree_add_item(ies_tree, hf_IAX_IE_CALLED_CONTEXT, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_USERNAME: proto_tree_add_item(ies_tree, hf_IAX_IE_USERNAME, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_PASSWORD: proto_tree_add_item(ies_tree, hf_IAX_IE_PASSWORD, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_LANGUAGE: proto_tree_add_item(ies_tree, hf_IAX_IE_LANGUAGE, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_DNID: proto_tree_add_item(ies_tree, hf_IAX_IE_DNID, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_CHALLENGE: proto_tree_add_item(ies_tree, hf_IAX_IE_CHALLENGE, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_MD5_RESULT: proto_tree_add_item(ies_tree, hf_IAX_IE_MD5_RESULT, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_RSA_RESULT: proto_tree_add_item(ies_tree, hf_IAX_IE_RSA_RESULT, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_RDNIS: proto_tree_add_item(ies_tree, hf_IAX_IE_RDNIS, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_CAPABILITY: codec_base = proto_tree_add_item(ies_tree, hf_IAX_IE_CAPABILITY, tvb, offset + 2, ies_len, FALSE); codec_tree = proto_item_add_subtree(codec_base, ett_iax2_codecs); codecs = tvb_get_ntohl(tvb, offset + 2); for(i=0;i<8;i++) { mask = (1 << i); if (codecs & mask) proto_tree_add_text(codec_tree, tvb, offset + 2, 4, "Supported: %s", val_to_str(mask, codec_types, "unknown")); } for(i=0;i<8;i++) { mask = (1 << i); if (!(codecs & mask)) proto_tree_add_text(codec_tree, tvb, offset + 2, 4, "Unsupported: %s", val_to_str(mask, codec_types, "unknown")); } break; case IAX_IE_FORMAT: proto_tree_add_item(ies_tree, hf_IAX_IE_FORMAT, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_VERSION: proto_tree_add_item(ies_tree, hf_IAX_IE_VERSION, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_ADSICPE: proto_tree_add_item(ies_tree, hf_IAX_IE_ADSICPE, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_AUTHMETHODS: proto_tree_add_item(ies_tree, hf_IAX_IE_AUTHMETHODS, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_APPARENT_ADDR: addr = (struct sockaddr_in*)tvb_get_ptr(tvb, offset+2, ies_len); sprintf(buffer, "Apparent address: %s:%d", inet_ntoa(addr->sin_addr), ntohs(addr->sin_port)); proto_tree_add_text(ies_tree, tvb, offset + 2, ies_len, buffer); break; case IAX_IE_REFRESH: proto_tree_add_item(ies_tree, hf_IAX_IE_REFRESH, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_DPSTATUS: proto_tree_add_item(ies_tree, hf_IAX_IE_DPSTATUS, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_CALLNO: proto_tree_add_item(ies_tree, hf_IAX_IE_CALLNO, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_CAUSE: proto_tree_add_item(ies_tree, hf_IAX_IE_CAUSE, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_IAX_UNKNOWN: proto_tree_add_item(ies_tree, hf_IAX_IE_IAX_UNKNOWN, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_MSGCOUNT: proto_tree_add_item(ies_tree, hf_IAX_IE_MSGCOUNT, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_AUTOANSWER: proto_tree_add_item(ies_tree, hf_IAX_IE_AUTOANSWER, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_MUSICONHOLD: proto_tree_add_item(ies_tree, hf_IAX_IE_MUSICONHOLD, tvb, offset + 2, ies_len, FALSE); break; case IAX_IE_TRANSFERID: proto_tree_add_item(ies_tree, hf_IAX_IE_TRANSFERID, tvb, offset + 2, ies_len, FALSE); break; } offset += ies_len + 2; } } else { struct ast_iax2_mini_hdr *h = (struct ast_iax2_mini_hdr*)data; if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "Voice frame (mini header), source call# %d, timestamp %ums", g_ntohs(h->callno) & 0x7FFF, g_ntohs(h->ts)); } /* remove the top bits for retransmission/header type detection */ proto_tree_add_uint(iax2_tree, hf_iax2_scallno, tvb, offset, 2, g_ntohs(h->callno)); proto_tree_add_uint(iax2_tree, hf_iax2_minits, tvb, offset+2, 2, g_ntohs(h->ts)); proto_tree_add_item(iax2_tree, hf_iax2_voicedata, tvb, offset+4, -1, FALSE); } } /* dissect_iax2 */ void proto_register_iax2(void) { static hf_register_info hf[] = { { &hf_iax2_retransmission, { "Retransmission", "iax2.retransmission", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_iax2_scallno, { "Source call", "iax2.src_call", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_iax2_dcallno, { "Destination call", "iax2.dst_call", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_iax2_ts, { "Timestamp", "iax2.timestamp", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_iax2_minits, { "Timestamp", "iax2.timestamp", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_iax2_voicedata, { "Voice data", "iax2.voicedata", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_iax2_oseqno, { "Outbound seq.no.", "iax2.oseqno", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_iax2_iseqno, { "Inbound seq.no.", "iax2.iseqno", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_iax2_type, { "Type", "iax2.type", FT_INT8, BASE_DEC, VALS(iax_frame_types), 0x0, "", HFILL }}, { &hf_iax2_csub, { "Sub-class", "iax2.subclass", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_iax2_dtmf_csub, { "DTMF digit", "iax2.dtmf.digit", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_iax2_cmd_csub, { "Control type", "iax2.control", FT_UINT8, BASE_DEC, VALS(iax_cmd_subclasses), 0x0, "", HFILL }}, { &hf_iax2_voice_csub, { "CODEC", "iax2.voice", FT_UINT8, BASE_DEC, VALS(codec_types), 0x0, "", HFILL }}, { &hf_iax2_iax_csub, { "IAX type", "iax2.iax", FT_UINT8, BASE_DEC, VALS(iax_iax_subclasses), 0x0, "", HFILL }}, { &hf_iax2_ies, { "Information elements", "iax2.ies", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_CALLED_NUMBER, { "Number/extension being called", "iax2.ies.called_number", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_CALLING_NUMBER,{ "Calling number", "iax2.ies.calling_number", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_CALLING_ANI, { "Calling number ANI for billing", "iax2.ies.calling_ani", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_CALLING_NAME, { "Name of caller", "iax2.ies.calling_name", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_CALLED_CONTEXT,{ "Context for number", "iax2.ies.called_context", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_USERNAME, { "Username (peer or user) for authentication", "iax2.ies.username",FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_PASSWORD, { "Password for authentication", "iax2.ies.password", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_CAPABILITY, { "Actual codec capability", "iax2.ies.capability", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_FORMAT, { "Desired codec format", "iax2.ies.format", FT_UINT32, BASE_HEX, VALS(codec_types), 0x0, "", HFILL }}, { &hf_IAX_IE_LANGUAGE, { "Desired language", "iax2.ies.language", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_VERSION, { "Protocol version", "iax2.ies.version", FT_INT16, BASE_HEX, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_ADSICPE, { "CPE ADSI capability", "iax2.ies.cpe_adsi", FT_INT16, BASE_HEX, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_DNID, { "Originally dialed DNID", "iax2.ies.dnid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_AUTHMETHODS, { "Authentication method(s)", "iax2.ies.auth.methods", FT_INT16, BASE_HEX, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_CHALLENGE, { "Challenge data for MD5/RSA", "iax2.ies.auth.challenge", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_MD5_RESULT, { "MD5 challenge result", "iax2.ies.auth.md5", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_RSA_RESULT, { "RSA challenge result", "iax2.ies.auth.rsa", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_APPARENT_ADDR, { "Apparent address of peer", "iax2.ies.address", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_REFRESH, { "When to refresh registration", "iax2.ies.refresh", FT_INT16, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_DPSTATUS, { "Dialplan status", "iax2.ies.dialplan_status", FT_INT16, BASE_HEX, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_CALLNO, { "Call number of peer", "iax2.ies.call_no", FT_INT16, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_CAUSE, { "Cause", "iax2.ies.cause", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_IAX_UNKNOWN, { "Unknown IAX command", "iax2.ies.iax_unknown", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_MSGCOUNT, { "How many messages waiting", "iax2.ies.msg_count", FT_INT16, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_AUTOANSWER, { "Request auto-answering", "iax2.ies.autoanswer", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_MUSICONHOLD, { "Request musiconhold with QUELCH", "iax2.ies.moh", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_TRANSFERID, { "Transfer Request Identifier", "iax2.ies.transferid", FT_INT32, BASE_HEX, NULL, 0x0, "", HFILL }}, { &hf_IAX_IE_RDNIS, { "Referring DNIS", "iax2.ies.rdnis", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }} }; static gint *ett[] = { &ett_iax2, &ett_iax2_ies, &ett_iax2_codecs }; proto_iax2 = proto_register_protocol("IAX2", "Inter-Asterisk eXchange v2", "iax2"); proto_register_field_array(proto_iax2, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); } void proto_reg_handoff_iax2(void) { dissector_handle_t iax2_handle = NULL; iax2_handle = create_dissector_handle(dissect_iax2, proto_iax2); dissector_add("udp.port", IAX2_PORT, iax2_handle); }
/* * Asterisk -- A telephony toolkit for Linux. * * Implementation of Inter-Asterisk eXchange * * Copyright (C) 2003, Digium * * Mark Spencer <markster@xxxxxxxxxxxxxxxxx> * * This program is free software, distributed under the terms of * the GNU General Public License */ #ifndef _PACKET_IAX2_H #define _PACKET_IAX2_H /* Max version of IAX protocol we support */ #define IAX_PROTO_VERSION 2 #define IAX_MAX_CALLS 32768 #define IAX_FLAG_FULL 0x8000 #define IAX_FLAG_RETRANS 0x8000 #define IAX_FLAG_SC_LOG 0x80 #define IAX_MAX_SHIFT 0x1F #define IAX_WINDOW 64 #define AST_FRAME_DTMF 1 /* A DTMF digit, subclass is the digit */ #define AST_FRAME_VOICE 2 /* Voice data, subclass is AST_FORMAT_* */ #define AST_FRAME_VIDEO 3 /* Video frame, maybe?? :) */ #define AST_FRAME_CONTROL 4 /* A control frame, subclass is AST_CONTROL_* */ #define AST_FRAME_NULL 5 /* An empty, useless frame */ #define AST_FRAME_IAX 6 /* Inter Aterisk Exchange private frame type */ #define AST_FRAME_TEXT 7 /* Text messages */ #define AST_FRAME_IMAGE 8 /* Image Frames */ #define AST_FRAME_HTML 9 /* HTML Frames */ /* Subclass for AST_FRAME_IAX */ #define IAX_COMMAND_NEW 1 #define IAX_COMMAND_PING 2 #define IAX_COMMAND_PONG 3 #define IAX_COMMAND_ACK 4 #define IAX_COMMAND_HANGUP 5 #define IAX_COMMAND_REJECT 6 #define IAX_COMMAND_ACCEPT 7 #define IAX_COMMAND_AUTHREQ 8 #define IAX_COMMAND_AUTHREP 9 #define IAX_COMMAND_INVAL 10 #define IAX_COMMAND_LAGRQ 11 #define IAX_COMMAND_LAGRP 12 #define IAX_COMMAND_REGREQ 13 /* Registration request */ #define IAX_COMMAND_REGAUTH 14 /* Registration authentication required */ #define IAX_COMMAND_REGACK 15 /* Registration accepted */ #define IAX_COMMAND_REGREJ 16 /* Registration rejected */ #define IAX_COMMAND_REGREL 17 /* Force release of registration */ #define IAX_COMMAND_VNAK 18 /* If we receive voice before valid first voice frame, send this */ #define IAX_COMMAND_DPREQ 19 /* Request status of a dialplan entry */ #define IAX_COMMAND_DPREP 20 /* Request status of a dialplan entry */ #define IAX_COMMAND_DIAL 21 /* Request a dial on channel brought up TBD */ #define IAX_COMMAND_TXREQ 22 /* Transfer Request */ #define IAX_COMMAND_TXCNT 23 /* Transfer Connect */ #define IAX_COMMAND_TXACC 24 /* Transfer Accepted */ #define IAX_COMMAND_TXREADY 25 /* Transfer ready */ #define IAX_COMMAND_TXREL 26 /* Transfer release */ #define IAX_COMMAND_TXREJ 27 /* Transfer reject */ #define IAX_COMMAND_QUELCH 28 /* Stop audio/video transmission */ #define IAX_COMMAND_UNQUELCH 29 /* Resume audio/video transmission */ #define IAX_COMMAND_POKE 30 /* Like ping, but does not require an open connection */ #define IAX_COMMAND_PAGE 31 /* Paging description */ #define IAX_COMMAND_MWI 32 /* Stand-alone message waiting indicator */ #define IAX_COMMAND_UNSUPPORT 33 /* Unsupported message received */ #define IAX_COMMAND_TRANSFER 34 /* Request remote transfer */ #define IAX_DEFAULT_REG_EXPIRE 60 /* By default require re-registration once per minute */ #define IAX_LINGER_TIMEOUT 10 /* How long to wait before closing bridged call */ #define IAX_DEFAULT_PORTNO 4569 /* IAX Information elements */ #define IAX_IE_CALLED_NUMBER 1 /* Number/extension being called - string */ #define IAX_IE_CALLING_NUMBER 2 /* Calling number - string */ #define IAX_IE_CALLING_ANI 3 /* Calling number ANI for billing - string */ #define IAX_IE_CALLING_NAME 4 /* Name of caller - string */ #define IAX_IE_CALLED_CONTEXT 5 /* Context for number - string */ #define IAX_IE_USERNAME 6 /* Username (peer or user) for authentication - string */ #define IAX_IE_PASSWORD 7 /* Password for authentication - string */ #define IAX_IE_CAPABILITY 8 /* Actual codec capability - unsigned int */ #define IAX_IE_FORMAT 9 /* Desired codec format - unsigned int */ #define IAX_IE_LANGUAGE 10 /* Desired language - string */ #define IAX_IE_VERSION 11 /* Protocol version - short */ #define IAX_IE_ADSICPE 12 /* CPE ADSI capability - short */ #define IAX_IE_DNID 13 /* Originally dialed DNID - string */ #define IAX_IE_AUTHMETHODS 14 /* Authentication method(s) - short */ #define IAX_IE_CHALLENGE 15 /* Challenge data for MD5/RSA - string */ #define IAX_IE_MD5_RESULT 16 /* MD5 challenge result - string */ #define IAX_IE_RSA_RESULT 17 /* RSA challenge result - string */ #define IAX_IE_APPARENT_ADDR 18 /* Apparent address of peer - struct sockaddr_in */ #define IAX_IE_REFRESH 19 /* When to refresh registration - short */ #define IAX_IE_DPSTATUS 20 /* Dialplan status - short */ #define IAX_IE_CALLNO 21 /* Call number of peer - short */ #define IAX_IE_CAUSE 22 /* Cause - string */ #define IAX_IE_IAX_UNKNOWN 23 /* Unknown IAX command - byte */ #define IAX_IE_MSGCOUNT 24 /* How many messages waiting - short */ #define IAX_IE_AUTOANSWER 25 /* Request auto-answering -- none */ #define IAX_IE_MUSICONHOLD 26 /* Request musiconhold with QUELCH -- none or string */ #define IAX_IE_TRANSFERID 27 /* Transfer Request Identifier -- int */ #define IAX_IE_RDNIS 28 /* Referring DNIS -- string */ #define IAX_AUTH_PLAINTEXT (1 << 0) #define IAX_AUTH_MD5 (1 << 1) #define IAX_AUTH_RSA (1 << 2) #define IAX_META_TRUNK 1 /* Trunk meta-message */ #define IAX_META_VIDEO 2 /* Video frame */ #define IAX_DPSTATUS_EXISTS (1 << 0) #define IAX_DPSTATUS_CANEXIST (1 << 1) #define IAX_DPSTATUS_NONEXISTANT (1 << 2) #define IAX_DPSTATUS_IGNOREPAT (1 << 14) #define IAX_DPSTATUS_MATCHMORE (1 << 15) #define AST_FORMAT_G723_1 (1 << 0) /* G.723.1 compression */ #define AST_FORMAT_GSM (1 << 1) /* GSM compression */ #define AST_FORMAT_ULAW (1 << 2) /* Raw mu-law data (G.711) */ #define AST_FORMAT_ALAW (1 << 3) /* Raw A-law data (G.711) */ #define AST_FORMAT_MP3 (1 << 4) /* MPEG-2 layer 3 */ #define AST_FORMAT_ADPCM (1 << 5) /* ADPCM (whose?) */ #define AST_FORMAT_SLINEAR (1 << 6) /* Raw 16-bit Signed Linear (8000 Hz) PCM */ #define AST_FORMAT_LPC10 (1 << 7) /* LPC10, 180 samples/frame */ #define AST_FORMAT_G729A (1 << 8) /* G.729a Audio */ /* Full frames are always delivered reliably */ struct ast_iax2_full_hdr { unsigned short scallno; /* Source call number -- high bit must be 1 */ unsigned short dcallno; /* Destination call number -- high bit is 1 if retransmission */ unsigned int ts; /* 32-bit timestamp in milliseconds (from 1st transmission) */ unsigned char oseqno; /* Packet number (outgoing) */ unsigned char iseqno; /* Packet number (next incoming expected) */ char type; /* Frame type */ unsigned char csub; /* Compressed subclass */ unsigned char iedata[0]; } __attribute__ ((__packed__)); /* Mini header is used only for voice frames -- delivered unreliably */ struct ast_iax2_mini_hdr { unsigned short callno; /* Source call number -- high bit must be 0, rest must be non-zero */ unsigned short ts; /* 16-bit Timestamp (high 16 bits from last ast_iax2_full_hdr) */ /* Frametype implicitly VOICE_FRAME */ /* subclass implicit from last ast_iax2_full_hdr */ unsigned char data[0]; } __attribute__ ((__packed__)); struct ast_iax2_meta_hdr { unsigned short zeros; /* Zeros field -- must be zero */ unsigned char metacmd; /* Meta command */ unsigned char cmddata; /* Command Data */ unsigned char data[0]; } __attribute__ ((__packed__)); struct ast_iax2_meta_trunk_hdr { unsigned int ts; /* 32-bit timestamp for all messages */ unsigned char data[0]; } __attribute__ ((__packed__)); struct ast_iax2_meta_trunk_entry { unsigned short callno; /* Call number */ unsigned short len; /* Length of data for this callno */ } __attribute__ ((__packed__)); #endif
- Prev by Date: [Ethereal-dev] Splitcap, Take 2
- Next by Date: Re: [Ethereal-dev] Build Error
- Previous by thread: [Ethereal-dev] Splitcap, Take 2
- Next by thread: [Ethereal-dev] RE: [Ethereal-users] Problems Running Ethereal on Windows 2000
- Index(es):