2 * Routines for Signaling Compression (SigComp) dissection.
3 * Copyright 2004-2005, Anders Broman <anders.broman@ericsson.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 * http://www.ietf.org/rfc/rfc3320.txt?number=3320
24 * http://www.ietf.org/rfc/rfc3321.txt?number=3321
25 * http://www.ietf.org/rfc/rfc4077.txt?number=4077
27 * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-impl-guide-03.txt
28 * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-sip-01.txt
34 #include <epan/packet.h>
35 #include <epan/prefs.h>
36 #include <epan/expert.h>
37 #include <epan/to_str.h>
38 #include <epan/sigcomp-udvm.h>
39 #include <epan/sigcomp_state_hdlr.h>
41 void proto_register_sigcomp(void);
42 void proto_reg_handoff_sigcomp(void);
44 /* Initialize the protocol and registered fields */
45 static int proto_sigcomp = -1;
46 static int proto_raw_sigcomp = -1;
47 static int hf_sigcomp_t_bit = -1;
48 static int hf_sigcomp_len = -1;
49 static int hf_sigcomp_returned_feedback_item = -1;
50 static int hf_sigcomp_returned_feedback_item_len = -1;
51 static int hf_sigcomp_code_len = -1;
52 static int hf_sigcomp_destination = -1;
53 static int hf_sigcomp_partial_state = -1;
54 static int hf_sigcomp_remaining_message_bytes = -1;
55 static int hf_sigcomp_compression_ratio = -1;
56 static int hf_sigcomp_udvm_bytecode = -1;
57 static int hf_sigcomp_udvm_instr = -1;
58 static int hf_udvm_multitype_bytecode = -1;
59 static int hf_udvm_reference_bytecode = -1;
60 static int hf_udvm_literal_bytecode = -1;
61 /* static int hf_udvm_operand = -1; */
62 static int hf_udvm_length = -1;
63 static int hf_udvm_addr_length = -1;
64 static int hf_udvm_destination = -1;
65 static int hf_udvm_addr_destination = -1;
66 static int hf_udvm_at_address = -1;
67 static int hf_udvm_address = -1;
68 static int hf_udvm_literal_num = -1;
69 static int hf_udvm_value = -1;
70 static int hf_udvm_addr_value = -1;
71 static int hf_partial_identifier_start = -1;
72 static int hf_partial_identifier_length = -1;
73 static int hf_state_begin = -1;
74 static int hf_udvm_state_length = -1;
75 static int hf_udvm_state_length_addr = -1;
76 static int hf_udvm_state_address = -1;
77 static int hf_udvm_state_address_addr = -1;
78 static int hf_udvm_state_instr = -1;
79 static int hf_udvm_operand_1 = -1;
80 static int hf_udvm_operand_2 = -1;
81 static int hf_udvm_operand_2_addr = -1;
82 static int hf_udvm_j = -1;
83 static int hf_udvm_addr_j = -1;
84 static int hf_udvm_output_start = -1;
85 static int hf_udvm_addr_output_start = -1;
86 static int hf_udvm_output_length = -1;
87 static int hf_udvm_output_length_addr = -1;
88 static int hf_udvm_req_feedback_loc = -1;
89 static int hf_udvm_min_acc_len = -1;
90 static int hf_udvm_state_ret_pri = -1;
91 static int hf_udvm_ret_param_loc = -1;
92 static int hf_udvm_position = -1;
93 static int hf_udvm_ref_dest = -1;
94 static int hf_udvm_bits = -1;
95 static int hf_udvm_lower_bound = -1;
96 static int hf_udvm_upper_bound = -1;
97 static int hf_udvm_uncompressed = -1;
98 static int hf_udvm_offset = -1;
99 static int hf_udvm_addr_offset = -1;
100 static int hf_udvm_start_value = -1;
101 static int hf_udvm_execution_trace = -1;
102 static int hf_sigcomp_nack_ver = -1;
103 static int hf_sigcomp_nack_reason_code = -1;
104 static int hf_sigcomp_nack_failed_op_code = -1;
105 static int hf_sigcomp_nack_pc = -1;
106 static int hf_sigcomp_nack_sha1 = -1;
107 static int hf_sigcomp_nack_state_id = -1;
108 static int hf_sigcomp_nack_memory_size = -1;
109 static int hf_sigcomp_nack_cycles_per_bit = -1;
111 /* Initialize the subtree pointers */
112 static gint ett_sigcomp = -1;
113 static gint ett_sigcomp_udvm = -1;
114 static gint ett_sigcomp_udvm_exe = -1;
115 static gint ett_raw_text = -1;
117 static expert_field ei_sigcomp_nack_failed_op_code = EI_INIT;
119 static dissector_handle_t sip_handle;
120 /* set the udp ports */
121 static guint SigCompUDPPort1 = 5555;
122 static guint SigCompUDPPort2 = 6666;
124 /* set the tcp ports */
125 static guint SigCompTCPPort1 = 5555;
126 static guint SigCompTCPPort2 = 6666;
128 /* Default preference whether to display the bytecode in UDVM operands or not */
129 static gboolean display_udvm_bytecode = FALSE;
130 /* Default preference whether to dissect the UDVM code or not */
131 static gboolean dissect_udvm_code = TRUE;
132 static gboolean display_raw_txt = FALSE;
133 /* Default preference whether to decompress the message or not */
134 static gboolean decompress = TRUE;
135 /* Default preference whether to print debug info at execution of UDVM
137 * 1 = details level 1
138 * 2 = details level 2
139 * 3 = details level 3
140 * 4 = details level 4
142 static gint udvm_print_detail_level = 0;
145 static const value_string length_encoding_vals[] = {
146 { 0x00, "No partial state (Message type 2)" },
147 { 0x01, "(6 bytes)" },
148 { 0x02, "(9 bytes)" },
149 { 0x03, "(12 bytes)" },
154 static const value_string destination_address_encoding_vals[] = {
155 { 0x00, "Reserved" },
173 static value_string_ext destination_address_encoding_vals_ext =
174 VALUE_STRING_EXT_INIT(destination_address_encoding_vals);
176 static const value_string udvm_instruction_code_vals[] = {
177 { 0, "DECOMPRESSION-FAILURE" },
188 { 11, "SORT-ASCENDING" },
189 { 12, "SORT-DESCENDING" },
196 { 19, "COPY-LITERAL" },
197 { 20, "COPY-OFFSET" },
205 { 28, "INPUT-BYTES" },
206 { 29, "INPUT-BITS" },
207 { 30, "INPUT-HUFFMAN" },
208 { 31, "STATE-ACCESS" },
209 { 32, "STATE-CREATE" },
210 { 33, "STATE-FREE" },
212 { 35, "END-MESSAGE" },
215 static value_string_ext udvm_instruction_code_vals_ext =
216 VALUE_STRING_EXT_INIT(udvm_instruction_code_vals);
219 * Figure 10: Bytecode for a multitype (%) operand
220 * Bytecode: Operand value: Range: HEX val
221 * 00nnnnnn N 0 - 63 0x00
222 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
223 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
224 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
225 * 111nnnnn N + 65504 65504 - 65535 0xe0
226 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
227 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
228 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
229 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
230 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
233 static const value_string display_bytecode_vals[] = {
234 { 0x00, "00nnnnnn, N, 0 - 63" },
235 { 0x40, "01nnnnnn, memory[2 * N],0 - 65535" },
236 { 0x86, "1000011n, 2 ^ (N + 6), 64 , 128" },
237 { 0x88, "10001nnn, 2 ^ (N + 8), 256,..., 32768" },
238 { 0xe0, "111nnnnn N + 65504, 65504 - 65535" },
239 { 0x90, "1001nnnn nnnnnnnn, N + 61440, 61440 - 65535" },
240 { 0xa0, "101nnnnn nnnnnnnn, N, 0 - 8191" },
241 { 0xc0, "110nnnnn nnnnnnnn, memory[N], 0 - 65535" },
242 { 0x80, "10000000 nnnnnnnn nnnnnnnn, N, 0 - 65535" },
243 { 0x81, "10000001 nnnnnnnn nnnnnnnn, memory[N], 0 - 65535" },
247 * 0nnnnnnn memory[2 * N] 0 - 65535
248 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
249 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
251 static const value_string display_ref_bytecode_vals[] = {
252 { 0x00, "0nnnnnnn memory[2 * N] 0 - 65535" },
253 { 0x80, "10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535" },
254 { 0xc0, "11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535" },
257 /* The simplest operand type is the literal (#), which encodes a
258 * constant integer from 0 to 65535 inclusive. A literal operand may
259 * require between 1 and 3 bytes depending on its value.
260 * Bytecode: Operand value: Range:
262 * 10nnnnnn nnnnnnnn N 0 - 16383
263 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
265 * Figure 8: Bytecode for a literal (#) operand
269 static const value_string display_lit_bytecode_vals[] = {
270 { 0x00, "0nnnnnnn N 0 - 127" },
271 { 0x80, "10nnnnnn nnnnnnnn N 0 - 16383" },
272 { 0xc0, "11000000 nnnnnnnn nnnnnnnn N 0 - 65535" },
276 #define SIGCOMP_NACK_STATE_NOT_FOUND 1
277 #define SIGCOMP_NACK_CYCLES_EXHAUSTED 2
278 #define SIGCOMP_NACK_BYTECODES_TOO_LARGE 18
279 #define SIGCOMP_NACK_ID_NOT_UNIQUE 21
280 #define SIGCOMP_NACK_STATE_TOO_SHORT 23
282 static const value_string sigcomp_nack_reason_code_vals[] = {
283 { 1, "STATE_NOT_FOUND" }, /*1 State ID (6 - 20 bytes) */
284 { 2, "CYCLES_EXHAUSTED" }, /*2 Cycles Per Bit (1 byte) */
285 { 3, "USER_REQUESTED" },
287 { 5, "TOO_MANY_STATE_REQUESTS" },
288 { 6, "INVALID_STATE_ID_LENGTH" },
289 { 7, "INVALID_STATE_PRIORITY" },
290 { 8, "OUTPUT_OVERFLOW" },
291 { 9, "STACK_UNDERFLOW" },
292 { 10, "BAD_INPUT_BITORDER" },
293 { 11, "DIV_BY_ZERO" },
294 { 12, "SWITCH_VALUE_TOO_HIGH" },
295 { 13, "TOO_MANY_BITS_REQUESTED" },
296 { 14, "INVALID_OPERAND" },
297 { 15, "HUFFMAN_NO_MATCH" },
298 { 16, "MESSAGE_TOO_SHORT" },
299 { 17, "INVALID_CODE_LOCATION" },
300 { 18, "BYTECODES_TOO_LARGE" }, /*18 Memory size (2 bytes) */
301 { 19, "INVALID_OPCODE" },
302 { 20, "INVALID_STATE_PROBE" },
303 { 21, "ID_NOT_UNIQUE" }, /*21 State ID (6 - 20 bytes) */
304 { 22, "MULTILOAD_OVERWRITTEN" },
305 { 23, "STATE_TOO_SHORT" }, /*23 State ID (6 - 20 bytes) */
306 { 24, "INTERNAL_ERROR" },
307 { 25, "FRAMING_ERROR" },
310 static value_string_ext sigcomp_nack_reason_code_vals_ext =
311 VALUE_STRING_EXT_INIT(sigcomp_nack_reason_code_vals);
314 static void dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, guint destination);
316 static int dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
317 gint offset,gboolean is_addr,gint *start_offset,
318 guint16 *value, gboolean *is_memory_address );
320 static int dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
321 gint offset, gint *start_offset, guint16 *value);
323 static int dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
324 gint offset, gint *start_offset, guint16 *value);
325 static void tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree);
327 static int dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
329 static proto_tree *top_tree;
331 /* Initialize the state handler
335 sigcomp_init_protocol(void)
339 /* Sigcomp over TCP record marking used
341 * 4.2.2. Record Marking
343 * For a stream-based transport, the dispatcher delimits messages by
344 * parsing the compressed data stream for instances of 0xFF and taking
345 * the following actions:
346 * Occurs in data stream: Action:
348 * 0xFF 00 one 0xFF byte in the data stream
349 * 0xFF 01 same, but the next byte is quoted (could
352 * 0xFF 7F same, but the next 127 bytes are quoted
353 * 0xFF 80 to 0xFF FE (reserved for future standardization)
354 * 0xFF FF end of SigComp message
356 * In UDVM version 0x01, any occurrence of the combinations 0xFF80 to
357 * 0xFFFE that are not protected by quoting causes decompression
358 * failure; the decompressor SHOULD close the stream-based transport in
363 * TODO: Reassembly, handle more than one message in a tcp segment.
367 dissect_sigcomp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *_data _U_)
370 proto_tree *sigcomp_tree;
371 tvbuff_t *unescaped_tvb;
380 gboolean end_off_message;
384 /* Is this SIGCOMP ? */
385 data = tvb_get_ntohs(tvb, offset);
389 octet = tvb_get_guint8(tvb,offset);
391 octet = tvb_get_guint8(tvb,offset);
393 if ((octet & 0xf8) != 0xf8)
396 /* Search for delimiter 0xffff in the remain tvb buffer */
397 length = tvb_ensure_length_remaining(tvb, offset);
398 for(i=0; i<(length-1); ++i){
399 /* Loop end criteria is (length-1) because we take 2 bytes each loop */
400 data = tvb_get_ntohs(tvb, offset+i);
401 if (0xffff == data) break;
403 if (i >= (length-1)){
404 /* SIGCOMP may be subdissector of SIP, so we use
405 * pinfo->saved_can_desegment to determine whether do desegment
406 * as well as pinfo->can_desegment */
407 if (pinfo->can_desegment || pinfo->saved_can_desegment){
408 /* Delimiter oxffff was not found, not a complete SIGCOMP PDU */
409 pinfo->desegment_offset = offset;
410 pinfo->desegment_len=DESEGMENT_ONE_MORE_SEGMENT;
415 /* Make entries in Protocol column and Info column on summary display */
416 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
418 col_clear(pinfo->cinfo, COL_INFO);
420 length = tvb_length_remaining(tvb,offset);
423 /* create display subtree for the protocol */
424 ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, ENC_NA);
425 sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
427 end_off_message = FALSE;
428 buff = (guint8 *)wmem_alloc(pinfo->pool, length-offset);
429 if (udvm_print_detail_level>2)
430 proto_tree_add_text(sigcomp_tree, tvb, offset, -1,"Starting to remove escape digits");
431 while ((offset < length) && (end_off_message == FALSE)){
432 octet = tvb_get_guint8(tvb,offset);
433 if ( octet == 0xff ){
434 if ( offset +1 >= length ){
435 /* if the tvb is short don't check for the second escape digit */
439 if (udvm_print_detail_level>2)
440 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
441 " Escape digit found (0xFF)");
442 octet = tvb_get_guint8(tvb, offset+1);
449 if ((octet > 0x7f) && (octet < 0xff )){
450 if (udvm_print_detail_level>2)
451 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
452 " Illegal escape code");
453 offset = offset + tvb_length_remaining(tvb,offset);
457 if (udvm_print_detail_level>2)
458 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
459 " End of SigComp message indication found (0xFFFF)");
460 end_off_message = TRUE;
465 if (udvm_print_detail_level>2)
466 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
467 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
470 if (udvm_print_detail_level>2)
471 proto_tree_add_text(sigcomp_tree, tvb, offset, octet,
472 " Copying %u bytes literally",octet);
473 if( offset+octet >= length)
474 /* if the tvb is short don't copy further than the end */
475 octet = length - offset;
476 for ( n=0; n < octet; n++ ){
477 buff[i] = tvb_get_guint8(tvb, offset);
478 if (udvm_print_detail_level>2)
479 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
480 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
487 if (udvm_print_detail_level>2)
488 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
489 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
494 unescaped_tvb = tvb_new_child_real_data(tvb, buff,i,i);
496 add_new_data_source(pinfo, unescaped_tvb, "Unescaped Data handed to the SigComp dissector");
498 proto_tree_add_text(sigcomp_tree, unescaped_tvb, 0, -1,"Data handed to the Sigcomp dissector");
499 if (end_off_message == TRUE){
500 dissect_sigcomp_common(unescaped_tvb, pinfo, sigcomp_tree);
502 proto_tree_add_text(sigcomp_tree, unescaped_tvb, 0, -1,"TCP Fragment, no end mark found");
504 if ( offset < length){
510 /* Code to actually dissect the packets */
512 dissect_sigcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
515 proto_tree *sigcomp_tree;
519 /* If we got called from SIP this might be over TCP */
520 if ( pinfo->ptype == PT_TCP )
521 return dissect_sigcomp_tcp(tvb, pinfo, tree, NULL);
523 /* Is this a SigComp message or not ? */
524 octet = tvb_get_guint8(tvb, offset);
525 if ((octet & 0xf8) != 0xf8)
528 /* Make entries in Protocol column and Info column on summary display */
529 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
531 col_clear(pinfo->cinfo, COL_INFO);
535 /* create display subtree for the protocol */
536 ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, ENC_NA);
537 sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
539 return dissect_sigcomp_common(tvb, pinfo, sigcomp_tree);
541 /* Code to actually dissect the packets */
543 dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sigcomp_tree)
546 /* Set up structures needed to add the protocol subtree and manage it */
547 tvbuff_t *udvm_tvb, *msg_tvb, *udvm2_tvb;
548 tvbuff_t *decomp_tvb = NULL;
549 proto_item *udvm_bytecode_item, *udvm_exe_item;
550 proto_tree *sigcomp_udvm_tree, *sigcomp_udvm_exe_tree;
552 gint bytecode_offset;
553 guint16 partial_state_len;
555 guint8 returned_feedback_field[128];
556 guint8 partial_state[12];
559 guint16 bytecode_len = 0;
566 guint16 state_length;
567 guint16 state_address;
568 guint16 state_instruction;
570 gchar *partial_state_str;
575 /* add an item to the subtree, see section 1.6 for more information */
576 octet = tvb_get_guint8(tvb, offset);
578 /* A SigComp message takes one of two forms depending on whether it
579 * accesses a state item at the receiving endpoint. The two variants of
580 * a SigComp message are given in Figure 3. (The T-bit controls the
581 * format of the returned feedback item and is defined in Section 7.1.)
583 * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
584 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
585 * | 1 1 1 1 1 | T | len | | 1 1 1 1 1 | T | 0 |
586 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
588 * : returned feedback item : : returned feedback item :
590 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
592 * : partial state identifier : +---+---+---+---+---+---+---+---+
594 * | | | code_len | destination |
595 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
597 * : remaining SigComp message : : uploaded UDVM bytecode :
599 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
601 * : remaining SigComp message :
603 * +---+---+---+---+---+---+---+---+
606 * The format of the NACK message and the use of the fields within it
607 * are shown in Figure 1.
610 * +---+---+---+---+---+---+---+---+
611 * | 1 1 1 1 1 | T | 0 |
612 * +---+---+---+---+---+---+---+---+
614 * : returned feedback item :
616 * +---+---+---+---+---+---+---+---+
618 * +---+---+---+---+---+---+---+---+
619 * | code_len = 0 | version = 1 |
620 * +---+---+---+---+---+---+---+---+
622 * +---+---+---+---+---+---+---+---+
623 * | OPCODE of failed instruction |
624 * +---+---+---+---+---+---+---+---+
625 * | PC of failed instruction |
627 * +---+---+---+---+---+---+---+---+
629 * : SHA-1 Hash of failed message :
631 * +---+---+---+---+---+---+---+---+
635 * +---+---+---+---+---+---+---+---+
636 * Figure 1: SigComp NACK Message Format
639 proto_tree_add_item(sigcomp_tree,hf_sigcomp_t_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
640 proto_tree_add_item(sigcomp_tree,hf_sigcomp_len, tvb, offset, 1, ENC_BIG_ENDIAN);
641 tbit = ( octet & 0x04)>>2;
642 partial_state_len = octet & 0x03;
644 if ( partial_state_len != 0 ){
646 * The len field encodes the number of transmitted bytes as follows:
648 * Encoding: Length of partial state identifier
655 partial_state_len = partial_state_len * 3 + 3;
660 col_set_str(pinfo->cinfo, COL_INFO, "Msg format 1");
664 * Returned feedback item exists
667 octet = tvb_get_guint8(tvb, offset);
668 /* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
669 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
670 * | 0 | returned_feedback_field | | 1 | returned_feedback_length |
671 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
673 * : returned_feedback_field :
675 * +---+---+---+---+---+---+---+---+
676 * Figure 4: Format of returned feedback item
679 if ( (octet & 0x80) != 0 ){
681 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
682 tvb, offset, 1, ENC_BIG_ENDIAN);
684 tvb_memcpy(tvb,returned_feedback_field,offset, len);
686 returned_feedback_field[0] = tvb_get_guint8(tvb, offset) & 0x7f;
688 proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
689 tvb, offset, len, returned_feedback_field);
690 offset = offset + len;
692 tvb_memcpy(tvb, partial_state, offset, partial_state_len);
693 partial_state_str = bytes_to_str(wmem_packet_scope(), partial_state, partial_state_len);
694 proto_tree_add_string(sigcomp_tree,hf_sigcomp_partial_state,
695 tvb, offset, partial_state_len, partial_state_str);
696 offset = offset + partial_state_len;
697 msg_len = tvb_reported_length_remaining(tvb, offset);
701 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_remaining_message_bytes, tvb,
703 PROTO_ITEM_SET_GENERATED(ti);
707 msg_tvb = tvb_new_subset_length(tvb, offset, msg_len);
709 * buff = Where "state" will be stored
710 * p_id_start = Partial state identifier start pos in the buffer(buff)
711 * partial_state_len = Partial state identifier length
712 * state_begin = Where to start to read state from
713 * state_length = Length of state
714 * state_address = Address where to store the state in the buffer(buff)
715 * state_instruction =
716 * TRUE = Indicates that state_* is in the stored state
719 * Note: The allocated buffer must be zeroed or some strange effects might occur.
721 buff = (guint8 *)wmem_alloc0(pinfo->pool, UDVM_MEMORY_SIZE);
726 /* These values will be loaded from the buffered state in sigcomp_state_hdlr
730 state_instruction =0;
733 while ( i < partial_state_len ){
734 buff[i] = partial_state[i];
738 /* begin partial state-id change cco@iptel.org */
740 result_code = udvm_state_access(tvb, sigcomp_tree, buff, p_id_start, partial_state_len, state_begin, &state_length,
741 &state_address, &state_instruction, hf_sigcomp_partial_state);
743 result_code = udvm_state_access(tvb, sigcomp_tree, buff, p_id_start, STATE_MIN_ACCESS_LEN, state_begin, &state_length,
744 &state_address, &state_instruction, hf_sigcomp_partial_state);
746 /* end partial state-id change cco@iptel.org */
747 if ( result_code != 0 ){
749 ti = proto_tree_add_text(sigcomp_tree, tvb, 0, -1,"Failed to Access state Wireshark UDVM diagnostic: %s.",
750 val_to_str(result_code, result_code_vals,"Unknown (%u)"));
751 PROTO_ITEM_SET_GENERATED(ti);
752 return tvb_length(tvb);
755 udvm_tvb = tvb_new_child_real_data(tvb, buff,state_length+state_address,state_length+state_address);
756 add_new_data_source(pinfo, udvm_tvb, "State/ExecutionTrace");
758 udvm2_tvb = tvb_new_subset_length(udvm_tvb, state_address, state_length);
759 udvm_exe_item = proto_tree_add_item(sigcomp_tree, hf_udvm_execution_trace,
760 udvm2_tvb, 0, state_length,
762 sigcomp_udvm_exe_tree = proto_item_add_subtree( udvm_exe_item, ett_sigcomp_udvm_exe);
764 decomp_tvb = decompress_sigcomp_message(udvm2_tvb, msg_tvb, pinfo,
765 sigcomp_udvm_exe_tree, state_address,
766 udvm_print_detail_level, hf_sigcomp_partial_state,
767 offset, state_length, partial_state_len, state_instruction);
772 guint32 compression_ratio =
773 (guint32)(((float)tvb_length(decomp_tvb) / (float)tvb_length(tvb)) * 100);
775 /* Celebrate success and show compression ratio achieved */
776 proto_tree_add_text(sigcomp_tree, decomp_tvb, 0, -1,"SigComp message Decompressed WOHO!!");
777 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_compression_ratio, decomp_tvb,
778 0, 0, compression_ratio);
779 PROTO_ITEM_SET_GENERATED(ti);
781 if ( display_raw_txt )
782 tvb_raw_text_add(decomp_tvb, top_tree);
784 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
785 col_set_fence(pinfo->cinfo,COL_PROTOCOL);
786 call_dissector(sip_handle, decomp_tvb, pinfo, top_tree);
795 col_set_str(pinfo->cinfo, COL_INFO, "Msg format 2");
798 * Returned feedback item exists
801 octet = tvb_get_guint8(tvb, offset);
802 if ( (octet & 0x80) != 0 ){
804 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
805 tvb, offset, 1, ENC_BIG_ENDIAN);
808 tvb_memcpy(tvb,returned_feedback_field,offset, len);
809 proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
810 tvb, offset, len, returned_feedback_field);
811 offset = offset + len;
813 len = tvb_get_ntohs(tvb, offset) >> 4;
814 nack_version = tvb_get_guint8(tvb, offset+1) & 0x0f;
815 if ((len == 0) && (nack_version == 1)){
817 proto_item *reason_ti;
820 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
822 octet = tvb_get_guint8(tvb, offset);
823 reason_ti = proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
825 opcode = tvb_get_guint8(tvb, offset);
826 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_failed_op_code, tvb, offset, 1, ENC_BIG_ENDIAN);
829 /* Add expert item for NACK */
830 expert_add_info_format(pinfo, reason_ti, &ei_sigcomp_nack_failed_op_code,
831 "SigComp NACK (reason=%s, opcode=%s)",
832 val_to_str_ext_const(octet, &sigcomp_nack_reason_code_vals_ext, "Unknown"),
833 val_to_str_ext_const(opcode, &udvm_instruction_code_vals_ext, "Unknown"));
835 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_pc, tvb, offset, 2, ENC_BIG_ENDIAN);
837 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_sha1, tvb, offset, 20, ENC_NA);
840 /* Add NACK info to info column */
841 col_append_fstr(pinfo->cinfo, COL_INFO, " NACK reason=%s, opcode=%s",
842 val_to_str_ext_const(octet, &sigcomp_nack_reason_code_vals_ext, "Unknown"),
843 val_to_str_ext_const(opcode, &udvm_instruction_code_vals_ext, "Unknown"));
846 case SIGCOMP_NACK_STATE_NOT_FOUND:
847 case SIGCOMP_NACK_ID_NOT_UNIQUE:
848 case SIGCOMP_NACK_STATE_TOO_SHORT:
849 /* State ID (6 - 20 bytes) */
850 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_state_id, tvb, offset, -1, ENC_NA);
852 case SIGCOMP_NACK_CYCLES_EXHAUSTED:
853 /* Cycles Per Bit (1 byte) */
854 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_cycles_per_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
856 case SIGCOMP_NACK_BYTECODES_TOO_LARGE:
857 /* Memory size (2 bytes) */
858 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_memory_size, tvb, offset, 2, ENC_BIG_ENDIAN);
864 octet = tvb_get_guint8(tvb, (offset + 1));
865 destination = (octet & 0x0f);
866 if ( destination != 0 )
867 destination = 64 + ( destination * 64 );
868 proto_tree_add_item(sigcomp_tree,hf_sigcomp_code_len, tvb, offset, 2, ENC_BIG_ENDIAN);
869 proto_tree_add_item(sigcomp_tree,hf_sigcomp_destination, tvb, (offset+ 1), 1, ENC_BIG_ENDIAN);
873 bytecode_offset = offset;
874 udvm_bytecode_item = proto_tree_add_item(sigcomp_tree, hf_sigcomp_udvm_bytecode, tvb,
875 bytecode_offset, bytecode_len, ENC_NA);
876 proto_item_append_text(udvm_bytecode_item,
877 " %u (0x%x) bytes", bytecode_len, bytecode_len);
878 sigcomp_udvm_tree = proto_item_add_subtree( udvm_bytecode_item, ett_sigcomp_udvm);
880 udvm_tvb = tvb_new_subset_length(tvb, offset, len);
881 if ( dissect_udvm_code )
882 dissect_udvm_bytecode(udvm_tvb, sigcomp_udvm_tree, destination);
884 offset = offset + len;
885 msg_len = tvb_reported_length_remaining(tvb, offset);
887 proto_item *ti = proto_tree_add_text(sigcomp_tree, tvb, offset, -1,
888 "Remaining SigComp message %u bytes",
889 tvb_reported_length_remaining(tvb, offset));
890 PROTO_ITEM_SET_GENERATED(ti);
894 msg_tvb = tvb_new_subset_length(tvb, offset, msg_len);
896 udvm_exe_item = proto_tree_add_item(sigcomp_tree, hf_udvm_execution_trace,
897 tvb, bytecode_offset, bytecode_len,
899 sigcomp_udvm_exe_tree = proto_item_add_subtree( udvm_exe_item, ett_sigcomp_udvm_exe);
900 decomp_tvb = decompress_sigcomp_message(udvm_tvb, msg_tvb, pinfo,
901 sigcomp_udvm_exe_tree, destination,
902 udvm_print_detail_level, hf_sigcomp_partial_state,
903 offset, 0, 0, destination);
906 guint32 compression_ratio =
907 (guint32)(((float)tvb_length(decomp_tvb) / (float)tvb_length(tvb)) * 100);
909 /* Celebrate success and show compression ratio achieved */
910 proto_tree_add_text(sigcomp_tree, decomp_tvb, 0, -1,"SigComp message Decompressed WOHO!!");
911 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_compression_ratio, decomp_tvb,
912 0, 0, compression_ratio);
913 PROTO_ITEM_SET_GENERATED(ti);
915 if ( display_raw_txt )
916 tvb_raw_text_add(decomp_tvb, top_tree);
918 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
919 col_set_fence(pinfo->cinfo,COL_PROTOCOL);
920 call_dissector(sip_handle, decomp_tvb, pinfo, top_tree);
922 } /* if decompress */
926 return tvb_length(tvb);
930 #define SIGCOMP_INSTR_DECOMPRESSION_FAILURE 0
931 #define SIGCOMP_INSTR_AND 1
932 #define SIGCOMP_INSTR_OR 2
933 #define SIGCOMP_INSTR_NOT 3
934 #define SIGCOMP_INSTR_LSHIFT 4
935 #define SIGCOMP_INSTR_RSHIFT 5
936 #define SIGCOMP_INSTR_ADD 6
937 #define SIGCOMP_INSTR_SUBTRACT 7
938 #define SIGCOMP_INSTR_MULTIPLY 8
939 #define SIGCOMP_INSTR_DIVIDE 9
940 #define SIGCOMP_INSTR_REMAINDER 10
941 #define SIGCOMP_INSTR_SORT_ASCENDING 11
942 #define SIGCOMP_INSTR_SORT_DESCENDING 12
943 #define SIGCOMP_INSTR_SHA_1 13
944 #define SIGCOMP_INSTR_LOAD 14
945 #define SIGCOMP_INSTR_MULTILOAD 15
946 #define SIGCOMP_INSTR_PUSH 16
947 #define SIGCOMP_INSTR_POP 17
948 #define SIGCOMP_INSTR_COPY 18
949 #define SIGCOMP_INSTR_COPY_LITERAL 19
950 #define SIGCOMP_INSTR_COPY_OFFSET 20
951 #define SIGCOMP_INSTR_MEMSET 21
952 #define SIGCOMP_INSTR_JUMP 22
953 #define SIGCOMP_INSTR_COMPARE 23
954 #define SIGCOMP_INSTR_CALL 24
955 #define SIGCOMP_INSTR_RETURN 25
956 #define SIGCOMP_INSTR_SWITCH 26
957 #define SIGCOMP_INSTR_CRC 27
958 #define SIGCOMP_INSTR_INPUT_BYTES 28
959 #define SIGCOMP_INSTR_INPUT_BITS 29
960 #define SIGCOMP_INSTR_INPUT_HUFFMAN 30
961 #define SIGCOMP_INSTR_STATE_ACCESS 31
962 #define SIGCOMP_INSTR_STATE_CREATE 32
963 #define SIGCOMP_INSTR_STATE_FREE 33
964 #define SIGCOMP_INSTR_OUTPUT 34
965 #define SIGCOMP_INSTR_END_MESSAGE 35
969 dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,guint start_address)
973 gint start_offset = 0;
976 guint instruction_no = 0;
978 proto_item *item, *item2;
979 guint UDVM_address = start_address;
980 gboolean is_memory_address;
981 guint16 msg_length = tvb_reported_length_remaining(udvm_tvb, offset);
984 while (msg_length > offset) {
985 instruction = tvb_get_guint8(udvm_tvb, offset);
987 UDVM_address = start_address + offset;
990 item = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
991 "######### UDVM instruction %u at UDVM-address %u (0x%x) #########",
992 instruction_no,UDVM_address,UDVM_address);
993 PROTO_ITEM_SET_GENERATED(item);
994 proto_tree_add_item(sigcomp_udvm_tree, hf_sigcomp_udvm_instr, udvm_tvb, offset, 1, ENC_BIG_ENDIAN);
996 switch ( instruction ) {
998 case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */
1000 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1001 len = offset - start_offset;
1002 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1003 udvm_tvb, start_offset, len, value);
1005 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1006 len = offset - start_offset;
1007 if ( is_memory_address ){
1008 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1009 udvm_tvb, start_offset, len, value);
1011 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1012 udvm_tvb, start_offset, len, value);
1016 case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */
1018 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1019 len = offset - start_offset;
1020 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1021 udvm_tvb, start_offset, len, value);
1023 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1024 len = offset - start_offset;
1025 if ( is_memory_address ){
1026 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1027 udvm_tvb, start_offset, len, value);
1029 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1030 udvm_tvb, start_offset, len, value);
1034 case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */
1036 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1037 len = offset - start_offset;
1038 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1039 udvm_tvb, start_offset, len, value);
1042 case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */
1044 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1045 len = offset - start_offset;
1046 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1047 udvm_tvb, start_offset, len, value);
1049 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1050 len = offset - start_offset;
1051 if ( is_memory_address ){
1052 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1053 udvm_tvb, start_offset, len, value);
1055 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1056 udvm_tvb, start_offset, len, value);
1060 case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */
1062 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1063 len = offset - start_offset;
1064 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1065 udvm_tvb, start_offset, len, value);
1067 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1068 len = offset - start_offset;
1069 if ( is_memory_address ){
1070 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1071 udvm_tvb, start_offset, len, value);
1073 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1074 udvm_tvb, start_offset, len, value);
1078 case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */
1080 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1081 len = offset - start_offset;
1082 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1083 udvm_tvb, start_offset, len, value);
1085 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1086 len = offset - start_offset;
1087 if ( is_memory_address ){
1088 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1089 udvm_tvb, start_offset, len, value);
1091 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1092 udvm_tvb, start_offset, len, value);
1096 case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */
1098 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1099 len = offset - start_offset;
1100 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1101 udvm_tvb, start_offset, len, value);
1103 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1104 len = offset - start_offset;
1105 if ( is_memory_address ){
1106 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1107 udvm_tvb, start_offset, len, value);
1109 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1110 udvm_tvb, start_offset, len, value);
1114 case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */
1116 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1117 len = offset - start_offset;
1118 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1119 udvm_tvb, start_offset, len, value);
1121 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1122 len = offset - start_offset;
1123 if ( is_memory_address ){
1124 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1125 udvm_tvb, start_offset, len, value);
1127 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1128 udvm_tvb, start_offset, len, value);
1132 case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */
1134 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1135 len = offset - start_offset;
1136 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1137 udvm_tvb, start_offset, len, value);
1139 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1140 len = offset - start_offset;
1141 if ( is_memory_address ){
1142 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1143 udvm_tvb, start_offset, len, value);
1145 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1146 udvm_tvb, start_offset, len, value);
1150 case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */
1152 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1153 len = offset - start_offset;
1154 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1155 udvm_tvb, start_offset, len, value);
1157 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1158 len = offset - start_offset;
1159 if ( is_memory_address ){
1160 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1161 udvm_tvb, start_offset, len, value);
1163 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1164 udvm_tvb, start_offset, len, value);
1167 case SIGCOMP_INSTR_SORT_ASCENDING: /* 11 SORT-ASCENDING (%start, %n, %k) */
1168 /* while programming stop while loop */
1169 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1172 case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */
1173 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1175 case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */
1177 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1178 len = offset - start_offset;
1179 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1180 udvm_tvb, start_offset, len, value);
1183 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1184 len = offset - start_offset;
1185 if ( is_memory_address ){
1186 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1187 udvm_tvb, start_offset, len, value);
1189 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1190 udvm_tvb, start_offset, len, value);
1194 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1195 len = offset - start_offset;
1196 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1197 udvm_tvb, start_offset, len, value);
1200 case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */
1202 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
1203 len = offset - start_offset;
1204 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1205 udvm_tvb, start_offset, len, value);
1207 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1208 len = offset - start_offset;
1209 if ( is_memory_address ){
1210 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1211 udvm_tvb, start_offset, len, value);
1213 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1214 udvm_tvb, start_offset, len, value);
1218 case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
1220 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1221 len = offset - start_offset;
1222 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1223 udvm_tvb, start_offset, len, value);
1225 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1226 len = offset - start_offset;
1227 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1228 udvm_tvb, start_offset, len, value);
1233 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1234 len = offset - start_offset;
1235 if ( is_memory_address ){
1236 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1237 udvm_tvb, start_offset, len, value);
1239 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1240 udvm_tvb, start_offset, len, value);
1245 case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */
1247 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1248 len = offset - start_offset;
1249 if ( is_memory_address ){
1250 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1251 udvm_tvb, start_offset, len, value);
1253 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1254 udvm_tvb, start_offset, len, value);
1258 case SIGCOMP_INSTR_POP: /* 17 POP (%address) */
1260 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1262 len = offset - start_offset;
1263 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1264 udvm_tvb, start_offset, len, value);
1267 case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */
1269 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1270 len = offset - start_offset;
1271 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1272 udvm_tvb, start_offset, len, value);
1275 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1276 len = offset - start_offset;
1277 if ( is_memory_address ){
1278 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1279 udvm_tvb, start_offset, len, value);
1281 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1282 udvm_tvb, start_offset, len, value);
1286 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1287 len = offset - start_offset;
1288 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1289 udvm_tvb, start_offset, len, value);
1292 case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */
1294 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1295 len = offset - start_offset;
1296 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1297 udvm_tvb, start_offset, len, value);
1300 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1301 len = offset - start_offset;
1302 if ( is_memory_address ){
1303 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1304 udvm_tvb, start_offset, len, value);
1306 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1307 udvm_tvb, start_offset, len, value);
1311 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1312 len = offset - start_offset;
1313 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1314 udvm_tvb, start_offset, len, value);
1317 case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */
1319 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1320 len = offset - start_offset;
1321 if ( is_memory_address ){
1322 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_offset,
1323 udvm_tvb, start_offset, len, value);
1325 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
1326 udvm_tvb, start_offset, len, value);
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_length,
1334 udvm_tvb, start_offset, len, value);
1336 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1337 udvm_tvb, start_offset, len, value);
1341 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1342 len = offset - start_offset;
1343 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1344 udvm_tvb, start_offset, len, value);
1346 case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */
1349 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1350 len = offset - start_offset;
1351 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1352 udvm_tvb, start_offset, len, value);
1355 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE, &start_offset, &value, &is_memory_address);
1356 len = offset - start_offset;
1357 if ( is_memory_address ){
1358 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1359 udvm_tvb, start_offset, len, value);
1361 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1362 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 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_start_value,
1369 udvm_tvb, start_offset, len, value);
1372 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1373 len = offset - start_offset;
1374 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
1375 udvm_tvb, start_offset, len, value);
1379 case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */
1381 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1382 len = offset - start_offset;
1383 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1384 value = ( value + UDVM_address ) & 0xffff;
1385 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1386 udvm_tvb, start_offset, len, value);
1389 case SIGCOMP_INSTR_COMPARE: /* 23 */
1390 /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
1393 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1394 len = offset - start_offset;
1395 if ( is_memory_address ){
1396 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1397 udvm_tvb, start_offset, len, value);
1399 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1400 udvm_tvb, start_offset, len, value);
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, TRUE, &start_offset, &value, &is_memory_address);
1416 len = offset - start_offset;
1417 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1418 value = ( value + UDVM_address ) & 0xffff;
1419 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1420 udvm_tvb, start_offset, len, value);
1423 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1424 len = offset - start_offset;
1425 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1426 value = ( value + UDVM_address ) & 0xffff;
1427 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1428 udvm_tvb, start_offset, len, value);
1431 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1432 len = offset - start_offset;
1433 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1434 value = ( value + UDVM_address ) & 0xffff;
1435 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1436 udvm_tvb, start_offset, len, value);
1439 case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/
1441 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1442 len = offset - start_offset;
1443 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1444 value = ( value + UDVM_address ) & 0xffff;
1445 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1446 udvm_tvb, start_offset, len, value);
1448 case SIGCOMP_INSTR_RETURN: /* 25 POP and return */
1452 case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
1454 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1455 len = offset - start_offset;
1456 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1457 udvm_tvb, start_offset, len, value);
1459 /* Number of addresses in the instruction */
1462 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1463 len = offset - start_offset;
1464 if ( is_memory_address ){
1465 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_j,
1466 udvm_tvb, start_offset, len, value);
1468 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_j,
1469 udvm_tvb, start_offset, len, value);
1475 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
1476 len = offset - start_offset;
1477 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1478 value = ( value + UDVM_address ) & 0xffff;
1479 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1480 udvm_tvb, start_offset, len, value);
1483 case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */
1485 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1486 len = offset - start_offset;
1487 if ( is_memory_address ){
1488 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1489 udvm_tvb, start_offset, len, value);
1491 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1492 udvm_tvb, start_offset, len, value);
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 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1499 udvm_tvb, start_offset, len, value);
1502 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1503 len = offset - start_offset;
1504 if ( is_memory_address ){
1505 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1506 udvm_tvb, start_offset, len, value);
1508 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1509 udvm_tvb, start_offset, len, value);
1513 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1514 len = offset - start_offset;
1515 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1516 value = ( value + UDVM_address ) & 0xffff;
1517 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1518 udvm_tvb, start_offset, len, value);
1522 case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */
1524 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1525 len = offset - start_offset;
1526 if ( is_memory_address ){
1527 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1528 udvm_tvb, start_offset, len, value);
1530 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1531 udvm_tvb, start_offset, len, value);
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_destination,
1539 udvm_tvb, start_offset, len, value);
1541 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1542 udvm_tvb, start_offset, len, value);
1546 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1547 len = offset - start_offset;
1548 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1549 value = ( value + UDVM_address ) & 0xffff;
1550 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1551 udvm_tvb, start_offset, len, value);
1553 case SIGCOMP_INSTR_INPUT_BITS:/* 29 INPUT-BITS (%length, %destination, @address) */
1555 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1556 len = offset - start_offset;
1557 if ( is_memory_address ){
1558 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1559 udvm_tvb, start_offset, len, value);
1561 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1562 udvm_tvb, start_offset, len, value);
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_destination,
1570 udvm_tvb, start_offset, len, value);
1572 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1573 udvm_tvb, start_offset, len, value);
1577 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1578 len = offset - start_offset;
1579 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1580 value = ( value + UDVM_address ) & 0xffff;
1581 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1582 udvm_tvb, start_offset, len, value);
1584 case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */
1586 * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1,
1587 * %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n,
1588 * %upper_bound_n, %uncompressed_n)
1591 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1592 len = offset - start_offset;
1593 if ( is_memory_address ){
1594 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
1595 udvm_tvb, start_offset, len, value);
1597 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1598 udvm_tvb, start_offset, len, value);
1601 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1602 len = offset - start_offset;
1603 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1604 value = ( value + UDVM_address ) & 0xffff;
1605 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1606 udvm_tvb, start_offset, len, value);
1608 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1609 len = offset - start_offset;
1610 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1611 udvm_tvb, start_offset, len, value);
1616 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1617 len = offset - start_offset;
1618 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_bits,
1619 udvm_tvb, start_offset, len, value);
1621 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1622 len = offset - start_offset;
1623 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_lower_bound,
1624 udvm_tvb, start_offset, len, value);
1625 /* %upper_bound_n */
1626 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1627 len = offset - start_offset;
1628 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_upper_bound,
1629 udvm_tvb, start_offset, len, value);
1630 /* %uncompressed_n */
1631 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1632 len = offset - start_offset;
1633 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_uncompressed,
1634 udvm_tvb, start_offset, len, value);
1638 case SIGCOMP_INSTR_STATE_ACCESS: /* 31 */
1639 /* STATE-ACCESS (%partial_identifier_start, %partial_identifier_length,
1640 * %state_begin, %state_length, %state_address, %state_instruction)
1644 * %partial_identifier_start
1646 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1647 len = offset - start_offset;
1648 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
1649 udvm_tvb, start_offset, len, value);
1652 * %partial_identifier_length
1654 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1655 len = offset - start_offset;
1656 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length,
1657 udvm_tvb, start_offset, len, value);
1661 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1662 len = offset - start_offset;
1663 proto_tree_add_uint(sigcomp_udvm_tree, hf_state_begin,
1664 udvm_tvb, start_offset, len, value);
1669 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1670 len = offset - start_offset;
1671 if ( is_memory_address ) {
1672 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1673 udvm_tvb, start_offset, len, value);
1675 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1676 udvm_tvb, start_offset, len, value);
1681 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1682 len = offset - start_offset;
1683 if ( is_memory_address ) {
1684 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1685 udvm_tvb, start_offset, len, value);
1687 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1688 udvm_tvb, start_offset, len, value);
1691 * %state_instruction
1693 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1694 len = offset - start_offset;
1695 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1696 udvm_tvb, start_offset, len, value);
1698 case SIGCOMP_INSTR_STATE_CREATE: /* 32 */
1700 * STATE-CREATE (%state_length, %state_address, %state_instruction,
1701 * %minimum_access_length, %state_retention_priority)
1707 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1708 len = offset - start_offset;
1709 if ( is_memory_address ) {
1710 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1711 udvm_tvb, start_offset, len, value);
1713 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1714 udvm_tvb, start_offset, len, value);
1719 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1720 len = offset - start_offset;
1721 if ( is_memory_address ) {
1722 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1723 udvm_tvb, start_offset, len, value);
1725 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1726 udvm_tvb, start_offset, len, value);
1729 * %state_instruction
1731 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1732 len = offset - start_offset;
1733 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1734 udvm_tvb, start_offset, len, value);
1736 * %minimum_access_length
1738 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1739 len = offset - start_offset;
1740 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len,
1741 udvm_tvb, start_offset, len, value);
1743 * %state_retention_priority
1745 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1746 len = offset - start_offset;
1747 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
1748 udvm_tvb, start_offset, len, value);
1751 case SIGCOMP_INSTR_STATE_FREE: /* 33 */
1753 * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
1756 * %partial_identifier_start
1758 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1759 len = offset - start_offset;
1760 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
1761 udvm_tvb, start_offset, len, value);
1764 * %partial_identifier_length
1766 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1767 len = offset - start_offset;
1768 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length,
1769 udvm_tvb, start_offset, len, value);
1771 case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */
1775 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1776 len = offset - start_offset;
1777 if ( is_memory_address ) {
1778 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_output_start,
1779 udvm_tvb, start_offset, len, value);
1781 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start,
1782 udvm_tvb, start_offset, len, value);
1787 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1788 len = offset - start_offset;
1789 if ( is_memory_address ) {
1790 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length_addr,
1791 udvm_tvb, start_offset, len, value);
1793 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length,
1794 udvm_tvb, start_offset, len, value);
1797 case SIGCOMP_INSTR_END_MESSAGE: /* 35 */
1799 * END-MESSAGE (%requested_feedback_location,
1800 * %returned_parameters_location, %state_length, %state_address,
1801 * %state_instruction, %minimum_access_length,
1802 * %state_retention_priority)
1804 /* %requested_feedback_location */
1805 if ((msg_length-1) < offset){
1806 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, 0, -1,
1807 "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1808 PROTO_ITEM_SET_GENERATED(item2);
1811 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1812 len = offset - start_offset;
1813 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_req_feedback_loc,
1814 udvm_tvb, start_offset, len, value);
1815 /* returned_parameters_location */
1816 if ((msg_length-1) < offset){
1817 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset-1, -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_ret_param_loc,
1825 udvm_tvb, start_offset, len, value);
1829 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1830 len = offset - start_offset;
1831 if ( is_memory_address ) {
1832 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1833 udvm_tvb, start_offset, len, value);
1835 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1836 udvm_tvb, start_offset, len, value);
1841 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1842 len = offset - start_offset;
1843 if ( is_memory_address ) {
1844 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1845 udvm_tvb, start_offset, len, value);
1847 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1848 udvm_tvb, start_offset, len, value);
1851 * %state_instruction
1853 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1854 len = offset - start_offset;
1855 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1856 udvm_tvb, start_offset, len, value);
1858 * %minimum_access_length
1860 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1861 len = offset - start_offset;
1862 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len,
1863 udvm_tvb, start_offset, len, value);
1865 * %state_retention_priority
1867 if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1868 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1869 len = offset - start_offset;
1870 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
1871 udvm_tvb, start_offset, len, value);
1873 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
1874 "state_retention_priority = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1875 PROTO_ITEM_SET_GENERATED(item2);
1877 if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1878 len = tvb_reported_length_remaining(udvm_tvb, offset);
1879 UDVM_address = start_address + offset;
1880 proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, len,
1881 "Remaining %u bytes starting at UDVM addr %u (0x%x)- State information ?",len, UDVM_address, UDVM_address);
1883 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1887 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1895 /* The simplest operand type is the literal (#), which encodes a
1896 * constant integer from 0 to 65535 inclusive. A literal operand may
1897 * require between 1 and 3 bytes depending on its value.
1898 * Bytecode: Operand value: Range:
1899 * 0nnnnnnn N 0 - 127
1900 * 10nnnnnn nnnnnnnn N 0 - 16383
1901 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
1903 * Figure 8: Bytecode for a literal (#) operand
1907 dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1908 gint offset, gint *start_offset, guint16 *value)
1913 guint display_bytecode;
1915 bytecode = tvb_get_guint8(udvm_tvb, offset);
1916 test_bits = bytecode >> 7;
1917 if (test_bits == 1){
1918 test_bits = bytecode >> 6;
1919 if (test_bits == 2){
1921 * 10nnnnnn nnnnnnnn N 0 - 16383
1923 display_bytecode = bytecode & 0xc0;
1924 if ( display_udvm_bytecode )
1925 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1926 udvm_tvb, offset, 1, display_bytecode);
1927 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
1929 *start_offset = offset;
1930 offset = offset + 2;
1934 * 111000000 nnnnnnnn nnnnnnnn N 0 - 65535
1936 display_bytecode = bytecode & 0xc0;
1937 if ( display_udvm_bytecode )
1938 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1939 udvm_tvb, offset, 1, display_bytecode);
1941 operand = tvb_get_ntohs(udvm_tvb, offset);
1943 *start_offset = offset;
1944 offset = offset + 2;
1949 * 0nnnnnnn N 0 - 127
1951 display_bytecode = bytecode & 0xc0;
1952 if ( display_udvm_bytecode )
1953 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1954 udvm_tvb, offset, 1, display_bytecode);
1955 operand = ( bytecode & 0x7f);
1957 *start_offset = offset;
1965 * The second operand type is the reference ($), which is always used to
1966 * access a 2-byte value located elsewhere in the UDVM memory. The
1967 * bytecode for a reference operand is decoded to be a constant integer
1968 * from 0 to 65535 inclusive, which is interpreted as the memory address
1969 * containing the actual value of the operand.
1970 * Bytecode: Operand value: Range:
1972 * 0nnnnnnn memory[2 * N] 0 - 65535
1973 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
1974 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
1976 * Figure 9: Bytecode for a reference ($) operand
1979 dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1980 gint offset, gint *start_offset, guint16 *value)
1985 guint display_bytecode;
1987 bytecode = tvb_get_guint8(udvm_tvb, offset);
1988 test_bits = bytecode >> 7;
1989 if (test_bits == 1){
1990 test_bits = bytecode >> 6;
1991 if (test_bits == 2){
1993 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
1995 display_bytecode = bytecode & 0xc0;
1996 if ( display_udvm_bytecode )
1997 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
1998 udvm_tvb, offset, 1, display_bytecode);
1999 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
2000 *value = (operand * 2);
2001 *start_offset = offset;
2002 offset = offset + 2;
2006 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
2008 display_bytecode = bytecode & 0xc0;
2009 if ( display_udvm_bytecode )
2010 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
2011 udvm_tvb, offset, 1, display_bytecode);
2013 operand = tvb_get_ntohs(udvm_tvb, offset);
2015 *start_offset = offset;
2016 offset = offset + 2;
2021 * 0nnnnnnn memory[2 * N] 0 - 65535
2023 display_bytecode = bytecode & 0xc0;
2024 if ( display_udvm_bytecode )
2025 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
2026 udvm_tvb, offset, 1, display_bytecode);
2027 operand = ( bytecode & 0x7f);
2028 *value = (operand * 2);
2029 *start_offset = offset;
2037 *The fourth operand type is the address (@). This operand is decoded
2038 * as a multitype operand followed by a further step: the memory address
2039 * of the UDVM instruction containing the address operand is added to
2040 * obtain the correct operand value. So if the operand value from
2041 * Figure 10 is D then the actual operand value of an address is
2042 * calculated as follows:
2044 * operand_value = (is_memory_address_of_instruction + D) modulo 2^16
2045 * TODO calculate correct value for operand in case of ADDR
2048 dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
2049 gint offset, gboolean is_addr _U_, gint *start_offset, guint16 *value, gboolean *is_memory_address )
2052 guint display_bytecode;
2057 * Figure 10: Bytecode for a multitype (%) operand
2058 * Bytecode: Operand value: Range: HEX val
2059 * 00nnnnnn N 0 - 63 0x00
2060 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
2061 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
2062 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
2063 * 111nnnnn N + 65504 65504 - 65535 0xe0
2064 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
2065 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
2066 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
2067 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
2068 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
2070 *is_memory_address = FALSE;
2071 bytecode = tvb_get_guint8(udvm_tvb, offset);
2072 test_bits = ( bytecode & 0xc0 ) >> 6;
2073 switch (test_bits ){
2078 display_bytecode = bytecode & 0xc0;
2079 if ( display_udvm_bytecode )
2080 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2081 udvm_tvb, offset, 1, display_bytecode);
2082 operand = ( bytecode & 0x3f);
2084 *start_offset = offset;
2089 * 01nnnnnn memory[2 * N] 0 - 65535
2091 display_bytecode = bytecode & 0xc0;
2092 if ( display_udvm_bytecode )
2093 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2094 udvm_tvb, offset, 1, display_bytecode);
2095 operand = ( bytecode & 0x3f) * 2;
2096 *is_memory_address = TRUE;
2098 *start_offset = offset;
2102 /* Check tree most significant bits */
2103 test_bits = ( bytecode & 0xe0 ) >> 5;
2104 if ( test_bits == 5 ){
2106 * 101nnnnn nnnnnnnn N 0 - 8191
2108 display_bytecode = bytecode & 0xe0;
2109 if ( display_udvm_bytecode )
2110 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2111 udvm_tvb, offset, 1, display_bytecode);
2112 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x1fff;
2114 *start_offset = offset;
2115 offset = offset + 2;
2117 test_bits = ( bytecode & 0xf0 ) >> 4;
2118 if ( test_bits == 9 ){
2120 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535
2122 display_bytecode = bytecode & 0xf0;
2123 if ( display_udvm_bytecode )
2124 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2125 udvm_tvb, offset, 1, display_bytecode);
2126 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x0fff) + 61440;
2127 *start_offset = offset;
2129 offset = offset + 2;
2131 test_bits = ( bytecode & 0x08 ) >> 3;
2132 if ( test_bits == 1){
2134 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768
2136 display_bytecode = bytecode & 0xf8;
2137 if ( display_udvm_bytecode )
2138 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2139 udvm_tvb, offset, 1, display_bytecode);
2140 result = (guint32)pow(2,( bytecode & 0x07) + 8);
2141 operand = result & 0xffff;
2142 *start_offset = offset;
2146 test_bits = ( bytecode & 0x0e ) >> 1;
2147 if ( test_bits == 3 ){
2149 * 1000 011n 2 ^ (N + 6) 64 , 128
2151 display_bytecode = bytecode & 0xfe;
2152 if ( display_udvm_bytecode )
2153 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2154 udvm_tvb, offset, 1, display_bytecode);
2155 result = (guint32)pow(2,( bytecode & 0x01) + 6);
2156 operand = result & 0xffff;
2157 *start_offset = offset;
2162 * 1000 0000 nnnnnnnn nnnnnnnn N 0 - 65535
2163 * 1000 0001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
2165 display_bytecode = bytecode;
2166 if ( display_udvm_bytecode )
2167 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2168 udvm_tvb, offset, 1, display_bytecode);
2169 if ( (bytecode & 0x01) == 1 )
2170 *is_memory_address = TRUE;
2172 operand = tvb_get_ntohs(udvm_tvb, offset);
2174 *start_offset = offset;
2185 test_bits = ( bytecode & 0x20 ) >> 5;
2186 if ( test_bits == 1 ){
2188 * 111nnnnn N + 65504 65504 - 65535
2190 display_bytecode = bytecode & 0xe0;
2191 if ( display_udvm_bytecode )
2192 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2193 udvm_tvb, offset, 1, display_bytecode);
2194 operand = ( bytecode & 0x1f) + 65504;
2195 *start_offset = offset;
2200 * 110nnnnn nnnnnnnn memory[N] 0 - 65535
2202 display_bytecode = bytecode & 0xe0;
2203 if ( display_udvm_bytecode )
2204 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2205 udvm_tvb, offset, 1, display_bytecode);
2206 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x1fff);
2207 *is_memory_address = TRUE;
2208 *start_offset = offset;
2220 tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree)
2222 proto_tree *raw_tree = NULL;
2223 proto_item *ti = NULL;
2224 int offset, next_offset, linelen;
2227 ti = proto_tree_add_item(tree, proto_raw_sigcomp, tvb, 0, -1, ENC_NA);
2228 raw_tree = proto_item_add_subtree(ti, ett_raw_text);
2233 while (tvb_offset_exists(tvb, offset)) {
2234 tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
2235 linelen = next_offset - offset;
2236 proto_tree_add_format_text(raw_tree, tvb, offset, linelen);
2237 offset = next_offset;
2241 /* Register the protocol with Wireshark */
2244 proto_register_sigcomp(void)
2246 /* Setup list of header fields See Section 1.6.1 for details*/
2247 static hf_register_info hf[] = {
2248 { &hf_sigcomp_t_bit,
2249 { "T bit", "sigcomp.t.bit",
2250 FT_UINT8, BASE_DEC, NULL, 0x04,
2251 "Sigcomp T bit", HFILL }
2254 { "Partial state id length","sigcomp.length",
2255 FT_UINT8, BASE_HEX, VALS(length_encoding_vals), 0x03,
2256 "Sigcomp length", HFILL }
2258 { &hf_sigcomp_returned_feedback_item,
2259 { "Returned_feedback item", "sigcomp.returned.feedback.item",
2260 FT_BYTES, BASE_NONE, NULL, 0x0,
2261 "Returned feedback item", HFILL }
2263 { &hf_sigcomp_partial_state,
2264 { "Partial state identifier", "sigcomp.partial.state.identifier",
2265 FT_STRING, BASE_NONE, NULL, 0x0,
2268 { &hf_sigcomp_remaining_message_bytes,
2269 { "Remaining SigComp message bytes", "sigcomp.remaining-bytes",
2270 FT_UINT32, BASE_DEC, NULL, 0x0,
2271 "Number of bytes remaining in message", HFILL }
2273 { &hf_sigcomp_compression_ratio,
2274 { "Compression ratio (%)", "sigcomp.compression-ratio",
2275 FT_UINT32, BASE_DEC, NULL, 0x0,
2276 "Compression ratio (decompressed / compressed) %", HFILL }
2278 { &hf_sigcomp_returned_feedback_item_len,
2279 { "Returned feedback item length", "sigcomp.returned.feedback.item.len",
2280 FT_UINT8, BASE_DEC, NULL, 0x7f,
2283 { &hf_sigcomp_code_len,
2284 { "Code length","sigcomp.code.len",
2285 FT_UINT16, BASE_HEX, NULL, 0xfff0,
2288 { &hf_sigcomp_destination,
2289 { "Destination","sigcomp.destination",
2290 FT_UINT8, BASE_HEX | BASE_EXT_STRING, &destination_address_encoding_vals_ext, 0xf,
2293 { &hf_sigcomp_udvm_bytecode,
2294 { "Uploaded UDVM bytecode","sigcomp.udvm.byte-code",
2295 FT_NONE, BASE_NONE, NULL, 0x0,
2298 { &hf_sigcomp_udvm_instr,
2299 { "UDVM instruction code","sigcomp.udvm.instr",
2300 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &udvm_instruction_code_vals_ext, 0x0,
2303 { &hf_udvm_execution_trace,
2304 { "UDVM execution trace","sigcomp.udvm.execution-trace",
2305 FT_NONE, BASE_NONE, NULL, 0x0,
2308 { &hf_udvm_multitype_bytecode,
2309 { "UDVM bytecode", "sigcomp.udvm.multyt.bytecode",
2310 FT_UINT8, BASE_HEX, VALS(display_bytecode_vals), 0x0,
2313 { &hf_udvm_reference_bytecode,
2314 { "UDVM bytecode", "sigcomp.udvm.ref.bytecode",
2315 FT_UINT8, BASE_HEX, VALS(display_ref_bytecode_vals), 0x0,
2318 { &hf_udvm_literal_bytecode,
2319 { "UDVM bytecode", "sigcomp.udvm.lit.bytecode",
2320 FT_UINT8, BASE_HEX, VALS(display_lit_bytecode_vals), 0x0,
2325 { "UDVM operand", "sigcomp.udvm.operand",
2326 FT_UINT16, BASE_DEC, NULL, 0x0,
2331 { "%Length", "sigcomp.udvm.length",
2332 FT_UINT16, BASE_DEC, NULL, 0x0,
2335 { &hf_udvm_addr_length,
2336 { "%Length[memory address]", "sigcomp.udvm.addr.length",
2337 FT_UINT16, BASE_DEC, NULL, 0x0,
2340 { &hf_udvm_destination,
2341 { "%Destination", "sigcomp.udvm.destination",
2342 FT_UINT16, BASE_DEC, NULL, 0x0,
2343 "Destination", HFILL }
2345 { &hf_udvm_addr_destination,
2346 { "%Destination[memory address]", "sigcomp.udvm.addr.destination",
2347 FT_UINT16, BASE_DEC, NULL, 0x0,
2348 "Destination", HFILL }
2350 { &hf_udvm_at_address,
2351 { "@Address(mem_add_of_inst + D) mod 2^16)", "sigcomp.udvm.at.address",
2352 FT_UINT16, BASE_DEC, NULL, 0x0,
2356 { "%Address", "sigcomp.udvm.length",
2357 FT_UINT16, BASE_DEC, NULL, 0x0,
2360 { &hf_udvm_literal_num,
2361 { "#n", "sigcomp.udvm.literal-num",
2362 FT_UINT16, BASE_DEC, NULL, 0x0,
2363 "Literal number", HFILL }
2366 { "%Value", "sigcomp.udvm.value",
2367 FT_UINT16, BASE_DEC, NULL, 0x0,
2370 { &hf_udvm_addr_value,
2371 { "%Value[memory address]", "sigcomp.udvm.value",
2372 FT_UINT16, BASE_DEC, NULL, 0x0,
2375 { &hf_partial_identifier_start,
2376 { "%Partial identifier start", "sigcomp.udvm.partial.identifier.start",
2377 FT_UINT16, BASE_DEC, NULL, 0x0,
2378 "Partial identifier start", HFILL }
2380 { &hf_partial_identifier_length,
2381 { "%Partial identifier length", "sigcomp.udvm.partial.identifier.length",
2382 FT_UINT16, BASE_DEC, NULL, 0x0,
2383 "Partial identifier length", HFILL }
2386 { "%State begin", "sigcomp.udvm.state.begin",
2387 FT_UINT16, BASE_DEC, NULL, 0x0,
2388 "State begin", HFILL }
2390 { &hf_udvm_state_length,
2391 { "%State length", "sigcomp.udvm.state.length",
2392 FT_UINT16, BASE_DEC, NULL, 0x0,
2393 "State length", HFILL }
2396 { &hf_udvm_state_length_addr,
2397 { "%State length[memory address]", "sigcomp.udvm.state.length.addr",
2398 FT_UINT16, BASE_DEC, NULL, 0x0,
2399 "State length", HFILL }
2401 { &hf_udvm_state_address,
2402 { "%State address", "sigcomp.udvm.start.address",
2403 FT_UINT16, BASE_DEC, NULL, 0x0,
2404 "State address", HFILL }
2406 { &hf_udvm_state_address_addr,
2407 { "%State address[memory address]", "sigcomp.udvm.start.address.addr",
2408 FT_UINT16, BASE_DEC, NULL, 0x0,
2409 "State address", HFILL }
2411 { &hf_udvm_state_instr,
2412 { "%State instruction", "sigcomp.udvm.start.instr",
2413 FT_UINT16, BASE_DEC, NULL, 0x0,
2414 "State instruction", HFILL }
2416 { &hf_udvm_operand_1,
2417 { "$Operand 1[memory address]", "sigcomp.udvm.operand.1",
2418 FT_UINT16, BASE_DEC, NULL, 0x0,
2419 "Reference $ Operand 1", HFILL }
2421 { &hf_udvm_operand_2,
2422 { "%Operand 2", "sigcomp.udvm.operand.2",
2423 FT_UINT16, BASE_DEC, NULL, 0x0,
2424 "Operand 2", HFILL }
2426 { &hf_udvm_operand_2_addr,
2427 { "%Operand 2[memory address]", "sigcomp.udvm.operand.2.addr",
2428 FT_UINT16, BASE_DEC, NULL, 0x0,
2429 "Operand 2", HFILL }
2432 { "%j", "sigcomp.udvm.j",
2433 FT_UINT16, BASE_DEC, NULL, 0x0,
2437 { "%j[memory address]", "sigcomp.udvm.addr.j",
2438 FT_UINT16, BASE_DEC, NULL, 0x0,
2441 { &hf_udvm_output_start,
2442 { "%Output_start", "sigcomp.output.start",
2443 FT_UINT16, BASE_DEC, NULL, 0x0,
2444 "Output start", HFILL }
2446 { &hf_udvm_addr_output_start,
2447 { "%Output_start[memory address]", "sigcomp.addr.output.start",
2448 FT_UINT16, BASE_DEC, NULL, 0x0,
2449 "Output start", HFILL }
2451 { &hf_udvm_output_length,
2452 { "%Output_length", "sigcomp.output.length",
2453 FT_UINT16, BASE_DEC, NULL, 0x0,
2454 "Output length", HFILL }
2456 { &hf_udvm_output_length_addr,
2457 { "%Output_length[memory address]", "sigcomp.output.length.addr",
2458 FT_UINT16, BASE_DEC, NULL, 0x0,
2459 "Output length", HFILL }
2461 { &hf_udvm_req_feedback_loc,
2462 { "%Requested feedback location", "sigcomp.req.feedback.loc",
2463 FT_UINT16, BASE_DEC, NULL, 0x0,
2464 "Requested feedback location", HFILL }
2466 { &hf_udvm_min_acc_len,
2467 { "%Minimum access length", "sigcomp.min.acc.len",
2468 FT_UINT16, BASE_DEC, NULL, 0x0,
2469 "Minimum access length", HFILL }
2471 { &hf_udvm_state_ret_pri,
2472 { "%State retention priority", "sigcomp.udvm.state.ret.pri",
2473 FT_UINT16, BASE_DEC, NULL, 0x0,
2474 "State retention priority", HFILL }
2476 { &hf_udvm_ret_param_loc,
2477 { "%Returned parameters location", "sigcomp.ret.param.loc",
2478 FT_UINT16, BASE_DEC, NULL, 0x0,
2479 "Returned parameters location", HFILL }
2481 { &hf_udvm_position,
2482 { "%Position", "sigcomp.udvm.position",
2483 FT_UINT16, BASE_DEC, NULL, 0x0,
2486 { &hf_udvm_ref_dest,
2487 { "$Destination[memory address]", "sigcomp.udvm.ref.destination",
2488 FT_UINT16, BASE_DEC, NULL, 0x0,
2489 "(reference)Destination", HFILL }
2492 { "%Bits", "sigcomp.udvm.bits",
2493 FT_UINT16, BASE_DEC, NULL, 0x0,
2496 { &hf_udvm_lower_bound,
2497 { "%Lower bound", "sigcomp.udvm.lower.bound",
2498 FT_UINT16, BASE_DEC, NULL, 0x0,
2499 "Lower_bound", HFILL }
2501 { &hf_udvm_upper_bound,
2502 { "%Upper bound", "sigcomp.udvm.upper.bound",
2503 FT_UINT16, BASE_DEC, NULL, 0x0,
2504 "Upper bound", HFILL }
2506 { &hf_udvm_uncompressed,
2507 { "%Uncompressed", "sigcomp.udvm.uncompressed",
2508 FT_UINT16, BASE_DEC, NULL, 0x0,
2509 "Uncompressed", HFILL }
2511 { &hf_udvm_start_value,
2512 { "%Start value", "sigcomp.udvm.start.value",
2513 FT_UINT16, BASE_DEC, NULL, 0x0,
2514 "Start value", HFILL }
2517 { "%Offset", "sigcomp.udvm.offset",
2518 FT_UINT16, BASE_DEC, NULL, 0x0,
2521 { &hf_udvm_addr_offset,
2522 { "%Offset[memory address]", "sigcomp.udvm.addr.offset",
2523 FT_UINT16, BASE_DEC, NULL, 0x0,
2526 { &hf_sigcomp_nack_ver,
2527 { "NACK Version", "sigcomp.nack.ver",
2528 FT_UINT8, BASE_DEC, NULL, 0x0f,
2531 { &hf_sigcomp_nack_reason_code,
2532 { "Reason Code", "sigcomp.nack.reason",
2533 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &sigcomp_nack_reason_code_vals_ext, 0x0,
2534 "NACK Reason Code", HFILL }
2536 { &hf_sigcomp_nack_failed_op_code,
2537 { "OPCODE of failed instruction", "sigcomp.nack.failed_op_code",
2538 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &udvm_instruction_code_vals_ext, 0x0,
2539 "NACK OPCODE of failed instruction", HFILL }
2541 { &hf_sigcomp_nack_pc,
2542 { "PC of failed instruction", "sigcomp.nack.pc",
2543 FT_UINT16, BASE_DEC, NULL, 0x0,
2544 "NACK PC of failed instruction", HFILL }
2546 { &hf_sigcomp_nack_sha1,
2547 { "SHA-1 Hash of failed message", "sigcomp.nack.sha1",
2548 FT_BYTES, BASE_NONE, NULL, 0x0,
2549 "NACK SHA-1 Hash of failed message", HFILL }
2551 { &hf_sigcomp_nack_state_id,
2552 { "State ID (6 - 20 bytes)", "sigcomp.nack.state_id",
2553 FT_BYTES, BASE_NONE, NULL, 0x0,
2554 "NACK State ID (6 - 20 bytes)", HFILL }
2556 { &hf_sigcomp_nack_cycles_per_bit,
2557 { "Cycles Per Bit", "sigcomp.nack.cycles_per_bit",
2558 FT_UINT8, BASE_DEC, NULL, 0x0,
2559 "NACK Cycles Per Bit", HFILL }
2561 { &hf_sigcomp_nack_memory_size,
2562 { "Memory size", "sigcomp.memory_size",
2563 FT_UINT16, BASE_DEC, NULL, 0x0,
2568 /* Setup protocol subtree array */
2569 static gint *ett[] = {
2572 &ett_sigcomp_udvm_exe,
2574 static gint *ett_raw[] = {
2578 static ei_register_info ei[] = {
2579 { &ei_sigcomp_nack_failed_op_code, { "sigcomp.nack.failed_op_code.expert", PI_SEQUENCE, PI_WARN, "SigComp NACK", EXPFILL }},
2582 module_t *sigcomp_module;
2583 expert_module_t* expert_sigcomp;
2585 static const enum_val_t udvm_detail_vals[] = {
2586 {"no-printout", "No-Printout", 0},
2587 {"low-detail", "Low-detail", 1},
2588 {"medium-detail", "Medium-detail", 2},
2589 {"high-detail", "High-detail", 3},
2594 /* Register the protocol name and description */
2595 proto_sigcomp = proto_register_protocol("Signaling Compression",
2596 "SIGCOMP", "sigcomp");
2597 proto_raw_sigcomp = proto_register_protocol("Decompressed SigComp message as raw text",
2598 "Raw_SigComp", "raw_sigcomp");
2600 new_register_dissector("sigcomp", dissect_sigcomp, proto_sigcomp);
2602 /* Required function calls to register the header fields and subtrees used */
2603 proto_register_field_array(proto_sigcomp, hf, array_length(hf));
2604 proto_register_subtree_array(ett, array_length(ett));
2605 proto_register_subtree_array(ett_raw, array_length(ett_raw));
2606 expert_sigcomp = expert_register_protocol(proto_sigcomp);
2607 expert_register_field_array(expert_sigcomp, ei, array_length(ei));
2609 /* Register a configuration option for port */
2610 sigcomp_module = prefs_register_protocol(proto_sigcomp,
2611 proto_reg_handoff_sigcomp);
2613 prefs_register_uint_preference(sigcomp_module, "udp.port",
2614 "Sigcomp UDP Port 1",
2615 "Set UDP port 1 for SigComp messages",
2619 prefs_register_uint_preference(sigcomp_module, "udp.port2",
2620 "Sigcomp UDP Port 2",
2621 "Set UDP port 2 for SigComp messages",
2624 prefs_register_uint_preference(sigcomp_module, "tcp.port",
2625 "Sigcomp TCP Port 1",
2626 "Set TCP port 1 for SigComp messages",
2630 prefs_register_uint_preference(sigcomp_module, "tcp.port2",
2631 "Sigcomp TCP Port 2",
2632 "Set TCP port 2 for SigComp messages",
2635 prefs_register_bool_preference(sigcomp_module, "display.udvm.code",
2636 "Dissect the UDVM code",
2637 "Preference whether to Dissect the UDVM code or not",
2638 &dissect_udvm_code);
2640 prefs_register_bool_preference(sigcomp_module, "display.bytecode",
2641 "Display the bytecode of operands",
2642 "preference whether to display the bytecode in "
2643 "UDVM operands or not",
2644 &display_udvm_bytecode);
2645 prefs_register_bool_preference(sigcomp_module, "decomp.msg",
2646 "Decompress message",
2647 "preference whether to decompress message or not",
2649 prefs_register_bool_preference(sigcomp_module, "display.decomp.msg.as.txt",
2650 "Displays the decompressed message as text",
2651 "preference whether to display the decompressed message "
2652 "as raw text or not",
2654 prefs_register_enum_preference(sigcomp_module, "show.udvm.execution",
2655 "Level of detail of UDVM execution:",
2656 "'No-Printout' = UDVM executes silently, then increasing detail "
2657 "about execution of UDVM instructions; "
2658 "Warning! CPU intense at high detail",
2659 &udvm_print_detail_level, udvm_detail_vals, FALSE);
2661 register_init_routine(&sigcomp_init_protocol);
2668 proto_reg_handoff_sigcomp(void)
2670 static dissector_handle_t sigcomp_handle;
2671 static dissector_handle_t sigcomp_tcp_handle;
2672 static gboolean Initialized=FALSE;
2673 static guint udp_port1;
2674 static guint udp_port2;
2675 static guint tcp_port1;
2676 static guint tcp_port2;
2679 sigcomp_handle = find_dissector("sigcomp");
2680 sigcomp_tcp_handle = new_create_dissector_handle(dissect_sigcomp_tcp,proto_sigcomp);
2681 sip_handle = find_dissector("sip");
2684 dissector_delete_uint("udp.port", udp_port1, sigcomp_handle);
2685 dissector_delete_uint("udp.port", udp_port2, sigcomp_handle);
2686 dissector_delete_uint("tcp.port", tcp_port1, sigcomp_tcp_handle);
2687 dissector_delete_uint("tcp.port", tcp_port2, sigcomp_tcp_handle);
2690 udp_port1 = SigCompUDPPort1;
2691 udp_port2 = SigCompUDPPort2;
2692 tcp_port1 = SigCompTCPPort1;
2693 tcp_port2 = SigCompTCPPort2;
2696 dissector_add_uint("udp.port", SigCompUDPPort1, sigcomp_handle);
2697 dissector_add_uint("udp.port", SigCompUDPPort2, sigcomp_handle);
2698 dissector_add_uint("tcp.port", SigCompTCPPort1, sigcomp_tcp_handle);
2699 dissector_add_uint("tcp.port", SigCompTCPPort2, sigcomp_tcp_handle);
2704 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2709 * indent-tabs-mode: nil
2712 * vi: set shiftwidth=4 tabstop=8 expandtab:
2713 * :indentSize=4:tabSize=8:noTabs=true: