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