1 /* packet-h225.c
2 * Routines for h225 packet dissection
3 * Copyright 2005, Anders Broman <anders.broman@ericsson.com>
4 *
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 *
11 * To quote the author of the previous H323/H225/H245 dissector:
12 * "This is a complete replacement of the previous limitied dissector
13 * that Ronnie was crazy enough to write by hand. It was a lot of time
14 * to hack it by hand, but it is incomplete and buggy and it is good when
15 * it will go away."
16 * Ronnie did a great job and all the VoIP users had made good use of it!
17 * Credit to Tomas Kukosa for developing the asn2wrs compiler.
18 *
19 */
20
21 #include "config.h"
22
23 #include <epan/packet.h>
24 #include <epan/conversation.h>
25 #include <epan/proto_data.h>
26
27 #include <epan/prefs.h>
28 #include <epan/oids.h>
29 #include <epan/next_tvb.h>
30 #include <epan/asn1.h>
31 #include <epan/t35.h>
32 #include <epan/tap.h>
33 #include <epan/stat_tap_ui.h>
34 #include <epan/rtd_table.h>
35 #include "packet-frame.h"
36 #include "packet-tpkt.h"
37 #include "packet-per.h"
38 #include "packet-h225.h"
39 #include "packet-h235.h"
40 #include "packet-h245.h"
41 #include "packet-h323.h"
42 #include "packet-q931.h"
43 #include "packet-tls.h"
44
45 #define PNAME "H323-MESSAGES"
46 #define PSNAME "H.225.0"
47 #define PFNAME "h225"
48
49 #define UDP_PORT_RAS_RANGE "1718-1719"
50 #define TCP_PORT_CS 1720
51 #define TLS_PORT_CS 1300
52
53 void proto_register_h225(void);
54 static h225_packet_info* create_h225_packet_info(packet_info *pinfo);
55 static void ras_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, h225_packet_info *pi);
56
57 /* Item of ras request list*/
58 typedef struct _h225ras_call_t {
59 guint32 requestSeqNum;
60 e_guid_t guid;
61 guint32 req_num; /* frame number request seen */
62 guint32 rsp_num; /* frame number response seen */
63 nstime_t req_time; /* arrival time of request */
64 gboolean responded; /* true, if request has been responded */
65 struct _h225ras_call_t *next_call; /* pointer to next ras request with same SequenceNumber and conversation handle */
66 } h225ras_call_t;
67
68
69 /* Item of ras-request key list*/
70 typedef struct _h225ras_call_info_key {
71 guint reqSeqNum;
72 conversation_t *conversation;
73 } h225ras_call_info_key;
74
75 /* Global Memory Chunks for lists and Global hash tables*/
76
77 static wmem_map_t *ras_calls[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
78
79 /* functions, needed using ras-request and halfcall matching*/
80 static h225ras_call_t * find_h225ras_call(h225ras_call_info_key *h225ras_call_key ,int category);
81 static h225ras_call_t * new_h225ras_call(h225ras_call_info_key *h225ras_call_key, packet_info *pinfo, e_guid_t *guid, int category);
82 static h225ras_call_t * append_h225ras_call(h225ras_call_t *prev_call, packet_info *pinfo, e_guid_t *guid, int category);
83
84
85 static dissector_handle_t h225ras_handle;
86 static dissector_handle_t data_handle;
87 /* Subdissector tables */
88 static dissector_table_t nsp_object_dissector_table;
89 static dissector_table_t nsp_h221_dissector_table;
90 static dissector_table_t tp_dissector_table;
91 static dissector_table_t gef_name_dissector_table;
92 static dissector_table_t gef_content_dissector_table;
93
94
95 static dissector_handle_t h245_handle=NULL;
96 static dissector_handle_t h245dg_handle=NULL;
97 static dissector_handle_t h4501_handle=NULL;
98
99 static dissector_handle_t nsp_handle;
100 static dissector_handle_t tp_handle;
101
102 static next_tvb_list_t *h245_list;
103 static next_tvb_list_t *tp_list;
104
105 /* Initialize the protocol and registered fields */
106 static int h225_tap = -1;
107 static int proto_h225 = -1;
108
109 static int hf_h221Manufacturer = -1;
110 static int hf_h225_ras_req_frame = -1;
111 static int hf_h225_ras_rsp_frame = -1;
112 static int hf_h225_ras_dup = -1;
113 static int hf_h225_ras_deltatime = -1;
114 static int hf_h225_debug_dissector_try_string = -1;
115
116 #include "packet-h225-hf.c"
117
118 /* Initialize the subtree pointers */
119 static gint ett_h225 = -1;
120 #include "packet-h225-ett.c"
121
122 /* Preferences */
123 static guint h225_tls_port = TLS_PORT_CS;
124 static gboolean h225_reassembly = TRUE;
125 static gboolean h225_h245_in_tree = TRUE;
126 static gboolean h225_tp_in_tree = TRUE;
127
128 /* Global variables */
129 static guint32 ipv4_address;
130 static ws_in6_addr ipv6_address;
131 static ws_in6_addr ipv6_address_zeros = {{0}};
132 static guint32 ip_port;
133 static gboolean contains_faststart = FALSE;
134 static e_guid_t *call_id_guid;
135
136 /* NonStandardParameter */
137 static const char *nsiOID;
138 static guint32 h221NonStandard;
139 static guint32 t35CountryCode;
140 static guint32 t35Extension;
141 static guint32 manufacturerCode;
142
143 /* TunnelledProtocol */
144 static const char *tpOID;
145
146 static const value_string ras_message_category[] = {
147 { 0, "Gatekeeper "},
148 { 1, "Registration "},
149 { 2, "UnRegistration"},
150 { 3, "Admission "},
151 { 4, "Bandwidth "},
152 { 5, "Disengage "},
153 { 6, "Location "},
154 { 0, NULL }
155 };
156
157 typedef enum _ras_type {
158 RAS_REQUEST,
159 RAS_CONFIRM,
160 RAS_REJECT,
161 RAS_OTHER
162 }ras_type;
163
164 typedef enum _ras_category {
165 RAS_GATEKEEPER,
166 RAS_REGISTRATION,
167 RAS_UNREGISTRATION,
168 RAS_ADMISSION,
169 RAS_BANDWIDTH,
170 RAS_DISENGAGE,
171 RAS_LOCATION,
172 RAS_OTHERS
173 }ras_category;
174
175 #define NUM_RAS_STATS 7
176
177 static tap_packet_status
h225rassrt_packet(void * phs,packet_info * pinfo _U_,epan_dissect_t * edt _U_,const void * phi)178 h225rassrt_packet(void *phs, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *phi)
179 {
180 rtd_data_t* rtd_data = (rtd_data_t*)phs;
181 rtd_stat_table* rs = &rtd_data->stat_table;
182 const h225_packet_info *pi=(const h225_packet_info *)phi;
183
184 ras_type rasmsg_type = RAS_OTHER;
185 ras_category rascategory = RAS_OTHERS;
186
187 if (pi->msg_type != H225_RAS || pi->msg_tag == -1) {
188 /* No RAS Message or uninitialized msg_tag -> return */
189 return TAP_PACKET_DONT_REDRAW;
190 }
191
192 if (pi->msg_tag < 21) {
193 /* */
194 rascategory = (ras_category)(pi->msg_tag / 3);
195 rasmsg_type = (ras_type)(pi->msg_tag % 3);
196 }
197 else {
198 /* No SRT yet (ToDo) */
199 return TAP_PACKET_DONT_REDRAW;
200 }
201
202 switch(rasmsg_type) {
203
204 case RAS_REQUEST:
205 if(pi->is_duplicate){
206 rs->time_stats[rascategory].req_dup_num++;
207 }
208 else {
209 rs->time_stats[rascategory].open_req_num++;
210 }
211 break;
212
213 case RAS_CONFIRM:
214 /* no break - delay stats are identical for Confirm and Reject */
215 case RAS_REJECT:
216 if(pi->is_duplicate){
217 /* Duplicate is ignored */
218 rs->time_stats[rascategory].rsp_dup_num++;
219 }
220 else if (!pi->request_available) {
221 /* no request was seen, ignore response */
222 rs->time_stats[rascategory].disc_rsp_num++;
223 }
224 else {
225 rs->time_stats[rascategory].open_req_num--;
226 time_stat_update(&(rs->time_stats[rascategory].rtd[0]),&(pi->delta_time), pinfo);
227 }
228 break;
229
230 default:
231 return TAP_PACKET_DONT_REDRAW;
232 }
233 return TAP_PACKET_REDRAW;
234 }
235
236 #include "packet-h225-fn.c"
237
238 /* Forward declaration we need below */
239 void proto_reg_handoff_h225(void);
240
241 /*
242 * Functions needed for Ras-Hash-Table
243 */
244
245 /* compare 2 keys */
h225ras_call_equal(gconstpointer k1,gconstpointer k2)246 static gint h225ras_call_equal(gconstpointer k1, gconstpointer k2)
247 {
248 const h225ras_call_info_key* key1 = (const h225ras_call_info_key*) k1;
249 const h225ras_call_info_key* key2 = (const h225ras_call_info_key*) k2;
250
251 return (key1->reqSeqNum == key2->reqSeqNum &&
252 key1->conversation == key2->conversation);
253 }
254
255 /* calculate a hash key */
h225ras_call_hash(gconstpointer k)256 static guint h225ras_call_hash(gconstpointer k)
257 {
258 const h225ras_call_info_key* key = (const h225ras_call_info_key*) k;
259
260 return key->reqSeqNum + GPOINTER_TO_UINT(key->conversation);
261 }
262
263
find_h225ras_call(h225ras_call_info_key * h225ras_call_key,int category)264 h225ras_call_t * find_h225ras_call(h225ras_call_info_key *h225ras_call_key ,int category)
265 {
266 h225ras_call_t *h225ras_call = (h225ras_call_t *)wmem_map_lookup(ras_calls[category], h225ras_call_key);
267
268 return h225ras_call;
269 }
270
new_h225ras_call(h225ras_call_info_key * h225ras_call_key,packet_info * pinfo,e_guid_t * guid,int category)271 h225ras_call_t * new_h225ras_call(h225ras_call_info_key *h225ras_call_key, packet_info *pinfo, e_guid_t *guid, int category)
272 {
273 h225ras_call_info_key *new_h225ras_call_key;
274 h225ras_call_t *h225ras_call = NULL;
275
276
277 /* Prepare the value data.
278 "req_num" and "rsp_num" are frame numbers;
279 frame numbers are 1-origin, so we use 0
280 to mean "we don't yet know in which frame
281 the reply for this call appears". */
282 new_h225ras_call_key = wmem_new(wmem_file_scope(), h225ras_call_info_key);
283 new_h225ras_call_key->reqSeqNum = h225ras_call_key->reqSeqNum;
284 new_h225ras_call_key->conversation = h225ras_call_key->conversation;
285 h225ras_call = wmem_new(wmem_file_scope(), h225ras_call_t);
286 h225ras_call->req_num = pinfo->num;
287 h225ras_call->rsp_num = 0;
288 h225ras_call->requestSeqNum = h225ras_call_key->reqSeqNum;
289 h225ras_call->responded = FALSE;
290 h225ras_call->next_call = NULL;
291 h225ras_call->req_time=pinfo->abs_ts;
292 h225ras_call->guid=*guid;
293 /* store it */
294 wmem_map_insert(ras_calls[category], new_h225ras_call_key, h225ras_call);
295
296 return h225ras_call;
297 }
298
append_h225ras_call(h225ras_call_t * prev_call,packet_info * pinfo,e_guid_t * guid,int category _U_)299 h225ras_call_t * append_h225ras_call(h225ras_call_t *prev_call, packet_info *pinfo, e_guid_t *guid, int category _U_)
300 {
301 h225ras_call_t *h225ras_call = NULL;
302
303 /* Prepare the value data.
304 "req_num" and "rsp_num" are frame numbers;
305 frame numbers are 1-origin, so we use 0
306 to mean "we don't yet know in which frame
307 the reply for this call appears". */
308 h225ras_call = wmem_new(wmem_file_scope(), h225ras_call_t);
309 h225ras_call->req_num = pinfo->num;
310 h225ras_call->rsp_num = 0;
311 h225ras_call->requestSeqNum = prev_call->requestSeqNum;
312 h225ras_call->responded = FALSE;
313 h225ras_call->next_call = NULL;
314 h225ras_call->req_time=pinfo->abs_ts;
315 h225ras_call->guid=*guid;
316
317 prev_call->next_call = h225ras_call;
318 return h225ras_call;
319 }
320
321 static void
h225_frame_end(void)322 h225_frame_end(void)
323 {
324 /* next_tvb pointers are allocated in packet scope, clear it. */
325 h245_list = NULL;
326 tp_list = NULL;
327 }
328
329 static int
dissect_h225_H323UserInformation(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)330 dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
331 {
332 proto_item *it;
333 proto_tree *tr;
334 int offset = 0;
335 h225_packet_info* h225_pi;
336
337 /* Init struct for collecting h225_packet_info */
338 h225_pi = create_h225_packet_info(pinfo);
339 h225_pi->msg_type = H225_CS;
340 p_add_proto_data(pinfo->pool, pinfo, proto_h225, 0, h225_pi);
341
342 register_frame_end_routine(pinfo, h225_frame_end);
343 h245_list = next_tvb_list_new(pinfo->pool);
344 tp_list = next_tvb_list_new(pinfo->pool);
345
346 col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME);
347 col_clear(pinfo->cinfo, COL_INFO);
348
349 it=proto_tree_add_protocol_format(tree, proto_h225, tvb, 0, -1, PSNAME" CS");
350 tr=proto_item_add_subtree(it, ett_h225);
351
352 offset = dissect_H323_UserInformation_PDU(tvb, pinfo, tr, NULL);
353
354 if (h245_list->count){
355 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
356 col_set_fence(pinfo->cinfo, COL_PROTOCOL);
357 }
358
359 next_tvb_call(h245_list, pinfo, tree, h245dg_handle, data_handle);
360 next_tvb_call(tp_list, pinfo, tree, NULL, data_handle);
361
362 tap_queue_packet(h225_tap, pinfo, h225_pi);
363
364 return offset;
365 }
366 static int
dissect_h225_h225_RasMessage(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)367 dissect_h225_h225_RasMessage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_){
368 proto_item *it;
369 proto_tree *tr;
370 guint32 offset=0;
371 h225_packet_info* h225_pi;
372
373 /* Init struct for collecting h225_packet_info */
374 h225_pi = create_h225_packet_info(pinfo);
375 h225_pi->msg_type = H225_RAS;
376 p_add_proto_data(pinfo->pool, pinfo, proto_h225, 0, h225_pi);
377
378 register_frame_end_routine(pinfo, h225_frame_end);
379 h245_list = next_tvb_list_new(pinfo->pool);
380 tp_list = next_tvb_list_new(pinfo->pool);
381
382 col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME);
383
384 it=proto_tree_add_protocol_format(tree, proto_h225, tvb, offset, -1, PSNAME" RAS");
385 tr=proto_item_add_subtree(it, ett_h225);
386
387 offset = dissect_RasMessage_PDU(tvb, pinfo, tr, NULL);
388
389 ras_call_matching(tvb, pinfo, tr, h225_pi);
390
391 next_tvb_call(h245_list, pinfo, tree, h245dg_handle, data_handle);
392 next_tvb_call(tp_list, pinfo, tree, NULL, data_handle);
393
394 tap_queue_packet(h225_tap, pinfo, h225_pi);
395
396 return offset;
397 }
398
399
400 /* The following values represent the size of their valuestring arrays */
401
402 #define RAS_MSG_TYPES (sizeof(h225_RasMessage_vals) / sizeof(value_string))
403 #define CS_MSG_TYPES (sizeof(T_h323_message_body_vals) / sizeof(value_string))
404
405 #define GRJ_REASONS (sizeof(GatekeeperRejectReason_vals) / sizeof(value_string))
406 #define RRJ_REASONS (sizeof(RegistrationRejectReason_vals) / sizeof(value_string))
407 #define URQ_REASONS (sizeof(UnregRequestReason_vals) / sizeof(value_string))
408 #define URJ_REASONS (sizeof(UnregRejectReason_vals) / sizeof(value_string))
409 #define ARJ_REASONS (sizeof(AdmissionRejectReason_vals) / sizeof(value_string))
410 #define BRJ_REASONS (sizeof(BandRejectReason_vals) / sizeof(value_string))
411 #define DRQ_REASONS (sizeof(DisengageReason_vals) / sizeof(value_string))
412 #define DRJ_REASONS (sizeof(DisengageRejectReason_vals) / sizeof(value_string))
413 #define LRJ_REASONS (sizeof(LocationRejectReason_vals) / sizeof(value_string))
414 #define IRQNAK_REASONS (sizeof(InfoRequestNakReason_vals) / sizeof(value_string))
415 #define REL_CMP_REASONS (sizeof(h225_ReleaseCompleteReason_vals) / sizeof(value_string))
416 #define FACILITY_REASONS (sizeof(FacilityReason_vals) / sizeof(value_string))
417
418 /* TAP STAT INFO */
419 typedef enum
420 {
421 MESSAGE_TYPE_COLUMN = 0,
422 COUNT_COLUMN
423 } h225_stat_columns;
424
425 typedef struct _h225_table_item {
426 guint count; /* Message count */
427 guint table_idx; /* stat_table index */
428 } h225_table_item_t;
429
430 static stat_tap_table_item h225_stat_fields[] = {{TABLE_ITEM_STRING, TAP_ALIGN_LEFT, "Message Type or Reason", "%-25s"}, {TABLE_ITEM_UINT, TAP_ALIGN_RIGHT, "Count", "%d"}};
431
432 static guint ras_msg_idx[RAS_MSG_TYPES];
433 static guint cs_msg_idx[CS_MSG_TYPES];
434
435 static guint grj_reason_idx[GRJ_REASONS];
436 static guint rrj_reason_idx[RRJ_REASONS];
437 static guint urq_reason_idx[URQ_REASONS];
438 static guint urj_reason_idx[URJ_REASONS];
439 static guint arj_reason_idx[ARJ_REASONS];
440 static guint brj_reason_idx[BRJ_REASONS];
441 static guint drq_reason_idx[DRQ_REASONS];
442 static guint drj_reason_idx[DRJ_REASONS];
443 static guint lrj_reason_idx[LRJ_REASONS];
444 static guint irqnak_reason_idx[IRQNAK_REASONS];
445 static guint rel_cmp_reason_idx[REL_CMP_REASONS];
446 static guint facility_reason_idx[FACILITY_REASONS];
447
448 static guint other_idx;
449
h225_stat_init(stat_tap_table_ui * new_stat)450 static void h225_stat_init(stat_tap_table_ui* new_stat)
451 {
452 const char *table_name = "H.225 Messages and Message Reasons";
453 int num_fields = sizeof(h225_stat_fields)/sizeof(stat_tap_table_item);
454 stat_tap_table *table;
455 int row_idx = 0, msg_idx;
456 stat_tap_table_item_type items[sizeof(h225_stat_fields)/sizeof(stat_tap_table_item)];
457
458 table = stat_tap_find_table(new_stat, table_name);
459 if (table) {
460 if (new_stat->stat_tap_reset_table_cb) {
461 new_stat->stat_tap_reset_table_cb(table);
462 }
463 return;
464 }
465
466 table = stat_tap_init_table(table_name, num_fields, 0, NULL);
467 stat_tap_add_table(new_stat, table);
468
469 items[MESSAGE_TYPE_COLUMN].type = TABLE_ITEM_STRING;
470 items[COUNT_COLUMN].type = TABLE_ITEM_UINT;
471 items[COUNT_COLUMN].value.uint_value = 0;
472
473 /* Add a row for each value type */
474
475 msg_idx = 0;
476 do
477 {
478 items[MESSAGE_TYPE_COLUMN].value.string_value =
479 h225_RasMessage_vals[msg_idx].strptr
480 ? h225_RasMessage_vals[msg_idx].strptr
481 : "Unknown RAS message";
482 ras_msg_idx[msg_idx] = row_idx;
483
484 stat_tap_init_table_row(table, row_idx, num_fields, items);
485 row_idx++;
486 msg_idx++;
487 } while (h225_RasMessage_vals[msg_idx].strptr);
488
489 msg_idx = 0;
490 do
491 {
492 items[MESSAGE_TYPE_COLUMN].value.string_value =
493 T_h323_message_body_vals[msg_idx].strptr
494 ? T_h323_message_body_vals[msg_idx].strptr
495 : "Unknown CS message";
496 cs_msg_idx[msg_idx] = row_idx;
497
498 stat_tap_init_table_row(table, row_idx, num_fields, items);
499 row_idx++;
500 msg_idx++;
501 } while (T_h323_message_body_vals[msg_idx].strptr);
502
503 msg_idx = 0;
504 do
505 {
506 items[MESSAGE_TYPE_COLUMN].value.string_value =
507 GatekeeperRejectReason_vals[msg_idx].strptr
508 ? GatekeeperRejectReason_vals[msg_idx].strptr
509 : "Unknown gatekeeper reject reason";
510 grj_reason_idx[msg_idx] = row_idx;
511
512 stat_tap_init_table_row(table, row_idx, num_fields, items);
513 row_idx++;
514 msg_idx++;
515 } while (GatekeeperRejectReason_vals[msg_idx].strptr);
516
517 msg_idx = 0;
518 do
519 {
520 items[MESSAGE_TYPE_COLUMN].value.string_value =
521 RegistrationRejectReason_vals[msg_idx].strptr
522 ? RegistrationRejectReason_vals[msg_idx].strptr
523 : "Unknown registration reject reason";
524 rrj_reason_idx[msg_idx] = row_idx;
525
526 stat_tap_init_table_row(table, row_idx, num_fields, items);
527 row_idx++;
528 msg_idx++;
529 } while (RegistrationRejectReason_vals[msg_idx].strptr);
530
531 msg_idx = 0;
532 do
533 {
534 items[MESSAGE_TYPE_COLUMN].value.string_value =
535 UnregRequestReason_vals[msg_idx].strptr
536 ? UnregRequestReason_vals[msg_idx].strptr
537 : "Unknown unregistration request reason";
538 urq_reason_idx[msg_idx] = row_idx;
539
540 stat_tap_init_table_row(table, row_idx, num_fields, items);
541 row_idx++;
542 msg_idx++;
543 } while (UnregRequestReason_vals[msg_idx].strptr);
544
545 msg_idx = 0;
546 do
547 {
548 items[MESSAGE_TYPE_COLUMN].value.string_value =
549 UnregRejectReason_vals[msg_idx].strptr
550 ? UnregRejectReason_vals[msg_idx].strptr
551 : "Unknown unregistration reject reason";
552 urj_reason_idx[msg_idx] = row_idx;
553
554 stat_tap_init_table_row(table, row_idx, num_fields, items);
555 row_idx++;
556 msg_idx++;
557 } while (UnregRejectReason_vals[msg_idx].strptr);
558
559 msg_idx = 0;
560 do
561 {
562 items[MESSAGE_TYPE_COLUMN].value.string_value =
563 AdmissionRejectReason_vals[msg_idx].strptr
564 ? AdmissionRejectReason_vals[msg_idx].strptr
565 : "Unknown admission reject reason";
566 arj_reason_idx[msg_idx] = row_idx;
567
568 stat_tap_init_table_row(table, row_idx, num_fields, items);
569 row_idx++;
570 msg_idx++;
571 } while (AdmissionRejectReason_vals[msg_idx].strptr);
572
573 msg_idx = 0;
574 do
575 {
576 items[MESSAGE_TYPE_COLUMN].value.string_value =
577 BandRejectReason_vals[msg_idx].strptr
578 ? BandRejectReason_vals[msg_idx].strptr
579 : "Unknown band reject reason";
580 brj_reason_idx[msg_idx] = row_idx;
581
582 stat_tap_init_table_row(table, row_idx, num_fields, items);
583 row_idx++;
584 msg_idx++;
585 } while (BandRejectReason_vals[msg_idx].strptr);
586
587 msg_idx = 0;
588 do
589 {
590 items[MESSAGE_TYPE_COLUMN].value.string_value =
591 DisengageReason_vals[msg_idx].strptr
592 ? DisengageReason_vals[msg_idx].strptr
593 : "Unknown disengage reason";
594 drq_reason_idx[msg_idx] = row_idx;
595
596 stat_tap_init_table_row(table, row_idx, num_fields, items);
597 row_idx++;
598 msg_idx++;
599 } while (DisengageReason_vals[msg_idx].strptr);
600
601 msg_idx = 0;
602 do
603 {
604 items[MESSAGE_TYPE_COLUMN].value.string_value =
605 DisengageRejectReason_vals[msg_idx].strptr
606 ? DisengageRejectReason_vals[msg_idx].strptr
607 : "Unknown disengage reject reason";
608 drj_reason_idx[msg_idx] = row_idx;
609
610 stat_tap_init_table_row(table, row_idx, num_fields, items);
611 row_idx++;
612 msg_idx++;
613 } while (DisengageRejectReason_vals[msg_idx].strptr);
614
615 msg_idx = 0;
616 do
617 {
618 items[MESSAGE_TYPE_COLUMN].value.string_value =
619 LocationRejectReason_vals[msg_idx].strptr
620 ? LocationRejectReason_vals[msg_idx].strptr
621 : "Unknown location reject reason";
622 lrj_reason_idx[msg_idx] = row_idx;
623
624 stat_tap_init_table_row(table, row_idx, num_fields, items);
625 row_idx++;
626 msg_idx++;
627 } while (LocationRejectReason_vals[msg_idx].strptr);
628
629 msg_idx = 0;
630 do
631 {
632 items[MESSAGE_TYPE_COLUMN].value.string_value =
633 InfoRequestNakReason_vals[msg_idx].strptr
634 ? InfoRequestNakReason_vals[msg_idx].strptr
635 : "Unknown info request nak reason";
636 irqnak_reason_idx[msg_idx] = row_idx;
637
638 stat_tap_init_table_row(table, row_idx, num_fields, items);
639 row_idx++;
640 msg_idx++;
641 } while (InfoRequestNakReason_vals[msg_idx].strptr);
642
643 msg_idx = 0;
644 do
645 {
646 items[MESSAGE_TYPE_COLUMN].value.string_value =
647 h225_ReleaseCompleteReason_vals[msg_idx].strptr
648 ? h225_ReleaseCompleteReason_vals[msg_idx].strptr
649 : "Unknown release complete reason";
650 rel_cmp_reason_idx[msg_idx] = row_idx;
651
652 stat_tap_init_table_row(table, row_idx, num_fields, items);
653 row_idx++;
654 msg_idx++;
655 } while (h225_ReleaseCompleteReason_vals[msg_idx].strptr);
656
657 msg_idx = 0;
658 do
659 {
660 items[MESSAGE_TYPE_COLUMN].value.string_value =
661 FacilityReason_vals[msg_idx].strptr
662 ? FacilityReason_vals[msg_idx].strptr
663 : "Unknown facility reason";
664 facility_reason_idx[msg_idx] = row_idx;
665
666 stat_tap_init_table_row(table, row_idx, num_fields, items);
667 row_idx++;
668 msg_idx++;
669 } while (FacilityReason_vals[msg_idx].strptr);
670
671
672 items[MESSAGE_TYPE_COLUMN].value.string_value = "Unknown H.225 message";
673 stat_tap_init_table_row(table, row_idx, num_fields, items);
674 other_idx = row_idx;
675 }
676
677 static tap_packet_status
h225_stat_packet(void * tapdata,packet_info * pinfo _U_,epan_dissect_t * edt _U_,const void * hpi_ptr)678 h225_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *hpi_ptr)
679 {
680 stat_data_t* stat_data = (stat_data_t*)tapdata;
681 const h225_packet_info *hpi = (const h225_packet_info *)hpi_ptr;
682 int tag_idx = -1;
683 int reason_idx = -1;
684
685 if(hpi->msg_tag < 0) { /* uninitialized */
686 return TAP_PACKET_DONT_REDRAW;
687 }
688
689 switch (hpi->msg_type) {
690
691 case H225_RAS:
692 tag_idx = ras_msg_idx[MIN(hpi->msg_tag, (int)RAS_MSG_TYPES-1)];
693
694 /* Look for reason tag */
695 if(hpi->reason < 0) { /* uninitialized */
696 break;
697 }
698
699 switch(hpi->msg_tag) {
700
701 case 2: /* GRJ */
702 reason_idx = grj_reason_idx[MIN(hpi->reason, (int)GRJ_REASONS-1)];
703 break;
704 case 5: /* RRJ */
705 reason_idx = rrj_reason_idx[MIN(hpi->reason, (int)RRJ_REASONS-1)];
706 break;
707 case 6: /* URQ */
708 reason_idx = urq_reason_idx[MIN(hpi->reason, (int)URQ_REASONS-1)];
709 break;
710 case 8: /* URJ */
711 reason_idx = urj_reason_idx[MIN(hpi->reason, (int)URJ_REASONS-1)];
712 break;
713 case 11: /* ARJ */
714 reason_idx = arj_reason_idx[MIN(hpi->reason, (int)ARJ_REASONS-1)];
715 break;
716 case 14: /* BRJ */
717 reason_idx = brj_reason_idx[MIN(hpi->reason, (int)BRJ_REASONS-1)];
718 break;
719 case 15: /* DRQ */
720 reason_idx = drq_reason_idx[MIN(hpi->reason, (int)DRQ_REASONS-1)];
721 break;
722 case 17: /* DRJ */
723 reason_idx = drj_reason_idx[MIN(hpi->reason, (int)DRJ_REASONS-1)];
724 break;
725 case 20: /* LRJ */
726 reason_idx = lrj_reason_idx[MIN(hpi->reason, (int)LRJ_REASONS-1)];
727 break;
728 case 29: /* IRQ Nak */
729 reason_idx = irqnak_reason_idx[MIN(hpi->reason, (int)IRQNAK_REASONS-1)];
730 break;
731 default:
732 /* do nothing */
733 break;
734 }
735
736 break;
737
738 case H225_CS:
739 tag_idx = cs_msg_idx[MIN(hpi->msg_tag, (int)CS_MSG_TYPES-1)];
740
741 /* Look for reason tag */
742 if(hpi->reason < 0) { /* uninitialized */
743 break;
744 }
745
746 switch(hpi->msg_tag) {
747
748 case 5: /* ReleaseComplete */
749 reason_idx = rel_cmp_reason_idx[MIN(hpi->reason, (int)REL_CMP_REASONS-1)];
750 break;
751 case 6: /* Facility */
752 reason_idx = facility_reason_idx[MIN(hpi->reason, (int)FACILITY_REASONS-1)];
753 break;
754 default:
755 /* do nothing */
756 break;
757 }
758
759 break;
760
761 case H225_OTHERS:
762 default:
763 tag_idx = other_idx;
764 }
765
766 if (tag_idx >= 0) {
767 stat_tap_table*table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table*, 0);
768 stat_tap_table_item_type* msg_data = stat_tap_get_field_data(table, tag_idx, COUNT_COLUMN);;
769 msg_data->value.uint_value++;
770 stat_tap_set_field_data(table, tag_idx, COUNT_COLUMN, msg_data);
771
772 if (reason_idx >= 0) {
773 msg_data = stat_tap_get_field_data(table, reason_idx, COUNT_COLUMN);;
774 msg_data->value.uint_value++;
775 stat_tap_set_field_data(table, reason_idx, COUNT_COLUMN, msg_data);
776 }
777
778 return TAP_PACKET_REDRAW;
779 }
780 return TAP_PACKET_DONT_REDRAW;
781 }
782
783 static void
h225_stat_reset(stat_tap_table * table)784 h225_stat_reset(stat_tap_table* table)
785 {
786 guint element;
787 stat_tap_table_item_type* item_data;
788
789 for (element = 0; element < table->num_elements; element++)
790 {
791 item_data = stat_tap_get_field_data(table, element, COUNT_COLUMN);
792 item_data->value.uint_value = 0;
793 stat_tap_set_field_data(table, element, COUNT_COLUMN, item_data);
794 }
795 }
796
797 /*--- proto_register_h225 -------------------------------------------*/
proto_register_h225(void)798 void proto_register_h225(void) {
799
800 /* List of fields */
801 static hf_register_info hf[] = {
802 { &hf_h221Manufacturer,
803 { "H.225 Manufacturer", "h225.Manufacturer", FT_UINT32, BASE_HEX,
804 VALS(H221ManufacturerCode_vals), 0, "h225.H.221 Manufacturer", HFILL }},
805
806 { &hf_h225_ras_req_frame,
807 { "RAS Request Frame", "h225.ras.reqframe", FT_FRAMENUM, BASE_NONE,
808 NULL, 0, NULL, HFILL }},
809
810 { &hf_h225_ras_rsp_frame,
811 { "RAS Response Frame", "h225.ras.rspframe", FT_FRAMENUM, BASE_NONE,
812 NULL, 0, NULL, HFILL }},
813
814 { &hf_h225_ras_dup,
815 { "Duplicate RAS Message", "h225.ras.dup", FT_UINT32, BASE_DEC,
816 NULL, 0, NULL, HFILL }},
817
818 { &hf_h225_ras_deltatime,
819 { "RAS Service Response Time", "h225.ras.timedelta", FT_RELATIVE_TIME, BASE_NONE,
820 NULL, 0, "Timedelta between RAS-Request and RAS-Response", HFILL }},
821
822 { &hf_h225_debug_dissector_try_string,
823 { "*** DEBUG dissector_try_string", "h225.debug.dissector_try_string", FT_STRING, BASE_NONE,
824 NULL, 0, NULL, HFILL }},
825
826 #include "packet-h225-hfarr.c"
827 };
828
829 /* List of subtrees */
830 static gint *ett[] = {
831 &ett_h225,
832 #include "packet-h225-ettarr.c"
833 };
834
835 static tap_param h225_stat_params[] = {
836 { PARAM_FILTER, "filter", "Filter", NULL, TRUE }
837 };
838
839 static stat_tap_table_ui h225_stat_table = {
840 REGISTER_STAT_GROUP_TELEPHONY,
841 "H.225",
842 PFNAME,
843 "h225,counter",
844 h225_stat_init,
845 h225_stat_packet,
846 h225_stat_reset,
847 NULL,
848 NULL,
849 sizeof(h225_stat_fields)/sizeof(stat_tap_table_item), h225_stat_fields,
850 sizeof(h225_stat_params)/sizeof(tap_param), h225_stat_params,
851 NULL,
852 0
853 };
854
855 module_t *h225_module;
856 int i, proto_h225_ras;
857
858 /* Register protocol */
859 proto_h225 = proto_register_protocol(PNAME, PSNAME, PFNAME);
860
861 /* Create a "fake" protocol to get proper display strings for SRT dialogs */
862 proto_h225_ras = proto_register_protocol("H.225 RAS", "H.225 RAS", "h225_ras");
863
864 /* Register fields and subtrees */
865 proto_register_field_array(proto_h225, hf, array_length(hf));
866 proto_register_subtree_array(ett, array_length(ett));
867
868 h225_module = prefs_register_protocol(proto_h225, proto_reg_handoff_h225);
869 prefs_register_uint_preference(h225_module, "tls.port",
870 "H.225 TLS Port",
871 "H.225 Server TLS Port",
872 10, &h225_tls_port);
873 prefs_register_bool_preference(h225_module, "reassembly",
874 "Reassemble H.225 messages spanning multiple TCP segments",
875 "Whether the H.225 dissector should reassemble messages spanning multiple TCP segments."
876 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
877 &h225_reassembly);
878 prefs_register_bool_preference(h225_module, "h245_in_tree",
879 "Display tunnelled H.245 inside H.225.0 tree",
880 "ON - display tunnelled H.245 inside H.225.0 tree, OFF - display tunnelled H.245 in root tree after H.225.0",
881 &h225_h245_in_tree);
882 prefs_register_bool_preference(h225_module, "tp_in_tree",
883 "Display tunnelled protocols inside H.225.0 tree",
884 "ON - display tunnelled protocols inside H.225.0 tree, OFF - display tunnelled protocols in root tree after H.225.0",
885 &h225_tp_in_tree);
886
887 register_dissector(PFNAME, dissect_h225_H323UserInformation, proto_h225);
888 register_dissector("h323ui",dissect_h225_H323UserInformation, proto_h225);
889 h225ras_handle = register_dissector("h225.ras", dissect_h225_h225_RasMessage, proto_h225);
890
891 nsp_object_dissector_table = register_dissector_table("h225.nsp.object", "H.225 NonStandardParameter Object", proto_h225, FT_STRING, BASE_NONE);
892 nsp_h221_dissector_table = register_dissector_table("h225.nsp.h221", "H.225 NonStandardParameter h221", proto_h225, FT_UINT32, BASE_HEX);
893 tp_dissector_table = register_dissector_table("h225.tp", "H.225 Tunnelled Protocol", proto_h225, FT_STRING, BASE_NONE);
894 gef_name_dissector_table = register_dissector_table("h225.gef.name", "H.225 Generic Extensible Framework Name", proto_h225, FT_STRING, BASE_NONE);
895 gef_content_dissector_table = register_dissector_table("h225.gef.content", "H.225 Generic Extensible Framework Content", proto_h225, FT_STRING, BASE_NONE);
896
897 for(i=0;i<7;i++) {
898 ras_calls[i] = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), h225ras_call_hash, h225ras_call_equal);
899 }
900
901 h225_tap = register_tap(PFNAME);
902
903 register_rtd_table(proto_h225_ras, PFNAME, NUM_RAS_STATS, 1, ras_message_category, h225rassrt_packet, NULL);
904
905 register_stat_tap_table_ui(&h225_stat_table);
906
907 oid_add_from_string("Version 1","0.0.8.2250.0.1");
908 oid_add_from_string("Version 2","0.0.8.2250.0.2");
909 oid_add_from_string("Version 3","0.0.8.2250.0.3");
910 oid_add_from_string("Version 4","0.0.8.2250.0.4");
911 oid_add_from_string("Version 5","0.0.8.2250.0.5");
912 oid_add_from_string("Version 6","0.0.8.2250.0.6");
913 }
914
915
916 /*--- proto_reg_handoff_h225 ---------------------------------------*/
917 void
proto_reg_handoff_h225(void)918 proto_reg_handoff_h225(void)
919 {
920 static gboolean h225_prefs_initialized = FALSE;
921 static dissector_handle_t q931_tpkt_handle;
922 static guint saved_h225_tls_port;
923
924 if (!h225_prefs_initialized) {
925 dissector_add_uint_range_with_preference("udp.port", UDP_PORT_RAS_RANGE, h225ras_handle);
926
927 h245_handle = find_dissector("h245");
928 h245dg_handle = find_dissector("h245dg");
929 h4501_handle = find_dissector_add_dependency("h4501", proto_h225);
930 data_handle = find_dissector("data");
931 h225_prefs_initialized = TRUE;
932 q931_tpkt_handle = find_dissector("q931.tpkt");
933 } else {
934 ssl_dissector_delete(saved_h225_tls_port, q931_tpkt_handle);
935 }
936
937 saved_h225_tls_port = h225_tls_port;
938 ssl_dissector_add(saved_h225_tls_port, q931_tpkt_handle);
939 }
940
create_h225_packet_info(packet_info * pinfo)941 static h225_packet_info* create_h225_packet_info(packet_info *pinfo)
942 {
943 h225_packet_info* pi = wmem_new0(pinfo->pool, h225_packet_info);
944
945 pi->msg_type = H225_OTHERS;
946 pi->cs_type = H225_OTHER;
947 pi->msg_tag = -1;
948 pi->reason = -1;
949
950 return pi;
951 }
952
953 /*
954 The following function contains the routines for RAS request/response matching.
955 A RAS response matches with a request, if both messages have the same
956 RequestSequenceNumber, belong to the same IP conversation and belong to the same
957 RAS "category" (e.g. Admission, Registration).
958
959 We use hashtables to access the lists of RAS calls (request/response pairs).
960 We have one hashtable for each RAS category. The hashkeys consist of the
961 non-unique 16-bit RequestSequenceNumber and values representing the conversation.
962
963 In big capture files, we might get different requests with identical keys.
964 These requests aren't necessarily duplicates. They might be valid new requests.
965 At the moment we just use the timedelta between the last valid and the new request
966 to decide if the new request is a duplicate or not. There might be better ways.
967 Two thresholds are defined below.
968
969 However the decision is made, another problem arises. We can't just add those
970 requests to our hashtables. Instead we create lists of RAS calls with identical keys.
971 The hashtables for RAS calls contain now pointers to the first RAS call in a list of
972 RAS calls with identical keys.
973 These lists aren't expected to contain more than 3 items and are usually single item
974 lists. So we don't need an expensive but intelligent way to access these lists
975 (e.g. hashtables). Just walk through such a list.
976 */
977
978 #define THRESHOLD_REPEATED_RESPONDED_CALL 300
979 #define THRESHOLD_REPEATED_NOT_RESPONDED_CALL 1800
980
ras_call_matching(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,h225_packet_info * pi)981 static void ras_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, h225_packet_info *pi)
982 {
983 proto_item *hidden_item;
984 conversation_t* conversation = NULL;
985 h225ras_call_info_key h225ras_call_key;
986 h225ras_call_t *h225ras_call = NULL;
987 nstime_t delta;
988 guint msg_category;
989
990 if(pi->msg_type == H225_RAS && pi->msg_tag < 21) {
991 /* make RAS request/response matching only for tags from 0 to 20 for now */
992
993 msg_category = pi->msg_tag / 3;
994 if(pi->msg_tag % 3 == 0) { /* Request Message */
995 conversation = find_or_create_conversation(pinfo);
996
997 /* prepare the key data */
998 h225ras_call_key.reqSeqNum = pi->requestSeqNum;
999 h225ras_call_key.conversation = conversation;
1000
1001 /* look up the request */
1002 h225ras_call = find_h225ras_call(&h225ras_call_key ,msg_category);
1003
1004 if (h225ras_call != NULL) {
1005 /* We've seen requests with this reqSeqNum, with the same
1006 source and destination, before - do we have
1007 *this* request already? */
1008 /* Walk through list of ras requests with identical keys */
1009 do {
1010 if (pinfo->num == h225ras_call->req_num) {
1011 /* We have seen this request before -> do nothing */
1012 break;
1013 }
1014
1015 /* if end of list is reached, exit loop and decide if request is duplicate or not. */
1016 if (h225ras_call->next_call == NULL) {
1017 if ( (pinfo->num > h225ras_call->rsp_num && h225ras_call->rsp_num != 0
1018 && pinfo->abs_ts.secs > (h225ras_call->req_time.secs + THRESHOLD_REPEATED_RESPONDED_CALL) )
1019 ||(pinfo->num > h225ras_call->req_num && h225ras_call->rsp_num == 0
1020 && pinfo->abs_ts.secs > (h225ras_call->req_time.secs + THRESHOLD_REPEATED_NOT_RESPONDED_CALL) ) )
1021 {
1022 /* if last request has been responded
1023 and this request appears after last response (has bigger frame number)
1024 and last request occurred more than 300 seconds ago,
1025 or if last request hasn't been responded
1026 and this request appears after last request (has bigger frame number)
1027 and last request occurred more than 1800 seconds ago,
1028 we decide that we have a new request */
1029 /* Append new ras call to list */
1030 h225ras_call = append_h225ras_call(h225ras_call, pinfo, &pi->guid, msg_category);
1031 } else {
1032 /* No, so it's a duplicate request.
1033 Mark it as such. */
1034 pi->is_duplicate = TRUE;
1035 hidden_item = proto_tree_add_uint(tree, hf_h225_ras_dup, tvb, 0,0, pi->requestSeqNum);
1036 proto_item_set_hidden(hidden_item);
1037 }
1038 break;
1039 }
1040 h225ras_call = h225ras_call->next_call;
1041 } while (h225ras_call != NULL );
1042 }
1043 else {
1044 h225ras_call = new_h225ras_call(&h225ras_call_key, pinfo, &pi->guid, msg_category);
1045 }
1046
1047 /* add link to response frame, if available */
1048 if(h225ras_call && h225ras_call->rsp_num != 0){
1049 proto_item *ti =
1050 proto_tree_add_uint_format(tree, hf_h225_ras_rsp_frame, tvb, 0, 0, h225ras_call->rsp_num,
1051 "The response to this request is in frame %u",
1052 h225ras_call->rsp_num);
1053 proto_item_set_generated(ti);
1054 }
1055
1056 /* end of request message handling*/
1057 }
1058 else { /* Confirm or Reject Message */
1059 conversation = find_conversation_pinfo(pinfo, 0);
1060 if (conversation != NULL) {
1061 /* look only for matching request, if
1062 matching conversation is available. */
1063 h225ras_call_key.reqSeqNum = pi->requestSeqNum;
1064 h225ras_call_key.conversation = conversation;
1065 h225ras_call = find_h225ras_call(&h225ras_call_key ,msg_category);
1066 if(h225ras_call) {
1067 /* find matching ras_call in list of ras calls with identical keys */
1068 do {
1069 if (pinfo->num == h225ras_call->rsp_num) {
1070 /* We have seen this response before -> stop now with matching ras call */
1071 break;
1072 }
1073
1074 /* Break when list end is reached */
1075 if(h225ras_call->next_call == NULL) {
1076 break;
1077 }
1078 h225ras_call = h225ras_call->next_call;
1079 } while (h225ras_call != NULL) ;
1080
1081 if (!h225ras_call) {
1082 return;
1083 }
1084
1085 /* if this is an ACF, ARJ or DCF, DRJ, give guid to tap and make it filterable */
1086 if (msg_category == 3 || msg_category == 5) {
1087 pi->guid = h225ras_call->guid;
1088 hidden_item = proto_tree_add_guid(tree, hf_h225_guid, tvb, 0, GUID_LEN, &pi->guid);
1089 proto_item_set_hidden(hidden_item);
1090 }
1091
1092 if (h225ras_call->rsp_num == 0) {
1093 /* We have not yet seen a response to that call, so
1094 this must be the first response; remember its
1095 frame number. */
1096 h225ras_call->rsp_num = pinfo->num;
1097 }
1098 else {
1099 /* We have seen a response to this call - but was it
1100 *this* response? */
1101 if (h225ras_call->rsp_num != pinfo->num) {
1102 /* No, so it's a duplicate response.
1103 Mark it as such. */
1104 pi->is_duplicate = TRUE;
1105 hidden_item = proto_tree_add_uint(tree, hf_h225_ras_dup, tvb, 0,0, pi->requestSeqNum);
1106 proto_item_set_hidden(hidden_item);
1107 }
1108 }
1109
1110 if(h225ras_call->req_num != 0){
1111 proto_item *ti;
1112 h225ras_call->responded = TRUE;
1113 pi->request_available = TRUE;
1114
1115 /* Indicate the frame to which this is a reply. */
1116 ti = proto_tree_add_uint_format(tree, hf_h225_ras_req_frame, tvb, 0, 0, h225ras_call->req_num,
1117 "This is a response to a request in frame %u", h225ras_call->req_num);
1118 proto_item_set_generated(ti);
1119
1120 /* Calculate RAS Service Response Time */
1121 nstime_delta(&delta, &pinfo->abs_ts, &h225ras_call->req_time);
1122 pi->delta_time = delta; /* give it to tap */
1123
1124 /* display Ras Service Response Time and make it filterable */
1125 ti = proto_tree_add_time(tree, hf_h225_ras_deltatime, tvb, 0, 0, &(pi->delta_time));
1126 proto_item_set_generated(ti);
1127 }
1128 }
1129 }
1130 }
1131 }
1132 }
1133
1134 /*
1135 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1136 *
1137 * Local Variables:
1138 * c-basic-offset: 2
1139 * tab-width: 8
1140 * indent-tabs-mode: nil
1141 * End:
1142 *
1143 * vi: set shiftwidth=2 tabstop=8 expandtab:
1144 * :indentSize=2:tabSize=8:noTabs=true:
1145 */
1146