2 * Routines for Signaling Compression (SigComp) dissection.
3 * Copyright 2004-2005, Anders Broman <anders.broman@ericsson.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 * http://www.ietf.org/rfc/rfc3320.txt?number=3320
26 * http://www.ietf.org/rfc/rfc3321.txt?number=3321
27 * http://www.ietf.org/rfc/rfc4077.txt?number=4077
29 * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-impl-guide-03.txt
30 * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-sip-01.txt
38 #include <epan/packet.h>
39 #include <epan/prefs.h>
40 #include <epan/strutil.h>
41 #include <epan/expert.h>
42 #include <epan/wmem/wmem.h>
43 #include <epan/sigcomp-udvm.h>
44 #include <epan/sigcomp_state_hdlr.h>
46 /* Initialize the protocol and registered fields */
47 static int proto_sigcomp
= -1;
48 static int proto_raw_sigcomp
= -1;
49 static int hf_sigcomp_t_bit
= -1;
50 static int hf_sigcomp_len
= -1;
51 static int hf_sigcomp_returned_feedback_item
= -1;
52 static int hf_sigcomp_returned_feedback_item_len
= -1;
53 static int hf_sigcomp_code_len
= -1;
54 static int hf_sigcomp_destination
= -1;
55 static int hf_sigcomp_partial_state
= -1;
56 static int hf_sigcomp_remaining_message_bytes
= -1;
57 static int hf_sigcomp_compression_ratio
= -1;
58 static int hf_sigcomp_udvm_bytecode
= -1;
59 static int hf_sigcomp_udvm_instr
= -1;
60 static int hf_udvm_multitype_bytecode
= -1;
61 static int hf_udvm_reference_bytecode
= -1;
62 static int hf_udvm_literal_bytecode
= -1;
63 /* static int hf_udvm_operand = -1; */
64 static int hf_udvm_length
= -1;
65 static int hf_udvm_addr_length
= -1;
66 static int hf_udvm_destination
= -1;
67 static int hf_udvm_addr_destination
= -1;
68 static int hf_udvm_at_address
= -1;
69 static int hf_udvm_address
= -1;
70 static int hf_udvm_literal_num
= -1;
71 static int hf_udvm_value
= -1;
72 static int hf_udvm_addr_value
= -1;
73 static int hf_partial_identifier_start
= -1;
74 static int hf_partial_identifier_length
= -1;
75 static int hf_state_begin
= -1;
76 static int hf_udvm_state_length
= -1;
77 static int hf_udvm_state_length_addr
= -1;
78 static int hf_udvm_state_address
= -1;
79 static int hf_udvm_state_address_addr
= -1;
80 static int hf_udvm_state_instr
= -1;
81 static int hf_udvm_operand_1
= -1;
82 static int hf_udvm_operand_2
= -1;
83 static int hf_udvm_operand_2_addr
= -1;
84 static int hf_udvm_j
= -1;
85 static int hf_udvm_addr_j
= -1;
86 static int hf_udvm_output_start
= -1;
87 static int hf_udvm_addr_output_start
= -1;
88 static int hf_udvm_output_length
= -1;
89 static int hf_udvm_output_length_addr
= -1;
90 static int hf_udvm_req_feedback_loc
= -1;
91 static int hf_udvm_min_acc_len
= -1;
92 static int hf_udvm_state_ret_pri
= -1;
93 static int hf_udvm_ret_param_loc
= -1;
94 static int hf_udvm_position
= -1;
95 static int hf_udvm_ref_dest
= -1;
96 static int hf_udvm_bits
= -1;
97 static int hf_udvm_lower_bound
= -1;
98 static int hf_udvm_upper_bound
= -1;
99 static int hf_udvm_uncompressed
= -1;
100 static int hf_udvm_offset
= -1;
101 static int hf_udvm_addr_offset
= -1;
102 static int hf_udvm_start_value
= -1;
103 static int hf_udvm_execution_trace
= -1;
104 static int hf_sigcomp_nack_ver
= -1;
105 static int hf_sigcomp_nack_reason_code
= -1;
106 static int hf_sigcomp_nack_failed_op_code
= -1;
107 static int hf_sigcomp_nack_pc
= -1;
108 static int hf_sigcomp_nack_sha1
= -1;
109 static int hf_sigcomp_nack_state_id
= -1;
110 static int hf_sigcomp_nack_memory_size
= -1;
111 static int hf_sigcomp_nack_cycles_per_bit
= -1;
113 /* Initialize the subtree pointers */
114 static gint ett_sigcomp
= -1;
115 static gint ett_sigcomp_udvm
= -1;
116 static gint ett_sigcomp_udvm_exe
= -1;
117 static gint ett_raw_text
= -1;
119 static expert_field ei_sigcomp_nack_failed_op_code
= EI_INIT
;
121 static dissector_handle_t sip_handle
;
122 /* set the udp ports */
123 static guint SigCompUDPPort1
= 5555;
124 static guint SigCompUDPPort2
= 6666;
126 /* set the tcp ports */
127 static guint SigCompTCPPort1
= 5555;
128 static guint SigCompTCPPort2
= 6666;
130 /* Default preference whether to display the bytecode in UDVM operands or not */
131 static gboolean display_udvm_bytecode
= FALSE
;
132 /* Default preference whether to dissect the UDVM code or not */
133 static gboolean dissect_udvm_code
= TRUE
;
134 static gboolean display_raw_txt
= FALSE
;
135 /* Default preference whether to decompress the message or not */
136 static gboolean decompress
= TRUE
;
137 /* Default preference whether to print debug info at execution of UDVM
139 * 1 = details level 1
140 * 2 = details level 2
141 * 3 = details level 3
142 * 4 = details level 4
144 static gint udvm_print_detail_level
= 0;
147 static const value_string length_encoding_vals
[] = {
148 { 0x00, "No partial state (Message type 2)" },
149 { 0x01, "(6 bytes)" },
150 { 0x02, "(9 bytes)" },
151 { 0x03, "(12 bytes)" },
156 static const value_string destination_address_encoding_vals
[] = {
157 { 0x00, "Reserved" },
176 static const value_string udvm_instruction_code_vals
[] = {
177 { 0, "DECOMPRESSION-FAILURE" },
188 { 11, "SORT-ASCENDING" },
189 { 12, "SORT-DESCENDING" },
196 { 19, "COPY-LITERAL" },
197 { 20, "COPY-OFFSET" },
205 { 28, "INPUT-BYTES" },
206 { 29, "INPUT-BITS" },
207 { 30, "INPUT-HUFFMAN" },
208 { 31, "STATE-ACCESS" },
209 { 32, "STATE-CREATE" },
210 { 33, "STATE-FREE" },
212 { 35, "END-MESSAGE" },
216 * Figure 10: Bytecode for a multitype (%) operand
217 * Bytecode: Operand value: Range: HEX val
218 * 00nnnnnn N 0 - 63 0x00
219 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
220 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
221 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
222 * 111nnnnn N + 65504 65504 - 65535 0xe0
223 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
224 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
225 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
226 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
227 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
230 static const value_string display_bytecode_vals
[] = {
231 { 0x00, "00nnnnnn, N, 0 - 63" },
232 { 0x40, "01nnnnnn, memory[2 * N],0 - 65535" },
233 { 0x86, "1000011n, 2 ^ (N + 6), 64 , 128" },
234 { 0x88, "10001nnn, 2 ^ (N + 8), 256,..., 32768" },
235 { 0xe0, "111nnnnn N + 65504, 65504 - 65535" },
236 { 0x90, "1001nnnn nnnnnnnn, N + 61440, 61440 - 65535" },
237 { 0xa0, "101nnnnn nnnnnnnn, N, 0 - 8191" },
238 { 0xc0, "110nnnnn nnnnnnnn, memory[N], 0 - 65535" },
239 { 0x80, "10000000 nnnnnnnn nnnnnnnn, N, 0 - 65535" },
240 { 0x81, "10000001 nnnnnnnn nnnnnnnn, memory[N], 0 - 65535" },
244 * 0nnnnnnn memory[2 * N] 0 - 65535
245 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
246 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
248 static const value_string display_ref_bytecode_vals
[] = {
249 { 0x00, "0nnnnnnn memory[2 * N] 0 - 65535" },
250 { 0x80, "10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535" },
251 { 0xc0, "11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535" },
254 /* The simplest operand type is the literal (#), which encodes a
255 * constant integer from 0 to 65535 inclusive. A literal operand may
256 * require between 1 and 3 bytes depending on its value.
257 * Bytecode: Operand value: Range:
259 * 10nnnnnn nnnnnnnn N 0 - 16383
260 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
262 * Figure 8: Bytecode for a literal (#) operand
266 static const value_string display_lit_bytecode_vals
[] = {
267 { 0x00, "0nnnnnnn N 0 - 127" },
268 { 0x80, "10nnnnnn nnnnnnnn N 0 - 16383" },
269 { 0xc0, "11000000 nnnnnnnn nnnnnnnn N 0 - 65535" },
273 #define SIGCOMP_NACK_STATE_NOT_FOUND 1
274 #define SIGCOMP_NACK_CYCLES_EXHAUSTED 2
275 #define SIGCOMP_NACK_BYTECODES_TOO_LARGE 18
276 #define SIGCOMP_NACK_ID_NOT_UNIQUE 21
277 #define SIGCOMP_NACK_STATE_TOO_SHORT 23
279 static const value_string sigcomp_nack_reason_code_vals
[] = {
280 { 1, "STATE_NOT_FOUND" }, /*1 State ID (6 - 20 bytes) */
281 { 2, "CYCLES_EXHAUSTED" }, /*2 Cycles Per Bit (1 byte) */
282 { 3, "USER_REQUESTED" },
284 { 5, "TOO_MANY_STATE_REQUESTS" },
285 { 6, "INVALID_STATE_ID_LENGTH" },
286 { 7, "INVALID_STATE_PRIORITY" },
287 { 8, "OUTPUT_OVERFLOW" },
288 { 9, "STACK_UNDERFLOW" },
289 { 10, "BAD_INPUT_BITORDER" },
290 { 11, "DIV_BY_ZERO" },
291 { 12, "SWITCH_VALUE_TOO_HIGH" },
292 { 13, "TOO_MANY_BITS_REQUESTED" },
293 { 14, "INVALID_OPERAND" },
294 { 15, "HUFFMAN_NO_MATCH" },
295 { 16, "MESSAGE_TOO_SHORT" },
296 { 17, "INVALID_CODE_LOCATION" },
297 { 18, "BYTECODES_TOO_LARGE" }, /*18 Memory size (2 bytes) */
298 { 19, "INVALID_OPCODE" },
299 { 20, "INVALID_STATE_PROBE" },
300 { 21, "ID_NOT_UNIQUE" }, /*21 State ID (6 - 20 bytes) */
301 { 22, "MULTILOAD_OVERWRITTEN" },
302 { 23, "STATE_TOO_SHORT" }, /*23 State ID (6 - 20 bytes) */
303 { 24, "INTERNAL_ERROR" },
304 { 25, "FRAMING_ERROR" },
309 static void dissect_udvm_bytecode(tvbuff_t
*udvm_tvb
, proto_tree
*sigcomp_udvm_tree
, guint destination
);
311 static int dissect_udvm_multitype_operand(tvbuff_t
*udvm_tvb
, proto_tree
*sigcomp_udvm_tree
,
312 gint offset
,gboolean is_addr
,gint
*start_offset
,
313 guint16
*value
, gboolean
*is_memory_address
);
315 static int dissect_udvm_literal_operand(tvbuff_t
*udvm_tvb
, proto_tree
*sigcomp_udvm_tree
,
316 gint offset
, gint
*start_offset
, guint16
*value
);
318 static int dissect_udvm_reference_operand(tvbuff_t
*udvm_tvb
, proto_tree
*sigcomp_udvm_tree
,
319 gint offset
, gint
*start_offset
, guint16
*value
);
320 static void tvb_raw_text_add(tvbuff_t
*tvb
, proto_tree
*tree
);
322 static int dissect_sigcomp_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
324 static proto_tree
*top_tree
;
326 /* Initialize the state handler
330 sigcomp_init_protocol(void)
334 /* Sigcomp over TCP record marking used
336 * 4.2.2. Record Marking
338 * For a stream-based transport, the dispatcher delimits messages by
339 * parsing the compressed data stream for instances of 0xFF and taking
340 * the following actions:
341 * Occurs in data stream: Action:
343 * 0xFF 00 one 0xFF byte in the data stream
344 * 0xFF 01 same, but the next byte is quoted (could
347 * 0xFF 7F same, but the next 127 bytes are quoted
348 * 0xFF 80 to 0xFF FE (reserved for future standardization)
349 * 0xFF FF end of SigComp message
351 * In UDVM version 0x01, any occurrence of the combinations 0xFF80 to
352 * 0xFFFE that are not protected by quoting causes decompression
353 * failure; the decompressor SHOULD close the stream-based transport in
358 * TODO: Reassembly, handle more than one message in a tcp segment.
362 dissect_sigcomp_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *_data _U_
)
365 proto_tree
*sigcomp_tree
;
366 tvbuff_t
*unescaped_tvb
;
375 gboolean end_off_message
;
379 /* Is this SIGCOMP ? */
380 data
= tvb_get_ntohs(tvb
, offset
);
384 octet
= tvb_get_guint8(tvb
,offset
);
386 octet
= tvb_get_guint8(tvb
,offset
);
388 if ((octet
& 0xf8) != 0xf8)
391 /* Search for delimiter 0xffff in the remain tvb buffer */
392 length
= tvb_ensure_length_remaining(tvb
, offset
);
393 for(i
=0; i
<(length
-1); ++i
){
394 /* Loop end criteria is (length-1) because we take 2 bytes each loop */
395 data
= tvb_get_ntohs(tvb
, offset
+i
);
396 if (0xffff == data
) break;
398 if (i
>= (length
-1)){
399 /* SIGCOMP may be subdissector of SIP, so we use
400 * pinfo->saved_can_desegment to determine whether do desegment
401 * as well as pinfo->can_desegment */
402 if (pinfo
->can_desegment
|| pinfo
->saved_can_desegment
){
403 /* Delimiter oxffff was not found, not a complete SIGCOMP PDU */
404 pinfo
->desegment_offset
= offset
;
405 pinfo
->desegment_len
=DESEGMENT_ONE_MORE_SEGMENT
;
410 /* Make entries in Protocol column and Info column on summary display */
411 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "SIGCOMP");
413 col_clear(pinfo
->cinfo
, COL_INFO
);
415 length
= tvb_length_remaining(tvb
,offset
);
418 /* create display subtree for the protocol */
419 ti
= proto_tree_add_item(tree
, proto_sigcomp
, tvb
, 0, -1, ENC_NA
);
420 sigcomp_tree
= proto_item_add_subtree(ti
, ett_sigcomp
);
422 end_off_message
= FALSE
;
423 buff
= (guint8
*)wmem_alloc(pinfo
->pool
, length
-offset
);
424 if (udvm_print_detail_level
>2)
425 proto_tree_add_text(sigcomp_tree
, tvb
, offset
, -1,"Starting to remove escape digits");
426 while ((offset
< length
) && (end_off_message
== FALSE
)){
427 octet
= tvb_get_guint8(tvb
,offset
);
428 if ( octet
== 0xff ){
429 if ( offset
+1 >= length
){
430 /* if the tvb is short dont check for the second escape digit */
434 if (udvm_print_detail_level
>2)
435 proto_tree_add_text(sigcomp_tree
, tvb
, offset
, 2,
436 " Escape digit found (0xFF)");
437 octet
= tvb_get_guint8(tvb
, offset
+1);
444 if ((octet
> 0x7f) && (octet
< 0xff )){
445 if (udvm_print_detail_level
>2)
446 proto_tree_add_text(sigcomp_tree
, tvb
, offset
, 2,
447 " Illegal escape code");
448 offset
= offset
+ tvb_length_remaining(tvb
,offset
);
452 if (udvm_print_detail_level
>2)
453 proto_tree_add_text(sigcomp_tree
, tvb
, offset
, 2,
454 " End of SigComp message indication found (0xFFFF)");
455 end_off_message
= TRUE
;
460 if (udvm_print_detail_level
>2)
461 proto_tree_add_text(sigcomp_tree
, tvb
, offset
, 1,
462 " Addr: %u tvb value(0x%0x) ", i
, buff
[i
]);
465 if (udvm_print_detail_level
>2)
466 proto_tree_add_text(sigcomp_tree
, tvb
, offset
, octet
,
467 " Copying %u bytes literally",octet
);
468 if( offset
+octet
>= length
)
469 /* if the tvb is short dont copy further than the end */
470 octet
= length
- offset
;
471 for ( n
=0; n
< octet
; n
++ ){
472 buff
[i
] = tvb_get_guint8(tvb
, offset
);
473 if (udvm_print_detail_level
>2)
474 proto_tree_add_text(sigcomp_tree
, tvb
, offset
, 1,
475 " Addr: %u tvb value(0x%0x) ", i
, buff
[i
]);
482 if (udvm_print_detail_level
>2)
483 proto_tree_add_text(sigcomp_tree
, tvb
, offset
, 1,
484 " Addr: %u tvb value(0x%0x) ", i
, buff
[i
]);
489 unescaped_tvb
= tvb_new_child_real_data(tvb
, buff
,i
,i
);
491 add_new_data_source(pinfo
, unescaped_tvb
, "Unescaped Data handed to the SigComp dissector");
493 proto_tree_add_text(sigcomp_tree
, unescaped_tvb
, 0, -1,"Data handed to the Sigcomp dissector");
494 if (end_off_message
== TRUE
){
495 dissect_sigcomp_common(unescaped_tvb
, pinfo
, sigcomp_tree
);
497 proto_tree_add_text(sigcomp_tree
, unescaped_tvb
, 0, -1,"TCP Fragment, no end mark found");
499 if ( offset
< length
){
505 /* Code to actually dissect the packets */
507 dissect_sigcomp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
510 proto_tree
*sigcomp_tree
;
514 /* If we got called from SIP this might be over TCP */
515 if ( pinfo
->ptype
== PT_TCP
)
516 return dissect_sigcomp_tcp(tvb
, pinfo
, tree
, NULL
);
518 /* Is this a SigComp message or not ? */
519 octet
= tvb_get_guint8(tvb
, offset
);
520 if ((octet
& 0xf8) != 0xf8)
523 /* Make entries in Protocol column and Info column on summary display */
524 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "SIGCOMP");
526 col_clear(pinfo
->cinfo
, COL_INFO
);
530 /* create display subtree for the protocol */
531 ti
= proto_tree_add_item(tree
, proto_sigcomp
, tvb
, 0, -1, ENC_NA
);
532 sigcomp_tree
= proto_item_add_subtree(ti
, ett_sigcomp
);
534 return dissect_sigcomp_common(tvb
, pinfo
, sigcomp_tree
);
536 /* Code to actually dissect the packets */
538 dissect_sigcomp_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*sigcomp_tree
)
541 /* Set up structures needed to add the protocol subtree and manage it */
542 tvbuff_t
*udvm_tvb
, *msg_tvb
, *udvm2_tvb
;
543 tvbuff_t
*decomp_tvb
= NULL
;
544 proto_item
*udvm_bytecode_item
, *udvm_exe_item
;
545 proto_tree
*sigcomp_udvm_tree
, *sigcomp_udvm_exe_tree
;
547 gint bytecode_offset
;
548 guint16 partial_state_len
;
550 guint8 returned_feedback_field
[128];
551 guint8 partial_state
[12];
554 guint16 bytecode_len
= 0;
561 guint16 state_length
;
562 guint16 state_address
;
563 guint16 state_instruction
;
565 gchar
*partial_state_str
;
570 /* add an item to the subtree, see section 1.6 for more information */
571 octet
= tvb_get_guint8(tvb
, offset
);
573 /* A SigComp message takes one of two forms depending on whether it
574 * accesses a state item at the receiving endpoint. The two variants of
575 * a SigComp message are given in Figure 3. (The T-bit controls the
576 * format of the returned feedback item and is defined in Section 7.1.)
578 * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
579 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
580 * | 1 1 1 1 1 | T | len | | 1 1 1 1 1 | T | 0 |
581 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
583 * : returned feedback item : : returned feedback item :
585 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
587 * : partial state identifier : +---+---+---+---+---+---+---+---+
589 * | | | code_len | destination |
590 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
592 * : remaining SigComp message : : uploaded UDVM bytecode :
594 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
596 * : remaining SigComp message :
598 * +---+---+---+---+---+---+---+---+
601 * The format of the NACK message and the use of the fields within it
602 * are shown in Figure 1.
605 * +---+---+---+---+---+---+---+---+
606 * | 1 1 1 1 1 | T | 0 |
607 * +---+---+---+---+---+---+---+---+
609 * : returned feedback item :
611 * +---+---+---+---+---+---+---+---+
613 * +---+---+---+---+---+---+---+---+
614 * | code_len = 0 | version = 1 |
615 * +---+---+---+---+---+---+---+---+
617 * +---+---+---+---+---+---+---+---+
618 * | OPCODE of failed instruction |
619 * +---+---+---+---+---+---+---+---+
620 * | PC of failed instruction |
622 * +---+---+---+---+---+---+---+---+
624 * : SHA-1 Hash of failed message :
626 * +---+---+---+---+---+---+---+---+
630 * +---+---+---+---+---+---+---+---+
631 * Figure 1: SigComp NACK Message Format
634 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_t_bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
635 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
636 tbit
= ( octet
& 0x04)>>2;
637 partial_state_len
= octet
& 0x03;
639 if ( partial_state_len
!= 0 ){
641 * The len field encodes the number of transmitted bytes as follows:
643 * Encoding: Length of partial state identifier
650 partial_state_len
= partial_state_len
* 3 + 3;
655 col_set_str(pinfo
->cinfo
, COL_INFO
, "Msg format 1");
659 * Returned feedback item exists
662 octet
= tvb_get_guint8(tvb
, offset
);
663 /* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
664 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
665 * | 0 | returned_feedback_field | | 1 | returned_feedback_length |
666 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
668 * : returned_feedback_field :
670 * +---+---+---+---+---+---+---+---+
671 * Figure 4: Format of returned feedback item
674 if ( (octet
& 0x80) != 0 ){
676 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_returned_feedback_item_len
,
677 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
679 tvb_memcpy(tvb
,returned_feedback_field
,offset
, len
);
681 returned_feedback_field
[0] = tvb_get_guint8(tvb
, offset
) & 0x7f;
683 proto_tree_add_bytes(sigcomp_tree
,hf_sigcomp_returned_feedback_item
,
684 tvb
, offset
, len
, returned_feedback_field
);
685 offset
= offset
+ len
;
687 tvb_memcpy(tvb
, partial_state
, offset
, partial_state_len
);
688 partial_state_str
= bytes_to_str(partial_state
, partial_state_len
);
689 proto_tree_add_string(sigcomp_tree
,hf_sigcomp_partial_state
,
690 tvb
, offset
, partial_state_len
, partial_state_str
);
691 offset
= offset
+ partial_state_len
;
692 msg_len
= tvb_reported_length_remaining(tvb
, offset
);
696 ti
= proto_tree_add_uint(sigcomp_tree
, hf_sigcomp_remaining_message_bytes
, tvb
,
698 PROTO_ITEM_SET_GENERATED(ti
);
702 msg_tvb
= tvb_new_subset(tvb
, offset
, msg_len
, msg_len
);
704 * buff = Where "state" will be stored
705 * p_id_start = Partial state identifier start pos in the buffer(buff)
706 * partial_state_len = Partial state identifier length
707 * state_begin = Where to start to read state from
708 * state_length = Length of state
709 * state_address = Address where to store the state in the buffer(buff)
710 * state_instruction =
711 * TRUE = Indicates that state_* is in the stored state
714 * Note: The allocated buffer must be zeroed or some strange effects might occur.
716 buff
= (guint8
*)wmem_alloc0(pinfo
->pool
, UDVM_MEMORY_SIZE
);
721 /* These values will be loaded from the buffered state in sigcomp_state_hdlr
725 state_instruction
=0;
728 while ( i
< partial_state_len
){
729 buff
[i
] = partial_state
[i
];
733 /* begin partial state-id change cco@iptel.org */
735 result_code
= udvm_state_access(tvb
, sigcomp_tree
, buff
, p_id_start
, partial_state_len
, state_begin
, &state_length
,
736 &state_address
, &state_instruction
, hf_sigcomp_partial_state
);
738 result_code
= udvm_state_access(tvb
, sigcomp_tree
, buff
, p_id_start
, STATE_MIN_ACCESS_LEN
, state_begin
, &state_length
,
739 &state_address
, &state_instruction
, hf_sigcomp_partial_state
);
741 /* end partial state-id change cco@iptel.org */
742 if ( result_code
!= 0 ){
744 ti
= proto_tree_add_text(sigcomp_tree
, tvb
, 0, -1,"Failed to Access state Wireshark UDVM diagnostic: %s.",
745 val_to_str(result_code
, result_code_vals
,"Unknown (%u)"));
746 PROTO_ITEM_SET_GENERATED(ti
);
747 return tvb_length(tvb
);
750 udvm_tvb
= tvb_new_child_real_data(tvb
, buff
,state_length
+state_address
,state_length
+state_address
);
751 add_new_data_source(pinfo
, udvm_tvb
, "State/ExecutionTrace");
753 udvm2_tvb
= tvb_new_subset(udvm_tvb
, state_address
, state_length
, state_length
);
754 udvm_exe_item
= proto_tree_add_item(sigcomp_tree
, hf_udvm_execution_trace
,
755 udvm2_tvb
, 0, state_length
,
757 sigcomp_udvm_exe_tree
= proto_item_add_subtree( udvm_exe_item
, ett_sigcomp_udvm_exe
);
759 decomp_tvb
= decompress_sigcomp_message(udvm2_tvb
, msg_tvb
, pinfo
,
760 sigcomp_udvm_exe_tree
, state_address
,
761 udvm_print_detail_level
, hf_sigcomp_partial_state
,
762 offset
, state_length
, partial_state_len
, state_instruction
);
767 guint32 compression_ratio
=
768 (guint32
)(((float)tvb_length(decomp_tvb
) / (float)tvb_length(tvb
)) * 100);
770 /* Celebrate success and show compression ratio achieved */
771 proto_tree_add_text(sigcomp_tree
, decomp_tvb
, 0, -1,"SigComp message Decompressed WOHO!!");
772 ti
= proto_tree_add_uint(sigcomp_tree
, hf_sigcomp_compression_ratio
, decomp_tvb
,
773 0, 0, compression_ratio
);
774 PROTO_ITEM_SET_GENERATED(ti
);
776 if ( display_raw_txt
)
777 tvb_raw_text_add(decomp_tvb
, top_tree
);
779 col_append_str(pinfo
->cinfo
, COL_PROTOCOL
, "/");
780 col_set_fence(pinfo
->cinfo
,COL_PROTOCOL
);
781 call_dissector(sip_handle
, decomp_tvb
, pinfo
, top_tree
);
790 col_set_str(pinfo
->cinfo
, COL_INFO
, "Msg format 2");
793 * Returned feedback item exists
796 octet
= tvb_get_guint8(tvb
, offset
);
797 if ( (octet
& 0x80) != 0 ){
799 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_returned_feedback_item_len
,
800 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
803 tvb_memcpy(tvb
,returned_feedback_field
,offset
, len
);
804 proto_tree_add_bytes(sigcomp_tree
,hf_sigcomp_returned_feedback_item
,
805 tvb
, offset
, len
, returned_feedback_field
);
806 offset
= offset
+ len
;
808 len
= tvb_get_ntohs(tvb
, offset
) >> 4;
809 nack_version
= tvb_get_guint8(tvb
, offset
+1) & 0x0f;
810 if ((len
== 0) && (nack_version
== 1)){
812 proto_item
*reason_ti
;
815 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_nack_ver
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
817 octet
= tvb_get_guint8(tvb
, offset
);
818 reason_ti
= proto_tree_add_item(sigcomp_tree
,hf_sigcomp_nack_reason_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
820 opcode
= tvb_get_guint8(tvb
, offset
);
821 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_nack_failed_op_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
824 /* Add expert item for NACK */
825 expert_add_info_format(pinfo
, reason_ti
, &ei_sigcomp_nack_failed_op_code
,
826 "SigComp NACK (reason=%s, opcode=%s)",
827 val_to_str_const(octet
, sigcomp_nack_reason_code_vals
, "Unknown"),
828 val_to_str_const(opcode
, udvm_instruction_code_vals
, "Unknown"));
830 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_nack_pc
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
832 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_nack_sha1
, tvb
, offset
, 20, ENC_NA
);
835 /* Add NACK info to info column */
836 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " NACK reason=%s, opcode=%s",
837 val_to_str_const(octet
, sigcomp_nack_reason_code_vals
, "Unknown"),
838 val_to_str_const(opcode
, udvm_instruction_code_vals
, "Unknown"));
841 case SIGCOMP_NACK_STATE_NOT_FOUND
:
842 case SIGCOMP_NACK_ID_NOT_UNIQUE
:
843 case SIGCOMP_NACK_STATE_TOO_SHORT
:
844 /* State ID (6 - 20 bytes) */
845 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_nack_state_id
, tvb
, offset
, -1, ENC_NA
);
847 case SIGCOMP_NACK_CYCLES_EXHAUSTED
:
848 /* Cycles Per Bit (1 byte) */
849 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_nack_cycles_per_bit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
851 case SIGCOMP_NACK_BYTECODES_TOO_LARGE
:
852 /* Memory size (2 bytes) */
853 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_nack_memory_size
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
859 octet
= tvb_get_guint8(tvb
, (offset
+ 1));
860 destination
= (octet
& 0x0f);
861 if ( destination
!= 0 )
862 destination
= 64 + ( destination
* 64 );
863 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_code_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
864 proto_tree_add_item(sigcomp_tree
,hf_sigcomp_destination
, tvb
, (offset
+ 1), 1, ENC_BIG_ENDIAN
);
868 bytecode_offset
= offset
;
869 udvm_bytecode_item
= proto_tree_add_item(sigcomp_tree
, hf_sigcomp_udvm_bytecode
, tvb
,
870 bytecode_offset
, bytecode_len
, ENC_NA
);
871 proto_item_append_text(udvm_bytecode_item
,
872 " %u (0x%x) bytes", bytecode_len
, bytecode_len
);
873 sigcomp_udvm_tree
= proto_item_add_subtree( udvm_bytecode_item
, ett_sigcomp_udvm
);
875 udvm_tvb
= tvb_new_subset(tvb
, offset
, len
, len
);
876 if ( dissect_udvm_code
)
877 dissect_udvm_bytecode(udvm_tvb
, sigcomp_udvm_tree
, destination
);
879 offset
= offset
+ len
;
880 msg_len
= tvb_reported_length_remaining(tvb
, offset
);
882 proto_item
*ti
= proto_tree_add_text(sigcomp_tree
, tvb
, offset
, -1,
883 "Remaining SigComp message %u bytes",
884 tvb_reported_length_remaining(tvb
, offset
));
885 PROTO_ITEM_SET_GENERATED(ti
);
889 msg_tvb
= tvb_new_subset(tvb
, offset
, msg_len
, msg_len
);
891 udvm_exe_item
= proto_tree_add_item(sigcomp_tree
, hf_udvm_execution_trace
,
892 tvb
, bytecode_offset
, bytecode_len
,
894 sigcomp_udvm_exe_tree
= proto_item_add_subtree( udvm_exe_item
, ett_sigcomp_udvm_exe
);
895 decomp_tvb
= decompress_sigcomp_message(udvm_tvb
, msg_tvb
, pinfo
,
896 sigcomp_udvm_exe_tree
, destination
,
897 udvm_print_detail_level
, hf_sigcomp_partial_state
,
898 offset
, 0, 0, destination
);
901 guint32 compression_ratio
=
902 (guint32
)(((float)tvb_length(decomp_tvb
) / (float)tvb_length(tvb
)) * 100);
904 /* Celebrate success and show compression ratio achieved */
905 proto_tree_add_text(sigcomp_tree
, decomp_tvb
, 0, -1,"SigComp message Decompressed WOHO!!");
906 ti
= proto_tree_add_uint(sigcomp_tree
, hf_sigcomp_compression_ratio
, decomp_tvb
,
907 0, 0, compression_ratio
);
908 PROTO_ITEM_SET_GENERATED(ti
);
910 if ( display_raw_txt
)
911 tvb_raw_text_add(decomp_tvb
, top_tree
);
913 col_append_str(pinfo
->cinfo
, COL_PROTOCOL
, "/");
914 col_set_fence(pinfo
->cinfo
,COL_PROTOCOL
);
915 call_dissector(sip_handle
, decomp_tvb
, pinfo
, top_tree
);
917 } /* if decompress */
921 return tvb_length(tvb
);
925 #define SIGCOMP_INSTR_DECOMPRESSION_FAILURE 0
926 #define SIGCOMP_INSTR_AND 1
927 #define SIGCOMP_INSTR_OR 2
928 #define SIGCOMP_INSTR_NOT 3
929 #define SIGCOMP_INSTR_LSHIFT 4
930 #define SIGCOMP_INSTR_RSHIFT 5
931 #define SIGCOMP_INSTR_ADD 6
932 #define SIGCOMP_INSTR_SUBTRACT 7
933 #define SIGCOMP_INSTR_MULTIPLY 8
934 #define SIGCOMP_INSTR_DIVIDE 9
935 #define SIGCOMP_INSTR_REMAINDER 10
936 #define SIGCOMP_INSTR_SORT_ASCENDING 11
937 #define SIGCOMP_INSTR_SORT_DESCENDING 12
938 #define SIGCOMP_INSTR_SHA_1 13
939 #define SIGCOMP_INSTR_LOAD 14
940 #define SIGCOMP_INSTR_MULTILOAD 15
941 #define SIGCOMP_INSTR_PUSH 16
942 #define SIGCOMP_INSTR_POP 17
943 #define SIGCOMP_INSTR_COPY 18
944 #define SIGCOMP_INSTR_COPY_LITERAL 19
945 #define SIGCOMP_INSTR_COPY_OFFSET 20
946 #define SIGCOMP_INSTR_MEMSET 21
947 #define SIGCOMP_INSTR_JUMP 22
948 #define SIGCOMP_INSTR_COMPARE 23
949 #define SIGCOMP_INSTR_CALL 24
950 #define SIGCOMP_INSTR_RETURN 25
951 #define SIGCOMP_INSTR_SWITCH 26
952 #define SIGCOMP_INSTR_CRC 27
953 #define SIGCOMP_INSTR_INPUT_BYTES 28
954 #define SIGCOMP_INSTR_INPUT_BITS 29
955 #define SIGCOMP_INSTR_INPUT_HUFFMAN 30
956 #define SIGCOMP_INSTR_STATE_ACCESS 31
957 #define SIGCOMP_INSTR_STATE_CREATE 32
958 #define SIGCOMP_INSTR_STATE_FREE 33
959 #define SIGCOMP_INSTR_OUTPUT 34
960 #define SIGCOMP_INSTR_END_MESSAGE 35
964 dissect_udvm_bytecode(tvbuff_t
*udvm_tvb
, proto_tree
*sigcomp_udvm_tree
,guint start_address
)
968 gint start_offset
= 0;
971 guint instruction_no
= 0;
973 proto_item
*item
, *item2
;
974 guint UDVM_address
= start_address
;
975 gboolean is_memory_address
;
976 guint16 msg_length
= tvb_reported_length_remaining(udvm_tvb
, offset
);
979 while (msg_length
> offset
) {
980 instruction
= tvb_get_guint8(udvm_tvb
, offset
);
982 UDVM_address
= start_address
+ offset
;
985 item
= proto_tree_add_text(sigcomp_udvm_tree
, udvm_tvb
, offset
, 1,
986 "######### UDVM instruction %u at UDVM-address %u (0x%x) #########",
987 instruction_no
,UDVM_address
,UDVM_address
);
988 PROTO_ITEM_SET_GENERATED(item
);
989 proto_tree_add_item(sigcomp_udvm_tree
, hf_sigcomp_udvm_instr
, udvm_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
991 switch ( instruction
) {
993 case SIGCOMP_INSTR_AND
: /* 1 AND ($operand_1, %operand_2) */
995 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
996 len
= offset
- start_offset
;
997 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_1
,
998 udvm_tvb
, start_offset
, len
, value
);
1000 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1001 len
= offset
- start_offset
;
1002 if ( is_memory_address
){
1003 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2_addr
,
1004 udvm_tvb
, start_offset
, len
, value
);
1006 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2
,
1007 udvm_tvb
, start_offset
, len
, value
);
1011 case SIGCOMP_INSTR_OR
: /* 2 OR ($operand_1, %operand_2) */
1013 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1014 len
= offset
- start_offset
;
1015 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_1
,
1016 udvm_tvb
, start_offset
, len
, value
);
1018 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1019 len
= offset
- start_offset
;
1020 if ( is_memory_address
){
1021 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2_addr
,
1022 udvm_tvb
, start_offset
, len
, value
);
1024 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2
,
1025 udvm_tvb
, start_offset
, len
, value
);
1029 case SIGCOMP_INSTR_NOT
: /* 3 NOT ($operand_1) */
1031 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1032 len
= offset
- start_offset
;
1033 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_1
,
1034 udvm_tvb
, start_offset
, len
, value
);
1037 case SIGCOMP_INSTR_LSHIFT
: /* 4 LSHIFT ($operand_1, %operand_2) */
1039 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1040 len
= offset
- start_offset
;
1041 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_1
,
1042 udvm_tvb
, start_offset
, len
, value
);
1044 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1045 len
= offset
- start_offset
;
1046 if ( is_memory_address
){
1047 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2_addr
,
1048 udvm_tvb
, start_offset
, len
, value
);
1050 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2
,
1051 udvm_tvb
, start_offset
, len
, value
);
1055 case SIGCOMP_INSTR_RSHIFT
: /* 5 RSHIFT ($operand_1, %operand_2) */
1057 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1058 len
= offset
- start_offset
;
1059 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_1
,
1060 udvm_tvb
, start_offset
, len
, value
);
1062 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1063 len
= offset
- start_offset
;
1064 if ( is_memory_address
){
1065 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2_addr
,
1066 udvm_tvb
, start_offset
, len
, value
);
1068 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2
,
1069 udvm_tvb
, start_offset
, len
, value
);
1073 case SIGCOMP_INSTR_ADD
: /* 6 ADD ($operand_1, %operand_2) */
1075 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1076 len
= offset
- start_offset
;
1077 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_1
,
1078 udvm_tvb
, start_offset
, len
, value
);
1080 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1081 len
= offset
- start_offset
;
1082 if ( is_memory_address
){
1083 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2_addr
,
1084 udvm_tvb
, start_offset
, len
, value
);
1086 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2
,
1087 udvm_tvb
, start_offset
, len
, value
);
1091 case SIGCOMP_INSTR_SUBTRACT
: /* 7 SUBTRACT ($operand_1, %operand_2) */
1093 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1094 len
= offset
- start_offset
;
1095 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_1
,
1096 udvm_tvb
, start_offset
, len
, value
);
1098 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1099 len
= offset
- start_offset
;
1100 if ( is_memory_address
){
1101 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2_addr
,
1102 udvm_tvb
, start_offset
, len
, value
);
1104 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2
,
1105 udvm_tvb
, start_offset
, len
, value
);
1109 case SIGCOMP_INSTR_MULTIPLY
: /* 8 MULTIPLY ($operand_1, %operand_2) */
1111 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1112 len
= offset
- start_offset
;
1113 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_1
,
1114 udvm_tvb
, start_offset
, len
, value
);
1116 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1117 len
= offset
- start_offset
;
1118 if ( is_memory_address
){
1119 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2_addr
,
1120 udvm_tvb
, start_offset
, len
, value
);
1122 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2
,
1123 udvm_tvb
, start_offset
, len
, value
);
1127 case SIGCOMP_INSTR_DIVIDE
: /* 9 DIVIDE ($operand_1, %operand_2) */
1129 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1130 len
= offset
- start_offset
;
1131 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_1
,
1132 udvm_tvb
, start_offset
, len
, value
);
1134 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1135 len
= offset
- start_offset
;
1136 if ( is_memory_address
){
1137 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2_addr
,
1138 udvm_tvb
, start_offset
, len
, value
);
1140 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2
,
1141 udvm_tvb
, start_offset
, len
, value
);
1145 case SIGCOMP_INSTR_REMAINDER
: /* 10 REMAINDER ($operand_1, %operand_2) */
1147 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1148 len
= offset
- start_offset
;
1149 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_1
,
1150 udvm_tvb
, start_offset
, len
, value
);
1152 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1153 len
= offset
- start_offset
;
1154 if ( is_memory_address
){
1155 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2_addr
,
1156 udvm_tvb
, start_offset
, len
, value
);
1158 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_operand_2
,
1159 udvm_tvb
, start_offset
, len
, value
);
1162 case SIGCOMP_INSTR_SORT_ASCENDING
: /* 11 SORT-ASCENDING (%start, %n, %k) */
1163 /* while programming stop while loop */
1164 offset
= offset
+ tvb_reported_length_remaining(udvm_tvb
, offset
);
1167 case SIGCOMP_INSTR_SORT_DESCENDING
: /* 12 SORT-DESCENDING (%start, %n, %k) */
1168 offset
= offset
+ tvb_reported_length_remaining(udvm_tvb
, offset
);
1170 case SIGCOMP_INSTR_SHA_1
: /* 13 SHA-1 (%position, %length, %destination) */
1172 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1173 len
= offset
- start_offset
;
1174 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_position
,
1175 udvm_tvb
, start_offset
, len
, value
);
1178 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1179 len
= offset
- start_offset
;
1180 if ( is_memory_address
){
1181 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_length
,
1182 udvm_tvb
, start_offset
, len
, value
);
1184 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_length
,
1185 udvm_tvb
, start_offset
, len
, value
);
1189 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1190 len
= offset
- start_offset
;
1191 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_ref_dest
,
1192 udvm_tvb
, start_offset
, len
, value
);
1195 case SIGCOMP_INSTR_LOAD
: /* 14 LOAD (%address, %value) */
1197 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
,&start_offset
, &value
, &is_memory_address
);
1198 len
= offset
- start_offset
;
1199 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_address
,
1200 udvm_tvb
, start_offset
, len
, value
);
1202 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1203 len
= offset
- start_offset
;
1204 if ( is_memory_address
){
1205 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_value
,
1206 udvm_tvb
, start_offset
, len
, value
);
1208 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_value
,
1209 udvm_tvb
, start_offset
, len
, value
);
1213 case SIGCOMP_INSTR_MULTILOAD
: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
1215 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1216 len
= offset
- start_offset
;
1217 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_address
,
1218 udvm_tvb
, start_offset
, len
, value
);
1220 offset
= dissect_udvm_literal_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1221 len
= offset
- start_offset
;
1222 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_literal_num
,
1223 udvm_tvb
, start_offset
, len
, value
);
1228 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1229 len
= offset
- start_offset
;
1230 if ( is_memory_address
){
1231 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_value
,
1232 udvm_tvb
, start_offset
, len
, value
);
1234 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_value
,
1235 udvm_tvb
, start_offset
, len
, value
);
1240 case SIGCOMP_INSTR_PUSH
: /* 16 PUSH (%value) */
1242 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1243 len
= offset
- start_offset
;
1244 if ( is_memory_address
){
1245 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_value
,
1246 udvm_tvb
, start_offset
, len
, value
);
1248 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_value
,
1249 udvm_tvb
, start_offset
, len
, value
);
1253 case SIGCOMP_INSTR_POP
: /* 17 POP (%address) */
1255 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1257 len
= offset
- start_offset
;
1258 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_address
,
1259 udvm_tvb
, start_offset
, len
, value
);
1262 case SIGCOMP_INSTR_COPY
: /* 18 COPY (%position, %length, %destination) */
1264 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1265 len
= offset
- start_offset
;
1266 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_position
,
1267 udvm_tvb
, start_offset
, len
, value
);
1270 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1271 len
= offset
- start_offset
;
1272 if ( is_memory_address
){
1273 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_length
,
1274 udvm_tvb
, start_offset
, len
, value
);
1276 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_length
,
1277 udvm_tvb
, start_offset
, len
, value
);
1281 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1282 len
= offset
- start_offset
;
1283 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_ref_dest
,
1284 udvm_tvb
, start_offset
, len
, value
);
1287 case SIGCOMP_INSTR_COPY_LITERAL
: /* 19 COPY-LITERAL (%position, %length, $destination) */
1289 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1290 len
= offset
- start_offset
;
1291 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_position
,
1292 udvm_tvb
, start_offset
, len
, value
);
1295 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1296 len
= offset
- start_offset
;
1297 if ( is_memory_address
){
1298 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_length
,
1299 udvm_tvb
, start_offset
, len
, value
);
1301 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_length
,
1302 udvm_tvb
, start_offset
, len
, value
);
1306 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1307 len
= offset
- start_offset
;
1308 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_ref_dest
,
1309 udvm_tvb
, start_offset
, len
, value
);
1312 case SIGCOMP_INSTR_COPY_OFFSET
: /* 20 COPY-OFFSET (%offset, %length, $destination) */
1314 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1315 len
= offset
- start_offset
;
1316 if ( is_memory_address
){
1317 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_offset
,
1318 udvm_tvb
, start_offset
, len
, value
);
1320 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_offset
,
1321 udvm_tvb
, start_offset
, len
, value
);
1325 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1326 len
= offset
- start_offset
;
1327 if ( is_memory_address
){
1328 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_length
,
1329 udvm_tvb
, start_offset
, len
, value
);
1331 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_length
,
1332 udvm_tvb
, start_offset
, len
, value
);
1336 offset
= dissect_udvm_reference_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1337 len
= offset
- start_offset
;
1338 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_ref_dest
,
1339 udvm_tvb
, start_offset
, len
, value
);
1341 case SIGCOMP_INSTR_MEMSET
: /* 21 MEMSET (%address, %length, %start_value, %offset) */
1344 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1345 len
= offset
- start_offset
;
1346 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_address
,
1347 udvm_tvb
, start_offset
, len
, value
);
1350 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
, &start_offset
, &value
, &is_memory_address
);
1351 len
= offset
- start_offset
;
1352 if ( is_memory_address
){
1353 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_length
,
1354 udvm_tvb
, start_offset
, len
, value
);
1356 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_length
,
1357 udvm_tvb
, start_offset
, len
, value
);
1361 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1362 len
= offset
- start_offset
;
1363 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_start_value
,
1364 udvm_tvb
, start_offset
, len
, value
);
1367 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1368 len
= offset
- start_offset
;
1369 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_offset
,
1370 udvm_tvb
, start_offset
, len
, value
);
1374 case SIGCOMP_INSTR_JUMP
: /* 22 JUMP (@address) */
1376 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1377 len
= offset
- start_offset
;
1378 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1379 value
= ( value
+ UDVM_address
) & 0xffff;
1380 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_at_address
,
1381 udvm_tvb
, start_offset
, len
, value
);
1384 case SIGCOMP_INSTR_COMPARE
: /* 23 */
1385 /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
1388 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1389 len
= offset
- start_offset
;
1390 if ( is_memory_address
){
1391 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_value
,
1392 udvm_tvb
, start_offset
, len
, value
);
1394 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_value
,
1395 udvm_tvb
, start_offset
, len
, value
);
1399 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1400 len
= offset
- start_offset
;
1401 if ( is_memory_address
){
1402 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_value
,
1403 udvm_tvb
, start_offset
, len
, value
);
1405 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_value
,
1406 udvm_tvb
, start_offset
, len
, value
);
1410 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1411 len
= offset
- start_offset
;
1412 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1413 value
= ( value
+ UDVM_address
) & 0xffff;
1414 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_at_address
,
1415 udvm_tvb
, start_offset
, len
, value
);
1418 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1419 len
= offset
- start_offset
;
1420 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1421 value
= ( value
+ UDVM_address
) & 0xffff;
1422 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_at_address
,
1423 udvm_tvb
, start_offset
, len
, value
);
1426 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1427 len
= offset
- start_offset
;
1428 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1429 value
= ( value
+ UDVM_address
) & 0xffff;
1430 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_at_address
,
1431 udvm_tvb
, start_offset
, len
, value
);
1434 case SIGCOMP_INSTR_CALL
: /* 24 CALL (@address) (PUSH addr )*/
1436 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1437 len
= offset
- start_offset
;
1438 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1439 value
= ( value
+ UDVM_address
) & 0xffff;
1440 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_at_address
,
1441 udvm_tvb
, start_offset
, len
, value
);
1443 case SIGCOMP_INSTR_RETURN
: /* 25 POP and return */
1447 case SIGCOMP_INSTR_SWITCH
: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
1449 offset
= dissect_udvm_literal_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1450 len
= offset
- start_offset
;
1451 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_literal_num
,
1452 udvm_tvb
, start_offset
, len
, value
);
1454 /* Number of addresses in the instruction */
1457 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1458 len
= offset
- start_offset
;
1459 if ( is_memory_address
){
1460 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_j
,
1461 udvm_tvb
, start_offset
, len
, value
);
1463 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_j
,
1464 udvm_tvb
, start_offset
, len
, value
);
1470 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
,&start_offset
, &value
, &is_memory_address
);
1471 len
= offset
- start_offset
;
1472 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1473 value
= ( value
+ UDVM_address
) & 0xffff;
1474 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_at_address
,
1475 udvm_tvb
, start_offset
, len
, value
);
1478 case SIGCOMP_INSTR_CRC
: /* 27 CRC (%value, %position, %length, @address) */
1480 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1481 len
= offset
- start_offset
;
1482 if ( is_memory_address
){
1483 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_value
,
1484 udvm_tvb
, start_offset
, len
, value
);
1486 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_value
,
1487 udvm_tvb
, start_offset
, len
, value
);
1491 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1492 len
= offset
- start_offset
;
1493 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_position
,
1494 udvm_tvb
, start_offset
, len
, value
);
1497 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1498 len
= offset
- start_offset
;
1499 if ( is_memory_address
){
1500 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_length
,
1501 udvm_tvb
, start_offset
, len
, value
);
1503 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_length
,
1504 udvm_tvb
, start_offset
, len
, value
);
1508 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1509 len
= offset
- start_offset
;
1510 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1511 value
= ( value
+ UDVM_address
) & 0xffff;
1512 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_at_address
,
1513 udvm_tvb
, start_offset
, len
, value
);
1517 case SIGCOMP_INSTR_INPUT_BYTES
: /* 28 INPUT-BYTES (%length, %destination, @address) */
1519 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1520 len
= offset
- start_offset
;
1521 if ( is_memory_address
){
1522 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_length
,
1523 udvm_tvb
, start_offset
, len
, value
);
1525 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_length
,
1526 udvm_tvb
, start_offset
, len
, value
);
1530 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1531 len
= offset
- start_offset
;
1532 if ( is_memory_address
){
1533 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_destination
,
1534 udvm_tvb
, start_offset
, len
, value
);
1536 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_destination
,
1537 udvm_tvb
, start_offset
, len
, value
);
1541 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1542 len
= offset
- start_offset
;
1543 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1544 value
= ( value
+ UDVM_address
) & 0xffff;
1545 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_at_address
,
1546 udvm_tvb
, start_offset
, len
, value
);
1548 case SIGCOMP_INSTR_INPUT_BITS
:/* 29 INPUT-BITS (%length, %destination, @address) */
1550 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1551 len
= offset
- start_offset
;
1552 if ( is_memory_address
){
1553 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_length
,
1554 udvm_tvb
, start_offset
, len
, value
);
1556 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_length
,
1557 udvm_tvb
, start_offset
, len
, value
);
1561 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1562 len
= offset
- start_offset
;
1563 if ( is_memory_address
){
1564 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_destination
,
1565 udvm_tvb
, start_offset
, len
, value
);
1567 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_destination
,
1568 udvm_tvb
, start_offset
, len
, value
);
1572 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1573 len
= offset
- start_offset
;
1574 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1575 value
= ( value
+ UDVM_address
) & 0xffff;
1576 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_at_address
,
1577 udvm_tvb
, start_offset
, len
, value
);
1579 case SIGCOMP_INSTR_INPUT_HUFFMAN
: /* 30 */
1581 * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1,
1582 * %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n,
1583 * %upper_bound_n, %uncompressed_n)
1586 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1587 len
= offset
- start_offset
;
1588 if ( is_memory_address
){
1589 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_destination
,
1590 udvm_tvb
, start_offset
, len
, value
);
1592 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_destination
,
1593 udvm_tvb
, start_offset
, len
, value
);
1596 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1597 len
= offset
- start_offset
;
1598 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1599 value
= ( value
+ UDVM_address
) & 0xffff;
1600 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_at_address
,
1601 udvm_tvb
, start_offset
, len
, value
);
1603 offset
= dissect_udvm_literal_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, &start_offset
, &value
);
1604 len
= offset
- start_offset
;
1605 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_literal_num
,
1606 udvm_tvb
, start_offset
, len
, value
);
1611 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1612 len
= offset
- start_offset
;
1613 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_bits
,
1614 udvm_tvb
, start_offset
, len
, value
);
1616 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1617 len
= offset
- start_offset
;
1618 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_lower_bound
,
1619 udvm_tvb
, start_offset
, len
, value
);
1620 /* %upper_bound_n */
1621 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1622 len
= offset
- start_offset
;
1623 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_upper_bound
,
1624 udvm_tvb
, start_offset
, len
, value
);
1625 /* %uncompressed_n */
1626 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, FALSE
,&start_offset
, &value
, &is_memory_address
);
1627 len
= offset
- start_offset
;
1628 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_uncompressed
,
1629 udvm_tvb
, start_offset
, len
, value
);
1633 case SIGCOMP_INSTR_STATE_ACCESS
: /* 31 */
1634 /* STATE-ACCESS (%partial_identifier_start, %partial_identifier_length,
1635 * %state_begin, %state_length, %state_address, %state_instruction)
1639 * %partial_identifier_start
1641 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
,&is_memory_address
);
1642 len
= offset
- start_offset
;
1643 proto_tree_add_uint(sigcomp_udvm_tree
, hf_partial_identifier_start
,
1644 udvm_tvb
, start_offset
, len
, value
);
1647 * %partial_identifier_length
1649 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
,&is_memory_address
);
1650 len
= offset
- start_offset
;
1651 proto_tree_add_uint(sigcomp_udvm_tree
, hf_partial_identifier_length
,
1652 udvm_tvb
, start_offset
, len
, value
);
1656 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1657 len
= offset
- start_offset
;
1658 proto_tree_add_uint(sigcomp_udvm_tree
, hf_state_begin
,
1659 udvm_tvb
, start_offset
, len
, value
);
1664 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1665 len
= offset
- start_offset
;
1666 if ( is_memory_address
) {
1667 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_length_addr
,
1668 udvm_tvb
, start_offset
, len
, value
);
1670 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_length
,
1671 udvm_tvb
, start_offset
, len
, value
);
1676 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
,&is_memory_address
);
1677 len
= offset
- start_offset
;
1678 if ( is_memory_address
) {
1679 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_address_addr
,
1680 udvm_tvb
, start_offset
, len
, value
);
1682 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_address
,
1683 udvm_tvb
, start_offset
, len
, value
);
1686 * %state_instruction
1688 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1689 len
= offset
- start_offset
;
1690 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_instr
,
1691 udvm_tvb
, start_offset
, len
, value
);
1693 case SIGCOMP_INSTR_STATE_CREATE
: /* 32 */
1695 * STATE-CREATE (%state_length, %state_address, %state_instruction,
1696 * %minimum_access_length, %state_retention_priority)
1702 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1703 len
= offset
- start_offset
;
1704 if ( is_memory_address
) {
1705 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_length_addr
,
1706 udvm_tvb
, start_offset
, len
, value
);
1708 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_length
,
1709 udvm_tvb
, start_offset
, len
, value
);
1714 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1715 len
= offset
- start_offset
;
1716 if ( is_memory_address
) {
1717 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_address_addr
,
1718 udvm_tvb
, start_offset
, len
, value
);
1720 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_address
,
1721 udvm_tvb
, start_offset
, len
, value
);
1724 * %state_instruction
1726 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1727 len
= offset
- start_offset
;
1728 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_instr
,
1729 udvm_tvb
, start_offset
, len
, value
);
1731 * %minimum_access_length
1733 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1734 len
= offset
- start_offset
;
1735 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_min_acc_len
,
1736 udvm_tvb
, start_offset
, len
, value
);
1738 * %state_retention_priority
1740 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1741 len
= offset
- start_offset
;
1742 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_ret_pri
,
1743 udvm_tvb
, start_offset
, len
, value
);
1746 case SIGCOMP_INSTR_STATE_FREE
: /* 33 */
1748 * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
1751 * %partial_identifier_start
1753 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1754 len
= offset
- start_offset
;
1755 proto_tree_add_uint(sigcomp_udvm_tree
, hf_partial_identifier_start
,
1756 udvm_tvb
, start_offset
, len
, value
);
1759 * %partial_identifier_length
1761 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1762 len
= offset
- start_offset
;
1763 proto_tree_add_uint(sigcomp_udvm_tree
, hf_partial_identifier_length
,
1764 udvm_tvb
, start_offset
, len
, value
);
1766 case SIGCOMP_INSTR_OUTPUT
: /* 34 OUTPUT (%output_start, %output_length) */
1770 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1771 len
= offset
- start_offset
;
1772 if ( is_memory_address
) {
1773 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_addr_output_start
,
1774 udvm_tvb
, start_offset
, len
, value
);
1776 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_output_start
,
1777 udvm_tvb
, start_offset
, len
, value
);
1782 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1783 len
= offset
- start_offset
;
1784 if ( is_memory_address
) {
1785 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_output_length_addr
,
1786 udvm_tvb
, start_offset
, len
, value
);
1788 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_output_length
,
1789 udvm_tvb
, start_offset
, len
, value
);
1792 case SIGCOMP_INSTR_END_MESSAGE
: /* 35 */
1794 * END-MESSAGE (%requested_feedback_location,
1795 * %returned_parameters_location, %state_length, %state_address,
1796 * %state_instruction, %minimum_access_length,
1797 * %state_retention_priority)
1799 /* %requested_feedback_location */
1800 if ((msg_length
-1) < offset
){
1801 item2
= proto_tree_add_text(sigcomp_udvm_tree
, udvm_tvb
, 0, -1,
1802 "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1803 PROTO_ITEM_SET_GENERATED(item2
);
1806 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1807 len
= offset
- start_offset
;
1808 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_req_feedback_loc
,
1809 udvm_tvb
, start_offset
, len
, value
);
1810 /* returned_parameters_location */
1811 if ((msg_length
-1) < offset
){
1812 item2
= proto_tree_add_text(sigcomp_udvm_tree
, udvm_tvb
, offset
-1, -1,
1813 "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1814 PROTO_ITEM_SET_GENERATED(item2
);
1817 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1818 len
= offset
- start_offset
;
1819 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_ret_param_loc
,
1820 udvm_tvb
, start_offset
, len
, value
);
1824 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1825 len
= offset
- start_offset
;
1826 if ( is_memory_address
) {
1827 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_length_addr
,
1828 udvm_tvb
, start_offset
, len
, value
);
1830 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_length
,
1831 udvm_tvb
, start_offset
, len
, value
);
1836 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1837 len
= offset
- start_offset
;
1838 if ( is_memory_address
) {
1839 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_address_addr
,
1840 udvm_tvb
, start_offset
, len
, value
);
1842 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_address
,
1843 udvm_tvb
, start_offset
, len
, value
);
1846 * %state_instruction
1848 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1849 len
= offset
- start_offset
;
1850 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_instr
,
1851 udvm_tvb
, start_offset
, len
, value
);
1853 * %minimum_access_length
1855 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1856 len
= offset
- start_offset
;
1857 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_min_acc_len
,
1858 udvm_tvb
, start_offset
, len
, value
);
1860 * %state_retention_priority
1862 if ( tvb_reported_length_remaining(udvm_tvb
, offset
) != 0 ){
1863 offset
= dissect_udvm_multitype_operand(udvm_tvb
, sigcomp_udvm_tree
, offset
, TRUE
, &start_offset
, &value
, &is_memory_address
);
1864 len
= offset
- start_offset
;
1865 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_state_ret_pri
,
1866 udvm_tvb
, start_offset
, len
, value
);
1868 item2
= proto_tree_add_text(sigcomp_udvm_tree
, udvm_tvb
, offset
, 1,
1869 "state_retention_priority = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1870 PROTO_ITEM_SET_GENERATED(item2
);
1872 if ( tvb_reported_length_remaining(udvm_tvb
, offset
) != 0 ){
1873 len
= tvb_reported_length_remaining(udvm_tvb
, offset
);
1874 UDVM_address
= start_address
+ offset
;
1875 proto_tree_add_text(sigcomp_udvm_tree
, udvm_tvb
, offset
, len
,
1876 "Remaining %u bytes starting at UDVM addr %u (0x%x)- State information ?",len
, UDVM_address
, UDVM_address
);
1878 offset
= offset
+ tvb_reported_length_remaining(udvm_tvb
, offset
);
1882 offset
= offset
+ tvb_reported_length_remaining(udvm_tvb
, offset
);
1890 /* The simplest operand type is the literal (#), which encodes a
1891 * constant integer from 0 to 65535 inclusive. A literal operand may
1892 * require between 1 and 3 bytes depending on its value.
1893 * Bytecode: Operand value: Range:
1894 * 0nnnnnnn N 0 - 127
1895 * 10nnnnnn nnnnnnnn N 0 - 16383
1896 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
1898 * Figure 8: Bytecode for a literal (#) operand
1902 dissect_udvm_literal_operand(tvbuff_t
*udvm_tvb
, proto_tree
*sigcomp_udvm_tree
,
1903 gint offset
, gint
*start_offset
, guint16
*value
)
1908 guint display_bytecode
;
1910 bytecode
= tvb_get_guint8(udvm_tvb
, offset
);
1911 test_bits
= bytecode
>> 7;
1912 if (test_bits
== 1){
1913 test_bits
= bytecode
>> 6;
1914 if (test_bits
== 2){
1916 * 10nnnnnn nnnnnnnn N 0 - 16383
1918 display_bytecode
= bytecode
& 0xc0;
1919 if ( display_udvm_bytecode
)
1920 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_literal_bytecode
,
1921 udvm_tvb
, offset
, 1, display_bytecode
);
1922 operand
= tvb_get_ntohs(udvm_tvb
, offset
) & 0x3fff;
1924 *start_offset
= offset
;
1925 offset
= offset
+ 2;
1929 * 111000000 nnnnnnnn nnnnnnnn N 0 - 65535
1931 display_bytecode
= bytecode
& 0xc0;
1932 if ( display_udvm_bytecode
)
1933 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_literal_bytecode
,
1934 udvm_tvb
, offset
, 1, display_bytecode
);
1936 operand
= tvb_get_ntohs(udvm_tvb
, offset
);
1938 *start_offset
= offset
;
1939 offset
= offset
+ 2;
1944 * 0nnnnnnn N 0 - 127
1946 display_bytecode
= bytecode
& 0xc0;
1947 if ( display_udvm_bytecode
)
1948 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_literal_bytecode
,
1949 udvm_tvb
, offset
, 1, display_bytecode
);
1950 operand
= ( bytecode
& 0x7f);
1952 *start_offset
= offset
;
1960 * The second operand type is the reference ($), which is always used to
1961 * access a 2-byte value located elsewhere in the UDVM memory. The
1962 * bytecode for a reference operand is decoded to be a constant integer
1963 * from 0 to 65535 inclusive, which is interpreted as the memory address
1964 * containing the actual value of the operand.
1965 * Bytecode: Operand value: Range:
1967 * 0nnnnnnn memory[2 * N] 0 - 65535
1968 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
1969 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
1971 * Figure 9: Bytecode for a reference ($) operand
1974 dissect_udvm_reference_operand(tvbuff_t
*udvm_tvb
, proto_tree
*sigcomp_udvm_tree
,
1975 gint offset
, gint
*start_offset
, guint16
*value
)
1980 guint display_bytecode
;
1982 bytecode
= tvb_get_guint8(udvm_tvb
, offset
);
1983 test_bits
= bytecode
>> 7;
1984 if (test_bits
== 1){
1985 test_bits
= bytecode
>> 6;
1986 if (test_bits
== 2){
1988 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
1990 display_bytecode
= bytecode
& 0xc0;
1991 if ( display_udvm_bytecode
)
1992 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_reference_bytecode
,
1993 udvm_tvb
, offset
, 1, display_bytecode
);
1994 operand
= tvb_get_ntohs(udvm_tvb
, offset
) & 0x3fff;
1995 *value
= (operand
* 2);
1996 *start_offset
= offset
;
1997 offset
= offset
+ 2;
2001 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
2003 display_bytecode
= bytecode
& 0xc0;
2004 if ( display_udvm_bytecode
)
2005 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_reference_bytecode
,
2006 udvm_tvb
, offset
, 1, display_bytecode
);
2008 operand
= tvb_get_ntohs(udvm_tvb
, offset
);
2010 *start_offset
= offset
;
2011 offset
= offset
+ 2;
2016 * 0nnnnnnn memory[2 * N] 0 - 65535
2018 display_bytecode
= bytecode
& 0xc0;
2019 if ( display_udvm_bytecode
)
2020 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_reference_bytecode
,
2021 udvm_tvb
, offset
, 1, display_bytecode
);
2022 operand
= ( bytecode
& 0x7f);
2023 *value
= (operand
* 2);
2024 *start_offset
= offset
;
2032 *The fourth operand type is the address (@). This operand is decoded
2033 * as a multitype operand followed by a further step: the memory address
2034 * of the UDVM instruction containing the address operand is added to
2035 * obtain the correct operand value. So if the operand value from
2036 * Figure 10 is D then the actual operand value of an address is
2037 * calculated as follows:
2039 * operand_value = (is_memory_address_of_instruction + D) modulo 2^16
2040 * TODO calculate correct value for operand in case of ADDR
2043 dissect_udvm_multitype_operand(tvbuff_t
*udvm_tvb
, proto_tree
*sigcomp_udvm_tree
,
2044 gint offset
, gboolean is_addr _U_
, gint
*start_offset
, guint16
*value
, gboolean
*is_memory_address
)
2047 guint display_bytecode
;
2052 * Figure 10: Bytecode for a multitype (%) operand
2053 * Bytecode: Operand value: Range: HEX val
2054 * 00nnnnnn N 0 - 63 0x00
2055 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
2056 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
2057 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
2058 * 111nnnnn N + 65504 65504 - 65535 0xe0
2059 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
2060 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
2061 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
2062 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
2063 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
2065 *is_memory_address
= FALSE
;
2066 bytecode
= tvb_get_guint8(udvm_tvb
, offset
);
2067 test_bits
= ( bytecode
& 0xc0 ) >> 6;
2068 switch (test_bits
){
2073 display_bytecode
= bytecode
& 0xc0;
2074 if ( display_udvm_bytecode
)
2075 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_multitype_bytecode
,
2076 udvm_tvb
, offset
, 1, display_bytecode
);
2077 operand
= ( bytecode
& 0x3f);
2079 *start_offset
= offset
;
2084 * 01nnnnnn memory[2 * N] 0 - 65535
2086 display_bytecode
= bytecode
& 0xc0;
2087 if ( display_udvm_bytecode
)
2088 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_multitype_bytecode
,
2089 udvm_tvb
, offset
, 1, display_bytecode
);
2090 operand
= ( bytecode
& 0x3f) * 2;
2091 *is_memory_address
= TRUE
;
2093 *start_offset
= offset
;
2097 /* Check tree most significant bits */
2098 test_bits
= ( bytecode
& 0xe0 ) >> 5;
2099 if ( test_bits
== 5 ){
2101 * 101nnnnn nnnnnnnn N 0 - 8191
2103 display_bytecode
= bytecode
& 0xe0;
2104 if ( display_udvm_bytecode
)
2105 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_multitype_bytecode
,
2106 udvm_tvb
, offset
, 1, display_bytecode
);
2107 operand
= tvb_get_ntohs(udvm_tvb
, offset
) & 0x1fff;
2109 *start_offset
= offset
;
2110 offset
= offset
+ 2;
2112 test_bits
= ( bytecode
& 0xf0 ) >> 4;
2113 if ( test_bits
== 9 ){
2115 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535
2117 display_bytecode
= bytecode
& 0xf0;
2118 if ( display_udvm_bytecode
)
2119 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_multitype_bytecode
,
2120 udvm_tvb
, offset
, 1, display_bytecode
);
2121 operand
= (tvb_get_ntohs(udvm_tvb
, offset
) & 0x0fff) + 61440;
2122 *start_offset
= offset
;
2124 offset
= offset
+ 2;
2126 test_bits
= ( bytecode
& 0x08 ) >> 3;
2127 if ( test_bits
== 1){
2129 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768
2131 display_bytecode
= bytecode
& 0xf8;
2132 if ( display_udvm_bytecode
)
2133 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_multitype_bytecode
,
2134 udvm_tvb
, offset
, 1, display_bytecode
);
2135 result
= (guint32
)pow(2,( bytecode
& 0x07) + 8);
2136 operand
= result
& 0xffff;
2137 *start_offset
= offset
;
2141 test_bits
= ( bytecode
& 0x0e ) >> 1;
2142 if ( test_bits
== 3 ){
2144 * 1000 011n 2 ^ (N + 6) 64 , 128
2146 display_bytecode
= bytecode
& 0xfe;
2147 if ( display_udvm_bytecode
)
2148 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_multitype_bytecode
,
2149 udvm_tvb
, offset
, 1, display_bytecode
);
2150 result
= (guint32
)pow(2,( bytecode
& 0x01) + 6);
2151 operand
= result
& 0xffff;
2152 *start_offset
= offset
;
2157 * 1000 0000 nnnnnnnn nnnnnnnn N 0 - 65535
2158 * 1000 0001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
2160 display_bytecode
= bytecode
;
2161 if ( display_udvm_bytecode
)
2162 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_multitype_bytecode
,
2163 udvm_tvb
, offset
, 1, display_bytecode
);
2164 if ( (bytecode
& 0x01) == 1 )
2165 *is_memory_address
= TRUE
;
2167 operand
= tvb_get_ntohs(udvm_tvb
, offset
);
2169 *start_offset
= offset
;
2180 test_bits
= ( bytecode
& 0x20 ) >> 5;
2181 if ( test_bits
== 1 ){
2183 * 111nnnnn N + 65504 65504 - 65535
2185 display_bytecode
= bytecode
& 0xe0;
2186 if ( display_udvm_bytecode
)
2187 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_multitype_bytecode
,
2188 udvm_tvb
, offset
, 1, display_bytecode
);
2189 operand
= ( bytecode
& 0x1f) + 65504;
2190 *start_offset
= offset
;
2195 * 110nnnnn nnnnnnnn memory[N] 0 - 65535
2197 display_bytecode
= bytecode
& 0xe0;
2198 if ( display_udvm_bytecode
)
2199 proto_tree_add_uint(sigcomp_udvm_tree
, hf_udvm_multitype_bytecode
,
2200 udvm_tvb
, offset
, 1, display_bytecode
);
2201 operand
= (tvb_get_ntohs(udvm_tvb
, offset
) & 0x1fff);
2202 *is_memory_address
= TRUE
;
2203 *start_offset
= offset
;
2215 tvb_raw_text_add(tvbuff_t
*tvb
, proto_tree
*tree
)
2217 proto_tree
*raw_tree
= NULL
;
2218 proto_item
*ti
= NULL
;
2219 int offset
, next_offset
, linelen
;
2222 ti
= proto_tree_add_item(tree
, proto_raw_sigcomp
, tvb
, 0, -1, ENC_NA
);
2223 raw_tree
= proto_item_add_subtree(ti
, ett_raw_text
);
2228 while (tvb_offset_exists(tvb
, offset
)) {
2229 tvb_find_line_end(tvb
, offset
, -1, &next_offset
, FALSE
);
2230 linelen
= next_offset
- offset
;
2232 proto_tree_add_text(raw_tree
, tvb
, offset
, linelen
,
2233 "%s", tvb_format_text(tvb
, offset
, linelen
));
2235 offset
= next_offset
;
2239 /* Register the protocol with Wireshark */
2242 proto_register_sigcomp(void)
2244 void proto_reg_handoff_sigcomp(void);
2246 /* Setup list of header fields See Section 1.6.1 for details*/
2247 static hf_register_info hf
[] = {
2248 { &hf_sigcomp_t_bit
,
2249 { "T bit", "sigcomp.t.bit",
2250 FT_UINT8
, BASE_DEC
, NULL
, 0x04,
2251 "Sigcomp T bit", HFILL
}
2254 { "Partial state id length","sigcomp.length",
2255 FT_UINT8
, BASE_HEX
, VALS(length_encoding_vals
), 0x03,
2256 "Sigcomp length", HFILL
}
2258 { &hf_sigcomp_returned_feedback_item
,
2259 { "Returned_feedback item", "sigcomp.returned.feedback.item",
2260 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2261 "Returned feedback item", HFILL
}
2263 { &hf_sigcomp_partial_state
,
2264 { "Partial state identifier", "sigcomp.partial.state.identifier",
2265 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2268 { &hf_sigcomp_remaining_message_bytes
,
2269 { "Remaining SigComp message bytes", "sigcomp.remaining-bytes",
2270 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2271 "Number of bytes remaining in message", HFILL
}
2273 { &hf_sigcomp_compression_ratio
,
2274 { "Compression ratio (%)", "sigcomp.compression-ratio",
2275 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2276 "Compression ratio (decompressed / compressed) %", HFILL
}
2278 { &hf_sigcomp_returned_feedback_item_len
,
2279 { "Returned feedback item length", "sigcomp.returned.feedback.item.len",
2280 FT_UINT8
, BASE_DEC
, NULL
, 0x7f,
2283 { &hf_sigcomp_code_len
,
2284 { "Code length","sigcomp.code.len",
2285 FT_UINT16
, BASE_HEX
, NULL
, 0xfff0,
2288 { &hf_sigcomp_destination
,
2289 { "Destination","sigcomp.destination",
2290 FT_UINT8
, BASE_HEX
, VALS(destination_address_encoding_vals
), 0xf,
2293 { &hf_sigcomp_udvm_bytecode
,
2294 { "Uploaded UDVM bytecode","sigcomp.udvm.byte-code",
2295 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2298 { &hf_sigcomp_udvm_instr
,
2299 { "UDVM instruction code","sigcomp.udvm.instr",
2300 FT_UINT8
, BASE_DEC
, VALS(udvm_instruction_code_vals
), 0x0,
2303 { &hf_udvm_execution_trace
,
2304 { "UDVM execution trace","sigcomp.udvm.execution-trace",
2305 FT_NONE
, BASE_NONE
, NULL
, 0x0,
2308 { &hf_udvm_multitype_bytecode
,
2309 { "UDVM bytecode", "sigcomp.udvm.multyt.bytecode",
2310 FT_UINT8
, BASE_HEX
, VALS(display_bytecode_vals
), 0x0,
2313 { &hf_udvm_reference_bytecode
,
2314 { "UDVM bytecode", "sigcomp.udvm.ref.bytecode",
2315 FT_UINT8
, BASE_HEX
, VALS(display_ref_bytecode_vals
), 0x0,
2318 { &hf_udvm_literal_bytecode
,
2319 { "UDVM bytecode", "sigcomp.udvm.lit.bytecode",
2320 FT_UINT8
, BASE_HEX
, VALS(display_lit_bytecode_vals
), 0x0,
2325 { "UDVM operand", "sigcomp.udvm.operand",
2326 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2331 { "%Length", "sigcomp.udvm.length",
2332 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2335 { &hf_udvm_addr_length
,
2336 { "%Length[memory address]", "sigcomp.udvm.addr.length",
2337 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2340 { &hf_udvm_destination
,
2341 { "%Destination", "sigcomp.udvm.destination",
2342 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2343 "Destination", HFILL
}
2345 { &hf_udvm_addr_destination
,
2346 { "%Destination[memory address]", "sigcomp.udvm.addr.destination",
2347 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2348 "Destination", HFILL
}
2350 { &hf_udvm_at_address
,
2351 { "@Address(mem_add_of_inst + D) mod 2^16)", "sigcomp.udvm.at.address",
2352 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2356 { "%Address", "sigcomp.udvm.length",
2357 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2360 { &hf_udvm_literal_num
,
2361 { "#n", "sigcomp.udvm.literal-num",
2362 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2363 "Literal number", HFILL
}
2366 { "%Value", "sigcomp.udvm.value",
2367 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2370 { &hf_udvm_addr_value
,
2371 { "%Value[memory address]", "sigcomp.udvm.value",
2372 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2375 { &hf_partial_identifier_start
,
2376 { "%Partial identifier start", "sigcomp.udvm.partial.identifier.start",
2377 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2378 "Partial identifier start", HFILL
}
2380 { &hf_partial_identifier_length
,
2381 { "%Partial identifier length", "sigcomp.udvm.partial.identifier.length",
2382 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2383 "Partial identifier length", HFILL
}
2386 { "%State begin", "sigcomp.udvm.state.begin",
2387 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2388 "State begin", HFILL
}
2390 { &hf_udvm_state_length
,
2391 { "%State length", "sigcomp.udvm.state.length",
2392 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2393 "State length", HFILL
}
2396 { &hf_udvm_state_length_addr
,
2397 { "%State length[memory address]", "sigcomp.udvm.state.length.addr",
2398 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2399 "State length", HFILL
}
2401 { &hf_udvm_state_address
,
2402 { "%State address", "sigcomp.udvm.start.address",
2403 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2404 "State address", HFILL
}
2406 { &hf_udvm_state_address_addr
,
2407 { "%State address[memory address]", "sigcomp.udvm.start.address.addr",
2408 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2409 "State address", HFILL
}
2411 { &hf_udvm_state_instr
,
2412 { "%State instruction", "sigcomp.udvm.start.instr",
2413 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2414 "State instruction", HFILL
}
2416 { &hf_udvm_operand_1
,
2417 { "$Operand 1[memory address]", "sigcomp.udvm.operand.1",
2418 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2419 "Reference $ Operand 1", HFILL
}
2421 { &hf_udvm_operand_2
,
2422 { "%Operand 2", "sigcomp.udvm.operand.2",
2423 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2424 "Operand 2", HFILL
}
2426 { &hf_udvm_operand_2_addr
,
2427 { "%Operand 2[memory address]", "sigcomp.udvm.operand.2.addr",
2428 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2429 "Operand 2", HFILL
}
2432 { "%j", "sigcomp.udvm.j",
2433 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2437 { "%j[memory address]", "sigcomp.udvm.addr.j",
2438 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2441 { &hf_udvm_output_start
,
2442 { "%Output_start", "sigcomp.output.start",
2443 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2444 "Output start", HFILL
}
2446 { &hf_udvm_addr_output_start
,
2447 { "%Output_start[memory address]", "sigcomp.addr.output.start",
2448 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2449 "Output start", HFILL
}
2451 { &hf_udvm_output_length
,
2452 { "%Output_length", "sigcomp.output.length",
2453 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2454 "Output length", HFILL
}
2456 { &hf_udvm_output_length_addr
,
2457 { "%Output_length[memory address]", "sigcomp.output.length.addr",
2458 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2459 "Output length", HFILL
}
2461 { &hf_udvm_req_feedback_loc
,
2462 { "%Requested feedback location", "sigcomp.req.feedback.loc",
2463 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2464 "Requested feedback location", HFILL
}
2466 { &hf_udvm_min_acc_len
,
2467 { "%Minimum access length", "sigcomp.min.acc.len",
2468 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2469 "Minimum access length", HFILL
}
2471 { &hf_udvm_state_ret_pri
,
2472 { "%State retention priority", "sigcomp.udvm.state.ret.pri",
2473 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2474 "State retention priority", HFILL
}
2476 { &hf_udvm_ret_param_loc
,
2477 { "%Returned parameters location", "sigcomp.ret.param.loc",
2478 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2479 "Returned parameters location", HFILL
}
2481 { &hf_udvm_position
,
2482 { "%Position", "sigcomp.udvm.position",
2483 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2486 { &hf_udvm_ref_dest
,
2487 { "$Destination[memory address]", "sigcomp.udvm.ref.destination",
2488 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2489 "(reference)Destination", HFILL
}
2492 { "%Bits", "sigcomp.udvm.bits",
2493 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2496 { &hf_udvm_lower_bound
,
2497 { "%Lower bound", "sigcomp.udvm.lower.bound",
2498 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2499 "Lower_bound", HFILL
}
2501 { &hf_udvm_upper_bound
,
2502 { "%Upper bound", "sigcomp.udvm.upper.bound",
2503 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2504 "Upper bound", HFILL
}
2506 { &hf_udvm_uncompressed
,
2507 { "%Uncompressed", "sigcomp.udvm.uncompressed",
2508 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2509 "Uncompressed", HFILL
}
2511 { &hf_udvm_start_value
,
2512 { "%Start value", "sigcomp.udvm.start.value",
2513 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2514 "Start value", HFILL
}
2517 { "%Offset", "sigcomp.udvm.offset",
2518 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2521 { &hf_udvm_addr_offset
,
2522 { "%Offset[memory address]", "sigcomp.udvm.addr.offset",
2523 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2526 { &hf_sigcomp_nack_ver
,
2527 { "NACK Version", "sigcomp.nack.ver",
2528 FT_UINT8
, BASE_DEC
, NULL
, 0x0f,
2531 { &hf_sigcomp_nack_reason_code
,
2532 { "Reason Code", "sigcomp.nack.reason",
2533 FT_UINT8
, BASE_DEC
, VALS(sigcomp_nack_reason_code_vals
), 0x0,
2534 "NACK Reason Code", HFILL
}
2536 { &hf_sigcomp_nack_failed_op_code
,
2537 { "OPCODE of failed instruction", "sigcomp.nack.failed_op_code",
2538 FT_UINT8
, BASE_DEC
, VALS(udvm_instruction_code_vals
), 0x0,
2539 "NACK OPCODE of failed instruction", HFILL
}
2541 { &hf_sigcomp_nack_pc
,
2542 { "PC of failed instruction", "sigcomp.nack.pc",
2543 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2544 "NACK PC of failed instruction", HFILL
}
2546 { &hf_sigcomp_nack_sha1
,
2547 { "SHA-1 Hash of failed message", "sigcomp.nack.sha1",
2548 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2549 "NACK SHA-1 Hash of failed message", HFILL
}
2551 { &hf_sigcomp_nack_state_id
,
2552 { "State ID (6 - 20 bytes)", "sigcomp.nack.state_id",
2553 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2554 "NACK State ID (6 - 20 bytes)", HFILL
}
2556 { &hf_sigcomp_nack_cycles_per_bit
,
2557 { "Cycles Per Bit", "sigcomp.nack.cycles_per_bit",
2558 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2559 "NACK Cycles Per Bit", HFILL
}
2561 { &hf_sigcomp_nack_memory_size
,
2562 { "Memory size", "sigcomp.memory_size",
2563 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2568 /* Setup protocol subtree array */
2569 static gint
*ett
[] = {
2572 &ett_sigcomp_udvm_exe
,
2574 static gint
*ett_raw
[] = {
2578 static ei_register_info ei
[] = {
2579 { &ei_sigcomp_nack_failed_op_code
, { "sigcomp.nack.failed_op_code.expert", PI_SEQUENCE
, PI_WARN
, "SigComp NACK", EXPFILL
}},
2582 module_t
*sigcomp_module
;
2583 expert_module_t
* expert_sigcomp
;
2585 static const enum_val_t udvm_detail_vals
[] = {
2586 {"no-printout", "No-Printout", 0},
2587 {"low-detail", "Low-detail", 1},
2588 {"medium-detail", "Medium-detail", 2},
2589 {"high-detail", "High-detail", 3},
2594 /* Register the protocol name and description */
2595 proto_sigcomp
= proto_register_protocol("Signaling Compression",
2596 "SIGCOMP", "sigcomp");
2597 proto_raw_sigcomp
= proto_register_protocol("Decompressed SigComp message as raw text",
2598 "Raw_SigComp", "raw_sigcomp");
2600 new_register_dissector("sigcomp", dissect_sigcomp
, proto_sigcomp
);
2602 /* Required function calls to register the header fields and subtrees used */
2603 proto_register_field_array(proto_sigcomp
, hf
, array_length(hf
));
2604 proto_register_subtree_array(ett
, array_length(ett
));
2605 proto_register_subtree_array(ett_raw
, array_length(ett_raw
));
2606 expert_sigcomp
= expert_register_protocol(proto_sigcomp
);
2607 expert_register_field_array(expert_sigcomp
, ei
, array_length(ei
));
2609 /* Register a configuration option for port */
2610 sigcomp_module
= prefs_register_protocol(proto_sigcomp
,
2611 proto_reg_handoff_sigcomp
);
2613 prefs_register_uint_preference(sigcomp_module
, "udp.port",
2614 "Sigcomp UDP Port 1",
2615 "Set UDP port 1 for SigComp messages",
2619 prefs_register_uint_preference(sigcomp_module
, "udp.port2",
2620 "Sigcomp UDP Port 2",
2621 "Set UDP port 2 for SigComp messages",
2624 prefs_register_uint_preference(sigcomp_module
, "tcp.port",
2625 "Sigcomp TCP Port 1",
2626 "Set TCP port 1 for SigComp messages",
2630 prefs_register_uint_preference(sigcomp_module
, "tcp.port2",
2631 "Sigcomp TCP Port 2",
2632 "Set TCP port 2 for SigComp messages",
2635 prefs_register_bool_preference(sigcomp_module
, "display.udvm.code",
2636 "Dissect the UDVM code",
2637 "Preference whether to Dissect the UDVM code or not",
2638 &dissect_udvm_code
);
2640 prefs_register_bool_preference(sigcomp_module
, "display.bytecode",
2641 "Display the bytecode of operands",
2642 "preference whether to display the bytecode in "
2643 "UDVM operands or not",
2644 &display_udvm_bytecode
);
2645 prefs_register_bool_preference(sigcomp_module
, "decomp.msg",
2646 "Decompress message",
2647 "preference whether to decompress message or not",
2649 prefs_register_bool_preference(sigcomp_module
, "display.decomp.msg.as.txt",
2650 "Displays the decompressed message as text",
2651 "preference whether to display the decompressed message "
2652 "as raw text or not",
2654 prefs_register_enum_preference(sigcomp_module
, "show.udvm.execution",
2655 "Level of detail of UDVM execution:",
2656 "'No-Printout' = UDVM executes silently, then increasing detail "
2657 "about execution of UDVM instructions; "
2658 "Warning! CPU intense at high detail",
2659 &udvm_print_detail_level
, udvm_detail_vals
, FALSE
);
2661 register_init_routine(&sigcomp_init_protocol
);
2668 proto_reg_handoff_sigcomp(void)
2670 static dissector_handle_t sigcomp_handle
;
2671 static dissector_handle_t sigcomp_tcp_handle
;
2672 static gboolean Initialized
=FALSE
;
2673 static guint udp_port1
;
2674 static guint udp_port2
;
2675 static guint tcp_port1
;
2676 static guint tcp_port2
;
2679 sigcomp_handle
= find_dissector("sigcomp");
2680 sigcomp_tcp_handle
= new_create_dissector_handle(dissect_sigcomp_tcp
,proto_sigcomp
);
2681 sip_handle
= find_dissector("sip");
2684 dissector_delete_uint("udp.port", udp_port1
, sigcomp_handle
);
2685 dissector_delete_uint("udp.port", udp_port2
, sigcomp_handle
);
2686 dissector_delete_uint("tcp.port", tcp_port1
, sigcomp_tcp_handle
);
2687 dissector_delete_uint("tcp.port", tcp_port2
, sigcomp_tcp_handle
);
2690 udp_port1
= SigCompUDPPort1
;
2691 udp_port2
= SigCompUDPPort2
;
2692 tcp_port1
= SigCompTCPPort1
;
2693 tcp_port2
= SigCompTCPPort2
;
2696 dissector_add_uint("udp.port", SigCompUDPPort1
, sigcomp_handle
);
2697 dissector_add_uint("udp.port", SigCompUDPPort2
, sigcomp_handle
);
2698 dissector_add_uint("tcp.port", SigCompTCPPort1
, sigcomp_tcp_handle
);
2699 dissector_add_uint("tcp.port", SigCompTCPPort2
, sigcomp_tcp_handle
);