bytes_to_ep_str -> bytes_to_str
[metze/wireshark/wip.git] / epan / dissectors / packet-sigcomp.c
1 /* packet-sigcomp.c
2  * Routines for Signaling Compression (SigComp) dissection.
3  * Copyright 2004-2005, Anders Broman <anders.broman@ericsson.com>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
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.
13  *
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.
18  *
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.
22  * References:
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
26  * Useful links :
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
29  */
30
31 #include "config.h"
32
33 #include <math.h>
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>
40
41 void proto_register_sigcomp(void);
42 void proto_reg_handoff_sigcomp(void);
43
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;
110
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;
116
117 static expert_field ei_sigcomp_nack_failed_op_code = EI_INIT;
118
119 static dissector_handle_t sip_handle;
120 /* set the udp ports */
121 static guint SigCompUDPPort1 = 5555;
122 static guint SigCompUDPPort2 = 6666;
123
124 /* set the tcp ports */
125 static guint SigCompTCPPort1 = 5555;
126 static guint SigCompTCPPort2 = 6666;
127
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
136  * 0 = No printout
137  * 1 = details level 1
138  * 2 = details level 2
139  * 3 = details level 3
140  * 4 = details level 4
141  */
142 static gint udvm_print_detail_level = 0;
143
144 /* Value strings */
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)" },
150     { 0,    NULL }
151 };
152
153
154 static const value_string destination_address_encoding_vals[] = {
155     { 0x00, "Reserved" },
156     { 0x01, "128" },
157     { 0x02, "192" },
158     { 0x03, "256" },
159     { 0x04, "320" },
160     { 0x05, "384" },
161     { 0x06, "448" },
162     { 0x07, "512" },
163     { 0x08, "576" },
164     { 0x09, "640" },
165     { 0x0a, "704" },
166     { 0x0b, "768" },
167     { 0x0c, "832" },
168     { 0x0d, "896" },
169     { 0x0e, "960" },
170     { 0x0F, "1024" },
171     { 0,    NULL }
172 };
173 static value_string_ext destination_address_encoding_vals_ext =
174     VALUE_STRING_EXT_INIT(destination_address_encoding_vals);
175
176 static const value_string udvm_instruction_code_vals[] = {
177     {  0,   "DECOMPRESSION-FAILURE" },
178     {  1,   "AND" },
179     {  2,   "OR" },
180     {  3,   "NOT" },
181     {  4,   "LSHIFT" },
182     {  5,   "RSHIFT" },
183     {  6,   "ADD" },
184     {  7,   "SUBTRACT" },
185     {  8,   "MULTIPLY" },
186     {  9,   "DIVIDE" },
187     { 10,   "REMAINDER" },
188     { 11,   "SORT-ASCENDING" },
189     { 12,   "SORT-DESCENDING" },
190     { 13,   "SHA-1" },
191     { 14,   "LOAD" },
192     { 15,   "MULTILOAD" },
193     { 16,   "PUSH" },
194     { 17,   "POP" },
195     { 18,   "COPY" },
196     { 19,   "COPY-LITERAL" },
197     { 20,   "COPY-OFFSET" },
198     { 21,   "MEMSET" },
199     { 22,   "JUMP" },
200     { 23,   "COMPARE" },
201     { 24,   "CALL" },
202     { 25,   "RETURN" },
203     { 26,   "SWITCH" },
204     { 27,   "CRC" },
205     { 28,   "INPUT-BYTES" },
206     { 29,   "INPUT-BITS" },
207     { 30,   "INPUT-HUFFMAN" },
208     { 31,   "STATE-ACCESS" },
209     { 32,   "STATE-CREATE" },
210     { 33,   "STATE-FREE" },
211     { 34,   "OUTPUT" },
212     { 35,   "END-MESSAGE" },
213     { 0,    NULL }
214 };
215 static value_string_ext udvm_instruction_code_vals_ext =
216     VALUE_STRING_EXT_INIT(udvm_instruction_code_vals);
217
218     /* RFC3320
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
231      */
232
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" },
244     { 0,    NULL }
245 };
246 /* RFC3320
247  * 0nnnnnnn                        memory[2 * N]       0 - 65535
248  * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
249  * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
250  */
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" },
255     { 0,    NULL }
256 };
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:
261   * 0nnnnnnn                        N                   0 - 127
262   * 10nnnnnn nnnnnnnn               N                   0 - 16383
263   * 11000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
264   *
265   *            Figure 8: Bytecode for a literal (#) operand
266   *
267   */
268
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" },
273     { 0,    NULL }
274 };
275
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
281
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" },
286     {  4,   "SEGFAULT" },
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" },
308     { 0,    NULL }
309 };
310 static value_string_ext sigcomp_nack_reason_code_vals_ext =
311     VALUE_STRING_EXT_INIT(sigcomp_nack_reason_code_vals);
312
313
314 static void dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, guint destination);
315
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 );
319
320 static int dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
321                                gint offset, gint *start_offset, guint16 *value);
322
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);
326
327 static int dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
328
329 static proto_tree *top_tree;
330
331 /* Initialize the state handler
332  *
333  */
334 static void
335 sigcomp_init_protocol(void)
336 {
337     sigcomp_init_udvm();
338 }
339 /* Sigcomp over TCP record marking used
340  * RFC 3320
341  * 4.2.2.  Record Marking
342  *
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:
347  *
348  *   0xFF 00                    one 0xFF byte in the data stream
349  *   0xFF 01                    same, but the next byte is quoted (could
350  *                              be another 0xFF)
351  *      :                                           :
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
355  *   :
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
359  *   this case.
360  */
361
362 /*
363  * TODO: Reassembly, handle more than one message in a tcp segment.
364  */
365
366 static int
367 dissect_sigcomp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *_data _U_)
368 {
369     proto_item  *ti;
370     proto_tree  *sigcomp_tree;
371     tvbuff_t    *unescaped_tvb;
372
373     guint8      *buff;
374     int         offset = 0;
375     int         length;
376     guint8      octet;
377     guint16     data;
378     int         i;
379     int         n;
380     gboolean    end_off_message;
381
382     top_tree = tree;
383
384     /* Is this SIGCOMP ? */
385     data = tvb_get_ntohs(tvb, offset);
386     if(data == 0xffff){
387         /* delimiter */
388         offset = offset + 2;
389         octet = tvb_get_guint8(tvb,offset);
390     }else{
391         octet = tvb_get_guint8(tvb,offset);
392     }
393     if ((octet  & 0xf8) != 0xf8)
394      return offset;
395
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;
402     }
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;
411             return -1;
412         }
413     }
414
415     /* Make entries in Protocol column and Info column on summary display */
416     col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
417
418     col_clear(pinfo->cinfo, COL_INFO);
419
420     length = tvb_length_remaining(tvb,offset);
421
422 try_again:
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);
426     i=0;
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 */
436                 offset++;
437                 continue;
438             }
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);
443             if ( octet == 0){
444                 buff[i] = 0xff;
445                 offset = offset +2;
446                 i++;
447                 continue;
448             }
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);
454                 return offset;
455             }
456             if ( octet == 0xff){
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;
461                 offset = offset+2;
462                 continue;
463             }
464             buff[i] = 0xff;
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]);
468             i++;
469             offset = offset+2;
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]);
481                 i++;
482                 offset++;
483             }
484             continue;
485         }
486         buff[i] = octet;
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]);
490
491         i++;
492         offset++;
493     }
494     unescaped_tvb = tvb_new_child_real_data(tvb, buff,i,i);
495
496     add_new_data_source(pinfo, unescaped_tvb, "Unescaped Data handed to the SigComp dissector");
497
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);
501     }else{
502         proto_tree_add_text(sigcomp_tree, unescaped_tvb, 0, -1,"TCP Fragment, no end mark found");
503     }
504     if ( offset < length){
505         goto try_again;
506     }
507
508     return offset;
509 }
510 /* Code to actually dissect the packets */
511 static int
512 dissect_sigcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
513 {
514     proto_item  *ti;
515     proto_tree  *sigcomp_tree;
516     gint        offset = 0;
517     gint8       octet;
518
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);
522
523     /* Is this a SigComp message or not ? */
524     octet = tvb_get_guint8(tvb, offset);
525     if ((octet  & 0xf8) != 0xf8)
526      return 0;
527
528     /* Make entries in Protocol column and Info column on summary display */
529     col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
530
531     col_clear(pinfo->cinfo, COL_INFO);
532
533     top_tree = tree;
534
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);
538
539     return dissect_sigcomp_common(tvb, pinfo, sigcomp_tree);
540 }
541 /* Code to actually dissect the packets */
542 static int
543 dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sigcomp_tree)
544 {
545
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;
551     gint        offset = 0;
552     gint        bytecode_offset;
553     guint16     partial_state_len;
554     guint       octet;
555     guint8      returned_feedback_field[128];
556     guint8      partial_state[12];
557     guint       tbit;
558     guint16     len = 0;
559     guint16     bytecode_len = 0;
560     guint       destination;
561     gint        msg_len = 0;
562     guint8      *buff;
563     guint16     p_id_start;
564     guint8      i;
565     guint16     state_begin;
566     guint16     state_length;
567     guint16     state_address;
568     guint16     state_instruction;
569     guint16     result_code;
570     gchar       *partial_state_str;
571     guint8      nack_version;
572
573
574
575 /* add an item to the subtree, see section 1.6 for more information */
576     octet = tvb_get_guint8(tvb, offset);
577
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.)
582  *
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  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
587  * |                               |   |                               |
588  * :    returned feedback item     :   :    returned feedback item     :
589  * |                               |   |                               |
590  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
591  * |                               |   |           code_len            |
592  * :   partial state identifier    :   +---+---+---+---+---+---+---+---+
593  *
594  * |                               |   |   code_len    |  destination  |
595  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
596  * |                               |   |                               |
597  * :   remaining SigComp message   :   :    uploaded UDVM bytecode     :
598  * |                               |   |                               |
599  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
600  *                                     |                               |
601  *                                     :   remaining SigComp message   :
602  *                                     |                               |
603  *                                     +---+---+---+---+---+---+---+---+
604  *
605  * RFC 4077:
606  * The format of the NACK message and the use of the fields within it
607  * are shown in Figure 1.
608  *
609  *                     0   1   2   3   4   5   6   7
610  *                  +---+---+---+---+---+---+---+---+
611  *                  | 1   1   1   1   1 | T |   0   |
612  *                  +---+---+---+---+---+---+---+---+
613  *                  |                               |
614  *                  :    returned feedback item     :
615  *                  |                               |
616  *                  +---+---+---+---+---+---+---+---+
617  *                  |         code_len = 0          |
618  *                  +---+---+---+---+---+---+---+---+
619  *                  | code_len = 0  |  version = 1  |
620  *                  +---+---+---+---+---+---+---+---+
621  *                  |          Reason Code          |
622  *                  +---+---+---+---+---+---+---+---+
623  *                  |  OPCODE of failed instruction |
624  *                  +---+---+---+---+---+---+---+---+
625  *                  |   PC of failed instruction    |
626  *                  |                               |
627  *                  +---+---+---+---+---+---+---+---+
628  *                  |                               |
629  *                  : SHA-1 Hash of failed message  :
630  *                  |                               |
631  *                  +---+---+---+---+---+---+---+---+
632  *                  |                               |
633  *                  :         Error Details         :
634  *                  |                               |
635  *                  +---+---+---+---+---+---+---+---+
636  *                  Figure 1: SigComp NACK Message Format
637  */
638
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;
643     offset ++;
644     if ( partial_state_len != 0 ){
645         /*
646          * The len field encodes the number of transmitted bytes as follows:
647          *
648          *   Encoding:   Length of partial state identifier
649          *
650          *   01          6 bytes
651          *   10          9 bytes
652          *   11          12 bytes
653          *
654          */
655         partial_state_len = partial_state_len * 3 + 3;
656
657         /*
658          * Message format 1
659          */
660         col_set_str(pinfo->cinfo, COL_INFO, "Msg format 1");
661
662         if ( tbit == 1 ) {
663             /*
664              * Returned feedback item exists
665              */
666             len = 1;
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              * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
672              *                                     |                               |
673              *                                     :    returned_feedback_field    :
674              *                                     |                               |
675              *                                     +---+---+---+---+---+---+---+---+
676              * Figure 4: Format of returned feedback item
677              */
678
679             if ( (octet & 0x80) != 0 ){
680                 len = octet & 0x7f;
681                 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
682                                     tvb, offset, 1, ENC_BIG_ENDIAN);
683                 offset ++;
684                 tvb_memcpy(tvb,returned_feedback_field,offset, len);
685             } else {
686                 returned_feedback_field[0] = tvb_get_guint8(tvb, offset) & 0x7f;
687             }
688             proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
689                                  tvb, offset, len, returned_feedback_field);
690             offset = offset + len;
691         }
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);
698
699         if(msg_len>0){
700             proto_item *ti;
701             ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_remaining_message_bytes, tvb,
702                                      offset, 0, msg_len);
703             PROTO_ITEM_SET_GENERATED(ti);
704         }
705
706         if ( decompress ) {
707             msg_tvb = tvb_new_subset_length(tvb, offset, msg_len);
708             /*
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
717              */
718             /*
719              * Note: The allocated buffer must be zeroed or some strange effects might occur.
720              */
721             buff = (guint8 *)wmem_alloc0(pinfo->pool, UDVM_MEMORY_SIZE);
722
723
724             p_id_start = 0;
725             state_begin = 0;
726             /* These values will be loaded from the buffered state in sigcomp_state_hdlr
727              */
728             state_length = 0;
729             state_address = 0;
730             state_instruction =0;
731
732             i = 0;
733             while ( i < partial_state_len ){
734                 buff[i] = partial_state[i];
735                 i++;
736             }
737
738 /* begin partial state-id change cco@iptel.org */
739 #if 0
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);
742 #endif
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);
745
746 /* end partial state-id change cco@iptel.org */
747             if ( result_code != 0 ){
748                 proto_item *ti;
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);
753             }
754
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");
757
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,
761                                                 ENC_NA);
762             sigcomp_udvm_exe_tree = proto_item_add_subtree( udvm_exe_item, ett_sigcomp_udvm_exe);
763
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);
768
769
770             if ( decomp_tvb ){
771                 proto_item *ti;
772                 guint32 compression_ratio =
773                     (guint32)(((float)tvb_length(decomp_tvb) / (float)tvb_length(tvb)) * 100);
774
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);
780
781                 if ( display_raw_txt )
782                     tvb_raw_text_add(decomp_tvb, top_tree);
783
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);
787             }
788         }/* if decompress */
789
790     }
791     else{
792         /*
793          * Message format 2
794          */
795     col_set_str(pinfo->cinfo, COL_INFO, "Msg format 2");
796         if ( tbit == 1 ) {
797             /*
798              * Returned feedback item exists
799              */
800             len = 1;
801             octet = tvb_get_guint8(tvb, offset);
802             if ( (octet & 0x80) != 0 ){
803                 len = octet & 0x7f;
804                 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
805                                     tvb, offset, 1, ENC_BIG_ENDIAN);
806                 offset ++;
807             }
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;
812         }
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)){
816             /* NACK MESSAGE */
817             proto_item *reason_ti;
818             guint8 opcode;
819             offset++;
820             proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
821             offset++;
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);
824             offset++;
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);
827             offset++;
828
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"));
834
835             proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_pc, tvb, offset, 2, ENC_BIG_ENDIAN);
836             offset = offset +2;
837             proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_sha1, tvb, offset, 20, ENC_NA);
838             offset = offset +20;
839
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"));
844
845             switch ( octet){
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);
851                 break;
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);
855                 break;
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);
859                 break;
860             default:
861                 break;
862             }
863         }else{
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);
870             offset = offset +2;
871
872             bytecode_len = len;
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);
879
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);
883
884             offset = offset + len;
885             msg_len = tvb_reported_length_remaining(tvb, offset);
886             if (msg_len>0) {
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);
891             }
892             if ( decompress ){
893
894                 msg_tvb = tvb_new_subset_length(tvb, offset, msg_len);
895
896                 udvm_exe_item = proto_tree_add_item(sigcomp_tree, hf_udvm_execution_trace,
897                                                     tvb, bytecode_offset, bytecode_len,
898                                                     ENC_NA);
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);
904                 if ( decomp_tvb ){
905                     proto_item *ti;
906                     guint32 compression_ratio =
907                         (guint32)(((float)tvb_length(decomp_tvb) / (float)tvb_length(tvb)) * 100);
908
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);
914
915                     if ( display_raw_txt )
916                         tvb_raw_text_add(decomp_tvb, top_tree);
917
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);
921                 }
922             } /* if decompress */
923         }/*if len==0 */
924
925     }
926     return tvb_length(tvb);
927 }
928
929
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
966
967
968 static void
969 dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,guint start_address)
970 {
971     guint instruction;
972     gint offset = 0;
973     gint start_offset = 0;
974     gint len;
975     gint n;
976     guint instruction_no = 0;
977     guint16 value = 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);
982
983
984     while (msg_length > offset) {
985         instruction = tvb_get_guint8(udvm_tvb, offset);
986         instruction_no ++;
987         UDVM_address = start_address + offset;
988 ;
989
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);
995         offset ++;
996         switch ( instruction ) {
997
998         case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */
999             /* $operand_1*/
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);
1004             /* %operand_2*/
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);
1010             }else{
1011                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1012                     udvm_tvb, start_offset, len, value);
1013             }
1014             break;
1015
1016         case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */
1017             /* $operand_1*/
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);
1022             /* %operand_2*/
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);
1028             }else{
1029                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1030                     udvm_tvb, start_offset, len, value);
1031             }
1032             break;
1033
1034         case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */
1035             /* $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);
1040             break;
1041
1042         case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */
1043             /* $operand_1*/
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);
1048             /* %operand_2*/
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);
1054             }else{
1055                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1056                     udvm_tvb, start_offset, len, value);
1057             }
1058             break;
1059
1060         case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */
1061             /* $operand_1*/
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);
1066             /* %operand_2*/
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);
1072             }else{
1073                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1074                     udvm_tvb, start_offset, len, value);
1075             }
1076             break;
1077
1078         case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */
1079             /* $operand_1*/
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);
1084             /* %operand_2*/
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);
1090             }else{
1091                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1092                     udvm_tvb, start_offset, len, value);
1093             }
1094             break;
1095
1096         case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */
1097             /* $operand_1*/
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);
1102             /* %operand_2*/
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);
1108             }else{
1109                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1110                     udvm_tvb, start_offset, len, value);
1111             }
1112             break;
1113
1114         case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */
1115             /* $operand_1*/
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);
1120             /* %operand_2*/
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);
1126             }else{
1127                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1128                     udvm_tvb, start_offset, len, value);
1129             }
1130             break;
1131
1132         case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */
1133             /* $operand_1*/
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);
1138             /* %operand_2*/
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);
1144             }else{
1145                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1146                     udvm_tvb, start_offset, len, value);
1147             }
1148             break;
1149
1150         case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */
1151             /* $operand_1*/
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);
1156             /* %operand_2*/
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);
1162             }else{
1163                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1164                     udvm_tvb, start_offset, len, value);
1165             }
1166             break;
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);
1170             break;
1171
1172         case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */
1173             offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1174             break;
1175         case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */
1176             /* %position */
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);
1181
1182             /*  %length, */
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);
1188             }else{
1189                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1190                     udvm_tvb, start_offset, len, value);
1191             }
1192
1193             /* $destination */
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);
1198             break;
1199
1200         case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */
1201             /* %address */
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);
1206             /* %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);
1212             }else{
1213                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1214                     udvm_tvb, start_offset, len, value);
1215             }
1216             break;
1217
1218         case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
1219             /* %address */
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);
1224             /* #n */
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);
1229             n = value;
1230             while ( n > 0) {
1231                 n = n -1;
1232                 /* %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);
1238                 }else{
1239                     proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1240                         udvm_tvb, start_offset, len, value);
1241                 }
1242             }
1243             break;
1244
1245         case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */
1246             /* %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);
1252             }else{
1253                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1254                     udvm_tvb, start_offset, len, value);
1255             }
1256             break;
1257
1258         case SIGCOMP_INSTR_POP: /* 17 POP (%address) */
1259             /* %address */
1260             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1261
1262             len = offset - start_offset;
1263             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1264                 udvm_tvb, start_offset, len, value);
1265             break;
1266
1267         case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */
1268             /* %position */
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);
1273
1274             /*  %length, */
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);
1280             }else{
1281                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1282                     udvm_tvb, start_offset, len, value);
1283             }
1284
1285             /* $destination */
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);
1290             break;
1291
1292         case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */
1293             /* %position */
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);
1298
1299             /*  %length, */
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);
1305             }else{
1306                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1307                     udvm_tvb, start_offset, len, value);
1308             }
1309
1310             /* $destination */
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);
1315             break;
1316
1317         case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */
1318             /* %offset */
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);
1324             }else{
1325                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
1326                     udvm_tvb, start_offset, len, value);
1327             }
1328
1329             /*  %length, */
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);
1335             }else{
1336                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1337                     udvm_tvb, start_offset, len, value);
1338             }
1339
1340             /* $destination */
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);
1345             break;
1346         case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */
1347
1348             /* %address */
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);
1353
1354             /*  %length, */
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);
1360             }else{
1361                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1362                     udvm_tvb, start_offset, len, value);
1363             }
1364
1365             /* %start_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);
1370
1371             /* %offset */
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);
1376             break;
1377
1378
1379         case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */
1380             /* @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);
1387             break;
1388
1389         case SIGCOMP_INSTR_COMPARE: /* 23 */
1390             /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
1391              */
1392             /* %value_1 */
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);
1398             }else{
1399                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1400                     udvm_tvb, start_offset, len, value);
1401             }
1402
1403             /* %value_2 */
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);
1409             }else{
1410                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1411                     udvm_tvb, start_offset, len, value);
1412             }
1413
1414             /* @address_1 */
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);
1421
1422             /* @address_2 */
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);
1429
1430             /* @address_3 */
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);
1437             break;
1438
1439         case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/
1440             /* @address */
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);
1447             break;
1448         case SIGCOMP_INSTR_RETURN: /* 25 POP and return */
1449
1450         break;
1451
1452         case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
1453             /* #n */
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);
1458
1459             /* Number of addresses in the instruction */
1460             n = value;
1461             /* %j */
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);
1467             }else{
1468                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_j,
1469                     udvm_tvb, start_offset, len, value);
1470             }
1471
1472             while ( n > 0) {
1473                 n = n -1;
1474                 /* @address_n-1 */
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);
1481             }
1482             break;
1483         case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */
1484             /* %value */
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);
1490             }else{
1491                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1492                     udvm_tvb, start_offset, len, value);
1493             }
1494
1495             /* %position */
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);
1500
1501             /* %length */
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);
1507             }else{
1508                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1509                     udvm_tvb, start_offset, len, value);
1510             }
1511
1512             /* @address */
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);
1519             break;
1520
1521
1522         case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */
1523             /* %length */
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);
1529             }else{
1530                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1531                     udvm_tvb, start_offset, len, value);
1532             }
1533
1534             /* %destination */
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);
1540             }else{
1541                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1542                     udvm_tvb, start_offset, len, value);
1543             }
1544
1545             /* @address */
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);
1552             break;
1553         case SIGCOMP_INSTR_INPUT_BITS:/* 29   INPUT-BITS (%length, %destination, @address) */
1554             /* %length */
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);
1560             }else{
1561                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1562                     udvm_tvb, start_offset, len, value);
1563             }
1564
1565             /* %destination */
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);
1571             }else{
1572                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1573                     udvm_tvb, start_offset, len, value);
1574             }
1575
1576             /* @address */
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);
1583             break;
1584         case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */
1585             /*
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)
1589              */
1590             /* %destination */
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);
1596             }else{
1597                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1598                     udvm_tvb, start_offset, len, value);
1599             }
1600             /* @address */
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);
1607             /* #n */
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);
1612             n = value;
1613             while ( n > 0) {
1614                 n = n -1;
1615                 /* %bits_n */
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);
1620                 /* %lower_bound_n*/
1621                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1622                 len = offset - start_offset;
1623                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_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);
1635             }
1636             break;
1637
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)
1641              */
1642
1643             /*
1644              * %partial_identifier_start
1645              */
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);
1650
1651             /*
1652              * %partial_identifier_length
1653              */
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);
1658             /*
1659              * %state_begin
1660              */
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);
1665
1666             /*
1667              * %state_length
1668              */
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);
1674             }else{
1675                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1676                     udvm_tvb, start_offset, len, value);
1677             }
1678             /*
1679              * %state_address
1680              */
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);
1686             }else{
1687                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1688                     udvm_tvb, start_offset, len, value);
1689             }
1690             /*
1691              * %state_instruction
1692              */
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);
1697             break;
1698         case SIGCOMP_INSTR_STATE_CREATE: /* 32 */
1699             /*
1700              * STATE-CREATE (%state_length, %state_address, %state_instruction,
1701              * %minimum_access_length, %state_retention_priority)
1702              */
1703
1704             /*
1705              * %state_length
1706              */
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);
1712             }else{
1713                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1714                     udvm_tvb, start_offset, len, value);
1715             }
1716             /*
1717              * %state_address
1718              */
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);
1724             }else{
1725                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1726                     udvm_tvb, start_offset, len, value);
1727             }
1728             /*
1729              * %state_instruction
1730              */
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);
1735             /*
1736              * %minimum_access_length
1737              */
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);
1742             /*
1743              * %state_retention_priority
1744              */
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);
1749
1750             break;
1751         case SIGCOMP_INSTR_STATE_FREE: /* 33 */
1752             /*
1753              * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
1754              */
1755             /*
1756              * %partial_identifier_start
1757              */
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);
1762
1763             /*
1764              * %partial_identifier_length
1765              */
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);
1770             break;
1771         case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */
1772             /*
1773              * %output_start
1774              */
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);
1780             }else{
1781                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start,
1782                     udvm_tvb, start_offset, len, value);
1783             }
1784             /*
1785              * %output_length
1786              */
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);
1792             }else{
1793                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length,
1794                     udvm_tvb, start_offset, len, value);
1795             }
1796             break;
1797         case SIGCOMP_INSTR_END_MESSAGE: /* 35 */
1798             /*
1799              * END-MESSAGE (%requested_feedback_location,
1800              * %returned_parameters_location, %state_length, %state_address,
1801              * %state_instruction, %minimum_access_length,
1802              * %state_retention_priority)
1803              */
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);
1809                 return;
1810             }
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);
1820                 return;
1821             }
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);
1826             /*
1827              * %state_length
1828              */
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);
1834             }else{
1835                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1836                     udvm_tvb, start_offset, len, value);
1837             }
1838             /*
1839              * %state_address
1840              */
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);
1846             }else{
1847                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1848                     udvm_tvb, start_offset, len, value);
1849             }
1850             /*
1851              * %state_instruction
1852              */
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);
1857             /*
1858              * %minimum_access_length
1859              */
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);
1864             /*
1865              * %state_retention_priority
1866              */
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);
1872             }else{
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);
1876             }
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);
1882             }
1883             offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1884             break;
1885
1886         default:
1887             offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1888             break;
1889         }
1890
1891
1892     }
1893     return;
1894 }
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
1902   *
1903   *            Figure 8: Bytecode for a literal (#) operand
1904   *
1905   */
1906 static int
1907 dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1908                                gint offset, gint *start_offset, guint16 *value)
1909 {
1910     guint bytecode;
1911     guint16 operand;
1912     guint test_bits;
1913     guint display_bytecode;
1914
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){
1920             /*
1921              * 10nnnnnn nnnnnnnn               N                   0 - 16383
1922              */
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;
1928             *value = operand;
1929             *start_offset = offset;
1930             offset = offset + 2;
1931
1932         }else{
1933             /*
1934              * 111000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
1935              */
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);
1940             offset ++;
1941             operand = tvb_get_ntohs(udvm_tvb, offset);
1942             *value = operand;
1943             *start_offset = offset;
1944             offset = offset + 2;
1945
1946         }
1947     }else{
1948         /*
1949          * 0nnnnnnn                        N                   0 - 127
1950          */
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);
1956         *value = operand;
1957         *start_offset = offset;
1958         offset ++;
1959     }
1960
1961     return offset;
1962
1963 }
1964 /*
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:
1971  *
1972  * 0nnnnnnn                        memory[2 * N]       0 - 65535
1973  * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
1974  * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
1975  *
1976  *            Figure 9: Bytecode for a reference ($) operand
1977  */
1978 static int
1979 dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1980                                gint offset, gint *start_offset, guint16 *value)
1981 {
1982     guint bytecode;
1983     guint16 operand;
1984     guint test_bits;
1985     guint display_bytecode;
1986
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){
1992             /*
1993              * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
1994              */
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;
2003
2004         }else{
2005             /*
2006              * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
2007              */
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);
2012             offset ++;
2013             operand = tvb_get_ntohs(udvm_tvb, offset);
2014             *value = operand;
2015             *start_offset = offset;
2016             offset = offset + 2;
2017
2018         }
2019     }else{
2020         /*
2021          * 0nnnnnnn                        memory[2 * N]       0 - 65535
2022          */
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;
2030         offset ++;
2031     }
2032
2033     return offset;
2034 }
2035
2036 /*
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:
2043  *
2044  * operand_value = (is_memory_address_of_instruction + D) modulo 2^16
2045  * TODO calculate correct value for operand in case of ADDR
2046  */
2047 static int
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 )
2050 {
2051     guint bytecode;
2052     guint display_bytecode;
2053     guint16 operand;
2054     guint32 result;
2055     guint test_bits;
2056     /* RFC3320
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
2069      */
2070     *is_memory_address = FALSE;
2071     bytecode = tvb_get_guint8(udvm_tvb, offset);
2072     test_bits = ( bytecode & 0xc0 ) >> 6;
2073     switch (test_bits ){
2074     case 0:
2075         /*
2076          * 00nnnnnn                        N                   0 - 63
2077          */
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);
2083         *value = operand;
2084         *start_offset = offset;
2085         offset ++;
2086         break;
2087     case 1:
2088         /*
2089          * 01nnnnnn                        memory[2 * N]       0 - 65535
2090          */
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;
2097         *value = operand;
2098         *start_offset = offset;
2099         offset ++;
2100         break;
2101     case 2:
2102         /* Check tree most significant bits */
2103         test_bits = ( bytecode & 0xe0 ) >> 5;
2104         if ( test_bits == 5 ){
2105         /*
2106          * 101nnnnn nnnnnnnn               N                   0 - 8191
2107          */
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;
2113             *value = operand;
2114             *start_offset = offset;
2115             offset = offset + 2;
2116         }else{
2117             test_bits = ( bytecode & 0xf0 ) >> 4;
2118             if ( test_bits == 9 ){
2119         /*
2120          * 1001nnnn nnnnnnnn               N + 61440       61440 - 65535
2121          */
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;
2128                 *value = operand;
2129                 offset = offset + 2;
2130             }else{
2131                 test_bits = ( bytecode & 0x08 ) >> 3;
2132                 if ( test_bits == 1){
2133         /*
2134          * 10001nnn                        2 ^ (N + 8)    256 , ... , 32768
2135          */
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;
2143                     *value = operand;
2144                     offset ++;
2145                 }else{
2146                     test_bits = ( bytecode & 0x0e ) >> 1;
2147                     if ( test_bits == 3 ){
2148                         /*
2149                          * 1000 011n                        2 ^ (N + 6)        64 , 128
2150                          */
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;
2158                         *value = operand;
2159                         offset ++;
2160                     }else{
2161                     /*
2162                      * 1000 0000 nnnnnnnn nnnnnnnn      N                   0 - 65535
2163                      * 1000 0001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
2164                      */
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;
2171                         offset ++;
2172                         operand = tvb_get_ntohs(udvm_tvb, offset);
2173                         *value = operand;
2174                         *start_offset = offset;
2175                         offset = offset +2;
2176                     }
2177
2178
2179                 }
2180             }
2181         }
2182         break;
2183
2184     case 3:
2185         test_bits = ( bytecode & 0x20 ) >> 5;
2186         if ( test_bits == 1 ){
2187         /*
2188          * 111nnnnn                        N + 65504       65504 - 65535
2189          */
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;
2196             *value = operand;
2197             offset ++;
2198         }else{
2199         /*
2200          * 110nnnnn nnnnnnnn               memory[N]           0 - 65535
2201          */
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;
2209             *value = operand;
2210             offset = offset +2;
2211         }
2212
2213     default :
2214         break;
2215     }
2216     return offset;
2217 }
2218
2219 static void
2220 tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree)
2221 {
2222     proto_tree *raw_tree = NULL;
2223     proto_item *ti = NULL;
2224     int offset, next_offset, linelen;
2225
2226     if(tree) {
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);
2229     }
2230
2231     offset = 0;
2232
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;
2238     }
2239 }
2240
2241 /* Register the protocol with Wireshark */
2242
2243 void
2244 proto_register_sigcomp(void)
2245 {
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 }
2252         },
2253         { &hf_sigcomp_len,
2254             { "Partial state id length","sigcomp.length",
2255             FT_UINT8, BASE_HEX, VALS(length_encoding_vals), 0x03,
2256             "Sigcomp length", HFILL }
2257         },
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 }
2262         },
2263         { &hf_sigcomp_partial_state,
2264             { "Partial state identifier", "sigcomp.partial.state.identifier",
2265             FT_STRING, BASE_NONE, NULL, 0x0,
2266             NULL, HFILL }
2267         },
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 }
2272         },
2273         { &hf_sigcomp_compression_ratio,
2274             { "Compression ratio (%)", "sigcomp.compression-ratio",
2275             FT_UINT32, BASE_DEC, NULL, 0x0,
2276             "Compression ratio (decompressed / compressed) %", HFILL }
2277         },
2278         { &hf_sigcomp_returned_feedback_item_len,
2279             { "Returned feedback item length", "sigcomp.returned.feedback.item.len",
2280             FT_UINT8, BASE_DEC, NULL, 0x7f,
2281             NULL, HFILL }
2282         },
2283         { &hf_sigcomp_code_len,
2284             { "Code length","sigcomp.code.len",
2285             FT_UINT16, BASE_HEX, NULL, 0xfff0,
2286             NULL, HFILL }
2287         },
2288         { &hf_sigcomp_destination,
2289             { "Destination","sigcomp.destination",
2290             FT_UINT8, BASE_HEX | BASE_EXT_STRING, &destination_address_encoding_vals_ext, 0xf,
2291             NULL, HFILL }
2292         },
2293         { &hf_sigcomp_udvm_bytecode,
2294             { "Uploaded UDVM bytecode","sigcomp.udvm.byte-code",
2295             FT_NONE, BASE_NONE, NULL, 0x0,
2296             NULL, HFILL }
2297         },
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,
2301             NULL, HFILL }
2302         },
2303         { &hf_udvm_execution_trace,
2304             { "UDVM execution trace","sigcomp.udvm.execution-trace",
2305             FT_NONE, BASE_NONE, NULL, 0x0,
2306             NULL, HFILL }
2307         },
2308         { &hf_udvm_multitype_bytecode,
2309             { "UDVM bytecode", "sigcomp.udvm.multyt.bytecode",
2310             FT_UINT8, BASE_HEX, VALS(display_bytecode_vals), 0x0,
2311             NULL, HFILL }
2312         },
2313         { &hf_udvm_reference_bytecode,
2314             { "UDVM bytecode", "sigcomp.udvm.ref.bytecode",
2315             FT_UINT8, BASE_HEX, VALS(display_ref_bytecode_vals), 0x0,
2316             NULL, HFILL }
2317         },
2318         { &hf_udvm_literal_bytecode,
2319             { "UDVM bytecode", "sigcomp.udvm.lit.bytecode",
2320             FT_UINT8, BASE_HEX, VALS(display_lit_bytecode_vals), 0x0,
2321             NULL, HFILL }
2322         },
2323 #if 0
2324         { &hf_udvm_operand,
2325             { "UDVM operand", "sigcomp.udvm.operand",
2326             FT_UINT16, BASE_DEC, NULL, 0x0,
2327             NULL, HFILL }
2328         },
2329 #endif
2330         { &hf_udvm_length,
2331             { "%Length", "sigcomp.udvm.length",
2332             FT_UINT16, BASE_DEC, NULL, 0x0,
2333             "Length", HFILL }
2334         },
2335         { &hf_udvm_addr_length,
2336             { "%Length[memory address]", "sigcomp.udvm.addr.length",
2337             FT_UINT16, BASE_DEC, NULL, 0x0,
2338             "Length", HFILL }
2339         },
2340         { &hf_udvm_destination,
2341             { "%Destination", "sigcomp.udvm.destination",
2342             FT_UINT16, BASE_DEC, NULL, 0x0,
2343             "Destination", HFILL }
2344         },
2345         { &hf_udvm_addr_destination,
2346             { "%Destination[memory address]", "sigcomp.udvm.addr.destination",
2347             FT_UINT16, BASE_DEC, NULL, 0x0,
2348             "Destination", HFILL }
2349         },
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,
2353             "Address", HFILL }
2354         },
2355         { &hf_udvm_address,
2356             { "%Address", "sigcomp.udvm.length",
2357             FT_UINT16, BASE_DEC, NULL, 0x0,
2358             "Address", HFILL }
2359         },
2360         { &hf_udvm_literal_num,
2361             { "#n", "sigcomp.udvm.literal-num",
2362             FT_UINT16, BASE_DEC, NULL, 0x0,
2363             "Literal number", HFILL }
2364         },
2365         { &hf_udvm_value,
2366             { "%Value", "sigcomp.udvm.value",
2367             FT_UINT16, BASE_DEC, NULL, 0x0,
2368             "Value", HFILL }
2369         },
2370         { &hf_udvm_addr_value,
2371             { "%Value[memory address]", "sigcomp.udvm.value",
2372             FT_UINT16, BASE_DEC, NULL, 0x0,
2373             "Value", HFILL }
2374         },
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 }
2379         },
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 }
2384         },
2385         { &hf_state_begin,
2386             { "%State begin", "sigcomp.udvm.state.begin",
2387             FT_UINT16, BASE_DEC, NULL, 0x0,
2388             "State begin", HFILL }
2389         },
2390         { &hf_udvm_state_length,
2391             { "%State length", "sigcomp.udvm.state.length",
2392             FT_UINT16, BASE_DEC, NULL, 0x0,
2393             "State length", HFILL }
2394         },
2395
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 }
2400         },
2401         { &hf_udvm_state_address,
2402             { "%State address", "sigcomp.udvm.start.address",
2403             FT_UINT16, BASE_DEC, NULL, 0x0,
2404             "State address", HFILL }
2405         },
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 }
2410         },
2411         { &hf_udvm_state_instr,
2412             { "%State instruction", "sigcomp.udvm.start.instr",
2413             FT_UINT16, BASE_DEC, NULL, 0x0,
2414             "State instruction", HFILL }
2415         },
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 }
2420         },
2421         { &hf_udvm_operand_2,
2422             { "%Operand 2", "sigcomp.udvm.operand.2",
2423             FT_UINT16, BASE_DEC, NULL, 0x0,
2424             "Operand 2", HFILL }
2425         },
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 }
2430         },
2431         { &hf_udvm_j,
2432             { "%j", "sigcomp.udvm.j",
2433             FT_UINT16, BASE_DEC, NULL, 0x0,
2434             "j", HFILL }
2435         },
2436         { &hf_udvm_addr_j,
2437             { "%j[memory address]", "sigcomp.udvm.addr.j",
2438             FT_UINT16, BASE_DEC, NULL, 0x0,
2439             "j", HFILL }
2440         },
2441         { &hf_udvm_output_start,
2442             { "%Output_start", "sigcomp.output.start",
2443             FT_UINT16, BASE_DEC, NULL, 0x0,
2444             "Output start", HFILL }
2445         },
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 }
2450         },
2451         { &hf_udvm_output_length,
2452             { "%Output_length", "sigcomp.output.length",
2453             FT_UINT16, BASE_DEC, NULL, 0x0,
2454             "Output length", HFILL }
2455         },
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 }
2460         },
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 }
2465         },
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 }
2470         },
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 }
2475         },
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 }
2480         },
2481         { &hf_udvm_position,
2482             { "%Position", "sigcomp.udvm.position",
2483             FT_UINT16, BASE_DEC, NULL, 0x0,
2484             "Position", HFILL }
2485         },
2486         { &hf_udvm_ref_dest,
2487             { "$Destination[memory address]", "sigcomp.udvm.ref.destination",
2488             FT_UINT16, BASE_DEC, NULL, 0x0,
2489             "(reference)Destination", HFILL }
2490         },
2491         { &hf_udvm_bits,
2492             { "%Bits", "sigcomp.udvm.bits",
2493             FT_UINT16, BASE_DEC, NULL, 0x0,
2494             "Bits", HFILL }
2495         },
2496         { &hf_udvm_lower_bound,
2497             { "%Lower bound", "sigcomp.udvm.lower.bound",
2498             FT_UINT16, BASE_DEC, NULL, 0x0,
2499             "Lower_bound", HFILL }
2500         },
2501         { &hf_udvm_upper_bound,
2502             { "%Upper bound", "sigcomp.udvm.upper.bound",
2503             FT_UINT16, BASE_DEC, NULL, 0x0,
2504             "Upper bound", HFILL }
2505         },
2506         { &hf_udvm_uncompressed,
2507             { "%Uncompressed", "sigcomp.udvm.uncompressed",
2508             FT_UINT16, BASE_DEC, NULL, 0x0,
2509             "Uncompressed", HFILL }
2510         },
2511         { &hf_udvm_start_value,
2512             { "%Start value", "sigcomp.udvm.start.value",
2513             FT_UINT16, BASE_DEC, NULL, 0x0,
2514             "Start value", HFILL }
2515         },
2516         { &hf_udvm_offset,
2517             { "%Offset", "sigcomp.udvm.offset",
2518             FT_UINT16, BASE_DEC, NULL, 0x0,
2519             "Offset", HFILL }
2520         },
2521         { &hf_udvm_addr_offset,
2522             { "%Offset[memory address]", "sigcomp.udvm.addr.offset",
2523             FT_UINT16, BASE_DEC, NULL, 0x0,
2524             "Offset", HFILL }
2525         },
2526         { &hf_sigcomp_nack_ver,
2527             { "NACK Version", "sigcomp.nack.ver",
2528             FT_UINT8, BASE_DEC, NULL, 0x0f,
2529             NULL, HFILL }
2530         },
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 }
2535         },
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 }
2540         },
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 }
2545         },
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 }
2550         },
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 }
2555         },
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 }
2560         },
2561         { &hf_sigcomp_nack_memory_size,
2562             { "Memory size", "sigcomp.memory_size",
2563             FT_UINT16, BASE_DEC, NULL, 0x0,
2564             NULL, HFILL }
2565         },
2566     };
2567
2568 /* Setup protocol subtree array */
2569     static gint *ett[] = {
2570         &ett_sigcomp,
2571         &ett_sigcomp_udvm,
2572         &ett_sigcomp_udvm_exe,
2573     };
2574     static gint *ett_raw[] = {
2575         &ett_raw_text,
2576     };
2577
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 }},
2580     };
2581
2582     module_t *sigcomp_module;
2583     expert_module_t* expert_sigcomp;
2584
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},
2590         {NULL, NULL, -1}
2591     };
2592
2593
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");
2599
2600     new_register_dissector("sigcomp", dissect_sigcomp, proto_sigcomp);
2601
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));
2608
2609 /* Register a configuration option for port */
2610     sigcomp_module = prefs_register_protocol(proto_sigcomp,
2611                                               proto_reg_handoff_sigcomp);
2612
2613     prefs_register_uint_preference(sigcomp_module, "udp.port",
2614                                    "Sigcomp UDP Port 1",
2615                                    "Set UDP port 1 for SigComp messages",
2616                                    10,
2617                                    &SigCompUDPPort1);
2618
2619     prefs_register_uint_preference(sigcomp_module, "udp.port2",
2620                                    "Sigcomp UDP Port 2",
2621                                    "Set UDP port 2 for SigComp messages",
2622                                    10,
2623                                    &SigCompUDPPort2);
2624     prefs_register_uint_preference(sigcomp_module, "tcp.port",
2625                                    "Sigcomp TCP Port 1",
2626                                    "Set TCP port 1 for SigComp messages",
2627                                    10,
2628                                    &SigCompTCPPort1);
2629
2630     prefs_register_uint_preference(sigcomp_module, "tcp.port2",
2631                                    "Sigcomp TCP Port 2",
2632                                    "Set TCP port 2 for SigComp messages",
2633                                    10,
2634                                    &SigCompTCPPort2);
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);
2639
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",
2648                                    &decompress);
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",
2653                                    &display_raw_txt);
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);
2660
2661     register_init_routine(&sigcomp_init_protocol);
2662
2663
2664
2665 }
2666
2667 void
2668 proto_reg_handoff_sigcomp(void)
2669 {
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;
2677
2678     if (!Initialized) {
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");
2682         Initialized=TRUE;
2683     }else{
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);
2688     }
2689
2690     udp_port1 = SigCompUDPPort1;
2691     udp_port2 = SigCompUDPPort2;
2692     tcp_port1 = SigCompTCPPort1;
2693     tcp_port2 = SigCompTCPPort2;
2694
2695
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);
2700
2701 }
2702
2703 /*
2704  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2705  *
2706  * Local variables:
2707  * c-basic-offset: 4
2708  * tab-width: 8
2709  * indent-tabs-mode: nil
2710  * End:
2711  *
2712  * vi: set shiftwidth=4 tabstop=8 expandtab:
2713  * :indentSize=4:tabSize=8:noTabs=true:
2714  */