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