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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
43 #include <epan/packet.h>
46 #include <epan/expert.h>
47 #include <epan/sigcomp-udvm.h>
48 #include <epan/sigcomp_state_hdlr.h>
50 /* Initialize the protocol and registered fields */
51 static int proto_sigcomp = -1;
52 static int proto_raw_sigcomp = -1;
53 static int hf_sigcomp_t_bit = -1;
54 static int hf_sigcomp_len = -1;
55 static int hf_sigcomp_returned_feedback_item = -1;
56 static int hf_sigcomp_returned_feedback_item_len = -1;
57 static int hf_sigcomp_code_len = -1;
58 static int hf_sigcomp_destination = -1;
59 static int hf_sigcomp_partial_state = -1;
60 static int hf_sigcomp_remaining_message_bytes = -1;
61 static int hf_sigcomp_compression_ratio = -1;
62 static int hf_sigcomp_udvm_bytecode = -1;
63 static int hf_sigcomp_udvm_instr = -1;
64 static int hf_udvm_multitype_bytecode = -1;
65 static int hf_udvm_reference_bytecode = -1;
66 static int hf_udvm_literal_bytecode = -1;
67 static int hf_udvm_operand = -1;
68 static int hf_udvm_length = -1;
69 static int hf_udvm_addr_length = -1;
70 static int hf_udvm_destination = -1;
71 static int hf_udvm_addr_destination = -1;
72 static int hf_udvm_at_address = -1;
73 static int hf_udvm_address = -1;
74 static int hf_udvm_literal_num = -1;
75 static int hf_udvm_value = -1;
76 static int hf_udvm_addr_value = -1;
77 static int hf_partial_identifier_start = -1;
78 static int hf_partial_identifier_length = -1;
79 static int hf_state_begin = -1;
80 static int hf_udvm_state_length = -1;
81 static int hf_udvm_state_length_addr = -1;
82 static int hf_udvm_state_address = -1;
83 static int hf_udvm_state_address_addr = -1;
84 static int hf_udvm_state_instr = -1;
85 static int hf_udvm_operand_1 = -1;
86 static int hf_udvm_operand_2 = -1;
87 static int hf_udvm_operand_2_addr = -1;
88 static int hf_udvm_j = -1;
89 static int hf_udvm_addr_j = -1;
90 static int hf_udvm_output_start = -1;
91 static int hf_udvm_addr_output_start = -1;
92 static int hf_udvm_output_length = -1;
93 static int hf_udvm_output_length_addr = -1;
94 static int hf_udvm_req_feedback_loc = -1;
95 static int hf_udvm_min_acc_len = -1;
96 static int hf_udvm_state_ret_pri = -1;
97 static int hf_udvm_ret_param_loc = -1;
98 static int hf_udvm_position = -1;
99 static int hf_udvm_ref_dest = -1;
100 static int hf_udvm_bits = -1;
101 static int hf_udvm_lower_bound = -1;
102 static int hf_udvm_upper_bound = -1;
103 static int hf_udvm_uncompressed = -1;
104 static int hf_udvm_offset = -1;
105 static int hf_udvm_addr_offset = -1;
106 static int hf_udvm_start_value = -1;
107 static int hf_udvm_execution_trace = -1;
108 static int hf_sigcomp_nack_ver = -1;
109 static int hf_sigcomp_nack_reason_code = -1;
110 static int hf_sigcomp_nack_failed_op_code = -1;
111 static int hf_sigcomp_nack_pc = -1;
112 static int hf_sigcomp_nack_sha1 = -1;
113 static int hf_sigcomp_nack_state_id = -1;
114 static int hf_sigcomp_nack_memory_size = -1;
115 static int hf_sigcomp_nack_cycles_per_bit = -1;
117 /* Initialize the subtree pointers */
118 static gint ett_sigcomp = -1;
119 static gint ett_sigcomp_udvm = -1;
120 static gint ett_sigcomp_udvm_exe = -1;
121 static gint ett_raw_text = -1;
123 static dissector_handle_t sip_handle;
124 /* set the udp ports */
125 static guint SigCompUDPPort1 = 5555;
126 static guint SigCompUDPPort2 = 6666;
128 /* set the tcp ports */
129 static guint SigCompTCPPort1 = 5555;
130 static guint SigCompTCPPort2 = 6666;
132 /* Default preference whether to display the bytecode in UDVM operands or not */
133 static gboolean display_udvm_bytecode = FALSE;
134 /* Default preference whether to dissect the UDVM code or not */
135 static gboolean dissect_udvm_code = TRUE;
136 static gboolean display_raw_txt = FALSE;
137 /* Default preference whether to decompress the message or not */
138 static gboolean decompress = TRUE;
139 /* Default preference whether to print debug info at execution of UDVM
141 * 1 = details level 1
142 * 2 = details level 2
143 * 3 = details level 3
144 * 4 = details level 4
146 static gint udvm_print_detail_level = 0;
149 static const value_string length_encoding_vals[] = {
150 { 0x00, "No partial state (Message type 2)" },
151 { 0x01, "(6 bytes)" },
152 { 0x02, "(9 bytes)" },
153 { 0x03, "(12 bytes)" },
158 static const value_string destination_address_encoding_vals[] = {
159 { 0x00, "Reserved" },
178 static const value_string udvm_instruction_code_vals[] = {
179 { 0, "DECOMPRESSION-FAILURE" },
190 { 11, "SORT-ASCENDING" },
191 { 12, "SORT-DESCENDING" },
198 { 19, "COPY-LITERAL" },
199 { 20, "COPY-OFFSET" },
207 { 28, "INPUT-BYTES" },
208 { 29, "INPUT-BITS" },
209 { 30, "INPUT-HUFFMAN" },
210 { 31, "STATE-ACCESS" },
211 { 32, "STATE-CREATE" },
212 { 33, "STATE-FREE" },
214 { 35, "END-MESSAGE" },
218 * Figure 10: Bytecode for a multitype (%) operand
219 * Bytecode: Operand value: Range: HEX val
220 * 00nnnnnn N 0 - 63 0x00
221 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
222 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
223 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
224 * 111nnnnn N + 65504 65504 - 65535 0xe0
225 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
226 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
227 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
228 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
229 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
232 static const value_string display_bytecode_vals[] = {
233 { 0x00, "00nnnnnn, N, 0 - 63" },
234 { 0x40, "01nnnnnn, memory[2 * N],0 - 65535" },
235 { 0x86, "1000011n, 2 ^ (N + 6), 64 , 128" },
236 { 0x88, "10001nnn, 2 ^ (N + 8), 256,..., 32768" },
237 { 0xe0, "111nnnnn N + 65504, 65504 - 65535" },
238 { 0x90, "1001nnnn nnnnnnnn, N + 61440, 61440 - 65535" },
239 { 0xa0, "101nnnnn nnnnnnnn, N, 0 - 8191" },
240 { 0xc0, "110nnnnn nnnnnnnn, memory[N], 0 - 65535" },
241 { 0x80, "10000000 nnnnnnnn nnnnnnnn, N, 0 - 65535" },
242 { 0x81, "10000001 nnnnnnnn nnnnnnnn, memory[N], 0 - 65535" },
246 * 0nnnnnnn memory[2 * N] 0 - 65535
247 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
248 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
250 static const value_string display_ref_bytecode_vals[] = {
251 { 0x00, "0nnnnnnn memory[2 * N] 0 - 65535" },
252 { 0x80, "10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535" },
253 { 0xc0, "11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535" },
256 /* The simplest operand type is the literal (#), which encodes a
257 * constant integer from 0 to 65535 inclusive. A literal operand may
258 * require between 1 and 3 bytes depending on its value.
259 * Bytecode: Operand value: Range:
261 * 10nnnnnn nnnnnnnn N 0 - 16383
262 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
264 * Figure 8: Bytecode for a literal (#) operand
268 static const value_string display_lit_bytecode_vals[] = {
269 { 0x00, "0nnnnnnn N 0 - 127" },
270 { 0x80, "10nnnnnn nnnnnnnn N 0 - 16383" },
271 { 0xc0, "11000000 nnnnnnnn nnnnnnnn N 0 - 65535" },
275 #define SIGCOMP_NACK_STATE_NOT_FOUND 1
276 #define SIGCOMP_NACK_CYCLES_EXHAUSTED 2
277 #define SIGCOMP_NACK_BYTECODES_TOO_LARGE 18
278 #define SIGCOMP_NACK_ID_NOT_UNIQUE 21
279 #define SIGCOMP_NACK_STATE_TOO_SHORT 23
281 static const value_string sigcomp_nack_reason_code_vals[] = {
282 { 1, "STATE_NOT_FOUND" }, /*1 State ID (6 - 20 bytes) */
283 { 2, "CYCLES_EXHAUSTED" }, /*2 Cycles Per Bit (1 byte) */
284 { 3, "USER_REQUESTED" },
286 { 5, "TOO_MANY_STATE_REQUESTS" },
287 { 6, "INVALID_STATE_ID_LENGTH" },
288 { 7, "INVALID_STATE_PRIORITY" },
289 { 8, "OUTPUT_OVERFLOW" },
290 { 9, "STACK_UNDERFLOW" },
291 { 10, "BAD_INPUT_BITORDER" },
292 { 11, "DIV_BY_ZERO" },
293 { 12, "SWITCH_VALUE_TOO_HIGH" },
294 { 13, "TOO_MANY_BITS_REQUESTED" },
295 { 14, "INVALID_OPERAND" },
296 { 15, "HUFFMAN_NO_MATCH" },
297 { 16, "MESSAGE_TOO_SHORT" },
298 { 17, "INVALID_CODE_LOCATION" },
299 { 18, "BYTECODES_TOO_LARGE" }, /*18 Memory size (2 bytes) */
300 { 19, "INVALID_OPCODE" },
301 { 20, "INVALID_STATE_PROBE" },
302 { 21, "ID_NOT_UNIQUE" }, /*21 State ID (6 - 20 bytes) */
303 { 22, "MULTILOAD_OVERWRITTEN" },
304 { 23, "STATE_TOO_SHORT" }, /*23 State ID (6 - 20 bytes) */
305 { 24, "INTERNAL_ERROR" },
306 { 25, "FRAMING_ERROR" },
311 static void dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, guint destination);
313 static int dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
314 gint offset,gboolean is_addr,gint *start_offset,
315 guint16 *value, gboolean *is_memory_address );
317 static int dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
318 gint offset, gint *start_offset, guint16 *value);
320 static int dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
321 gint offset, gint *start_offset, guint16 *value);
322 static void tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree);
324 static int dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
326 static proto_tree *top_tree;
328 /* Initialize the state handler
332 sigcomp_init_protocol(void)
336 /* Sigcomp over TCP record marking used
338 * 4.2.2. Record Marking
340 * For a stream-based transport, the dispatcher delimits messages by
341 * parsing the compressed data stream for instances of 0xFF and taking
342 * the following actions:
343 * Occurs in data stream: Action:
345 * 0xFF 00 one 0xFF byte in the data stream
346 * 0xFF 01 same, but the next byte is quoted (could
349 * 0xFF 7F same, but the next 127 bytes are quoted
350 * 0xFF 80 to 0xFF FE (reserved for future standardization)
351 * 0xFF FF end of SigComp message
353 * In UDVM version 0x01, any occurrence of the combinations 0xFF80 to
354 * 0xFFFE that are not protected by quoting causes decompression
355 * failure; the decompressor SHOULD close the stream-based transport in
360 * TODO: Reassembly, handle more than one message in a tcp segment.
364 dissect_sigcomp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
367 proto_tree *sigcomp_tree;
368 tvbuff_t *unescaped_tvb;
377 gboolean end_off_message;
381 /* Is this SIGCOMP ? */
382 data = tvb_get_ntohs(tvb, offset);
386 octet = tvb_get_guint8(tvb,offset);
388 octet = tvb_get_guint8(tvb,offset);
390 if ((octet & 0xf8) != 0xf8)
393 /* Search for delimiter 0xffff in the remain tvb buffer */
394 length = tvb_ensure_length_remaining(tvb, offset);
395 for(i=0; i<(length-1); ++i){
396 /* Loop end criteria is (length-1) because we take 2 bytes each loop */
397 data = tvb_get_ntohs(tvb, offset+i);
398 if (0xffff == data) break;
400 if (i >= (length-1)){
401 /* SIGCOMP may be subdissector of SIP, so we use
402 * pinfo->saved_can_desegment to determine whether do desegment
403 * as well as pinfo->can_desegment */
404 if (pinfo->can_desegment || pinfo->saved_can_desegment){
405 /* Delimiter oxffff was not found, not a complete SIGCOMP PDU */
406 pinfo->desegment_offset = offset;
407 pinfo->desegment_len=DESEGMENT_ONE_MORE_SEGMENT;
412 /* Make entries in Protocol column and Info column on summary display */
413 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
415 col_clear(pinfo->cinfo, COL_INFO);
417 length = tvb_length_remaining(tvb,offset);
420 /* create display subtree for the protocol */
421 ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, FALSE);
422 sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
424 end_off_message = FALSE;
425 buff = g_malloc(length-offset);
426 if (udvm_print_detail_level>2)
427 proto_tree_add_text(sigcomp_tree, tvb, offset, -1,"Starting to remove escape digits");
428 while ((offset < length) && (end_off_message == FALSE)){
429 octet = tvb_get_guint8(tvb,offset);
430 if ( octet == 0xff ){
431 if ( offset +1 >= length ){
432 /* if the tvb is short dont check for the second escape digit */
436 if (udvm_print_detail_level>2)
437 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
438 " Escape digit found (0xFF)");
439 octet = tvb_get_guint8(tvb, offset+1);
446 if ((octet > 0x7f) && (octet < 0xff )){
447 if (udvm_print_detail_level>2)
448 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
449 " Illegal escape code");
450 offset = offset + tvb_length_remaining(tvb,offset);
454 if (udvm_print_detail_level>2)
455 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
456 " End of SigComp message indication found (0xFFFF)");
457 end_off_message = TRUE;
462 if (udvm_print_detail_level>2)
463 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
464 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
467 if (udvm_print_detail_level>2)
468 proto_tree_add_text(sigcomp_tree, tvb, offset, octet,
469 " Copying %u bytes literally",octet);
470 if( offset+octet >= length)
471 /* if the tvb is short dont copy further than the end */
472 octet = length - offset;
473 for ( n=0; n < octet; n++ ){
474 buff[i] = tvb_get_guint8(tvb, offset);
475 if (udvm_print_detail_level>2)
476 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
477 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
484 if (udvm_print_detail_level>2)
485 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
486 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
491 unescaped_tvb = tvb_new_child_real_data(tvb, buff,i,i);
492 /* Arrange that the allocated packet data copy be freed when the
495 tvb_set_free_cb( unescaped_tvb, g_free );
497 add_new_data_source(pinfo, unescaped_tvb, "Unescaped Data handed to the SigComp dissector");
499 proto_tree_add_text(sigcomp_tree, unescaped_tvb, 0, -1,"Data handed to the Sigcomp dissector");
500 if (end_off_message == TRUE){
501 dissect_sigcomp_common(unescaped_tvb, pinfo, sigcomp_tree);
503 proto_tree_add_text(sigcomp_tree, unescaped_tvb, 0, -1,"TCP Fragment, no end mark found");
505 if ( offset < length){
511 /* Code to actually dissect the packets */
513 dissect_sigcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
516 proto_tree *sigcomp_tree;
520 /* If we got called from SIP this might be over TCP */
521 if ( pinfo->ptype == PT_TCP )
522 return dissect_sigcomp_tcp(tvb, pinfo, tree);
524 /* Is this a SigComp message or not ? */
525 octet = tvb_get_guint8(tvb, offset);
526 if ((octet & 0xf8) != 0xf8)
529 /* Make entries in Protocol column and Info column on summary display */
530 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
532 col_clear(pinfo->cinfo, COL_INFO);
536 /* create display subtree for the protocol */
537 ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, FALSE);
538 sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
540 return dissect_sigcomp_common(tvb, pinfo, sigcomp_tree);
542 /* Code to actually dissect the packets */
544 dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sigcomp_tree)
547 /* Set up structures needed to add the protocol subtree and manage it */
548 tvbuff_t *udvm_tvb, *msg_tvb, *udvm2_tvb;
549 tvbuff_t *decomp_tvb = NULL;
550 proto_item *udvm_bytecode_item, *udvm_exe_item;
551 proto_tree *sigcomp_udvm_tree, *sigcomp_udvm_exe_tree;
553 gint bytecode_offset;
554 guint16 partial_state_len;
556 guint8 returned_feedback_field[128];
557 guint8 partial_state[12];
560 guint16 bytecode_len = 0;
567 guint16 state_length;
568 guint16 state_address;
569 guint16 state_instruction;
571 gchar *partial_state_str;
576 /* add an item to the subtree, see section 1.6 for more information */
577 octet = tvb_get_guint8(tvb, offset);
579 /* A SigComp message takes one of two forms depending on whether it
580 * accesses a state item at the receiving endpoint. The two variants of
581 * a SigComp message are given in Figure 3. (The T-bit controls the
582 * format of the returned feedback item and is defined in Section 7.1.)
584 * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
585 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
586 * | 1 1 1 1 1 | T | len | | 1 1 1 1 1 | T | 0 |
587 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
589 * : returned feedback item : : returned feedback item :
591 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
593 * : partial state identifier : +---+---+---+---+---+---+---+---+
595 * | | | code_len | destination |
596 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
598 * : remaining SigComp message : : uploaded UDVM bytecode :
600 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
602 * : remaining SigComp message :
604 * +---+---+---+---+---+---+---+---+
607 * The format of the NACK message and the use of the fields within it
608 * are shown in Figure 1.
611 * +---+---+---+---+---+---+---+---+
612 * | 1 1 1 1 1 | T | 0 |
613 * +---+---+---+---+---+---+---+---+
615 * : returned feedback item :
617 * +---+---+---+---+---+---+---+---+
619 * +---+---+---+---+---+---+---+---+
620 * | code_len = 0 | version = 1 |
621 * +---+---+---+---+---+---+---+---+
623 * +---+---+---+---+---+---+---+---+
624 * | OPCODE of failed instruction |
625 * +---+---+---+---+---+---+---+---+
626 * | PC of failed instruction |
628 * +---+---+---+---+---+---+---+---+
630 * : SHA-1 Hash of failed message :
632 * +---+---+---+---+---+---+---+---+
636 * +---+---+---+---+---+---+---+---+
637 * Figure 1: SigComp NACK Message Format
640 proto_tree_add_item(sigcomp_tree,hf_sigcomp_t_bit, tvb, offset, 1, FALSE);
641 proto_tree_add_item(sigcomp_tree,hf_sigcomp_len, tvb, offset, 1, FALSE);
642 tbit = ( octet & 0x04)>>2;
643 partial_state_len = octet & 0x03;
645 if ( partial_state_len != 0 ){
647 * The len field encodes the number of transmitted bytes as follows:
649 * Encoding: Length of partial state identifier
656 partial_state_len = partial_state_len * 3 + 3;
661 col_set_str(pinfo->cinfo, COL_INFO, "Msg format 1");
665 * Returned feedback item exists
668 octet = tvb_get_guint8(tvb, offset);
669 /* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
670 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
671 * | 0 | returned_feedback_field | | 1 | returned_feedback_length |
672 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
674 * : returned_feedback_field :
676 * +---+---+---+---+---+---+---+---+
677 * Figure 4: Format of returned feedback item
680 if ( (octet & 0x80) != 0 ){
682 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
683 tvb, offset, 1, FALSE);
685 tvb_memcpy(tvb,returned_feedback_field,offset, len);
687 returned_feedback_field[0] = tvb_get_guint8(tvb, offset) & 0x7f;
689 proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
690 tvb, offset, len, returned_feedback_field);
691 offset = offset + len;
693 tvb_memcpy(tvb, partial_state, offset, partial_state_len);
694 partial_state_str = bytes_to_str(partial_state, partial_state_len);
695 proto_tree_add_string(sigcomp_tree,hf_sigcomp_partial_state,
696 tvb, offset, partial_state_len, partial_state_str);
697 offset = offset + partial_state_len;
698 msg_len = tvb_reported_length_remaining(tvb, offset);
702 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_remaining_message_bytes, tvb,
704 PROTO_ITEM_SET_GENERATED(ti);
708 msg_tvb = tvb_new_subset(tvb, offset, msg_len, msg_len);
710 * buff = Where "state" will be stored
711 * p_id_start = Partial state identifier start pos in the buffer(buff)
712 * partial_state_len = Partial state identifier length
713 * state_begin = Where to start to read state from
714 * state_length = Length of state
715 * state_address = Address where to store the state in the buffer(buff)
716 * state_instruction =
717 * TRUE = Indicates that state_* is in the stored state
720 * Note: The allocate buffer must be zeroed or some strange effects might occur.
722 buff = g_malloc0(UDVM_MEMORY_SIZE);
727 /* These values will be loaded from the buffered state in sigcomp_state_hdlr
731 state_instruction =0;
734 while ( i < partial_state_len ){
735 buff[i] = partial_state[i];
739 /* begin partial state-id change cco@iptel.org */
741 result_code = udvm_state_access(tvb, sigcomp_tree, buff, p_id_start, partial_state_len, state_begin, &state_length,
742 &state_address, &state_instruction, hf_sigcomp_partial_state);
744 result_code = udvm_state_access(tvb, sigcomp_tree, buff, p_id_start, STATE_MIN_ACCESS_LEN, state_begin, &state_length,
745 &state_address, &state_instruction, hf_sigcomp_partial_state);
747 /* end partial state-id change cco@iptel.org */
748 if ( result_code != 0 ){
750 ti = proto_tree_add_text(sigcomp_tree, tvb, 0, -1,"Failed to Access state Wireshark UDVM diagnostic: %s.",
751 val_to_str(result_code, result_code_vals,"Unknown (%u)"));
752 PROTO_ITEM_SET_GENERATED(ti);
754 return tvb_length(tvb);
757 udvm_tvb = tvb_new_child_real_data(tvb, buff,state_length+state_address,state_length+state_address);
758 /* Arrange that the allocated packet data copy be freed when the
761 tvb_set_free_cb( udvm_tvb, g_free );
764 udvm2_tvb = tvb_new_subset(udvm_tvb, state_address, state_length, state_length);
765 /* TODO Check if buff needs to be free'd */
766 udvm_exe_item = proto_tree_add_item(sigcomp_tree, hf_udvm_execution_trace,
767 udvm2_tvb, 0, state_length,
769 sigcomp_udvm_exe_tree = proto_item_add_subtree( udvm_exe_item, ett_sigcomp_udvm_exe);
771 decomp_tvb = decompress_sigcomp_message(udvm2_tvb, msg_tvb, pinfo,
772 sigcomp_udvm_exe_tree, state_address,
773 udvm_print_detail_level, hf_sigcomp_partial_state,
774 offset, state_length, partial_state_len, state_instruction);
779 guint32 compression_ratio =
780 (guint32)(((float)tvb_length(decomp_tvb) / (float)tvb_length(tvb)) * 100);
782 /* Celebrate success and show compression ratio achieved */
783 proto_tree_add_text(sigcomp_tree, decomp_tvb, 0, -1,"SigComp message Decompressed WOHO!!");
784 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_compression_ratio, decomp_tvb,
785 0, 0, compression_ratio);
786 PROTO_ITEM_SET_GENERATED(ti);
788 if ( display_raw_txt )
789 tvb_raw_text_add(decomp_tvb, top_tree);
790 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
791 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
792 col_set_fence(pinfo->cinfo,COL_PROTOCOL);
794 call_dissector(sip_handle, decomp_tvb, pinfo, top_tree);
803 col_set_str(pinfo->cinfo, COL_INFO, "Msg format 2");
806 * Returned feedback item exists
809 octet = tvb_get_guint8(tvb, offset);
810 if ( (octet & 0x80) != 0 ){
812 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
813 tvb, offset, 1, FALSE);
816 tvb_memcpy(tvb,returned_feedback_field,offset, len);
817 proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
818 tvb, offset, len, returned_feedback_field);
819 offset = offset + len;
821 len = tvb_get_ntohs(tvb, offset) >> 4;
822 nack_version = tvb_get_guint8(tvb, offset+1) & 0x0f;
823 if ((len == 0) && (nack_version == 1)){
825 proto_item *reason_ti;
828 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_ver, tvb, offset, 1, FALSE);
830 octet = tvb_get_guint8(tvb, offset);
831 reason_ti = proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_reason_code, tvb, offset, 1, FALSE);
833 opcode = tvb_get_guint8(tvb, offset);
834 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_failed_op_code, tvb, offset, 1, FALSE);
837 /* Add expert item for NACK */
838 expert_add_info_format(pinfo, reason_ti, PI_SEQUENCE, PI_WARN,
839 "SigComp NACK (reason=%s, opcode=%s)",
840 val_to_str(octet, sigcomp_nack_reason_code_vals, "Unknown"),
841 val_to_str(opcode, udvm_instruction_code_vals, "Unknown"));
843 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_pc, tvb, offset, 2, FALSE);
845 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_sha1, tvb, offset, 20, FALSE);
848 /* Add NACK info to info column */
849 if (check_col(pinfo->cinfo, COL_INFO)){
850 col_append_fstr(pinfo->cinfo, COL_INFO, " NACK reason=%s, opcode=%s",
851 val_to_str(octet, sigcomp_nack_reason_code_vals, "Unknown"),
852 val_to_str(opcode, udvm_instruction_code_vals, "Unknown"));
856 case SIGCOMP_NACK_STATE_NOT_FOUND:
857 case SIGCOMP_NACK_ID_NOT_UNIQUE:
858 case SIGCOMP_NACK_STATE_TOO_SHORT:
859 /* State ID (6 - 20 bytes) */
860 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_state_id, tvb, offset, -1, FALSE);
862 case SIGCOMP_NACK_CYCLES_EXHAUSTED:
863 /* Cycles Per Bit (1 byte) */
864 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_cycles_per_bit, tvb, offset, 1, FALSE);
866 case SIGCOMP_NACK_BYTECODES_TOO_LARGE:
867 /* Memory size (2 bytes) */
868 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_memory_size, tvb, offset, 2, FALSE);
874 octet = tvb_get_guint8(tvb, (offset + 1));
875 destination = (octet & 0x0f);
876 if ( destination != 0 )
877 destination = 64 + ( destination * 64 );
878 proto_tree_add_item(sigcomp_tree,hf_sigcomp_code_len, tvb, offset, 2, FALSE);
879 proto_tree_add_item(sigcomp_tree,hf_sigcomp_destination, tvb, (offset+ 1), 1, FALSE);
883 bytecode_offset = offset;
884 udvm_bytecode_item = proto_tree_add_item(sigcomp_tree, hf_sigcomp_udvm_bytecode, tvb,
885 bytecode_offset, bytecode_len, FALSE);
886 proto_item_append_text(udvm_bytecode_item,
887 " %u (0x%x) bytes", bytecode_len, bytecode_len);
888 sigcomp_udvm_tree = proto_item_add_subtree( udvm_bytecode_item, ett_sigcomp_udvm);
890 udvm_tvb = tvb_new_subset(tvb, offset, len, len);
891 if ( dissect_udvm_code )
892 dissect_udvm_bytecode(udvm_tvb, sigcomp_udvm_tree, destination);
894 offset = offset + len;
895 msg_len = tvb_reported_length_remaining(tvb, offset);
897 proto_item *ti = proto_tree_add_text(sigcomp_tree, tvb, offset, -1,
898 "Remaining SigComp message %u bytes",
899 tvb_reported_length_remaining(tvb, offset));
900 PROTO_ITEM_SET_GENERATED(ti);
904 msg_tvb = tvb_new_subset(tvb, offset, msg_len, msg_len);
906 udvm_exe_item = proto_tree_add_item(sigcomp_tree, hf_udvm_execution_trace,
907 tvb, bytecode_offset, bytecode_len,
909 sigcomp_udvm_exe_tree = proto_item_add_subtree( udvm_exe_item, ett_sigcomp_udvm_exe);
910 decomp_tvb = decompress_sigcomp_message(udvm_tvb, msg_tvb, pinfo,
911 sigcomp_udvm_exe_tree, destination,
912 udvm_print_detail_level, hf_sigcomp_partial_state,
913 offset, 0, 0, destination);
916 guint32 compression_ratio =
917 (guint32)(((float)tvb_length(decomp_tvb) / (float)tvb_length(tvb)) * 100);
919 /* Celebrate success and show compression ratio achieved */
920 proto_tree_add_text(sigcomp_tree, decomp_tvb, 0, -1,"SigComp message Decompressed WOHO!!");
921 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_compression_ratio, decomp_tvb,
922 0, 0, compression_ratio);
923 PROTO_ITEM_SET_GENERATED(ti);
925 if ( display_raw_txt )
926 tvb_raw_text_add(decomp_tvb, top_tree);
927 if (check_col(pinfo->cinfo, COL_PROTOCOL)){
928 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
929 col_set_fence(pinfo->cinfo,COL_PROTOCOL);
931 call_dissector(sip_handle, decomp_tvb, pinfo, top_tree);
933 } /* if decompress */
937 return tvb_length(tvb);
941 #define SIGCOMP_INSTR_DECOMPRESSION_FAILURE 0
942 #define SIGCOMP_INSTR_AND 1
943 #define SIGCOMP_INSTR_OR 2
944 #define SIGCOMP_INSTR_NOT 3
945 #define SIGCOMP_INSTR_LSHIFT 4
946 #define SIGCOMP_INSTR_RSHIFT 5
947 #define SIGCOMP_INSTR_ADD 6
948 #define SIGCOMP_INSTR_SUBTRACT 7
949 #define SIGCOMP_INSTR_MULTIPLY 8
950 #define SIGCOMP_INSTR_DIVIDE 9
951 #define SIGCOMP_INSTR_REMAINDER 10
952 #define SIGCOMP_INSTR_SORT_ASCENDING 11
953 #define SIGCOMP_INSTR_SORT_DESCENDING 12
954 #define SIGCOMP_INSTR_SHA_1 13
955 #define SIGCOMP_INSTR_LOAD 14
956 #define SIGCOMP_INSTR_MULTILOAD 15
957 #define SIGCOMP_INSTR_PUSH 16
958 #define SIGCOMP_INSTR_POP 17
959 #define SIGCOMP_INSTR_COPY 18
960 #define SIGCOMP_INSTR_COPY_LITERAL 19
961 #define SIGCOMP_INSTR_COPY_OFFSET 20
962 #define SIGCOMP_INSTR_MEMSET 21
963 #define SIGCOMP_INSTR_JUMP 22
964 #define SIGCOMP_INSTR_COMPARE 23
965 #define SIGCOMP_INSTR_CALL 24
966 #define SIGCOMP_INSTR_RETURN 25
967 #define SIGCOMP_INSTR_SWITCH 26
968 #define SIGCOMP_INSTR_CRC 27
969 #define SIGCOMP_INSTR_INPUT_BYTES 28
970 #define SIGCOMP_INSTR_INPUT_BITS 29
971 #define SIGCOMP_INSTR_INPUT_HUFFMAN 30
972 #define SIGCOMP_INSTR_STATE_ACCESS 31
973 #define SIGCOMP_INSTR_STATE_CREATE 32
974 #define SIGCOMP_INSTR_STATE_FREE 33
975 #define SIGCOMP_INSTR_OUTPUT 34
976 #define SIGCOMP_INSTR_END_MESSAGE 35
980 dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,guint start_address)
987 guint instruction_no = 0;
989 proto_item *item, *item2;
990 guint UDVM_address = start_address;
991 gboolean is_memory_address;
992 guint16 msg_length = tvb_reported_length_remaining(udvm_tvb, offset);
995 while (msg_length > offset) {
996 instruction = tvb_get_guint8(udvm_tvb, offset);
998 UDVM_address = start_address + offset;
1001 item = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
1002 "######### UDVM instruction %u at UDVM-address %u (0x%x) #########",
1003 instruction_no,UDVM_address,UDVM_address);
1004 PROTO_ITEM_SET_GENERATED(item);
1005 proto_tree_add_item(sigcomp_udvm_tree, hf_sigcomp_udvm_instr, udvm_tvb, offset, 1, FALSE);
1007 switch ( instruction ) {
1009 case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */
1011 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1012 len = offset - start_offset;
1013 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1014 udvm_tvb, start_offset, len, value);
1016 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1017 len = offset - start_offset;
1018 if ( is_memory_address ){
1019 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1020 udvm_tvb, start_offset, len, value);
1022 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1023 udvm_tvb, start_offset, len, value);
1027 case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */
1029 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1030 len = offset - start_offset;
1031 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1032 udvm_tvb, start_offset, len, value);
1034 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1035 len = offset - start_offset;
1036 if ( is_memory_address ){
1037 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1038 udvm_tvb, start_offset, len, value);
1040 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1041 udvm_tvb, start_offset, len, value);
1045 case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */
1047 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1048 len = offset - start_offset;
1049 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1050 udvm_tvb, start_offset, len, value);
1053 case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */
1055 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1056 len = offset - start_offset;
1057 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1058 udvm_tvb, start_offset, len, value);
1060 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1061 len = offset - start_offset;
1062 if ( is_memory_address ){
1063 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1064 udvm_tvb, start_offset, len, value);
1066 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1067 udvm_tvb, start_offset, len, value);
1071 case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */
1073 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1074 len = offset - start_offset;
1075 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1076 udvm_tvb, start_offset, len, value);
1078 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1079 len = offset - start_offset;
1080 if ( is_memory_address ){
1081 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1082 udvm_tvb, start_offset, len, value);
1084 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1085 udvm_tvb, start_offset, len, value);
1089 case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */
1091 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1092 len = offset - start_offset;
1093 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1094 udvm_tvb, start_offset, len, value);
1096 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1097 len = offset - start_offset;
1098 if ( is_memory_address ){
1099 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1100 udvm_tvb, start_offset, len, value);
1102 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1103 udvm_tvb, start_offset, len, value);
1107 case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */
1109 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1110 len = offset - start_offset;
1111 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1112 udvm_tvb, start_offset, len, value);
1114 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1115 len = offset - start_offset;
1116 if ( is_memory_address ){
1117 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1118 udvm_tvb, start_offset, len, value);
1120 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1121 udvm_tvb, start_offset, len, value);
1125 case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */
1127 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1128 len = offset - start_offset;
1129 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1130 udvm_tvb, start_offset, len, value);
1132 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1133 len = offset - start_offset;
1134 if ( is_memory_address ){
1135 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1136 udvm_tvb, start_offset, len, value);
1138 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1139 udvm_tvb, start_offset, len, value);
1143 case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */
1145 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1146 len = offset - start_offset;
1147 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1148 udvm_tvb, start_offset, len, value);
1150 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1151 len = offset - start_offset;
1152 if ( is_memory_address ){
1153 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1154 udvm_tvb, start_offset, len, value);
1156 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1157 udvm_tvb, start_offset, len, value);
1161 case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */
1163 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1164 len = offset - start_offset;
1165 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1166 udvm_tvb, start_offset, len, value);
1168 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1169 len = offset - start_offset;
1170 if ( is_memory_address ){
1171 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1172 udvm_tvb, start_offset, len, value);
1174 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1175 udvm_tvb, start_offset, len, value);
1178 case SIGCOMP_INSTR_SORT_ASCENDING: /* 11 SORT-ASCENDING (%start, %n, %k) */
1179 /* while programming stop while loop */
1180 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1183 case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */
1184 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1186 case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */
1188 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1189 len = offset - start_offset;
1190 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1191 udvm_tvb, start_offset, len, value);
1194 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1195 len = offset - start_offset;
1196 if ( is_memory_address ){
1197 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1198 udvm_tvb, start_offset, len, value);
1200 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1201 udvm_tvb, start_offset, len, value);
1205 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1206 len = offset - start_offset;
1207 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1208 udvm_tvb, start_offset, len, value);
1211 case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */
1213 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
1214 len = offset - start_offset;
1215 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1216 udvm_tvb, start_offset, len, value);
1218 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1219 len = offset - start_offset;
1220 if ( is_memory_address ){
1221 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1222 udvm_tvb, start_offset, len, value);
1224 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1225 udvm_tvb, start_offset, len, value);
1229 case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
1231 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1232 len = offset - start_offset;
1233 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1234 udvm_tvb, start_offset, len, value);
1236 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1237 len = offset - start_offset;
1238 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1239 udvm_tvb, start_offset, len, value);
1244 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1245 len = offset - start_offset;
1246 if ( is_memory_address ){
1247 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1248 udvm_tvb, start_offset, len, value);
1250 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1251 udvm_tvb, start_offset, len, value);
1256 case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */
1258 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1259 len = offset - start_offset;
1260 if ( is_memory_address ){
1261 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1262 udvm_tvb, start_offset, len, value);
1264 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1265 udvm_tvb, start_offset, len, value);
1269 case SIGCOMP_INSTR_POP: /* 17 POP (%address) */
1271 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1273 len = offset - start_offset;
1274 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1275 udvm_tvb, start_offset, len, value);
1278 case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */
1280 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1281 len = offset - start_offset;
1282 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1283 udvm_tvb, start_offset, len, value);
1286 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1287 len = offset - start_offset;
1288 if ( is_memory_address ){
1289 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1290 udvm_tvb, start_offset, len, value);
1292 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1293 udvm_tvb, start_offset, len, value);
1297 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1298 len = offset - start_offset;
1299 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1300 udvm_tvb, start_offset, len, value);
1303 case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */
1305 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1306 len = offset - start_offset;
1307 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1308 udvm_tvb, start_offset, len, value);
1311 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1312 len = offset - start_offset;
1313 if ( is_memory_address ){
1314 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1315 udvm_tvb, start_offset, len, value);
1317 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1318 udvm_tvb, start_offset, len, value);
1322 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1323 len = offset - start_offset;
1324 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1325 udvm_tvb, start_offset, len, value);
1328 case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */
1330 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1331 len = offset - start_offset;
1332 if ( is_memory_address ){
1333 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_offset,
1334 udvm_tvb, start_offset, len, value);
1336 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
1337 udvm_tvb, start_offset, len, value);
1341 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1342 len = offset - start_offset;
1343 if ( is_memory_address ){
1344 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1345 udvm_tvb, start_offset, len, value);
1347 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1348 udvm_tvb, start_offset, len, value);
1352 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1353 len = offset - start_offset;
1354 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1355 udvm_tvb, start_offset, len, value);
1357 case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */
1360 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1361 len = offset - start_offset;
1362 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1363 udvm_tvb, start_offset, len, value);
1366 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE, &start_offset, &value, &is_memory_address);
1367 len = offset - start_offset;
1368 if ( is_memory_address ){
1369 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1370 udvm_tvb, start_offset, len, value);
1372 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1373 udvm_tvb, start_offset, len, value);
1377 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1378 len = offset - start_offset;
1379 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_start_value,
1380 udvm_tvb, start_offset, len, value);
1383 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1384 len = offset - start_offset;
1385 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
1386 udvm_tvb, start_offset, len, value);
1390 case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */
1392 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1393 len = offset - start_offset;
1394 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1395 value = ( value + UDVM_address ) & 0xffff;
1396 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1397 udvm_tvb, start_offset, len, value);
1400 case SIGCOMP_INSTR_COMPARE: /* 23 */
1401 /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
1404 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1405 len = offset - start_offset;
1406 if ( is_memory_address ){
1407 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1408 udvm_tvb, start_offset, len, value);
1410 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1411 udvm_tvb, start_offset, len, value);
1415 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1416 len = offset - start_offset;
1417 if ( is_memory_address ){
1418 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1419 udvm_tvb, start_offset, len, value);
1421 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1422 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 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1435 len = offset - start_offset;
1436 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1437 value = ( value + UDVM_address ) & 0xffff;
1438 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1439 udvm_tvb, start_offset, len, value);
1442 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1443 len = offset - start_offset;
1444 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1445 value = ( value + UDVM_address ) & 0xffff;
1446 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1447 udvm_tvb, start_offset, len, value);
1450 case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/
1452 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1453 len = offset - start_offset;
1454 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1455 value = ( value + UDVM_address ) & 0xffff;
1456 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1457 udvm_tvb, start_offset, len, value);
1459 case SIGCOMP_INSTR_RETURN: /* 25 POP and return */
1463 case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
1465 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1466 len = offset - start_offset;
1467 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1468 udvm_tvb, start_offset, len, value);
1470 /* Number of addresses in the instruction */
1473 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1474 len = offset - start_offset;
1475 if ( is_memory_address ){
1476 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_j,
1477 udvm_tvb, start_offset, len, value);
1479 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_j,
1480 udvm_tvb, start_offset, len, value);
1486 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
1487 len = offset - start_offset;
1488 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1489 value = ( value + UDVM_address ) & 0xffff;
1490 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1491 udvm_tvb, start_offset, len, value);
1494 case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */
1496 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1497 len = offset - start_offset;
1498 if ( is_memory_address ){
1499 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1500 udvm_tvb, start_offset, len, value);
1502 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1503 udvm_tvb, start_offset, len, value);
1507 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1508 len = offset - start_offset;
1509 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1510 udvm_tvb, start_offset, len, value);
1513 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1514 len = offset - start_offset;
1515 if ( is_memory_address ){
1516 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1517 udvm_tvb, start_offset, len, value);
1519 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1520 udvm_tvb, start_offset, len, value);
1524 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1525 len = offset - start_offset;
1526 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1527 value = ( value + UDVM_address ) & 0xffff;
1528 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1529 udvm_tvb, start_offset, len, value);
1533 case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */
1535 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1536 len = offset - start_offset;
1537 if ( is_memory_address ){
1538 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1539 udvm_tvb, start_offset, len, value);
1541 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1542 udvm_tvb, start_offset, len, value);
1546 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1547 len = offset - start_offset;
1548 if ( is_memory_address ){
1549 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
1550 udvm_tvb, start_offset, len, value);
1552 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1553 udvm_tvb, start_offset, len, value);
1557 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1558 len = offset - start_offset;
1559 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1560 value = ( value + UDVM_address ) & 0xffff;
1561 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1562 udvm_tvb, start_offset, len, value);
1564 case SIGCOMP_INSTR_INPUT_BITS:/* 29 INPUT-BITS (%length, %destination, @address) */
1566 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1567 len = offset - start_offset;
1568 if ( is_memory_address ){
1569 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1570 udvm_tvb, start_offset, len, value);
1572 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1573 udvm_tvb, start_offset, len, value);
1577 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1578 len = offset - start_offset;
1579 if ( is_memory_address ){
1580 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
1581 udvm_tvb, start_offset, len, value);
1583 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1584 udvm_tvb, start_offset, len, value);
1588 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1589 len = offset - start_offset;
1590 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1591 value = ( value + UDVM_address ) & 0xffff;
1592 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1593 udvm_tvb, start_offset, len, value);
1595 case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */
1597 * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1,
1598 * %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n,
1599 * %upper_bound_n, %uncompressed_n)
1602 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1603 len = offset - start_offset;
1604 if ( is_memory_address ){
1605 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
1606 udvm_tvb, start_offset, len, value);
1608 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1609 udvm_tvb, start_offset, len, value);
1612 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1613 len = offset - start_offset;
1614 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1615 value = ( value + UDVM_address ) & 0xffff;
1616 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1617 udvm_tvb, start_offset, len, value);
1619 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1620 len = offset - start_offset;
1621 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1622 udvm_tvb, start_offset, len, value);
1627 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1628 len = offset - start_offset;
1629 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_bits,
1630 udvm_tvb, start_offset, len, value);
1632 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1633 len = offset - start_offset;
1634 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_lower_bound,
1635 udvm_tvb, start_offset, len, value);
1636 /* %upper_bound_n */
1637 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1638 len = offset - start_offset;
1639 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_upper_bound,
1640 udvm_tvb, start_offset, len, value);
1641 /* %uncompressed_n */
1642 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1643 len = offset - start_offset;
1644 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_uncompressed,
1645 udvm_tvb, start_offset, len, value);
1649 case SIGCOMP_INSTR_STATE_ACCESS: /* 31 */
1650 /* STATE-ACCESS (%partial_identifier_start, %partial_identifier_length,
1651 * %state_begin, %state_length, %state_address, %state_instruction)
1655 * %partial_identifier_start
1657 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1658 len = offset - start_offset;
1659 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
1660 udvm_tvb, start_offset, len, value);
1663 * %partial_identifier_length
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_partial_identifier_length,
1668 udvm_tvb, start_offset, len, value);
1672 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1673 len = offset - start_offset;
1674 proto_tree_add_uint(sigcomp_udvm_tree, hf_state_begin,
1675 udvm_tvb, start_offset, len, value);
1680 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1681 len = offset - start_offset;
1682 if ( is_memory_address ) {
1683 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1684 udvm_tvb, start_offset, len, value);
1686 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1687 udvm_tvb, start_offset, len, value);
1692 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1693 len = offset - start_offset;
1694 if ( is_memory_address ) {
1695 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1696 udvm_tvb, start_offset, len, value);
1698 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1699 udvm_tvb, start_offset, len, value);
1702 * %state_instruction
1704 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1705 len = offset - start_offset;
1706 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1707 udvm_tvb, start_offset, len, value);
1709 case SIGCOMP_INSTR_STATE_CREATE: /* 32 */
1711 * STATE-CREATE (%state_length, %state_address, %state_instruction,
1712 * %minimum_access_length, %state_retention_priority)
1718 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1719 len = offset - start_offset;
1720 if ( is_memory_address ) {
1721 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1722 udvm_tvb, start_offset, len, value);
1724 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1725 udvm_tvb, start_offset, len, value);
1730 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1731 len = offset - start_offset;
1732 if ( is_memory_address ) {
1733 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1734 udvm_tvb, start_offset, len, value);
1736 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1737 udvm_tvb, start_offset, len, value);
1740 * %state_instruction
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_state_instr,
1745 udvm_tvb, start_offset, len, value);
1747 * %minimum_access_length
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_min_acc_len,
1752 udvm_tvb, start_offset, len, value);
1754 * %state_retention_priority
1756 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1757 len = offset - start_offset;
1758 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
1759 udvm_tvb, start_offset, len, value);
1762 case SIGCOMP_INSTR_STATE_FREE: /* 33 */
1764 * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
1767 * %partial_identifier_start
1769 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1770 len = offset - start_offset;
1771 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
1772 udvm_tvb, start_offset, len, value);
1775 * %partial_identifier_length
1777 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1778 len = offset - start_offset;
1779 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length,
1780 udvm_tvb, start_offset, len, value);
1782 case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */
1786 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1787 len = offset - start_offset;
1788 if ( is_memory_address ) {
1789 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_output_start,
1790 udvm_tvb, start_offset, len, value);
1792 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start,
1793 udvm_tvb, start_offset, len, value);
1798 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1799 len = offset - start_offset;
1800 if ( is_memory_address ) {
1801 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length_addr,
1802 udvm_tvb, start_offset, len, value);
1804 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length,
1805 udvm_tvb, start_offset, len, value);
1808 case SIGCOMP_INSTR_END_MESSAGE: /* 35 */
1810 * END-MESSAGE (%requested_feedback_location,
1811 * %returned_parameters_location, %state_length, %state_address,
1812 * %state_instruction, %minimum_access_length,
1813 * %state_retention_priority)
1815 /* %requested_feedback_location */
1816 if ((msg_length-1) < offset){
1817 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, 0, -1,
1818 "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1819 PROTO_ITEM_SET_GENERATED(item2);
1822 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1823 len = offset - start_offset;
1824 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_req_feedback_loc,
1825 udvm_tvb, start_offset, len, value);
1826 /* returned_parameters_location */
1827 if ((msg_length-1) < offset){
1828 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset-1, -1,
1829 "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1830 PROTO_ITEM_SET_GENERATED(item2);
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 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ret_param_loc,
1836 udvm_tvb, start_offset, len, value);
1840 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1841 len = offset - start_offset;
1842 if ( is_memory_address ) {
1843 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1844 udvm_tvb, start_offset, len, value);
1846 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1847 udvm_tvb, start_offset, len, value);
1852 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1853 len = offset - start_offset;
1854 if ( is_memory_address ) {
1855 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1856 udvm_tvb, start_offset, len, value);
1858 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1859 udvm_tvb, start_offset, len, value);
1862 * %state_instruction
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_state_instr,
1867 udvm_tvb, start_offset, len, value);
1869 * %minimum_access_length
1871 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1872 len = offset - start_offset;
1873 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len,
1874 udvm_tvb, start_offset, len, value);
1876 * %state_retention_priority
1878 if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1879 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1880 len = offset - start_offset;
1881 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
1882 udvm_tvb, start_offset, len, value);
1884 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
1885 "state_retention_priority = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1886 PROTO_ITEM_SET_GENERATED(item2);
1888 if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1889 len = tvb_reported_length_remaining(udvm_tvb, offset);
1890 UDVM_address = start_address + offset;
1891 proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, len,
1892 "Remaining %u bytes starting at UDVM addr %u (0x%x)- State information ?",len, UDVM_address, UDVM_address);
1894 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1898 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1906 /* The simplest operand type is the literal (#), which encodes a
1907 * constant integer from 0 to 65535 inclusive. A literal operand may
1908 * require between 1 and 3 bytes depending on its value.
1909 * Bytecode: Operand value: Range:
1910 * 0nnnnnnn N 0 - 127
1911 * 10nnnnnn nnnnnnnn N 0 - 16383
1912 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
1914 * Figure 8: Bytecode for a literal (#) operand
1918 dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1919 gint offset, gint *start_offset, guint16 *value)
1924 guint display_bytecode;
1926 bytecode = tvb_get_guint8(udvm_tvb, offset);
1927 test_bits = bytecode >> 7;
1928 if (test_bits == 1){
1929 test_bits = bytecode >> 6;
1930 if (test_bits == 2){
1932 * 10nnnnnn nnnnnnnn N 0 - 16383
1934 display_bytecode = bytecode & 0xc0;
1935 if ( display_udvm_bytecode )
1936 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1937 udvm_tvb, offset, 1, display_bytecode);
1938 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
1940 *start_offset = offset;
1941 offset = offset + 2;
1945 * 111000000 nnnnnnnn nnnnnnnn N 0 - 65535
1947 display_bytecode = bytecode & 0xc0;
1948 if ( display_udvm_bytecode )
1949 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1950 udvm_tvb, offset, 1, display_bytecode);
1952 operand = tvb_get_ntohs(udvm_tvb, offset);
1954 *start_offset = offset;
1955 offset = offset + 2;
1960 * 0nnnnnnn N 0 - 127
1962 display_bytecode = bytecode & 0xc0;
1963 if ( display_udvm_bytecode )
1964 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1965 udvm_tvb, offset, 1, display_bytecode);
1966 operand = ( bytecode & 0x7f);
1968 *start_offset = offset;
1976 * The second operand type is the reference ($), which is always used to
1977 * access a 2-byte value located elsewhere in the UDVM memory. The
1978 * bytecode for a reference operand is decoded to be a constant integer
1979 * from 0 to 65535 inclusive, which is interpreted as the memory address
1980 * containing the actual value of the operand.
1981 * Bytecode: Operand value: Range:
1983 * 0nnnnnnn memory[2 * N] 0 - 65535
1984 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
1985 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
1987 * Figure 9: Bytecode for a reference ($) operand
1990 dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1991 gint offset, gint *start_offset, guint16 *value)
1996 guint display_bytecode;
1998 bytecode = tvb_get_guint8(udvm_tvb, offset);
1999 test_bits = bytecode >> 7;
2000 if (test_bits == 1){
2001 test_bits = bytecode >> 6;
2002 if (test_bits == 2){
2004 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
2006 display_bytecode = bytecode & 0xc0;
2007 if ( display_udvm_bytecode )
2008 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
2009 udvm_tvb, offset, 1, display_bytecode);
2010 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
2011 *value = (operand * 2);
2012 *start_offset = offset;
2013 offset = offset + 2;
2017 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
2019 display_bytecode = bytecode & 0xc0;
2020 if ( display_udvm_bytecode )
2021 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
2022 udvm_tvb, offset, 1, display_bytecode);
2024 operand = tvb_get_ntohs(udvm_tvb, offset);
2026 *start_offset = offset;
2027 offset = offset + 2;
2032 * 0nnnnnnn memory[2 * N] 0 - 65535
2034 display_bytecode = bytecode & 0xc0;
2035 if ( display_udvm_bytecode )
2036 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
2037 udvm_tvb, offset, 1, display_bytecode);
2038 operand = ( bytecode & 0x7f);
2039 *value = (operand * 2);
2040 *start_offset = offset;
2048 *The fourth operand type is the address (@). This operand is decoded
2049 * as a multitype operand followed by a further step: the memory address
2050 * of the UDVM instruction containing the address operand is added to
2051 * obtain the correct operand value. So if the operand value from
2052 * Figure 10 is D then the actual operand value of an address is
2053 * calculated as follows:
2055 * operand_value = (is_memory_address_of_instruction + D) modulo 2^16
2056 * TODO calculate correct value for operand in case of ADDR
2059 dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
2060 gint offset, gboolean is_addr _U_, gint *start_offset, guint16 *value, gboolean *is_memory_address )
2063 guint display_bytecode;
2068 * Figure 10: Bytecode for a multitype (%) operand
2069 * Bytecode: Operand value: Range: HEX val
2070 * 00nnnnnn N 0 - 63 0x00
2071 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
2072 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
2073 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
2074 * 111nnnnn N + 65504 65504 - 65535 0xe0
2075 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
2076 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
2077 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
2078 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
2079 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
2081 *is_memory_address = FALSE;
2082 bytecode = tvb_get_guint8(udvm_tvb, offset);
2083 test_bits = ( bytecode & 0xc0 ) >> 6;
2084 switch (test_bits ){
2089 display_bytecode = bytecode & 0xc0;
2090 if ( display_udvm_bytecode )
2091 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2092 udvm_tvb, offset, 1, display_bytecode);
2093 operand = ( bytecode & 0x3f);
2095 *start_offset = offset;
2100 * 01nnnnnn memory[2 * N] 0 - 65535
2102 display_bytecode = bytecode & 0xc0;
2103 if ( display_udvm_bytecode )
2104 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2105 udvm_tvb, offset, 1, display_bytecode);
2106 operand = ( bytecode & 0x3f) * 2;
2107 *is_memory_address = TRUE;
2109 *start_offset = offset;
2113 /* Check tree most significant bits */
2114 test_bits = ( bytecode & 0xe0 ) >> 5;
2115 if ( test_bits == 5 ){
2117 * 101nnnnn nnnnnnnn N 0 - 8191
2119 display_bytecode = bytecode & 0xe0;
2120 if ( display_udvm_bytecode )
2121 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2122 udvm_tvb, offset, 1, display_bytecode);
2123 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x1fff;
2125 *start_offset = offset;
2126 offset = offset + 2;
2128 test_bits = ( bytecode & 0xf0 ) >> 4;
2129 if ( test_bits == 9 ){
2131 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535
2133 display_bytecode = bytecode & 0xf0;
2134 if ( display_udvm_bytecode )
2135 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2136 udvm_tvb, offset, 1, display_bytecode);
2137 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x0fff) + 61440;
2138 *start_offset = offset;
2140 offset = offset + 2;
2142 test_bits = ( bytecode & 0x08 ) >> 3;
2143 if ( test_bits == 1){
2145 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768
2147 display_bytecode = bytecode & 0xf8;
2148 if ( display_udvm_bytecode )
2149 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2150 udvm_tvb, offset, 1, display_bytecode);
2151 result = (guint32)pow(2,( bytecode & 0x07) + 8);
2152 operand = result & 0xffff;
2153 *start_offset = offset;
2157 test_bits = ( bytecode & 0x0e ) >> 1;
2158 if ( test_bits == 3 ){
2160 * 1000 011n 2 ^ (N + 6) 64 , 128
2162 display_bytecode = bytecode & 0xfe;
2163 if ( display_udvm_bytecode )
2164 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2165 udvm_tvb, offset, 1, display_bytecode);
2166 result = (guint32)pow(2,( bytecode & 0x01) + 6);
2167 operand = result & 0xffff;
2168 *start_offset = offset;
2173 * 1000 0000 nnnnnnnn nnnnnnnn N 0 - 65535
2174 * 1000 0001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
2176 display_bytecode = bytecode;
2177 if ( display_udvm_bytecode )
2178 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2179 udvm_tvb, offset, 1, display_bytecode);
2180 if ( (bytecode & 0x01) == 1 )
2181 *is_memory_address = TRUE;
2183 operand = tvb_get_ntohs(udvm_tvb, offset);
2185 *start_offset = offset;
2196 test_bits = ( bytecode & 0x20 ) >> 5;
2197 if ( test_bits == 1 ){
2199 * 111nnnnn N + 65504 65504 - 65535
2201 display_bytecode = bytecode & 0xe0;
2202 if ( display_udvm_bytecode )
2203 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2204 udvm_tvb, offset, 1, display_bytecode);
2205 operand = ( bytecode & 0x1f) + 65504;
2206 *start_offset = offset;
2211 * 110nnnnn nnnnnnnn memory[N] 0 - 65535
2213 display_bytecode = bytecode & 0xe0;
2214 if ( display_udvm_bytecode )
2215 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2216 udvm_tvb, offset, 1, display_bytecode);
2217 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x1fff);
2218 *is_memory_address = TRUE;
2219 *start_offset = offset;
2231 tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree)
2233 proto_tree *raw_tree = NULL;
2234 proto_item *ti = NULL;
2235 int offset, next_offset, linelen;
2238 ti = proto_tree_add_item(tree, proto_raw_sigcomp, tvb, 0, -1, FALSE);
2239 raw_tree = proto_item_add_subtree(ti, ett_raw_text);
2244 while (tvb_offset_exists(tvb, offset)) {
2245 tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
2246 linelen = next_offset - offset;
2248 proto_tree_add_text(raw_tree, tvb, offset, linelen,
2249 "%s", tvb_format_text(tvb, offset, linelen));
2251 offset = next_offset;
2255 /* Register the protocol with Wireshark */
2258 /* If this dissector uses sub-dissector registration add a registration routine.
2259 This format is required because a script is used to find these routines and
2260 create the code that calls these routines.
2263 proto_reg_handoff_sigcomp(void)
2265 static dissector_handle_t sigcomp_handle;
2266 static dissector_handle_t sigcomp_tcp_handle;
2267 static gboolean Initialized=FALSE;
2268 static guint udp_port1;
2269 static guint udp_port2;
2270 static guint tcp_port1;
2271 static guint tcp_port2;
2274 sigcomp_handle = find_dissector("sigcomp");
2275 sigcomp_tcp_handle = new_create_dissector_handle(dissect_sigcomp_tcp,proto_sigcomp);
2276 sip_handle = find_dissector("sip");
2279 dissector_delete("udp.port", udp_port1, sigcomp_handle);
2280 dissector_delete("udp.port", udp_port2, sigcomp_handle);
2281 dissector_delete("tcp.port", tcp_port1, sigcomp_tcp_handle);
2282 dissector_delete("tcp.port", tcp_port2, sigcomp_tcp_handle);
2285 udp_port1 = SigCompUDPPort1;
2286 udp_port2 = SigCompUDPPort2;
2287 tcp_port1 = SigCompTCPPort1;
2288 tcp_port2 = SigCompTCPPort2;
2291 dissector_add("udp.port", SigCompUDPPort1, sigcomp_handle);
2292 dissector_add("udp.port", SigCompUDPPort2, sigcomp_handle);
2293 dissector_add("tcp.port", SigCompTCPPort1, sigcomp_tcp_handle);
2294 dissector_add("tcp.port", SigCompTCPPort2, sigcomp_tcp_handle);
2298 /* this format is require because a script is used to build the C function
2299 that calls all the protocol registration.
2303 proto_register_sigcomp(void)
2306 /* Setup list of header fields See Section 1.6.1 for details*/
2307 static hf_register_info hf[] = {
2308 { &hf_sigcomp_t_bit,
2309 { "T bit", "sigcomp.t.bit",
2310 FT_UINT8, BASE_DEC, NULL, 0x04,
2311 "Sigcomp T bit", HFILL }
2314 { "Partial state id length","sigcomp.length",
2315 FT_UINT8, BASE_HEX, VALS(&length_encoding_vals), 0x03,
2316 "Sigcomp length", HFILL }
2318 { &hf_sigcomp_returned_feedback_item,
2319 { "Returned_feedback item", "sigcomp.returned.feedback.item",
2320 FT_BYTES, BASE_NONE, NULL, 0x0,
2321 "Returned feedback item", HFILL }
2323 { &hf_sigcomp_partial_state,
2324 { "Partial state identifier", "sigcomp.partial.state.identifier",
2325 FT_STRING, BASE_NONE, NULL, 0x0,
2328 { &hf_sigcomp_remaining_message_bytes,
2329 { "Remaining SigComp message bytes", "sigcomp.remaining-bytes",
2330 FT_UINT32, BASE_DEC, NULL, 0x0,
2331 "Number of bytes remaining in message", HFILL }
2333 { &hf_sigcomp_compression_ratio,
2334 { "Compression ratio (%)", "sigcomp.compression-ratio",
2335 FT_UINT32, BASE_DEC, NULL, 0x0,
2336 "Compression ratio (decompressed / compressed) %", HFILL }
2338 { &hf_sigcomp_returned_feedback_item_len,
2339 { "Returned feedback item length", "sigcomp.returned.feedback.item.len",
2340 FT_UINT8, BASE_DEC, NULL, 0x7f,
2343 { &hf_sigcomp_code_len,
2344 { "Code length","sigcomp.code.len",
2345 FT_UINT16, BASE_HEX, NULL, 0xfff0,
2348 { &hf_sigcomp_destination,
2349 { "Destination","sigcomp.destination",
2350 FT_UINT8, BASE_HEX, VALS(&destination_address_encoding_vals), 0xf,
2353 { &hf_sigcomp_udvm_bytecode,
2354 { "Uploaded UDVM bytecode","sigcomp.udvm.byte-code",
2355 FT_NONE, BASE_NONE, NULL, 0x0,
2358 { &hf_sigcomp_udvm_instr,
2359 { "UDVM instruction code","sigcomp.udvm.instr",
2360 FT_UINT8, BASE_DEC, VALS(&udvm_instruction_code_vals), 0x0,
2363 { &hf_udvm_execution_trace,
2364 { "UDVM execution trace","sigcomp.udvm.execution-trace",
2365 FT_NONE, BASE_NONE, NULL, 0x0,
2368 { &hf_udvm_multitype_bytecode,
2369 { "UDVM bytecode", "sigcomp.udvm.multyt.bytecode",
2370 FT_UINT8, BASE_HEX, VALS(&display_bytecode_vals), 0x0,
2373 { &hf_udvm_reference_bytecode,
2374 { "UDVM bytecode", "sigcomp.udvm.ref.bytecode",
2375 FT_UINT8, BASE_HEX, VALS(&display_ref_bytecode_vals), 0x0,
2378 { &hf_udvm_literal_bytecode,
2379 { "UDVM bytecode", "sigcomp.udvm.lit.bytecode",
2380 FT_UINT8, BASE_HEX, VALS(&display_lit_bytecode_vals), 0x0,
2384 { "UDVM operand", "sigcomp.udvm.operand",
2385 FT_UINT16, BASE_DEC, NULL, 0x0,
2389 { "%Length", "sigcomp.udvm.length",
2390 FT_UINT16, BASE_DEC, NULL, 0x0,
2393 { &hf_udvm_addr_length,
2394 { "%Length[memory address]", "sigcomp.udvm.addr.length",
2395 FT_UINT16, BASE_DEC, NULL, 0x0,
2398 { &hf_udvm_destination,
2399 { "%Destination", "sigcomp.udvm.destination",
2400 FT_UINT16, BASE_DEC, NULL, 0x0,
2401 "Destination", HFILL }
2403 { &hf_udvm_addr_destination,
2404 { "%Destination[memory address]", "sigcomp.udvm.addr.destination",
2405 FT_UINT16, BASE_DEC, NULL, 0x0,
2406 "Destination", HFILL }
2408 { &hf_udvm_at_address,
2409 { "@Address(mem_add_of_inst + D) mod 2^16)", "sigcomp.udvm.at.address",
2410 FT_UINT16, BASE_DEC, NULL, 0x0,
2414 { "%Address", "sigcomp.udvm.length",
2415 FT_UINT16, BASE_DEC, NULL, 0x0,
2418 { &hf_udvm_literal_num,
2419 { "#n", "sigcomp.udvm.literal-num",
2420 FT_UINT16, BASE_DEC, NULL, 0x0,
2421 "Literal number", HFILL }
2424 { "%Value", "sigcomp.udvm.value",
2425 FT_UINT16, BASE_DEC, NULL, 0x0,
2428 { &hf_udvm_addr_value,
2429 { "%Value[memory address]", "sigcomp.udvm.value",
2430 FT_UINT16, BASE_DEC, NULL, 0x0,
2433 { &hf_partial_identifier_start,
2434 { "%Partial identifier start", "sigcomp.udvm.partial.identifier.start",
2435 FT_UINT16, BASE_DEC, NULL, 0x0,
2436 "Partial identifier start", HFILL }
2438 { &hf_partial_identifier_length,
2439 { "%Partial identifier length", "sigcomp.udvm.partial.identifier.length",
2440 FT_UINT16, BASE_DEC, NULL, 0x0,
2441 "Partial identifier length", HFILL }
2444 { "%State begin", "sigcomp.udvm.state.begin",
2445 FT_UINT16, BASE_DEC, NULL, 0x0,
2446 "State begin", HFILL }
2448 { &hf_udvm_state_length,
2449 { "%State length", "sigcomp.udvm.state.length",
2450 FT_UINT16, BASE_DEC, NULL, 0x0,
2451 "State length", HFILL }
2454 { &hf_udvm_state_length_addr,
2455 { "%State length[memory address]", "sigcomp.udvm.state.length.addr",
2456 FT_UINT16, BASE_DEC, NULL, 0x0,
2457 "State length", HFILL }
2459 { &hf_udvm_state_address,
2460 { "%State address", "sigcomp.udvm.start.address",
2461 FT_UINT16, BASE_DEC, NULL, 0x0,
2462 "State address", HFILL }
2464 { &hf_udvm_state_address_addr,
2465 { "%State address[memory address]", "sigcomp.udvm.start.address.addr",
2466 FT_UINT16, BASE_DEC, NULL, 0x0,
2467 "State address", HFILL }
2469 { &hf_udvm_state_instr,
2470 { "%State instruction", "sigcomp.udvm.start.instr",
2471 FT_UINT16, BASE_DEC, NULL, 0x0,
2472 "State instruction", HFILL }
2474 { &hf_udvm_operand_1,
2475 { "$Operand 1[memory address]", "sigcomp.udvm.operand.1",
2476 FT_UINT16, BASE_DEC, NULL, 0x0,
2477 "Reference $ Operand 1", HFILL }
2479 { &hf_udvm_operand_2,
2480 { "%Operand 2", "sigcomp.udvm.operand.2",
2481 FT_UINT16, BASE_DEC, NULL, 0x0,
2482 "Operand 2", HFILL }
2484 { &hf_udvm_operand_2_addr,
2485 { "%Operand 2[memory address]", "sigcomp.udvm.operand.2.addr",
2486 FT_UINT16, BASE_DEC, NULL, 0x0,
2487 "Operand 2", HFILL }
2490 { "%j", "sigcomp.udvm.j",
2491 FT_UINT16, BASE_DEC, NULL, 0x0,
2495 { "%j[memory address]", "sigcomp.udvm.addr.j",
2496 FT_UINT16, BASE_DEC, NULL, 0x0,
2499 { &hf_udvm_output_start,
2500 { "%Output_start", "sigcomp.output.start",
2501 FT_UINT16, BASE_DEC, NULL, 0x0,
2502 "Output start", HFILL }
2504 { &hf_udvm_addr_output_start,
2505 { "%Output_start[memory address]", "sigcomp.addr.output.start",
2506 FT_UINT16, BASE_DEC, NULL, 0x0,
2507 "Output start", HFILL }
2509 { &hf_udvm_output_length,
2510 { "%Output_length", "sigcomp.output.length",
2511 FT_UINT16, BASE_DEC, NULL, 0x0,
2512 "Output length", HFILL }
2514 { &hf_udvm_output_length_addr,
2515 { "%Output_length[memory address]", "sigcomp.output.length.addr",
2516 FT_UINT16, BASE_DEC, NULL, 0x0,
2517 "Output length", HFILL }
2519 { &hf_udvm_req_feedback_loc,
2520 { "%Requested feedback location", "sigcomp.req.feedback.loc",
2521 FT_UINT16, BASE_DEC, NULL, 0x0,
2522 "Requested feedback location", HFILL }
2524 { &hf_udvm_min_acc_len,
2525 { "%Minimum access length", "sigcomp.min.acc.len",
2526 FT_UINT16, BASE_DEC, NULL, 0x0,
2527 "Minimum access length", HFILL }
2529 { &hf_udvm_state_ret_pri,
2530 { "%State retention priority", "sigcomp.udvm.state.ret.pri",
2531 FT_UINT16, BASE_DEC, NULL, 0x0,
2532 "State retention priority", HFILL }
2534 { &hf_udvm_ret_param_loc,
2535 { "%Returned parameters location", "sigcomp.ret.param.loc",
2536 FT_UINT16, BASE_DEC, NULL, 0x0,
2537 "Returned parameters location", HFILL }
2539 { &hf_udvm_position,
2540 { "%Position", "sigcomp.udvm.position",
2541 FT_UINT16, BASE_DEC, NULL, 0x0,
2544 { &hf_udvm_ref_dest,
2545 { "$Destination[memory address]", "sigcomp.udvm.ref.destination",
2546 FT_UINT16, BASE_DEC, NULL, 0x0,
2547 "(reference)Destination", HFILL }
2550 { "%Bits", "sigcomp.udvm.bits",
2551 FT_UINT16, BASE_DEC, NULL, 0x0,
2554 { &hf_udvm_lower_bound,
2555 { "%Lower bound", "sigcomp.udvm.lower.bound",
2556 FT_UINT16, BASE_DEC, NULL, 0x0,
2557 "Lower_bound", HFILL }
2559 { &hf_udvm_upper_bound,
2560 { "%Upper bound", "sigcomp.udvm.upper.bound",
2561 FT_UINT16, BASE_DEC, NULL, 0x0,
2562 "Upper bound", HFILL }
2564 { &hf_udvm_uncompressed,
2565 { "%Uncompressed", "sigcomp.udvm.uncompressed",
2566 FT_UINT16, BASE_DEC, NULL, 0x0,
2567 "Uncompressed", HFILL }
2569 { &hf_udvm_start_value,
2570 { "%Start value", "sigcomp.udvm.start.value",
2571 FT_UINT16, BASE_DEC, NULL, 0x0,
2572 "Start value", HFILL }
2575 { "%Offset", "sigcomp.udvm.offset",
2576 FT_UINT16, BASE_DEC, NULL, 0x0,
2579 { &hf_udvm_addr_offset,
2580 { "%Offset[memory address]", "sigcomp.udvm.addr.offset",
2581 FT_UINT16, BASE_DEC, NULL, 0x0,
2584 { &hf_sigcomp_nack_ver,
2585 { "NACK Version", "sigcomp.nack.ver",
2586 FT_UINT8, BASE_DEC, NULL, 0x0f,
2589 { &hf_sigcomp_nack_reason_code,
2590 { "Reason Code", "sigcomp.nack.reason",
2591 FT_UINT8, BASE_DEC, VALS(sigcomp_nack_reason_code_vals), 0x0,
2592 "NACK Reason Code", HFILL }
2594 { &hf_sigcomp_nack_failed_op_code,
2595 { "OPCODE of failed instruction", "sigcomp.nack.failed_op_code",
2596 FT_UINT8, BASE_DEC, VALS(udvm_instruction_code_vals), 0x0,
2597 "NACK OPCODE of failed instruction", HFILL }
2599 { &hf_sigcomp_nack_pc,
2600 { "PC of failed instruction", "sigcomp.nack.pc",
2601 FT_UINT16, BASE_DEC, NULL, 0x0,
2602 "NACK PC of failed instruction", HFILL }
2604 { &hf_sigcomp_nack_sha1,
2605 { "SHA-1 Hash of failed message", "sigcomp.nack.sha1",
2606 FT_BYTES, BASE_NONE, NULL, 0x0,
2607 "NACK SHA-1 Hash of failed message", HFILL }
2609 { &hf_sigcomp_nack_state_id,
2610 { "State ID (6 - 20 bytes)", "sigcomp.nack.state_id",
2611 FT_BYTES, BASE_NONE, NULL, 0x0,
2612 "NACK State ID (6 - 20 bytes)", HFILL }
2614 { &hf_sigcomp_nack_cycles_per_bit,
2615 { "Cycles Per Bit", "sigcomp.nack.cycles_per_bit",
2616 FT_UINT8, BASE_DEC, NULL, 0x0,
2617 "NACK Cycles Per Bit", HFILL }
2619 { &hf_sigcomp_nack_memory_size,
2620 { "Memory size", "sigcomp.memory_size",
2621 FT_UINT16, BASE_DEC, NULL, 0x0,
2626 /* Setup protocol subtree array */
2627 static gint *ett[] = {
2630 &ett_sigcomp_udvm_exe,
2632 static gint *ett_raw[] = {
2636 module_t *sigcomp_module;
2637 static enum_val_t udvm_detail_vals[] = {
2638 {"no-printout", "No-Printout", 0},
2639 {"low-detail", "Low-detail", 1},
2640 {"medium-detail", "Medium-detail", 2},
2641 {"high-detail", "High-detail", 3},
2646 /* Register the protocol name and description */
2647 proto_sigcomp = proto_register_protocol("Signaling Compression",
2648 "SIGCOMP", "sigcomp");
2649 proto_raw_sigcomp = proto_register_protocol("Decompressed SigComp message as raw text",
2650 "Raw_SigComp", "raw_sigcomp");
2652 new_register_dissector("sigcomp", dissect_sigcomp, proto_sigcomp);
2654 /* Required function calls to register the header fields and subtrees used */
2655 proto_register_field_array(proto_sigcomp, hf, array_length(hf));
2656 proto_register_subtree_array(ett, array_length(ett));
2657 proto_register_subtree_array(ett_raw, array_length(ett_raw));
2659 /* Register a configuration option for port */
2660 sigcomp_module = prefs_register_protocol(proto_sigcomp,
2661 proto_reg_handoff_sigcomp);
2663 prefs_register_uint_preference(sigcomp_module, "udp.port",
2664 "Sigcomp UDP Port 1",
2665 "Set UDP port 1 for SigComp messages",
2669 prefs_register_uint_preference(sigcomp_module, "udp.port2",
2670 "Sigcomp UDP Port 2",
2671 "Set UDP port 2 for SigComp messages",
2674 prefs_register_uint_preference(sigcomp_module, "tcp.port",
2675 "Sigcomp TCP Port 1",
2676 "Set TCP port 1 for SigComp messages",
2680 prefs_register_uint_preference(sigcomp_module, "tcp.port2",
2681 "Sigcomp TCP Port 2",
2682 "Set TCP port 2 for SigComp messages",
2685 prefs_register_bool_preference(sigcomp_module, "display.udvm.code",
2686 "Dissect the UDVM code",
2687 "Preference whether to Dissect the UDVM code or not",
2688 &dissect_udvm_code);
2690 prefs_register_bool_preference(sigcomp_module, "display.bytecode",
2691 "Display the bytecode of operands",
2692 "preference whether to display the bytecode in "
2693 "UDVM operands or not",
2694 &display_udvm_bytecode);
2695 prefs_register_bool_preference(sigcomp_module, "decomp.msg",
2696 "Decompress message",
2697 "preference whether to decompress message or not",
2699 prefs_register_bool_preference(sigcomp_module, "display.decomp.msg.as.txt",
2700 "Displays the decompressed message as text",
2701 "preference whether to display the decompressed message "
2702 "as raw text or not",
2704 prefs_register_enum_preference(sigcomp_module, "show.udvm.execution",
2705 "Level of detail of UDVM execution:",
2706 "'No-Printout' = UDVM executes silently, then increasing detail "
2707 "about execution of UDVM instructions; "
2708 "Warning! CPU intense at high detail",
2709 &udvm_print_detail_level, udvm_detail_vals, FALSE);
2711 register_init_routine(&sigcomp_init_protocol);