4 * Routines for IAX2 packet disassembly
5 * By Alastair Maw <asterisk@almaw.com>
6 * Copyright 2003 Alastair Maw
8 * IAX2 is a VoIP protocol for the open source PBX Asterisk. Please see
9 * http://www.asterisk.org for more information; see RFC 5456 for the
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * SPDX-License-Identifier: GPL-2.0-or-later
22 #include <epan/packet.h>
23 #include <epan/conversation.h>
24 #include <epan/reassemble.h>
25 #include <epan/expert.h>
26 #include <epan/aftypes.h>
28 #include <epan/proto_data.h>
30 #include <wsutil/array.h>
31 #include <wsutil/str_util.h>
33 #include "packet-iax2.h"
34 #include <epan/iax2_codec_type.h>
36 void proto_register_iax2(void);
37 void proto_reg_handoff_iax2(void);
39 #define IAX2_PORT 4569
40 #define PROTO_TAG_IAX2 "IAX2"
42 /* enough to hold any address in an address_t */
43 #define MAX_ADDRESS 16
45 /* the maximum number of transfers (of each end) we can deal with per call,
47 #define IAX_MAX_TRANSFERS 2
49 /* #define DEBUG_HASHING */
50 /* #define DEBUG_DESEGMENT */
52 /* Wireshark ID of the IAX2 protocol */
53 static int proto_iax2
;
58 /* protocol tap info */
59 static iax2_info_t ii_arr
[1];
60 static iax2_info_t
*iax2_info
= ii_arr
;
62 /* The following hf_* variables are used to hold the wireshark IDs of
63 * our header fields; they are filled out when we call
64 * proto_register_field_array() in proto_register_iax2()
66 static int hf_iax2_packet_type
;
67 static int hf_iax2_retransmission
;
68 static int hf_iax2_callno
;
69 static int hf_iax2_scallno
;
70 static int hf_iax2_dcallno
;
71 static int hf_iax2_ts
;
72 static int hf_iax2_minits
;
73 static int hf_iax2_minividts
;
74 static int hf_iax2_absts
;
75 static int hf_iax2_lateness
;
76 static int hf_iax2_minividmarker
;
77 static int hf_iax2_oseqno
;
78 static int hf_iax2_iseqno
;
79 static int hf_iax2_type
;
80 static int hf_iax2_csub
;
81 static int hf_iax2_dtmf_csub
;
82 static int hf_iax2_cmd_csub
;
83 static int hf_iax2_iax_csub
;
84 static int hf_iax2_voice_csub
;
85 static int hf_iax2_voice_codec
;
86 static int hf_iax2_video_csub
;
87 static int hf_iax2_video_codec
;
88 static int hf_iax2_marker
;
89 static int hf_iax2_modem_csub
;
90 static int hf_iax2_text_csub
;
91 static int hf_iax2_text_text
;
92 static int hf_iax2_html_csub
;
93 static int hf_iax2_html_url
;
94 static int hf_iax2_trunk_metacmd
;
95 static int hf_iax2_trunk_cmddata
;
96 static int hf_iax2_trunk_cmddata_ts
;
97 static int hf_iax2_trunk_ts
;
98 static int hf_iax2_trunk_ncalls
;
99 static int hf_iax2_trunk_call_len
;
100 static int hf_iax2_trunk_call_scallno
;
101 static int hf_iax2_trunk_call_ts
;
102 static int hf_iax2_trunk_call_data
;
104 static int hf_iax2_ie_id
;
105 static int hf_iax2_length
;
106 static int hf_iax2_version
;
107 static int hf_iax2_cap_g723_1
;
108 static int hf_iax2_cap_gsm
;
109 static int hf_iax2_cap_ulaw
;
110 static int hf_iax2_cap_alaw
;
111 static int hf_iax2_cap_g726_aal2
;
112 static int hf_iax2_cap_adpcm
;
113 static int hf_iax2_cap_slinear
;
114 static int hf_iax2_cap_lpc10
;
115 static int hf_iax2_cap_g729a
;
116 static int hf_iax2_cap_speex
;
117 static int hf_iax2_cap_ilbc
;
118 static int hf_iax2_cap_g726
;
119 static int hf_iax2_cap_g722
;
120 static int hf_iax2_cap_siren7
;
121 static int hf_iax2_cap_siren14
;
122 static int hf_iax2_cap_slinear16
;
123 static int hf_iax2_cap_jpeg
;
124 static int hf_iax2_cap_png
;
125 static int hf_iax2_cap_h261
;
126 static int hf_iax2_cap_h263
;
127 static int hf_iax2_cap_h263_plus
;
128 static int hf_iax2_cap_h264
;
129 static int hf_iax2_cap_mpeg4
;
130 static int hf_iax2_cap_vp8
;
131 static int hf_iax2_cap_t140_red
;
132 static int hf_iax2_cap_t140
;
133 static int hf_iax2_cap_g719
;
134 static int hf_iax2_cap_speex16
;
135 static int hf_iax2_cap_opus
;
136 static int hf_iax2_cap_testlaw
;
138 static int * const hf_iax2_caps
[] = {
143 &hf_iax2_cap_g726_aal2
,
145 &hf_iax2_cap_slinear
,
153 &hf_iax2_cap_siren14
,
154 &hf_iax2_cap_slinear16
,
159 &hf_iax2_cap_h263_plus
,
163 &hf_iax2_cap_t140_red
,
166 &hf_iax2_cap_speex16
,
168 &hf_iax2_cap_testlaw
,
172 static int hf_iax2_fragment_unfinished
;
173 static int hf_iax2_payload_data
;
174 static int hf_iax2_fragments
;
175 static int hf_iax2_fragment
;
176 static int hf_iax2_fragment_overlap
;
177 static int hf_iax2_fragment_overlap_conflict
;
178 static int hf_iax2_fragment_multiple_tails
;
179 static int hf_iax2_fragment_too_long_fragment
;
180 static int hf_iax2_fragment_error
;
181 static int hf_iax2_fragment_count
;
182 static int hf_iax2_reassembled_in
;
183 static int hf_iax2_reassembled_length
;
186 /* hf_iax2_ies is an array of header fields, one per potential Information
187 * Element. It's done this way (rather than having separate variables for each
188 * IE) to make the dissection of information elements clearer and more
191 * To add the ability to dissect a new information element, just add an
192 * appropriate entry to hf[] in proto_register_iax2(); dissect_ies() will then
193 * pick it up automatically.
195 #define NUM_HF_IAX2_IES 256
196 static int hf_iax2_ies
[NUM_HF_IAX2_IES
];
197 static int hf_iax2_ie_datetime
;
198 static int hf_IAX_IE_APPARENTADDR_SINFAMILY
;
199 static int hf_IAX_IE_APPARENTADDR_SINPORT
;
200 static int hf_IAX_IE_APPARENTADDR_SINADDR
;
201 static int hf_IAX_IE_UNKNOWN_BYTE
;
202 static int hf_IAX_IE_UNKNOWN_I16
;
203 static int hf_IAX_IE_UNKNOWN_I32
;
204 static int hf_IAX_IE_UNKNOWN_BYTES
;
206 /* These are the ids of the subtrees that we may be creating */
208 static int ett_iax2_full_mini_subtree
;
209 static int ett_iax2_type
; /* Frame-type specific subtree */
210 static int ett_iax2_ie
; /* single IE */
211 static int ett_iax2_codecs
; /* capabilities IE */
212 static int ett_iax2_ies_apparent_addr
; /* apparent address IE */
213 static int ett_iax2_fragment
;
214 static int ett_iax2_fragments
;
215 static int ett_iax2_trunk_cmddata
;
216 static int ett_iax2_trunk_call
;
218 static expert_field ei_iax_too_many_transfers
;
219 static expert_field ei_iax_circuit_id_conflict
;
220 static expert_field ei_iax_peer_address_unsupported
;
221 static expert_field ei_iax_invalid_len
;
223 static dissector_handle_t iax2_handle
;
225 static const fragment_items iax2_fragment_items
= {
230 &hf_iax2_fragment_overlap
,
231 &hf_iax2_fragment_overlap_conflict
,
232 &hf_iax2_fragment_multiple_tails
,
233 &hf_iax2_fragment_too_long_fragment
,
234 &hf_iax2_fragment_error
,
235 &hf_iax2_fragment_count
,
236 &hf_iax2_reassembled_in
,
237 &hf_iax2_reassembled_length
,
238 /* Reassembled data field */
243 /* data-call subdissectors, AST_DATAFORMAT_* */
244 static dissector_table_t iax2_dataformat_dissector_table
;
245 /* voice/video call subdissectors, AST_FORMAT_* */
246 static dissector_table_t iax2_codec_dissector_table
;
249 /* IAX2 Meta trunk packet Command data flags */
250 #define IAX2_TRUNK_TS 1
252 /* IAX2 Full-frame types */
253 static const value_string iax_frame_types
[] = {
255 {AST_FRAME_DTMF_END
, "DTMF End"},
256 {AST_FRAME_VOICE
, "Voice"},
257 {AST_FRAME_VIDEO
, "Video"},
258 {AST_FRAME_CONTROL
, "Control"},
259 {AST_FRAME_NULL
, "NULL"},
260 {AST_FRAME_IAX
, "IAX"},
261 {AST_FRAME_TEXT
, "Text"},
262 {AST_FRAME_IMAGE
, "Image"},
263 {AST_FRAME_HTML
, "HTML"},
264 {AST_FRAME_CNG
, "Comfort Noise"},
265 {AST_FRAME_MODEM
, "Modem"},
266 {AST_FRAME_DTMF_BEGIN
, "DTMF Begin"},
269 static value_string_ext iax_frame_types_ext
= VALUE_STRING_EXT_INIT(iax_frame_types
);
271 /* Subclasses for IAX packets */
272 static const value_string iax_iax_subclasses
[] = {
316 static value_string_ext iax_iax_subclasses_ext
= VALUE_STRING_EXT_INIT(iax_iax_subclasses
);
318 /* Subclasses for Control packets */
319 static const value_string iax_cmd_subclasses
[] = {
328 {0xFF, "stop sounds"}, /* sent by app_dial, and not much else */
331 static value_string_ext iax_cmd_subclasses_ext
= VALUE_STRING_EXT_INIT(iax_cmd_subclasses
);
333 /* IAX2 to tap-voip call state mapping for command frames */
334 static const voip_call_state tap_cmd_voip_state
[] = {
336 VOIP_COMPLETED
, /*HANGUP*/
337 VOIP_RINGING
, /*RING*/
338 VOIP_RINGING
, /*RINGING*/
339 VOIP_IN_CALL
, /*ANSWER*/
340 VOIP_REJECTED
, /*BUSY*/
341 VOIP_UNKNOWN
, /*TKOFFHK*/
342 VOIP_UNKNOWN
/*OFFHOOK*/
344 #define NUM_TAP_CMD_VOIP_STATES array_length(tap_cmd_voip_state)
346 /* IAX2 to tap-voip call state mapping for IAX frames */
347 static const voip_call_state tap_iax_voip_state
[] = {
349 VOIP_CALL_SETUP
, /*NEW*/
352 VOIP_COMPLETED
, /*HANGUP*/
353 VOIP_REJECTED
, /*REJECT*/
354 VOIP_RINGING
, /*ACCEPT*/
369 VOIP_CALL_SETUP
, /*DIAL*/
388 #define NUM_TAP_IAX_VOIP_STATES array_length(tap_iax_voip_state)
390 /* Subclasses for Modem packets */
391 static const value_string iax_modem_subclasses
[] = {
398 /* Subclasses for Text packets */
399 static const value_string iax_text_subclasses
[] = {
404 /* Subclasses for HTML packets */
405 static const value_string iax_html_subclasses
[] = {
406 {0x01, "Sending a URL"},
407 {0x02, "Data frame"},
408 {0x04, "Beginning frame"},
410 {0x10, "Load is complete"},
411 {0x11, "Peer does not support HTML"},
413 {0x13, "Unlink URL"},
414 {0x14, "Reject Link URL"},
419 /* Information elements */
420 static const value_string iax_ies_type
[] = {
421 {IAX_IE_CALLED_NUMBER
, "Number/extension being called"},
422 {IAX_IE_CALLING_NUMBER
, "Calling number"},
423 {IAX_IE_CALLING_ANI
, "Calling number ANI for billing"},
424 {IAX_IE_CALLING_NAME
, "Name of caller"},
425 {IAX_IE_CALLED_CONTEXT
, "Context for number"},
426 {IAX_IE_USERNAME
, "Username (peer or user) for authentication"},
427 {IAX_IE_PASSWORD
, "Password for authentication"},
428 {IAX_IE_CAPABILITY
, "Actual codec capability"},
429 {IAX_IE_FORMAT
, "Desired codec format"},
430 {IAX_IE_LANGUAGE
, "Desired language"},
431 {IAX_IE_VERSION
, "Protocol version"},
432 {IAX_IE_ADSICPE
, "CPE ADSI capability"},
433 {IAX_IE_DNID
, "Originally dialed DNID"},
434 {IAX_IE_AUTHMETHODS
, "Authentication method(s)"},
435 {IAX_IE_CHALLENGE
, "Challenge data for MD5/RSA"},
436 {IAX_IE_MD5_RESULT
, "MD5 challenge result"},
437 {IAX_IE_RSA_RESULT
, "RSA challenge result"},
438 {IAX_IE_APPARENT_ADDR
, "Apparent address of peer"},
439 {IAX_IE_REFRESH
, "When to refresh registration"},
440 {IAX_IE_DPSTATUS
, "Dialplan status"},
441 {IAX_IE_CALLNO
, "Call number of peer"},
442 {IAX_IE_CAUSE
, "Cause"},
443 {IAX_IE_IAX_UNKNOWN
, "Unknown IAX command"},
444 {IAX_IE_MSGCOUNT
, "How many messages waiting"},
445 {IAX_IE_AUTOANSWER
, "Request auto-answering"},
446 {IAX_IE_MUSICONHOLD
, "Request musiconhold with QUELCH"},
447 {IAX_IE_TRANSFERID
, "Transfer Request Identifier"},
448 {IAX_IE_RDNIS
, "Referring DNIS"},
449 {IAX_IE_PROVISIONING
, "Provisioning info"},
450 {IAX_IE_AESPROVISIONING
, "AES Provisioning info"},
451 {IAX_IE_DATETIME
, "Date/Time"},
452 {IAX_IE_DEVICETYPE
, "Device type"},
453 {IAX_IE_SERVICEIDENT
, "Service Identifier"},
454 {IAX_IE_FIRMWAREVER
, "Firmware revision"},
455 {IAX_IE_FWBLOCKDESC
, "Firmware block description"},
456 {IAX_IE_FWBLOCKDATA
, "Firmware block of data"},
457 {IAX_IE_PROVVER
, "Provisioning version"},
458 {IAX_IE_CALLINGPRES
, "Calling presentation"},
459 {IAX_IE_CALLINGTON
, "Calling type of number"},
460 {IAX_IE_CALLINGTNS
, "Calling transit network select"},
461 {IAX_IE_SAMPLINGRATE
, "Supported sampling rates"},
462 {IAX_IE_CAUSECODE
, "Hangup cause"},
463 {IAX_IE_ENCRYPTION
, "Encryption format"},
464 {IAX_IE_ENCKEY
, "Raw encryption key"},
465 {IAX_IE_CODEC_PREFS
, "Codec preferences"},
466 {IAX_IE_RR_JITTER
, "Received jitter"},
467 {IAX_IE_RR_LOSS
, "Received loss"},
468 {IAX_IE_RR_PKTS
, "Received frames"},
469 {IAX_IE_RR_DELAY
, "Max playout delay in ms for received frames"},
470 {IAX_IE_RR_DROPPED
, "Dropped frames"},
471 {IAX_IE_RR_OOO
, "Frames received out of order"},
472 {IAX_IE_VARIABLE
, "IAX2 variable"},
473 {IAX_IE_OSPTOKEN
, "OSP Token"},
474 {IAX_IE_CALLTOKEN
, "Call Token"},
475 {IAX_IE_CAPABILITY2
, "64-bit codec capability"},
476 {IAX_IE_FORMAT2
, "64-bit codec format"},
477 {IAX_IE_DATAFORMAT
, "Data call format"},
480 static value_string_ext iax_ies_type_ext
= VALUE_STRING_EXT_INIT(iax_ies_type
);
482 #define CODEC_MASK(codec) ((codec) == (uint32_t)-1 ? 0 : (UINT64_C(1) << (codec)))
484 static const val64_string codec_types
[] = {
485 {CODEC_MASK(AST_FORMAT_G723_1
), "G.723.1 compression"},
486 {CODEC_MASK(AST_FORMAT_GSM
), "GSM compression"},
487 {CODEC_MASK(AST_FORMAT_ULAW
), "Raw mu-law data (G.711)"},
488 {CODEC_MASK(AST_FORMAT_ALAW
), "Raw A-law data (G.711)"},
489 {CODEC_MASK(AST_FORMAT_G726_AAL2
), "ADPCM (G.726), 32kbps, AAL2 codeword packing)"},
490 {CODEC_MASK(AST_FORMAT_ADPCM
), "ADPCM (IMA)"},
491 {CODEC_MASK(AST_FORMAT_SLINEAR
), "Raw 16-bit Signed Linear (8000 Hz) PCM"},
492 {CODEC_MASK(AST_FORMAT_LPC10
), "LPC10, 180 samples/frame"},
493 {CODEC_MASK(AST_FORMAT_G729A
), "G.729a Audio"},
494 {CODEC_MASK(AST_FORMAT_SPEEX
), "SpeeX Free Compression"},
495 {CODEC_MASK(AST_FORMAT_ILBC
), "iLBC Free Compression"},
496 {CODEC_MASK(AST_FORMAT_G726
), "ADPCM (G.726, 32kbps, RFC3551 codeword packing)"},
497 {CODEC_MASK(AST_FORMAT_G722
), "G.722"},
498 {CODEC_MASK(AST_FORMAT_SIREN7
), "G.722.1 (also known as Siren7, 32kbps assumed)"},
499 {CODEC_MASK(AST_FORMAT_SIREN14
), "G.722.1 Annex C (also known as Siren14, 48kbps assumed)"},
500 {CODEC_MASK(AST_FORMAT_SLINEAR16
), "Raw 16-bit Signed Linear (16000 Hz) PCM"},
501 {CODEC_MASK(AST_FORMAT_JPEG
), "JPEG Images"},
502 {CODEC_MASK(AST_FORMAT_PNG
), "PNG Images"},
503 {CODEC_MASK(AST_FORMAT_H261
), "H.261 Video"},
504 {CODEC_MASK(AST_FORMAT_H263
), "H.263 Video"},
505 {CODEC_MASK(AST_FORMAT_H263_PLUS
), "H.263+ Video"},
506 {CODEC_MASK(AST_FORMAT_H264
), "H.264 Video"},
507 {CODEC_MASK(AST_FORMAT_MP4_VIDEO
), "MPEG4 Video"},
508 {CODEC_MASK(AST_FORMAT_VP8
), "VP8 Video"},
509 {CODEC_MASK(AST_FORMAT_T140_RED
), "T.140 RED Text format RFC 4103"},
510 {CODEC_MASK(AST_FORMAT_T140
), "T.140 Text format - ITU T.140, RFC 4103"},
511 {CODEC_MASK(AST_FORMAT_G719
), "G.719 (64 kbps assumed)"},
512 {CODEC_MASK(AST_FORMAT_SPEEX16
), "SpeeX Wideband (16kHz) Free Compression"},
513 {CODEC_MASK(AST_FORMAT_OPUS
), "Opus audio (8kHz, 16kHz, 24kHz, 48Khz)"},
514 {CODEC_MASK(AST_FORMAT_TESTLAW
), "Raw testing-law data (G.711)"},
517 static val64_string_ext codec_types_ext
= VAL64_STRING_EXT_INIT(codec_types
);
519 static const value_string iax_dataformats
[] = {
520 {AST_DATAFORMAT_NULL
, "N/A (analogue call?)"},
521 {AST_DATAFORMAT_V110
, "ITU-T V.110 rate adaption"},
522 {AST_DATAFORMAT_H223_H245
, "ITU-T H.223/H.245"},
527 static const value_string iax_packet_types
[] = {
528 {IAX2_FULL_PACKET
, "Full packet"},
529 {IAX2_MINI_VOICE_PACKET
, "Mini voice packet"},
530 {IAX2_MINI_VIDEO_PACKET
, "Mini video packet"},
531 {IAX2_TRUNK_PACKET
, "Trunk packet"},
535 static const value_string iax_causecodes
[] = {
536 {AST_CAUSE_UNALLOCATED
, "Unallocated"},
537 {AST_CAUSE_NO_ROUTE_TRANSIT_NET
, "No route transit net"},
538 {AST_CAUSE_NO_ROUTE_DESTINATION
, "No route to destination"},
539 {AST_CAUSE_MISDIALLED_TRUNK_PREFIX
, "Misdialled trunk prefix"},
540 {AST_CAUSE_CHANNEL_UNACCEPTABLE
, "Channel unacceptable"},
541 {AST_CAUSE_CALL_AWARDED_DELIVERED
, "Call awarded delivered"},
542 {AST_CAUSE_PRE_EMPTED
, "Preempted"},
543 {AST_CAUSE_NUMBER_PORTED_NOT_HERE
, "Number ported not here"},
544 {AST_CAUSE_NORMAL_CLEARING
, "Normal clearing"},
545 {AST_CAUSE_USER_BUSY
, "User busy"},
546 {AST_CAUSE_NO_USER_RESPONSE
, "No user response"},
547 {AST_CAUSE_NO_ANSWER
, "No answer"},
548 {AST_CAUSE_SUBSCRIBER_ABSENT
, "Subscriber absent"},
549 {AST_CAUSE_CALL_REJECTED
, "Call rejected"},
550 {AST_CAUSE_NUMBER_CHANGED
, "Number changed"},
551 {AST_CAUSE_REDIRECTED_TO_NEW_DESTINATION
, "Redirected to new destination"},
552 {AST_CAUSE_ANSWERED_ELSEWHERE
, "Answered elsewhere"},
553 {AST_CAUSE_DESTINATION_OUT_OF_ORDER
, "Destination out of order"},
554 {AST_CAUSE_INVALID_NUMBER_FORMAT
, "Invalid number format"},
555 {AST_CAUSE_FACILITY_REJECTED
, "Facility rejected"},
556 {AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY
, "Response to status inquiry"},
557 {AST_CAUSE_NORMAL_UNSPECIFIED
, "Normal unspecified"},
558 {AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
, "Normal circuit congestion"},
559 {AST_CAUSE_NETWORK_OUT_OF_ORDER
, "Network out of order"},
560 {AST_CAUSE_NORMAL_TEMPORARY_FAILURE
, "Normal temporary failure"},
561 {AST_CAUSE_SWITCH_CONGESTION
, "Switch congestion"},
562 {AST_CAUSE_ACCESS_INFO_DISCARDED
, "Access info discarded"},
563 {AST_CAUSE_REQUESTED_CHAN_UNAVAIL
, "Requested channel unavailable"},
564 {AST_CAUSE_FACILITY_NOT_SUBSCRIBED
, "Facility not subscribed"},
565 {AST_CAUSE_OUTGOING_CALL_BARRED
, "Outgoing call barred"},
566 {AST_CAUSE_INCOMING_CALL_BARRED
, "Incoming call barred"},
567 {AST_CAUSE_BEARERCAPABILITY_NOTAUTH
, "Bearer capability not authorized"},
568 {AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
, "Bearer capability not available"},
569 {AST_CAUSE_BEARERCAPABILITY_NOTIMPL
, "Bearer capability not implemented"},
570 {AST_CAUSE_CHAN_NOT_IMPLEMENTED
, "Channel not implemented"},
571 {AST_CAUSE_FACILITY_NOT_IMPLEMENTED
, "Facility not implemented"},
572 {AST_CAUSE_INVALID_CALL_REFERENCE
, "Invalid call reference"},
573 {AST_CAUSE_INCOMPATIBLE_DESTINATION
, "Incompatible destination"},
574 {AST_CAUSE_INVALID_MSG_UNSPECIFIED
, "Invalid message unspecified"},
575 {AST_CAUSE_MANDATORY_IE_MISSING
, "Mandatory IE missing"},
576 {AST_CAUSE_MESSAGE_TYPE_NONEXIST
, "Message type nonexistent"},
577 {AST_CAUSE_WRONG_MESSAGE
, "Wrong message"},
578 {AST_CAUSE_IE_NONEXIST
, "IE nonexistent"},
579 {AST_CAUSE_INVALID_IE_CONTENTS
, "Invalid IE contents"},
580 {AST_CAUSE_WRONG_CALL_STATE
, "Wrong call state"},
581 {AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE
, "Recovery on timer expire"},
582 {AST_CAUSE_MANDATORY_IE_LENGTH_ERROR
, "Mandatory IE length error"},
583 {AST_CAUSE_PROTOCOL_ERROR
, "Protocol error"},
584 {AST_CAUSE_INTERWORKING
, "Interworking"},
587 static value_string_ext iax_causecodes_ext
= VALUE_STRING_EXT_INIT(iax_causecodes
);
589 /* ************************************************************************* */
591 /* In order to track IAX calls, we have a hash table which maps
592 * {addr,port type,port,call} to a unique circuit id.
594 * Each call has two such circuits associated with it (a forward and a
595 * reverse circuit, where 'forward' is defined as the direction the NEW
596 * packet went in), and we maintain an iax_call_data structure for each
597 * call, attached to both circuits with circuit_add_proto_data.
599 * Because {addr,port type,port,call} quadruplets can be reused
600 * (Asterisk reuses call numbers), circuit ids aren't unique to
601 * individual calls and we treat NEW packets somewhat specially. When we
602 * get such a packet, we see if there are any calls with a matching
603 * circuit id, and make sure that its circuits are marked as ended
604 * before that packet.
606 * A second complication is that we only know one quadruplet at the time
607 * the NEW packet is processed: there is therefore cunningness in
608 * iax_lookup_circuit_details() to look for replies to NEW packets and
609 * create the reverse circuit.
613 /* start with a hash of {addr,port type,port,call}->{id} */
621 /* this is where addr->data points to. it's put in here for easy freeing */
622 uint8_t address_data
[MAX_ADDRESS
];
626 static GHashTable
*iax_fid_table
;
627 static reassembly_table iax_reassembly_table
;
629 static GHashTable
*iax_circuit_hashtab
;
630 static unsigned circuitcount
;
632 /* the number of keys and values to reserve space for in each memory chunk.
633 We assume we won't be tracking many calls at once so this is quite low.
635 #define IAX_INIT_PACKET_COUNT 10
638 static char *key_to_str( const iax_circuit_key
*key
)
641 static char str
[3][80];
651 addrstr
= address_to_str(NULL
, &key
->addr
);
652 snprintf(strp
, 80, "{%s:%i,%i}",
656 wmem_free(NULL
, addrstr
);
662 static int iax_circuit_equal(const void *v
, const void *w
)
664 const iax_circuit_key
*v1
= (const iax_circuit_key
*)v
;
665 const iax_circuit_key
*v2
= (const iax_circuit_key
*)w
;
668 result
= (addresses_equal(&(v1
->addr
), &(v2
->addr
)) &&
669 v1
->ptype
== v2
->ptype
&&
670 v1
->port
== v2
->port
&&
671 v1
->callno
== v2
->callno
);
673 ws_debug("+++ Comparing for equality: %s, %s: %u", key_to_str(v1
), key_to_str(v2
), result
);
679 static unsigned iax_circuit_hash(const void *v
)
681 const iax_circuit_key
*key
= (const iax_circuit_key
*)v
;
685 hash_val
= add_address_to_hash(hash_val
, &key
->addr
);
686 hash_val
+= (unsigned)(key
->ptype
);
687 hash_val
+= (unsigned)(key
->port
);
688 hash_val
+= (unsigned)(key
->callno
);
691 ws_debug("+++ Hashing key: %s, result %#x", key_to_str(key
), hash_val
);
694 return (unsigned)hash_val
;
697 /* Find, or create, a circuit for the given
698 {address,porttype,port,call} quadruplet
700 static unsigned iax_circuit_lookup(const address
*address_p
,
706 uint32_t *circuit_id_p
;
708 key
.addr
= *address_p
;
713 circuit_id_p
= (uint32_t *)g_hash_table_lookup(iax_circuit_hashtab
, &key
);
714 if (! circuit_id_p
) {
715 iax_circuit_key
*new_key
;
717 new_key
= wmem_new(wmem_file_scope(), iax_circuit_key
);
718 new_key
->addr
.type
= address_p
->type
;
719 new_key
->addr
.len
= MIN(address_p
->len
, MAX_ADDRESS
);
720 new_key
->addr
.data
= new_key
->address_data
;
721 if (new_key
->addr
.len
> 0)
722 memcpy(new_key
->address_data
, address_p
->data
, new_key
->addr
.len
);
723 new_key
->ptype
= ptype
;
724 new_key
->port
= port
;
725 new_key
->callno
= callno
;
727 circuit_id_p
= (uint32_t *)wmem_new(wmem_file_scope(), iax_circuit_key
);
728 *circuit_id_p
= ++circuitcount
;
730 g_hash_table_insert(iax_circuit_hashtab
, new_key
, circuit_id_p
);
733 ws_debug("Created new circuit id %u for node %s", *circuit_id_p
, key_to_str(new_key
));
737 return *circuit_id_p
;
741 /* ************************************************************************* */
744 uint32_t current_frag_id
; /* invalid unless current_frag_bytes > 0 */
745 uint32_t current_frag_bytes
;
746 uint32_t current_frag_minlen
;
749 /* This is our per-call data structure, which is attached to both the
750 * forward and reverse circuits.
752 typedef struct iax_call_data
{
753 /* For this data, src and dst are relative to the original direction under
754 which this call is stored. Obviously if the reversed flag is set true by
755 iax_find_call, src and dst are reversed relative to the direction the
756 actual source and destination of the data.
758 if the codec changes mid-call, we update it here; because we store a codec
759 number with each packet too, we handle going back to earlier packets
763 iax_dataformat_t dataformat
;
764 uint32_t src_codec
, dst_codec
;
765 uint32_t src_vformat
, dst_vformat
;
767 /* when a transfer takes place, we'll get a new circuit id; we assume that we
768 don't try to transfer more than IAX_MAX_TRANSFERS times in a call */
769 unsigned forward_circuit_ids
[IAX_MAX_TRANSFERS
];
770 unsigned reverse_circuit_ids
[IAX_MAX_TRANSFERS
];
771 unsigned n_forward_circuit_ids
;
772 unsigned n_reverse_circuit_ids
;
774 /* this is the subdissector for the call */
775 dissector_handle_t subdissector
;
777 /* the absolute start time of the call */
780 /* time stamp from last full frame, in the first pass */
781 uint32_t last_full_frame_ts
;
783 iax_call_dirdata dirdata
[2];
788 /* creates a new CONVERSATION_IAX2 circuit with a specified circuit id for a call
790 * typically a call has up to three associated circuits: an original source, an
791 * original destination, and the result of a transfer.
793 * For each endpoint, a CONVERSATION_IAX2 circuit is created and added to the call_data
796 * 'reversed' should be true if this end is the one which would have _received_
797 * the NEW packet, or it is an endpoint to which the 'destination' is being
801 static conversation_t
*iax2_new_circuit_for_call(packet_info
*pinfo
, proto_item
* item
,
802 unsigned circuit_id
, unsigned framenum
,
803 iax_call_data
*iax_call
, bool reversed
)
805 conversation_t
*conv
;
810 if ((reversed
&& iax_call
->n_reverse_circuit_ids
>= IAX_MAX_TRANSFERS
) ||
811 (! reversed
&& iax_call
->n_forward_circuit_ids
>= IAX_MAX_TRANSFERS
)) {
812 expert_add_info(pinfo
, item
, &ei_iax_too_many_transfers
);
816 conv
= conversation_new_by_id(framenum
, CONVERSATION_IAX2
,
819 conversation_add_proto_data(conv
, proto_iax2
, iax_call
);
822 iax_call
-> reverse_circuit_ids
[iax_call
->n_reverse_circuit_ids
++] = circuit_id
;
824 iax_call
-> forward_circuit_ids
[iax_call
->n_forward_circuit_ids
++] = circuit_id
;
830 /* returns true if this circuit id is a "forward" circuit for this call: ie, it
831 * is the point which _sent_ the original 'NEW' packet, or a point to which that
832 * end was subsequently transferred */
833 static bool is_forward_circuit(unsigned circuit_id
,
834 const iax_call_data
*iax_call
)
837 for(i
=0; i
<iax_call
->n_forward_circuit_ids
; i
++) {
838 if (circuit_id
== iax_call
->forward_circuit_ids
[i
])
844 /* returns true if this circuit id is a "reverse" circuit for this call: ie, it
845 * is the point which _received_ the original 'NEW' packet, or a point to which that
846 * end was subsequently transferred */
847 static bool is_reverse_circuit(unsigned circuit_id
,
848 const iax_call_data
*iax_call
)
851 for(i
=0; i
<iax_call
->n_reverse_circuit_ids
; i
++){
852 if (circuit_id
== iax_call
->reverse_circuit_ids
[i
])
859 static iax_call_data
*iax_lookup_call_from_dest(packet_info
*pinfo
, proto_item
* item
,
860 unsigned src_circuit_id
,
861 unsigned dst_circuit_id
,
865 conversation_t
*dst_conv
;
866 iax_call_data
*iax_call
;
867 bool reversed
= false;
869 dst_conv
= find_conversation_by_id(framenum
, CONVERSATION_IAX2
, dst_circuit_id
);
873 ws_debug("++ destination circuit not found, must have missed NEW packet");
881 ws_debug("++ found destination circuit");
884 iax_call
= (iax_call_data
*)conversation_get_proto_data(dst_conv
, proto_iax2
);
886 /* there's no way we can create a CONVERSATION_IAX2 circuit without adding
887 iax call data to it; assert this */
888 DISSECTOR_ASSERT(iax_call
);
890 if (is_forward_circuit(dst_circuit_id
, iax_call
)) {
892 ws_debug("++ destination circuit matches forward_circuit_id of call, "
893 "therefore packet is reversed");
898 if (iax_call
-> n_reverse_circuit_ids
== 0) {
899 /* we are going in the reverse direction, and this call
900 doesn't have a reverse circuit associated with it.
903 ws_debug("++ reverse_circuit_id of call is zero, need to create a "
904 "new reverse circuit for this call");
907 iax2_new_circuit_for_call(pinfo
, item
, src_circuit_id
, framenum
, iax_call
, true);
911 } else if (!is_reverse_circuit(src_circuit_id
, iax_call
)) {
912 expert_add_info_format(pinfo
, item
, &ei_iax_circuit_id_conflict
,
913 "IAX Packet %u from circuit ids %u->%u conflicts with earlier call with circuit ids %u->%u",
915 src_circuit_id
, dst_circuit_id
,
916 iax_call
->forward_circuit_ids
[0],
917 iax_call
->reverse_circuit_ids
[0]);
920 } else if (is_reverse_circuit(dst_circuit_id
, iax_call
)) {
922 ws_debug("++ destination circuit matches reverse_circuit_id of call, "
923 "therefore packet is forward");
927 if (!is_forward_circuit(src_circuit_id
, iax_call
)) {
928 expert_add_info_format(pinfo
, item
, &ei_iax_circuit_id_conflict
,
929 "IAX Packet %u from circuit ids %u->%u conflicts with earlier call with circuit ids %u->%u",
931 src_circuit_id
, dst_circuit_id
,
932 iax_call
->forward_circuit_ids
[0],
933 iax_call
->reverse_circuit_ids
[0]);
939 DISSECTOR_ASSERT_NOT_REACHED();
943 *reversed_p
= reversed
;
949 /* looks up an iax_call for this packet */
950 static iax_call_data
*iax_lookup_call( packet_info
*pinfo
,
955 bool reversed
= false;
956 iax_call_data
*iax_call
= NULL
;
957 unsigned src_circuit_id
;
959 char *srcstr
, *dststr
;
963 srcstr
= address_to_str(NULL
, &pinfo
->src
);
964 dststr
= address_to_str(NULL
, &pinfo
->dst
);
965 ws_debug("++ iax_lookup_circuit_details: Looking up circuit for frame %u, "
966 "from {%s:%u:%u} to {%s:%u:%u}", pinfo
->num
,
967 srcstr
, pinfo
->srcport
, scallno
,
968 dststr
, pinfo
->destport
, dcallno
);
969 wmem_free(NULL
, srcstr
);
970 wmem_free(NULL
, dststr
);
974 src_circuit_id
= iax_circuit_lookup(&pinfo
->src
, pinfo
->ptype
,
975 pinfo
->srcport
, scallno
);
978 /* the most reliable indicator of call is the destination callno, if
981 unsigned dst_circuit_id
;
983 ws_debug("++ dcallno non-zero, looking up destination circuit");
986 dst_circuit_id
= iax_circuit_lookup(&pinfo
->dst
, pinfo
->ptype
,
987 pinfo
->destport
, dcallno
);
989 iax_call
= iax_lookup_call_from_dest(pinfo
, NULL
, src_circuit_id
, dst_circuit_id
,
990 pinfo
->num
, &reversed
);
992 conversation_t
*src_conv
;
994 /* in all other circumstances, the source circuit should already
995 * exist: its absence indicates that we missed the all-important NEW
999 src_conv
= find_conversation_by_id(pinfo
->num
, CONVERSATION_IAX2
, src_circuit_id
);
1002 iax_call
= (iax_call_data
*)conversation_get_proto_data(src_conv
, proto_iax2
);
1004 /* there's no way we can create a CONVERSATION_IAX2 circuit without adding
1005 iax call data to it; assert this */
1006 DISSECTOR_ASSERT(iax_call
);
1008 if (is_forward_circuit(src_circuit_id
, iax_call
))
1010 else if (is_reverse_circuit(src_circuit_id
, iax_call
))
1013 /* there's also no way we can attach an iax_call_data to a circuit
1014 without the circuit being either the forward or reverse circuit
1015 for that call; assert this too.
1017 DISSECTOR_ASSERT_NOT_REACHED();
1023 *reversed_p
= reversed
;
1025 #ifdef DEBUG_HASHING
1027 ws_debug("++ Found call for packet: id %u, reversed=%c", iax_call
->forward_circuit_ids
[0], reversed
?'1':'0');
1029 ws_debug("++ Call not found. Must have missed the NEW packet?");
1036 /* initialize the per-direction parts of an iax_call_data structure */
1037 static void init_dir_data(iax_call_dirdata
*dirdata
)
1039 dirdata
-> current_frag_bytes
=0;
1040 dirdata
-> current_frag_minlen
=0;
1044 /* handles a NEW packet by creating a new iax call and forward circuit.
1045 the reverse circuit is not created until the ACK is received and
1046 is created by iax_lookup_circuit_details. */
1047 static iax_call_data
*iax_new_call( packet_info
*pinfo
,
1050 iax_call_data
*call
;
1051 unsigned circuit_id
;
1052 static const nstime_t millisecond
= NSTIME_INIT_SECS_MSECS(0, 1);
1054 #ifdef DEBUG_HASHING
1055 ws_debug("+ new_circuit: Handling NEW packet, frame %u", pinfo
->num
);
1058 circuit_id
= iax_circuit_lookup(&pinfo
->src
, pinfo
->ptype
,
1059 pinfo
->srcport
, scallno
);
1061 call
= wmem_new(wmem_file_scope(), iax_call_data
);
1062 call
-> dataformat
= AST_DATAFORMAT_NULL
;
1063 call
-> src_codec
= 0;
1064 call
-> dst_codec
= 0;
1065 call
-> src_vformat
= 0;
1066 call
-> dst_vformat
= 0;
1067 call
-> n_forward_circuit_ids
= 0;
1068 call
-> n_reverse_circuit_ids
= 0;
1069 call
-> subdissector
= NULL
;
1070 call
-> start_time
= pinfo
->abs_ts
;
1071 call
-> last_full_frame_ts
= 0;
1072 nstime_delta(&call
-> start_time
, &call
-> start_time
, &millisecond
);
1073 init_dir_data(&call
->dirdata
[0]);
1074 init_dir_data(&call
->dirdata
[1]);
1076 iax2_new_circuit_for_call(pinfo
, NULL
, circuit_id
, pinfo
->num
, call
, false);
1082 /* ************************************************************************* */
1084 /* per-packet data */
1085 typedef struct iax_packet_data
{
1086 bool first_time
; /* we're dissecting this packet for the first time; so
1087 * things like codec and transfer requests should be
1088 * propagated into the call data */
1089 iax_call_data
*call_data
;
1092 nstime_t abstime
; /* the absolute time of this packet, based on its
1093 * timestamp and the NEW packet's time (-1 if unknown) */
1096 static iax_packet_data
*iax_new_packet_data(iax_call_data
*call
, bool reversed
)
1098 iax_packet_data
*p
= wmem_new(wmem_file_scope(), iax_packet_data
);
1099 p
->first_time
= true;
1100 p
->call_data
= call
;
1102 p
->reversed
= reversed
;
1103 p
->abstime
.secs
= -1;
1104 p
->abstime
.nsecs
= -1;
1108 static void iax2_populate_pinfo_from_packet_data(packet_info
*pinfo
, const iax_packet_data
*p
)
1110 if (p
->call_data
!= NULL
) {
1111 /* if we missed the NEW packet for this call, call_data will be null. it's
1112 * tbd what the best thing to do here is. */
1113 pinfo
->p2p_dir
= p
->reversed
?P2P_DIR_RECV
:P2P_DIR_SENT
;
1115 col_set_str(pinfo
->cinfo
, COL_IF_DIR
, p
->reversed
? "rev" : "fwd");
1120 /* ************************************************************************* */
1122 /* this is passed up from the IE dissector to the main dissector */
1125 address peer_address
;
1126 port_type peer_ptype
;
1128 uint32_t peer_callno
;
1129 uint32_t dataformat
;
1133 static uint32_t dissect_fullpacket(tvbuff_t
*tvb
, uint32_t offset
,
1136 proto_tree
*iax2_tree
,
1137 proto_tree
*main_tree
);
1140 static uint32_t dissect_minipacket(tvbuff_t
*tvb
, uint32_t offset
,
1143 proto_tree
*iax2_tree
,
1144 proto_tree
*main_tree
);
1146 static uint32_t dissect_minivideopacket(tvbuff_t
*tvb
, uint32_t offset
,
1149 proto_tree
*iax2_tree
,
1150 proto_tree
*main_tree
);
1152 static uint32_t dissect_trunkpacket(tvbuff_t
*tvb
, uint32_t offset
,
1155 proto_tree
*iax2_tree
,
1156 proto_tree
*main_tree
);
1158 static void dissect_payload(tvbuff_t
*tvb
, uint32_t offset
,
1159 packet_info
*pinfo
, proto_tree
*iax2_tree
,
1160 proto_tree
*tree
, uint32_t ts
, bool video
,
1161 iax_packet_data
*iax_packet
);
1166 dissect_iax2(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1168 proto_item
*iax2_item
;
1169 proto_tree
*iax2_tree
;
1170 proto_tree
*full_mini_subtree
= NULL
;
1171 uint32_t offset
= 0, len
;
1172 uint16_t scallno
= 0;
1175 proto_item
*full_mini_base
;
1177 /* set up the protocol and info fields in the summary pane */
1178 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, PROTO_TAG_IAX2
);
1179 col_clear(pinfo
->cinfo
, COL_INFO
);
1181 /* add the 'iax2' tree to the main tree */
1182 iax2_item
= proto_tree_add_item(tree
, proto_iax2
, tvb
, offset
, -1, ENC_NA
);
1183 iax2_tree
= proto_item_add_subtree(iax2_item
, ett_iax2
);
1185 stmp
= tvb_get_ntohs(tvb
, offset
);
1187 /* starting with 0x0000 indicates meta packet which can be either a mini
1188 * video packet or a trunk packet */
1190 stmp
= tvb_get_ntohs(tvb
, offset
);
1191 if (stmp
& 0x8000) {
1192 /* mini video packet */
1193 type
= IAX2_MINI_VIDEO_PACKET
;
1194 scallno
= stmp
& 0x7FFF;
1198 type
= IAX2_TRUNK_PACKET
;
1201 /* The source call/fullpacket flag is common to both mini and full packets */
1202 scallno
= tvb_get_ntohs(tvb
, offset
);
1204 if (scallno
& 0x8000)
1205 type
= IAX2_FULL_PACKET
;
1207 type
= IAX2_MINI_VOICE_PACKET
;
1212 full_mini_base
= proto_tree_add_uint(iax2_tree
, hf_iax2_packet_type
, tvb
, 0, offset
, type
);
1213 full_mini_subtree
= proto_item_add_subtree(full_mini_base
, ett_iax2_full_mini_subtree
);
1216 proto_tree_add_item(full_mini_subtree
, hf_iax2_scallno
, tvb
, offset
-2, 2, ENC_BIG_ENDIAN
);
1218 iax2_info
->ptype
= type
;
1219 iax2_info
->scallno
= 0;
1220 iax2_info
->dcallno
= 0;
1221 iax2_info
->ftype
= 0;
1222 iax2_info
->csub
= 0;
1223 iax2_info
->payload_len
= 0;
1224 iax2_info
->timestamp
= 0;
1225 iax2_info
->callState
= VOIP_NO_STATE
;
1226 iax2_info
->messageName
= NULL
;
1227 iax2_info
->callingParty
= NULL
;
1228 iax2_info
->calledParty
= NULL
;
1229 iax2_info
->payload_data
= NULL
;
1232 case IAX2_FULL_PACKET
:
1233 len
= dissect_fullpacket(tvb
, offset
, scallno
, pinfo
, full_mini_subtree
, tree
);
1235 case IAX2_MINI_VOICE_PACKET
:
1236 iax2_info
->messageName
= "MINI_VOICE_PACKET";
1237 len
= dissect_minipacket(tvb
, offset
, scallno
, pinfo
, full_mini_subtree
, tree
);
1239 case IAX2_MINI_VIDEO_PACKET
:
1240 iax2_info
->messageName
= "MINI_VIDEO_PACKET";
1241 len
= dissect_minivideopacket(tvb
, offset
, scallno
, pinfo
, full_mini_subtree
, tree
);
1243 case IAX2_TRUNK_PACKET
:
1244 iax2_info
->messageName
= "TRUNK_PACKET";
1245 len
= dissect_trunkpacket(tvb
, offset
, scallno
, pinfo
, full_mini_subtree
, tree
);
1251 /* update the 'length' of the main IAX2 header field so that it covers just the headers,
1252 not the audio data. */
1253 proto_item_set_len(iax2_item
, len
);
1254 tap_queue_packet(iax2_tap
, pinfo
, iax2_info
);
1255 return tvb_captured_length(tvb
);
1258 static proto_item
*dissect_datetime_ie(tvbuff_t
*tvb
, uint32_t offset
, proto_tree
*ies_tree
)
1264 proto_tree_add_item(ies_tree
, hf_iax2_ies
[IAX_IE_DATETIME
], tvb
, offset
+ 2, 4, ENC_BIG_ENDIAN
);
1265 ie_val
= tvb_get_ntohl(tvb
, offset
+2);
1267 /* who's crazy idea for a time encoding was this? */
1268 tm
.tm_sec
= (ie_val
& 0x1f) << 1;
1269 tm
.tm_min
= (ie_val
>>5) & 0x3f;
1270 tm
.tm_hour
= (ie_val
>>11) & 0x1f;
1271 tm
.tm_mday
= (ie_val
>>16) & 0x1f;
1272 tm
.tm_mon
= ((ie_val
>>21) & 0x0f) - 1;
1273 tm
.tm_year
= ((ie_val
>>25) & 0x7f) + 100;
1274 tm
.tm_isdst
= -1; /* there's no info on whether DST was in force; assume it's
1275 * the same as currently */
1277 datetime
.secs
= mktime(&tm
);
1279 return proto_tree_add_time(ies_tree
, hf_iax2_ie_datetime
, tvb
, offset
+2, 4, &datetime
);
1283 /* dissect the information elements in an IAX frame. Returns the updated offset */
1284 static uint32_t dissect_ies(tvbuff_t
*tvb
, packet_info
*pinfo
, uint32_t offset
,
1285 proto_tree
*iax_tree
, proto_item
* iax_item
,
1286 iax2_ie_data
*ie_data
)
1288 DISSECTOR_ASSERT(ie_data
);
1290 while (offset
< tvb_reported_length(tvb
)) {
1292 int ies_type
= tvb_get_uint8(tvb
, offset
);
1293 int ies_len
= tvb_get_uint8(tvb
, offset
+ 1);
1294 uint16_t apparent_addr_family
;
1296 /* do non-tree-dependent stuff first */
1298 case IAX_IE_DATAFORMAT
:
1300 proto_tree_add_expert(iax_tree
, pinfo
, &ei_iax_invalid_len
, tvb
, offset
+1, 1);
1303 ie_data
-> dataformat
= tvb_get_ntohl(tvb
, offset
+2);
1306 case IAX_IE_CALLED_NUMBER
:
1307 iax2_info
->calledParty
= tvb_format_text(pinfo
->pool
, tvb
, offset
+2, ies_len
);
1309 case IAX_IE_CALLING_NUMBER
:
1310 iax2_info
->callingParty
= tvb_format_text(pinfo
->pool
, tvb
, offset
+2, ies_len
);
1313 case IAX_IE_APPARENT_ADDR
:
1314 /* The IAX2 I-D says that the "apparent address" structure
1315 "is the same as the linux struct sockaddr_in", without
1316 bothering to note that the address family field is in
1317 *host* byte order in that structure (the I-D seems to be
1318 assuming that "everything is a Vax^Wx86 or x86-64" with
1319 the address family field being little-endian).
1321 This means the address family values are the Linux
1322 address family values. */
1323 apparent_addr_family
= tvb_get_letohs(tvb
, offset
+2);
1324 switch (apparent_addr_family
) {
1326 /* IAX is always over UDP */
1327 ie_data
->peer_ptype
= PT_UDP
;
1328 ie_data
->peer_port
= tvb_get_ntohs(tvb
, offset
+4);
1330 /* the ip address is big-endian, but then so is peer_address.data */
1331 set_address_tvb(&ie_data
->peer_address
, AT_IPv4
, 4, tvb
, offset
+6);
1335 expert_add_info_format(pinfo
, iax_item
, &ei_iax_peer_address_unsupported
,
1336 "Not supported in IAX dissector: peer address family of %u", apparent_addr_family
);
1343 /* the rest of this stuff only needs doing if we have an iax_tree */
1345 if (iax_tree
&& ies_type
< NUM_HF_IAX2_IES
) {
1346 proto_item
*ti
, *ie_item
= NULL
;
1347 proto_tree
*ies_tree
;
1348 int ie_hf
= hf_iax2_ies
[ies_type
];
1350 ies_tree
= proto_tree_add_subtree(iax_tree
, tvb
, offset
, ies_len
+2, ett_iax2_ie
, &ti
, " ");
1352 proto_tree_add_uint(ies_tree
, hf_iax2_ie_id
, tvb
, offset
, 1, ies_type
);
1353 proto_tree_add_uint(ies_tree
, hf_iax2_length
, tvb
, offset
+ 1, 1, ies_len
);
1356 /* hf_iax2_ies[] is an array, indexed by IE number, of header-fields, one
1357 per IE. Apart from a couple of special cases which require more
1358 complex decoding, we can just look up an entry from the array, and add
1359 the relevant item, although the encoding value used depends on the
1364 case IAX_IE_DATETIME
:
1365 ie_item
= dissect_datetime_ie(tvb
, offset
, ies_tree
);
1369 case IAX_IE_CAPABILITY
:
1372 proto_tree_add_expert(ies_tree
, pinfo
, &ei_iax_invalid_len
, tvb
, offset
+1, 1);
1377 proto_tree_add_bitmask(ies_tree
, tvb
, offset
+ 2, ie_hf
,
1378 ett_iax2_codecs
, hf_iax2_caps
, ENC_BIG_ENDIAN
);
1383 case IAX_IE_CAPABILITY2
:
1385 int version
= tvb_get_uint8(tvb
, offset
+ 2);
1387 proto_tree_add_uint(ies_tree
, hf_iax2_version
, tvb
, offset
+ 2, 1, version
);
1391 proto_tree_add_expert(ies_tree
, pinfo
, &ei_iax_invalid_len
, tvb
, offset
+1, 1);
1396 proto_tree_add_bitmask(ies_tree
, tvb
, offset
+ 3, ie_hf
,
1397 ett_iax2_codecs
, hf_iax2_caps
, ENC_BIG_ENDIAN
);
1406 proto_tree_add_expert(ies_tree
, pinfo
, &ei_iax_invalid_len
, tvb
, offset
+1, 1);
1411 proto_tree_add_item(ies_tree
, ie_hf
,
1412 tvb
, offset
+ 2, 4, ENC_BIG_ENDIAN
);
1417 case IAX_IE_FORMAT2
:
1419 int version
= tvb_get_uint8(tvb
, offset
+ 2);
1421 proto_tree_add_uint(ies_tree
, hf_iax2_version
, tvb
, offset
+ 2, 1, version
);
1425 proto_tree_add_expert(ies_tree
, pinfo
, &ei_iax_invalid_len
, tvb
, offset
+1, 1);
1430 proto_tree_add_item(ies_tree
, ie_hf
,
1431 tvb
, offset
+ 3, 8, ENC_BIG_ENDIAN
);
1437 case IAX_IE_APPARENT_ADDR
:
1439 proto_tree
*sockaddr_tree
;
1441 sockaddr_tree
= proto_tree_add_subtree(ies_tree
, tvb
, offset
+ 2, 16,
1442 ett_iax2_ies_apparent_addr
, &ie_item
, "Apparent Address");
1444 /* The IAX2 I-D says that the "apparent address" structure
1445 "is the same as the linux struct sockaddr_in", without
1446 bothering to note that the address family field is in
1447 *host* byte order in that structure (the I-D seems to be
1448 assuming that "everything is a Vax^Wx86 or x86-64" with
1449 the address family field being little-endian).
1451 This means the address family values are the Linux
1452 address family values. */
1453 apparent_addr_family
= tvb_get_letohs(tvb
, offset
+2);
1454 proto_tree_add_uint(sockaddr_tree
, hf_IAX_IE_APPARENTADDR_SINFAMILY
, tvb
, offset
+ 2, 2, apparent_addr_family
);
1456 if (apparent_addr_family
== LINUX_AF_INET
) {
1458 proto_tree_add_uint(sockaddr_tree
, hf_IAX_IE_APPARENTADDR_SINPORT
, tvb
, offset
+ 4, 2, ie_data
->peer_port
);
1459 memcpy(&addr
, ie_data
->peer_address
.data
, 4);
1460 proto_tree_add_ipv4(sockaddr_tree
, hf_IAX_IE_APPARENTADDR_SINADDR
, tvb
, offset
+ 6, 4, addr
);
1467 int explen
= proto_registrar_get_length(ie_hf
);
1468 if (explen
!= 0 && ies_len
!= explen
) {
1469 proto_tree_add_expert(ies_tree
, pinfo
, &ei_iax_invalid_len
, tvb
, offset
+1, 1);
1473 switch (proto_registrar_get_ftype(ie_hf
)) {
1486 ie_item
= proto_tree_add_item(ies_tree
, ie_hf
, tvb
, offset
+ 2, ies_len
, ENC_BIG_ENDIAN
);
1491 ie_item
= proto_tree_add_item(ies_tree
, ie_hf
, tvb
, offset
+ 2, ies_len
, ENC_NA
);
1496 ie_item
= proto_tree_add_item(ies_tree
, ie_hf
, tvb
, offset
+ 2, ies_len
, ENC_UTF_8
|ENC_NA
);
1500 DISSECTOR_ASSERT_NOT_REACHED();
1504 /* we don't understand this ie: add a generic one */
1507 const char *ie_name
= val_to_str_ext_const(ies_type
, &iax_ies_type_ext
, "Unknown");
1511 value
= tvb_get_uint8(tvb
, offset
+ 2);
1513 proto_tree_add_uint_format(ies_tree
, hf_IAX_IE_UNKNOWN_BYTE
,
1514 tvb
, offset
+2, 1, value
,
1515 "%s: %#02x", ie_name
, value
);
1519 value
= tvb_get_ntohs(tvb
, offset
+ 2);
1521 proto_tree_add_uint_format(ies_tree
, hf_IAX_IE_UNKNOWN_I16
,
1522 tvb
, offset
+2, 2, value
,
1523 "%s: %#04x", ie_name
, value
);
1527 value
= tvb_get_ntohl(tvb
, offset
+ 2);
1529 proto_tree_add_uint_format(ies_tree
, hf_IAX_IE_UNKNOWN_I32
,
1530 tvb
, offset
+2, 4, value
,
1531 "%s: %#08x", ie_name
, value
);
1535 ptr
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
+ 2, ies_len
, ENC_ASCII
);
1537 proto_tree_add_string_format(ies_tree
, hf_IAX_IE_UNKNOWN_BYTES
,
1538 tvb
, offset
+2, ies_len
, ptr
,
1539 "%s: %s", ie_name
, ptr
);
1546 /* Retrieve the text from the item we added, and append it to the main IE
1548 if (ie_item
&& !proto_item_is_hidden(ti
)) {
1549 field_info
*ie_finfo
= PITEM_FINFO(ie_item
);
1551 /* if the representation of the item has already been set, use that;
1552 else we have to allocate a block to put the text into */
1553 if (ie_finfo
&& ie_finfo
->rep
!= NULL
)
1554 proto_item_set_text(ti
, "Information Element: %s",
1555 ie_finfo
->rep
->representation
);
1557 uint8_t *ie_val
= (uint8_t *)wmem_alloc(pinfo
->pool
, ITEM_LABEL_LENGTH
);
1558 proto_item_fill_label(ie_finfo
, ie_val
, NULL
);
1559 proto_item_set_text(ti
, "Information Element: %s",
1565 offset
+= ies_len
+ 2;
1570 static uint32_t uncompress_subclass(uint8_t csub
)
1572 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
1574 /* special case for 'compressed' -1 */
1576 return (uint32_t)-1;
1582 case 0x01: return 0;
1583 case 0x02: return 1;
1584 case 0x04: return 2;
1585 case 0x08: return 3;
1586 case 0x10: return 4;
1587 case 0x20: return 5;
1588 case 0x40: return 6;
1589 default: return (uint32_t)-1;
1594 /* returns the new offset */
1595 static uint32_t dissect_iax2_command(tvbuff_t
*tvb
, uint32_t offset
,
1596 packet_info
*pinfo
, proto_tree
*tree
,
1597 iax_packet_data
*iax_packet
)
1599 uint8_t csub
= tvb_get_uint8(tvb
, offset
);
1601 iax2_ie_data ie_data
;
1602 iax_call_data
*iax_call
;
1604 ie_data
.peer_address
.type
= AT_NONE
;
1605 ie_data
.peer_address
.len
= 0;
1606 ie_data
.peer_address
.data
= NULL
;
1607 ie_data
.peer_ptype
= PT_NONE
;
1608 ie_data
.peer_port
= 0;
1609 ie_data
.peer_callno
= 0;
1610 ie_data
.dataformat
= (uint32_t)-1;
1611 iax_call
= iax_packet
-> call_data
;
1613 /* add the subclass */
1614 ti
= proto_tree_add_uint(tree
, hf_iax2_iax_csub
, tvb
, offset
, 1, csub
);
1617 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s",
1618 val_to_str_ext(csub
, &iax_iax_subclasses_ext
, "unknown (0x%02x)"));
1620 if (offset
>= tvb_reported_length(tvb
))
1623 offset
= dissect_ies(tvb
, pinfo
, offset
, tree
, ti
, &ie_data
);
1625 /* if this is a data call, set up a subdissector for the circuit */
1626 if (iax_call
&& ie_data
.dataformat
!= (uint32_t)-1 && iax_call
-> subdissector
== NULL
) {
1627 iax_call
-> subdissector
= dissector_get_uint_handle(iax2_dataformat_dissector_table
, ie_data
.dataformat
);
1628 iax_call
-> dataformat
= (iax_dataformat_t
)ie_data
.dataformat
;
1631 /* if this is a transfer request, record it in the call data */
1632 if (csub
== IAX_COMMAND_TXREQ
&& iax_packet
-> first_time
) {
1633 if (ie_data
.peer_address
.type
!= AT_NONE
&& ie_data
.peer_callno
!= 0) {
1634 unsigned tx_circuit
= iax_circuit_lookup(&ie_data
.peer_address
,
1637 ie_data
.peer_callno
);
1639 iax2_new_circuit_for_call(pinfo
, NULL
, tx_circuit
, pinfo
->num
, iax_call
, iax_packet
->reversed
);
1646 static void iax2_add_ts_fields(packet_info
*pinfo
, proto_tree
*iax2_tree
, tvbuff_t
*tvb
, iax_packet_data
*iax_packet
, packet_type type
, uint32_t relts
)
1648 uint32_t full_relts
= relts
;
1652 if (iax_packet
->call_data
== NULL
) {
1653 /* no call info for this frame; perhaps we missed the NEW packet */
1657 if (iax_packet
->abstime
.secs
== -1) {
1661 case IAX2_MINI_VOICE_PACKET
:
1664 * Abbreviated 'Mini Frames' are normally used for audio and
1665 * video; however, each time the time-stamp is a multiple of
1666 * 32,768 (0x8000 hex), a standard or 'Full Frame' MUST be sent.
1668 * and, for what it later calls "Mini Frames", by which it means
1669 * what we're calling "mini voice packets", it says:
1671 * Mini frames carry a 16-bit time-stamp, which is the lower 16 bits
1672 * of the transmitting peer's full 32-bit time-stamp for the call.
1673 * The time-stamp allows synchronization of incoming frames so that
1674 * they MAY be processed in chronological order instead of the
1675 * (possibly different) order in which they are received. The 16-bit
1676 * time-stamp wraps after 65.536 seconds, at which point a full frame
1677 * SHOULD be sent to notify the remote peer that its time-stamp has
1678 * been reset. A call MUST continue to send mini frames starting
1679 * with time-stamp 0 even if acknowledgment of the resynchronization
1682 * *If* we see all the full frames, that means we *should* be able
1683 * to convert the 16-bit time stamp to a full 32-bit time stamp by
1684 * ORing the upper 16 bits of the last full frame time stamp we saw
1685 * in above the 16-bit time stamp.
1687 * XXX - what, if anything, should we do about full frames we've
1689 full_relts
= (iax_packet
->call_data
->last_full_frame_ts
& 0xFFFF0000) | relts
;
1692 case IAX2_FULL_PACKET
:
1693 case IAX2_TRUNK_PACKET
:
1694 /* Timestamps have the full 32 bits of the timestamp.
1695 * Save it, to add to the mini-packet time stamps.
1697 * XXX - that's a maximum of 4294967296 milliseconds
1698 * or about 4294967 seconds or about 49 days.
1699 * Do we need to worry about that overflowing? */
1701 iax_packet
->call_data
->last_full_frame_ts
= full_relts
;
1704 case IAX2_MINI_VIDEO_PACKET
:
1705 /* See the comment above in the IAX2_MINI_VOICE_PACKET case.
1706 * Note also that RFC 5456 says, in section 8.1.3.1 "Meta Video
1707 * Frames", which covers what we're calling "mini video packets":
1709 * Meta video frames carry a 16-bit time-stamp, which is the lower 16
1710 * bits of the transmitting peer's full 32-bit time-stamp for the
1711 * call. When this time-stamp wraps, a Full Frame SHOULD be sent to
1712 * notify the remote peer that the time-stamp has been reset to 0.
1714 * *but* it also shows the uppermost bit of that time stamp as "?",
1715 * with a 15-bit time stamp, in the ASCII-art packet diagram after
1716 * it. dissect_minivideopacket() says "bit 15 of the ts is used to
1717 * represent the rtp 'marker' bit"; presumably that's what's going
1718 * on, but the RFC doesn't say that.
1720 * So we assume that the time stamp is only 15 bits, and that the
1721 * upper *17* bits of the last full frame's time stamp need to be
1722 * ORed in above the 15 bits of time stamp.
1724 * XXX - do we need to worry about overflows or missed packets
1725 * with full timestamps? */
1726 full_relts
= (iax_packet
->call_data
->last_full_frame_ts
& 0xFFFF8000) | relts
;
1730 /* Convert the full relative time stamp to an nstime_t */
1731 rel
.secs
= full_relts
/ 1000;
1732 rel
.nsecs
= (full_relts
% 1000) * 1000000;
1734 /* Add it to the start time to get the absolute time. */
1735 nstime_sum(&iax_packet
->abstime
, &iax_packet
->call_data
->start_time
, &rel
);
1737 iax2_info
->timestamp
= relts
; /* raw time stamp; nobody uses it */
1740 item
= proto_tree_add_time(iax2_tree
, hf_iax2_absts
, tvb
, 0, 0, &iax_packet
->abstime
);
1741 proto_item_set_generated(item
);
1743 nstime_delta(&lateness
, &pinfo
->abs_ts
, &iax_packet
->abstime
);
1745 item
= proto_tree_add_time(iax2_tree
, hf_iax2_lateness
, tvb
, 0, 0, &lateness
);
1746 proto_item_set_generated(item
);
1750 /* returns the new offset */
1752 dissect_fullpacket(tvbuff_t
*tvb
, uint32_t offset
,
1754 packet_info
*pinfo
, proto_tree
*iax2_tree
,
1755 proto_tree
*main_tree
)
1763 proto_tree
*packet_type_tree
= NULL
;
1764 iax_call_data
*iax_call
;
1765 iax_packet_data
*iax_packet
;
1770 * remove the top bit for retransmission detection
1772 dcallno
= tvb_get_ntohs(tvb
, offset
) & 0x7FFF;
1773 ts
= tvb_get_ntohl(tvb
, offset
+ 2);
1774 type
= tvb_get_uint8(tvb
, offset
+ 8);
1775 csub
= tvb_get_uint8(tvb
, offset
+ 9);
1776 iax2_info
->ftype
= type
;
1777 iax2_info
->csub
= csub
;
1778 iax2_info
->scallno
= scallno
;
1779 iax2_info
->dcallno
= dcallno
;
1781 /* see if we've seen this packet before */
1782 iax_packet
= (iax_packet_data
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_iax2
, 0);
1784 /* if not, find or create an iax_call info structure for this IAX session. */
1786 if (type
== AST_FRAME_IAX
&& csub
== IAX_COMMAND_NEW
) {
1787 /* NEW packets start a new call */
1788 iax_call
= iax_new_call(pinfo
, scallno
);
1791 iax_call
= iax_lookup_call(pinfo
, scallno
, dcallno
,
1795 iax_packet
= iax_new_packet_data(iax_call
, reversed
);
1796 p_add_proto_data(wmem_file_scope(), pinfo
, proto_iax2
, 0, iax_packet
);
1798 iax_call
= iax_packet
->call_data
;
1799 reversed
= iax_packet
->reversed
;
1802 iax2_populate_pinfo_from_packet_data(pinfo
, iax_packet
);
1805 proto_item
*packet_type_base
;
1807 proto_tree_add_item(iax2_tree
, hf_iax2_dcallno
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1809 proto_tree_add_item(iax2_tree
, hf_iax2_retransmission
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1813 proto_tree_add_uint(iax2_tree
, hf_iax2_callno
, tvb
, 0, 4,
1814 iax_call
->forward_circuit_ids
[0]);
1815 proto_item_set_generated(item
);
1818 proto_tree_add_uint(iax2_tree
, hf_iax2_ts
, tvb
, offset
+2, 4, ts
);
1819 iax2_add_ts_fields(pinfo
, iax2_tree
, tvb
, iax_packet
, IAX2_FULL_PACKET
, ts
);
1821 proto_tree_add_item(iax2_tree
, hf_iax2_oseqno
, tvb
, offset
+6, 1,
1824 proto_tree_add_item(iax2_tree
, hf_iax2_iseqno
, tvb
, offset
+7, 1,
1826 packet_type_base
= proto_tree_add_uint(iax2_tree
, hf_iax2_type
, tvb
,
1829 /* add the type-specific subtree */
1830 packet_type_tree
= proto_item_add_subtree(packet_type_base
, ett_iax2_type
);
1832 iax2_add_ts_fields(pinfo
, iax2_tree
, tvb
, iax_packet
, IAX2_FULL_PACKET
, ts
);
1836 /* add frame type to info line */
1837 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s, source call# %d, timestamp %ums",
1838 val_to_str_ext(type
, &iax_frame_types_ext
, "Unknown (0x%02x)"),
1841 iax2_info
->messageName
= val_to_str_ext(type
, &iax_frame_types_ext
, "Unknown (0x%02x)");
1845 offset
=dissect_iax2_command(tvb
, offset
+9, pinfo
, packet_type_tree
, iax_packet
);
1846 iax2_info
->messageName
= val_to_str_ext(csub
, &iax_iax_subclasses_ext
, "unknown (0x%02x)");
1847 if (csub
< NUM_TAP_IAX_VOIP_STATES
) iax2_info
->callState
= tap_iax_voip_state
[csub
];
1850 case AST_FRAME_DTMF_BEGIN
:
1851 case AST_FRAME_DTMF_END
:
1852 proto_tree_add_item(packet_type_tree
, hf_iax2_dtmf_csub
, tvb
, offset
+9, 1, ENC_ASCII
);
1855 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " digit %s", format_char(pinfo
->pool
, csub
));
1858 case AST_FRAME_CONTROL
:
1859 /* add the subclass */
1860 proto_tree_add_uint(packet_type_tree
, hf_iax2_cmd_csub
, tvb
,
1864 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s",
1865 val_to_str_ext(csub
, &iax_cmd_subclasses_ext
, "unknown (0x%02x)"));
1866 iax2_info
->messageName
= val_to_str_ext (csub
, &iax_cmd_subclasses_ext
, "unknown (0x%02x)");
1867 if (csub
< NUM_TAP_CMD_VOIP_STATES
) iax2_info
->callState
= tap_cmd_voip_state
[csub
];
1870 case AST_FRAME_VOICE
:
1872 iax_packet
-> codec
= codec
= uncompress_subclass(csub
);
1874 if (packet_type_tree
) {
1876 proto_tree_add_item(packet_type_tree
, hf_iax2_voice_csub
, tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
1877 item
= proto_tree_add_uint64(packet_type_tree
, hf_iax2_voice_codec
, tvb
, offset
+9, 1, CODEC_MASK(codec
));
1878 proto_item_set_generated(item
);
1885 iax_call
->dst_codec
= codec
;
1887 iax_call
->src_codec
= codec
;
1891 dissect_payload(tvb
, offset
, pinfo
, iax2_tree
, main_tree
, ts
, false, iax_packet
);
1894 case AST_FRAME_VIDEO
:
1895 /* bit 6 of the csub is used to represent the rtp 'marker' bit */
1896 rtp_marker
= csub
& 0x40 ? true:false;
1897 iax_packet
-> codec
= codec
= uncompress_subclass((uint8_t)(csub
& ~0x40));
1899 if (packet_type_tree
) {
1901 proto_tree_add_item(packet_type_tree
, hf_iax2_video_csub
, tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
1902 proto_tree_add_item(packet_type_tree
, hf_iax2_marker
, tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
1903 item
= proto_tree_add_uint64(packet_type_tree
, hf_iax2_video_codec
, tvb
, offset
+9, 1, CODEC_MASK(codec
));
1904 proto_item_set_generated(item
);
1909 if (iax_call
&& iax_packet
-> first_time
) {
1911 iax_call
->dst_vformat
= codec
;
1913 iax_call
->src_vformat
= codec
;
1918 col_append_str(pinfo
->cinfo
, COL_INFO
, ", Mark");
1921 dissect_payload(tvb
, offset
, pinfo
, iax2_tree
, main_tree
, ts
, true, iax_packet
);
1924 case AST_FRAME_MODEM
:
1925 proto_tree_add_item(packet_type_tree
, hf_iax2_modem_csub
, tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
1928 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s",
1929 val_to_str(csub
, iax_modem_subclasses
, "unknown (0x%02x)"));
1932 case AST_FRAME_TEXT
:
1933 proto_tree_add_item(packet_type_tree
, hf_iax2_text_csub
, tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
1937 int textlen
= tvb_captured_length_remaining(tvb
, offset
);
1940 proto_tree_add_item(packet_type_tree
, hf_iax2_text_text
, tvb
, offset
, textlen
, ENC_UTF_8
);
1946 case AST_FRAME_HTML
:
1947 proto_tree_add_item(packet_type_tree
, hf_iax2_html_csub
, tvb
, offset
+9, 1, ENC_BIG_ENDIAN
);
1952 int urllen
= tvb_captured_length_remaining(tvb
, offset
);
1955 proto_item
*pi
= proto_tree_add_item(packet_type_tree
, hf_iax2_html_url
, tvb
, offset
, urllen
, ENC_UTF_8
);
1956 proto_item_set_url(pi
);
1964 proto_tree_add_uint(packet_type_tree
, hf_iax2_csub
, tvb
, offset
+9,
1968 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " subclass %d", csub
);
1972 /* next time we come to parse this packet, don't propagate the codec into the
1974 iax_packet
->first_time
= false;
1979 static iax_packet_data
*iax2_get_packet_data_for_minipacket(packet_info
*pinfo
,
1983 /* see if we've seen this packet before */
1984 iax_packet_data
*p
= (iax_packet_data
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_iax2
, 0);
1987 /* if not, find or create an iax_call info structure for this IAX session. */
1989 iax_call_data
*iax_call
;
1991 iax_call
= iax_lookup_call(pinfo
, scallno
, 0, &reversed
);
1993 p
= iax_new_packet_data(iax_call
, reversed
);
1994 p_add_proto_data(wmem_file_scope(), pinfo
, proto_iax2
, 0, p
);
1996 /* set the codec for this frame to be whatever the last full frame used */
1999 p
->codec
= reversed
? iax_call
-> dst_vformat
: iax_call
-> src_vformat
;
2001 p
->codec
= reversed
? iax_call
-> dst_codec
: iax_call
-> src_codec
;
2005 iax2_populate_pinfo_from_packet_data(pinfo
, p
);
2010 static uint32_t dissect_minivideopacket(tvbuff_t
*tvb
, uint32_t offset
,
2011 uint16_t scallno
, packet_info
*pinfo
,
2012 proto_tree
*iax2_tree
, proto_tree
*main_tree
)
2015 iax_packet_data
*iax_packet
;
2019 ts
= tvb_get_ntohs(tvb
, offset
);
2021 /* bit 15 of the ts is used to represent the rtp 'marker' bit */
2022 rtp_marker
= ts
& 0x8000 ? true:false;
2025 iax_packet
= iax2_get_packet_data_for_minipacket(pinfo
, scallno
, true);
2028 if (iax_packet
->call_data
) {
2030 proto_tree_add_uint(iax2_tree
, hf_iax2_callno
, tvb
, 0, 4,
2031 iax_packet
->call_data
->forward_circuit_ids
[0]);
2032 proto_item_set_generated(item
);
2035 proto_tree_add_item(iax2_tree
, hf_iax2_minividts
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2036 iax2_add_ts_fields(pinfo
, iax2_tree
, tvb
, iax_packet
, IAX2_MINI_VIDEO_PACKET
, ts
);
2037 proto_tree_add_item(iax2_tree
, hf_iax2_minividmarker
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2039 iax2_add_ts_fields(pinfo
, iax2_tree
, tvb
, iax_packet
, IAX2_MINI_VIDEO_PACKET
, ts
);
2044 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
2045 "Mini video packet, source call# %d, timestamp %ums%s",
2046 scallno
, ts
, rtp_marker
?", Mark":"");
2049 dissect_payload(tvb
, offset
, pinfo
, iax2_tree
, main_tree
, ts
, true, iax_packet
);
2051 /* next time we come to parse this packet, don't propagate the codec into the
2053 iax_packet
->first_time
= false;
2058 static uint32_t dissect_minipacket(tvbuff_t
*tvb
, uint32_t offset
, uint16_t scallno
,
2059 packet_info
*pinfo
, proto_tree
*iax2_tree
,
2060 proto_tree
*main_tree
)
2063 iax_packet_data
*iax_packet
;
2066 ts
= tvb_get_ntohs(tvb
, offset
);
2068 iax_packet
= iax2_get_packet_data_for_minipacket(pinfo
, scallno
, false);
2071 if (iax_packet
->call_data
) {
2072 item
= proto_tree_add_uint(iax2_tree
, hf_iax2_callno
, tvb
, 0, 4,
2073 iax_packet
->call_data
->forward_circuit_ids
[0]);
2074 proto_item_set_generated(item
);
2077 proto_tree_add_uint(iax2_tree
, hf_iax2_minits
, tvb
, offset
, 2, ts
);
2078 iax2_add_ts_fields(pinfo
, iax2_tree
, tvb
, iax_packet
, IAX2_MINI_VOICE_PACKET
, ts
);
2080 iax2_add_ts_fields(pinfo
, iax2_tree
, tvb
, iax_packet
, IAX2_MINI_VOICE_PACKET
, ts
);
2086 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
2087 "Mini packet, source call# %d, timestamp %ums",
2091 /* XXX fix the timestamp logic */
2092 dissect_payload(tvb
, offset
, pinfo
, iax2_tree
, main_tree
, ts
, false, iax_packet
);
2095 /* next time we come to parse this packet, don't propagate the codec into the
2097 iax_packet
->first_time
= false;
2103 static uint32_t dissect_trunkcall_ts(tvbuff_t
*tvb
, uint32_t offset
, proto_tree
*iax2_tree
, uint16_t *scallno
)
2105 proto_tree
*call_tree
;
2106 uint16_t datalen
, rlen
, ts
;
2108 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2109 | Data Length (in octets) |R| Source Call Number |
2110 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2112 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
2116 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2118 datalen
= tvb_get_ntohs(tvb
, offset
);
2119 *scallno
= tvb_get_ntohs(tvb
, offset
+ 2);
2120 ts
= tvb_get_ntohs(tvb
, offset
+ 4);
2122 rlen
= MIN(tvb_captured_length(tvb
) - offset
- 6, datalen
);
2125 call_tree
= proto_tree_add_subtree_format(iax2_tree
, tvb
, offset
, rlen
+ 6,
2126 ett_iax2_trunk_call
, NULL
, "Trunk call from %u, ts: %u", *scallno
, ts
);
2128 proto_tree_add_item(call_tree
, hf_iax2_trunk_call_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2129 proto_tree_add_item(call_tree
, hf_iax2_trunk_call_scallno
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
2130 proto_tree_add_item(call_tree
, hf_iax2_trunk_call_ts
, tvb
, offset
+ 4, 2, ENC_BIG_ENDIAN
);
2131 proto_tree_add_item(call_tree
, hf_iax2_trunk_call_data
, tvb
, offset
+ 6, rlen
, ENC_NA
);
2138 static uint32_t dissect_trunkcall_nots(tvbuff_t
*tvb
, uint32_t offset
, proto_tree
*iax2_tree
, uint16_t *scallno
)
2140 proto_tree
*call_tree
;
2141 uint16_t datalen
, rlen
;
2143 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2144 |R| Source Call Number | Data Length (in octets) |
2145 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2149 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2151 *scallno
= tvb_get_ntohs(tvb
, offset
);
2152 datalen
= tvb_get_ntohs(tvb
, offset
+ 2);
2154 rlen
= MIN(tvb_captured_length(tvb
) - offset
- 4, datalen
);
2157 call_tree
= proto_tree_add_subtree_format(iax2_tree
, tvb
, offset
, rlen
+ 6,
2158 ett_iax2_trunk_call
, NULL
, "Trunk call from %u", *scallno
);
2160 proto_tree_add_item(call_tree
, hf_iax2_trunk_call_scallno
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2161 proto_tree_add_item(call_tree
, hf_iax2_trunk_call_len
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
2162 proto_tree_add_item(call_tree
, hf_iax2_trunk_call_data
, tvb
, offset
+ 4, rlen
, ENC_NA
);
2169 typedef struct _call_list
{
2171 struct _call_list
*next
;
2174 static call_list
*call_list_append(wmem_allocator_t
*pool
, call_list
*list
, uint16_t scallno
)
2176 call_list
*node
= wmem_new0(pool
, call_list
);
2178 node
->scallno
= scallno
;
2181 call_list
*cur
= list
;
2192 static bool call_list_find(call_list
*list
, uint16_t scallno
)
2194 for (; list
; list
= list
->next
) {
2195 if (list
->scallno
== scallno
) {
2202 static unsigned call_list_length(call_list
*list
)
2205 for (; list
; list
= list
->next
) {
2211 static uint32_t dissect_trunkpacket(tvbuff_t
*tvb
, uint32_t offset
,
2212 uint16_t scallno_param _U_
, packet_info
*pinfo
,
2213 proto_tree
*iax2_tree
, proto_tree
*main_tree _U_
)
2215 uint8_t cmddata
, trunkts
;
2216 unsigned nframes
= 0, ncalls
= 0;
2217 proto_item
*cd
, *nc
= NULL
;
2218 proto_tree
*field_tree
= NULL
;
2219 call_list
*calls
= NULL
;
2220 /*iax_packet_data *iax_packet;*/
2222 cmddata
= tvb_get_uint8(tvb
, offset
+ 1);
2223 trunkts
= cmddata
& IAX2_TRUNK_TS
;
2225 /* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 */
2226 /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
2227 /* |F| Meta Indicator |V|Meta Command | Cmd Data (0) | */
2228 /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
2229 /* | time-stamp | */
2230 /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
2234 proto_tree_add_item(iax2_tree
, hf_iax2_trunk_metacmd
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2237 cd
= proto_tree_add_uint(iax2_tree
, hf_iax2_trunk_cmddata
, tvb
, offset
+ 1, 1, cmddata
);
2238 field_tree
= proto_item_add_subtree(cd
, ett_iax2_trunk_cmddata
);
2240 proto_item_append_text(cd
, " (trunk timestamps)");
2242 /* CD -> Trunk timestamp */
2243 proto_tree_add_boolean(field_tree
, hf_iax2_trunk_cmddata_ts
, tvb
, offset
+ 1, 1, cmddata
);
2246 proto_tree_add_item(iax2_tree
, hf_iax2_trunk_ts
, tvb
, offset
+ 2, 4, ENC_BIG_ENDIAN
);
2252 /* Trunk calls with timestamp */
2253 while(tvb_captured_length_remaining(tvb
, offset
) >= 6) {
2255 offset
= dissect_trunkcall_ts(tvb
, offset
, iax2_tree
, &scallno
);
2256 if (!call_list_find(calls
, scallno
)) {
2257 calls
= call_list_append(pinfo
->pool
, calls
, scallno
);
2263 /* Trunk calls without timestamp */
2264 while(tvb_captured_length_remaining(tvb
, offset
) >= 4) {
2266 offset
= dissect_trunkcall_nots(tvb
, offset
, iax2_tree
, &scallno
);
2267 if (!call_list_find(calls
, scallno
)) {
2268 calls
= call_list_append(pinfo
->pool
, calls
, scallno
);
2274 ncalls
= call_list_length(calls
);
2277 /* number of items */
2278 nc
= proto_tree_add_uint(iax2_tree
, hf_iax2_trunk_ncalls
, NULL
, 0, 0, ncalls
);
2279 proto_item_set_generated(nc
);
2282 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Trunk packet with %d media frame%s for %d call%s",
2283 nframes
, plurality(nframes
, "", "s"),
2284 ncalls
, plurality(ncalls
, "", "s"));
2290 static void process_iax_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
2291 bool video
, iax_packet_data
*iax_packet
)
2293 uint32_t codec
= iax_packet
-> codec
;
2294 iax_call_data
*iax_call
= iax_packet
-> call_data
;
2296 #ifdef DEBUG_DESEGMENT
2297 ws_debug("calling process_iax_pdu; len = %u", tvb_reported_length(tvb
));
2300 if (!video
&& iax_call
&& iax_call
->subdissector
) {
2301 iax2_dissector_info_t dissector_info
;
2303 /* info for subdissectors. We always pass on the original forward circuit,
2304 * and steal the p2p_dir flag to indicate the direction */
2305 if (iax_packet
->call_data
== NULL
) {
2306 /* if we missed the NEW packet for this call, call_data will be null. it's
2307 * tbd what the best thing to do here is. */
2308 memset(&dissector_info
, 0, sizeof(dissector_info
));
2310 dissector_info
.ctype
= CONVERSATION_IAX2
;
2311 dissector_info
.circuit_id
= (uint32_t)iax_packet
->call_data
->forward_circuit_ids
[0];
2314 call_dissector_with_data(iax_call
->subdissector
, tvb
, pinfo
, tree
, &dissector_info
);
2315 } else if (codec
!= 0 && dissector_try_uint(iax2_codec_dissector_table
, codec
, tvb
, pinfo
, tree
)) {
2316 /* codec dissector handled our data */
2318 /* we don't know how to dissect our data: dissect it as data */
2319 call_data_dissector(tvb
, pinfo
, tree
);
2322 #ifdef DEBUG_DESEGMENT
2323 ws_debug("called process_iax_pdu; pinfo->desegment_len=%u; pinfo->desegment_offset=%u",
2324 pinfo
->desegment_len
, pinfo
->desegment_offset
);
2328 static void desegment_iax(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*iax2_tree
,
2329 proto_tree
*tree
, bool video
, iax_packet_data
*iax_packet
)
2332 iax_call_data
*iax_call
= iax_packet
-> call_data
;
2333 iax_call_dirdata
*dirdata
;
2334 void * value
= NULL
;
2335 uint32_t frag_offset
= 0;
2336 fragment_head
*fd_head
;
2337 bool must_desegment
= false;
2339 DISSECTOR_ASSERT(iax_call
);
2341 pinfo
->can_desegment
= 2;
2342 pinfo
->desegment_offset
= 0;
2343 pinfo
->desegment_len
= 0;
2345 #ifdef DEBUG_DESEGMENT
2346 ws_debug("dissecting packet %u", pinfo
->num
);
2349 dirdata
= &(iax_call
->dirdata
[!!(iax_packet
->reversed
)]);
2351 if ((!pinfo
->fd
->visited
&& (dirdata
->current_frag_bytes
> 0)) ||
2352 ((value
= g_hash_table_lookup(iax_fid_table
, GUINT_TO_POINTER(pinfo
->num
))) != NULL
)) {
2354 /* then we are continuing an already-started pdu */
2356 uint32_t frag_len
= tvb_reported_length(tvb
);
2359 #ifdef DEBUG_DESEGMENT
2360 ws_debug("visited: %i; c_f_b: %u; hash: %u->%u", pinfo
->fd
->visited
?1:0,
2361 dirdata
->current_frag_bytes
, pinfo
->num
, dirdata
->current_frag_id
);
2364 if (!pinfo
->fd
->visited
) {
2366 fid
= dirdata
->current_frag_id
;
2367 tot_len
= dirdata
->current_frag_minlen
;
2368 DISSECTOR_ASSERT(g_hash_table_lookup(iax_fid_table
, GUINT_TO_POINTER(pinfo
->num
)) == NULL
);
2369 g_hash_table_insert(iax_fid_table
, GUINT_TO_POINTER(pinfo
->num
), GUINT_TO_POINTER(fid
));
2370 frag_offset
= dirdata
->current_frag_bytes
;
2371 dirdata
->current_frag_bytes
+= frag_len
;
2372 complete
= dirdata
->current_frag_bytes
> tot_len
;
2373 #ifdef DEBUG_DESEGMENT
2374 ws_debug("hash: %u->%u; frag_offset: %u; c_f_b: %u; totlen: %u",
2375 pinfo
->num
, fid
, frag_offset
, dirdata
->current_frag_bytes
, tot_len
);
2378 fid
= GPOINTER_TO_UINT(value
);
2379 /* these values are unused by fragment_add if pinfo->fd->visited */
2380 dirdata
->current_frag_bytes
= 0;
2384 /* fragment_add checks for already-added */
2385 fd_head
= fragment_add(&iax_reassembly_table
, tvb
, 0, pinfo
, fid
, NULL
,
2387 frag_len
, !complete
);
2389 if (fd_head
&& (pinfo
->num
== fd_head
->reassembled_in
)) {
2391 tvbuff_t
*next_tvb
= tvb_new_chain(tvb
, fd_head
->tvb_data
);
2392 add_new_data_source(pinfo
, next_tvb
, "Reassembled IAX2");
2394 process_iax_pdu(next_tvb
, pinfo
, tree
, video
, iax_packet
);
2396 /* calculate the amount of data which was available to the higher-level
2397 dissector before we added this segment; if the returned offset is
2398 within that section, the higher-level dissector was unable to find any
2399 pdus; if it's after that, it found one or more complete PDUs.
2401 old_len
= (int32_t)(tvb_reported_length(next_tvb
) - frag_len
);
2402 if (pinfo
->desegment_len
&&
2403 (pinfo
->desegment_offset
< old_len
)) {
2404 /* oops, it wasn't actually complete */
2405 fragment_set_partial_reassembly(&iax_reassembly_table
, pinfo
, fid
, NULL
);
2406 if (pinfo
->desegment_len
== DESEGMENT_ONE_MORE_SEGMENT
) {
2407 /* only one more byte should be enough for a retry */
2408 dirdata
->current_frag_minlen
= fd_head
->datalen
+ 1;
2410 dirdata
->current_frag_minlen
= fd_head
->datalen
+ pinfo
->desegment_len
;
2413 /* we successfully dissected some data; create the proto tree items for
2414 * the fragments, and flag any remaining data for desegmentation */
2416 proto_item
*iax_tree_item
, *frag_tree_item
;
2417 /* this nargery is to insert the fragment tree into the main tree
2418 * between the IAX protocol entry and the subdissector entry */
2419 show_fragment_tree(fd_head
, &iax2_fragment_items
, tree
, pinfo
, next_tvb
, &frag_tree_item
);
2420 iax_tree_item
= proto_item_get_parent(proto_tree_get_parent(iax2_tree
));
2421 if (frag_tree_item
&& iax_tree_item
)
2422 proto_tree_move_item(tree
, iax_tree_item
, frag_tree_item
);
2424 dirdata
->current_frag_minlen
= dirdata
->current_frag_id
= dirdata
->current_frag_bytes
= 0;
2426 if (pinfo
->desegment_len
) {
2427 /* there's a bit of data left to desegment */
2428 must_desegment
= true;
2429 /* make desegment_offset relative to our tvb */
2430 pinfo
->desegment_offset
-= old_len
;
2433 /* don't add a 'reassembled in' item for this pdu */
2438 /* This segment was not found in our table, so it doesn't
2439 contain a continuation of a higher-level PDU.
2440 Call the normal subdissector.
2443 process_iax_pdu(tvb
, pinfo
, tree
, video
, iax_packet
);
2445 if (pinfo
->desegment_len
) {
2446 /* the higher-level dissector has asked for some more data - ie,
2447 the end of this segment does not coincide with the end of a
2448 higher-level PDU. */
2449 must_desegment
= true;
2455 /* must_desegment is set if the end of this segment (or the whole of it)
2456 * contained the start of a higher-level PDU; we must add whatever is left of
2457 * this segment (after pinfo->desegment_offset) to a fragment table for disassembly. */
2458 if (must_desegment
) {
2459 uint32_t fid
= pinfo
->num
; /* a new fragment id */
2460 uint32_t deseg_offset
= pinfo
->desegment_offset
;
2461 uint32_t frag_len
= tvb_reported_length_remaining(tvb
, deseg_offset
);
2462 dirdata
->current_frag_id
= fid
;
2463 dirdata
->current_frag_bytes
= frag_len
;
2465 if (pinfo
->desegment_len
== DESEGMENT_ONE_MORE_SEGMENT
) {
2466 /* only one more byte should be enough for a retry */
2467 dirdata
->current_frag_minlen
= frag_len
+ 1;
2469 dirdata
->current_frag_minlen
= frag_len
+ pinfo
->desegment_len
;
2472 fd_head
= fragment_add(&iax_reassembly_table
,
2473 tvb
, deseg_offset
, pinfo
, fid
, NULL
,
2475 #ifdef DEBUG_DESEGMENT
2476 ws_debug("Start offset of undissected bytes: %u; "
2477 "Bytes remaining in this segment: %u; min required bytes: %u\n",
2478 deseg_offset
, frag_len
, frag_len
+ pinfo
->desegment_len
);
2482 /* add a 'reassembled in' item if necessary */
2483 if (fd_head
!= NULL
) {
2484 uint32_t deseg_offset
= pinfo
->desegment_offset
;
2485 if (fd_head
->reassembled_in
!= 0 &&
2486 !(fd_head
->flags
& FD_PARTIAL_REASSEMBLY
)) {
2487 proto_item
*iax_tree_item
;
2488 iax_tree_item
= proto_tree_add_uint(tree
, hf_iax2_reassembled_in
,
2489 tvb
, deseg_offset
, tvb_reported_length_remaining(tvb
, deseg_offset
),
2490 fd_head
->reassembled_in
);
2491 proto_item_set_generated(iax_tree_item
);
2493 /* this fragment is never reassembled */
2494 proto_tree_add_item(tree
, hf_iax2_fragment_unfinished
, tvb
, deseg_offset
, -1, ENC_NA
);
2497 if (pinfo
->desegment_offset
== 0) {
2498 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "IAX2");
2499 col_set_str(pinfo
->cinfo
, COL_INFO
, "[IAX2 segment of a reassembled PDU]");
2503 pinfo
->can_desegment
= 0;
2504 pinfo
->desegment_offset
= 0;
2505 pinfo
->desegment_len
= 0;
2508 static void dissect_payload(tvbuff_t
*tvb
, uint32_t offset
,
2509 packet_info
*pinfo
, proto_tree
*iax2_tree
,
2510 proto_tree
*tree
, uint32_t ts _U_
, bool video
,
2511 iax_packet_data
*iax_packet
)
2514 bool out_of_order
= false;
2517 uint32_t codec
= iax_packet
-> codec
;
2519 iax_call_data
*iax_call
= iax_packet
-> call_data
;
2521 if (offset
>= tvb_reported_length(tvb
)) {
2522 col_append_str(pinfo
->cinfo
, COL_INFO
, ", empty frame");
2526 sub_tvb
= tvb_new_subset_remaining(tvb
, offset
);
2528 /* XXX shouldn't pass through out-of-order packets. */
2530 if (!video
&& iax_call
&& iax_call
-> dataformat
!= 0) {
2531 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", data, format %s",
2532 val_to_str(iax_call
-> dataformat
,
2533 iax_dataformats
, "unknown (0x%02x)"));
2536 col_append_str(pinfo
->cinfo
, COL_INFO
, " (out-of-order packet)");
2539 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %s",
2540 val64_to_str_ext(CODEC_MASK(codec
), &codec_types_ext
, "unknown (0x%04x)"));
2543 nbytes
= tvb_reported_length(sub_tvb
);
2544 proto_tree_add_item(iax2_tree
, hf_iax2_payload_data
, sub_tvb
, 0, -1, ENC_NA
);
2546 iax2_info
->payload_len
= nbytes
;
2547 iax2_info
->payload_data
= tvb_get_ptr(sub_tvb
, 0, -1);
2549 /* pass the rest of the block to a subdissector */
2550 if (iax_packet
->call_data
)
2551 desegment_iax(sub_tvb
, pinfo
, iax2_tree
, tree
, video
, iax_packet
);
2553 process_iax_pdu(sub_tvb
, pinfo
, tree
, video
, iax_packet
);
2560 /* called at the start of a capture. We should clear out our static, per-capture
2565 iax_init_protocol(void)
2567 iax_circuit_hashtab
= g_hash_table_new(iax_circuit_hash
, iax_circuit_equal
);
2570 iax_fid_table
= g_hash_table_new(g_direct_hash
, g_direct_equal
);
2574 iax_cleanup_protocol(void)
2576 g_hash_table_destroy(iax_circuit_hashtab
);
2577 g_hash_table_destroy(iax_fid_table
);
2582 proto_register_iax2(void)
2584 /* A header field is something you can search/filter on.
2586 * We create a structure to register our fields. It consists of an
2587 * array of hf_register_info structures, each of which are of the format
2588 * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
2591 static hf_register_info hf
[] = {
2593 {&hf_iax2_packet_type
,
2594 {"Packet type", "iax2.packet_type",
2595 FT_UINT8
, BASE_DEC
, VALS(iax_packet_types
), 0,
2596 "Full/minivoice/minivideo/trunk packet",
2600 {"Call identifier", "iax2.call",
2601 FT_UINT32
, BASE_DEC
, NULL
, 0,
2602 "This is the identifier Wireshark assigns to identify this call."
2603 " It does not correspond to any real field in the protocol",
2607 {"Source call", "iax2.src_call",
2608 FT_UINT16
, BASE_DEC
, NULL
, 0x7FFF,
2609 "src_call holds the number of this call at the packet source pbx",
2612 /* FIXME could this be turned into a FRAMENUM field? */
2614 {"Destination call", "iax2.dst_call",
2615 FT_UINT16
, BASE_DEC
, NULL
, 0x7FFF,
2616 "dst_call holds the number of this call at the packet destination",
2619 {&hf_iax2_retransmission
,
2620 {"Retransmission", "iax2.retransmission",
2621 FT_BOOLEAN
, 16, NULL
, 0x8000,
2622 "retransmission is set if this packet is a retransmission of an earlier failed packet",
2626 {"Timestamp", "iax2.timestamp",
2627 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2628 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2632 {"Timestamp", "iax2.timestamp",
2633 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2634 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2637 {&hf_iax2_minividts
,
2638 {"Timestamp", "iax2.timestamp",
2639 FT_UINT16
, BASE_DEC
, NULL
, 0x7FFF,
2640 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2644 {"Absolute Time", "iax2.abstime",
2645 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2646 "The absolute time of this packet (calculated by adding the IAX timestamp to the start time of this call)",
2650 {"Lateness", "iax2.lateness",
2651 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x0,
2652 "The lateness of this packet compared to its timestamp",
2655 {&hf_iax2_minividmarker
,
2656 {"Marker", "iax2.video.mini_marker",
2657 FT_UINT16
, BASE_DEC
, NULL
, 0x8000,
2658 "RTP end-of-frame marker",
2662 {"Outbound seq.no.", "iax2.oseqno",
2663 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2664 "oseqno is the sequence no of this packet. The first packet has oseqno==0,"
2665 " and subsequent packets increment the oseqno by 1",
2669 {"Inbound seq.no.", "iax2.iseqno",
2670 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2671 "iseqno is the sequence no of the last successfully received packet",
2675 {"Type", "iax2.type",
2676 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &iax_frame_types_ext
, 0x0,
2677 "For full IAX2 frames, type is the type of frame",
2681 {"Unknown subclass", "iax2.subclass",
2682 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2683 "Subclass of unknown type of full IAX2 frame",
2686 {&hf_iax2_dtmf_csub
,
2687 {"DTMF subclass (digit)", "iax2.dtmf.subclass",
2688 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
2689 "DTMF subclass gives the DTMF digit",
2693 {"Control subclass", "iax2.control.subclass",
2694 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &iax_cmd_subclasses_ext
, 0x0,
2695 "This gives the command number for a Control packet.",
2699 {"IAX subclass", "iax2.iax.subclass",
2700 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &iax_iax_subclasses_ext
, 0x0,
2701 "IAX subclass gives the command number for IAX signaling packets",
2704 {&hf_iax2_voice_csub
,
2705 {"Voice Subclass (compressed codec no)", "iax2.voice.subclass",
2706 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2709 {&hf_iax2_voice_codec
,
2710 {"CODEC", "iax2.voice.codec",
2711 FT_UINT64
, BASE_HEX
| BASE_EXT_STRING
| BASE_VAL64_STRING
, &codec_types_ext
, 0x0,
2712 "CODEC gives the codec used to encode audio data",
2715 {&hf_iax2_video_csub
,
2716 {"Video Subclass (compressed codec no)", "iax2.video.subclass",
2717 FT_UINT8
, BASE_DEC
, NULL
, 0xBF,
2721 {"Marker", "iax2.video.marker",
2722 FT_BOOLEAN
, 8, NULL
, 0x40,
2723 "RTP end-of-frame marker",
2726 {&hf_iax2_video_codec
,
2727 {"CODEC", "iax2.video.codec",
2728 FT_UINT64
, BASE_HEX
| BASE_EXT_STRING
| BASE_VAL64_STRING
, &codec_types_ext
, 0,
2729 "The codec used to encode video data",
2732 {&hf_iax2_modem_csub
,
2733 {"Modem subclass", "iax2.modem.subclass",
2734 FT_UINT8
, BASE_DEC
, VALS(iax_modem_subclasses
), 0x0,
2735 "Modem subclass gives the type of modem",
2738 {&hf_iax2_text_csub
,
2739 {"Text subclass", "iax2.text.subclass",
2740 FT_UINT8
, BASE_DEC
, VALS(iax_text_subclasses
), 0x0,
2744 {&hf_iax2_text_text
,
2745 {"Text", "iax2.text.text",
2746 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2750 {&hf_iax2_html_csub
,
2751 {"HTML subclass", "iax2.html.subclass",
2752 FT_UINT8
, BASE_DEC
, VALS(iax_html_subclasses
), 0x0,
2757 {"HTML URL", "iax2.html.url",
2758 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2763 {"Timestamp", "iax2.timestamp",
2764 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2765 "timestamp is the time, in ms after the start of Command data this call,"
2766 " at which this trunk packet was transmitted",
2769 {&hf_iax2_trunk_metacmd
,
2770 {"Meta command", "iax2.trunk.metacmd",
2771 FT_UINT8
, BASE_DEC
, NULL
, 0x7F,
2772 "Meta command indicates whether or not the Meta Frame is a trunk.",
2775 {&hf_iax2_trunk_cmddata
,
2776 {"Command data", "iax2.trunk.cmddata",
2777 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2778 "Flags for options that apply to a trunked call",
2781 {&hf_iax2_trunk_cmddata_ts
,
2782 {"Trunk timestamps", "iax2.trunk.cmddata.ts",
2783 FT_BOOLEAN
, 8, NULL
, IAX2_TRUNK_TS
,
2784 "True: calls do each include their own timestamp",
2787 {&hf_iax2_trunk_call_len
,
2788 {"Data length", "iax2.trunk.call.len",
2789 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2790 "Trunk call data length in octets",
2793 {&hf_iax2_trunk_call_scallno
,
2794 {"Source call number", "iax2.trunk.call.scallno",
2795 FT_UINT16
, BASE_DEC
, NULL
, 0x7FFF,
2796 "Trunk call source call number",
2799 {&hf_iax2_trunk_call_ts
,
2800 {"Timestamp", "iax2.trunk.call.ts",
2801 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2802 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2805 {&hf_iax2_trunk_call_data
,
2806 {"Data", "iax2.trunk.call.payload",
2807 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2808 "Payload carried by this trunked packet.",
2811 {&hf_iax2_trunk_ncalls
,
2812 {"Number of calls", "iax2.trunk.ncalls",
2813 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2814 "Number of calls in this trunk packet",
2818 * Decoding for the ies
2821 {&hf_IAX_IE_APPARENTADDR_SINFAMILY
,
2822 {"Family", "iax2.iax.app_addr.sinfamily",
2823 FT_UINT16
, BASE_DEC
, NULL
, 0,
2826 {&hf_IAX_IE_APPARENTADDR_SINPORT
,
2827 {"Port", "iax2.iax.app_addr.sinport",
2828 FT_UINT16
, BASE_DEC
, NULL
, 0,
2831 {&hf_IAX_IE_APPARENTADDR_SINADDR
,
2832 {"Address", "iax2.iax.app_addr.sinaddr",
2833 FT_IPv4
, BASE_NONE
, NULL
, 0,
2836 {&hf_iax2_ies
[IAX_IE_CALLED_NUMBER
],
2837 {"Number/extension being called", "iax2.iax.called_number",
2839 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2841 {&hf_iax2_ies
[IAX_IE_CALLING_NUMBER
],
2842 {"Calling number", "iax2.iax.calling_number",
2843 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2847 {&hf_iax2_ies
[IAX_IE_CALLING_ANI
],
2848 {"Calling number ANI for billing", "iax2.iax.calling_ani",
2849 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2852 {&hf_iax2_ies
[IAX_IE_CALLING_NAME
],
2853 {"Name of caller", "iax2.iax.calling_name",
2854 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2857 {&hf_iax2_ies
[IAX_IE_CALLED_CONTEXT
],
2858 {"Context for number", "iax2.iax.called_context",
2859 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2862 {&hf_iax2_ies
[IAX_IE_USERNAME
],
2863 {"Username (peer or user) for authentication", "iax2.iax.username",
2864 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2867 {&hf_iax2_ies
[IAX_IE_PASSWORD
],
2868 {"Password for authentication", "iax2.iax.password",
2869 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2872 {&hf_iax2_ies
[IAX_IE_CAPABILITY
],
2873 {"Actual codec capability", "iax2.iax.capability",
2874 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2877 {&hf_iax2_ies
[IAX_IE_FORMAT
],
2878 {"Desired codec format", "iax2.iax.format",
2879 FT_UINT64
, BASE_HEX
| BASE_EXT_STRING
| BASE_VAL64_STRING
, &codec_types_ext
, 0x0,
2882 {&hf_iax2_ies
[IAX_IE_LANGUAGE
],
2883 {"Desired language", "iax2.iax.language",
2884 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2887 {&hf_iax2_ies
[IAX_IE_VERSION
],
2888 {"Protocol version", "iax2.iax.version",
2889 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2892 {&hf_iax2_ies
[IAX_IE_ADSICPE
],
2893 {"CPE ADSI capability", "iax2.iax.cpe_adsi",
2894 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2897 {&hf_iax2_ies
[IAX_IE_DNID
],
2898 {"Originally dialed DNID", "iax2.iax.dnid",
2899 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2902 {&hf_iax2_ies
[IAX_IE_AUTHMETHODS
],
2903 {"Authentication method(s)", "iax2.iax.auth.methods",
2904 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2907 {&hf_iax2_ies
[IAX_IE_CHALLENGE
],
2908 {"Challenge data for MD5/RSA", "iax2.iax.auth.challenge",
2909 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2912 {&hf_iax2_ies
[IAX_IE_MD5_RESULT
],
2913 {"MD5 challenge result", "iax2.iax.auth.md5",
2914 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2917 {&hf_iax2_ies
[IAX_IE_RSA_RESULT
],
2918 {"RSA challenge result", "iax2.iax.auth.rsa",
2919 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2922 {&hf_iax2_ies
[IAX_IE_REFRESH
],
2923 {"When to refresh registration", "iax2.iax.refresh",
2924 FT_INT16
, BASE_DEC
, NULL
, 0x0,
2927 {&hf_iax2_ies
[IAX_IE_DPSTATUS
],
2928 {"Dialplan status", "iax2.iax.dialplan_status",
2929 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2932 {&hf_iax2_ies
[IAX_IE_CALLNO
],
2933 {"Call number of peer", "iax2.iax.call_no",
2934 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2937 {&hf_iax2_ies
[IAX_IE_CAUSE
],
2938 {"Cause", "iax2.iax.cause",
2939 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2942 {&hf_iax2_ies
[IAX_IE_IAX_UNKNOWN
],
2943 {"Unknown IAX command", "iax2.iax.iax_unknown",
2944 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2947 {&hf_iax2_ies
[IAX_IE_MSGCOUNT
],
2948 {"How many messages waiting", "iax2.iax.msg_count",
2949 FT_INT16
, BASE_DEC
, NULL
, 0x0,
2952 {&hf_iax2_ies
[IAX_IE_AUTOANSWER
],
2953 {"Request auto-answering", "iax2.iax.autoanswer",
2954 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2957 {&hf_iax2_ies
[IAX_IE_MUSICONHOLD
],
2958 {"Request musiconhold with QUELCH", "iax2.iax.moh",
2959 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2962 {&hf_iax2_ies
[IAX_IE_TRANSFERID
],
2963 {"Transfer Request Identifier", "iax2.iax.transferid",
2964 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2967 {&hf_iax2_ies
[IAX_IE_RDNIS
],
2968 {"Referring DNIS", "iax2.iax.rdnis",
2969 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2972 {&hf_iax2_ies
[IAX_IE_PROVISIONING
],
2973 {"Provisioning info", "iax2.iax.provisioning",
2974 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2977 {&hf_iax2_ies
[IAX_IE_AESPROVISIONING
],
2978 {"AES Provisioning info", "iax2.iax.aesprovisioning",
2979 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2982 {&hf_iax2_ies
[IAX_IE_DATETIME
],
2983 {"Date/Time", "iax2.iax.datetime.raw",
2984 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2987 {&hf_iax2_ie_datetime
,
2988 {"Date/Time", "iax2.iax.datetime",
2989 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
2992 {&hf_iax2_ies
[IAX_IE_DEVICETYPE
],
2993 {"Device type", "iax2.iax.devicetype",
2994 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2997 {&hf_iax2_ies
[IAX_IE_SERVICEIDENT
],
2998 {"Service identifier", "iax2.iax.serviceident",
2999 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3002 {&hf_iax2_ies
[IAX_IE_FIRMWAREVER
],
3003 {"Firmware version", "iax2.iax.firmwarever",
3004 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3007 {&hf_iax2_ies
[IAX_IE_FWBLOCKDESC
],
3008 {"Firmware block description", "iax2.iax.fwblockdesc",
3009 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3012 {&hf_iax2_ies
[IAX_IE_FWBLOCKDATA
],
3013 {"Firmware block of data", "iax2.iax.fwblockdata",
3014 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3017 {&hf_iax2_ies
[IAX_IE_PROVVER
],
3018 {"Provisioning version", "iax2.iax.provver",
3019 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3022 {&hf_iax2_ies
[IAX_IE_CALLINGPRES
],
3023 {"Calling presentation", "iax2.iax.callingpres",
3024 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
3027 {&hf_iax2_ies
[IAX_IE_CALLINGTON
],
3028 {"Calling type of number", "iax2.iax.callington",
3029 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
3032 {&hf_iax2_ies
[IAX_IE_CALLINGTNS
],
3033 {"Calling transit network select", "iax2.iax.callingtns",
3034 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3037 {&hf_iax2_ies
[IAX_IE_SAMPLINGRATE
],
3038 {"Supported sampling rates", "iax2.iax.samplingrate",
3039 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3042 {&hf_iax2_ies
[IAX_IE_CAUSECODE
],
3043 {"Hangup cause", "iax2.iax.causecode",
3044 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &iax_causecodes_ext
, 0x0,
3047 {&hf_iax2_ies
[IAX_IE_ENCRYPTION
],
3048 {"Encryption format", "iax2.iax.encryption",
3049 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3052 {&hf_iax2_ies
[IAX_IE_ENCKEY
],
3053 {"Encryption key", "iax2.iax.enckey",
3054 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3057 {&hf_iax2_ies
[IAX_IE_CODEC_PREFS
],
3058 {"Codec negotiation", "iax2.iax.codecprefs",
3059 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3062 {&hf_iax2_ies
[IAX_IE_RR_JITTER
],
3063 {"Received jitter (as in RFC1889)", "iax2.iax.rrjitter",
3064 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3067 {&hf_iax2_ies
[IAX_IE_RR_LOSS
],
3068 {"Received loss (high byte loss pct, low 24 bits loss count, as in rfc1889)", "iax2.iax.rrloss",
3069 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3072 {&hf_iax2_ies
[IAX_IE_RR_PKTS
],
3073 {"Total frames received", "iax2.iax.rrpkts",
3074 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3077 {&hf_iax2_ies
[IAX_IE_RR_DELAY
],
3078 {"Max playout delay in ms for received frames", "iax2.iax.rrdelay",
3079 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3082 {&hf_iax2_ies
[IAX_IE_RR_DROPPED
],
3083 {"Dropped frames (presumably by jitterbuffer)", "iax2.iax.rrdropped",
3084 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3087 {&hf_iax2_ies
[IAX_IE_RR_OOO
],
3088 {"Frame received out of order", "iax2.iax.rrooo",
3089 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3092 {&hf_iax2_ies
[IAX_IE_CAPABILITY2
],
3093 {"64-bit codec capability", "iax2.iax.capability2",
3094 FT_UINT64
, BASE_HEX
, NULL
, 0x0,
3097 {&hf_iax2_ies
[IAX_IE_FORMAT2
],
3098 {"64-bit codec format", "iax2.iax.format2",
3099 FT_UINT64
, BASE_HEX
| BASE_EXT_STRING
| BASE_VAL64_STRING
, &codec_types_ext
, 0x0,
3102 {&hf_iax2_ies
[IAX_IE_DATAFORMAT
],
3103 {"Data call format", "iax2.iax.dataformat",
3104 FT_UINT32
, BASE_HEX
, VALS(iax_dataformats
), 0x0,
3107 {&hf_IAX_IE_UNKNOWN_BYTE
,
3108 {"Unknown", "iax2.iax.unknownbyte",
3109 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
3110 "Raw data for unknown IEs", HFILL
}},
3112 {&hf_IAX_IE_UNKNOWN_I16
,
3113 {"Unknown", "iax2.iax.unknownshort",
3114 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
3115 "Raw data for unknown IEs", HFILL
}},
3117 {&hf_IAX_IE_UNKNOWN_I32
,
3118 {"Unknown", "iax2.iax.unknownlong",
3119 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3120 "Raw data for unknown IEs", HFILL
}},
3122 {&hf_IAX_IE_UNKNOWN_BYTES
,
3123 {"Unknown", "iax2.iax.unknownstring",
3124 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3125 "Raw data for unknown IEs", HFILL
}},
3128 {"IE id", "iax2.ie_id",
3129 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &iax_ies_type_ext
, 0x0,
3133 {"Length", "iax2.length",
3134 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3138 {"Version", "iax2.version",
3139 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3143 {&hf_iax2_cap_g723_1
,
3144 {"G.723.1 compression", "iax2.cap.g723_1",
3145 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_G723_1
),
3149 {"GSM compression", "iax2.cap.gsm",
3150 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_GSM
),
3154 {"Raw mu-law data (G.711)", "iax2.cap.ulaw",
3155 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_ULAW
),
3159 {"Raw A-law data (G.711)", "iax2.cap.alaw",
3160 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_ALAW
),
3163 {&hf_iax2_cap_g726_aal2
,
3164 {"ADPCM (G.726, 32kbps, AAL2 codeword packing)", "iax2.cap.g726_aal2",
3165 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_G726_AAL2
),
3168 {&hf_iax2_cap_adpcm
,
3169 {"ADPCM", "iax2.cap.adpcm",
3170 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_ADPCM
),
3173 {&hf_iax2_cap_slinear
,
3174 {"Raw 16-bit Signed Linear (8000 Hz) PCM", "iax2.cap.slinear",
3175 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_SLINEAR
),
3178 {&hf_iax2_cap_lpc10
,
3179 {"LPC10, 180 samples/frame", "iax2.cap.lpc10",
3180 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_LPC10
),
3183 {&hf_iax2_cap_g729a
,
3184 {"G.729a Audio", "iax2.cap.g729a",
3185 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_G729A
),
3188 {&hf_iax2_cap_speex
,
3189 {"SpeeX Free Compression", "iax2.cap.speex",
3190 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_SPEEX
),
3194 {"iLBC Free Compression", "iax2.cap.ilbc",
3195 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_ILBC
),
3199 {"ADPCM (G.726, 32kbps, RFC3551 codeword packing)", "iax2.cap.g726",
3200 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_G726
),
3204 {"G.722", "iax2.cap.g722",
3205 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_G722
),
3208 {&hf_iax2_cap_siren7
,
3209 {"G.722.1 (also known as Siren7, 32kbps assumed)", "iax2.cap.siren7",
3210 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_SIREN7
),
3213 {&hf_iax2_cap_siren14
,
3214 {"G.722.1 Annex C (also known as Siren14, 48kbps assumed)", "iax2.cap.siren14",
3215 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_SIREN14
),
3218 {&hf_iax2_cap_slinear16
,
3219 {"Raw 16-bit Signed Linear (16000 Hz) PCM", "iax2.cap.slinear16",
3220 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_SLINEAR16
),
3224 {"JPEG images", "iax2.cap.jpeg",
3225 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_JPEG
),
3229 {"PNG images", "iax2.cap.png",
3230 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_PNG
),
3234 {"H.261 video", "iax2.cap.h261",
3235 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_H261
),
3239 {"H.263 video", "iax2.cap.h263",
3240 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_H263
),
3243 {&hf_iax2_cap_h263_plus
,
3244 {"H.263+ video", "iax2.cap.h263_plus",
3245 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_H263_PLUS
),
3249 {"H.264 video", "iax2.cap.h264",
3250 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_H264
),
3253 {&hf_iax2_cap_mpeg4
,
3254 {"MPEG4 video", "iax2.cap.mpeg4",
3255 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_MP4_VIDEO
),
3259 {"VP8 video", "iax2.cap.vp8",
3260 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_VP8
),
3263 {&hf_iax2_cap_t140_red
,
3264 {"T.140 RED Text format RFC 4103", "iax2.cap.t140_red",
3265 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_T140_RED
),
3269 {"T.140 Text format - ITU T.140, RFC 4103", "iax2.cap.t140",
3270 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_T140
),
3274 {"G.719 (64 kbps assumed)", "iax2.cap.g719",
3275 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_G719
),
3278 {&hf_iax2_cap_speex16
,
3279 {"SpeeX Wideband (16kHz) Free Compression", "iax2.cap.speex16",
3280 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_SPEEX16
),
3284 {"Opus audio (8kHz, 16kHz, 24kHz, 48Khz)", "iax2.cap.opus",
3285 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_OPUS
),
3288 {&hf_iax2_cap_testlaw
,
3289 {"Raw testing-law data (G.711)", "iax2.cap.testlaw",
3290 FT_BOOLEAN
, 64, TFS(&tfs_supported_not_supported
), CODEC_MASK(AST_FORMAT_TESTLAW
),
3293 {&hf_iax2_fragment_unfinished
,
3294 {"IAX2 fragment, unfinished", "iax2.fragment_unfinished",
3295 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3298 {&hf_iax2_payload_data
,
3299 {"IAX2 payload", "iax2.payload_data",
3300 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3303 /* reassembly stuff */
3304 {&hf_iax2_fragments
,
3305 {"IAX2 Fragments", "iax2.fragments",
3306 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3310 {"IAX2 Fragment data", "iax2.fragment",
3311 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
3314 {&hf_iax2_fragment_overlap
,
3315 {"Fragment overlap", "iax2.fragment.overlap",
3316 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
3317 "Fragment overlaps with other fragments", HFILL
}},
3319 {&hf_iax2_fragment_overlap_conflict
,
3320 {"Conflicting data in fragment overlap", "iax2.fragment.overlap.conflict",
3321 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
3322 "Overlapping fragments contained conflicting data", HFILL
}},
3324 {&hf_iax2_fragment_multiple_tails
,
3325 {"Multiple tail fragments found", "iax2.fragment.multipletails",
3326 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
3327 "Several tails were found when defragmenting the packet", HFILL
}},
3329 {&hf_iax2_fragment_too_long_fragment
,
3330 {"Fragment too long", "iax2.fragment.toolongfragment",
3331 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
3332 "Fragment contained data past end of packet", HFILL
}},
3334 {&hf_iax2_fragment_error
,
3335 {"Defragmentation error", "iax2.fragment.error",
3336 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
3337 "Defragmentation error due to illegal fragments", HFILL
}},
3339 {&hf_iax2_fragment_count
,
3340 {"Fragment count", "iax2.fragment.count",
3341 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3344 {&hf_iax2_reassembled_in
,
3345 {"IAX2 fragment, reassembled in frame", "iax2.reassembled_in",
3346 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
3347 "This IAX2 packet is reassembled in this frame", HFILL
}},
3349 {&hf_iax2_reassembled_length
,
3350 {"Reassembled IAX2 length", "iax2.reassembled.length",
3351 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3352 "The total length of the reassembled payload", HFILL
}}
3355 static int *ett
[] = {
3357 &ett_iax2_full_mini_subtree
,
3361 &ett_iax2_ies_apparent_addr
,
3363 &ett_iax2_fragments
,
3364 &ett_iax2_trunk_cmddata
,
3365 &ett_iax2_trunk_call
3368 static ei_register_info ei
[] = {
3369 { &ei_iax_too_many_transfers
, { "iax2.too_many_transfers", PI_PROTOCOL
, PI_WARN
, "Too many transfers for iax_call", EXPFILL
}},
3370 { &ei_iax_circuit_id_conflict
, { "iax2.circuit_id_conflict", PI_PROTOCOL
, PI_WARN
, "Circuit ID conflict", EXPFILL
}},
3371 { &ei_iax_peer_address_unsupported
, { "iax2.peer_address_unsupported", PI_PROTOCOL
, PI_WARN
, "Peer address unsupported", EXPFILL
}},
3372 { &ei_iax_invalid_len
, { "iax2.invalid_len", PI_PROTOCOL
, PI_WARN
, "Invalid length", EXPFILL
}},
3375 expert_module_t
* expert_iax
;
3377 proto_iax2
= proto_register_protocol("Inter-Asterisk eXchange v2", "IAX2", "iax2");
3378 proto_register_field_array(proto_iax2
, hf
, array_length(hf
));
3379 proto_register_subtree_array(ett
, array_length(ett
));
3380 expert_iax
= expert_register_protocol(proto_iax2
);
3381 expert_register_field_array(expert_iax
, ei
, array_length(ei
));
3383 iax2_handle
= register_dissector("iax2", dissect_iax2
, proto_iax2
);
3385 iax2_codec_dissector_table
= register_dissector_table(
3386 "iax2.codec", "IAX codec number", proto_iax2
, FT_UINT32
, BASE_HEX
);
3387 iax2_dataformat_dissector_table
= register_dissector_table(
3388 "iax2.dataformat", "IAX dataformat number", proto_iax2
, FT_UINT32
, BASE_HEX
);
3390 /* register our init routine to be called at the start of a capture,
3391 to clear out our hash tables etc */
3392 register_init_routine(&iax_init_protocol
);
3393 register_cleanup_routine(&iax_cleanup_protocol
);
3394 reassembly_table_register(&iax_reassembly_table
,
3395 &addresses_reassembly_table_functions
);
3397 iax2_tap
= register_tap("IAX2");
3401 proto_reg_handoff_iax2(void)
3403 dissector_handle_t v110_handle
;
3405 dissector_add_uint_with_preference("udp.port", IAX2_PORT
, iax2_handle
);
3406 v110_handle
= find_dissector("v110");
3408 dissector_add_uint("iax2.dataformat", AST_DATAFORMAT_V110
, v110_handle
);
3417 * indent-tabs-mode: nil
3420 * ex: set shiftwidth=2 tabstop=8 expandtab:
3421 * :indentSize=2:tabSize=8:noTabs=true: