Remove more deprecated tvb_length calls
[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  * https://tools.ietf.org/html/draft-ietf-rohc-sigcomp-impl-guide-10
28  * http://www.ietf.org/archive/id/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/strutil.h>
39 #include <epan/exceptions.h>
40
41 #include <wsutil/sha1.h>
42 #include <wsutil/crc16.h>
43
44 void proto_register_sigcomp(void);
45 void proto_reg_handoff_sigcomp(void);
46
47 /* Initialize the protocol and registered fields */
48 static int proto_sigcomp                            = -1;
49 static int proto_raw_sigcomp                        = -1;
50 static int hf_sigcomp_t_bit                         = -1;
51 static int hf_sigcomp_len                           = -1;
52 static int hf_sigcomp_returned_feedback_item        = -1;
53 static int hf_sigcomp_returned_feedback_item_len    = -1;
54 static int hf_sigcomp_code_len                      = -1;
55 static int hf_sigcomp_destination                   = -1;
56 static int hf_sigcomp_partial_state                 = -1;
57 static int hf_sigcomp_remaining_message_bytes       = -1;
58 static int hf_sigcomp_compression_ratio             = -1;
59 static int hf_sigcomp_udvm_bytecode                 = -1;
60 static int hf_sigcomp_udvm_instr                    = -1;
61 static int hf_udvm_multitype_bytecode               = -1;
62 static int hf_udvm_reference_bytecode               = -1;
63 static int hf_udvm_literal_bytecode                 = -1;
64 /* static int hf_udvm_operand                          = -1; */
65 static int hf_udvm_length                           = -1;
66 static int hf_udvm_addr_length                      = -1;
67 static int hf_udvm_destination                      = -1;
68 static int hf_udvm_addr_destination                 = -1;
69 static int hf_udvm_at_address                       = -1;
70 static int hf_udvm_address                          = -1;
71 static int hf_udvm_literal_num                      = -1;
72 static int hf_udvm_value                            = -1;
73 static int hf_udvm_addr_value                       = -1;
74 static int hf_partial_identifier_start              = -1;
75 static int hf_partial_identifier_length             = -1;
76 static int hf_state_begin                           = -1;
77 static int hf_udvm_state_length                     = -1;
78 static int hf_udvm_state_length_addr                = -1;
79 static int hf_udvm_state_address                    = -1;
80 static int hf_udvm_state_address_addr               = -1;
81 static int hf_udvm_state_instr                      = -1;
82 static int hf_udvm_operand_1                        = -1;
83 static int hf_udvm_operand_2                        = -1;
84 static int hf_udvm_operand_2_addr                   = -1;
85 static int hf_udvm_j                                = -1;
86 static int hf_udvm_addr_j                           = -1;
87 static int hf_udvm_output_start                     = -1;
88 static int hf_udvm_addr_output_start                = -1;
89 static int hf_udvm_output_length                    = -1;
90 static int hf_udvm_output_length_addr               = -1;
91 static int hf_udvm_req_feedback_loc                 = -1;
92 static int hf_udvm_min_acc_len                      = -1;
93 static int hf_udvm_state_ret_pri                    = -1;
94 static int hf_udvm_ret_param_loc                    = -1;
95 static int hf_udvm_position                         = -1;
96 static int hf_udvm_ref_dest                         = -1;
97 static int hf_udvm_bits                             = -1;
98 static int hf_udvm_lower_bound                      = -1;
99 static int hf_udvm_upper_bound                      = -1;
100 static int hf_udvm_uncompressed                     = -1;
101 static int hf_udvm_offset                           = -1;
102 static int hf_udvm_addr_offset                      = -1;
103 static int hf_udvm_start_value                      = -1;
104 static int hf_udvm_execution_trace                  = -1;
105 static int hf_sigcomp_nack_ver                      = -1;
106 static int hf_sigcomp_nack_reason_code              = -1;
107 static int hf_sigcomp_nack_failed_op_code           = -1;
108 static int hf_sigcomp_nack_pc                       = -1;
109 static int hf_sigcomp_nack_sha1                     = -1;
110 static int hf_sigcomp_nack_state_id                 = -1;
111 static int hf_sigcomp_nack_memory_size              = -1;
112 static int hf_sigcomp_nack_cycles_per_bit           = -1;
113 static int hf_sigcomp_decompress_instruction        = -1;
114 static int hf_sigcomp_loading_result                = -1;
115
116 /* Initialize the subtree pointers */
117 static gint ett_sigcomp             = -1;
118 static gint ett_sigcomp_udvm        = -1;
119 static gint ett_sigcomp_udvm_exe    = -1;
120 static gint ett_raw_text            = -1;
121
122 static expert_field ei_sigcomp_nack_failed_op_code = EI_INIT;
123 static expert_field ei_sigcomp_invalid_instruction = EI_INIT;
124
125 static dissector_handle_t sip_handle;
126 /* set the udp ports */
127 static guint SigCompUDPPort1 = 5555;
128 static guint SigCompUDPPort2 = 6666;
129
130 /* set the tcp ports */
131 static guint SigCompTCPPort1 = 5555;
132 static guint SigCompTCPPort2 = 6666;
133
134 /* Default preference whether to display the bytecode in UDVM operands or not */
135 static gboolean display_udvm_bytecode = FALSE;
136 /* Default preference whether to dissect the UDVM code or not */
137 static gboolean dissect_udvm_code = TRUE;
138 static gboolean display_raw_txt = FALSE;
139 /* Default preference whether to decompress the message or not */
140 static gboolean decompress = TRUE;
141 /* Default preference whether to print debug info at execution of UDVM
142  * 0 = No printout
143  * 1 = details level 1
144  * 2 = details level 2
145  * 3 = details level 3
146  * 4 = details level 4
147  */
148 static gint udvm_print_detail_level = 0;
149
150 /* Value strings */
151 static const value_string length_encoding_vals[] = {
152     { 0x00, "No partial state (Message type 2)" },
153     { 0x01, "(6 bytes)" },
154     { 0x02, "(9 bytes)" },
155     { 0x03, "(12 bytes)" },
156     { 0,    NULL }
157 };
158
159
160 static const value_string destination_address_encoding_vals[] = {
161     { 0x00, "Reserved" },
162     { 0x01, "128" },
163     { 0x02, "192" },
164     { 0x03, "256" },
165     { 0x04, "320" },
166     { 0x05, "384" },
167     { 0x06, "448" },
168     { 0x07, "512" },
169     { 0x08, "576" },
170     { 0x09, "640" },
171     { 0x0a, "704" },
172     { 0x0b, "768" },
173     { 0x0c, "832" },
174     { 0x0d, "896" },
175     { 0x0e, "960" },
176     { 0x0F, "1024" },
177     { 0,    NULL }
178 };
179 static value_string_ext destination_address_encoding_vals_ext =
180     VALUE_STRING_EXT_INIT(destination_address_encoding_vals);
181
182     /* RFC3320
183      * Figure 10: Bytecode for a multitype (%) operand
184      * Bytecode:                       Operand value:      Range:               HEX val
185      * 00nnnnnn                        N                   0 - 63               0x00
186      * 01nnnnnn                        memory[2 * N]       0 - 65535            0x40
187      * 1000011n                        2 ^ (N + 6)        64 , 128              0x86
188      * 10001nnn                        2 ^ (N + 8)    256 , ... , 32768         0x88
189      * 111nnnnn                        N + 65504       65504 - 65535            0xe0
190      * 1001nnnn nnnnnnnn               N + 61440       61440 - 65535            0x90
191      * 101nnnnn nnnnnnnn               N                   0 - 8191             0xa0
192      * 110nnnnn nnnnnnnn               memory[N]           0 - 65535            0xc0
193      * 10000000 nnnnnnnn nnnnnnnn      N                   0 - 65535            0x80
194      * 10000001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535            0x81
195      */
196
197 static const value_string display_bytecode_vals[] = {
198     { 0x00, "00nnnnnn, N, 0 - 63" },
199     { 0x40, "01nnnnnn, memory[2 * N],0 - 65535" },
200     { 0x86, "1000011n, 2 ^ (N + 6), 64 , 128" },
201     { 0x88, "10001nnn, 2 ^ (N + 8), 256,..., 32768" },
202     { 0xe0, "111nnnnn N + 65504, 65504 - 65535" },
203     { 0x90, "1001nnnn nnnnnnnn, N + 61440, 61440 - 65535" },
204     { 0xa0, "101nnnnn nnnnnnnn, N, 0 - 8191" },
205     { 0xc0, "110nnnnn nnnnnnnn, memory[N], 0 - 65535" },
206     { 0x80, "10000000 nnnnnnnn nnnnnnnn, N, 0 - 65535" },
207     { 0x81, "10000001 nnnnnnnn nnnnnnnn, memory[N], 0 - 65535" },
208     { 0,    NULL }
209 };
210 /* RFC3320
211  * 0nnnnnnn                        memory[2 * N]       0 - 65535
212  * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
213  * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
214  */
215 static const value_string display_ref_bytecode_vals[] = {
216     { 0x00, "0nnnnnnn memory[2 * N] 0 - 65535" },
217     { 0x80, "10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535" },
218     { 0xc0, "11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535" },
219     { 0,    NULL }
220 };
221  /*  The simplest operand type is the literal (#), which encodes a
222   * constant integer from 0 to 65535 inclusive.  A literal operand may
223   * require between 1 and 3 bytes depending on its value.
224   * Bytecode:                       Operand value:      Range:
225   * 0nnnnnnn                        N                   0 - 127
226   * 10nnnnnn nnnnnnnn               N                   0 - 16383
227   * 11000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
228   *
229   *            Figure 8: Bytecode for a literal (#) operand
230   *
231   */
232
233 static const value_string display_lit_bytecode_vals[] = {
234     { 0x00, "0nnnnnnn N 0 - 127" },
235     { 0x80, "10nnnnnn nnnnnnnn N 0 - 16383" },
236     { 0xc0, "11000000 nnnnnnnn nnnnnnnn N 0 - 65535" },
237     { 0,    NULL }
238 };
239
240 #define SIGCOMP_NACK_STATE_NOT_FOUND              1
241 #define SIGCOMP_NACK_CYCLES_EXHAUSTED             2
242 #define SIGCOMP_NACK_BYTECODES_TOO_LARGE         18
243 #define SIGCOMP_NACK_ID_NOT_UNIQUE               21
244 #define SIGCOMP_NACK_STATE_TOO_SHORT             23
245
246 static const value_string sigcomp_nack_reason_code_vals[] = {
247     {  1,   "STATE_NOT_FOUND" },            /*1  State ID (6 - 20 bytes) */
248     {  2,   "CYCLES_EXHAUSTED" },           /*2  Cycles Per Bit (1 byte) */
249     {  3,   "USER_REQUESTED" },
250     {  4,   "SEGFAULT" },
251     {  5,   "TOO_MANY_STATE_REQUESTS" },
252     {  6,   "INVALID_STATE_ID_LENGTH" },
253     {  7,   "INVALID_STATE_PRIORITY" },
254     {  8,   "OUTPUT_OVERFLOW" },
255     {  9,   "STACK_UNDERFLOW" },
256     { 10,   "BAD_INPUT_BITORDER" },
257     { 11,   "DIV_BY_ZERO" },
258     { 12,   "SWITCH_VALUE_TOO_HIGH" },
259     { 13,   "TOO_MANY_BITS_REQUESTED" },
260     { 14,   "INVALID_OPERAND" },
261     { 15,   "HUFFMAN_NO_MATCH" },
262     { 16,   "MESSAGE_TOO_SHORT" },
263     { 17,   "INVALID_CODE_LOCATION" },
264     { 18,   "BYTECODES_TOO_LARGE" },        /*18  Memory size (2 bytes) */
265     { 19,   "INVALID_OPCODE" },
266     { 20,   "INVALID_STATE_PROBE" },
267     { 21,   "ID_NOT_UNIQUE" },              /*21  State ID (6 - 20 bytes) */
268     { 22,   "MULTILOAD_OVERWRITTEN" },
269     { 23,   "STATE_TOO_SHORT" },            /*23  State ID (6 - 20 bytes) */
270     { 24,   "INTERNAL_ERROR" },
271     { 25,   "FRAMING_ERROR" },
272     { 0,    NULL }
273 };
274 static value_string_ext sigcomp_nack_reason_code_vals_ext =
275     VALUE_STRING_EXT_INIT(sigcomp_nack_reason_code_vals);
276
277
278 static void dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, guint destination);
279
280 static int dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
281                                           gint offset,gboolean is_addr,gint *start_offset,
282                                           guint16 *value, gboolean *is_memory_address );
283
284 static int dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
285                                gint offset, gint *start_offset, guint16 *value);
286
287 static int dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
288                                gint offset, gint *start_offset, guint16 *value);
289 static void tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree);
290
291 static int dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
292
293 static proto_tree *top_tree;
294
295 #define UDVM_MEMORY_SIZE   65536
296
297 /**********************************************************************************************
298  *
299  *                       SIGCOMP STATE HANDLER
300  *
301  **********************************************************************************************/
302 #define STATE_BUFFER_SIZE 20
303 #define STATE_MIN_ACCESS_LEN 6
304
305 /*
306  * Defenitions for:
307  * The Session Initiation Protocol (SIP) and Session Description Protocol
308  *    (SDP) Static Dictionary for Signaling Compression (SigComp)
309  * http://www.ietf.org/rfc/rfc3485.txt?number=3485
310  */
311 #define SIP_SDP_STATE_LENGTH 0x12e4
312
313 static const guint8 sip_sdp_state_identifier[STATE_BUFFER_SIZE] =
314 {
315    /* -0000, */  0xfb, 0xe5, 0x07, 0xdf, 0xe5, 0xe6, 0xaa, 0x5a, 0xf2, 0xab, 0xb9, 0x14, 0xce, 0xaa, 0x05, 0xf9,
316    /* -0010, */  0x9c, 0xe6, 0x1b, 0xa5
317 };
318
319 static const guint8 sip_sdp_static_dictionaty_for_sigcomp[0x12e4] =
320 {
321
322    /* -0000, */  0x0d, 0x0a, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74,
323    /* -0010, */  0x3a, 0x20, 0x0d, 0x0a, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x49, 0x6e, 0x66, 0x6f, 0x3a, 0x20,
324    /* -0020, */  0x0d, 0x0a, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x3a, 0x20, 0x0d, 0x0a, 0x43,
325    /* -0030, */  0x61, 0x6c, 0x6c, 0x2d, 0x49, 0x6e, 0x66, 0x6f, 0x3a, 0x20, 0x0d, 0x0a, 0x52, 0x65, 0x70, 0x6c,
326    /* -0040, */  0x79, 0x2d, 0x54, 0x6f, 0x3a, 0x20, 0x0d, 0x0a, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a,
327    /* -0050, */  0x20, 0x0d, 0x0a, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, 0x3b, 0x68, 0x61, 0x6e,
328    /* -0060, */  0x64, 0x6c, 0x69, 0x6e, 0x67, 0x3d, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3b, 0x70, 0x75, 0x72, 0x70,
329    /* -0070, */  0x6f, 0x73, 0x65, 0x3d, 0x3b, 0x63, 0x61, 0x75, 0x73, 0x65, 0x3d, 0x3b, 0x74, 0x65, 0x78, 0x74,
330    /* -0080, */  0x3d, 0x63, 0x61, 0x72, 0x64, 0x33, 0x30, 0x30, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c,
331    /* -0090, */  0x65, 0x20, 0x43, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x6d, 0x69, 0x6d, 0x65, 0x73, 0x73, 0x61,
332    /* -00A0, */  0x67, 0x65, 0x2f, 0x73, 0x69, 0x70, 0x66, 0x72, 0x61, 0x67, 0x34, 0x30, 0x37, 0x20, 0x50, 0x72,
333    /* -00B0, */  0x6f, 0x78, 0x79, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69,
334    /* -00C0, */  0x6f, 0x6e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74,
335    /* -00D0, */  0x2d, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x34, 0x38, 0x34, 0x20, 0x41, 0x64,
336    /* -00E0, */  0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65,
337    /* -00F0, */  0x6c, 0x65, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x2d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x34, 0x39,
338    /* -0100, */  0x34, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x41, 0x67, 0x72, 0x65, 0x65,
339    /* -0110, */  0x6d, 0x65, 0x6e, 0x74, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x65, 0x61, 0x63,
340    /* -0120, */  0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x64, 0x34, 0x38, 0x31, 0x20, 0x43, 0x61, 0x6c, 0x6c, 0x2f,
341    /* -0130, */  0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x6f, 0x65, 0x73,
342    /* -0140, */  0x20, 0x4e, 0x6f, 0x74, 0x20, 0x45, 0x78, 0x69, 0x73, 0x74, 0x61, 0x6c, 0x65, 0x3d, 0x35, 0x30,
343    /* -0150, */  0x30, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
344    /* -0160, */  0x6c, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x6f, 0x62, 0x75, 0x73, 0x74, 0x2d, 0x73, 0x6f, 0x72,
345    /* -0170, */  0x74, 0x69, 0x6e, 0x67, 0x3d, 0x34, 0x31, 0x36, 0x20, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f,
346    /* -0180, */  0x72, 0x74, 0x65, 0x64, 0x20, 0x55, 0x52, 0x49, 0x20, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x72,
347    /* -0190, */  0x67, 0x65, 0x6e, 0x63, 0x79, 0x34, 0x31, 0x35, 0x20, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f,
348    /* -01A0, */  0x72, 0x74, 0x65, 0x64, 0x20, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x54, 0x79, 0x70, 0x65, 0x6e,
349    /* -01B0, */  0x64, 0x69, 0x6e, 0x67, 0x34, 0x38, 0x38, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x41, 0x63, 0x63, 0x65,
350    /* -01C0, */  0x70, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x48, 0x65, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65,
351    /* -01D0, */  0x64, 0x34, 0x32, 0x33, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x20, 0x54, 0x6f,
352    /* -01E0, */  0x6f, 0x20, 0x42, 0x72, 0x69, 0x65, 0x66, 0x72, 0x6f, 0x6d, 0x2d, 0x74, 0x61, 0x67, 0x51, 0x2e,
353    /* -01F0, */  0x38, 0x35, 0x30, 0x35, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x4e, 0x6f, 0x74,
354    /* -0200, */  0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x34, 0x30, 0x33, 0x20, 0x46, 0x6f,
355    /* -0210, */  0x72, 0x62, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x6f, 0x6e, 0x2d, 0x75, 0x72, 0x67, 0x65, 0x6e, 0x74,
356    /* -0220, */  0x34, 0x32, 0x39, 0x20, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x52, 0x65, 0x66, 0x65,
357    /* -0230, */  0x72, 0x72, 0x6f, 0x72, 0x20, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x34, 0x32, 0x30,
358    /* -0240, */  0x20, 0x42, 0x61, 0x64, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x6f, 0x72,
359    /* -0250, */  0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x0d, 0x0a, 0x61, 0x3d, 0x6b, 0x65, 0x79, 0x2d, 0x6d,
360    /* -0260, */  0x67, 0x6d, 0x74, 0x3a, 0x6d, 0x69, 0x6b, 0x65, 0x79, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x53,
361    /* -0270, */  0x20, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x35, 0x30, 0x34, 0x20, 0x53,
362    /* -0280, */  0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x2d, 0x6f, 0x75, 0x74, 0x6f, 0x2d,
363    /* -0290, */  0x74, 0x61, 0x67, 0x0d, 0x0a, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
364    /* -02A0, */  0x69, 0x6f, 0x6e, 0x2d, 0x49, 0x6e, 0x66, 0x6f, 0x3a, 0x20, 0x44, 0x65, 0x63, 0x20, 0x33, 0x38,
365    /* -02B0, */  0x30, 0x20, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x53, 0x65,
366    /* -02C0, */  0x72, 0x76, 0x69, 0x63, 0x65, 0x35, 0x30, 0x33, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
367    /* -02D0, */  0x20, 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x34, 0x32, 0x31, 0x20,
368    /* -02E0, */  0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72,
369    /* -02F0, */  0x65, 0x64, 0x34, 0x30, 0x35, 0x20, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x4e, 0x6f, 0x74,
370    /* -0300, */  0x20, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x34, 0x38, 0x37, 0x20, 0x52, 0x65, 0x71, 0x75,
371    /* -0310, */  0x65, 0x73, 0x74, 0x20, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x61, 0x75,
372    /* -0320, */  0x74, 0x68, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6c, 0x65, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x3d,
373    /* -0330, */  0x0d, 0x0a, 0x6d, 0x3d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
374    /* -0340, */  0x41, 0x75, 0x67, 0x20, 0x35, 0x31, 0x33, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20,
375    /* -0350, */  0x54, 0x6f, 0x6f, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x36, 0x38, 0x37, 0x20, 0x44, 0x69, 0x61,
376    /* -0360, */  0x6c, 0x6f, 0x67, 0x20, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x33, 0x30,
377    /* -0370, */  0x32, 0x20, 0x4d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72,
378    /* -0380, */  0x69, 0x6c, 0x79, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72,
379    /* -0390, */  0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72,
380    /* -03A0, */  0x74, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x0d, 0x0a, 0x52, 0x65, 0x74, 0x72, 0x79, 0x2d,
381    /* -03B0, */  0x41, 0x66, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x47, 0x4d, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x34, 0x30,
382    /* -03C0, */  0x32, 0x20, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72,
383    /* -03D0, */  0x65, 0x64, 0x0d, 0x0a, 0x61, 0x3d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x3a, 0x6c, 0x61, 0x6e,
384    /* -03E0, */  0x64, 0x73, 0x63, 0x61, 0x70, 0x65, 0x34, 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, 0x65,
385    /* -03F0, */  0x71, 0x75, 0x65, 0x73, 0x74, 0x72, 0x75, 0x65, 0x34, 0x39, 0x31, 0x20, 0x52, 0x65, 0x71, 0x75,
386    /* -0400, */  0x65, 0x73, 0x74, 0x20, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x35, 0x30, 0x31, 0x20, 0x4e,
387    /* -0410, */  0x6f, 0x74, 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x34, 0x30,
388    /* -0420, */  0x36, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x62, 0x6c, 0x65,
389    /* -0430, */  0x36, 0x30, 0x36, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x62,
390    /* -0440, */  0x6c, 0x65, 0x0d, 0x0a, 0x61, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x62, 0x72, 0x6f, 0x61, 0x64,
391    /* -0450, */  0x63, 0x61, 0x73, 0x74, 0x6f, 0x6e, 0x65, 0x34, 0x39, 0x33, 0x20, 0x55, 0x6e, 0x64, 0x65, 0x63,
392    /* -0460, */  0x69, 0x70, 0x68, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x0d, 0x0a, 0x4d, 0x49, 0x4d, 0x45, 0x2d,
393    /* -0470, */  0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x34, 0x38, 0x32,
394    /* -0480, */  0x20, 0x4c, 0x6f, 0x6f, 0x70, 0x20, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x0d, 0x0a,
395    /* -0490, */  0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4a, 0x75,
396    /* -04A0, */  0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2d, 0x6e, 0x65,
397    /* -04B0, */  0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x3d, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x65,
398    /* -04C0, */  0x72, 0x74, 0x63, 0x70, 0x2d, 0x66, 0x62, 0x34, 0x38, 0x39, 0x20, 0x42, 0x61, 0x64, 0x20, 0x45,
399    /* -04D0, */  0x76, 0x65, 0x6e, 0x74, 0x6c, 0x73, 0x0d, 0x0a, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72,
400    /* -04E0, */  0x74, 0x65, 0x64, 0x3a, 0x20, 0x4a, 0x61, 0x6e, 0x20, 0x35, 0x30, 0x32, 0x20, 0x42, 0x61, 0x64,
401    /* -04F0, */  0x20, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x6d, 0x6f, 0x64, 0x65, 0x2d, 0x63, 0x68, 0x61,
402    /* -0500, */  0x6e, 0x67, 0x65, 0x2d, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x3d, 0x0d, 0x0a, 0x61, 0x3d, 0x6f,
403    /* -0510, */  0x72, 0x69, 0x65, 0x6e, 0x74, 0x3a, 0x73, 0x65, 0x61, 0x73, 0x63, 0x61, 0x70, 0x65, 0x0d, 0x0a,
404    /* -0520, */  0x61, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64,
405    /* -0530, */  0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x33, 0x30, 0x35,
406    /* -0540, */  0x20, 0x55, 0x73, 0x65, 0x20, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x0d, 0x0a, 0x61, 0x3d, 0x74, 0x79,
407    /* -0550, */  0x70, 0x65, 0x3a, 0x72, 0x65, 0x63, 0x76, 0x6f, 0x6e, 0x6c, 0x79, 0x0d, 0x0a, 0x61, 0x3d, 0x74,
408    /* -0560, */  0x79, 0x70, 0x65, 0x3a, 0x6d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x0d, 0x0a, 0x6b, 0x3d, 0x70,
409    /* -0570, */  0x72, 0x6f, 0x6d, 0x70, 0x74, 0x3a, 0x0d, 0x0a, 0x52, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64,
410    /* -0580, */  0x2d, 0x42, 0x79, 0x3a, 0x20, 0x0d, 0x0a, 0x49, 0x6e, 0x2d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x2d,
411    /* -0590, */  0x54, 0x6f, 0x3a, 0x20, 0x54, 0x52, 0x55, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a,
412    /* -05A0, */  0x20, 0x31, 0x38, 0x32, 0x20, 0x51, 0x75, 0x65, 0x75, 0x65, 0x64, 0x41, 0x75, 0x74, 0x68, 0x65,
413    /* -05B0, */  0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
414    /* -05C0, */  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x0d, 0x0a, 0x61, 0x3d, 0x66, 0x72, 0x61, 0x6d, 0x65,
415    /* -05D0, */  0x72, 0x61, 0x74, 0x65, 0x3a, 0x0d, 0x0a, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x2d, 0x49, 0x6e, 0x66,
416    /* -05E0, */  0x6f, 0x3a, 0x20, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x20, 0x0d, 0x0a, 0x61, 0x3d, 0x6d, 0x61,
417    /* -05F0, */  0x78, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3b, 0x72, 0x65, 0x74, 0x72, 0x79, 0x2d, 0x61, 0x66,
418    /* -0600, */  0x74, 0x65, 0x72, 0x3d, 0x75, 0x61, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x3d, 0x34,
419    /* -0610, */  0x31, 0x30, 0x20, 0x47, 0x6f, 0x6e, 0x65, 0x0d, 0x0a, 0x52, 0x65, 0x66, 0x65, 0x72, 0x2d, 0x54,
420    /* -0620, */  0x6f, 0x3a, 0x20, 0x0d, 0x0a, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x0d,
421    /* -0630, */  0x0a, 0x6d, 0x3d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x0d, 0x0a, 0x61, 0x3d, 0x71,
422    /* -0640, */  0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x3a, 0x0d, 0x0a, 0x61, 0x3d, 0x73, 0x64, 0x70, 0x6c, 0x61,
423    /* -0650, */  0x6e, 0x67, 0x3a, 0x0d, 0x0a, 0x61, 0x3d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3a, 0x0d,
424    /* -0660, */  0x0a, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x3a, 0x20, 0x52, 0x45, 0x46, 0x45, 0x52,
425    /* -0670, */  0x20, 0x69, 0x70, 0x73, 0x65, 0x63, 0x2d, 0x69, 0x6b, 0x65, 0x3b, 0x74, 0x72, 0x61, 0x6e, 0x73,
426    /* -0680, */  0x70, 0x6f, 0x72, 0x74, 0x3d, 0x0d, 0x0a, 0x61, 0x3d, 0x6b, 0x65, 0x79, 0x77, 0x64, 0x73, 0x3a,
427    /* -0690, */  0x0d, 0x0a, 0x6b, 0x3d, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x3a, 0x3b, 0x72, 0x65, 0x66, 0x72,
428    /* -06A0, */  0x65, 0x73, 0x68, 0x65, 0x72, 0x3d, 0x0d, 0x0a, 0x61, 0x3d, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x3a,
429    /* -06B0, */  0x0d, 0x0a, 0x6b, 0x3d, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x3a, 0x3b, 0x72, 0x65, 0x63, 0x65, 0x69,
430    /* -06C0, */  0x76, 0x65, 0x64, 0x3d, 0x3b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x0d, 0x0a,
431    /* -06D0, */  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x0d, 0x0a, 0x61, 0x3d, 0x67, 0x72, 0x6f, 0x75,
432    /* -06E0, */  0x70, 0x3a, 0x46, 0x41, 0x4c, 0x53, 0x45, 0x3a, 0x20, 0x49, 0x4e, 0x46, 0x4f, 0x20, 0x0d, 0x0a,
433    /* -06F0, */  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x0d, 0x0a, 0x61, 0x3d, 0x6c, 0x61, 0x6e, 0x67, 0x3a,
434    /* -0700, */  0x0d, 0x0a, 0x6d, 0x3d, 0x64, 0x61, 0x74, 0x61, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x2d, 0x73, 0x65,
435    /* -0710, */  0x74, 0x3d, 0x0d, 0x0a, 0x61, 0x3d, 0x74, 0x6f, 0x6f, 0x6c, 0x3a, 0x54, 0x4c, 0x53, 0x75, 0x6e,
436    /* -0720, */  0x2c, 0x20, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x0d, 0x0a, 0x61, 0x3d, 0x63, 0x61,
437    /* -0730, */  0x74, 0x3a, 0x0d, 0x0a, 0x6b, 0x3d, 0x75, 0x72, 0x69, 0x3a, 0x0d, 0x0a, 0x50, 0x72, 0x6f, 0x78,
438    /* -0740, */  0x79, 0x2d, 0x3b, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3d, 0x3b, 0x6d, 0x65, 0x74, 0x68, 0x6f,
439    /* -0750, */  0x64, 0x3d, 0x0d, 0x0a, 0x61, 0x3d, 0x6d, 0x69, 0x64, 0x3a, 0x3b, 0x6d, 0x61, 0x64, 0x64, 0x72,
440    /* -0760, */  0x3d, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x3d, 0x0d, 0x0a, 0x4d, 0x69, 0x6e, 0x2d, 0x3b, 0x61,
441    /* -0770, */  0x6c, 0x67, 0x3d, 0x4d, 0x6f, 0x6e, 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, 0x65, 0x64,
442    /* -0780, */  0x2c, 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, 0x74, 0x2c, 0x20, 0x3b, 0x74, 0x74, 0x6c,
443    /* -0790, */  0x3d, 0x61, 0x75, 0x74, 0x73, 0x3d, 0x0d, 0x0a, 0x72, 0x3d, 0x0d, 0x0a, 0x7a, 0x3d, 0x0d, 0x0a,
444    /* -07A0, */  0x65, 0x3d, 0x3b, 0x69, 0x64, 0x3d, 0x0d, 0x0a, 0x69, 0x3d, 0x63, 0x72, 0x63, 0x3d, 0x0d, 0x0a,
445    /* -07B0, */  0x75, 0x3d, 0x3b, 0x71, 0x3d, 0x75, 0x61, 0x73, 0x34, 0x31, 0x34, 0x20, 0x52, 0x65, 0x71, 0x75,
446    /* -07C0, */  0x65, 0x73, 0x74, 0x2d, 0x55, 0x52, 0x49, 0x20, 0x54, 0x6f, 0x6f, 0x20, 0x4c, 0x6f, 0x6e, 0x67,
447    /* -07D0, */  0x69, 0x76, 0x65, 0x75, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x75, 0x64, 0x70, 0x72, 0x65,
448    /* -07E0, */  0x66, 0x65, 0x72, 0x36, 0x30, 0x30, 0x20, 0x42, 0x75, 0x73, 0x79, 0x20, 0x45, 0x76, 0x65, 0x72,
449    /* -07F0, */  0x79, 0x77, 0x68, 0x65, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x34, 0x38, 0x30, 0x20,
450    /* -0800, */  0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x69, 0x6c, 0x79, 0x20, 0x55, 0x6e, 0x61, 0x76,
451    /* -0810, */  0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x0d, 0x0a, 0x61, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x3a,
452    /* -0820, */  0x48, 0x2e, 0x33, 0x33, 0x32, 0x30, 0x32, 0x20, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64,
453    /* -0830, */  0x0d, 0x0a, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65,
454    /* -0840, */  0x73, 0x3a, 0x20, 0x0d, 0x0a, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
455    /* -0850, */  0x6e, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x0d, 0x0a, 0x53,
456    /* -0860, */  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x3a, 0x20, 0x53, 0x65,
457    /* -0870, */  0x70, 0x20, 0x0d, 0x0a, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x2d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73,
458    /* -0880, */  0x3a, 0x20, 0x46, 0x65, 0x62, 0x20, 0x0d, 0x0a, 0x61, 0x3d, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69,
459    /* -0890, */  0x76, 0x65, 0x52, 0x54, 0x50, 0x2f, 0x53, 0x41, 0x56, 0x50, 0x20, 0x52, 0x54, 0x50, 0x2f, 0x41,
460    /* -08A0, */  0x56, 0x50, 0x46, 0x20, 0x41, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x69, 0x70, 0x73,
461    /* -08B0, */  0x3a, 0x0d, 0x0a, 0x61, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x65, 0x6c,
462    /* -08C0, */  0x3a, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x20, 0x0d, 0x0a, 0x61, 0x3d, 0x72, 0x65, 0x63,
463    /* -08D0, */  0x76, 0x6f, 0x6e, 0x6c, 0x79, 0x0d, 0x0a, 0x61, 0x3d, 0x73, 0x65, 0x6e, 0x64, 0x6f, 0x6e, 0x6c,
464    /* -08E0, */  0x79, 0x0d, 0x0a, 0x63, 0x3d, 0x49, 0x4e, 0x20, 0x49, 0x50, 0x34, 0x20, 0x0d, 0x0a, 0x52, 0x65,
465    /* -08F0, */  0x61, 0x73, 0x6f, 0x6e, 0x3a, 0x20, 0x0d, 0x0a, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x3a, 0x20, 0x0d,
466    /* -0900, */  0x0a, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x0d, 0x0a, 0x50, 0x61, 0x74, 0x68, 0x3a, 0x20,
467    /* -0910, */  0x3b, 0x75, 0x73, 0x65, 0x72, 0x3d, 0x0d, 0x0a, 0x62, 0x3d, 0x41, 0x53, 0x20, 0x43, 0x54, 0x20,
468    /* -0920, */  0x0d, 0x0a, 0x57, 0x57, 0x57, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61,
469    /* -0930, */  0x74, 0x65, 0x3a, 0x20, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x20, 0x0d, 0x0a, 0x61, 0x3d, 0x73,
470    /* -0940, */  0x65, 0x6e, 0x64, 0x72, 0x65, 0x63, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d,
471    /* -0950, */  0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
472    /* -0960, */  0x6e, 0x2f, 0x73, 0x64, 0x70, 0x61, 0x74, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x70, 0x61,
473    /* -0970, */  0x75, 0x74, 0x68, 0x3d, 0x0d, 0x0a, 0x61, 0x3d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x3a, 0x70,
474    /* -0980, */  0x6f, 0x72, 0x74, 0x72, 0x61, 0x69, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x74, 0x72, 0x2d,
475    /* -0990, */  0x69, 0x6e, 0x74, 0x69, 0x63, 0x6f, 0x6e, 0x63, 0x3d, 0x34, 0x38, 0x33, 0x20, 0x54, 0x6f, 0x6f,
476    /* -09A0, */  0x20, 0x4d, 0x61, 0x6e, 0x79, 0x20, 0x48, 0x6f, 0x70, 0x73, 0x6c, 0x69, 0x6e, 0x66, 0x6f, 0x70,
477    /* -09B0, */  0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x3d, 0x36, 0x30,
478    /* -09C0, */  0x34, 0x20, 0x44, 0x6f, 0x65, 0x73, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x45, 0x78, 0x69, 0x73, 0x74,
479    /* -09D0, */  0x20, 0x41, 0x6e, 0x79, 0x77, 0x68, 0x65, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3d,
480    /* -09E0, */  0x0d, 0x0a, 0x0d, 0x0a, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2d, 0x44, 0x69, 0x73, 0x70,
481    /* -09F0, */  0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4d, 0x44, 0x35, 0x38, 0x30, 0x20, 0x50,
482    /* -0A00, */  0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x61, 0x69, 0x6c,
483    /* -0A10, */  0x75, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x34, 0x32, 0x32, 0x20, 0x53, 0x65, 0x73,
484    /* -0A20, */  0x73, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x20, 0x54, 0x6f,
485    /* -0A30, */  0x6f, 0x20, 0x53, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x31, 0x38, 0x31, 0x20, 0x43,
486    /* -0A40, */  0x61, 0x6c, 0x6c, 0x20, 0x49, 0x73, 0x20, 0x42, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x46, 0x6f, 0x72,
487    /* -0A50, */  0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x3d, 0x66, 0x61, 0x69, 0x6c,
488    /* -0A60, */  0x75, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x3d, 0x53, 0x55, 0x42, 0x53,
489    /* -0A70, */  0x43, 0x52, 0x49, 0x42, 0x45, 0x20, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69,
490    /* -0A80, */  0x6f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x70, 0x73, 0x65, 0x63, 0x2d, 0x6d, 0x61, 0x6e,
491    /* -0A90, */  0x64, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x34, 0x31, 0x33, 0x20, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
492    /* -0AA0, */  0x74, 0x20, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x54, 0x6f, 0x6f, 0x20, 0x4c, 0x61, 0x72,
493    /* -0AB0, */  0x67, 0x65, 0x32, 0x65, 0x31, 0x38, 0x33, 0x20, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20,
494    /* -0AC0, */  0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x63, 0x74, 0x70, 0x34, 0x38, 0x36, 0x20, 0x42,
495    /* -0AD0, */  0x75, 0x73, 0x79, 0x20, 0x48, 0x65, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e,
496    /* -0AE0, */  0x61, 0x74, 0x65, 0x64, 0x41, 0x4b, 0x41, 0x76, 0x31, 0x2d, 0x4d, 0x44, 0x35, 0x2d, 0x73, 0x65,
497    /* -0AF0, */  0x73, 0x73, 0x69, 0x6f, 0x6e, 0x6f, 0x6e, 0x65, 0x0d, 0x0a, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
498    /* -0B00, */  0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x36, 0x30, 0x33, 0x20, 0x44, 0x65, 0x63,
499    /* -0B10, */  0x6c, 0x69, 0x6e, 0x65, 0x78, 0x74, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x3d, 0x34, 0x38, 0x35, 0x20,
500    /* -0B20, */  0x41, 0x6d, 0x62, 0x69, 0x67, 0x75, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x3d,
501    /* -0B30, */  0x61, 0x75, 0x64, 0x69, 0x6f, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54,
502    /* -0B40, */  0x79, 0x70, 0x65, 0x3a, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x0d, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72,
503    /* -0B50, */  0x64, 0x2d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x3a, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x34, 0x30, 0x31,
504    /* -0B60, */  0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x0d, 0x0a, 0x52,
505    /* -0B70, */  0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x3a, 0x20, 0x0d, 0x0a, 0x74, 0x3d, 0x30, 0x20, 0x30, 0x2e,
506    /* -0B80, */  0x30, 0x2e, 0x30, 0x2e, 0x30, 0x0d, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x52,
507    /* -0B90, */  0x45, 0x47, 0x49, 0x53, 0x54, 0x45, 0x52, 0x20, 0x0d, 0x0a, 0x63, 0x3d, 0x49, 0x4e, 0x20, 0x49,
508    /* -0BA0, */  0x50, 0x36, 0x20, 0x31, 0x38, 0x30, 0x20, 0x52, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x31, 0x30,
509    /* -0BB0, */  0x30, 0x20, 0x54, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x76, 0x3d, 0x30, 0x0d, 0x0a, 0x6f, 0x3d, 0x55,
510    /* -0BC0, */  0x50, 0x44, 0x41, 0x54, 0x45, 0x20, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x59, 0x20, 0x0d, 0x0a, 0x53,
511    /* -0BD0, */  0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x3a, 0x20, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
512    /* -0BE0, */  0x6e, 0x41, 0x4d, 0x52, 0x54, 0x50, 0x2f, 0x41, 0x56, 0x50, 0x20, 0x0d, 0x0a, 0x50, 0x72, 0x69,
513    /* -0BF0, */  0x76, 0x61, 0x63, 0x79, 0x3a, 0x20, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
514    /* -0C00, */  0x2d, 0x0d, 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x0d, 0x0a, 0x61, 0x3d,
515    /* -0C10, */  0x72, 0x74, 0x70, 0x6d, 0x61, 0x70, 0x3a, 0x0d, 0x0a, 0x6d, 0x3d, 0x76, 0x69, 0x64, 0x65, 0x6f,
516    /* -0C20, */  0x20, 0x0d, 0x0a, 0x6d, 0x3d, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x0d, 0x0a, 0x73, 0x3d, 0x20,
517    /* -0C30, */  0x66, 0x61, 0x6c, 0x73, 0x65, 0x0d, 0x0a, 0x61, 0x3d, 0x63, 0x6f, 0x6e, 0x66, 0x3a, 0x3b, 0x65,
518    /* -0C40, */  0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x3d, 0x0d, 0x0a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x3a, 0x20,
519    /* -0C50, */  0x0d, 0x0a, 0x61, 0x3d, 0x66, 0x6d, 0x74, 0x70, 0x3a, 0x0d, 0x0a, 0x61, 0x3d, 0x63, 0x75, 0x72,
520    /* -0C60, */  0x72, 0x3a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79,
521    /* -0C70, */  0x3a, 0x20, 0x0d, 0x0a, 0x61, 0x3d, 0x64, 0x65, 0x73, 0x3a, 0x0d, 0x0a, 0x52, 0x41, 0x63, 0x6b,
522    /* -0C80, */  0x3a, 0x20, 0x0d, 0x0a, 0x52, 0x53, 0x65, 0x71, 0x3a, 0x20, 0x42, 0x59, 0x45, 0x20, 0x63, 0x6e,
523    /* -0C90, */  0x6f, 0x6e, 0x63, 0x65, 0x3d, 0x31, 0x30, 0x30, 0x72, 0x65, 0x6c, 0x75, 0x72, 0x69, 0x3d, 0x71,
524    /* -0CA0, */  0x6f, 0x70, 0x3d, 0x54, 0x43, 0x50, 0x55, 0x44, 0x50, 0x71, 0x6f, 0x73, 0x78, 0x6d, 0x6c, 0x3b,
525    /* -0CB0, */  0x6c, 0x72, 0x0d, 0x0a, 0x56, 0x69, 0x61, 0x3a, 0x20, 0x53, 0x49, 0x50, 0x2f, 0x32, 0x2e, 0x30,
526    /* -0CC0, */  0x2f, 0x54, 0x43, 0x50, 0x20, 0x34, 0x30, 0x38, 0x20, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
527    /* -0CD0, */  0x20, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x70, 0x73, 0x69, 0x70,
528    /* -0CE0, */  0x3a, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74,
529    /* -0CF0, */  0x68, 0x3a, 0x20, 0x4f, 0x63, 0x74, 0x20, 0x0d, 0x0a, 0x56, 0x69, 0x61, 0x3a, 0x20, 0x53, 0x49,
530    /* -0D00, */  0x50, 0x2f, 0x32, 0x2e, 0x30, 0x2f, 0x55, 0x44, 0x50, 0x20, 0x3b, 0x63, 0x6f, 0x6d, 0x70, 0x3d,
531    /* -0D10, */  0x73, 0x69, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x6f, 0x62, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61,
532    /* -0D20, */  0x63, 0x6b, 0x3b, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x3d, 0x7a, 0x39, 0x68, 0x47, 0x34, 0x62,
533    /* -0D30, */  0x4b, 0x0d, 0x0a, 0x4d, 0x61, 0x78, 0x2d, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x3a,
534    /* -0D40, */  0x20, 0x41, 0x70, 0x72, 0x20, 0x53, 0x43, 0x54, 0x50, 0x52, 0x41, 0x43, 0x4b, 0x20, 0x49, 0x4e,
535    /* -0D50, */  0x56, 0x49, 0x54, 0x45, 0x20, 0x0d, 0x0a, 0x43, 0x61, 0x6c, 0x6c, 0x2d, 0x49, 0x44, 0x3a, 0x20,
536    /* -0D60, */  0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x3a, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f,
537    /* -0D70, */  0x4b, 0x0d, 0x0a, 0x46, 0x72, 0x6f, 0x6d, 0x3a, 0x20, 0x0d, 0x0a, 0x43, 0x53, 0x65, 0x71, 0x3a,
538    /* -0D80, */  0x20, 0x0d, 0x0a, 0x54, 0x6f, 0x3a, 0x20, 0x3b, 0x74, 0x61, 0x67, 0x3d, 0x04, 0x10, 0xdd, 0x10,
539    /* -0D90, */  0x11, 0x31, 0x0d, 0x11, 0x0a, 0x07, 0x10, 0xb9, 0x0c, 0x10, 0xfe, 0x12, 0x10, 0xe1, 0x06, 0x11,
540    /* -0DA0, */  0x4e, 0x07, 0x11, 0x4e, 0x03, 0x11, 0x4a, 0x04, 0x11, 0x4a, 0x07, 0x10, 0xb2, 0x08, 0x11, 0x79,
541    /* -0DB0, */  0x06, 0x11, 0x81, 0x0f, 0x11, 0x22, 0x0b, 0x11, 0x55, 0x06, 0x11, 0x6b, 0x0b, 0x11, 0x60, 0x13,
542    /* -0DC0, */  0x10, 0xb2, 0x08, 0x11, 0x71, 0x05, 0x11, 0x87, 0x13, 0x10, 0xf7, 0x09, 0x0e, 0x8d, 0x08, 0x0d,
543    /* -0DD0, */  0xae, 0x0c, 0x10, 0xb9, 0x07, 0x10, 0x8e, 0x03, 0x0d, 0x96, 0x03, 0x10, 0x8a, 0x04, 0x10, 0x8a,
544    /* -0DE0, */  0x09, 0x0d, 0xd7, 0x0a, 0x0f, 0x12, 0x08, 0x0f, 0x8f, 0x09, 0x0f, 0x8f, 0x08, 0x0d, 0x6c, 0x06,
545    /* -0DF0, */  0x0e, 0x66, 0x09, 0x0e, 0x6c, 0x0a, 0x0e, 0x6c, 0x06, 0x0f, 0xc6, 0x07, 0x0f, 0xc6, 0x05, 0x11,
546    /* -0E00, */  0x48, 0x06, 0x11, 0x48, 0x06, 0x0f, 0xbf, 0x07, 0x0f, 0xbf, 0x07, 0x0e, 0x55, 0x06, 0x0f, 0x16,
547    /* -0E10, */  0x04, 0x0e, 0xf4, 0x03, 0x0e, 0xb1, 0x03, 0x10, 0xa6, 0x09, 0x10, 0x50, 0x03, 0x10, 0xa3, 0x0a,
548    /* -0E20, */  0x0d, 0xb4, 0x05, 0x0e, 0x36, 0x06, 0x0e, 0xd6, 0x03, 0x0d, 0xf9, 0x11, 0x0e, 0xf8, 0x04, 0x0c,
549    /* -0E30, */  0xd9, 0x08, 0x0e, 0xea, 0x04, 0x09, 0x53, 0x03, 0x0a, 0x4b, 0x04, 0x0e, 0xe4, 0x10, 0x0f, 0x35,
550    /* -0E40, */  0x09, 0x0e, 0xe4, 0x08, 0x0d, 0x3f, 0x03, 0x0f, 0xe1, 0x0b, 0x10, 0x01, 0x03, 0x10, 0xac, 0x06,
551    /* -0E50, */  0x10, 0x95, 0x0c, 0x0e, 0x76, 0x0b, 0x0f, 0xeb, 0x0a, 0x0f, 0xae, 0x05, 0x10, 0x2b, 0x04, 0x10,
552    /* -0E60, */  0x2b, 0x08, 0x10, 0x7a, 0x10, 0x0f, 0x49, 0x07, 0x0f, 0xb8, 0x09, 0x10, 0x3e, 0x0b, 0x10, 0x0c,
553    /* -0E70, */  0x07, 0x0f, 0x78, 0x0b, 0x0f, 0x6d, 0x09, 0x10, 0x47, 0x08, 0x10, 0x82, 0x0b, 0x0f, 0xf6, 0x08,
554    /* -0E80, */  0x10, 0x62, 0x08, 0x0f, 0x87, 0x08, 0x10, 0x6a, 0x04, 0x0f, 0x78, 0x0d, 0x0f, 0xcd, 0x08, 0x0d,
555    /* -0E90, */  0xae, 0x10, 0x0f, 0x5d, 0x0b, 0x0f, 0x98, 0x14, 0x0d, 0x20, 0x1b, 0x0d, 0x20, 0x04, 0x0d, 0xe0,
556    /* -0EA0, */  0x14, 0x0e, 0xb4, 0x0b, 0x0f, 0xa3, 0x0b, 0x07, 0x34, 0x0f, 0x0d, 0x56, 0x04, 0x0e, 0xf4, 0x03,
557    /* -0EB0, */  0x10, 0xaf, 0x07, 0x0d, 0x34, 0x09, 0x0f, 0x27, 0x04, 0x10, 0x9b, 0x04, 0x10, 0x9f, 0x09, 0x10,
558    /* -0EC0, */  0x59, 0x08, 0x10, 0x72, 0x09, 0x10, 0x35, 0x0a, 0x10, 0x21, 0x0a, 0x10, 0x17, 0x08, 0x0f, 0xe3,
559    /* -0ED0, */  0x03, 0x10, 0xa9, 0x05, 0x0c, 0xac, 0x04, 0x0c, 0xbd, 0x07, 0x0c, 0xc1, 0x08, 0x0c, 0xc1, 0x09,
560    /* -0EE0, */  0x0c, 0xf6, 0x10, 0x0c, 0x72, 0x0c, 0x0c, 0x86, 0x04, 0x0d, 0x64, 0x0c, 0x0c, 0xd5, 0x09, 0x0c,
561    /* -0EF0, */  0xff, 0x1b, 0x0b, 0xfc, 0x11, 0x0c, 0x5d, 0x13, 0x0c, 0x30, 0x09, 0x0c, 0xa4, 0x0c, 0x0c, 0x24,
562    /* -0F00, */  0x0c, 0x0d, 0x3b, 0x03, 0x0d, 0x1a, 0x03, 0x0d, 0x1d, 0x16, 0x0c, 0x43, 0x09, 0x0c, 0x92, 0x09,
563    /* -0F10, */  0x0c, 0x9b, 0x0d, 0x0e, 0xcb, 0x04, 0x0d, 0x16, 0x06, 0x0d, 0x10, 0x05, 0x04, 0xf2, 0x0b, 0x0c,
564    /* -0F20, */  0xe1, 0x05, 0x0b, 0xde, 0x0a, 0x0c, 0xec, 0x13, 0x0b, 0xe3, 0x07, 0x0b, 0xd4, 0x08, 0x0d, 0x08,
565    /* -0F30, */  0x0c, 0x0c, 0xc9, 0x09, 0x0c, 0x3a, 0x04, 0x0a, 0xe5, 0x0c, 0x0a, 0x23, 0x08, 0x0b, 0x3a, 0x0e,
566    /* -0F40, */  0x09, 0xab, 0x0f, 0x0e, 0xfa, 0x09, 0x0f, 0x6f, 0x0c, 0x0a, 0x17, 0x0f, 0x09, 0x76, 0x0c, 0x0a,
567    /* -0F50, */  0x5f, 0x17, 0x0d, 0xe2, 0x0f, 0x07, 0xa8, 0x0a, 0x0f, 0x85, 0x0f, 0x08, 0xd6, 0x0e, 0x09, 0xb9,
568    /* -0F60, */  0x0b, 0x0a, 0x7a, 0x03, 0x0b, 0xdb, 0x03, 0x08, 0xc1, 0x04, 0x0e, 0xc7, 0x03, 0x08, 0xd3, 0x02,
569    /* -0F70, */  0x04, 0x8d, 0x08, 0x0b, 0x4a, 0x05, 0x0b, 0x8c, 0x07, 0x0b, 0x61, 0x06, 0x05, 0x48, 0x04, 0x07,
570    /* -0F80, */  0xf4, 0x05, 0x10, 0x30, 0x04, 0x07, 0x1e, 0x08, 0x07, 0x1e, 0x05, 0x0b, 0x91, 0x10, 0x04, 0xca,
571    /* -0F90, */  0x09, 0x0a, 0x71, 0x09, 0x0e, 0x87, 0x05, 0x04, 0x98, 0x05, 0x0b, 0x6e, 0x0b, 0x04, 0x9b, 0x0f,
572    /* -0FA0, */  0x04, 0x9b, 0x07, 0x04, 0x9b, 0x03, 0x04, 0xa3, 0x07, 0x04, 0xa3, 0x10, 0x07, 0x98, 0x09, 0x07,
573    /* -0FB0, */  0x98, 0x05, 0x0b, 0x73, 0x05, 0x0b, 0x78, 0x05, 0x0b, 0x7d, 0x05, 0x07, 0xb9, 0x05, 0x0b, 0x82,
574    /* -0FC0, */  0x05, 0x0b, 0x87, 0x05, 0x0b, 0x1d, 0x05, 0x08, 0xe4, 0x05, 0x0c, 0x81, 0x05, 0x0f, 0x44, 0x05,
575    /* -0FD0, */  0x11, 0x40, 0x05, 0x08, 0x78, 0x05, 0x08, 0x9d, 0x05, 0x0f, 0x58, 0x05, 0x07, 0x3f, 0x05, 0x0c,
576    /* -0FE0, */  0x6d, 0x05, 0x10, 0xf2, 0x05, 0x0c, 0x58, 0x05, 0x06, 0xa9, 0x04, 0x07, 0xb6, 0x09, 0x05, 0x8c,
577    /* -0FF0, */  0x06, 0x06, 0x1a, 0x06, 0x0e, 0x81, 0x0a, 0x06, 0x16, 0x0a, 0x0a, 0xc4, 0x07, 0x0b, 0x5a, 0x0a,
578    /* -1000, */  0x0a, 0xba, 0x03, 0x0b, 0x1b, 0x04, 0x11, 0x45, 0x06, 0x0c, 0x8c, 0x07, 0x05, 0xad, 0x0a, 0x0e,
579    /* -1010, */  0xda, 0x08, 0x0b, 0x42, 0x0d, 0x09, 0xf7, 0x0b, 0x05, 0x1c, 0x09, 0x11, 0x16, 0x08, 0x05, 0xc9,
580    /* -1020, */  0x07, 0x0d, 0x86, 0x06, 0x0b, 0xcf, 0x0a, 0x06, 0x4d, 0x04, 0x0b, 0xa2, 0x06, 0x06, 0x8d, 0x08,
581    /* -1030, */  0x05, 0xe6, 0x08, 0x0e, 0x11, 0x0b, 0x0a, 0x9b, 0x03, 0x0a, 0x04, 0x03, 0x0b, 0xb5, 0x05, 0x10,
582    /* -1040, */  0xd7, 0x04, 0x09, 0x94, 0x05, 0x0a, 0xe2, 0x03, 0x0b, 0xb2, 0x06, 0x0d, 0x67, 0x04, 0x0d, 0x11,
583    /* -1050, */  0x08, 0x08, 0xb7, 0x1b, 0x0e, 0x3b, 0x0a, 0x09, 0xa1, 0x14, 0x04, 0x85, 0x15, 0x07, 0x83, 0x15,
584    /* -1060, */  0x07, 0x6e, 0x0d, 0x09, 0x3d, 0x17, 0x06, 0xae, 0x0f, 0x07, 0xe6, 0x14, 0x07, 0xbe, 0x0d, 0x06,
585    /* -1070, */  0x0a, 0x0d, 0x09, 0x30, 0x16, 0x06, 0xf2, 0x12, 0x08, 0x1e, 0x21, 0x04, 0xaa, 0x13, 0x10, 0xc5,
586    /* -1080, */  0x08, 0x0a, 0x0f, 0x1c, 0x0e, 0x96, 0x18, 0x0b, 0xb8, 0x1a, 0x05, 0x95, 0x1a, 0x05, 0x75, 0x11,
587    /* -1090, */  0x06, 0x3d, 0x16, 0x06, 0xdc, 0x1e, 0x0e, 0x19, 0x16, 0x05, 0xd1, 0x1d, 0x06, 0x20, 0x23, 0x05,
588    /* -10A0, */  0x27, 0x11, 0x08, 0x7d, 0x11, 0x0d, 0x99, 0x16, 0x04, 0xda, 0x0d, 0x0f, 0x1c, 0x16, 0x07, 0x08,
589    /* -10B0, */  0x17, 0x05, 0xb4, 0x0d, 0x08, 0xc7, 0x13, 0x07, 0xf8, 0x12, 0x08, 0x57, 0x1f, 0x04, 0xfe, 0x19,
590    /* -10C0, */  0x05, 0x4e, 0x13, 0x08, 0x0b, 0x0f, 0x08, 0xe9, 0x17, 0x06, 0xc5, 0x13, 0x06, 0x7b, 0x19, 0x05,
591    /* -10D0, */  0xf1, 0x15, 0x07, 0x44, 0x18, 0x0d, 0xfb, 0x0b, 0x0f, 0x09, 0x1b, 0x0d, 0xbe, 0x12, 0x08, 0x30,
592    /* -10E0, */  0x15, 0x07, 0x59, 0x04, 0x0b, 0xa6, 0x04, 0x0b, 0xae, 0x04, 0x0b, 0x9e, 0x04, 0x0b, 0x96, 0x04,
593    /* -10F0, */  0x0b, 0x9a, 0x0a, 0x0a, 0xb0, 0x0b, 0x0a, 0x90, 0x08, 0x0b, 0x32, 0x0b, 0x09, 0x6b, 0x08, 0x0b,
594    /* -1100, */  0x2a, 0x0b, 0x0a, 0x85, 0x09, 0x0b, 0x12, 0x0a, 0x0a, 0xa6, 0x0d, 0x09, 0xea, 0x13, 0x0d, 0x74,
595    /* -1110, */  0x14, 0x07, 0xd2, 0x13, 0x09, 0x0b, 0x12, 0x08, 0x42, 0x10, 0x09, 0x5b, 0x12, 0x09, 0x1e, 0x0d,
596    /* -1120, */  0x0c, 0xb1, 0x0e, 0x0c, 0x17, 0x11, 0x09, 0x4a, 0x0c, 0x0a, 0x53, 0x0c, 0x0a, 0x47, 0x09, 0x0a,
597    /* -1130, */  0xf7, 0x0e, 0x09, 0xc7, 0x0c, 0x0a, 0x3b, 0x07, 0x06, 0x69, 0x08, 0x06, 0x69, 0x06, 0x09, 0xe3,
598    /* -1140, */  0x08, 0x0b, 0x52, 0x0a, 0x0a, 0xd8, 0x12, 0x06, 0x57, 0x0d, 0x06, 0x57, 0x07, 0x09, 0xe3, 0x04,
599    /* -1150, */  0x0a, 0xe9, 0x10, 0x07, 0x30, 0x09, 0x0b, 0x00, 0x0c, 0x0a, 0x2f, 0x05, 0x0a, 0xe9, 0x05, 0x0a,
600    /* -1160, */  0x6b, 0x06, 0x0a, 0x6b, 0x0a, 0x0a, 0xce, 0x09, 0x0a, 0xee, 0x03, 0x0b, 0xdb, 0x07, 0x0f, 0x7e,
601    /* -1170, */  0x0a, 0x09, 0x97, 0x0a, 0x06, 0x71, 0x0e, 0x09, 0xd5, 0x17, 0x06, 0x93, 0x07, 0x0e, 0x5c, 0x07,
602    /* -1180, */  0x0f, 0xda, 0x0a, 0x0f, 0x35, 0x0d, 0x0d, 0xec, 0x0a, 0x09, 0x97, 0x0a, 0x06, 0x71, 0x08, 0x0b,
603    /* -1190, */  0x22, 0x0f, 0x09, 0x85, 0x06, 0x0b, 0x68, 0x0c, 0x0d, 0x4a, 0x09, 0x0b, 0x09, 0x13, 0x08, 0xf8,
604    /* -11A0, */  0x15, 0x08, 0xa2, 0x04, 0x0b, 0xaa, 0x0f, 0x05, 0x66, 0x0d, 0x07, 0x23, 0x09, 0x0a, 0x06, 0x0b,
605    /* -11B0, */  0x0d, 0x4a, 0x0f, 0x04, 0xee, 0x06, 0x04, 0xf8, 0x04, 0x09, 0x2b, 0x04, 0x08, 0x53, 0x07, 0x08,
606    /* -11C0, */  0xc0, 0x03, 0x11, 0x1f, 0x04, 0x11, 0x1e, 0x07, 0x0d, 0x8c, 0x03, 0x07, 0x34, 0x04, 0x10, 0xdb,
607    /* -11D0, */  0x03, 0x07, 0x36, 0x03, 0x0d, 0xa9, 0x0d, 0x04, 0x20, 0x0b, 0x04, 0x51, 0x0c, 0x04, 0x3a, 0x04,
608    /* -11E0, */  0x0b, 0xb8, 0x04, 0x0c, 0x24, 0x04, 0x05, 0x95, 0x04, 0x04, 0x7c, 0x04, 0x05, 0x75, 0x04, 0x04,
609    /* -11F0, */  0x85, 0x04, 0x09, 0x6b, 0x04, 0x06, 0x3d, 0x06, 0x04, 0x7b, 0x04, 0x06, 0xdc, 0x04, 0x07, 0x83,
610    /* -1200, */  0x04, 0x0e, 0x19, 0x12, 0x04, 0x00, 0x10, 0x08, 0x8e, 0x10, 0x08, 0x69, 0x0e, 0x04, 0x12, 0x0d,
611    /* -1210, */  0x04, 0x2d, 0x03, 0x10, 0xb9, 0x04, 0x05, 0xd1, 0x04, 0x07, 0x6e, 0x04, 0x06, 0x20, 0x07, 0x04,
612    /* -1220, */  0x74, 0x04, 0x0b, 0xfc, 0x0a, 0x04, 0x5c, 0x04, 0x05, 0x27, 0x04, 0x09, 0x3d, 0x04, 0x08, 0x7d,
613    /* -1230, */  0x04, 0x0f, 0xae, 0x04, 0x0d, 0x99, 0x04, 0x06, 0xae, 0x04, 0x04, 0xda, 0x09, 0x04, 0x09, 0x08,
614    /* -1240, */  0x11, 0x22, 0x04, 0x0f, 0x1c, 0x04, 0x07, 0xe6, 0x04, 0x0e, 0xcb, 0x05, 0x08, 0xbd, 0x04, 0x07,
615    /* -1250, */  0x08, 0x04, 0x0f, 0xa3, 0x04, 0x06, 0x57, 0x04, 0x05, 0xb4, 0x04, 0x0f, 0x5d, 0x04, 0x08, 0xc7,
616    /* -1260, */  0x08, 0x0b, 0xf4, 0x04, 0x07, 0xf8, 0x04, 0x07, 0x30, 0x04, 0x07, 0xbe, 0x04, 0x08, 0x57, 0x05,
617    /* -1270, */  0x0d, 0x46, 0x04, 0x04, 0xfe, 0x04, 0x06, 0x0a, 0x04, 0x05, 0x4e, 0x04, 0x0e, 0x3b, 0x04, 0x08,
618    /* -1280, */  0x0b, 0x04, 0x09, 0x30, 0x04, 0x08, 0xe9, 0x05, 0x05, 0xee, 0x04, 0x06, 0xc5, 0x04, 0x06, 0xf2,
619    /* -1290, */  0x04, 0x06, 0x7b, 0x04, 0x09, 0xa1, 0x04, 0x05, 0xf1, 0x04, 0x08, 0x1e, 0x04, 0x07, 0x44, 0x04,
620    /* -12A0, */  0x0b, 0xdd, 0x04, 0x0d, 0xfb, 0x04, 0x04, 0xaa, 0x04, 0x0b, 0xe3, 0x07, 0x0e, 0xee, 0x04, 0x0f,
621    /* -12B0, */  0x09, 0x04, 0x0e, 0xb4, 0x04, 0x0d, 0xbe, 0x04, 0x10, 0xc5, 0x04, 0x08, 0x30, 0x05, 0x0f, 0x30,
622    /* -12C0, */  0x04, 0x07, 0x59, 0x04, 0x0a, 0x0f, 0x06, 0x0e, 0x61, 0x04, 0x04, 0x81, 0x04, 0x0d, 0xab, 0x04,
623    /* -12D0, */  0x0d, 0x93, 0x04, 0x11, 0x6b, 0x04, 0x0e, 0x96, 0x05, 0x04, 0x66, 0x09, 0x04, 0x6b, 0x0b, 0x04,
624    /* -12E0, */  0x46, 0x04, 0x0c, 0xe1
625
626 };
627
628 /*
629  * Definitions for:
630  * The Presence-Specific Static Dictionary for Signaling
631  * http://www.ietf.org/rfc/rfc5112.txt?number=5112
632  */
633 #define PRESENCE_STATE_LENGTH 0x0d93
634
635 static const guint8 presence_state_identifier[STATE_BUFFER_SIZE] =
636 {
637    /* -0000, */  0xd9, 0x42, 0x29, 0x7d, 0x0b, 0xb3, 0x8f, 0xc0, 0x1d, 0x67, 0x41, 0xd6, 0xb3, 0xb4, 0x81, 0x57,
638    /* -0010, */  0xac, 0x8e, 0x1b, 0xe0
639 };
640
641 static const guint8 presence_static_dictionary_for_sigcomp[PRESENCE_STATE_LENGTH] =
642 {
643    /* -0000, */  0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x63, 0x65, 0x6e, 0x74, 0x65,
644    /* -0010, */  0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x65, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64,
645    /* -0020, */  0x69, 0x73, 0x67, 0x75, 0x73, 0x74, 0x65, 0x64, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69,
646    /* -0030, */  0x61, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x3d, 0x68, 0x75, 0x6d, 0x69,
647    /* -0040, */  0x6c, 0x69, 0x61, 0x74, 0x65, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x3d, 0x61, 0x75, 0x74, 0x6f,
648    /* -0050, */  0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x63, 0x75, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x70, 0x69, 0x72,
649    /* -0060, */  0x69, 0x74, 0x73, 0x2d, 0x49, 0x4e, 0x44, 0x50, 0x73, 0x65, 0x6e, 0x64, 0x2d, 0x6f, 0x6e, 0x6c,
650    /* -0070, */  0x79, 0x70, 0x61, 0x74, 0x68, 0x65, 0x61, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x6c, 0x65, 0x73,
651    /* -0080, */  0x73, 0x6c, 0x65, 0x65, 0x70, 0x79, 0x69, 0x6e, 0x2d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61,
652    /* -0090, */  0x6c, 0x6f, 0x6e, 0x65, 0x6c, 0x79, 0x70, 0x6c, 0x61, 0x79, 0x66, 0x75, 0x6c, 0x6f, 0x77, 0x65,
653    /* -00A0, */  0x72, 0x74, 0x68, 0x61, 0x6e, 0x6e, 0x6f, 0x79, 0x65, 0x64, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x66,
654    /* -00B0, */  0x6f, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x3d, 0x63, 0x6f,
655    /* -00C0, */  0x6e, 0x66, 0x75, 0x73, 0x65, 0x64, 0x76, 0x61, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x63, 0x6c,
656    /* -00D0, */  0x75, 0x62, 0x75, 0x73, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x63,
657    /* -00E0, */  0x72, 0x61, 0x66, 0x74, 0x68, 0x69, 0x72, 0x73, 0x74, 0x79, 0x63, 0x6f, 0x75, 0x72, 0x69, 0x65,
658    /* -00F0, */  0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x68, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x66, 0x6f,
659    /* -0100, */  0x66, 0x66, 0x69, 0x63, 0x65, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x3d, 0x61, 0x72, 0x65, 0x6e,
660    /* -0110, */  0x61, 0x62, 0x6c, 0x65, 0x64, 0x3d, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54,
661    /* -0120, */  0x45, 0x52, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x72, 0x75, 0x6d, 0x70, 0x79, 0x70, 0x72,
662    /* -0130, */  0x65, 0x66, 0x69, 0x78, 0x3d, 0x68, 0x61, 0x6c, 0x66, 0x72, 0x65, 0x69, 0x67, 0x68, 0x74, 0x6d,
663    /* -0140, */  0x65, 0x61, 0x6e, 0x67, 0x72, 0x79, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x42, 0x45, 0x70,
664    /* -0150, */  0x72, 0x6f, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x3d,
665    /* -0160, */  0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x68, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x75,
666    /* -0170, */  0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x70, 0x61, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x4d, 0x45, 0x53,
667    /* -0180, */  0x53, 0x41, 0x47, 0x45, 0x77, 0x6f, 0x72, 0x72, 0x69, 0x65, 0x64, 0x68, 0x75, 0x6d, 0x62, 0x6c,
668    /* -0190, */  0x65, 0x64, 0x61, 0x69, 0x72, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x73, 0x68, 0x61, 0x6d, 0x65, 0x64,
669    /* -01A0, */  0x70, 0x6c, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x68, 0x75,
670    /* -01B0, */  0x6e, 0x67, 0x72, 0x79, 0x63, 0x72, 0x61, 0x6e, 0x6b, 0x79, 0x61, 0x6d, 0x61, 0x7a, 0x65, 0x64,
671    /* -01C0, */  0x61, 0x66, 0x72, 0x61, 0x69, 0x64, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x4e, 0x4f, 0x54, 0x49,
672    /* -01D0, */  0x46, 0x59, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x66, 0x72,
673    /* -01E0, */  0x69, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x73, 0x74, 0x61, 0x6c, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79,
674    /* -01F0, */  0x70, 0x72, 0x69, 0x73, 0x6f, 0x6e, 0x69, 0x6e, 0x5f, 0x61, 0x77, 0x65, 0x62, 0x72, 0x61, 0x76,
675    /* -0200, */  0x65, 0x71, 0x75, 0x69, 0x65, 0x74, 0x62, 0x6f, 0x72, 0x65, 0x64, 0x50, 0x52, 0x41, 0x43, 0x4b,
676    /* -0210, */  0x70, 0x72, 0x6f, 0x75, 0x64, 0x66, 0x69, 0x78, 0x65, 0x64, 0x68, 0x6f, 0x74, 0x65, 0x6c, 0x68,
677    /* -0220, */  0x61, 0x70, 0x70, 0x79, 0x63, 0x61, 0x66, 0x65, 0x63, 0x69, 0x64, 0x3d, 0x62, 0x61, 0x6e, 0x6b,
678    /* -0230, */  0x6d, 0x69, 0x6e, 0x3d, 0x61, 0x77, 0x61, 0x79, 0x6d, 0x61, 0x78, 0x3d, 0x6d, 0x65, 0x61, 0x6c,
679    /* -0240, */  0x62, 0x75, 0x73, 0x79, 0x77, 0x6f, 0x72, 0x6b, 0x75, 0x72, 0x6e, 0x3d, 0x63, 0x6f, 0x6c, 0x64,
680    /* -0250, */  0x68, 0x75, 0x72, 0x74, 0x6a, 0x65, 0x61, 0x6c, 0x6f, 0x75, 0x73, 0x70, 0x69, 0x72, 0x69, 0x74,
681    /* -0260, */  0x73, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x70, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e,
682    /* -0270, */  0x6d, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
683    /* -0280, */  0x6f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x66,
684    /* -0290, */  0x6f, 0x72, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2d,
685    /* -02A0, */  0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73,
686    /* -02B0, */  0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x3d, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72,
687    /* -02C0, */  0x74, 0x68, 0x61, 0x6e, 0x78, 0x69, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2d,
688    /* -02D0, */  0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x62, 0x72, 0x65, 0x61,
689    /* -02E0, */  0x6b, 0x66, 0x61, 0x73, 0x74, 0x61, 0x64, 0x69, 0x75, 0x6d, 0x73, 0x67, 0x2d, 0x74, 0x61, 0x6b,
690    /* -02F0, */  0x65, 0x72, 0x65, 0x6d, 0x6f, 0x72, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x6c, 0x3a, 0x63, 0x69, 0x76,
691    /* -0300, */  0x69, 0x63, 0x4c, 0x6f, 0x63, 0x6f, 0x6e, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x71, 0x75,
692    /* -0310, */  0x61, 0x6c, 0x73, 0x74, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x77, 0x61, 0x74, 0x65, 0x72, 0x63,
693    /* -0320, */  0x72, 0x61, 0x66, 0x74, 0x65, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3a, 0x62, 0x61, 0x73, 0x69, 0x63,
694    /* -0330, */  0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79,
695    /* -0340, */  0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x3d, 0x61, 0x64, 0x64,
696    /* -0350, */  0x65, 0x64, 0x75, 0x72, 0x69, 0x3d, 0x77, 0x68, 0x61, 0x74, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e,
697    /* -0360, */  0x65, 0x6e, 0x74, 0x2d, 0x61, 0x62, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x72,
698    /* -0370, */  0x61, 0x73, 0x73, 0x65, 0x64, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x64, 0x69,
699    /* -0380, */  0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x64, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x76, 0x6f, 0x75,
700    /* -0390, */  0x73, 0x65, 0x6c, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x6c, 0x69, 0x65, 0x76, 0x65, 0x64,
701    /* -03A0, */  0x66, 0x6c, 0x69, 0x72, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x2d, 0x72,
702    /* -03B0, */  0x75, 0x6c, 0x65, 0x73, 0x65, 0x72, 0x76, 0x63, 0x61, 0x70, 0x73, 0x70, 0x68, 0x65, 0x72, 0x65,
703    /* -03C0, */  0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x65,
704    /* -03D0, */  0x3d, 0x62, 0x61, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x78, 0x74,
705    /* -03E0, */  0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2d, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x65, 0x74, 0x69, 0x6d, 0x65,
706    /* -03F0, */  0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x64, 0x69, 0x61, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f,
707    /* -0400, */  0x6c, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x77, 0x69, 0x6c, 0x6c,
708    /* -0410, */  0x69, 0x6e, 0x67, 0x6e, 0x65, 0x73, 0x73, 0x70, 0x65, 0x63, 0x74, 0x61, 0x74, 0x6f, 0x72, 0x65,
709    /* -0420, */  0x73, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2d, 0x70, 0x61, 0x63, 0x6b,
710    /* -0430, */  0x61, 0x67, 0x65, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x65, 0x73, 0x74,
711    /* -0440, */  0x61, 0x75, 0x72, 0x61, 0x6e, 0x74, 0x72, 0x75, 0x63, 0x6b, 0x70, 0x6c, 0x6d, 0x6f, 0x62, 0x69,
712    /* -0450, */  0x6c, 0x69, 0x74, 0x79, 0x6a, 0x6f, 0x69, 0x6e, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x70, 0x72, 0x69,
713    /* -0460, */  0x61, 0x74, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x65, 0x72, 0x69, 0x6e,
714    /* -0470, */  0x67, 0x69, 0x76, 0x65, 0x75, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x61, 0x6e,
715    /* -0480, */  0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
716    /* -0490, */  0x2d, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2d, 0x6f, 0x66,
717    /* -04A0, */  0x2d, 0x77, 0x6f, 0x72, 0x73, 0x68, 0x69, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2d, 0x74, 0x79, 0x70,
718    /* -04B0, */  0x65, 0x3d, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2d,
719    /* -04C0, */  0x69, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x75, 0x74,
720    /* -04D0, */  0x72, 0x61, 0x6c, 0x49, 0x4e, 0x46, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x69, 0x65, 0x6d,
721    /* -04E0, */  0x65, 0x6e, 0x73, 0x2d, 0x52, 0x54, 0x50, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x65, 0x72, 0x76,
722    /* -04F0, */  0x69, 0x63, 0x65, 0x2d, 0x69, 0x64, 0x6c, 0x65, 0x2d, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f,
723    /* -0500, */  0x6c, 0x64, 0x3d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70,
724    /* -0510, */  0x6f, 0x72, 0x74, 0x6f, 0x6f, 0x62, 0x72, 0x69, 0x67, 0x68, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65,
725    /* -0520, */  0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3d, 0x3a, 0x67, 0x65, 0x6f, 0x70, 0x72, 0x69,
726    /* -0530, */  0x76, 0x31, 0x30, 0x30, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70,
727    /* -0540, */  0x6f, 0x63, 0x2d, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x75, 0x72, 0x70, 0x72, 0x69,
728    /* -0550, */  0x73, 0x65, 0x64, 0x61, 0x72, 0x6b, 0x75, 0x72, 0x6e, 0x3a, 0x6f, 0x6d, 0x61, 0x3a, 0x78, 0x6d,
729    /* -0560, */  0x6c, 0x3a, 0x70, 0x72, 0x73, 0x3a, 0x70, 0x69, 0x64, 0x66, 0x3a, 0x6f, 0x6d, 0x61, 0x2d, 0x70,
730    /* -0570, */  0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x6f, 0x69, 0x73, 0x79, 0x3a,
731    /* -0580, */  0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2d, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x65,
732    /* -0590, */  0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x64, 0x6f, 0x6f, 0x72, 0x73, 0x63, 0x68, 0x6f, 0x6f,
733    /* -05A0, */  0x6c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d,
734    /* -05B0, */  0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6d, 0x65, 0x65, 0x74,
735    /* -05C0, */  0x69, 0x6e, 0x67, 0x63, 0x61, 0x6c, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x74, 0x6f, 0x72,
736    /* -05D0, */  0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x3a,
737    /* -05E0, */  0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x66, 0x66, 0x65, 0x6e, 0x64,
738    /* -05F0, */  0x65, 0x64, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x2d,
739    /* -0600, */  0x66, 0x6f, 0x72, 0x2d, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x77, 0x61, 0x74, 0x63, 0x68,
740    /* -0610, */  0x65, 0x72, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x70, 0x6c, 0x61, 0x63, 0x65,
741    /* -0620, */  0x2d, 0x69, 0x73, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x77, 0x61,
742    /* -0630, */  0x79, 0x68, 0x6f, 0x6d, 0x65, 0x70, 0x61, 0x67, 0x65, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79,
743    /* -0640, */  0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x69, 0x6e, 0x70, 0x75, 0x74,
744    /* -0650, */  0x72, 0x61, 0x76, 0x65, 0x6c, 0x62, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76,
745    /* -0660, */  0x65, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x3a, 0x72, 0x6c, 0x6d, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x75,
746    /* -0670, */  0x65, 0x3d, 0x3a, 0x63, 0x61, 0x70, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x69, 0x6e, 0x67, 0x75, 0x69,
747    /* -0680, */  0x6c, 0x74, 0x79, 0x69, 0x6e, 0x76, 0x69, 0x6e, 0x63, 0x69, 0x62, 0x6c, 0x65, 0x76, 0x65, 0x6e,
748    /* -0690, */  0x74, 0x3d, 0x6d, 0x6f, 0x6f, 0x64, 0x79, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x3d, 0x70,
749    /* -06A0, */  0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x66, 0x72, 0x6f, 0x6d,
750    /* -06B0, */  0x3d, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x63, 0x61, 0x72, 0x64, 0x70, 0x6f, 0x73, 0x3d, 0x61, 0x75,
751    /* -06C0, */  0x74, 0x6f, 0x6d, 0x61, 0x74, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
752    /* -06D0, */  0x6f, 0x74, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
753    /* -06E0, */  0x49, 0x44, 0x69, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x69, 0x73, 0x61, 0x70, 0x70,
754    /* -06F0, */  0x6f, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x6e, 0x6f, 0x74, 0x65, 0x2d, 0x77, 0x65, 0x6c, 0x6c, 0x69,
755    /* -0700, */  0x62, 0x72, 0x61, 0x72, 0x79, 0x3a, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x6c,
756    /* -0710, */  0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x69, 0x76, 0x69, 0x63, 0x41, 0x64, 0x64, 0x72,
757    /* -0720, */  0x65, 0x73, 0x73, 0x61, 0x72, 0x63, 0x61, 0x73, 0x74, 0x69, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
758    /* -0730, */  0x74, 0x65, 0x64, 0x69, 0x6e, 0x64, 0x69, 0x67, 0x6e, 0x61, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x72,
759    /* -0740, */  0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x73, 0x68, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x63, 0x6c, 0x61,
760    /* -0750, */  0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
761    /* -0760, */  0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x2d, 0x62, 0x79, 0x3a, 0x63, 0x69, 0x70, 0x69, 0x64,
762    /* -0770, */  0x66, 0x2d, 0x66, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3d, 0x61, 0x63, 0x74, 0x6f,
763    /* -0780, */  0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x65,
764    /* -0790, */  0x72, 0x69, 0x6f, 0x75, 0x73, 0x65, 0x6c, 0x3d, 0x3a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x78,
765    /* -07A0, */  0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x3a, 0x72, 0x70, 0x69, 0x64, 0x75, 0x72, 0x6e, 0x3a, 0x69,
766    /* -07B0, */  0x65, 0x74, 0x66, 0x3a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x78, 0x6d, 0x6c, 0x2d, 0x70,
767    /* -07C0, */  0x61, 0x74, 0x63, 0x68, 0x2d, 0x6f, 0x70, 0x73, 0x65, 0x63, 0x2d, 0x61, 0x67, 0x72, 0x65, 0x65,
768    /* -07D0, */  0x61, 0x72, 0x6c, 0x79, 0x2d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x70, 0x61, 0x74,
769    /* -07E0, */  0x69, 0x63, 0x69, 0x70, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x74, 0x68, 0x65, 0x2d, 0x70, 0x68,
770    /* -07F0, */  0x6f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2d, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62,
771    /* -0800, */  0x69, 0x6c, 0x69, 0x74, 0x79, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65,
772    /* -0810, */  0x78, 0x63, 0x69, 0x74, 0x65, 0x64, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69,
773    /* -0820, */  0x6f, 0x6e, 0x6f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6f,
774    /* -0830, */  0x72, 0x69, 0x74, 0x79, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2d,
775    /* -0840, */  0x63, 0x6c, 0x61, 0x73, 0x73, 0x72, 0x6f, 0x6f, 0x6d, 0x75, 0x73, 0x74, 0x55, 0x6e, 0x64, 0x65,
776    /* -0850, */  0x72, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2d, 0x6e, 0x61, 0x6d,
777    /* -0860, */  0x65, 0x3d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
778    /* -0870, */  0x6f, 0x6e, 0x73, 0x2d, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x64, 0x70, 0x2d, 0x61,
779    /* -0880, */  0x6e, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x64, 0x61, 0x6e, 0x74, 0x72, 0x75, 0x65, 0x3a, 0x70, 0x69,
780    /* -0890, */  0x64, 0x66, 0x2d, 0x64, 0x69, 0x66, 0x66, 0x72, 0x75, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x64,
781    /* -08A0, */  0x75, 0x70, 0x6c, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x63, 0x6f,
782    /* -08B0, */  0x6e, 0x74, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x68, 0x6f, 0x70, 0x70,
783    /* -08C0, */  0x69, 0x6e, 0x67, 0x2d, 0x61, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3d, 0x61, 0x70, 0x70, 0x6f,
784    /* -08D0, */  0x69, 0x6e, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3d, 0x61, 0x73, 0x73, 0x6f, 0x63,
785    /* -08E0, */  0x69, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x69, 0x6e, 0x74, 0x65,
786    /* -08F0, */  0x72, 0x65, 0x73, 0x74, 0x65, 0x64, 0x65, 0x76, 0x63, 0x61, 0x70, 0x73, 0x74, 0x61, 0x74, 0x75,
787    /* -0900, */  0x73, 0x3d, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x77, 0x69,
788    /* -0910, */  0x6e, 0x66, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x72, 0x61,
789    /* -0920, */  0x6e, 0x73, 0x69, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x68, 0x6f, 0x73, 0x70, 0x69, 0x74, 0x61, 0x6c,
790    /* -0930, */  0x61, 0x6e, 0x67, 0x3d, 0x3c, 0x3f, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3d, 0x73, 0x69, 0x63, 0x6b,
791    /* -0940, */  0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x3f, 0x3e, 0x63,
792    /* -0950, */  0x6c, 0x6f, 0x73, 0x65, 0x64, 0x05, 0x0d, 0x34, 0x08, 0x0d, 0x06, 0x09, 0x0c, 0xe3, 0x07, 0x0d,
793    /* -0960, */  0x48, 0x06, 0x0d, 0x36, 0x13, 0x0b, 0xab, 0x05, 0x09, 0x65, 0x07, 0x0c, 0xd4, 0x08, 0x0d, 0x40,
794    /* -0970, */  0x05, 0x0d, 0x23, 0x05, 0x0c, 0x35, 0x07, 0x0c, 0xae, 0x05, 0x0d, 0x2f, 0x06, 0x08, 0xb9, 0x05,
795    /* -0980, */  0x07, 0x2b, 0x04, 0x0d, 0x12, 0x06, 0x0d, 0x4f, 0x09, 0x0c, 0x2c, 0x04, 0x0c, 0x89, 0x04, 0x0a,
796    /* -0990, */  0xf6, 0x09, 0x0b, 0x57, 0x0b, 0x0b, 0x05, 0x08, 0x0a, 0xda, 0x06, 0x0a, 0xda, 0x06, 0x04, 0x89,
797    /* -09A0, */  0x05, 0x0b, 0xa6, 0x04, 0x0b, 0x94, 0x06, 0x05, 0x05, 0x07, 0x0b, 0x3f, 0x0e, 0x0b, 0xba, 0x07,
798    /* -09B0, */  0x0b, 0x98, 0x0a, 0x0c, 0x8d, 0x09, 0x0b, 0x6d, 0x09, 0x0c, 0x8e, 0x0e, 0x0c, 0x48, 0x0a, 0x0c,
799    /* -09C0, */  0xb2, 0x1d, 0x09, 0x56, 0x0d, 0x0c, 0x38, 0x06, 0x07, 0xba, 0x0b, 0x08, 0xb9, 0x0b, 0x07, 0xec,
800    /* -09D0, */  0x06, 0x0d, 0x02, 0x0a, 0x0a, 0x46, 0x04, 0x08, 0xf4, 0x06, 0x0b, 0x6a, 0x04, 0x0a, 0xb6, 0x0c,
801    /* -09E0, */  0x0c, 0x55, 0x08, 0x0a, 0x31, 0x04, 0x0a, 0x92, 0x08, 0x0a, 0x1b, 0x05, 0x0a, 0xb1, 0x04, 0x08,
802    /* -09F0, */  0xc0, 0x05, 0x0a, 0x27, 0x05, 0x0a, 0xa7, 0x05, 0x0a, 0xac, 0x04, 0x0a, 0xba, 0x04, 0x07, 0xdc,
803    /* -0A00, */  0x05, 0x08, 0xad, 0x0a, 0x09, 0x29, 0x0a, 0x08, 0xa7, 0x05, 0x0a, 0x56, 0x05, 0x0b, 0x4d, 0x07,
804    /* -0A10, */  0x09, 0x2a, 0x0d, 0x09, 0xa7, 0x0b, 0x07, 0xa9, 0x06, 0x09, 0xc6, 0x0b, 0x0b, 0x5f, 0x0c, 0x09,
805    /* -0A20, */  0xdf, 0x0b, 0x09, 0xe0, 0x06, 0x07, 0xcb, 0x0c, 0x0a, 0x0b, 0x09, 0x09, 0x20, 0x08, 0x0a, 0x97,
806    /* -0A30, */  0x07, 0x09, 0xe0, 0x07, 0x0c, 0xfb, 0x06, 0x0a, 0x8c, 0x0e, 0x09, 0x7f, 0x0a, 0x09, 0x87, 0x0b,
807    /* -0A40, */  0x0c, 0x71, 0x0a, 0x0c, 0x71, 0x06, 0x07, 0x93, 0x05, 0x0a, 0x66, 0x04, 0x08, 0x67, 0x04, 0x09,
808    /* -0A50, */  0xba, 0x08, 0x09, 0x20, 0x0a, 0x0b, 0x72, 0x05, 0x0a, 0x72, 0x08, 0x07, 0xb3, 0x0b, 0x0a, 0xc5,
809    /* -0A60, */  0x07, 0x09, 0xf2, 0x07, 0x08, 0x89, 0x04, 0x08, 0xad, 0x08, 0x0a, 0xbe, 0x06, 0x0c, 0x9f, 0x0b,
810    /* -0A70, */  0x06, 0xd0, 0x0e, 0x08, 0x26, 0x08, 0x0a, 0x9f, 0x07, 0x09, 0xc6, 0x0a, 0x0c, 0x69, 0x07, 0x08,
811    /* -0A80, */  0x85, 0x05, 0x0b, 0x7c, 0x07, 0x0a, 0x39, 0x0c, 0x09, 0x34, 0x07, 0x0a, 0x21, 0x09, 0x08, 0x7d,
812    /* -0A90, */  0x07, 0x0c, 0xf5, 0x0b, 0x0c, 0xa3, 0x14, 0x06, 0xa6, 0x0d, 0x08, 0xb2, 0x0c, 0x07, 0x2a, 0x0c,
813    /* -0AA0, */  0x08, 0xb3, 0x04, 0x07, 0x56, 0x07, 0x09, 0x1a, 0x04, 0x07, 0x52, 0x07, 0x07, 0x40, 0x05, 0x07,
814    /* -0AB0, */  0x4d, 0x07, 0x0b, 0x80, 0x06, 0x07, 0x47, 0x16, 0x06, 0x91, 0x08, 0x0c, 0x62, 0x10, 0x09, 0xcf,
815    /* -0AC0, */  0x10, 0x07, 0xdd, 0x09, 0x0a, 0xf6, 0x09, 0x06, 0xfc, 0x0c, 0x0b, 0x17, 0x07, 0x07, 0x39, 0x04,
816    /* -0AD0, */  0x06, 0xf8, 0x07, 0x09, 0xa1, 0x06, 0x06, 0x8d, 0x05, 0x07, 0x21, 0x04, 0x0a, 0x55, 0x09, 0x0a,
817    /* -0AE0, */  0xd2, 0x0c, 0x0a, 0xcf, 0x13, 0x06, 0xc8, 0x0a, 0x08, 0xec, 0x07, 0x0d, 0x06, 0x0b, 0x08, 0x0c,
818    /* -0AF0, */  0x14, 0x0b, 0xd5, 0x12, 0x07, 0xbe, 0x0d, 0x07, 0xd1, 0x16, 0x08, 0x01, 0x14, 0x0b, 0xf1, 0x06,
819    /* -0B00, */  0x05, 0xb4, 0x07, 0x04, 0x56, 0x09, 0x04, 0x17, 0x0c, 0x0a, 0xea, 0x09, 0x04, 0x1f, 0x0a, 0x07,
820    /* -0B10, */  0x7e, 0x0b, 0x07, 0x6a, 0x07, 0x0c, 0x0f, 0x0b, 0x07, 0xa0, 0x0a, 0x0c, 0x96, 0x06, 0x05, 0x28,
821    /* -0B20, */  0x06, 0x0a, 0x7d, 0x05, 0x06, 0x1f, 0x07, 0x05, 0x8b, 0x0a, 0x04, 0x3c, 0x06, 0x05, 0xae, 0x04,
822    /* -0B30, */  0x06, 0x50, 0x09, 0x0a, 0xe2, 0x06, 0x05, 0xf6, 0x07, 0x07, 0xfd, 0x09, 0x0b, 0x33, 0x0a, 0x0c,
823    /* -0B40, */  0xec, 0x0a, 0x0a, 0x83, 0x07, 0x06, 0x54, 0x06, 0x04, 0x90, 0x04, 0x05, 0x3f, 0x05, 0x0a, 0x92,
824    /* -0B50, */  0x07, 0x07, 0x8a, 0x07, 0x08, 0xcc, 0x08, 0x09, 0xea, 0x07, 0x04, 0x96, 0x05, 0x06, 0x10, 0x08,
825    /* -0B60, */  0x07, 0x98, 0x0a, 0x06, 0xf1, 0x08, 0x04, 0x79, 0x09, 0x0b, 0x22, 0x07, 0x0b, 0x8e, 0x07, 0x0b,
826    /* -0B70, */  0x46, 0x04, 0x0d, 0x3c, 0x06, 0x04, 0x80, 0x08, 0x07, 0x12, 0x09, 0x09, 0x4a, 0x07, 0x04, 0xe3,
827    /* -0B80, */  0x07, 0x05, 0x84, 0x05, 0x09, 0x7a, 0x05, 0x06, 0x01, 0x09, 0x09, 0x12, 0x04, 0x09, 0x52, 0x0d,
828    /* -0B90, */  0x04, 0xaa, 0x0d, 0x08, 0x56, 0x08, 0x04, 0xdc, 0x07, 0x05, 0x92, 0x05, 0x05, 0x0c, 0x0a, 0x04,
829    /* -0BA0, */  0x4c, 0x04, 0x06, 0x2c, 0x0b, 0x04, 0xd1, 0x04, 0x06, 0x24, 0x09, 0x0c, 0x40, 0x04, 0x04, 0xce,
830    /* -0BB0, */  0x0c, 0x08, 0xc1, 0x11, 0x04, 0x00, 0x05, 0x07, 0x34, 0x0a, 0x06, 0x6a, 0x08, 0x0d, 0x28, 0x05,
831    /* -0BC0, */  0x06, 0x1a, 0x0a, 0x04, 0x28, 0x07, 0x0a, 0xfe, 0x06, 0x04, 0xff, 0x08, 0x09, 0x94, 0x07, 0x05,
832    /* -0BD0, */  0x76, 0x10, 0x08, 0x98, 0x06, 0x05, 0xf0, 0x06, 0x09, 0x03, 0x10, 0x09, 0x03, 0x09, 0x08, 0x1e,
833    /* -0BE0, */  0x0a, 0x08, 0x3c, 0x06, 0x09, 0x9b, 0x0d, 0x0c, 0xbb, 0x07, 0x06, 0xe3, 0x05, 0x09, 0xcc, 0x06,
834    /* -0BF0, */  0x0a, 0x15, 0x07, 0x04, 0x73, 0x05, 0x06, 0x73, 0x0d, 0x06, 0x73, 0x05, 0x08, 0x45, 0x08, 0x0a,
835    /* -0C00, */  0x29, 0x09, 0x0a, 0x40, 0x05, 0x07, 0x1a, 0x0a, 0x07, 0x1a, 0x09, 0x0b, 0x4f, 0x09, 0x0c, 0xdb,
836    /* -0C10, */  0x06, 0x05, 0xea, 0x06, 0x05, 0xde, 0x0a, 0x04, 0x0e, 0x0a, 0x0b, 0x0e, 0x09, 0x06, 0x86, 0x08,
837    /* -0C20, */  0x05, 0x60, 0x0b, 0x07, 0x74, 0x09, 0x05, 0x4f, 0x08, 0x04, 0xf0, 0x07, 0x09, 0x90, 0x06, 0x08,
838    /* -0C30, */  0x70, 0x0a, 0x0c, 0x21, 0x07, 0x05, 0x6f, 0x0b, 0x0c, 0xcc, 0x04, 0x07, 0x90, 0x07, 0x04, 0xea,
839    /* -0C40, */  0x0a, 0x08, 0x33, 0x04, 0x06, 0x34, 0x09, 0x06, 0xdc, 0x04, 0x06, 0x40, 0x07, 0x05, 0x2e, 0x04,
840    /* -0C50, */  0x06, 0x48, 0x06, 0x07, 0x87, 0x07, 0x05, 0x68, 0x0a, 0x0d, 0x1a, 0x07, 0x04, 0x45, 0x07, 0x05,
841    /* -0C60, */  0x05, 0x08, 0x05, 0x0e, 0x08, 0x05, 0x58, 0x08, 0x04, 0xb6, 0x10, 0x09, 0xf8, 0x04, 0x06, 0x3c,
842    /* -0C70, */  0x07, 0x09, 0xbc, 0x0c, 0x06, 0xd0, 0x0c, 0x0b, 0xe7, 0x04, 0x06, 0x44, 0x04, 0x0a, 0x31, 0x0b,
843    /* -0C80, */  0x0c, 0x05, 0x04, 0x06, 0x28, 0x11, 0x07, 0x5a, 0x07, 0x0c, 0xc5, 0x07, 0x05, 0xa0, 0x0c, 0x09,
844    /* -0C90, */  0x6f, 0x08, 0x0c, 0xbb, 0x08, 0x0a, 0x76, 0x09, 0x08, 0x16, 0x08, 0x08, 0x69, 0x06, 0x05, 0xe4,
845    /* -0CA0, */  0x09, 0x04, 0x86, 0x07, 0x05, 0x38, 0x06, 0x0a, 0x4f, 0x08, 0x04, 0xc6, 0x0f, 0x08, 0xf4, 0x0b,
846    /* -0CB0, */  0x04, 0x31, 0x07, 0x0a, 0x04, 0x07, 0x08, 0xa1, 0x0d, 0x0c, 0x55, 0x06, 0x05, 0xc0, 0x06, 0x05,
847    /* -0CC0, */  0xba, 0x05, 0x05, 0x41, 0x08, 0x0b, 0x87, 0x08, 0x04, 0x89, 0x04, 0x05, 0x35, 0x0c, 0x0a, 0x5a,
848    /* -0CD0, */  0x09, 0x04, 0x68, 0x09, 0x04, 0x9c, 0x0a, 0x06, 0xba, 0x06, 0x07, 0x0d, 0x05, 0x07, 0x25, 0x09,
849    /* -0CE0, */  0x0b, 0x9d, 0x09, 0x0a, 0x69, 0x06, 0x0a, 0x6c, 0x04, 0x06, 0x38, 0x04, 0x06, 0x30, 0x07, 0x0d,
850    /* -0CF0, */  0x13, 0x08, 0x08, 0x4c, 0x05, 0x06, 0x15, 0x06, 0x04, 0x50, 0x0a, 0x07, 0x04, 0x06, 0x07, 0xf7,
851    /* -0D00, */  0x04, 0x08, 0x49, 0x0f, 0x08, 0x89, 0x0c, 0x09, 0x3f, 0x05, 0x06, 0x81, 0x11, 0x08, 0xdc, 0x0d,
852    /* -0D10, */  0x04, 0x5c, 0x11, 0x06, 0x5a, 0x05, 0x0d, 0x0e, 0x06, 0x05, 0xd8, 0x04, 0x08, 0xd3, 0x06, 0x05,
853    /* -0D20, */  0xd2, 0x07, 0x05, 0x7d, 0x06, 0x05, 0xcc, 0x07, 0x08, 0xd6, 0x05, 0x06, 0x0b, 0x07, 0x05, 0xa7,
854    /* -0D30, */  0x05, 0x05, 0x16, 0x08, 0x05, 0x1a, 0x09, 0x05, 0x46, 0x06, 0x05, 0xc6, 0x06, 0x09, 0x31, 0x0d,
855    /* -0D40, */  0x0b, 0xcf, 0x09, 0x08, 0x62, 0x08, 0x04, 0xf8, 0x04, 0x08, 0x54, 0x0a, 0x06, 0x7f, 0x04, 0x04,
856    /* -0D50, */  0x71, 0x0c, 0x0c, 0x16, 0x04, 0x05, 0x2e, 0x08, 0x0b, 0x3f, 0x11, 0x0c, 0x23, 0x08, 0x0c, 0x7b,
857    /* -0D60, */  0x09, 0x0b, 0xc7, 0x07, 0x07, 0xf6, 0x05, 0x0b, 0x3b, 0x09, 0x08, 0x75, 0x09, 0x0c, 0x81, 0x09,
858    /* -0D70, */  0x06, 0xe9, 0x0b, 0x09, 0xb0, 0x07, 0x05, 0x22, 0x07, 0x04, 0xa3, 0x07, 0x06, 0xc2, 0x07, 0x05,
859    /* -0D80, */  0x99, 0x05, 0x06, 0x06, 0x05, 0x05, 0xfc, 0x04, 0x09, 0xc3, 0x04, 0x06, 0x4c, 0x08, 0x04, 0xbe,
860    /* -0D90, */  0x09, 0x0b, 0x2a
861 };
862
863 static GHashTable *state_buffer_table=NULL;
864
865
866 static void
867 sigcomp_init_udvm(void) {
868
869     gchar  *partial_state_str;
870     guint8 *sip_sdp_buff, *presence_buff;
871
872     /* Destroy any existing memory chunks / hashes. */
873     if (state_buffer_table) {
874         g_hash_table_destroy(state_buffer_table);
875     }
876
877
878     state_buffer_table = g_hash_table_new_full(g_str_hash,
879                                                g_str_equal,
880                                                g_free, /* key_destroy_func */
881                                                g_free); /* value_destroy_func */
882     /*
883      * Store static dictionaries in hash table
884      */
885     sip_sdp_buff = (guint8 *)g_malloc(SIP_SDP_STATE_LENGTH + 8);
886
887     partial_state_str = bytes_to_str(NULL, sip_sdp_state_identifier, 6);
888
889     /*
890      * Debug  g_warning("Sigcomp init: Storing partial state =%s",partial_state_str);
891      */
892     memset(sip_sdp_buff, 0, 8);
893     sip_sdp_buff[0] = SIP_SDP_STATE_LENGTH >> 8;
894     sip_sdp_buff[1] = SIP_SDP_STATE_LENGTH & 0xff;
895     memcpy(sip_sdp_buff+8, sip_sdp_static_dictionaty_for_sigcomp, SIP_SDP_STATE_LENGTH);
896
897     g_hash_table_insert(state_buffer_table, g_strdup(partial_state_str), sip_sdp_buff);
898     wmem_free(NULL, partial_state_str);
899     /* Debug
900      *  g_warning("g_hash_table_insert = 0x%x",sip_sdp_buff);
901      *  g_warning("g_hash_table_insert = 0x%x",sip_sdp_buff);
902      */
903
904     presence_buff = (guint8 *)g_malloc(PRESENCE_STATE_LENGTH + 8);
905
906     partial_state_str = bytes_to_str(NULL, presence_state_identifier, 6);
907
908     memset(presence_buff, 0, 8);
909     presence_buff[0] = PRESENCE_STATE_LENGTH >> 8;
910     presence_buff[1] = PRESENCE_STATE_LENGTH & 0xff;
911     memcpy(presence_buff+8, presence_static_dictionary_for_sigcomp, PRESENCE_STATE_LENGTH);
912
913     g_hash_table_insert(state_buffer_table, g_strdup(partial_state_str), presence_buff);
914     wmem_free(NULL, partial_state_str);
915 }
916
917
918 static int udvm_state_access(tvbuff_t *tvb, proto_tree *tree,guint8 *buff,guint16 p_id_start, guint16 p_id_length, guint16 state_begin, guint16 *state_length,
919                              guint16 *state_address, guint16 *state_instruction,
920                              gint hf_id)
921 {
922     int      result_code = 0;
923     guint32  n;
924     guint16  k;
925     guint16  buf_size_real;
926     guint16  byte_copy_right;
927     guint16  byte_copy_left;
928     char     partial_state[STATE_BUFFER_SIZE]; /* Size is 6 - 20 */
929     guint8  *state_buff;
930     gchar   *partial_state_str;
931
932     /*
933      * Perform initial checks on validity of data
934      * RFC 3320 :
935      * 9.4.5.  STATE-ACCESS
936      * :
937      * Decompression failure occurs if partial_identifier_length does not
938      * lie between 6 and 20 inclusive.  Decompression failure also occurs if
939      * no state item matching the partial state identifier can be found, if
940      * more than one state item matches the partial identifier, or if
941      * partial_identifier_length is less than the minimum_access_length of
942      * the matched state item. Otherwise, a state item is returned from the
943      * state handler.
944      */
945
946     if (( p_id_length < STATE_MIN_ACCESS_LEN ) || ( p_id_length > STATE_BUFFER_SIZE )) {
947         result_code = 1;
948         return result_code;
949     }
950
951     n = 0;
952     while ( n < p_id_length && n < STATE_BUFFER_SIZE && p_id_start + n < UDVM_MEMORY_SIZE ) {
953         partial_state[n] = buff[p_id_start + n];
954         n++;
955     }
956     partial_state_str = bytes_to_str(wmem_packet_scope(), partial_state, p_id_length);
957     proto_tree_add_text(tree,tvb, 0, -1,"### Accessing state ###");
958     proto_tree_add_string(tree,hf_id, tvb, 0, 0, partial_state_str);
959
960     /* Debug
961      * g_warning("State Access: partial state =%s",partial_state_str);
962      * g_warning("g_hash_table_lookup = 0x%x",state_buff);
963      * g_warning("State Access: partial state =%s",partial_state_str);
964      */
965     state_buff = (guint8 *)g_hash_table_lookup(state_buffer_table, partial_state_str);
966     if ( state_buff == NULL ) {
967         result_code = 2; /* No state match */
968         return result_code;
969     }
970     /*
971      * sip_sdp_static_dictionaty
972      *
973      * 8.4.  Byte copying
974      * :
975      * The string of bytes is copied in ascending order of memory address,
976      * respecting the bounds set by byte_copy_left and byte_copy_right.
977      * More precisely, if a byte is copied from/to Address m then the next
978      * byte is copied from/to Address n where n is calculated as follows:
979      *
980      * Set k := m + 1 (modulo 2^16)
981      * If k = byte_copy_right then set n := byte_copy_left, else set n := k
982      *
983      */
984
985     /*
986      * buff              = Where "state" will be stored
987      * p_id_start        = Partial state identifier start pos in the buffer(buff)
988      * p-id_length       = Partial state identifier length
989      * state_begin       = Where to start to read state from
990      * state_length      = Length of state
991      * state_address     = Address where to store the state in the buffer(buff)
992      * state_instruction =
993      * FALSE             = Indicates that state_* is in the stored state
994      */
995
996     buf_size_real = (state_buff[0] << 8) | state_buff[1];
997
998     /*
999      * The value of
1000      * state_length MUST be taken from the returned item of state in the
1001      * case that the state_length operand is set to 0.
1002      *
1003      * The same is true of state_address, state_instruction.
1004      */
1005     if (*state_length == 0) {
1006         *state_length = buf_size_real;
1007     }
1008     if ( *state_address == 0 ) {
1009         *state_address = state_buff[2] << 8;
1010         *state_address = *state_address | state_buff[3];
1011     }
1012     if ( *state_instruction == 0 ) {
1013         *state_instruction = state_buff[4] << 8;
1014         *state_instruction = *state_instruction | state_buff[5];
1015     }
1016
1017     /*
1018      * Decompression failure occurs if bytes are copied from beyond the end of
1019      * the state_value.
1020      */
1021     if ((state_begin + *state_length) > buf_size_real) {
1022         return 3;
1023     }
1024
1025     /*
1026      * Note that decompression failure will always occur if the state_length
1027      * operand is set to 0 but the state_begin operand is non-zero.
1028      */
1029     if (*state_length == 0 && state_begin != 0) {
1030         return 17;
1031     }
1032
1033     n = state_begin + 8;
1034     k = *state_address;
1035
1036     /*
1037      * NOTE: Strictly speaking, byte_copy_left and byte_copy_right should
1038      *       not be used if this has been called for bytecode referenced in
1039      *       the message header. However, since the memory is initialised
1040      *       to zero, the code works OK.
1041      */
1042     byte_copy_right = buff[66] << 8;
1043     byte_copy_right = byte_copy_right | buff[67];
1044     byte_copy_left = buff[64] << 8;
1045     byte_copy_left = byte_copy_left | buff[65];
1046     /* debug
1047      *g_warning(" state_begin %u state_address %u",state_begin , *state_address);
1048      */
1049     while ( (gint32) n < (state_begin + *state_length + 8) && n < UDVM_MEMORY_SIZE ) {
1050         buff[k] = state_buff[n];
1051         /*  debug
1052             g_warning(" Loading 0x%x at address %u",buff[k] , k);
1053         */
1054         k = ( k + 1 ) & 0xffff;
1055         if ( k == byte_copy_right ) {
1056             k = byte_copy_left;
1057         }
1058         n++;
1059     }
1060     return 0;
1061     /*
1062      * End SIP
1063      */
1064
1065 }
1066
1067 static void udvm_state_create(guint8 *state_buff,guint8 *state_identifier,guint16 p_id_length) {
1068
1069     char   partial_state[STATE_BUFFER_SIZE];
1070     guint  i;
1071     gchar *partial_state_str;
1072     gchar *dummy_buff;
1073     /*
1074      * Debug
1075      g_warning("Received items of state,state_length_buff[0]= %u, state_length_buff[1]= %u",
1076      state_length_buff[0],state_length_buff[1]);
1077
1078     */
1079     i = 0;
1080     while ( i < p_id_length && i < STATE_BUFFER_SIZE ) {
1081         partial_state[i] = state_identifier[i];
1082         i++;
1083     }
1084     partial_state_str = bytes_to_str(NULL, partial_state, p_id_length);
1085
1086     dummy_buff = (gchar *)g_hash_table_lookup(state_buffer_table, partial_state_str);
1087     if ( dummy_buff == NULL ) {
1088         g_hash_table_insert(state_buffer_table, g_strdup(partial_state_str), state_buff);
1089     } else {
1090         /* The buffer allocated by sigcomp-udvm.c wasen't needed so free it
1091          */
1092         g_free(state_buff);
1093
1094     }
1095     wmem_free(NULL, partial_state_str);
1096 }
1097
1098 #if 1
1099 static void udvm_state_free(guint8 buff[] _U_,guint16 p_id_start _U_,guint16 p_id_length _U_) {
1100 }
1101 #else
1102 void udvm_state_free(guint8 buff[],guint16 p_id_start,guint16 p_id_length) {
1103     char   partial_state[STATE_BUFFER_SIZE];
1104     guint  i;
1105     gchar *partial_state_str;
1106
1107     gchar *dummy_buff;
1108
1109     i = 0;
1110     while ( i < p_id_length && i < STATE_BUFFER_SIZE && p_id_start + i < UDVM_MEMORY_SIZE ) {
1111         partial_state[i] = buff[p_id_start + i];
1112         i++;
1113     }
1114     partial_state_str = bytes_to_str(NULL, partial_state, p_id_length);
1115     /* TODO Implement a state create counter before actually freeing states
1116      * Hmm is it a good idea to free the buffer at all?
1117      */
1118     g_warning("State-free on  %s ",partial_state_str);
1119     dummy_buff = g_hash_table_lookup(state_buffer_table, partial_state_str);
1120     if ( dummy_buff == NULL ) {
1121         g_warning("State-free, state not found  %s",partial_state_str);
1122     } else {
1123         g_hash_table_remove (state_buffer_table, partial_state_str);
1124         g_free(dummy_buff);
1125     }
1126     wmem_free(NULL, partial_state_str);
1127 }
1128 #endif
1129
1130 /**********************************************************************************************
1131  *
1132  *                       SIGCOMP DECOMPRESSION
1133  *
1134  **********************************************************************************************/
1135 #define SIGCOMP_INSTR_DECOMPRESSION_FAILURE     0
1136 #define SIGCOMP_INSTR_AND                       1
1137 #define SIGCOMP_INSTR_OR                        2
1138 #define SIGCOMP_INSTR_NOT                       3
1139 #define SIGCOMP_INSTR_LSHIFT                    4
1140 #define SIGCOMP_INSTR_RSHIFT                    5
1141 #define SIGCOMP_INSTR_ADD                       6
1142 #define SIGCOMP_INSTR_SUBTRACT                  7
1143 #define SIGCOMP_INSTR_MULTIPLY                  8
1144 #define SIGCOMP_INSTR_DIVIDE                    9
1145 #define SIGCOMP_INSTR_REMAINDER                 10
1146 #define SIGCOMP_INSTR_SORT_ASCENDING            11
1147 #define SIGCOMP_INSTR_SORT_DESCENDING           12
1148 #define SIGCOMP_INSTR_SHA_1                     13
1149 #define SIGCOMP_INSTR_LOAD                      14
1150 #define SIGCOMP_INSTR_MULTILOAD                 15
1151 #define SIGCOMP_INSTR_PUSH                      16
1152 #define SIGCOMP_INSTR_POP                       17
1153 #define SIGCOMP_INSTR_COPY                      18
1154 #define SIGCOMP_INSTR_COPY_LITERAL              19
1155 #define SIGCOMP_INSTR_COPY_OFFSET               20
1156 #define SIGCOMP_INSTR_MEMSET                    21
1157 #define SIGCOMP_INSTR_JUMP                      22
1158 #define SIGCOMP_INSTR_COMPARE                   23
1159 #define SIGCOMP_INSTR_CALL                      24
1160 #define SIGCOMP_INSTR_RETURN                    25
1161 #define SIGCOMP_INSTR_SWITCH                    26
1162 #define SIGCOMP_INSTR_CRC                       27
1163 #define SIGCOMP_INSTR_INPUT_BYTES               28
1164 #define SIGCOMP_INSTR_INPUT_BITS                29
1165 #define SIGCOMP_INSTR_INPUT_HUFFMAN             30
1166 #define SIGCOMP_INSTR_STATE_ACCESS              31
1167 #define SIGCOMP_INSTR_STATE_CREATE              32
1168 #define SIGCOMP_INSTR_STATE_FREE                33
1169 #define SIGCOMP_INSTR_OUTPUT                    34
1170 #define SIGCOMP_INSTR_END_MESSAGE               35
1171
1172 static const value_string udvm_instruction_code_vals[] = {
1173     { SIGCOMP_INSTR_DECOMPRESSION_FAILURE,   "DECOMPRESSION-FAILURE" },
1174     { SIGCOMP_INSTR_AND,   "AND" },
1175     { SIGCOMP_INSTR_OR,   "OR" },
1176     { SIGCOMP_INSTR_NOT,   "NOT" },
1177     { SIGCOMP_INSTR_LSHIFT,   "LSHIFT" },
1178     { SIGCOMP_INSTR_RSHIFT,   "RSHIFT" },
1179     { SIGCOMP_INSTR_ADD,   "ADD" },
1180     { SIGCOMP_INSTR_SUBTRACT,   "SUBTRACT" },
1181     { SIGCOMP_INSTR_MULTIPLY,   "MULTIPLY" },
1182     { SIGCOMP_INSTR_DIVIDE,   "DIVIDE" },
1183     { SIGCOMP_INSTR_REMAINDER,   "REMAINDER" },
1184     { SIGCOMP_INSTR_SORT_ASCENDING,   "SORT-ASCENDING" },
1185     { SIGCOMP_INSTR_SORT_DESCENDING,   "SORT-DESCENDING" },
1186     { SIGCOMP_INSTR_SHA_1,   "SHA-1" },
1187     { SIGCOMP_INSTR_LOAD,   "LOAD" },
1188     { SIGCOMP_INSTR_MULTILOAD,   "MULTILOAD" },
1189     { SIGCOMP_INSTR_PUSH,   "PUSH" },
1190     { SIGCOMP_INSTR_POP,   "POP" },
1191     { SIGCOMP_INSTR_COPY,   "COPY" },
1192     { SIGCOMP_INSTR_COPY_LITERAL,   "COPY-LITERAL" },
1193     { SIGCOMP_INSTR_COPY_OFFSET,   "COPY-OFFSET" },
1194     { SIGCOMP_INSTR_MEMSET,   "MEMSET" },
1195     { SIGCOMP_INSTR_JUMP,   "JUMP" },
1196     { SIGCOMP_INSTR_COMPARE,   "COMPARE" },
1197     { SIGCOMP_INSTR_CALL,   "CALL" },
1198     { SIGCOMP_INSTR_RETURN,   "RETURN" },
1199     { SIGCOMP_INSTR_SWITCH,   "SWITCH" },
1200     { SIGCOMP_INSTR_CRC,   "CRC" },
1201     { SIGCOMP_INSTR_INPUT_BYTES,   "INPUT-BYTES" },
1202     { SIGCOMP_INSTR_INPUT_BITS,   "INPUT-BITS" },
1203     { SIGCOMP_INSTR_INPUT_HUFFMAN,   "INPUT-HUFFMAN" },
1204     { SIGCOMP_INSTR_STATE_ACCESS,   "STATE-ACCESS" },
1205     { SIGCOMP_INSTR_STATE_CREATE,   "STATE-CREATE" },
1206     { SIGCOMP_INSTR_STATE_FREE,   "STATE-FREE" },
1207     { SIGCOMP_INSTR_OUTPUT,   "OUTPUT" },
1208     { SIGCOMP_INSTR_END_MESSAGE,   "END-MESSAGE" },
1209     { 0,    NULL }
1210 };
1211 static value_string_ext udvm_instruction_code_vals_ext =
1212     VALUE_STRING_EXT_INIT(udvm_instruction_code_vals);
1213
1214 /* Internal result code values of decompression failures */
1215 static const value_string result_code_vals[] = {
1216     {  0, "No decompression failure" },
1217     {  1, "Partial state length less than 6 or greater than 20 bytes long" },
1218     {  2, "No state match" },
1219     {  3, "state_begin + state_length > size of state" },
1220     {  4, "Operand_2 is Zero" },
1221     {  5, "Switch statement failed j >= n" },
1222     {  6, "Attempt to jump outside of UDVM memory" },
1223     {  7, "L in input-bits > 16" },
1224     {  8, "input_bit_order > 7" },
1225     {  9, "Instruction Decompression failure encountered" },
1226     { 10, "Input huffman failed j > n" },
1227     { 11, "Input bits requested beyond end of message" },
1228     { 12, "more than four state creation requests are made before the END-MESSAGE instruction" },
1229     { 13, "state_retention_priority is 65535" },
1230     { 14, "Input bytes requested beyond end of message" },
1231     { 15, "Maximum number of UDVM cycles reached" },
1232     { 16, "UDVM stack underflow" },
1233     { 17, "state_length is 0, but state_begin is non-zero" },
1234     {255, "This branch isn't coded yet" },
1235     { 0,    NULL }
1236 };
1237
1238  /*  The simplest operand type is the literal (#), which encodes a
1239   * constant integer from 0 to 65535 inclusive.  A literal operand may
1240   * require between 1 and 3 bytes depending on its value.
1241   * Bytecode:                       Operand value:      Range:
1242   * 0nnnnnnn                        N                   0 - 127
1243   * 10nnnnnn nnnnnnnn               N                   0 - 16383
1244   * 11000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
1245   *
1246   *            Figure 8: Bytecode for a literal (#) operand
1247   *
1248   */
1249 static int
1250 decode_udvm_literal_operand(guint8 *buff,guint operand_address, guint16 *value)
1251 {
1252     guint   bytecode;
1253     guint16 operand;
1254     guint   test_bits;
1255     guint   offset = operand_address;
1256     guint8  temp_data;
1257
1258     bytecode = buff[operand_address];
1259     test_bits = bytecode >> 7;
1260     if (test_bits == 1) {
1261         test_bits = bytecode >> 6;
1262         if (test_bits == 2) {
1263             /*
1264              * 10nnnnnn nnnnnnnn               N                   0 - 16383
1265              */
1266             temp_data = buff[operand_address] & 0x1f;
1267             operand = temp_data << 8;
1268             temp_data = buff[(operand_address + 1) & 0xffff];
1269             operand = operand | temp_data;
1270             *value = operand;
1271             offset = offset + 2;
1272
1273         } else {
1274             /*
1275              * 111000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
1276              */
1277             offset ++;
1278             temp_data = buff[operand_address] & 0x1f;
1279             operand = temp_data << 8;
1280             temp_data = buff[(operand_address + 1) & 0xffff];
1281             operand = operand | temp_data;
1282             *value = operand;
1283             offset = offset + 2;
1284
1285         }
1286     } else {
1287         /*
1288          * 0nnnnnnn                        N                   0 - 127
1289          */
1290         operand = ( bytecode & 0x7f);
1291         *value = operand;
1292         offset ++;
1293     }
1294
1295     return offset;
1296
1297 }
1298
1299 /*
1300  * The second operand type is the reference ($), which is always used to
1301  * access a 2-byte value located elsewhere in the UDVM memory.  The
1302  * bytecode for a reference operand is decoded to be a constant integer
1303  * from 0 to 65535 inclusive, which is interpreted as the memory address
1304  * containing the actual value of the operand.
1305  * Bytecode:                       Operand value:      Range:
1306  *
1307  * 0nnnnnnn                        memory[2 * N]       0 - 65535
1308  * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
1309  * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
1310  *
1311  *            Figure 9: Bytecode for a reference ($) operand
1312  */
1313 static int
1314 dissect_udvm_reference_operand_memory(guint8 *buff,guint operand_address, guint16 *value,guint *result_dest)
1315 {
1316     guint   bytecode;
1317     guint16 operand;
1318     guint   offset = operand_address;
1319     guint   test_bits;
1320     guint8  temp_data;
1321     guint16 temp_data16;
1322
1323     bytecode = buff[operand_address];
1324     test_bits = bytecode >> 7;
1325     if (test_bits == 1) {
1326         test_bits = bytecode >> 6;
1327         if (test_bits == 2) {
1328             /*
1329              * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
1330              */
1331             temp_data = buff[operand_address] & 0x3f;
1332             operand = temp_data << 8;
1333             temp_data = buff[(operand_address + 1) & 0xffff];
1334             operand = operand | temp_data;
1335             operand = (operand * 2);
1336             *result_dest = operand;
1337             temp_data16 = buff[operand] << 8;
1338             temp_data16 = temp_data16 | buff[(operand+1) & 0xffff];
1339             *value = temp_data16;
1340             offset = offset + 2;
1341
1342         } else {
1343             /*
1344              * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
1345              */
1346             operand_address++;
1347             operand = buff[operand_address] << 8;
1348             operand = operand | buff[(operand_address + 1) & 0xffff];
1349             *result_dest = operand;
1350             temp_data16 = buff[operand] << 8;
1351             temp_data16 = temp_data16 | buff[(operand+1) & 0xffff];
1352             *value = temp_data16;
1353             offset = offset + 3;
1354
1355         }
1356     } else {
1357         /*
1358          * 0nnnnnnn                        memory[2 * N]       0 - 65535
1359          */
1360         operand = ( bytecode & 0x7f);
1361         operand = (operand * 2);
1362         *result_dest = operand;
1363         temp_data16 = buff[operand] << 8;
1364         temp_data16 = temp_data16 | buff[(operand+1) & 0xffff];
1365         *value = temp_data16;
1366         offset ++;
1367     }
1368
1369     if (offset >= UDVM_MEMORY_SIZE || *result_dest >= UDVM_MEMORY_SIZE - 1 )
1370         THROW(ReportedBoundsError);
1371
1372     return offset;
1373 }
1374
1375 /* RFC3320
1376  * Figure 10: Bytecode for a multitype (%) operand
1377  * Bytecode:                       Operand value:      Range:           HEX val
1378  * 00nnnnnn                        N                   0 - 63           0x00
1379  * 01nnnnnn                        memory[2 * N]       0 - 65535        0x40
1380  * 1000011n                        2 ^ (N + 6)        64 , 128          0x86
1381  * 10001nnn                        2 ^ (N + 8)    256 , ... , 32768     0x88
1382  * 111nnnnn                        N + 65504       65504 - 65535        0xe0
1383  * 1001nnnn nnnnnnnn               N + 61440       61440 - 65535        0x90
1384  * 101nnnnn nnnnnnnn               N                   0 - 8191         0xa0
1385  * 110nnnnn nnnnnnnn               memory[N]           0 - 65535        0xc0
1386  * 10000000 nnnnnnnn nnnnnnnn      N                   0 - 65535        0x80
1387  * 10000001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535        0x81
1388  */
1389 static int
1390 decode_udvm_multitype_operand(guint8 *buff,guint operand_address, guint16 *value)
1391 {
1392     guint   test_bits;
1393     guint   bytecode;
1394     guint   offset = operand_address;
1395     guint16 operand;
1396     guint32 result;
1397     guint8  temp_data;
1398     guint16 temp_data16;
1399     guint16 memmory_addr = 0;
1400
1401     *value = 0;
1402
1403     bytecode = buff[operand_address];
1404     test_bits = ( bytecode & 0xc0 ) >> 6;
1405     switch (test_bits ) {
1406     case 0:
1407         /*
1408          * 00nnnnnn                        N                   0 - 63
1409          */
1410         operand =  buff[operand_address];
1411         /* debug
1412          *g_warning("Reading 0x%x From address %u",operand,offset);
1413          */
1414         *value = operand;
1415         offset ++;
1416         break;
1417     case 1:
1418         /*
1419          * 01nnnnnn                        memory[2 * N]       0 - 65535
1420          */
1421         memmory_addr = ( bytecode & 0x3f) * 2;
1422         temp_data16 = buff[memmory_addr] << 8;
1423         temp_data16 = temp_data16 | buff[(memmory_addr+1) & 0xffff];
1424         *value = temp_data16;
1425         offset ++;
1426         break;
1427     case 2:
1428         /* Check tree most significant bits */
1429         test_bits = ( bytecode & 0xe0 ) >> 5;
1430         if ( test_bits == 5 ) {
1431             /*
1432              * 101nnnnn nnnnnnnn               N                   0 - 8191
1433              */
1434             temp_data = buff[operand_address] & 0x1f;
1435             operand = temp_data << 8;
1436             temp_data = buff[(operand_address + 1) & 0xffff];
1437             operand = operand | temp_data;
1438             *value = operand;
1439             offset = offset + 2;
1440         } else {
1441             test_bits = ( bytecode & 0xf0 ) >> 4;
1442             if ( test_bits == 9 ) {
1443                 /*
1444                  * 1001nnnn nnnnnnnn               N + 61440       61440 - 65535
1445                  */
1446                 temp_data = buff[operand_address] & 0x0f;
1447                 operand = temp_data << 8;
1448                 temp_data = buff[(operand_address + 1) & 0xffff];
1449                 operand = operand | temp_data;
1450                 operand = operand + 61440;
1451                 *value = operand;
1452                 offset = offset + 2;
1453             } else {
1454                 test_bits = ( bytecode & 0x08 ) >> 3;
1455                 if ( test_bits == 1) {
1456                     /*
1457                      * 10001nnn                        2 ^ (N + 8)    256 , ... , 32768
1458                      */
1459
1460                     result = 1 << ((buff[operand_address] & 0x07) + 8);
1461                     operand = result & 0xffff;
1462                     *value = operand;
1463                     offset ++;
1464                 } else {
1465                     test_bits = ( bytecode & 0x0e ) >> 1;
1466                     if ( test_bits == 3 ) {
1467                         /*
1468                          * 1000 011n                        2 ^ (N + 6)        64 , 128
1469                          */
1470                         result = 1 << ((buff[operand_address] & 0x01) + 6);
1471                         operand = result & 0xffff;
1472                         *value = operand;
1473                         offset ++;
1474                     } else {
1475                         /*
1476                          * 1000 0000 nnnnnnnn nnnnnnnn      N                   0 - 65535
1477                          * 1000 0001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
1478                          */
1479                         offset ++;
1480                         temp_data16 = buff[(operand_address + 1) & 0xffff] << 8;
1481                         temp_data16 = temp_data16 | buff[(operand_address + 2) & 0xffff];
1482                         /*  debug
1483                          * g_warning("Reading 0x%x From address %u",temp_data16,operand_address);
1484                          */
1485                         if ( (bytecode & 0x01) == 1 ) {
1486                             memmory_addr = temp_data16;
1487                             temp_data16 = buff[memmory_addr] << 8;
1488                             temp_data16 = temp_data16 | buff[(memmory_addr+1) & 0xffff];
1489                         }
1490                         *value = temp_data16;
1491                         offset = offset +2;
1492                     }
1493
1494
1495                 }
1496             }
1497         }
1498         break;
1499
1500     case 3:
1501         test_bits = ( bytecode & 0x20 ) >> 5;
1502         if ( test_bits == 1 ) {
1503             /*
1504              * 111nnnnn                        N + 65504       65504 - 65535
1505              */
1506             operand = ( buff[operand_address] & 0x1f) + 65504;
1507             *value = operand;
1508             offset ++;
1509         } else {
1510             /*
1511              * 110nnnnn nnnnnnnn               memory[N]           0 - 65535
1512              */
1513             memmory_addr = buff[operand_address] & 0x1f;
1514             memmory_addr = memmory_addr << 8;
1515             memmory_addr = memmory_addr | buff[(operand_address + 1) & 0xffff];
1516             temp_data16 = buff[memmory_addr] << 8;
1517             temp_data16 = temp_data16 | buff[(memmory_addr+1) & 0xffff];
1518             *value = temp_data16;
1519             /*  debug
1520              * g_warning("Reading 0x%x From address %u",temp_data16,memmory_addr);
1521              */
1522             offset = offset +2;
1523         }
1524
1525     default :
1526         break;
1527     }
1528     return offset;
1529 }
1530 /*
1531  *
1532  * The fourth operand type is the address (@).  This operand is decoded
1533  * as a multitype operand followed by a further step: the memory address
1534  * of the UDVM instruction containing the address operand is added to
1535  * obtain the correct operand value.  So if the operand value from
1536  * Figure 10 is D then the actual operand value of an address is
1537  * calculated as follows:
1538  *
1539  * operand_value = (memory_address_of_instruction + D) modulo 2^16
1540  *
1541  * Address operands are always used in instructions that control program
1542  * flow, because they ensure that the UDVM bytecode is position-
1543  * independent code (i.e., it will run independently of where it is
1544  * placed in the UDVM memory).
1545  */
1546 static int
1547 decode_udvm_address_operand(guint8 *buff,guint operand_address, guint16 *value,guint current_address)
1548 {
1549     guint32 result;
1550     guint16 value1;
1551     guint   next_opreand_address;
1552
1553     next_opreand_address = decode_udvm_multitype_operand(buff, operand_address, &value1);
1554     result = value1 & 0xffff;
1555     result = result + current_address;
1556     *value = result & 0xffff;
1557     return next_opreand_address;
1558 }
1559
1560
1561 /*
1562  * This is a lookup table used to reverse the bits in a byte.
1563  */
1564 static guint8 reverse [] = {
1565     0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
1566     0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
1567     0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
1568     0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
1569     0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
1570     0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
1571     0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
1572     0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
1573     0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
1574     0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
1575     0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
1576     0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
1577     0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
1578     0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
1579     0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
1580     0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
1581     0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
1582     0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
1583     0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
1584     0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
1585     0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
1586     0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
1587     0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
1588     0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
1589     0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
1590     0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
1591     0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
1592     0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
1593     0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
1594     0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
1595     0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
1596     0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
1597 };
1598
1599
1600 static int
1601 decomp_dispatch_get_bits(
1602     tvbuff_t   *message_tvb,
1603     proto_tree *udvm_tree,
1604     guint8      bit_order,
1605     guint8     *buff,
1606     guint16    *old_input_bit_order,
1607     guint16    *remaining_bits,
1608     guint16    *input_bits,
1609     guint      *input_address,
1610     guint16     length,
1611     guint16    *result_code,
1612     guint       msg_end,
1613     gboolean    print_level_1)
1614 {
1615     guint16     input_bit_order;
1616     guint16     bits_still_required   = length;
1617     guint16     value                 = 0;
1618     guint8      octet;
1619     gint        extra_bytes_available = msg_end - *input_address;
1620     gint        p_bit;
1621     gint        prev_p_bit            = *old_input_bit_order & 0x0001;
1622     gint        bits_to_use           = 0;
1623
1624
1625     input_bit_order = buff[68] << 8;
1626     input_bit_order = input_bit_order | buff[69];
1627     *result_code = 0;
1628     p_bit = (input_bit_order & 0x0001) != 0;
1629
1630     /*
1631      * Discard any spare bits.
1632      * Note: We take care to avoid remaining_bits having the value of 8.
1633      */
1634     if (prev_p_bit != p_bit)
1635     {
1636         *remaining_bits = 0;
1637         *old_input_bit_order = input_bit_order;
1638     }
1639
1640     /*
1641      * Check we can suppy the required number of bits now, before we alter
1642      * the input buffer's state.
1643      */
1644     if (*remaining_bits + extra_bytes_available * 8 < length)
1645     {
1646         *result_code = 11;
1647         return 0xfbad;
1648     }
1649
1650     /* Note: This is never called with length > 16, so the following loop
1651      *       never loops more than three time. */
1652     while (bits_still_required > 0)
1653     {
1654         /*
1655          * We only put anything into input_bits if we know we will remove
1656          * at least one bit. That ensures we can simply discard the spare
1657          * bits if the P-bit changes.
1658          */
1659         if (*remaining_bits == 0)
1660         {
1661             octet = tvb_get_guint8(message_tvb, *input_address);
1662             if (print_level_1 ) {
1663                 proto_tree_add_text(udvm_tree, message_tvb, *input_address , 1,
1664                                     "               Getting value: %u (0x%x) From Addr: %u", octet, octet, *input_address);
1665             }
1666             *input_address = *input_address + 1;
1667
1668             if (p_bit != 0)
1669             {
1670                 octet = reverse[octet];
1671             }
1672             *input_bits = octet;
1673             *remaining_bits = 8;
1674         }
1675
1676         /* Add some more bits to the accumulated value. */
1677         bits_to_use = bits_still_required < *remaining_bits ? bits_still_required : *remaining_bits;
1678         bits_still_required -= bits_to_use;
1679
1680         *input_bits <<= bits_to_use;           /* Shift bits into MSByte */
1681         value = (value << bits_to_use)         /* Then add to the accumulated value */
1682             | ((*input_bits >> 8) & 0xFF);
1683         *remaining_bits -= bits_to_use;
1684         *input_bits &= 0x00FF;                 /* Leave just the remaining bits */
1685     }
1686
1687     if (bit_order != 0)
1688     {
1689         /* Bit reverse the entire word. */
1690         guint16 lsb = reverse[(value >> 8) & 0xFF];
1691         guint16 msb = reverse[value & 0xFF];
1692
1693         value = ((msb << 8) | lsb) >> (16 - length);
1694     }
1695
1696     return value;
1697 }
1698
1699 static tvbuff_t*
1700 decompress_sigcomp_message(tvbuff_t *bytecode_tvb, tvbuff_t *message_tvb, packet_info *pinfo,
1701                            proto_tree *udvm_tree, gint udvm_mem_dest,
1702                            gint print_flags, gint hf_id,
1703                            gint header_len,
1704                            gint byte_code_state_len, gint byte_code_id_len,
1705                            gint udvm_start_ip)
1706 {
1707     tvbuff_t      *decomp_tvb;
1708     /* UDVM memory must be initialised to zero */
1709     guint8        *buff                       = (guint8 *)wmem_alloc0(wmem_packet_scope(), UDVM_MEMORY_SIZE);
1710     char           string[2];
1711     guint8        *out_buff;    /* Largest allowed size for a message is UDVM_MEMORY_SIZE = 65536 */
1712     guint32        i                          = 0;
1713     guint16        n                          = 0;
1714     guint16        m                          = 0;
1715     guint16        x;
1716     guint          k                          = 0;
1717     guint16        H;
1718     guint16        oldH;
1719     guint          offset                     = 0;
1720     guint          start_offset;
1721     guint          result_dest;
1722     guint          code_length                = 0;
1723     guint8         current_instruction;
1724     guint          current_address;
1725     guint          operand_address;
1726     guint          input_address;
1727     guint16        output_address             = 0;
1728     guint          next_operand_address;
1729     guint8         octet;
1730     guint8         msb;
1731     guint8         lsb;
1732     guint16        byte_copy_right;
1733     guint16        byte_copy_left;
1734     guint16        input_bit_order;
1735     guint16        stack_location;
1736     guint16        stack_fill;
1737     guint16        result;
1738     guint          msg_end                    = tvb_reported_length_remaining(message_tvb, 0);
1739     guint16        result_code                = 0;
1740     guint16        old_input_bit_order        = 0;
1741     guint16        remaining_bits             = 0;
1742     guint16        input_bits                 = 0;
1743     guint8         bit_order                  = 0;
1744     gboolean       outside_huffman_boundaries = TRUE;
1745     gboolean       print_in_loop              = FALSE;
1746     guint16        instruction_address;
1747     guint8         no_of_state_create         = 0;
1748     guint16        state_length_buff[5];
1749     guint16        state_address_buff[5];
1750     guint16        state_instruction_buff[5];
1751     guint16        state_minimum_access_length_buff[5];
1752     /* guint16        state_state_retention_priority_buff[5]; */
1753     guint32        used_udvm_cycles           = 0;
1754     guint          cycles_per_bit;
1755     guint          maximum_UDVM_cycles;
1756     guint8        *sha1buff;
1757     unsigned char  sha1_digest_buf[STATE_BUFFER_SIZE];
1758     sha1_context   ctx;
1759     proto_item    *addr_item = NULL;
1760
1761
1762     /* UDVM operand variables */
1763     guint16 length;
1764     guint16 at_address;
1765     guint16 destination;
1766     guint16 addr;
1767     guint16 value;
1768     guint16 p_id_start;
1769     guint16 p_id_length;
1770     guint16 state_begin;
1771     guint16 state_length;
1772     guint16 state_address;
1773     guint16 state_instruction;
1774     guint16 operand_1;
1775     guint16 operand_2;
1776     guint16 value_1;
1777     guint16 value_2;
1778     guint16 at_address_1;
1779     guint16 at_address_2;
1780     guint16 at_address_3;
1781     guint16 j;
1782     guint16 bits_n;
1783     guint16 lower_bound_n;
1784     guint16 upper_bound_n;
1785     guint16 uncompressed_n;
1786     guint16 position;
1787     guint16 ref_destination; /* could I have used $destination ? */
1788     guint16 multy_offset;
1789     guint16 output_start;
1790     guint16 output_length;
1791     guint16 minimum_access_length;
1792     guint16 state_retention_priority;
1793     guint16 requested_feedback_location;
1794     guint16 returned_parameters_location;
1795     guint16 start_value;
1796
1797     /* Set print parameters */
1798     gboolean print_level_1 = FALSE;
1799     gboolean print_level_2 = FALSE;
1800     gboolean print_level_3 = FALSE;
1801     gint show_instr_detail_level = 0;
1802
1803     switch ( print_flags ) {
1804     case 0:
1805         break;
1806
1807     case 1:
1808         print_level_1 = TRUE;
1809         show_instr_detail_level = 1;
1810         break;
1811     case 2:
1812         print_level_1 = TRUE;
1813         print_level_2 = TRUE;
1814         show_instr_detail_level = 1;
1815         break;
1816     case 3:
1817         print_level_1 = TRUE;
1818         print_level_2 = TRUE;
1819         print_level_3 = TRUE;
1820         show_instr_detail_level = 2;
1821         break;
1822     default:
1823         print_level_1 = TRUE;
1824         show_instr_detail_level = 1;
1825         break;
1826     }
1827
1828     /* Set initial UDVM data
1829      *  The first 32 bytes of UDVM memory are then initialized to special
1830      *  values as illustrated in Figure 5.
1831      *
1832      *                      0             7 8            15
1833      *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1834      *                     |       UDVM_memory_size        |  0 - 1
1835      *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1836      *                     |        cycles_per_bit         |  2 - 3
1837      *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1838      *                     |        SigComp_version        |  4 - 5
1839      *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1840      *                     |    partial_state_ID_length    |  6 - 7
1841      *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1842      *                     |         state_length          |  8 - 9
1843      *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1844      *                     |                               |
1845      *                     :           reserved            :  10 - 31
1846      *                     |                               |
1847      *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1848      *
1849      *            Figure 5: Initializing Useful Values in UDVM memory
1850      */
1851     /* UDVM_memory_size  */
1852     buff[0] = (UDVM_MEMORY_SIZE >> 8) & 0x00FF;
1853     buff[1] = UDVM_MEMORY_SIZE & 0x00FF;
1854     /* cycles_per_bit */
1855     buff[2] = 0;
1856     buff[3] = 16;
1857     /* SigComp_version */
1858     buff[4] = 0;
1859     buff[5] = 1;
1860     /* partial_state_ID_length */
1861     buff[6] = (byte_code_id_len >> 8) & 0x00FF;
1862     buff[7] = byte_code_id_len & 0x00FF;
1863     /* state_length  */
1864     buff[8] = (byte_code_state_len >> 8) & 0x00FF;
1865     buff[9] = byte_code_state_len & 0x00FF;
1866
1867     code_length = tvb_reported_length_remaining(bytecode_tvb, 0);
1868
1869     cycles_per_bit = buff[2] << 8;
1870     cycles_per_bit = cycles_per_bit | buff[3];
1871     /*
1872      * maximum_UDVM_cycles = (8 * n + 1000) * cycles_per_bit
1873      */
1874     maximum_UDVM_cycles = (( 8 * (header_len + msg_end) ) + 1000) * cycles_per_bit;
1875
1876     proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,"Message Length: %u,Byte code length: %u, Maximum UDVM cycles: %u",msg_end,code_length,maximum_UDVM_cycles);
1877
1878     /* Load bytecode into UDVM starting at "udvm_mem_dest" */
1879     i = udvm_mem_dest;
1880     if ( print_level_3 )
1881         proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,"Load bytecode into UDVM starting at %u",i);
1882     while ( code_length > offset && i < UDVM_MEMORY_SIZE ) {
1883         buff[i] = tvb_get_guint8(bytecode_tvb, offset);
1884         if ( print_level_3 )
1885             proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,
1886                                 "              Addr: %u Instruction code(0x%02x) ", i, buff[i]);
1887
1888         i++;
1889         offset++;
1890
1891     }
1892     /* Start executing code */
1893     current_address = udvm_start_ip;
1894     input_address = 0;
1895
1896     proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,"UDVM EXECUTION STARTED at Address: %u Message size %u",
1897                         current_address, msg_end);
1898
1899     /* Largest allowed size for a message is UDVM_MEMORY_SIZE = 65536  */
1900     out_buff = (guint8 *)g_malloc(UDVM_MEMORY_SIZE);
1901
1902     /* Reset offset so proto_tree_add_xxx items below accurately reflect the bytes they represent */
1903     offset = 0;
1904
1905 execute_next_instruction:
1906
1907     if ( used_udvm_cycles > maximum_UDVM_cycles ) {
1908         result_code = 15;
1909         goto decompression_failure;
1910     }
1911     used_udvm_cycles++;
1912     current_instruction = buff[current_address & 0xffff];
1913
1914     if (show_instr_detail_level == 2 ) {
1915         addr_item = proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,
1916                             "Addr: %u ## %s(%d)", current_address,
1917                             val_to_str_ext_const(current_instruction, &udvm_instruction_code_vals_ext, "INVALID INSTRUCTION"),
1918                             current_instruction);
1919     }
1920     offset++;
1921
1922     switch ( current_instruction ) {
1923     case SIGCOMP_INSTR_DECOMPRESSION_FAILURE:
1924         if ( result_code == 0 )
1925             result_code = 9;
1926         proto_tree_add_text(udvm_tree, NULL, 0, 0,
1927                             "Addr: %u ## DECOMPRESSION-FAILURE(0)",
1928                             current_address);
1929         proto_tree_add_text(udvm_tree, NULL, 0, 0,"Wireshark UDVM diagnostic: %s.",
1930                             val_to_str(result_code, result_code_vals,"Unknown (%u)"));
1931         if ( output_address > 0 ) {
1932             /* At least something got decompressed, show it */
1933             decomp_tvb = tvb_new_child_real_data(message_tvb, out_buff,output_address,output_address);
1934             /* Arrange that the allocated packet data copy be freed when the
1935              * tvbuff is freed.
1936              */
1937             tvb_set_free_cb( decomp_tvb, g_free );
1938             /* Add the tvbuff to the list of tvbuffs to which the tvbuff we
1939              * were handed refers, so it'll get cleaned up when that tvbuff
1940              * is cleaned up.
1941              */
1942             add_new_data_source(pinfo, decomp_tvb, "Decompressed SigComp message(Incomplete)");
1943             proto_tree_add_text(udvm_tree, decomp_tvb, 0, -1,"SigComp message Decompression failure");
1944             return decomp_tvb;
1945         }
1946         g_free(out_buff);
1947         return NULL;
1948         break;
1949
1950     case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */
1951         if (show_instr_detail_level == 2 ) {
1952             proto_item_append_text(addr_item, " (operand_1, operand_2)");
1953         }
1954         start_offset = offset;
1955         /* $operand_1*/
1956         operand_address = current_address + 1;
1957         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
1958         if (show_instr_detail_level == 2 ) {
1959             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
1960                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
1961         }
1962         offset += (next_operand_address-operand_address);
1963         operand_address = next_operand_address;
1964         /* %operand_2*/
1965         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
1966         if (show_instr_detail_level == 2 ) {
1967             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
1968                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
1969         }
1970         offset += (next_operand_address-operand_address);
1971         if (show_instr_detail_level == 1)
1972         {
1973             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
1974                                 "Addr: %u ## AND (operand_1=%u, operand_2=%u)",
1975                                 current_address, operand_1, operand_2);
1976         }
1977         /* execute the instruction */
1978         result = operand_1 & operand_2;
1979         lsb = result & 0xff;
1980         msb = result >> 8;
1981         buff[result_dest] = msb;
1982         buff[(result_dest+1) & 0xffff] = lsb;
1983         if (print_level_1 ) {
1984             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
1985                                 "     Loading result %u at %u", result, result_dest);
1986         }
1987         current_address = next_operand_address;
1988         goto execute_next_instruction;
1989
1990         break;
1991
1992     case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */
1993         if (show_instr_detail_level == 2 ) {
1994             proto_item_append_text(addr_item, " (operand_1, operand_2)");
1995         }
1996         start_offset = offset;
1997         /* $operand_1*/
1998         operand_address = current_address + 1;
1999         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
2000         if (show_instr_detail_level == 2 ) {
2001             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
2002                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
2003         }
2004         offset += (next_operand_address-operand_address);
2005         operand_address = next_operand_address;
2006         /* %operand_2*/
2007         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
2008         if (show_instr_detail_level == 2 ) {
2009             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
2010                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
2011         }
2012         offset += (next_operand_address-operand_address);
2013         if (show_instr_detail_level == 1)
2014         {
2015             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2016                                 "Addr: %u ## OR (operand_1=%u, operand_2=%u)",
2017                                 current_address, operand_1, operand_2);
2018         }
2019         /* execute the instruction */
2020         result = operand_1 | operand_2;
2021         lsb = result & 0xff;
2022         msb = result >> 8;
2023         buff[result_dest] = msb;
2024         buff[(result_dest+1) & 0xffff] = lsb;
2025         if (print_level_1 ) {
2026             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
2027                                 "     Loading result %u at %u", result, result_dest);
2028         }
2029         current_address = next_operand_address;
2030         goto execute_next_instruction;
2031
2032         break;
2033
2034     case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */
2035         if (show_instr_detail_level == 2 ) {
2036             proto_item_append_text(addr_item, " ($operand_1)");
2037         }
2038         start_offset = offset;
2039         /* $operand_1*/
2040         operand_address = current_address + 1;
2041         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
2042         if (show_instr_detail_level == 2 ) {
2043             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
2044                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
2045         }
2046         offset += (next_operand_address-operand_address);
2047         if (show_instr_detail_level == 1)
2048         {
2049             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2050                                 "Addr: %u ## NOT (operand_1=%u)",
2051                                 current_address, operand_1);
2052         }
2053         /* execute the instruction */
2054         result = operand_1 ^ 0xffff;
2055         lsb = result & 0xff;
2056         msb = result >> 8;
2057         buff[result_dest] = msb;
2058         buff[(result_dest+1) & 0xffff] = lsb;
2059         if (print_level_1 ) {
2060             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
2061                                 "     Loading result %u at %u", result, result_dest);
2062         }
2063         current_address = next_operand_address;
2064         goto execute_next_instruction;
2065         break;
2066
2067     case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */
2068         if (show_instr_detail_level == 2 ) {
2069             proto_item_append_text(addr_item, " ($operand_1, operand_2)");
2070         }
2071         start_offset = offset;
2072         /* $operand_1*/
2073         operand_address = current_address + 1;
2074         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
2075         if (show_instr_detail_level == 2 ) {
2076             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
2077                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
2078         }
2079         offset += (next_operand_address-operand_address);
2080         operand_address = next_operand_address;
2081         /* %operand_2*/
2082         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
2083         if (show_instr_detail_level == 2 ) {
2084             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
2085                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
2086         }
2087         offset += (next_operand_address-operand_address);
2088         if (show_instr_detail_level == 1)
2089         {
2090             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2091                                 "Addr: %u ## LSHIFT (operand_1=%u, operand_2=%u)",
2092                                 current_address, operand_1, operand_2);
2093         }
2094         /* execute the instruction */
2095         result = operand_1 << operand_2;
2096         lsb = result & 0xff;
2097         msb = result >> 8;
2098         buff[result_dest] = msb;
2099         buff[(result_dest+1) & 0xffff] = lsb;
2100         if (print_level_1 ) {
2101             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
2102                                 "     Loading result %u at %u", result, result_dest);
2103         }
2104         current_address = next_operand_address;
2105         goto execute_next_instruction;
2106
2107         break;
2108     case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */
2109         if (show_instr_detail_level == 2 ) {
2110             proto_item_append_text(addr_item, " (operand_1, operand_2)");
2111         }
2112         start_offset = offset;
2113         /* $operand_1*/
2114         operand_address = current_address + 1;
2115         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
2116         if (show_instr_detail_level == 2 ) {
2117             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
2118                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
2119         }
2120         offset += (next_operand_address-operand_address);
2121         operand_address = next_operand_address;
2122         /* %operand_2*/
2123         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
2124         if (show_instr_detail_level == 2 ) {
2125             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
2126                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
2127         }
2128         offset += (next_operand_address-operand_address);
2129         if (show_instr_detail_level == 1)
2130         {
2131             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2132                                 "Addr: %u ## RSHIFT (operand_1=%u, operand_2=%u)",
2133                                 current_address, operand_1, operand_2);
2134         }
2135         /* execute the instruction */
2136         result = operand_1 >> operand_2;
2137         lsb = result & 0xff;
2138         msb = result >> 8;
2139         buff[result_dest] = msb;
2140         buff[(result_dest+1) & 0xffff] = lsb;
2141         if (print_level_1 ) {
2142             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
2143                                 "     Loading result %u at %u", result, result_dest);
2144         }
2145         current_address = next_operand_address;
2146         goto execute_next_instruction;
2147         break;
2148     case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */
2149         if (show_instr_detail_level == 2 ) {
2150             proto_item_append_text(addr_item, " (operand_1, operand_2)");
2151         }
2152         start_offset = offset;
2153         /* $operand_1*/
2154         operand_address = current_address + 1;
2155         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
2156         if (show_instr_detail_level == 2 ) {
2157             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
2158                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
2159         }
2160         offset += (next_operand_address-operand_address);
2161         operand_address = next_operand_address;
2162         /* %operand_2*/
2163         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
2164         if (show_instr_detail_level == 2 ) {
2165             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
2166                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
2167         }
2168         offset += (next_operand_address-operand_address);
2169         if (show_instr_detail_level == 1)
2170         {
2171             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2172                                 "Addr: %u ## ADD (operand_1=%u, operand_2=%u)",
2173                                 current_address, operand_1, operand_2);
2174         }
2175         /* execute the instruction */
2176         result = operand_1 + operand_2;
2177         lsb = result & 0xff;
2178         msb = result >> 8;
2179         buff[result_dest] = msb;
2180         buff[(result_dest+1) & 0xffff] = lsb;
2181         if (print_level_1 ) {
2182             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
2183                                 "               Loading result %u at %u", result, result_dest);
2184         }
2185         current_address = next_operand_address;
2186         goto execute_next_instruction;
2187
2188     case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */
2189         if (show_instr_detail_level == 2 ) {
2190             proto_item_append_text(addr_item, " (operand_1, operand_2)");
2191         }
2192         start_offset = offset;
2193         /* $operand_1*/
2194         operand_address = current_address + 1;
2195         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
2196         if (show_instr_detail_level == 2 ) {
2197             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
2198                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
2199         }
2200         offset += (next_operand_address-operand_address);
2201         operand_address = next_operand_address;
2202         /* %operand_2*/
2203         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
2204         if (show_instr_detail_level == 2 ) {
2205             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
2206                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
2207         }
2208         offset += (next_operand_address-operand_address);
2209         if (show_instr_detail_level == 1)
2210         {
2211             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2212                                 "Addr: %u ## SUBTRACT (operand_1=%u, operand_2=%u)",
2213                                 current_address, operand_1, operand_2);
2214         }
2215         /* execute the instruction */
2216         result = operand_1 - operand_2;
2217         lsb = result & 0xff;
2218         msb = result >> 8;
2219         buff[result_dest] = msb;
2220         buff[(result_dest+1) & 0xffff] = lsb;
2221         if (print_level_1 ) {
2222             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
2223                                 "               Loading result %u at %u", result, result_dest);
2224         }
2225         current_address = next_operand_address;
2226         goto execute_next_instruction;
2227         break;
2228
2229     case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */
2230         if (show_instr_detail_level == 2 ) {
2231             proto_item_append_text(addr_item, " (operand_1, operand_2)");
2232         }
2233         start_offset = offset;
2234         /* $operand_1*/
2235         operand_address = current_address + 1;
2236         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
2237         if (show_instr_detail_level == 2 ) {
2238             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
2239                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
2240         }
2241         offset += (next_operand_address-operand_address);
2242         operand_address = next_operand_address;
2243         /* %operand_2*/
2244         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
2245         if (show_instr_detail_level == 2 ) {
2246             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
2247                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
2248         }
2249         offset += (next_operand_address-operand_address);
2250         if (show_instr_detail_level == 1)
2251         {
2252             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2253                                 "Addr: %u ## MULTIPLY (operand_1=%u, operand_2=%u)",
2254                                 current_address, operand_1, operand_2);
2255         }
2256         /*
2257          * execute the instruction
2258          * MULTIPLY (m, n)  := m * n (modulo 2^16)
2259          */
2260         if ( operand_2 == 0) {
2261             result_code = 4;
2262             goto decompression_failure;
2263         }
2264         result = operand_1 * operand_2;
2265         lsb = result & 0xff;
2266         msb = result >> 8;
2267         buff[result_dest] = msb;
2268         buff[(result_dest+1) & 0xffff] = lsb;
2269         if (print_level_1 ) {
2270             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
2271                                 "     Loading result %u at %u", result, result_dest);
2272         }
2273         current_address = next_operand_address;
2274         goto execute_next_instruction;
2275         break;
2276
2277     case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */
2278         if (show_instr_detail_level == 2 ) {
2279             proto_item_append_text(addr_item, " (operand_1, operand_2)");
2280         }
2281         start_offset = offset;
2282         /* $operand_1*/
2283         operand_address = current_address + 1;
2284         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
2285         if (show_instr_detail_level == 2 ) {
2286             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
2287                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
2288         }
2289         offset += (next_operand_address-operand_address);
2290         operand_address = next_operand_address;
2291         /* %operand_2*/
2292         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
2293         if (show_instr_detail_level == 2 ) {
2294             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
2295                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
2296         }
2297         offset += (next_operand_address-operand_address);
2298         if (show_instr_detail_level == 1)
2299         {
2300             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2301                                 "Addr: %u ## DIVIDE (operand_1=%u, operand_2=%u)",
2302                                 current_address, operand_1, operand_2);
2303         }
2304         /*
2305          * execute the instruction
2306          * DIVIDE (m, n)    := floor(m / n)
2307          * Decompression failure occurs if a DIVIDE or REMAINDER instruction
2308          * encounters an operand_2 that is zero.
2309          */
2310         if ( operand_2 == 0) {
2311             result_code = 4;
2312             goto decompression_failure;
2313         }
2314         result = operand_1 / operand_2;
2315         lsb = result & 0xff;
2316         msb = result >> 8;
2317         buff[result_dest] = msb;
2318         buff[(result_dest+1) & 0xffff] = lsb;
2319         if (print_level_1 ) {
2320             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
2321                                 "     Loading result %u at %u", result, result_dest);
2322         }
2323         current_address = next_operand_address;
2324         goto execute_next_instruction;
2325         break;
2326
2327     case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */
2328         if (show_instr_detail_level == 2 ) {
2329             proto_item_append_text(addr_item, " (operand_1, operand_2)");
2330         }
2331         start_offset = offset;
2332         /* $operand_1*/
2333         operand_address = current_address + 1;
2334         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
2335         if (show_instr_detail_level == 2 ) {
2336             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
2337                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
2338         }
2339         offset += (next_operand_address-operand_address);
2340         operand_address = next_operand_address;
2341         /* %operand_2*/
2342         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
2343         if (show_instr_detail_level == 2 ) {
2344             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
2345                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
2346         }
2347         offset += (next_operand_address-operand_address);
2348         if (show_instr_detail_level == 1)
2349         {
2350             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2351                                 "Addr: %u ## REMAINDER (operand_1=%u, operand_2=%u)",
2352                                 current_address, operand_1, operand_2);
2353         }
2354         /*
2355          * execute the instruction
2356          * REMAINDER (m, n) := m - n * floor(m / n)
2357          * Decompression failure occurs if a DIVIDE or REMAINDER instruction
2358          * encounters an operand_2 that is zero.
2359          */
2360         if ( operand_2 == 0) {
2361             result_code = 4;
2362             goto decompression_failure;
2363         }
2364         result = operand_1 - operand_2 * (operand_1 / operand_2);
2365         lsb = result & 0xff;
2366         msb = result >> 8;
2367         buff[result_dest] = msb;
2368         buff[(result_dest+1) & 0xffff] = lsb;
2369         if (print_level_1 ) {
2370             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
2371                                 "     Loading result %u at %u", result, result_dest);
2372         }
2373         current_address = next_operand_address;
2374         goto execute_next_instruction;
2375         break;
2376     case SIGCOMP_INSTR_SORT_ASCENDING: /* 11 SORT-ASCENDING (%start, %n, %k) */
2377         /*
2378          *      used_udvm_cycles =  1 + k * (ceiling(log2(k)) + n)
2379          */
2380         if (show_instr_detail_level == 2 ) {
2381             proto_item_append_text(addr_item, " (start, n, k))");
2382         }
2383         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Execution of this instruction is NOT implemented");
2384         /*
2385          *      used_udvm_cycles =  1 + k * (ceiling(log2(k)) + n)
2386          */
2387         break;
2388
2389     case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */
2390         if (show_instr_detail_level == 2 ) {
2391             proto_item_append_text(addr_item, " (start, n, k))");
2392         }
2393         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Execution of this instruction is NOT implemented");
2394         /*
2395          *      used_udvm_cycles =  1 + k * (ceiling(log2(k)) + n)
2396          */
2397         break;
2398     case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */
2399         if (show_instr_detail_level == 2 ) {
2400             proto_item_append_text(addr_item, " (position, length, destination)");
2401         }
2402         operand_address = current_address + 1;
2403         /* %position */
2404         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
2405         if (print_level_1 ) {
2406             proto_tree_add_uint_format(udvm_tree, hf_udvm_position, bytecode_tvb, offset, (next_operand_address-operand_address), position,
2407                                 "Addr: %u      position %u", operand_address, position);
2408         }
2409         offset += (next_operand_address-operand_address);
2410         operand_address = next_operand_address;
2411
2412         /* %length */
2413         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
2414         if (print_level_1 ) {
2415             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
2416                                 "Addr: %u      Length %u", operand_address, length);
2417         }
2418         offset += (next_operand_address-operand_address);
2419         operand_address = next_operand_address;
2420
2421         /* $destination */
2422         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &ref_destination, &result_dest);
2423         if (print_level_1 ) {
2424             proto_tree_add_uint_format(udvm_tree, hf_udvm_ref_dest, bytecode_tvb, offset, (next_operand_address-operand_address), ref_destination,
2425                                 "Addr: %u      $destination %u", operand_address, ref_destination);
2426         }
2427         offset += (next_operand_address-operand_address);
2428         used_udvm_cycles = used_udvm_cycles + length;
2429
2430         n = 0;
2431         k = position;
2432         byte_copy_right = buff[66] << 8;
2433         byte_copy_right = byte_copy_right | buff[67];
2434         byte_copy_left = buff[64] << 8;
2435         byte_copy_left = byte_copy_left | buff[65];
2436
2437         if (print_level_2 ) {
2438             proto_tree_add_text(udvm_tree, message_tvb, 0, -1,
2439                                 "byte_copy_right = %u", byte_copy_right);
2440         }
2441
2442         sha1_starts( &ctx );
2443
2444         while (n<length) {
2445             guint16 handle_now = length;
2446
2447             if ( k < byte_copy_right && byte_copy_right <= k + (length-n) ) {
2448                 handle_now = byte_copy_right - position;
2449             }
2450
2451             if (k + handle_now >= UDVM_MEMORY_SIZE)
2452                 goto decompression_failure;
2453             sha1_update( &ctx, &buff[k], handle_now );
2454
2455             k = ( k + handle_now ) & 0xffff;
2456             n = ( n + handle_now ) & 0xffff;
2457
2458             if ( k >= byte_copy_right ) {
2459                 k = byte_copy_left;
2460             }
2461         }
2462
2463         sha1_finish( &ctx, sha1_digest_buf );
2464
2465         k = ref_destination;
2466
2467         for ( n=0; n< STATE_BUFFER_SIZE; n++ ) {
2468
2469             buff[k] = sha1_digest_buf[n];
2470
2471             k = ( k + 1 ) & 0xffff;
2472             n++;
2473
2474             if ( k == byte_copy_right ) {
2475                 k = byte_copy_left;
2476             }
2477         }
2478
2479         if (print_level_2 ) {
2480             proto_tree_add_text(udvm_tree, message_tvb, 0, -1,
2481                                 "Calculated SHA-1: %s",
2482                                 bytes_to_str(wmem_packet_scope(), sha1_digest_buf, STATE_BUFFER_SIZE));
2483         }
2484
2485         current_address = next_operand_address;
2486         goto execute_next_instruction;
2487         break;
2488
2489     case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */
2490         if (show_instr_detail_level == 2 ) {
2491             proto_item_append_text(addr_item, " (%%address, %%value)");
2492         }
2493         start_offset = offset;
2494         operand_address = current_address + 1;
2495         /* %address */
2496         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &addr);
2497         if (show_instr_detail_level == 2 ) {
2498             proto_tree_add_uint_format(udvm_tree, hf_udvm_address, bytecode_tvb, offset, (next_operand_address-operand_address), addr,
2499                                 "Addr: %u      Address %u", operand_address, addr);
2500         }
2501         offset += (next_operand_address-operand_address);
2502         operand_address = next_operand_address;
2503         /* %value */
2504         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
2505         if (show_instr_detail_level == 2)
2506         {
2507             proto_tree_add_uint_format(udvm_tree, hf_udvm_value, bytecode_tvb, offset, (next_operand_address-operand_address), value,
2508                                 "Addr: %u      Value %u", operand_address, value);
2509         }
2510         offset += (next_operand_address-operand_address);
2511         lsb = value & 0xff;
2512         msb = value >> 8;
2513
2514         buff[addr] = msb;
2515         buff[(addr + 1) & 0xffff] = lsb;
2516
2517         if (print_level_1 ) {
2518             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2519                                 "Addr: %u ## LOAD (%%address=%u, %%value=%u)",
2520                                 current_address, addr, value);
2521             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
2522                                 "     Loading bytes at %u Value %u 0x%x", addr, value, value);
2523         }
2524         current_address = next_operand_address;
2525         goto execute_next_instruction;
2526         break;
2527
2528     case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
2529         /* RFC 3320:
2530          * The MULTILOAD instruction sets a contiguous block of 2-byte words in
2531          * the UDVM memory to specified values.
2532          * Hmm what if the value to load only takes one byte ? Chose to always load two bytes.
2533          */
2534         if (show_instr_detail_level == 2 ) {
2535             proto_item_append_text(addr_item, " (%%address, #n, value_0, ..., value_n-1)");
2536         }
2537         start_offset = offset;
2538         operand_address = current_address + 1;
2539         /* %address */
2540         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &addr);
2541         if (show_instr_detail_level == 2 ) {
2542             proto_tree_add_uint_format(udvm_tree, hf_udvm_address, bytecode_tvb, offset, (next_operand_address-operand_address), addr,
2543                                 "Addr: %u      Address %u", operand_address, addr);
2544         }
2545         offset += (next_operand_address-operand_address);
2546         operand_address = next_operand_address;
2547
2548         /* #n */
2549         next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
2550         if (show_instr_detail_level == 2 ) {
2551             proto_tree_add_uint_format(udvm_tree, hf_udvm_literal_num, bytecode_tvb, offset, (next_operand_address-operand_address), n,
2552                                 "Addr: %u      n %u", operand_address, n);
2553         }
2554         offset += (next_operand_address-operand_address);
2555         if (show_instr_detail_level == 1)
2556         {
2557             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2558                                 "Addr: %u ## MULTILOAD (%%address=%u, #n=%u, value_0, ..., value_%d)",
2559                                 current_address, addr, n, n-1);
2560         }
2561         operand_address = next_operand_address;
2562         used_udvm_cycles = used_udvm_cycles + n;
2563         while ( n > 0) {
2564             n = n - 1;
2565             /* %value */
2566             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
2567             lsb = value & 0xff;
2568             msb = value >> 8;
2569
2570             if (addr >= UDVM_MEMORY_SIZE - 1)
2571                 goto decompression_failure;
2572
2573             buff[addr] = msb;
2574             buff[(addr + 1) & 0xffff] = lsb;
2575             /* debug
2576              */
2577             length = next_operand_address - operand_address;
2578
2579             if (print_level_1 ) {
2580                 proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, bytecode_tvb, 0, -1,
2581                                     "Addr: %u      Value %5u      - Loading bytes at %5u Value %5u 0x%x", operand_address, value, addr, value, value);
2582             }
2583             addr = addr + 2;
2584             operand_address = next_operand_address;
2585         }
2586         current_address = next_operand_address;
2587         goto execute_next_instruction;
2588
2589         break;
2590
2591     case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */
2592         if (show_instr_detail_level == 2) {
2593             proto_item_append_text(addr_item, " (value)");
2594         }
2595         start_offset = offset;
2596         operand_address = current_address + 1;
2597         /* %value */
2598         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
2599         if (show_instr_detail_level == 2) {
2600             proto_tree_add_uint_format(udvm_tree, hf_udvm_value, bytecode_tvb, offset, (next_operand_address-operand_address), value,
2601                                 "Addr: %u      Value %u", operand_address, value);
2602         }
2603         offset += (next_operand_address-operand_address);
2604         if (show_instr_detail_level == 1)
2605         {
2606             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2607                                 "Addr: %u ## PUSH (value=%u)",
2608                                 current_address, value);
2609         }
2610         current_address = next_operand_address;
2611
2612         /* Push the value address onto the stack */
2613         stack_location = (buff[70] << 8) | buff[71];
2614         stack_fill = (buff[stack_location] << 8)
2615             | buff[(stack_location+1) & 0xFFFF];
2616         addr = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
2617
2618         if (addr >= UDVM_MEMORY_SIZE - 1)
2619             goto decompression_failure;
2620
2621         buff[addr] = (value >> 8) & 0x00FF;
2622         buff[(addr+1) & 0xFFFF] = value & 0x00FF;
2623
2624         if (stack_location >= UDVM_MEMORY_SIZE - 1)
2625             goto decompression_failure;
2626
2627         stack_fill = (stack_fill + 1) & 0xFFFF;
2628         buff[stack_location] = (stack_fill >> 8) & 0x00FF;
2629         buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
2630
2631         goto execute_next_instruction;
2632
2633         break;
2634
2635     case SIGCOMP_INSTR_POP: /* 17 POP (%address) */
2636         if (show_instr_detail_level == 2) {
2637             proto_item_append_text(addr_item, " (value)");
2638         }
2639         start_offset = offset;
2640         operand_address = current_address + 1;
2641         /* %value */
2642         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
2643         if (show_instr_detail_level == 2) {
2644             proto_tree_add_uint_format(udvm_tree, hf_udvm_address, bytecode_tvb, offset, (next_operand_address-operand_address), destination,
2645                                 "Addr: %u      Value %u", operand_address, destination);
2646         }
2647         offset += (next_operand_address-operand_address);
2648         if (show_instr_detail_level == 1)
2649         {
2650             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2651                                 "Addr: %u ## POP (address=%u)",
2652                                 current_address, destination);
2653         }
2654         current_address = next_operand_address;
2655
2656         /* Pop value from the top of the stack */
2657         stack_location = (buff[70] << 8) | buff[71];
2658         stack_fill = (buff[stack_location] << 8)
2659             | buff[(stack_location+1) & 0xFFFF];
2660         if (stack_fill == 0)
2661         {
2662             result_code = 16;
2663             goto decompression_failure;
2664         }
2665
2666         if (stack_location >= UDVM_MEMORY_SIZE - 1)
2667             goto decompression_failure;
2668
2669         stack_fill = (stack_fill - 1) & 0xFFFF;
2670         buff[stack_location] = (stack_fill >> 8) & 0x00FF;
2671         buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
2672
2673         addr = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
2674
2675         if (addr >= UDVM_MEMORY_SIZE - 1)
2676             goto decompression_failure;
2677
2678         value = (buff[addr] << 8)
2679             | buff[(addr+1) & 0xFFFF];
2680
2681         /* ... and store the popped value. */
2682         if (destination >= UDVM_MEMORY_SIZE - 1)
2683             goto decompression_failure;
2684         buff[destination] = (value >> 8) & 0x00FF;
2685         buff[(destination+1) & 0xFFFF] = value & 0x00FF;
2686
2687         goto execute_next_instruction;
2688
2689         break;
2690
2691     case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */
2692         if (show_instr_detail_level == 2 ) {
2693             proto_item_append_text(addr_item, " (position, length, destination)");
2694         }
2695         start_offset = offset;
2696         operand_address = current_address + 1;
2697         /* %position */
2698         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
2699         if (show_instr_detail_level == 2 ) {
2700             proto_tree_add_uint_format(udvm_tree, hf_udvm_position, bytecode_tvb, offset, (next_operand_address-operand_address), position,
2701                                 "Addr: %u      position %u", operand_address, position);
2702         }
2703         offset += (next_operand_address-operand_address);
2704         operand_address = next_operand_address;
2705
2706         /* %length */
2707         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
2708         if (show_instr_detail_level == 2 ) {
2709             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
2710                                 "Addr: %u      Length %u", operand_address, length);
2711         }
2712         offset += (next_operand_address-operand_address);
2713         operand_address = next_operand_address;
2714
2715         /* %destination */
2716         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
2717         if (show_instr_detail_level == 2 ) {
2718             proto_tree_add_uint_format(udvm_tree, hf_udvm_ref_dest, bytecode_tvb, offset, (next_operand_address-operand_address), destination,
2719                                 "Addr: %u      Destination %u", operand_address, destination);
2720         }
2721         offset += (next_operand_address-operand_address);
2722         if (show_instr_detail_level == 1)
2723         {
2724             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2725                                 "Addr: %u ## COPY (position=%u, length=%u, destination=%u)",
2726                                 current_address, position, length, destination);
2727         }
2728         current_address = next_operand_address;
2729         /*
2730          * 8.4.  Byte copying
2731          * :
2732          * The string of bytes is copied in ascending order of memory address,
2733          * respecting the bounds set by byte_copy_left and byte_copy_right.
2734          * More precisely, if a byte is copied from/to Address m then the next
2735          * byte is copied from/to Address n where n is calculated as follows:
2736          *
2737          * Set k := m + 1 (modulo 2^16)
2738          * If k = byte_copy_right then set n := byte_copy_left, else set n := k
2739          *
2740          */
2741
2742         n = 0;
2743         k = destination;
2744         byte_copy_right = buff[66] << 8;
2745         byte_copy_right = byte_copy_right | buff[67];
2746         byte_copy_left = buff[64] << 8;
2747         byte_copy_left = byte_copy_left | buff[65];
2748         if (print_level_2 ) {
2749             proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
2750                                 "               byte_copy_right = %u", byte_copy_right);
2751         }
2752
2753         while ( n < length ) {
2754             buff[k] = buff[position];
2755             if (print_level_2 ) {
2756                 proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
2757                                     "               Copying value: %u (0x%x) to Addr: %u",
2758                                     buff[position], buff[position], k);
2759             }
2760             position = ( position + 1 ) & 0xffff;
2761             k = ( k + 1 ) & 0xffff;
2762             n++;
2763
2764             /*
2765              * Check for circular buffer wrapping after the positions are
2766              * incremented. If either started at BCR then they should continue
2767              * to increment beyond BCR.
2768              */
2769             if ( k == byte_copy_right ) {
2770                 k = byte_copy_left;
2771             }
2772             if ( position == byte_copy_right ) {
2773                 position = byte_copy_left;
2774             }
2775         }
2776         used_udvm_cycles = used_udvm_cycles + length;
2777         goto execute_next_instruction;
2778         break;
2779
2780     case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */
2781         if (show_instr_detail_level == 2 ) {
2782             proto_item_append_text(addr_item, " (position, length, $destination)");
2783         }
2784         start_offset = offset;
2785         operand_address = current_address + 1;
2786         /* %position */
2787         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
2788         if (show_instr_detail_level == 2 ) {
2789             proto_tree_add_uint_format(udvm_tree, hf_udvm_position, bytecode_tvb, offset, (next_operand_address-operand_address), position,
2790                                 "Addr: %u      position %u", operand_address, position);
2791         }
2792         offset += (next_operand_address-operand_address);
2793         operand_address = next_operand_address;
2794
2795         /* %length */
2796         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
2797         if (show_instr_detail_level == 2 ) {
2798             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
2799                                 "Addr: %u      Length %u", operand_address, length);
2800         }
2801         offset += (next_operand_address-operand_address);
2802         operand_address = next_operand_address;
2803
2804
2805         /* $destination */
2806         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &ref_destination, &result_dest);
2807         if (show_instr_detail_level == 2 ) {
2808             proto_tree_add_uint_format(udvm_tree, hf_udvm_ref_dest, bytecode_tvb, offset, (next_operand_address-operand_address), ref_destination,
2809                                 "Addr: %u      destination %u", operand_address, ref_destination);
2810         }
2811         offset += (next_operand_address-operand_address);
2812         if (show_instr_detail_level == 1)
2813         {
2814             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2815                                 "Addr: %u ## COPY-LITERAL (position=%u, length=%u, $destination=%u)",
2816                                 current_address, position, length, ref_destination);
2817         }
2818         current_address = next_operand_address;
2819
2820
2821         /*
2822          * 8.4.  Byte copying
2823          * :
2824          * The string of bytes is copied in ascending order of memory address,
2825          * respecting the bounds set by byte_copy_left and byte_copy_right.
2826          * More precisely, if a byte is copied from/to Address m then the next
2827          * byte is copied from/to Address n where n is calculated as follows:
2828          *
2829          * Set k := m + 1 (modulo 2^16)
2830          * If k = byte_copy_right then set n := byte_copy_left, else set n := k
2831          *
2832          */
2833
2834         n = 0;
2835         k = ref_destination;
2836         byte_copy_right = buff[66] << 8;
2837         byte_copy_right = byte_copy_right | buff[67];
2838         byte_copy_left = buff[64] << 8;
2839         byte_copy_left = byte_copy_left | buff[65];
2840         if (print_level_2 ) {
2841             proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
2842                                 "               byte_copy_right = %u", byte_copy_right);
2843         }
2844         while ( n < length ) {
2845
2846             buff[k] = buff[position];
2847             if (print_level_2 ) {
2848                 proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
2849                                     "               Copying value: %u (0x%x) to Addr: %u",
2850                                     buff[position], buff[position], k);
2851             }
2852             position = ( position + 1 ) & 0xffff;
2853             k = ( k + 1 ) & 0xffff;
2854             n++;
2855
2856             /*
2857              * Check for circular buffer wrapping after the positions are
2858              * incremented. It is important that k cannot be left set
2859              * to BCR. Also, if either started at BCR then they should continue
2860              * to increment beyond BCR.
2861              */
2862             if ( k == byte_copy_right ) {
2863                 k = byte_copy_left;
2864             }
2865             if ( position == byte_copy_right ) {
2866                 position = byte_copy_left;
2867             }
2868         }
2869         buff[result_dest] = k >> 8;
2870         buff[(result_dest + 1) & 0xffff] = k & 0x00ff;
2871
2872         used_udvm_cycles = used_udvm_cycles + length;
2873         goto execute_next_instruction;
2874         break;
2875
2876     case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */
2877         if (show_instr_detail_level == 2 ) {
2878             proto_item_append_text(addr_item, " (offset, length, $destination)");
2879         }
2880         start_offset = offset;
2881         operand_address = current_address + 1;
2882         /* %offset */
2883         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &multy_offset);
2884         if (show_instr_detail_level == 2 ) {
2885             proto_tree_add_uint_format(udvm_tree, hf_udvm_offset, bytecode_tvb, offset, (next_operand_address-operand_address), multy_offset,
2886                                 "Addr: %u      offset %u", operand_address, multy_offset);
2887         }
2888         offset += (next_operand_address-operand_address);
2889         operand_address = next_operand_address;
2890
2891         /* %length */
2892         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
2893         if (show_instr_detail_level == 2 ) {
2894             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
2895                                 "Addr: %u      Length %u", operand_address, length);
2896         }
2897         offset += (next_operand_address-operand_address);
2898         operand_address = next_operand_address;
2899
2900
2901         /* $destination */
2902         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &ref_destination, &result_dest);
2903         if (show_instr_detail_level == 2 ) {
2904             proto_tree_add_uint_format(udvm_tree, hf_udvm_ref_dest, bytecode_tvb, offset, (next_operand_address-operand_address), ref_destination,
2905                                 "Addr: %u      $destination %u", operand_address, ref_destination);
2906         }
2907         offset += (next_operand_address-operand_address);
2908
2909         if (show_instr_detail_level == 1)
2910         {
2911             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
2912                                 "Addr: %u ## COPY-OFFSET (offset=%u, length=%u, $destination=%u)",
2913                                 current_address, multy_offset, length, result_dest);
2914         }
2915         current_address = next_operand_address;
2916
2917         /* Execute the instruction:
2918          * To derive the value of the position operand, starting at the memory
2919          * address specified by destination, the UDVM counts backwards a total
2920          * of offset memory addresses.
2921          *
2922          * If the memory address specified in byte_copy_left is reached, the
2923          * next memory address is taken to be (byte_copy_right - 1) modulo 2^16.
2924          */
2925         byte_copy_left = buff[64] << 8;
2926         byte_copy_left = byte_copy_left | buff[65];
2927         byte_copy_right = buff[66] << 8;
2928         byte_copy_right = byte_copy_right | buff[67];
2929
2930         /*
2931          * In order to work out the position, simple arithmetic is tricky
2932          * to apply because there some nasty corner cases. A simple loop
2933          * is inefficient but the logic is simple.
2934          *
2935          * FUTURE: This could be optimised.
2936          */
2937         for (position = ref_destination, i = 0; i < multy_offset; i++)
2938         {
2939             if ( position == byte_copy_left )
2940             {
2941                 position = (byte_copy_right - 1) & 0xffff;
2942             }
2943             else
2944             {
2945                 position = (position - 1) & 0xffff;
2946             }
2947         }
2948
2949         if (print_level_2 ) {
2950             proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
2951                                 "               byte_copy_left = %u byte_copy_right = %u position= %u",
2952                                 byte_copy_left, byte_copy_right, position);
2953         }
2954         /* The COPY-OFFSET instruction then behaves as a COPY-LITERAL
2955          * instruction, taking the value of the position operand to be the last
2956          * memory address reached in the above step.
2957          */
2958
2959         /*
2960          * 8.4.  Byte copying
2961          * :
2962          * The string of bytes is copied in ascending order of memory address,
2963          * respecting the bounds set by byte_copy_left and byte_copy_right.
2964          * More precisely, if a byte is copied from/to Address m then the next
2965          * byte is copied from/to Address n where n is calculated as follows:
2966          *
2967          * Set k := m + 1 (modulo 2^16)
2968          * If k = byte_copy_right then set n := byte_copy_left, else set n := k
2969          *
2970          */
2971
2972         n = 0;
2973         k = ref_destination;
2974         if (print_level_2 ) {
2975             proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
2976                                 "               byte_copy_left = %u byte_copy_right = %u", byte_copy_left, byte_copy_right);
2977         }
2978         while ( n < length ) {
2979             buff[k] = buff[position];
2980             if (print_level_2 ) {
2981                 proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
2982                                     "               Copying value: %5u (0x%x) from Addr: %u to Addr: %u",
2983                                     buff[position], buff[position],(position), k);
2984             }
2985             n++;
2986             k = ( k + 1 ) & 0xffff;
2987             position = ( position + 1 ) & 0xffff;
2988
2989             /*
2990              * Check for circular buffer wrapping after the positions are
2991              * incremented. It is important that k cannot be left set
2992              * to BCR. Also, if either started at BCR then they should continue
2993              * to increment beyond BCR.
2994              */
2995             if ( k == byte_copy_right ) {
2996                 k = byte_copy_left;
2997             }
2998             if ( position == byte_copy_right ) {
2999                 position = byte_copy_left;
3000             }
3001         }
3002         buff[result_dest] = k >> 8;
3003         buff[result_dest + 1] = k & 0x00ff;
3004         used_udvm_cycles = used_udvm_cycles + length;
3005         goto execute_next_instruction;
3006
3007         break;
3008     case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */
3009         if (show_instr_detail_level == 2 ) {
3010             proto_item_append_text(addr_item, " (address, length, start_value, offset)");
3011         }
3012         start_offset = offset;
3013         operand_address = current_address + 1;
3014
3015         /* %address */
3016         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &addr);
3017         if (show_instr_detail_level == 2 ) {
3018             proto_tree_add_uint_format(udvm_tree, hf_udvm_address, bytecode_tvb, offset, (next_operand_address-operand_address), addr,
3019                                 "Addr: %u      Address %u", operand_address, addr);
3020         }
3021         offset += (next_operand_address-operand_address);
3022         operand_address = next_operand_address;
3023
3024         /*  %length, */
3025         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
3026         if (show_instr_detail_level == 2 ) {
3027             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
3028                                 "Addr: %u      Length %u", operand_address, length);
3029         }
3030         offset += (next_operand_address-operand_address);
3031         operand_address = next_operand_address;
3032         /* %start_value */
3033         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &start_value);
3034         if (show_instr_detail_level == 2 ) {
3035             proto_tree_add_uint_format(udvm_tree, hf_udvm_start_value, bytecode_tvb, offset, (next_operand_address-operand_address), start_value,
3036                                 "Addr: %u      start_value %u", operand_address, start_value);
3037         }
3038         offset += (next_operand_address-operand_address);
3039         operand_address = next_operand_address;
3040
3041         /* %offset */
3042         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &multy_offset);
3043         if (show_instr_detail_level == 2 ) {
3044             proto_tree_add_uint_format(udvm_tree, hf_udvm_offset, bytecode_tvb, offset, (next_operand_address-operand_address), multy_offset,
3045                                 "Addr: %u      offset %u", operand_address, multy_offset);
3046         }
3047         offset += (next_operand_address-operand_address);
3048         if (show_instr_detail_level == 1)
3049         {
3050             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
3051                                 "Addr: %u ## MEMSET (address=%u, length=%u, start_value=%u, offset=%u)",
3052                                 current_address, addr, length, start_value, multy_offset);
3053         }
3054         current_address = next_operand_address;
3055         /* exetute the instruction
3056          * The sequence of values used by the MEMSET instruction is specified by
3057          * the following formula:
3058          *
3059          * Seq[n] := (start_value + n * offset) modulo 256
3060          */
3061         n = 0;
3062         k = addr;
3063         byte_copy_right = buff[66] << 8;
3064         byte_copy_right = byte_copy_right | buff[67];
3065         byte_copy_left = buff[64] << 8;
3066         byte_copy_left = byte_copy_left | buff[65];
3067         if (print_level_2 ) {
3068             proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
3069                                 "               byte_copy_left = %u byte_copy_right = %u", byte_copy_left, byte_copy_right);
3070         }
3071         while ( n < length ) {
3072             if ( k == byte_copy_right ) {
3073                 k = byte_copy_left;
3074             }
3075             buff[k] = (start_value + ( n * multy_offset)) & 0xff;
3076             if (print_level_2 ) {
3077                 proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
3078                                     "     Storing value: %u (0x%x) at Addr: %u",
3079                                     buff[k], buff[k], k);
3080             }
3081             k = ( k + 1 ) & 0xffff;
3082             n++;
3083         }/* end while */
3084         used_udvm_cycles = used_udvm_cycles + length;
3085         goto execute_next_instruction;
3086         break;
3087
3088
3089     case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */
3090         if (show_instr_detail_level == 2 ) {
3091             proto_item_append_text(addr_item, " (@address)");
3092         }
3093         start_offset = offset;
3094         operand_address = current_address + 1;
3095         /* @address */
3096         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
3097         next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
3098         if (show_instr_detail_level == 2 ) {
3099             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
3100                                 "Addr: %u      @Address %u", operand_address, at_address);
3101         }
3102         offset += (next_operand_address-operand_address);
3103         if (show_instr_detail_level == 1)
3104         {
3105             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
3106                                 "Addr: %u ## JUMP (@address=%u)",
3107                                 current_address, at_address);
3108         }
3109         current_address = at_address;
3110         goto execute_next_instruction;
3111         break;
3112
3113     case SIGCOMP_INSTR_COMPARE: /* 23 */
3114         /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
3115          */
3116         if (show_instr_detail_level == 2 ) {
3117             proto_item_append_text(addr_item, " (value_1, value_2, @address_1, @address_2, @address_3)");
3118         }
3119         start_offset = offset;
3120         operand_address = current_address + 1;
3121
3122         /* %value_1 */
3123         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value_1);
3124         if (show_instr_detail_level == 2 ) {
3125             proto_tree_add_uint_format(udvm_tree, hf_udvm_value, bytecode_tvb, offset, (next_operand_address-operand_address), value_1,
3126                                 "Addr: %u      Value %u", operand_address, value_1);
3127         }
3128         offset += (next_operand_address-operand_address);
3129         operand_address = next_operand_address;
3130
3131         /* %value_2 */
3132         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value_2);
3133         if (show_instr_detail_level == 2 ) {
3134             proto_tree_add_uint_format(udvm_tree, hf_udvm_value, bytecode_tvb, offset, (next_operand_address-operand_address), value_2,
3135                                 "Addr: %u      Value %u", operand_address, value_2);
3136         }
3137         offset += (next_operand_address-operand_address);
3138         operand_address = next_operand_address;
3139
3140         /* @address_1 */
3141         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
3142         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_1);
3143         at_address_1 = ( current_address + at_address_1) & 0xffff;
3144         if (show_instr_detail_level == 2 ) {
3145             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address_1,
3146                                 "Addr: %u      @Address %u", operand_address, at_address_1);
3147         }
3148         offset += (next_operand_address-operand_address);
3149         operand_address = next_operand_address;
3150
3151
3152         /* @address_2 */
3153         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
3154         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_2);
3155         at_address_2 = ( current_address + at_address_2) & 0xffff;
3156         if (show_instr_detail_level == 2 ) {
3157             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address_2,
3158                                 "Addr: %u      @Address %u", operand_address, at_address_2);
3159         }
3160         offset += (next_operand_address-operand_address);
3161         operand_address = next_operand_address;
3162
3163         /* @address_3 */
3164         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
3165         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_3);
3166         at_address_3 = ( current_address + at_address_3) & 0xffff;
3167         if (show_instr_detail_level == 2 ) {
3168             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address_3,
3169                                 "Addr: %u      @Address %u", operand_address, at_address_3);
3170         }
3171         offset += (next_operand_address-operand_address);
3172         if (show_instr_detail_level == 1)
3173         {
3174             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
3175                                 "Addr: %u ## COMPARE (value_1=%u, value_2=%u, @address_1=%u, @address_2=%u, @address_3=%u)",
3176                                 current_address, value_1, value_2, at_address_1, at_address_2, at_address_3);
3177         }
3178         /* execute the instruction
3179          * If value_1 < value_2 then the UDVM continues instruction execution at
3180          * the memory address specified by address 1. If value_1 = value_2 then
3181          * it jumps to the address specified by address_2. If value_1 > value_2
3182          * then it jumps to the address specified by address_3.
3183          */
3184         if ( value_1 < value_2 )
3185             current_address = at_address_1;
3186         if ( value_1 == value_2 )
3187             current_address = at_address_2;
3188         if ( value_1 > value_2 )
3189             current_address = at_address_3;
3190         goto execute_next_instruction;
3191         break;
3192
3193     case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/
3194         if (show_instr_detail_level == 2) {
3195             proto_item_append_text(addr_item, " (@address) (PUSH addr )");
3196         }
3197         start_offset = offset;
3198         operand_address = current_address + 1;
3199         /* @address */
3200         next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
3201         if (show_instr_detail_level == 2 ) {
3202             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
3203                                 "Addr: %u      @Address %u", operand_address, at_address);
3204         }
3205         offset += (next_operand_address-operand_address);
3206         if (show_instr_detail_level == 1)
3207         {
3208             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
3209                                 "Addr: %u ## CALL (@address=%u)",
3210                                 current_address, at_address);
3211         }
3212         current_address = next_operand_address;
3213
3214         /* Push the current address onto the stack */
3215         stack_location = (buff[70] << 8) | buff[71];
3216         stack_fill = (buff[stack_location] << 8)
3217             | buff[(stack_location+1) & 0xFFFF];
3218         addr = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
3219         if (addr >= UDVM_MEMORY_SIZE - 1)
3220             goto decompression_failure;
3221         buff[addr] = (current_address >> 8) & 0x00FF;
3222         buff[(addr+1) & 0xFFFF] = current_address & 0x00FF;
3223
3224         stack_fill = (stack_fill + 1) & 0xFFFF;
3225         if (stack_location >= UDVM_MEMORY_SIZE - 1)
3226             goto decompression_failure;
3227         buff[stack_location] = (stack_fill >> 8) & 0x00FF;
3228         buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
3229
3230         /* ... and jump to the destination address */
3231         current_address = at_address;
3232
3233         goto execute_next_instruction;
3234
3235         break;
3236
3237     case SIGCOMP_INSTR_RETURN: /* 25 POP and return */
3238         /* Pop value from the top of the stack */
3239         stack_location = (buff[70] << 8) | buff[71];
3240         stack_fill = (buff[stack_location] << 8)
3241             | buff[(stack_location+1) & 0xFFFF];
3242         if (stack_fill == 0)
3243         {
3244             result_code = 16;
3245             goto decompression_failure;
3246         }
3247
3248         stack_fill = (stack_fill - 1) & 0xFFFF;
3249         if (stack_location >= UDVM_MEMORY_SIZE - 1)
3250             goto decompression_failure;
3251         buff[stack_location] = (stack_fill >> 8) & 0x00FF;
3252         buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
3253
3254         addr = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
3255         at_address = (buff[addr] << 8)
3256             | buff[(addr+1) & 0xFFFF];
3257
3258         /* ... and set the PC to the popped value */
3259         current_address = at_address;
3260
3261         goto execute_next_instruction;
3262
3263         break;
3264
3265     case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
3266         /*
3267          * When a SWITCH instruction is encountered the UDVM reads the value of
3268          * j. It then continues instruction execution at the address specified
3269          * by address j.
3270          *
3271          * Decompression failure occurs if j specifies a value of n or more, or
3272          * if the address lies beyond the overall UDVM memory size.
3273          */
3274         instruction_address = current_address;
3275         if (show_instr_detail_level == 2) {
3276             proto_item_append_text(addr_item, " (#n, j, @address_0, @address_1, ... , @address_n-1))");
3277         }
3278         operand_address = current_address + 1;
3279         /* #n
3280          * Number of addresses in the instruction
3281          */
3282         next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
3283         if (print_level_2 ) {
3284             proto_tree_add_uint_format(udvm_tree, hf_udvm_literal_num, bytecode_tvb, offset, (next_operand_address-operand_address), n,
3285                                 "Addr: %u      n %u", operand_address, n);
3286         }
3287         offset += (next_operand_address-operand_address);
3288         operand_address = next_operand_address;
3289         /* %j */
3290         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &j);
3291         if (print_level_2 ) {
3292             proto_tree_add_uint_format(udvm_tree, hf_udvm_j, bytecode_tvb, offset, (next_operand_address-operand_address), j,
3293                                 "Addr: %u      j %u", operand_address, j);
3294         }
3295         offset += (next_operand_address-operand_address);
3296         operand_address = next_operand_address;
3297         m = 0;
3298         while ( m < n ) {
3299             /* @address_n-1 */
3300             /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
3301             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_1);
3302             at_address_1 = ( instruction_address + at_address_1) & 0xffff;
3303             if (print_level_2 ) {
3304                 proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address_1,
3305                                     "Addr: %u      @Address %u", operand_address, at_address_1);
3306             }
3307             offset += (next_operand_address-operand_address);
3308             if ( j == m ) {
3309                 current_address = at_address_1;
3310             }
3311             operand_address = next_operand_address;
3312             m++;
3313         }
3314         /* Check decompression failure */
3315         if ( ( j == n ) || ( j > n )) {
3316             result_code = 5;
3317             goto decompression_failure;
3318         }
3319         if ( current_address > UDVM_MEMORY_SIZE ) {
3320             result_code = 6;
3321             goto decompression_failure;
3322         }
3323         used_udvm_cycles = used_udvm_cycles + n;
3324
3325         goto execute_next_instruction;
3326
3327         break;
3328     case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */
3329         if (show_instr_detail_level == 2) {
3330             proto_item_append_text(addr_item, " (value, position, length, @address)");
3331         }
3332         start_offset = offset;
3333
3334         operand_address = current_address + 1;
3335
3336         /* %value */
3337         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
3338         if (print_level_2 ) {
3339             proto_tree_add_uint_format(udvm_tree, hf_udvm_value, bytecode_tvb, offset, (next_operand_address-operand_address), value,
3340                                 "Addr: %u      Value %u", operand_address, value);
3341         }
3342         offset += (next_operand_address-operand_address);
3343         operand_address = next_operand_address;
3344
3345         /* %position */
3346         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
3347         if (print_level_2 ) {
3348             proto_tree_add_uint_format(udvm_tree, hf_udvm_position, bytecode_tvb, offset, (next_operand_address-operand_address), position,
3349                                 "Addr: %u      position %u", operand_address, position);
3350         }
3351         offset += (next_operand_address-operand_address);
3352         operand_address = next_operand_address;
3353
3354         /* %length */
3355         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
3356         if (print_level_2 ) {
3357             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
3358                                 "Addr: %u      Length %u", operand_address, length);
3359         }
3360         offset += (next_operand_address-operand_address);
3361         operand_address = next_operand_address;
3362
3363         /* @address */
3364         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address);
3365         at_address = ( current_address + at_address) & 0xffff;
3366         if (print_level_2 ) {
3367             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
3368                                 "Addr: %u      @Address %u", operand_address, at_address);
3369         }
3370         offset += (next_operand_address-operand_address);
3371         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
3372         used_udvm_cycles = used_udvm_cycles + length;
3373
3374         n = 0;
3375         k = position;
3376         byte_copy_right = buff[66] << 8;
3377         byte_copy_right = byte_copy_right | buff[67];
3378         byte_copy_left = buff[64] << 8;
3379         byte_copy_left = byte_copy_left | buff[65];
3380         result = 0;
3381
3382         if (print_level_2 ) {
3383             proto_tree_add_text(udvm_tree, message_tvb, 0, -1,
3384                                 "byte_copy_right = %u", byte_copy_right);
3385         }
3386
3387         while (n<length) {
3388
3389             guint16 handle_now = length - n;
3390
3391             if ( k < byte_copy_right && byte_copy_right <= k + (length-n) ) {
3392                 handle_now = byte_copy_right - k;
3393             }
3394
3395             if (k + handle_now >= UDVM_MEMORY_SIZE)
3396                 goto decompression_failure;
3397             result = crc16_ccitt_seed(&buff[k], handle_now, (guint16) (result ^ 0xffff));
3398
3399             k = ( k + handle_now ) & 0xffff;
3400             n = ( n + handle_now ) & 0xffff;
3401
3402             if ( k >= byte_copy_right ) {
3403                 k = byte_copy_left;
3404             }
3405         }
3406
3407         result = result ^ 0xffff;
3408
3409         if (print_level_1 ) {
3410             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
3411                                         "Calculated CRC %u", result);
3412         }
3413         if (result != value) {
3414             current_address = at_address;
3415         }
3416         else {
3417             current_address = next_operand_address;
3418         }
3419         goto execute_next_instruction;
3420         break;
3421
3422
3423     case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */
3424         if (show_instr_detail_level == 2 ) {
3425             proto_item_append_text(addr_item, " length, destination, @address)");
3426         }
3427         start_offset = offset;
3428         operand_address = current_address + 1;
3429         /* %length */
3430         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
3431         if (show_instr_detail_level == 2 ) {
3432             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
3433                                 "Addr: %u      Length %u", operand_address, length);
3434         }
3435         offset += (next_operand_address-operand_address);
3436         operand_address = next_operand_address;
3437
3438         /* %destination */
3439         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
3440         if (show_instr_detail_level == 2 ) {
3441             proto_tree_add_uint_format(udvm_tree, hf_udvm_destination, bytecode_tvb, offset, (next_operand_address-operand_address), destination,
3442                                 "Addr: %u      Destination %u", operand_address, destination);
3443         }
3444         offset += (next_operand_address-operand_address);
3445         operand_address = next_operand_address;
3446
3447         /* @address */
3448         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
3449         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address);
3450         at_address = ( current_address + at_address) & 0xffff;
3451         if (show_instr_detail_level == 2 ) {
3452             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
3453                                 "Addr: %u      @Address %u", operand_address, at_address);
3454         }
3455         offset += (next_operand_address-operand_address);
3456         if (show_instr_detail_level == 1)
3457         {
3458             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
3459                                 "Addr: %u ## INPUT-BYTES length=%u, destination=%u, @address=%u)",
3460                                 current_address, length, destination, at_address);
3461         }
3462         /* execute the instruction TODO insert checks
3463          * RFC 3320 :
3464          *
3465          *    0             7 8            15
3466          *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3467          *   |        byte_copy_left         |  64 - 65
3468          *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3469          *   |        byte_copy_right        |  66 - 67
3470          *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3471          *   |        input_bit_order        |  68 - 69
3472          *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3473          *   |        stack_location         |  70 - 71
3474          *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3475          *
3476          * Figure 7: Memory addresses of the UDVM registers
3477          * :
3478          * 8.4.  Byte copying
3479          * :
3480          * The string of bytes is copied in ascending order of memory address,
3481          * respecting the bounds set by byte_copy_left and byte_copy_right.
3482          * More precisely, if a byte is copied from/to Address m then the next
3483          * byte is copied from/to Address n where n is calculated as follows:
3484          *
3485          * Set k := m + 1 (modulo 2^16)
3486          * If k = byte_copy_right then set n := byte_copy_left, else set n := k
3487          *
3488          */
3489
3490         n = 0;
3491         k = destination;
3492         byte_copy_right = buff[66] << 8;
3493         byte_copy_right = byte_copy_right | buff[67];
3494         byte_copy_left = buff[64] << 8;
3495         byte_copy_left = byte_copy_left | buff[65];
3496         if (print_level_1 ) {
3497             proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
3498                                 "               byte_copy_right = %u", byte_copy_right);
3499         }
3500         /* clear out remaining bits if any */
3501         remaining_bits = 0;
3502         input_bits=0;
3503         /* operand_address used as dummy */
3504         while ( n < length ) {
3505             if (input_address > ( msg_end - 1)) {
3506                 current_address = at_address;
3507                 result_code = 14;
3508                 goto execute_next_instruction;
3509             }
3510
3511             if ( k == byte_copy_right ) {
3512                 k = byte_copy_left;
3513             }
3514             octet = tvb_get_guint8(message_tvb, input_address);
3515             buff[k] = octet;
3516             if (print_level_1 ) {
3517                 proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
3518                                     "               Loading value: %u (0x%x) at Addr: %u", octet, octet, k);
3519             }
3520             input_address++;
3521             /*
3522              * If the instruction requests data that lies beyond the end of the
3523              * SigComp message, no data is returned.  Instead the UDVM moves program
3524              * execution to the address specified by the address operand.
3525              */
3526
3527
3528             k = ( k + 1 ) & 0xffff;
3529             n++;
3530         }
3531         used_udvm_cycles = used_udvm_cycles + length;
3532         current_address = next_operand_address;
3533         goto execute_next_instruction;
3534         break;
3535     case SIGCOMP_INSTR_INPUT_BITS:/* 29   INPUT-BITS (%length, %destination, @address) */
3536         /*
3537          * The length operand indicates the requested number of bits.
3538          * Decompression failure occurs if this operand does not lie between 0
3539          * and 16 inclusive.
3540          *
3541          * The destination operand specifies the memory address to which the
3542          * compressed data should be copied.  Note that the requested bits are
3543          * interpreted as a 2-byte integer ranging from 0 to 2^length - 1, as
3544          * explained in Section 8.2.
3545          *
3546          * If the instruction requests data that lies beyond the end of the
3547          * SigComp message, no data is returned.  Instead the UDVM moves program
3548          * execution to the address specified by the address operand.
3549          */
3550
3551         if (show_instr_detail_level == 2 ) {
3552             proto_item_append_text(addr_item, " (length, destination, @address)");
3553         }
3554         start_offset = offset;
3555         operand_address = current_address + 1;
3556
3557         /* %length */
3558         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
3559         if (show_instr_detail_level == 2 ) {
3560             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
3561                                 "Addr: %u      length %u", operand_address, length);
3562         }
3563         offset += (next_operand_address-operand_address);
3564         operand_address = next_operand_address;
3565         /* %destination */
3566         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
3567         if (show_instr_detail_level == 2 ) {
3568             proto_tree_add_uint_format(udvm_tree, hf_udvm_destination, bytecode_tvb, offset, (next_operand_address-operand_address), destination,
3569                                 "Addr: %u      Destination %u", operand_address, destination);
3570         }
3571         offset += (next_operand_address-operand_address);
3572         operand_address = next_operand_address;
3573
3574         /* @address */
3575         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
3576         next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
3577         if (show_instr_detail_level == 2 ) {
3578             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
3579                                 "Addr: %u      @Address %u", operand_address, at_address);
3580         }
3581         offset += (next_operand_address-operand_address);
3582         if (show_instr_detail_level == 1)
3583         {
3584             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
3585                                 "Addr: %u ## INPUT-BITS length=%u, destination=%u, @address=%u)",
3586                                 current_address, length, destination, at_address);
3587         }
3588         current_address = next_operand_address;
3589
3590         /*
3591          * Execute actual instr.
3592          * The input_bit_order register contains the following three flags:
3593          *
3594          *            0             7 8            15
3595          *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3596          *           |         reserved        |F|H|P|  68 - 69
3597          *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3598          */
3599         input_bit_order = buff[68] << 8;
3600         input_bit_order = input_bit_order | buff[69];
3601         /*
3602          * If the instruction requests data that lies beyond the end of the
3603          * SigComp message, no data is returned.  Instead the UDVM moves program
3604          * execution to the address specified by the address operand.
3605          */
3606
3607         if ( length > 16 ) {
3608             result_code = 7;
3609             goto decompression_failure;
3610         }
3611         if ( input_bit_order > 7 ) {
3612             result_code = 8;
3613             goto decompression_failure;
3614         }
3615
3616         /*
3617          * Transfer F bit to bit_order to tell decomp dispatcher which bit order to use
3618          */
3619         bit_order = ( input_bit_order & 0x0004 ) >> 2;
3620         value = decomp_dispatch_get_bits( message_tvb, udvm_tree, bit_order,
3621                                           buff, &old_input_bit_order, &remaining_bits,
3622                                           &input_bits, &input_address, length, &result_code, msg_end, print_level_1);
3623         if ( result_code == 11 ) {
3624             current_address = at_address;
3625             goto execute_next_instruction;
3626         }
3627         msb = value >> 8;
3628         lsb = value & 0x00ff;
3629         if (destination >= UDVM_MEMORY_SIZE - 1)
3630             goto decompression_failure;
3631         buff[destination] = msb;
3632         buff[(destination + 1) & 0xffff]=lsb;
3633         if (print_level_1 ) {
3634             proto_tree_add_none_format(udvm_tree, hf_sigcomp_loading_result, message_tvb, input_address, 1,
3635                                 "               Loading value: %u (0x%x) at Addr: %u, remaining_bits: %u", value, value, destination, remaining_bits);
3636         }
3637
3638         goto execute_next_instruction;
3639         break;
3640     case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */
3641         /*
3642          * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1,
3643          *  %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n,
3644          *  %upper_bound_n, %uncompressed_n)
3645          */
3646         if (show_instr_detail_level == 2 ) {
3647             proto_item_append_text(addr_item, " (destination, @address, #n, bits_1, lower_bound_1,upper_bound_1, uncompressed_1, ... , bits_n, lower_bound_n,upper_bound_n, uncompressed_n)");
3648         }
3649         start_offset = offset;
3650         operand_address = current_address + 1;
3651
3652         /* %destination */
3653         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
3654         if (show_instr_detail_level == 2 ) {
3655             proto_tree_add_uint_format(udvm_tree, hf_udvm_destination, bytecode_tvb, offset, (next_operand_address-operand_address), destination,
3656                                 "Addr: %u      Destination %u", operand_address, destination);
3657         }
3658         offset += (next_operand_address-operand_address);
3659         operand_address = next_operand_address;
3660
3661         /* @address */
3662         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
3663         next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
3664         if (show_instr_detail_level == 2 ) {
3665             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
3666                                 "Addr: %u      @Address %u", operand_address, at_address);
3667         }
3668         offset += (next_operand_address-operand_address);
3669         operand_address = next_operand_address;
3670
3671         /* #n */
3672         next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
3673         if (show_instr_detail_level == 2 ) {
3674             proto_tree_add_uint_format(udvm_tree, hf_udvm_literal_num, bytecode_tvb, offset, (next_operand_address-operand_address), n,
3675                                 "Addr: %u      n %u", operand_address, n);
3676         }
3677         offset += (next_operand_address-operand_address);
3678         operand_address = next_operand_address;
3679         if (show_instr_detail_level == 1)
3680         {
3681             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
3682                                 "Addr: %u ## INPUT-HUFFMAN (destination=%u, @address=%u, #n=%u, bits_1, lower_1,upper_1, unc_1, ... , bits_%d, lower_%d,upper_%d, unc_%d)",
3683                                 current_address, destination, at_address, n, n, n, n, n);
3684         }
3685
3686         used_udvm_cycles = used_udvm_cycles + n;
3687
3688         /*
3689          * Note that if n = 0 then the INPUT-HUFFMAN instruction is ignored and
3690          * program execution resumes at the following instruction.
3691          * Decompression failure occurs if (bits_1 + ... + bits_n) > 16.
3692          *
3693          * In all other cases, the behavior of the INPUT-HUFFMAN instruction is
3694          * defined below:
3695          *
3696          * 1. Set j := 1 and set H := 0.
3697          *
3698          * 2. Request bits_j compressed bits.  Interpret the returned bits as an
3699          * integer k from 0 to 2^bits_j - 1, as explained in Section 8.2.
3700          *
3701          * 3. Set H := H * 2^bits_j + k.
3702          *
3703          * 4. If data is requested that lies beyond the end of the SigComp
3704          * message, terminate the INPUT-HUFFMAN instruction and move program
3705          * execution to the memory address specified by the address operand.
3706          *
3707          * 5. If (H < lower_bound_j) or (H > upper_bound_j) then set j := j + 1.
3708          * Then go back to Step 2, unless j > n in which case decompression
3709          * failure occurs.
3710          *
3711          * 6. Copy (H + uncompressed_j - lower_bound_j) modulo 2^16 to the
3712          * memory address specified by the destination operand.
3713          *
3714          */
3715         /*
3716          * The input_bit_order register contains the following three flags:
3717          *
3718          *            0             7 8            15
3719          *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3720          *           |         reserved        |F|H|P|  68 - 69
3721          *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3722          *
3723          * Transfer H bit to bit_order to tell decomp dispatcher which bit order to use
3724          */
3725         input_bit_order = buff[68] << 8;
3726         input_bit_order = input_bit_order | buff[69];
3727         bit_order = ( input_bit_order & 0x0002 ) >> 1;
3728
3729         j = 1;
3730         H = 0;
3731         m = n;
3732         outside_huffman_boundaries = TRUE;
3733         print_in_loop = print_level_3;
3734         while ( m > 0 ) {
3735             /* %bits_n */
3736             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &bits_n);
3737             if (print_in_loop ) {
3738                 proto_tree_add_uint_format(udvm_tree, hf_udvm_bits, bytecode_tvb, offset, (next_operand_address-operand_address), bits_n,
3739                                     "Addr: %u      bits_n %u", operand_address, bits_n);
3740             }
3741             offset += (next_operand_address-operand_address);
3742             operand_address = next_operand_address;
3743
3744             /* %lower_bound_n */
3745             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &lower_bound_n);
3746             if (print_in_loop ) {
3747                 proto_tree_add_uint_format(udvm_tree, hf_udvm_lower_bound, bytecode_tvb, offset, (next_operand_address-operand_address), lower_bound_n,
3748                                     "Addr: %u      lower_bound_n %u", operand_address, lower_bound_n);
3749             }
3750             offset += (next_operand_address-operand_address);
3751             operand_address = next_operand_address;
3752             /* %upper_bound_n */
3753             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &upper_bound_n);
3754             if (print_in_loop ) {
3755                 proto_tree_add_uint_format(udvm_tree, hf_udvm_upper_bound, bytecode_tvb, offset, (next_operand_address-operand_address), upper_bound_n,
3756                                     "Addr: %u      upper_bound_n %u", operand_address, upper_bound_n);
3757             }
3758             offset += (next_operand_address-operand_address);
3759             operand_address = next_operand_address;
3760             /* %uncompressed_n */
3761             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &uncompressed_n);
3762             if (print_in_loop ) {
3763                 proto_tree_add_uint_format(udvm_tree, hf_udvm_uncompressed, bytecode_tvb, offset, (next_operand_address-operand_address), uncompressed_n,
3764                                     "Addr: %u      uncompressed_n %u", operand_address, uncompressed_n);
3765             }
3766             offset += (next_operand_address-operand_address);
3767             operand_address = next_operand_address;
3768             /* execute instruction */
3769             if ( outside_huffman_boundaries ) {
3770                 /*
3771                  * 2. Request bits_j compressed bits.  Interpret the returned bits as an
3772                  *    integer k from 0 to 2^bits_j - 1, as explained in Section 8.2.
3773                  */
3774                 k = decomp_dispatch_get_bits( message_tvb, udvm_tree, bit_order,
3775                                               buff, &old_input_bit_order, &remaining_bits,
3776                                               &input_bits, &input_address, bits_n, &result_code, msg_end, print_level_1);
3777                 if ( result_code == 11 ) {
3778                     /*
3779                      * 4. If data is requested that lies beyond the end of the SigComp
3780                      * message, terminate the INPUT-HUFFMAN instruction and move program
3781                      * execution to the memory address specified by the address operand.
3782                      */
3783                     current_address = at_address;
3784                     goto execute_next_instruction;
3785                 }
3786
3787                 /*
3788                  * 3. Set H := H * 2^bits_j + k.
3789                  * [In practice is a shift+OR operation.]
3790                  */
3791                 oldH = H;
3792                 H = (H << bits_n) | k;
3793                 if (print_level_3 ) {
3794                     proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"               Set H(%u) := H(%u) * 2^bits_j(%u) + k(%u)",
3795                                         H ,oldH, 1<<bits_n,k);
3796                 }
3797
3798                 /*
3799                  * 5. If (H < lower_bound_j) or (H > upper_bound_j) then set j := j + 1.
3800                  * Then go back to Step 2, unless j > n in which case decompression
3801                  * failure occurs.
3802                  */
3803                 if ((H < lower_bound_n) || (H > upper_bound_n)) {
3804                     outside_huffman_boundaries = TRUE;
3805                 } else {
3806                     outside_huffman_boundaries = FALSE;
3807                     print_in_loop = FALSE;
3808                     /*
3809                      * 6. Copy (H + uncompressed_j - lower_bound_j) modulo 2^16 to the
3810                      * memory address specified by the destination operand.
3811                      */
3812                     if (print_level_2 ) {
3813                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
3814                                             "               H(%u) = H(%u) + uncompressed_n(%u) - lower_bound_n(%u)",
3815                                             (H + uncompressed_n - lower_bound_n ),H, uncompressed_n, lower_bound_n);
3816                     }
3817                     H = H + uncompressed_n - lower_bound_n;
3818                     msb = H >> 8;
3819                     lsb = H & 0x00ff;
3820                     if (destination >= UDVM_MEMORY_SIZE - 1)
3821                         goto decompression_failure;
3822                     buff[destination] = msb;
3823                     buff[(destination + 1) & 0xffff]=lsb;
3824                     if (print_level_1 ) {
3825                         proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
3826                                             "               Loading H: %u (0x%x) at Addr: %u,j = %u remaining_bits: %u",
3827                                             H, H, destination,( n - m + 1 ), remaining_bits);
3828                     }
3829
3830                 }
3831
3832
3833             }
3834             m = m - 1;
3835         }
3836         if ( outside_huffman_boundaries ) {
3837             result_code = 10;
3838             goto decompression_failure;
3839         }
3840
3841         current_address = next_operand_address;
3842         goto execute_next_instruction;
3843         break;
3844
3845     case SIGCOMP_INSTR_STATE_ACCESS: /* 31 */
3846         /*   STATE-ACCESS (%partial_identifier_start, %partial_identifier_length,
3847          * %state_begin, %state_length, %state_address, %state_instruction)
3848          */
3849         if (show_instr_detail_level == 2 ) {
3850             proto_item_append_text(addr_item, " (partial_identifier_start, partial_identifier_length,state_begin, state_length, state_address, state_instruction)");
3851         }
3852         start_offset = offset;
3853         operand_address = current_address + 1;
3854
3855         /*
3856          * %partial_identifier_start
3857          */
3858         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_start);
3859         if (show_instr_detail_level == 2 ) {
3860             proto_tree_add_uint_format(udvm_tree, hf_partial_identifier_start, bytecode_tvb, offset, (next_operand_address-operand_address), p_id_start,
3861                                 "Addr: %u       partial_identifier_start %u", operand_address, p_id_start);
3862         }
3863         offset += (next_operand_address-operand_address);
3864
3865         /*
3866          * %partial_identifier_length
3867          */
3868         operand_address = next_operand_address;
3869         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_length);
3870         if (show_instr_detail_level == 2 ) {
3871             proto_tree_add_uint_format(udvm_tree, hf_partial_identifier_length, bytecode_tvb, offset, (next_operand_address-operand_address), p_id_length,
3872                                 "Addr: %u       partial_identifier_length %u", operand_address, p_id_length);
3873         }
3874         offset += (next_operand_address-operand_address);
3875         /*
3876          * %state_begin
3877          */
3878         operand_address = next_operand_address;
3879         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_begin);
3880         if (show_instr_detail_level == 2 ) {
3881             proto_tree_add_uint_format(udvm_tree, hf_state_begin, bytecode_tvb, offset, (next_operand_address-operand_address), state_begin,
3882                                 "Addr: %u       state_begin %u", operand_address, state_begin);
3883         }
3884         offset += (next_operand_address-operand_address);
3885         /*
3886          * %state_length
3887          */
3888         operand_address = next_operand_address;
3889         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
3890         if (show_instr_detail_level == 2 ) {
3891             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_length, bytecode_tvb, offset, (next_operand_address-operand_address), state_length,
3892                                 "Addr: %u       state_length %u", operand_address, state_length);
3893         }
3894         offset += (next_operand_address-operand_address);
3895         /*
3896          * %state_address
3897          */
3898         operand_address = next_operand_address;
3899         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
3900         if (show_instr_detail_level == 2 ) {
3901             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_address, bytecode_tvb, offset, (next_operand_address-operand_address), state_address,
3902                                 "Addr: %u       state_address %u", operand_address, state_address);
3903         }
3904         offset += (next_operand_address-operand_address);
3905         /*
3906          * %state_instruction
3907          */
3908         operand_address = next_operand_address;
3909         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
3910         if (show_instr_detail_level == 2 ) {
3911             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_instr, bytecode_tvb, offset, (next_operand_address-operand_address), state_instruction,
3912                                 "Addr: %u       state_instruction %u", operand_address, state_instruction);
3913         }
3914         offset += (next_operand_address-operand_address);
3915         if (show_instr_detail_level == 1)
3916         {
3917             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
3918                                 "Addr: %u ## STATE-ACCESS(31) (partial_identifier_start=%u, partial_identifier_length=%u,state_begin=%u, state_length=%u, state_address=%u, state_instruction=%u)",
3919                                 current_address, p_id_start, p_id_length, state_begin, state_length, state_address, state_instruction);
3920         }
3921         current_address = next_operand_address;
3922         byte_copy_right = buff[66] << 8;
3923         byte_copy_right = byte_copy_right | buff[67];
3924         byte_copy_left = buff[64] << 8;
3925         byte_copy_left = byte_copy_left | buff[65];
3926         if (print_level_2 ) {
3927             proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
3928                                 "               byte_copy_right = %u, byte_copy_left = %u", byte_copy_right,byte_copy_left);
3929         }
3930
3931         result_code = udvm_state_access(message_tvb, udvm_tree, buff, p_id_start, p_id_length, state_begin, &state_length,
3932                                         &state_address, &state_instruction, hf_id);
3933         if ( result_code != 0 ) {
3934             goto decompression_failure;
3935         }
3936         used_udvm_cycles = used_udvm_cycles + state_length;
3937         goto execute_next_instruction;
3938         break;
3939     case SIGCOMP_INSTR_STATE_CREATE: /* 32 */
3940         /*
3941          * STATE-CREATE (%state_length, %state_address, %state_instruction,
3942          * %minimum_access_length, %state_retention_priority)
3943          */
3944         if (show_instr_detail_level == 2 ) {
3945             proto_item_append_text(addr_item, " (state_length, state_address, state_instruction,minimum_access_length, state_retention_priority)");
3946         }
3947         start_offset = offset;
3948         operand_address = current_address + 1;
3949
3950         /*
3951          * %state_length
3952          */
3953         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
3954         if (show_instr_detail_level == 2 ) {
3955             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_length, bytecode_tvb, offset, (next_operand_address-operand_address), state_length,
3956                                 "Addr: %u       state_length %u", operand_address, state_length);
3957         }
3958         offset += (next_operand_address-operand_address);
3959         /*
3960          * %state_address
3961          */
3962         operand_address = next_operand_address;
3963         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
3964         if (show_instr_detail_level == 2 ) {
3965             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_address, bytecode_tvb, offset, (next_operand_address-operand_address), state_address,
3966                                 "Addr: %u       state_address %u", operand_address, state_address);
3967         }
3968         offset += (next_operand_address-operand_address);
3969         /*
3970          * %state_instruction
3971          */
3972         operand_address = next_operand_address;
3973         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
3974         if (show_instr_detail_level == 2 ) {
3975             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_instr, bytecode_tvb, offset, (next_operand_address-operand_address), state_instruction,
3976                                 "Addr: %u       state_instruction %u", operand_address, state_instruction);
3977         }
3978         offset += (next_operand_address-operand_address);
3979         /*
3980          * %minimum_access_length
3981          */
3982         operand_address = next_operand_address;
3983         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &minimum_access_length);
3984         if (show_instr_detail_level == 2 ) {
3985             proto_tree_add_uint_format(udvm_tree, hf_udvm_min_acc_len, bytecode_tvb, offset, (next_operand_address-operand_address), minimum_access_length,
3986                                 "Addr: %u       minimum_access_length %u", operand_address, minimum_access_length);
3987         }
3988         offset += (next_operand_address-operand_address);
3989         /*
3990          * %state_retention_priority
3991          */
3992         operand_address = next_operand_address;
3993         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_retention_priority);
3994         if (show_instr_detail_level == 2 ) {
3995             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_ret_pri, bytecode_tvb, offset, (next_operand_address-operand_address), state_retention_priority,
3996                                 "Addr: %u       state_retention_priority %u", operand_address, state_retention_priority);
3997         }
3998         offset += (next_operand_address-operand_address);
3999         if (show_instr_detail_level == 1)
4000         {
4001             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
4002                                 "Addr: %u ## STATE-CREATE(32) (state_length=%u, state_address=%u, state_instruction=%u,minimum_access_length=%u, state_retention_priority=%u)",
4003                                 current_address, state_length, state_address, state_instruction,minimum_access_length, state_retention_priority);
4004         }
4005         current_address = next_operand_address;
4006         /* Execute the instruction
4007          * TODO Implement the instruction
4008          * RFC3320:
4009          *    Note that the new state item cannot be created until a valid
4010          *    compartment identifier has been returned by the application.
4011          *    Consequently, when a STATE-CREATE instruction is encountered the UDVM
4012          *    simply buffers the five supplied operands until the END-MESSAGE
4013          *    instruction is reached.  The steps taken at this point are described
4014          *    in Section 9.4.9.
4015          *
4016          *   Decompression failure MUST occur if more than four state creation
4017          *   requests are made before the END-MESSAGE instruction is encountered.
4018          *   Decompression failure also occurs if the minimum_access_length does
4019          *   not lie between 6 and 20 inclusive, or if the
4020          *   state_retention_priority is 65535.
4021          */
4022         no_of_state_create++;
4023         if ( no_of_state_create > 4 ) {
4024             result_code = 12;
4025             goto decompression_failure;
4026         }
4027         if (( minimum_access_length < 6 ) || ( minimum_access_length > STATE_BUFFER_SIZE )) {
4028             result_code = 1;
4029             goto decompression_failure;
4030         }
4031         if ( state_retention_priority == 65535 ) {
4032             result_code = 13;
4033             goto decompression_failure;
4034         }
4035         state_length_buff[no_of_state_create] = state_length;
4036         state_address_buff[no_of_state_create] = state_address;
4037         state_instruction_buff[no_of_state_create] = state_instruction;
4038         state_minimum_access_length_buff[no_of_state_create] = minimum_access_length;
4039         /* state_state_retention_priority_buff[no_of_state_create] = state_retention_priority; */
4040         used_udvm_cycles = used_udvm_cycles + state_length;
4041         /* Debug */
4042         byte_copy_right = buff[66] << 8;
4043         byte_copy_right = byte_copy_right | buff[67];
4044         byte_copy_left = buff[64] << 8;
4045         byte_copy_left = byte_copy_left | buff[65];
4046         n = 0;
4047         k = state_address;
4048         while ( n < state_length ) {
4049             if ( k == byte_copy_right ) {
4050                 k = byte_copy_left;
4051             }
4052             string[0]= buff[k];
4053             string[1]= '\0';
4054             if (print_level_3 ) {
4055                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
4056                                     "               Addr: %5u State value: %u (0x%x) ASCII(%s)",
4057                                     k,buff[k],buff[k],format_text(string, 1));
4058             }
4059             k = ( k + 1 ) & 0xffff;
4060             n++;
4061         }
4062         /* End debug */
4063
4064         goto execute_next_instruction;
4065         break;
4066     case SIGCOMP_INSTR_STATE_FREE: /* 33 */
4067         /*
4068          * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
4069          */
4070         if (show_instr_detail_level == 2 ) {
4071             proto_item_append_text(addr_item, " (partial_identifier_start, partial_identifier_length)");
4072         }
4073         start_offset = offset;
4074         operand_address = current_address + 1;
4075         /*
4076          * %partial_identifier_start
4077          */
4078         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_start);
4079         if (show_instr_detail_level == 2 ) {
4080             proto_tree_add_uint_format(udvm_tree, hf_partial_identifier_start, bytecode_tvb, offset, (next_operand_address-operand_address), p_id_start,
4081                                 "Addr: %u       partial_identifier_start %u", operand_address, p_id_start);
4082         }
4083         offset += (next_operand_address-operand_address);
4084         operand_address = next_operand_address;
4085
4086         /*
4087          * %partial_identifier_length
4088          */
4089         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_length);
4090         if (show_instr_detail_level == 2 ) {
4091             proto_tree_add_uint_format(udvm_tree, hf_partial_identifier_length, bytecode_tvb, offset, (next_operand_address-operand_address), p_id_length,
4092                                 "Addr: %u       partial_identifier_length %u", operand_address, p_id_length);
4093         }
4094         offset += (next_operand_address-operand_address);
4095         if (show_instr_detail_level == 1)
4096         {
4097             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
4098                                 "Addr: %u ## STATE-FREE (partial_identifier_start=%u, partial_identifier_length=%u)",
4099                                 current_address, p_id_start, p_id_length);
4100         }
4101         current_address = next_operand_address;
4102
4103         /* Execute the instruction:
4104          * TODO implement it
4105          */
4106         udvm_state_free(buff,p_id_start,p_id_length);
4107
4108         goto execute_next_instruction;
4109         break;
4110     case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */
4111         if (show_instr_detail_level == 2 ) {
4112             proto_item_append_text(addr_item, " (output_start, output_length)");
4113         }
4114         start_offset = offset;
4115         operand_address = current_address + 1;
4116         /*
4117          * %output_start
4118          */
4119         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &output_start);
4120         if (show_instr_detail_level == 2 ) {
4121             proto_tree_add_uint_format(udvm_tree, hf_udvm_output_start, bytecode_tvb, offset, (next_operand_address-operand_address), output_start,
4122                                 "Addr: %u      output_start %u", operand_address, output_start);
4123         }
4124         offset += (next_operand_address-operand_address);
4125         operand_address = next_operand_address;
4126         /*
4127          * %output_length
4128          */
4129         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &output_length);
4130         if (show_instr_detail_level == 2 ) {
4131             proto_tree_add_uint_format(udvm_tree, hf_udvm_output_length, bytecode_tvb, offset, (next_operand_address-operand_address), output_length,
4132                                 "Addr: %u      output_length %u", operand_address, output_length);
4133         }
4134         offset += (next_operand_address-operand_address);
4135         if (show_instr_detail_level == 1)
4136         {
4137             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
4138                                 "Addr: %u ## OUTPUT (output_start=%u, output_length=%u)",
4139                                 current_address, output_start, output_length);
4140         }
4141         current_address = next_operand_address;
4142
4143         /*
4144          * Execute instruction
4145          * 8.4.  Byte copying
4146          * :
4147          * The string of bytes is copied in ascending order of memory address,
4148          * respecting the bounds set by byte_copy_left and byte_copy_right.
4149          * More precisely, if a byte is copied from/to Address m then the next
4150          * byte is copied from/to Address n where n is calculated as follows:
4151          *
4152          * Set k := m + 1 (modulo 2^16)
4153          * If k = byte_copy_right then set n := byte_copy_left, else set n := k
4154          *
4155          */
4156
4157         n = 0;
4158         k = output_start;
4159         byte_copy_right = buff[66] << 8;
4160         byte_copy_right = byte_copy_right | buff[67];
4161         byte_copy_left = buff[64] << 8;
4162         byte_copy_left = byte_copy_left | buff[65];
4163         if (print_level_3 ) {
4164             proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
4165                                 "               byte_copy_right = %u", byte_copy_right);
4166         }
4167         while ( n < output_length ) {
4168
4169             if ( k == byte_copy_right ) {
4170                 k = byte_copy_left;
4171             }
4172             out_buff[output_address] = buff[k];
4173             string[0]= buff[k];
4174             string[1]= '\0';
4175             if (print_level_3 ) {
4176                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
4177                                     "               Output value: %u (0x%x) ASCII(%s) from Addr: %u ,output to dispatcher position %u",
4178                                     buff[k],buff[k],format_text(string,1), k,output_address);
4179             }
4180             k = ( k + 1 ) & 0xffff;
4181             output_address ++;
4182             n++;
4183         }
4184         used_udvm_cycles = used_udvm_cycles + output_length;
4185         goto execute_next_instruction;
4186         break;
4187     case SIGCOMP_INSTR_END_MESSAGE: /* 35 */
4188         /*
4189          * END-MESSAGE (%requested_feedback_location,
4190          * %returned_parameters_location, %state_length, %state_address,
4191          * %state_instruction, %minimum_access_length,
4192          * %state_retention_priority)
4193          */
4194         if (show_instr_detail_level == 2 ) {
4195             proto_item_append_text(addr_item, " (requested_feedback_location,state_instruction, minimum_access_length,state_retention_priority)");
4196         }
4197         start_offset = offset;
4198         operand_address = current_address + 1;
4199
4200         /* %requested_feedback_location */
4201         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &requested_feedback_location);
4202         if (show_instr_detail_level == 2 ) {
4203             proto_tree_add_uint_format(udvm_tree, hf_udvm_req_feedback_loc, bytecode_tvb, offset, (next_operand_address-operand_address), requested_feedback_location,
4204                                 "Addr: %u      requested_feedback_location %u",
4205                                 operand_address, requested_feedback_location);
4206         }
4207         offset += (next_operand_address-operand_address);
4208         operand_address = next_operand_address;
4209         /* returned_parameters_location */
4210         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &returned_parameters_location);
4211         if (show_instr_detail_level == 2 ) {
4212             proto_tree_add_uint_format(udvm_tree, hf_udvm_ret_param_loc, bytecode_tvb, offset, (next_operand_address-operand_address), returned_parameters_location,
4213                                 "Addr: %u      returned_parameters_location %u", operand_address, returned_parameters_location);
4214         }
4215         offset += (next_operand_address-operand_address);
4216         /*
4217          * %state_length
4218          */
4219         operand_address = next_operand_address;
4220         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
4221         if (show_instr_detail_level == 2 ) {
4222             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_length, bytecode_tvb, offset, (next_operand_address-operand_address), state_length,
4223                                 "Addr: %u      state_length %u", operand_address, state_length);
4224         }
4225         offset += (next_operand_address-operand_address);
4226         /*
4227          * %state_address
4228          */
4229         operand_address = next_operand_address;
4230         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
4231         if (show_instr_detail_level == 2 ) {
4232             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_address, bytecode_tvb, offset, (next_operand_address-operand_address), state_address,
4233                                 "Addr: %u      state_address %u", operand_address, state_address);
4234         }
4235         offset += (next_operand_address-operand_address);
4236         /*
4237          * %state_instruction
4238          */
4239         operand_address = next_operand_address;
4240         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
4241         if (show_instr_detail_level == 2 ) {
4242             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_instr, bytecode_tvb, offset, (next_operand_address-operand_address), state_instruction,
4243                                 "Addr: %u      state_instruction %u", operand_address, state_instruction);
4244         }
4245         offset += (next_operand_address-operand_address);
4246
4247         /*
4248          * %minimum_access_length
4249          */
4250         operand_address = next_operand_address;
4251         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &minimum_access_length);
4252         if (show_instr_detail_level == 2 ) {
4253             proto_tree_add_uint_format(udvm_tree, hf_udvm_min_acc_len, bytecode_tvb, offset, (next_operand_address-operand_address), minimum_access_length,
4254                                 "Addr: %u      minimum_access_length %u", operand_address, minimum_access_length);
4255         }
4256         offset += (next_operand_address-operand_address);
4257
4258         /*
4259          * %state_retention_priority
4260          */
4261         operand_address = next_operand_address;
4262         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_retention_priority);
4263         if (show_instr_detail_level == 2 ) {
4264             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_ret_pri, bytecode_tvb, offset, (next_operand_address-operand_address), state_retention_priority,
4265                                 "Addr: %u      state_retention_priority %u", operand_address, state_retention_priority);
4266         }
4267         offset += (next_operand_address-operand_address);
4268         if (show_instr_detail_level == 1)
4269         {
4270             proto_tree_add_none_format(udvm_tree, hf_sigcomp_decompress_instruction, bytecode_tvb, start_offset, offset-start_offset,
4271                                 "Addr: %u ## END-MESSAGE (requested_feedback_location=%u, returned_parameters_location=%u, state_length=%u, state_address=%u, state_instruction=%u, minimum_access_length=%u, state_retention_priority=%u)",
4272                                 current_address, requested_feedback_location, returned_parameters_location, state_length, state_address, state_instruction, minimum_access_length,state_retention_priority);
4273         }
4274         /* TODO: This isn't currently totaly correct as END_INSTRUCTION might not create state */
4275         no_of_state_create++;
4276         if ( no_of_state_create > 4 ) {
4277             result_code = 12;
4278             goto decompression_failure;
4279         }
4280         state_length_buff[no_of_state_create] = state_length;
4281         state_address_buff[no_of_state_create] = state_address;
4282         state_instruction_buff[no_of_state_create] = state_instruction;
4283         /* Not used ? */
4284         state_minimum_access_length_buff[no_of_state_create] = minimum_access_length;
4285         /* state_state_retention_priority_buff[no_of_state_create] = state_retention_priority; */
4286
4287         /* Execute the instruction
4288          */
4289         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"no_of_state_create %u",no_of_state_create);
4290         if ( no_of_state_create != 0 ) {
4291             memset(sha1_digest_buf, 0, STATE_BUFFER_SIZE);
4292             n = 1;
4293             byte_copy_right = buff[66] << 8;
4294             byte_copy_right = byte_copy_right | buff[67];
4295             byte_copy_left = buff[64] << 8;
4296             byte_copy_left = byte_copy_left | buff[65];
4297             while ( n < no_of_state_create + 1 ) {
4298                 sha1buff = (guint8 *)g_malloc(state_length_buff[n]+8);
4299                 sha1buff[0] = state_length_buff[n] >> 8;
4300                 sha1buff[1] = state_length_buff[n] & 0xff;
4301                 sha1buff[2] = state_address_buff[n] >> 8;
4302                 sha1buff[3] = state_address_buff[n] & 0xff;
4303                 sha1buff[4] = state_instruction_buff[n] >> 8;
4304                 sha1buff[5] = state_instruction_buff[n] & 0xff;
4305                 sha1buff[6] = state_minimum_access_length_buff[n] >> 8;
4306                 sha1buff[7] = state_minimum_access_length_buff[n] & 0xff;
4307                 if (print_level_3 ) {
4308                     for ( x=0; x < 8; x++) {
4309                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"sha1buff %u 0x%x",
4310                                             x,sha1buff[x]);
4311                     }
4312                 }
4313                 k = state_address_buff[n];
4314                 for ( x=0; x < state_length_buff[n]; x++)
4315                 {
4316                     if ( k == byte_copy_right ) {
4317                         k = byte_copy_left;
4318                     }
4319                     sha1buff[8+x] = buff[k];
4320                     k = ( k + 1 ) & 0xffff;
4321                 }
4322
4323                 sha1_starts( &ctx );
4324                 sha1_update( &ctx, (guint8 *) sha1buff, state_length_buff[n] + 8);
4325                 sha1_finish( &ctx, sha1_digest_buf );
4326                 if (print_level_3 ) {
4327                     proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"SHA1 digest %s", bytes_to_str(wmem_packet_scope(), sha1_digest_buf, STATE_BUFFER_SIZE));
4328
4329                 }
4330 /* begin partial state-id change cco@iptel.org */
4331 #if 0
4332                 udvm_state_create(sha1buff, sha1_digest_buf, state_minimum_access_length_buff[n]);
4333 #endif
4334                 udvm_state_create(sha1buff, sha1_digest_buf, STATE_MIN_ACCESS_LEN);
4335 /* end partial state-id change cco@iptel.org */
4336                 proto_tree_add_text(udvm_tree,bytecode_tvb, 0, -1,"### Creating state ###");
4337                 proto_tree_add_string(udvm_tree,hf_id, bytecode_tvb, 0, 0, bytes_to_str(wmem_packet_scope(), sha1_digest_buf, STATE_MIN_ACCESS_LEN));
4338
4339                 n++;
4340
4341             }
4342         }
4343
4344
4345
4346         /* At least something got decompressed, show it */
4347         decomp_tvb = tvb_new_child_real_data(message_tvb, out_buff,output_address,output_address);
4348         /* Arrange that the allocated packet data copy be freed when the
4349          * tvbuff is freed.
4350          */
4351         tvb_set_free_cb( decomp_tvb, g_free );
4352
4353         add_new_data_source(pinfo, decomp_tvb, "Decompressed SigComp message");
4354         /*
4355           proto_tree_add_text(udvm_tree, decomp_tvb, 0, -1,"SigComp message Decompressed");
4356         */
4357         used_udvm_cycles = used_udvm_cycles + state_length;
4358         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"maximum_UDVM_cycles %u used_udvm_cycles %u",
4359                             maximum_UDVM_cycles, used_udvm_cycles);
4360         return decomp_tvb;
4361         break;
4362
4363     default:
4364         expert_add_info_format(pinfo, addr_item, &ei_sigcomp_invalid_instruction,
4365                             "Addr %u Invalid instruction: %u (0x%x)", current_address,current_instruction,current_instruction);
4366         break;
4367     }
4368     g_free(out_buff);
4369     return NULL;
4370 decompression_failure:
4371
4372     proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"DECOMPRESSION FAILURE: %s",
4373                         val_to_str(result_code, result_code_vals,"Unknown (%u)"));
4374     g_free(out_buff);
4375     THROW(ReportedBoundsError);
4376     return NULL;
4377
4378 }
4379
4380 /**********************************************************************************************
4381  *
4382  *                       SIGCOMP DISSECTOR
4383  *
4384  **********************************************************************************************/
4385
4386
4387 /* Sigcomp over TCP record marking used
4388  * RFC 3320
4389  * 4.2.2.  Record Marking
4390  *
4391  * For a stream-based transport, the dispatcher delimits messages by
4392  * parsing the compressed data stream for instances of 0xFF and taking
4393  * the following actions:
4394  * Occurs in data stream:     Action:
4395  *
4396  *   0xFF 00                    one 0xFF byte in the data stream
4397  *   0xFF 01                    same, but the next byte is quoted (could
4398  *                              be another 0xFF)
4399  *      :                                           :
4400  *   0xFF 7F                    same, but the next 127 bytes are quoted
4401  *   0xFF 80 to 0xFF FE         (reserved for future standardization)
4402  *   0xFF FF                    end of SigComp message
4403  *   :
4404  *   In UDVM version 0x01, any occurrence of the combinations 0xFF80 to
4405  *   0xFFFE that are not protected by quoting causes decompression
4406  *   failure; the decompressor SHOULD close the stream-based transport in
4407  *   this case.
4408  */
4409
4410 /*
4411  * TODO: Reassembly, handle more than one message in a tcp segment.
4412  */
4413
4414 static int
4415 dissect_sigcomp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *_data _U_)
4416 {
4417     proto_item *ti;
4418     proto_tree *sigcomp_tree;
4419     tvbuff_t   *unescaped_tvb;
4420
4421     guint8     *buff;
4422     int         offset = 0;
4423     int         length;
4424     guint8      octet;
4425     guint16     data;
4426     int         i;
4427     int         n;
4428     gboolean    end_off_message;
4429
4430     top_tree = tree;
4431
4432     /* Is this SIGCOMP ? */
4433     data = tvb_get_ntohs(tvb, offset);
4434     if (data == 0xffff) {
4435         /* delimiter */
4436         offset = offset + 2;
4437         octet = tvb_get_guint8(tvb,offset);
4438     } else {
4439         octet = tvb_get_guint8(tvb,offset);
4440     }
4441     if ((octet  & 0xf8) != 0xf8)
4442      return offset;
4443
4444     /* Search for delimiter 0xffff in the remain tvb buffer */
4445     length = tvb_ensure_length_remaining(tvb, offset);
4446     for (i=0; i<(length-1); ++i) {
4447         /* Loop end criteria is (length-1) because we take 2 bytes each loop */
4448         data = tvb_get_ntohs(tvb, offset+i);
4449         if (0xffff == data) break;
4450     }
4451     if (i >= (length-1)) {
4452         /* SIGCOMP may be subdissector of SIP, so we use
4453          * pinfo->saved_can_desegment to determine whether do desegment
4454          * as well as pinfo->can_desegment */
4455         if (pinfo->can_desegment || pinfo->saved_can_desegment) {
4456             /* Delimiter oxffff was not found, not a complete SIGCOMP PDU */
4457             pinfo->desegment_offset = offset;
4458             pinfo->desegment_len=DESEGMENT_ONE_MORE_SEGMENT;
4459             return -1;
4460         }
4461     }
4462
4463     /* Make entries in Protocol column and Info column on summary display */
4464     col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
4465
4466     col_clear(pinfo->cinfo, COL_INFO);
4467
4468     length = tvb_captured_length_remaining(tvb,offset);
4469
4470 try_again:
4471     /* create display subtree for the protocol */
4472     ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, ENC_NA);
4473     sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
4474     i=0;
4475     end_off_message = FALSE;
4476     buff = (guint8 *)wmem_alloc(pinfo->pool, length-offset);
4477     if (udvm_print_detail_level>2)
4478         proto_tree_add_text(sigcomp_tree, tvb, offset, -1,"Starting to remove escape digits");
4479     while ((offset < length) && (end_off_message == FALSE)) {
4480         octet = tvb_get_guint8(tvb,offset);
4481         if ( octet == 0xff ) {
4482             if ( offset +1 >= length ) {
4483                 /* if the tvb is short don't check for the second escape digit */
4484                 offset++;
4485                 continue;
4486             }
4487             if (udvm_print_detail_level>2)
4488                 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
4489                     "              Escape digit found (0xFF)");
4490             octet = tvb_get_guint8(tvb, offset+1);
4491             if ( octet == 0) {
4492                 buff[i] = 0xff;
4493                 offset = offset +2;
4494                 i++;
4495                 continue;
4496             }
4497             if ((octet > 0x7f) && (octet < 0xff )) {
4498                 if (udvm_print_detail_level>2)
4499                     proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
4500                         "              Illegal escape code");
4501                 offset += tvb_captured_length_remaining(tvb,offset);
4502                 return offset;
4503             }
4504             if ( octet == 0xff) {
4505                 if (udvm_print_detail_level>2)
4506                     proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
4507                         "              End of SigComp message indication found (0xFFFF)");
4508                 end_off_message = TRUE;
4509                 offset = offset+2;
4510                 continue;
4511             }
4512             buff[i] = 0xff;
4513             if (udvm_print_detail_level>2)
4514                 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
4515                             "              Addr: %u tvb value(0x%0x) ", i, buff[i]);
4516             i++;
4517             offset = offset+2;
4518             if (udvm_print_detail_level>2)
4519             proto_tree_add_text(sigcomp_tree, tvb, offset, octet,
4520                         "              Copying %u bytes literally",octet);
4521             if ( offset+octet >= length)
4522                 /* if the tvb is short don't copy further than the end */
4523                 octet = length - offset;
4524             for ( n=0; n < octet; n++ ) {
4525                 buff[i] = tvb_get_guint8(tvb, offset);
4526                 if (udvm_print_detail_level>2)
4527                     proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
4528                                 "                  Addr: %u tvb value(0x%0x) ", i, buff[i]);
4529                 i++;
4530                 offset++;
4531             }
4532             continue;
4533         }
4534         buff[i] = octet;
4535         if (udvm_print_detail_level>2)
4536             proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
4537                         "              Addr: %u tvb value(0x%0x) ", i, buff[i]);
4538
4539         i++;
4540         offset++;
4541     }
4542     unescaped_tvb = tvb_new_child_real_data(tvb, buff,i,i);
4543
4544     add_new_data_source(pinfo, unescaped_tvb, "Unescaped Data handed to the SigComp dissector");
4545
4546     proto_tree_add_text(sigcomp_tree, unescaped_tvb, 0, -1,"Data handed to the Sigcomp dissector");
4547     if (end_off_message == TRUE) {
4548         dissect_sigcomp_common(unescaped_tvb, pinfo, sigcomp_tree);
4549     } else {
4550         proto_tree_add_text(sigcomp_tree, unescaped_tvb, 0, -1,"TCP Fragment, no end mark found");
4551     }
4552     if ( offset < length) {
4553         goto try_again;
4554     }
4555
4556     return offset;
4557 }
4558 /* Code to actually dissect the packets */
4559 static int
4560 dissect_sigcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
4561 {
4562     proto_item *ti;
4563     proto_tree *sigcomp_tree;
4564     gint        offset = 0;
4565     gint8       octet;
4566
4567     /* If we got called from SIP this might be over TCP */
4568     if ( pinfo->ptype == PT_TCP )
4569         return dissect_sigcomp_tcp(tvb, pinfo, tree, NULL);
4570
4571     /* Is this a SigComp message or not ? */
4572     octet = tvb_get_guint8(tvb, offset);
4573     if ((octet  & 0xf8) != 0xf8)
4574      return 0;
4575
4576     /* Make entries in Protocol column and Info column on summary display */
4577     col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
4578
4579     col_clear(pinfo->cinfo, COL_INFO);
4580
4581     top_tree = tree;
4582
4583     /* create display subtree for the protocol */
4584     ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, ENC_NA);
4585     sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
4586
4587     return dissect_sigcomp_common(tvb, pinfo, sigcomp_tree);
4588 }
4589 /* Code to actually dissect the packets */
4590 static int
4591 dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sigcomp_tree)
4592 {
4593
4594 /* Set up structures needed to add the protocol subtree and manage it */
4595     tvbuff_t   *udvm_tvb, *msg_tvb, *udvm2_tvb;
4596     tvbuff_t   *decomp_tvb   = NULL;
4597     proto_item *udvm_bytecode_item, *udvm_exe_item;
4598     proto_tree *sigcomp_udvm_tree, *sigcomp_udvm_exe_tree;
4599     gint        offset       = 0;
4600     gint        bytecode_offset;
4601     guint16     partial_state_len;
4602     guint       octet;
4603     guint8      returned_feedback_field[128];
4604     guint8      partial_state[12];
4605     guint       tbit;
4606     guint16     len          = 0;
4607     guint16     bytecode_len = 0;
4608     guint       destination;
4609     gint        msg_len      = 0;
4610     guint8     *buff;
4611     guint16     p_id_start;
4612     guint8      i;
4613     guint16     state_begin;
4614     guint16     state_length;
4615     guint16     state_address;
4616     guint16     state_instruction;
4617     guint16     result_code;
4618     gchar      *partial_state_str;
4619     guint8      nack_version;
4620
4621
4622
4623 /* add an item to the subtree, see section 1.6 for more information */
4624     octet = tvb_get_guint8(tvb, offset);
4625
4626 /*   A SigComp message takes one of two forms depending on whether it
4627  *  accesses a state item at the receiving endpoint.  The two variants of
4628  *  a SigComp message are given in Figure 3.  (The T-bit controls the
4629  *  format of the returned feedback item and is defined in Section 7.1.)
4630  *
4631  *   0   1   2   3   4   5   6   7       0   1   2   3   4   5   6   7
4632  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
4633  * | 1   1   1   1   1 | T |  len  |   | 1   1   1   1   1 | T |   0   |
4634  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
4635  * |                               |   |                               |
4636  * :    returned feedback item     :   :    returned feedback item     :
4637  * |                               |   |                               |
4638  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
4639  * |                               |   |           code_len            |
4640  * :   partial state identifier    :   +---+---+---+---+---+---+---+---+
4641  *
4642  * |                               |   |   code_len    |  destination  |
4643  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
4644  * |                               |   |                               |
4645  * :   remaining SigComp message   :   :    uploaded UDVM bytecode     :
4646  * |                               |   |                               |
4647  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
4648  *                                     |                               |
4649  *                                     :   remaining SigComp message   :
4650  *                                     |                               |
4651  *                                     +---+---+---+---+---+---+---+---+
4652  *
4653  * RFC 4077:
4654  * The format of the NACK message and the use of the fields within it
4655  * are shown in Figure 1.
4656  *
4657  *                     0   1   2   3   4   5   6   7
4658  *                  +---+---+---+---+---+---+---+---+
4659  *                  | 1   1   1   1   1 | T |   0   |
4660  *                  +---+---+---+---+---+---+---+---+
4661  *                  |                               |
4662  *                  :    returned feedback item     :
4663  *                  |                               |
4664  *                  +---+---+---+---+---+---+---+---+
4665  *                  |         code_len = 0          |
4666  *                  +---+---+---+---+---+---+---+---+
4667  *                  | code_len = 0  |  version = 1  |
4668  *                  +---+---+---+---+---+---+---+---+
4669  *                  |          Reason Code          |
4670  *                  +---+---+---+---+---+---+---+---+
4671  *                  |  OPCODE of failed instruction |
4672  *                  +---+---+---+---+---+---+---+---+
4673  *                  |   PC of failed instruction    |
4674  *                  |                               |
4675  *                  +---+---+---+---+---+---+---+---+
4676  *                  |                               |
4677  *                  : SHA-1 Hash of failed message  :
4678  *                  |                               |
4679  *                  +---+---+---+---+---+---+---+---+
4680  *                  |                               |
4681  *                  :         Error Details         :
4682  *                  |                               |
4683  *                  +---+---+---+---+---+---+---+---+
4684  *                  Figure 1: SigComp NACK Message Format
4685  */
4686
4687     proto_tree_add_item(sigcomp_tree,hf_sigcomp_t_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
4688     proto_tree_add_item(sigcomp_tree,hf_sigcomp_len, tvb, offset, 1, ENC_BIG_ENDIAN);
4689     tbit = ( octet & 0x04)>>2;
4690     partial_state_len = octet & 0x03;
4691     offset ++;
4692     if ( partial_state_len != 0 ) {
4693         /*
4694          * The len field encodes the number of transmitted bytes as follows:
4695          *
4696          *   Encoding:   Length of partial state identifier
4697          *
4698          *   01          6 bytes
4699          *   10          9 bytes
4700          *   11          12 bytes
4701          *
4702          */
4703         partial_state_len = partial_state_len * 3 + 3;
4704
4705         /*
4706          * Message format 1
4707          */
4708         col_set_str(pinfo->cinfo, COL_INFO, "Msg format 1");
4709
4710         if ( tbit == 1 ) {
4711             /*
4712              * Returned feedback item exists
4713              */
4714             len = 1;
4715             octet = tvb_get_guint8(tvb, offset);
4716             /* 0   1   2   3   4   5   6   7       0   1   2   3   4   5   6   7
4717              * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
4718              * | 0 |  returned_feedback_field  |   | 1 | returned_feedback_length  |
4719              * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
4720              *                                     |                               |
4721              *                                     :    returned_feedback_field    :
4722              *                                     |                               |
4723              *                                     +---+---+---+---+---+---+---+---+
4724              * Figure 4: Format of returned feedback item
4725              */
4726
4727             if ( (octet & 0x80) != 0 ) {
4728                 len = octet & 0x7f;
4729                 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
4730                                     tvb, offset, 1, ENC_BIG_ENDIAN);
4731                 offset ++;
4732                 tvb_memcpy(tvb,returned_feedback_field,offset, len);
4733             } else {
4734                 returned_feedback_field[0] = tvb_get_guint8(tvb, offset) & 0x7f;
4735             }
4736             proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
4737                                  tvb, offset, len, returned_feedback_field);
4738             offset = offset + len;
4739         }
4740         tvb_memcpy(tvb, partial_state, offset, partial_state_len);
4741         partial_state_str = bytes_to_str(wmem_packet_scope(), partial_state, partial_state_len);
4742         proto_tree_add_string(sigcomp_tree,hf_sigcomp_partial_state,
4743             tvb, offset, partial_state_len, partial_state_str);
4744         offset = offset + partial_state_len;
4745         msg_len = tvb_reported_length_remaining(tvb, offset);
4746
4747         if (msg_len>0) {
4748             proto_item *ti;
4749             ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_remaining_message_bytes, tvb,
4750                                      offset, 0, msg_len);
4751             PROTO_ITEM_SET_GENERATED(ti);
4752         }
4753
4754         if ( decompress ) {
4755             msg_tvb = tvb_new_subset_length(tvb, offset, msg_len);
4756             /*
4757              * buff                 = Where "state" will be stored
4758              * p_id_start           = Partial state identifier start pos in the buffer(buff)
4759              * partial_state_len    = Partial state identifier length
4760              * state_begin          = Where to start to read state from
4761              * state_length         = Length of state
4762              * state_address            = Address where to store the state in the buffer(buff)
4763              * state_instruction    =
4764              * TRUE                 = Indicates that state_* is in the stored state
4765              */
4766             /*
4767              * Note: The allocated buffer must be zeroed or some strange effects might occur.
4768              */
4769             buff = (guint8 *)wmem_alloc0(pinfo->pool, UDVM_MEMORY_SIZE);
4770
4771
4772             p_id_start = 0;
4773             state_begin = 0;
4774             /* These values will be loaded from the buffered state in sigcomp_state_hdlr
4775              */
4776             state_length = 0;
4777             state_address = 0;
4778             state_instruction =0;
4779
4780             i = 0;
4781             while ( i < partial_state_len ) {
4782                 buff[i] = partial_state[i];
4783                 i++;
4784             }
4785
4786 /* begin partial state-id change cco@iptel.org */
4787 #if 0
4788             result_code = udvm_state_access(tvb, sigcomp_tree, buff, p_id_start, partial_state_len, state_begin, &state_length,
4789                 &state_address, &state_instruction, hf_sigcomp_partial_state);
4790 #endif
4791             result_code = udvm_state_access(tvb, sigcomp_tree, buff, p_id_start, STATE_MIN_ACCESS_LEN, state_begin, &state_length,
4792                 &state_address, &state_instruction, hf_sigcomp_partial_state);
4793
4794 /* end partial state-id change cco@iptel.org */
4795             if ( result_code != 0 ) {
4796                 proto_item *ti;
4797                 ti = proto_tree_add_text(sigcomp_tree, tvb, 0, -1,"Failed to Access state Wireshark UDVM diagnostic: %s.",
4798                                          val_to_str(result_code, result_code_vals,"Unknown (%u)"));
4799                 PROTO_ITEM_SET_GENERATED(ti);
4800                 return tvb_captured_length(tvb);
4801             }
4802
4803             udvm_tvb = tvb_new_child_real_data(tvb, buff,state_length+state_address,state_length+state_address);
4804             add_new_data_source(pinfo, udvm_tvb, "State/ExecutionTrace");
4805
4806             udvm2_tvb = tvb_new_subset_length(udvm_tvb, state_address, state_length);
4807             udvm_exe_item = proto_tree_add_item(sigcomp_tree, hf_udvm_execution_trace,
4808                                                 udvm2_tvb, 0, state_length,
4809                                                 ENC_NA);
4810             sigcomp_udvm_exe_tree = proto_item_add_subtree( udvm_exe_item, ett_sigcomp_udvm_exe);
4811
4812             decomp_tvb = decompress_sigcomp_message(udvm2_tvb, msg_tvb, pinfo,
4813                            sigcomp_udvm_exe_tree, state_address,
4814                            udvm_print_detail_level, hf_sigcomp_partial_state,
4815                            offset, state_length, partial_state_len, state_instruction);
4816
4817
4818             if ( decomp_tvb ) {
4819                 proto_item *ti;
4820                 guint32 compression_ratio =
4821                     (guint32)(((float)tvb_reported_length(decomp_tvb) / (float)tvb_reported_length(tvb)) * 100);
4822
4823                 /* Show compression ratio achieved */
4824                 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_compression_ratio, decomp_tvb,
4825                                          0, 0, compression_ratio);
4826                 PROTO_ITEM_SET_GENERATED(ti);
4827
4828                 if ( display_raw_txt )
4829                     tvb_raw_text_add(decomp_tvb, top_tree);
4830
4831                 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
4832                 col_set_fence(pinfo->cinfo,COL_PROTOCOL);
4833                 call_dissector(sip_handle, decomp_tvb, pinfo, top_tree);
4834             }
4835         }/* if decompress */
4836
4837     }
4838     else{
4839         /*
4840          * Message format 2
4841          */
4842     col_set_str(pinfo->cinfo, COL_INFO, "Msg format 2");
4843         if ( tbit == 1 ) {
4844             /*
4845              * Returned feedback item exists
4846              */
4847             len = 1;
4848             octet = tvb_get_guint8(tvb, offset);
4849             if ( (octet & 0x80) != 0 ) {
4850                 len = octet & 0x7f;
4851                 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
4852                                     tvb, offset, 1, ENC_BIG_ENDIAN);
4853                 offset ++;
4854             }
4855             tvb_memcpy(tvb,returned_feedback_field,offset, len);
4856             proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
4857                                  tvb, offset, len, returned_feedback_field);
4858             offset = offset + len;
4859         }
4860         len = tvb_get_ntohs(tvb, offset) >> 4;
4861         nack_version = tvb_get_guint8(tvb, offset+1) & 0x0f;
4862         if ((len == 0) && (nack_version == 1)) {
4863             /* NACK MESSAGE */
4864             proto_item *reason_ti;
4865             guint8 opcode;
4866             offset++;
4867             proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
4868             offset++;
4869             octet = tvb_get_guint8(tvb, offset);
4870             reason_ti = proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
4871             offset++;
4872             opcode = tvb_get_guint8(tvb, offset);
4873             proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_failed_op_code, tvb, offset, 1, ENC_BIG_ENDIAN);
4874             offset++;
4875
4876             /* Add expert item for NACK */
4877             expert_add_info_format(pinfo, reason_ti, &ei_sigcomp_nack_failed_op_code,
4878                                    "SigComp NACK (reason=%s, opcode=%s)",
4879                                    val_to_str_ext_const(octet, &sigcomp_nack_reason_code_vals_ext, "Unknown"),
4880                                    val_to_str_ext_const(opcode, &udvm_instruction_code_vals_ext, "Unknown"));
4881
4882             proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_pc, tvb, offset, 2, ENC_BIG_ENDIAN);
4883             offset = offset +2;
4884             proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_sha1, tvb, offset, SHA1_DIGEST_LEN, ENC_NA);
4885             offset = offset +SHA1_DIGEST_LEN;
4886
4887             /* Add NACK info to info column */
4888             col_append_fstr(pinfo->cinfo, COL_INFO, "  NACK reason=%s, opcode=%s",
4889                             val_to_str_ext_const(octet, &sigcomp_nack_reason_code_vals_ext, "Unknown"),
4890                             val_to_str_ext_const(opcode, &udvm_instruction_code_vals_ext, "Unknown"));
4891
4892             switch ( octet) {
4893             case SIGCOMP_NACK_STATE_NOT_FOUND:
4894             case SIGCOMP_NACK_ID_NOT_UNIQUE:
4895             case SIGCOMP_NACK_STATE_TOO_SHORT:
4896                 /* State ID (6 - 20 bytes) */
4897                 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_state_id, tvb, offset, -1, ENC_NA);
4898                 break;
4899             case SIGCOMP_NACK_CYCLES_EXHAUSTED:
4900                 /* Cycles Per Bit (1 byte) */
4901                 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_cycles_per_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
4902                 break;
4903             case SIGCOMP_NACK_BYTECODES_TOO_LARGE:
4904                 /* Memory size (2 bytes) */
4905                 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_memory_size, tvb, offset, 2, ENC_BIG_ENDIAN);
4906                 break;
4907             default:
4908                 break;
4909             }
4910         } else {
4911             octet = tvb_get_guint8(tvb, (offset + 1));
4912             destination = (octet & 0x0f);
4913             if ( destination != 0 )
4914                 destination = 64 + ( destination * 64 );
4915             proto_tree_add_item(sigcomp_tree,hf_sigcomp_code_len, tvb, offset, 2, ENC_BIG_ENDIAN);
4916             proto_tree_add_item(sigcomp_tree,hf_sigcomp_destination, tvb, (offset+ 1), 1, ENC_BIG_ENDIAN);
4917             offset = offset +2;
4918
4919             bytecode_len = len;
4920             bytecode_offset = offset;
4921             udvm_bytecode_item = proto_tree_add_item(sigcomp_tree, hf_sigcomp_udvm_bytecode, tvb,
4922                                                      bytecode_offset, bytecode_len, ENC_NA);
4923             proto_item_append_text(udvm_bytecode_item,
4924                                    " %u (0x%x) bytes", bytecode_len, bytecode_len);
4925             sigcomp_udvm_tree = proto_item_add_subtree( udvm_bytecode_item, ett_sigcomp_udvm);
4926
4927             udvm_tvb = tvb_new_subset_length(tvb, offset, len);
4928             if ( dissect_udvm_code )
4929                 dissect_udvm_bytecode(udvm_tvb, sigcomp_udvm_tree, destination);
4930
4931             offset = offset + len;
4932             msg_len = tvb_reported_length_remaining(tvb, offset);
4933             if (msg_len>0) {
4934                 proto_item *ti = proto_tree_add_text(sigcomp_tree, tvb, offset, -1,
4935                                                      "Remaining SigComp message %u bytes",
4936                                                      tvb_reported_length_remaining(tvb, offset));
4937                 PROTO_ITEM_SET_GENERATED(ti);
4938             }
4939             if ( decompress ) {
4940
4941                 msg_tvb = tvb_new_subset_length(tvb, offset, msg_len);
4942
4943                 udvm_exe_item = proto_tree_add_item(sigcomp_tree, hf_udvm_execution_trace,
4944                                                     tvb, bytecode_offset, bytecode_len,
4945                                                     ENC_NA);
4946                 sigcomp_udvm_exe_tree = proto_item_add_subtree( udvm_exe_item, ett_sigcomp_udvm_exe);
4947                 decomp_tvb = decompress_sigcomp_message(udvm_tvb, msg_tvb, pinfo,
4948                            sigcomp_udvm_exe_tree, destination,
4949                            udvm_print_detail_level, hf_sigcomp_partial_state,
4950                            offset, 0, 0, destination);
4951                 if ( decomp_tvb ) {
4952                     proto_item *ti;
4953                     guint32 compression_ratio =
4954                         (guint32)(((float)tvb_reported_length(decomp_tvb) / (float)tvb_reported_length(tvb)) * 100);
4955
4956                     /* Show compression ratio achieved */
4957                     ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_compression_ratio, decomp_tvb,
4958                                              0, 0, compression_ratio);
4959                     PROTO_ITEM_SET_GENERATED(ti);
4960
4961                     if ( display_raw_txt )
4962                         tvb_raw_text_add(decomp_tvb, top_tree);
4963
4964                     col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
4965                     col_set_fence(pinfo->cinfo,COL_PROTOCOL);
4966                     call_dissector(sip_handle, decomp_tvb, pinfo, top_tree);
4967                 }
4968             } /* if decompress */
4969         }/*if len==0 */
4970
4971     }
4972     return tvb_captured_length(tvb);
4973 }
4974
4975 static void
4976 dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,guint start_address)
4977 {
4978     guint       instruction;
4979     gint        offset         = 0;
4980     gint        start_offset   = 0;
4981     gint        len;
4982     gint        n;
4983     guint       instruction_no = 0;
4984     guint16     value          = 0;
4985     proto_item *item, *item2;
4986     guint       UDVM_address   = start_address;
4987     gboolean    is_memory_address;
4988     guint16     msg_length     = tvb_reported_length_remaining(udvm_tvb, offset);
4989
4990
4991     while (msg_length > offset) {
4992         instruction = tvb_get_guint8(udvm_tvb, offset);
4993         instruction_no ++;
4994         UDVM_address = start_address + offset;
4995
4996         item = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
4997                     "######### UDVM instruction %u at UDVM-address %u (0x%x) #########",
4998                     instruction_no,UDVM_address,UDVM_address);
4999         PROTO_ITEM_SET_GENERATED(item);
5000         proto_tree_add_item(sigcomp_udvm_tree, hf_sigcomp_udvm_instr, udvm_tvb, offset, 1, ENC_BIG_ENDIAN);
5001         offset ++;
5002         switch ( instruction ) {
5003
5004         case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */
5005             /* $operand_1*/
5006             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5007             len = offset - start_offset;
5008             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
5009                 udvm_tvb, start_offset, len, value);
5010             /* %operand_2*/
5011             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5012             len = offset - start_offset;
5013             if ( is_memory_address ) {
5014                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
5015                     udvm_tvb, start_offset, len, value);
5016             } else {
5017                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
5018                     udvm_tvb, start_offset, len, value);
5019             }
5020             break;
5021
5022         case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */
5023             /* $operand_1*/
5024             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5025             len = offset - start_offset;
5026             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
5027                 udvm_tvb, start_offset, len, value);
5028             /* %operand_2*/
5029             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5030             len = offset - start_offset;
5031             if ( is_memory_address ) {
5032                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
5033                     udvm_tvb, start_offset, len, value);
5034             } else {
5035                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
5036                     udvm_tvb, start_offset, len, value);
5037             }
5038             break;
5039
5040         case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */
5041             /* $operand_1*/
5042             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5043             len = offset - start_offset;
5044             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
5045                 udvm_tvb, start_offset, len, value);
5046             break;
5047
5048         case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */
5049             /* $operand_1*/
5050             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5051             len = offset - start_offset;
5052             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
5053                 udvm_tvb, start_offset, len, value);
5054             /* %operand_2*/
5055             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5056             len = offset - start_offset;
5057             if ( is_memory_address ) {
5058                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
5059                     udvm_tvb, start_offset, len, value);
5060             } else {
5061                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
5062                     udvm_tvb, start_offset, len, value);
5063             }
5064             break;
5065
5066         case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */
5067             /* $operand_1*/
5068             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5069             len = offset - start_offset;
5070             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
5071                 udvm_tvb, start_offset, len, value);
5072             /* %operand_2*/
5073             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5074             len = offset - start_offset;
5075             if ( is_memory_address ) {
5076                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
5077                     udvm_tvb, start_offset, len, value);
5078             } else {
5079                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
5080                     udvm_tvb, start_offset, len, value);
5081             }
5082             break;
5083
5084         case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */
5085             /* $operand_1*/
5086             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5087             len = offset - start_offset;
5088             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
5089                 udvm_tvb, start_offset, len, value);
5090             /* %operand_2*/
5091             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5092             len = offset - start_offset;
5093             if ( is_memory_address ) {
5094                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
5095                     udvm_tvb, start_offset, len, value);
5096             } else {
5097                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
5098                     udvm_tvb, start_offset, len, value);
5099             }
5100             break;
5101
5102         case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */
5103             /* $operand_1*/
5104             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5105             len = offset - start_offset;
5106             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
5107                 udvm_tvb, start_offset, len, value);
5108             /* %operand_2*/
5109             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5110             len = offset - start_offset;
5111             if ( is_memory_address ) {
5112                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
5113                     udvm_tvb, start_offset, len, value);
5114             } else {
5115                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
5116                     udvm_tvb, start_offset, len, value);
5117             }
5118             break;
5119
5120         case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */
5121             /* $operand_1*/
5122             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5123             len = offset - start_offset;
5124             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
5125                 udvm_tvb, start_offset, len, value);
5126             /* %operand_2*/
5127             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5128             len = offset - start_offset;
5129             if ( is_memory_address ) {
5130                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
5131                     udvm_tvb, start_offset, len, value);
5132             } else {
5133                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
5134                     udvm_tvb, start_offset, len, value);
5135             }
5136             break;
5137
5138         case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */
5139             /* $operand_1*/
5140             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5141             len = offset - start_offset;
5142             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
5143                 udvm_tvb, start_offset, len, value);
5144             /* %operand_2*/
5145             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5146             len = offset - start_offset;
5147             if ( is_memory_address ) {
5148                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
5149                     udvm_tvb, start_offset, len, value);
5150             } else {
5151                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
5152                     udvm_tvb, start_offset, len, value);
5153             }
5154             break;
5155
5156         case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */
5157             /* $operand_1*/
5158             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5159             len = offset - start_offset;
5160             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
5161                 udvm_tvb, start_offset, len, value);
5162             /* %operand_2*/
5163             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5164             len = offset - start_offset;
5165             if ( is_memory_address ) {
5166                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
5167                     udvm_tvb, start_offset, len, value);
5168             } else {
5169                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
5170                     udvm_tvb, start_offset, len, value);
5171             }
5172             break;
5173         case SIGCOMP_INSTR_SORT_ASCENDING: /* 11 SORT-ASCENDING (%start, %n, %k) */
5174                         /* while programming stop while loop */
5175             offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
5176             break;
5177
5178         case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */
5179             offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
5180             break;
5181         case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */
5182             /* %position */
5183             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5184             len = offset - start_offset;
5185             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
5186                 udvm_tvb, start_offset, len, value);
5187
5188             /*  %length, */
5189             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5190             len = offset - start_offset;
5191             if ( is_memory_address ) {
5192                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
5193                     udvm_tvb, start_offset, len, value);
5194             } else {
5195                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
5196                     udvm_tvb, start_offset, len, value);
5197             }
5198
5199             /* $destination */
5200             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5201             len = offset - start_offset;
5202             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
5203                 udvm_tvb, start_offset, len, value);
5204             break;
5205
5206         case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */
5207             /* %address */
5208             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
5209             len = offset - start_offset;
5210             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
5211                 udvm_tvb, start_offset, len, value);
5212             /* %value */
5213             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5214             len = offset - start_offset;
5215             if ( is_memory_address ) {
5216                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
5217                     udvm_tvb, start_offset, len, value);
5218             } else {
5219                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
5220                     udvm_tvb, start_offset, len, value);
5221             }
5222             break;
5223
5224         case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
5225             /* %address */
5226             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5227             len = offset - start_offset;
5228             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
5229                 udvm_tvb, start_offset, len, value);
5230             /* #n */
5231             offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5232             len = offset - start_offset;
5233             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
5234                 udvm_tvb, start_offset, len, value);
5235             n = value;
5236             while ( n > 0) {
5237                 n = n -1;
5238                 /* %value */
5239                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5240                 len = offset - start_offset;
5241                 if ( is_memory_address ) {
5242                     proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
5243                         udvm_tvb, start_offset, len, value);
5244                 } else {
5245                     proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
5246                         udvm_tvb, start_offset, len, value);
5247                 }
5248             }
5249             break;
5250
5251         case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */
5252             /* %value */
5253             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5254             len = offset - start_offset;
5255             if ( is_memory_address ) {
5256                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
5257                     udvm_tvb, start_offset, len, value);
5258             } else {
5259                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
5260                     udvm_tvb, start_offset, len, value);
5261             }
5262             break;
5263
5264         case SIGCOMP_INSTR_POP: /* 17 POP (%address) */
5265             /* %address */
5266             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5267
5268             len = offset - start_offset;
5269             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
5270                 udvm_tvb, start_offset, len, value);
5271             break;
5272
5273         case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */
5274             /* %position */
5275             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5276             len = offset - start_offset;
5277             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
5278                 udvm_tvb, start_offset, len, value);
5279
5280             /*  %length, */
5281             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5282             len = offset - start_offset;
5283             if ( is_memory_address ) {
5284                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
5285                     udvm_tvb, start_offset, len, value);
5286             } else {
5287                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
5288                     udvm_tvb, start_offset, len, value);
5289             }
5290
5291             /* $destination */
5292             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5293             len = offset - start_offset;
5294             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
5295                 udvm_tvb, start_offset, len, value);
5296             break;
5297
5298         case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */
5299             /* %position */
5300             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5301             len = offset - start_offset;
5302             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
5303                 udvm_tvb, start_offset, len, value);
5304
5305             /*  %length, */
5306             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5307             len = offset - start_offset;
5308             if ( is_memory_address ) {
5309                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
5310                     udvm_tvb, start_offset, len, value);
5311             } else {
5312                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
5313                     udvm_tvb, start_offset, len, value);
5314             }
5315
5316             /* $destination */
5317             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5318             len = offset - start_offset;
5319             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
5320                 udvm_tvb, start_offset, len, value);
5321             break;
5322
5323         case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */
5324             /* %offset */
5325             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5326             len = offset - start_offset;
5327             if ( is_memory_address ) {
5328                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_offset,
5329                     udvm_tvb, start_offset, len, value);
5330             } else {
5331                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
5332                     udvm_tvb, start_offset, len, value);
5333             }
5334
5335             /*  %length, */
5336             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5337             len = offset - start_offset;
5338             if ( is_memory_address ) {
5339                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
5340                     udvm_tvb, start_offset, len, value);
5341             } else {
5342                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
5343                     udvm_tvb, start_offset, len, value);
5344             }
5345
5346             /* $destination */
5347             offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5348             len = offset - start_offset;
5349             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
5350                 udvm_tvb, start_offset, len, value);
5351             break;
5352         case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */
5353
5354             /* %address */
5355             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5356             len = offset - start_offset;
5357             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
5358                 udvm_tvb, start_offset, len, value);
5359
5360             /*  %length, */
5361             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE, &start_offset, &value, &is_memory_address);
5362             len = offset - start_offset;
5363             if ( is_memory_address ) {
5364                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
5365                     udvm_tvb, start_offset, len, value);
5366             } else {
5367                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
5368                     udvm_tvb, start_offset, len, value);
5369             }
5370
5371             /* %start_value */
5372             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5373             len = offset - start_offset;
5374             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_start_value,
5375                 udvm_tvb, start_offset, len, value);
5376
5377             /* %offset */
5378             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5379             len = offset - start_offset;
5380             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
5381                 udvm_tvb, start_offset, len, value);
5382             break;
5383
5384
5385         case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */
5386             /* @address */
5387             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5388             len = offset - start_offset;
5389              /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
5390             value = ( value + UDVM_address ) & 0xffff;
5391             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
5392                 udvm_tvb, start_offset, len, value);
5393             break;
5394
5395         case SIGCOMP_INSTR_COMPARE: /* 23 */
5396             /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
5397              */
5398             /* %value_1 */
5399             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5400             len = offset - start_offset;
5401             if ( is_memory_address ) {
5402                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
5403                     udvm_tvb, start_offset, len, value);
5404             } else {
5405                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
5406                     udvm_tvb, start_offset, len, value);
5407             }
5408
5409             /* %value_2 */
5410             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5411             len = offset - start_offset;
5412             if ( is_memory_address ) {
5413                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
5414                     udvm_tvb, start_offset, len, value);
5415             } else {
5416                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
5417                     udvm_tvb, start_offset, len, value);
5418             }
5419
5420             /* @address_1 */
5421             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5422             len = offset - start_offset;
5423              /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
5424             value = ( value + UDVM_address ) & 0xffff;
5425             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
5426                 udvm_tvb, start_offset, len, value);
5427
5428             /* @address_2 */
5429             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5430             len = offset - start_offset;
5431              /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
5432             value = ( value + UDVM_address ) & 0xffff;
5433             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
5434                 udvm_tvb, start_offset, len, value);
5435
5436             /* @address_3 */
5437             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5438             len = offset - start_offset;
5439              /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
5440             value = ( value + UDVM_address ) & 0xffff;
5441             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
5442                 udvm_tvb, start_offset, len, value);
5443             break;
5444
5445         case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/
5446             /* @address */
5447             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5448             len = offset - start_offset;
5449              /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
5450             value = ( value + UDVM_address ) & 0xffff;
5451             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
5452                 udvm_tvb, start_offset, len, value);
5453             break;
5454         case SIGCOMP_INSTR_RETURN: /* 25 POP and return */
5455
5456         break;
5457
5458         case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
5459             /* #n */
5460             offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5461             len = offset - start_offset;
5462             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
5463                 udvm_tvb, start_offset, len, value);
5464
5465             /* Number of addresses in the instruction */
5466             n = value;
5467             /* %j */
5468             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5469             len = offset - start_offset;
5470             if ( is_memory_address ) {
5471                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_j,
5472                     udvm_tvb, start_offset, len, value);
5473             } else {
5474                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_j,
5475                     udvm_tvb, start_offset, len, value);
5476             }
5477
5478             while ( n > 0) {
5479                 n = n -1;
5480                 /* @address_n-1 */
5481                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
5482                 len = offset - start_offset;
5483                  /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
5484                 value = ( value + UDVM_address ) & 0xffff;
5485                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
5486                     udvm_tvb, start_offset, len, value);
5487             }
5488             break;
5489         case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */
5490             /* %value */
5491             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5492             len = offset - start_offset;
5493             if ( is_memory_address ) {
5494                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
5495                     udvm_tvb, start_offset, len, value);
5496             } else {
5497                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
5498                     udvm_tvb, start_offset, len, value);
5499             }
5500
5501             /* %position */
5502             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5503             len = offset - start_offset;
5504             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
5505                 udvm_tvb, start_offset, len, value);
5506
5507             /* %length */
5508             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5509             len = offset - start_offset;
5510             if ( is_memory_address ) {
5511                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
5512                     udvm_tvb, start_offset, len, value);
5513             } else {
5514                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
5515                     udvm_tvb, start_offset, len, value);
5516             }
5517
5518             /* @address */
5519             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5520             len = offset - start_offset;
5521              /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
5522             value = ( value + UDVM_address ) & 0xffff;
5523             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
5524                 udvm_tvb, start_offset, len, value);
5525             break;
5526
5527
5528         case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */
5529             /* %length */
5530             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5531             len = offset - start_offset;
5532             if ( is_memory_address ) {
5533                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
5534                     udvm_tvb, start_offset, len, value);
5535             } else {
5536                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
5537                     udvm_tvb, start_offset, len, value);
5538             }
5539
5540             /* %destination */
5541             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5542             len = offset - start_offset;
5543             if ( is_memory_address ) {
5544                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
5545                     udvm_tvb, start_offset, len, value);
5546             } else {
5547                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
5548                     udvm_tvb, start_offset, len, value);
5549             }
5550
5551             /* @address */
5552             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5553             len = offset - start_offset;
5554              /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
5555             value = ( value + UDVM_address ) & 0xffff;
5556             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
5557                 udvm_tvb, start_offset, len, value);
5558             break;
5559         case SIGCOMP_INSTR_INPUT_BITS:/* 29   INPUT-BITS (%length, %destination, @address) */
5560             /* %length */
5561             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5562             len = offset - start_offset;
5563             if ( is_memory_address ) {
5564                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
5565                     udvm_tvb, start_offset, len, value);
5566             } else {
5567                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
5568                     udvm_tvb, start_offset, len, value);
5569             }
5570
5571             /* %destination */
5572             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5573             len = offset - start_offset;
5574             if ( is_memory_address ) {
5575                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
5576                     udvm_tvb, start_offset, len, value);
5577             } else {
5578                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
5579                     udvm_tvb, start_offset, len, value);
5580             }
5581
5582             /* @address */
5583             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5584             len = offset - start_offset;
5585              /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
5586             value = ( value + UDVM_address ) & 0xffff;
5587             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
5588                 udvm_tvb, start_offset, len, value);
5589             break;
5590         case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */
5591             /*
5592              * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1,
5593              *  %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n,
5594              *  %upper_bound_n, %uncompressed_n)
5595              */
5596             /* %destination */
5597             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5598             len = offset - start_offset;
5599             if ( is_memory_address ) {
5600                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
5601                     udvm_tvb, start_offset, len, value);
5602             } else {
5603                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
5604                     udvm_tvb, start_offset, len, value);
5605             }
5606             /* @address */
5607             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5608             len = offset - start_offset;
5609              /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
5610             value = ( value + UDVM_address ) & 0xffff;
5611             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
5612                 udvm_tvb, start_offset, len, value);
5613             /* #n */
5614             offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
5615             len = offset - start_offset;
5616             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
5617                 udvm_tvb, start_offset, len, value);
5618             n = value;
5619             while ( n > 0) {
5620                 n = n -1;
5621                 /* %bits_n */
5622                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5623                 len = offset - start_offset;
5624                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_bits,
5625                     udvm_tvb, start_offset, len, value);
5626                 /* %lower_bound_n*/
5627                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5628                 len = offset - start_offset;
5629                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_lower_bound,
5630                     udvm_tvb, start_offset, len, value);
5631                 /* %upper_bound_n */
5632                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5633                 len = offset - start_offset;
5634                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_upper_bound,
5635                     udvm_tvb, start_offset, len, value);
5636                 /* %uncompressed_n */
5637                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
5638                 len = offset - start_offset;
5639                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_uncompressed,
5640                     udvm_tvb, start_offset, len, value);
5641             }
5642             break;
5643
5644         case SIGCOMP_INSTR_STATE_ACCESS: /* 31 */
5645             /*   STATE-ACCESS (%partial_identifier_start, %partial_identifier_length,
5646              * %state_begin, %state_length, %state_address, %state_instruction)
5647              */
5648
5649             /*
5650              * %partial_identifier_start
5651              */
5652             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
5653             len = offset - start_offset;
5654             proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
5655                 udvm_tvb, start_offset, len, value);
5656
5657             /*
5658              * %partial_identifier_length
5659              */
5660             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
5661             len = offset - start_offset;
5662             proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length,
5663                 udvm_tvb, start_offset, len, value);
5664             /*
5665              * %state_begin
5666              */
5667             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5668             len = offset - start_offset;
5669             proto_tree_add_uint(sigcomp_udvm_tree, hf_state_begin,
5670                 udvm_tvb, start_offset, len, value);
5671
5672             /*
5673              * %state_length
5674              */
5675             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5676             len = offset - start_offset;
5677             if ( is_memory_address ) {
5678                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
5679                     udvm_tvb, start_offset, len, value);
5680             } else {
5681                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
5682                     udvm_tvb, start_offset, len, value);
5683             }
5684             /*
5685              * %state_address
5686              */
5687             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
5688             len = offset - start_offset;
5689             if ( is_memory_address ) {
5690                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
5691                     udvm_tvb, start_offset, len, value);
5692             } else {
5693                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
5694                     udvm_tvb, start_offset, len, value);
5695             }
5696             /*
5697              * %state_instruction
5698              */
5699             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5700             len = offset - start_offset;
5701             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
5702                 udvm_tvb, start_offset, len, value);
5703             break;
5704         case SIGCOMP_INSTR_STATE_CREATE: /* 32 */
5705             /*
5706              * STATE-CREATE (%state_length, %state_address, %state_instruction,
5707              * %minimum_access_length, %state_retention_priority)
5708              */
5709
5710             /*
5711              * %state_length
5712              */
5713             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5714             len = offset - start_offset;
5715             if ( is_memory_address ) {
5716                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
5717                     udvm_tvb, start_offset, len, value);
5718             } else {
5719                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
5720                     udvm_tvb, start_offset, len, value);
5721             }
5722             /*
5723              * %state_address
5724              */
5725             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5726             len = offset - start_offset;
5727             if ( is_memory_address ) {
5728                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
5729                     udvm_tvb, start_offset, len, value);
5730             } else {
5731                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
5732                     udvm_tvb, start_offset, len, value);
5733             }
5734             /*
5735              * %state_instruction
5736              */
5737             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5738             len = offset - start_offset;
5739             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
5740                 udvm_tvb, start_offset, len, value);
5741             /*
5742              * %minimum_access_length
5743              */
5744             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5745             len = offset - start_offset;
5746             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len,
5747                 udvm_tvb, start_offset, len, value);
5748             /*
5749              * %state_retention_priority
5750              */
5751             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5752             len = offset - start_offset;
5753             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
5754                 udvm_tvb, start_offset, len, value);
5755
5756             break;
5757         case SIGCOMP_INSTR_STATE_FREE: /* 33 */
5758             /*
5759              * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
5760              */
5761             /*
5762              * %partial_identifier_start
5763              */
5764             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5765             len = offset - start_offset;
5766             proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
5767                 udvm_tvb, start_offset, len, value);
5768
5769             /*
5770              * %partial_identifier_length
5771              */
5772             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5773             len = offset - start_offset;
5774             proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length,
5775                 udvm_tvb, start_offset, len, value);
5776             break;
5777         case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */
5778             /*
5779              * %output_start
5780              */
5781             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5782             len = offset - start_offset;
5783             if ( is_memory_address ) {
5784                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_output_start,
5785                     udvm_tvb, start_offset, len, value);
5786             } else {
5787                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start,
5788                     udvm_tvb, start_offset, len, value);
5789             }
5790             /*
5791              * %output_length
5792              */
5793             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5794             len = offset - start_offset;
5795             if ( is_memory_address ) {
5796                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length_addr,
5797                     udvm_tvb, start_offset, len, value);
5798             } else {
5799                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length,
5800                     udvm_tvb, start_offset, len, value);
5801             }
5802             break;
5803         case SIGCOMP_INSTR_END_MESSAGE: /* 35 */
5804             /*
5805              * END-MESSAGE (%requested_feedback_location,
5806              * %returned_parameters_location, %state_length, %state_address,
5807              * %state_instruction, %minimum_access_length,
5808              * %state_retention_priority)
5809              */
5810             /* %requested_feedback_location */
5811             if ((msg_length-1) < offset) {
5812                 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, 0, -1,
5813                         "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
5814                 PROTO_ITEM_SET_GENERATED(item2);
5815                 return;
5816             }
5817             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5818             len = offset - start_offset;
5819             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_req_feedback_loc,
5820                 udvm_tvb, start_offset, len, value);
5821             /* returned_parameters_location */
5822             if ((msg_length-1) < offset) {
5823                 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset-1, -1,
5824                         "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
5825                 PROTO_ITEM_SET_GENERATED(item2);
5826                 return;
5827             }
5828             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5829             len = offset - start_offset;
5830             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ret_param_loc,
5831                 udvm_tvb, start_offset, len, value);
5832             /*
5833              * %state_length
5834              */
5835             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5836             len = offset - start_offset;
5837             if ( is_memory_address ) {
5838                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
5839                     udvm_tvb, start_offset, len, value);
5840             } else {
5841                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
5842                     udvm_tvb, start_offset, len, value);
5843             }
5844             /*
5845              * %state_address
5846              */
5847             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5848             len = offset - start_offset;
5849             if ( is_memory_address ) {
5850                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
5851                     udvm_tvb, start_offset, len, value);
5852             } else {
5853                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
5854                     udvm_tvb, start_offset, len, value);
5855             }
5856             /*
5857              * %state_instruction
5858              */
5859             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5860             len = offset - start_offset;
5861             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
5862                 udvm_tvb, start_offset, len, value);
5863             /*
5864              * %minimum_access_length
5865              */
5866             offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5867             len = offset - start_offset;
5868             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len,
5869                 udvm_tvb, start_offset, len, value);
5870             /*
5871              * %state_retention_priority
5872              */
5873             if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ) {
5874                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
5875                 len = offset - start_offset;
5876                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
5877                     udvm_tvb, start_offset, len, value);
5878             } else {
5879                 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
5880                         "state_retention_priority = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
5881                 PROTO_ITEM_SET_GENERATED(item2);
5882             }
5883             if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ) {
5884                 len = tvb_reported_length_remaining(udvm_tvb, offset);
5885                 UDVM_address = start_address + offset;
5886                 proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, len,
5887                         "Remaining %u bytes starting at UDVM addr %u (0x%x)- State information ?",len, UDVM_address, UDVM_address);
5888             }
5889             offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
5890             break;
5891
5892         default:
5893             offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
5894             break;
5895         }
5896
5897
5898     }
5899     return;
5900 }
5901  /*  The simplest operand type is the literal (#), which encodes a
5902   * constant integer from 0 to 65535 inclusive.  A literal operand may
5903   * require between 1 and 3 bytes depending on its value.
5904   * Bytecode:                       Operand value:      Range:
5905   * 0nnnnnnn                        N                   0 - 127
5906   * 10nnnnnn nnnnnnnn               N                   0 - 16383
5907   * 11000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
5908   *
5909   *            Figure 8: Bytecode for a literal (#) operand
5910   *
5911   */
5912 static int
5913 dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
5914                                gint offset, gint *start_offset, guint16 *value)
5915 {
5916     guint   bytecode;
5917     guint16 operand;
5918     guint   test_bits;
5919     guint   display_bytecode;
5920
5921     bytecode = tvb_get_guint8(udvm_tvb, offset);
5922     test_bits = bytecode >> 7;
5923     if (test_bits == 1) {
5924         test_bits = bytecode >> 6;
5925         if (test_bits == 2) {
5926             /*
5927              * 10nnnnnn nnnnnnnn               N                   0 - 16383
5928              */
5929             display_bytecode = bytecode & 0xc0;
5930             if ( display_udvm_bytecode )
5931                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
5932                     udvm_tvb, offset, 1, display_bytecode);
5933             operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
5934             *value = operand;
5935             *start_offset = offset;
5936             offset = offset + 2;
5937
5938         } else {
5939             /*
5940              * 111000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
5941              */
5942             display_bytecode = bytecode & 0xc0;
5943             if ( display_udvm_bytecode )
5944                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
5945                     udvm_tvb, offset, 1, display_bytecode);
5946             offset ++;
5947             operand = tvb_get_ntohs(udvm_tvb, offset);
5948             *value = operand;
5949             *start_offset = offset;
5950             offset = offset + 2;
5951
5952         }
5953     } else {
5954         /*
5955          * 0nnnnnnn                        N                   0 - 127
5956          */
5957         display_bytecode = bytecode & 0xc0;
5958         if ( display_udvm_bytecode )
5959             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
5960                 udvm_tvb, offset, 1, display_bytecode);
5961         operand = ( bytecode & 0x7f);
5962         *value = operand;
5963         *start_offset = offset;
5964         offset ++;
5965     }
5966
5967     return offset;
5968
5969 }
5970 /*
5971  * The second operand type is the reference ($), which is always used to
5972  * access a 2-byte value located elsewhere in the UDVM memory.  The
5973  * bytecode for a reference operand is decoded to be a constant integer
5974  * from 0 to 65535 inclusive, which is interpreted as the memory address
5975  * containing the actual value of the operand.
5976  * Bytecode:                       Operand value:      Range:
5977  *
5978  * 0nnnnnnn                        memory[2 * N]       0 - 65535
5979  * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
5980  * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
5981  *
5982  *            Figure 9: Bytecode for a reference ($) operand
5983  */
5984 static int
5985 dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
5986                                gint offset, gint *start_offset, guint16 *value)
5987 {
5988     guint   bytecode;
5989     guint16 operand;
5990     guint   test_bits;
5991     guint   display_bytecode;
5992
5993     bytecode = tvb_get_guint8(udvm_tvb, offset);
5994     test_bits = bytecode >> 7;
5995     if (test_bits == 1) {
5996         test_bits = bytecode >> 6;
5997         if (test_bits == 2) {
5998             /*
5999              * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
6000              */
6001             display_bytecode = bytecode & 0xc0;
6002             if ( display_udvm_bytecode )
6003                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
6004                     udvm_tvb, offset, 1, display_bytecode);
6005             operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
6006             *value = (operand * 2);
6007             *start_offset = offset;
6008             offset = offset + 2;
6009
6010         } else {
6011             /*
6012              * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
6013              */
6014             display_bytecode = bytecode & 0xc0;
6015             if ( display_udvm_bytecode )
6016                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
6017                     udvm_tvb, offset, 1, display_bytecode);
6018             offset ++;
6019             operand = tvb_get_ntohs(udvm_tvb, offset);
6020             *value = operand;
6021             *start_offset = offset;
6022             offset = offset + 2;
6023
6024         }
6025     } else {
6026         /*
6027          * 0nnnnnnn                        memory[2 * N]       0 - 65535
6028          */
6029         display_bytecode = bytecode & 0xc0;
6030         if ( display_udvm_bytecode )
6031             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
6032                 udvm_tvb, offset, 1, display_bytecode);
6033         operand = ( bytecode & 0x7f);
6034         *value = (operand * 2);
6035         *start_offset = offset;
6036         offset ++;
6037     }
6038
6039     return offset;
6040 }
6041
6042 /*
6043  *The fourth operand type is the address (@).  This operand is decoded
6044  * as a multitype operand followed by a further step: the memory address
6045  * of the UDVM instruction containing the address operand is added to
6046  * obtain the correct operand value.  So if the operand value from
6047  * Figure 10 is D then the actual operand value of an address is
6048  * calculated as follows:
6049  *
6050  * operand_value = (is_memory_address_of_instruction + D) modulo 2^16
6051  * TODO calculate correct value for operand in case of ADDR
6052  */
6053 static int
6054 dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
6055                                gint offset, gboolean is_addr _U_, gint *start_offset, guint16 *value, gboolean *is_memory_address )
6056 {
6057     guint bytecode;
6058     guint display_bytecode;
6059     guint16 operand;
6060     guint32 result;
6061     guint test_bits;
6062     /* RFC3320
6063      * Figure 10: Bytecode for a multitype (%) operand
6064      * Bytecode:                       Operand value:      Range:               HEX val
6065      * 00nnnnnn                        N                   0 - 63               0x00
6066      * 01nnnnnn                        memory[2 * N]       0 - 65535            0x40
6067      * 1000011n                        2 ^ (N + 6)        64 , 128              0x86
6068      * 10001nnn                        2 ^ (N + 8)    256 , ... , 32768         0x88
6069      * 111nnnnn                        N + 65504       65504 - 65535            0xe0
6070      * 1001nnnn nnnnnnnn               N + 61440       61440 - 65535            0x90
6071      * 101nnnnn nnnnnnnn               N                   0 - 8191             0xa0
6072      * 110nnnnn nnnnnnnn               memory[N]           0 - 65535            0xc0
6073      * 10000000 nnnnnnnn nnnnnnnn      N                   0 - 65535            0x80
6074      * 10000001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535            0x81
6075      */
6076     *is_memory_address = FALSE;
6077     bytecode = tvb_get_guint8(udvm_tvb, offset);
6078     test_bits = ( bytecode & 0xc0 ) >> 6;
6079     switch (test_bits ) {
6080     case 0:
6081         /*
6082          * 00nnnnnn                        N                   0 - 63
6083          */
6084         display_bytecode = bytecode & 0xc0;
6085         if ( display_udvm_bytecode )
6086         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
6087             udvm_tvb, offset, 1, display_bytecode);
6088         operand = ( bytecode & 0x3f);
6089         *value = operand;
6090         *start_offset = offset;
6091         offset ++;
6092         break;
6093     case 1:
6094         /*
6095          * 01nnnnnn                        memory[2 * N]       0 - 65535
6096          */
6097         display_bytecode = bytecode & 0xc0;
6098         if ( display_udvm_bytecode )
6099             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
6100                 udvm_tvb, offset, 1, display_bytecode);
6101         operand = ( bytecode & 0x3f) * 2;
6102         *is_memory_address = TRUE;
6103         *value = operand;
6104         *start_offset = offset;
6105         offset ++;
6106         break;
6107     case 2:
6108         /* Check tree most significant bits */
6109         test_bits = ( bytecode & 0xe0 ) >> 5;
6110         if ( test_bits == 5 ) {
6111         /*
6112          * 101nnnnn nnnnnnnn               N                   0 - 8191
6113          */
6114             display_bytecode = bytecode & 0xe0;
6115             if ( display_udvm_bytecode )
6116                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
6117                     udvm_tvb, offset, 1, display_bytecode);
6118             operand = tvb_get_ntohs(udvm_tvb, offset) & 0x1fff;
6119             *value = operand;
6120             *start_offset = offset;
6121             offset = offset + 2;
6122         } else {
6123             test_bits = ( bytecode & 0xf0 ) >> 4;
6124             if ( test_bits == 9 ) {
6125         /*
6126          * 1001nnnn nnnnnnnn               N + 61440       61440 - 65535
6127          */
6128                 display_bytecode = bytecode & 0xf0;
6129                 if ( display_udvm_bytecode )
6130                     proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
6131                             udvm_tvb, offset, 1, display_bytecode);
6132                 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x0fff) + 61440;
6133                 *start_offset = offset;
6134                 *value = operand;
6135                 offset = offset + 2;
6136             } else {
6137                 test_bits = ( bytecode & 0x08 ) >> 3;
6138                 if ( test_bits == 1) {
6139         /*
6140          * 10001nnn                        2 ^ (N + 8)    256 , ... , 32768
6141          */
6142                     display_bytecode = bytecode & 0xf8;
6143                     if ( display_udvm_bytecode )
6144                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
6145                                 udvm_tvb, offset, 1, display_bytecode);
6146                     result = (guint32)pow(2,( bytecode & 0x07) + 8);
6147                     operand = result & 0xffff;
6148                     *start_offset = offset;
6149                     *value = operand;
6150                     offset ++;
6151                 } else {
6152                     test_bits = ( bytecode & 0x0e ) >> 1;
6153                     if ( test_bits == 3 ) {
6154                         /*
6155                          * 1000 011n                        2 ^ (N + 6)        64 , 128
6156                          */
6157                         display_bytecode = bytecode & 0xfe;
6158                         if ( display_udvm_bytecode )
6159                             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
6160                                 udvm_tvb, offset, 1, display_bytecode);
6161                         result = (guint32)pow(2,( bytecode & 0x01) + 6);
6162                         operand = result & 0xffff;
6163                         *start_offset = offset;
6164                         *value = operand;
6165                         offset ++;
6166                     } else {
6167                     /*
6168                      * 1000 0000 nnnnnnnn nnnnnnnn      N                   0 - 65535
6169                      * 1000 0001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
6170                      */
6171                         display_bytecode = bytecode;
6172                         if ( display_udvm_bytecode )
6173                             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
6174                                 udvm_tvb, offset, 1, display_bytecode);
6175                         if ( (bytecode & 0x01) == 1 )
6176                             *is_memory_address = TRUE;
6177                         offset ++;
6178                         operand = tvb_get_ntohs(udvm_tvb, offset);
6179                         *value = operand;
6180                         *start_offset = offset;
6181                         offset = offset +2;
6182                     }
6183
6184
6185                 }
6186             }
6187         }
6188         break;
6189
6190     case 3:
6191         test_bits = ( bytecode & 0x20 ) >> 5;
6192         if ( test_bits == 1 ) {
6193         /*
6194          * 111nnnnn                        N + 65504       65504 - 65535
6195          */
6196             display_bytecode = bytecode & 0xe0;
6197             if ( display_udvm_bytecode )
6198                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
6199                         udvm_tvb, offset, 1, display_bytecode);
6200             operand = ( bytecode & 0x1f) + 65504;
6201             *start_offset = offset;
6202             *value = operand;
6203             offset ++;
6204         } else {
6205         /*
6206          * 110nnnnn nnnnnnnn               memory[N]           0 - 65535
6207          */
6208             display_bytecode = bytecode & 0xe0;
6209             if ( display_udvm_bytecode )
6210                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
6211                         udvm_tvb, offset, 1, display_bytecode);
6212             operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x1fff);
6213             *is_memory_address = TRUE;
6214             *start_offset = offset;
6215             *value = operand;
6216             offset = offset +2;
6217         }
6218
6219     default :
6220         break;
6221     }
6222     return offset;
6223 }
6224
6225 static void
6226 tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree)
6227 {
6228     proto_tree *raw_tree = NULL;
6229     proto_item *ti = NULL;
6230     int offset, next_offset, linelen;
6231
6232     if (tree) {
6233         ti = proto_tree_add_item(tree, proto_raw_sigcomp, tvb, 0, -1, ENC_NA);
6234         raw_tree = proto_item_add_subtree(ti, ett_raw_text);
6235     }
6236
6237     offset = 0;
6238
6239     while (tvb_offset_exists(tvb, offset)) {
6240         tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
6241         linelen = next_offset - offset;
6242         proto_tree_add_format_text(raw_tree, tvb, offset, linelen);
6243         offset = next_offset;
6244     }
6245 }
6246
6247 /* Register the protocol with Wireshark */
6248
6249 void
6250 proto_register_sigcomp(void)
6251 {
6252 /* Setup list of header fields  See Section 1.6.1 for details*/
6253     static hf_register_info hf[] = {
6254         { &hf_sigcomp_t_bit,
6255             { "T bit", "sigcomp.t.bit",
6256             FT_UINT8, BASE_DEC, NULL, 0x04,
6257             "Sigcomp T bit", HFILL }
6258         },
6259         { &hf_sigcomp_len,
6260             { "Partial state id length","sigcomp.length",
6261             FT_UINT8, BASE_HEX, VALS(length_encoding_vals), 0x03,
6262             "Sigcomp length", HFILL }
6263         },
6264         { &hf_sigcomp_returned_feedback_item,
6265             { "Returned_feedback item", "sigcomp.returned.feedback.item",
6266             FT_BYTES, BASE_NONE, NULL, 0x0,
6267             "Returned feedback item", HFILL }
6268         },
6269         { &hf_sigcomp_partial_state,
6270             { "Partial state identifier", "sigcomp.partial.state.identifier",
6271             FT_STRING, BASE_NONE, NULL, 0x0,
6272             NULL, HFILL }
6273         },
6274         { &hf_sigcomp_remaining_message_bytes,
6275             { "Remaining SigComp message bytes", "sigcomp.remaining-bytes",
6276             FT_UINT32, BASE_DEC, NULL, 0x0,
6277             "Number of bytes remaining in message", HFILL }
6278         },
6279         { &hf_sigcomp_compression_ratio,
6280             { "Compression ratio (%)", "sigcomp.compression-ratio",
6281             FT_UINT32, BASE_DEC, NULL, 0x0,
6282             "Compression ratio (decompressed / compressed) %", HFILL }
6283         },
6284         { &hf_sigcomp_returned_feedback_item_len,
6285             { "Returned feedback item length", "sigcomp.returned.feedback.item.len",
6286             FT_UINT8, BASE_DEC, NULL, 0x7f,
6287             NULL, HFILL }
6288         },
6289         { &hf_sigcomp_code_len,
6290             { "Code length","sigcomp.code.len",
6291             FT_UINT16, BASE_HEX, NULL, 0xfff0,
6292             NULL, HFILL }
6293         },
6294         { &hf_sigcomp_destination,
6295             { "Destination","sigcomp.destination",
6296             FT_UINT8, BASE_HEX | BASE_EXT_STRING, &destination_address_encoding_vals_ext, 0xf,
6297             NULL, HFILL }
6298         },
6299         { &hf_sigcomp_udvm_bytecode,
6300             { "Uploaded UDVM bytecode","sigcomp.udvm.byte-code",
6301             FT_NONE, BASE_NONE, NULL, 0x0,
6302             NULL, HFILL }
6303         },
6304         { &hf_sigcomp_udvm_instr,
6305             { "UDVM instruction code","sigcomp.udvm.instr",
6306             FT_UINT8, BASE_DEC | BASE_EXT_STRING, &udvm_instruction_code_vals_ext, 0x0,
6307             NULL, HFILL }
6308         },
6309         { &hf_udvm_execution_trace,
6310             { "UDVM execution trace","sigcomp.udvm.execution-trace",
6311             FT_NONE, BASE_NONE, NULL, 0x0,
6312             NULL, HFILL }
6313         },
6314         { &hf_udvm_multitype_bytecode,
6315             { "UDVM bytecode", "sigcomp.udvm.multyt.bytecode",
6316             FT_UINT8, BASE_HEX, VALS(display_bytecode_vals), 0x0,
6317             NULL, HFILL }
6318         },
6319         { &hf_udvm_reference_bytecode,
6320             { "UDVM bytecode", "sigcomp.udvm.ref.bytecode",
6321             FT_UINT8, BASE_HEX, VALS(display_ref_bytecode_vals), 0x0,
6322             NULL, HFILL }
6323         },
6324         { &hf_udvm_literal_bytecode,
6325             { "UDVM bytecode", "sigcomp.udvm.lit.bytecode",
6326             FT_UINT8, BASE_HEX, VALS(display_lit_bytecode_vals), 0x0,
6327             NULL, HFILL }
6328         },
6329 #if 0
6330         { &hf_udvm_operand,
6331             { "UDVM operand", "sigcomp.udvm.operand",
6332             FT_UINT16, BASE_DEC, NULL, 0x0,
6333             NULL, HFILL }
6334         },
6335 #endif
6336         { &hf_udvm_length,
6337             { "%Length", "sigcomp.udvm.length",
6338             FT_UINT16, BASE_DEC, NULL, 0x0,
6339             "Length", HFILL }
6340         },
6341         { &hf_udvm_addr_length,
6342             { "%Length[memory address]", "sigcomp.udvm.addr.length",
6343             FT_UINT16, BASE_DEC, NULL, 0x0,
6344             "Length", HFILL }
6345         },
6346         { &hf_udvm_destination,
6347             { "%Destination", "sigcomp.udvm.destination",
6348             FT_UINT16, BASE_DEC, NULL, 0x0,
6349             "Destination", HFILL }
6350         },
6351         { &hf_udvm_addr_destination,
6352             { "%Destination[memory address]", "sigcomp.udvm.addr.destination",
6353             FT_UINT16, BASE_DEC, NULL, 0x0,
6354             "Destination", HFILL }
6355         },
6356         { &hf_udvm_at_address,
6357             { "@Address(mem_add_of_inst + D) mod 2^16)", "sigcomp.udvm.at.address",
6358             FT_UINT16, BASE_DEC, NULL, 0x0,
6359             "Address", HFILL }
6360         },
6361         { &hf_udvm_address,
6362             { "%Address", "sigcomp.udvm.length",
6363             FT_UINT16, BASE_DEC, NULL, 0x0,
6364             "Address", HFILL }
6365         },
6366         { &hf_udvm_literal_num,
6367             { "#n", "sigcomp.udvm.literal-num",
6368             FT_UINT16, BASE_DEC, NULL, 0x0,
6369             "Literal number", HFILL }
6370         },
6371         { &hf_udvm_value,
6372             { "%Value", "sigcomp.udvm.value",
6373             FT_UINT16, BASE_DEC, NULL, 0x0,
6374             "Value", HFILL }
6375         },
6376         { &hf_udvm_addr_value,
6377             { "%Value[memory address]", "sigcomp.udvm.value",
6378             FT_UINT16, BASE_DEC, NULL, 0x0,
6379             "Value", HFILL }
6380         },
6381         { &hf_partial_identifier_start,
6382             { "%Partial identifier start", "sigcomp.udvm.partial.identifier.start",
6383             FT_UINT16, BASE_DEC, NULL, 0x0,
6384             "Partial identifier start", HFILL }
6385         },
6386         { &hf_partial_identifier_length,
6387             { "%Partial identifier length", "sigcomp.udvm.partial.identifier.length",
6388             FT_UINT16, BASE_DEC, NULL, 0x0,
6389             "Partial identifier length", HFILL }
6390         },
6391         { &hf_state_begin,
6392             { "%State begin", "sigcomp.udvm.state.begin",
6393             FT_UINT16, BASE_DEC, NULL, 0x0,
6394             "State begin", HFILL }
6395         },
6396         { &hf_udvm_state_length,
6397             { "%State length", "sigcomp.udvm.state.length",
6398             FT_UINT16, BASE_DEC, NULL, 0x0,
6399             "State length", HFILL }
6400         },
6401
6402         { &hf_udvm_state_length_addr,
6403             { "%State length[memory address]", "sigcomp.udvm.state.length.addr",
6404             FT_UINT16, BASE_DEC, NULL, 0x0,
6405             "State length", HFILL }
6406         },
6407         { &hf_udvm_state_address,
6408             { "%State address", "sigcomp.udvm.start.address",
6409             FT_UINT16, BASE_DEC, NULL, 0x0,
6410             "State address", HFILL }
6411         },
6412         { &hf_udvm_state_address_addr,
6413             { "%State address[memory address]", "sigcomp.udvm.start.address.addr",
6414             FT_UINT16, BASE_DEC, NULL, 0x0,
6415             "State address", HFILL }
6416         },
6417         { &hf_udvm_state_instr,
6418             { "%State instruction", "sigcomp.udvm.start.instr",
6419             FT_UINT16, BASE_DEC, NULL, 0x0,
6420             "State instruction", HFILL }
6421         },
6422         { &hf_udvm_operand_1,
6423             { "$Operand 1[memory address]", "sigcomp.udvm.operand.1",
6424             FT_UINT16, BASE_DEC, NULL, 0x0,
6425             "Reference $ Operand 1", HFILL }
6426         },
6427         { &hf_udvm_operand_2,
6428             { "%Operand 2", "sigcomp.udvm.operand.2",
6429             FT_UINT16, BASE_DEC, NULL, 0x0,
6430             "Operand 2", HFILL }
6431         },
6432         { &hf_udvm_operand_2_addr,
6433             { "%Operand 2[memory address]", "sigcomp.udvm.operand.2.addr",
6434             FT_UINT16, BASE_DEC, NULL, 0x0,
6435             "Operand 2", HFILL }
6436         },
6437         { &hf_udvm_j,
6438             { "%j", "sigcomp.udvm.j",
6439             FT_UINT16, BASE_DEC, NULL, 0x0,
6440             "j", HFILL }
6441         },
6442         { &hf_udvm_addr_j,
6443             { "%j[memory address]", "sigcomp.udvm.addr.j",
6444             FT_UINT16, BASE_DEC, NULL, 0x0,
6445             "j", HFILL }
6446         },
6447         { &hf_udvm_output_start,
6448             { "%Output_start", "sigcomp.output.start",
6449             FT_UINT16, BASE_DEC, NULL, 0x0,
6450             "Output start", HFILL }
6451         },
6452         { &hf_udvm_addr_output_start,
6453             { "%Output_start[memory address]", "sigcomp.addr.output.start",
6454             FT_UINT16, BASE_DEC, NULL, 0x0,
6455             "Output start", HFILL }
6456         },
6457         { &hf_udvm_output_length,
6458             { "%Output_length", "sigcomp.output.length",
6459             FT_UINT16, BASE_DEC, NULL, 0x0,
6460             "Output length", HFILL }
6461         },
6462         { &hf_udvm_output_length_addr,
6463             { "%Output_length[memory address]", "sigcomp.output.length.addr",
6464             FT_UINT16, BASE_DEC, NULL, 0x0,
6465             "Output length", HFILL }
6466         },
6467         { &hf_udvm_req_feedback_loc,
6468             { "%Requested feedback location", "sigcomp.req.feedback.loc",
6469             FT_UINT16, BASE_DEC, NULL, 0x0,
6470             "Requested feedback location", HFILL }
6471         },
6472         { &hf_udvm_min_acc_len,
6473             { "%Minimum access length", "sigcomp.min.acc.len",
6474             FT_UINT16, BASE_DEC, NULL, 0x0,
6475             "Minimum access length", HFILL }
6476         },
6477         { &hf_udvm_state_ret_pri,
6478             { "%State retention priority", "sigcomp.udvm.state.ret.pri",
6479             FT_UINT16, BASE_DEC, NULL, 0x0,
6480             "State retention priority", HFILL }
6481         },
6482         { &hf_udvm_ret_param_loc,
6483             { "%Returned parameters location", "sigcomp.ret.param.loc",
6484             FT_UINT16, BASE_DEC, NULL, 0x0,
6485             "Returned parameters location", HFILL }
6486         },
6487         { &hf_udvm_position,
6488             { "%Position", "sigcomp.udvm.position",
6489             FT_UINT16, BASE_DEC, NULL, 0x0,
6490             "Position", HFILL }
6491         },
6492         { &hf_udvm_ref_dest,
6493             { "$Destination[memory address]", "sigcomp.udvm.ref.destination",
6494             FT_UINT16, BASE_DEC, NULL, 0x0,
6495             "(reference)Destination", HFILL }
6496         },
6497         { &hf_udvm_bits,
6498             { "%Bits", "sigcomp.udvm.bits",
6499             FT_UINT16, BASE_DEC, NULL, 0x0,
6500             "Bits", HFILL }
6501         },
6502         { &hf_udvm_lower_bound,
6503             { "%Lower bound", "sigcomp.udvm.lower.bound",
6504             FT_UINT16, BASE_DEC, NULL, 0x0,
6505             "Lower_bound", HFILL }
6506         },
6507         { &hf_udvm_upper_bound,
6508             { "%Upper bound", "sigcomp.udvm.upper.bound",
6509             FT_UINT16, BASE_DEC, NULL, 0x0,
6510             "Upper bound", HFILL }
6511         },
6512         { &hf_udvm_uncompressed,
6513             { "%Uncompressed", "sigcomp.udvm.uncompressed",
6514             FT_UINT16, BASE_DEC, NULL, 0x0,
6515             "Uncompressed", HFILL }
6516         },
6517         { &hf_udvm_start_value,
6518             { "%Start value", "sigcomp.udvm.start.value",
6519             FT_UINT16, BASE_DEC, NULL, 0x0,
6520             "Start value", HFILL }
6521         },
6522         { &hf_udvm_offset,
6523             { "%Offset", "sigcomp.udvm.offset",
6524             FT_UINT16, BASE_DEC, NULL, 0x0,
6525             "Offset", HFILL }
6526         },
6527         { &hf_udvm_addr_offset,
6528             { "%Offset[memory address]", "sigcomp.udvm.addr.offset",
6529             FT_UINT16, BASE_DEC, NULL, 0x0,
6530             "Offset", HFILL }
6531         },
6532         { &hf_sigcomp_nack_ver,
6533             { "NACK Version", "sigcomp.nack.ver",
6534             FT_UINT8, BASE_DEC, NULL, 0x0f,
6535             NULL, HFILL }
6536         },
6537         { &hf_sigcomp_nack_reason_code,
6538             { "Reason Code", "sigcomp.nack.reason",
6539             FT_UINT8, BASE_DEC | BASE_EXT_STRING, &sigcomp_nack_reason_code_vals_ext, 0x0,
6540             "NACK Reason Code", HFILL }
6541         },
6542         { &hf_sigcomp_nack_failed_op_code,
6543             { "OPCODE of failed instruction", "sigcomp.nack.failed_op_code",
6544             FT_UINT8, BASE_DEC | BASE_EXT_STRING, &udvm_instruction_code_vals_ext, 0x0,
6545             "NACK OPCODE of failed instruction", HFILL }
6546         },
6547         { &hf_sigcomp_nack_pc,
6548             { "PC of failed instruction", "sigcomp.nack.pc",
6549             FT_UINT16, BASE_DEC, NULL, 0x0,
6550             "NACK PC of failed instruction", HFILL }
6551         },
6552         { &hf_sigcomp_nack_sha1,
6553             { "SHA-1 Hash of failed message", "sigcomp.nack.sha1",
6554             FT_BYTES, BASE_NONE, NULL, 0x0,
6555             "NACK SHA-1 Hash of failed message", HFILL }
6556         },
6557         { &hf_sigcomp_nack_state_id,
6558             { "State ID (6 - 20 bytes)", "sigcomp.nack.state_id",
6559             FT_BYTES, BASE_NONE, NULL, 0x0,
6560             "NACK State ID (6 - 20 bytes)", HFILL }
6561         },
6562         { &hf_sigcomp_nack_cycles_per_bit,
6563             { "Cycles Per Bit", "sigcomp.nack.cycles_per_bit",
6564             FT_UINT8, BASE_DEC, NULL, 0x0,
6565             "NACK Cycles Per Bit", HFILL }
6566         },
6567         { &hf_sigcomp_nack_memory_size,
6568             { "Memory size", "sigcomp.memory_size",
6569             FT_UINT16, BASE_DEC, NULL, 0x0,
6570             NULL, HFILL }
6571         },
6572         { &hf_sigcomp_decompress_instruction,
6573             { "Instruction", "sigcomp.decompress_instruction",
6574             FT_NONE, BASE_NONE, NULL, 0x0,
6575             NULL, HFILL }
6576         },
6577         { &hf_sigcomp_loading_result,
6578             { "Loading result", "sigcomp.loading_result",
6579             FT_NONE, BASE_NONE, NULL, 0x0,
6580             NULL, HFILL }
6581         },
6582     };
6583
6584 /* Setup protocol subtree array */
6585     static gint *ett[] = {
6586         &ett_sigcomp,
6587         &ett_sigcomp_udvm,
6588         &ett_sigcomp_udvm_exe,
6589     };
6590     static gint *ett_raw[] = {
6591         &ett_raw_text,
6592     };
6593
6594     static ei_register_info ei[] = {
6595         { &ei_sigcomp_nack_failed_op_code, { "sigcomp.nack.failed_op_code.expert", PI_SEQUENCE, PI_WARN, "SigComp NACK", EXPFILL }},
6596         { &ei_sigcomp_invalid_instruction, { "sigcomp.invalid_instruction", PI_PROTOCOL, PI_WARN, "Invalid instruction", EXPFILL }},
6597     };
6598
6599     module_t *sigcomp_module;
6600     expert_module_t* expert_sigcomp;
6601
6602     static const enum_val_t udvm_detail_vals[] = {
6603         {"no-printout",   "No-Printout", 0},
6604         {"low-detail",    "Low-detail", 1},
6605         {"medium-detail", "Medium-detail", 2},
6606         {"high-detail",   "High-detail", 3},
6607         {NULL, NULL, -1}
6608     };
6609
6610
6611 /* Register the protocol name and description */
6612     proto_sigcomp = proto_register_protocol("Signaling Compression",
6613                                             "SIGCOMP", "sigcomp");
6614     proto_raw_sigcomp = proto_register_protocol("Decompressed SigComp message as raw text",
6615                                                 "Raw_SigComp", "raw_sigcomp");
6616
6617     new_register_dissector("sigcomp", dissect_sigcomp, proto_sigcomp);
6618
6619 /* Required function calls to register the header fields and subtrees used */
6620     proto_register_field_array(proto_sigcomp, hf, array_length(hf));
6621     proto_register_subtree_array(ett, array_length(ett));
6622     proto_register_subtree_array(ett_raw, array_length(ett_raw));
6623     expert_sigcomp = expert_register_protocol(proto_sigcomp);
6624     expert_register_field_array(expert_sigcomp, ei, array_length(ei));
6625
6626 /* Register a configuration option for port */
6627     sigcomp_module = prefs_register_protocol(proto_sigcomp,
6628                                               proto_reg_handoff_sigcomp);
6629
6630     prefs_register_uint_preference(sigcomp_module, "udp.port",
6631                                    "Sigcomp UDP Port 1",
6632                                    "Set UDP port 1 for SigComp messages",
6633                                    10,
6634                                    &SigCompUDPPort1);
6635
6636     prefs_register_uint_preference(sigcomp_module, "udp.port2",
6637                                    "Sigcomp UDP Port 2",
6638                                    "Set UDP port 2 for SigComp messages",
6639                                    10,
6640                                    &SigCompUDPPort2);
6641     prefs_register_uint_preference(sigcomp_module, "tcp.port",
6642                                    "Sigcomp TCP Port 1",
6643                                    "Set TCP port 1 for SigComp messages",
6644                                    10,
6645                                    &SigCompTCPPort1);
6646
6647     prefs_register_uint_preference(sigcomp_module, "tcp.port2",
6648                                    "Sigcomp TCP Port 2",
6649                                    "Set TCP port 2 for SigComp messages",
6650                                    10,
6651                                    &SigCompTCPPort2);
6652     prefs_register_bool_preference(sigcomp_module, "display.udvm.code",
6653                                    "Dissect the UDVM code",
6654                                    "Preference whether to Dissect the UDVM code or not",
6655                                    &dissect_udvm_code);
6656
6657     prefs_register_bool_preference(sigcomp_module, "display.bytecode",
6658                                    "Display the bytecode of operands",
6659                                    "preference whether to display the bytecode in "
6660                                      "UDVM operands or not",
6661                                    &display_udvm_bytecode);
6662     prefs_register_bool_preference(sigcomp_module, "decomp.msg",
6663                                    "Decompress message",
6664                                    "preference whether to decompress message or not",
6665                                    &decompress);
6666     prefs_register_bool_preference(sigcomp_module, "display.decomp.msg.as.txt",
6667                                    "Displays the decompressed message as text",
6668                                    "preference whether to display the decompressed message "
6669                                      "as raw text or not",
6670                                    &display_raw_txt);
6671     prefs_register_enum_preference(sigcomp_module, "show.udvm.execution",
6672                                    "Level of detail of UDVM execution:",
6673                                    "'No-Printout' = UDVM executes silently, then increasing detail "
6674                                      "about execution of UDVM instructions; "
6675                                      "Warning! CPU intense at high detail",
6676                                    &udvm_print_detail_level, udvm_detail_vals, FALSE);
6677
6678     register_init_routine(&sigcomp_init_udvm);
6679
6680
6681
6682 }
6683
6684 void
6685 proto_reg_handoff_sigcomp(void)
6686 {
6687     static dissector_handle_t sigcomp_handle;
6688     static dissector_handle_t sigcomp_tcp_handle;
6689     static gboolean Initialized = FALSE;
6690     static guint udp_port1;
6691     static guint udp_port2;
6692     static guint tcp_port1;
6693     static guint tcp_port2;
6694
6695     if (!Initialized) {
6696         sigcomp_handle = find_dissector("sigcomp");
6697         sigcomp_tcp_handle = new_create_dissector_handle(dissect_sigcomp_tcp,proto_sigcomp);
6698         sip_handle = find_dissector("sip");
6699         Initialized=TRUE;
6700     } else {
6701         dissector_delete_uint("udp.port", udp_port1, sigcomp_handle);
6702         dissector_delete_uint("udp.port", udp_port2, sigcomp_handle);
6703         dissector_delete_uint("tcp.port", tcp_port1, sigcomp_tcp_handle);
6704         dissector_delete_uint("tcp.port", tcp_port2, sigcomp_tcp_handle);
6705     }
6706
6707     udp_port1 = SigCompUDPPort1;
6708     udp_port2 = SigCompUDPPort2;
6709     tcp_port1 = SigCompTCPPort1;
6710     tcp_port2 = SigCompTCPPort2;
6711
6712
6713     dissector_add_uint("udp.port", SigCompUDPPort1, sigcomp_handle);
6714     dissector_add_uint("udp.port", SigCompUDPPort2, sigcomp_handle);
6715     dissector_add_uint("tcp.port", SigCompTCPPort1, sigcomp_tcp_handle);
6716     dissector_add_uint("tcp.port", SigCompTCPPort2, sigcomp_tcp_handle);
6717
6718 }
6719
6720 /*
6721  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
6722  *
6723  * Local variables:
6724  * c-basic-offset: 4
6725  * tab-width: 8
6726  * indent-tabs-mode: nil
6727  * End:
6728  *
6729  * vi: set shiftwidth=4 tabstop=8 expandtab:
6730  * :indentSize=4:tabSize=8:noTabs=true:
6731  */