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
40 #include <epan/packet.h>
41 #include <epan/prefs.h>
42 #include <epan/strutil.h>
43 #include <epan/expert.h>
44 #include <epan/sigcomp-udvm.h>
45 #include <epan/sigcomp_state_hdlr.h>
47 /* Initialize the protocol and registered fields */
48 static int proto_sigcomp = -1;
49 static int proto_raw_sigcomp = -1;
50 static int hf_sigcomp_t_bit = -1;
51 static int hf_sigcomp_len = -1;
52 static int hf_sigcomp_returned_feedback_item = -1;
53 static int hf_sigcomp_returned_feedback_item_len = -1;
54 static int hf_sigcomp_code_len = -1;
55 static int hf_sigcomp_destination = -1;
56 static int hf_sigcomp_partial_state = -1;
57 static int hf_sigcomp_remaining_message_bytes = -1;
58 static int hf_sigcomp_compression_ratio = -1;
59 static int hf_sigcomp_udvm_bytecode = -1;
60 static int hf_sigcomp_udvm_instr = -1;
61 static int hf_udvm_multitype_bytecode = -1;
62 static int hf_udvm_reference_bytecode = -1;
63 static int hf_udvm_literal_bytecode = -1;
64 static int hf_udvm_operand = -1;
65 static int hf_udvm_length = -1;
66 static int hf_udvm_addr_length = -1;
67 static int hf_udvm_destination = -1;
68 static int hf_udvm_addr_destination = -1;
69 static int hf_udvm_at_address = -1;
70 static int hf_udvm_address = -1;
71 static int hf_udvm_literal_num = -1;
72 static int hf_udvm_value = -1;
73 static int hf_udvm_addr_value = -1;
74 static int hf_partial_identifier_start = -1;
75 static int hf_partial_identifier_length = -1;
76 static int hf_state_begin = -1;
77 static int hf_udvm_state_length = -1;
78 static int hf_udvm_state_length_addr = -1;
79 static int hf_udvm_state_address = -1;
80 static int hf_udvm_state_address_addr = -1;
81 static int hf_udvm_state_instr = -1;
82 static int hf_udvm_operand_1 = -1;
83 static int hf_udvm_operand_2 = -1;
84 static int hf_udvm_operand_2_addr = -1;
85 static int hf_udvm_j = -1;
86 static int hf_udvm_addr_j = -1;
87 static int hf_udvm_output_start = -1;
88 static int hf_udvm_addr_output_start = -1;
89 static int hf_udvm_output_length = -1;
90 static int hf_udvm_output_length_addr = -1;
91 static int hf_udvm_req_feedback_loc = -1;
92 static int hf_udvm_min_acc_len = -1;
93 static int hf_udvm_state_ret_pri = -1;
94 static int hf_udvm_ret_param_loc = -1;
95 static int hf_udvm_position = -1;
96 static int hf_udvm_ref_dest = -1;
97 static int hf_udvm_bits = -1;
98 static int hf_udvm_lower_bound = -1;
99 static int hf_udvm_upper_bound = -1;
100 static int hf_udvm_uncompressed = -1;
101 static int hf_udvm_offset = -1;
102 static int hf_udvm_addr_offset = -1;
103 static int hf_udvm_start_value = -1;
104 static int hf_udvm_execution_trace = -1;
105 static int hf_sigcomp_nack_ver = -1;
106 static int hf_sigcomp_nack_reason_code = -1;
107 static int hf_sigcomp_nack_failed_op_code = -1;
108 static int hf_sigcomp_nack_pc = -1;
109 static int hf_sigcomp_nack_sha1 = -1;
110 static int hf_sigcomp_nack_state_id = -1;
111 static int hf_sigcomp_nack_memory_size = -1;
112 static int hf_sigcomp_nack_cycles_per_bit = -1;
114 /* Initialize the subtree pointers */
115 static gint ett_sigcomp = -1;
116 static gint ett_sigcomp_udvm = -1;
117 static gint ett_sigcomp_udvm_exe = -1;
118 static gint ett_raw_text = -1;
120 static dissector_handle_t sip_handle;
121 /* set the udp ports */
122 static guint SigCompUDPPort1 = 5555;
123 static guint SigCompUDPPort2 = 6666;
125 /* set the tcp ports */
126 static guint SigCompTCPPort1 = 5555;
127 static guint SigCompTCPPort2 = 6666;
129 /* Default preference whether to display the bytecode in UDVM operands or not */
130 static gboolean display_udvm_bytecode = FALSE;
131 /* Default preference whether to dissect the UDVM code or not */
132 static gboolean dissect_udvm_code = TRUE;
133 static gboolean display_raw_txt = FALSE;
134 /* Default preference whether to decompress the message or not */
135 static gboolean decompress = TRUE;
136 /* Default preference whether to print debug info at execution of UDVM
138 * 1 = details level 1
139 * 2 = details level 2
140 * 3 = details level 3
141 * 4 = details level 4
143 static gint udvm_print_detail_level = 0;
146 static const value_string length_encoding_vals[] = {
147 { 0x00, "No partial state (Message type 2)" },
148 { 0x01, "(6 bytes)" },
149 { 0x02, "(9 bytes)" },
150 { 0x03, "(12 bytes)" },
155 static const value_string destination_address_encoding_vals[] = {
156 { 0x00, "Reserved" },
175 static const value_string udvm_instruction_code_vals[] = {
176 { 0, "DECOMPRESSION-FAILURE" },
187 { 11, "SORT-ASCENDING" },
188 { 12, "SORT-DESCENDING" },
195 { 19, "COPY-LITERAL" },
196 { 20, "COPY-OFFSET" },
204 { 28, "INPUT-BYTES" },
205 { 29, "INPUT-BITS" },
206 { 30, "INPUT-HUFFMAN" },
207 { 31, "STATE-ACCESS" },
208 { 32, "STATE-CREATE" },
209 { 33, "STATE-FREE" },
211 { 35, "END-MESSAGE" },
215 * Figure 10: Bytecode for a multitype (%) operand
216 * Bytecode: Operand value: Range: HEX val
217 * 00nnnnnn N 0 - 63 0x00
218 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
219 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
220 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
221 * 111nnnnn N + 65504 65504 - 65535 0xe0
222 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
223 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
224 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
225 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
226 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
229 static const value_string display_bytecode_vals[] = {
230 { 0x00, "00nnnnnn, N, 0 - 63" },
231 { 0x40, "01nnnnnn, memory[2 * N],0 - 65535" },
232 { 0x86, "1000011n, 2 ^ (N + 6), 64 , 128" },
233 { 0x88, "10001nnn, 2 ^ (N + 8), 256,..., 32768" },
234 { 0xe0, "111nnnnn N + 65504, 65504 - 65535" },
235 { 0x90, "1001nnnn nnnnnnnn, N + 61440, 61440 - 65535" },
236 { 0xa0, "101nnnnn nnnnnnnn, N, 0 - 8191" },
237 { 0xc0, "110nnnnn nnnnnnnn, memory[N], 0 - 65535" },
238 { 0x80, "10000000 nnnnnnnn nnnnnnnn, N, 0 - 65535" },
239 { 0x81, "10000001 nnnnnnnn nnnnnnnn, memory[N], 0 - 65535" },
243 * 0nnnnnnn memory[2 * N] 0 - 65535
244 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
245 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
247 static const value_string display_ref_bytecode_vals[] = {
248 { 0x00, "0nnnnnnn memory[2 * N] 0 - 65535" },
249 { 0x80, "10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535" },
250 { 0xc0, "11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535" },
253 /* The simplest operand type is the literal (#), which encodes a
254 * constant integer from 0 to 65535 inclusive. A literal operand may
255 * require between 1 and 3 bytes depending on its value.
256 * Bytecode: Operand value: Range:
258 * 10nnnnnn nnnnnnnn N 0 - 16383
259 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
261 * Figure 8: Bytecode for a literal (#) operand
265 static const value_string display_lit_bytecode_vals[] = {
266 { 0x00, "0nnnnnnn N 0 - 127" },
267 { 0x80, "10nnnnnn nnnnnnnn N 0 - 16383" },
268 { 0xc0, "11000000 nnnnnnnn nnnnnnnn N 0 - 65535" },
272 #define SIGCOMP_NACK_STATE_NOT_FOUND 1
273 #define SIGCOMP_NACK_CYCLES_EXHAUSTED 2
274 #define SIGCOMP_NACK_BYTECODES_TOO_LARGE 18
275 #define SIGCOMP_NACK_ID_NOT_UNIQUE 21
276 #define SIGCOMP_NACK_STATE_TOO_SHORT 23
278 static const value_string sigcomp_nack_reason_code_vals[] = {
279 { 1, "STATE_NOT_FOUND" }, /*1 State ID (6 - 20 bytes) */
280 { 2, "CYCLES_EXHAUSTED" }, /*2 Cycles Per Bit (1 byte) */
281 { 3, "USER_REQUESTED" },
283 { 5, "TOO_MANY_STATE_REQUESTS" },
284 { 6, "INVALID_STATE_ID_LENGTH" },
285 { 7, "INVALID_STATE_PRIORITY" },
286 { 8, "OUTPUT_OVERFLOW" },
287 { 9, "STACK_UNDERFLOW" },
288 { 10, "BAD_INPUT_BITORDER" },
289 { 11, "DIV_BY_ZERO" },
290 { 12, "SWITCH_VALUE_TOO_HIGH" },
291 { 13, "TOO_MANY_BITS_REQUESTED" },
292 { 14, "INVALID_OPERAND" },
293 { 15, "HUFFMAN_NO_MATCH" },
294 { 16, "MESSAGE_TOO_SHORT" },
295 { 17, "INVALID_CODE_LOCATION" },
296 { 18, "BYTECODES_TOO_LARGE" }, /*18 Memory size (2 bytes) */
297 { 19, "INVALID_OPCODE" },
298 { 20, "INVALID_STATE_PROBE" },
299 { 21, "ID_NOT_UNIQUE" }, /*21 State ID (6 - 20 bytes) */
300 { 22, "MULTILOAD_OVERWRITTEN" },
301 { 23, "STATE_TOO_SHORT" }, /*23 State ID (6 - 20 bytes) */
302 { 24, "INTERNAL_ERROR" },
303 { 25, "FRAMING_ERROR" },
308 static void dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, guint destination);
310 static int dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
311 gint offset,gboolean is_addr,gint *start_offset,
312 guint16 *value, gboolean *is_memory_address );
314 static int dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
315 gint offset, gint *start_offset, guint16 *value);
317 static int dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
318 gint offset, gint *start_offset, guint16 *value);
319 static void tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree);
321 static int dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
323 static proto_tree *top_tree;
325 /* Initialize the state handler
329 sigcomp_init_protocol(void)
333 /* Sigcomp over TCP record marking used
335 * 4.2.2. Record Marking
337 * For a stream-based transport, the dispatcher delimits messages by
338 * parsing the compressed data stream for instances of 0xFF and taking
339 * the following actions:
340 * Occurs in data stream: Action:
342 * 0xFF 00 one 0xFF byte in the data stream
343 * 0xFF 01 same, but the next byte is quoted (could
346 * 0xFF 7F same, but the next 127 bytes are quoted
347 * 0xFF 80 to 0xFF FE (reserved for future standardization)
348 * 0xFF FF end of SigComp message
350 * In UDVM version 0x01, any occurrence of the combinations 0xFF80 to
351 * 0xFFFE that are not protected by quoting causes decompression
352 * failure; the decompressor SHOULD close the stream-based transport in
357 * TODO: Reassembly, handle more than one message in a tcp segment.
361 dissect_sigcomp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
364 proto_tree *sigcomp_tree;
365 tvbuff_t *unescaped_tvb;
374 gboolean end_off_message;
378 /* Is this SIGCOMP ? */
379 data = tvb_get_ntohs(tvb, offset);
383 octet = tvb_get_guint8(tvb,offset);
385 octet = tvb_get_guint8(tvb,offset);
387 if ((octet & 0xf8) != 0xf8)
390 /* Search for delimiter 0xffff in the remain tvb buffer */
391 length = tvb_ensure_length_remaining(tvb, offset);
392 for(i=0; i<(length-1); ++i){
393 /* Loop end criteria is (length-1) because we take 2 bytes each loop */
394 data = tvb_get_ntohs(tvb, offset+i);
395 if (0xffff == data) break;
397 if (i >= (length-1)){
398 /* SIGCOMP may be subdissector of SIP, so we use
399 * pinfo->saved_can_desegment to determine whether do desegment
400 * as well as pinfo->can_desegment */
401 if (pinfo->can_desegment || pinfo->saved_can_desegment){
402 /* Delimiter oxffff was not found, not a complete SIGCOMP PDU */
403 pinfo->desegment_offset = offset;
404 pinfo->desegment_len=DESEGMENT_ONE_MORE_SEGMENT;
409 /* Make entries in Protocol column and Info column on summary display */
410 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
412 col_clear(pinfo->cinfo, COL_INFO);
414 length = tvb_length_remaining(tvb,offset);
417 /* create display subtree for the protocol */
418 ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, ENC_NA);
419 sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
421 end_off_message = FALSE;
422 buff = g_malloc(length-offset);
423 if (udvm_print_detail_level>2)
424 proto_tree_add_text(sigcomp_tree, tvb, offset, -1,"Starting to remove escape digits");
425 while ((offset < length) && (end_off_message == FALSE)){
426 octet = tvb_get_guint8(tvb,offset);
427 if ( octet == 0xff ){
428 if ( offset +1 >= length ){
429 /* if the tvb is short dont check for the second escape digit */
433 if (udvm_print_detail_level>2)
434 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
435 " Escape digit found (0xFF)");
436 octet = tvb_get_guint8(tvb, offset+1);
443 if ((octet > 0x7f) && (octet < 0xff )){
444 if (udvm_print_detail_level>2)
445 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
446 " Illegal escape code");
447 offset = offset + tvb_length_remaining(tvb,offset);
451 if (udvm_print_detail_level>2)
452 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
453 " End of SigComp message indication found (0xFFFF)");
454 end_off_message = TRUE;
459 if (udvm_print_detail_level>2)
460 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
461 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
464 if (udvm_print_detail_level>2)
465 proto_tree_add_text(sigcomp_tree, tvb, offset, octet,
466 " Copying %u bytes literally",octet);
467 if( offset+octet >= length)
468 /* if the tvb is short dont copy further than the end */
469 octet = length - offset;
470 for ( n=0; n < octet; n++ ){
471 buff[i] = tvb_get_guint8(tvb, offset);
472 if (udvm_print_detail_level>2)
473 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
474 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
481 if (udvm_print_detail_level>2)
482 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
483 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
488 unescaped_tvb = tvb_new_child_real_data(tvb, buff,i,i);
489 /* Arrange that the allocated packet data copy be freed when the
492 tvb_set_free_cb( unescaped_tvb, g_free );
494 add_new_data_source(pinfo, unescaped_tvb, "Unescaped Data handed to the SigComp dissector");
496 proto_tree_add_text(sigcomp_tree, unescaped_tvb, 0, -1,"Data handed to the Sigcomp dissector");
497 if (end_off_message == TRUE){
498 dissect_sigcomp_common(unescaped_tvb, pinfo, sigcomp_tree);
500 proto_tree_add_text(sigcomp_tree, unescaped_tvb, 0, -1,"TCP Fragment, no end mark found");
502 if ( offset < length){
508 /* Code to actually dissect the packets */
510 dissect_sigcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
513 proto_tree *sigcomp_tree;
517 /* If we got called from SIP this might be over TCP */
518 if ( pinfo->ptype == PT_TCP )
519 return dissect_sigcomp_tcp(tvb, pinfo, tree);
521 /* Is this a SigComp message or not ? */
522 octet = tvb_get_guint8(tvb, offset);
523 if ((octet & 0xf8) != 0xf8)
526 /* Make entries in Protocol column and Info column on summary display */
527 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
529 col_clear(pinfo->cinfo, COL_INFO);
533 /* create display subtree for the protocol */
534 ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, ENC_NA);
535 sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
537 return dissect_sigcomp_common(tvb, pinfo, sigcomp_tree);
539 /* Code to actually dissect the packets */
541 dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sigcomp_tree)
544 /* Set up structures needed to add the protocol subtree and manage it */
545 tvbuff_t *udvm_tvb, *msg_tvb, *udvm2_tvb;
546 tvbuff_t *decomp_tvb = NULL;
547 proto_item *udvm_bytecode_item, *udvm_exe_item;
548 proto_tree *sigcomp_udvm_tree, *sigcomp_udvm_exe_tree;
550 gint bytecode_offset;
551 guint16 partial_state_len;
553 guint8 returned_feedback_field[128];
554 guint8 partial_state[12];
557 guint16 bytecode_len = 0;
564 guint16 state_length;
565 guint16 state_address;
566 guint16 state_instruction;
568 gchar *partial_state_str;
573 /* add an item to the subtree, see section 1.6 for more information */
574 octet = tvb_get_guint8(tvb, offset);
576 /* A SigComp message takes one of two forms depending on whether it
577 * accesses a state item at the receiving endpoint. The two variants of
578 * a SigComp message are given in Figure 3. (The T-bit controls the
579 * format of the returned feedback item and is defined in Section 7.1.)
581 * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
582 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
583 * | 1 1 1 1 1 | T | len | | 1 1 1 1 1 | T | 0 |
584 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
586 * : returned feedback item : : returned feedback item :
588 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
590 * : partial state identifier : +---+---+---+---+---+---+---+---+
592 * | | | code_len | destination |
593 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
595 * : remaining SigComp message : : uploaded UDVM bytecode :
597 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
599 * : remaining SigComp message :
601 * +---+---+---+---+---+---+---+---+
604 * The format of the NACK message and the use of the fields within it
605 * are shown in Figure 1.
608 * +---+---+---+---+---+---+---+---+
609 * | 1 1 1 1 1 | T | 0 |
610 * +---+---+---+---+---+---+---+---+
612 * : returned feedback item :
614 * +---+---+---+---+---+---+---+---+
616 * +---+---+---+---+---+---+---+---+
617 * | code_len = 0 | version = 1 |
618 * +---+---+---+---+---+---+---+---+
620 * +---+---+---+---+---+---+---+---+
621 * | OPCODE of failed instruction |
622 * +---+---+---+---+---+---+---+---+
623 * | PC of failed instruction |
625 * +---+---+---+---+---+---+---+---+
627 * : SHA-1 Hash of failed message :
629 * +---+---+---+---+---+---+---+---+
633 * +---+---+---+---+---+---+---+---+
634 * Figure 1: SigComp NACK Message Format
637 proto_tree_add_item(sigcomp_tree,hf_sigcomp_t_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
638 proto_tree_add_item(sigcomp_tree,hf_sigcomp_len, tvb, offset, 1, ENC_BIG_ENDIAN);
639 tbit = ( octet & 0x04)>>2;
640 partial_state_len = octet & 0x03;
642 if ( partial_state_len != 0 ){
644 * The len field encodes the number of transmitted bytes as follows:
646 * Encoding: Length of partial state identifier
653 partial_state_len = partial_state_len * 3 + 3;
658 col_set_str(pinfo->cinfo, COL_INFO, "Msg format 1");
662 * Returned feedback item exists
665 octet = tvb_get_guint8(tvb, offset);
666 /* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
667 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
668 * | 0 | returned_feedback_field | | 1 | returned_feedback_length |
669 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
671 * : returned_feedback_field :
673 * +---+---+---+---+---+---+---+---+
674 * Figure 4: Format of returned feedback item
677 if ( (octet & 0x80) != 0 ){
679 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
680 tvb, offset, 1, ENC_BIG_ENDIAN);
682 tvb_memcpy(tvb,returned_feedback_field,offset, len);
684 returned_feedback_field[0] = tvb_get_guint8(tvb, offset) & 0x7f;
686 proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
687 tvb, offset, len, returned_feedback_field);
688 offset = offset + len;
690 tvb_memcpy(tvb, partial_state, offset, partial_state_len);
691 partial_state_str = bytes_to_str(partial_state, partial_state_len);
692 proto_tree_add_string(sigcomp_tree,hf_sigcomp_partial_state,
693 tvb, offset, partial_state_len, partial_state_str);
694 offset = offset + partial_state_len;
695 msg_len = tvb_reported_length_remaining(tvb, offset);
699 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_remaining_message_bytes, tvb,
701 PROTO_ITEM_SET_GENERATED(ti);
705 msg_tvb = tvb_new_subset(tvb, offset, msg_len, msg_len);
707 * buff = Where "state" will be stored
708 * p_id_start = Partial state identifier start pos in the buffer(buff)
709 * partial_state_len = Partial state identifier length
710 * state_begin = Where to start to read state from
711 * state_length = Length of state
712 * state_address = Address where to store the state in the buffer(buff)
713 * state_instruction =
714 * TRUE = Indicates that state_* is in the stored state
717 * Note: The allocated buffer must be zeroed or some strange effects might occur.
719 buff = g_malloc0(UDVM_MEMORY_SIZE);
724 /* These values will be loaded from the buffered state in sigcomp_state_hdlr
728 state_instruction =0;
731 while ( i < partial_state_len ){
732 buff[i] = partial_state[i];
736 /* begin partial state-id change cco@iptel.org */
738 result_code = udvm_state_access(tvb, sigcomp_tree, buff, p_id_start, partial_state_len, state_begin, &state_length,
739 &state_address, &state_instruction, hf_sigcomp_partial_state);
741 result_code = udvm_state_access(tvb, sigcomp_tree, buff, p_id_start, STATE_MIN_ACCESS_LEN, state_begin, &state_length,
742 &state_address, &state_instruction, hf_sigcomp_partial_state);
744 /* end partial state-id change cco@iptel.org */
745 if ( result_code != 0 ){
747 ti = proto_tree_add_text(sigcomp_tree, tvb, 0, -1,"Failed to Access state Wireshark UDVM diagnostic: %s.",
748 val_to_str(result_code, result_code_vals,"Unknown (%u)"));
749 PROTO_ITEM_SET_GENERATED(ti);
751 return tvb_length(tvb);
754 udvm_tvb = tvb_new_child_real_data(tvb, buff,state_length+state_address,state_length+state_address);
755 add_new_data_source(pinfo, udvm_tvb, "State/ExecutionTrace");
756 /* Arrange that the allocated packet data copy be freed when the
759 tvb_set_free_cb( udvm_tvb, g_free );
762 udvm2_tvb = tvb_new_subset(udvm_tvb, state_address, state_length, state_length);
763 udvm_exe_item = proto_tree_add_item(sigcomp_tree, hf_udvm_execution_trace,
764 udvm2_tvb, 0, state_length,
766 sigcomp_udvm_exe_tree = proto_item_add_subtree( udvm_exe_item, ett_sigcomp_udvm_exe);
768 decomp_tvb = decompress_sigcomp_message(udvm2_tvb, msg_tvb, pinfo,
769 sigcomp_udvm_exe_tree, state_address,
770 udvm_print_detail_level, hf_sigcomp_partial_state,
771 offset, state_length, partial_state_len, state_instruction);
776 guint32 compression_ratio =
777 (guint32)(((float)tvb_length(decomp_tvb) / (float)tvb_length(tvb)) * 100);
779 /* Celebrate success and show compression ratio achieved */
780 proto_tree_add_text(sigcomp_tree, decomp_tvb, 0, -1,"SigComp message Decompressed WOHO!!");
781 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_compression_ratio, decomp_tvb,
782 0, 0, compression_ratio);
783 PROTO_ITEM_SET_GENERATED(ti);
785 if ( display_raw_txt )
786 tvb_raw_text_add(decomp_tvb, top_tree);
788 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
789 col_set_fence(pinfo->cinfo,COL_PROTOCOL);
790 call_dissector(sip_handle, decomp_tvb, pinfo, top_tree);
799 col_set_str(pinfo->cinfo, COL_INFO, "Msg format 2");
802 * Returned feedback item exists
805 octet = tvb_get_guint8(tvb, offset);
806 if ( (octet & 0x80) != 0 ){
808 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
809 tvb, offset, 1, ENC_BIG_ENDIAN);
812 tvb_memcpy(tvb,returned_feedback_field,offset, len);
813 proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
814 tvb, offset, len, returned_feedback_field);
815 offset = offset + len;
817 len = tvb_get_ntohs(tvb, offset) >> 4;
818 nack_version = tvb_get_guint8(tvb, offset+1) & 0x0f;
819 if ((len == 0) && (nack_version == 1)){
821 proto_item *reason_ti;
824 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
826 octet = tvb_get_guint8(tvb, offset);
827 reason_ti = proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
829 opcode = tvb_get_guint8(tvb, offset);
830 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_failed_op_code, tvb, offset, 1, ENC_BIG_ENDIAN);
833 /* Add expert item for NACK */
834 expert_add_info_format(pinfo, reason_ti, PI_SEQUENCE, PI_WARN,
835 "SigComp NACK (reason=%s, opcode=%s)",
836 val_to_str_const(octet, sigcomp_nack_reason_code_vals, "Unknown"),
837 val_to_str_const(opcode, udvm_instruction_code_vals, "Unknown"));
839 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_pc, tvb, offset, 2, ENC_BIG_ENDIAN);
841 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_sha1, tvb, offset, 20, ENC_NA);
844 /* Add NACK info to info column */
845 col_append_fstr(pinfo->cinfo, COL_INFO, " NACK reason=%s, opcode=%s",
846 val_to_str_const(octet, sigcomp_nack_reason_code_vals, "Unknown"),
847 val_to_str_const(opcode, udvm_instruction_code_vals, "Unknown"));
850 case SIGCOMP_NACK_STATE_NOT_FOUND:
851 case SIGCOMP_NACK_ID_NOT_UNIQUE:
852 case SIGCOMP_NACK_STATE_TOO_SHORT:
853 /* State ID (6 - 20 bytes) */
854 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_state_id, tvb, offset, -1, ENC_NA);
856 case SIGCOMP_NACK_CYCLES_EXHAUSTED:
857 /* Cycles Per Bit (1 byte) */
858 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_cycles_per_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
860 case SIGCOMP_NACK_BYTECODES_TOO_LARGE:
861 /* Memory size (2 bytes) */
862 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_memory_size, tvb, offset, 2, ENC_BIG_ENDIAN);
868 octet = tvb_get_guint8(tvb, (offset + 1));
869 destination = (octet & 0x0f);
870 if ( destination != 0 )
871 destination = 64 + ( destination * 64 );
872 proto_tree_add_item(sigcomp_tree,hf_sigcomp_code_len, tvb, offset, 2, ENC_BIG_ENDIAN);
873 proto_tree_add_item(sigcomp_tree,hf_sigcomp_destination, tvb, (offset+ 1), 1, ENC_BIG_ENDIAN);
877 bytecode_offset = offset;
878 udvm_bytecode_item = proto_tree_add_item(sigcomp_tree, hf_sigcomp_udvm_bytecode, tvb,
879 bytecode_offset, bytecode_len, ENC_NA);
880 proto_item_append_text(udvm_bytecode_item,
881 " %u (0x%x) bytes", bytecode_len, bytecode_len);
882 sigcomp_udvm_tree = proto_item_add_subtree( udvm_bytecode_item, ett_sigcomp_udvm);
884 udvm_tvb = tvb_new_subset(tvb, offset, len, len);
885 if ( dissect_udvm_code )
886 dissect_udvm_bytecode(udvm_tvb, sigcomp_udvm_tree, destination);
888 offset = offset + len;
889 msg_len = tvb_reported_length_remaining(tvb, offset);
891 proto_item *ti = proto_tree_add_text(sigcomp_tree, tvb, offset, -1,
892 "Remaining SigComp message %u bytes",
893 tvb_reported_length_remaining(tvb, offset));
894 PROTO_ITEM_SET_GENERATED(ti);
898 msg_tvb = tvb_new_subset(tvb, offset, msg_len, msg_len);
900 udvm_exe_item = proto_tree_add_item(sigcomp_tree, hf_udvm_execution_trace,
901 tvb, bytecode_offset, bytecode_len,
903 sigcomp_udvm_exe_tree = proto_item_add_subtree( udvm_exe_item, ett_sigcomp_udvm_exe);
904 decomp_tvb = decompress_sigcomp_message(udvm_tvb, msg_tvb, pinfo,
905 sigcomp_udvm_exe_tree, destination,
906 udvm_print_detail_level, hf_sigcomp_partial_state,
907 offset, 0, 0, destination);
910 guint32 compression_ratio =
911 (guint32)(((float)tvb_length(decomp_tvb) / (float)tvb_length(tvb)) * 100);
913 /* Celebrate success and show compression ratio achieved */
914 proto_tree_add_text(sigcomp_tree, decomp_tvb, 0, -1,"SigComp message Decompressed WOHO!!");
915 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_compression_ratio, decomp_tvb,
916 0, 0, compression_ratio);
917 PROTO_ITEM_SET_GENERATED(ti);
919 if ( display_raw_txt )
920 tvb_raw_text_add(decomp_tvb, top_tree);
922 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
923 col_set_fence(pinfo->cinfo,COL_PROTOCOL);
924 call_dissector(sip_handle, decomp_tvb, pinfo, top_tree);
926 } /* if decompress */
930 return tvb_length(tvb);
934 #define SIGCOMP_INSTR_DECOMPRESSION_FAILURE 0
935 #define SIGCOMP_INSTR_AND 1
936 #define SIGCOMP_INSTR_OR 2
937 #define SIGCOMP_INSTR_NOT 3
938 #define SIGCOMP_INSTR_LSHIFT 4
939 #define SIGCOMP_INSTR_RSHIFT 5
940 #define SIGCOMP_INSTR_ADD 6
941 #define SIGCOMP_INSTR_SUBTRACT 7
942 #define SIGCOMP_INSTR_MULTIPLY 8
943 #define SIGCOMP_INSTR_DIVIDE 9
944 #define SIGCOMP_INSTR_REMAINDER 10
945 #define SIGCOMP_INSTR_SORT_ASCENDING 11
946 #define SIGCOMP_INSTR_SORT_DESCENDING 12
947 #define SIGCOMP_INSTR_SHA_1 13
948 #define SIGCOMP_INSTR_LOAD 14
949 #define SIGCOMP_INSTR_MULTILOAD 15
950 #define SIGCOMP_INSTR_PUSH 16
951 #define SIGCOMP_INSTR_POP 17
952 #define SIGCOMP_INSTR_COPY 18
953 #define SIGCOMP_INSTR_COPY_LITERAL 19
954 #define SIGCOMP_INSTR_COPY_OFFSET 20
955 #define SIGCOMP_INSTR_MEMSET 21
956 #define SIGCOMP_INSTR_JUMP 22
957 #define SIGCOMP_INSTR_COMPARE 23
958 #define SIGCOMP_INSTR_CALL 24
959 #define SIGCOMP_INSTR_RETURN 25
960 #define SIGCOMP_INSTR_SWITCH 26
961 #define SIGCOMP_INSTR_CRC 27
962 #define SIGCOMP_INSTR_INPUT_BYTES 28
963 #define SIGCOMP_INSTR_INPUT_BITS 29
964 #define SIGCOMP_INSTR_INPUT_HUFFMAN 30
965 #define SIGCOMP_INSTR_STATE_ACCESS 31
966 #define SIGCOMP_INSTR_STATE_CREATE 32
967 #define SIGCOMP_INSTR_STATE_FREE 33
968 #define SIGCOMP_INSTR_OUTPUT 34
969 #define SIGCOMP_INSTR_END_MESSAGE 35
973 dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,guint start_address)
977 gint start_offset = 0;
980 guint instruction_no = 0;
982 proto_item *item, *item2;
983 guint UDVM_address = start_address;
984 gboolean is_memory_address;
985 guint16 msg_length = tvb_reported_length_remaining(udvm_tvb, offset);
988 while (msg_length > offset) {
989 instruction = tvb_get_guint8(udvm_tvb, offset);
991 UDVM_address = start_address + offset;
994 item = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
995 "######### UDVM instruction %u at UDVM-address %u (0x%x) #########",
996 instruction_no,UDVM_address,UDVM_address);
997 PROTO_ITEM_SET_GENERATED(item);
998 proto_tree_add_item(sigcomp_udvm_tree, hf_sigcomp_udvm_instr, udvm_tvb, offset, 1, ENC_BIG_ENDIAN);
1000 switch ( instruction ) {
1002 case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */
1004 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1005 len = offset - start_offset;
1006 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1007 udvm_tvb, start_offset, len, value);
1009 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1010 len = offset - start_offset;
1011 if ( is_memory_address ){
1012 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1013 udvm_tvb, start_offset, len, value);
1015 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1016 udvm_tvb, start_offset, len, value);
1020 case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */
1022 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1023 len = offset - start_offset;
1024 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1025 udvm_tvb, start_offset, len, value);
1027 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1028 len = offset - start_offset;
1029 if ( is_memory_address ){
1030 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1031 udvm_tvb, start_offset, len, value);
1033 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1034 udvm_tvb, start_offset, len, value);
1038 case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */
1040 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1041 len = offset - start_offset;
1042 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1043 udvm_tvb, start_offset, len, value);
1046 case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */
1048 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1049 len = offset - start_offset;
1050 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1051 udvm_tvb, start_offset, len, value);
1053 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1054 len = offset - start_offset;
1055 if ( is_memory_address ){
1056 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1057 udvm_tvb, start_offset, len, value);
1059 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1060 udvm_tvb, start_offset, len, value);
1064 case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */
1066 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1067 len = offset - start_offset;
1068 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1069 udvm_tvb, start_offset, len, value);
1071 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1072 len = offset - start_offset;
1073 if ( is_memory_address ){
1074 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1075 udvm_tvb, start_offset, len, value);
1077 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1078 udvm_tvb, start_offset, len, value);
1082 case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */
1084 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1085 len = offset - start_offset;
1086 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1087 udvm_tvb, start_offset, len, value);
1089 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1090 len = offset - start_offset;
1091 if ( is_memory_address ){
1092 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1093 udvm_tvb, start_offset, len, value);
1095 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1096 udvm_tvb, start_offset, len, value);
1100 case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */
1102 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1103 len = offset - start_offset;
1104 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1105 udvm_tvb, start_offset, len, value);
1107 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1108 len = offset - start_offset;
1109 if ( is_memory_address ){
1110 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1111 udvm_tvb, start_offset, len, value);
1113 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1114 udvm_tvb, start_offset, len, value);
1118 case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */
1120 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1121 len = offset - start_offset;
1122 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1123 udvm_tvb, start_offset, len, value);
1125 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1126 len = offset - start_offset;
1127 if ( is_memory_address ){
1128 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1129 udvm_tvb, start_offset, len, value);
1131 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1132 udvm_tvb, start_offset, len, value);
1136 case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */
1138 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1139 len = offset - start_offset;
1140 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1141 udvm_tvb, start_offset, len, value);
1143 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1144 len = offset - start_offset;
1145 if ( is_memory_address ){
1146 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1147 udvm_tvb, start_offset, len, value);
1149 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1150 udvm_tvb, start_offset, len, value);
1154 case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */
1156 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1157 len = offset - start_offset;
1158 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1159 udvm_tvb, start_offset, len, value);
1161 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1162 len = offset - start_offset;
1163 if ( is_memory_address ){
1164 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1165 udvm_tvb, start_offset, len, value);
1167 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1168 udvm_tvb, start_offset, len, value);
1171 case SIGCOMP_INSTR_SORT_ASCENDING: /* 11 SORT-ASCENDING (%start, %n, %k) */
1172 /* while programming stop while loop */
1173 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1176 case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */
1177 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1179 case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */
1181 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1182 len = offset - start_offset;
1183 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1184 udvm_tvb, start_offset, len, value);
1187 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1188 len = offset - start_offset;
1189 if ( is_memory_address ){
1190 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1191 udvm_tvb, start_offset, len, value);
1193 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1194 udvm_tvb, start_offset, len, value);
1198 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1199 len = offset - start_offset;
1200 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1201 udvm_tvb, start_offset, len, value);
1204 case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */
1206 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
1207 len = offset - start_offset;
1208 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1209 udvm_tvb, start_offset, len, value);
1211 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1212 len = offset - start_offset;
1213 if ( is_memory_address ){
1214 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1215 udvm_tvb, start_offset, len, value);
1217 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1218 udvm_tvb, start_offset, len, value);
1222 case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
1224 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1225 len = offset - start_offset;
1226 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1227 udvm_tvb, start_offset, len, value);
1229 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1230 len = offset - start_offset;
1231 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1232 udvm_tvb, start_offset, len, value);
1237 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1238 len = offset - start_offset;
1239 if ( is_memory_address ){
1240 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1241 udvm_tvb, start_offset, len, value);
1243 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1244 udvm_tvb, start_offset, len, value);
1249 case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */
1251 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1252 len = offset - start_offset;
1253 if ( is_memory_address ){
1254 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1255 udvm_tvb, start_offset, len, value);
1257 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1258 udvm_tvb, start_offset, len, value);
1262 case SIGCOMP_INSTR_POP: /* 17 POP (%address) */
1264 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1266 len = offset - start_offset;
1267 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1268 udvm_tvb, start_offset, len, value);
1271 case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */
1273 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1274 len = offset - start_offset;
1275 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1276 udvm_tvb, start_offset, len, value);
1279 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1280 len = offset - start_offset;
1281 if ( is_memory_address ){
1282 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1283 udvm_tvb, start_offset, len, value);
1285 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1286 udvm_tvb, start_offset, len, value);
1290 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1291 len = offset - start_offset;
1292 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1293 udvm_tvb, start_offset, len, value);
1296 case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */
1298 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1299 len = offset - start_offset;
1300 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1301 udvm_tvb, start_offset, len, value);
1304 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1305 len = offset - start_offset;
1306 if ( is_memory_address ){
1307 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1308 udvm_tvb, start_offset, len, value);
1310 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1311 udvm_tvb, start_offset, len, value);
1315 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1316 len = offset - start_offset;
1317 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1318 udvm_tvb, start_offset, len, value);
1321 case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */
1323 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1324 len = offset - start_offset;
1325 if ( is_memory_address ){
1326 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_offset,
1327 udvm_tvb, start_offset, len, value);
1329 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
1330 udvm_tvb, start_offset, len, value);
1334 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1335 len = offset - start_offset;
1336 if ( is_memory_address ){
1337 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1338 udvm_tvb, start_offset, len, value);
1340 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1341 udvm_tvb, start_offset, len, value);
1345 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1346 len = offset - start_offset;
1347 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1348 udvm_tvb, start_offset, len, value);
1350 case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */
1353 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1354 len = offset - start_offset;
1355 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1356 udvm_tvb, start_offset, len, value);
1359 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE, &start_offset, &value, &is_memory_address);
1360 len = offset - start_offset;
1361 if ( is_memory_address ){
1362 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1363 udvm_tvb, start_offset, len, value);
1365 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1366 udvm_tvb, start_offset, len, value);
1370 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1371 len = offset - start_offset;
1372 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_start_value,
1373 udvm_tvb, start_offset, len, value);
1376 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1377 len = offset - start_offset;
1378 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
1379 udvm_tvb, start_offset, len, value);
1383 case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */
1385 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1386 len = offset - start_offset;
1387 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1388 value = ( value + UDVM_address ) & 0xffff;
1389 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1390 udvm_tvb, start_offset, len, value);
1393 case SIGCOMP_INSTR_COMPARE: /* 23 */
1394 /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
1397 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1398 len = offset - start_offset;
1399 if ( is_memory_address ){
1400 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1401 udvm_tvb, start_offset, len, value);
1403 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1404 udvm_tvb, start_offset, len, value);
1408 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1409 len = offset - start_offset;
1410 if ( is_memory_address ){
1411 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1412 udvm_tvb, start_offset, len, value);
1414 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1415 udvm_tvb, start_offset, len, value);
1419 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1420 len = offset - start_offset;
1421 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1422 value = ( value + UDVM_address ) & 0xffff;
1423 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1424 udvm_tvb, start_offset, len, value);
1427 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1428 len = offset - start_offset;
1429 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1430 value = ( value + UDVM_address ) & 0xffff;
1431 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1432 udvm_tvb, start_offset, len, value);
1435 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1436 len = offset - start_offset;
1437 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1438 value = ( value + UDVM_address ) & 0xffff;
1439 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1440 udvm_tvb, start_offset, len, value);
1443 case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/
1445 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1446 len = offset - start_offset;
1447 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1448 value = ( value + UDVM_address ) & 0xffff;
1449 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1450 udvm_tvb, start_offset, len, value);
1452 case SIGCOMP_INSTR_RETURN: /* 25 POP and return */
1456 case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
1458 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1459 len = offset - start_offset;
1460 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1461 udvm_tvb, start_offset, len, value);
1463 /* Number of addresses in the instruction */
1466 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1467 len = offset - start_offset;
1468 if ( is_memory_address ){
1469 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_j,
1470 udvm_tvb, start_offset, len, value);
1472 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_j,
1473 udvm_tvb, start_offset, len, value);
1479 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
1480 len = offset - start_offset;
1481 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1482 value = ( value + UDVM_address ) & 0xffff;
1483 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1484 udvm_tvb, start_offset, len, value);
1487 case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */
1489 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1490 len = offset - start_offset;
1491 if ( is_memory_address ){
1492 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1493 udvm_tvb, start_offset, len, value);
1495 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1496 udvm_tvb, start_offset, len, value);
1500 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1501 len = offset - start_offset;
1502 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1503 udvm_tvb, start_offset, len, value);
1506 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1507 len = offset - start_offset;
1508 if ( is_memory_address ){
1509 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1510 udvm_tvb, start_offset, len, value);
1512 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1513 udvm_tvb, start_offset, len, value);
1517 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1518 len = offset - start_offset;
1519 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1520 value = ( value + UDVM_address ) & 0xffff;
1521 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1522 udvm_tvb, start_offset, len, value);
1526 case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */
1528 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1529 len = offset - start_offset;
1530 if ( is_memory_address ){
1531 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1532 udvm_tvb, start_offset, len, value);
1534 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1535 udvm_tvb, start_offset, len, value);
1539 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1540 len = offset - start_offset;
1541 if ( is_memory_address ){
1542 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
1543 udvm_tvb, start_offset, len, value);
1545 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1546 udvm_tvb, start_offset, len, value);
1550 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1551 len = offset - start_offset;
1552 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1553 value = ( value + UDVM_address ) & 0xffff;
1554 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1555 udvm_tvb, start_offset, len, value);
1557 case SIGCOMP_INSTR_INPUT_BITS:/* 29 INPUT-BITS (%length, %destination, @address) */
1559 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1560 len = offset - start_offset;
1561 if ( is_memory_address ){
1562 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1563 udvm_tvb, start_offset, len, value);
1565 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1566 udvm_tvb, start_offset, len, value);
1570 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1571 len = offset - start_offset;
1572 if ( is_memory_address ){
1573 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
1574 udvm_tvb, start_offset, len, value);
1576 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1577 udvm_tvb, start_offset, len, value);
1581 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1582 len = offset - start_offset;
1583 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1584 value = ( value + UDVM_address ) & 0xffff;
1585 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1586 udvm_tvb, start_offset, len, value);
1588 case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */
1590 * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1,
1591 * %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n,
1592 * %upper_bound_n, %uncompressed_n)
1595 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1596 len = offset - start_offset;
1597 if ( is_memory_address ){
1598 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
1599 udvm_tvb, start_offset, len, value);
1601 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1602 udvm_tvb, start_offset, len, value);
1605 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1606 len = offset - start_offset;
1607 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1608 value = ( value + UDVM_address ) & 0xffff;
1609 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1610 udvm_tvb, start_offset, len, value);
1612 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1613 len = offset - start_offset;
1614 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1615 udvm_tvb, start_offset, len, value);
1620 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1621 len = offset - start_offset;
1622 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_bits,
1623 udvm_tvb, start_offset, len, value);
1625 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1626 len = offset - start_offset;
1627 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_lower_bound,
1628 udvm_tvb, start_offset, len, value);
1629 /* %upper_bound_n */
1630 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1631 len = offset - start_offset;
1632 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_upper_bound,
1633 udvm_tvb, start_offset, len, value);
1634 /* %uncompressed_n */
1635 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1636 len = offset - start_offset;
1637 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_uncompressed,
1638 udvm_tvb, start_offset, len, value);
1642 case SIGCOMP_INSTR_STATE_ACCESS: /* 31 */
1643 /* STATE-ACCESS (%partial_identifier_start, %partial_identifier_length,
1644 * %state_begin, %state_length, %state_address, %state_instruction)
1648 * %partial_identifier_start
1650 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1651 len = offset - start_offset;
1652 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
1653 udvm_tvb, start_offset, len, value);
1656 * %partial_identifier_length
1658 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1659 len = offset - start_offset;
1660 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length,
1661 udvm_tvb, start_offset, len, value);
1665 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1666 len = offset - start_offset;
1667 proto_tree_add_uint(sigcomp_udvm_tree, hf_state_begin,
1668 udvm_tvb, start_offset, len, value);
1673 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1674 len = offset - start_offset;
1675 if ( is_memory_address ) {
1676 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1677 udvm_tvb, start_offset, len, value);
1679 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1680 udvm_tvb, start_offset, len, value);
1685 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1686 len = offset - start_offset;
1687 if ( is_memory_address ) {
1688 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1689 udvm_tvb, start_offset, len, value);
1691 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1692 udvm_tvb, start_offset, len, value);
1695 * %state_instruction
1697 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1698 len = offset - start_offset;
1699 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1700 udvm_tvb, start_offset, len, value);
1702 case SIGCOMP_INSTR_STATE_CREATE: /* 32 */
1704 * STATE-CREATE (%state_length, %state_address, %state_instruction,
1705 * %minimum_access_length, %state_retention_priority)
1711 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1712 len = offset - start_offset;
1713 if ( is_memory_address ) {
1714 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1715 udvm_tvb, start_offset, len, value);
1717 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1718 udvm_tvb, start_offset, len, value);
1723 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1724 len = offset - start_offset;
1725 if ( is_memory_address ) {
1726 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1727 udvm_tvb, start_offset, len, value);
1729 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1730 udvm_tvb, start_offset, len, value);
1733 * %state_instruction
1735 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1736 len = offset - start_offset;
1737 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1738 udvm_tvb, start_offset, len, value);
1740 * %minimum_access_length
1742 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1743 len = offset - start_offset;
1744 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len,
1745 udvm_tvb, start_offset, len, value);
1747 * %state_retention_priority
1749 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1750 len = offset - start_offset;
1751 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
1752 udvm_tvb, start_offset, len, value);
1755 case SIGCOMP_INSTR_STATE_FREE: /* 33 */
1757 * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
1760 * %partial_identifier_start
1762 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1763 len = offset - start_offset;
1764 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
1765 udvm_tvb, start_offset, len, value);
1768 * %partial_identifier_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 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length,
1773 udvm_tvb, start_offset, len, value);
1775 case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */
1779 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1780 len = offset - start_offset;
1781 if ( is_memory_address ) {
1782 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_output_start,
1783 udvm_tvb, start_offset, len, value);
1785 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start,
1786 udvm_tvb, start_offset, len, value);
1791 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1792 len = offset - start_offset;
1793 if ( is_memory_address ) {
1794 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length_addr,
1795 udvm_tvb, start_offset, len, value);
1797 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length,
1798 udvm_tvb, start_offset, len, value);
1801 case SIGCOMP_INSTR_END_MESSAGE: /* 35 */
1803 * END-MESSAGE (%requested_feedback_location,
1804 * %returned_parameters_location, %state_length, %state_address,
1805 * %state_instruction, %minimum_access_length,
1806 * %state_retention_priority)
1808 /* %requested_feedback_location */
1809 if ((msg_length-1) < offset){
1810 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, 0, -1,
1811 "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1812 PROTO_ITEM_SET_GENERATED(item2);
1815 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1816 len = offset - start_offset;
1817 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_req_feedback_loc,
1818 udvm_tvb, start_offset, len, value);
1819 /* returned_parameters_location */
1820 if ((msg_length-1) < offset){
1821 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset-1, -1,
1822 "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1823 PROTO_ITEM_SET_GENERATED(item2);
1826 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1827 len = offset - start_offset;
1828 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ret_param_loc,
1829 udvm_tvb, start_offset, len, value);
1833 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1834 len = offset - start_offset;
1835 if ( is_memory_address ) {
1836 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1837 udvm_tvb, start_offset, len, value);
1839 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1840 udvm_tvb, start_offset, len, value);
1845 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1846 len = offset - start_offset;
1847 if ( is_memory_address ) {
1848 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1849 udvm_tvb, start_offset, len, value);
1851 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1852 udvm_tvb, start_offset, len, value);
1855 * %state_instruction
1857 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1858 len = offset - start_offset;
1859 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1860 udvm_tvb, start_offset, len, value);
1862 * %minimum_access_length
1864 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1865 len = offset - start_offset;
1866 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len,
1867 udvm_tvb, start_offset, len, value);
1869 * %state_retention_priority
1871 if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1872 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1873 len = offset - start_offset;
1874 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
1875 udvm_tvb, start_offset, len, value);
1877 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
1878 "state_retention_priority = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1879 PROTO_ITEM_SET_GENERATED(item2);
1881 if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1882 len = tvb_reported_length_remaining(udvm_tvb, offset);
1883 UDVM_address = start_address + offset;
1884 proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, len,
1885 "Remaining %u bytes starting at UDVM addr %u (0x%x)- State information ?",len, UDVM_address, UDVM_address);
1887 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1891 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1899 /* The simplest operand type is the literal (#), which encodes a
1900 * constant integer from 0 to 65535 inclusive. A literal operand may
1901 * require between 1 and 3 bytes depending on its value.
1902 * Bytecode: Operand value: Range:
1903 * 0nnnnnnn N 0 - 127
1904 * 10nnnnnn nnnnnnnn N 0 - 16383
1905 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
1907 * Figure 8: Bytecode for a literal (#) operand
1911 dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1912 gint offset, gint *start_offset, guint16 *value)
1917 guint display_bytecode;
1919 bytecode = tvb_get_guint8(udvm_tvb, offset);
1920 test_bits = bytecode >> 7;
1921 if (test_bits == 1){
1922 test_bits = bytecode >> 6;
1923 if (test_bits == 2){
1925 * 10nnnnnn nnnnnnnn N 0 - 16383
1927 display_bytecode = bytecode & 0xc0;
1928 if ( display_udvm_bytecode )
1929 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1930 udvm_tvb, offset, 1, display_bytecode);
1931 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
1933 *start_offset = offset;
1934 offset = offset + 2;
1938 * 111000000 nnnnnnnn nnnnnnnn N 0 - 65535
1940 display_bytecode = bytecode & 0xc0;
1941 if ( display_udvm_bytecode )
1942 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1943 udvm_tvb, offset, 1, display_bytecode);
1945 operand = tvb_get_ntohs(udvm_tvb, offset);
1947 *start_offset = offset;
1948 offset = offset + 2;
1953 * 0nnnnnnn N 0 - 127
1955 display_bytecode = bytecode & 0xc0;
1956 if ( display_udvm_bytecode )
1957 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1958 udvm_tvb, offset, 1, display_bytecode);
1959 operand = ( bytecode & 0x7f);
1961 *start_offset = offset;
1969 * The second operand type is the reference ($), which is always used to
1970 * access a 2-byte value located elsewhere in the UDVM memory. The
1971 * bytecode for a reference operand is decoded to be a constant integer
1972 * from 0 to 65535 inclusive, which is interpreted as the memory address
1973 * containing the actual value of the operand.
1974 * Bytecode: Operand value: Range:
1976 * 0nnnnnnn memory[2 * N] 0 - 65535
1977 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
1978 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
1980 * Figure 9: Bytecode for a reference ($) operand
1983 dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1984 gint offset, gint *start_offset, guint16 *value)
1989 guint display_bytecode;
1991 bytecode = tvb_get_guint8(udvm_tvb, offset);
1992 test_bits = bytecode >> 7;
1993 if (test_bits == 1){
1994 test_bits = bytecode >> 6;
1995 if (test_bits == 2){
1997 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
1999 display_bytecode = bytecode & 0xc0;
2000 if ( display_udvm_bytecode )
2001 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
2002 udvm_tvb, offset, 1, display_bytecode);
2003 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
2004 *value = (operand * 2);
2005 *start_offset = offset;
2006 offset = offset + 2;
2010 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
2012 display_bytecode = bytecode & 0xc0;
2013 if ( display_udvm_bytecode )
2014 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
2015 udvm_tvb, offset, 1, display_bytecode);
2017 operand = tvb_get_ntohs(udvm_tvb, offset);
2019 *start_offset = offset;
2020 offset = offset + 2;
2025 * 0nnnnnnn memory[2 * N] 0 - 65535
2027 display_bytecode = bytecode & 0xc0;
2028 if ( display_udvm_bytecode )
2029 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
2030 udvm_tvb, offset, 1, display_bytecode);
2031 operand = ( bytecode & 0x7f);
2032 *value = (operand * 2);
2033 *start_offset = offset;
2041 *The fourth operand type is the address (@). This operand is decoded
2042 * as a multitype operand followed by a further step: the memory address
2043 * of the UDVM instruction containing the address operand is added to
2044 * obtain the correct operand value. So if the operand value from
2045 * Figure 10 is D then the actual operand value of an address is
2046 * calculated as follows:
2048 * operand_value = (is_memory_address_of_instruction + D) modulo 2^16
2049 * TODO calculate correct value for operand in case of ADDR
2052 dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
2053 gint offset, gboolean is_addr _U_, gint *start_offset, guint16 *value, gboolean *is_memory_address )
2056 guint display_bytecode;
2061 * Figure 10: Bytecode for a multitype (%) operand
2062 * Bytecode: Operand value: Range: HEX val
2063 * 00nnnnnn N 0 - 63 0x00
2064 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
2065 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
2066 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
2067 * 111nnnnn N + 65504 65504 - 65535 0xe0
2068 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
2069 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
2070 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
2071 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
2072 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
2074 *is_memory_address = FALSE;
2075 bytecode = tvb_get_guint8(udvm_tvb, offset);
2076 test_bits = ( bytecode & 0xc0 ) >> 6;
2077 switch (test_bits ){
2082 display_bytecode = bytecode & 0xc0;
2083 if ( display_udvm_bytecode )
2084 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2085 udvm_tvb, offset, 1, display_bytecode);
2086 operand = ( bytecode & 0x3f);
2088 *start_offset = offset;
2093 * 01nnnnnn memory[2 * N] 0 - 65535
2095 display_bytecode = bytecode & 0xc0;
2096 if ( display_udvm_bytecode )
2097 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2098 udvm_tvb, offset, 1, display_bytecode);
2099 operand = ( bytecode & 0x3f) * 2;
2100 *is_memory_address = TRUE;
2102 *start_offset = offset;
2106 /* Check tree most significant bits */
2107 test_bits = ( bytecode & 0xe0 ) >> 5;
2108 if ( test_bits == 5 ){
2110 * 101nnnnn nnnnnnnn N 0 - 8191
2112 display_bytecode = bytecode & 0xe0;
2113 if ( display_udvm_bytecode )
2114 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2115 udvm_tvb, offset, 1, display_bytecode);
2116 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x1fff;
2118 *start_offset = offset;
2119 offset = offset + 2;
2121 test_bits = ( bytecode & 0xf0 ) >> 4;
2122 if ( test_bits == 9 ){
2124 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535
2126 display_bytecode = bytecode & 0xf0;
2127 if ( display_udvm_bytecode )
2128 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2129 udvm_tvb, offset, 1, display_bytecode);
2130 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x0fff) + 61440;
2131 *start_offset = offset;
2133 offset = offset + 2;
2135 test_bits = ( bytecode & 0x08 ) >> 3;
2136 if ( test_bits == 1){
2138 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768
2140 display_bytecode = bytecode & 0xf8;
2141 if ( display_udvm_bytecode )
2142 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2143 udvm_tvb, offset, 1, display_bytecode);
2144 result = (guint32)pow(2,( bytecode & 0x07) + 8);
2145 operand = result & 0xffff;
2146 *start_offset = offset;
2150 test_bits = ( bytecode & 0x0e ) >> 1;
2151 if ( test_bits == 3 ){
2153 * 1000 011n 2 ^ (N + 6) 64 , 128
2155 display_bytecode = bytecode & 0xfe;
2156 if ( display_udvm_bytecode )
2157 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2158 udvm_tvb, offset, 1, display_bytecode);
2159 result = (guint32)pow(2,( bytecode & 0x01) + 6);
2160 operand = result & 0xffff;
2161 *start_offset = offset;
2166 * 1000 0000 nnnnnnnn nnnnnnnn N 0 - 65535
2167 * 1000 0001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
2169 display_bytecode = bytecode;
2170 if ( display_udvm_bytecode )
2171 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2172 udvm_tvb, offset, 1, display_bytecode);
2173 if ( (bytecode & 0x01) == 1 )
2174 *is_memory_address = TRUE;
2176 operand = tvb_get_ntohs(udvm_tvb, offset);
2178 *start_offset = offset;
2189 test_bits = ( bytecode & 0x20 ) >> 5;
2190 if ( test_bits == 1 ){
2192 * 111nnnnn N + 65504 65504 - 65535
2194 display_bytecode = bytecode & 0xe0;
2195 if ( display_udvm_bytecode )
2196 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2197 udvm_tvb, offset, 1, display_bytecode);
2198 operand = ( bytecode & 0x1f) + 65504;
2199 *start_offset = offset;
2204 * 110nnnnn nnnnnnnn memory[N] 0 - 65535
2206 display_bytecode = bytecode & 0xe0;
2207 if ( display_udvm_bytecode )
2208 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2209 udvm_tvb, offset, 1, display_bytecode);
2210 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x1fff);
2211 *is_memory_address = TRUE;
2212 *start_offset = offset;
2224 tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree)
2226 proto_tree *raw_tree = NULL;
2227 proto_item *ti = NULL;
2228 int offset, next_offset, linelen;
2231 ti = proto_tree_add_item(tree, proto_raw_sigcomp, tvb, 0, -1, ENC_NA);
2232 raw_tree = proto_item_add_subtree(ti, ett_raw_text);
2237 while (tvb_offset_exists(tvb, offset)) {
2238 tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
2239 linelen = next_offset - offset;
2241 proto_tree_add_text(raw_tree, tvb, offset, linelen,
2242 "%s", tvb_format_text(tvb, offset, linelen));
2244 offset = next_offset;
2248 /* Register the protocol with Wireshark */
2251 proto_register_sigcomp(void)
2253 void proto_reg_handoff_sigcomp(void);
2255 /* Setup list of header fields See Section 1.6.1 for details*/
2256 static hf_register_info hf[] = {
2257 { &hf_sigcomp_t_bit,
2258 { "T bit", "sigcomp.t.bit",
2259 FT_UINT8, BASE_DEC, NULL, 0x04,
2260 "Sigcomp T bit", HFILL }
2263 { "Partial state id length","sigcomp.length",
2264 FT_UINT8, BASE_HEX, VALS(length_encoding_vals), 0x03,
2265 "Sigcomp length", HFILL }
2267 { &hf_sigcomp_returned_feedback_item,
2268 { "Returned_feedback item", "sigcomp.returned.feedback.item",
2269 FT_BYTES, BASE_NONE, NULL, 0x0,
2270 "Returned feedback item", HFILL }
2272 { &hf_sigcomp_partial_state,
2273 { "Partial state identifier", "sigcomp.partial.state.identifier",
2274 FT_STRING, BASE_NONE, NULL, 0x0,
2277 { &hf_sigcomp_remaining_message_bytes,
2278 { "Remaining SigComp message bytes", "sigcomp.remaining-bytes",
2279 FT_UINT32, BASE_DEC, NULL, 0x0,
2280 "Number of bytes remaining in message", HFILL }
2282 { &hf_sigcomp_compression_ratio,
2283 { "Compression ratio (%)", "sigcomp.compression-ratio",
2284 FT_UINT32, BASE_DEC, NULL, 0x0,
2285 "Compression ratio (decompressed / compressed) %", HFILL }
2287 { &hf_sigcomp_returned_feedback_item_len,
2288 { "Returned feedback item length", "sigcomp.returned.feedback.item.len",
2289 FT_UINT8, BASE_DEC, NULL, 0x7f,
2292 { &hf_sigcomp_code_len,
2293 { "Code length","sigcomp.code.len",
2294 FT_UINT16, BASE_HEX, NULL, 0xfff0,
2297 { &hf_sigcomp_destination,
2298 { "Destination","sigcomp.destination",
2299 FT_UINT8, BASE_HEX, VALS(destination_address_encoding_vals), 0xf,
2302 { &hf_sigcomp_udvm_bytecode,
2303 { "Uploaded UDVM bytecode","sigcomp.udvm.byte-code",
2304 FT_NONE, BASE_NONE, NULL, 0x0,
2307 { &hf_sigcomp_udvm_instr,
2308 { "UDVM instruction code","sigcomp.udvm.instr",
2309 FT_UINT8, BASE_DEC, VALS(udvm_instruction_code_vals), 0x0,
2312 { &hf_udvm_execution_trace,
2313 { "UDVM execution trace","sigcomp.udvm.execution-trace",
2314 FT_NONE, BASE_NONE, NULL, 0x0,
2317 { &hf_udvm_multitype_bytecode,
2318 { "UDVM bytecode", "sigcomp.udvm.multyt.bytecode",
2319 FT_UINT8, BASE_HEX, VALS(display_bytecode_vals), 0x0,
2322 { &hf_udvm_reference_bytecode,
2323 { "UDVM bytecode", "sigcomp.udvm.ref.bytecode",
2324 FT_UINT8, BASE_HEX, VALS(display_ref_bytecode_vals), 0x0,
2327 { &hf_udvm_literal_bytecode,
2328 { "UDVM bytecode", "sigcomp.udvm.lit.bytecode",
2329 FT_UINT8, BASE_HEX, VALS(display_lit_bytecode_vals), 0x0,
2333 { "UDVM operand", "sigcomp.udvm.operand",
2334 FT_UINT16, BASE_DEC, NULL, 0x0,
2338 { "%Length", "sigcomp.udvm.length",
2339 FT_UINT16, BASE_DEC, NULL, 0x0,
2342 { &hf_udvm_addr_length,
2343 { "%Length[memory address]", "sigcomp.udvm.addr.length",
2344 FT_UINT16, BASE_DEC, NULL, 0x0,
2347 { &hf_udvm_destination,
2348 { "%Destination", "sigcomp.udvm.destination",
2349 FT_UINT16, BASE_DEC, NULL, 0x0,
2350 "Destination", HFILL }
2352 { &hf_udvm_addr_destination,
2353 { "%Destination[memory address]", "sigcomp.udvm.addr.destination",
2354 FT_UINT16, BASE_DEC, NULL, 0x0,
2355 "Destination", HFILL }
2357 { &hf_udvm_at_address,
2358 { "@Address(mem_add_of_inst + D) mod 2^16)", "sigcomp.udvm.at.address",
2359 FT_UINT16, BASE_DEC, NULL, 0x0,
2363 { "%Address", "sigcomp.udvm.length",
2364 FT_UINT16, BASE_DEC, NULL, 0x0,
2367 { &hf_udvm_literal_num,
2368 { "#n", "sigcomp.udvm.literal-num",
2369 FT_UINT16, BASE_DEC, NULL, 0x0,
2370 "Literal number", HFILL }
2373 { "%Value", "sigcomp.udvm.value",
2374 FT_UINT16, BASE_DEC, NULL, 0x0,
2377 { &hf_udvm_addr_value,
2378 { "%Value[memory address]", "sigcomp.udvm.value",
2379 FT_UINT16, BASE_DEC, NULL, 0x0,
2382 { &hf_partial_identifier_start,
2383 { "%Partial identifier start", "sigcomp.udvm.partial.identifier.start",
2384 FT_UINT16, BASE_DEC, NULL, 0x0,
2385 "Partial identifier start", HFILL }
2387 { &hf_partial_identifier_length,
2388 { "%Partial identifier length", "sigcomp.udvm.partial.identifier.length",
2389 FT_UINT16, BASE_DEC, NULL, 0x0,
2390 "Partial identifier length", HFILL }
2393 { "%State begin", "sigcomp.udvm.state.begin",
2394 FT_UINT16, BASE_DEC, NULL, 0x0,
2395 "State begin", HFILL }
2397 { &hf_udvm_state_length,
2398 { "%State length", "sigcomp.udvm.state.length",
2399 FT_UINT16, BASE_DEC, NULL, 0x0,
2400 "State length", HFILL }
2403 { &hf_udvm_state_length_addr,
2404 { "%State length[memory address]", "sigcomp.udvm.state.length.addr",
2405 FT_UINT16, BASE_DEC, NULL, 0x0,
2406 "State length", HFILL }
2408 { &hf_udvm_state_address,
2409 { "%State address", "sigcomp.udvm.start.address",
2410 FT_UINT16, BASE_DEC, NULL, 0x0,
2411 "State address", HFILL }
2413 { &hf_udvm_state_address_addr,
2414 { "%State address[memory address]", "sigcomp.udvm.start.address.addr",
2415 FT_UINT16, BASE_DEC, NULL, 0x0,
2416 "State address", HFILL }
2418 { &hf_udvm_state_instr,
2419 { "%State instruction", "sigcomp.udvm.start.instr",
2420 FT_UINT16, BASE_DEC, NULL, 0x0,
2421 "State instruction", HFILL }
2423 { &hf_udvm_operand_1,
2424 { "$Operand 1[memory address]", "sigcomp.udvm.operand.1",
2425 FT_UINT16, BASE_DEC, NULL, 0x0,
2426 "Reference $ Operand 1", HFILL }
2428 { &hf_udvm_operand_2,
2429 { "%Operand 2", "sigcomp.udvm.operand.2",
2430 FT_UINT16, BASE_DEC, NULL, 0x0,
2431 "Operand 2", HFILL }
2433 { &hf_udvm_operand_2_addr,
2434 { "%Operand 2[memory address]", "sigcomp.udvm.operand.2.addr",
2435 FT_UINT16, BASE_DEC, NULL, 0x0,
2436 "Operand 2", HFILL }
2439 { "%j", "sigcomp.udvm.j",
2440 FT_UINT16, BASE_DEC, NULL, 0x0,
2444 { "%j[memory address]", "sigcomp.udvm.addr.j",
2445 FT_UINT16, BASE_DEC, NULL, 0x0,
2448 { &hf_udvm_output_start,
2449 { "%Output_start", "sigcomp.output.start",
2450 FT_UINT16, BASE_DEC, NULL, 0x0,
2451 "Output start", HFILL }
2453 { &hf_udvm_addr_output_start,
2454 { "%Output_start[memory address]", "sigcomp.addr.output.start",
2455 FT_UINT16, BASE_DEC, NULL, 0x0,
2456 "Output start", HFILL }
2458 { &hf_udvm_output_length,
2459 { "%Output_length", "sigcomp.output.length",
2460 FT_UINT16, BASE_DEC, NULL, 0x0,
2461 "Output length", HFILL }
2463 { &hf_udvm_output_length_addr,
2464 { "%Output_length[memory address]", "sigcomp.output.length.addr",
2465 FT_UINT16, BASE_DEC, NULL, 0x0,
2466 "Output length", HFILL }
2468 { &hf_udvm_req_feedback_loc,
2469 { "%Requested feedback location", "sigcomp.req.feedback.loc",
2470 FT_UINT16, BASE_DEC, NULL, 0x0,
2471 "Requested feedback location", HFILL }
2473 { &hf_udvm_min_acc_len,
2474 { "%Minimum access length", "sigcomp.min.acc.len",
2475 FT_UINT16, BASE_DEC, NULL, 0x0,
2476 "Minimum access length", HFILL }
2478 { &hf_udvm_state_ret_pri,
2479 { "%State retention priority", "sigcomp.udvm.state.ret.pri",
2480 FT_UINT16, BASE_DEC, NULL, 0x0,
2481 "State retention priority", HFILL }
2483 { &hf_udvm_ret_param_loc,
2484 { "%Returned parameters location", "sigcomp.ret.param.loc",
2485 FT_UINT16, BASE_DEC, NULL, 0x0,
2486 "Returned parameters location", HFILL }
2488 { &hf_udvm_position,
2489 { "%Position", "sigcomp.udvm.position",
2490 FT_UINT16, BASE_DEC, NULL, 0x0,
2493 { &hf_udvm_ref_dest,
2494 { "$Destination[memory address]", "sigcomp.udvm.ref.destination",
2495 FT_UINT16, BASE_DEC, NULL, 0x0,
2496 "(reference)Destination", HFILL }
2499 { "%Bits", "sigcomp.udvm.bits",
2500 FT_UINT16, BASE_DEC, NULL, 0x0,
2503 { &hf_udvm_lower_bound,
2504 { "%Lower bound", "sigcomp.udvm.lower.bound",
2505 FT_UINT16, BASE_DEC, NULL, 0x0,
2506 "Lower_bound", HFILL }
2508 { &hf_udvm_upper_bound,
2509 { "%Upper bound", "sigcomp.udvm.upper.bound",
2510 FT_UINT16, BASE_DEC, NULL, 0x0,
2511 "Upper bound", HFILL }
2513 { &hf_udvm_uncompressed,
2514 { "%Uncompressed", "sigcomp.udvm.uncompressed",
2515 FT_UINT16, BASE_DEC, NULL, 0x0,
2516 "Uncompressed", HFILL }
2518 { &hf_udvm_start_value,
2519 { "%Start value", "sigcomp.udvm.start.value",
2520 FT_UINT16, BASE_DEC, NULL, 0x0,
2521 "Start value", HFILL }
2524 { "%Offset", "sigcomp.udvm.offset",
2525 FT_UINT16, BASE_DEC, NULL, 0x0,
2528 { &hf_udvm_addr_offset,
2529 { "%Offset[memory address]", "sigcomp.udvm.addr.offset",
2530 FT_UINT16, BASE_DEC, NULL, 0x0,
2533 { &hf_sigcomp_nack_ver,
2534 { "NACK Version", "sigcomp.nack.ver",
2535 FT_UINT8, BASE_DEC, NULL, 0x0f,
2538 { &hf_sigcomp_nack_reason_code,
2539 { "Reason Code", "sigcomp.nack.reason",
2540 FT_UINT8, BASE_DEC, VALS(sigcomp_nack_reason_code_vals), 0x0,
2541 "NACK Reason Code", HFILL }
2543 { &hf_sigcomp_nack_failed_op_code,
2544 { "OPCODE of failed instruction", "sigcomp.nack.failed_op_code",
2545 FT_UINT8, BASE_DEC, VALS(udvm_instruction_code_vals), 0x0,
2546 "NACK OPCODE of failed instruction", HFILL }
2548 { &hf_sigcomp_nack_pc,
2549 { "PC of failed instruction", "sigcomp.nack.pc",
2550 FT_UINT16, BASE_DEC, NULL, 0x0,
2551 "NACK PC of failed instruction", HFILL }
2553 { &hf_sigcomp_nack_sha1,
2554 { "SHA-1 Hash of failed message", "sigcomp.nack.sha1",
2555 FT_BYTES, BASE_NONE, NULL, 0x0,
2556 "NACK SHA-1 Hash of failed message", HFILL }
2558 { &hf_sigcomp_nack_state_id,
2559 { "State ID (6 - 20 bytes)", "sigcomp.nack.state_id",
2560 FT_BYTES, BASE_NONE, NULL, 0x0,
2561 "NACK State ID (6 - 20 bytes)", HFILL }
2563 { &hf_sigcomp_nack_cycles_per_bit,
2564 { "Cycles Per Bit", "sigcomp.nack.cycles_per_bit",
2565 FT_UINT8, BASE_DEC, NULL, 0x0,
2566 "NACK Cycles Per Bit", HFILL }
2568 { &hf_sigcomp_nack_memory_size,
2569 { "Memory size", "sigcomp.memory_size",
2570 FT_UINT16, BASE_DEC, NULL, 0x0,
2575 /* Setup protocol subtree array */
2576 static gint *ett[] = {
2579 &ett_sigcomp_udvm_exe,
2581 static gint *ett_raw[] = {
2585 module_t *sigcomp_module;
2586 static enum_val_t udvm_detail_vals[] = {
2587 {"no-printout", "No-Printout", 0},
2588 {"low-detail", "Low-detail", 1},
2589 {"medium-detail", "Medium-detail", 2},
2590 {"high-detail", "High-detail", 3},
2595 /* Register the protocol name and description */
2596 proto_sigcomp = proto_register_protocol("Signaling Compression",
2597 "SIGCOMP", "sigcomp");
2598 proto_raw_sigcomp = proto_register_protocol("Decompressed SigComp message as raw text",
2599 "Raw_SigComp", "raw_sigcomp");
2601 new_register_dissector("sigcomp", dissect_sigcomp, proto_sigcomp);
2603 /* Required function calls to register the header fields and subtrees used */
2604 proto_register_field_array(proto_sigcomp, hf, array_length(hf));
2605 proto_register_subtree_array(ett, array_length(ett));
2606 proto_register_subtree_array(ett_raw, array_length(ett_raw));
2608 /* Register a configuration option for port */
2609 sigcomp_module = prefs_register_protocol(proto_sigcomp,
2610 proto_reg_handoff_sigcomp);
2612 prefs_register_uint_preference(sigcomp_module, "udp.port",
2613 "Sigcomp UDP Port 1",
2614 "Set UDP port 1 for SigComp messages",
2618 prefs_register_uint_preference(sigcomp_module, "udp.port2",
2619 "Sigcomp UDP Port 2",
2620 "Set UDP port 2 for SigComp messages",
2623 prefs_register_uint_preference(sigcomp_module, "tcp.port",
2624 "Sigcomp TCP Port 1",
2625 "Set TCP port 1 for SigComp messages",
2629 prefs_register_uint_preference(sigcomp_module, "tcp.port2",
2630 "Sigcomp TCP Port 2",
2631 "Set TCP port 2 for SigComp messages",
2634 prefs_register_bool_preference(sigcomp_module, "display.udvm.code",
2635 "Dissect the UDVM code",
2636 "Preference whether to Dissect the UDVM code or not",
2637 &dissect_udvm_code);
2639 prefs_register_bool_preference(sigcomp_module, "display.bytecode",
2640 "Display the bytecode of operands",
2641 "preference whether to display the bytecode in "
2642 "UDVM operands or not",
2643 &display_udvm_bytecode);
2644 prefs_register_bool_preference(sigcomp_module, "decomp.msg",
2645 "Decompress message",
2646 "preference whether to decompress message or not",
2648 prefs_register_bool_preference(sigcomp_module, "display.decomp.msg.as.txt",
2649 "Displays the decompressed message as text",
2650 "preference whether to display the decompressed message "
2651 "as raw text or not",
2653 prefs_register_enum_preference(sigcomp_module, "show.udvm.execution",
2654 "Level of detail of UDVM execution:",
2655 "'No-Printout' = UDVM executes silently, then increasing detail "
2656 "about execution of UDVM instructions; "
2657 "Warning! CPU intense at high detail",
2658 &udvm_print_detail_level, udvm_detail_vals, FALSE);
2660 register_init_routine(&sigcomp_init_protocol);
2667 proto_reg_handoff_sigcomp(void)
2669 static dissector_handle_t sigcomp_handle;
2670 static dissector_handle_t sigcomp_tcp_handle;
2671 static gboolean Initialized=FALSE;
2672 static guint udp_port1;
2673 static guint udp_port2;
2674 static guint tcp_port1;
2675 static guint tcp_port2;
2678 sigcomp_handle = find_dissector("sigcomp");
2679 sigcomp_tcp_handle = new_create_dissector_handle(dissect_sigcomp_tcp,proto_sigcomp);
2680 sip_handle = find_dissector("sip");
2683 dissector_delete_uint("udp.port", udp_port1, sigcomp_handle);
2684 dissector_delete_uint("udp.port", udp_port2, sigcomp_handle);
2685 dissector_delete_uint("tcp.port", tcp_port1, sigcomp_tcp_handle);
2686 dissector_delete_uint("tcp.port", tcp_port2, sigcomp_tcp_handle);
2689 udp_port1 = SigCompUDPPort1;
2690 udp_port2 = SigCompUDPPort2;
2691 tcp_port1 = SigCompTCPPort1;
2692 tcp_port2 = SigCompTCPPort2;
2695 dissector_add_uint("udp.port", SigCompUDPPort1, sigcomp_handle);
2696 dissector_add_uint("udp.port", SigCompUDPPort2, sigcomp_handle);
2697 dissector_add_uint("tcp.port", SigCompTCPPort1, sigcomp_tcp_handle);
2698 dissector_add_uint("tcp.port", SigCompTCPPort2, sigcomp_tcp_handle);