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