2 * Routines for H.248/MEGACO packet dissection
6 * Luis Ontanon 2005 - Context and Transaction Tracing
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include <epan/packet.h>
18 #include <epan/exceptions.h>
20 #include <epan/asn1.h>
21 #include <epan/proto_data.h>
22 #include <epan/prefs.h>
23 #include <epan/exported_pdu.h>
24 #include <epan/address_types.h>
25 #include <wsutil/array.h>
26 #include "packet-alcap.h"
27 #include "packet-ber.h"
28 #include "packet-tpkt.h"
29 #include "packet-mtp3.h"
30 #include "packet-h248.h"
32 #define PNAME "H.248 MEGACO"
33 #define PSNAME "H.248"
36 void proto_register_h248(void);
38 /* Initialize the protocol and registered fields */
39 static int proto_h248
;
40 static int hf_248_magic_num
;
41 static int hf_h248_mtpaddress_ni
;
42 static int hf_h248_mtpaddress_pc
;
43 static int hf_h248_pkg_name
;
44 static int hf_248_pkg_param
;
45 static int hf_h248_event_name
;
46 static int hf_h248_signal_name
;
47 static int hf_h248_signal_code
;
48 static int hf_h248_event_code
;
49 static int hf_h248_pkg_bcp_BNCChar_PDU
;
53 static int hf_h248_context_id
;
54 static int hf_h248_term_wild_type
;
55 static int hf_h248_term_wild_level
;
56 static int hf_h248_term_wild_position
;
58 static int hf_h248_no_pkg
;
59 static int hf_h248_no_sig
;
60 static int hf_h248_no_evt
;
61 static int hf_h248_param
;
63 static int hf_h248_serviceChangeReasonStr
;
64 static int hf_h248_transactionId64
;
65 static int hf_h248_context_id64
;
68 static int hf_h248_auditValueReplyV1
;
70 #include "packet-h248-hf.c"
72 /* Initialize the subtree pointers */
74 static int ett_mtpaddress
;
75 static int ett_packagename
;
77 static int ett_wildcard
;
79 static int ett_h248_no_pkg
;
80 static int ett_h248_no_sig
;
81 static int ett_h248_no_evt
;
85 static gcp_hf_ett_t h248_arrel
;
87 static int exported_pdu_tap
= -1;
90 #include "packet-h248-ett.c"
92 static expert_field ei_h248_errored_command
;
93 static expert_field ei_h248_transactionId64
;
94 static expert_field ei_h248_context_id64
;
95 static expert_field ei_h248_octet_string_expected
;
97 static dissector_table_t subdissector_table
;
99 static int ss7pc_address_type
= -1;
101 /* Gateway Control Protocol -- Context Tracking */
103 const value_string gcp_cmd_type
[] = {
104 { GCP_CMD_NONE
, "NoCommand"},
105 { GCP_CMD_ADD_REQ
, "addReq"},
106 { GCP_CMD_MOVE_REQ
, "moveReq"},
107 { GCP_CMD_MOD_REQ
, "modReq"},
108 { GCP_CMD_SUB_REQ
, "subtractReq"},
109 { GCP_CMD_AUDITCAP_REQ
, "auditCapRequest"},
110 { GCP_CMD_AUDITVAL_REQ
, "auditValueRequest"},
111 { GCP_CMD_NOTIFY_REQ
, "notifyReq"},
112 { GCP_CMD_SVCCHG_REQ
, "serviceChangeReq"},
113 { GCP_CMD_TOPOLOGY_REQ
, "topologyReq"},
114 { GCP_CMD_CTX_ATTR_AUDIT_REQ
, "ctxAttrAuditReq"},
115 { GCP_CMD_ADD_REPLY
, "addReply"},
116 { GCP_CMD_MOVE_REPLY
, "moveReply"},
117 { GCP_CMD_MOD_REPLY
, "modReply"},
118 { GCP_CMD_SUB_REPLY
, "subtractReply"},
119 { GCP_CMD_AUDITCAP_REPLY
, "auditCapReply"},
120 { GCP_CMD_AUDITVAL_REPLY
, "auditValReply"},
121 { GCP_CMD_NOTIFY_REPLY
, "notifyReply"},
122 { GCP_CMD_SVCCHG_REPLY
, "serviceChangeReply"},
123 { GCP_CMD_TOPOLOGY_REPLY
, "topologyReply"},
127 const value_string gcp_term_types
[] = {
128 { GCP_TERM_TYPE_AAL1
, "aal1" },
129 { GCP_TERM_TYPE_AAL2
, "aal2" },
130 { GCP_TERM_TYPE_AAL1_STRUCT
, "aal1struct" },
131 { GCP_TERM_TYPE_IP_RTP
, "ipRtp" },
132 { GCP_TERM_TYPE_TDM
, "tdm" },
136 static wmem_tree_t
* gcp_msgs
;
137 static wmem_tree_t
* gcp_trxs
;
138 static wmem_tree_t
* gcp_ctxs_by_trx
;
139 static wmem_tree_t
* gcp_ctxs
;
141 gcp_msg_t
* gcp_msg(packet_info
* pinfo
, int o
, bool keep_persistent_data
) {
143 uint32_t framenum
= (uint32_t)pinfo
->num
;
144 uint32_t offset
= (uint32_t)o
;
145 address
* src
= &(pinfo
->src
);
146 address
* dst
= &(pinfo
->dst
);
150 if (keep_persistent_data
) {
151 wmem_tree_key_t key
[3];
154 key
[0].key
= &(framenum
);
156 key
[1].key
= &offset
;
160 if (( m
= (gcp_msg_t
*)wmem_tree_lookup32_array(gcp_msgs
,key
) )) {
164 m
= wmem_new(wmem_file_scope(), gcp_msg_t
);
165 m
->framenum
= framenum
;
166 m
->frametime
= pinfo
->abs_ts
;
168 m
->committed
= false;
170 wmem_tree_insert32_array(gcp_msgs
,key
,m
);
173 m
= wmem_new0(pinfo
->pool
, gcp_msg_t
);
174 m
->framenum
= framenum
;
176 m
->committed
= false;
179 if (cmp_address(src
, dst
) < 0) {
187 switch(lo_addr
->type
) {
193 memcpy((uint8_t*)&(m
->hi_addr
),hi_addr
->data
,4);
194 memcpy((uint8_t*)&(m
->lo_addr
),lo_addr
->data
,4);
197 if (lo_addr
->type
== ss7pc_address_type
) {
198 m
->hi_addr
= mtp3_pc_hash((const mtp3_addr_pc_t
*)hi_addr
->data
);
199 m
->lo_addr
= mtp3_pc_hash((const mtp3_addr_pc_t
*)lo_addr
->data
);
202 /* XXX: heuristic and error prone */
203 m
->hi_addr
= g_str_hash(address_to_str(pinfo
->pool
, hi_addr
));
204 m
->lo_addr
= g_str_hash(address_to_str(pinfo
->pool
, lo_addr
));
212 gcp_trx_t
* gcp_trx(gcp_msg_t
* m
,uint32_t t_id
, gcp_trx_type_t type
, packet_info
*pinfo
, bool keep_persistent_data
) {
214 gcp_trx_msg_t
* trxmsg
;
216 if ( !m
) return NULL
;
218 if (keep_persistent_data
) {
221 for ( trxmsg
= m
->trxs
; trxmsg
; trxmsg
= trxmsg
->next
) {
222 if (trxmsg
->trx
&& trxmsg
->trx
->id
== t_id
) {
226 DISSECTOR_ASSERT_NOT_REACHED();
228 wmem_tree_key_t key
[4];
231 key
[0].key
= &(m
->hi_addr
);
233 key
[1].key
= &(m
->lo_addr
);
235 key
[2].key
= &(t_id
);
239 trxmsg
= wmem_new(wmem_file_scope(), gcp_trx_msg_t
);
240 t
= (gcp_trx_t
*)wmem_tree_lookup32_array(gcp_trxs
,key
);
243 t
= wmem_new(wmem_file_scope(), gcp_trx_t
);
251 wmem_tree_insert32_array(gcp_trxs
,key
,t
);
254 /* XXX: request, reply and ack + point to frames where they are */
256 case GCP_TRX_PENDING
:
265 t
= wmem_new(pinfo
->pool
, gcp_trx_t
);
266 trxmsg
= wmem_new(pinfo
->pool
, gcp_trx_msg_t
);
275 DISSECTOR_ASSERT(trxmsg
);
279 trxmsg
->last
= trxmsg
;
282 m
->trxs
->last
= m
->trxs
->last
->next
= trxmsg
;
291 gcp_ctx_t
* gcp_ctx(gcp_msg_t
* m
, gcp_trx_t
* t
, uint32_t c_id
, packet_info
*pinfo
, bool persistent
) {
292 gcp_ctx_t
* context
= NULL
;
293 gcp_ctx_t
** context_p
= NULL
;
295 if ( !m
|| !t
) return NULL
;
299 wmem_tree_key_t ctx_key
[4];
300 wmem_tree_key_t trx_key
[4];
302 ctx_key
[0].length
= 1;
303 ctx_key
[0].key
= &(m
->hi_addr
);
304 ctx_key
[1].length
= 1;
305 ctx_key
[1].key
= &(m
->lo_addr
);
306 ctx_key
[2].length
= 1;
307 ctx_key
[2].key
= &(c_id
);
308 ctx_key
[3].length
= 0;
309 ctx_key
[3].key
= NULL
;
311 trx_key
[0].length
= 1;
312 trx_key
[0].key
= &(m
->hi_addr
);
313 trx_key
[1].length
= 1;
314 trx_key
[1].key
= &(m
->lo_addr
);
315 trx_key
[2].length
= 1;
316 trx_key
[2].key
= &(t
->id
);
317 trx_key
[3].length
= 0;
318 trx_key
[3].key
= NULL
;
321 if (( context
= (gcp_ctx_t
*)wmem_tree_lookup32_array(gcp_ctxs_by_trx
,trx_key
) )) {
323 } if ((context_p
= (gcp_ctx_t
**)wmem_tree_lookup32_array(gcp_ctxs
,ctx_key
))) {
324 context
= *context_p
;
327 if (context
->initial
->framenum
<= m
->framenum
) {
330 } while(( context
= context
->prev
));
332 DISSECTOR_ASSERT(! "a context should exist");
335 if (c_id
== CHOOSE_CONTEXT
) {
336 if (! ( context
= (gcp_ctx_t
*)wmem_tree_lookup32_array(gcp_ctxs_by_trx
,trx_key
))) {
337 context
= wmem_new(wmem_file_scope(), gcp_ctx_t
);
338 context
->initial
= m
;
339 context
->cmds
= NULL
;
341 context
->terms
.last
= &(context
->terms
);
342 context
->terms
.next
= NULL
;
343 context
->terms
.term
= NULL
;
345 wmem_tree_insert32_array(gcp_ctxs_by_trx
,trx_key
,context
);
348 if (( context
= (gcp_ctx_t
*)wmem_tree_lookup32_array(gcp_ctxs_by_trx
,trx_key
) )) {
349 if (( context_p
= (gcp_ctx_t
**)wmem_tree_lookup32_array(gcp_ctxs
,ctx_key
) )) {
350 if (context
!= *context_p
) {
351 if(context
->id
!= CHOOSE_CONTEXT
) {
352 context
= wmem_new(wmem_file_scope(), gcp_ctx_t
);
354 context
->initial
= m
;
356 context
->cmds
= NULL
;
357 context
->terms
.last
= &(context
->terms
);
358 context
->terms
.next
= NULL
;
359 context
->terms
.term
= NULL
;
361 context
->prev
= *context_p
;
362 *context_p
= context
;
365 context_p
= wmem_new(wmem_file_scope(), gcp_ctx_t
*);
366 *context_p
= context
;
367 context
->initial
= m
;
369 wmem_tree_insert32_array(gcp_ctxs
,ctx_key
,context_p
);
371 } else if (! ( context_p
= (gcp_ctx_t
**)wmem_tree_lookup32_array(gcp_ctxs
,ctx_key
) )) {
372 context
= wmem_new(wmem_file_scope(), gcp_ctx_t
);
373 context
->initial
= m
;
375 context
->cmds
= NULL
;
376 context
->terms
.last
= &(context
->terms
);
377 context
->terms
.next
= NULL
;
378 context
->terms
.term
= NULL
;
380 context_p
= wmem_new(wmem_file_scope(), gcp_ctx_t
*);
381 *context_p
= context
;
382 wmem_tree_insert32_array(gcp_ctxs
,ctx_key
,context_p
);
384 context
= *context_p
;
389 context
= wmem_new(pinfo
->pool
, gcp_ctx_t
);
390 context
->initial
= m
;
391 context
->cmds
= NULL
;
393 context
->terms
.last
= &(context
->terms
);
394 context
->terms
.next
= NULL
;
395 context
->terms
.term
= NULL
;
401 gcp_cmd_t
* gcp_cmd(gcp_msg_t
* m
, gcp_trx_t
* t
, gcp_ctx_t
* c
, gcp_cmd_type_t type
, unsigned offset
, packet_info
*pinfo
, bool persistent
) {
403 gcp_cmd_msg_t
* cmdtrx
;
404 gcp_cmd_msg_t
* cmdctx
;
406 if ( !m
|| !t
|| !c
) return NULL
;
410 DISSECTOR_ASSERT(t
->cmds
!= NULL
);
412 for (cmdctx
= t
->cmds
; cmdctx
; cmdctx
= cmdctx
->next
) {
414 if (cmd
->msg
== m
&& cmd
->offset
== offset
) {
419 DISSECTOR_ASSERT(!"called for a command that does not exist!");
423 cmd
= wmem_new(wmem_file_scope(), gcp_cmd_t
);
424 cmdtrx
= wmem_new(wmem_file_scope(), gcp_cmd_msg_t
);
425 cmdctx
= wmem_new(wmem_file_scope(), gcp_cmd_msg_t
);
428 cmd
= wmem_new(pinfo
->pool
, gcp_cmd_t
);
429 cmdtrx
= wmem_new(pinfo
->pool
, gcp_cmd_msg_t
);
430 cmdctx
= wmem_new(pinfo
->pool
, gcp_cmd_msg_t
);
434 cmd
->offset
= offset
;
435 cmd
->terms
.term
= NULL
;
436 cmd
->terms
.next
= NULL
;
437 cmd
->terms
.last
= &(cmd
->terms
);
440 if ((type
!= GCP_CMD_NONE
) && (!persistent
)){
441 cmd
->str
= val_to_str_const(type
, gcp_cmd_type
, "Unknown");
447 cmdctx
->cmd
= cmdtrx
->cmd
= cmd
;
448 cmdctx
->next
= cmdtrx
->next
= NULL
;
449 cmdctx
->last
= cmdtrx
->last
= NULL
;
452 t
->cmds
->last
->next
= cmdtrx
;
453 t
->cmds
->last
= cmdtrx
;
456 t
->cmds
->last
= cmdtrx
;
460 c
->cmds
->last
->next
= cmdctx
;
461 c
->cmds
->last
= cmdctx
;
464 c
->cmds
->last
= cmdctx
;
470 gcp_term_t
* gcp_cmd_add_term(gcp_msg_t
* m
, gcp_trx_t
* tr
, gcp_cmd_t
* c
, gcp_term_t
* t
, gcp_wildcard_t wildcard
, packet_info
*pinfo
, bool persistent
) {
474 static gcp_term_t all_terms
= {"$",(const uint8_t*)"",1,GCP_TERM_TYPE_UNKNOWN
,NULL
,NULL
,NULL
};
476 if ( !c
) return NULL
;
478 if ( wildcard
== GCP_WILDCARD_CHOOSE
) {
483 if ( c
->msg
->committed
) {
484 if (wildcard
== GCP_WILDCARD_ALL
) {
485 for (ct
= c
->ctx
->terms
.next
; ct
; ct
= ct
->next
) {
486 /* XXX not handling more wildcards in one msg */
487 if ( ct
->term
->start
== m
) {
493 for (ct
= c
->ctx
->terms
.next
; ct
; ct
= ct
->next
) {
494 if ( g_str_equal(ct
->term
->str
,t
->str
) ) {
502 for (ct
= c
->ctx
->terms
.next
; ct
; ct
= ct
->next
) {
503 if ( g_str_equal(ct
->term
->str
,t
->str
) || ct
->term
->start
== m
) {
510 if (wildcard
== GCP_WILDCARD_ALL
) {
511 ct
= wmem_new(wmem_file_scope(), gcp_terms_t
);
513 ct
->term
= wmem_new0(wmem_file_scope(), gcp_term_t
);
517 ct
->term
->buffer
= NULL
;
520 c
->terms
.last
= c
->terms
.last
->next
= ct
;
522 ct2
= wmem_new0(wmem_file_scope(), gcp_terms_t
);
523 ct2
->term
= ct
->term
;
525 c
->ctx
->terms
.last
->next
= ct2
;
526 c
->ctx
->terms
.last
= ct2
;
530 for (ct
= c
->ctx
->terms
.next
; ct
; ct
= ct
->next
) {
531 /* XXX not handling more wildcards in one msg */
532 if ( ct
->term
->buffer
== NULL
&& tr
->cmds
->cmd
->msg
== ct
->term
->start
) {
533 ct
->term
->str
= wmem_strdup(wmem_file_scope(), t
->str
);
534 ct
->term
->buffer
= (const uint8_t *)wmem_memdup(wmem_file_scope(), t
->buffer
,t
->len
);
535 ct
->term
->len
= t
->len
;
537 ct2
= wmem_new0(wmem_file_scope(), gcp_terms_t
);
538 ct2
->term
= ct
->term
;
540 c
->terms
.last
= c
->terms
.last
->next
= ct2
;
545 if ( g_str_equal(ct
->term
->str
,t
->str
) ) {
546 ct2
= wmem_new0(wmem_file_scope(), gcp_terms_t
);
547 ct2
->term
= ct
->term
;
549 c
->terms
.last
= c
->terms
.last
->next
= ct2
;
555 ct
= wmem_new(wmem_file_scope(), gcp_terms_t
);
557 ct
->term
= wmem_new0(wmem_file_scope(), gcp_term_t
);
560 ct
->term
->str
= wmem_strdup(wmem_file_scope(), t
->str
);
561 ct
->term
->buffer
= (const uint8_t *)wmem_memdup(wmem_file_scope(), t
->buffer
,t
->len
);
562 ct
->term
->len
= t
->len
;
564 ct2
= wmem_new0(wmem_file_scope(), gcp_terms_t
);
565 ct2
->term
= ct
->term
;
567 c
->terms
.last
= c
->terms
.last
->next
= ct2
;
569 ct2
= wmem_new0(wmem_file_scope(), gcp_terms_t
);
570 ct2
->term
= ct
->term
;
572 c
->ctx
->terms
.last
= c
->ctx
->terms
.last
->next
= ct2
;
577 ct2
= wmem_new0(wmem_file_scope(), gcp_terms_t
);
578 ct2
->term
= ct
->term
;
580 c
->terms
.last
= c
->terms
.last
->next
= ct2
;
584 DISSECTOR_ASSERT_NOT_REACHED();
587 ct
= wmem_new(pinfo
->pool
, gcp_terms_t
);
590 c
->terms
.last
= c
->terms
.last
->next
= ct
;
597 static const char* gcp_cmd_to_str(gcp_cmd_t
* c
, wmem_allocator_t
*scope
, bool persistent
) {
601 if ( !c
) return "-";
606 case GCP_CMD_ADD_REQ
:
609 case GCP_CMD_MOVE_REQ
:
612 case GCP_CMD_MOD_REQ
:
615 case GCP_CMD_SUB_REQ
:
618 case GCP_CMD_AUDITCAP_REQ
:
621 case GCP_CMD_AUDITVAL_REQ
:
624 case GCP_CMD_NOTIFY_REQ
:
627 case GCP_CMD_SVCCHG_REQ
:
630 case GCP_CMD_TOPOLOGY_REQ
:
633 case GCP_CMD_CTX_ATTR_AUDIT_REQ
:
634 s
= "CtxAttribAuditReq {";
636 case GCP_CMD_ADD_REPLY
:
639 case GCP_CMD_MOVE_REPLY
:
642 case GCP_CMD_MOD_REPLY
:
645 case GCP_CMD_SUB_REPLY
:
648 case GCP_CMD_AUDITCAP_REPLY
:
649 s
= "AuditCapReply {";
651 case GCP_CMD_AUDITVAL_REPLY
:
652 s
= "AuditValReply {";
654 case GCP_CMD_NOTIFY_REPLY
:
657 case GCP_CMD_SVCCHG_REPLY
:
660 case GCP_CMD_TOPOLOGY_REPLY
:
661 s
= "TopologyReply {";
666 case GCP_CMD_OTHER_REQ
:
674 for (term
= c
->terms
.next
; term
; term
= term
->next
) {
675 s
= wmem_strdup_printf(scope
, "%s %s", s
, term
->term
->str
);
679 s
= wmem_strdup_printf(scope
, "%s Error=%i", s
, c
->error
);
682 s
= wmem_strdup_printf(scope
, "%s }", s
);
685 /* FIXME: this method has a side-effect but is buried deep within an apparently side-effect free string helper */
686 if (! c
->str
) c
->str
= wmem_strdup(wmem_file_scope(), s
);
694 static const char * gcp_trx_to_str(gcp_msg_t
* m
, gcp_trx_t
* t
, wmem_allocator_t
*scope
, bool persistent
) {
698 if ( !m
|| !t
) return "-";
700 s
= wmem_strbuf_new(scope
, NULL
);
701 wmem_strbuf_append_printf(s
, "T %x { ", t
->id
);
704 if (t
->cmds
->cmd
->ctx
) {
705 wmem_strbuf_append_printf(s
, " C %x {", t
->cmds
->cmd
->ctx
->id
);
707 for (c
= t
->cmds
; c
; c
= c
->next
) {
708 if (c
->cmd
->msg
== m
) {
709 wmem_strbuf_append_c(s
, ' ');
710 wmem_strbuf_append(s
, gcp_cmd_to_str(c
->cmd
, scope
, persistent
));
714 wmem_strbuf_append(s
, " }");
719 wmem_strbuf_append_printf(s
, " Error=%i", t
->error
);
722 wmem_strbuf_append(s
, " }");
724 return wmem_strbuf_finalize(s
);
727 const char* gcp_msg_to_str(gcp_msg_t
* m
, wmem_allocator_t
*scope
, bool persistent
) {
731 if ( !m
) return "-";
733 s
= wmem_strbuf_new(scope
, NULL
);
734 for (t
= m
->trxs
; t
; t
= t
->next
) {
735 wmem_strbuf_append_c(s
, ' ');
736 wmem_strbuf_append(s
, gcp_trx_to_str(m
, t
->trx
, scope
, persistent
));
739 return wmem_strbuf_finalize(s
);
742 typedef struct _gcp_ctxs_t
{
743 struct _gcp_ctx_t
* ctx
;
744 struct _gcp_ctxs_t
* next
;
747 /*static const char* trx_types[] = {"None","Req","Reply","Pending","Ack"};*/
749 void gcp_analyze_msg(proto_tree
* gcp_tree
, packet_info
* pinfo
, tvbuff_t
* gcp_tvb
, gcp_msg_t
* m
, gcp_hf_ett_t
* ids
, expert_field
* command_err
) {
751 gcp_ctxs_t contexts
= {NULL
,NULL
};
752 gcp_ctxs_t
* ctx_node
;
756 for (t
= m
->trxs
; t
; t
= t
->next
) {
757 for (c
= t
->trx
->cmds
; c
; c
= c
->next
) {
758 gcp_ctx_t
* ctx
= c
->cmd
->ctx
;
760 for (ctx_node
= contexts
.next
; ctx_node
; ctx_node
= ctx_node
->next
) {
761 if (ctx_node
->ctx
->id
== ctx
->id
) {
767 ctx_node
= wmem_new(pinfo
->pool
, gcp_ctxs_t
);
769 ctx_node
->next
= contexts
.next
;
770 contexts
.next
= ctx_node
;
775 for (ctx_node
= contexts
.next
; ctx_node
; ctx_node
= ctx_node
->next
) {
776 gcp_ctx_t
* ctx
= ctx_node
->ctx
;
777 proto_item
* ctx_item
= proto_tree_add_uint(gcp_tree
,ids
->hf
.ctx
,gcp_tvb
,0,0,ctx
->id
);
778 proto_tree
* ctx_tree
= proto_item_add_subtree(ctx_item
,ids
->ett
.ctx
);
779 gcp_terms_t
*ctx_term
;
781 proto_item_set_generated(ctx_item
);
784 proto_tree
* history_tree
= proto_tree_add_subtree(ctx_tree
,gcp_tvb
,0,0,ids
->ett
.ctx_cmds
,NULL
,"[ Command History ]");
786 for (c
= ctx
->cmds
; c
; c
= c
->next
) {
787 proto_item
* cmd_item
= proto_tree_add_uint(history_tree
,ids
->hf
.ctx_cmd
,gcp_tvb
,0,0,c
->cmd
->msg
->framenum
);
788 if (c
->cmd
->str
) proto_item_append_text(cmd_item
," %s ",c
->cmd
->str
);
789 proto_item_set_generated(cmd_item
);
791 expert_add_info(pinfo
, cmd_item
, command_err
);
796 if (( ctx_term
= ctx
->terms
.next
)) {
797 proto_tree
* terms_tree
= proto_tree_add_subtree(ctx_tree
,gcp_tvb
,0,0,ids
->ett
.ctx_terms
,NULL
,"[ Terminations Used ]");
799 for (; ctx_term
; ctx_term
= ctx_term
->next
) {
800 if ( ctx_term
->term
&& ctx_term
->term
->str
) {
801 proto_item
* pi
= proto_tree_add_string(terms_tree
,ids
->hf
.ctx_term
,gcp_tvb
,0,0,ctx_term
->term
->str
);
802 proto_tree
* term_tree
= proto_item_add_subtree(pi
,ids
->ett
.ctx_term
);
804 proto_item_set_generated(pi
);
806 if (ctx_term
->term
->type
) {
807 pi
= proto_tree_add_uint(term_tree
,ids
->hf
.ctx_term_type
,gcp_tvb
,0,0,ctx_term
->term
->type
);
808 proto_item_set_generated(pi
);
811 if (ctx_term
->term
->bir
) {
812 pi
= proto_tree_add_string(term_tree
,ids
->hf
.ctx_term_bir
,gcp_tvb
,0,0,ctx_term
->term
->bir
);
813 proto_item_set_generated(pi
);
816 if (ctx_term
->term
->nsap
) {
817 pi
= proto_tree_add_string(term_tree
,ids
->hf
.ctx_term_nsap
,gcp_tvb
,0,0,ctx_term
->term
->nsap
);
818 proto_item_set_generated(pi
);
821 if (ctx_term
->term
->bir
&& ctx_term
->term
->nsap
) {
822 char* tmp_key
= wmem_strdup_printf(pinfo
->pool
, "%s:%s",ctx_term
->term
->nsap
,ctx_term
->term
->bir
);
823 char* key
= g_ascii_strdown(tmp_key
, -1);
824 alcap_tree_from_bearer_key(term_tree
, gcp_tvb
, pinfo
, key
);
833 /* END Gateway Control Protocol -- Context Tracking */
835 #define H248_PORT 2945
836 static bool keep_persistent_data
;
837 static bool h248_desegment
= true;
841 static proto_tree
*h248_tree
;
843 static dissector_handle_t h248_handle
;
844 static dissector_handle_t h248_term_handle
;
845 static dissector_handle_t h248_tpkt_handle
;
847 /* Forward declarations */
848 static int dissect_h248_ServiceChangeReasonStr(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
);
851 static int dissect_h248_AuditReplyV1(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
);
853 static int dissect_h248_EventParameterV1(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
);
854 static int dissect_h248_SigParameterV1(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
);
855 static int dissect_h248_SigParamValueV1(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index
);
858 static const value_string context_id_type
[] = {
859 {NULL_CONTEXT
,"0 (Null Context)"},
860 {CHOOSE_CONTEXT
,"$ (Choose Context)"},
861 {ALL_CONTEXTS
,"* (All Contexts)"},
866 /* the following value_strings are used to build defalut packages.
867 To add additional detail to a package, build a register a h248_package_t structure
870 static const value_string base_package_name_vals
[] = {
871 { 0x0000, "Media stream properties H.248.1 Annex C" },
872 { 0x0001, "Generic H.248.1 Annex E" },
873 { 0x0002, "root H.248.1 Annex E" },
874 { 0x0003, "tonegen H.248.1 Annex E" },
875 { 0x0004, "tonedet H.248.1 Annex E" },
876 { 0x0005, "dg H.248.1 Annex E" },
877 { 0x0006, "dd H.248.1 Annex E" },
878 { 0x0007, "cg H.248.1 Annex E" },
879 { 0x0008, "cd H.248.1 Annex E" },
880 { 0x0009, "al H.248.1 Annex E" },
881 { 0x000a, "ct H.248.1 Annex E" },
882 { 0x000b, "nt H.248.1 Annex E" },
883 { 0x000c, "rtp H.248.1 Annex E" },
884 { 0x000d, "tdmc H.248.1 Annex E" },
885 { 0x000e, "ftmd H.248.1 Annex E" },
886 { 0x000f, "txc H.248.2" }, /* H.248.2 */
887 { 0x0010, "txp H.248.2" },
888 { 0x0011, "ctyp H.248.2" },
889 { 0x0012, "fax H.248.2" },
890 { 0x0013, "ipfax H.248.2" },
891 { 0x0014, "dis H.248.3" }, /* H.248.3 */
892 { 0x0015, "key H.248.3" },
893 { 0x0016, "kp H.248.3" },
894 { 0x0017, "labelkey H.248.3" },
895 { 0x0018, "kf H.248.3" },
896 { 0x0019, "ind H.248.3" },
897 { 0x001a, "ks H.248.3" },
898 { 0x001b, "anci H.248.3" },
899 { 0x001c, "dtd H.248.6" }, /* H.248.6 */
900 { 0x001d, "an H.248.7" }, /* H.248.7 */
901 { 0x001e, "Bearer Characteristics Q.1950 Annex A" }, /* Q.1950 Annex A */
902 { 0x001f, "Bearer Network Connection Cut Q.1950 Annex A" },
903 { 0x0020, "Reuse Idle Q.1950 Annex A" },
904 { 0x0021, "Generic Bearer Connection Q.1950 Annex A" },
905 { 0x0022, "Bearer Control Tunnelling Q.1950 Annex A" },
906 { 0x0023, "Basic Call Progress Tones Q.1950 Annex A" },
907 { 0x0024, "Expanded Call Progress Tones Q.1950 Annex A" },
908 { 0x0025, "Basic Services Tones Q.1950 Annex A" },
909 { 0x0026, "Expanded Services Tones Q.1950 Annex A" },
910 { 0x0027, "Intrusion Tones Q.1950 Annex A" },
911 { 0x0028, "Business Tones Q.1950 Annex A" },
912 { 0x0029, "Media Gateway Resource Congestion Handling H.248.10" }, /* H.248.10 */
913 { 0x002a, "H245 package H.248.12" }, /* H.248.12 */
914 { 0x002b, "H323 bearer control package H.248.12" }, /* H.248.12 */
915 { 0x002c, "H324 package H.248.12" }, /* H.248.12 */
916 { 0x002d, "H245 command package H.248.12" }, /* H.248.12 */
917 { 0x002e, "H245 indication package H.248.12" }, /* H.248.12 */
918 { 0x002f, "3G User Plane" }, /* 3GPP TS 29.232 v4.1.0 */
919 { 0x0030, "3G Circuit Switched Data" },
920 { 0x0031, "3G TFO Control" },
921 { 0x0032, "3G Expanded Call Progress Tones" },
922 { 0x0033, "Advanced Audio Server (AAS Base)" }, /* H.248.9 */
923 { 0x0034, "AAS Digit Collection" }, /* H.248.9 */
924 { 0x0035, "AAS Recording" }, /* H.248.9 */
925 { 0x0036, "AAS Segment Management" }, /* H.248.9 */
926 { 0x0037, "Quality Alert Ceasing" }, /* H.248.13 */
927 { 0x0038, "Conferencing Tones Generation" }, /* H.248.27 */
928 { 0x0039, "Diagnostic Tones Generation" }, /* H.248.27 */
929 { 0x003a, "Carrier Tones Generation Package H.248.23" }, /* H.248.27 */
930 { 0x003b, "Enhanced Alerting Package H.248.23" }, /* H.248.23 */
931 { 0x003c, "Analog Display Signalling Package H.248.23" }, /* H.248.23 */
932 { 0x003d, "Multi-Frequency Tone Generation Package H.248.24" }, /* H.248.24 */
933 { 0x003e, "H.248.23Multi-Frequency Tone Detection Package H.248.24" }, /* H.248.24 */
934 { 0x003f, "Basic CAS Package H.248.25" }, /* H.248.25 */
935 { 0x0040, "Robbed Bit Signalling Package H.248.25" }, /* H.248.25 */
936 { 0x0041, "Operator Services and Emergency Services Package H.248.25" },
937 { 0x0042, "Operator Services Extension Package H.248.25" },
938 { 0x0043, "Extended Analog Line Supervision Package H.248.26" },
939 { 0x0044, "Automatic Metering Package H.248.26" },
940 { 0x0045, "Inactivity Timer Package H.248.14" },
941 { 0x0046, "3G Modification of Link Characteristics Bearer Capability" }, /* 3GPP TS 29.232 v4.4.0 */
942 { 0x0047, "Base Announcement Syntax H.248.9" },
943 { 0x0048, "Voice Variable Syntax H.248.9" },
944 { 0x0049, "Announcement Set Syntax H.248.9" },
945 { 0x004a, "Phrase Variable Syntax H.248.9" },
946 { 0x004b, "Basic NAS package" },
947 { 0x004c, "NAS incoming package" },
948 { 0x004d, "NAS outgoing package" },
949 { 0x004e, "NAS control package" },
950 { 0x004f, "NAS root package" },
951 { 0x0050, "Profile Handling Package H.248.18" },
952 { 0x0051, "Media Gateway Overload Control Package H.248.11" },
953 { 0x0052, "Extended DTMF Detection Package H.248.16" },
954 { 0x0053, "Quiet Termination Line Test" },
955 { 0x0054, "Loopback Line Test Response" }, /* H.248.17 */
956 { 0x0055, "ITU 404Hz Line Test" }, /* H.248.17 */
957 { 0x0056, "ITU 816Hz Line Test" }, /* H.248.17 */
958 { 0x0057, "ITU 1020Hz Line Test" }, /* H.248.17 */
959 { 0x0058, "ITU 2100Hz Disable Tone Line Test" }, /* H.248.17 */
960 { 0x0059, "ITU 2100Hz Disable Echo Canceller Tone Line Test" }, /* H.248.17 */
961 { 0x005a, "ITU 2804Hz Tone Line Test" }, /* H.248.17 */
962 { 0x005b, "ITU Noise Test Tone Line Test" }, /* H.248.17 */
963 { 0x005c, "ITU Digital Pseudo Random Test Line Test" }, /* H.248.17 */
964 { 0x005d, "ITU ATME No.2 Test Line Response" }, /* H.248.17 */
965 { 0x005e, "ANSI 1004Hz Test Tone Line Test" }, /* H.248.17 */
966 { 0x005f, "ANSI Test Responder Line Test" }, /* H.248.17 */
967 { 0x0060, "ANSI 2225Hz Test Progress Tone Line Test" }, /* H.248.17 */
968 { 0x0061, "ANSI Digital Test Signal Line Test" }, /* H.248.17 */
969 { 0x0062, "ANSI Inverting Loopback Line Test Response" }, /* H.248.17 */
970 { 0x0063, "Extended H.324 Packages H.248.12 Annex A" },
971 { 0x0064, "Extended H.245 Command Package H.248.12 Annex A" },
972 { 0x0065, "Extended H.245 Indication Package H.248.12 Annex A" },
973 { 0x0066, "Enhanced DTMF Detection Package H.248.16" },
974 { 0x0067, "Connection Group Identity Package Q.1950 Annex E" },
975 { 0x0068, "CTM Text Transport 3GPP TS 29.232 v5.2.0" },
976 { 0x0069, "SPNE Control Package Q.115.0" },
977 { 0x006a, "Semi-permanent Connection Package H.248.21" },
978 { 0x006b, "Shared Risk Group Package H.248.22" },
979 { 0x006c, "isuptn Annex B of ITU-T Rec. J.171" },
980 { 0x006d, "Basic CAS Addressing Package H.248.25" },
981 { 0x006e, "Floor Control Package H.248.19" },
982 { 0x006f, "Indication of Being Viewed Package H.248.19" },
983 { 0x0070, "Volume Control Package H.248.19" },
984 { 0x0071, "UNASSIGNED" },
985 { 0x0072, "Volume Detection Package H.248.19" },
986 { 0x0073, "Volume Level Mixing Package H.248.19" },
987 { 0x0074, "Mixing Volume Level Control Package H.248.19" },
988 { 0x0075, "Voice Activated Video Switch Package H.248.19" },
989 { 0x0076, "Lecture Video Mode Package H.248.19" },
990 { 0x0077, "Contributing Video Source Package H.248.19" },
991 { 0x0078, "Video Window Package H.248.19" },
992 { 0x0079, "Tiled Window Package H.248.19" },
993 { 0x007a, "Adaptive Jitter Buffer Package H.248.31" },
994 { 0x007b, "International CAS Package H.248.28" },
995 { 0x007c, "CAS Blocking Package H.248.28" },
996 { 0x007d, "International CAS Compelled Package H.248.29" },
997 { 0x007e, "International CAS Compelled with Overlap Package H.248.29" },
998 { 0x007f, "International CAS Compelled with End-to-end Package H.248.29" },
999 { 0x0080, "RTCP XR Package H.248.30" },
1000 { 0x0081, "RTCP XR Burst Metrics Package H.248.30" },
1001 { 0x0082, "threegcsden 3G Circuit Switched Data" }, /* 3GPP TS 29.232 v5.6.0 */
1002 { 0x0083, "threegiptra 3G Circuit Switched Data" }, /* 3GPP TS 29.232 v5.6.0 */
1003 { 0x0084, "threegflex 3G Circuit Switched Data" }, /* 3GPP TS 29.232 v5.6.0 */
1004 { 0x0085, "H.248 PCMSB" },
1005 { 0x008a, "TIPHON Extended H.248/MEGACO Package" }, /* ETSI specification TS 101 3 */
1006 { 0x008b, "Differentiated Services Package" }, /* Annex A of ETSI TS 102 333 */
1007 { 0x008c, "Gate Management Package" }, /* Annex B of ETSI TS 102 333 */
1008 { 0x008d, "Traffic Management Package" }, /* Annex C of ETSI TS 102 333 */
1009 { 0x008e, "Gate Recovery Information Package" }, /* Annex D of ETSI TS 102 333 */
1010 { 0x008f, "NAT Traversal Package" }, /* Annex E of ETSI TS 102 333 */
1011 { 0x0090, "MPLS Package" }, /* Annex F of ETSI TS 102 333 */
1012 { 0x0091, "VLAN Package" }, /* Annex G of ETSI TS 102 333 */
1013 { 0x0092, "Detailed Congestion Reporting Package" }, /* H.248.32 */
1014 { 0x0093, "Stimulus Analogue Lines Package" }, /* H.248.34 */
1015 { 0x0094, "icascgen" }, /* H.248.29 Annex B */
1016 { 0x0095, "Coin Operated Phone Control Package" }, /* H.248.35 */
1017 { 0x0096, "Metering Pulse Detection Package" }, /* H.248.26 Amendment 1 */
1018 { 0x0097, "Trace Package" }, /* 3GPP TS 29.232 v6.3.0 */
1019 { 0x0098, "Hanging Termination Package" }, /* H.248.36 */
1020 { 0x0099, "IP NAPT Traversal Package" }, /* H.248.37 */
1021 { 0x009a, "Notification Behaviour Package" }, /* H.248.1v3 */
1022 { 0x009b, "Base Context Package" }, /* H.248.38 */
1023 { 0x009c, "Application Data Inactivity Detection Package" }, /* H.248.40 */
1024 { 0x009d, "Domain Connection Package " }, /* H.248.41 */
1025 { 0x009e, "Digital Circuit Multiplication Equipment Package" }, /* H.248.42 */
1026 { 0x009f, "Multi-level Precedence and Pre-emption Package" }, /* H.248.44 */
1027 { 0x00a0, "MGC Information Package" }, /* H.248.45 */
1028 { 0x00a1, "Text Overlay Package" }, /* H.248.19 Amendment 1 */
1029 { 0x00a2, "Border and Background Package" }, /* H.248.19 Amendment 1 */
1030 { 0x00a3, "Segmentation Package" }, /* H.248.1v3 */
1031 { 0x00a4, "ETSI notification behaviour package" }, /* ETSI ES 283 039-3 */
1032 { 0x00a5, "ETSI notification rate package" }, /* ETSI ES 283 039-4 */
1033 { 0x00a6, "Automatic Speech Recognition Package" }, /* H.248.9 Amendment 1 */
1034 { 0x00a7, "Set extension to basic syntax for TTS enhancement Package" },/* H.248.9 Amendment 1 */
1035 { 0x00a8, "Advanced audio server base package for TTS enhancement" }, /* H.248.9 Amendment 1 */
1036 { 0x00a9, "Multimedia Play Package" }, /* H.248.9 Amendment 1 */
1037 { 0x00aa, "Floor Status Detection Package" }, /* H.248.19 Amendment 2 */
1038 { 0x00ab, "Floor Control Policy Package" }, /* H.248.19 Amendment 2 */
1039 { 0x00ac, "Address Reporting Package" }, /* H.248.37 Amendment 1 */
1040 { 0x00ad, "Connection Capability Control Package" }, /* H.248.46 */
1041 { 0x00ae, "Statistic Conditional Reporting Package" }, /* H.248.47 Amendment 1 */
1042 { 0x00af, "RTCP HR QoS Statistics Package" }, /* H.248.48 */
1043 { 0x00b0, "Received RTCP XR Package" }, /* H.248.30 (01/2007) */
1044 { 0x00b1, "Received RTCP XR Burst Metrics Package" }, /* H.248.30 (01/2007) */
1045 { 0x00b2, "ASCI Group call package" }, /* 3GPP TS 29.232 v7.4.0 */
1046 { 0x00b3, "Multimedia Recording Package" }, /* H.248.9 Amendment 1 */
1047 { 0x00b4, "H.245 Transport Package" }, /* H.248.12 Amendment 2 */
1048 { 0x00b5, "RTCP Handling package" }, /* H.248.57 */
1049 { 0x00b6, "Gate Management - Outgoing Destination Address/Port Filtering Package" },/* H.248.43 */
1050 { 0x00b7, "Gate Management - Incoming Protocol Filtering Package" }, /* H.248.43 */
1051 { 0x00b8, "Gate Management - Outgoing Protocol Filtering Package" }, /* H.248.43 */
1052 { 0x00b9, "Gate Management - Incoming Filtering Behaviour Package" }, /* H.248.43 */
1053 { 0x00ba, "Gate Management - Outgoing Filtering Behaviour Package" }, /* H.248.43 */
1054 { 0x00bb, "Session Description Protocol RFC Package" }, /* H.248.49 */
1055 { 0x00bc, "Session Description Protocol Capabilities Package" }, /* H.248.49 */
1056 { 0x00bd, "NAT Traversal Toolkit - STUN Base Package" }, /* H.248.50 */
1057 { 0x00be, "NAT Traversal Toolkit - MG STUN Client Package" }, /* H.248.50 */
1058 { 0x00bf, "NAT Traversal Toolkit - MG TURN Client Package" }, /* H.248.50 */
1059 { 0x00c0, "NAT Traversal Toolkit - MGC STUN Client Package" }, /* H.248.50 */
1060 { 0x00c1, "NAT Traversal Toolkit - STUN Information Package" }, /* H.248.50 */
1061 { 0x00c2, "NAT Traversal Toolkit - MG Act-as STUN Server Package" }, /* H.248.50 */
1062 { 0x00c3, "NAT Traversal Toolkit - Originate STUN Continuity Check Package" }, /* H.248.50 */
1063 { 0x00c4, "NAT Traversal Toolkit - MGC Originated STUN Request Package" }, /* H.248.50 */
1064 { 0x00c5, "NAT Traversal Toolkit - RTP NOOP Request Package" }, /* H.248.50 */
1065 { 0x00c6, "Termination Connection Model Package" }, /* H.248.51 */
1066 { 0x00c7, "QoS Class Package" }, /* H.248.52 */
1067 { 0x00c8, "Traffic Policing Statistics Package" }, /* H.248.53 */
1068 { 0x00c9, "Packet Size Package" }, /* H.248.53 */
1069 { 0x00ca, "Pull Mode Package" }, /* H.248.55 */
1070 { 0x00cb, "RTP Application Data Package" }, /* H.248.58 */
1071 { 0x00cc, "Event Timestamp Notification Package" }, /* H.248.59 */
1072 { 0x00cd, "Resource Management Rules Package" }, /* H.248.63 */
1073 { 0x00ce, "Resource Management Configuration Package" }, /* H.248.63 */
1074 { 0x00cf, "Abstract Resource Management Packages" }, /* H.248.63 */
1075 { 0x00d0, "IP layer octets count statistics Package" }, /* H.248.61 */
1076 { 0x00d1, "Content of Communication Identity Package" }, /* H.248.60 */
1077 { 0x00d2, "RSVP extension package" }, /* H.248.65 */
1078 { 0x00d3, "GCP Transport Mode Indication Package" }, /* H.248.67 */
1079 { 0x00d4, "IP Router Package" }, /* H.248.64 */
1080 { 0x00d5, "Media Resource Identification Package" }, /* H.248.66 */
1081 { 0x00d6, "Range Format Support Package" }, /* H.248.66 */
1082 { 0x00d7, "Media Resource Description Expiry Package" }, /* H.248.66 */
1083 { 0x00d8, "Media Block Size Package" }, /* H.248.66 */
1084 { 0x00d9, "RTSP Media Resource Syntax Package" }, /* H.248.66 */
1085 { 0x00da, "RTSP Play Package" }, /* H.248.66 */
1086 { 0x00db, "Signal Pause Package" }, /* H.248.66 */
1087 { 0x00dc, "Data Delivery Speed Adjustme Package" }, /* H.248.66 */
1088 { 0x00dd, "Playback Relative Scale Adjustment Package" }, /* H.248.66 */
1089 { 0x00de, "RTP Information Package" }, /* H.248.66 */
1090 { 0x00df, "RTP Interleaving Package" }, /* H.248.66 */
1091 { 0x00e0, "IP Realm Availability Package" }, /* H.248.41 Amendment 1 */
1092 { 0x00e1, "General IP Header QoS Octet Package" }, /* H.248.52 */
1093 { 0x00e2, "Re-answer Package" }, /* H.248.62 */
1094 { 0x00e3, "3G Interface Type package" }, /* 3GPP TS 29.232 v8.4.0 */
1095 { 0x00e4, "Latch Statistics Package" }, /* H.248.37 */
1096 { 0x00e5, "Floor Control Signalling Package" }, /* H.248.19 Amendment 2 */
1097 { 0x00e6, "Include Participant in Mix Package" }, /* H.248.19 Amendment 2 */
1098 { 0x00e7, "Speaker Reporting Package" }, /* H.248.19 Amendment 2 */
1099 { 0x00e8, "IP Layer Packet Count Statistics Package" }, /* H.248.61 */
1100 { 0x00e9, "Removal of Digits and Tones Package" }, /* H.248.68 */
1101 { 0x00ea, "MSRP Statistics Package" }, /* H.248.69 */
1102 { 0x00eb, "MSRP Connection Status Package" }, /* H.248.69 */
1103 { 0x00ec, "Play Message Package" }, /* H.248.69 */
1104 { 0x00ed, "Delete Stored Message Package" }, /* H.248.69 */
1105 { 0x00ee, "Message Session Information Package" }, /* H.248.69 */
1106 { 0x00ef, "Message Filtering Package" }, /* H.248.69 */
1107 { 0x00f0, "Stored Message Information Package" }, /* H.248.69 */
1108 { 0x00f1, "Record Message Package" }, /* H.248.69 */
1109 { 0x00f2, "Digit Dialling Method Information Package" }, /* H.248.70 */
1110 { 0x00f3, "Digit Dialling Method Information for Extended Digitmap Detection Package" }, /* H.248.70 */
1111 { 0x00f4, "Digit Dialling Method Information for Enhanced Digitmap Detection Package" }, /* H.248.70 */
1112 { 0x00f5, "Received RTCP Package " }, /* H.248.71 */
1113 { 0x00f6, "RTP Cumulative Loss Package" }, /* H.248.71 */
1114 { 0x00f7, "H.245 Transport Package for SPC use" }, /* H.248.72 */
1115 { 0x00f8, "MONA Preference Package" }, /* H.248.72 */
1116 { 0x00f9, "TDM Gain Control Package" }, /* H.248.73 */
1117 { 0x00fa, "Media Start Package" }, /* H.248.74 */
1118 { 0x00fb, "Trim Package" }, /* H.248.74 */
1119 { 0x00fc, "Enhanced Recording Package" }, /* H.248.74 */
1120 { 0x00fd, "Enhanced ASR Package" }, /* H.248.74 */
1121 { 0x00fe, "Enhanced TTS Package" }, /* H.248.74 */
1122 { 0x00ff, "Play Offset Control Package" }, /* H.248.74 */
1123 { 0x0100, "Enhanced DTMF Detection Package" }, /* H.248.9 Revised 2009 */
1124 { 0x0101, "IP Router NAT Package" }, /* H.248.64 */
1125 { 0x0102, "Voice Enrolled Grammar Package" }, /* H.248.74 */
1126 { 0x0103, "Filter Group Package" }, /* H.248.76 */
1127 { 0x0104, "RTCP Source Description Package" }, /* H.248.71 */
1128 { 0x0105, "Speaker Verification and Identification Package" }, /* H.248.74 */
1129 { 0x0106, "Package Identifier Publishing and Application Package" }, /* H.248 */
1130 { 0x0107, "Secure RTP Package " }, /* H.248.77 */
1131 { 0x0108, "MGC Controlled Bearer Level ALG Package" }, /* H.248.78 */
1132 { 0x0109, "Enhanced Revised Offer/Answer SDP Support Package" }, /* H.248.80 */
1133 { 0x010a, "Enhanced SDP Media Capabilities Negotiation Support Package" }, /* H.248.80 */
1134 { 0x8000, "Ericsson IU" },
1135 { 0x8001, "Ericsson UMTS and GSM Circuit" },
1136 { 0x8002, "Ericsson Tone Generator Package" },
1137 { 0x8003, "Ericsson Line Test Package" },
1138 { 0x8004, "Nokia Advanced TFO Package" },
1139 { 0x8005, "Nokia IWF Package" },
1140 { 0x8006, "Nokia Root Package" },
1141 { 0x8007, "Nokia Trace Package" },
1142 { 0x8008, "Ericsson V5.2 Layer" },
1143 { 0x8009, "Ericsson Detailed Termination Information Package" },
1144 { 0x800a, "Nokia Bearer Characteristics Package" },
1145 { 0x800b, "Nokia Test Call Package" },
1146 { 0x800c, "Nokia Extended Continuity Package" },
1147 { 0x800d, "Nokia IPnwR Package" },
1148 { 0x800e, "Ericsson Tracing Enhancements Package" },
1149 { 0x800f, "Ericsson Partially Wildcarded TerminationID Package" },
1150 { 0x8010, "SCTP Stream Handling Package" },
1155 * This table consist of PackageName + EventName and its corresponding string
1158 static const value_string base_event_name_vals
[] = {
1159 { 0x00000000, "Media stream properties H.248.1 Annex C" },
1160 { 0x00010000, "g H.248.1 Annex E" },
1161 { 0x00010001, "g/Cause" },
1162 { 0x00010002, "g/Signal Completion" },
1163 { 0x00040000, "tonedet H.248.1 Annex E" },
1164 { 0x00040001, "tonedet/std(Start tone detected)" },
1165 { 0x00040002, "tonedet/etd(End tone detected)" },
1166 { 0x00040003, "tonedet/ltd(Long tone detected)" },
1167 { 0x00060000, "dd H.248.1 Annex E" },
1168 { 0x00060001, "dd/std" },
1169 { 0x00060002, "dd/etd" },
1170 { 0x00060003, "dd/ltd" },
1171 { 0x00060004, "dd, DigitMap Completion Event" },
1172 { 0x00060010, "dd/d0, DTMF character 0" },
1173 { 0x00060011, "dd/d1, DTMF character 1" },
1174 { 0x00060012, "dd/d2, DTMF character 2" },
1175 { 0x00060013, "dd/d3, DTMF character 3" },
1176 { 0x00060014, "dd/d4, DTMF character 4" },
1177 { 0x00060015, "dd/d5, DTMF character 5" },
1178 { 0x00060016, "dd/d6, DTMF character 6" },
1179 { 0x00060017, "dd/d7, DTMF character 7" },
1180 { 0x00060018, "dd/d8, DTMF character 8" },
1181 { 0x00060019, "dd/d9, DTMF character 9" },
1182 { 0x0006001a, "dd/a, DTMF character A" },
1183 { 0x0006001b, "dd/b, DTMF character B" },
1184 { 0x0006001c, "dd/c, DTMF character C" },
1185 { 0x0006001d, "dd/d, DTMF character D" },
1186 { 0x00060020, "dd/" "*, DTMF character *" }, /* XXX: hack so checkAPIs & etc won't see a 'start of comment' */
1187 { 0x00060021, "dd/#, DTMF character #" },
1188 { 0x00080030, "cd, Dial Tone" },
1189 { 0x00080031, "cd, Ringing Tone" },
1190 { 0x00080032, "cd, Busy Tone" },
1191 { 0x00080033, "cd, Congestion Tone" },
1192 { 0x00080034, "cd, Special Information Tone" },
1193 { 0x00080035, "cd, (Recording) Warning Tone" },
1194 { 0x00080036, "cd, Payphone Recognition Tone" },
1195 { 0x00080037, "cd, Call Waiting Tone" },
1196 { 0x00080038, "cd, Caller Waiting Tone" },
1197 { 0x00090004, "al, onhook" },
1198 { 0x00090005, "al, offhook" },
1199 { 0x00090006, "al, flashhook" },
1200 { 0x0009ffff, "al, *" },
1201 { 0x000a0005, "ct, Completion of Continuity test" },
1202 { 0x000b0005, "nt, network failure" },
1203 { 0x000b0006, "nt, quality alert" },
1204 { 0x000c0001, "rtp, Payload Transition" },
1205 { 0x00210000, "Generic Bearer Connection Q.1950 Annex A" },
1206 { 0x00210001, "GB/BNCChange" },
1207 { 0x00220001, "BT/TIND (Tunnel Indication)" },
1208 { 0x002a0001, "H.245/h245msg (Incoming H.245 Message)" },
1209 { 0x002a0004, "H.245/h245ChC (H.245 Channel Closed)" },
1210 { 0x00450000, "Inactivity Timer H.248.14" },
1211 { 0x00450001, "it/ito" },
1212 { 0x00450002, "it/ito" },
1213 { 0x00460001, "threegmlc/mod_link_supp (Bearer Modification Support Event)" },
1214 { 0x00980000, "Hanging Termination Package" },
1215 { 0x00980001, "Termination Heartbeat" },
1216 { 0x800a0000, "Nokia Bearer Characteristics Package" },
1221 * This table consist of PackageName + SignalName and its corresponding string
1223 static const value_string base_signal_name_vals
[] = {
1224 { 0x00000000, "Media stream properties H.248.1 Annex C" },
1225 { 0x00010000, "g H.248.1 Annex E" },
1226 { 0x00030001, "tonegen/pt(Play tone)" },
1227 { 0x00050010, "dg, DTMF character 0" },
1228 { 0x00050011, "dg, DTMF character 1" },
1229 { 0x00050012, "dg, DTMF character 2" },
1230 { 0x00050013, "dg, DTMF character 3" },
1231 { 0x00050014, "dg, DTMF character 4" },
1232 { 0x00050015, "dg, DTMF character 5" },
1233 { 0x00050016, "dg, DTMF character 6" },
1234 { 0x00050017, "dg, DTMF character 7" },
1235 { 0x00050018, "dg, DTMF character 8" },
1236 { 0x00050019, "dg, DTMF character 9" },
1237 { 0x0005001a, "dg, DTMF character A" },
1238 { 0x0005001b, "dg, DTMF character B" },
1239 { 0x0005001c, "dg, DTMF character C" },
1240 { 0x0005001d, "dg, DTMF character D" },
1241 { 0x00050020, "dg, DTMF character *" },
1242 { 0x00050021, "dg, DTMF character #" },
1243 { 0x00070030, "cg, Dial Tone" },
1244 { 0x00070031, "cg/rt (Ringing Tone)" },
1245 { 0x00070032, "cg, Busy Tone" },
1246 { 0x00070033, "cg, Congestion Tone" },
1247 { 0x00070034, "cg, Special Information Tone" },
1248 { 0x00070035, "cg, (Recording) Warning Tone" },
1249 { 0x00070036, "cg, Payphone Recognition Tone" },
1250 { 0x00070037, "cg, Call Waiting Tone" },
1251 { 0x00070038, "cg, Caller Waiting Tone" },
1252 { 0x00090002, "al, ring" },
1253 { 0x0009ffff, "al, *" },
1254 { 0x000a0003, "ct, Continuity test" },
1255 { 0x000a0004, "ct, Continuity respond" },
1256 { 0x00210000, "GB Generic Bearer Connection Q.1950 Annex A" },
1257 { 0x00210001, "GB/EstBNC(Establish BNC)" },
1258 { 0x00210002, "GB/ModBNC (Modify BNC)" },
1259 { 0x00210003, "GB/RelBNC(Release BNC)" },
1260 { 0x002a0001, "H.245/cs (channel state)" },
1261 { 0x002a0002, "H.245/termtype (Terminal Type)" },
1262 { 0x002c0001, "H.324/cmod (Communication mode)" },
1263 { 0x002c0002, "H.324/muxlv (Highest Multiplexing level)" },
1264 { 0x002c0003, "H.324/demux (Demultiplex)" },
1265 { 0x002c0004, "H.324/h223capr (Remote H.223 capability)" },
1266 { 0x002c0005, "H.324/muxtbl_in (Incoming Multiplex Table)" },
1267 { 0x002c0006, "H.324/muxtbl_out (Outgoing Multiplex Table)" },
1268 { 0x800a0000, "Nokia Bearer Characteristics Package" },
1273 static const value_string h248_reasons
[] = {
1274 { 400, "Syntax error in message"},
1275 { 401, "Protocol Error"},
1276 { 402, "Unauthorized"},
1277 { 403, "Syntax error in transaction request"},
1278 { 406, "Version Not Supported"},
1279 { 410, "Incorrect identifier"},
1280 { 411, "The transaction refers to an unknown ContextId"},
1281 { 412, "No ContextIDs available"},
1282 { 413, "Number of transactions in message exceeds maximum"}, /* [H.248.8 (08/07)] */
1283 { 421, "Unknown action or illegal combination of actions"},
1284 { 422, "Syntax Error in Action"},
1285 { 430, "Unknown TerminationID"},
1286 { 431, "No TerminationID matched a wildcard"},
1287 { 432, "Out of TerminationIDs or No TerminationID available"},
1288 { 433, "TerminationID is already in a Context"},
1289 { 434, "Max number of Terminations in a Context exceeded"},
1290 { 435, "Termination ID is not in specified Context"},
1291 { 440, "Unsupported or unknown Package"},
1292 { 441, "Missing Remote or Local Descriptor"},
1293 { 442, "Syntax Error in Command"},
1294 { 443, "Unsupported or Unknown Command"},
1295 { 444, "Unsupported or Unknown Descriptor"},
1296 { 445, "Unsupported or Unknown Property"},
1297 { 446, "Unsupported or Unknown Parameter"},
1298 { 447, "Descriptor not legal in this command"},
1299 { 448, "Descriptor appears twice in a command"},
1300 { 449, "Unsupported or Unknown Parameter or Property Value"},
1301 { 450, "No such property in this package"},
1302 { 451, "No such event in this package"},
1303 { 452, "No such signal in this package"},
1304 { 453, "No such statistic in this package"},
1305 { 454, "No such parameter value in this package"},
1306 { 455, "Property illegal in this Descriptor"},
1307 { 456, "Property appears twice in this Descriptor"},
1308 { 457, "Missing parameter in signal or event"},
1309 { 458, "Unexpected Event/Request ID"},
1310 { 459, "Unsupported or Unknown Profile"},
1311 { 460, "Unable to set statistic on stream"},
1312 { 461, "Unsupported or Unknown Profile"}, /*[H.248.18] */
1314 { 471, "Implied Add for Multiplex failure"},
1315 { 472, "Required Information Missing"}, /*[H.248.8 (08/07)] */
1316 { 473, "Conflicting Property Values"}, /*[H.248.8 (08/07)] */
1317 { 474, "Invalid SDP Syntax"}, /*[H.248.49] */
1318 { 475, "Unable to pause the playout of the signal"}, /*[H.248.66] */
1319 { 476, "Unable to adjust the data delivery speed of the Signal"}, /*[H.248.66] */
1321 { 477, "Unable to adjust the playback relative scale of the signal"}, /*[H.248.66] */
1323 { 478, "Behaviour Contradicts Resource Rule"}, /*[H.248.63] */
1325 { 500, "Internal software Failure in MG"},
1326 { 501, "Not Implemented"},
1327 { 502, "Not ready"},
1328 { 503, "Service Unavailable"},
1329 { 504, "Command Received from unauthorized entity"},
1330 { 505, "Transaction Request Received before a Service Change Reply has been received"},
1331 { 506, "Number of Transaction Pendings Exceeded"},
1332 { 510, "Insufficient resources"},
1333 { 511, "Temporarily Busy"}, /* [H.248.8 (08/07)] */
1334 { 512, "Media Gateway unequipped to detect requested Event"},
1335 { 513, "Media Gateway unequipped to generate requested Signals"},
1336 { 514, "Media Gateway cannot send the specified announcement"},
1337 { 515, "Unsupported Media Type"},
1338 { 517, "Unsupported or invalid mode"},
1339 { 518, "Event buffer full"},
1340 { 519, "Out of space to store digit map"},
1341 { 520, "Digit Map undefined in the MG"},
1342 { 521, "Termination is ServiceChanging"},
1343 { 522, "Functionality Requested in Topology Triple Not Supported"},
1344 { 526, "Insufficient bandwidth"},
1345 { 529, "Internal hardware failure in MG"},
1346 { 530, "Temporary Network failure"},
1347 { 531, "Permanent Network failure"},
1348 { 532, "Audited Property, Statistic, Event or Signal does not exist"},
1349 { 533, "Response exceeds maximum transport PDU size"},
1350 { 534, "Illegal write or read only property"},
1351 { 540, "Unexpected initial hook state"},
1352 { 541, "Unexpected Spare Bit State"}, /* [H.248.33] */
1353 { 542, "Command is not allowed on this termination"},
1354 { 543, "MGC requested event detection timestamp not supported"}, /* [H.248.8 (08/07)] */
1355 { 581, "Does Not Exist"},
1356 { 600, "Illegal syntax within an announcement specification"},
1357 { 601, "Variable type not supported"},
1358 { 602, "Variable value out of range"},
1359 { 603, "Category not supported"},
1360 { 604, "Selector type not supported"},
1361 { 605, "Selector value not supported"},
1362 { 606, "Unknown segment ID"},
1363 { 607, "Mismatch between play specification and provisioned data"},
1364 { 608, "Provisioning error"},
1365 { 609, "Invalid offset"},
1366 { 610, "No free segment IDs"},
1367 { 611, "Temporary segment not found"},
1368 { 612, "Segment in use"},
1369 { 613, "ISP port limit overrun"},
1370 { 614, "No modems available"},
1371 { 615, "Calling number unacceptable"},
1372 { 616, "Called number unacceptable"},
1373 { 617, "Reserved for H.248.9 return code"}, /* [H.248.9] */
1374 { 618, "Reserved for H.248.9 return code"}, /* [H.248.9] */
1375 { 622, "Reserved for H.248.9 return code"}, /* [H.248.9] */
1376 { 623, "Reserved for H.248.9 return code"}, /* [H.248.9] */
1377 { 624, "Reserved for H.248.9 return code"}, /* [H.248.9] */
1378 { 625, "Reserved for H.248.9 return code"}, /* [H.248.9 Amendment 1] */
1379 { 626, "Reserved for H.248.9 return code"}, /* [H.248.9 Amendment 1] */
1380 { 627, "Reserved for H.248.9 return code"}, /* [H.248.9 Amendment 1] */
1381 { 628, "Reserved for H.248.9 return code"}, /* [H.248.9 Amendment 1] */
1382 { 629, "Reserved for H.248.9 return code"}, /* [H.248.9 Amendment 1] */
1383 { 700, "Sieve Script Syntax Error"}, /* [H.248.69] */
1384 { 701, "Unsupported Sieve Require Error"}, /* [H.248.69] */
1385 { 702, "Sieve Actions Exceeded Error"}, /* [H.248.69] */
1387 { 900, "Service Restored"},
1388 { 901, "Cold Boot"},
1389 { 902, "Warm Boot"},
1390 { 903, "MGC Directed Change"},
1391 { 904, "Termination malfunctioning"},
1392 { 905, "Termination taken out of service"},
1393 { 906, "Loss of lower layer connectivity (e.g. downstream sync)"},
1394 { 907, "Transmission Failure"},
1395 { 908, "MG Impending Failure"},
1396 { 909, "MGC Impending Failure"},
1397 { 910, "Media Capability Failure"},
1398 { 911, "Modem Capability Failure"},
1399 { 912, "Mux Capability Failure"},
1400 { 913, "Signal Capability Failure"},
1401 { 914, "Event Capability Failure"},
1402 { 915, "State Loss"},
1403 { 916, "Packages Change"},
1404 { 917, "Capabilities Change"},
1405 { 918, "Cancel Graceful"},
1406 { 919, "Warm Failover"},
1407 { 920, "Cold Failover"},
1410 static value_string_ext h248_reasons_ext
= VALUE_STRING_EXT_INIT(h248_reasons
);
1412 static const value_string wildcard_modes
[] = {
1418 static const value_string wildcard_levels
[] = {
1419 { 0, "This One Level" },
1420 { 1, "This Level and those below" },
1424 static h248_curr_info_t curr_info
;
1425 static uint32_t error_code
;
1426 static uint32_t h248_version
; /* h248v1 support */
1427 static gcp_wildcard_t wild_term
;
1428 static uint8_t wild_card
= 0xFF; /* place to store wildcardField */
1430 /* Call the export PDU tap with relevant data */
1432 export_h248_pdu(packet_info
*pinfo
, tvbuff_t
*tvb
)
1434 if (have_tap_listener(exported_pdu_tap
)) {
1435 exp_pdu_data_t
*exp_pdu_data
= export_pdu_create_common_tags(pinfo
, "h248", EXP_PDU_TAG_DISSECTOR_NAME
);
1437 exp_pdu_data
->tvb_captured_length
= tvb_captured_length(tvb
);
1438 exp_pdu_data
->tvb_reported_length
= tvb_reported_length(tvb
);
1439 exp_pdu_data
->pdu_tvb
= tvb
;
1441 tap_queue_packet(exported_pdu_tap
, pinfo
, exp_pdu_data
);
1445 extern void h248_param_ber_integer(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, int hfid
, h248_curr_info_t
* u _U_
, void* implicit
) {
1446 asn1_ctx_t asn1_ctx
;
1447 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
1448 dissect_ber_integer(implicit
? *((bool*)implicit
) : false, &asn1_ctx
, tree
, tvb
, 0, hfid
, NULL
);
1451 extern void h248_param_ber_octetstring(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, int hfid
, h248_curr_info_t
* u _U_
, void* implicit
) {
1452 asn1_ctx_t asn1_ctx
;
1453 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
1454 dissect_ber_octet_string(implicit
? *((bool*)implicit
) : false, &asn1_ctx
, tree
, tvb
, 0, hfid
, NULL
);
1457 extern void h248_param_ber_boolean(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, int hfid
, h248_curr_info_t
* u _U_
, void* implicit
) {
1458 asn1_ctx_t asn1_ctx
;
1459 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
1460 dissect_ber_boolean(implicit
? *((bool*)implicit
) : false, &asn1_ctx
, tree
, tvb
, 0, hfid
, NULL
);
1463 extern void h248_param_bytes_item(proto_tree
* tree
,
1465 packet_info
* pinfo _U_
,
1467 h248_curr_info_t
* h248_info _U_
,
1469 int len
= lenp
? *((int*)lenp
) : -1;
1470 proto_tree_add_item(tree
,hfid
,tvb
,0,len
,ENC_NA
);
1473 extern void h248_param_uint_item(proto_tree
* tree
,
1475 packet_info
* pinfo _U_
,
1477 h248_curr_info_t
* h248_info _U_
,
1479 int len
= lenp
? *((int*)lenp
) : -1;
1480 proto_tree_add_item(tree
,hfid
,tvb
,0,len
,ENC_BIG_ENDIAN
);
1483 extern void h248_param_external_dissector(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, int hfid _U_
, h248_curr_info_t
* u _U_
, void* dissector_hdl
) {
1484 call_dissector((dissector_handle_t
) dissector_hdl
,tvb
,pinfo
,tree
);
1488 static const h248_package_t no_package
= { 0xffff, &hf_h248_no_pkg
, &ett_h248_no_pkg
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1489 static const h248_pkg_sig_t no_signal
= { 0, &hf_h248_no_sig
, &ett_h248_no_sig
, NULL
, NULL
};
1490 static const h248_pkg_param_t no_param
= { 0, &hf_h248_param
, h248_param_uint_item
, NULL
};
1491 static const h248_pkg_evt_t no_event
= { 0, &hf_h248_no_evt
, &ett_h248_no_evt
, NULL
, NULL
};
1493 static const h248_package_t
*find_package_id(uint16_t pkgid
);
1494 static wmem_tree_t
* packages
;
1496 extern void h248_param_PkgdName(proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, int hfid _U_
, h248_curr_info_t
* u1 _U_
, void* u2 _U_
) {
1497 tvbuff_t
*new_tvb
= NULL
;
1498 proto_tree
*package_tree
=NULL
;
1499 uint16_t name_major
, name_minor
;
1500 const h248_package_t
* pkg
= NULL
;
1502 asn1_ctx_t asn1_ctx
;
1503 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
1505 offset
= dissect_ber_octet_string(false, &asn1_ctx
, tree
, tvb
, offset
, hfid
, &new_tvb
);
1508 /* this field is always 4 bytes so just read it into two integers */
1509 name_major
=tvb_get_ntohs(new_tvb
, 0);
1510 name_minor
=tvb_get_ntohs(new_tvb
, 2);
1511 pkg
= find_package_id(name_major
);
1512 /* do the prettification */
1513 proto_item_append_text(asn1_ctx
.created_item
, " %s (%04x)",
1514 val_to_str_const(0, pkg
->param_names
, "Unknown Package"),
1521 package_tree
= proto_item_add_subtree(asn1_ctx
.created_item
, ett_packagename
);
1522 proto_tree_add_uint_format(package_tree
, hf_h248_pkg_name
, tvb
, offset
-4, 2, name_major
,
1523 "%s (0x%04x)", val_to_str_const(0, pkg
->param_names
, "Unknown Package"), name_major
);
1525 pi
= proto_tree_add_uint(package_tree
, hf_248_pkg_param
, tvb
, offset
-2, 2, name_minor
);
1527 if (pkg
->signal_names
&& ( strval
= try_val_to_str(name_minor
, pkg
->signal_names
) )) {
1528 strval
= wmem_strdup_printf(pinfo
->pool
, "%s (%d)",strval
,name_minor
);
1530 strval
= wmem_strdup_printf(pinfo
->pool
, "Unknown (%d)",name_minor
);
1533 proto_item_set_text(pi
,"Signal ID: %s", strval
);
1540 static int dissect_h248_trx_id(bool implicit_tag
, packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, uint32_t* trx_id_p
) {
1541 uint64_t trx_id
= 0;
1549 offset
=dissect_ber_identifier(pinfo
, tree
, tvb
, offset
, &ber_class
, &pc
, &tag
);
1550 offset
=dissect_ber_length(pinfo
, tree
, tvb
, offset
, &len
, NULL
);
1552 len
=tvb_reported_length_remaining(tvb
, offset
);
1556 if (len
> 8 || len
< 1) {
1559 for(i
=1;i
<=len
;i
++){
1560 trx_id
=(trx_id
<<8)|tvb_get_uint8(tvb
, offset
);
1563 if (trx_id
> 0xffffffff) {
1564 proto_item
* pi
= proto_tree_add_uint64(tree
, hf_h248_transactionId64
, tvb
, offset
-len
, len
, trx_id
);
1565 expert_add_info(pinfo
, pi
, &ei_h248_transactionId64
);
1570 proto_tree_add_uint(tree
, hf_h248_transactionId
, tvb
, offset
-len
, len
, (uint32_t)trx_id
);
1571 *trx_id_p
= (uint32_t)trx_id
;
1578 static int dissect_h248_ctx_id(bool implicit_tag
, packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, uint32_t* ctx_id_p
) {
1583 uint64_t ctx_id
= 0;
1587 offset
=dissect_ber_identifier(pinfo
, tree
, tvb
, offset
, &ber_class
, &pc
, &tag
);
1588 offset
=dissect_ber_length(pinfo
, tree
, tvb
, offset
, &len
, NULL
);
1590 len
=tvb_reported_length_remaining(tvb
, offset
);
1594 if (len
> 8 || len
< 1) {
1597 for(i
=1;i
<=len
;i
++){
1598 ctx_id
=(ctx_id
<<8)|tvb_get_uint8(tvb
, offset
);
1602 if (ctx_id
> 0xffffffff) {
1603 proto_item
* pi
= proto_tree_add_uint64(tree
, hf_h248_context_id64
, tvb
, offset
-len
, len
, ctx_id
);
1604 expert_add_info(pinfo
, pi
, &ei_h248_context_id64
);
1606 *ctx_id_p
= 0xfffffffd;
1609 proto_item
* pi
= proto_tree_add_uint(tree
, hf_h248_context_id
, tvb
, offset
-len
, len
, (uint32_t)ctx_id
);
1611 if ( ctx_id
== NULL_CONTEXT
) {
1612 proto_item_set_text(pi
,"contextId: Null Context(0)");
1613 } else if ( ctx_id
== CHOOSE_CONTEXT
) {
1614 proto_item_set_text(pi
,"contextId: $ (Choose Context = 0xfffffffe)");
1615 } else if ( ctx_id
== ALL_CONTEXTS
) {
1616 proto_item_set_text(pi
,"contextId: * (All Contexts = 0xffffffff)");
1619 *ctx_id_p
= (uint32_t) ctx_id
;
1626 static s_h248_package_t
*s_find_package_id(uint16_t pkgid
) {
1627 s_h248_package_t
*s_pkg
= NULL
;
1628 s_pkg
= (s_h248_package_t
*)wmem_tree_lookup32(packages
, (uint32_t)(pkgid
));
1632 static const h248_package_t
*find_package_id(uint16_t pkgid
) {
1633 s_h248_package_t
*s_pkg
= NULL
;
1634 s_pkg
= s_find_package_id(pkgid
); /*(packages, GUINT_TO_POINTER((uint32_t)(pkgid))); */
1635 if (! s_pkg
) return &no_package
;
1639 static bool is_pkg_default(uint16_t pkgid
) {
1640 s_h248_package_t
*s_pkg
= NULL
;
1641 s_pkg
= (s_h248_package_t
*)wmem_tree_lookup32(packages
, (uint32_t)(pkgid
));
1642 if(! s_pkg
) return true;
1643 return s_pkg
->is_default
;
1646 void h248_register_package(h248_package_t
* pkg
, pkg_reg_action reg_action
) {
1647 h248_package_t
*pkg_found
= NULL
, *pkg_high
= NULL
, *pkg_low
= NULL
;
1648 s_h248_package_t
*s_pkg
= NULL
;
1650 bool pkg_default
= false;
1651 int j
= 0, idx
= 0, i
= 0, k
= 0;
1653 /* no packaegs are yet registerd so create tree and add default packages to tree
1655 packages
= wmem_tree_new(wmem_epan_scope()); /* init tree if no entries */
1656 while (base_package_name_vals
[i
].strptr
!= NULL
) {
1657 pkg_found
= wmem_new0(wmem_epan_scope(), h248_package_t
); /* create a h248 package structure */
1658 pkg_found
->id
= base_package_name_vals
[i
].value
;
1659 vst
= (value_string
*)wmem_alloc0(wmem_epan_scope(), sizeof(value_string
)*2);
1660 vst
[0].strptr
= base_package_name_vals
[i
].strptr
;
1661 pkg_found
->param_names
= vst
;
1662 pkg_found
->hfid
= &hf_h248_pkg_name
;
1663 pkg_found
->ett
= &ett_packagename
;
1664 try_val_to_str_idx((pkg_found
->id
)<<16,base_event_name_vals
, &j
);
1665 /* now look for events and signals that may be defined for package. If found, create value_strings */
1668 while((base_event_name_vals
[j
].strptr
!=NULL
) && (((base_event_name_vals
[j
].value
)>>16) == (pkg_found
->id
))) {
1672 vst
= (value_string
*)wmem_alloc0(wmem_epan_scope(), sizeof(value_string
)*(j
-idx
+1));
1673 for (k
=0;idx
<j
;k
++) {
1674 vst
[k
].strptr
= base_event_name_vals
[idx
].strptr
;
1675 vst
[k
].value
= (base_event_name_vals
[idx
].value
& 0xffff);
1678 pkg_found
->event_names
= vst
;
1681 /* now look at signals */
1682 if (!try_val_to_str_idx((pkg_found
->id
)<<16, base_signal_name_vals
, &j
)) {
1684 while((base_signal_name_vals
[j
].strptr
!= NULL
) && ((base_signal_name_vals
[j
].value
>>16) == (pkg_found
->id
))) {
1688 vst
= (value_string
*)wmem_alloc0(wmem_epan_scope(), sizeof(value_string
)*(j
-idx
+1));
1689 for (k
=0;idx
<j
;k
++) {
1690 vst
[k
].strptr
= base_signal_name_vals
[idx
].strptr
;
1691 vst
[k
].value
= (base_signal_name_vals
[idx
].value
&0xffff);
1694 pkg_found
->signal_names
= vst
;
1697 s_pkg
= wmem_new0(wmem_epan_scope(), s_h248_package_t
);
1698 s_pkg
->is_default
= true;
1699 s_pkg
->pkg
= pkg_found
;
1700 wmem_tree_insert32(packages
, pkg_found
->id
, s_pkg
);
1703 pkg_found
= NULL
; /* reset pointer */
1705 pkg_default
= is_pkg_default(pkg
->id
);
1706 if (((reg_action
==REPLACE_PKG
) || (reg_action
==ADD_PKG
)) && pkg_default
) {
1707 /* add/replace in tree */
1708 s_pkg
= wmem_new0(wmem_epan_scope(), s_h248_package_t
);
1709 s_pkg
->is_default
= false;
1710 s_pkg
->pkg
= (h248_package_t
*)pkg
;
1711 wmem_tree_insert32(packages
, pkg
->id
, s_pkg
);
1714 if(pkg_default
) reg_action
= MERGE_PKG_HIGH
; /* always make new package override default */
1715 s_pkg
= s_find_package_id(pkg
->id
);
1716 if (s_pkg
== NULL
) { /* no need to merge - package not in tree */
1717 s_pkg
= wmem_new0(wmem_epan_scope(), s_h248_package_t
);
1718 s_pkg
->is_default
= false;
1719 s_pkg
->pkg
= (h248_package_t
*)pkg
;
1720 wmem_tree_insert32(packages
, pkg
->id
, s_pkg
);
1723 pkg_found
= s_pkg
->pkg
;
1724 if (reg_action
==MERGE_PKG_HIGH
) {
1725 pkg_high
= (h248_package_t
*)pkg
;
1726 pkg_low
= pkg_found
;
1728 if (reg_action
==MERGE_PKG_LOW
) {
1729 pkg_high
= pkg_found
;
1730 pkg_low
= (h248_package_t
*)pkg
;
1733 /* if h248_package_t High Priority value !NULL, replace it in the found tree entry else use current entry */
1734 (pkg_high
->hfid
? (pkg_found
->hfid
=pkg_high
->hfid
) : (pkg_found
->hfid
=pkg_low
->hfid
));
1735 (pkg_high
->ett
? (pkg_found
->ett
=pkg_high
->ett
):( pkg_found
->ett
=pkg_low
->ett
));
1736 (pkg_high
->param_names
? (pkg_found
->param_names
=pkg_high
->param_names
):( pkg_found
->param_names
=pkg_low
->param_names
));
1737 (pkg_high
->signal_names
? (pkg_found
->signal_names
=pkg_high
->signal_names
):( pkg_found
->signal_names
=pkg_low
->signal_names
));
1738 (pkg_high
->event_names
? (pkg_found
->event_names
=pkg_high
->event_names
):( pkg_found
->event_names
=pkg_low
->event_names
));
1739 (pkg_high
->stats_names
? (pkg_found
->stats_names
=pkg_high
->stats_names
):( pkg_found
->stats_names
=pkg_low
->stats_names
));
1740 (pkg_high
->properties
? (pkg_found
->properties
=pkg_high
->properties
):( pkg_found
->properties
=pkg_low
->properties
));
1741 (pkg_high
->signals
? (pkg_found
->signals
=pkg_high
->signals
):( pkg_found
->signals
=pkg_low
->signals
));
1742 (pkg_high
->events
? (pkg_found
->events
=pkg_high
->events
):( pkg_found
->events
=pkg_low
->events
));
1743 (pkg_high
->statistics
? (pkg_found
->statistics
=pkg_high
->statistics
):( pkg_found
->statistics
=pkg_low
->statistics
));
1744 s_pkg
->pkg
= pkg_found
;
1745 s_pkg
->is_default
= false;
1750 static uint32_t packageandid
;
1752 static int dissect_h248_PkgdName(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index
) {
1753 tvbuff_t
*new_tvb
= NULL
;
1754 proto_tree
*package_tree
=NULL
;
1755 uint16_t name_major
, name_minor
;
1756 const h248_package_t
* pkg
= NULL
;
1758 offset
= dissect_ber_octet_string(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, &new_tvb
);
1761 /* this field is always 4 bytes so just read it into two integers */
1762 name_major
=tvb_get_ntohs(new_tvb
, 0);
1763 name_minor
=tvb_get_ntohs(new_tvb
, 2);
1764 packageandid
=(name_major
<<16)|name_minor
;
1766 pkg
= find_package_id(name_major
);
1767 /* do the prettification */
1768 proto_item_append_text(actx
->created_item
, " %s (%04x)",
1769 val_to_str_const(0, pkg
->param_names
, "Unknown Package"),
1773 package_tree
= proto_item_add_subtree(actx
->created_item
, ett_packagename
);
1774 proto_tree_add_uint_format(package_tree
, hf_h248_pkg_name
, tvb
, offset
-4, 2, name_major
,
1775 "PkgName: %s (0x%04x)", val_to_str_const(0, pkg
->param_names
, "Unknown Package"), name_major
);
1779 proto_item
* pi
= proto_tree_add_uint(package_tree
, hf_248_pkg_param
, tvb
, offset
-2, 2, name_minor
);
1782 if (pkg
->param_names
&& ( strval
= try_val_to_str(name_minor
, pkg
->param_names
) )) {
1783 strval
= wmem_strdup_printf(actx
->pinfo
->pool
, "%s (%d)",strval
,name_minor
);
1785 strval
= wmem_strdup_printf(actx
->pinfo
->pool
, "Unknown (%d)",name_minor
);
1788 proto_item_set_text(pi
,"Parameter: %s", strval
);
1794 curr_info
.pkg
= pkg
;
1799 static int dissect_h248_EventName(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index
) {
1801 proto_tree
*package_tree
=NULL
;
1802 uint16_t name_major
, name_minor
;
1803 const h248_package_t
* pkg
= NULL
;
1804 const h248_pkg_evt_t
* evt
= NULL
;
1806 offset
= dissect_ber_octet_string(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, &new_tvb
);
1809 /* this field is always 4 bytes so just read it into two integers */
1810 name_major
=tvb_get_ntohs(new_tvb
, 0);
1811 name_minor
=tvb_get_ntohs(new_tvb
, 2);
1812 packageandid
=(name_major
<<16)|name_minor
;
1814 pkg
= find_package_id(name_major
);
1815 /* do the prettification */
1816 proto_item_append_text(actx
->created_item
, " %s (%04x)",
1817 val_to_str_const(0, pkg
->param_names
, "Unknown Package"),
1820 package_tree
= proto_item_add_subtree(actx
->created_item
, ett_packagename
);
1822 proto_tree_add_uint_format(package_tree
, hf_h248_pkg_name
, tvb
, offset
-4, 2, name_major
,
1823 "%s (0x%04x)", val_to_str_const(0, pkg
->param_names
, "Unknown Package"), name_major
);
1825 curr_info
.pkg
= pkg
;
1828 for (evt
= pkg
->events
; evt
->hfid
; evt
++) {
1829 if (name_minor
== evt
->id
) {
1834 if (! evt
->hfid
) evt
= &no_event
;
1839 curr_info
.evt
= evt
;
1842 proto_item
* pi
= proto_tree_add_uint(package_tree
, hf_h248_event_code
, tvb
, offset
-2, 2, name_minor
);
1845 if (pkg
->event_names
&& ( strval
= try_val_to_str(name_minor
, pkg
->event_names
) )) {
1846 strval
= wmem_strdup_printf(actx
->pinfo
->pool
, "%s (%d)",strval
,name_minor
);
1848 strval
= wmem_strdup_printf(actx
->pinfo
->pool
, "Unknown (%d)",name_minor
);
1851 proto_item_set_text(pi
,"Event ID: %s", strval
);
1855 curr_info
.pkg
= &no_package
;
1856 curr_info
.evt
= &no_event
;
1864 static int dissect_h248_SignalName(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index
) {
1866 proto_tree
*package_tree
=NULL
;
1867 uint16_t name_major
, name_minor
;
1868 const h248_package_t
* pkg
= NULL
;
1869 const h248_pkg_sig_t
* sig
;
1871 offset
= dissect_ber_octet_string(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, &new_tvb
);
1874 /* this field is always 4 bytes so just read it into two integers */
1875 name_major
=tvb_get_ntohs(new_tvb
, 0);
1876 name_minor
=tvb_get_ntohs(new_tvb
, 2);
1877 packageandid
=(name_major
<<16)|name_minor
;
1879 pkg
= find_package_id(name_major
);
1880 /* do the prettification */
1881 proto_item_append_text(actx
->created_item
, " %s (%04x)",
1882 val_to_str_const(0, pkg
->param_names
, "Unknown Package"),
1885 package_tree
= proto_item_add_subtree(actx
->created_item
, ett_packagename
);
1887 proto_tree_add_uint_format(package_tree
, hf_h248_pkg_name
, tvb
, offset
-4, 2, name_major
,
1888 "%s (0x%04x)", val_to_str_const(0, pkg
->param_names
, "Unknown Package"), name_major
);
1891 for (sig
= pkg
->signals
; sig
->hfid
; sig
++) {
1892 if (name_minor
== sig
->id
) {
1897 if (! sig
->hfid
) sig
= &no_signal
;
1899 curr_info
.pkg
= pkg
;
1900 curr_info
.sig
= sig
;
1902 curr_info
.pkg
= &no_package
;
1903 curr_info
.sig
= &no_signal
;
1907 proto_item
* pi
= proto_tree_add_uint(package_tree
, hf_h248_signal_code
, tvb
, offset
-2, 2, name_minor
);
1910 if (pkg
->signal_names
&& ( strval
= try_val_to_str(name_minor
, pkg
->signal_names
) )) {
1911 strval
= wmem_strdup_printf(actx
->pinfo
->pool
, "%s (%d)",strval
,name_minor
);
1913 strval
= wmem_strdup_printf(actx
->pinfo
->pool
, "Unknown (%d)",name_minor
);
1916 proto_item_set_text(pi
,"Signal ID: %s", strval
);
1920 curr_info
.pkg
= &no_package
;
1921 curr_info
.sig
= &no_signal
;
1927 static int dissect_h248_PropertyID(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index _U_
) {
1933 uint16_t name_minor
;
1935 const h248_package_t
* pkg
;
1936 const h248_pkg_param_t
* prop
;
1937 tvbuff_t
*next_tvb
= NULL
;
1939 offset
=dissect_ber_identifier(actx
->pinfo
, tree
, tvb
, offset
, &ber_class
, &pc
, &tag
);
1940 offset
=dissect_ber_length(actx
->pinfo
, tree
, tvb
, offset
, &len
, &ind
);
1941 end_offset
=offset
+len
;
1943 if( (ber_class
!=BER_CLASS_UNI
)
1944 ||(tag
!=BER_UNI_TAG_OCTETSTRING
) ){
1945 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_h248_octet_string_expected
, tvb
, offset
-2, 2,
1946 "H.248 BER Error: OctetString expected but Class:%d PC:%d Tag:%d was unexpected", ber_class
, pc
, tag
);
1950 next_tvb
= tvb_new_subset_length(tvb
,offset
,len
);
1952 name_minor
= packageandid
& 0xffff;
1954 pkg
= (curr_info
.pkg
) ? curr_info
.pkg
: &no_package
;
1956 if (pkg
->properties
) {
1957 for (prop
= pkg
->properties
; prop
&& prop
->hfid
; prop
++) {
1958 if (name_minor
== prop
->id
) {
1965 if (prop
&& prop
->hfid
&& prop
->dissector
) {
1966 prop
->dissector(tree
, next_tvb
, actx
->pinfo
, *(prop
->hfid
), &curr_info
, prop
->data
);
1974 static int dissect_h248_SigParameterName(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index _U_
) {
1976 uint32_t param_id
= 0xffffffff;
1977 const h248_pkg_param_t
* sigpar
;
1981 offset
= dissect_ber_octet_string(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, &next_tvb
);
1982 pi
= actx
->created_item
;
1984 switch(tvb_reported_length(next_tvb
)) {
1985 case 4: param_id
= tvb_get_ntohl(next_tvb
,0); break;
1986 case 3: param_id
= tvb_get_ntoh24(next_tvb
,0); break;
1987 case 2: param_id
= tvb_get_ntohs(next_tvb
,0); break;
1988 case 1: param_id
= tvb_get_uint8(next_tvb
,0); break;
1992 curr_info
.par
= &no_param
;
1994 if (curr_info
.sig
&& curr_info
.sig
->parameters
) {
1995 for(sigpar
= curr_info
.sig
->parameters
; sigpar
->hfid
; sigpar
++) {
1996 if (sigpar
->id
== param_id
) {
1997 curr_info
.par
= sigpar
;
2003 if (curr_info
.sig
&& curr_info
.sig
->param_names
&& ( strval
= try_val_to_str(param_id
, curr_info
.sig
->param_names
) )) {
2004 strval
= wmem_strdup_printf(actx
->pinfo
->pool
, "%s (%d)",strval
,param_id
);
2006 strval
= wmem_strdup_printf(actx
->pinfo
->pool
, "Unknown (%d)",param_id
);
2009 proto_item_set_text(pi
,"Parameter: %s", strval
);
2014 static int dissect_h248_SigParamValue(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index _U_
) {
2020 tvbuff_t
*next_tvb
= NULL
;
2022 offset
=dissect_ber_identifier(actx
->pinfo
, tree
, tvb
, offset
, &ber_class
, &pc
, &tag
);
2023 offset
=dissect_ber_length(actx
->pinfo
, tree
, tvb
, offset
, &len
, &ind
);
2024 end_offset
=offset
+len
;
2026 if( (ber_class
!=BER_CLASS_UNI
)
2027 ||(tag
!=BER_UNI_TAG_OCTETSTRING
) ){
2028 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_h248_octet_string_expected
, tvb
, offset
-2, 2,
2029 "H.248 BER Error: OctetString expected but Class:%d PC:%d Tag:%d was unexpected", ber_class
, pc
, tag
);
2033 next_tvb
= tvb_new_subset_length(tvb
,offset
,len
);
2035 if ( curr_info
.par
&& curr_info
.par
->dissector
) {
2036 curr_info
.par
->dissector(tree
, next_tvb
, actx
->pinfo
, *(curr_info
.par
->hfid
), &curr_info
, curr_info
.par
->data
);
2042 static int dissect_h248_SigParamValueV1(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index _U_
) {
2043 return dissect_ber_octet_string(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, NULL
);
2047 static int dissect_h248_EventParameterName(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index _U_
) {
2049 uint32_t param_id
= 0xffffffff;
2050 const h248_pkg_param_t
* evtpar
;
2054 offset
= dissect_ber_octet_string(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, &next_tvb
);
2055 pi
= actx
->created_item
;
2058 switch(tvb_reported_length(next_tvb
)) {
2059 case 4: param_id
= tvb_get_ntohl(next_tvb
,0); break;
2060 case 3: param_id
= tvb_get_ntoh24(next_tvb
,0); break;
2061 case 2: param_id
= tvb_get_ntohs(next_tvb
,0); break;
2062 case 1: param_id
= tvb_get_uint8(next_tvb
,0); break;
2068 curr_info
.par
= &no_param
;
2070 if (curr_info
.evt
&& curr_info
.evt
->parameters
) {
2071 for(evtpar
= curr_info
.evt
->parameters
; evtpar
->hfid
; evtpar
++) {
2072 if (evtpar
->id
== param_id
) {
2073 curr_info
.par
= evtpar
;
2078 curr_info
.par
= &no_param
;
2081 if (curr_info
.evt
&& curr_info
.evt
->param_names
&& ( strval
= try_val_to_str(param_id
, curr_info
.evt
->param_names
) )) {
2082 strval
= wmem_strdup_printf(actx
->pinfo
->pool
, "%s (%d)",strval
,param_id
);
2084 strval
= wmem_strdup_printf(actx
->pinfo
->pool
, "Unknown (%d)",param_id
);
2087 proto_item_set_text(pi
,"Parameter: %s", strval
);
2093 static int dissect_h248_EventParamValue(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index _U_
) {
2101 offset
=dissect_ber_identifier(actx
->pinfo
, tree
, tvb
, offset
, &ber_class
, &pc
, &tag
);
2102 offset
=dissect_ber_length(actx
->pinfo
, tree
, tvb
, offset
, &len
, &ind
);
2103 end_offset
=offset
+len
;
2105 if( (ber_class
!=BER_CLASS_UNI
)
2106 ||(tag
!=BER_UNI_TAG_OCTETSTRING
) ){
2107 proto_tree_add_expert_format(tree
, actx
->pinfo
, &ei_h248_octet_string_expected
, tvb
, offset
-2, 2,
2108 "H.248 BER Error: OctetString expected but Class:%d PC:%d Tag:%d was unexpected", ber_class
, pc
, tag
);
2112 next_tvb
= tvb_new_subset_length(tvb
,offset
,len
);
2114 if ( curr_info
.par
&& curr_info
.par
->dissector
) {
2115 curr_info
.par
->dissector(tree
, next_tvb
, actx
->pinfo
, *(curr_info
.par
->hfid
), &curr_info
, curr_info
.par
->data
);
2121 static int dissect_h248_EventParamValueV1(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index _U_
) {
2122 return dissect_ber_octet_string(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, &tvb
);
2126 static int dissect_h248_MtpAddress(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index
) {
2128 proto_tree
*mtp_tree
=NULL
;
2130 int i
, len
, old_offset
;
2133 offset
= dissect_ber_octet_string(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, &new_tvb
);
2136 /* this field is either 2 or 4 bytes so just read it into an integer */
2138 len
=tvb_reported_length(new_tvb
);
2140 val
= (val
<<8)|tvb_get_uint8(new_tvb
, i
);
2143 /* do the prettification */
2144 proto_item_append_text(actx
->created_item
, " NI = %d, PC = %d ( %d-%d )", val
&0x03,val
>>2,val
&0x03,val
>>2);
2146 mtp_tree
= proto_item_add_subtree(actx
->created_item
, ett_mtpaddress
);
2148 proto_tree_add_uint(mtp_tree
, hf_h248_mtpaddress_ni
, tvb
, old_offset
, offset
-old_offset
, val
&0x03);
2149 proto_tree_add_uint(mtp_tree
, hf_h248_mtpaddress_pc
, tvb
, old_offset
, offset
-old_offset
, val
>>2);
2155 #define H248_TAP() do { if (keep_persistent_data && curr_info.cmd) tap_queue_packet(h248_tap, actx->pinfo, curr_info.cmd); } while(0)
2157 #include "packet-h248-fn.c"
2159 static int dissect_h248_tpkt(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
) {
2160 dissect_tpkt_encap(tvb
, pinfo
, tree
, h248_desegment
, h248_handle
);
2161 return tvb_captured_length(tvb
);
2165 dissect_h248(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
2167 proto_item
*h248_item
;
2168 asn1_ctx_t asn1_ctx
;
2171 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
2173 curr_info
.msg
= NULL
;
2174 curr_info
.trx
= NULL
;
2175 curr_info
.ctx
= NULL
;
2176 curr_info
.cmd
= NULL
;
2177 curr_info
.term
= NULL
;
2178 curr_info
.pkg
= NULL
;
2179 curr_info
.evt
= NULL
;
2180 curr_info
.sig
= NULL
;
2181 curr_info
.stat
= NULL
;
2182 curr_info
.par
= NULL
;
2184 /* Check if it is actually a text-based H.248 encoding, which we
2185 dissect with the "megaco" dissector in Wireshark. (Both
2186 encodings are MEGACO (RFC 3015) and both are H.248.)
2188 if(tvb_captured_length(tvb
)>=6){
2189 if(!tvb_strneql(tvb
, 0, "MEGACO", 6)){
2190 static dissector_handle_t megaco_handle
=NULL
;
2192 megaco_handle
= find_dissector("megaco");
2195 call_dissector(megaco_handle
, tvb
, pinfo
, tree
);
2196 return tvb_captured_length(tvb
);
2200 proto_item
*hidden_item
= NULL
;
2201 uint32_t magic_num
= 0, offset
= 0;
2202 magic_num
= tvb_get_ntohl(tvb
, offset
);
2203 hidden_item
= proto_tree_add_uint(tree
, hf_248_magic_num
, tvb
, offset
, 4, magic_num
);
2204 proto_item_set_hidden(hidden_item
);
2205 if( dissector_try_uint(subdissector_table
, magic_num
, tvb
, pinfo
, tree
) ) {
2206 return tvb_captured_length(tvb
);
2211 export_h248_pdu(pinfo
, tvb
);
2213 /* Make entry in the Protocol column on summary display */
2214 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "H.248");
2217 h248_item
= proto_tree_add_item(tree
, proto_h248
, tvb
, 0, -1, ENC_NA
);
2218 h248_tree
= proto_item_add_subtree(h248_item
, ett_h248
);
2221 dissect_h248_MegacoMessage(false, tvb
, 0, &asn1_ctx
, h248_tree
, -1);
2223 return tvb_captured_length(tvb
);
2226 /*--- proto_register_h248 ----------------------------------------------*/
2227 void proto_reg_handoff_h248(void);
2229 void proto_register_h248(void) {
2231 /* List of fields */
2232 static hf_register_info hf
[] = {
2233 { &hf_248_magic_num
,
2234 { "Magic Number for Avaya H.248", "h248.magic_num",
2235 FT_UINT32
, BASE_HEX
, NULL
, 0,
2237 { &hf_h248_mtpaddress_ni
,
2238 { "NI", "h248.mtpaddress.ni",
2239 FT_UINT32
, BASE_DEC
, NULL
, 0,
2241 { &hf_h248_mtpaddress_pc
,
2242 { "PC", "h248.mtpaddress.pc",
2243 FT_UINT32
, BASE_DEC
, NULL
, 0,
2245 { &hf_h248_pkg_name
,
2246 { "Package", "h248.package_name",
2247 FT_UINT16
, BASE_HEX
, NULL
, 0,
2249 { &hf_248_pkg_param
,
2250 { "Parameter ID", "h248.package_paramid",
2251 FT_UINT16
, BASE_HEX
, NULL
, 0,
2253 { &hf_h248_signal_code
,
2254 { "Signal ID", "h248.package_signalid",
2255 FT_UINT16
, BASE_HEX
, NULL
, 0,
2257 { &hf_h248_event_code
,
2258 { "Event ID", "h248.package_eventid",
2259 FT_UINT16
, BASE_HEX
, NULL
, 0,
2261 { &hf_h248_event_name
,
2262 { "Package and Event name", "h248.event_name",
2263 FT_UINT32
, BASE_HEX
, NULL
, 0,
2265 { &hf_h248_signal_name
,
2266 { "Package and Signal name", "h248.signal_name",
2267 FT_UINT32
, BASE_HEX
, NULL
, 0,
2269 { &hf_h248_pkg_bcp_BNCChar_PDU
,
2270 { "BNCChar", "h248.package_bcp.BNCChar",
2271 FT_UINT32
, BASE_DEC
, VALS(gcp_term_types
), 0,
2273 { &hf_h248_context_id
,
2274 { "contextId", "h248.contextId",
2275 FT_UINT32
, BASE_HEX
, NULL
, 0,
2276 "Context ID", HFILL
}},
2277 { &hf_h248_term_wild_type
,
2278 { "Wildcard Mode", "h248.term.wildcard.mode",
2279 FT_UINT8
, BASE_DEC
, VALS(wildcard_modes
), 0x80,
2281 { &hf_h248_term_wild_level
,
2282 { "Wildcarding Level", "h248.term.wildcard.level",
2283 FT_UINT8
, BASE_DEC
, VALS(wildcard_levels
), 0x40,
2285 { &hf_h248_term_wild_position
,
2286 { "Wildcarding Position", "h248.term.wildcard.pos",
2287 FT_UINT8
, BASE_DEC
, NULL
, 0x3F,
2291 { "Unknown Package", "h248.pkg.unknown",
2292 FT_BYTES
, BASE_NONE
, NULL
, 0,
2295 { "Unknown Signal", "h248.pkg.unknown.sig",
2296 FT_BYTES
, BASE_NONE
, NULL
, 0,
2299 { "Unknown Event", "h248.pkg.unknown.evt",
2300 FT_BYTES
, BASE_NONE
, NULL
, 0,
2303 { "Parameter", "h248.pkg.unknown.param",
2304 FT_BYTES
, BASE_NONE
, NULL
, 0,
2306 { &hf_h248_serviceChangeReasonStr
,
2307 { "ServiceChangeReasonStr", "h248.serviceChangeReasonstr",
2308 FT_STRING
, BASE_NONE
, NULL
, 0,
2309 "h248.IA5String", HFILL
}},
2310 { &hf_h248_context_id64
,
2311 { "contextId", "h248.contextId64",
2312 FT_UINT64
, BASE_HEX
, NULL
, 0,
2313 "Context ID", HFILL
}},
2314 { &hf_h248_transactionId64
,
2315 { "transactionId", "h248.transactionId",
2316 FT_UINT64
, BASE_DEC
, NULL
, 0,
2319 /* h248v1 support */
2320 { &hf_h248_auditValueReplyV1
,
2321 { "auditValueReplyV1", "h248.auditValueReplyV1",
2322 FT_NONE
, BASE_NONE
, NULL
, 0,
2325 #include "packet-h248-hfarr.c"
2327 GCP_HF_ARR_ELEMS("h248",h248_arrel
)
2331 /* List of subtrees */
2332 static int *ett
[] = {
2341 GCP_ETT_ARR_ELEMS(h248_arrel
),
2343 #include "packet-h248-ettarr.c"
2346 static ei_register_info ei
[] = {
2347 { &ei_h248_errored_command
, { "h248.errored_command", PI_RESPONSE_CODE
, PI_WARN
, "Errored Command", EXPFILL
}},
2348 { &ei_h248_transactionId64
, { "h248.transactionId.error", PI_MALFORMED
, PI_WARN
, "Transaction ID invalid", EXPFILL
}},
2349 { &ei_h248_context_id64
, { "h248.contextId.error", PI_MALFORMED
, PI_WARN
, "Context ID invalid", EXPFILL
}},
2350 { &ei_h248_octet_string_expected
, { "h248.octet_string_expected", PI_PROTOCOL
, PI_WARN
, "H.248 BER Error: OctetString expected", EXPFILL
}},
2353 expert_module_t
* expert_h248
;
2354 module_t
*h248_module
;
2356 /* Register protocol */
2357 proto_h248
= proto_register_protocol(PNAME
, PSNAME
, PFNAME
);
2358 h248_handle
= register_dissector("h248", dissect_h248
, proto_h248
);
2359 h248_tpkt_handle
= register_dissector("h248.tpkt", dissect_h248_tpkt
, proto_h248
);
2361 /* Register fields and subtrees */
2362 proto_register_field_array(proto_h248
, hf
, array_length(hf
));
2363 proto_register_subtree_array(ett
, array_length(ett
));
2364 expert_h248
= expert_register_protocol(proto_h248
);
2365 expert_register_field_array(expert_h248
, ei
, array_length(ei
));
2367 subdissector_table
= register_dissector_table("h248.magic_num", "H.248 Magic Num", proto_h248
, FT_UINT32
, BASE_HEX
);
2369 h248_module
= prefs_register_protocol(proto_h248
, NULL
);
2370 prefs_register_bool_preference(h248_module
, "ctx_info",
2372 "Maintain relationships between transactions and contexts and display an extra tree showing context data",
2373 &keep_persistent_data
);
2374 prefs_register_bool_preference(h248_module
, "desegment",
2375 "Desegment H.248 over TCP",
2376 "Desegment H.248 messages that span more TCP segments",
2379 gcp_msgs
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2380 gcp_trxs
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2381 gcp_ctxs_by_trx
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2382 gcp_ctxs
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
2384 h248_tap
= register_tap("h248");
2387 /*--- proto_reg_handoff_h248 -------------------------------------------*/
2388 void proto_reg_handoff_h248(void) {
2390 dissector_add_uint("mtp3.service_indicator", MTP_SI_GCP
, h248_handle
);
2391 h248_term_handle
= find_dissector_add_dependency("h248term", proto_h248
);
2392 dissector_add_uint_with_preference("tcp.port", H248_PORT
, h248_tpkt_handle
);
2393 dissector_add_uint_with_preference("udp.port", H248_PORT
, h248_handle
);
2395 ss7pc_address_type
= address_type_get_by_name("AT_SS7PC");
2396 exported_pdu_tap
= find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7
);