Bug Summary

File:epan/dissectors/packet-iax2.c
Warning:line 1459, column 13
Null pointer passed to 2nd parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-iax2.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-20/lib/clang/20 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-20/lib/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-09-13-101102-3933-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-iax2.c
1 /*
2 * packet-iax2.c
3 *
4 * Routines for IAX2 packet disassembly
5 * By Alastair Maw <[email protected]>
6 * Copyright 2003 Alastair Maw
7 *
8 * IAX2 is a VoIP protocol for the open source PBX Asterisk. Please see
9 * http://www.asterisk.org for more information; see RFC 5456 for the
10 * protocol.
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <[email protected]>
14 * Copyright 1998 Gerald Combs
15 *
16 * SPDX-License-Identifier: GPL-2.0-or-later
17 */
18
19#include "config.h"
20
21
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>
27#include <epan/tap.h>
28#include <epan/proto_data.h>
29#include <epan/tfs.h>
30#include <wsutil/array.h>
31#include <wsutil/str_util.h>
32
33#include "packet-iax2.h"
34#include <epan/iax2_codec_type.h>
35
36void proto_register_iax2(void);
37void proto_reg_handoff_iax2(void);
38
39#define IAX2_PORT4569 4569
40#define PROTO_TAG_IAX2"IAX2" "IAX2"
41
42/* enough to hold any address in an address_t */
43#define MAX_ADDRESS16 16
44
45/* the maximum number of transfers (of each end) we can deal with per call,
46 * plus one */
47#define IAX_MAX_TRANSFERS2 2
48
49/* #define DEBUG_HASHING */
50/* #define DEBUG_DESEGMENT */
51
52/* Wireshark ID of the IAX2 protocol */
53static int proto_iax2;
54
55/* tap register id */
56static int iax2_tap;
57
58/* protocol tap info */
59static iax2_info_t ii_arr[1];
60static iax2_info_t *iax2_info = ii_arr;
61
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()
65 */
66static int hf_iax2_packet_type;
67static int hf_iax2_retransmission;
68static int hf_iax2_callno;
69static int hf_iax2_scallno;
70static int hf_iax2_dcallno;
71static int hf_iax2_ts;
72static int hf_iax2_minits;
73static int hf_iax2_minividts;
74static int hf_iax2_absts;
75static int hf_iax2_lateness;
76static int hf_iax2_minividmarker;
77static int hf_iax2_oseqno;
78static int hf_iax2_iseqno;
79static int hf_iax2_type;
80static int hf_iax2_csub;
81static int hf_iax2_dtmf_csub;
82static int hf_iax2_cmd_csub;
83static int hf_iax2_iax_csub;
84static int hf_iax2_voice_csub;
85static int hf_iax2_voice_codec;
86static int hf_iax2_video_csub;
87static int hf_iax2_video_codec;
88static int hf_iax2_marker;
89static int hf_iax2_modem_csub;
90static int hf_iax2_text_csub;
91static int hf_iax2_text_text;
92static int hf_iax2_html_csub;
93static int hf_iax2_html_url;
94static int hf_iax2_trunk_metacmd;
95static int hf_iax2_trunk_cmddata;
96static int hf_iax2_trunk_cmddata_ts;
97static int hf_iax2_trunk_ts;
98static int hf_iax2_trunk_ncalls;
99static int hf_iax2_trunk_call_len;
100static int hf_iax2_trunk_call_scallno;
101static int hf_iax2_trunk_call_ts;
102static int hf_iax2_trunk_call_data;
103
104static int hf_iax2_ie_id;
105static int hf_iax2_length;
106static int hf_iax2_version;
107static int hf_iax2_cap_g723_1;
108static int hf_iax2_cap_gsm;
109static int hf_iax2_cap_ulaw;
110static int hf_iax2_cap_alaw;
111static int hf_iax2_cap_g726_aal2;
112static int hf_iax2_cap_adpcm;
113static int hf_iax2_cap_slinear;
114static int hf_iax2_cap_lpc10;
115static int hf_iax2_cap_g729a;
116static int hf_iax2_cap_speex;
117static int hf_iax2_cap_ilbc;
118static int hf_iax2_cap_g726;
119static int hf_iax2_cap_g722;
120static int hf_iax2_cap_siren7;
121static int hf_iax2_cap_siren14;
122static int hf_iax2_cap_slinear16;
123static int hf_iax2_cap_jpeg;
124static int hf_iax2_cap_png;
125static int hf_iax2_cap_h261;
126static int hf_iax2_cap_h263;
127static int hf_iax2_cap_h263_plus;
128static int hf_iax2_cap_h264;
129static int hf_iax2_cap_mpeg4;
130static int hf_iax2_cap_vp8;
131static int hf_iax2_cap_t140_red;
132static int hf_iax2_cap_t140;
133static int hf_iax2_cap_g719;
134static int hf_iax2_cap_speex16;
135static int hf_iax2_cap_opus;
136static int hf_iax2_cap_testlaw;
137
138static int * const hf_iax2_caps[] = {
139 &hf_iax2_cap_g723_1,
140 &hf_iax2_cap_gsm,
141 &hf_iax2_cap_ulaw,
142 &hf_iax2_cap_alaw,
143 &hf_iax2_cap_g726_aal2,
144 &hf_iax2_cap_adpcm,
145 &hf_iax2_cap_slinear,
146 &hf_iax2_cap_lpc10,
147 &hf_iax2_cap_g729a,
148 &hf_iax2_cap_speex,
149 &hf_iax2_cap_ilbc,
150 &hf_iax2_cap_g726,
151 &hf_iax2_cap_g722,
152 &hf_iax2_cap_siren7,
153 &hf_iax2_cap_siren14,
154 &hf_iax2_cap_slinear16,
155 &hf_iax2_cap_jpeg,
156 &hf_iax2_cap_png,
157 &hf_iax2_cap_h261,
158 &hf_iax2_cap_h263,
159 &hf_iax2_cap_h263_plus,
160 &hf_iax2_cap_h264,
161 &hf_iax2_cap_mpeg4,
162 &hf_iax2_cap_vp8,
163 &hf_iax2_cap_t140_red,
164 &hf_iax2_cap_t140,
165 &hf_iax2_cap_g719,
166 &hf_iax2_cap_speex16,
167 &hf_iax2_cap_opus,
168 &hf_iax2_cap_testlaw,
169 NULL((void*)0)
170};
171
172static int hf_iax2_fragment_unfinished;
173static int hf_iax2_payload_data;
174static int hf_iax2_fragments;
175static int hf_iax2_fragment;
176static int hf_iax2_fragment_overlap;
177static int hf_iax2_fragment_overlap_conflict;
178static int hf_iax2_fragment_multiple_tails;
179static int hf_iax2_fragment_too_long_fragment;
180static int hf_iax2_fragment_error;
181static int hf_iax2_fragment_count;
182static int hf_iax2_reassembled_in;
183static int hf_iax2_reassembled_length;
184
185
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
189 * orthogonal.
190 *
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.
194 */
195#define NUM_HF_IAX2_IES256 256
196static int hf_iax2_ies[NUM_HF_IAX2_IES256];
197static int hf_iax2_ie_datetime;
198static int hf_IAX_IE_APPARENTADDR_SINFAMILY;
199static int hf_IAX_IE_APPARENTADDR_SINPORT;
200static int hf_IAX_IE_APPARENTADDR_SINADDR;
201static int hf_IAX_IE_UNKNOWN_BYTE;
202static int hf_IAX_IE_UNKNOWN_I16;
203static int hf_IAX_IE_UNKNOWN_I32;
204static int hf_IAX_IE_UNKNOWN_BYTES;
205
206/* These are the ids of the subtrees that we may be creating */
207static int ett_iax2;
208static int ett_iax2_full_mini_subtree;
209static int ett_iax2_type; /* Frame-type specific subtree */
210static int ett_iax2_ie; /* single IE */
211static int ett_iax2_codecs; /* capabilities IE */
212static int ett_iax2_ies_apparent_addr; /* apparent address IE */
213static int ett_iax2_fragment;
214static int ett_iax2_fragments;
215static int ett_iax2_trunk_cmddata;
216static int ett_iax2_trunk_call;
217
218static expert_field ei_iax_too_many_transfers;
219static expert_field ei_iax_circuit_id_conflict;
220static expert_field ei_iax_peer_address_unsupported;
221static expert_field ei_iax_invalid_len;
222
223static dissector_handle_t iax2_handle;
224
225static const fragment_items iax2_fragment_items = {
226 &ett_iax2_fragment,
227 &ett_iax2_fragments,
228 &hf_iax2_fragments,
229 &hf_iax2_fragment,
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 */
239 NULL((void*)0),
240 "iax2 fragments"
241};
242
243/* data-call subdissectors, AST_DATAFORMAT_* */
244static dissector_table_t iax2_dataformat_dissector_table;
245/* voice/video call subdissectors, AST_FORMAT_* */
246static dissector_table_t iax2_codec_dissector_table;
247
248
249/* IAX2 Meta trunk packet Command data flags */
250#define IAX2_TRUNK_TS1 1
251
252/* IAX2 Full-frame types */
253static const value_string iax_frame_types[] = {
254 {0, "(0?)"},
255 {AST_FRAME_DTMF_END1, "DTMF End"},
256 {AST_FRAME_VOICE2, "Voice"},
257 {AST_FRAME_VIDEO3, "Video"},
258 {AST_FRAME_CONTROL4, "Control"},
259 {AST_FRAME_NULL5, "NULL"},
260 {AST_FRAME_IAX6, "IAX"},
261 {AST_FRAME_TEXT7, "Text"},
262 {AST_FRAME_IMAGE8, "Image"},
263 {AST_FRAME_HTML9, "HTML"},
264 {AST_FRAME_CNG10, "Comfort Noise"},
265 {AST_FRAME_MODEM11, "Modem"},
266 {AST_FRAME_DTMF_BEGIN12, "DTMF Begin"},
267 {0, NULL((void*)0)}
268};
269static value_string_ext iax_frame_types_ext = VALUE_STRING_EXT_INIT(iax_frame_types){ _try_val_to_str_ext_init, 0, (sizeof (iax_frame_types) / sizeof
((iax_frame_types)[0]))-1, iax_frame_types, "iax_frame_types"
, ((void*)0) }
;
270
271/* Subclasses for IAX packets */
272static const value_string iax_iax_subclasses[] = {
273 { 0, "(0?)"},
274 { 1, "NEW"},
275 { 2, "PING"},
276 { 3, "PONG"},
277 { 4, "ACK"},
278 { 5, "HANGUP"},
279 { 6, "REJECT"},
280 { 7, "ACCEPT"},
281 { 8, "AUTHREQ"},
282 { 9, "AUTHREP"},
283 {10, "INVAL"},
284 {11, "LAGRQ"},
285 {12, "LAGRP"},
286 {13, "REGREQ"},
287 {14, "REGAUTH"},
288 {15, "REGACK"},
289 {16, "REGREJ"},
290 {17, "REGREL"},
291 {18, "VNAK"},
292 {19, "DPREQ"},
293 {20, "DPREP"},
294 {21, "DIAL"},
295 {22, "TXREQ"},
296 {23, "TXCNT"},
297 {24, "TXACC"},
298 {25, "TXREADY"},
299 {26, "TXREL"},
300 {27, "TXREJ"},
301 {28, "QUELCH"},
302 {29, "UNQULCH"},
303 {30, "POKE"},
304 {31, "PAGE"},
305 {32, "MWI"},
306 {33, "UNSUPPORTED"},
307 {34, "TRANSFER"},
308 {35, "PROVISION"},
309 {36, "FWDOWNL"},
310 {37, "FWDATA"},
311 {38, "TXMEDIA"},
312 {39, "RTKEY"},
313 {40, "CALLTOKEN"},
314 {0, NULL((void*)0)}
315};
316static value_string_ext iax_iax_subclasses_ext = VALUE_STRING_EXT_INIT(iax_iax_subclasses){ _try_val_to_str_ext_init, 0, (sizeof (iax_iax_subclasses) /
sizeof ((iax_iax_subclasses)[0]))-1, iax_iax_subclasses, "iax_iax_subclasses"
, ((void*)0) }
;
317
318/* Subclasses for Control packets */
319static const value_string iax_cmd_subclasses[] = {
320 {0, "(0?)"},
321 {1, "HANGUP"},
322 {2, "RING"},
323 {3, "RINGING"},
324 {4, "ANSWER"},
325 {5, "BUSY"},
326 {6, "TKOFFHK"},
327 {7, "OFFHOOK"},
328 {0xFF, "stop sounds"}, /* sent by app_dial, and not much else */
329 {0, NULL((void*)0)}
330};
331static value_string_ext iax_cmd_subclasses_ext = VALUE_STRING_EXT_INIT(iax_cmd_subclasses){ _try_val_to_str_ext_init, 0, (sizeof (iax_cmd_subclasses) /
sizeof ((iax_cmd_subclasses)[0]))-1, iax_cmd_subclasses, "iax_cmd_subclasses"
, ((void*)0) }
;
332
333/* IAX2 to tap-voip call state mapping for command frames */
334static const voip_call_state tap_cmd_voip_state[] = {
335 VOIP_NO_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*/
343};
344#define NUM_TAP_CMD_VOIP_STATES(sizeof (tap_cmd_voip_state) / sizeof (tap_cmd_voip_state)[0]
)
array_length(tap_cmd_voip_state)(sizeof (tap_cmd_voip_state) / sizeof (tap_cmd_voip_state)[0]
)
345
346/* IAX2 to tap-voip call state mapping for IAX frames */
347static const voip_call_state tap_iax_voip_state[] = {
348 VOIP_NO_STATE,
349 VOIP_CALL_SETUP, /*NEW*/
350 VOIP_NO_STATE,
351 VOIP_NO_STATE,
352 VOIP_COMPLETED, /*HANGUP*/
353 VOIP_REJECTED, /*REJECT*/
354 VOIP_RINGING, /*ACCEPT*/
355 VOIP_NO_STATE,
356 VOIP_NO_STATE,
357 VOIP_NO_STATE,
358 VOIP_NO_STATE,
359 VOIP_NO_STATE,
360 VOIP_NO_STATE,
361 VOIP_NO_STATE,
362 VOIP_NO_STATE,
363 VOIP_NO_STATE,
364 VOIP_NO_STATE,
365 VOIP_NO_STATE,
366 VOIP_NO_STATE,
367 VOIP_NO_STATE,
368 VOIP_NO_STATE,
369 VOIP_CALL_SETUP, /*DIAL*/
370 VOIP_NO_STATE,
371 VOIP_NO_STATE,
372 VOIP_NO_STATE,
373 VOIP_NO_STATE,
374 VOIP_NO_STATE,
375 VOIP_NO_STATE,
376 VOIP_NO_STATE,
377 VOIP_NO_STATE,
378 VOIP_NO_STATE,
379 VOIP_NO_STATE,
380 VOIP_NO_STATE,
381 VOIP_NO_STATE,
382 VOIP_NO_STATE,
383 VOIP_NO_STATE,
384 VOIP_NO_STATE,
385 VOIP_NO_STATE
386};
387
388#define NUM_TAP_IAX_VOIP_STATES(sizeof (tap_iax_voip_state) / sizeof (tap_iax_voip_state)[0]
)
array_length(tap_iax_voip_state)(sizeof (tap_iax_voip_state) / sizeof (tap_iax_voip_state)[0]
)
389
390/* Subclasses for Modem packets */
391static const value_string iax_modem_subclasses[] = {
392 {0, "(0?)"},
393 {1, "T.38"},
394 {2, "V.150"},
395 {0, NULL((void*)0)}
396};
397
398/* Subclasses for Text packets */
399static const value_string iax_text_subclasses[] = {
400 {0, "Text"},
401 {0, NULL((void*)0)}
402};
403
404/* Subclasses for HTML packets */
405static const value_string iax_html_subclasses[] = {
406 {0x01, "Sending a URL"},
407 {0x02, "Data frame"},
408 {0x04, "Beginning frame"},
409 {0x08, "End frame"},
410 {0x10, "Load is complete"},
411 {0x11, "Peer does not support HTML"},
412 {0x12, "Link URL"},
413 {0x13, "Unlink URL"},
414 {0x14, "Reject Link URL"},
415 {0, NULL((void*)0)}
416};
417
418
419/* Information elements */
420static const value_string iax_ies_type[] = {
421 {IAX_IE_CALLED_NUMBER1, "Number/extension being called"},
422 {IAX_IE_CALLING_NUMBER2, "Calling number"},
423 {IAX_IE_CALLING_ANI3, "Calling number ANI for billing"},
424 {IAX_IE_CALLING_NAME4, "Name of caller"},
425 {IAX_IE_CALLED_CONTEXT5, "Context for number"},
426 {IAX_IE_USERNAME6, "Username (peer or user) for authentication"},
427 {IAX_IE_PASSWORD7, "Password for authentication"},
428 {IAX_IE_CAPABILITY8, "Actual codec capability"},
429 {IAX_IE_FORMAT9, "Desired codec format"},
430 {IAX_IE_LANGUAGE10, "Desired language"},
431 {IAX_IE_VERSION11, "Protocol version"},
432 {IAX_IE_ADSICPE12, "CPE ADSI capability"},
433 {IAX_IE_DNID13, "Originally dialed DNID"},
434 {IAX_IE_AUTHMETHODS14, "Authentication method(s)"},
435 {IAX_IE_CHALLENGE15, "Challenge data for MD5/RSA"},
436 {IAX_IE_MD5_RESULT16, "MD5 challenge result"},
437 {IAX_IE_RSA_RESULT17, "RSA challenge result"},
438 {IAX_IE_APPARENT_ADDR18, "Apparent address of peer"},
439 {IAX_IE_REFRESH19, "When to refresh registration"},
440 {IAX_IE_DPSTATUS20, "Dialplan status"},
441 {IAX_IE_CALLNO21, "Call number of peer"},
442 {IAX_IE_CAUSE22, "Cause"},
443 {IAX_IE_IAX_UNKNOWN23, "Unknown IAX command"},
444 {IAX_IE_MSGCOUNT24, "How many messages waiting"},
445 {IAX_IE_AUTOANSWER25, "Request auto-answering"},
446 {IAX_IE_MUSICONHOLD26, "Request musiconhold with QUELCH"},
447 {IAX_IE_TRANSFERID27, "Transfer Request Identifier"},
448 {IAX_IE_RDNIS28, "Referring DNIS"},
449 {IAX_IE_PROVISIONING29, "Provisioning info"},
450 {IAX_IE_AESPROVISIONING30, "AES Provisioning info"},
451 {IAX_IE_DATETIME31, "Date/Time"},
452 {IAX_IE_DEVICETYPE32, "Device type"},
453 {IAX_IE_SERVICEIDENT33, "Service Identifier"},
454 {IAX_IE_FIRMWAREVER34, "Firmware revision"},
455 {IAX_IE_FWBLOCKDESC35, "Firmware block description"},
456 {IAX_IE_FWBLOCKDATA36, "Firmware block of data"},
457 {IAX_IE_PROVVER37, "Provisioning version"},
458 {IAX_IE_CALLINGPRES38, "Calling presentation"},
459 {IAX_IE_CALLINGTON39, "Calling type of number"},
460 {IAX_IE_CALLINGTNS40, "Calling transit network select"},
461 {IAX_IE_SAMPLINGRATE41, "Supported sampling rates"},
462 {IAX_IE_CAUSECODE42, "Hangup cause"},
463 {IAX_IE_ENCRYPTION43, "Encryption format"},
464 {IAX_IE_ENCKEY44, "Raw encryption key"},
465 {IAX_IE_CODEC_PREFS45, "Codec preferences"},
466 {IAX_IE_RR_JITTER46, "Received jitter"},
467 {IAX_IE_RR_LOSS47, "Received loss"},
468 {IAX_IE_RR_PKTS48, "Received frames"},
469 {IAX_IE_RR_DELAY49, "Max playout delay in ms for received frames"},
470 {IAX_IE_RR_DROPPED50, "Dropped frames"},
471 {IAX_IE_RR_OOO51, "Frames received out of order"},
472 {IAX_IE_VARIABLE52, "IAX2 variable"},
473 {IAX_IE_OSPTOKEN53, "OSP Token"},
474 {IAX_IE_CALLTOKEN54, "Call Token"},
475 {IAX_IE_CAPABILITY255, "64-bit codec capability"},
476 {IAX_IE_FORMAT256, "64-bit codec format"},
477 {IAX_IE_DATAFORMAT255, "Data call format"},
478 {0, NULL((void*)0)}
479};
480static value_string_ext iax_ies_type_ext = VALUE_STRING_EXT_INIT(iax_ies_type){ _try_val_to_str_ext_init, 0, (sizeof (iax_ies_type) / sizeof
((iax_ies_type)[0]))-1, iax_ies_type, "iax_ies_type", ((void
*)0) }
;
481
482#define CODEC_MASK(codec)((codec) == (uint32_t)-1 ? 0 : (1UL << (codec))) ((codec) == (uint32_t)-1 ? 0 : (UINT64_C(1)1UL << (codec)))
483
484static const val64_string codec_types[] = {
485 {CODEC_MASK(AST_FORMAT_G723_1)((0) == (uint32_t)-1 ? 0 : (1UL << (0))), "G.723.1 compression"},
486 {CODEC_MASK(AST_FORMAT_GSM)((1) == (uint32_t)-1 ? 0 : (1UL << (1))), "GSM compression"},
487 {CODEC_MASK(AST_FORMAT_ULAW)((2) == (uint32_t)-1 ? 0 : (1UL << (2))), "Raw mu-law data (G.711)"},
488 {CODEC_MASK(AST_FORMAT_ALAW)((3) == (uint32_t)-1 ? 0 : (1UL << (3))), "Raw A-law data (G.711)"},
489 {CODEC_MASK(AST_FORMAT_G726_AAL2)((4) == (uint32_t)-1 ? 0 : (1UL << (4))), "ADPCM (G.726), 32kbps, AAL2 codeword packing)"},
490 {CODEC_MASK(AST_FORMAT_ADPCM)((5) == (uint32_t)-1 ? 0 : (1UL << (5))), "ADPCM (IMA)"},
491 {CODEC_MASK(AST_FORMAT_SLINEAR)((6) == (uint32_t)-1 ? 0 : (1UL << (6))), "Raw 16-bit Signed Linear (8000 Hz) PCM"},
492 {CODEC_MASK(AST_FORMAT_LPC10)((7) == (uint32_t)-1 ? 0 : (1UL << (7))), "LPC10, 180 samples/frame"},
493 {CODEC_MASK(AST_FORMAT_G729A)((8) == (uint32_t)-1 ? 0 : (1UL << (8))), "G.729a Audio"},
494 {CODEC_MASK(AST_FORMAT_SPEEX)((9) == (uint32_t)-1 ? 0 : (1UL << (9))), "SpeeX Free Compression"},
495 {CODEC_MASK(AST_FORMAT_ILBC)((10) == (uint32_t)-1 ? 0 : (1UL << (10))), "iLBC Free Compression"},
496 {CODEC_MASK(AST_FORMAT_G726)((11) == (uint32_t)-1 ? 0 : (1UL << (11))), "ADPCM (G.726, 32kbps, RFC3551 codeword packing)"},
497 {CODEC_MASK(AST_FORMAT_G722)((12) == (uint32_t)-1 ? 0 : (1UL << (12))), "G.722"},
498 {CODEC_MASK(AST_FORMAT_SIREN7)((13) == (uint32_t)-1 ? 0 : (1UL << (13))), "G.722.1 (also known as Siren7, 32kbps assumed)"},
499 {CODEC_MASK(AST_FORMAT_SIREN14)((14) == (uint32_t)-1 ? 0 : (1UL << (14))), "G.722.1 Annex C (also known as Siren14, 48kbps assumed)"},
500 {CODEC_MASK(AST_FORMAT_SLINEAR16)((15) == (uint32_t)-1 ? 0 : (1UL << (15))), "Raw 16-bit Signed Linear (16000 Hz) PCM"},
501 {CODEC_MASK(AST_FORMAT_JPEG)((16) == (uint32_t)-1 ? 0 : (1UL << (16))), "JPEG Images"},
502 {CODEC_MASK(AST_FORMAT_PNG)((17) == (uint32_t)-1 ? 0 : (1UL << (17))), "PNG Images"},
503 {CODEC_MASK(AST_FORMAT_H261)((18) == (uint32_t)-1 ? 0 : (1UL << (18))), "H.261 Video"},
504 {CODEC_MASK(AST_FORMAT_H263)((19) == (uint32_t)-1 ? 0 : (1UL << (19))), "H.263 Video"},
505 {CODEC_MASK(AST_FORMAT_H263_PLUS)((20) == (uint32_t)-1 ? 0 : (1UL << (20))), "H.263+ Video"},
506 {CODEC_MASK(AST_FORMAT_H264)((21) == (uint32_t)-1 ? 0 : (1UL << (21))), "H.264 Video"},
507 {CODEC_MASK(AST_FORMAT_MP4_VIDEO)((22) == (uint32_t)-1 ? 0 : (1UL << (22))), "MPEG4 Video"},
508 {CODEC_MASK(AST_FORMAT_VP8)((23) == (uint32_t)-1 ? 0 : (1UL << (23))), "VP8 Video"},
509 {CODEC_MASK(AST_FORMAT_T140_RED)((26) == (uint32_t)-1 ? 0 : (1UL << (26))), "T.140 RED Text format RFC 4103"},
510 {CODEC_MASK(AST_FORMAT_T140)((27) == (uint32_t)-1 ? 0 : (1UL << (27))), "T.140 Text format - ITU T.140, RFC 4103"},
511 {CODEC_MASK(AST_FORMAT_G719)((32) == (uint32_t)-1 ? 0 : (1UL << (32))), "G.719 (64 kbps assumed)"},
512 {CODEC_MASK(AST_FORMAT_SPEEX16)((33) == (uint32_t)-1 ? 0 : (1UL << (33))), "SpeeX Wideband (16kHz) Free Compression"},
513 {CODEC_MASK(AST_FORMAT_OPUS)((34) == (uint32_t)-1 ? 0 : (1UL << (34))), "Opus audio (8kHz, 16kHz, 24kHz, 48Khz)"},
514 {CODEC_MASK(AST_FORMAT_TESTLAW)((47) == (uint32_t)-1 ? 0 : (1UL << (47))), "Raw testing-law data (G.711)"},
515 {0, NULL((void*)0)}
516};
517static val64_string_ext codec_types_ext = VAL64_STRING_EXT_INIT(codec_types){ _try_val64_to_str_ext_init, 0, (sizeof (codec_types) / sizeof
((codec_types)[0]))-1, codec_types, "codec_types", ((void*)0
) }
;
518
519static 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"},
523 {0, NULL((void*)0)}
524};
525
526
527static 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"},
532 {0, NULL((void*)0)}
533};
534
535static const value_string iax_causecodes[] = {
536 {AST_CAUSE_UNALLOCATED1, "Unallocated"},
537 {AST_CAUSE_NO_ROUTE_TRANSIT_NET2, "No route transit net"},
538 {AST_CAUSE_NO_ROUTE_DESTINATION3, "No route to destination"},
539 {AST_CAUSE_MISDIALLED_TRUNK_PREFIX5, "Misdialled trunk prefix"},
540 {AST_CAUSE_CHANNEL_UNACCEPTABLE6, "Channel unacceptable"},
541 {AST_CAUSE_CALL_AWARDED_DELIVERED7, "Call awarded delivered"},
542 {AST_CAUSE_PRE_EMPTED8, "Preempted"},
543 {AST_CAUSE_NUMBER_PORTED_NOT_HERE14, "Number ported not here"},
544 {AST_CAUSE_NORMAL_CLEARING16, "Normal clearing"},
545 {AST_CAUSE_USER_BUSY17, "User busy"},
546 {AST_CAUSE_NO_USER_RESPONSE18, "No user response"},
547 {AST_CAUSE_NO_ANSWER19, "No answer"},
548 {AST_CAUSE_SUBSCRIBER_ABSENT20, "Subscriber absent"},
549 {AST_CAUSE_CALL_REJECTED21, "Call rejected"},
550 {AST_CAUSE_NUMBER_CHANGED22, "Number changed"},
551 {AST_CAUSE_REDIRECTED_TO_NEW_DESTINATION23, "Redirected to new destination"},
552 {AST_CAUSE_ANSWERED_ELSEWHERE26, "Answered elsewhere"},
553 {AST_CAUSE_DESTINATION_OUT_OF_ORDER27, "Destination out of order"},
554 {AST_CAUSE_INVALID_NUMBER_FORMAT28, "Invalid number format"},
555 {AST_CAUSE_FACILITY_REJECTED29, "Facility rejected"},
556 {AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY30, "Response to status inquiry"},
557 {AST_CAUSE_NORMAL_UNSPECIFIED31, "Normal unspecified"},
558 {AST_CAUSE_NORMAL_CIRCUIT_CONGESTION34, "Normal circuit congestion"},
559 {AST_CAUSE_NETWORK_OUT_OF_ORDER38, "Network out of order"},
560 {AST_CAUSE_NORMAL_TEMPORARY_FAILURE41, "Normal temporary failure"},
561 {AST_CAUSE_SWITCH_CONGESTION42, "Switch congestion"},
562 {AST_CAUSE_ACCESS_INFO_DISCARDED43, "Access info discarded"},
563 {AST_CAUSE_REQUESTED_CHAN_UNAVAIL44, "Requested channel unavailable"},
564 {AST_CAUSE_FACILITY_NOT_SUBSCRIBED50, "Facility not subscribed"},
565 {AST_CAUSE_OUTGOING_CALL_BARRED52, "Outgoing call barred"},
566 {AST_CAUSE_INCOMING_CALL_BARRED54, "Incoming call barred"},
567 {AST_CAUSE_BEARERCAPABILITY_NOTAUTH57, "Bearer capability not authorized"},
568 {AST_CAUSE_BEARERCAPABILITY_NOTAVAIL58, "Bearer capability not available"},
569 {AST_CAUSE_BEARERCAPABILITY_NOTIMPL65, "Bearer capability not implemented"},
570 {AST_CAUSE_CHAN_NOT_IMPLEMENTED66, "Channel not implemented"},
571 {AST_CAUSE_FACILITY_NOT_IMPLEMENTED69, "Facility not implemented"},
572 {AST_CAUSE_INVALID_CALL_REFERENCE81, "Invalid call reference"},
573 {AST_CAUSE_INCOMPATIBLE_DESTINATION88, "Incompatible destination"},
574 {AST_CAUSE_INVALID_MSG_UNSPECIFIED95, "Invalid message unspecified"},
575 {AST_CAUSE_MANDATORY_IE_MISSING96, "Mandatory IE missing"},
576 {AST_CAUSE_MESSAGE_TYPE_NONEXIST97, "Message type nonexistent"},
577 {AST_CAUSE_WRONG_MESSAGE98, "Wrong message"},
578 {AST_CAUSE_IE_NONEXIST99, "IE nonexistent"},
579 {AST_CAUSE_INVALID_IE_CONTENTS100, "Invalid IE contents"},
580 {AST_CAUSE_WRONG_CALL_STATE101, "Wrong call state"},
581 {AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE102, "Recovery on timer expire"},
582 {AST_CAUSE_MANDATORY_IE_LENGTH_ERROR103, "Mandatory IE length error"},
583 {AST_CAUSE_PROTOCOL_ERROR111, "Protocol error"},
584 {AST_CAUSE_INTERWORKING127, "Interworking"},
585 {0, NULL((void*)0)}
586};
587static value_string_ext iax_causecodes_ext = VALUE_STRING_EXT_INIT(iax_causecodes){ _try_val_to_str_ext_init, 0, (sizeof (iax_causecodes) / sizeof
((iax_causecodes)[0]))-1, iax_causecodes, "iax_causecodes", (
(void*)0) }
;
588
589/* ************************************************************************* */
590
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.
593 *
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.
598 *
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.
605 *
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.
610 */
611
612
613/* start with a hash of {addr,port type,port,call}->{id} */
614
615typedef struct {
616 address addr;
617 port_type ptype;
618 uint32_t port;
619 uint32_t callno;
620
621 /* this is where addr->data points to. it's put in here for easy freeing */
622 uint8_t address_data[MAX_ADDRESS16];
623} iax_circuit_key;
624
625/* tables */
626static GHashTable *iax_fid_table;
627static reassembly_table iax_reassembly_table;
628
629static GHashTable *iax_circuit_hashtab;
630static unsigned circuitcount;
631
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.
634*/
635#define IAX_INIT_PACKET_COUNT10 10
636
637#ifdef DEBUG_HASHING
638static char *key_to_str( const iax_circuit_key *key )
639{
640 static int i = 0;
641 static char str[3][80];
642 char *strp;
643 char *addrstr;
644
645 i++;
646 if (i >= 3) {
647 i = 0;
648 }
649 strp = str[i];
650
651 addrstr = address_to_str(NULL((void*)0), &key->addr);
652 snprintf(strp, 80, "{%s:%i,%i}",
653 addrstr,
654 key->port,
655 key->callno);
656 wmem_free(NULL((void*)0), addrstr);
657 return strp;
658}
659#endif
660
661/* Hash Functions */
662static int iax_circuit_equal(const void *v, const void *w)
663{
664 const iax_circuit_key *v1 = (const iax_circuit_key *)v;
665 const iax_circuit_key *v2 = (const iax_circuit_key *)w;
666 int result;
667
668 result = (addresses_equal(&(v1->addr), &(v2->addr)) &&
669 v1->ptype == v2->ptype &&
670 v1->port == v2->port &&
671 v1->callno== v2->callno);
672#ifdef DEBUG_HASHING
673 ws_debug("+++ Comparing for equality: %s, %s: %u", key_to_str(v1), key_to_str(v2), result)do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 673, __func__, "+++ Comparing for equality: %s, %s: %u", key_to_str
(v1), key_to_str(v2), result); } } while (0)
;
674#endif
675
676 return result;
677}
678
679static unsigned iax_circuit_hash(const void *v)
680{
681 const iax_circuit_key *key = (const iax_circuit_key *)v;
682 unsigned hash_val;
683
684 hash_val = 0;
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);
689
690#ifdef DEBUG_HASHING
691 ws_debug("+++ Hashing key: %s, result %#x", key_to_str(key), hash_val)do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 691, __func__, "+++ Hashing key: %s, result %#x", key_to_str
(key), hash_val); } } while (0)
;
692#endif
693
694 return (unsigned)hash_val;
695}
696
697/* Find, or create, a circuit for the given
698 {address,porttype,port,call} quadruplet
699*/
700static unsigned iax_circuit_lookup(const address *address_p,
701 port_type ptype,
702 uint32_t port,
703 uint32_t callno)
704{
705 iax_circuit_key key;
706 uint32_t *circuit_id_p;
707
708 key.addr = *address_p;
709 key.ptype = ptype;
710 key.port = port;
711 key.callno = callno;
712
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;
716
717 new_key = wmem_new(wmem_file_scope(), iax_circuit_key)((iax_circuit_key*)wmem_alloc((wmem_file_scope()), sizeof(iax_circuit_key
)))
;
718 new_key->addr.type = address_p->type;
719 new_key->addr.len = MIN(address_p->len, MAX_ADDRESS)(((address_p->len) < (16)) ? (address_p->len) : (16)
)
;
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;
726
727 circuit_id_p = (uint32_t *)wmem_new(wmem_file_scope(), iax_circuit_key)((iax_circuit_key*)wmem_alloc((wmem_file_scope()), sizeof(iax_circuit_key
)))
;
728 *circuit_id_p = ++circuitcount;
729
730 g_hash_table_insert(iax_circuit_hashtab, new_key, circuit_id_p);
731
732#ifdef DEBUG_HASHING
733 ws_debug("Created new circuit id %u for node %s", *circuit_id_p, key_to_str(new_key))do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 733, __func__, "Created new circuit id %u for node %s", *circuit_id_p
, key_to_str(new_key)); } } while (0)
;
734#endif
735 }
736
737 return *circuit_id_p;
738}
739
740
741/* ************************************************************************* */
742
743typedef struct {
744 uint32_t current_frag_id; /* invalid unless current_frag_bytes > 0 */
745 uint32_t current_frag_bytes;
746 uint32_t current_frag_minlen;
747} iax_call_dirdata;
748
749/* This is our per-call data structure, which is attached to both the
750 * forward and reverse circuits.
751 */
752typedef 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.
757
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
760 without problem.
761 */
762
763 iax_dataformat_t dataformat;
764 uint32_t src_codec, dst_codec;
765 uint32_t src_vformat, dst_vformat;
766
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_TRANSFERS2];
770 unsigned reverse_circuit_ids[IAX_MAX_TRANSFERS2];
771 unsigned n_forward_circuit_ids;
772 unsigned n_reverse_circuit_ids;
773
774 /* this is the subdissector for the call */
775 dissector_handle_t subdissector;
776
777 /* the absolute start time of the call */
778 nstime_t start_time;
779
780 /* time stamp from last full frame, in the first pass */
781 uint32_t last_full_frame_ts;
782
783 iax_call_dirdata dirdata[2];
784} iax_call_data;
785
786
787
788/* creates a new CONVERSATION_IAX2 circuit with a specified circuit id for a call
789 *
790 * typically a call has up to three associated circuits: an original source, an
791 * original destination, and the result of a transfer.
792 *
793 * For each endpoint, a CONVERSATION_IAX2 circuit is created and added to the call_data
794 * by this function
795 *
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
798 * transferred.
799 *
800 */
801static 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_Bool reversed)
804{
805 conversation_t *conv;
806
807 if(!iax_call){
808 return NULL((void*)0);
809 }
810 if ((reversed && iax_call->n_reverse_circuit_ids >= IAX_MAX_TRANSFERS2) ||
811 (! reversed && iax_call->n_forward_circuit_ids >= IAX_MAX_TRANSFERS2)) {
812 expert_add_info(pinfo, item, &ei_iax_too_many_transfers);
813 return NULL((void*)0);
814 }
815
816 conv = conversation_new_by_id(framenum, CONVERSATION_IAX2,
817 circuit_id);
818
819 conversation_add_proto_data(conv, proto_iax2, iax_call);
820
821 if (reversed)
822 iax_call -> reverse_circuit_ids[iax_call->n_reverse_circuit_ids++] = circuit_id;
823 else
824 iax_call -> forward_circuit_ids[iax_call->n_forward_circuit_ids++] = circuit_id;
825
826 return conv;
827}
828
829
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 */
833static bool_Bool is_forward_circuit(unsigned circuit_id,
834 const iax_call_data *iax_call)
835{
836 unsigned i;
837 for(i=0; i<iax_call->n_forward_circuit_ids; i++) {
838 if (circuit_id == iax_call->forward_circuit_ids[i])
839 return true1;
840 }
841 return false0;
842}
843
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 */
847static bool_Bool is_reverse_circuit(unsigned circuit_id,
848 const iax_call_data *iax_call)
849{
850 unsigned i;
851 for(i=0; i<iax_call->n_reverse_circuit_ids; i++){
852 if (circuit_id == iax_call->reverse_circuit_ids[i])
853 return true1;
854 }
855 return false0;
856}
857
858
859static iax_call_data *iax_lookup_call_from_dest(packet_info *pinfo, proto_item * item,
860 unsigned src_circuit_id,
861 unsigned dst_circuit_id,
862 unsigned framenum,
863 bool_Bool *reversed_p)
864{
865 conversation_t *dst_conv;
866 iax_call_data *iax_call;
867 bool_Bool reversed = false0;
868
869 dst_conv = find_conversation_by_id(framenum, CONVERSATION_IAX2, dst_circuit_id);
870
871 if (!dst_conv) {
872#ifdef DEBUG_HASHING
873 ws_debug("++ destination circuit not found, must have missed NEW packet")do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 873, __func__, "++ destination circuit not found, must have missed NEW packet"
); } } while (0)
;
874#endif
875 if (reversed_p)
876 *reversed_p = false0;
877 return NULL((void*)0);
878 }
879
880#ifdef DEBUG_HASHING
881 ws_debug("++ found destination circuit")do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 881, __func__, "++ found destination circuit"); } } while (
0)
;
882#endif
883
884 iax_call = (iax_call_data *)conversation_get_proto_data(dst_conv, proto_iax2);
885
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)((void) ((iax_call) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/dissectors/packet-iax2.c", 888, "iax_call"))))
;
889
890 if (is_forward_circuit(dst_circuit_id, iax_call)) {
891#ifdef DEBUG_HASHING
892 ws_debug("++ destination circuit matches forward_circuit_id of call, "do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 893, __func__, "++ destination circuit matches forward_circuit_id of call, "
"therefore packet is reversed"); } } while (0)
893 "therefore packet is reversed")do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 893, __func__, "++ destination circuit matches forward_circuit_id of call, "
"therefore packet is reversed"); } } while (0)
;
894#endif
895
896 reversed = true1;
897
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.
901 create one now. */
902#ifdef DEBUG_HASHING
903 ws_debug("++ reverse_circuit_id of call is zero, need to create a "do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 904, __func__, "++ reverse_circuit_id of call is zero, need to create a "
"new reverse circuit for this call"); } } while (0)
904 "new reverse circuit for this call")do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 904, __func__, "++ reverse_circuit_id of call is zero, need to create a "
"new reverse circuit for this call"); } } while (0)
;
905#endif
906
907 iax2_new_circuit_for_call(pinfo, item, src_circuit_id, framenum, iax_call, true1);
908#ifdef DEBUG_HASHING
909 ws_debug("++ done")do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 909, __func__, "++ done"); } } while (0)
;
910#endif
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",
914 framenum,
915 src_circuit_id, dst_circuit_id,
916 iax_call->forward_circuit_ids[0],
917 iax_call->reverse_circuit_ids[0]);
918 return NULL((void*)0);
919 }
920 } else if (is_reverse_circuit(dst_circuit_id, iax_call)) {
921#ifdef DEBUG_HASHING
922 ws_debug("++ destination circuit matches reverse_circuit_id of call, "do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 923, __func__, "++ destination circuit matches reverse_circuit_id of call, "
"therefore packet is forward"); } } while (0)
923 "therefore packet is forward")do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 923, __func__, "++ destination circuit matches reverse_circuit_id of call, "
"therefore packet is forward"); } } while (0)
;
924#endif
925
926 reversed = false0;
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",
930 framenum,
931 src_circuit_id, dst_circuit_id,
932 iax_call->forward_circuit_ids[0],
933 iax_call->reverse_circuit_ids[0]);
934 if (reversed_p)
935 *reversed_p = false0;
936 return NULL((void*)0);
937 }
938 } else {
939 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/dissectors/packet-iax2.c", 939))
;
940 }
941
942 if (reversed_p)
943 *reversed_p = reversed;
944
945 return iax_call;
946}
947
948
949/* looks up an iax_call for this packet */
950static iax_call_data *iax_lookup_call( packet_info *pinfo,
951 uint32_t scallno,
952 uint32_t dcallno,
953 bool_Bool *reversed_p)
954{
955 bool_Bool reversed = false0;
956 iax_call_data *iax_call = NULL((void*)0);
957 unsigned src_circuit_id;
958#ifdef DEBUG_HASHING
959 char *srcstr, *dststr;
960#endif
961
962#ifdef DEBUG_HASHING
963 srcstr = address_to_str(NULL((void*)0), &pinfo->src);
964 dststr = address_to_str(NULL((void*)0), &pinfo->dst);
965 ws_debug("++ iax_lookup_circuit_details: Looking up circuit for frame %u, "do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 968, __func__, "++ iax_lookup_circuit_details: Looking up circuit for frame %u, "
"from {%s:%u:%u} to {%s:%u:%u}", pinfo->num, srcstr, pinfo
->srcport, scallno, dststr, pinfo->destport, dcallno); }
} while (0)
966 "from {%s:%u:%u} to {%s:%u:%u}", pinfo->num,do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 968, __func__, "++ iax_lookup_circuit_details: Looking up circuit for frame %u, "
"from {%s:%u:%u} to {%s:%u:%u}", pinfo->num, srcstr, pinfo
->srcport, scallno, dststr, pinfo->destport, dcallno); }
} while (0)
967 srcstr, pinfo->srcport, scallno,do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 968, __func__, "++ iax_lookup_circuit_details: Looking up circuit for frame %u, "
"from {%s:%u:%u} to {%s:%u:%u}", pinfo->num, srcstr, pinfo
->srcport, scallno, dststr, pinfo->destport, dcallno); }
} while (0)
968 dststr, pinfo->destport, dcallno)do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 968, __func__, "++ iax_lookup_circuit_details: Looking up circuit for frame %u, "
"from {%s:%u:%u} to {%s:%u:%u}", pinfo->num, srcstr, pinfo
->srcport, scallno, dststr, pinfo->destport, dcallno); }
} while (0)
;
969 wmem_free(NULL((void*)0), srcstr);
970 wmem_free(NULL((void*)0), dststr);
971#endif
972
973
974 src_circuit_id = iax_circuit_lookup(&pinfo->src, pinfo->ptype,
975 pinfo->srcport, scallno);
976
977
978 /* the most reliable indicator of call is the destination callno, if
979 we have one */
980 if (dcallno != 0) {
981 unsigned dst_circuit_id;
982#ifdef DEBUG_HASHING
983 ws_debug("++ dcallno non-zero, looking up destination circuit")do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 983, __func__, "++ dcallno non-zero, looking up destination circuit"
); } } while (0)
;
984#endif
985
986 dst_circuit_id = iax_circuit_lookup(&pinfo->dst, pinfo->ptype,
987 pinfo->destport, dcallno);
988
989 iax_call = iax_lookup_call_from_dest(pinfo, NULL((void*)0), src_circuit_id, dst_circuit_id,
990 pinfo->num, &reversed);
991 } else {
992 conversation_t *src_conv;
993
994 /* in all other circumstances, the source circuit should already
995 * exist: its absence indicates that we missed the all-important NEW
996 * packet.
997 */
998
999 src_conv = find_conversation_by_id(pinfo->num, CONVERSATION_IAX2, src_circuit_id);
1000
1001 if (src_conv) {
1002 iax_call = (iax_call_data *)conversation_get_proto_data(src_conv, proto_iax2);
1003
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)((void) ((iax_call) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/dissectors/packet-iax2.c", 1006, "iax_call"))))
;
1007
1008 if (is_forward_circuit(src_circuit_id, iax_call))
1009 reversed = false0;
1010 else if (is_reverse_circuit(src_circuit_id, iax_call))
1011 reversed = true1;
1012 else {
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.
1016 */
1017 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/dissectors/packet-iax2.c", 1017))
;
1018 }
1019 }
1020 }
1021
1022 if (reversed_p)
1023 *reversed_p = reversed;
1024
1025#ifdef DEBUG_HASHING
1026 if (iax_call) {
1027 ws_debug("++ Found call for packet: id %u, reversed=%c", iax_call->forward_circuit_ids[0], reversed?'1':'0')do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 1027, __func__, "++ Found call for packet: id %u, reversed=%c"
, iax_call->forward_circuit_ids[0], reversed?'1':'0'); } }
while (0)
;
1028 } else {
1029 ws_debug("++ Call not found. Must have missed the NEW packet?")do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 1029, __func__, "++ Call not found. Must have missed the NEW packet?"
); } } while (0)
;
1030 }
1031#endif
1032
1033 return iax_call;
1034}
1035
1036/* initialize the per-direction parts of an iax_call_data structure */
1037static void init_dir_data(iax_call_dirdata *dirdata)
1038{
1039 dirdata -> current_frag_bytes=0;
1040 dirdata -> current_frag_minlen=0;
1041}
1042
1043
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. */
1047static iax_call_data *iax_new_call( packet_info *pinfo,
1048 uint32_t scallno)
1049{
1050 iax_call_data *call;
1051 unsigned circuit_id;
1052 static const nstime_t millisecond = NSTIME_INIT_SECS_MSECS(0, 1){0, 1*1000000};
1053
1054#ifdef DEBUG_HASHING
1055 ws_debug("+ new_circuit: Handling NEW packet, frame %u", pinfo->num)do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 1055, __func__, "+ new_circuit: Handling NEW packet, frame %u"
, pinfo->num); } } while (0)
;
1056#endif
1057
1058 circuit_id = iax_circuit_lookup(&pinfo->src, pinfo->ptype,
1059 pinfo->srcport, scallno);
1060
1061 call = wmem_new(wmem_file_scope(), iax_call_data)((iax_call_data*)wmem_alloc((wmem_file_scope()), sizeof(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((void*)0);
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]);
1075
1076 iax2_new_circuit_for_call(pinfo, NULL((void*)0), circuit_id, pinfo->num, call, false0);
1077
1078 return call;
1079}
1080
1081
1082/* ************************************************************************* */
1083
1084/* per-packet data */
1085typedef struct iax_packet_data {
1086 bool_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;
1090 uint32_t codec;
1091 bool_Bool reversed;
1092 nstime_t abstime; /* the absolute time of this packet, based on its
1093 * timestamp and the NEW packet's time (-1 if unknown) */
1094} iax_packet_data;
1095
1096static iax_packet_data *iax_new_packet_data(iax_call_data *call, bool_Bool reversed)
1097{
1098 iax_packet_data *p = wmem_new(wmem_file_scope(), iax_packet_data)((iax_packet_data*)wmem_alloc((wmem_file_scope()), sizeof(iax_packet_data
)))
;
1099 p->first_time = true1;
1100 p->call_data = call;
1101 p->codec = 0;
1102 p->reversed = reversed;
1103 p->abstime.secs = -1;
1104 p->abstime.nsecs = -1;
1105 return p;
1106}
1107
1108static void iax2_populate_pinfo_from_packet_data(packet_info *pinfo, const iax_packet_data *p)
1109{
1110 if (p->call_data != NULL((void*)0)) {
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_RECV1:P2P_DIR_SENT0;
1114
1115 col_set_str(pinfo->cinfo, COL_IF_DIR, p->reversed ? "rev" : "fwd");
1116 }
1117}
1118
1119
1120/* ************************************************************************* */
1121
1122/* this is passed up from the IE dissector to the main dissector */
1123typedef struct
1124{
1125 address peer_address;
1126 port_type peer_ptype;
1127 uint32_t peer_port;
1128 uint32_t peer_callno;
1129 uint32_t dataformat;
1130} iax2_ie_data;
1131
1132
1133static uint32_t dissect_fullpacket(tvbuff_t *tvb, uint32_t offset,
1134 uint16_t scallno,
1135 packet_info *pinfo,
1136 proto_tree *iax2_tree,
1137 proto_tree *main_tree);
1138
1139
1140static uint32_t dissect_minipacket(tvbuff_t *tvb, uint32_t offset,
1141 uint16_t scallno,
1142 packet_info *pinfo,
1143 proto_tree *iax2_tree,
1144 proto_tree *main_tree);
1145
1146static uint32_t dissect_minivideopacket(tvbuff_t *tvb, uint32_t offset,
1147 uint16_t scallno,
1148 packet_info *pinfo,
1149 proto_tree *iax2_tree,
1150 proto_tree *main_tree);
1151
1152static uint32_t dissect_trunkpacket(tvbuff_t *tvb, uint32_t offset,
1153 uint16_t scallno,
1154 packet_info *pinfo,
1155 proto_tree *iax2_tree,
1156 proto_tree *main_tree);
1157
1158static 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_Bool video,
1161 iax_packet_data *iax_packet);
1162
1163
1164
1165static int
1166dissect_iax2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U___attribute__((unused)))
1167{
1168 proto_item *iax2_item;
1169 proto_tree *iax2_tree;
1170 proto_tree *full_mini_subtree = NULL((void*)0);
1171 uint32_t offset = 0, len;
1172 uint16_t scallno = 0;
1173 uint16_t stmp;
1174 packet_type type;
1175 proto_item *full_mini_base;
1176
1177 /* set up the protocol and info fields in the summary pane */
1178 col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_IAX2"IAX2");
1179 col_clear(pinfo->cinfo, COL_INFO);
1180
1181 /* add the 'iax2' tree to the main tree */
1182 iax2_item = proto_tree_add_item(tree, proto_iax2, tvb, offset, -1, ENC_NA0x00000000);
1183 iax2_tree = proto_item_add_subtree(iax2_item, ett_iax2);
1184
1185 stmp = tvb_get_ntohs(tvb, offset);
1186 if (stmp == 0) {
1
Assuming 'stmp' is not equal to 0
2
Taking false branch
1187 /* starting with 0x0000 indicates meta packet which can be either a mini
1188 * video packet or a trunk packet */
1189 offset+=2;
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;
1195 offset += 2;
1196 }
1197 else {
1198 type = IAX2_TRUNK_PACKET;
1199 }
1200 } else {
1201 /* The source call/fullpacket flag is common to both mini and full packets */
1202 scallno = tvb_get_ntohs(tvb, offset);
1203 offset += 2;
1204 if (scallno & 0x8000)
3
Assuming the condition is true
4
Taking true branch
1205 type = IAX2_FULL_PACKET;
1206 else {
1207 type = IAX2_MINI_VOICE_PACKET;
1208 }
1209 scallno &= 0x7FFF;
1210 }
1211
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);
1214
1215 if (scallno != 0)
5
Assuming 'scallno' is equal to 0
6
Taking false branch
1216 proto_tree_add_item(full_mini_subtree, hf_iax2_scallno, tvb, offset-2, 2, ENC_BIG_ENDIAN0x00000000);
1217
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((void*)0);
1227 iax2_info->callingParty = NULL((void*)0);
1228 iax2_info->calledParty = NULL((void*)0);
1229 iax2_info->payload_data = NULL((void*)0);
1230
1231 switch (type) {
7
Control jumps to 'case IAX2_FULL_PACKET:' at line 1232
1232 case IAX2_FULL_PACKET:
1233 len = dissect_fullpacket(tvb, offset, scallno, pinfo, full_mini_subtree, tree);
8
Calling 'dissect_fullpacket'
1234 break;
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);
1238 break;
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);
1242 break;
1243 case IAX2_TRUNK_PACKET:
1244 iax2_info->messageName = "TRUNK_PACKET";
1245 len = dissect_trunkpacket(tvb, offset, scallno, pinfo, full_mini_subtree, tree);
1246 break;
1247 default:
1248 len = 0;
1249 }
1250
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);
1256}
1257
1258static proto_item *dissect_datetime_ie(tvbuff_t *tvb, uint32_t offset, proto_tree *ies_tree)
1259{
1260 struct tm tm;
1261 uint32_t ie_val;
1262 nstime_t datetime;
1263
1264 proto_tree_add_item(ies_tree, hf_iax2_ies[IAX_IE_DATETIME31], tvb, offset + 2, 4, ENC_BIG_ENDIAN0x00000000);
1265 ie_val = tvb_get_ntohl(tvb, offset+2);
1266
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 */
1276
1277 datetime.secs = mktime(&tm);
1278 datetime.nsecs = 0;
1279 return proto_tree_add_time(ies_tree, hf_iax2_ie_datetime, tvb, offset+2, 4, &datetime);
1280}
1281
1282
1283/* dissect the information elements in an IAX frame. Returns the updated offset */
1284static 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)
1287{
1288 DISSECTOR_ASSERT(ie_data)((void) ((ie_data) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/dissectors/packet-iax2.c", 1288, "ie_data"))))
;
20
'?' condition is true
1289
1290 while (offset < tvb_reported_length(tvb)) {
21
Assuming the condition is true
22
Loop condition is true. Entering loop body
1291
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;
1295
1296 /* do non-tree-dependent stuff first */
1297 switch (ies_type) {
23
Control jumps to 'case 18:' at line 1313
1298 case IAX_IE_DATAFORMAT255:
1299 if (ies_len != 4) {
1300 proto_tree_add_expert(iax_tree, pinfo, &ei_iax_invalid_len, tvb, offset+1, 1);
1301 break;
1302 }
1303 ie_data -> dataformat = tvb_get_ntohl(tvb, offset+2);
1304 break;
1305
1306 case IAX_IE_CALLED_NUMBER1:
1307 iax2_info->calledParty = tvb_format_text(pinfo->pool, tvb, offset+2, ies_len);
1308 break;
1309 case IAX_IE_CALLING_NUMBER2:
1310 iax2_info->callingParty = tvb_format_text(pinfo->pool, tvb, offset+2, ies_len);
1311 break;
1312
1313 case IAX_IE_APPARENT_ADDR18:
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).
1320
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) {
24
Control jumps to the 'default' case at line 1334
1325 case LINUX_AF_INET2:
1326 /* IAX is always over UDP */
1327 ie_data->peer_ptype = PT_UDP;
1328 ie_data->peer_port = tvb_get_ntohs(tvb, offset+4);
1329
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);
1332 break;
1333
1334 default:
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);
1337 break;
25
Execution continues on line 1339
1338 }
1339 break;
1340 }
1341
1342
1343 /* the rest of this stuff only needs doing if we have an iax_tree */
1344
1345 if (iax_tree && ies_type
26.1
'ies_type' is < NUM_HF_IAX2_IES
< NUM_HF_IAX2_IES256) {
26
Assuming 'iax_tree' is non-null
27
Taking true branch
1346 proto_item *ti, *ie_item = NULL((void*)0);
1347 proto_tree *ies_tree;
1348 int ie_hf = hf_iax2_ies[ies_type];
1349
1350 ies_tree = proto_tree_add_subtree(iax_tree, tvb, offset, ies_len+2, ett_iax2_ie, &ti, " ");
1351
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);
1354
1355
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
1360 type of the item.
1361 */
1362
1363 switch (ies_type) {
28
Control jumps to 'case 18:' at line 1437
1364 case IAX_IE_DATETIME31:
1365 ie_item = dissect_datetime_ie(tvb, offset, ies_tree);
1366 break;
1367
1368
1369 case IAX_IE_CAPABILITY8:
1370 {
1371 if (ies_len != 4) {
1372 proto_tree_add_expert(ies_tree, pinfo, &ei_iax_invalid_len, tvb, offset+1, 1);
1373 break;
1374 }
1375
1376 ie_item =
1377 proto_tree_add_bitmask(ies_tree, tvb, offset + 2, ie_hf,
1378 ett_iax2_codecs, hf_iax2_caps, ENC_BIG_ENDIAN0x00000000);
1379 break;
1380 }
1381
1382
1383 case IAX_IE_CAPABILITY255:
1384 {
1385 int version = tvb_get_uint8(tvb, offset + 2);
1386
1387 proto_tree_add_uint(ies_tree, hf_iax2_version, tvb, offset + 2, 1, version);
1388
1389 if (version == 0) {
1390 if (ies_len != 9) {
1391 proto_tree_add_expert(ies_tree, pinfo, &ei_iax_invalid_len, tvb, offset+1, 1);
1392 break;
1393 }
1394
1395 ie_item =
1396 proto_tree_add_bitmask(ies_tree, tvb, offset + 3, ie_hf,
1397 ett_iax2_codecs, hf_iax2_caps, ENC_BIG_ENDIAN0x00000000);
1398 }
1399 break;
1400 }
1401
1402
1403 case IAX_IE_FORMAT9:
1404 {
1405 if (ies_len != 4) {
1406 proto_tree_add_expert(ies_tree, pinfo, &ei_iax_invalid_len, tvb, offset+1, 1);
1407 break;
1408 }
1409
1410 ie_item =
1411 proto_tree_add_item(ies_tree, ie_hf,
1412 tvb, offset + 2, 4, ENC_BIG_ENDIAN0x00000000);
1413 break;
1414 }
1415
1416
1417 case IAX_IE_FORMAT256:
1418 {
1419 int version = tvb_get_uint8(tvb, offset + 2);
1420
1421 proto_tree_add_uint(ies_tree, hf_iax2_version, tvb, offset + 2, 1, version);
1422
1423 if (version == 0) {
1424 if (ies_len != 9) {
1425 proto_tree_add_expert(ies_tree, pinfo, &ei_iax_invalid_len, tvb, offset+1, 1);
1426 break;
1427 }
1428
1429 ie_item =
1430 proto_tree_add_item(ies_tree, ie_hf,
1431 tvb, offset + 3, 8, ENC_BIG_ENDIAN0x00000000);
1432 }
1433 break;
1434 }
1435
1436
1437 case IAX_IE_APPARENT_ADDR18:
1438 {
1439 proto_tree *sockaddr_tree;
1440
1441 sockaddr_tree = proto_tree_add_subtree(ies_tree, tvb, offset + 2, 16,
1442 ett_iax2_ies_apparent_addr, &ie_item, "Apparent Address");
1443
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).
1450
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);
1455
1456 if (apparent_addr_family == LINUX_AF_INET2) {
29
Assuming 'apparent_addr_family' is equal to LINUX_AF_INET
30
Taking true branch
1457 uint32_t addr;
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);
31
Null pointer passed to 2nd parameter expecting 'nonnull'
1460 proto_tree_add_ipv4(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINADDR, tvb, offset + 6, 4, addr);
1461 }
1462 break;
1463 }
1464
1465 default:
1466 if (ie_hf != 0) {
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);
1470 break;
1471 }
1472
1473 switch (proto_registrar_get_ftype(ie_hf)) {
1474 case FT_UINT8:
1475 case FT_UINT16:
1476 case FT_UINT24:
1477 case FT_UINT32:
1478 case FT_UINT64:
1479 case FT_INT8:
1480 case FT_INT16:
1481 case FT_INT24:
1482 case FT_INT32:
1483 case FT_INT64:
1484 case FT_BOOLEAN:
1485 case FT_IPv4:
1486 ie_item = proto_tree_add_item(ies_tree, ie_hf, tvb, offset + 2, ies_len, ENC_BIG_ENDIAN0x00000000);
1487 break;
1488
1489 case FT_BYTES:
1490 case FT_NONE:
1491 ie_item = proto_tree_add_item(ies_tree, ie_hf, tvb, offset + 2, ies_len, ENC_NA0x00000000);
1492 break;
1493
1494 case FT_STRING:
1495 case FT_STRINGZ:
1496 ie_item = proto_tree_add_item(ies_tree, ie_hf, tvb, offset + 2, ies_len, ENC_UTF_80x00000002|ENC_NA0x00000000);
1497 break;
1498
1499 default:
1500 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/dissectors/packet-iax2.c", 1500))
;
1501 break;
1502 }
1503 } else {
1504 /* we don't understand this ie: add a generic one */
1505 uint32_t value;
1506 const uint8_t *ptr;
1507 const char *ie_name = val_to_str_ext_const(ies_type, &iax_ies_type_ext, "Unknown");
1508
1509 switch (ies_len) {
1510 case 1:
1511 value = tvb_get_uint8(tvb, offset + 2);
1512 ie_item =
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);
1516 break;
1517
1518 case 2:
1519 value = tvb_get_ntohs(tvb, offset + 2);
1520 ie_item =
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);
1524 break;
1525
1526 case 4:
1527 value = tvb_get_ntohl(tvb, offset + 2);
1528 ie_item =
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);
1532 break;
1533
1534 default:
1535 ptr = tvb_get_string_enc(pinfo->pool, tvb, offset + 2, ies_len, ENC_ASCII0x00000000);
1536 ie_item =
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);
1540 break;
1541 }
1542 }
1543 break;
1544 }
1545
1546 /* Retrieve the text from the item we added, and append it to the main IE
1547 * item */
1548 if (ie_item && !proto_item_is_hidden(ti)) {
1549 field_info *ie_finfo = PITEM_FINFO(ie_item)((ie_item)->finfo);
1550
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((void*)0))
1554 proto_item_set_text(ti, "Information Element: %s",
1555 ie_finfo->rep->representation);
1556 else {
1557 uint8_t *ie_val = (uint8_t *)wmem_alloc(pinfo->pool, ITEM_LABEL_LENGTH240);
1558 proto_item_fill_label(ie_finfo, ie_val, NULL((void*)0));
1559 proto_item_set_text(ti, "Information Element: %s",
1560 ie_val);
1561 }
1562 }
1563 }
1564
1565 offset += ies_len + 2;
1566 }
1567 return offset;
1568}
1569
1570static uint32_t uncompress_subclass(uint8_t csub)
1571{
1572 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
1573 if (csub & 0x80) {
1574 /* special case for 'compressed' -1 */
1575 if (csub == 0xff)
1576 return (uint32_t)-1;
1577 else
1578 return csub & 0x3F;
1579 }
1580 else {
1581 switch (csub) {
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;
1590 }
1591 }
1592}
1593
1594/* returns the new offset */
1595static uint32_t dissect_iax2_command(tvbuff_t *tvb, uint32_t offset,
1596 packet_info *pinfo, proto_tree *tree,
1597 iax_packet_data *iax_packet)
1598{
1599 uint8_t csub = tvb_get_uint8(tvb, offset);
1600 proto_item* ti;
1601 iax2_ie_data ie_data;
1602 iax_call_data *iax_call;
1603
1604 ie_data.peer_address.type = AT_NONE;
1605 ie_data.peer_address.len = 0;
1606 ie_data.peer_address.data = NULL((void*)0);
16
Null pointer value stored to 'ie_data.peer_address.data'
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;
1612
1613 /* add the subclass */
1614 ti = proto_tree_add_uint(tree, hf_iax2_iax_csub, tvb, offset, 1, csub);
1615 offset++;
1616
1617 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1618 val_to_str_ext(pinfo->pool, csub, &iax_iax_subclasses_ext, "unknown (0x%02x)"));
1619
1620 if (offset >= tvb_reported_length(tvb))
17
Assuming the condition is false
18
Taking false branch
1621 return offset;
1622
1623 offset = dissect_ies(tvb, pinfo, offset, tree, ti, &ie_data);
19
Calling 'dissect_ies'
1624
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((void*)0)) {
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;
1629 }
1630
1631 /* if this is a transfer request, record it in the call data */
1632 if (csub == IAX_COMMAND_TXREQ22 && 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,
1635 ie_data.peer_ptype,
1636 ie_data.peer_port,
1637 ie_data.peer_callno);
1638
1639 iax2_new_circuit_for_call(pinfo, NULL((void*)0), tx_circuit, pinfo->num, iax_call, iax_packet->reversed);
1640 }
1641 }
1642
1643 return offset;
1644}
1645
1646static 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)
1647{
1648 uint32_t full_relts = relts;
1649 nstime_t lateness;
1650 proto_item *item;
1651
1652 if (iax_packet->call_data == NULL((void*)0)) {
1653 /* no call info for this frame; perhaps we missed the NEW packet */
1654 return;
1655 }
1656
1657 if (iax_packet->abstime.secs == -1) {
1658 nstime_t rel;
1659
1660 switch (type) {
1661 case IAX2_MINI_VOICE_PACKET:
1662 /* RFC 5456 says
1663 *
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.
1667 *
1668 * and, for what it later calls "Mini Frames", by which it means
1669 * what we're calling "mini voice packets", it says:
1670 *
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
1680 * is not received.
1681 *
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.
1686 *
1687 * XXX - what, if anything, should we do about full frames we've
1688 * missed? */
1689 full_relts = (iax_packet->call_data->last_full_frame_ts & 0xFFFF0000) | relts;
1690 break;
1691
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.
1696 *
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? */
1700 full_relts = relts;
1701 iax_packet->call_data->last_full_frame_ts = full_relts;
1702 break;
1703
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":
1708 *
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.
1713 *
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.
1719 *
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.
1723 *
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;
1727 break;
1728 }
1729
1730 /* Convert the full relative time stamp to an nstime_t */
1731 rel.secs = full_relts / 1000;
1732 rel.nsecs = (full_relts % 1000) * 1000000;
1733
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);
1736 }
1737 iax2_info->timestamp = relts; /* raw time stamp; nobody uses it */
1738
1739 if (iax2_tree) {
1740 item = proto_tree_add_time(iax2_tree, hf_iax2_absts, tvb, 0, 0, &iax_packet->abstime);
1741 proto_item_set_generated(item);
1742
1743 nstime_delta(&lateness, &pinfo->abs_ts, &iax_packet->abstime);
1744
1745 item = proto_tree_add_time(iax2_tree, hf_iax2_lateness, tvb, 0, 0, &lateness);
1746 proto_item_set_generated(item);
1747 }
1748}
1749
1750/* returns the new offset */
1751static uint32_t
1752dissect_fullpacket(tvbuff_t *tvb, uint32_t offset,
1753 uint16_t scallno,
1754 packet_info *pinfo, proto_tree *iax2_tree,
1755 proto_tree *main_tree)
1756{
1757 uint16_t dcallno;
1758 uint32_t ts;
1759 uint8_t type;
1760 uint8_t csub;
1761 uint32_t codec;
1762
1763 proto_tree *packet_type_tree = NULL((void*)0);
1764 iax_call_data *iax_call;
1765 iax_packet_data *iax_packet;
1766 bool_Bool reversed;
1767 bool_Bool rtp_marker;
1768
1769 /*
1770 * remove the top bit for retransmission detection
1771 */
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;
1780
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);
1783 if (!iax_packet) {
9
Assuming 'iax_packet' is non-null
10
Taking false branch
1784 /* if not, find or create an iax_call info structure for this IAX session. */
1785
1786 if (type == AST_FRAME_IAX6 && csub == IAX_COMMAND_NEW1) {
1787 /* NEW packets start a new call */
1788 iax_call = iax_new_call(pinfo, scallno);
1789 reversed = false0;
1790 } else {
1791 iax_call = iax_lookup_call(pinfo, scallno, dcallno,
1792 &reversed);
1793 }
1794
1795 iax_packet = iax_new_packet_data(iax_call, reversed);
1796 p_add_proto_data(wmem_file_scope(), pinfo, proto_iax2, 0, iax_packet);
1797 } else {
1798 iax_call = iax_packet->call_data;
1799 reversed = iax_packet->reversed;
1800 }
1801
1802 iax2_populate_pinfo_from_packet_data(pinfo, iax_packet);
1803
1804 if (iax2_tree) {
11
Assuming 'iax2_tree' is non-null
12
Taking true branch
1805 proto_item *packet_type_base;
1806
1807 proto_tree_add_item(iax2_tree, hf_iax2_dcallno, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
1808
1809 proto_tree_add_item(iax2_tree, hf_iax2_retransmission, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
1810
1811 if (iax_call
12.1
'iax_call' is null
) {
13
Taking false branch
1812 proto_item *item =
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);
1816 }
1817
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);
1820
1821 proto_tree_add_item(iax2_tree, hf_iax2_oseqno, tvb, offset+6, 1,
1822 ENC_BIG_ENDIAN0x00000000);
1823
1824 proto_tree_add_item(iax2_tree, hf_iax2_iseqno, tvb, offset+7, 1,
1825 ENC_BIG_ENDIAN0x00000000);
1826 packet_type_base = proto_tree_add_uint(iax2_tree, hf_iax2_type, tvb,
1827 offset+8, 1, type);
1828
1829 /* add the type-specific subtree */
1830 packet_type_tree = proto_item_add_subtree(packet_type_base, ett_iax2_type);
1831 } else {
1832 iax2_add_ts_fields(pinfo, iax2_tree, tvb, iax_packet, IAX2_FULL_PACKET, ts);
1833 }
1834
1835
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(pinfo->pool, type, &iax_frame_types_ext, "Unknown (0x%02x)"),
1839 scallno, ts);
1840
1841 iax2_info->messageName = val_to_str_ext(pinfo->pool, type, &iax_frame_types_ext, "Unknown (0x%02x)");
1842
1843 switch (type) {
14
Control jumps to 'case 6:' at line 1844
1844 case AST_FRAME_IAX6:
1845 offset=dissect_iax2_command(tvb, offset+9, pinfo, packet_type_tree, iax_packet);
15
Calling 'dissect_iax2_command'
1846 iax2_info->messageName = val_to_str_ext(pinfo->pool, csub, &iax_iax_subclasses_ext, "unknown (0x%02x)");
1847 if (csub < NUM_TAP_IAX_VOIP_STATES(sizeof (tap_iax_voip_state) / sizeof (tap_iax_voip_state)[0]
)
) iax2_info->callState = tap_iax_voip_state[csub];
1848 break;
1849
1850 case AST_FRAME_DTMF_BEGIN12:
1851 case AST_FRAME_DTMF_END1:
1852 proto_tree_add_item(packet_type_tree, hf_iax2_dtmf_csub, tvb, offset+9, 1, ENC_ASCII0x00000000);
1853 offset += 10;
1854
1855 col_append_fstr(pinfo->cinfo, COL_INFO, " digit %s", format_char(pinfo->pool, csub));
1856 break;
1857
1858 case AST_FRAME_CONTROL4:
1859 /* add the subclass */
1860 proto_tree_add_uint(packet_type_tree, hf_iax2_cmd_csub, tvb,
1861 offset+9, 1, csub);
1862 offset += 10;
1863
1864 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1865 val_to_str_ext(pinfo->pool, csub, &iax_cmd_subclasses_ext, "unknown (0x%02x)"));
1866 iax2_info->messageName = val_to_str_ext(pinfo->pool, csub, &iax_cmd_subclasses_ext, "unknown (0x%02x)");
1867 if (csub < NUM_TAP_CMD_VOIP_STATES(sizeof (tap_cmd_voip_state) / sizeof (tap_cmd_voip_state)[0]
)
) iax2_info->callState = tap_cmd_voip_state[csub];
1868 break;
1869
1870 case AST_FRAME_VOICE2:
1871 /* add the codec */
1872 iax_packet -> codec = codec = uncompress_subclass(csub);
1873
1874 if (packet_type_tree) {
1875 proto_item *item;
1876 proto_tree_add_item(packet_type_tree, hf_iax2_voice_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN0x00000000);
1877 item = proto_tree_add_uint64(packet_type_tree, hf_iax2_voice_codec, tvb, offset+9, 1, CODEC_MASK(codec)((codec) == (uint32_t)-1 ? 0 : (1UL << (codec))));
1878 proto_item_set_generated(item);
1879 }
1880
1881 offset += 10;
1882
1883 if (iax_call) {
1884 if (reversed) {
1885 iax_call->dst_codec = codec;
1886 } else {
1887 iax_call->src_codec = codec;
1888 }
1889 }
1890
1891 dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, false0, iax_packet);
1892 break;
1893
1894 case AST_FRAME_VIDEO3:
1895 /* bit 6 of the csub is used to represent the rtp 'marker' bit */
1896 rtp_marker = csub & 0x40 ? true1:false0;
1897 iax_packet -> codec = codec = uncompress_subclass((uint8_t)(csub & ~0x40));
1898
1899 if (packet_type_tree) {
1900 proto_item *item;
1901 proto_tree_add_item(packet_type_tree, hf_iax2_video_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN0x00000000);
1902 proto_tree_add_item(packet_type_tree, hf_iax2_marker, tvb, offset+9, 1, ENC_BIG_ENDIAN0x00000000);
1903 item = proto_tree_add_uint64(packet_type_tree, hf_iax2_video_codec, tvb, offset+9, 1, CODEC_MASK(codec)((codec) == (uint32_t)-1 ? 0 : (1UL << (codec))));
1904 proto_item_set_generated(item);
1905 }
1906
1907 offset += 10;
1908
1909 if (iax_call && iax_packet -> first_time) {
1910 if (reversed) {
1911 iax_call->dst_vformat = codec;
1912 } else {
1913 iax_call->src_vformat = codec;
1914 }
1915 }
1916
1917 if (rtp_marker)
1918 col_append_str(pinfo->cinfo, COL_INFO, ", Mark");
1919
1920
1921 dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, true1, iax_packet);
1922 break;
1923
1924 case AST_FRAME_MODEM11:
1925 proto_tree_add_item(packet_type_tree, hf_iax2_modem_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN0x00000000);
1926 offset += 10;
1927
1928 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1929 val_to_str(pinfo->pool, csub, iax_modem_subclasses, "unknown (0x%02x)"));
1930 break;
1931
1932 case AST_FRAME_TEXT7:
1933 proto_tree_add_item(packet_type_tree, hf_iax2_text_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN0x00000000);
1934 offset += 10;
1935
1936 {
1937 int textlen = tvb_captured_length_remaining(tvb, offset);
1938 if (textlen > 0)
1939 {
1940 proto_tree_add_item(packet_type_tree, hf_iax2_text_text, tvb, offset, textlen, ENC_UTF_80x00000002);
1941 offset += textlen;
1942 }
1943 }
1944 break;
1945
1946 case AST_FRAME_HTML9:
1947 proto_tree_add_item(packet_type_tree, hf_iax2_html_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN0x00000000);
1948 offset += 10;
1949
1950 if (csub == 0x01)
1951 {
1952 int urllen = tvb_captured_length_remaining(tvb, offset);
1953 if (urllen > 0)
1954 {
1955 proto_item *pi = proto_tree_add_item(packet_type_tree, hf_iax2_html_url, tvb, offset, urllen, ENC_UTF_80x00000002);
1956 proto_item_set_url(pi);
1957 offset += urllen;
1958 }
1959 }
1960 break;
1961
1962 case AST_FRAME_CNG10:
1963 default:
1964 proto_tree_add_uint(packet_type_tree, hf_iax2_csub, tvb, offset+9,
1965 1, csub);
1966 offset += 10;
1967
1968 col_append_fstr(pinfo->cinfo, COL_INFO, " subclass %d", csub);
1969 break;
1970 }
1971
1972 /* next time we come to parse this packet, don't propagate the codec into the
1973 * call_data */
1974 iax_packet->first_time = false0;
1975
1976 return offset;
1977}
1978
1979static iax_packet_data *iax2_get_packet_data_for_minipacket(packet_info *pinfo,
1980 uint16_t scallno,
1981 bool_Bool video)
1982{
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);
1985
1986 if (!p) {
1987 /* if not, find or create an iax_call info structure for this IAX session. */
1988 bool_Bool reversed;
1989 iax_call_data *iax_call;
1990
1991 iax_call = iax_lookup_call(pinfo, scallno, 0, &reversed);
1992
1993 p = iax_new_packet_data(iax_call, reversed);
1994 p_add_proto_data(wmem_file_scope(), pinfo, proto_iax2, 0, p);
1995
1996 /* set the codec for this frame to be whatever the last full frame used */
1997 if (iax_call) {
1998 if (video)
1999 p->codec = reversed ? iax_call -> dst_vformat : iax_call -> src_vformat;
2000 else
2001 p->codec = reversed ? iax_call -> dst_codec : iax_call -> src_codec;
2002 }
2003 }
2004
2005 iax2_populate_pinfo_from_packet_data(pinfo, p);
2006 return p;
2007}
2008
2009
2010static 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)
2013{
2014 uint32_t ts;
2015 iax_packet_data *iax_packet;
2016 bool_Bool rtp_marker;
2017 proto_item *item;
2018
2019 ts = tvb_get_ntohs(tvb, offset);
2020
2021 /* bit 15 of the ts is used to represent the rtp 'marker' bit */
2022 rtp_marker = ts & 0x8000 ? true1:false0;
2023 ts &= ~0x8000;
2024
2025 iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, true1);
2026
2027 if (iax2_tree) {
2028 if (iax_packet->call_data) {
2029 item =
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);
2033 }
2034
2035 proto_tree_add_item(iax2_tree, hf_iax2_minividts, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
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_ENDIAN0x00000000);
2038 } else {
2039 iax2_add_ts_fields(pinfo, iax2_tree, tvb, iax_packet, IAX2_MINI_VIDEO_PACKET, ts);
2040 }
2041
2042 offset += 2;
2043
2044 col_add_fstr(pinfo->cinfo, COL_INFO,
2045 "Mini video packet, source call# %d, timestamp %ums%s",
2046 scallno, ts, rtp_marker?", Mark":"");
2047
2048
2049 dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, true1, iax_packet);
2050
2051 /* next time we come to parse this packet, don't propagate the codec into the
2052 * call_data */
2053 iax_packet->first_time = false0;
2054
2055 return offset;
2056}
2057
2058static 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)
2061{
2062 uint32_t ts;
2063 iax_packet_data *iax_packet;
2064 proto_item *item;
2065
2066 ts = tvb_get_ntohs(tvb, offset);
2067
2068 iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, false0);
2069
2070 if (iax2_tree) {
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);
2075 }
2076
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);
2079 } else {
2080 iax2_add_ts_fields(pinfo, iax2_tree, tvb, iax_packet, IAX2_MINI_VOICE_PACKET, ts);
2081 }
2082
2083
2084 offset += 2;
2085
2086 col_add_fstr(pinfo->cinfo, COL_INFO,
2087 "Mini packet, source call# %d, timestamp %ums",
2088 scallno, ts);
2089
2090
2091 /* XXX fix the timestamp logic */
2092 dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, false0, iax_packet);
2093
2094
2095 /* next time we come to parse this packet, don't propagate the codec into the
2096 * call_data */
2097 iax_packet->first_time = false0;
2098
2099 return offset;
2100}
2101
2102
2103static uint32_t dissect_trunkcall_ts(tvbuff_t *tvb, uint32_t offset, proto_tree *iax2_tree, uint16_t *scallno)
2104{
2105 proto_tree *call_tree;
2106 uint16_t datalen, rlen, ts;
2107 /*
2108 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2109 | Data Length (in octets) |R| Source Call Number |
2110 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2111 | time-stamp | |
2112 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
2113 | Data |
2114 : :
2115 | |
2116 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2117 */
2118 datalen = tvb_get_ntohs(tvb, offset);
2119 *scallno = tvb_get_ntohs(tvb, offset + 2);
2120 ts = tvb_get_ntohs(tvb, offset + 4);
2121
2122 rlen = MIN(tvb_captured_length(tvb) - offset - 6, datalen)(((tvb_captured_length(tvb) - offset - 6) < (datalen)) ? (
tvb_captured_length(tvb) - offset - 6) : (datalen))
;
2123
2124 if (iax2_tree) {
2125 call_tree = proto_tree_add_subtree_format(iax2_tree, tvb, offset, rlen + 6,
2126 ett_iax2_trunk_call, NULL((void*)0), "Trunk call from %u, ts: %u", *scallno, ts);
2127
2128 proto_tree_add_item(call_tree, hf_iax2_trunk_call_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
2129 proto_tree_add_item(call_tree, hf_iax2_trunk_call_scallno, tvb, offset + 2, 2, ENC_BIG_ENDIAN0x00000000);
2130 proto_tree_add_item(call_tree, hf_iax2_trunk_call_ts, tvb, offset + 4, 2, ENC_BIG_ENDIAN0x00000000);
2131 proto_tree_add_item(call_tree, hf_iax2_trunk_call_data, tvb, offset + 6, rlen, ENC_NA0x00000000);
2132 }
2133 offset += 6 + rlen;
2134
2135 return offset;
2136}
2137
2138static uint32_t dissect_trunkcall_nots(tvbuff_t *tvb, uint32_t offset, proto_tree *iax2_tree, uint16_t *scallno)
2139{
2140 proto_tree *call_tree;
2141 uint16_t datalen, rlen;
2142 /*
2143 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2144 |R| Source Call Number | Data Length (in octets) |
2145 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2146 | |
2147 : Data :
2148 | |
2149 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2150 */
2151 *scallno = tvb_get_ntohs(tvb, offset);
2152 datalen = tvb_get_ntohs(tvb, offset + 2);
2153
2154 rlen = MIN(tvb_captured_length(tvb) - offset - 4, datalen)(((tvb_captured_length(tvb) - offset - 4) < (datalen)) ? (
tvb_captured_length(tvb) - offset - 4) : (datalen))
;
2155
2156 if (iax2_tree) {
2157 call_tree = proto_tree_add_subtree_format(iax2_tree, tvb, offset, rlen + 6,
2158 ett_iax2_trunk_call, NULL((void*)0), "Trunk call from %u", *scallno);
2159
2160 proto_tree_add_item(call_tree, hf_iax2_trunk_call_scallno, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
2161 proto_tree_add_item(call_tree, hf_iax2_trunk_call_len, tvb, offset + 2, 2, ENC_BIG_ENDIAN0x00000000);
2162 proto_tree_add_item(call_tree, hf_iax2_trunk_call_data, tvb, offset + 4, rlen, ENC_NA0x00000000);
2163 }
2164 offset += 4 + rlen;
2165
2166 return offset;
2167}
2168
2169typedef struct _call_list {
2170 uint16_t scallno;
2171 struct _call_list *next;
2172} call_list;
2173
2174static call_list *call_list_append(wmem_allocator_t *pool, call_list *list, uint16_t scallno)
2175{
2176 call_list *node = wmem_new0(pool, call_list)((call_list*)wmem_alloc0((pool), sizeof(call_list)));
2177
2178 node->scallno = scallno;
2179
2180 if (list) {
2181 call_list *cur = list;
2182 while (cur->next) {
2183 cur = cur->next;
2184 }
2185 cur->next = node;
2186 return list;
2187 } else {
2188 return node;
2189 }
2190}
2191
2192static bool_Bool call_list_find(call_list *list, uint16_t scallno)
2193{
2194 for (; list; list = list->next) {
2195 if (list->scallno == scallno) {
2196 return true1;
2197 }
2198 }
2199 return false0;
2200}
2201
2202static unsigned call_list_length(call_list *list)
2203{
2204 unsigned count = 0;
2205 for (; list; list = list->next) {
2206 count++;
2207 }
2208 return count;
2209}
2210
2211static uint32_t dissect_trunkpacket(tvbuff_t *tvb, uint32_t offset,
2212 uint16_t scallno_param _U___attribute__((unused)), packet_info *pinfo,
2213 proto_tree *iax2_tree, proto_tree *main_tree _U___attribute__((unused)))
2214{
2215 uint8_t cmddata, trunkts;
2216 unsigned nframes = 0, ncalls = 0;
2217 proto_item *cd, *nc = NULL((void*)0);
2218 proto_tree *field_tree = NULL((void*)0);
2219 call_list *calls = NULL((void*)0);
2220 /*iax_packet_data *iax_packet;*/
2221
2222 cmddata = tvb_get_uint8(tvb, offset + 1);
2223 trunkts = cmddata & IAX2_TRUNK_TS1;
2224
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 /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
2231
2232 if (iax2_tree) {
2233 /* Meta Command */
2234 proto_tree_add_item(iax2_tree, hf_iax2_trunk_metacmd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2235
2236 /* Command data */
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);
2239 if (trunkts)
2240 proto_item_append_text(cd, " (trunk timestamps)");
2241
2242 /* CD -> Trunk timestamp */
2243 proto_tree_add_boolean(field_tree, hf_iax2_trunk_cmddata_ts, tvb, offset + 1, 1, cmddata);
2244
2245 /* Timestamp */
2246 proto_tree_add_item(iax2_tree, hf_iax2_trunk_ts, tvb, offset + 2, 4, ENC_BIG_ENDIAN0x00000000);
2247 }
2248
2249 offset += 6;
2250
2251 if (trunkts) {
2252 /* Trunk calls with timestamp */
2253 while(tvb_captured_length_remaining(tvb, offset) >= 6) {
2254 uint16_t scallno;
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);
2258 }
2259 nframes++;
2260 }
2261 }
2262 else {
2263 /* Trunk calls without timestamp */
2264 while(tvb_captured_length_remaining(tvb, offset) >= 4) {
2265 uint16_t scallno;
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);
2269 }
2270 nframes++;
2271 }
2272 }
2273
2274 ncalls = call_list_length(calls);
2275
2276 if (iax2_tree) {
2277 /* number of items */
2278 nc = proto_tree_add_uint(iax2_tree, hf_iax2_trunk_ncalls, NULL((void*)0), 0, 0, ncalls);
2279 proto_item_set_generated(nc);
2280 }
2281
2282 col_add_fstr(pinfo->cinfo, COL_INFO, "Trunk packet with %d media frame%s for %d call%s",
2283 nframes, plurality(nframes, "", "s")((nframes) == 1 ? ("") : ("s")),
2284 ncalls, plurality(ncalls, "", "s")((ncalls) == 1 ? ("") : ("s")));
2285
2286 return offset;
2287}
2288
2289
2290static void process_iax_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2291 bool_Bool video, iax_packet_data *iax_packet)
2292{
2293 uint32_t codec = iax_packet -> codec;
2294 iax_call_data *iax_call = iax_packet -> call_data;
2295
2296#ifdef DEBUG_DESEGMENT
2297 ws_debug("calling process_iax_pdu; len = %u", tvb_reported_length(tvb))do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 2297, __func__, "calling process_iax_pdu; len = %u", tvb_reported_length
(tvb)); } } while (0)
;
2298#endif
2299
2300 if (!video && iax_call && iax_call->subdissector) {
2301 iax2_dissector_info_t dissector_info;
2302
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((void*)0)) {
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));
2309 } else {
2310 dissector_info.ctype = CONVERSATION_IAX2;
2311 dissector_info.circuit_id = (uint32_t)iax_packet->call_data->forward_circuit_ids[0];
2312 }
2313
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 */
2317 } else {
2318 /* we don't know how to dissect our data: dissect it as data */
2319 call_data_dissector(tvb, pinfo, tree);
2320 }
2321
2322#ifdef DEBUG_DESEGMENT
2323 ws_debug("called process_iax_pdu; pinfo->desegment_len=%u; pinfo->desegment_offset=%u",do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 2324, __func__, "called process_iax_pdu; pinfo->desegment_len=%u; pinfo->desegment_offset=%u"
, pinfo->desegment_len, pinfo->desegment_offset); } } while
(0)
2324 pinfo->desegment_len, pinfo->desegment_offset)do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 2324, __func__, "called process_iax_pdu; pinfo->desegment_len=%u; pinfo->desegment_offset=%u"
, pinfo->desegment_len, pinfo->desegment_offset); } } while
(0)
;
2325#endif
2326}
2327
2328static void desegment_iax(tvbuff_t *tvb, packet_info *pinfo, proto_tree *iax2_tree,
2329 proto_tree *tree, bool_Bool video, iax_packet_data *iax_packet)
2330{
2331
2332 iax_call_data *iax_call = iax_packet -> call_data;
2333 iax_call_dirdata *dirdata;
2334 void * value = NULL((void*)0);
2335 uint32_t frag_offset = 0;
2336 fragment_head *fd_head;
2337 bool_Bool must_desegment = false0;
2338
2339 DISSECTOR_ASSERT(iax_call)((void) ((iax_call) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/dissectors/packet-iax2.c", 2339, "iax_call"))))
;
2340
2341 pinfo->can_desegment = 2;
2342 pinfo->desegment_offset = 0;
2343 pinfo->desegment_len = 0;
2344
2345#ifdef DEBUG_DESEGMENT
2346 ws_debug("dissecting packet %u", pinfo->num)do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 2346, __func__, "dissecting packet %u", pinfo->num); } }
while (0)
;
2347#endif
2348
2349 dirdata = &(iax_call->dirdata[!!(iax_packet->reversed)]);
2350
2351 if ((!pinfo->fd->visited && (dirdata->current_frag_bytes > 0)) ||
2352 ((value = g_hash_table_lookup(iax_fid_table, GUINT_TO_POINTER(pinfo->num)((gpointer) (gulong) (pinfo->num)))) != NULL((void*)0))) {
2353
2354 /* then we are continuing an already-started pdu */
2355 uint32_t fid;
2356 uint32_t frag_len = tvb_reported_length(tvb);
2357 bool_Bool complete;
2358
2359#ifdef DEBUG_DESEGMENT
2360 ws_debug("visited: %i; c_f_b: %u; hash: %u->%u", pinfo->fd->visited?1:0,do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 2361, __func__, "visited: %i; c_f_b: %u; hash: %u->%u", pinfo
->fd->visited?1:0, dirdata->current_frag_bytes, pinfo
->num, dirdata->current_frag_id); } } while (0)
2361 dirdata->current_frag_bytes, pinfo->num, dirdata->current_frag_id)do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 2361, __func__, "visited: %i; c_f_b: %u; hash: %u->%u", pinfo
->fd->visited?1:0, dirdata->current_frag_bytes, pinfo
->num, dirdata->current_frag_id); } } while (0)
;
2362#endif
2363
2364 if (!pinfo->fd->visited) {
2365 uint32_t tot_len;
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)((void) ((g_hash_table_lookup(iax_fid_table, ((gpointer) (gulong
) (pinfo->num))) == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/dissectors/packet-iax2.c"
, 2368, "g_hash_table_lookup(iax_fid_table, ((gpointer) (gulong) (pinfo->num))) == ((void*)0)"
))))
;
2369 g_hash_table_insert(iax_fid_table, GUINT_TO_POINTER(pinfo->num)((gpointer) (gulong) (pinfo->num)), GUINT_TO_POINTER(fid)((gpointer) (gulong) (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",do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 2375, __func__, "hash: %u->%u; frag_offset: %u; c_f_b: %u; totlen: %u"
, pinfo->num, fid, frag_offset, dirdata->current_frag_bytes
, tot_len); } } while (0)
2375 pinfo->num, fid, frag_offset, dirdata->current_frag_bytes, tot_len)do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 2375, __func__, "hash: %u->%u; frag_offset: %u; c_f_b: %u; totlen: %u"
, pinfo->num, fid, frag_offset, dirdata->current_frag_bytes
, tot_len); } } while (0)
;
2376#endif
2377 } else {
2378 fid = GPOINTER_TO_UINT(value)((guint) (gulong) (value));
2379 /* these values are unused by fragment_add if pinfo->fd->visited */
2380 dirdata->current_frag_bytes = 0;
2381 complete = false0;
2382 }
2383
2384 /* fragment_add checks for already-added */
2385 fd_head = fragment_add(&iax_reassembly_table, tvb, 0, pinfo, fid, NULL((void*)0),
2386 frag_offset,
2387 frag_len, !complete);
2388
2389 if (fd_head && (pinfo->num == fd_head->reassembled_in)) {
2390 int32_t old_len;
2391 tvbuff_t *next_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
2392 add_new_data_source(pinfo, next_tvb, "Reassembled IAX2");
2393
2394 process_iax_pdu(next_tvb, pinfo, tree, video, iax_packet);
2395
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.
2400 */
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((void*)0));
2406 if (pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT0x0fffffff) {
2407 /* only one more byte should be enough for a retry */
2408 dirdata->current_frag_minlen = fd_head->datalen + 1;
2409 } else {
2410 dirdata->current_frag_minlen = fd_head->datalen + pinfo->desegment_len;
2411 }
2412 } else {
2413 /* we successfully dissected some data; create the proto tree items for
2414 * the fragments, and flag any remaining data for desegmentation */
2415
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);
2423
2424 dirdata->current_frag_minlen = dirdata->current_frag_id = dirdata->current_frag_bytes = 0;
2425
2426 if (pinfo->desegment_len) {
2427 /* there's a bit of data left to desegment */
2428 must_desegment = true1;
2429 /* make desegment_offset relative to our tvb */
2430 pinfo->desegment_offset -= old_len;
2431 }
2432
2433 /* don't add a 'reassembled in' item for this pdu */
2434 fd_head = NULL((void*)0);
2435 }
2436 }
2437 } else {
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.
2441 */
2442
2443 process_iax_pdu(tvb, pinfo, tree, video, iax_packet);
2444
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 = true1;
2450 }
2451
2452 fd_head = NULL((void*)0);
2453 }
2454
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;
2464
2465 if (pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT0x0fffffff) {
2466 /* only one more byte should be enough for a retry */
2467 dirdata->current_frag_minlen = frag_len + 1;
2468 } else {
2469 dirdata->current_frag_minlen = frag_len + pinfo->desegment_len;
2470 }
2471
2472 fd_head = fragment_add(&iax_reassembly_table,
2473 tvb, deseg_offset, pinfo, fid, NULL((void*)0),
2474 0, frag_len, true1);
2475#ifdef DEBUG_DESEGMENT
2476 ws_debug("Start offset of undissected bytes: %u; "do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 2478, __func__, "Start offset of undissected bytes: %u; " "Bytes remaining in this segment: %u; min required bytes: %u\n"
, deseg_offset, frag_len, frag_len + pinfo->desegment_len)
; } } while (0)
2477 "Bytes remaining in this segment: %u; min required bytes: %u\n",do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 2478, __func__, "Start offset of undissected bytes: %u; " "Bytes remaining in this segment: %u; min required bytes: %u\n"
, deseg_offset, frag_len, frag_len + pinfo->desegment_len)
; } } while (0)
2478 deseg_offset, frag_len, frag_len + pinfo->desegment_len)do { if (1) { ws_log_full("", LOG_LEVEL_DEBUG, "epan/dissectors/packet-iax2.c"
, 2478, __func__, "Start offset of undissected bytes: %u; " "Bytes remaining in this segment: %u; min required bytes: %u\n"
, deseg_offset, frag_len, frag_len + pinfo->desegment_len)
; } } while (0)
;
2479#endif
2480 }
2481
2482 /* add a 'reassembled in' item if necessary */
2483 if (fd_head != NULL((void*)0)) {
2484 uint32_t deseg_offset = pinfo->desegment_offset;
2485 if (fd_head->reassembled_in != 0 &&
2486 !(fd_head->flags & FD_PARTIAL_REASSEMBLY0x0040)) {
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);
2492 } else {
2493 /* this fragment is never reassembled */
2494 proto_tree_add_item(tree, hf_iax2_fragment_unfinished, tvb, deseg_offset, -1, ENC_NA0x00000000);
2495 }
2496
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]");
2500 }
2501 }
2502
2503 pinfo->can_desegment = 0;
2504 pinfo->desegment_offset = 0;
2505 pinfo->desegment_len = 0;
2506}
2507
2508static 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___attribute__((unused)), bool_Bool video,
2511 iax_packet_data *iax_packet)
2512{
2513#if 0
2514 bool_Bool out_of_order = false0;
2515#endif
2516 tvbuff_t *sub_tvb;
2517 uint32_t codec = iax_packet -> codec;
2518 uint32_t nbytes;
2519 iax_call_data *iax_call = iax_packet -> call_data;
2520
2521 if (offset >= tvb_reported_length(tvb)) {
2522 col_append_str(pinfo->cinfo, COL_INFO, ", empty frame");
2523 return;
2524 }
2525
2526 sub_tvb = tvb_new_subset_remaining(tvb, offset);
2527
2528 /* XXX shouldn't pass through out-of-order packets. */
2529
2530 if (!video && iax_call && iax_call -> dataformat != 0) {
2531 col_append_fstr(pinfo->cinfo, COL_INFO, ", data, format %s",
2532 val_to_str(pinfo->pool, iax_call -> dataformat,
2533 iax_dataformats, "unknown (0x%02x)"));
2534#if 0
2535 if (out_of_order)
2536 col_append_str(pinfo->cinfo, COL_INFO, " (out-of-order packet)");
2537#endif
2538 } else {
2539 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
2540 val64_to_str_ext_wmem(pinfo->pool, CODEC_MASK(codec)((codec) == (uint32_t)-1 ? 0 : (1UL << (codec))), &codec_types_ext, "unknown (0x%04x)"));
2541 }
2542
2543 nbytes = tvb_reported_length(sub_tvb);
2544 proto_tree_add_item(iax2_tree, hf_iax2_payload_data, sub_tvb, 0, -1, ENC_NA0x00000000);
2545
2546 iax2_info->payload_len = nbytes;
2547 iax2_info->payload_data = tvb_get_ptr(sub_tvb, 0, -1);
2548
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);
2552 else
2553 process_iax_pdu(sub_tvb, pinfo, tree, video, iax_packet);
2554}
2555
2556/*
2557 * Init routines
2558 */
2559
2560/* called at the start of a capture. We should clear out our static, per-capture
2561 * data.
2562 */
2563
2564static void
2565iax_init_protocol(void)
2566{
2567 iax_circuit_hashtab = g_hash_table_new(iax_circuit_hash, iax_circuit_equal);
2568 circuitcount = 0;
2569
2570 iax_fid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
2571}
2572
2573static void
2574iax_cleanup_protocol(void)
2575{
2576 g_hash_table_destroy(iax_circuit_hashtab);
2577 g_hash_table_destroy(iax_fid_table);
2578}
2579
2580
2581void
2582proto_register_iax2(void)
2583{
2584 /* A header field is something you can search/filter on.
2585 *
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}}.
2589 */
2590
2591 static hf_register_info hf[] = {
2592
2593 {&hf_iax2_packet_type,
2594 {"Packet type", "iax2.packet_type",
2595 FT_UINT8, BASE_DEC, VALS(iax_packet_types)((0 ? (const struct _value_string*)0 : ((iax_packet_types)))), 0,
2596 "Full/minivoice/minivideo/trunk packet",
2597 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2598
2599 {&hf_iax2_callno,
2600 {"Call identifier", "iax2.call",
2601 FT_UINT32, BASE_DEC, NULL((void*)0), 0,
2602 "This is the identifier Wireshark assigns to identify this call."
2603 " It does not correspond to any real field in the protocol",
2604 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2605
2606 {&hf_iax2_scallno,
2607 {"Source call", "iax2.src_call",
2608 FT_UINT16, BASE_DEC, NULL((void*)0), 0x7FFF,
2609 "src_call holds the number of this call at the packet source pbx",
2610 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2611
2612 /* FIXME could this be turned into a FRAMENUM field? */
2613 {&hf_iax2_dcallno,
2614 {"Destination call", "iax2.dst_call",
2615 FT_UINT16, BASE_DEC, NULL((void*)0), 0x7FFF,
2616 "dst_call holds the number of this call at the packet destination",
2617 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2618
2619 {&hf_iax2_retransmission,
2620 {"Retransmission", "iax2.retransmission",
2621 FT_BOOLEAN, 16, NULL((void*)0), 0x8000,
2622 "retransmission is set if this packet is a retransmission of an earlier failed packet",
2623 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2624
2625 {&hf_iax2_ts,
2626 {"Timestamp", "iax2.timestamp",
2627 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
2628 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2629 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2630
2631 {&hf_iax2_minits,
2632 {"Timestamp", "iax2.timestamp",
2633 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
2634 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2635 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2636
2637 {&hf_iax2_minividts,
2638 {"Timestamp", "iax2.timestamp",
2639 FT_UINT16, BASE_DEC, NULL((void*)0), 0x7FFF,
2640 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2641 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2642
2643 {&hf_iax2_absts,
2644 {"Absolute Time", "iax2.abstime",
2645 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL((void*)0), 0x0,
2646 "The absolute time of this packet (calculated by adding the IAX timestamp to the start time of this call)",
2647 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2648
2649 {&hf_iax2_lateness,
2650 {"Lateness", "iax2.lateness",
2651 FT_RELATIVE_TIME, BASE_NONE, NULL((void*)0), 0x0,
2652 "The lateness of this packet compared to its timestamp",
2653 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2654
2655 {&hf_iax2_minividmarker,
2656 {"Marker", "iax2.video.mini_marker",
2657 FT_UINT16, BASE_DEC, NULL((void*)0), 0x8000,
2658 "RTP end-of-frame marker",
2659 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2660
2661 {&hf_iax2_oseqno,
2662 {"Outbound seq.no.", "iax2.oseqno",
2663 FT_UINT16, BASE_DEC, NULL((void*)0), 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",
2666 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2667
2668 {&hf_iax2_iseqno,
2669 {"Inbound seq.no.", "iax2.iseqno",
2670 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
2671 "iseqno is the sequence no of the last successfully received packet",
2672 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2673
2674 {&hf_iax2_type,
2675 {"Type", "iax2.type",
2676 FT_UINT8, BASE_DEC | BASE_EXT_STRING0x00000200, &iax_frame_types_ext, 0x0,
2677 "For full IAX2 frames, type is the type of frame",
2678 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2679
2680 {&hf_iax2_csub,
2681 {"Unknown subclass", "iax2.subclass",
2682 FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
2683 "Subclass of unknown type of full IAX2 frame",
2684 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2685
2686 {&hf_iax2_dtmf_csub,
2687 {"DTMF subclass (digit)", "iax2.dtmf.subclass",
2688 FT_STRINGZ, BASE_NONE, NULL((void*)0), 0x0,
2689 "DTMF subclass gives the DTMF digit",
2690 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2691
2692 {&hf_iax2_cmd_csub,
2693 {"Control subclass", "iax2.control.subclass",
2694 FT_UINT8, BASE_DEC | BASE_EXT_STRING0x00000200, &iax_cmd_subclasses_ext, 0x0,
2695 "This gives the command number for a Control packet.",
2696 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2697
2698 {&hf_iax2_iax_csub,
2699 {"IAX subclass", "iax2.iax.subclass",
2700 FT_UINT8, BASE_DEC | BASE_EXT_STRING0x00000200, &iax_iax_subclasses_ext, 0x0,
2701 "IAX subclass gives the command number for IAX signaling packets",
2702 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2703
2704 {&hf_iax2_voice_csub,
2705 {"Voice Subclass (compressed codec no)", "iax2.voice.subclass",
2706 FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
2707 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2708
2709 {&hf_iax2_voice_codec,
2710 {"CODEC", "iax2.voice.codec",
2711 FT_UINT64, BASE_HEX | BASE_EXT_STRING0x00000200 | BASE_VAL64_STRING0x00000400, &codec_types_ext, 0x0,
2712 "CODEC gives the codec used to encode audio data",
2713 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2714
2715 {&hf_iax2_video_csub,
2716 {"Video Subclass (compressed codec no)", "iax2.video.subclass",
2717 FT_UINT8, BASE_DEC, NULL((void*)0), 0xBF,
2718 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2719
2720 {&hf_iax2_marker,
2721 {"Marker", "iax2.video.marker",
2722 FT_BOOLEAN, 8, NULL((void*)0), 0x40,
2723 "RTP end-of-frame marker",
2724 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2725
2726 {&hf_iax2_video_codec,
2727 {"CODEC", "iax2.video.codec",
2728 FT_UINT64, BASE_HEX | BASE_EXT_STRING0x00000200 | BASE_VAL64_STRING0x00000400, &codec_types_ext, 0,
2729 "The codec used to encode video data",
2730 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2731
2732 {&hf_iax2_modem_csub,
2733 {"Modem subclass", "iax2.modem.subclass",
2734 FT_UINT8, BASE_DEC, VALS(iax_modem_subclasses)((0 ? (const struct _value_string*)0 : ((iax_modem_subclasses
))))
, 0x0,
2735 "Modem subclass gives the type of modem",
2736 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2737
2738 {&hf_iax2_text_csub,
2739 {"Text subclass", "iax2.text.subclass",
2740 FT_UINT8, BASE_DEC, VALS(iax_text_subclasses)((0 ? (const struct _value_string*)0 : ((iax_text_subclasses)
)))
, 0x0,
2741 NULL((void*)0),
2742 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2743
2744 {&hf_iax2_text_text,
2745 {"Text", "iax2.text.text",
2746 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2747 NULL((void*)0),
2748 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2749
2750 {&hf_iax2_html_csub,
2751 {"HTML subclass", "iax2.html.subclass",
2752 FT_UINT8, BASE_DEC, VALS(iax_html_subclasses)((0 ? (const struct _value_string*)0 : ((iax_html_subclasses)
)))
, 0x0,
2753 NULL((void*)0),
2754 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2755
2756 {&hf_iax2_html_url,
2757 {"HTML URL", "iax2.html.url",
2758 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2759 NULL((void*)0),
2760 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2761
2762 {&hf_iax2_trunk_ts,
2763 {"Timestamp", "iax2.timestamp",
2764 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
2765 "timestamp is the time, in ms after the start of Command data this call,"
2766 " at which this trunk packet was transmitted",
2767 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2768
2769 {&hf_iax2_trunk_metacmd,
2770 {"Meta command", "iax2.trunk.metacmd",
2771 FT_UINT8, BASE_DEC, NULL((void*)0), 0x7F,
2772 "Meta command indicates whether or not the Meta Frame is a trunk.",
2773 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2774
2775 {&hf_iax2_trunk_cmddata,
2776 {"Command data", "iax2.trunk.cmddata",
2777 FT_UINT8, BASE_HEX, NULL((void*)0), 0x0,
2778 "Flags for options that apply to a trunked call",
2779 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2780
2781 {&hf_iax2_trunk_cmddata_ts,
2782 {"Trunk timestamps", "iax2.trunk.cmddata.ts",
2783 FT_BOOLEAN, 8, NULL((void*)0), IAX2_TRUNK_TS1,
2784 "True: calls do each include their own timestamp",
2785 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2786
2787 {&hf_iax2_trunk_call_len,
2788 {"Data length", "iax2.trunk.call.len",
2789 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
2790 "Trunk call data length in octets",
2791 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2792
2793 {&hf_iax2_trunk_call_scallno,
2794 {"Source call number", "iax2.trunk.call.scallno",
2795 FT_UINT16, BASE_DEC, NULL((void*)0), 0x7FFF,
2796 "Trunk call source call number",
2797 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2798
2799 {&hf_iax2_trunk_call_ts,
2800 {"Timestamp", "iax2.trunk.call.ts",
2801 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
2802 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2803 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2804
2805 {&hf_iax2_trunk_call_data,
2806 {"Data", "iax2.trunk.call.payload",
2807 FT_BYTES, BASE_NONE, NULL((void*)0), 0x0,
2808 "Payload carried by this trunked packet.",
2809 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2810
2811 {&hf_iax2_trunk_ncalls,
2812 {"Number of calls", "iax2.trunk.ncalls",
2813 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
2814 "Number of calls in this trunk packet",
2815 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2816
2817 /*
2818 * Decoding for the ies
2819 */
2820
2821 {&hf_IAX_IE_APPARENTADDR_SINFAMILY,
2822 {"Family", "iax2.iax.app_addr.sinfamily",
2823 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
2824 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2825
2826 {&hf_IAX_IE_APPARENTADDR_SINPORT,
2827 {"Port", "iax2.iax.app_addr.sinport",
2828 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
2829 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2830
2831 {&hf_IAX_IE_APPARENTADDR_SINADDR,
2832 {"Address", "iax2.iax.app_addr.sinaddr",
2833 FT_IPv4, BASE_NONE, NULL((void*)0), 0,
2834 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2835
2836 {&hf_iax2_ies[IAX_IE_CALLED_NUMBER1],
2837 {"Number/extension being called", "iax2.iax.called_number",
2838 FT_STRING,
2839 BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2840
2841 {&hf_iax2_ies[IAX_IE_CALLING_NUMBER2],
2842 {"Calling number", "iax2.iax.calling_number",
2843 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2844 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2845
2846
2847 {&hf_iax2_ies[IAX_IE_CALLING_ANI3],
2848 {"Calling number ANI for billing", "iax2.iax.calling_ani",
2849 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2850 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2851
2852 {&hf_iax2_ies[IAX_IE_CALLING_NAME4],
2853 {"Name of caller", "iax2.iax.calling_name",
2854 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2855 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2856
2857 {&hf_iax2_ies[IAX_IE_CALLED_CONTEXT5],
2858 {"Context for number", "iax2.iax.called_context",
2859 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2860 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2861
2862 {&hf_iax2_ies[IAX_IE_USERNAME6],
2863 {"Username (peer or user) for authentication", "iax2.iax.username",
2864 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2865 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2866
2867 {&hf_iax2_ies[IAX_IE_PASSWORD7],
2868 {"Password for authentication", "iax2.iax.password",
2869 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2870 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2871
2872 {&hf_iax2_ies[IAX_IE_CAPABILITY8],
2873 {"Actual codec capability", "iax2.iax.capability",
2874 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
2875 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2876
2877 {&hf_iax2_ies[IAX_IE_FORMAT9],
2878 {"Desired codec format", "iax2.iax.format",
2879 FT_UINT64, BASE_HEX | BASE_EXT_STRING0x00000200 | BASE_VAL64_STRING0x00000400, &codec_types_ext, 0x0,
2880 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2881
2882 {&hf_iax2_ies[IAX_IE_LANGUAGE10],
2883 {"Desired language", "iax2.iax.language",
2884 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2885 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2886
2887 {&hf_iax2_ies[IAX_IE_VERSION11],
2888 {"Protocol version", "iax2.iax.version",
2889 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
2890 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2891
2892 {&hf_iax2_ies[IAX_IE_ADSICPE12],
2893 {"CPE ADSI capability", "iax2.iax.cpe_adsi",
2894 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
2895 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2896
2897 {&hf_iax2_ies[IAX_IE_DNID13],
2898 {"Originally dialed DNID", "iax2.iax.dnid",
2899 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2900 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2901
2902 {&hf_iax2_ies[IAX_IE_AUTHMETHODS14],
2903 {"Authentication method(s)", "iax2.iax.auth.methods",
2904 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
2905 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2906
2907 {&hf_iax2_ies[IAX_IE_CHALLENGE15],
2908 {"Challenge data for MD5/RSA", "iax2.iax.auth.challenge",
2909 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2910 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2911
2912 {&hf_iax2_ies[IAX_IE_MD5_RESULT16],
2913 {"MD5 challenge result", "iax2.iax.auth.md5",
2914 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2915 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2916
2917 {&hf_iax2_ies[IAX_IE_RSA_RESULT17],
2918 {"RSA challenge result", "iax2.iax.auth.rsa",
2919 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2920 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2921
2922 {&hf_iax2_ies[IAX_IE_REFRESH19],
2923 {"When to refresh registration", "iax2.iax.refresh",
2924 FT_INT16, BASE_DEC, NULL((void*)0), 0x0,
2925 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2926
2927 {&hf_iax2_ies[IAX_IE_DPSTATUS20],
2928 {"Dialplan status", "iax2.iax.dialplan_status",
2929 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
2930 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2931
2932 {&hf_iax2_ies[IAX_IE_CALLNO21],
2933 {"Call number of peer", "iax2.iax.call_no",
2934 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
2935 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2936
2937 {&hf_iax2_ies[IAX_IE_CAUSE22],
2938 {"Cause", "iax2.iax.cause",
2939 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2940 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2941
2942 {&hf_iax2_ies[IAX_IE_IAX_UNKNOWN23],
2943 {"Unknown IAX command", "iax2.iax.iax_unknown",
2944 FT_BYTES, BASE_NONE, NULL((void*)0), 0x0,
2945 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2946
2947 {&hf_iax2_ies[IAX_IE_MSGCOUNT24],
2948 {"How many messages waiting", "iax2.iax.msg_count",
2949 FT_INT16, BASE_DEC, NULL((void*)0), 0x0,
2950 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2951
2952 {&hf_iax2_ies[IAX_IE_AUTOANSWER25],
2953 {"Request auto-answering", "iax2.iax.autoanswer",
2954 FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
2955 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2956
2957 {&hf_iax2_ies[IAX_IE_MUSICONHOLD26],
2958 {"Request musiconhold with QUELCH", "iax2.iax.moh",
2959 FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
2960 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2961
2962 {&hf_iax2_ies[IAX_IE_TRANSFERID27],
2963 {"Transfer Request Identifier", "iax2.iax.transferid",
2964 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
2965 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2966
2967 {&hf_iax2_ies[IAX_IE_RDNIS28],
2968 {"Referring DNIS", "iax2.iax.rdnis",
2969 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2970 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2971
2972 {&hf_iax2_ies[IAX_IE_PROVISIONING29],
2973 {"Provisioning info", "iax2.iax.provisioning",
2974 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2975 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2976
2977 {&hf_iax2_ies[IAX_IE_AESPROVISIONING30],
2978 {"AES Provisioning info", "iax2.iax.aesprovisioning",
2979 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2980 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2981
2982 {&hf_iax2_ies[IAX_IE_DATETIME31],
2983 {"Date/Time", "iax2.iax.datetime.raw",
2984 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
2985 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2986
2987 {&hf_iax2_ie_datetime,
2988 {"Date/Time", "iax2.iax.datetime",
2989 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL((void*)0), 0x0,
2990 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2991
2992 {&hf_iax2_ies[IAX_IE_DEVICETYPE32],
2993 {"Device type", "iax2.iax.devicetype",
2994 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2995 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
2996
2997 {&hf_iax2_ies[IAX_IE_SERVICEIDENT33],
2998 {"Service identifier", "iax2.iax.serviceident",
2999 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3000 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3001
3002 {&hf_iax2_ies[IAX_IE_FIRMWAREVER34],
3003 {"Firmware version", "iax2.iax.firmwarever",
3004 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
3005 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3006
3007 {&hf_iax2_ies[IAX_IE_FWBLOCKDESC35],
3008 {"Firmware block description", "iax2.iax.fwblockdesc",
3009 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
3010 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3011
3012 {&hf_iax2_ies[IAX_IE_FWBLOCKDATA36],
3013 {"Firmware block of data", "iax2.iax.fwblockdata",
3014 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3015 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3016
3017 {&hf_iax2_ies[IAX_IE_PROVVER37],
3018 {"Provisioning version", "iax2.iax.provver",
3019 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
3020 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3021
3022 {&hf_iax2_ies[IAX_IE_CALLINGPRES38],
3023 {"Calling presentation", "iax2.iax.callingpres",
3024 FT_UINT8, BASE_HEX, NULL((void*)0), 0x0,
3025 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3026
3027 {&hf_iax2_ies[IAX_IE_CALLINGTON39],
3028 {"Calling type of number", "iax2.iax.callington",
3029 FT_UINT8, BASE_HEX, NULL((void*)0), 0x0,
3030 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3031
3032 {&hf_iax2_ies[IAX_IE_CALLINGTNS40],
3033 {"Calling transit network select", "iax2.iax.callingtns",
3034 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
3035 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3036
3037 {&hf_iax2_ies[IAX_IE_SAMPLINGRATE41],
3038 {"Supported sampling rates", "iax2.iax.samplingrate",
3039 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
3040 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3041
3042 {&hf_iax2_ies[IAX_IE_CAUSECODE42],
3043 {"Hangup cause", "iax2.iax.causecode",
3044 FT_UINT8, BASE_HEX | BASE_EXT_STRING0x00000200, &iax_causecodes_ext, 0x0,
3045 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3046
3047 {&hf_iax2_ies[IAX_IE_ENCRYPTION43],
3048 {"Encryption format", "iax2.iax.encryption",
3049 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
3050 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3051
3052 {&hf_iax2_ies[IAX_IE_ENCKEY44],
3053 {"Encryption key", "iax2.iax.enckey",
3054 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3055 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3056
3057 {&hf_iax2_ies[IAX_IE_CODEC_PREFS45],
3058 {"Codec negotiation", "iax2.iax.codecprefs",
3059 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3060 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3061
3062 {&hf_iax2_ies[IAX_IE_RR_JITTER46],
3063 {"Received jitter (as in RFC1889)", "iax2.iax.rrjitter",
3064 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
3065 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3066
3067 {&hf_iax2_ies[IAX_IE_RR_LOSS47],
3068 {"Received loss (high byte loss pct, low 24 bits loss count, as in rfc1889)", "iax2.iax.rrloss",
3069 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
3070 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3071
3072 {&hf_iax2_ies[IAX_IE_RR_PKTS48],
3073 {"Total frames received", "iax2.iax.rrpkts",
3074 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
3075 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3076
3077 {&hf_iax2_ies[IAX_IE_RR_DELAY49],
3078 {"Max playout delay in ms for received frames", "iax2.iax.rrdelay",
3079 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
3080 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3081
3082 {&hf_iax2_ies[IAX_IE_RR_DROPPED50],
3083 {"Dropped frames (presumably by jitterbuffer)", "iax2.iax.rrdropped",
3084 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
3085 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3086
3087 {&hf_iax2_ies[IAX_IE_RR_OOO51],
3088 {"Frame received out of order", "iax2.iax.rrooo",
3089 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
3090 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3091
3092 {&hf_iax2_ies[IAX_IE_CAPABILITY255],
3093 {"64-bit codec capability", "iax2.iax.capability2",
3094 FT_UINT64, BASE_HEX, NULL((void*)0), 0x0,
3095 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3096
3097 {&hf_iax2_ies[IAX_IE_FORMAT256],
3098 {"64-bit codec format", "iax2.iax.format2",
3099 FT_UINT64, BASE_HEX | BASE_EXT_STRING0x00000200 | BASE_VAL64_STRING0x00000400, &codec_types_ext, 0x0,
3100 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3101
3102 {&hf_iax2_ies[IAX_IE_DATAFORMAT255],
3103 {"Data call format", "iax2.iax.dataformat",
3104 FT_UINT32, BASE_HEX, VALS(iax_dataformats)((0 ? (const struct _value_string*)0 : ((iax_dataformats)))), 0x0,
3105 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3106
3107 {&hf_IAX_IE_UNKNOWN_BYTE,
3108 {"Unknown", "iax2.iax.unknownbyte",
3109 FT_UINT8, BASE_HEX, NULL((void*)0), 0x0,
3110 "Raw data for unknown IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3111
3112 {&hf_IAX_IE_UNKNOWN_I16,
3113 {"Unknown", "iax2.iax.unknownshort",
3114 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
3115 "Raw data for unknown IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3116
3117 {&hf_IAX_IE_UNKNOWN_I32,
3118 {"Unknown", "iax2.iax.unknownlong",
3119 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
3120 "Raw data for unknown IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3121
3122 {&hf_IAX_IE_UNKNOWN_BYTES,
3123 {"Unknown", "iax2.iax.unknownstring",
3124 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
3125 "Raw data for unknown IEs", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3126
3127 {&hf_iax2_ie_id,
3128 {"IE id", "iax2.ie_id",
3129 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200, &iax_ies_type_ext, 0x0,
3130 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3131
3132 {&hf_iax2_length,
3133 {"Length", "iax2.length",
3134 FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
3135 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3136
3137 {&hf_iax2_version,
3138 {"Version", "iax2.version",
3139 FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
3140 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)}},
3141
3142 /* capabilities */
3143 {&hf_iax2_cap_g723_1,
3144 {"G.723.1 compression", "iax2.cap.g723_1",
3145 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_G723_1)((0) == (uint32_t)-1 ? 0 : (1UL << (0))),
3146 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3147
3148 {&hf_iax2_cap_gsm,
3149 {"GSM compression", "iax2.cap.gsm",
3150 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_GSM)((1) == (uint32_t)-1 ? 0 : (1UL << (1))),
3151 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3152
3153 {&hf_iax2_cap_ulaw,
3154 {"Raw mu-law data (G.711)", "iax2.cap.ulaw",
3155 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_ULAW)((2) == (uint32_t)-1 ? 0 : (1UL << (2))),
3156 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3157
3158 {&hf_iax2_cap_alaw,
3159 {"Raw A-law data (G.711)", "iax2.cap.alaw",
3160 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_ALAW)((3) == (uint32_t)-1 ? 0 : (1UL << (3))),
3161 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } },
3162
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)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_G726_AAL2)((4) == (uint32_t)-1 ? 0 : (1UL << (4))),
3166 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3167
3168 {&hf_iax2_cap_adpcm,
3169 {"ADPCM", "iax2.cap.adpcm",
3170 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_ADPCM)((5) == (uint32_t)-1 ? 0 : (1UL << (5))),
3171 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3172
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)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_SLINEAR)((6) == (uint32_t)-1 ? 0 : (1UL << (6))),
3176 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3177
3178 {&hf_iax2_cap_lpc10,
3179 {"LPC10, 180 samples/frame", "iax2.cap.lpc10",
3180 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_LPC10)((7) == (uint32_t)-1 ? 0 : (1UL << (7))),
3181 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3182
3183 {&hf_iax2_cap_g729a,
3184 {"G.729a Audio", "iax2.cap.g729a",
3185 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_G729A)((8) == (uint32_t)-1 ? 0 : (1UL << (8))),
3186 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3187
3188 {&hf_iax2_cap_speex,
3189 {"SpeeX Free Compression", "iax2.cap.speex",
3190 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_SPEEX)((9) == (uint32_t)-1 ? 0 : (1UL << (9))),
3191 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3192
3193 {&hf_iax2_cap_ilbc,
3194 {"iLBC Free Compression", "iax2.cap.ilbc",
3195 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_ILBC)((10) == (uint32_t)-1 ? 0 : (1UL << (10))),
3196 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3197
3198 {&hf_iax2_cap_g726,
3199 {"ADPCM (G.726, 32kbps, RFC3551 codeword packing)", "iax2.cap.g726",
3200 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_G726)((11) == (uint32_t)-1 ? 0 : (1UL << (11))),
3201 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3202
3203 {&hf_iax2_cap_g722,
3204 {"G.722", "iax2.cap.g722",
3205 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_G722)((12) == (uint32_t)-1 ? 0 : (1UL << (12))),
3206 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3207
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)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_SIREN7)((13) == (uint32_t)-1 ? 0 : (1UL << (13))),
3211 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3212
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)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_SIREN14)((14) == (uint32_t)-1 ? 0 : (1UL << (14))),
3216 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3217
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)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_SLINEAR16)((15) == (uint32_t)-1 ? 0 : (1UL << (15))),
3221 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3222
3223 {&hf_iax2_cap_jpeg,
3224 {"JPEG images", "iax2.cap.jpeg",
3225 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_JPEG)((16) == (uint32_t)-1 ? 0 : (1UL << (16))),
3226 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3227
3228 {&hf_iax2_cap_png,
3229 {"PNG images", "iax2.cap.png",
3230 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_PNG)((17) == (uint32_t)-1 ? 0 : (1UL << (17))),
3231 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3232
3233 {&hf_iax2_cap_h261,
3234 {"H.261 video", "iax2.cap.h261",
3235 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_H261)((18) == (uint32_t)-1 ? 0 : (1UL << (18))),
3236 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3237
3238 {&hf_iax2_cap_h263,
3239 {"H.263 video", "iax2.cap.h263",
3240 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_H263)((19) == (uint32_t)-1 ? 0 : (1UL << (19))),
3241 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3242
3243 {&hf_iax2_cap_h263_plus,
3244 {"H.263+ video", "iax2.cap.h263_plus",
3245 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_H263_PLUS)((20) == (uint32_t)-1 ? 0 : (1UL << (20))),
3246 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3247
3248 {&hf_iax2_cap_h264,
3249 {"H.264 video", "iax2.cap.h264",
3250 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_H264)((21) == (uint32_t)-1 ? 0 : (1UL << (21))),
3251 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3252
3253 {&hf_iax2_cap_mpeg4,
3254 {"MPEG4 video", "iax2.cap.mpeg4",
3255 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_MP4_VIDEO)((22) == (uint32_t)-1 ? 0 : (1UL << (22))),
3256 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3257
3258 {&hf_iax2_cap_vp8,
3259 {"VP8 video", "iax2.cap.vp8",
3260 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_VP8)((23) == (uint32_t)-1 ? 0 : (1UL << (23))),
3261 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3262
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)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_T140_RED)((26) == (uint32_t)-1 ? 0 : (1UL << (26))),
3266 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3267
3268 {&hf_iax2_cap_t140,
3269 {"T.140 Text format - ITU T.140, RFC 4103", "iax2.cap.t140",
3270 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_T140)((27) == (uint32_t)-1 ? 0 : (1UL << (27))),
3271 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3272
3273 {&hf_iax2_cap_g719,
3274 {"G.719 (64 kbps assumed)", "iax2.cap.g719",
3275 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_G719)((32) == (uint32_t)-1 ? 0 : (1UL << (32))),
3276 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3277
3278 {&hf_iax2_cap_speex16,
3279 {"SpeeX Wideband (16kHz) Free Compression", "iax2.cap.speex16",
3280 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_SPEEX16)((33) == (uint32_t)-1 ? 0 : (1UL << (33))),
3281 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3282
3283 {&hf_iax2_cap_opus,
3284 {"Opus audio (8kHz, 16kHz, 24kHz, 48Khz)", "iax2.cap.opus",
3285 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_OPUS)((34) == (uint32_t)-1 ? 0 : (1UL << (34))),
3286 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3287
3288 {&hf_iax2_cap_testlaw,
3289 {"Raw testing-law data (G.711)", "iax2.cap.testlaw",
3290 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported)((0 ? (const struct true_false_string*)0 : ((&tfs_supported_not_supported
))))
, CODEC_MASK(AST_FORMAT_TESTLAW)((47) == (uint32_t)-1 ? 0 : (1UL << (47))),
3291 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3292
3293 {&hf_iax2_fragment_unfinished,
3294 {"IAX2 fragment, unfinished", "iax2.fragment_unfinished",
3295 FT_BYTES, BASE_NONE, NULL((void*)0), 0x0,
3296 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3297
3298 {&hf_iax2_payload_data,
3299 {"IAX2 payload", "iax2.payload_data",
3300 FT_BYTES, BASE_NONE, NULL((void*)0), 0x0,
3301 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3302
3303 /* reassembly stuff */
3304 {&hf_iax2_fragments,
3305 {"IAX2 Fragments", "iax2.fragments",
3306 FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
3307 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3308
3309 {&hf_iax2_fragment,
3310 {"IAX2 Fragment data", "iax2.fragment",
3311 FT_FRAMENUM, BASE_NONE, NULL((void*)0), 0x0,
3312 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3313
3314 {&hf_iax2_fragment_overlap,
3315 {"Fragment overlap", "iax2.fragment.overlap",
3316 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
3317 "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3318
3319 {&hf_iax2_fragment_overlap_conflict,
3320 {"Conflicting data in fragment overlap", "iax2.fragment.overlap.conflict",
3321 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
3322 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3323
3324 {&hf_iax2_fragment_multiple_tails,
3325 {"Multiple tail fragments found", "iax2.fragment.multipletails",
3326 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
3327 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3328
3329 {&hf_iax2_fragment_too_long_fragment,
3330 {"Fragment too long", "iax2.fragment.toolongfragment",
3331 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
3332 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3333
3334 {&hf_iax2_fragment_error,
3335 {"Defragmentation error", "iax2.fragment.error",
3336 FT_FRAMENUM, BASE_NONE, NULL((void*)0), 0x0,
3337 "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3338
3339 {&hf_iax2_fragment_count,
3340 {"Fragment count", "iax2.fragment.count",
3341 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
3342 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3343
3344 {&hf_iax2_reassembled_in,
3345 {"IAX2 fragment, reassembled in frame", "iax2.reassembled_in",
3346 FT_FRAMENUM, BASE_NONE, NULL((void*)0), 0x0,
3347 "This IAX2 packet is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
3348
3349 {&hf_iax2_reassembled_length,
3350 {"Reassembled IAX2 length", "iax2.reassembled.length",
3351 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
3352 "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }}
3353 };
3354
3355 static int *ett[] = {
3356 &ett_iax2,
3357 &ett_iax2_full_mini_subtree,
3358 &ett_iax2_type,
3359 &ett_iax2_ie,
3360 &ett_iax2_codecs,
3361 &ett_iax2_ies_apparent_addr,
3362 &ett_iax2_fragment,
3363 &ett_iax2_fragments,
3364 &ett_iax2_trunk_cmddata,
3365 &ett_iax2_trunk_call
3366 };
3367
3368 static ei_register_info ei[] = {
3369 { &ei_iax_too_many_transfers, { "iax2.too_many_transfers", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "Too many transfers for iax_call", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
3370 { &ei_iax_circuit_id_conflict, { "iax2.circuit_id_conflict", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "Circuit ID conflict", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
3371 { &ei_iax_peer_address_unsupported, { "iax2.peer_address_unsupported", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "Peer address unsupported", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
3372 { &ei_iax_invalid_len, { "iax2.invalid_len", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "Invalid length", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
3373 };
3374
3375 expert_module_t* expert_iax;
3376
3377 proto_iax2 = proto_register_protocol("Inter-Asterisk eXchange v2", "IAX2", "iax2");
3378 proto_register_field_array(proto_iax2, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
3379 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
3380 expert_iax = expert_register_protocol(proto_iax2);
3381 expert_register_field_array(expert_iax, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
3382
3383 iax2_handle = register_dissector("iax2", dissect_iax2, proto_iax2);
3384
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);
3389
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);
3396
3397 iax2_tap = register_tap("IAX2");
3398}
3399
3400void
3401proto_reg_handoff_iax2(void)
3402{
3403 dissector_handle_t v110_handle;
3404
3405 dissector_add_uint_with_preference("udp.port", IAX2_PORT4569, iax2_handle);
3406 v110_handle = find_dissector("v110");
3407 if (v110_handle)
3408 dissector_add_uint("iax2.dataformat", AST_DATAFORMAT_V110, v110_handle);
3409}
3410
3411/*
3412 * Editor modelines
3413 *
3414 * Local Variables:
3415 * c-basic-offset: 2
3416 * tab-width: 8
3417 * indent-tabs-mode: nil
3418 * End:
3419 *
3420 * ex: set shiftwidth=2 tabstop=8 expandtab:
3421 * :indentSize=2:tabSize=8:noTabs=true:
3422 */