Get rid of more new_ prefixes for statistics functions and types.
[metze/wireshark/wip.git] / epan / dissectors / asn1 / h225 / packet-h225-template.c
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-ssl.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 gboolean
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 FALSE;
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 FALSE;
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 FALSE;
232   }
233   return TRUE;
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 */
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 */
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
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
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
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
322 h225_frame_end(void)
323 {
324   /* next_tvb pointers are allocated in packet scope, clear it. */
325   next_tvb_init(&h245_list);
326   next_tvb_init(&tp_list);
327 }
328
329 static int
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   next_tvb_init(&h245_list);
344   next_tvb_init(&tp_list);
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
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
380   col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME);
381
382   it=proto_tree_add_protocol_format(tree, proto_h225, tvb, offset, -1, PSNAME" RAS");
383   tr=proto_item_add_subtree(it, ett_h225);
384
385   offset = dissect_RasMessage_PDU(tvb, pinfo, tr, NULL);
386
387   ras_call_matching(tvb, pinfo, tr, h225_pi);
388
389   tap_queue_packet(h225_tap, pinfo, h225_pi);
390
391   return offset;
392 }
393
394
395 /* The following values represent the size of their valuestring arrays */
396
397 #define RAS_MSG_TYPES (sizeof(h225_RasMessage_vals) / sizeof(value_string))
398 #define CS_MSG_TYPES (sizeof(T_h323_message_body_vals) / sizeof(value_string))
399
400 #define GRJ_REASONS (sizeof(GatekeeperRejectReason_vals) / sizeof(value_string))
401 #define RRJ_REASONS (sizeof(RegistrationRejectReason_vals) / sizeof(value_string))
402 #define URQ_REASONS (sizeof(UnregRequestReason_vals) / sizeof(value_string))
403 #define URJ_REASONS (sizeof(UnregRejectReason_vals) / sizeof(value_string))
404 #define ARJ_REASONS (sizeof(AdmissionRejectReason_vals) / sizeof(value_string))
405 #define BRJ_REASONS (sizeof(BandRejectReason_vals) / sizeof(value_string))
406 #define DRQ_REASONS (sizeof(DisengageReason_vals) / sizeof(value_string))
407 #define DRJ_REASONS (sizeof(DisengageRejectReason_vals) / sizeof(value_string))
408 #define LRJ_REASONS (sizeof(LocationRejectReason_vals) / sizeof(value_string))
409 #define IRQNAK_REASONS (sizeof(InfoRequestNakReason_vals) / sizeof(value_string))
410 #define REL_CMP_REASONS (sizeof(h225_ReleaseCompleteReason_vals) / sizeof(value_string))
411 #define FACILITY_REASONS (sizeof(FacilityReason_vals) / sizeof(value_string))
412
413 /* TAP STAT INFO */
414 typedef enum
415 {
416   MESSAGE_TYPE_COLUMN = 0,
417   COUNT_COLUMN
418 } h225_stat_columns;
419
420 typedef struct _h225_table_item {
421   guint count;     /* Message count */
422   guint table_idx; /* stat_table index */
423 } h225_table_item_t;
424
425 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"}};
426
427 static guint ras_msg_idx[RAS_MSG_TYPES];
428 static guint cs_msg_idx[CS_MSG_TYPES];
429
430 static guint grj_reason_idx[GRJ_REASONS];
431 static guint rrj_reason_idx[RRJ_REASONS];
432 static guint urq_reason_idx[URQ_REASONS];
433 static guint urj_reason_idx[URJ_REASONS];
434 static guint arj_reason_idx[ARJ_REASONS];
435 static guint brj_reason_idx[BRJ_REASONS];
436 static guint drq_reason_idx[DRQ_REASONS];
437 static guint drj_reason_idx[DRJ_REASONS];
438 static guint lrj_reason_idx[LRJ_REASONS];
439 static guint irqnak_reason_idx[IRQNAK_REASONS];
440 static guint rel_cmp_reason_idx[REL_CMP_REASONS];
441 static guint facility_reason_idx[FACILITY_REASONS];
442
443 static guint other_idx;
444
445 static void h225_stat_init(stat_tap_table_ui* new_stat, stat_tap_gui_init_cb gui_callback, void* gui_data)
446 {
447   int num_fields = sizeof(h225_stat_fields)/sizeof(stat_tap_table_item);
448   stat_tap_table* table = stat_tap_init_table("H.225 Messages and Message Reasons", num_fields, 0, NULL, gui_callback, gui_data);
449   int row_idx = 0, msg_idx;
450   stat_tap_table_item_type items[sizeof(h225_stat_fields)/sizeof(stat_tap_table_item)];
451
452   stat_tap_add_table(new_stat, table);
453
454   items[MESSAGE_TYPE_COLUMN].type = TABLE_ITEM_STRING;
455   items[COUNT_COLUMN].type = TABLE_ITEM_UINT;
456   items[COUNT_COLUMN].value.uint_value = 0;
457
458   /* Add a row for each value type */
459
460   msg_idx = 0;
461   do
462   {
463     items[MESSAGE_TYPE_COLUMN].value.string_value =
464       h225_RasMessage_vals[msg_idx].strptr
465       ? h225_RasMessage_vals[msg_idx].strptr
466       : "Unknown RAS message";
467     ras_msg_idx[msg_idx] = row_idx;
468
469     stat_tap_init_table_row(table, row_idx, num_fields, items);
470     row_idx++;
471     msg_idx++;
472   } while (h225_RasMessage_vals[msg_idx].strptr);
473
474   msg_idx = 0;
475   do
476   {
477     items[MESSAGE_TYPE_COLUMN].value.string_value =
478       T_h323_message_body_vals[msg_idx].strptr
479       ? T_h323_message_body_vals[msg_idx].strptr
480       : "Unknown CS message";
481     cs_msg_idx[msg_idx] = row_idx;
482
483     stat_tap_init_table_row(table, row_idx, num_fields, items);
484     row_idx++;
485     msg_idx++;
486   } while (T_h323_message_body_vals[msg_idx].strptr);
487
488   msg_idx = 0;
489   do
490   {
491     items[MESSAGE_TYPE_COLUMN].value.string_value =
492       GatekeeperRejectReason_vals[msg_idx].strptr
493       ? GatekeeperRejectReason_vals[msg_idx].strptr
494       : "Unknown gatekeeper reject reason";
495     grj_reason_idx[msg_idx] = row_idx;
496
497     stat_tap_init_table_row(table, row_idx, num_fields, items);
498     row_idx++;
499     msg_idx++;
500   } while (GatekeeperRejectReason_vals[msg_idx].strptr);
501
502   msg_idx = 0;
503   do
504   {
505     items[MESSAGE_TYPE_COLUMN].value.string_value =
506       RegistrationRejectReason_vals[msg_idx].strptr
507       ? RegistrationRejectReason_vals[msg_idx].strptr
508       : "Unknown registration reject reason";
509     rrj_reason_idx[msg_idx] = row_idx;
510
511     stat_tap_init_table_row(table, row_idx, num_fields, items);
512     row_idx++;
513     msg_idx++;
514   } while (RegistrationRejectReason_vals[msg_idx].strptr);
515
516   msg_idx = 0;
517   do
518   {
519     items[MESSAGE_TYPE_COLUMN].value.string_value =
520       UnregRequestReason_vals[msg_idx].strptr
521       ? UnregRequestReason_vals[msg_idx].strptr
522       : "Unknown unregistration request reason";
523     urq_reason_idx[msg_idx] = row_idx;
524
525     stat_tap_init_table_row(table, row_idx, num_fields, items);
526     row_idx++;
527     msg_idx++;
528   } while (UnregRequestReason_vals[msg_idx].strptr);
529
530   msg_idx = 0;
531   do
532   {
533     items[MESSAGE_TYPE_COLUMN].value.string_value =
534       UnregRejectReason_vals[msg_idx].strptr
535       ? UnregRejectReason_vals[msg_idx].strptr
536       : "Unknown unregistration reject reason";
537     urj_reason_idx[msg_idx] = row_idx;
538
539     stat_tap_init_table_row(table, row_idx, num_fields, items);
540     row_idx++;
541     msg_idx++;
542   } while (UnregRejectReason_vals[msg_idx].strptr);
543
544   msg_idx = 0;
545   do
546   {
547     items[MESSAGE_TYPE_COLUMN].value.string_value =
548       AdmissionRejectReason_vals[msg_idx].strptr
549       ? AdmissionRejectReason_vals[msg_idx].strptr
550       : "Unknown admission reject reason";
551     arj_reason_idx[msg_idx] = row_idx;
552
553     stat_tap_init_table_row(table, row_idx, num_fields, items);
554     row_idx++;
555     msg_idx++;
556   } while (AdmissionRejectReason_vals[msg_idx].strptr);
557
558   msg_idx = 0;
559   do
560   {
561     items[MESSAGE_TYPE_COLUMN].value.string_value =
562       BandRejectReason_vals[msg_idx].strptr
563       ? BandRejectReason_vals[msg_idx].strptr
564       : "Unknown band reject reason";
565     brj_reason_idx[msg_idx] = row_idx;
566
567     stat_tap_init_table_row(table, row_idx, num_fields, items);
568     row_idx++;
569     msg_idx++;
570   } while (BandRejectReason_vals[msg_idx].strptr);
571
572   msg_idx = 0;
573   do
574   {
575     items[MESSAGE_TYPE_COLUMN].value.string_value =
576       DisengageReason_vals[msg_idx].strptr
577       ? DisengageReason_vals[msg_idx].strptr
578       : "Unknown disengage reason";
579     drq_reason_idx[msg_idx] = row_idx;
580
581     stat_tap_init_table_row(table, row_idx, num_fields, items);
582     row_idx++;
583     msg_idx++;
584   } while (DisengageReason_vals[msg_idx].strptr);
585
586   msg_idx = 0;
587   do
588   {
589     items[MESSAGE_TYPE_COLUMN].value.string_value =
590       DisengageRejectReason_vals[msg_idx].strptr
591       ? DisengageRejectReason_vals[msg_idx].strptr
592       : "Unknown disengage reject reason";
593     drj_reason_idx[msg_idx] = row_idx;
594
595     stat_tap_init_table_row(table, row_idx, num_fields, items);
596     row_idx++;
597     msg_idx++;
598   } while (DisengageRejectReason_vals[msg_idx].strptr);
599
600   msg_idx = 0;
601   do
602   {
603     items[MESSAGE_TYPE_COLUMN].value.string_value =
604       LocationRejectReason_vals[msg_idx].strptr
605       ? LocationRejectReason_vals[msg_idx].strptr
606       : "Unknown location reject reason";
607     lrj_reason_idx[msg_idx] = row_idx;
608
609     stat_tap_init_table_row(table, row_idx, num_fields, items);
610     row_idx++;
611     msg_idx++;
612   } while (LocationRejectReason_vals[msg_idx].strptr);
613
614   msg_idx = 0;
615   do
616   {
617     items[MESSAGE_TYPE_COLUMN].value.string_value =
618       InfoRequestNakReason_vals[msg_idx].strptr
619       ? InfoRequestNakReason_vals[msg_idx].strptr
620       : "Unknown info request nak reason";
621     irqnak_reason_idx[msg_idx] = row_idx;
622
623     stat_tap_init_table_row(table, row_idx, num_fields, items);
624     row_idx++;
625     msg_idx++;
626   } while (InfoRequestNakReason_vals[msg_idx].strptr);
627
628   msg_idx = 0;
629   do
630   {
631     items[MESSAGE_TYPE_COLUMN].value.string_value =
632       h225_ReleaseCompleteReason_vals[msg_idx].strptr
633       ? h225_ReleaseCompleteReason_vals[msg_idx].strptr
634       : "Unknown release complete reason";
635     rel_cmp_reason_idx[msg_idx] = row_idx;
636
637     stat_tap_init_table_row(table, row_idx, num_fields, items);
638     row_idx++;
639     msg_idx++;
640   } while (h225_ReleaseCompleteReason_vals[msg_idx].strptr);
641
642   msg_idx = 0;
643   do
644   {
645     items[MESSAGE_TYPE_COLUMN].value.string_value =
646       FacilityReason_vals[msg_idx].strptr
647       ? FacilityReason_vals[msg_idx].strptr
648       : "Unknown facility reason";
649     facility_reason_idx[msg_idx] = row_idx;
650
651     stat_tap_init_table_row(table, row_idx, num_fields, items);
652     row_idx++;
653     msg_idx++;
654   } while (FacilityReason_vals[msg_idx].strptr);
655
656
657   items[MESSAGE_TYPE_COLUMN].value.string_value = "Unknown H.225 message";
658   stat_tap_init_table_row(table, row_idx, num_fields, items);
659   other_idx = row_idx;
660 }
661
662 static gboolean
663 h225_stat_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *hpi_ptr)
664 {
665   stat_data_t* stat_data = (stat_data_t*)tapdata;
666   const h225_packet_info *hpi = (const h225_packet_info *)hpi_ptr;
667   int tag_idx = -1;
668   int reason_idx = -1;
669
670   if(hpi->msg_tag < 0) { /* uninitialized */
671     return FALSE;
672   }
673
674   switch (hpi->msg_type) {
675
676   case H225_RAS:
677     tag_idx = ras_msg_idx[MIN(hpi->msg_tag, (int)RAS_MSG_TYPES-1)];
678
679     /* Look for reason tag */
680     if(hpi->reason < 0) { /* uninitialized */
681       break;
682     }
683
684     switch(hpi->msg_tag) {
685
686     case 2: /* GRJ */
687       reason_idx = grj_reason_idx[MIN(hpi->reason, (int)GRJ_REASONS-1)];
688       break;
689     case 5: /* RRJ */
690       reason_idx = rrj_reason_idx[MIN(hpi->reason, (int)RRJ_REASONS-1)];
691       break;
692     case 6: /* URQ */
693       reason_idx = urq_reason_idx[MIN(hpi->reason, (int)URQ_REASONS-1)];
694       break;
695     case 8: /* URJ */
696       reason_idx = urj_reason_idx[MIN(hpi->reason, (int)URJ_REASONS-1)];
697       break;
698     case 11: /* ARJ */
699       reason_idx = arj_reason_idx[MIN(hpi->reason, (int)ARJ_REASONS-1)];
700       break;
701     case 14: /* BRJ */
702       reason_idx = brj_reason_idx[MIN(hpi->reason, (int)BRJ_REASONS-1)];
703       break;
704     case 15: /* DRQ */
705       reason_idx = drq_reason_idx[MIN(hpi->reason, (int)DRQ_REASONS-1)];
706       break;
707     case 17: /* DRJ */
708       reason_idx = drj_reason_idx[MIN(hpi->reason, (int)DRJ_REASONS-1)];
709       break;
710     case 20: /* LRJ */
711       reason_idx = lrj_reason_idx[MIN(hpi->reason, (int)LRJ_REASONS-1)];
712       break;
713     case 29: /* IRQ Nak */
714       reason_idx = irqnak_reason_idx[MIN(hpi->reason, (int)IRQNAK_REASONS-1)];
715       break;
716     default:
717       /* do nothing */
718       break;
719     }
720
721     break;
722
723   case H225_CS:
724     tag_idx = cs_msg_idx[MIN(hpi->msg_tag, (int)CS_MSG_TYPES-1)];
725
726     /* Look for reason tag */
727     if(hpi->reason < 0) { /* uninitialized */
728       break;
729     }
730
731     switch(hpi->msg_tag) {
732
733     case 5: /* ReleaseComplete */
734       reason_idx = rel_cmp_reason_idx[MIN(hpi->reason, (int)REL_CMP_REASONS-1)];
735       break;
736     case 6: /* Facility */
737       reason_idx = facility_reason_idx[MIN(hpi->reason, (int)FACILITY_REASONS-1)];
738       break;
739     default:
740       /* do nothing */
741       break;
742     }
743
744     break;
745
746   case H225_OTHERS:
747   default:
748     tag_idx = other_idx;
749   }
750
751   if (tag_idx >= 0) {
752     stat_tap_table*table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table*, 0);
753     stat_tap_table_item_type* msg_data = stat_tap_get_field_data(table, tag_idx, COUNT_COLUMN);;
754     msg_data->value.uint_value++;
755     stat_tap_set_field_data(table, tag_idx, COUNT_COLUMN, msg_data);
756
757     if (reason_idx >= 0) {
758       msg_data = stat_tap_get_field_data(table, reason_idx, COUNT_COLUMN);;
759       msg_data->value.uint_value++;
760       stat_tap_set_field_data(table, reason_idx, COUNT_COLUMN, msg_data);
761     }
762
763     return TRUE;
764   }
765   return FALSE;
766 }
767
768 static void
769 h225_stat_reset(stat_tap_table* table)
770 {
771   guint element;
772   stat_tap_table_item_type* item_data;
773
774   for (element = 0; element < table->num_elements; element++)
775   {
776     item_data = stat_tap_get_field_data(table, element, COUNT_COLUMN);
777     item_data->value.uint_value = 0;
778     stat_tap_set_field_data(table, element, COUNT_COLUMN, item_data);
779   }
780 }
781
782 /*--- proto_register_h225 -------------------------------------------*/
783 void proto_register_h225(void) {
784
785   /* List of fields */
786   static hf_register_info hf[] = {
787   { &hf_h221Manufacturer,
788     { "H.225 Manufacturer", "h225.Manufacturer", FT_UINT32, BASE_HEX,
789     VALS(H221ManufacturerCode_vals), 0, "h225.H.221 Manufacturer", HFILL }},
790
791   { &hf_h225_ras_req_frame,
792     { "RAS Request Frame", "h225.ras.reqframe", FT_FRAMENUM, BASE_NONE,
793     NULL, 0, NULL, HFILL }},
794
795   { &hf_h225_ras_rsp_frame,
796     { "RAS Response Frame", "h225.ras.rspframe", FT_FRAMENUM, BASE_NONE,
797     NULL, 0, NULL, HFILL }},
798
799   { &hf_h225_ras_dup,
800     { "Duplicate RAS Message", "h225.ras.dup", FT_UINT32, BASE_DEC,
801     NULL, 0, NULL, HFILL }},
802
803   { &hf_h225_ras_deltatime,
804     { "RAS Service Response Time", "h225.ras.timedelta", FT_RELATIVE_TIME, BASE_NONE,
805     NULL, 0, "Timedelta between RAS-Request and RAS-Response", HFILL }},
806
807   { &hf_h225_debug_dissector_try_string,
808     { "*** DEBUG dissector_try_string", "h225.debug.dissector_try_string", FT_STRING, BASE_NONE,
809     NULL, 0, NULL, HFILL }},
810
811 #include "packet-h225-hfarr.c"
812   };
813
814   /* List of subtrees */
815   static gint *ett[] = {
816     &ett_h225,
817 #include "packet-h225-ettarr.c"
818   };
819
820   static tap_param h225_stat_params[] = {
821     { PARAM_FILTER, "filter", "Filter", NULL, TRUE }
822   };
823
824   static stat_tap_table_ui h225_stat_table = {
825     REGISTER_STAT_GROUP_TELEPHONY,
826     "H.225",
827     PFNAME,
828     "h225,counter",
829     h225_stat_init,
830     h225_stat_packet,
831     h225_stat_reset,
832     NULL,
833     NULL,
834     sizeof(h225_stat_fields)/sizeof(stat_tap_table_item), h225_stat_fields,
835     sizeof(h225_stat_params)/sizeof(tap_param), h225_stat_params,
836     NULL,
837     0
838   };
839
840   module_t *h225_module;
841   int i, proto_h225_ras;
842
843   /* Register protocol */
844   proto_h225 = proto_register_protocol(PNAME, PSNAME, PFNAME);
845
846   /* Create a "fake" protocol to get proper display strings for SRT dialogs */
847   proto_h225_ras = proto_register_protocol("H.225 RAS", "H.225 RAS", "h225_ras");
848
849   /* Register fields and subtrees */
850   proto_register_field_array(proto_h225, hf, array_length(hf));
851   proto_register_subtree_array(ett, array_length(ett));
852
853   h225_module = prefs_register_protocol(proto_h225, proto_reg_handoff_h225);
854   prefs_register_uint_preference(h225_module, "tls.port",
855     "H.225 TLS Port",
856     "H.225 Server TLS Port",
857     10, &h225_tls_port);
858   prefs_register_bool_preference(h225_module, "reassembly",
859     "Reassemble H.225 messages spanning multiple TCP segments",
860     "Whether the H.225 dissector should reassemble messages spanning multiple TCP segments."
861     " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
862     &h225_reassembly);
863   prefs_register_bool_preference(h225_module, "h245_in_tree",
864     "Display tunnelled H.245 inside H.225.0 tree",
865     "ON - display tunnelled H.245 inside H.225.0 tree, OFF - display tunnelled H.245 in root tree after H.225.0",
866     &h225_h245_in_tree);
867   prefs_register_bool_preference(h225_module, "tp_in_tree",
868     "Display tunnelled protocols inside H.225.0 tree",
869     "ON - display tunnelled protocols inside H.225.0 tree, OFF - display tunnelled protocols in root tree after H.225.0",
870     &h225_tp_in_tree);
871
872   register_dissector(PFNAME, dissect_h225_H323UserInformation, proto_h225);
873   register_dissector("h323ui",dissect_h225_H323UserInformation, proto_h225);
874   h225ras_handle = register_dissector("h225.ras", dissect_h225_h225_RasMessage, proto_h225);
875
876   nsp_object_dissector_table = register_dissector_table("h225.nsp.object", "H.225 NonStandardParameter Object", proto_h225, FT_STRING, BASE_NONE);
877   nsp_h221_dissector_table = register_dissector_table("h225.nsp.h221", "H.225 NonStandardParameter h221", proto_h225, FT_UINT32, BASE_HEX);
878   tp_dissector_table = register_dissector_table("h225.tp", "H.225 Tunnelled Protocol", proto_h225, FT_STRING, BASE_NONE);
879   gef_name_dissector_table = register_dissector_table("h225.gef.name", "H.225 Generic Extensible Framework Name", proto_h225, FT_STRING, BASE_NONE);
880   gef_content_dissector_table = register_dissector_table("h225.gef.content", "H.225 Generic Extensible Framework Content", proto_h225, FT_STRING, BASE_NONE);
881
882   for(i=0;i<7;i++) {
883     ras_calls[i] = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), h225ras_call_hash, h225ras_call_equal);
884   }
885
886   h225_tap = register_tap(PFNAME);
887
888   register_rtd_table(proto_h225_ras, PFNAME, NUM_RAS_STATS, 1, ras_message_category, h225rassrt_packet, NULL);
889
890   register_stat_tap_table_ui(&h225_stat_table);
891
892   oid_add_from_string("Version 1","0.0.8.2250.0.1");
893   oid_add_from_string("Version 2","0.0.8.2250.0.2");
894   oid_add_from_string("Version 3","0.0.8.2250.0.3");
895   oid_add_from_string("Version 4","0.0.8.2250.0.4");
896   oid_add_from_string("Version 5","0.0.8.2250.0.5");
897   oid_add_from_string("Version 6","0.0.8.2250.0.6");
898 }
899
900
901 /*--- proto_reg_handoff_h225 ---------------------------------------*/
902 void
903 proto_reg_handoff_h225(void)
904 {
905   static gboolean h225_prefs_initialized = FALSE;
906   static dissector_handle_t q931_tpkt_handle;
907   static guint saved_h225_tls_port;
908
909   if (!h225_prefs_initialized) {
910     dissector_add_uint_range_with_preference("udp.port", UDP_PORT_RAS_RANGE, h225ras_handle);
911
912     h245_handle = find_dissector("h245");
913     h245dg_handle = find_dissector("h245dg");
914     h4501_handle = find_dissector_add_dependency("h4501", proto_h225);
915     data_handle = find_dissector("data");
916     h225_prefs_initialized = TRUE;
917     q931_tpkt_handle = find_dissector("q931.tpkt");
918   } else {
919     ssl_dissector_delete(saved_h225_tls_port, q931_tpkt_handle);
920   }
921
922   saved_h225_tls_port = h225_tls_port;
923   ssl_dissector_add(saved_h225_tls_port, q931_tpkt_handle);
924 }
925
926 static h225_packet_info* create_h225_packet_info(packet_info *pinfo)
927 {
928   h225_packet_info* pi = wmem_new0(pinfo->pool, h225_packet_info);
929
930   pi->msg_type = H225_OTHERS;
931   pi->cs_type = H225_OTHER;
932   pi->msg_tag = -1;
933   pi->reason = -1;
934
935   return pi;
936 }
937
938 /*
939   The following function contains the routines for RAS request/response matching.
940   A RAS response matches with a request, if both messages have the same
941   RequestSequenceNumber, belong to the same IP conversation and belong to the same
942   RAS "category" (e.g. Admission, Registration).
943
944   We use hashtables to access the lists of RAS calls (request/response pairs).
945   We have one hashtable for each RAS category. The hashkeys consist of the
946   non-unique 16-bit RequestSequenceNumber and values representing the conversation.
947
948   In big capture files, we might get different requests with identical keys.
949   These requests aren't necessarily duplicates. They might be valid new requests.
950   At the moment we just use the timedelta between the last valid and the new request
951   to decide if the new request is a duplicate or not. There might be better ways.
952   Two thresholds are defined below.
953
954   However the decision is made, another problem arises. We can't just add those
955   requests to our hashtables. Instead we create lists of RAS calls with identical keys.
956   The hashtables for RAS calls contain now pointers to the first RAS call in a list of
957   RAS calls with identical keys.
958   These lists aren't expected to contain more than 3 items and are usually single item
959   lists. So we don't need an expensive but intelligent way to access these lists
960   (e.g. hashtables). Just walk through such a list.
961 */
962
963 #define THRESHOLD_REPEATED_RESPONDED_CALL 300
964 #define THRESHOLD_REPEATED_NOT_RESPONDED_CALL 1800
965
966 static void ras_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, h225_packet_info *pi)
967 {
968   proto_item *hidden_item;
969   conversation_t* conversation = NULL;
970   h225ras_call_info_key h225ras_call_key;
971   h225ras_call_t *h225ras_call = NULL;
972   nstime_t delta;
973   guint msg_category;
974
975   if(pi->msg_type == H225_RAS && pi->msg_tag < 21) {
976     /* make RAS request/response matching only for tags from 0 to 20 for now */
977
978     msg_category = pi->msg_tag / 3;
979     if(pi->msg_tag % 3 == 0) {    /* Request Message */
980       conversation = find_or_create_conversation(pinfo);
981
982       /* prepare the key data */
983       h225ras_call_key.reqSeqNum = pi->requestSeqNum;
984       h225ras_call_key.conversation = conversation;
985
986       /* look up the request */
987       h225ras_call = find_h225ras_call(&h225ras_call_key ,msg_category);
988
989       if (h225ras_call != NULL) {
990         /* We've seen requests with this reqSeqNum, with the same
991            source and destination, before - do we have
992            *this* request already? */
993         /* Walk through list of ras requests with identical keys */
994         do {
995           if (pinfo->num == h225ras_call->req_num) {
996             /* We have seen this request before -> do nothing */
997             break;
998           }
999
1000           /* if end of list is reached, exit loop and decide if request is duplicate or not. */
1001           if (h225ras_call->next_call == NULL) {
1002             if ( (pinfo->num > h225ras_call->rsp_num && h225ras_call->rsp_num != 0
1003                && pinfo->abs_ts.secs > (h225ras_call->req_time.secs + THRESHOLD_REPEATED_RESPONDED_CALL) )
1004                ||(pinfo->num > h225ras_call->req_num && h225ras_call->rsp_num == 0
1005                && pinfo->abs_ts.secs > (h225ras_call->req_time.secs + THRESHOLD_REPEATED_NOT_RESPONDED_CALL) ) )
1006             {
1007               /* if last request has been responded
1008                  and this request appears after last response (has bigger frame number)
1009                  and last request occurred more than 300 seconds ago,
1010                  or if last request hasn't been responded
1011                  and this request appears after last request (has bigger frame number)
1012                  and last request occurred more than 1800 seconds ago,
1013                  we decide that we have a new request */
1014               /* Append new ras call to list */
1015               h225ras_call = append_h225ras_call(h225ras_call, pinfo, &pi->guid, msg_category);
1016             } else {
1017               /* No, so it's a duplicate request.
1018                  Mark it as such. */
1019               pi->is_duplicate = TRUE;
1020               hidden_item = proto_tree_add_uint(tree, hf_h225_ras_dup, tvb, 0,0, pi->requestSeqNum);
1021               PROTO_ITEM_SET_HIDDEN(hidden_item);
1022             }
1023             break;
1024           }
1025           h225ras_call = h225ras_call->next_call;
1026         } while (h225ras_call != NULL );
1027       }
1028       else {
1029         h225ras_call = new_h225ras_call(&h225ras_call_key, pinfo, &pi->guid, msg_category);
1030       }
1031
1032       /* add link to response frame, if available */
1033       if(h225ras_call && h225ras_call->rsp_num != 0){
1034         proto_item *ti =
1035         proto_tree_add_uint_format(tree, hf_h225_ras_rsp_frame, tvb, 0, 0, h225ras_call->rsp_num,
1036                                      "The response to this request is in frame %u",
1037                                      h225ras_call->rsp_num);
1038         PROTO_ITEM_SET_GENERATED(ti);
1039       }
1040
1041     /* end of request message handling*/
1042     }
1043     else {          /* Confirm or Reject Message */
1044       conversation = find_conversation_pinfo(pinfo, 0);
1045       if (conversation != NULL) {
1046         /* look only for matching request, if
1047            matching conversation is available. */
1048         h225ras_call_key.reqSeqNum = pi->requestSeqNum;
1049         h225ras_call_key.conversation = conversation;
1050         h225ras_call = find_h225ras_call(&h225ras_call_key ,msg_category);
1051         if(h225ras_call) {
1052           /* find matching ras_call in list of ras calls with identical keys */
1053           do {
1054             if (pinfo->num == h225ras_call->rsp_num) {
1055               /* We have seen this response before -> stop now with matching ras call */
1056               break;
1057             }
1058
1059             /* Break when list end is reached */
1060             if(h225ras_call->next_call == NULL) {
1061               break;
1062             }
1063             h225ras_call = h225ras_call->next_call;
1064           } while (h225ras_call != NULL) ;
1065
1066           if (!h225ras_call) {
1067             return;
1068           }
1069
1070           /* if this is an ACF, ARJ or DCF, DRJ, give guid to tap and make it filterable */
1071           if (msg_category == 3 || msg_category == 5) {
1072             pi->guid = h225ras_call->guid;
1073             hidden_item = proto_tree_add_guid(tree, hf_h225_guid, tvb, 0, GUID_LEN, &pi->guid);
1074             PROTO_ITEM_SET_HIDDEN(hidden_item);
1075           }
1076
1077           if (h225ras_call->rsp_num == 0) {
1078             /* We have not yet seen a response to that call, so
1079                this must be the first response; remember its
1080                frame number. */
1081             h225ras_call->rsp_num = pinfo->num;
1082           }
1083           else {
1084             /* We have seen a response to this call - but was it
1085                *this* response? */
1086             if (h225ras_call->rsp_num != pinfo->num) {
1087               /* No, so it's a duplicate response.
1088                  Mark it as such. */
1089               pi->is_duplicate = TRUE;
1090               hidden_item = proto_tree_add_uint(tree, hf_h225_ras_dup, tvb, 0,0, pi->requestSeqNum);
1091               PROTO_ITEM_SET_HIDDEN(hidden_item);
1092             }
1093           }
1094
1095           if(h225ras_call->req_num != 0){
1096             proto_item *ti;
1097             h225ras_call->responded = TRUE;
1098             pi->request_available = TRUE;
1099
1100             /* Indicate the frame to which this is a reply. */
1101             ti = proto_tree_add_uint_format(tree, hf_h225_ras_req_frame, tvb, 0, 0, h225ras_call->req_num,
1102               "This is a response to a request in frame %u", h225ras_call->req_num);
1103             PROTO_ITEM_SET_GENERATED(ti);
1104
1105             /* Calculate RAS Service Response Time */
1106             nstime_delta(&delta, &pinfo->abs_ts, &h225ras_call->req_time);
1107             pi->delta_time = delta; /* give it to tap */
1108
1109             /* display Ras Service Response Time and make it filterable */
1110             ti = proto_tree_add_time(tree, hf_h225_ras_deltatime, tvb, 0, 0, &(pi->delta_time));
1111             PROTO_ITEM_SET_GENERATED(ti);
1112           }
1113         }
1114       }
1115     }
1116   }
1117 }
1118
1119 /*
1120  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1121  *
1122  * Local Variables:
1123  * c-basic-offset: 2
1124  * tab-width: 8
1125  * indent-tabs-mode: nil
1126  * End:
1127  *
1128  * vi: set shiftwidth=2 tabstop=8 expandtab:
1129  * :indentSize=2:tabSize=8:noTabs=true:
1130  */