1 /*
2 * packet-iax2.c
3 *
4 * Routines for IAX2 packet disassembly
5 * By Alastair Maw <asterisk@almaw.com>
6 * Copyright 2003 Alastair Maw
7 *
8 * IAX2 is a VoIP protocol for the open source PBX Asterisk. Please see
9 * http://www.asterisk.org for more information; see RFC 5456 for the
10 * protocol.
11 *
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
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/exceptions.h>
25 #include <epan/reassemble.h>
26 #include <epan/expert.h>
27 #include <epan/aftypes.h>
28 #include <epan/tap.h>
29 #include <epan/proto_data.h>
30 #include <epan/to_str.h>
31
32 #include <wsutil/str_util.h>
33
34 #include "packet-iax2.h"
35 #include <epan/iax2_codec_type.h>
36
37 void proto_register_iax2(void);
38 void proto_reg_handoff_iax2(void);
39
40 #define IAX2_PORT 4569
41 #define PROTO_TAG_IAX2 "IAX2"
42
43 /* enough to hold any address in an address_t */
44 #define MAX_ADDRESS 16
45
46 /* the maximum number of transfers (of each end) we can deal with per call,
47 * plus one */
48 #define IAX_MAX_TRANSFERS 2
49
50 /* #define DEBUG_HASHING */
51 /* #define DEBUG_DESEGMENT */
52
53 /* Wireshark ID of the IAX2 protocol */
54 static int proto_iax2 = -1;
55
56 /* tap register id */
57 static int iax2_tap = -1;
58
59 /* protocol tap info */
60 static iax2_info_t ii_arr[1];
61 static iax2_info_t *iax2_info = ii_arr;
62
63 /* The following hf_* variables are used to hold the wireshark IDs of
64 * our header fields; they are filled out when we call
65 * proto_register_field_array() in proto_register_iax2()
66 */
67 static int hf_iax2_packet_type = -1;
68 static int hf_iax2_retransmission = -1;
69 static int hf_iax2_callno = -1;
70 static int hf_iax2_scallno = -1;
71 static int hf_iax2_dcallno = -1;
72 static int hf_iax2_ts = -1;
73 static int hf_iax2_minits = -1;
74 static int hf_iax2_minividts = -1;
75 static int hf_iax2_absts = -1;
76 static int hf_iax2_lateness = -1;
77 static int hf_iax2_minividmarker = -1;
78 static int hf_iax2_oseqno = -1;
79 static int hf_iax2_iseqno = -1;
80 static int hf_iax2_type = -1;
81 static int hf_iax2_csub = -1;
82 static int hf_iax2_dtmf_csub = -1;
83 static int hf_iax2_cmd_csub = -1;
84 static int hf_iax2_iax_csub = -1;
85 static int hf_iax2_voice_csub = -1;
86 static int hf_iax2_voice_codec = -1;
87 static int hf_iax2_video_csub = -1;
88 static int hf_iax2_video_codec = -1;
89 static int hf_iax2_marker = -1;
90 static int hf_iax2_modem_csub = -1;
91 static int hf_iax2_text_csub = -1;
92 static int hf_iax2_text_text = -1;
93 static int hf_iax2_html_csub = -1;
94 static int hf_iax2_html_url = -1;
95 static int hf_iax2_trunk_metacmd = -1;
96 static int hf_iax2_trunk_cmddata = -1;
97 static int hf_iax2_trunk_cmddata_ts = -1;
98 static int hf_iax2_trunk_ts = -1;
99 static int hf_iax2_trunk_ncalls = -1;
100 static int hf_iax2_trunk_call_len = -1;
101 static int hf_iax2_trunk_call_scallno = -1;
102 static int hf_iax2_trunk_call_ts = -1;
103 static int hf_iax2_trunk_call_data = -1;
104
105 static int hf_iax2_ie_id = -1;
106 static int hf_iax2_length = -1;
107 static int hf_iax2_version = -1;
108 static int hf_iax2_cap_g723_1 = -1;
109 static int hf_iax2_cap_gsm = -1;
110 static int hf_iax2_cap_ulaw = -1;
111 static int hf_iax2_cap_alaw = -1;
112 static int hf_iax2_cap_g726_aal2 = -1;
113 static int hf_iax2_cap_adpcm = -1;
114 static int hf_iax2_cap_slinear = -1;
115 static int hf_iax2_cap_lpc10 = -1;
116 static int hf_iax2_cap_g729a = -1;
117 static int hf_iax2_cap_speex = -1;
118 static int hf_iax2_cap_ilbc = -1;
119 static int hf_iax2_cap_g726 = -1;
120 static int hf_iax2_cap_g722 = -1;
121 static int hf_iax2_cap_siren7 = -1;
122 static int hf_iax2_cap_siren14 = -1;
123 static int hf_iax2_cap_slinear16 = -1;
124 static int hf_iax2_cap_jpeg = -1;
125 static int hf_iax2_cap_png = -1;
126 static int hf_iax2_cap_h261 = -1;
127 static int hf_iax2_cap_h263 = -1;
128 static int hf_iax2_cap_h263_plus = -1;
129 static int hf_iax2_cap_h264 = -1;
130 static int hf_iax2_cap_mpeg4 = -1;
131 static int hf_iax2_cap_vp8 = -1;
132 static int hf_iax2_cap_t140_red = -1;
133 static int hf_iax2_cap_t140 = -1;
134 static int hf_iax2_cap_g719 = -1;
135 static int hf_iax2_cap_speex16 = -1;
136 static int hf_iax2_cap_opus = -1;
137 static int hf_iax2_cap_testlaw = -1;
138
139 static int * const hf_iax2_caps[] = {
140 &hf_iax2_cap_g723_1,
141 &hf_iax2_cap_gsm,
142 &hf_iax2_cap_ulaw,
143 &hf_iax2_cap_alaw,
144 &hf_iax2_cap_g726_aal2,
145 &hf_iax2_cap_adpcm,
146 &hf_iax2_cap_slinear,
147 &hf_iax2_cap_lpc10,
148 &hf_iax2_cap_g729a,
149 &hf_iax2_cap_speex,
150 &hf_iax2_cap_ilbc,
151 &hf_iax2_cap_g726,
152 &hf_iax2_cap_g722,
153 &hf_iax2_cap_siren7,
154 &hf_iax2_cap_siren14,
155 &hf_iax2_cap_slinear16,
156 &hf_iax2_cap_jpeg,
157 &hf_iax2_cap_png,
158 &hf_iax2_cap_h261,
159 &hf_iax2_cap_h263,
160 &hf_iax2_cap_h263_plus,
161 &hf_iax2_cap_h264,
162 &hf_iax2_cap_mpeg4,
163 &hf_iax2_cap_vp8,
164 &hf_iax2_cap_t140_red,
165 &hf_iax2_cap_t140,
166 &hf_iax2_cap_g719,
167 &hf_iax2_cap_speex16,
168 &hf_iax2_cap_opus,
169 &hf_iax2_cap_testlaw,
170 NULL
171 };
172
173 static int hf_iax2_fragment_unfinished = -1;
174 static int hf_iax2_payload_data = -1;
175 static int hf_iax2_fragments = -1;
176 static int hf_iax2_fragment = -1;
177 static int hf_iax2_fragment_overlap = -1;
178 static int hf_iax2_fragment_overlap_conflict = -1;
179 static int hf_iax2_fragment_multiple_tails = -1;
180 static int hf_iax2_fragment_too_long_fragment = -1;
181 static int hf_iax2_fragment_error = -1;
182 static int hf_iax2_fragment_count = -1;
183 static int hf_iax2_reassembled_in = -1;
184 static int hf_iax2_reassembled_length = -1;
185
186
187 /* hf_iax2_ies is an array of header fields, one per potential Information
188 * Element. It's done this way (rather than having separate variables for each
189 * IE) to make the dissection of information elements clearer and more
190 * orthogonal.
191 *
192 * To add the ability to dissect a new information element, just add an
193 * appropriate entry to hf[] in proto_register_iax2(); dissect_ies() will then
194 * pick it up automatically.
195 */
196 #define NUM_HF_IAX2_IES 256
197 static int hf_iax2_ies[NUM_HF_IAX2_IES];
198 static int hf_iax2_ie_datetime = -1;
199 static int hf_IAX_IE_APPARENTADDR_SINFAMILY = -1;
200 static int hf_IAX_IE_APPARENTADDR_SINPORT = -1;
201 static int hf_IAX_IE_APPARENTADDR_SINADDR = -1;
202 static int hf_IAX_IE_UNKNOWN_BYTE = -1;
203 static int hf_IAX_IE_UNKNOWN_I16 = -1;
204 static int hf_IAX_IE_UNKNOWN_I32 = -1;
205 static int hf_IAX_IE_UNKNOWN_BYTES = -1;
206
207 /* These are the ids of the subtrees that we may be creating */
208 static gint ett_iax2 = -1;
209 static gint ett_iax2_full_mini_subtree = -1;
210 static gint ett_iax2_type = -1; /* Frame-type specific subtree */
211 static gint ett_iax2_ie = -1; /* single IE */
212 static gint ett_iax2_codecs = -1; /* capabilities IE */
213 static gint ett_iax2_ies_apparent_addr = -1; /* apparent address IE */
214 static gint ett_iax2_fragment = -1;
215 static gint ett_iax2_fragments = -1;
216 static gint ett_iax2_trunk_cmddata = -1;
217 static gint ett_iax2_trunk_call = -1;
218
219 static expert_field ei_iax_too_many_transfers = EI_INIT;
220 static expert_field ei_iax_circuit_id_conflict = EI_INIT;
221 static expert_field ei_iax_peer_address_unsupported = EI_INIT;
222 static expert_field ei_iax_invalid_len = EI_INIT;
223
224 static dissector_handle_t iax2_handle;
225
226 static const fragment_items iax2_fragment_items = {
227 &ett_iax2_fragment,
228 &ett_iax2_fragments,
229 &hf_iax2_fragments,
230 &hf_iax2_fragment,
231 &hf_iax2_fragment_overlap,
232 &hf_iax2_fragment_overlap_conflict,
233 &hf_iax2_fragment_multiple_tails,
234 &hf_iax2_fragment_too_long_fragment,
235 &hf_iax2_fragment_error,
236 &hf_iax2_fragment_count,
237 &hf_iax2_reassembled_in,
238 &hf_iax2_reassembled_length,
239 /* Reassembled data field */
240 NULL,
241 "iax2 fragments"
242 };
243
244 /* data-call subdissectors, AST_DATAFORMAT_* */
245 static dissector_table_t iax2_dataformat_dissector_table;
246 /* voice/video call subdissectors, AST_FORMAT_* */
247 static dissector_table_t iax2_codec_dissector_table;
248
249
250 /* IAX2 Meta trunk packet Command data flags */
251 #define IAX2_TRUNK_TS 1
252
253 /* IAX2 Full-frame types */
254 static const value_string iax_frame_types[] = {
255 {0, "(0?)"},
256 {AST_FRAME_DTMF_END, "DTMF End"},
257 {AST_FRAME_VOICE, "Voice"},
258 {AST_FRAME_VIDEO, "Video"},
259 {AST_FRAME_CONTROL, "Control"},
260 {AST_FRAME_NULL, "NULL"},
261 {AST_FRAME_IAX, "IAX"},
262 {AST_FRAME_TEXT, "Text"},
263 {AST_FRAME_IMAGE, "Image"},
264 {AST_FRAME_HTML, "HTML"},
265 {AST_FRAME_CNG, "Comfort Noise"},
266 {AST_FRAME_MODEM, "Modem"},
267 {AST_FRAME_DTMF_BEGIN, "DTMF Begin"},
268 {0, NULL}
269 };
270 static value_string_ext iax_frame_types_ext = VALUE_STRING_EXT_INIT(iax_frame_types);
271
272 /* Subclasses for IAX packets */
273 static const value_string iax_iax_subclasses[] = {
274 { 0, "(0?)"},
275 { 1, "NEW"},
276 { 2, "PING"},
277 { 3, "PONG"},
278 { 4, "ACK"},
279 { 5, "HANGUP"},
280 { 6, "REJECT"},
281 { 7, "ACCEPT"},
282 { 8, "AUTHREQ"},
283 { 9, "AUTHREP"},
284 {10, "INVAL"},
285 {11, "LAGRQ"},
286 {12, "LAGRP"},
287 {13, "REGREQ"},
288 {14, "REGAUTH"},
289 {15, "REGACK"},
290 {16, "REGREJ"},
291 {17, "REGREL"},
292 {18, "VNAK"},
293 {19, "DPREQ"},
294 {20, "DPREP"},
295 {21, "DIAL"},
296 {22, "TXREQ"},
297 {23, "TXCNT"},
298 {24, "TXACC"},
299 {25, "TXREADY"},
300 {26, "TXREL"},
301 {27, "TXREJ"},
302 {28, "QUELCH"},
303 {29, "UNQULCH"},
304 {30, "POKE"},
305 {31, "PAGE"},
306 {32, "MWI"},
307 {33, "UNSUPPORTED"},
308 {34, "TRANSFER"},
309 {35, "PROVISION"},
310 {36, "FWDOWNL"},
311 {37, "FWDATA"},
312 {38, "TXMEDIA"},
313 {39, "RTKEY"},
314 {40, "CALLTOKEN"},
315 {0, NULL}
316 };
317 static value_string_ext iax_iax_subclasses_ext = VALUE_STRING_EXT_INIT(iax_iax_subclasses);
318
319 /* Subclasses for Control packets */
320 static const value_string iax_cmd_subclasses[] = {
321 {0, "(0?)"},
322 {1, "HANGUP"},
323 {2, "RING"},
324 {3, "RINGING"},
325 {4, "ANSWER"},
326 {5, "BUSY"},
327 {6, "TKOFFHK"},
328 {7, "OFFHOOK"},
329 {0xFF, "stop sounds"}, /* sent by app_dial, and not much else */
330 {0, NULL}
331 };
332 static value_string_ext iax_cmd_subclasses_ext = VALUE_STRING_EXT_INIT(iax_cmd_subclasses);
333
334 /* IAX2 to tap-voip call state mapping for command frames */
335 static const voip_call_state tap_cmd_voip_state[] = {
336 VOIP_NO_STATE,
337 VOIP_COMPLETED, /*HANGUP*/
338 VOIP_RINGING, /*RING*/
339 VOIP_RINGING, /*RINGING*/
340 VOIP_IN_CALL, /*ANSWER*/
341 VOIP_REJECTED, /*BUSY*/
342 VOIP_UNKNOWN, /*TKOFFHK*/
343 VOIP_UNKNOWN /*OFFHOOK*/
344 };
345 #define NUM_TAP_CMD_VOIP_STATES array_length(tap_cmd_voip_state)
346
347 /* IAX2 to tap-voip call state mapping for IAX frames */
348 static const voip_call_state tap_iax_voip_state[] = {
349 VOIP_NO_STATE,
350 VOIP_CALL_SETUP, /*NEW*/
351 VOIP_NO_STATE,
352 VOIP_NO_STATE,
353 VOIP_COMPLETED, /*HANGUP*/
354 VOIP_REJECTED, /*REJECT*/
355 VOIP_RINGING, /*ACCEPT*/
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_NO_STATE,
370 VOIP_CALL_SETUP, /*DIAL*/
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 VOIP_NO_STATE
387 };
388
389 #define NUM_TAP_IAX_VOIP_STATES array_length(tap_iax_voip_state)
390
391 /* Subclasses for Modem packets */
392 static const value_string iax_modem_subclasses[] = {
393 {0, "(0?)"},
394 {1, "T.38"},
395 {2, "V.150"},
396 {0, NULL}
397 };
398
399 /* Subclasses for Text packets */
400 static const value_string iax_text_subclasses[] = {
401 {0, "Text"},
402 {0, NULL}
403 };
404
405 /* Subclasses for HTML packets */
406 static const value_string iax_html_subclasses[] = {
407 {0x01, "Sending a URL"},
408 {0x02, "Data frame"},
409 {0x04, "Beginning frame"},
410 {0x08, "End frame"},
411 {0x10, "Load is complete"},
412 {0x11, "Peer does not support HTML"},
413 {0x12, "Link URL"},
414 {0x13, "Unlink URL"},
415 {0x14, "Reject Link URL"},
416 {0, NULL}
417 };
418
419
420 /* Information elements */
421 static const value_string iax_ies_type[] = {
422 {IAX_IE_CALLED_NUMBER, "Number/extension being called"},
423 {IAX_IE_CALLING_NUMBER, "Calling number"},
424 {IAX_IE_CALLING_ANI, "Calling number ANI for billing"},
425 {IAX_IE_CALLING_NAME, "Name of caller"},
426 {IAX_IE_CALLED_CONTEXT, "Context for number"},
427 {IAX_IE_USERNAME, "Username (peer or user) for authentication"},
428 {IAX_IE_PASSWORD, "Password for authentication"},
429 {IAX_IE_CAPABILITY, "Actual codec capability"},
430 {IAX_IE_FORMAT, "Desired codec format"},
431 {IAX_IE_LANGUAGE, "Desired language"},
432 {IAX_IE_VERSION, "Protocol version"},
433 {IAX_IE_ADSICPE, "CPE ADSI capability"},
434 {IAX_IE_DNID, "Originally dialed DNID"},
435 {IAX_IE_AUTHMETHODS, "Authentication method(s)"},
436 {IAX_IE_CHALLENGE, "Challenge data for MD5/RSA"},
437 {IAX_IE_MD5_RESULT, "MD5 challenge result"},
438 {IAX_IE_RSA_RESULT, "RSA challenge result"},
439 {IAX_IE_APPARENT_ADDR, "Apparent address of peer"},
440 {IAX_IE_REFRESH, "When to refresh registration"},
441 {IAX_IE_DPSTATUS, "Dialplan status"},
442 {IAX_IE_CALLNO, "Call number of peer"},
443 {IAX_IE_CAUSE, "Cause"},
444 {IAX_IE_IAX_UNKNOWN, "Unknown IAX command"},
445 {IAX_IE_MSGCOUNT, "How many messages waiting"},
446 {IAX_IE_AUTOANSWER, "Request auto-answering"},
447 {IAX_IE_MUSICONHOLD, "Request musiconhold with QUELCH"},
448 {IAX_IE_TRANSFERID, "Transfer Request Identifier"},
449 {IAX_IE_RDNIS, "Referring DNIS"},
450 {IAX_IE_PROVISIONING, "Provisioning info"},
451 {IAX_IE_AESPROVISIONING, "AES Provisioning info"},
452 {IAX_IE_DATETIME, "Date/Time"},
453 {IAX_IE_DEVICETYPE, "Device type"},
454 {IAX_IE_SERVICEIDENT, "Service Identifier"},
455 {IAX_IE_FIRMWAREVER, "Firmware revision"},
456 {IAX_IE_FWBLOCKDESC, "Firmware block description"},
457 {IAX_IE_FWBLOCKDATA, "Firmware block of data"},
458 {IAX_IE_PROVVER, "Provisioning version"},
459 {IAX_IE_CALLINGPRES, "Calling presentation"},
460 {IAX_IE_CALLINGTON, "Calling type of number"},
461 {IAX_IE_CALLINGTNS, "Calling transit network select"},
462 {IAX_IE_SAMPLINGRATE, "Supported sampling rates"},
463 {IAX_IE_CAUSECODE, "Hangup cause"},
464 {IAX_IE_ENCRYPTION, "Encryption format"},
465 {IAX_IE_ENCKEY, "Raw encryption key"},
466 {IAX_IE_CODEC_PREFS, "Codec preferences"},
467 {IAX_IE_RR_JITTER, "Received jitter"},
468 {IAX_IE_RR_LOSS, "Received loss"},
469 {IAX_IE_RR_PKTS, "Received frames"},
470 {IAX_IE_RR_DELAY, "Max playout delay in ms for received frames"},
471 {IAX_IE_RR_DROPPED, "Dropped frames"},
472 {IAX_IE_RR_OOO, "Frames received out of order"},
473 {IAX_IE_VARIABLE, "IAX2 variable"},
474 {IAX_IE_OSPTOKEN, "OSP Token"},
475 {IAX_IE_CALLTOKEN, "Call Token"},
476 {IAX_IE_CAPABILITY2, "64-bit codec capability"},
477 {IAX_IE_FORMAT2, "64-bit codec format"},
478 {IAX_IE_DATAFORMAT, "Data call format"},
479 {0, NULL}
480 };
481 static value_string_ext iax_ies_type_ext = VALUE_STRING_EXT_INIT(iax_ies_type);
482
483 #define CODEC_MASK(codec) ((codec) == (guint32)-1 ? 0 : (G_GUINT64_CONSTANT(1) << (codec)))
484
485 static const val64_string codec_types[] = {
486 {CODEC_MASK(AST_FORMAT_G723_1), "G.723.1 compression"},
487 {CODEC_MASK(AST_FORMAT_GSM), "GSM compression"},
488 {CODEC_MASK(AST_FORMAT_ULAW), "Raw mu-law data (G.711)"},
489 {CODEC_MASK(AST_FORMAT_ALAW), "Raw A-law data (G.711)"},
490 {CODEC_MASK(AST_FORMAT_G726_AAL2), "ADPCM (G.726), 32kbps, AAL2 codeword packing)"},
491 {CODEC_MASK(AST_FORMAT_ADPCM), "ADPCM (IMA)"},
492 {CODEC_MASK(AST_FORMAT_SLINEAR), "Raw 16-bit Signed Linear (8000 Hz) PCM"},
493 {CODEC_MASK(AST_FORMAT_LPC10), "LPC10, 180 samples/frame"},
494 {CODEC_MASK(AST_FORMAT_G729A), "G.729a Audio"},
495 {CODEC_MASK(AST_FORMAT_SPEEX), "SpeeX Free Compression"},
496 {CODEC_MASK(AST_FORMAT_ILBC), "iLBC Free Compression"},
497 {CODEC_MASK(AST_FORMAT_G726), "ADPCM (G.726, 32kbps, RFC3551 codeword packing)"},
498 {CODEC_MASK(AST_FORMAT_G722), "G.722"},
499 {CODEC_MASK(AST_FORMAT_SIREN7), "G.722.1 (also known as Siren7, 32kbps assumed)"},
500 {CODEC_MASK(AST_FORMAT_SIREN14), "G.722.1 Annex C (also known as Siren14, 48kbps assumed)"},
501 {CODEC_MASK(AST_FORMAT_SLINEAR16), "Raw 16-bit Signed Linear (16000 Hz) PCM"},
502 {CODEC_MASK(AST_FORMAT_JPEG), "JPEG Images"},
503 {CODEC_MASK(AST_FORMAT_PNG), "PNG Images"},
504 {CODEC_MASK(AST_FORMAT_H261), "H.261 Video"},
505 {CODEC_MASK(AST_FORMAT_H263), "H.263 Video"},
506 {CODEC_MASK(AST_FORMAT_H263_PLUS), "H.263+ Video"},
507 {CODEC_MASK(AST_FORMAT_H264), "H.264 Video"},
508 {CODEC_MASK(AST_FORMAT_MP4_VIDEO), "MPEG4 Video"},
509 {CODEC_MASK(AST_FORMAT_VP8), "VP8 Video"},
510 {CODEC_MASK(AST_FORMAT_T140_RED), "T.140 RED Text format RFC 4103"},
511 {CODEC_MASK(AST_FORMAT_T140), "T.140 Text format - ITU T.140, RFC 4103"},
512 {CODEC_MASK(AST_FORMAT_G719), "G.719 (64 kbps assumed)"},
513 {CODEC_MASK(AST_FORMAT_SPEEX16), "SpeeX Wideband (16kHz) Free Compression"},
514 {CODEC_MASK(AST_FORMAT_OPUS), "Opus audio (8kHz, 16kHz, 24kHz, 48Khz)"},
515 {CODEC_MASK(AST_FORMAT_TESTLAW), "Raw testing-law data (G.711)"},
516 {0, NULL}
517 };
518 static val64_string_ext codec_types_ext = VAL64_STRING_EXT_INIT(codec_types);
519
520 static const value_string iax_dataformats[] = {
521 {AST_DATAFORMAT_NULL, "N/A (analogue call?)"},
522 {AST_DATAFORMAT_V110, "ITU-T V.110 rate adaption"},
523 {AST_DATAFORMAT_H223_H245, "ITU-T H.223/H.245"},
524 {0, NULL}
525 };
526
527
528 static const value_string iax_packet_types[] = {
529 {IAX2_FULL_PACKET, "Full packet"},
530 {IAX2_MINI_VOICE_PACKET, "Mini voice packet"},
531 {IAX2_MINI_VIDEO_PACKET, "Mini video packet"},
532 {IAX2_TRUNK_PACKET, "Trunk packet"},
533 {0, NULL}
534 };
535
536 static const value_string iax_causecodes[] = {
537 {AST_CAUSE_UNALLOCATED, "Unallocated"},
538 {AST_CAUSE_NO_ROUTE_TRANSIT_NET, "No route transit net"},
539 {AST_CAUSE_NO_ROUTE_DESTINATION, "No route to destination"},
540 {AST_CAUSE_MISDIALLED_TRUNK_PREFIX, "Misdialled trunk prefix"},
541 {AST_CAUSE_CHANNEL_UNACCEPTABLE, "Channel unacceptable"},
542 {AST_CAUSE_CALL_AWARDED_DELIVERED, "Call awarded delivered"},
543 {AST_CAUSE_PRE_EMPTED, "Preempted"},
544 {AST_CAUSE_NUMBER_PORTED_NOT_HERE, "Number ported not here"},
545 {AST_CAUSE_NORMAL_CLEARING, "Normal clearing"},
546 {AST_CAUSE_USER_BUSY, "User busy"},
547 {AST_CAUSE_NO_USER_RESPONSE, "No user response"},
548 {AST_CAUSE_NO_ANSWER, "No answer"},
549 {AST_CAUSE_SUBSCRIBER_ABSENT, "Subscriber absent"},
550 {AST_CAUSE_CALL_REJECTED, "Call rejected"},
551 {AST_CAUSE_NUMBER_CHANGED, "Number changed"},
552 {AST_CAUSE_REDIRECTED_TO_NEW_DESTINATION, "Redirected to new destination"},
553 {AST_CAUSE_ANSWERED_ELSEWHERE, "Answered elsewhere"},
554 {AST_CAUSE_DESTINATION_OUT_OF_ORDER, "Destination out of order"},
555 {AST_CAUSE_INVALID_NUMBER_FORMAT, "Invalid number format"},
556 {AST_CAUSE_FACILITY_REJECTED, "Facility rejected"},
557 {AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "Response to status inquiry"},
558 {AST_CAUSE_NORMAL_UNSPECIFIED, "Normal unspecified"},
559 {AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "Normal circuit congestion"},
560 {AST_CAUSE_NETWORK_OUT_OF_ORDER, "Network out of order"},
561 {AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "Normal temporary failure"},
562 {AST_CAUSE_SWITCH_CONGESTION, "Switch congestion"},
563 {AST_CAUSE_ACCESS_INFO_DISCARDED, "Access info discarded"},
564 {AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "Requested channel unavailable"},
565 {AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "Facility not subscribed"},
566 {AST_CAUSE_OUTGOING_CALL_BARRED, "Outgoing call barred"},
567 {AST_CAUSE_INCOMING_CALL_BARRED, "Incoming call barred"},
568 {AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "Bearer capability not authorized"},
569 {AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "Bearer capability not available"},
570 {AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "Bearer capability not implemented"},
571 {AST_CAUSE_CHAN_NOT_IMPLEMENTED, "Channel not implemented"},
572 {AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "Facility not implemented"},
573 {AST_CAUSE_INVALID_CALL_REFERENCE, "Invalid call reference"},
574 {AST_CAUSE_INCOMPATIBLE_DESTINATION, "Incompatible destination"},
575 {AST_CAUSE_INVALID_MSG_UNSPECIFIED, "Invalid message unspecified"},
576 {AST_CAUSE_MANDATORY_IE_MISSING, "Mandatory IE missing"},
577 {AST_CAUSE_MESSAGE_TYPE_NONEXIST, "Message type nonexistent"},
578 {AST_CAUSE_WRONG_MESSAGE, "Wrong message"},
579 {AST_CAUSE_IE_NONEXIST, "IE nonexistent"},
580 {AST_CAUSE_INVALID_IE_CONTENTS, "Invalid IE contents"},
581 {AST_CAUSE_WRONG_CALL_STATE, "Wrong call state"},
582 {AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "Recovery on timer expire"},
583 {AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "Mandatory IE length error"},
584 {AST_CAUSE_PROTOCOL_ERROR, "Protocol error"},
585 {AST_CAUSE_INTERWORKING, "Interworking"},
586 {0, NULL}
587 };
588 static value_string_ext iax_causecodes_ext = VALUE_STRING_EXT_INIT(iax_causecodes);
589
590 /* ************************************************************************* */
591
592 /* In order to track IAX calls, we have a hash table which maps
593 * {addr,port type,port,call} to a unique circuit id.
594 *
595 * Each call has two such circuits associated with it (a forward and a
596 * reverse circuit, where 'forward' is defined as the direction the NEW
597 * packet went in), and we maintain an iax_call_data structure for each
598 * call, attached to both circuits with circuit_add_proto_data.
599 *
600 * Because {addr,port type,port,call} quadruplets can be reused
601 * (Asterisk reuses call numbers), circuit ids aren't unique to
602 * individual calls and we treat NEW packets somewhat specially. When we
603 * get such a packet, we see if there are any calls with a matching
604 * circuit id, and make sure that its circuits are marked as ended
605 * before that packet.
606 *
607 * A second complication is that we only know one quadruplet at the time
608 * the NEW packet is processed: there is therefore cunningness in
609 * iax_lookup_circuit_details() to look for replies to NEW packets and
610 * create the reverse circuit.
611 */
612
613
614 /* start with a hash of {addr,port type,port,call}->{id} */
615
616 typedef struct {
617 address addr;
618 port_type ptype;
619 guint32 port;
620 guint32 callno;
621
622 /* this is where addr->data points to. it's put in here for easy freeing */
623 guint8 address_data[MAX_ADDRESS];
624 } iax_circuit_key;
625
626 /* tables */
627 static GHashTable *iax_fid_table = NULL;
628 static reassembly_table iax_reassembly_table;
629
630 static GHashTable *iax_circuit_hashtab = NULL;
631 static guint circuitcount = 0;
632
633 /* the number of keys and values to reserve space for in each memory chunk.
634 We assume we won't be tracking many calls at once so this is quite low.
635 */
636 #define IAX_INIT_PACKET_COUNT 10
637
638 #ifdef DEBUG_HASHING
key_to_str(const iax_circuit_key * key)639 static gchar *key_to_str( const iax_circuit_key *key )
640 {
641 static int i = 0;
642 static gchar str[3][80];
643 gchar *strp;
644 gchar *addrstr;
645
646 i++;
647 if (i >= 3) {
648 i = 0;
649 }
650 strp = str[i];
651
652 addrstr = address_to_str(NULL, &key->addr);
653 g_snprintf(strp, 80, "{%s:%i,%i}",
654 addrstr,
655 key->port,
656 key->callno);
657 wmem_free(NULL, addrstr);
658 return strp;
659 }
660 #endif
661
662 /* Hash Functions */
iax_circuit_equal(gconstpointer v,gconstpointer w)663 static gint iax_circuit_equal(gconstpointer v, gconstpointer w)
664 {
665 const iax_circuit_key *v1 = (const iax_circuit_key *)v;
666 const iax_circuit_key *v2 = (const iax_circuit_key *)w;
667 gint result;
668
669 result = (addresses_equal(&(v1->addr), &(v2->addr)) &&
670 v1->ptype == v2->ptype &&
671 v1->port == v2->port &&
672 v1->callno== v2->callno);
673 #ifdef DEBUG_HASHING
674 ws_debug("+++ Comparing for equality: %s, %s: %u", key_to_str(v1), key_to_str(v2), result);
675 #endif
676
677 return result;
678 }
679
iax_circuit_hash(gconstpointer v)680 static guint iax_circuit_hash(gconstpointer v)
681 {
682 const iax_circuit_key *key = (const iax_circuit_key *)v;
683 guint hash_val;
684
685 hash_val = 0;
686 hash_val = add_address_to_hash(hash_val, &key->addr);
687 hash_val += (guint)(key->ptype);
688 hash_val += (guint)(key->port);
689 hash_val += (guint)(key->callno);
690
691 #ifdef DEBUG_HASHING
692 ws_debug("+++ Hashing key: %s, result %#x", key_to_str(key), hash_val);
693 #endif
694
695 return (guint)hash_val;
696 }
697
698 /* Find, or create, a circuit for the given
699 {address,porttype,port,call} quadruplet
700 */
iax_circuit_lookup(const address * address_p,port_type ptype,guint32 port,guint32 callno)701 static guint iax_circuit_lookup(const address *address_p,
702 port_type ptype,
703 guint32 port,
704 guint32 callno)
705 {
706 iax_circuit_key key;
707 guint32 *circuit_id_p;
708
709 key.addr = *address_p;
710 key.ptype = ptype;
711 key.port = port;
712 key.callno = callno;
713
714 circuit_id_p = (guint32 *)g_hash_table_lookup(iax_circuit_hashtab, &key);
715 if (! circuit_id_p) {
716 iax_circuit_key *new_key;
717
718 new_key = wmem_new(wmem_file_scope(), iax_circuit_key);
719 new_key->addr.type = address_p->type;
720 new_key->addr.len = MIN(address_p->len, MAX_ADDRESS);
721 new_key->addr.data = new_key->address_data;
722 if (new_key->addr.len > 0)
723 memcpy(new_key->address_data, address_p->data, new_key->addr.len);
724 new_key->ptype = ptype;
725 new_key->port = port;
726 new_key->callno = callno;
727
728 circuit_id_p = (guint32 *)wmem_new(wmem_file_scope(), iax_circuit_key);
729 *circuit_id_p = ++circuitcount;
730
731 g_hash_table_insert(iax_circuit_hashtab, new_key, circuit_id_p);
732
733 #ifdef DEBUG_HASHING
734 ws_debug("Created new circuit id %u for node %s", *circuit_id_p, key_to_str(new_key));
735 #endif
736 }
737
738 return *circuit_id_p;
739 }
740
741
742 /* ************************************************************************* */
743
744 typedef struct {
745 guint32 current_frag_id; /* invalid unless current_frag_bytes > 0 */
746 guint32 current_frag_bytes;
747 guint32 current_frag_minlen;
748 } iax_call_dirdata;
749
750 /* This is our per-call data structure, which is attached to both the
751 * forward and reverse circuits.
752 */
753 typedef struct iax_call_data {
754 /* For this data, src and dst are relative to the original direction under
755 which this call is stored. Obviously if the reversed flag is set true by
756 iax_find_call, src and dst are reversed relative to the direction the
757 actual source and destination of the data.
758
759 if the codec changes mid-call, we update it here; because we store a codec
760 number with each packet too, we handle going back to earlier packets
761 without problem.
762 */
763
764 iax_dataformat_t dataformat;
765 guint32 src_codec, dst_codec;
766 guint32 src_vformat, dst_vformat;
767
768 /* when a transfer takes place, we'll get a new circuit id; we assume that we
769 don't try to transfer more than IAX_MAX_TRANSFERS times in a call */
770 guint forward_circuit_ids[IAX_MAX_TRANSFERS];
771 guint reverse_circuit_ids[IAX_MAX_TRANSFERS];
772 guint n_forward_circuit_ids;
773 guint n_reverse_circuit_ids;
774
775 /* this is the subdissector for the call */
776 dissector_handle_t subdissector;
777
778 /* the absolute start time of the call */
779 nstime_t start_time;
780
781 /* time stamp from last full frame, in the first pass */
782 guint32 last_full_frame_ts;
783
784 iax_call_dirdata dirdata[2];
785 } iax_call_data;
786
787
788
789 /* creates a new ENDPOINT_IAX2 circuit with a specified circuit id for a call
790 *
791 * typically a call has up to three associated circuits: an original source, an
792 * original destination, and the result of a transfer.
793 *
794 * For each endpoint, a ENDPOINT_IAX2 circuit is created and added to the call_data
795 * by this function
796 *
797 * 'reversed' should be true if this end is the one which would have _received_
798 * the NEW packet, or it is an endpoint to which the 'destination' is being
799 * transferred.
800 *
801 */
iax2_new_circuit_for_call(packet_info * pinfo,proto_item * item,guint circuit_id,guint framenum,iax_call_data * iax_call,gboolean reversed)802 static conversation_t *iax2_new_circuit_for_call(packet_info *pinfo, proto_item * item,
803 guint circuit_id, guint framenum,
804 iax_call_data *iax_call, gboolean reversed)
805 {
806 conversation_t *conv;
807
808 if(!iax_call){
809 return NULL;
810 }
811 if ((reversed && iax_call->n_reverse_circuit_ids >= IAX_MAX_TRANSFERS) ||
812 (! reversed && iax_call->n_forward_circuit_ids >= IAX_MAX_TRANSFERS)) {
813 expert_add_info(pinfo, item, &ei_iax_too_many_transfers);
814 return NULL;
815 }
816
817 conv = conversation_new_by_id(framenum, ENDPOINT_IAX2,
818 circuit_id, 0);
819
820 conversation_add_proto_data(conv, proto_iax2, iax_call);
821
822 if (reversed)
823 iax_call -> reverse_circuit_ids[iax_call->n_reverse_circuit_ids++] = circuit_id;
824 else
825 iax_call -> forward_circuit_ids[iax_call->n_forward_circuit_ids++] = circuit_id;
826
827 return conv;
828 }
829
830
831 /* returns true if this circuit id is a "forward" circuit for this call: ie, it
832 * is the point which _sent_ the original 'NEW' packet, or a point to which that
833 * end was subsequently transferred */
is_forward_circuit(guint circuit_id,const iax_call_data * iax_call)834 static gboolean is_forward_circuit(guint circuit_id,
835 const iax_call_data *iax_call)
836 {
837 guint i;
838 for(i=0; i<iax_call->n_forward_circuit_ids; i++) {
839 if (circuit_id == iax_call->forward_circuit_ids[i])
840 return TRUE;
841 }
842 return FALSE;
843 }
844
845 /* returns true if this circuit id is a "reverse" circuit for this call: ie, it
846 * is the point which _received_ the original 'NEW' packet, or a point to which that
847 * end was subsequently transferred */
is_reverse_circuit(guint circuit_id,const iax_call_data * iax_call)848 static gboolean is_reverse_circuit(guint circuit_id,
849 const iax_call_data *iax_call)
850 {
851 guint i;
852 for(i=0; i<iax_call->n_reverse_circuit_ids; i++){
853 if (circuit_id == iax_call->reverse_circuit_ids[i])
854 return TRUE;
855 }
856 return FALSE;
857 }
858
859
iax_lookup_call_from_dest(packet_info * pinfo,proto_item * item,guint src_circuit_id,guint dst_circuit_id,guint framenum,gboolean * reversed_p)860 static iax_call_data *iax_lookup_call_from_dest(packet_info *pinfo, proto_item * item,
861 guint src_circuit_id,
862 guint dst_circuit_id,
863 guint framenum,
864 gboolean *reversed_p)
865 {
866 conversation_t *dst_conv;
867 iax_call_data *iax_call;
868 gboolean reversed = FALSE;
869
870 dst_conv = find_conversation_by_id(framenum, ENDPOINT_IAX2, dst_circuit_id, 0);
871
872 if (!dst_conv) {
873 #ifdef DEBUG_HASHING
874 ws_debug("++ destination circuit not found, must have missed NEW packet");
875 #endif
876 if (reversed_p)
877 *reversed_p = FALSE;
878 return NULL;
879 }
880
881 #ifdef DEBUG_HASHING
882 ws_debug("++ found destination circuit");
883 #endif
884
885 iax_call = (iax_call_data *)conversation_get_proto_data(dst_conv, proto_iax2);
886
887 /* there's no way we can create a ENDPOINT_IAX2 circuit without adding
888 iax call data to it; assert this */
889 DISSECTOR_ASSERT(iax_call);
890
891 if (is_forward_circuit(dst_circuit_id, iax_call)) {
892 #ifdef DEBUG_HASHING
893 ws_debug("++ destination circuit matches forward_circuit_id of call, "
894 "therefore packet is reversed");
895 #endif
896
897 reversed = TRUE;
898
899 if (iax_call -> n_reverse_circuit_ids == 0) {
900 /* we are going in the reverse direction, and this call
901 doesn't have a reverse circuit associated with it.
902 create one now. */
903 #ifdef DEBUG_HASHING
904 ws_debug("++ reverse_circuit_id of call is zero, need to create a "
905 "new reverse circuit for this call");
906 #endif
907
908 iax2_new_circuit_for_call(pinfo, item, src_circuit_id, framenum, iax_call, TRUE);
909 #ifdef DEBUG_HASHING
910 ws_debug("++ done");
911 #endif
912 } else if (!is_reverse_circuit(src_circuit_id, iax_call)) {
913 expert_add_info_format(pinfo, item, &ei_iax_circuit_id_conflict,
914 "IAX Packet %u from circuit ids %u->%u conflicts with earlier call with circuit ids %u->%u",
915 framenum,
916 src_circuit_id, dst_circuit_id,
917 iax_call->forward_circuit_ids[0],
918 iax_call->reverse_circuit_ids[0]);
919 return NULL;
920 }
921 } else if (is_reverse_circuit(dst_circuit_id, iax_call)) {
922 #ifdef DEBUG_HASHING
923 ws_debug("++ destination circuit matches reverse_circuit_id of call, "
924 "therefore packet is forward");
925 #endif
926
927 reversed = FALSE;
928 if (!is_forward_circuit(src_circuit_id, iax_call)) {
929 expert_add_info_format(pinfo, item, &ei_iax_circuit_id_conflict,
930 "IAX Packet %u from circuit ids %u->%u conflicts with earlier call with circuit ids %u->%u",
931 framenum,
932 src_circuit_id, dst_circuit_id,
933 iax_call->forward_circuit_ids[0],
934 iax_call->reverse_circuit_ids[0]);
935 if (reversed_p)
936 *reversed_p = FALSE;
937 return NULL;
938 }
939 } else {
940 DISSECTOR_ASSERT_NOT_REACHED();
941 }
942
943 if (reversed_p)
944 *reversed_p = reversed;
945
946 return iax_call;
947 }
948
949
950 /* looks up an iax_call for this packet */
iax_lookup_call(packet_info * pinfo,guint32 scallno,guint32 dcallno,gboolean * reversed_p)951 static iax_call_data *iax_lookup_call( packet_info *pinfo,
952 guint32 scallno,
953 guint32 dcallno,
954 gboolean *reversed_p)
955 {
956 gboolean reversed = FALSE;
957 iax_call_data *iax_call = NULL;
958 guint src_circuit_id;
959 #ifdef DEBUG_HASHING
960 gchar *srcstr, *dststr;
961 #endif
962
963 #ifdef DEBUG_HASHING
964 srcstr = address_to_str(NULL, &pinfo->src);
965 dststr = address_to_str(NULL, &pinfo->dst);
966 ws_debug("++ iax_lookup_circuit_details: Looking up circuit for frame %u, "
967 "from {%s:%u:%u} to {%s:%u:%u}", pinfo->num,
968 srcstr, pinfo->srcport, scallno,
969 dststr, pinfo->destport, dcallno);
970 wmem_free(NULL, srcstr);
971 wmem_free(NULL, dststr);
972 #endif
973
974
975 src_circuit_id = iax_circuit_lookup(&pinfo->src, pinfo->ptype,
976 pinfo->srcport, scallno);
977
978
979 /* the most reliable indicator of call is the destination callno, if
980 we have one */
981 if (dcallno != 0) {
982 guint dst_circuit_id;
983 #ifdef DEBUG_HASHING
984 ws_debug("++ dcallno non-zero, looking up destination circuit");
985 #endif
986
987 dst_circuit_id = iax_circuit_lookup(&pinfo->dst, pinfo->ptype,
988 pinfo->destport, dcallno);
989
990 iax_call = iax_lookup_call_from_dest(pinfo, NULL, src_circuit_id, dst_circuit_id,
991 pinfo->num, &reversed);
992 } else {
993 conversation_t *src_conv;
994
995 /* in all other circumstances, the source circuit should already
996 * exist: its absence indicates that we missed the all-important NEW
997 * packet.
998 */
999
1000 src_conv = find_conversation_by_id(pinfo->num, ENDPOINT_IAX2, src_circuit_id, 0);
1001
1002 if (src_conv) {
1003 iax_call = (iax_call_data *)conversation_get_proto_data(src_conv, proto_iax2);
1004
1005 /* there's no way we can create a ENDPOINT_IAX2 circuit without adding
1006 iax call data to it; assert this */
1007 DISSECTOR_ASSERT(iax_call);
1008
1009 if (is_forward_circuit(src_circuit_id, iax_call))
1010 reversed = FALSE;
1011 else if (is_reverse_circuit(src_circuit_id, iax_call))
1012 reversed = TRUE;
1013 else {
1014 /* there's also no way we can attach an iax_call_data to a circuit
1015 without the circuit being either the forward or reverse circuit
1016 for that call; assert this too.
1017 */
1018 DISSECTOR_ASSERT_NOT_REACHED();
1019 }
1020 }
1021 }
1022
1023 if (reversed_p)
1024 *reversed_p = reversed;
1025
1026 #ifdef DEBUG_HASHING
1027 if (iax_call) {
1028 ws_debug("++ Found call for packet: id %u, reversed=%c", iax_call->forward_circuit_ids[0], reversed?'1':'0');
1029 } else {
1030 ws_debug("++ Call not found. Must have missed the NEW packet?");
1031 }
1032 #endif
1033
1034 return iax_call;
1035 }
1036
1037 /* initialize the per-direction parts of an iax_call_data structure */
init_dir_data(iax_call_dirdata * dirdata)1038 static void init_dir_data(iax_call_dirdata *dirdata)
1039 {
1040 dirdata -> current_frag_bytes=0;
1041 dirdata -> current_frag_minlen=0;
1042 }
1043
1044
1045 /* handles a NEW packet by creating a new iax call and forward circuit.
1046 the reverse circuit is not created until the ACK is received and
1047 is created by iax_lookup_circuit_details. */
iax_new_call(packet_info * pinfo,guint32 scallno)1048 static iax_call_data *iax_new_call( packet_info *pinfo,
1049 guint32 scallno)
1050 {
1051 iax_call_data *call;
1052 guint circuit_id;
1053 static const nstime_t millisecond = NSTIME_INIT_SECS_MSECS(0, 1);
1054
1055 #ifdef DEBUG_HASHING
1056 ws_debug("+ new_circuit: Handling NEW packet, frame %u", pinfo->num);
1057 #endif
1058
1059 circuit_id = iax_circuit_lookup(&pinfo->src, pinfo->ptype,
1060 pinfo->srcport, scallno);
1061
1062 call = wmem_new(wmem_file_scope(), iax_call_data);
1063 call -> dataformat = AST_DATAFORMAT_NULL;
1064 call -> src_codec = 0;
1065 call -> dst_codec = 0;
1066 call -> src_vformat = 0;
1067 call -> dst_vformat = 0;
1068 call -> n_forward_circuit_ids = 0;
1069 call -> n_reverse_circuit_ids = 0;
1070 call -> subdissector = NULL;
1071 call -> start_time = pinfo->abs_ts;
1072 call -> last_full_frame_ts = 0;
1073 nstime_delta(&call -> start_time, &call -> start_time, &millisecond);
1074 init_dir_data(&call->dirdata[0]);
1075 init_dir_data(&call->dirdata[1]);
1076
1077 iax2_new_circuit_for_call(pinfo, NULL, circuit_id, pinfo->num, call, FALSE);
1078
1079 return call;
1080 }
1081
1082
1083 /* ************************************************************************* */
1084
1085 /* per-packet data */
1086 typedef struct iax_packet_data {
1087 gboolean first_time; /* we're dissecting this packet for the first time; so
1088 * things like codec and transfer requests should be
1089 * propagated into the call data */
1090 iax_call_data *call_data;
1091 guint32 codec;
1092 gboolean reversed;
1093 nstime_t abstime; /* the absolute time of this packet, based on its
1094 * timestamp and the NEW packet's time (-1 if unknown) */
1095 } iax_packet_data;
1096
iax_new_packet_data(iax_call_data * call,gboolean reversed)1097 static iax_packet_data *iax_new_packet_data(iax_call_data *call, gboolean reversed)
1098 {
1099 iax_packet_data *p = wmem_new(wmem_file_scope(), iax_packet_data);
1100 p->first_time = TRUE;
1101 p->call_data = call;
1102 p->codec = 0;
1103 p->reversed = reversed;
1104 p->abstime.secs = -1;
1105 p->abstime.nsecs = -1;
1106 return p;
1107 }
1108
iax2_populate_pinfo_from_packet_data(packet_info * pinfo,const iax_packet_data * p)1109 static void iax2_populate_pinfo_from_packet_data(packet_info *pinfo, const iax_packet_data *p)
1110 {
1111 if (p->call_data != NULL) {
1112 /* if we missed the NEW packet for this call, call_data will be null. it's
1113 * tbd what the best thing to do here is. */
1114 pinfo->p2p_dir = p->reversed?P2P_DIR_RECV:P2P_DIR_SENT;
1115
1116 col_set_str(pinfo->cinfo, COL_IF_DIR, p->reversed ? "rev" : "fwd");
1117 }
1118 }
1119
1120
1121 /* ************************************************************************* */
1122
1123 /* this is passed up from the IE dissector to the main dissector */
1124 typedef struct
1125 {
1126 address peer_address;
1127 port_type peer_ptype;
1128 guint32 peer_port;
1129 guint32 peer_callno;
1130 guint32 dataformat;
1131 } iax2_ie_data;
1132
1133
1134 static guint32 dissect_fullpacket(tvbuff_t *tvb, guint32 offset,
1135 guint16 scallno,
1136 packet_info *pinfo,
1137 proto_tree *iax2_tree,
1138 proto_tree *main_tree);
1139
1140
1141 static guint32 dissect_minipacket(tvbuff_t *tvb, guint32 offset,
1142 guint16 scallno,
1143 packet_info *pinfo,
1144 proto_tree *iax2_tree,
1145 proto_tree *main_tree);
1146
1147 static guint32 dissect_minivideopacket(tvbuff_t *tvb, guint32 offset,
1148 guint16 scallno,
1149 packet_info *pinfo,
1150 proto_tree *iax2_tree,
1151 proto_tree *main_tree);
1152
1153 static guint32 dissect_trunkpacket(tvbuff_t *tvb, guint32 offset,
1154 guint16 scallno,
1155 packet_info *pinfo,
1156 proto_tree *iax2_tree,
1157 proto_tree *main_tree);
1158
1159 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
1160 packet_info *pinfo, proto_tree *iax2_tree,
1161 proto_tree *tree, guint32 ts, gboolean video,
1162 iax_packet_data *iax_packet);
1163
1164
1165
1166 static int
dissect_iax2(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1167 dissect_iax2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1168 {
1169 proto_item *iax2_item;
1170 proto_tree *iax2_tree;
1171 proto_tree *full_mini_subtree = NULL;
1172 guint32 offset = 0, len;
1173 guint16 scallno = 0;
1174 guint16 stmp;
1175 packet_type type;
1176 proto_item *full_mini_base;
1177
1178 /* set up the protocol and info fields in the summary pane */
1179 col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_IAX2);
1180 col_clear(pinfo->cinfo, COL_INFO);
1181
1182 /* add the 'iax2' tree to the main tree */
1183 iax2_item = proto_tree_add_item(tree, proto_iax2, tvb, offset, -1, ENC_NA);
1184 iax2_tree = proto_item_add_subtree(iax2_item, ett_iax2);
1185
1186 stmp = tvb_get_ntohs(tvb, offset);
1187 if (stmp == 0) {
1188 /* starting with 0x0000 indicates meta packet which can be either a mini
1189 * video packet or a trunk packet */
1190 offset+=2;
1191 stmp = tvb_get_ntohs(tvb, offset);
1192 if (stmp & 0x8000) {
1193 /* mini video packet */
1194 type = IAX2_MINI_VIDEO_PACKET;
1195 scallno = stmp & 0x7FFF;
1196 offset += 2;
1197 }
1198 else {
1199 type = IAX2_TRUNK_PACKET;
1200 }
1201 } else {
1202 /* The source call/fullpacket flag is common to both mini and full packets */
1203 scallno = tvb_get_ntohs(tvb, offset);
1204 offset += 2;
1205 if (scallno & 0x8000)
1206 type = IAX2_FULL_PACKET;
1207 else {
1208 type = IAX2_MINI_VOICE_PACKET;
1209 }
1210 scallno &= 0x7FFF;
1211 }
1212
1213 full_mini_base = proto_tree_add_uint(iax2_tree, hf_iax2_packet_type, tvb, 0, offset, type);
1214 full_mini_subtree = proto_item_add_subtree(full_mini_base, ett_iax2_full_mini_subtree);
1215
1216 if (scallno != 0)
1217 proto_tree_add_item(full_mini_subtree, hf_iax2_scallno, tvb, offset-2, 2, ENC_BIG_ENDIAN);
1218
1219 iax2_info->ptype = type;
1220 iax2_info->scallno = 0;
1221 iax2_info->dcallno = 0;
1222 iax2_info->ftype = 0;
1223 iax2_info->csub = 0;
1224 iax2_info->payload_len = 0;
1225 iax2_info->timestamp = 0;
1226 iax2_info->callState = VOIP_NO_STATE;
1227 iax2_info->messageName = NULL;
1228 iax2_info->callingParty = NULL;
1229 iax2_info->calledParty = NULL;
1230 iax2_info->payload_data = NULL;
1231
1232 switch (type) {
1233 case IAX2_FULL_PACKET:
1234 len = dissect_fullpacket(tvb, offset, scallno, pinfo, full_mini_subtree, tree);
1235 break;
1236 case IAX2_MINI_VOICE_PACKET:
1237 iax2_info->messageName = "MINI_VOICE_PACKET";
1238 len = dissect_minipacket(tvb, offset, scallno, pinfo, full_mini_subtree, tree);
1239 break;
1240 case IAX2_MINI_VIDEO_PACKET:
1241 iax2_info->messageName = "MINI_VIDEO_PACKET";
1242 len = dissect_minivideopacket(tvb, offset, scallno, pinfo, full_mini_subtree, tree);
1243 break;
1244 case IAX2_TRUNK_PACKET:
1245 iax2_info->messageName = "TRUNK_PACKET";
1246 len = dissect_trunkpacket(tvb, offset, scallno, pinfo, full_mini_subtree, tree);
1247 break;
1248 default:
1249 len = 0;
1250 }
1251
1252 /* update the 'length' of the main IAX2 header field so that it covers just the headers,
1253 not the audio data. */
1254 proto_item_set_len(iax2_item, len);
1255 tap_queue_packet(iax2_tap, pinfo, iax2_info);
1256 return tvb_captured_length(tvb);
1257 }
1258
dissect_datetime_ie(tvbuff_t * tvb,guint32 offset,proto_tree * ies_tree)1259 static proto_item *dissect_datetime_ie(tvbuff_t *tvb, guint32 offset, proto_tree *ies_tree)
1260 {
1261 struct tm tm;
1262 guint32 ie_val;
1263 nstime_t datetime;
1264
1265 proto_tree_add_item(ies_tree, hf_iax2_ies[IAX_IE_DATETIME], tvb, offset + 2, 4, ENC_BIG_ENDIAN);
1266 ie_val = tvb_get_ntohl(tvb, offset+2);
1267
1268 /* who's crazy idea for a time encoding was this? */
1269 tm.tm_sec = (ie_val & 0x1f) << 1;
1270 tm.tm_min = (ie_val>>5) & 0x3f;
1271 tm.tm_hour = (ie_val>>11) & 0x1f;
1272 tm.tm_mday = (ie_val>>16) & 0x1f;
1273 tm.tm_mon = ((ie_val>>21) & 0x0f) - 1;
1274 tm.tm_year = ((ie_val>>25) & 0x7f) + 100;
1275 tm.tm_isdst= -1; /* there's no info on whether DST was in force; assume it's
1276 * the same as currently */
1277
1278 datetime.secs = mktime(&tm);
1279 datetime.nsecs = 0;
1280 return proto_tree_add_time(ies_tree, hf_iax2_ie_datetime, tvb, offset+2, 4, &datetime);
1281 }
1282
1283
1284 /* dissect the information elements in an IAX frame. Returns the updated offset */
dissect_ies(tvbuff_t * tvb,packet_info * pinfo,guint32 offset,proto_tree * iax_tree,proto_item * iax_item,iax2_ie_data * ie_data)1285 static guint32 dissect_ies(tvbuff_t *tvb, packet_info *pinfo, guint32 offset,
1286 proto_tree *iax_tree, proto_item * iax_item,
1287 iax2_ie_data *ie_data)
1288 {
1289 DISSECTOR_ASSERT(ie_data);
1290
1291 while (offset < tvb_reported_length(tvb)) {
1292
1293 int ies_type = tvb_get_guint8(tvb, offset);
1294 int ies_len = tvb_get_guint8(tvb, offset + 1);
1295 guint16 apparent_addr_family;
1296
1297 /* do non-tree-dependent stuff first */
1298 switch (ies_type) {
1299 case IAX_IE_DATAFORMAT:
1300 if (ies_len != 4) {
1301 proto_tree_add_expert(iax_tree, pinfo, &ei_iax_invalid_len, tvb, offset+1, 1);
1302 break;
1303 }
1304 ie_data -> dataformat = tvb_get_ntohl(tvb, offset+2);
1305 break;
1306
1307 case IAX_IE_CALLED_NUMBER:
1308 iax2_info->calledParty = tvb_format_text(pinfo->pool, tvb, offset+2, ies_len);
1309 break;
1310 case IAX_IE_CALLING_NUMBER:
1311 iax2_info->callingParty = tvb_format_text(pinfo->pool, tvb, offset+2, ies_len);
1312 break;
1313
1314 case IAX_IE_APPARENT_ADDR:
1315 /* The IAX2 I-D says that the "apparent address" structure
1316 "is the same as the linux struct sockaddr_in", without
1317 bothering to note that the address family field is in
1318 *host* byte order in that structure (the I-D seems to be
1319 assuming that "everything is a Vax^Wx86 or x86-64" with
1320 the address family field being little-endian).
1321
1322 This means the address family values are the Linux
1323 address family values. */
1324 apparent_addr_family = tvb_get_letohs(tvb, offset+2);
1325 switch (apparent_addr_family) {
1326 case LINUX_AF_INET:
1327 /* IAX is always over UDP */
1328 ie_data->peer_ptype = PT_UDP;
1329 ie_data->peer_port = tvb_get_ntohs(tvb, offset+4);
1330
1331 /* the ip address is big-endian, but then so is peer_address.data */
1332 set_address_tvb(&ie_data->peer_address, AT_IPv4, 4, tvb, offset+6);
1333 break;
1334
1335 default:
1336 expert_add_info_format(pinfo, iax_item, &ei_iax_peer_address_unsupported,
1337 "Not supported in IAX dissector: peer address family of %u", apparent_addr_family);
1338 break;
1339 }
1340 break;
1341 }
1342
1343
1344 /* the rest of this stuff only needs doing if we have an iax_tree */
1345
1346 if (iax_tree && ies_type < NUM_HF_IAX2_IES) {
1347 proto_item *ti, *ie_item = NULL;
1348 proto_tree *ies_tree;
1349 int ie_hf = hf_iax2_ies[ies_type];
1350
1351 ies_tree = proto_tree_add_subtree(iax_tree, tvb, offset, ies_len+2, ett_iax2_ie, &ti, " ");
1352
1353 proto_tree_add_uint(ies_tree, hf_iax2_ie_id, tvb, offset, 1, ies_type);
1354 proto_tree_add_uint(ies_tree, hf_iax2_length, tvb, offset + 1, 1, ies_len);
1355
1356
1357 /* hf_iax2_ies[] is an array, indexed by IE number, of header-fields, one
1358 per IE. Apart from a couple of special cases which require more
1359 complex decoding, we can just look up an entry from the array, and add
1360 the relevant item, although the encoding value used depends on the
1361 type of the item.
1362 */
1363
1364 switch (ies_type) {
1365 case IAX_IE_DATETIME:
1366 ie_item = dissect_datetime_ie(tvb, offset, ies_tree);
1367 break;
1368
1369
1370 case IAX_IE_CAPABILITY:
1371 {
1372 if (ies_len != 4) {
1373 proto_tree_add_expert(ies_tree, pinfo, &ei_iax_invalid_len, tvb, offset+1, 1);
1374 break;
1375 }
1376
1377 ie_item =
1378 proto_tree_add_bitmask(ies_tree, tvb, offset + 2, ie_hf,
1379 ett_iax2_codecs, hf_iax2_caps, ENC_BIG_ENDIAN);
1380 break;
1381 }
1382
1383
1384 case IAX_IE_CAPABILITY2:
1385 {
1386 int version = tvb_get_guint8(tvb, offset + 2);
1387
1388 proto_tree_add_uint(ies_tree, hf_iax2_version, tvb, offset + 2, 1, version);
1389
1390 if (version == 0) {
1391 if (ies_len != 9) {
1392 proto_tree_add_expert(ies_tree, pinfo, &ei_iax_invalid_len, tvb, offset+1, 1);
1393 break;
1394 }
1395
1396 ie_item =
1397 proto_tree_add_bitmask(ies_tree, tvb, offset + 3, ie_hf,
1398 ett_iax2_codecs, hf_iax2_caps, ENC_BIG_ENDIAN);
1399 }
1400 break;
1401 }
1402
1403
1404 case IAX_IE_FORMAT:
1405 {
1406 if (ies_len != 4) {
1407 proto_tree_add_expert(ies_tree, pinfo, &ei_iax_invalid_len, tvb, offset+1, 1);
1408 break;
1409 }
1410
1411 ie_item =
1412 proto_tree_add_item(ies_tree, ie_hf,
1413 tvb, offset + 2, 4, ENC_BIG_ENDIAN);
1414 break;
1415 }
1416
1417
1418 case IAX_IE_FORMAT2:
1419 {
1420 int version = tvb_get_guint8(tvb, offset + 2);
1421
1422 proto_tree_add_uint(ies_tree, hf_iax2_version, tvb, offset + 2, 1, version);
1423
1424 if (version == 0) {
1425 if (ies_len != 9) {
1426 proto_tree_add_expert(ies_tree, pinfo, &ei_iax_invalid_len, tvb, offset+1, 1);
1427 break;
1428 }
1429
1430 ie_item =
1431 proto_tree_add_item(ies_tree, ie_hf,
1432 tvb, offset + 3, 8, ENC_BIG_ENDIAN);
1433 }
1434 break;
1435 }
1436
1437
1438 case IAX_IE_APPARENT_ADDR:
1439 {
1440 proto_tree *sockaddr_tree;
1441
1442 sockaddr_tree = proto_tree_add_subtree(ies_tree, tvb, offset + 2, 16,
1443 ett_iax2_ies_apparent_addr, &ie_item, "Apparent Address");
1444
1445 /* The IAX2 I-D says that the "apparent address" structure
1446 "is the same as the linux struct sockaddr_in", without
1447 bothering to note that the address family field is in
1448 *host* byte order in that structure (the I-D seems to be
1449 assuming that "everything is a Vax^Wx86 or x86-64" with
1450 the address family field being little-endian).
1451
1452 This means the address family values are the Linux
1453 address family values. */
1454 apparent_addr_family = tvb_get_letohs(tvb, offset+2);
1455 proto_tree_add_uint(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINFAMILY, tvb, offset + 2, 2, apparent_addr_family);
1456
1457 if (apparent_addr_family == LINUX_AF_INET) {
1458 guint32 addr;
1459 proto_tree_add_uint(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINPORT, tvb, offset + 4, 2, ie_data->peer_port);
1460 memcpy(&addr, ie_data->peer_address.data, 4);
1461 proto_tree_add_ipv4(sockaddr_tree, hf_IAX_IE_APPARENTADDR_SINADDR, tvb, offset + 6, 4, addr);
1462 }
1463 break;
1464 }
1465
1466 default:
1467 if (ie_hf != -1) {
1468 gint explen = proto_registrar_get_length(ie_hf);
1469 if (explen != 0 && ies_len != explen) {
1470 proto_tree_add_expert(ies_tree, pinfo, &ei_iax_invalid_len, tvb, offset+1, 1);
1471 break;
1472 }
1473
1474 switch (proto_registrar_get_ftype(ie_hf)) {
1475 case FT_UINT8:
1476 case FT_UINT16:
1477 case FT_UINT24:
1478 case FT_UINT32:
1479 case FT_UINT64:
1480 case FT_INT8:
1481 case FT_INT16:
1482 case FT_INT24:
1483 case FT_INT32:
1484 case FT_INT64:
1485 case FT_BOOLEAN:
1486 case FT_IPv4:
1487 ie_item = proto_tree_add_item(ies_tree, ie_hf, tvb, offset + 2, ies_len, ENC_BIG_ENDIAN);
1488 break;
1489
1490 case FT_BYTES:
1491 case FT_NONE:
1492 ie_item = proto_tree_add_item(ies_tree, ie_hf, tvb, offset + 2, ies_len, ENC_NA);
1493 break;
1494
1495 case FT_STRING:
1496 case FT_STRINGZ:
1497 ie_item = proto_tree_add_item(ies_tree, ie_hf, tvb, offset + 2, ies_len, ENC_UTF_8|ENC_NA);
1498 break;
1499
1500 default:
1501 DISSECTOR_ASSERT_NOT_REACHED();
1502 break;
1503 }
1504 } else {
1505 /* we don't understand this ie: add a generic one */
1506 guint32 value;
1507 const guint8 *ptr;
1508 const gchar *ie_name = val_to_str_ext_const(ies_type, &iax_ies_type_ext, "Unknown");
1509
1510 switch (ies_len) {
1511 case 1:
1512 value = tvb_get_guint8(tvb, offset + 2);
1513 ie_item =
1514 proto_tree_add_uint_format(ies_tree, hf_IAX_IE_UNKNOWN_BYTE,
1515 tvb, offset+2, 1, value,
1516 "%s: %#02x", ie_name, value);
1517 break;
1518
1519 case 2:
1520 value = tvb_get_ntohs(tvb, offset + 2);
1521 ie_item =
1522 proto_tree_add_uint_format(ies_tree, hf_IAX_IE_UNKNOWN_I16,
1523 tvb, offset+2, 2, value,
1524 "%s: %#04x", ie_name, value);
1525 break;
1526
1527 case 4:
1528 value = tvb_get_ntohl(tvb, offset + 2);
1529 ie_item =
1530 proto_tree_add_uint_format(ies_tree, hf_IAX_IE_UNKNOWN_I32,
1531 tvb, offset+2, 4, value,
1532 "%s: %#08x", ie_name, value);
1533 break;
1534
1535 default:
1536 ptr = tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 2, ies_len, ENC_ASCII);
1537 ie_item =
1538 proto_tree_add_string_format(ies_tree, hf_IAX_IE_UNKNOWN_BYTES,
1539 tvb, offset+2, ies_len, ptr,
1540 "%s: %s", ie_name, ptr);
1541 break;
1542 }
1543 }
1544 break;
1545 }
1546
1547 /* Retrieve the text from the item we added, and append it to the main IE
1548 * item */
1549 if (ie_item && !proto_item_is_hidden(ti)) {
1550 field_info *ie_finfo = PITEM_FINFO(ie_item);
1551
1552 /* if the representation of the item has already been set, use that;
1553 else we have to allocate a block to put the text into */
1554 if (ie_finfo && ie_finfo->rep != NULL)
1555 proto_item_set_text(ti, "Information Element: %s",
1556 ie_finfo->rep->representation);
1557 else {
1558 guint8 *ie_val = (guint8 *)wmem_alloc(wmem_packet_scope(), ITEM_LABEL_LENGTH);
1559 proto_item_fill_label(ie_finfo, ie_val);
1560 proto_item_set_text(ti, "Information Element: %s",
1561 ie_val);
1562 }
1563 }
1564 }
1565
1566 offset += ies_len + 2;
1567 }
1568 return offset;
1569 }
1570
uncompress_subclass(guint8 csub)1571 static guint32 uncompress_subclass(guint8 csub)
1572 {
1573 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
1574 if (csub & 0x80) {
1575 /* special case for 'compressed' -1 */
1576 if (csub == 0xff)
1577 return (guint32)-1;
1578 else
1579 return csub & 0x3F;
1580 }
1581 else {
1582 switch (csub) {
1583 case 0x01: return 0;
1584 case 0x02: return 1;
1585 case 0x04: return 2;
1586 case 0x08: return 3;
1587 case 0x10: return 4;
1588 case 0x20: return 5;
1589 case 0x40: return 6;
1590 default: return (guint32)-1;
1591 }
1592 }
1593 }
1594
1595 /* returns the new offset */
dissect_iax2_command(tvbuff_t * tvb,guint32 offset,packet_info * pinfo,proto_tree * tree,iax_packet_data * iax_packet)1596 static guint32 dissect_iax2_command(tvbuff_t *tvb, guint32 offset,
1597 packet_info *pinfo, proto_tree *tree,
1598 iax_packet_data *iax_packet)
1599 {
1600 guint8 csub = tvb_get_guint8(tvb, offset);
1601 proto_item* ti;
1602 iax2_ie_data ie_data;
1603 iax_call_data *iax_call;
1604
1605 ie_data.peer_address.type = AT_NONE;
1606 ie_data.peer_address.len = 0;
1607 ie_data.peer_address.data = NULL;
1608 ie_data.peer_ptype = PT_NONE;
1609 ie_data.peer_port = 0;
1610 ie_data.peer_callno = 0;
1611 ie_data.dataformat = (guint32)-1;
1612 iax_call = iax_packet -> call_data;
1613
1614 /* add the subclass */
1615 ti = proto_tree_add_uint(tree, hf_iax2_iax_csub, tvb, offset, 1, csub);
1616 offset++;
1617
1618 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1619 val_to_str_ext(csub, &iax_iax_subclasses_ext, "unknown (0x%02x)"));
1620
1621 if (offset >= tvb_reported_length(tvb))
1622 return offset;
1623
1624 offset = dissect_ies(tvb, pinfo, offset, tree, ti, &ie_data);
1625
1626 /* if this is a data call, set up a subdissector for the circuit */
1627 if (iax_call && ie_data.dataformat != (guint32)-1 && iax_call -> subdissector == NULL) {
1628 iax_call -> subdissector = dissector_get_uint_handle(iax2_dataformat_dissector_table, ie_data.dataformat);
1629 iax_call -> dataformat = (iax_dataformat_t)ie_data.dataformat;
1630 }
1631
1632 /* if this is a transfer request, record it in the call data */
1633 if (csub == IAX_COMMAND_TXREQ && iax_packet -> first_time) {
1634 if (ie_data.peer_address.type != AT_NONE && ie_data.peer_callno != 0) {
1635 guint tx_circuit = iax_circuit_lookup(&ie_data.peer_address,
1636 ie_data.peer_ptype,
1637 ie_data.peer_port,
1638 ie_data.peer_callno);
1639
1640 iax2_new_circuit_for_call(pinfo, NULL, tx_circuit, pinfo->num, iax_call, iax_packet->reversed);
1641 }
1642 }
1643
1644 return offset;
1645 }
1646
iax2_add_ts_fields(packet_info * pinfo,proto_tree * iax2_tree,tvbuff_t * tvb,iax_packet_data * iax_packet,packet_type type,guint32 relts)1647 static void iax2_add_ts_fields(packet_info *pinfo, proto_tree *iax2_tree, tvbuff_t *tvb, iax_packet_data *iax_packet, packet_type type, guint32 relts)
1648 {
1649 guint32 full_relts = relts;
1650 nstime_t lateness;
1651 proto_item *item;
1652
1653 if (iax_packet->call_data == NULL) {
1654 /* no call info for this frame; perhaps we missed the NEW packet */
1655 return;
1656 }
1657
1658 if (iax_packet->abstime.secs == -1) {
1659 nstime_t rel;
1660
1661 switch (type) {
1662 case IAX2_MINI_VOICE_PACKET:
1663 /* RFC 5456 says
1664 *
1665 * Abbreviated 'Mini Frames' are normally used for audio and
1666 * video; however, each time the time-stamp is a multiple of
1667 * 32,768 (0x8000 hex), a standard or 'Full Frame' MUST be sent.
1668 *
1669 * and, for what it later calls "Mini Frames", by which it means
1670 * what we're calling "mini voice packets", it says:
1671 *
1672 * Mini frames carry a 16-bit time-stamp, which is the lower 16 bits
1673 * of the transmitting peer's full 32-bit time-stamp for the call.
1674 * The time-stamp allows synchronization of incoming frames so that
1675 * they MAY be processed in chronological order instead of the
1676 * (possibly different) order in which they are received. The 16-bit
1677 * time-stamp wraps after 65.536 seconds, at which point a full frame
1678 * SHOULD be sent to notify the remote peer that its time-stamp has
1679 * been reset. A call MUST continue to send mini frames starting
1680 * with time-stamp 0 even if acknowledgment of the resynchronization
1681 * is not received.
1682 *
1683 * *If* we see all the full frames, that means we *should* be able
1684 * to convert the 16-bit time stamp to a full 32-bit time stamp by
1685 * ORing the upper 16 bits of the last full frame time stamp we saw
1686 * in above the 16-bit time stamp.
1687 *
1688 * XXX - what, if anything, should we do about full frames we've
1689 * missed? */
1690 full_relts = (iax_packet->call_data->last_full_frame_ts & 0xFFFF0000) | relts;
1691 break;
1692
1693 case IAX2_FULL_PACKET:
1694 case IAX2_TRUNK_PACKET:
1695 /* Timestamps have the full 32 bits of the timestamp.
1696 * Save it, to add to the mini-packet time stamps.
1697 *
1698 * XXX - that's a maximum of 4294967296 milliseconds
1699 * or about 4294967 seconds or about 49 days.
1700 * Do we need to worry about that overflowing? */
1701 full_relts = relts;
1702 iax_packet->call_data->last_full_frame_ts = full_relts;
1703 break;
1704
1705 case IAX2_MINI_VIDEO_PACKET:
1706 /* See the comment above in the IAX2_MINI_VOICE_PACKET case.
1707 * Note also that RFC 5456 says, in section 8.1.3.1 "Meta Video
1708 * Frames", which covers what we're calling "mini video packets":
1709 *
1710 * Meta video frames carry a 16-bit time-stamp, which is the lower 16
1711 * bits of the transmitting peer's full 32-bit time-stamp for the
1712 * call. When this time-stamp wraps, a Full Frame SHOULD be sent to
1713 * notify the remote peer that the time-stamp has been reset to 0.
1714 *
1715 * *but* it also shows the uppermost bit of that time stamp as "?",
1716 * with a 15-bit time stamp, in the ASCII-art packet diagram after
1717 * it. dissect_minivideopacket() says "bit 15 of the ts is used to
1718 * represent the rtp 'marker' bit"; presumably that's what's going
1719 * on, but the RFC doesn't say that.
1720 *
1721 * So we assume that the time stamp is only 15 bits, and that the
1722 * upper *17* bits of the last full frame's time stamp need to be
1723 * ORed in above the 15 bits of time stamp.
1724 *
1725 * XXX - do we need to worry about overflows or missed packets
1726 * with full timestamps? */
1727 full_relts = (iax_packet->call_data->last_full_frame_ts & 0xFFFF8000) | relts;
1728 break;
1729 }
1730
1731 /* Convert the full relative time stamp to an nstime_t */
1732 rel.secs = full_relts / 1000;
1733 rel.nsecs = (full_relts % 1000) * 1000000;
1734
1735 /* Add it to the start time to get the absolute time. */
1736 nstime_sum(&iax_packet->abstime, &iax_packet->call_data->start_time, &rel);
1737 }
1738 iax2_info->timestamp = relts; /* raw time stamp; nobody uses it */
1739
1740 if (iax2_tree) {
1741 item = proto_tree_add_time(iax2_tree, hf_iax2_absts, tvb, 0, 0, &iax_packet->abstime);
1742 proto_item_set_generated(item);
1743
1744 nstime_delta(&lateness, &pinfo->abs_ts, &iax_packet->abstime);
1745
1746 item = proto_tree_add_time(iax2_tree, hf_iax2_lateness, tvb, 0, 0, &lateness);
1747 proto_item_set_generated(item);
1748 }
1749 }
1750
1751 /* returns the new offset */
1752 static guint32
dissect_fullpacket(tvbuff_t * tvb,guint32 offset,guint16 scallno,packet_info * pinfo,proto_tree * iax2_tree,proto_tree * main_tree)1753 dissect_fullpacket(tvbuff_t *tvb, guint32 offset,
1754 guint16 scallno,
1755 packet_info *pinfo, proto_tree *iax2_tree,
1756 proto_tree *main_tree)
1757 {
1758 guint16 dcallno;
1759 guint32 ts;
1760 guint8 type;
1761 guint8 csub;
1762 guint32 codec;
1763
1764 proto_tree *packet_type_tree = NULL;
1765 iax_call_data *iax_call;
1766 iax_packet_data *iax_packet;
1767 gboolean reversed;
1768 gboolean rtp_marker;
1769
1770 /*
1771 * remove the top bit for retransmission detection
1772 */
1773 dcallno = tvb_get_ntohs(tvb, offset) & 0x7FFF;
1774 ts = tvb_get_ntohl(tvb, offset + 2);
1775 type = tvb_get_guint8(tvb, offset + 8);
1776 csub = tvb_get_guint8(tvb, offset + 9);
1777 iax2_info->ftype = type;
1778 iax2_info->csub = csub;
1779 iax2_info->scallno = scallno;
1780 iax2_info->dcallno = dcallno;
1781
1782 /* see if we've seen this packet before */
1783 iax_packet = (iax_packet_data *)p_get_proto_data(wmem_file_scope(), pinfo, proto_iax2, 0);
1784 if (!iax_packet) {
1785 /* if not, find or create an iax_call info structure for this IAX session. */
1786
1787 if (type == AST_FRAME_IAX && csub == IAX_COMMAND_NEW) {
1788 /* NEW packets start a new call */
1789 iax_call = iax_new_call(pinfo, scallno);
1790 reversed = FALSE;
1791 } else {
1792 iax_call = iax_lookup_call(pinfo, scallno, dcallno,
1793 &reversed);
1794 }
1795
1796 iax_packet = iax_new_packet_data(iax_call, reversed);
1797 p_add_proto_data(wmem_file_scope(), pinfo, proto_iax2, 0, iax_packet);
1798 } else {
1799 iax_call = iax_packet->call_data;
1800 reversed = iax_packet->reversed;
1801 }
1802
1803 iax2_populate_pinfo_from_packet_data(pinfo, iax_packet);
1804
1805 if (iax2_tree) {
1806 proto_item *packet_type_base;
1807
1808 proto_tree_add_item(iax2_tree, hf_iax2_dcallno, tvb, offset, 2, ENC_BIG_ENDIAN);
1809
1810 proto_tree_add_item(iax2_tree, hf_iax2_retransmission, tvb, offset, 2, ENC_BIG_ENDIAN);
1811
1812 if (iax_call) {
1813 proto_item *item =
1814 proto_tree_add_uint(iax2_tree, hf_iax2_callno, tvb, 0, 4,
1815 iax_call->forward_circuit_ids[0]);
1816 proto_item_set_generated(item);
1817 }
1818
1819 proto_tree_add_uint(iax2_tree, hf_iax2_ts, tvb, offset+2, 4, ts);
1820 iax2_add_ts_fields(pinfo, iax2_tree, tvb, iax_packet, IAX2_FULL_PACKET, ts);
1821
1822 proto_tree_add_item(iax2_tree, hf_iax2_oseqno, tvb, offset+6, 1,
1823 ENC_BIG_ENDIAN);
1824
1825 proto_tree_add_item(iax2_tree, hf_iax2_iseqno, tvb, offset+7, 1,
1826 ENC_BIG_ENDIAN);
1827 packet_type_base = proto_tree_add_uint(iax2_tree, hf_iax2_type, tvb,
1828 offset+8, 1, type);
1829
1830 /* add the type-specific subtree */
1831 packet_type_tree = proto_item_add_subtree(packet_type_base, ett_iax2_type);
1832 } else {
1833 iax2_add_ts_fields(pinfo, iax2_tree, tvb, iax_packet, IAX2_FULL_PACKET, ts);
1834 }
1835
1836
1837 /* add frame type to info line */
1838 col_add_fstr(pinfo->cinfo, COL_INFO, "%s, source call# %d, timestamp %ums",
1839 val_to_str_ext(type, &iax_frame_types_ext, "Unknown (0x%02x)"),
1840 scallno, ts);
1841
1842 iax2_info->messageName = val_to_str_ext(type, &iax_frame_types_ext, "Unknown (0x%02x)");
1843
1844 switch (type) {
1845 case AST_FRAME_IAX:
1846 offset=dissect_iax2_command(tvb, offset+9, pinfo, packet_type_tree, iax_packet);
1847 iax2_info->messageName = val_to_str_ext(csub, &iax_iax_subclasses_ext, "unknown (0x%02x)");
1848 if (csub < NUM_TAP_IAX_VOIP_STATES) iax2_info->callState = tap_iax_voip_state[csub];
1849 break;
1850
1851 case AST_FRAME_DTMF_BEGIN:
1852 case AST_FRAME_DTMF_END:
1853 proto_tree_add_item(packet_type_tree, hf_iax2_dtmf_csub, tvb, offset+9, 1, ENC_ASCII|ENC_NA);
1854 offset += 10;
1855
1856 col_append_fstr(pinfo->cinfo, COL_INFO, " digit %c", csub);
1857 break;
1858
1859 case AST_FRAME_CONTROL:
1860 /* add the subclass */
1861 proto_tree_add_uint(packet_type_tree, hf_iax2_cmd_csub, tvb,
1862 offset+9, 1, csub);
1863 offset += 10;
1864
1865 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1866 val_to_str_ext(csub, &iax_cmd_subclasses_ext, "unknown (0x%02x)"));
1867 iax2_info->messageName = val_to_str_ext (csub, &iax_cmd_subclasses_ext, "unknown (0x%02x)");
1868 if (csub < NUM_TAP_CMD_VOIP_STATES) iax2_info->callState = tap_cmd_voip_state[csub];
1869 break;
1870
1871 case AST_FRAME_VOICE:
1872 /* add the codec */
1873 iax_packet -> codec = codec = uncompress_subclass(csub);
1874
1875 if (packet_type_tree) {
1876 proto_item *item;
1877 proto_tree_add_item(packet_type_tree, hf_iax2_voice_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1878 item = proto_tree_add_uint64(packet_type_tree, hf_iax2_voice_codec, tvb, offset+9, 1, CODEC_MASK(codec));
1879 proto_item_set_generated(item);
1880 }
1881
1882 offset += 10;
1883
1884 if (iax_call) {
1885 if (reversed) {
1886 iax_call->dst_codec = codec;
1887 } else {
1888 iax_call->src_codec = codec;
1889 }
1890 }
1891
1892 dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, FALSE, iax_packet);
1893 break;
1894
1895 case AST_FRAME_VIDEO:
1896 /* bit 6 of the csub is used to represent the rtp 'marker' bit */
1897 rtp_marker = csub & 0x40 ? TRUE:FALSE;
1898 iax_packet -> codec = codec = uncompress_subclass((guint8)(csub & ~0x40));
1899
1900 if (packet_type_tree) {
1901 proto_item *item;
1902 proto_tree_add_item(packet_type_tree, hf_iax2_video_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1903 proto_tree_add_item(packet_type_tree, hf_iax2_marker, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1904 item = proto_tree_add_uint64(packet_type_tree, hf_iax2_video_codec, tvb, offset+9, 1, CODEC_MASK(codec));
1905 proto_item_set_generated(item);
1906 }
1907
1908 offset += 10;
1909
1910 if (iax_call && iax_packet -> first_time) {
1911 if (reversed) {
1912 iax_call->dst_vformat = codec;
1913 } else {
1914 iax_call->src_vformat = codec;
1915 }
1916 }
1917
1918 if (rtp_marker)
1919 col_append_str(pinfo->cinfo, COL_INFO, ", Mark");
1920
1921
1922 dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, TRUE, iax_packet);
1923 break;
1924
1925 case AST_FRAME_MODEM:
1926 proto_tree_add_item(packet_type_tree, hf_iax2_modem_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1927 offset += 10;
1928
1929 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1930 val_to_str(csub, iax_modem_subclasses, "unknown (0x%02x)"));
1931 break;
1932
1933 case AST_FRAME_TEXT:
1934 proto_tree_add_item(packet_type_tree, hf_iax2_text_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1935 offset += 10;
1936
1937 {
1938 int textlen = tvb_captured_length_remaining(tvb, offset);
1939 if (textlen > 0)
1940 {
1941 proto_tree_add_item(packet_type_tree, hf_iax2_text_text, tvb, offset, textlen, ENC_UTF_8|ENC_NA);
1942 offset += textlen;
1943 }
1944 }
1945 break;
1946
1947 case AST_FRAME_HTML:
1948 proto_tree_add_item(packet_type_tree, hf_iax2_html_csub, tvb, offset+9, 1, ENC_BIG_ENDIAN);
1949 offset += 10;
1950
1951 if (csub == 0x01)
1952 {
1953 int urllen = tvb_captured_length_remaining(tvb, offset);
1954 if (urllen > 0)
1955 {
1956 proto_item *pi = proto_tree_add_item(packet_type_tree, hf_iax2_html_url, tvb, offset, urllen, ENC_UTF_8|ENC_NA);
1957 proto_item_set_url(pi);
1958 offset += urllen;
1959 }
1960 }
1961 break;
1962
1963 case AST_FRAME_CNG:
1964 default:
1965 proto_tree_add_uint(packet_type_tree, hf_iax2_csub, tvb, offset+9,
1966 1, csub);
1967 offset += 10;
1968
1969 col_append_fstr(pinfo->cinfo, COL_INFO, " subclass %d", csub);
1970 break;
1971 }
1972
1973 /* next time we come to parse this packet, don't propagate the codec into the
1974 * call_data */
1975 iax_packet->first_time = FALSE;
1976
1977 return offset;
1978 }
1979
iax2_get_packet_data_for_minipacket(packet_info * pinfo,guint16 scallno,gboolean video)1980 static iax_packet_data *iax2_get_packet_data_for_minipacket(packet_info *pinfo,
1981 guint16 scallno,
1982 gboolean video)
1983 {
1984 /* see if we've seen this packet before */
1985 iax_packet_data *p = (iax_packet_data *)p_get_proto_data(wmem_file_scope(), pinfo, proto_iax2, 0);
1986
1987 if (!p) {
1988 /* if not, find or create an iax_call info structure for this IAX session. */
1989 gboolean reversed;
1990 iax_call_data *iax_call;
1991
1992 iax_call = iax_lookup_call(pinfo, scallno, 0, &reversed);
1993
1994 p = iax_new_packet_data(iax_call, reversed);
1995 p_add_proto_data(wmem_file_scope(), pinfo, proto_iax2, 0, p);
1996
1997 /* set the codec for this frame to be whatever the last full frame used */
1998 if (iax_call) {
1999 if (video)
2000 p->codec = reversed ? iax_call -> dst_vformat : iax_call -> src_vformat;
2001 else
2002 p->codec = reversed ? iax_call -> dst_codec : iax_call -> src_codec;
2003 }
2004 }
2005
2006 iax2_populate_pinfo_from_packet_data(pinfo, p);
2007 return p;
2008 }
2009
2010
dissect_minivideopacket(tvbuff_t * tvb,guint32 offset,guint16 scallno,packet_info * pinfo,proto_tree * iax2_tree,proto_tree * main_tree)2011 static guint32 dissect_minivideopacket(tvbuff_t *tvb, guint32 offset,
2012 guint16 scallno, packet_info *pinfo,
2013 proto_tree *iax2_tree, proto_tree *main_tree)
2014 {
2015 guint32 ts;
2016 iax_packet_data *iax_packet;
2017 gboolean rtp_marker;
2018 proto_item *item;
2019
2020 ts = tvb_get_ntohs(tvb, offset);
2021
2022 /* bit 15 of the ts is used to represent the rtp 'marker' bit */
2023 rtp_marker = ts & 0x8000 ? TRUE:FALSE;
2024 ts &= ~0x8000;
2025
2026 iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, TRUE);
2027
2028 if (iax2_tree) {
2029 if (iax_packet->call_data) {
2030 item =
2031 proto_tree_add_uint(iax2_tree, hf_iax2_callno, tvb, 0, 4,
2032 iax_packet->call_data->forward_circuit_ids[0]);
2033 proto_item_set_generated(item);
2034 }
2035
2036 proto_tree_add_item(iax2_tree, hf_iax2_minividts, tvb, offset, 2, ENC_BIG_ENDIAN);
2037 iax2_add_ts_fields(pinfo, iax2_tree, tvb, iax_packet, IAX2_MINI_VIDEO_PACKET, ts);
2038 proto_tree_add_item(iax2_tree, hf_iax2_minividmarker, tvb, offset, 2, ENC_BIG_ENDIAN);
2039 } else {
2040 iax2_add_ts_fields(pinfo, iax2_tree, tvb, iax_packet, IAX2_MINI_VIDEO_PACKET, ts);
2041 }
2042
2043 offset += 2;
2044
2045 col_add_fstr(pinfo->cinfo, COL_INFO,
2046 "Mini video packet, source call# %d, timestamp %ums%s",
2047 scallno, ts, rtp_marker?", Mark":"");
2048
2049
2050 dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, TRUE, iax_packet);
2051
2052 /* next time we come to parse this packet, don't propagate the codec into the
2053 * call_data */
2054 iax_packet->first_time = FALSE;
2055
2056 return offset;
2057 }
2058
dissect_minipacket(tvbuff_t * tvb,guint32 offset,guint16 scallno,packet_info * pinfo,proto_tree * iax2_tree,proto_tree * main_tree)2059 static guint32 dissect_minipacket(tvbuff_t *tvb, guint32 offset, guint16 scallno,
2060 packet_info *pinfo, proto_tree *iax2_tree,
2061 proto_tree *main_tree)
2062 {
2063 guint32 ts;
2064 iax_packet_data *iax_packet;
2065 proto_item *item;
2066
2067 ts = tvb_get_ntohs(tvb, offset);
2068
2069 iax_packet = iax2_get_packet_data_for_minipacket(pinfo, scallno, FALSE);
2070
2071 if (iax2_tree) {
2072 if (iax_packet->call_data) {
2073 item = proto_tree_add_uint(iax2_tree, hf_iax2_callno, tvb, 0, 4,
2074 iax_packet->call_data->forward_circuit_ids[0]);
2075 proto_item_set_generated(item);
2076 }
2077
2078 proto_tree_add_uint(iax2_tree, hf_iax2_minits, tvb, offset, 2, ts);
2079 iax2_add_ts_fields(pinfo, iax2_tree, tvb, iax_packet, IAX2_MINI_VOICE_PACKET, ts);
2080 } else {
2081 iax2_add_ts_fields(pinfo, iax2_tree, tvb, iax_packet, IAX2_MINI_VOICE_PACKET, ts);
2082 }
2083
2084
2085 offset += 2;
2086
2087 col_add_fstr(pinfo->cinfo, COL_INFO,
2088 "Mini packet, source call# %d, timestamp %ums",
2089 scallno, ts);
2090
2091
2092 /* XXX fix the timestamp logic */
2093 dissect_payload(tvb, offset, pinfo, iax2_tree, main_tree, ts, FALSE, iax_packet);
2094
2095
2096 /* next time we come to parse this packet, don't propagate the codec into the
2097 * call_data */
2098 iax_packet->first_time = FALSE;
2099
2100 return offset;
2101 }
2102
2103
dissect_trunkcall_ts(tvbuff_t * tvb,guint32 offset,proto_tree * iax2_tree,guint16 * scallno)2104 static guint32 dissect_trunkcall_ts(tvbuff_t *tvb, guint32 offset, proto_tree *iax2_tree, guint16 *scallno)
2105 {
2106 proto_tree *call_tree;
2107 guint16 datalen, rlen, ts;
2108 /*
2109 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2110 | Data Length (in octets) |R| Source Call Number |
2111 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2112 | time-stamp | |
2113 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
2114 | Data |
2115 : :
2116 | |
2117 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2118 */
2119 datalen = tvb_get_ntohs(tvb, offset);
2120 *scallno = tvb_get_ntohs(tvb, offset + 2);
2121 ts = tvb_get_ntohs(tvb, offset + 4);
2122
2123 rlen = MIN(tvb_captured_length(tvb) - offset - 6, datalen);
2124
2125 if (iax2_tree) {
2126 call_tree = proto_tree_add_subtree_format(iax2_tree, tvb, offset, rlen + 6,
2127 ett_iax2_trunk_call, NULL, "Trunk call from %u, ts: %u", *scallno, ts);
2128
2129 proto_tree_add_item(call_tree, hf_iax2_trunk_call_len, tvb, offset, 2, ENC_BIG_ENDIAN);
2130 proto_tree_add_item(call_tree, hf_iax2_trunk_call_scallno, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2131 proto_tree_add_item(call_tree, hf_iax2_trunk_call_ts, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
2132 proto_tree_add_item(call_tree, hf_iax2_trunk_call_data, tvb, offset + 6, rlen, ENC_NA);
2133 }
2134 offset += 6 + rlen;
2135
2136 return offset;
2137 }
2138
dissect_trunkcall_nots(tvbuff_t * tvb,guint32 offset,proto_tree * iax2_tree,guint16 * scallno)2139 static guint32 dissect_trunkcall_nots(tvbuff_t *tvb, guint32 offset, proto_tree *iax2_tree, guint16 *scallno)
2140 {
2141 proto_tree *call_tree;
2142 guint16 datalen, rlen;
2143 /*
2144 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2145 |R| Source Call Number | Data Length (in octets) |
2146 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2147 | |
2148 : Data :
2149 | |
2150 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2151 */
2152 *scallno = tvb_get_ntohs(tvb, offset);
2153 datalen = tvb_get_ntohs(tvb, offset + 2);
2154
2155 rlen = MIN(tvb_captured_length(tvb) - offset - 4, datalen);
2156
2157 if (iax2_tree) {
2158 call_tree = proto_tree_add_subtree_format(iax2_tree, tvb, offset, rlen + 6,
2159 ett_iax2_trunk_call, NULL, "Trunk call from %u", *scallno);
2160
2161 proto_tree_add_item(call_tree, hf_iax2_trunk_call_scallno, tvb, offset, 2, ENC_BIG_ENDIAN);
2162 proto_tree_add_item(call_tree, hf_iax2_trunk_call_len, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2163 proto_tree_add_item(call_tree, hf_iax2_trunk_call_data, tvb, offset + 4, rlen, ENC_NA);
2164 }
2165 offset += 4 + rlen;
2166
2167 return offset;
2168 }
2169
2170 typedef struct _call_list {
2171 guint16 scallno;
2172 struct _call_list *next;
2173 } call_list;
2174
call_list_append(call_list * list,guint16 scallno)2175 static call_list *call_list_append(call_list *list, guint16 scallno)
2176 {
2177 call_list *node = wmem_new0(wmem_packet_scope(), call_list);
2178
2179 node->scallno = scallno;
2180
2181 if (list) {
2182 call_list *cur = list;
2183 while (cur->next) {
2184 cur = cur->next;
2185 }
2186 cur->next = node;
2187 return list;
2188 } else {
2189 return node;
2190 }
2191 }
2192
call_list_find(call_list * list,guint16 scallno)2193 static gboolean call_list_find(call_list *list, guint16 scallno)
2194 {
2195 for (; list; list = list->next) {
2196 if (list->scallno == scallno) {
2197 return TRUE;
2198 }
2199 }
2200 return FALSE;
2201 }
2202
call_list_length(call_list * list)2203 static guint call_list_length(call_list *list)
2204 {
2205 guint count = 0;
2206 for (; list; list = list->next) {
2207 count++;
2208 }
2209 return count;
2210 }
2211
dissect_trunkpacket(tvbuff_t * tvb,guint32 offset,guint16 scallno_param _U_,packet_info * pinfo,proto_tree * iax2_tree,proto_tree * main_tree _U_)2212 static guint32 dissect_trunkpacket(tvbuff_t *tvb, guint32 offset,
2213 guint16 scallno_param _U_, packet_info *pinfo,
2214 proto_tree *iax2_tree, proto_tree *main_tree _U_)
2215 {
2216 guint8 cmddata, trunkts;
2217 guint nframes = 0, ncalls = 0;
2218 proto_item *cd, *nc = NULL;
2219 proto_tree *field_tree = NULL;
2220 call_list *calls = NULL;
2221 /*iax_packet_data *iax_packet;*/
2222
2223 cmddata = tvb_get_guint8(tvb, offset + 1);
2224 trunkts = cmddata & IAX2_TRUNK_TS;
2225
2226 /* 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 */
2227 /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
2228 /* |F| Meta Indicator |V|Meta Command | Cmd Data (0) | */
2229 /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
2230 /* | time-stamp | */
2231 /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
2232
2233 if (iax2_tree) {
2234 /* Meta Command */
2235 proto_tree_add_item(iax2_tree, hf_iax2_trunk_metacmd, tvb, offset, 1, ENC_BIG_ENDIAN);
2236
2237 /* Command data */
2238 cd = proto_tree_add_uint(iax2_tree, hf_iax2_trunk_cmddata, tvb, offset + 1, 1, cmddata);
2239 field_tree = proto_item_add_subtree(cd, ett_iax2_trunk_cmddata);
2240 if (trunkts)
2241 proto_item_append_text(cd, " (trunk timestamps)");
2242
2243 /* CD -> Trunk timestamp */
2244 proto_tree_add_boolean(field_tree, hf_iax2_trunk_cmddata_ts, tvb, offset + 1, 1, cmddata);
2245
2246 /* Timestamp */
2247 proto_tree_add_item(iax2_tree, hf_iax2_trunk_ts, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
2248 }
2249
2250 offset += 6;
2251
2252 if (trunkts) {
2253 /* Trunk calls with timestamp */
2254 while(tvb_captured_length_remaining(tvb, offset) >= 6) {
2255 guint16 scallno;
2256 offset = dissect_trunkcall_ts(tvb, offset, iax2_tree, &scallno);
2257 if (!call_list_find(calls, scallno)) {
2258 calls = call_list_append(calls, scallno);
2259 }
2260 nframes++;
2261 }
2262 }
2263 else {
2264 /* Trunk calls without timestamp */
2265 while(tvb_captured_length_remaining(tvb, offset) >= 4) {
2266 guint16 scallno;
2267 offset = dissect_trunkcall_nots(tvb, offset, iax2_tree, &scallno);
2268 if (!call_list_find(calls, scallno)) {
2269 calls = call_list_append(calls, scallno);
2270 }
2271 nframes++;
2272 }
2273 }
2274
2275 ncalls = call_list_length(calls);
2276
2277 if (iax2_tree) {
2278 /* number of items */
2279 nc = proto_tree_add_uint(iax2_tree, hf_iax2_trunk_ncalls, NULL, 0, 0, ncalls);
2280 proto_item_set_generated(nc);
2281 }
2282
2283 col_add_fstr(pinfo->cinfo, COL_INFO, "Trunk packet with %d media frame%s for %d call%s",
2284 nframes, plurality(nframes, "", "s"),
2285 ncalls, plurality(ncalls, "", "s"));
2286
2287 return offset;
2288 }
2289
2290
process_iax_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,gboolean video,iax_packet_data * iax_packet)2291 static void process_iax_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2292 gboolean video, iax_packet_data *iax_packet)
2293 {
2294 guint32 codec = iax_packet -> codec;
2295 iax_call_data *iax_call = iax_packet -> call_data;
2296
2297 #ifdef DEBUG_DESEGMENT
2298 ws_debug("calling process_iax_pdu; len = %u", tvb_reported_length(tvb));
2299 #endif
2300
2301 if (!video && iax_call && iax_call->subdissector) {
2302 iax2_dissector_info_t dissector_info;
2303
2304 /* info for subdissectors. We always pass on the original forward circuit,
2305 * and steal the p2p_dir flag to indicate the direction */
2306 if (iax_packet->call_data == NULL) {
2307 /* if we missed the NEW packet for this call, call_data will be null. it's
2308 * tbd what the best thing to do here is. */
2309 memset(&dissector_info, 0, sizeof(dissector_info));
2310 } else {
2311 dissector_info.etype = ENDPOINT_IAX2;
2312 dissector_info.circuit_id = (guint32)iax_packet->call_data->forward_circuit_ids[0];
2313 }
2314
2315 call_dissector_with_data(iax_call->subdissector, tvb, pinfo, tree, &dissector_info);
2316 } else if (codec != 0 && dissector_try_uint(iax2_codec_dissector_table, codec, tvb, pinfo, tree)) {
2317 /* codec dissector handled our data */
2318 } else {
2319 /* we don't know how to dissect our data: dissect it as data */
2320 call_data_dissector(tvb, pinfo, tree);
2321 }
2322
2323 #ifdef DEBUG_DESEGMENT
2324 ws_debug("called process_iax_pdu; pinfo->desegment_len=%u; pinfo->desegment_offset=%u",
2325 pinfo->desegment_len, pinfo->desegment_offset);
2326 #endif
2327 }
2328
desegment_iax(tvbuff_t * tvb,packet_info * pinfo,proto_tree * iax2_tree,proto_tree * tree,gboolean video,iax_packet_data * iax_packet)2329 static void desegment_iax(tvbuff_t *tvb, packet_info *pinfo, proto_tree *iax2_tree,
2330 proto_tree *tree, gboolean video, iax_packet_data *iax_packet)
2331 {
2332
2333 iax_call_data *iax_call = iax_packet -> call_data;
2334 iax_call_dirdata *dirdata;
2335 gpointer value = NULL;
2336 guint32 frag_offset = 0;
2337 fragment_head *fd_head;
2338 gboolean must_desegment = FALSE;
2339
2340 DISSECTOR_ASSERT(iax_call);
2341
2342 pinfo->can_desegment = 2;
2343 pinfo->desegment_offset = 0;
2344 pinfo->desegment_len = 0;
2345
2346 #ifdef DEBUG_DESEGMENT
2347 ws_debug("dissecting packet %u", pinfo->num);
2348 #endif
2349
2350 dirdata = &(iax_call->dirdata[!!(iax_packet->reversed)]);
2351
2352 if ((!pinfo->fd->visited && (dirdata->current_frag_bytes > 0)) ||
2353 ((value = g_hash_table_lookup(iax_fid_table, GUINT_TO_POINTER(pinfo->num))) != NULL)) {
2354
2355 /* then we are continuing an already-started pdu */
2356 guint32 fid;
2357 guint32 frag_len = tvb_reported_length(tvb);
2358 gboolean complete;
2359
2360 #ifdef DEBUG_DESEGMENT
2361 ws_debug("visited: %i; c_f_b: %u; hash: %u->%u", pinfo->fd->visited?1:0,
2362 dirdata->current_frag_bytes, pinfo->num, dirdata->current_frag_id);
2363 #endif
2364
2365 if (!pinfo->fd->visited) {
2366 guint32 tot_len;
2367 fid = dirdata->current_frag_id;
2368 tot_len = dirdata->current_frag_minlen;
2369 DISSECTOR_ASSERT(g_hash_table_lookup(iax_fid_table, GUINT_TO_POINTER(pinfo->num)) == NULL);
2370 g_hash_table_insert(iax_fid_table, GUINT_TO_POINTER(pinfo->num), GUINT_TO_POINTER(fid));
2371 frag_offset = dirdata->current_frag_bytes;
2372 dirdata->current_frag_bytes += frag_len;
2373 complete = dirdata->current_frag_bytes > tot_len;
2374 #ifdef DEBUG_DESEGMENT
2375 ws_debug("hash: %u->%u; frag_offset: %u; c_f_b: %u; totlen: %u",
2376 pinfo->num, fid, frag_offset, dirdata->current_frag_bytes, tot_len);
2377 #endif
2378 } else {
2379 fid = GPOINTER_TO_UINT(value);
2380 /* these values are unused by fragment_add if pinfo->fd->visited */
2381 dirdata->current_frag_bytes = 0;
2382 complete = FALSE;
2383 }
2384
2385 /* fragment_add checks for already-added */
2386 fd_head = fragment_add(&iax_reassembly_table, tvb, 0, pinfo, fid, NULL,
2387 frag_offset,
2388 frag_len, !complete);
2389
2390 if (fd_head && (pinfo->num == fd_head->reassembled_in)) {
2391 gint32 old_len;
2392 tvbuff_t *next_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
2393 add_new_data_source(pinfo, next_tvb, "Reassembled IAX2");
2394
2395 process_iax_pdu(next_tvb, pinfo, tree, video, iax_packet);
2396
2397 /* calculate the amount of data which was available to the higher-level
2398 dissector before we added this segment; if the returned offset is
2399 within that section, the higher-level dissector was unable to find any
2400 pdus; if it's after that, it found one or more complete PDUs.
2401 */
2402 old_len = (gint32)(tvb_reported_length(next_tvb) - frag_len);
2403 if (pinfo->desegment_len &&
2404 (pinfo->desegment_offset < old_len)) {
2405 /* oops, it wasn't actually complete */
2406 fragment_set_partial_reassembly(&iax_reassembly_table, pinfo, fid, NULL);
2407 if (pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
2408 /* only one more byte should be enough for a retry */
2409 dirdata->current_frag_minlen = fd_head->datalen + 1;
2410 } else {
2411 dirdata->current_frag_minlen = fd_head->datalen + pinfo->desegment_len;
2412 }
2413 } else {
2414 /* we successfully dissected some data; create the proto tree items for
2415 * the fragments, and flag any remaining data for desegmentation */
2416
2417 proto_item *iax_tree_item, *frag_tree_item;
2418 /* this nargery is to insert the fragment tree into the main tree
2419 * between the IAX protocol entry and the subdissector entry */
2420 show_fragment_tree(fd_head, &iax2_fragment_items, tree, pinfo, next_tvb, &frag_tree_item);
2421 iax_tree_item = proto_item_get_parent(proto_tree_get_parent(iax2_tree));
2422 if (frag_tree_item && iax_tree_item)
2423 proto_tree_move_item(tree, iax_tree_item, frag_tree_item);
2424
2425 dirdata->current_frag_minlen = dirdata->current_frag_id = dirdata->current_frag_bytes = 0;
2426
2427 if (pinfo->desegment_len) {
2428 /* there's a bit of data left to desegment */
2429 must_desegment = TRUE;
2430 /* make desegment_offset relative to our tvb */
2431 pinfo->desegment_offset -= old_len;
2432 }
2433
2434 /* don't add a 'reassembled in' item for this pdu */
2435 fd_head = NULL;
2436 }
2437 }
2438 } else {
2439 /* This segment was not found in our table, so it doesn't
2440 contain a continuation of a higher-level PDU.
2441 Call the normal subdissector.
2442 */
2443
2444 process_iax_pdu(tvb, pinfo, tree, video, iax_packet);
2445
2446 if (pinfo->desegment_len) {
2447 /* the higher-level dissector has asked for some more data - ie,
2448 the end of this segment does not coincide with the end of a
2449 higher-level PDU. */
2450 must_desegment = TRUE;
2451 }
2452
2453 fd_head = NULL;
2454 }
2455
2456 /* must_desegment is set if the end of this segment (or the whole of it)
2457 * contained the start of a higher-level PDU; we must add whatever is left of
2458 * this segment (after pinfo->desegment_offset) to a fragment table for disassembly. */
2459 if (must_desegment) {
2460 guint32 fid = pinfo->num; /* a new fragment id */
2461 guint32 deseg_offset = pinfo->desegment_offset;
2462 guint32 frag_len = tvb_reported_length_remaining(tvb, deseg_offset);
2463 dirdata->current_frag_id = fid;
2464 dirdata->current_frag_bytes = frag_len;
2465
2466 if (pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) {
2467 /* only one more byte should be enough for a retry */
2468 dirdata->current_frag_minlen = frag_len + 1;
2469 } else {
2470 dirdata->current_frag_minlen = frag_len + pinfo->desegment_len;
2471 }
2472
2473 fd_head = fragment_add(&iax_reassembly_table,
2474 tvb, deseg_offset, pinfo, fid, NULL,
2475 0, frag_len, TRUE);
2476 #ifdef DEBUG_DESEGMENT
2477 ws_debug("Start offset of undissected bytes: %u; "
2478 "Bytes remaining in this segment: %u; min required bytes: %u\n",
2479 deseg_offset, frag_len, frag_len + pinfo->desegment_len);
2480 #endif
2481 }
2482
2483 /* add a 'reassembled in' item if necessary */
2484 if (fd_head != NULL) {
2485 guint32 deseg_offset = pinfo->desegment_offset;
2486 if (fd_head->reassembled_in != 0 &&
2487 !(fd_head->flags & FD_PARTIAL_REASSEMBLY)) {
2488 proto_item *iax_tree_item;
2489 iax_tree_item = proto_tree_add_uint(tree, hf_iax2_reassembled_in,
2490 tvb, deseg_offset, tvb_reported_length_remaining(tvb, deseg_offset),
2491 fd_head->reassembled_in);
2492 proto_item_set_generated(iax_tree_item);
2493 } else {
2494 /* this fragment is never reassembled */
2495 proto_tree_add_item(tree, hf_iax2_fragment_unfinished, tvb, deseg_offset, -1, ENC_NA);
2496 }
2497
2498 if (pinfo->desegment_offset == 0) {
2499 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IAX2");
2500 col_set_str(pinfo->cinfo, COL_INFO, "[IAX2 segment of a reassembled PDU]");
2501 }
2502 }
2503
2504 pinfo->can_desegment = 0;
2505 pinfo->desegment_offset = 0;
2506 pinfo->desegment_len = 0;
2507 }
2508
dissect_payload(tvbuff_t * tvb,guint32 offset,packet_info * pinfo,proto_tree * iax2_tree,proto_tree * tree,guint32 ts _U_,gboolean video,iax_packet_data * iax_packet)2509 static void dissect_payload(tvbuff_t *tvb, guint32 offset,
2510 packet_info *pinfo, proto_tree *iax2_tree,
2511 proto_tree *tree, guint32 ts _U_, gboolean video,
2512 iax_packet_data *iax_packet)
2513 {
2514 #if 0
2515 gboolean out_of_order = FALSE;
2516 #endif
2517 tvbuff_t *sub_tvb;
2518 guint32 codec = iax_packet -> codec;
2519 guint32 nbytes;
2520 iax_call_data *iax_call = iax_packet -> call_data;
2521
2522 if (offset >= tvb_reported_length(tvb)) {
2523 col_append_str(pinfo->cinfo, COL_INFO, ", empty frame");
2524 return;
2525 }
2526
2527 sub_tvb = tvb_new_subset_remaining(tvb, offset);
2528
2529 /* XXX shouldn't pass through out-of-order packets. */
2530
2531 if (!video && iax_call && iax_call -> dataformat != 0) {
2532 col_append_fstr(pinfo->cinfo, COL_INFO, ", data, format %s",
2533 val_to_str(iax_call -> dataformat,
2534 iax_dataformats, "unknown (0x%02x)"));
2535 #if 0
2536 if (out_of_order)
2537 col_append_str(pinfo->cinfo, COL_INFO, " (out-of-order packet)");
2538 #endif
2539 } else {
2540 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
2541 val64_to_str_ext(CODEC_MASK(codec), &codec_types_ext, "unknown (0x%04x)"));
2542 }
2543
2544 nbytes = tvb_reported_length(sub_tvb);
2545 proto_tree_add_item(iax2_tree, hf_iax2_payload_data, sub_tvb, 0, -1, ENC_NA);
2546
2547 iax2_info->payload_len = nbytes;
2548 iax2_info->payload_data = tvb_get_ptr(sub_tvb, 0, -1);
2549
2550 /* pass the rest of the block to a subdissector */
2551 if (iax_packet->call_data)
2552 desegment_iax(sub_tvb, pinfo, iax2_tree, tree, video, iax_packet);
2553 else
2554 process_iax_pdu(sub_tvb, pinfo, tree, video, iax_packet);
2555 }
2556
2557 /*
2558 * Init routines
2559 */
2560
2561 /* called at the start of a capture. We should clear out our static, per-capture
2562 * data.
2563 */
2564
2565 static void
iax_init_protocol(void)2566 iax_init_protocol(void)
2567 {
2568 iax_circuit_hashtab = g_hash_table_new(iax_circuit_hash, iax_circuit_equal);
2569 circuitcount = 0;
2570
2571 iax_fid_table = g_hash_table_new(g_direct_hash, g_direct_equal);
2572 }
2573
2574 static void
iax_cleanup_protocol(void)2575 iax_cleanup_protocol(void)
2576 {
2577 g_hash_table_destroy(iax_circuit_hashtab);
2578 g_hash_table_destroy(iax_fid_table);
2579 }
2580
2581
2582 void
proto_register_iax2(void)2583 proto_register_iax2(void)
2584 {
2585 /* A header field is something you can search/filter on.
2586 *
2587 * We create a structure to register our fields. It consists of an
2588 * array of hf_register_info structures, each of which are of the format
2589 * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
2590 */
2591
2592 static hf_register_info hf[] = {
2593
2594 {&hf_iax2_packet_type,
2595 {"Packet type", "iax2.packet_type",
2596 FT_UINT8, BASE_DEC, VALS(iax_packet_types), 0,
2597 "Full/minivoice/minivideo/trunk packet",
2598 HFILL}},
2599
2600 {&hf_iax2_callno,
2601 {"Call identifier", "iax2.call",
2602 FT_UINT32, BASE_DEC, NULL, 0,
2603 "This is the identifier Wireshark assigns to identify this call."
2604 " It does not correspond to any real field in the protocol",
2605 HFILL }},
2606
2607 {&hf_iax2_scallno,
2608 {"Source call", "iax2.src_call",
2609 FT_UINT16, BASE_DEC, NULL, 0x7FFF,
2610 "src_call holds the number of this call at the packet source pbx",
2611 HFILL}},
2612
2613 /* FIXME could this be turned into a FRAMENUM field? */
2614 {&hf_iax2_dcallno,
2615 {"Destination call", "iax2.dst_call",
2616 FT_UINT16, BASE_DEC, NULL, 0x7FFF,
2617 "dst_call holds the number of this call at the packet destination",
2618 HFILL}},
2619
2620 {&hf_iax2_retransmission,
2621 {"Retransmission", "iax2.retransmission",
2622 FT_BOOLEAN, 16, NULL, 0x8000,
2623 "retransmission is set if this packet is a retransmission of an earlier failed packet",
2624 HFILL}},
2625
2626 {&hf_iax2_ts,
2627 {"Timestamp", "iax2.timestamp",
2628 FT_UINT32, BASE_DEC, NULL, 0x0,
2629 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2630 HFILL}},
2631
2632 {&hf_iax2_minits,
2633 {"Timestamp", "iax2.timestamp",
2634 FT_UINT16, BASE_DEC, NULL, 0x0,
2635 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2636 HFILL}},
2637
2638 {&hf_iax2_minividts,
2639 {"Timestamp", "iax2.timestamp",
2640 FT_UINT16, BASE_DEC, NULL, 0x7FFF,
2641 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2642 HFILL}},
2643
2644 {&hf_iax2_absts,
2645 {"Absolute Time", "iax2.abstime",
2646 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
2647 "The absolute time of this packet (calculated by adding the IAX timestamp to the start time of this call)",
2648 HFILL}},
2649
2650 {&hf_iax2_lateness,
2651 {"Lateness", "iax2.lateness",
2652 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2653 "The lateness of this packet compared to its timestamp",
2654 HFILL}},
2655
2656 {&hf_iax2_minividmarker,
2657 {"Marker", "iax2.video.mini_marker",
2658 FT_UINT16, BASE_DEC, NULL, 0x8000,
2659 "RTP end-of-frame marker",
2660 HFILL}},
2661
2662 {&hf_iax2_oseqno,
2663 {"Outbound seq.no.", "iax2.oseqno",
2664 FT_UINT16, BASE_DEC, NULL, 0x0,
2665 "oseqno is the sequence no of this packet. The first packet has oseqno==0,"
2666 " and subsequent packets increment the oseqno by 1",
2667 HFILL}},
2668
2669 {&hf_iax2_iseqno,
2670 {"Inbound seq.no.", "iax2.iseqno",
2671 FT_UINT16, BASE_DEC, NULL, 0x0,
2672 "iseqno is the sequence no of the last successfully received packet",
2673 HFILL}},
2674
2675 {&hf_iax2_type,
2676 {"Type", "iax2.type",
2677 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &iax_frame_types_ext, 0x0,
2678 "For full IAX2 frames, type is the type of frame",
2679 HFILL}},
2680
2681 {&hf_iax2_csub,
2682 {"Unknown subclass", "iax2.subclass",
2683 FT_UINT8, BASE_DEC, NULL, 0x0,
2684 "Subclass of unknown type of full IAX2 frame",
2685 HFILL}},
2686
2687 {&hf_iax2_dtmf_csub,
2688 {"DTMF subclass (digit)", "iax2.dtmf.subclass",
2689 FT_STRINGZ, BASE_NONE, NULL, 0x0,
2690 "DTMF subclass gives the DTMF digit",
2691 HFILL}},
2692
2693 {&hf_iax2_cmd_csub,
2694 {"Control subclass", "iax2.control.subclass",
2695 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &iax_cmd_subclasses_ext, 0x0,
2696 "This gives the command number for a Control packet.",
2697 HFILL}},
2698
2699 {&hf_iax2_iax_csub,
2700 {"IAX subclass", "iax2.iax.subclass",
2701 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &iax_iax_subclasses_ext, 0x0,
2702 "IAX subclass gives the command number for IAX signaling packets",
2703 HFILL}},
2704
2705 {&hf_iax2_voice_csub,
2706 {"Voice Subclass (compressed codec no)", "iax2.voice.subclass",
2707 FT_UINT8, BASE_DEC, NULL, 0x0,
2708 NULL, HFILL}},
2709
2710 {&hf_iax2_voice_codec,
2711 {"CODEC", "iax2.voice.codec",
2712 FT_UINT64, BASE_HEX | BASE_EXT_STRING | BASE_VAL64_STRING, &codec_types_ext, 0x0,
2713 "CODEC gives the codec used to encode audio data",
2714 HFILL}},
2715
2716 {&hf_iax2_video_csub,
2717 {"Video Subclass (compressed codec no)", "iax2.video.subclass",
2718 FT_UINT8, BASE_DEC, NULL, 0xBF,
2719 NULL, HFILL}},
2720
2721 {&hf_iax2_marker,
2722 {"Marker", "iax2.video.marker",
2723 FT_BOOLEAN, 8, NULL, 0x40,
2724 "RTP end-of-frame marker",
2725 HFILL}},
2726
2727 {&hf_iax2_video_codec,
2728 {"CODEC", "iax2.video.codec",
2729 FT_UINT64, BASE_HEX | BASE_EXT_STRING | BASE_VAL64_STRING, &codec_types_ext, 0,
2730 "The codec used to encode video data",
2731 HFILL}},
2732
2733 {&hf_iax2_modem_csub,
2734 {"Modem subclass", "iax2.modem.subclass",
2735 FT_UINT8, BASE_DEC, VALS(iax_modem_subclasses), 0x0,
2736 "Modem subclass gives the type of modem",
2737 HFILL}},
2738
2739 {&hf_iax2_text_csub,
2740 {"Text subclass", "iax2.text.subclass",
2741 FT_UINT8, BASE_DEC, VALS(iax_text_subclasses), 0x0,
2742 NULL,
2743 HFILL}},
2744
2745 {&hf_iax2_text_text,
2746 {"Text", "iax2.text.text",
2747 FT_STRING, BASE_NONE, NULL, 0x0,
2748 NULL,
2749 HFILL}},
2750
2751 {&hf_iax2_html_csub,
2752 {"HTML subclass", "iax2.html.subclass",
2753 FT_UINT8, BASE_DEC, VALS(iax_html_subclasses), 0x0,
2754 NULL,
2755 HFILL}},
2756
2757 {&hf_iax2_html_url,
2758 {"HTML URL", "iax2.html.url",
2759 FT_STRING, BASE_NONE, NULL, 0x0,
2760 NULL,
2761 HFILL}},
2762
2763 {&hf_iax2_trunk_ts,
2764 {"Timestamp", "iax2.timestamp",
2765 FT_UINT32, BASE_DEC, NULL, 0x0,
2766 "timestamp is the time, in ms after the start of Command data this call,"
2767 " at which this trunk packet was transmitted",
2768 HFILL}},
2769
2770 {&hf_iax2_trunk_metacmd,
2771 {"Meta command", "iax2.trunk.metacmd",
2772 FT_UINT8, BASE_DEC, NULL, 0x7F,
2773 "Meta command indicates whether or not the Meta Frame is a trunk.",
2774 HFILL}},
2775
2776 {&hf_iax2_trunk_cmddata,
2777 {"Command data", "iax2.trunk.cmddata",
2778 FT_UINT8, BASE_HEX, NULL, 0x0,
2779 "Flags for options that apply to a trunked call",
2780 HFILL}},
2781
2782 {&hf_iax2_trunk_cmddata_ts,
2783 {"Trunk timestamps", "iax2.trunk.cmddata.ts",
2784 FT_BOOLEAN, 8, NULL, IAX2_TRUNK_TS,
2785 "True: calls do each include their own timestamp",
2786 HFILL}},
2787
2788 {&hf_iax2_trunk_call_len,
2789 {"Data length", "iax2.trunk.call.len",
2790 FT_UINT16, BASE_DEC, NULL, 0x0,
2791 "Trunk call data length in octets",
2792 HFILL}},
2793
2794 {&hf_iax2_trunk_call_scallno,
2795 {"Source call number", "iax2.trunk.call.scallno",
2796 FT_UINT16, BASE_DEC, NULL, 0x7FFF,
2797 "Trunk call source call number",
2798 HFILL}},
2799
2800 {&hf_iax2_trunk_call_ts,
2801 {"Timestamp", "iax2.trunk.call.ts",
2802 FT_UINT16, BASE_DEC, NULL, 0x0,
2803 "timestamp is the time, in ms after the start of this call, at which this packet was transmitted",
2804 HFILL}},
2805
2806 {&hf_iax2_trunk_call_data,
2807 {"Data", "iax2.trunk.call.payload",
2808 FT_BYTES, BASE_NONE, NULL, 0x0,
2809 "Payload carried by this trunked packet.",
2810 HFILL}},
2811
2812 {&hf_iax2_trunk_ncalls,
2813 {"Number of calls", "iax2.trunk.ncalls",
2814 FT_UINT16, BASE_DEC, NULL, 0x0,
2815 "Number of calls in this trunk packet",
2816 HFILL}},
2817
2818 /*
2819 * Decoding for the ies
2820 */
2821
2822 {&hf_IAX_IE_APPARENTADDR_SINFAMILY,
2823 {"Family", "iax2.iax.app_addr.sinfamily",
2824 FT_UINT16, BASE_DEC, NULL, 0,
2825 NULL, HFILL }},
2826
2827 {&hf_IAX_IE_APPARENTADDR_SINPORT,
2828 {"Port", "iax2.iax.app_addr.sinport",
2829 FT_UINT16, BASE_DEC, NULL, 0,
2830 NULL, HFILL }},
2831
2832 {&hf_IAX_IE_APPARENTADDR_SINADDR,
2833 {"Address", "iax2.iax.app_addr.sinaddr",
2834 FT_IPv4, BASE_NONE, NULL, 0,
2835 NULL, HFILL }},
2836
2837 {&hf_iax2_ies[IAX_IE_CALLED_NUMBER],
2838 {"Number/extension being called", "iax2.iax.called_number",
2839 FT_STRING,
2840 BASE_NONE, NULL, 0x0, NULL, HFILL}},
2841
2842 {&hf_iax2_ies[IAX_IE_CALLING_NUMBER],
2843 {"Calling number", "iax2.iax.calling_number",
2844 FT_STRING, BASE_NONE, NULL, 0x0,
2845 NULL, HFILL}},
2846
2847
2848 {&hf_iax2_ies[IAX_IE_CALLING_ANI],
2849 {"Calling number ANI for billing", "iax2.iax.calling_ani",
2850 FT_STRING, BASE_NONE, NULL, 0x0,
2851 NULL, HFILL}},
2852
2853 {&hf_iax2_ies[IAX_IE_CALLING_NAME],
2854 {"Name of caller", "iax2.iax.calling_name",
2855 FT_STRING, BASE_NONE, NULL, 0x0,
2856 NULL, HFILL}},
2857
2858 {&hf_iax2_ies[IAX_IE_CALLED_CONTEXT],
2859 {"Context for number", "iax2.iax.called_context",
2860 FT_STRING, BASE_NONE, NULL, 0x0,
2861 NULL, HFILL}},
2862
2863 {&hf_iax2_ies[IAX_IE_USERNAME],
2864 {"Username (peer or user) for authentication", "iax2.iax.username",
2865 FT_STRING, BASE_NONE, NULL, 0x0,
2866 NULL, HFILL}},
2867
2868 {&hf_iax2_ies[IAX_IE_PASSWORD],
2869 {"Password for authentication", "iax2.iax.password",
2870 FT_STRING, BASE_NONE, NULL, 0x0,
2871 NULL, HFILL}},
2872
2873 {&hf_iax2_ies[IAX_IE_CAPABILITY],
2874 {"Actual codec capability", "iax2.iax.capability",
2875 FT_UINT32, BASE_HEX, NULL, 0x0,
2876 NULL, HFILL}},
2877
2878 {&hf_iax2_ies[IAX_IE_FORMAT],
2879 {"Desired codec format", "iax2.iax.format",
2880 FT_UINT64, BASE_HEX | BASE_EXT_STRING | BASE_VAL64_STRING, &codec_types_ext, 0x0,
2881 NULL, HFILL}},
2882
2883 {&hf_iax2_ies[IAX_IE_LANGUAGE],
2884 {"Desired language", "iax2.iax.language",
2885 FT_STRING, BASE_NONE, NULL, 0x0,
2886 NULL, HFILL}},
2887
2888 {&hf_iax2_ies[IAX_IE_VERSION],
2889 {"Protocol version", "iax2.iax.version",
2890 FT_UINT16, BASE_HEX, NULL, 0x0,
2891 NULL, HFILL}},
2892
2893 {&hf_iax2_ies[IAX_IE_ADSICPE],
2894 {"CPE ADSI capability", "iax2.iax.cpe_adsi",
2895 FT_UINT16, BASE_HEX, NULL, 0x0,
2896 NULL, HFILL}},
2897
2898 {&hf_iax2_ies[IAX_IE_DNID],
2899 {"Originally dialed DNID", "iax2.iax.dnid",
2900 FT_STRING, BASE_NONE, NULL, 0x0,
2901 NULL, HFILL}},
2902
2903 {&hf_iax2_ies[IAX_IE_AUTHMETHODS],
2904 {"Authentication method(s)", "iax2.iax.auth.methods",
2905 FT_UINT16, BASE_HEX, NULL, 0x0,
2906 NULL, HFILL}},
2907
2908 {&hf_iax2_ies[IAX_IE_CHALLENGE],
2909 {"Challenge data for MD5/RSA", "iax2.iax.auth.challenge",
2910 FT_STRING, BASE_NONE, NULL, 0x0,
2911 NULL, HFILL}},
2912
2913 {&hf_iax2_ies[IAX_IE_MD5_RESULT],
2914 {"MD5 challenge result", "iax2.iax.auth.md5",
2915 FT_STRING, BASE_NONE, NULL, 0x0,
2916 NULL, HFILL}},
2917
2918 {&hf_iax2_ies[IAX_IE_RSA_RESULT],
2919 {"RSA challenge result", "iax2.iax.auth.rsa",
2920 FT_STRING, BASE_NONE, NULL, 0x0,
2921 NULL, HFILL}},
2922
2923 {&hf_iax2_ies[IAX_IE_REFRESH],
2924 {"When to refresh registration", "iax2.iax.refresh",
2925 FT_INT16, BASE_DEC, NULL, 0x0,
2926 NULL, HFILL}},
2927
2928 {&hf_iax2_ies[IAX_IE_DPSTATUS],
2929 {"Dialplan status", "iax2.iax.dialplan_status",
2930 FT_UINT16, BASE_HEX, NULL, 0x0,
2931 NULL, HFILL}},
2932
2933 {&hf_iax2_ies[IAX_IE_CALLNO],
2934 {"Call number of peer", "iax2.iax.call_no",
2935 FT_UINT16, BASE_DEC, NULL, 0x0,
2936 NULL, HFILL}},
2937
2938 {&hf_iax2_ies[IAX_IE_CAUSE],
2939 {"Cause", "iax2.iax.cause",
2940 FT_STRING, BASE_NONE, NULL, 0x0,
2941 NULL, HFILL}},
2942
2943 {&hf_iax2_ies[IAX_IE_IAX_UNKNOWN],
2944 {"Unknown IAX command", "iax2.iax.iax_unknown",
2945 FT_BYTES, BASE_NONE, NULL, 0x0,
2946 NULL, HFILL}},
2947
2948 {&hf_iax2_ies[IAX_IE_MSGCOUNT],
2949 {"How many messages waiting", "iax2.iax.msg_count",
2950 FT_INT16, BASE_DEC, NULL, 0x0,
2951 NULL, HFILL}},
2952
2953 {&hf_iax2_ies[IAX_IE_AUTOANSWER],
2954 {"Request auto-answering", "iax2.iax.autoanswer",
2955 FT_NONE, BASE_NONE, NULL, 0x0,
2956 NULL, HFILL}},
2957
2958 {&hf_iax2_ies[IAX_IE_MUSICONHOLD],
2959 {"Request musiconhold with QUELCH", "iax2.iax.moh",
2960 FT_NONE, BASE_NONE, NULL, 0x0,
2961 NULL, HFILL}},
2962
2963 {&hf_iax2_ies[IAX_IE_TRANSFERID],
2964 {"Transfer Request Identifier", "iax2.iax.transferid",
2965 FT_UINT32, BASE_HEX, NULL, 0x0,
2966 NULL, HFILL}},
2967
2968 {&hf_iax2_ies[IAX_IE_RDNIS],
2969 {"Referring DNIS", "iax2.iax.rdnis",
2970 FT_STRING, BASE_NONE, NULL, 0x0,
2971 NULL, HFILL}},
2972
2973 {&hf_iax2_ies[IAX_IE_PROVISIONING],
2974 {"Provisioning info", "iax2.iax.provisioning",
2975 FT_STRING, BASE_NONE, NULL, 0x0,
2976 NULL, HFILL}},
2977
2978 {&hf_iax2_ies[IAX_IE_AESPROVISIONING],
2979 {"AES Provisioning info", "iax2.iax.aesprovisioning",
2980 FT_STRING, BASE_NONE, NULL, 0x0,
2981 NULL, HFILL}},
2982
2983 {&hf_iax2_ies[IAX_IE_DATETIME],
2984 {"Date/Time", "iax2.iax.datetime.raw",
2985 FT_UINT32, BASE_DEC, NULL, 0x0,
2986 NULL, HFILL}},
2987
2988 {&hf_iax2_ie_datetime,
2989 {"Date/Time", "iax2.iax.datetime",
2990 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
2991 NULL, HFILL }},
2992
2993 {&hf_iax2_ies[IAX_IE_DEVICETYPE],
2994 {"Device type", "iax2.iax.devicetype",
2995 FT_STRING, BASE_NONE, NULL, 0x0,
2996 NULL, HFILL}},
2997
2998 {&hf_iax2_ies[IAX_IE_SERVICEIDENT],
2999 {"Service identifier", "iax2.iax.serviceident",
3000 FT_STRING, BASE_NONE, NULL, 0x0,
3001 NULL, HFILL}},
3002
3003 {&hf_iax2_ies[IAX_IE_FIRMWAREVER],
3004 {"Firmware version", "iax2.iax.firmwarever",
3005 FT_UINT16, BASE_HEX, NULL, 0x0,
3006 NULL, HFILL}},
3007
3008 {&hf_iax2_ies[IAX_IE_FWBLOCKDESC],
3009 {"Firmware block description", "iax2.iax.fwblockdesc",
3010 FT_UINT32, BASE_HEX, NULL, 0x0,
3011 NULL, HFILL}},
3012
3013 {&hf_iax2_ies[IAX_IE_FWBLOCKDATA],
3014 {"Firmware block of data", "iax2.iax.fwblockdata",
3015 FT_STRING, BASE_NONE, NULL, 0x0,
3016 NULL, HFILL}},
3017
3018 {&hf_iax2_ies[IAX_IE_PROVVER],
3019 {"Provisioning version", "iax2.iax.provver",
3020 FT_UINT32, BASE_HEX, NULL, 0x0,
3021 NULL, HFILL}},
3022
3023 {&hf_iax2_ies[IAX_IE_CALLINGPRES],
3024 {"Calling presentation", "iax2.iax.callingpres",
3025 FT_UINT8, BASE_HEX, NULL, 0x0,
3026 NULL, HFILL}},
3027
3028 {&hf_iax2_ies[IAX_IE_CALLINGTON],
3029 {"Calling type of number", "iax2.iax.callington",
3030 FT_UINT8, BASE_HEX, NULL, 0x0,
3031 NULL, HFILL}},
3032
3033 {&hf_iax2_ies[IAX_IE_CALLINGTNS],
3034 {"Calling transit network select", "iax2.iax.callingtns",
3035 FT_UINT16, BASE_HEX, NULL, 0x0,
3036 NULL, HFILL}},
3037
3038 {&hf_iax2_ies[IAX_IE_SAMPLINGRATE],
3039 {"Supported sampling rates", "iax2.iax.samplingrate",
3040 FT_UINT16, BASE_HEX, NULL, 0x0,
3041 NULL, HFILL}},
3042
3043 {&hf_iax2_ies[IAX_IE_CAUSECODE],
3044 {"Hangup cause", "iax2.iax.causecode",
3045 FT_UINT8, BASE_HEX | BASE_EXT_STRING, &iax_causecodes_ext, 0x0,
3046 NULL, HFILL}},
3047
3048 {&hf_iax2_ies[IAX_IE_ENCRYPTION],
3049 {"Encryption format", "iax2.iax.encryption",
3050 FT_UINT16, BASE_HEX, NULL, 0x0,
3051 NULL, HFILL}},
3052
3053 {&hf_iax2_ies[IAX_IE_ENCKEY],
3054 {"Encryption key", "iax2.iax.enckey",
3055 FT_STRING, BASE_NONE, NULL, 0x0,
3056 NULL, HFILL}},
3057
3058 {&hf_iax2_ies[IAX_IE_CODEC_PREFS],
3059 {"Codec negotiation", "iax2.iax.codecprefs",
3060 FT_STRING, BASE_NONE, NULL, 0x0,
3061 NULL, HFILL}},
3062
3063 {&hf_iax2_ies[IAX_IE_RR_JITTER],
3064 {"Received jitter (as in RFC1889)", "iax2.iax.rrjitter",
3065 FT_UINT32, BASE_HEX, NULL, 0x0,
3066 NULL, HFILL}},
3067
3068 {&hf_iax2_ies[IAX_IE_RR_LOSS],
3069 {"Received loss (high byte loss pct, low 24 bits loss count, as in rfc1889)", "iax2.iax.rrloss",
3070 FT_UINT32, BASE_HEX, NULL, 0x0,
3071 NULL, HFILL}},
3072
3073 {&hf_iax2_ies[IAX_IE_RR_PKTS],
3074 {"Total frames received", "iax2.iax.rrpkts",
3075 FT_UINT32, BASE_HEX, NULL, 0x0,
3076 NULL, HFILL}},
3077
3078 {&hf_iax2_ies[IAX_IE_RR_DELAY],
3079 {"Max playout delay in ms for received frames", "iax2.iax.rrdelay",
3080 FT_UINT16, BASE_HEX, NULL, 0x0,
3081 NULL, HFILL}},
3082
3083 {&hf_iax2_ies[IAX_IE_RR_DROPPED],
3084 {"Dropped frames (presumably by jitterbuffer)", "iax2.iax.rrdropped",
3085 FT_UINT32, BASE_HEX, NULL, 0x0,
3086 NULL, HFILL}},
3087
3088 {&hf_iax2_ies[IAX_IE_RR_OOO],
3089 {"Frame received out of order", "iax2.iax.rrooo",
3090 FT_UINT32, BASE_HEX, NULL, 0x0,
3091 NULL, HFILL}},
3092
3093 {&hf_iax2_ies[IAX_IE_CAPABILITY2],
3094 {"64-bit codec capability", "iax2.iax.capability2",
3095 FT_UINT64, BASE_HEX, NULL, 0x0,
3096 NULL, HFILL}},
3097
3098 {&hf_iax2_ies[IAX_IE_FORMAT2],
3099 {"64-bit codec format", "iax2.iax.format2",
3100 FT_UINT64, BASE_HEX | BASE_EXT_STRING | BASE_VAL64_STRING, &codec_types_ext, 0x0,
3101 NULL, HFILL}},
3102
3103 {&hf_iax2_ies[IAX_IE_DATAFORMAT],
3104 {"Data call format", "iax2.iax.dataformat",
3105 FT_UINT32, BASE_HEX, VALS(iax_dataformats), 0x0,
3106 NULL, HFILL}},
3107
3108 {&hf_IAX_IE_UNKNOWN_BYTE,
3109 {"Unknown", "iax2.iax.unknownbyte",
3110 FT_UINT8, BASE_HEX, NULL, 0x0,
3111 "Raw data for unknown IEs", HFILL}},
3112
3113 {&hf_IAX_IE_UNKNOWN_I16,
3114 {"Unknown", "iax2.iax.unknownshort",
3115 FT_UINT16, BASE_HEX, NULL, 0x0,
3116 "Raw data for unknown IEs", HFILL}},
3117
3118 {&hf_IAX_IE_UNKNOWN_I32,
3119 {"Unknown", "iax2.iax.unknownlong",
3120 FT_UINT32, BASE_HEX, NULL, 0x0,
3121 "Raw data for unknown IEs", HFILL}},
3122
3123 {&hf_IAX_IE_UNKNOWN_BYTES,
3124 {"Unknown", "iax2.iax.unknownstring",
3125 FT_STRING, BASE_NONE, NULL, 0x0,
3126 "Raw data for unknown IEs", HFILL}},
3127
3128 {&hf_iax2_ie_id,
3129 {"IE id", "iax2.ie_id",
3130 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &iax_ies_type_ext, 0x0,
3131 NULL, HFILL}},
3132
3133 {&hf_iax2_length,
3134 {"Length", "iax2.length",
3135 FT_UINT8, BASE_DEC, NULL, 0x0,
3136 NULL, HFILL}},
3137
3138 {&hf_iax2_version,
3139 {"Version", "iax2.version",
3140 FT_UINT8, BASE_DEC, NULL, 0x0,
3141 NULL, HFILL}},
3142
3143 /* capabilities */
3144 {&hf_iax2_cap_g723_1,
3145 {"G.723.1 compression", "iax2.cap.g723_1",
3146 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_G723_1),
3147 NULL, HFILL }},
3148
3149 {&hf_iax2_cap_gsm,
3150 {"GSM compression", "iax2.cap.gsm",
3151 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_GSM),
3152 NULL, HFILL }},
3153
3154 {&hf_iax2_cap_ulaw,
3155 {"Raw mu-law data (G.711)", "iax2.cap.ulaw",
3156 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_ULAW),
3157 NULL, HFILL }},
3158
3159 {&hf_iax2_cap_alaw,
3160 {"Raw A-law data (G.711)", "iax2.cap.alaw",
3161 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_ALAW),
3162 NULL, HFILL } },
3163
3164 {&hf_iax2_cap_g726_aal2,
3165 {"ADPCM (G.726, 32kbps, AAL2 codeword packing)", "iax2.cap.g726_aal2",
3166 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_G726_AAL2),
3167 NULL, HFILL }},
3168
3169 {&hf_iax2_cap_adpcm,
3170 {"ADPCM", "iax2.cap.adpcm",
3171 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_ADPCM),
3172 NULL, HFILL }},
3173
3174 {&hf_iax2_cap_slinear,
3175 {"Raw 16-bit Signed Linear (8000 Hz) PCM", "iax2.cap.slinear",
3176 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_SLINEAR),
3177 NULL, HFILL }},
3178
3179 {&hf_iax2_cap_lpc10,
3180 {"LPC10, 180 samples/frame", "iax2.cap.lpc10",
3181 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_LPC10),
3182 NULL, HFILL }},
3183
3184 {&hf_iax2_cap_g729a,
3185 {"G.729a Audio", "iax2.cap.g729a",
3186 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_G729A),
3187 NULL, HFILL }},
3188
3189 {&hf_iax2_cap_speex,
3190 {"SpeeX Free Compression", "iax2.cap.speex",
3191 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_SPEEX),
3192 NULL, HFILL }},
3193
3194 {&hf_iax2_cap_ilbc,
3195 {"iLBC Free Compression", "iax2.cap.ilbc",
3196 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_ILBC),
3197 NULL, HFILL }},
3198
3199 {&hf_iax2_cap_g726,
3200 {"ADPCM (G.726, 32kbps, RFC3551 codeword packing)", "iax2.cap.g726",
3201 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_G726),
3202 NULL, HFILL }},
3203
3204 {&hf_iax2_cap_g722,
3205 {"G.722", "iax2.cap.g722",
3206 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_G722),
3207 NULL, HFILL }},
3208
3209 {&hf_iax2_cap_siren7,
3210 {"G.722.1 (also known as Siren7, 32kbps assumed)", "iax2.cap.siren7",
3211 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_SIREN7),
3212 NULL, HFILL }},
3213
3214 {&hf_iax2_cap_siren14,
3215 {"G.722.1 Annex C (also known as Siren14, 48kbps assumed)", "iax2.cap.siren14",
3216 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_SIREN14),
3217 NULL, HFILL }},
3218
3219 {&hf_iax2_cap_slinear16,
3220 {"Raw 16-bit Signed Linear (16000 Hz) PCM", "iax2.cap.slinear16",
3221 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_SLINEAR16),
3222 NULL, HFILL }},
3223
3224 {&hf_iax2_cap_jpeg,
3225 {"JPEG images", "iax2.cap.jpeg",
3226 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_JPEG),
3227 NULL, HFILL }},
3228
3229 {&hf_iax2_cap_png,
3230 {"PNG images", "iax2.cap.png",
3231 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_PNG),
3232 NULL, HFILL }},
3233
3234 {&hf_iax2_cap_h261,
3235 {"H.261 video", "iax2.cap.h261",
3236 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_H261),
3237 NULL, HFILL }},
3238
3239 {&hf_iax2_cap_h263,
3240 {"H.263 video", "iax2.cap.h263",
3241 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_H263),
3242 NULL, HFILL }},
3243
3244 {&hf_iax2_cap_h263_plus,
3245 {"H.263+ video", "iax2.cap.h263_plus",
3246 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_H263_PLUS),
3247 NULL, HFILL }},
3248
3249 {&hf_iax2_cap_h264,
3250 {"H.264 video", "iax2.cap.h264",
3251 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_H264),
3252 NULL, HFILL }},
3253
3254 {&hf_iax2_cap_mpeg4,
3255 {"MPEG4 video", "iax2.cap.mpeg4",
3256 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_MP4_VIDEO),
3257 NULL, HFILL }},
3258
3259 {&hf_iax2_cap_vp8,
3260 {"VP8 video", "iax2.cap.vp8",
3261 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_VP8),
3262 NULL, HFILL }},
3263
3264 {&hf_iax2_cap_t140_red,
3265 {"T.140 RED Text format RFC 4103", "iax2.cap.t140_red",
3266 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_T140_RED),
3267 NULL, HFILL }},
3268
3269 {&hf_iax2_cap_t140,
3270 {"T.140 Text format - ITU T.140, RFC 4103", "iax2.cap.t140",
3271 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_T140),
3272 NULL, HFILL }},
3273
3274 {&hf_iax2_cap_g719,
3275 {"G.719 (64 kbps assumed)", "iax2.cap.g719",
3276 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_G719),
3277 NULL, HFILL }},
3278
3279 {&hf_iax2_cap_speex16,
3280 {"SpeeX Wideband (16kHz) Free Compression", "iax2.cap.speex16",
3281 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_SPEEX16),
3282 NULL, HFILL }},
3283
3284 {&hf_iax2_cap_opus,
3285 {"Opus audio (8kHz, 16kHz, 24kHz, 48Khz)", "iax2.cap.opus",
3286 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_OPUS),
3287 NULL, HFILL }},
3288
3289 {&hf_iax2_cap_testlaw,
3290 {"Raw testing-law data (G.711)", "iax2.cap.testlaw",
3291 FT_BOOLEAN, 64, TFS(&tfs_supported_not_supported), CODEC_MASK(AST_FORMAT_TESTLAW),
3292 NULL, HFILL }},
3293
3294 {&hf_iax2_fragment_unfinished,
3295 {"IAX2 fragment, unfinished", "iax2.fragment_unfinished",
3296 FT_BYTES, BASE_NONE, NULL, 0x0,
3297 NULL, HFILL }},
3298
3299 {&hf_iax2_payload_data,
3300 {"IAX2 payload", "iax2.payload_data",
3301 FT_BYTES, BASE_NONE, NULL, 0x0,
3302 NULL, HFILL }},
3303
3304 /* reassembly stuff */
3305 {&hf_iax2_fragments,
3306 {"IAX2 Fragments", "iax2.fragments",
3307 FT_NONE, BASE_NONE, NULL, 0x0,
3308 NULL, HFILL }},
3309
3310 {&hf_iax2_fragment,
3311 {"IAX2 Fragment data", "iax2.fragment",
3312 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3313 NULL, HFILL }},
3314
3315 {&hf_iax2_fragment_overlap,
3316 {"Fragment overlap", "iax2.fragment.overlap",
3317 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3318 "Fragment overlaps with other fragments", HFILL }},
3319
3320 {&hf_iax2_fragment_overlap_conflict,
3321 {"Conflicting data in fragment overlap", "iax2.fragment.overlap.conflict",
3322 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3323 "Overlapping fragments contained conflicting data", HFILL }},
3324
3325 {&hf_iax2_fragment_multiple_tails,
3326 {"Multiple tail fragments found", "iax2.fragment.multipletails",
3327 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3328 "Several tails were found when defragmenting the packet", HFILL }},
3329
3330 {&hf_iax2_fragment_too_long_fragment,
3331 {"Fragment too long", "iax2.fragment.toolongfragment",
3332 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3333 "Fragment contained data past end of packet", HFILL }},
3334
3335 {&hf_iax2_fragment_error,
3336 {"Defragmentation error", "iax2.fragment.error",
3337 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3338 "Defragmentation error due to illegal fragments", HFILL }},
3339
3340 {&hf_iax2_fragment_count,
3341 {"Fragment count", "iax2.fragment.count",
3342 FT_UINT32, BASE_DEC, NULL, 0x0,
3343 NULL, HFILL }},
3344
3345 {&hf_iax2_reassembled_in,
3346 {"IAX2 fragment, reassembled in frame", "iax2.reassembled_in",
3347 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3348 "This IAX2 packet is reassembled in this frame", HFILL }},
3349
3350 {&hf_iax2_reassembled_length,
3351 {"Reassembled IAX2 length", "iax2.reassembled.length",
3352 FT_UINT32, BASE_DEC, NULL, 0x0,
3353 "The total length of the reassembled payload", HFILL }}
3354 };
3355
3356 static gint *ett[] = {
3357 &ett_iax2,
3358 &ett_iax2_full_mini_subtree,
3359 &ett_iax2_type,
3360 &ett_iax2_ie,
3361 &ett_iax2_codecs,
3362 &ett_iax2_ies_apparent_addr,
3363 &ett_iax2_fragment,
3364 &ett_iax2_fragments,
3365 &ett_iax2_trunk_cmddata,
3366 &ett_iax2_trunk_call
3367 };
3368
3369 static ei_register_info ei[] = {
3370 { &ei_iax_too_many_transfers, { "iax2.too_many_transfers", PI_PROTOCOL, PI_WARN, "Too many transfers for iax_call", EXPFILL }},
3371 { &ei_iax_circuit_id_conflict, { "iax2.circuit_id_conflict", PI_PROTOCOL, PI_WARN, "Circuit ID conflict", EXPFILL }},
3372 { &ei_iax_peer_address_unsupported, { "iax2.peer_address_unsupported", PI_PROTOCOL, PI_WARN, "Peer address unsupported", EXPFILL }},
3373 { &ei_iax_invalid_len, { "iax2.invalid_len", PI_PROTOCOL, PI_WARN, "Invalid length", EXPFILL }},
3374 };
3375
3376 expert_module_t* expert_iax;
3377
3378 /* initialize the hf_iax2_ies[] array to -1 */
3379 memset(hf_iax2_ies, 0xff, sizeof(hf_iax2_ies));
3380
3381 proto_iax2 =
3382 proto_register_protocol("Inter-Asterisk eXchange v2", "IAX2", "iax2");
3383 proto_register_field_array(proto_iax2, hf, array_length(hf));
3384 proto_register_subtree_array(ett, array_length(ett));
3385 expert_iax = expert_register_protocol(proto_iax2);
3386 expert_register_field_array(expert_iax, ei, array_length(ei));
3387
3388 iax2_handle = register_dissector("iax2", dissect_iax2, proto_iax2);
3389
3390 iax2_codec_dissector_table = register_dissector_table(
3391 "iax2.codec", "IAX codec number", proto_iax2, FT_UINT32, BASE_HEX);
3392 iax2_dataformat_dissector_table = register_dissector_table(
3393 "iax2.dataformat", "IAX dataformat number", proto_iax2, FT_UINT32, BASE_HEX);
3394
3395 /* register our init routine to be called at the start of a capture,
3396 to clear out our hash tables etc */
3397 register_init_routine(&iax_init_protocol);
3398 register_cleanup_routine(&iax_cleanup_protocol);
3399 reassembly_table_register(&iax_reassembly_table,
3400 &addresses_reassembly_table_functions);
3401
3402 iax2_tap = register_tap("IAX2");
3403 }
3404
3405 void
proto_reg_handoff_iax2(void)3406 proto_reg_handoff_iax2(void)
3407 {
3408 dissector_handle_t v110_handle;
3409
3410 dissector_add_uint_with_preference("udp.port", IAX2_PORT, iax2_handle);
3411 v110_handle = find_dissector("v110");
3412 if (v110_handle)
3413 dissector_add_uint("iax2.dataformat", AST_DATAFORMAT_V110, v110_handle);
3414 }
3415
3416 /*
3417 * Editor modelines
3418 *
3419 * Local Variables:
3420 * c-basic-offset: 2
3421 * tab-width: 8
3422 * indent-tabs-mode: nil
3423 * End:
3424 *
3425 * ex: set shiftwidth=2 tabstop=8 expandtab:
3426 * :indentSize=2:tabSize=8:noTabs=true:
3427 */
3428