Coverage Report

Created: 2025-08-04 07:15

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