I think this is the check that was intended....
[obnox/wireshark/wip.git] / epan / sigcomp-udvm.c
1 /* sigcomp-udvm.c
2  * Routines making up the Universal Decompressor Virtual Machine (UDVM) used for
3  * Signaling Compression (SigComp) dissection.
4  * Copyright 2004, Anders Broman <anders.broman@ericsson.com>
5  *
6  * $Id$
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25  * References:
26  * http://www.ietf.org/rfc/rfc3320.txt?number=3320
27  * http://www.ietf.org/rfc/rfc3321.txt?number=3321
28  * Useful links :
29  * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-impl-guide-05.txt
30  * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-sip-01.txt
31  */
32
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <glib.h>
41
42 #include "packet.h"
43 #include "strutil.h"
44 #include "sigcomp-udvm.h"
45 #include "sigcomp_state_hdlr.h"
46 #include "sha1.h"
47 #include "crc16.h"
48 #include "except.h"
49
50 #define SIGCOMP_INSTR_DECOMPRESSION_FAILURE     0
51 #define SIGCOMP_INSTR_AND                       1
52 #define SIGCOMP_INSTR_OR                        2
53 #define SIGCOMP_INSTR_NOT                       3
54 #define SIGCOMP_INSTR_LSHIFT                    4
55 #define SIGCOMP_INSTR_RSHIFT                    5
56 #define SIGCOMP_INSTR_ADD                       6
57 #define SIGCOMP_INSTR_SUBTRACT                  7
58 #define SIGCOMP_INSTR_MULTIPLY                  8
59 #define SIGCOMP_INSTR_DIVIDE                    9
60 #define SIGCOMP_INSTR_REMAINDER                 10
61 #define SIGCOMP_INSTR_SORT_ASCENDING            11
62 #define SIGCOMP_INSTR_SORT_DESCENDING           12
63 #define SIGCOMP_INSTR_SHA_1                     13
64 #define SIGCOMP_INSTR_LOAD                      14
65 #define SIGCOMP_INSTR_MULTILOAD                 15
66 #define SIGCOMP_INSTR_PUSH                      16
67 #define SIGCOMP_INSTR_POP                       17
68 #define SIGCOMP_INSTR_COPY                      18
69 #define SIGCOMP_INSTR_COPY_LITERAL              19
70 #define SIGCOMP_INSTR_COPY_OFFSET               20
71 #define SIGCOMP_INSTR_MEMSET                    21
72 #define SIGCOMP_INSTR_JUMP                      22
73 #define SIGCOMP_INSTR_COMPARE                   23
74 #define SIGCOMP_INSTR_CALL                      24
75 #define SIGCOMP_INSTR_RETURN                    25
76 #define SIGCOMP_INSTR_SWITCH                    26
77 #define SIGCOMP_INSTR_CRC                       27
78 #define SIGCOMP_INSTR_INPUT_BYTES               28
79 #define SIGCOMP_INSTR_INPUT_BITS                29
80 #define SIGCOMP_INSTR_INPUT_HUFFMAN             30
81 #define SIGCOMP_INSTR_STATE_ACCESS              31
82 #define SIGCOMP_INSTR_STATE_CREATE              32
83 #define SIGCOMP_INSTR_STATE_FREE                33
84 #define SIGCOMP_INSTR_OUTPUT                    34
85 #define SIGCOMP_INSTR_END_MESSAGE               35
86
87
88 static gboolean print_level_1;
89 static gboolean print_level_2;
90 static gboolean print_level_3;
91 static gint show_instr_detail_level;
92
93 /* Internal result code values of decompression failures */
94 const value_string result_code_vals[] = {
95         { 0,    "No decomprssion failure" },
96         { 1,    "Partial state length less than 6 or greater than 20 bytes long" },
97         { 2,    "No state match" },
98         { 3,    "state_begin + state_length > size of state" },
99         { 4,    "Operand_2 is Zero" },
100         { 5,    "Switch statement failed j >= n" },
101         { 6,    "Atempt to jump outside of UDVM memory" },
102         { 7,    "L in input-bits > 16" },
103         { 8,    "input_bit_order > 7" },
104         { 9,    "Instruction Decompression failure encountered" },
105         {10,    "Input huffman failed j > n" },
106         {11,    "Input bits requested beyond end of message" },
107         {12,    "more than four state creation requests are made before the END-MESSAGE instruction" },
108         {13,    "state_retention_priority is 65535" },
109         {14,    "Input bytes requested beond end of message" },
110         {15,    "Maximum number of UDVM cycles reached" },
111         {16,    "UDVM stack underflow" },
112         { 255,  "This branch isn't coded yet" },
113         { 0,    NULL }
114 };
115
116 static int decode_udvm_literal_operand(guint8 *buff,guint operand_address, guint16 *value);
117 static int dissect_udvm_reference_operand(guint8 *buff,guint operand_address, guint16 *value, guint *result_dest);
118 static int decode_udvm_multitype_operand(guint8 *buff,guint operand_address,guint16 *value);
119 static int decode_udvm_address_operand(guint8 *buff,guint operand_address, guint16 *value,guint current_address);
120 static int decomp_dispatch_get_bits(tvbuff_t *message_tvb,proto_tree *udvm_tree,guint8 bit_order, 
121                         guint8 *buff,guint16 *old_input_bit_order, guint16 *remaining_bits,
122                         guint16 *input_bits, guint *input_address, guint16 length, guint16 *result_code,guint msg_end);
123
124
125 tvbuff_t*
126 decompress_sigcomp_message(tvbuff_t *bytecode_tvb, tvbuff_t *message_tvb, packet_info *pinfo,
127                                                    proto_tree *udvm_tree, gint udvm_mem_dest, 
128                                                    gint print_flags, gint hf_id,
129                                                    gint header_len,
130                                                    gint byte_code_state_len, gint byte_code_id_len,
131                                                    gint udvm_start_ip)
132 {
133         tvbuff_t        *decomp_tvb;
134         guint8          buff[UDVM_MEMORY_SIZE];
135         char            string[2];
136         guint8          *out_buff;              /* Largest allowed size for a message is 65535  */
137         guint32         i = 0;
138         guint16         n = 0;
139         guint16         m = 0;
140         guint16         x;
141         guint           k = 0;
142         guint16         H;
143         guint16         oldH;
144         guint           offset = 0;
145         guint           result_dest;
146         guint           code_length =0;
147         guint8          current_instruction;
148         guint           current_address;
149         guint           operand_address;
150         guint           input_address;
151         guint16         output_address = 0;
152         guint           next_operand_address;
153         guint8          octet;
154         guint8          msb;
155         guint8          lsb;
156         guint16         byte_copy_right;
157         guint16         byte_copy_left;
158         guint16         input_bit_order;
159         guint16         stack_location;
160         guint16         stack_fill;
161         guint16         result;
162         guint           msg_end = tvb_reported_length_remaining(message_tvb, 0);
163         guint16         result_code = 0;
164         guint16         old_input_bit_order = 0;
165         guint16         remaining_bits = 0;
166         guint16         input_bits = 0;
167         guint8          bit_order = 0;
168         gboolean        outside_huffman_boundaries = TRUE;
169         gboolean        print_in_loop = FALSE;
170         guint16         instruction_address;
171         guint8          no_of_state_create = 0;
172         guint16         state_length_buff[5];
173         guint16         state_address_buff[5];
174         guint16         state_instruction_buff[5];
175         guint16         state_minimum_access_length_buff[5];
176         guint16         state_state_retention_priority_buff[5];
177         guint32         used_udvm_cycles = 0;
178         guint           cycles_per_bit;
179         guint           maximum_UDVM_cycles;
180         guint8          *sha1buff;
181         unsigned char sha1_digest_buf[STATE_BUFFER_SIZE];
182         sha1_context ctx;
183
184
185         /* UDVM operand variables */
186         guint16 length;
187         guint16 at_address;
188         guint16 destination;
189         guint16 address;
190         guint16 value;
191         guint16 p_id_start;
192         guint16 p_id_length;
193         guint16 state_begin;
194         guint16 state_length;
195         guint16 state_address;
196         guint16 state_instruction;
197         guint16 operand_1;
198         guint16 operand_2;
199         guint16 value_1;
200         guint16 value_2;
201         guint16 at_address_1;
202         guint16 at_address_2;
203         guint16 at_address_3;
204         guint16 j;
205         guint16 bits_n;
206         guint16 lower_bound_n;
207         guint16 upper_bound_n;
208         guint16 uncompressed_n;
209         guint16 position;
210         guint16 ref_destination; /* could I have used $destination ? */
211         guint16 multy_offset;
212         guint16 output_start;
213         guint16 output_length;
214         guint16 minimum_access_length;
215         guint16 state_retention_priority;
216         guint16 requested_feedback_location;
217         guint16 returned_parameters_location;
218         guint16 start_value;
219
220
221         /* Set print parameters */
222         print_level_1 = FALSE;
223         print_level_2 = FALSE;
224         print_level_3 = FALSE;
225         show_instr_detail_level = 0;
226
227
228
229         switch( print_flags ) {
230                 case 0:
231                         break;
232
233                 case 1:
234                         print_level_1 = TRUE;
235                         show_instr_detail_level = 1;
236                         break;
237                 case 2:
238                         print_level_1 = TRUE;
239                         print_level_2 = TRUE;
240                         show_instr_detail_level = 1;
241                         break;
242                 case 3:
243                         print_level_1 = TRUE;
244                         print_level_2 = TRUE;
245                         print_level_3 = TRUE;
246                         show_instr_detail_level = 2;
247                         break;
248                 default:
249                         print_level_1 = TRUE;
250                         show_instr_detail_level = 1;
251                         break;
252         }
253
254
255
256
257
258         /* UDVM memory must be initialised to zero */
259         memset(buff, 0, UDVM_MEMORY_SIZE);
260         /* Set initial UDVM data 
261          *  The first 32 bytes of UDVM memory are then initialized to special
262          *  values as illustrated in Figure 5.
263          *
264          *                      0             7 8            15
265          *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
266          *                     |       UDVM_memory_size        |  0 - 1
267          *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
268          *                     |        cycles_per_bit         |  2 - 3
269          *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
270          *                     |        SigComp_version        |  4 - 5
271          *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
272          *                     |    partial_state_ID_length    |  6 - 7
273          *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
274          *                     |         state_length          |  8 - 9
275          *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
276          *                     |                               |
277          *                     :           reserved            :  10 - 31
278          *                     |                               |
279          *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
280          *
281          *            Figure 5: Initializing Useful Values in UDVM memory
282          */
283         /* UDVM_memory_size  */
284         buff[0] = (UDVM_MEMORY_SIZE >> 8) & 0x00FF;
285         buff[1] = UDVM_MEMORY_SIZE & 0x00FF;
286         /* cycles_per_bit */
287         buff[2] = 0;
288         buff[3] = 16;
289         /* SigComp_version */
290         buff[4] = 0;
291         buff[5] = 1;
292         /* partial_state_ID_length */
293         buff[6] = (byte_code_id_len >> 8) & 0x00FF;
294         buff[7] = byte_code_id_len & 0x00FF;
295         /* state_length  */
296         buff[8] = (byte_code_state_len >> 8) & 0x00FF;
297         buff[9] = byte_code_state_len & 0x00FF;
298
299         code_length = tvb_reported_length_remaining(bytecode_tvb, 0);
300
301         cycles_per_bit = buff[2] << 8;
302         cycles_per_bit = cycles_per_bit | buff[3];
303         /* 
304          * maximum_UDVM_cycles = (8 * n + 1000) * cycles_per_bit
305          */
306         maximum_UDVM_cycles = (( 8 * (header_len + msg_end) ) + 1000) * cycles_per_bit;
307
308         proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,"maximum_UDVM_cycles(%u) = (( 8 * msg_end(%u) ) + 1000) * cycles_per_bit(%u)",maximum_UDVM_cycles,msg_end,cycles_per_bit);
309         proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,"Message Length: %u,Byte code length: %u, Maximum UDVM cycles: %u",msg_end,code_length,maximum_UDVM_cycles);
310
311         /* Load bytecode into UDVM starting at "udvm_mem_dest" */
312         i = udvm_mem_dest;
313         if ( print_level_3 )
314                 proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,"Load bytecode into UDVM starting at %u",i);
315         while ( code_length > offset && i < UDVM_MEMORY_SIZE ) {
316                 buff[i] = tvb_get_guint8(bytecode_tvb, offset);
317                 if ( print_level_3 )
318                         proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,
319                                                 "              Addr: %u Instruction code(0x%0x) ", i, buff[i]);
320
321                 i++;
322                 offset++;
323
324         }
325         /* Largest allowed size for a message is 65535  */
326         out_buff = g_malloc(65535);
327         /* Start executing code */
328         current_address = udvm_start_ip;
329         input_address = 0;
330         operand_address = 0;
331         
332         proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,"UDVM EXECUTION STARTED at Address: %u Message size %u",
333                 current_address, msg_end);
334
335 execute_next_instruction:
336
337         if ( used_udvm_cycles > maximum_UDVM_cycles ){
338                 result_code = 15;
339                 goto decompression_failure;
340         }
341         current_instruction = buff[current_address];
342
343         switch ( current_instruction ) {
344         case SIGCOMP_INSTR_DECOMPRESSION_FAILURE:
345                 used_udvm_cycles++;
346                 if ( result_code == 0 )
347                         result_code = 9;
348                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
349                         "Addr: %u ## DECOMPRESSION-FAILURE(0)",
350                         current_address);
351                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Ethereal UDVM diagnostic: %s.",
352                                     val_to_str(result_code, result_code_vals,"Unknown (%u)"));
353                 if ( output_address > 0 ){
354                         /* At least something got decompressed, show it */
355                         decomp_tvb = tvb_new_real_data(out_buff,output_address,output_address);
356                         /* Arrange that the allocated packet data copy be freed when the
357                          * tvbuff is freed. 
358                          */
359                         tvb_set_free_cb( decomp_tvb, g_free );
360                         /* Add the tvbuff to the list of tvbuffs to which the tvbuff we
361                          * were handed refers, so it'll get cleaned up when that tvbuff
362                          * is cleaned up. 
363                          */
364                         tvb_set_child_real_data_tvbuff(message_tvb,decomp_tvb);
365                         add_new_data_source(pinfo, decomp_tvb, "Decompressed SigComp message(Incomplete)");
366                         proto_tree_add_text(udvm_tree, decomp_tvb, 0, -1,"SigComp message Decompression failure");
367                 return decomp_tvb;
368                 }
369                 g_free(out_buff);
370                 return NULL;
371                 break;
372
373         case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */
374                 used_udvm_cycles++;
375                 if (show_instr_detail_level == 2 ){
376                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
377                                 "Addr: %u ## AND(1) (operand_1, operand_2)",
378                                 current_address);
379                 }
380                 /* $operand_1*/
381                 operand_address = current_address + 1;
382                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
383                 if (show_instr_detail_level == 2 ){
384                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
385                                 operand_address, operand_1);
386                 }
387                 operand_address = next_operand_address; 
388                 /* %operand_2*/
389                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
390                 if (show_instr_detail_level == 2 ){
391                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
392                                 operand_address, operand_2);
393                 }
394                 if (show_instr_detail_level == 1)
395                 {
396                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
397                                 "Addr: %u ## AND (operand_1=%u, operand_2=%u)",
398                                 current_address, operand_1, operand_2);
399                 }
400                 /* execute the instruction */
401                 result = operand_1 & operand_2;
402                 lsb = result & 0xff;
403                 msb = result >> 8;              
404                 buff[result_dest] = msb;
405                 buff[result_dest+1] = lsb;
406                 if (print_level_1 ){
407                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
408                                 result, result_dest);
409                 }
410                 current_address = next_operand_address; 
411                 goto execute_next_instruction;
412
413                 break;
414
415         case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */
416                 used_udvm_cycles++;
417                 if (show_instr_detail_level == 2 ){
418                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
419                                 "Addr: %u ## OR(2) (operand_1, operand_2)",
420                                 current_address);
421                 }
422                 /* $operand_1*/
423                 operand_address = current_address + 1;
424                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
425                 if (show_instr_detail_level == 2 ){
426                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
427                                 operand_address, operand_1);
428                 }
429                 operand_address = next_operand_address; 
430                 /* %operand_2*/
431                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
432                 if (show_instr_detail_level == 2 ){
433                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
434                                 operand_address, operand_2);
435                 }
436                 if (show_instr_detail_level == 1)
437                 {
438                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
439                                 "Addr: %u ## OR (operand_1=%u, operand_2=%u)",
440                                 current_address, operand_1, operand_2);
441                 }
442                 /* execute the instruction */
443                 result = operand_1 | operand_2;
444                 lsb = result & 0xff;
445                 msb = result >> 8;              
446                 buff[result_dest] = msb;
447                 buff[result_dest+1] = lsb;
448                 if (print_level_1 ){
449                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
450                                 result, result_dest);
451                 }
452                 current_address = next_operand_address; 
453                 goto execute_next_instruction;
454
455                 break;
456
457         case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */
458                 used_udvm_cycles++;
459                 if (show_instr_detail_level == 2 ){
460                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
461                                 "Addr: %u ## NOT(3) ($operand_1)",
462                                 current_address);
463                 }
464                 /* $operand_1*/
465                 operand_address = current_address + 1;
466                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
467                 if (show_instr_detail_level == 2 ){
468                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
469                                 operand_address, operand_1);
470                 }
471                 if (show_instr_detail_level == 1)
472                 {
473                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
474                                 "Addr: %u ## NOT (operand_1=%u)",
475                                 current_address, operand_1);
476                 }
477                 /* execute the instruction */
478                 result = operand_1 ^ 0xffff;
479                 lsb = result & 0xff;
480                 msb = result >> 8;              
481                 buff[result_dest] = msb;
482                 buff[result_dest+1] = lsb;
483                 if (print_level_1 ){
484                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
485                                 result, result_dest);
486                 }
487                 current_address = next_operand_address; 
488                 goto execute_next_instruction;
489                 break;
490
491         case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */
492                 used_udvm_cycles++;
493                 if (show_instr_detail_level == 2 ){
494                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
495                                 "Addr: %u ## LSHIFT(4) ($operand_1, operand_2)",
496                                 current_address);
497                 }
498                 /* $operand_1*/
499                 operand_address = current_address + 1;
500                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
501                 if (show_instr_detail_level == 2 ){
502                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
503                                 operand_address, operand_1);
504                 }
505                 operand_address = next_operand_address; 
506                 /* %operand_2*/
507                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
508                 if (show_instr_detail_level == 2 ){
509                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
510                                 operand_address, operand_2);
511                 }
512                 if (show_instr_detail_level == 1)
513                 {
514                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
515                                 "Addr: %u ## LSHIFT (operand_1=%u, operand_2=%u)",
516                                 current_address, operand_1, operand_2);
517                 }
518                 /* execute the instruction */
519                 result = operand_1 << operand_2;
520                 lsb = result & 0xff;
521                 msb = result >> 8;              
522                 buff[result_dest] = msb;
523                 buff[result_dest+1] = lsb;
524                 if (print_level_1 ){
525                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
526                                 result, result_dest);
527                 }
528                 current_address = next_operand_address; 
529                 goto execute_next_instruction;
530
531                 break;
532         case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */
533                 used_udvm_cycles++;
534                 if (show_instr_detail_level == 2 ){
535                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
536                                 "Addr: %u ## RSHIFT(5) (operand_1, operand_2)",
537                                 current_address);
538                 }
539                 /* $operand_1*/
540                 operand_address = current_address + 1;
541                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
542                 if (show_instr_detail_level == 2 ){
543                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
544                                 operand_address, operand_1);
545                 }
546                 operand_address = next_operand_address; 
547                 /* %operand_2*/
548                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
549                 if (show_instr_detail_level == 2 ){
550                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
551                                 operand_address, operand_2);
552                 }
553                 if (show_instr_detail_level == 1)
554                 {
555                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
556                                 "Addr: %u ## RSHIFT (operand_1=%u, operand_2=%u)",
557                                 current_address, operand_1, operand_2);
558                 }
559                 /* execute the instruction */
560                 result = operand_1 >> operand_2;
561                 lsb = result & 0xff;
562                 msb = result >> 8;              
563                 buff[result_dest] = msb;
564                 buff[result_dest+1] = lsb;
565                 if (print_level_1 ){
566                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
567                                 result, result_dest);
568                 }
569                 current_address = next_operand_address; 
570                 goto execute_next_instruction;
571                 break;
572         case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */
573                 used_udvm_cycles++;
574                 if (show_instr_detail_level == 2 ){
575                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
576                                 "Addr: %u ## ADD(6) (operand_1, operand_2)",
577                                 current_address);
578                 }
579                 /* $operand_1*/
580                 operand_address = current_address + 1;
581                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
582                 if (show_instr_detail_level == 2 ){
583                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
584                                 operand_address, operand_1);
585                 }
586                 operand_address = next_operand_address; 
587                 /* %operand_2*/
588                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
589                 if (show_instr_detail_level == 2 ){
590                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
591                                 operand_address, operand_2);
592                 }
593                 if (show_instr_detail_level == 1)
594                 {
595                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
596                                 "Addr: %u ## ADD (operand_1=%u, operand_2=%u)",
597                                 current_address, operand_1, operand_2);
598                 }
599                 /* execute the instruction */
600                 result = operand_1 + operand_2;
601                 lsb = result & 0xff;
602                 msb = result >> 8;              
603                 buff[result_dest] = msb;
604                 buff[result_dest+1] = lsb;
605                 if (print_level_1 ){
606                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"               Loading result %u at %u",
607                                 result, result_dest);
608                 }
609                 current_address = next_operand_address; 
610                 goto execute_next_instruction;
611
612         case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */
613                 used_udvm_cycles++;
614                 if (show_instr_detail_level == 2 ){
615                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
616                                 "Addr: %u ## SUBTRACT(7) (operand_1, operand_2)",
617                                 current_address);
618                 }
619                 /* $operand_1*/
620                 operand_address = current_address + 1;
621                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
622                 if (show_instr_detail_level == 2 ){
623                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
624                                 operand_address, operand_1);
625                 }
626                 operand_address = next_operand_address; 
627                 /* %operand_2*/
628                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
629                 if (show_instr_detail_level == 2 ){
630                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
631                                 operand_address, operand_2);
632                 }
633                 if (show_instr_detail_level == 1)
634                 {
635                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
636                                 "Addr: %u ## SUBTRACT (operand_1=%u, operand_2=%u)",
637                                 current_address, operand_1, operand_2);
638                 }
639                 /* execute the instruction */
640                 result = operand_1 - operand_2;
641                 lsb = result & 0xff;
642                 msb = result >> 8;              
643                 buff[result_dest] = msb;
644                 buff[result_dest+1] = lsb;
645                 if (print_level_1 ){
646                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"               Loading result %u at %u",
647                                 result, result_dest);
648                 }
649                 current_address = next_operand_address; 
650                 goto execute_next_instruction;
651                 break;
652
653         case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */
654                 used_udvm_cycles++;
655                 if (show_instr_detail_level == 2 ){
656                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
657                                 "Addr: %u ##MULTIPLY(8) (operand_1, operand_2)",
658                                 current_address);
659                 }
660                 /* $operand_1*/
661                 operand_address = current_address + 1;
662                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
663                 if (show_instr_detail_level == 2 ){
664                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
665                                 operand_address, operand_1);
666                 }
667                 operand_address = next_operand_address; 
668                 /* %operand_2*/
669                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
670                 if (show_instr_detail_level == 2 ){
671                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
672                                 operand_address, operand_2);
673                 }
674                 if (show_instr_detail_level == 1)
675                 {
676                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
677                                 "Addr: %u ## MULTIPLY (operand_1=%u, operand_2=%u)",
678                                 current_address, operand_1, operand_2);
679                 }
680                 /* 
681                  * execute the instruction
682                  * MULTIPLY (m, n)  := m * n (modulo 2^16)
683                  */
684                 if ( operand_2 == 0){
685                         result_code = 4;
686                         goto decompression_failure;
687                 }
688                 result = operand_1 * operand_2;
689                 lsb = result & 0xff;
690                 msb = result >> 8;              
691                 buff[result_dest] = msb;
692                 buff[result_dest+1] = lsb;
693                 if (print_level_1 ){
694                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
695                                 result, result_dest);
696                 }
697                 current_address = next_operand_address; 
698                 goto execute_next_instruction;
699                 break;
700
701         case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */
702                 used_udvm_cycles++;
703                 if (show_instr_detail_level == 2 ){
704                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
705                                 "Addr: %u ## DIVIDE(9) (operand_1, operand_2)",
706                                 current_address);
707                 }
708                 /* $operand_1*/
709                 operand_address = current_address + 1;
710                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
711                 if (show_instr_detail_level == 2 ){
712                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
713                                 operand_address, operand_1);
714                 }
715                 operand_address = next_operand_address; 
716                 /* %operand_2*/
717                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
718                 if (show_instr_detail_level == 2 ){
719                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
720                                 operand_address, operand_2);
721                 }
722                 if (show_instr_detail_level == 1)
723                 {
724                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
725                                 "Addr: %u ## DIVIDE (operand_1=%u, operand_2=%u)",
726                                 current_address, operand_1, operand_2);
727                 }
728                 /* 
729                  * execute the instruction
730                  * DIVIDE (m, n)    := floor(m / n)
731                  * Decompression failure occurs if a DIVIDE or REMAINDER instruction
732                  * encounters an operand_2 that is zero.
733                  */
734                 if ( operand_2 == 0){
735                         result_code = 4;
736                         goto decompression_failure;
737                 }
738                 result = operand_1 / operand_2;
739                 lsb = result & 0xff;
740                 msb = result >> 8;              
741                 buff[result_dest] = msb;
742                 buff[result_dest+1] = lsb;
743                 if (print_level_1 ){
744                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
745                                 result, result_dest);
746                 }
747                 current_address = next_operand_address; 
748                 goto execute_next_instruction;
749                 break;
750
751         case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */
752                 used_udvm_cycles++;
753                 if (show_instr_detail_level == 2 ){
754                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
755                                 "Addr: %u ## REMAINDER(10) (operand_1, operand_2)",
756                                 current_address);
757                 }
758                 /* $operand_1*/
759                 operand_address = current_address + 1;
760                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
761                 if (show_instr_detail_level == 2 ){
762                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
763                                 operand_address, operand_1);
764                 }
765                 operand_address = next_operand_address; 
766                 /* %operand_2*/
767                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
768                 if (show_instr_detail_level == 2 ){
769                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
770                                 operand_address, operand_2);
771                 }
772                 if (show_instr_detail_level == 1)
773                 {
774                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
775                                 "Addr: %u ## REMAINDER (operand_1=%u, operand_2=%u)",
776                                 current_address, operand_1, operand_2);
777                 }
778                 /* 
779                  * execute the instruction
780                  * REMAINDER (m, n) := m - n * floor(m / n)
781                  * Decompression failure occurs if a DIVIDE or REMAINDER instruction
782                  * encounters an operand_2 that is zero.
783                  */
784                 if ( operand_2 == 0){
785                         result_code = 4;
786                         goto decompression_failure;
787                 }
788                 result = operand_1 - operand_2 * (operand_1 / operand_2);
789                 lsb = result & 0xff;
790                 msb = result >> 8;              
791                 buff[result_dest] = msb;
792                 buff[result_dest+1] = lsb;
793                 if (print_level_1 ){
794                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
795                                 result, result_dest);
796                 }
797                 current_address = next_operand_address; 
798                 goto execute_next_instruction;
799                 break;
800         case SIGCOMP_INSTR_SORT_ASCENDING: /* 11 SORT-ASCENDING (%start, %n, %k) */
801                 /*
802                  *      used_udvm_cycles =  1 + k * (ceiling(log2(k)) + n)
803                  */
804                 if (print_level_1 ){
805                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
806                                 "Addr: %u ## SORT-ASCENDING(11) (start, n, k))",
807                                 current_address);
808                 }
809                 operand_address = current_address + 1;
810                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Execution of this instruction is NOT implemented");
811                 /*
812                  *      used_udvm_cycles =  1 + k * (ceiling(log2(k)) + n)
813                  */
814                 break;
815
816         case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */
817                 if (print_level_1 ){
818                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
819                                 "Addr: %u ## SORT-DESCENDING(12) (start, n, k))",
820                                 current_address);
821                 }
822                 operand_address = current_address + 1;
823                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Execution of this instruction is NOT implemented");
824                 /*
825                  *      used_udvm_cycles =  1 + k * (ceiling(log2(k)) + n)
826                  */
827                 break;
828         case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */
829                 if (print_level_1 ){
830                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
831                                 "Addr: %u ## SHA-1(13) (position, length, destination)",
832                                 current_address);
833                 }
834                 operand_address = current_address + 1;
835                 /* %position */
836                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
837                 if (print_level_1 ){
838                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      position %u",
839                                 operand_address, position);
840                 }
841                 operand_address = next_operand_address; 
842
843                 /* %length */
844                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
845                 if (print_level_1 ){
846                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
847                                 operand_address, length);
848                 }
849                 operand_address = next_operand_address;
850
851                 /* $destination */
852                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &ref_destination, &result_dest);
853                 if (print_level_1 ){
854                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      $destination %u",
855                                 operand_address, ref_destination);
856                 }
857                 current_address = next_operand_address; 
858                 used_udvm_cycles = used_udvm_cycles + 1 + length;
859
860                 n = 0;
861                 k = position;
862                 byte_copy_right = buff[66] << 8;
863                 byte_copy_right = byte_copy_right | buff[67];
864                 byte_copy_left = buff[64] << 8;
865                 byte_copy_left = byte_copy_left | buff[65];
866
867                 if (print_level_2 ){
868                         proto_tree_add_text(udvm_tree, message_tvb, 0, -1,
869                                         "byte_copy_right = %u", byte_copy_right);
870                 }
871
872                 sha1_starts( &ctx );
873
874                 while (n<length) {
875                         guint16 handle_now = length;
876
877                         if ( k < byte_copy_right && byte_copy_right <= k + (length-n) ){
878                                 handle_now = byte_copy_right - position;
879                         }
880
881                         if (k + handle_now >= UDVM_MEMORY_SIZE)
882                                 goto decompression_failure;
883                         sha1_update( &ctx, &buff[k], handle_now );
884
885                         k = ( k + handle_now ) & 0xffff;
886                         n = ( n + handle_now ) & 0xffff;
887
888                         if ( k >= byte_copy_right ) {
889                                 k = byte_copy_left;
890                         }
891                 }
892
893                 sha1_finish( &ctx, sha1_digest_buf );
894
895                 k = ref_destination; 
896
897                 for ( n=0; n< STATE_BUFFER_SIZE; n++ ) {
898
899                         buff[k] = sha1_digest_buf[n];
900
901                         k = ( k + 1 ) & 0xffff;
902                         n++;
903
904                         if ( k == byte_copy_right ){
905                                 k = byte_copy_left;
906                         }
907                 }
908
909                 if (print_level_2 ){
910                         proto_tree_add_text(udvm_tree, message_tvb, 0, -1,
911                                         "Calculated SHA-1: %s",
912                                         bytes_to_str(sha1_digest_buf, STATE_BUFFER_SIZE));
913                 }
914
915                 current_address = next_operand_address;
916                 goto execute_next_instruction;
917                 break;
918
919         case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */
920                 if (show_instr_detail_level == 2 ){
921                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
922                                 "Addr: %u ## LOAD(14) (%%address, %%value)",
923                                 current_address);
924                 }
925                 operand_address = current_address + 1;
926                 /* %address */
927                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &address);
928                 if (show_instr_detail_level == 2 ){
929                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Address %u",
930                                 operand_address, address);
931                 }
932                 operand_address = next_operand_address; 
933                 /* %value */
934                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
935                 if (show_instr_detail_level == 1)
936                 {
937                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
938                                 "Addr: %u ## LOAD (%%address=%u, %%value=%u)",
939                                 current_address, address, value);
940                 }
941                 lsb = value & 0xff;
942                 msb = value >> 8;
943
944                 buff[address] = msb;
945                 buff[address + 1] = lsb;
946
947                 if (print_level_1 ){
948                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
949                                 operand_address, value);
950                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading bytes at %u Value %u 0x%x",
951                                         address, value, value);
952                 }
953                 used_udvm_cycles++;
954                 current_address = next_operand_address;
955                 goto execute_next_instruction;
956                 break;
957
958         case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
959                 /* RFC 3320:
960                  * The MULTILOAD instruction sets a contiguous block of 2-byte words in
961                  * the UDVM memory to specified values.
962                  * Hmm what if the value to load only takes one byte ? Chose to always load two bytes.
963                  */
964                 if (show_instr_detail_level == 2 ){
965                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
966                                 "Addr: %u ## MULTILOAD(15) (%%address, #n, value_0, ..., value_n-1)",
967                                 current_address);
968                 }
969                 operand_address = current_address + 1;
970                 /* %address */
971                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &address);
972                 if (show_instr_detail_level == 2 ){
973                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Address %u",
974                                 operand_address, address);
975                 }
976                 operand_address = next_operand_address; 
977
978                 /* #n */
979                 next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
980                 if (show_instr_detail_level == 2 ){
981                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      n %u",
982                                 operand_address, n);
983                 }
984                 if (show_instr_detail_level == 1)
985                 {
986                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
987                                 "Addr: %u ## MULTILOAD (%%address=%u, #n=%u, value_0, ..., value_%d)",
988                                 current_address, address, n, n-1);
989                 }
990                 operand_address = next_operand_address; 
991                 used_udvm_cycles = used_udvm_cycles + 1 + n;
992                 while ( n > 0) {
993                         n = n - 1;
994                         /* %value */
995                         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
996                         lsb = value & 0xff;
997                         msb = value >> 8;
998
999                         if (address >= UDVM_MEMORY_SIZE - 1)
1000                                 goto decompression_failure;
1001
1002                         buff[address] = msb;
1003                         buff[address + 1] = lsb;
1004                         /* debug
1005                         */
1006                         length = next_operand_address - operand_address;
1007
1008                         if (print_level_1 ){
1009                                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1, "Addr: %u      Value %5u      - Loading bytes at %5u Value %5u 0x%x",
1010                                 operand_address, value, address, value, value);
1011                         }
1012                         address = address + 2;
1013                         operand_address = next_operand_address; 
1014                 }
1015                 current_address = next_operand_address;
1016                 goto execute_next_instruction;
1017
1018                 break;
1019                          
1020         case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */
1021                 if (show_instr_detail_level == 2){
1022                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1023                                 "Addr: %u ## PUSH(16) (value)",
1024                                 current_address);
1025                 }
1026                 operand_address = current_address + 1;
1027                 /* %value */
1028                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
1029                 if (show_instr_detail_level == 2){
1030                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
1031                                 operand_address, value);
1032                 }
1033                 if (show_instr_detail_level == 1)
1034                 {
1035                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1036                                 "Addr: %u ## PUSH (value=%u)",
1037                                 current_address, value);
1038                 }
1039                 current_address = next_operand_address; 
1040
1041                 /* Push the value address onto the stack */ 
1042                 stack_location = (buff[70] << 8) | buff[71];
1043                 stack_fill = (buff[stack_location] << 8) 
1044                            | buff[(stack_location+1) & 0xFFFF];
1045                 address = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
1046
1047                 if (address >= UDVM_MEMORY_SIZE - 1)
1048                         goto decompression_failure;
1049
1050                 buff[address] = (value >> 8) & 0x00FF;
1051                 buff[(address+1) & 0xFFFF] = value & 0x00FF;
1052
1053                 if (stack_location >= UDVM_MEMORY_SIZE - 1)
1054                         goto decompression_failure;
1055                 
1056                 stack_fill = (stack_fill + 1) & 0xFFFF;
1057                 buff[stack_location] = (stack_fill >> 8) & 0x00FF;
1058                 buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
1059
1060                 used_udvm_cycles++;
1061                 goto execute_next_instruction;
1062
1063                 break;
1064
1065         case SIGCOMP_INSTR_POP: /* 17 POP (%address) */
1066                 if (show_instr_detail_level == 2){
1067                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1068                                 "Addr: %u ## POP(16) (value)",
1069                                 current_address);
1070                 }
1071                 operand_address = current_address + 1;
1072                 /* %value */
1073                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
1074                 if (show_instr_detail_level == 2){
1075                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
1076                                 operand_address, destination);
1077                 }
1078                 if (show_instr_detail_level == 1)
1079                 {
1080                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1081                                 "Addr: %u ## POP (address=%u)",
1082                                 current_address, destination);
1083                 }
1084                 current_address = next_operand_address; 
1085
1086                 /* Pop value from the top of the stack */ 
1087                 stack_location = (buff[70] << 8) | buff[71];
1088                 stack_fill = (buff[stack_location] << 8) 
1089                            | buff[(stack_location+1) & 0xFFFF];
1090                 if (stack_fill == 0)
1091                 {
1092                     result_code = 16;
1093                     goto decompression_failure;
1094                 }
1095
1096                 if (stack_location >= UDVM_MEMORY_SIZE - 1)
1097                         goto decompression_failure;
1098
1099                 stack_fill = (stack_fill - 1) & 0xFFFF;
1100                 buff[stack_location] = (stack_fill >> 8) & 0x00FF;
1101                 buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
1102
1103                 if (address >= UDVM_MEMORY_SIZE - 1)
1104                         goto decompression_failure;
1105
1106                 address = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
1107                 value = (buff[address] << 8) 
1108                            | buff[(address+1) & 0xFFFF];
1109
1110                 /* ... and store the popped value. */
1111                 if (destination >= UDVM_MEMORY_SIZE - 1)
1112                         goto decompression_failure;
1113                 buff[destination] = (value >> 8) & 0x00FF;
1114                 buff[(destination+1) & 0xFFFF] = value & 0x00FF;
1115
1116                 used_udvm_cycles++;
1117                 goto execute_next_instruction;
1118
1119                 break;
1120
1121         case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */
1122                 if (show_instr_detail_level == 2 ){
1123                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1124                                 "Addr: %u ## COPY(18) (position, length, destination)",
1125                                 current_address);
1126                 }
1127                 operand_address = current_address + 1;
1128                 /* %position */
1129                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
1130                 if (show_instr_detail_level == 2 ){
1131                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      position %u",
1132                                 operand_address, position);
1133                 }
1134                 operand_address = next_operand_address; 
1135
1136                 /* %length */
1137                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
1138                 if (show_instr_detail_level == 2 ){
1139                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
1140                                 operand_address, length);
1141                 }
1142                 operand_address = next_operand_address;
1143
1144                 /* %destination */
1145                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
1146                 if (show_instr_detail_level == 2 ){
1147                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Destination %u",
1148                                 operand_address, destination);
1149                 }
1150                 if (show_instr_detail_level == 1)
1151                 {
1152                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1153                                 "Addr: %u ## COPY (position=%u, length=%u, destination=%u)",
1154                                 current_address, position, length, destination);
1155                 }
1156                 current_address = next_operand_address;
1157                 /*
1158                  * 8.4.  Byte copying
1159                  * :
1160                  * The string of bytes is copied in ascending order of memory address,
1161                  * respecting the bounds set by byte_copy_left and byte_copy_right.
1162                  * More precisely, if a byte is copied from/to Address m then the next
1163                  * byte is copied from/to Address n where n is calculated as follows:
1164                  *
1165                  * Set k := m + 1 (modulo 2^16)
1166                  * If k = byte_copy_right then set n := byte_copy_left, else set n := k
1167                  *
1168                  */ 
1169
1170                 n = 0;
1171                 k = destination; 
1172                 byte_copy_right = buff[66] << 8;
1173                 byte_copy_right = byte_copy_right | buff[67];
1174                 byte_copy_left = buff[64] << 8;
1175                 byte_copy_left = byte_copy_left | buff[65];
1176                 if (print_level_2 ){
1177                         proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
1178                                                 "               byte_copy_right = %u", byte_copy_right);
1179                 }
1180
1181                 while ( n < length ){
1182                         buff[k] = buff[position];
1183                         if (print_level_2 ){
1184                                 proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
1185                                         "               Copying value: %u (0x%x) to Addr: %u",
1186                                         buff[position], buff[position], k);
1187                         }
1188                         position = ( position + 1 ) & 0xffff;
1189                         k = ( k + 1 ) & 0xffff;
1190                         n++;
1191
1192                         /*
1193                          * Check for circular buffer wrapping after the positions are
1194                          * incremented. If either started at BCR then they should continue
1195                          * to increment beyond BCR.
1196                          */
1197                         if ( k == byte_copy_right ){
1198                                 k = byte_copy_left;
1199                         }
1200                         if ( position == byte_copy_right ){
1201                                 position = byte_copy_left;
1202                         }
1203                 }
1204                 used_udvm_cycles = used_udvm_cycles + 1 + length;
1205                 goto execute_next_instruction;
1206                 break;
1207
1208         case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */
1209                 if (show_instr_detail_level == 2 ){
1210                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1211                                 "Addr: %u ## COPY-LITERAL(19) (position, length, $destination)",
1212                                 current_address);
1213                 }
1214                 operand_address = current_address + 1;
1215                 /* %position */
1216                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
1217                 if (show_instr_detail_level == 2 ){
1218                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      position %u",
1219                                 operand_address, position);
1220                 }
1221                 operand_address = next_operand_address; 
1222
1223                 /* %length */
1224                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
1225                 if (show_instr_detail_level == 2 ){
1226                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
1227                                 operand_address, length);
1228                 }
1229                 operand_address = next_operand_address;
1230
1231
1232                 /* $destination */
1233                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &ref_destination, &result_dest);
1234                 if (show_instr_detail_level == 2 ){
1235                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      destination %u",
1236                                 operand_address, ref_destination);
1237                 }
1238                 if (show_instr_detail_level == 1)
1239                 {
1240                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1241                                 "Addr: %u ## COPY-LITERAL (position=%u, length=%u, $destination=%u)",
1242                                 current_address, position, length, destination);
1243                 }
1244                 current_address = next_operand_address; 
1245
1246
1247                 /*
1248                  * 8.4.  Byte copying
1249                  * :
1250                  * The string of bytes is copied in ascending order of memory address,
1251                  * respecting the bounds set by byte_copy_left and byte_copy_right.
1252                  * More precisely, if a byte is copied from/to Address m then the next
1253                  * byte is copied from/to Address n where n is calculated as follows:
1254                  *
1255                  * Set k := m + 1 (modulo 2^16)
1256                  * If k = byte_copy_right then set n := byte_copy_left, else set n := k
1257                  *
1258                  */ 
1259
1260                 n = 0;
1261                 k = ref_destination; 
1262                 byte_copy_right = buff[66] << 8;
1263                 byte_copy_right = byte_copy_right | buff[67];
1264                 byte_copy_left = buff[64] << 8;
1265                 byte_copy_left = byte_copy_left | buff[65];
1266                 if (print_level_2 ){
1267                         proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
1268                                         "               byte_copy_right = %u", byte_copy_right);
1269                 }
1270                 while ( n < length ){
1271
1272                         buff[k] = buff[position];
1273                         if (print_level_2 ){
1274                                 proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
1275                                         "               Copying value: %u (0x%x) to Addr: %u", 
1276                                         buff[position], buff[position], k);
1277                         }
1278                         position = ( position + 1 ) & 0xffff;
1279                         k = ( k + 1 ) & 0xffff;
1280                         n++;
1281
1282                         /*
1283                          * Check for circular buffer wrapping after the positions are
1284                          * incremented. It is important that k cannot be left set
1285                          * to BCR. Also, if either started at BCR then they should continue
1286                          * to increment beyond BCR.
1287                          */
1288                         if ( k == byte_copy_right ){
1289                                 k = byte_copy_left;
1290                         }
1291                         if ( position == byte_copy_right ){
1292                                 position = byte_copy_left;
1293                         }
1294                 }
1295                 buff[result_dest] = k >> 8;
1296                 buff[result_dest + 1] = k & 0x00ff;
1297
1298                 used_udvm_cycles = used_udvm_cycles + 1 + length;
1299                 goto execute_next_instruction;
1300                 break;
1301  
1302         case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */
1303                 if (show_instr_detail_level == 2 ){
1304                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1305                                 "Addr: %u ## COPY-OFFSET(20) (offset, length, $destination)",
1306                                 current_address);
1307                 }
1308                 operand_address = current_address + 1;
1309                 /* %offset */
1310                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &multy_offset);
1311                 if (show_instr_detail_level == 2 ){
1312                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      offset %u",
1313                                 operand_address, multy_offset);
1314                 }
1315                 operand_address = next_operand_address; 
1316
1317                 /* %length */
1318                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
1319                 if (show_instr_detail_level == 2 ){
1320                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
1321                                 operand_address, length);
1322                 }
1323                 operand_address = next_operand_address;
1324
1325
1326                 /* $destination */
1327                 next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &ref_destination, &result_dest);
1328                 if (show_instr_detail_level == 2 ){
1329                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      $destination %u",
1330                                 operand_address, ref_destination);
1331                 }
1332
1333                 if (show_instr_detail_level == 1)
1334                 {
1335                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1336                                 "Addr: %u ## COPY-OFFSET (offset=%u, length=%u, $destination=%u)",
1337                                 current_address, multy_offset, length, result_dest);
1338                 }
1339                 current_address = next_operand_address; 
1340
1341                 /* Execute the instruction:
1342                  * To derive the value of the position operand, starting at the memory
1343                  * address specified by destination, the UDVM counts backwards a total
1344                  * of offset memory addresses.
1345                  * 
1346                  * If the memory address specified in byte_copy_left is reached, the
1347                  * next memory address is taken to be (byte_copy_right - 1) modulo 2^16.
1348                  */
1349                 byte_copy_left = buff[64] << 8;
1350                 byte_copy_left = byte_copy_left | buff[65];
1351                 byte_copy_right = buff[66] << 8;
1352                 byte_copy_right = byte_copy_right | buff[67];
1353
1354                 /*
1355                  * In order to work out the position, simple arithmetic is tricky
1356                  * to apply because there some nasty corner cases. A simple loop
1357                  * is inefficient but the logic is simple.
1358                  *
1359                  * FUTURE: This could be optimised.
1360                  */
1361                 for (position = ref_destination, i = 0; i < multy_offset; i++)
1362                 {
1363                         if ( position == byte_copy_left )
1364                         {
1365                                 position = (byte_copy_right - 1) & 0xffff;
1366                         }
1367                         else
1368                         {
1369                                 position = (position - 1) & 0xffff;
1370                         }
1371                 }
1372
1373                 if (print_level_2 ){
1374                         proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
1375                                         "               byte_copy_left = %u byte_copy_right = %u position= %u",
1376                                         byte_copy_left, byte_copy_right, position);
1377                         }
1378                 /* The COPY-OFFSET instruction then behaves as a COPY-LITERAL
1379                  * instruction, taking the value of the position operand to be the last
1380                  * memory address reached in the above step.
1381                  */
1382
1383                 /*
1384                  * 8.4.  Byte copying
1385                  * :
1386                  * The string of bytes is copied in ascending order of memory address,
1387                  * respecting the bounds set by byte_copy_left and byte_copy_right.
1388                  * More precisely, if a byte is copied from/to Address m then the next
1389                  * byte is copied from/to Address n where n is calculated as follows:
1390                  *
1391                  * Set k := m + 1 (modulo 2^16)
1392                  * If k = byte_copy_right then set n := byte_copy_left, else set n := k
1393                  *
1394                  */ 
1395
1396                 n = 0;
1397                 k = ref_destination; 
1398                 if (print_level_2 ){
1399                         proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
1400                                         "               byte_copy_left = %u byte_copy_right = %u", byte_copy_left, byte_copy_right);
1401                 }
1402                 while ( n < length ){
1403                         buff[k] = buff[position];
1404                         if (print_level_2 ){
1405                                 proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
1406                                         "               Copying value: %5u (0x%x) from Addr: %u to Addr: %u",
1407                                         buff[position], buff[position],(position), k);
1408                         }
1409                         n++;
1410                         k = ( k + 1 ) & 0xffff;
1411                         position = ( position + 1 ) & 0xffff;
1412
1413                         /*
1414                          * Check for circular buffer wrapping after the positions are
1415                          * incremented. It is important that k cannot be left set
1416                          * to BCR. Also, if either started at BCR then they should continue
1417                          * to increment beyond BCR.
1418                          */
1419                         if ( k == byte_copy_right ){
1420                                 k = byte_copy_left;
1421                         }
1422                         if ( position == byte_copy_right ){
1423                                 position = byte_copy_left;
1424                         }
1425                 }
1426                 buff[result_dest] = k >> 8;
1427                 buff[result_dest + 1] = k & 0x00ff;
1428                 used_udvm_cycles = used_udvm_cycles + 1 + length;
1429                 goto execute_next_instruction;
1430
1431                 break;
1432         case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */
1433                 if (show_instr_detail_level == 2 ){
1434                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1435                                 "Addr: %u ## MEMSET(21) (address, length, start_value, offset)",
1436                                 current_address);
1437                 }
1438                 operand_address = current_address + 1;
1439
1440                 /* %address */
1441                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &address);
1442                 if (show_instr_detail_level == 2 ){
1443                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Address %u",
1444                                 operand_address, address);
1445                 }
1446                 operand_address = next_operand_address; 
1447
1448                 /*  %length, */
1449                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
1450                 if (show_instr_detail_level == 2 ){
1451                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
1452                                 operand_address, length);
1453                 }
1454                 operand_address = next_operand_address;
1455                 /* %start_value */
1456                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &start_value);
1457                 if (show_instr_detail_level == 2 ){
1458                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      start_value %u",
1459                                 operand_address, start_value);
1460                 }
1461                 operand_address = next_operand_address; 
1462
1463                 /* %offset */
1464                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &multy_offset);
1465                 if (show_instr_detail_level == 2 ){
1466                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      offset %u",
1467                                 operand_address, multy_offset);
1468                 }
1469                 if (show_instr_detail_level == 1)
1470                 {
1471                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1472                                 "Addr: %u ## MEMSET (address=%u, length=%u, start_value=%u, offset=%u)",
1473                                 current_address, address, length, start_value, multy_offset);
1474                 }
1475                 current_address = next_operand_address; 
1476                 /* exetute the instruction
1477                  * The sequence of values used by the MEMSET instruction is specified by
1478                  * the following formula:
1479                  * 
1480                  * Seq[n] := (start_value + n * offset) modulo 256
1481                  */
1482                 n = 0;
1483                 k = address; 
1484                 byte_copy_right = buff[66] << 8;
1485                 byte_copy_right = byte_copy_right | buff[67];
1486                 byte_copy_left = buff[64] << 8;
1487                 byte_copy_left = byte_copy_left | buff[65];
1488                 if (print_level_2 ){
1489                         proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
1490                                         "               byte_copy_left = %u byte_copy_right = %u", byte_copy_left, byte_copy_right);
1491                 }
1492                 while ( n < length ){
1493                         if ( k == byte_copy_right ){
1494                                 k = byte_copy_left;
1495                         }
1496                         buff[k] = (start_value + ( n * multy_offset)) & 0xff;
1497                         if (print_level_2 ){
1498                                 proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
1499                                         "     Storing value: %u (0x%x) at Addr: %u",
1500                                         buff[k], buff[k], k);
1501                         }
1502                         k = ( k + 1 ) & 0xffff;
1503                         n++;
1504                 }/* end while */
1505                 used_udvm_cycles = used_udvm_cycles + 1 + length;
1506                 goto execute_next_instruction;
1507                 break;
1508
1509
1510         case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */
1511                 if (show_instr_detail_level == 2 ){
1512                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1513                                 "Addr: %u ## JUMP(22) (@address)",
1514                                 current_address);
1515                 }
1516                 operand_address = current_address + 1;
1517                 /* @address */
1518                  /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1519                 next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
1520                 if (show_instr_detail_level == 2 ){
1521                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
1522                                 operand_address, at_address);
1523                 }
1524                 if (show_instr_detail_level == 1)
1525                 {
1526                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1527                                 "Addr: %u ## JUMP (@address=%u)",
1528                                 current_address, at_address);
1529                 }
1530                 current_address = at_address;
1531                 used_udvm_cycles++;
1532                 goto execute_next_instruction;
1533                 break;
1534
1535         case SIGCOMP_INSTR_COMPARE: /* 23 */
1536                 /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
1537                  */
1538                 if (show_instr_detail_level == 2 ){
1539                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1540                                 "Addr: %u ## COMPARE(23) (value_1, value_2, @address_1, @address_2, @address_3)",
1541                                 current_address);
1542                 }
1543                 operand_address = current_address + 1;
1544
1545                 /* %value_1 */
1546                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value_1);
1547                 if (show_instr_detail_level == 2 ){
1548                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
1549                                         operand_address, value_1);
1550                 }
1551                 operand_address = next_operand_address;
1552
1553                 /* %value_2 */
1554                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value_2);
1555                 if (show_instr_detail_level == 2 ){
1556                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
1557                                         operand_address, value_2);
1558                 }
1559                 operand_address = next_operand_address;
1560
1561                 /* @address_1 */
1562                  /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1563                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_1);
1564                 at_address_1 = ( current_address + at_address_1) & 0xffff;
1565                 if (show_instr_detail_level == 2 ){
1566                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
1567                                 operand_address, at_address_1);
1568                 }
1569                 operand_address = next_operand_address;
1570
1571
1572                 /* @address_2 */
1573                  /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1574                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_2);
1575                 at_address_2 = ( current_address + at_address_2) & 0xffff;
1576                 if (show_instr_detail_level == 2 ){
1577                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
1578                                 operand_address, at_address_2);
1579                 }
1580                 operand_address = next_operand_address;
1581
1582                 /* @address_3 */
1583                  /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1584                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_3);
1585                 at_address_3 = ( current_address + at_address_3) & 0xffff;
1586                 if (show_instr_detail_level == 2 ){
1587                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
1588                                 operand_address, at_address_3);
1589                 }
1590                 if (show_instr_detail_level == 1)
1591                 {
1592                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1593                                 "Addr: %u ## COMPARE (value_1=%u, value_2=%u, @address_1=%u, @address_2=%u, @address_3=%u)",
1594                                 current_address, value_1, value_2, at_address_1, at_address_2, at_address_3);
1595                 }
1596                 /* execute the instruction
1597                  * If value_1 < value_2 then the UDVM continues instruction execution at
1598                  * the memory address specified by address 1. If value_1 = value_2 then
1599                  * it jumps to the address specified by address_2. If value_1 > value_2
1600                  * then it jumps to the address specified by address_3.
1601                  */
1602                 if ( value_1 < value_2 )
1603                         current_address = at_address_1;
1604                 if ( value_1 == value_2 )
1605                         current_address = at_address_2;
1606                 if ( value_1 > value_2 )
1607                         current_address = at_address_3;
1608                 used_udvm_cycles++;
1609                 goto execute_next_instruction;
1610                 break;
1611
1612         case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/
1613                 if (show_instr_detail_level == 2){
1614                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1615                                 "Addr: %u ## CALL(24) (@address) (PUSH addr )",
1616                                 current_address);
1617                 }
1618                 operand_address = current_address + 1;
1619                 /* @address */
1620                 next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
1621                 if (show_instr_detail_level == 2 ){
1622                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
1623                                 operand_address, at_address);
1624                 }
1625                 if (show_instr_detail_level == 1)
1626                 {
1627                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1628                                 "Addr: %u ## CALL (@address=%u)",
1629                                 current_address, at_address);
1630                 }
1631                 current_address = next_operand_address; 
1632
1633                 /* Push the current address onto the stack */ 
1634                 stack_location = (buff[70] << 8) | buff[71];
1635                 stack_fill = (buff[stack_location] << 8) 
1636                            | buff[(stack_location+1) & 0xFFFF];
1637                 address = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
1638                 if (address >= UDVM_MEMORY_SIZE - 1)
1639                         goto decompression_failure;
1640                 buff[address] = (current_address >> 8) & 0x00FF;
1641                 buff[(address+1) & 0xFFFF] = current_address & 0x00FF;
1642                 
1643                 stack_fill = (stack_fill + 1) & 0xFFFF;
1644                 if (stack_location >= UDVM_MEMORY_SIZE - 1)
1645                         goto decompression_failure;
1646                 buff[stack_location] = (stack_fill >> 8) & 0x00FF;
1647                 buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
1648
1649                 /* ... and jump to the destination address */
1650                 current_address = at_address;
1651
1652                 used_udvm_cycles++;
1653                 goto execute_next_instruction;
1654
1655                 break;
1656
1657         case SIGCOMP_INSTR_RETURN: /* 25 POP and return */
1658                 if (print_level_1 || show_instr_detail_level == 1){
1659                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1660                                 "Addr: %u ## POP(25) and return",
1661                                 current_address);
1662                 }
1663
1664                 /* Pop value from the top of the stack */ 
1665                 stack_location = (buff[70] << 8) | buff[71];
1666                 stack_fill = (buff[stack_location] << 8) 
1667                            | buff[(stack_location+1) & 0xFFFF];
1668                 if (stack_fill == 0)
1669                 {
1670                     result_code = 16;
1671                     goto decompression_failure;
1672                 }
1673
1674                 stack_fill = (stack_fill - 1) & 0xFFFF;
1675                 if (stack_location >= UDVM_MEMORY_SIZE - 1)
1676                         goto decompression_failure;
1677                 buff[stack_location] = (stack_fill >> 8) & 0x00FF;
1678                 buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
1679
1680                 address = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
1681                 at_address = (buff[address] << 8) 
1682                            | buff[(address+1) & 0xFFFF];
1683
1684                 /* ... and set the PC to the popped value */
1685                 current_address = at_address;
1686
1687                 used_udvm_cycles++;
1688                 goto execute_next_instruction;
1689
1690                 break;
1691
1692         case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
1693                 /*
1694                  * When a SWITCH instruction is encountered the UDVM reads the value of
1695                  * j. It then continues instruction execution at the address specified
1696                  * by address j.
1697                  * 
1698                  * Decompression failure occurs if j specifies a value of n or more, or
1699                  * if the address lies beyond the overall UDVM memory size.
1700                  */
1701                 instruction_address = current_address;
1702                 if (print_level_1 ){
1703                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1704                                 "Addr: %u ## SWITCH (#n, j, @address_0, @address_1, ... , @address_n-1))",
1705                                 current_address);
1706                 }
1707                 operand_address = current_address + 1;
1708                 /* #n 
1709                  * Number of addresses in the instruction
1710                  */
1711                 next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
1712                 if (print_level_1 ){
1713                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      n %u",
1714                                 operand_address, n);
1715                 }
1716                 operand_address = next_operand_address; 
1717                 /* %j */
1718                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &j);
1719                 if (print_level_1 ){
1720                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      j %u",
1721                                         operand_address, j);
1722                 }
1723                 operand_address = next_operand_address;
1724                 m = 0;
1725                 while ( m < n ){
1726                         /* @address_n-1 */
1727                         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1728                         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_1);
1729                         at_address_1 = ( instruction_address + at_address_1) & 0xffff;
1730                         if (print_level_1 ){
1731                                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
1732                                         operand_address, at_address_1);
1733                         }
1734                         if ( j == m ){
1735                                 current_address = at_address_1;
1736                         }
1737                         operand_address = next_operand_address;
1738                         m++;
1739                 }
1740                 /* Check decompression failure */
1741                 if ( ( j == n ) || ( j > n )){
1742                         result_code = 5;
1743                         goto decompression_failure;
1744                 }
1745                 if ( current_address > UDVM_MEMORY_SIZE ){
1746                         result_code = 6;
1747                         goto decompression_failure;
1748                 }
1749                 used_udvm_cycles = used_udvm_cycles + 1 + n;
1750
1751                 goto execute_next_instruction;
1752
1753                 break;
1754         case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */
1755                 if (print_level_1 ){
1756                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1757                                 "Addr: %u ## CRC (value, position, length, @address)",
1758                                 current_address);
1759                 }
1760
1761                 operand_address = current_address + 1;
1762
1763                 /* %value */
1764                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
1765                 if (print_level_1 ){
1766                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
1767                                 operand_address, value);
1768                 }
1769                 operand_address = next_operand_address; 
1770
1771                 /* %position */
1772                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
1773                 if (print_level_1 ){
1774                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      position %u",
1775                                 operand_address, position);
1776                 }
1777                 operand_address = next_operand_address; 
1778
1779                 /* %length */
1780                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
1781                 if (print_level_1 ){
1782                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
1783                                 operand_address, length);
1784                 }
1785                 operand_address = next_operand_address;
1786
1787                 /* @address */
1788                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address);
1789                 at_address = ( current_address + at_address) & 0xffff;
1790                 if (print_level_1 ){
1791                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
1792                                 operand_address, at_address);
1793                 }
1794                  /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1795                 used_udvm_cycles = used_udvm_cycles + 1 + length;
1796                 
1797                 n = 0;
1798                 k = position;
1799                 byte_copy_right = buff[66] << 8;
1800                 byte_copy_right = byte_copy_right | buff[67];
1801                 byte_copy_left = buff[64] << 8;
1802                 byte_copy_left = byte_copy_left | buff[65];
1803                 result = 0;
1804
1805                 if (print_level_2 ){
1806                         proto_tree_add_text(udvm_tree, message_tvb, 0, -1,
1807                                         "byte_copy_right = %u", byte_copy_right);
1808                 }
1809
1810                 while (n<length) {
1811
1812                         guint16 handle_now = length - n;
1813
1814                         if ( k < byte_copy_right && byte_copy_right <= k + (length-n) ){
1815                                 handle_now = byte_copy_right - k;
1816                         }
1817
1818                         if (k + handle_now >= UDVM_MEMORY_SIZE)
1819                                 goto decompression_failure;
1820                         result = crc16_ccitt_seed(&buff[k], handle_now, result ^ 0xffff);
1821
1822                         k = ( k + handle_now ) & 0xffff;
1823                         n = ( n + handle_now ) & 0xffff;
1824
1825                         if ( k >= byte_copy_right ) {
1826                                 k = byte_copy_left;
1827                         }
1828                 }
1829
1830                 result = result ^ 0xffff;
1831
1832                 if (print_level_1 ){
1833                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1, "Calculated CRC %u", result);
1834                 }
1835                 if (result != value){
1836                         current_address = at_address;
1837                 }
1838                 else {
1839                         current_address = next_operand_address;
1840                 }
1841                 goto execute_next_instruction;
1842                 break;
1843
1844
1845         case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */
1846                 if (show_instr_detail_level == 2 ){
1847                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1848                                 "Addr: %u ## INPUT-BYTES(28) length, destination, @address)",
1849                                 current_address);
1850                 }
1851                 operand_address = current_address + 1;
1852                 /* %length */
1853                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
1854                 if (show_instr_detail_level == 2 ){
1855                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
1856                                 operand_address, length);
1857                 }
1858                 operand_address = next_operand_address;
1859
1860                 /* %destination */
1861                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
1862                 if (show_instr_detail_level == 2 ){
1863                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Destination %u",
1864                                 operand_address, destination);
1865                 }
1866                 operand_address = next_operand_address;
1867
1868                 /* @address */
1869                  /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1870                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address);
1871                 at_address = ( current_address + at_address) & 0xffff;
1872                 if (show_instr_detail_level == 2 ){
1873                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
1874                                 operand_address, at_address);
1875                 }
1876                 if (show_instr_detail_level == 1)
1877                 {
1878                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1879                                 "Addr: %u ## INPUT-BYTES length=%u, destination=%u, @address=%u)",
1880                                 current_address, length, destination, at_address);
1881                 }
1882                 /* execute the instruction TODO insert checks 
1883                  * RFC 3320 :
1884                  *
1885                  *    0             7 8            15
1886                  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1887                  *   |        byte_copy_left         |  64 - 65
1888                  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1889                  *   |        byte_copy_right        |  66 - 67
1890                  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1891                  *   |        input_bit_order        |  68 - 69
1892                  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1893                  *   |        stack_location         |  70 - 71
1894                  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1895                  * 
1896                  * Figure 7: Memory addresses of the UDVM registers
1897                  * :
1898                  * 8.4.  Byte copying
1899                  * :
1900                  * The string of bytes is copied in ascending order of memory address,
1901                  * respecting the bounds set by byte_copy_left and byte_copy_right.
1902                  * More precisely, if a byte is copied from/to Address m then the next
1903                  * byte is copied from/to Address n where n is calculated as follows:
1904                  *
1905                  * Set k := m + 1 (modulo 2^16)
1906                  * If k = byte_copy_right then set n := byte_copy_left, else set n := k
1907                  *
1908                  */ 
1909
1910                 n = 0;
1911                 k = destination; 
1912                 byte_copy_right = buff[66] << 8;
1913                 byte_copy_right = byte_copy_right | buff[67];
1914                 byte_copy_left = buff[64] << 8;
1915                 byte_copy_left = byte_copy_left | buff[65];
1916                 if (print_level_1 ){
1917                         proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
1918                                         "               byte_copy_right = %u", byte_copy_right);
1919                 }
1920                 /* clear out remaining bits if any */
1921                 remaining_bits = 0;
1922                 input_bits=0;
1923                 /* operand_address used as dummy */
1924                 while ( n < length ){
1925                         if (input_address > ( msg_end - 1)){
1926                                 current_address = at_address;
1927                                 result_code = 14;
1928                                 goto execute_next_instruction;
1929                         }
1930
1931                         if ( k == byte_copy_right ){
1932                                 k = byte_copy_left;
1933                         }
1934                         octet = tvb_get_guint8(message_tvb, input_address);
1935                         buff[k] = octet;
1936                         if (print_level_1 ){
1937                                 proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
1938                                         "               Loading value: %u (0x%x) at Addr: %u", octet, octet, k);
1939                         }
1940                         input_address++;
1941                         /*
1942                          * If the instruction requests data that lies beyond the end of the
1943                          * SigComp message, no data is returned.  Instead the UDVM moves program
1944                          * execution to the address specified by the address operand.
1945                          */
1946
1947                         
1948                         k = ( k + 1 ) & 0xffff;
1949                         n++;
1950                 }
1951                 used_udvm_cycles = used_udvm_cycles + 1 + length;
1952                 current_address = next_operand_address;
1953                 goto execute_next_instruction;
1954                 break;
1955         case SIGCOMP_INSTR_INPUT_BITS:/* 29   INPUT-BITS (%length, %destination, @address) */
1956                 /*
1957                  * The length operand indicates the requested number of bits.
1958                  * Decompression failure occurs if this operand does not lie between 0
1959                  * and 16 inclusive.
1960                  * 
1961                  * The destination operand specifies the memory address to which the
1962                  * compressed data should be copied.  Note that the requested bits are
1963                  * interpreted as a 2-byte integer ranging from 0 to 2^length - 1, as
1964                  * explained in Section 8.2.
1965                  *
1966                  * If the instruction requests data that lies beyond the end of the
1967                  * SigComp message, no data is returned.  Instead the UDVM moves program
1968                  * execution to the address specified by the address operand.
1969                  */
1970
1971                 if (show_instr_detail_level == 2 ){
1972                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
1973                                 "Addr: %u ## INPUT-BITS(29) (length, destination, @address)",
1974                                 current_address);
1975                 }
1976                 operand_address = current_address + 1;
1977
1978                 /* %length */
1979                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
1980                 if (show_instr_detail_level == 2 ){
1981                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      length %u",
1982                                 operand_address, length);
1983                 }
1984                 operand_address = next_operand_address;
1985                 /* %destination */
1986                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
1987                 if (show_instr_detail_level == 2 ){
1988                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Destination %u",
1989                                 operand_address, destination);
1990                 }
1991                 operand_address = next_operand_address;
1992
1993                 /* @address */
1994                  /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1995                 next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
1996                 if (show_instr_detail_level == 2 ){
1997                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
1998                                 operand_address, at_address);
1999                 }
2000                 if (show_instr_detail_level == 1)
2001                 {
2002                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2003                                 "Addr: %u ## INPUT-BITS length=%u, destination=%u, @address=%u)",
2004                                 current_address, length, destination, at_address);
2005                 }
2006                 current_address = next_operand_address;
2007
2008                 /*
2009                  * Execute actual instr.
2010                  * The input_bit_order register contains the following three flags:
2011                  * 
2012                  *            0             7 8            15
2013                  *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2014                  *           |         reserved        |F|H|P|  68 - 69
2015                  *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2016                  */
2017                 input_bit_order = buff[68] << 8;
2018                 input_bit_order = input_bit_order | buff[69];
2019                 /*
2020                  * If the instruction requests data that lies beyond the end of the
2021                  * SigComp message, no data is returned.  Instead the UDVM moves program
2022                  * execution to the address specified by the address operand.
2023                  */
2024
2025                 if ( length > 16 ){
2026                         result_code = 7;
2027                         goto decompression_failure;
2028                 }
2029                 if ( input_bit_order > 7 ){
2030                         result_code = 8;
2031                         goto decompression_failure;
2032                 }
2033
2034                 /* 
2035                  * Transfer F bit to bit_order to tell decomp dispatcher which bit order to use 
2036                  */
2037                 bit_order = ( input_bit_order & 0x0004 ) >> 2;
2038                 value = decomp_dispatch_get_bits( message_tvb, udvm_tree, bit_order, 
2039                                 buff, &old_input_bit_order, &remaining_bits,
2040                                 &input_bits, &input_address, length, &result_code, msg_end);
2041                 if ( result_code == 11 ){
2042                         used_udvm_cycles = used_udvm_cycles + 1;
2043                         current_address = at_address;
2044                         goto execute_next_instruction;
2045                 }
2046                 msb = value >> 8;
2047                 lsb = value & 0x00ff;
2048                 if (destination >= UDVM_MEMORY_SIZE - 1)
2049                         goto decompression_failure;
2050                 buff[destination] = msb;
2051                 buff[destination + 1]=lsb;
2052                 if (print_level_1 ){
2053                         proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
2054                         "               Loading value: %u (0x%x) at Addr: %u, remaining_bits: %u", value, value, destination, remaining_bits);
2055                 }
2056
2057                 used_udvm_cycles = used_udvm_cycles + 1;
2058                 goto execute_next_instruction;
2059                 break;
2060         case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */
2061                 /*
2062                  * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1,
2063                  *  %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n,
2064                  *  %upper_bound_n, %uncompressed_n)
2065                  */
2066                 if (show_instr_detail_level == 2 ){
2067                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2068                                 "Addr: %u ## INPUT-HUFFMAN (destination, @address, #n, bits_1, lower_bound_1,upper_bound_1, uncompressed_1, ... , bits_n, lower_bound_n,upper_bound_n, uncompressed_n)",
2069                                 current_address);
2070                 }
2071                 operand_address = current_address + 1;
2072
2073                 /* %destination */
2074                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
2075                 if (show_instr_detail_level == 2 ){
2076                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Destination %u",
2077                                 operand_address, destination);
2078                 }
2079                 operand_address = next_operand_address;
2080
2081                 /* @address */
2082                  /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
2083                 next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
2084                 if (show_instr_detail_level == 2 ){
2085                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
2086                                 operand_address, at_address);
2087                 }
2088                 operand_address = next_operand_address;
2089
2090                 /* #n */
2091                 next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
2092                 if (show_instr_detail_level == 2 ){
2093                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      n %u",
2094                                 operand_address, n);
2095                 }
2096                 operand_address = next_operand_address; 
2097                 if (show_instr_detail_level == 1)
2098                 {
2099                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2100                                 "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)",
2101                                 current_address, destination, at_address, n, n, n, n, n);
2102                 }
2103
2104                 used_udvm_cycles = used_udvm_cycles + 1 + n;
2105
2106                 /*
2107                  * Note that if n = 0 then the INPUT-HUFFMAN instruction is ignored and
2108                  * program execution resumes at the following instruction.
2109                  * Decompression failure occurs if (bits_1 + ... + bits_n) > 16.
2110                  * 
2111                  * In all other cases, the behavior of the INPUT-HUFFMAN instruction is
2112                  * defined below:
2113                  * 
2114                  * 1. Set j := 1 and set H := 0.
2115                  * 
2116                  * 2. Request bits_j compressed bits.  Interpret the returned bits as an
2117                  * integer k from 0 to 2^bits_j - 1, as explained in Section 8.2.
2118                  * 
2119                  * 3. Set H := H * 2^bits_j + k.
2120                  * 
2121                  * 4. If data is requested that lies beyond the end of the SigComp
2122                  * message, terminate the INPUT-HUFFMAN instruction and move program
2123                  * execution to the memory address specified by the address operand.
2124                  * 
2125                  * 5. If (H < lower_bound_j) or (H > upper_bound_j) then set j := j + 1.
2126                  * Then go back to Step 2, unless j > n in which case decompression
2127                  * failure occurs.
2128                  * 
2129                  * 6. Copy (H + uncompressed_j - lower_bound_j) modulo 2^16 to the
2130                  * memory address specified by the destination operand.
2131                  * 
2132                  */
2133                 /*
2134                  * The input_bit_order register contains the following three flags:
2135                  * 
2136                  *            0             7 8            15
2137                  *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2138                  *           |         reserved        |F|H|P|  68 - 69
2139                  *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2140                  *
2141                  * Transfer H bit to bit_order to tell decomp dispatcher which bit order to use 
2142                  */
2143                 input_bit_order = buff[68] << 8;
2144                 input_bit_order = input_bit_order | buff[69];
2145                 bit_order = ( input_bit_order & 0x0002 ) >> 1;
2146
2147                 j = 1;
2148                 H = 0;
2149                 m = n;
2150                 outside_huffman_boundaries = TRUE;
2151                 print_in_loop = print_level_3;
2152                 while ( m > 0 ){
2153                         /* %bits_n */
2154                         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &bits_n);
2155                         if (print_in_loop ){
2156                                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      bits_n %u",
2157                                         operand_address, bits_n);
2158                         }
2159                         operand_address = next_operand_address; 
2160
2161                         /* %lower_bound_n */
2162                         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &lower_bound_n);
2163                         if (print_in_loop ){
2164                                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      lower_bound_n %u",
2165                                         operand_address, lower_bound_n);
2166                         }
2167                         operand_address = next_operand_address; 
2168                         /* %upper_bound_n */
2169                         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &upper_bound_n);
2170                         if (print_in_loop ){
2171                                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      upper_bound_n %u",
2172                                         operand_address, upper_bound_n);
2173                         }
2174                         operand_address = next_operand_address; 
2175                         /* %uncompressed_n */
2176                         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &uncompressed_n);
2177                         if (print_in_loop ){
2178                                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      uncompressed_n %u",
2179                                         operand_address, uncompressed_n);
2180                         }
2181                         operand_address = next_operand_address;
2182                         /* execute instruction */
2183                         if ( outside_huffman_boundaries ) {
2184                                 /*
2185                                  * 2. Request bits_j compressed bits.  Interpret the returned bits as an
2186                                  *    integer k from 0 to 2^bits_j - 1, as explained in Section 8.2.
2187                                  */
2188                                 k = decomp_dispatch_get_bits( message_tvb, udvm_tree, bit_order, 
2189                                                 buff, &old_input_bit_order, &remaining_bits,
2190                                                 &input_bits, &input_address, bits_n, &result_code, msg_end);
2191                                 if ( result_code == 11 ){
2192                                         /*
2193                                         * 4. If data is requested that lies beyond the end of the SigComp
2194                                         * message, terminate the INPUT-HUFFMAN instruction and move program
2195                                         * execution to the memory address specified by the address operand.
2196                                         */
2197                                         current_address = at_address;
2198                                         goto execute_next_instruction;
2199                                 }
2200
2201                                 /* 
2202                                  * 3. Set H := H * 2^bits_j + k.
2203                                  * [In practice is a shift+OR operation.]
2204                                  */
2205                                 oldH = H;
2206                                 H = (H << bits_n) | k;
2207                                 if (print_level_3 ){
2208                                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"               Set H(%u) := H(%u) * 2^bits_j(%u) + k(%u)",
2209                                                  H ,oldH, 1<<bits_n,k);
2210                                 }
2211
2212                                 /*
2213                                  * 5. If (H < lower_bound_j) or (H > upper_bound_j) then set j := j + 1.
2214                                  * Then go back to Step 2, unless j > n in which case decompression
2215                                  * failure occurs.
2216                                  */
2217                                 if ((H < lower_bound_n) || (H > upper_bound_n)){
2218                                         outside_huffman_boundaries = TRUE;
2219                                 }else{
2220                                         outside_huffman_boundaries = FALSE;
2221                                         print_in_loop = FALSE;
2222                                         /*
2223                                          * 6. Copy (H + uncompressed_j - lower_bound_j) modulo 2^16 to the
2224                                          * memory address specified by the destination operand.
2225                                          */
2226                                         if (print_level_2 ){
2227                                                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2228                                                         "               H(%u) = H(%u) + uncompressed_n(%u) - lower_bound_n(%u)",
2229                                                 (H + uncompressed_n - lower_bound_n ),H, uncompressed_n, lower_bound_n);
2230                                         }
2231                                         H = H + uncompressed_n - lower_bound_n;
2232                                         msb = H >> 8;
2233                                         lsb = H & 0x00ff;
2234                                         if (destination >= UDVM_MEMORY_SIZE - 1)
2235                                                 goto decompression_failure;
2236                                         buff[destination] = msb;
2237                                         buff[destination + 1]=lsb;
2238                                         if (print_level_1 ){
2239                                                 proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
2240                                         "               Loading H: %u (0x%x) at Addr: %u,j = %u remaining_bits: %u", 
2241                                                 H, H, destination,( n - m + 1 ), remaining_bits);
2242                                         }
2243                                         
2244                                 }
2245
2246
2247                         }
2248                         m = m - 1;
2249                 }
2250                 if ( outside_huffman_boundaries ) {
2251                         result_code = 10;
2252                         goto decompression_failure;
2253                 }
2254
2255                 current_address = next_operand_address;
2256                 goto execute_next_instruction;
2257                 break;
2258
2259         case SIGCOMP_INSTR_STATE_ACCESS: /* 31 */
2260                 /*   STATE-ACCESS (%partial_identifier_start, %partial_identifier_length,
2261                  * %state_begin, %state_length, %state_address, %state_instruction)
2262                  */
2263                 if (show_instr_detail_level == 2 ){
2264                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2265                                 "Addr: %u ## STATE-ACCESS(31) (partial_identifier_start, partial_identifier_length,state_begin, state_length, state_address, state_instruction)",
2266                                 current_address);
2267                 }
2268                 operand_address = current_address + 1;
2269
2270                 /* 
2271                  * %partial_identifier_start
2272                  */
2273                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_start);
2274                 if (show_instr_detail_level == 2 ){
2275                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       partial_identifier_start %u",
2276                                 operand_address, p_id_start);
2277                 }
2278                 operand_address = next_operand_address;
2279
2280                 /*
2281                  * %partial_identifier_length
2282                  */
2283                 operand_address = next_operand_address;
2284                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_length);
2285                 if (show_instr_detail_level == 2 ){
2286                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       partial_identifier_length %u",
2287                                 operand_address, p_id_length);
2288                 }
2289                 /*
2290                  * %state_begin
2291                  */
2292                 operand_address = next_operand_address;
2293                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_begin);
2294                 if (show_instr_detail_level == 2 ){
2295                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_begin %u",
2296                                 operand_address, state_begin);
2297                 }
2298                 /*
2299                  * %state_length
2300                  */
2301                 operand_address = next_operand_address;
2302                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
2303                 if (show_instr_detail_level == 2 ){
2304                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_length %u",
2305                                 operand_address, state_length);
2306                 }
2307                 /*
2308                  * %state_address
2309                  */
2310                 operand_address = next_operand_address;
2311                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
2312                 if (show_instr_detail_level == 2 ){
2313                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_address %u",
2314                                 operand_address, state_address);
2315                 }
2316                 /*
2317                  * %state_instruction
2318                  */
2319                 operand_address = next_operand_address;
2320                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
2321                 if (show_instr_detail_level == 2 ){
2322                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_instruction %u",
2323                                 operand_address, state_instruction);
2324                 }
2325                 if (show_instr_detail_level == 1)
2326                 {
2327                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2328                                 "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)",
2329                                 current_address, p_id_start, p_id_length, state_begin, state_length, state_address, state_instruction);
2330                 }
2331                 current_address = next_operand_address;
2332                 byte_copy_right = buff[66] << 8;
2333                 byte_copy_right = byte_copy_right | buff[67];
2334                 byte_copy_left = buff[64] << 8;
2335                 byte_copy_left = byte_copy_left | buff[65];
2336                 if (print_level_2 ){
2337                         proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
2338                                         "               byte_copy_right = %u, byte_copy_left = %u", byte_copy_right,byte_copy_left);
2339                 }
2340
2341                 result_code = udvm_state_access(message_tvb, udvm_tree, buff, p_id_start, p_id_length, state_begin, &state_length, 
2342                         &state_address, &state_instruction, hf_id);
2343                 if ( result_code != 0 ){
2344                         goto decompression_failure; 
2345                 }
2346                 used_udvm_cycles = used_udvm_cycles + 1 + state_length;
2347                 goto execute_next_instruction;
2348                 break;
2349         case SIGCOMP_INSTR_STATE_CREATE: /* 32 */
2350                 /*
2351                  * STATE-CREATE (%state_length, %state_address, %state_instruction,
2352                  * %minimum_access_length, %state_retention_priority)
2353                  */
2354                 if (show_instr_detail_level == 2 ){
2355                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2356                                 "Addr: %u ## STATE-CREATE(32) (state_length, state_address, state_instruction,minimum_access_length, state_retention_priority)",
2357                                 current_address);
2358                 }
2359                 operand_address = current_address + 1;
2360
2361                 /*
2362                  * %state_length
2363                  */
2364                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
2365                 if (show_instr_detail_level == 2 ){
2366                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_length %u",
2367                                 operand_address, state_length);
2368                 }
2369                 /*
2370                  * %state_address
2371                  */
2372                 operand_address = next_operand_address;
2373                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
2374                 if (show_instr_detail_level == 2 ){
2375                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_address %u",
2376                                 operand_address, state_address);
2377                 }
2378                 /*
2379                  * %state_instruction
2380                  */
2381                 operand_address = next_operand_address;
2382                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
2383                 if (show_instr_detail_level == 2 ){
2384                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_instruction %u",
2385                                 operand_address, state_instruction);
2386                 }
2387                 operand_address = next_operand_address;
2388                 /*
2389                  * %minimum_access_length
2390                  */
2391                 operand_address = next_operand_address;
2392                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &minimum_access_length);
2393                 if (show_instr_detail_level == 2 ){
2394                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       minimum_access_length %u",
2395                                 operand_address, minimum_access_length);
2396                 }
2397                 operand_address = next_operand_address;
2398                 /*
2399                  * %state_retention_priority
2400                  */
2401                 operand_address = next_operand_address;
2402                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_retention_priority);
2403                 if (show_instr_detail_level == 2 ){
2404                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_retention_priority %u",
2405                                 operand_address, state_retention_priority);
2406                 }
2407                 if (show_instr_detail_level == 1)
2408                 {
2409                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2410                                 "Addr: %u ## STATE-CREATE(32) (state_length=%u, state_address=%u, state_instruction=%u,minimum_access_length=%u, state_retention_priority=%u)",
2411                                 current_address, state_length, state_address, state_instruction,minimum_access_length, state_retention_priority);
2412                 }
2413                 current_address = next_operand_address;
2414                 /* Execute the instruction
2415                  * TODO Implement the instruction
2416                  * RFC3320:
2417                  *    Note that the new state item cannot be created until a valid
2418                  *    compartment identifier has been returned by the application.
2419                  *    Consequently, when a STATE-CREATE instruction is encountered the UDVM
2420                  *    simply buffers the five supplied operands until the END-MESSAGE
2421                  *    instruction is reached.  The steps taken at this point are described
2422                  *    in Section 9.4.9.
2423                  *
2424                  *   Decompression failure MUST occur if more than four state creation
2425                  *   requests are made before the END-MESSAGE instruction is encountered.
2426                  *   Decompression failure also occurs if the minimum_access_length does
2427                  *   not lie between 6 and 20 inclusive, or if the
2428                  *   state_retention_priority is 65535.
2429                  */
2430                 no_of_state_create++;
2431                 if ( no_of_state_create > 4 ){
2432                         result_code = 12;
2433                         goto decompression_failure; 
2434                 }
2435                 if (( minimum_access_length < 6 ) || ( minimum_access_length > STATE_BUFFER_SIZE )){
2436                         result_code = 1;
2437                         goto decompression_failure; 
2438                 }
2439                 if ( state_retention_priority == 65535 ){
2440                         result_code = 13;
2441                         goto decompression_failure; 
2442                 }
2443                 state_length_buff[no_of_state_create] = state_length;
2444                 state_address_buff[no_of_state_create] = state_address;
2445                 state_instruction_buff[no_of_state_create] = state_instruction;
2446                 state_minimum_access_length_buff[no_of_state_create] = minimum_access_length;
2447                 state_state_retention_priority_buff[no_of_state_create] = state_retention_priority;
2448                 used_udvm_cycles = used_udvm_cycles + 1 + state_length;
2449                 /* Debug */
2450                 byte_copy_right = buff[66] << 8;
2451                 byte_copy_right = byte_copy_right | buff[67];
2452                 byte_copy_left = buff[64] << 8;
2453                 byte_copy_left = byte_copy_left | buff[65];
2454                 n = 0;
2455                 k = state_address;
2456                 while ( n < state_length ){
2457                         if ( k == byte_copy_right ){
2458                                 k = byte_copy_left;
2459                         }
2460                         string[0]= buff[k];
2461                         string[1]= '\0';
2462                         if (print_level_3 ){
2463                                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2464                                         "               Addr: %5u State value: %u (0x%x) ASCII(%s)",
2465                                         k,buff[k],buff[k],format_text(string, 1));
2466                         }
2467                         k = ( k + 1 ) & 0xffff;
2468                         n++;
2469                 }
2470                 /* End debug */
2471
2472                 goto execute_next_instruction;
2473                 break;
2474         case SIGCOMP_INSTR_STATE_FREE: /* 33 */
2475                 /*
2476                  * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
2477                  */
2478                 if (show_instr_detail_level == 2 ){
2479                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2480                                 "Addr: %u ## STATE-FREE (partial_identifier_start, partial_identifier_length)",
2481                                 current_address);
2482                 }
2483                 operand_address = current_address + 1;
2484                 /* 
2485                  * %partial_identifier_start
2486                  */
2487                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_start);
2488                 if (show_instr_detail_level == 2 ){
2489                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       partial_identifier_start %u",
2490                                 operand_address, p_id_start);
2491                 }
2492                 operand_address = next_operand_address;
2493
2494                 /*
2495                  * %partial_identifier_length
2496                  */
2497                 operand_address = next_operand_address;
2498                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_length);
2499                 if (show_instr_detail_level == 2 ){
2500                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       partial_identifier_length %u",
2501                                 operand_address, p_id_length);
2502                 }
2503                 if (show_instr_detail_level == 1)
2504                 {
2505                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2506                                 "Addr: %u ## STATE-FREE (partial_identifier_start=%u, partial_identifier_length=%u)",
2507                                 current_address, p_id_start, p_id_length);
2508                 }
2509                 current_address = next_operand_address;
2510
2511                 /* Execute the instruction:
2512                  * TODO implement it
2513                  */
2514                 udvm_state_free(buff,p_id_start,p_id_length);
2515                 used_udvm_cycles++;
2516
2517                 goto execute_next_instruction;
2518                 break;
2519         case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */
2520                 if (show_instr_detail_level == 2 ){
2521                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2522                                 "Addr: %u ## OUTPUT(34) (output_start, output_length)",
2523                                 current_address);
2524                 }
2525                 operand_address = current_address + 1;
2526                 /* 
2527                  * %output_start
2528                  */
2529                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &output_start);
2530                 if (show_instr_detail_level == 2 ){
2531                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      output_start %u",
2532                                 operand_address, output_start);
2533                 }
2534                 operand_address = next_operand_address;
2535                 /* 
2536                  * %output_length
2537                  */
2538                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &output_length);
2539                 if (show_instr_detail_level == 2 ){
2540                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      output_length %u",
2541                                 operand_address, output_length);
2542                 }
2543                 if (show_instr_detail_level == 1)
2544                 {
2545                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2546                                 "Addr: %u ## OUTPUT (output_start=%u, output_length=%u)",
2547                                 current_address, output_start, output_length);
2548                 }
2549                 current_address = next_operand_address;
2550
2551                 /* 
2552                  * Execute instruction 
2553                  * 8.4.  Byte copying
2554                  * :
2555                  * The string of bytes is copied in ascending order of memory address,
2556                  * respecting the bounds set by byte_copy_left and byte_copy_right.
2557                  * More precisely, if a byte is copied from/to Address m then the next
2558                  * byte is copied from/to Address n where n is calculated as follows:
2559                  *
2560                  * Set k := m + 1 (modulo 2^16)
2561                  * If k = byte_copy_right then set n := byte_copy_left, else set n := k
2562                  *
2563                  */ 
2564
2565                 n = 0;
2566                 k = output_start; 
2567                 byte_copy_right = buff[66] << 8;
2568                 byte_copy_right = byte_copy_right | buff[67];
2569                 byte_copy_left = buff[64] << 8;
2570                 byte_copy_left = byte_copy_left | buff[65];
2571                 if (print_level_3 ){
2572                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2573                                         "               byte_copy_right = %u", byte_copy_right);
2574                 }
2575                 while ( n < output_length ){
2576
2577                         if ( k == byte_copy_right ){
2578                                 k = byte_copy_left;
2579                         }
2580                         out_buff[output_address] = buff[k];
2581                         string[0]= buff[k];
2582                         string[1]= '\0';
2583                         if (print_level_3 ){
2584                                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2585                                         "               Output value: %u (0x%x) ASCII(%s) from Addr: %u ,output to dispatcher position %u",
2586                                         buff[k],buff[k],format_text(string,1), k,output_address);
2587                         }
2588                         k = ( k + 1 ) & 0xffff;
2589                         output_address ++;
2590                         n++;
2591                 }
2592                 used_udvm_cycles = used_udvm_cycles + 1 + output_length;
2593                 goto execute_next_instruction;
2594                 break;
2595         case SIGCOMP_INSTR_END_MESSAGE: /* 35 */
2596                 /*
2597                  * END-MESSAGE (%requested_feedback_location,
2598                  * %returned_parameters_location, %state_length, %state_address,
2599                  * %state_instruction, %minimum_access_length,
2600                  * %state_retention_priority)
2601                  */
2602                 if (show_instr_detail_level == 2 ){
2603                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2604                                 "Addr: %u ## END-MESSAGE (requested_feedback_location,state_instruction, minimum_access_length,state_retention_priority)",
2605                                 current_address);
2606                 }
2607                 operand_address = current_address + 1;
2608
2609                 /* %requested_feedback_location */
2610                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &requested_feedback_location);
2611                 if (show_instr_detail_level == 2 ){
2612                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      requested_feedback_location %u",
2613                                 operand_address, requested_feedback_location);
2614                 }
2615                 operand_address = next_operand_address;
2616                 /* returned_parameters_location */
2617                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &returned_parameters_location);
2618                 if (show_instr_detail_level == 2 ){
2619                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      returned_parameters_location %u",
2620                                 operand_address, returned_parameters_location);
2621                 }
2622                 operand_address = next_operand_address;
2623                 /*
2624                  * %state_length
2625                  */
2626                 operand_address = next_operand_address;
2627                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
2628                 if (show_instr_detail_level == 2 ){
2629                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      state_length %u",
2630                                 operand_address, state_length);
2631                 }
2632                 /*
2633                  * %state_address
2634                  */
2635                 operand_address = next_operand_address;
2636                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
2637                 if (show_instr_detail_level == 2 ){
2638                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      state_address %u",
2639                                 operand_address, state_address);
2640                 }
2641                 /*
2642                  * %state_instruction
2643                  */
2644                 operand_address = next_operand_address;
2645                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
2646                 if (show_instr_detail_level == 2 ){
2647                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      state_instruction %u",
2648                                 operand_address, state_instruction);
2649                 }
2650
2651                 /*
2652                  * %minimum_access_length
2653                  */
2654                 operand_address = next_operand_address;
2655                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &minimum_access_length);
2656                 if (show_instr_detail_level == 2 ){
2657                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      minimum_access_length %u",
2658                                 operand_address, minimum_access_length);
2659                 }
2660
2661                 /*
2662                  * %state_retention_priority
2663                  */
2664                 operand_address = next_operand_address;
2665                 next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_retention_priority);
2666                 if (show_instr_detail_level == 2 ){
2667                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      state_retention_priority %u",
2668                                 operand_address, state_retention_priority);
2669                 }
2670                 if (show_instr_detail_level == 1)
2671                 {
2672                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
2673                                 "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)",
2674                                 current_address, requested_feedback_location, returned_parameters_location, state_length, state_address, state_instruction, minimum_access_length,state_retention_priority);
2675                 }
2676                 current_address = next_operand_address;
2677                 /* TODO: This isn't currently totaly correct as END_INSTRUCTION might not create state */
2678                 no_of_state_create++;
2679                 if ( no_of_state_create > 4 ){
2680                         result_code = 12;
2681                         goto decompression_failure; 
2682                 }
2683                 state_length_buff[no_of_state_create] = state_length;
2684                 state_address_buff[no_of_state_create] = state_address;
2685                 state_instruction_buff[no_of_state_create] = state_instruction;
2686                 /* Not used ? */
2687                 state_minimum_access_length_buff[no_of_state_create] = minimum_access_length;
2688                 state_state_retention_priority_buff[no_of_state_create] = state_retention_priority;
2689                 
2690                 /* Execute the instruction
2691                  */
2692                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"no_of_state_create %u",no_of_state_create);
2693                 if ( no_of_state_create != 0 ){
2694                         memset(sha1_digest_buf, 0, STATE_BUFFER_SIZE);
2695                         n = 1;
2696                         byte_copy_right = buff[66] << 8;
2697                         byte_copy_right = byte_copy_right | buff[67];
2698                         byte_copy_left = buff[64] << 8;
2699                         byte_copy_left = byte_copy_left | buff[65];
2700                         while ( n < no_of_state_create + 1 ){
2701                                 sha1buff = g_malloc(state_length_buff[n]+8);
2702                                 sha1buff[0] = state_length_buff[n] >> 8;
2703                                 sha1buff[1] = state_length_buff[n] & 0xff;
2704                                 sha1buff[2] = state_address_buff[n] >> 8;
2705                                 sha1buff[3] = state_address_buff[n] & 0xff;
2706                                 sha1buff[4] = state_instruction_buff[n] >> 8;
2707                                 sha1buff[5] = state_instruction_buff[n] & 0xff; 
2708                                 sha1buff[6] = state_minimum_access_length_buff[n] >> 8;
2709                                 sha1buff[7] = state_minimum_access_length_buff[n] & 0xff;
2710                                 if (print_level_3 ){
2711                                         for( x=0; x < 8; x++){
2712                                                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"sha1buff %u 0x%x",
2713                                                         x,sha1buff[x]);
2714                                         }
2715                                 }
2716                                 k = state_address_buff[n];
2717                                 for( x=0; x < state_length_buff[n]; x++)
2718                                         {
2719                                         if ( k == byte_copy_right ){
2720                                                 k = byte_copy_left;
2721                                         }
2722                                         sha1buff[8+x] = buff[k];
2723                                         k = ( k + 1 ) & 0xffff;
2724                                         }
2725
2726                                 sha1_starts( &ctx );
2727                                 sha1_update( &ctx, (guint8 *) sha1buff, state_length_buff[n] + 8);
2728                                 sha1_finish( &ctx, sha1_digest_buf );
2729                                 if (print_level_3 ){
2730                                         proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"SHA1 digest %s",bytes_to_str(sha1_digest_buf, STATE_BUFFER_SIZE));
2731
2732                                 }
2733                                 udvm_state_create(sha1buff, sha1_digest_buf, state_minimum_access_length_buff[n]);
2734                                 proto_tree_add_text(udvm_tree,bytecode_tvb, 0, -1,"### Creating state ###");
2735                                 proto_tree_add_string(udvm_tree,hf_id, bytecode_tvb, 0, 0, bytes_to_str(sha1_digest_buf, state_minimum_access_length_buff[n]));
2736
2737                                 n++;
2738
2739                         }
2740                 }
2741
2742
2743
2744                 /* At least something got decompressed, show it */
2745                 decomp_tvb = tvb_new_real_data(out_buff,output_address,output_address);
2746                 /* Arrange that the allocated packet data copy be freed when the
2747                  * tvbuff is freed. 
2748                  */
2749                 tvb_set_free_cb( decomp_tvb, g_free );
2750
2751                 tvb_set_child_real_data_tvbuff(message_tvb,decomp_tvb);
2752                 add_new_data_source(pinfo, decomp_tvb, "Decompressed SigComp message");
2753                 /*
2754                 proto_tree_add_text(udvm_tree, decomp_tvb, 0, -1,"SigComp message Decompressed");
2755                 */      
2756                 used_udvm_cycles = used_udvm_cycles + 1 + state_length;
2757                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"maximum_UDVM_cycles %u used_udvm_cycles %u",
2758                         maximum_UDVM_cycles, used_udvm_cycles);
2759                 return decomp_tvb;
2760                 break;
2761
2762         default:
2763             proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1," ### Addr %u Invalid instruction: %u (0x%x)",
2764                         current_address,current_instruction,current_instruction);
2765                 break;
2766                 }
2767                 g_free(out_buff);
2768                 return NULL;
2769 decompression_failure:
2770                 
2771                 proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"DECOMPRESSION FAILURE: %s",
2772                                     val_to_str(result_code, result_code_vals,"Unknown (%u)"));
2773                 THROW(ReportedBoundsError);
2774                 g_free(out_buff);
2775                 return NULL;
2776
2777 }
2778         
2779  /*  The simplest operand type is the literal (#), which encodes a
2780   * constant integer from 0 to 65535 inclusive.  A literal operand may
2781   * require between 1 and 3 bytes depending on its value.
2782   * Bytecode:                       Operand value:      Range:
2783   * 0nnnnnnn                        N                   0 - 127
2784   * 10nnnnnn nnnnnnnn               N                   0 - 16383
2785   * 11000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
2786   *
2787   *            Figure 8: Bytecode for a literal (#) operand
2788   *
2789   */
2790 static int
2791 decode_udvm_literal_operand(guint8 *buff,guint operand_address, guint16 *value) 
2792 {
2793         guint   bytecode;
2794         guint16 operand;
2795         guint   test_bits;
2796         guint   offset = operand_address;
2797         guint8  temp_data;
2798
2799         bytecode = buff[operand_address];
2800         test_bits = bytecode >> 7;
2801         if (test_bits == 1){
2802                 test_bits = bytecode >> 6;
2803                 if (test_bits == 2){
2804                         /*
2805                          * 10nnnnnn nnnnnnnn               N                   0 - 16383
2806                          */
2807                         temp_data = buff[operand_address] & 0x1f;
2808                         operand = temp_data << 8;
2809                         temp_data = buff[operand_address + 1];
2810                         operand = operand | temp_data;
2811                         *value = operand;
2812                         offset = offset + 2;
2813
2814                 }else{
2815                         /*
2816                          * 111000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
2817                          */
2818                         offset ++;
2819                         temp_data = buff[operand_address] & 0x1f;
2820                         operand = temp_data << 8;
2821                         temp_data = buff[operand_address + 1];
2822                         operand = operand | temp_data;
2823                         *value = operand;
2824                         offset = offset + 2;
2825
2826                 }
2827         }else{
2828                 /*
2829                  * 0nnnnnnn                        N                   0 - 127
2830                  */
2831                 operand = ( bytecode & 0x7f);
2832                 *value = operand;
2833                 offset ++;
2834         }
2835
2836         return offset;
2837
2838 }
2839
2840 /*
2841  * The second operand type is the reference ($), which is always used to
2842  * access a 2-byte value located elsewhere in the UDVM memory.  The
2843  * bytecode for a reference operand is decoded to be a constant integer
2844  * from 0 to 65535 inclusive, which is interpreted as the memory address
2845  * containing the actual value of the operand.
2846  * Bytecode:                       Operand value:      Range:
2847  *
2848  * 0nnnnnnn                        memory[2 * N]       0 - 65535
2849  * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
2850  * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
2851  *
2852  *            Figure 9: Bytecode for a reference ($) operand
2853  */
2854 static int
2855 dissect_udvm_reference_operand(guint8 *buff,guint operand_address, guint16 *value,guint *result_dest) 
2856 {
2857         guint bytecode;
2858         guint16 operand;
2859         guint   offset = operand_address;
2860         guint test_bits;
2861         guint8  temp_data;
2862         guint16 temp_data16;
2863
2864         bytecode = buff[operand_address];
2865         test_bits = bytecode >> 7;
2866         if (test_bits == 1){
2867                 test_bits = bytecode >> 6;
2868                 if (test_bits == 2){
2869                         /*
2870                          * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
2871                          */
2872                         temp_data = buff[operand_address] & 0x3f;
2873                         operand = temp_data << 8;
2874                         temp_data = buff[operand_address + 1];
2875                         operand = operand | temp_data;
2876                         operand = (operand * 2);
2877                         *result_dest = operand;
2878                         temp_data16 = buff[operand] << 8;
2879                         temp_data16 = temp_data16 | buff[operand+1];
2880                         *value = temp_data16;
2881                         offset = offset + 2;
2882
2883                 }else{
2884                         /*
2885                          * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
2886                          */
2887                         operand_address++;
2888                         operand = buff[operand_address] << 8;
2889                         operand = operand | buff[operand_address + 1];
2890                         *result_dest = operand;
2891                         temp_data16 = buff[operand] << 8;
2892                         temp_data16 = temp_data16 | buff[operand+1];
2893                         *value = temp_data16;
2894                         offset = offset + 3;
2895
2896                 }
2897         }else{
2898                 /*
2899                  * 0nnnnnnn                        memory[2 * N]       0 - 65535
2900                  */
2901                 operand = ( bytecode & 0x7f);
2902                 operand = (operand * 2);
2903                 *result_dest = operand;
2904                 temp_data16 = buff[operand] << 8;
2905                 temp_data16 = temp_data16 | buff[operand+1];
2906                 *value = temp_data16;
2907                 offset ++;
2908         }
2909
2910         if (offset >= UDVM_MEMORY_SIZE || *result_dest >= UDVM_MEMORY_SIZE - 1 )
2911                 THROW(ReportedBoundsError);
2912
2913         return offset;
2914 }
2915
2916         /* RFC3320
2917          * Figure 10: Bytecode for a multitype (%) operand
2918          * Bytecode:                       Operand value:      Range:               HEX val
2919          * 00nnnnnn                        N                   0 - 63                           0x00
2920          * 01nnnnnn                        memory[2 * N]       0 - 65535                        0x40
2921          * 1000011n                        2 ^ (N + 6)        64 , 128                          0x86    
2922          * 10001nnn                        2 ^ (N + 8)    256 , ... , 32768                     0x88
2923          * 111nnnnn                        N + 65504       65504 - 65535                        0xe0
2924          * 1001nnnn nnnnnnnn               N + 61440       61440 - 65535                        0x90
2925          * 101nnnnn nnnnnnnn               N                   0 - 8191                         0xa0
2926          * 110nnnnn nnnnnnnn               memory[N]           0 - 65535                        0xc0
2927          * 10000000 nnnnnnnn nnnnnnnn      N                   0 - 65535                        0x80
2928          * 10000001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535                        0x81
2929          */
2930 static int
2931 decode_udvm_multitype_operand(guint8 *buff,guint operand_address, guint16 *value)
2932 {
2933         guint test_bits;
2934         guint bytecode;
2935         guint offset = operand_address;
2936         guint16 operand;
2937         guint32 result;
2938         guint8 temp_data;
2939         guint16 temp_data16;
2940         guint16 memmory_addr = 0;
2941
2942         bytecode = buff[operand_address];
2943         test_bits = ( bytecode & 0xc0 ) >> 6;
2944         switch (test_bits ){
2945         case 0:
2946                 /*  
2947                  * 00nnnnnn                        N                   0 - 63
2948                  */
2949                 operand =  buff[operand_address];
2950                 /* debug
2951                  *g_warning("Reading 0x%x From address %u",operand,offset);
2952                  */
2953                 *value = operand;
2954                 offset ++;
2955                 break;
2956         case 1:
2957                 /*  
2958                  * 01nnnnnn                        memory[2 * N]       0 - 65535
2959                  */
2960                 memmory_addr = ( bytecode & 0x3f) * 2;
2961                 temp_data16 = buff[memmory_addr] << 8;
2962                 temp_data16 = temp_data16 | buff[memmory_addr+1];
2963                 *value = temp_data16;
2964                 offset ++;
2965                 break;
2966         case 2:
2967                 /* Check tree most significant bits */
2968                 test_bits = ( bytecode & 0xe0 ) >> 5;
2969                 if ( test_bits == 5 ){
2970                 /*
2971                  * 101nnnnn nnnnnnnn               N                   0 - 8191
2972                  */
2973                         temp_data = buff[operand_address] & 0x1f;
2974                         operand = temp_data << 8;
2975                         temp_data = buff[operand_address + 1];
2976                         operand = operand | temp_data;
2977                         *value = operand;
2978                         offset = offset + 2;
2979                 }else{
2980                         test_bits = ( bytecode & 0xf0 ) >> 4;
2981                         if ( test_bits == 9 ){
2982                 /*
2983                  * 1001nnnn nnnnnnnn               N + 61440       61440 - 65535
2984                  */
2985                                 temp_data = buff[operand_address] & 0x0f;
2986                                 operand = temp_data << 8;
2987                                 temp_data = buff[operand_address + 1];
2988                                 operand = operand | temp_data;
2989                                 operand = operand + 61440;
2990                                 *value = operand;
2991                                 offset = offset + 2;
2992                         }else{
2993                                 test_bits = ( bytecode & 0x08 ) >> 3;
2994                                 if ( test_bits == 1){
2995                 /*
2996                  * 10001nnn                        2 ^ (N + 8)    256 , ... , 32768
2997                  */
2998
2999                                         result = 1 << ((buff[operand_address] & 0x07) + 8);
3000                                         operand = result & 0xffff;
3001                                         *value = operand;
3002                                         offset ++;
3003                                 }else{
3004                                         test_bits = ( bytecode & 0x0e ) >> 1;
3005                                         if ( test_bits == 3 ){
3006                                                 /*
3007                                                  * 1000 011n                        2 ^ (N + 6)        64 , 128
3008                                                  */
3009                                                 result = 1 << ((buff[operand_address] & 0x01) + 6);
3010                                                 operand = result & 0xffff;
3011                                                 *value = operand;
3012                                                 offset ++;
3013                                         }else{
3014                                         /*
3015                                          * 1000 0000 nnnnnnnn nnnnnnnn      N                   0 - 65535
3016                                          * 1000 0001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
3017                                          */
3018                                                 offset ++;
3019                                                 temp_data16 = buff[operand_address + 1] << 8;
3020                                                 temp_data16 = temp_data16 | buff[operand_address + 2];
3021                                                 /*  debug
3022                                                  * g_warning("Reading 0x%x From address %u",temp_data16,operand_address);
3023                                                  */
3024                                                 if ( (bytecode & 0x01) == 1 ){
3025                                                         memmory_addr = temp_data16;
3026                                                         temp_data16 = buff[memmory_addr] << 8;
3027                                                         temp_data16 = temp_data16 | buff[memmory_addr+1];
3028                                                 }
3029                                                 *value = temp_data16;
3030                                                 offset = offset +2;
3031                                         }
3032
3033
3034                                 }
3035                         }
3036                 }
3037                 break;
3038
3039         case 3:
3040                 test_bits = ( bytecode & 0x20 ) >> 5;
3041                 if ( test_bits == 1 ){
3042                 /*
3043                  * 111nnnnn                        N + 65504       65504 - 65535
3044                  */
3045                         operand = ( buff[operand_address] & 0x1f) + 65504;
3046                         *value = operand;
3047                         offset ++;
3048                 }else{
3049                 /*
3050                  * 110nnnnn nnnnnnnn               memory[N]           0 - 65535
3051                  */
3052                         memmory_addr = buff[operand_address] & 0x1f;
3053                         memmory_addr = memmory_addr << 8;
3054                         memmory_addr = memmory_addr | buff[operand_address + 1];
3055                         temp_data16 = buff[memmory_addr] << 8;
3056                         temp_data16 = temp_data16 | buff[memmory_addr+1];
3057                         *value = temp_data16;
3058                         /*  debug 
3059                          * g_warning("Reading 0x%x From address %u",temp_data16,memmory_addr);
3060                          */
3061                         offset = offset +2;
3062                 }
3063                         
3064         default :
3065                 break;
3066         }
3067         return offset;
3068 }
3069         /*
3070          *
3071          * The fourth operand type is the address (@).  This operand is decoded
3072          * as a multitype operand followed by a further step: the memory address
3073          * of the UDVM instruction containing the address operand is added to
3074          * obtain the correct operand value.  So if the operand value from
3075          * Figure 10 is D then the actual operand value of an address is
3076          * calculated as follows:
3077          *
3078          * operand_value = (memory_address_of_instruction + D) modulo 2^16
3079          *
3080          * Address operands are always used in instructions that control program
3081          * flow, because they ensure that the UDVM bytecode is position-
3082          * independent code (i.e., it will run independently of where it is
3083          * placed in the UDVM memory).
3084          */
3085 static int
3086 decode_udvm_address_operand(guint8 *buff,guint operand_address, guint16 *value,guint current_address)
3087 {
3088         guint32 result;
3089         guint16 value1;
3090         guint next_opreand_address;
3091
3092         next_opreand_address = decode_udvm_multitype_operand(buff, operand_address, &value1);
3093         result = value1 & 0xffff;
3094         result = result + current_address;
3095         *value = result & 0xffff;
3096         return next_opreand_address;
3097 }
3098
3099
3100 /*
3101  * This is a lookup table used to reverse the bits in a byte.
3102  */
3103 static guint8 reverse [] = {
3104     0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
3105     0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
3106     0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
3107     0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
3108     0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
3109     0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
3110     0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
3111     0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
3112     0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
3113     0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
3114     0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
3115     0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
3116     0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
3117     0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
3118     0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
3119     0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
3120     0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
3121     0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
3122     0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
3123     0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
3124     0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
3125     0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
3126     0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
3127     0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
3128     0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
3129     0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
3130     0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
3131     0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
3132     0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
3133     0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
3134     0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
3135     0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
3136 };
3137
3138
3139 static int
3140 decomp_dispatch_get_bits(
3141                 tvbuff_t *message_tvb,
3142                 proto_tree *udvm_tree,
3143                 guint8 bit_order, 
3144                 guint8 *buff,
3145                 guint16 *old_input_bit_order, 
3146                 guint16 *remaining_bits,
3147                 guint16 *input_bits, 
3148                 guint *input_address, 
3149                 guint16 length, 
3150                 guint16 *result_code,
3151                 guint msg_end)
3152 {
3153         guint16 input_bit_order;
3154         guint16 bits_still_required = length;
3155         guint16 value = 0;
3156         guint8  octet;
3157         gint    extra_bytes_available = msg_end - *input_address;
3158         gint    p_bit;
3159         gint    prev_p_bit = *old_input_bit_order & 0x0001;
3160         gint    bits_to_use = 0;
3161
3162
3163         input_bit_order = buff[68] << 8;
3164         input_bit_order = input_bit_order | buff[69];
3165         *result_code = 0;
3166         p_bit = (input_bit_order & 0x0001) != 0;
3167
3168         /*
3169          * Discard any spare bits.
3170          * Note: We take care to avoid remaining_bits having the value of 8.
3171          */
3172         if (prev_p_bit != p_bit)
3173         {
3174                 *remaining_bits = 0;
3175                 *old_input_bit_order = input_bit_order;
3176         }
3177
3178         /*
3179          * Check we can suppy the required number of bits now, before we alter
3180          * the input buffer's state.
3181          */
3182         if (*remaining_bits + extra_bytes_available * 8 < length)
3183         {
3184                 *result_code = 11;
3185                 return 0xfbad;
3186         }
3187
3188         /* Note: This is never called with length > 16, so the following loop 
3189         *       never loops more than three time. */
3190         while (bits_still_required > 0)
3191         {
3192                 /* 
3193                  * We only put anything into input_bits if we know we will remove
3194                  * at least one bit. That ensures we can simply discard the spare
3195                  * bits if the P-bit changes.
3196                  */
3197                 if (*remaining_bits == 0)
3198                 {
3199                         octet = tvb_get_guint8(message_tvb, *input_address);
3200                         if (print_level_1 ){
3201                                 proto_tree_add_text(udvm_tree, message_tvb, *input_address , 1,
3202                                                 "               Geting value: %u (0x%x) From Addr: %u", octet, octet, *input_address);
3203                         }
3204                         *input_address = *input_address + 1;
3205
3206                         if (p_bit != 0)
3207                         {
3208                                 octet = reverse[octet];
3209                         }
3210                         *input_bits = octet;
3211                         *remaining_bits = 8;
3212                 }
3213
3214                 /* Add some more bits to the accumulated value. */
3215                 bits_to_use = bits_still_required < *remaining_bits ? bits_still_required : *remaining_bits;
3216                 bits_still_required -= bits_to_use;
3217
3218                 *input_bits <<= bits_to_use;           /* Shift bits into MSByte */
3219                 value = (value << bits_to_use)         /* Then add to the accumulated value */
3220                         | ((*input_bits >> 8) & 0xFF);
3221                 *remaining_bits -= bits_to_use;            
3222                 *input_bits &= 0x00FF;                 /* Leave just the remaining bits */
3223         }
3224
3225         if (bit_order != 0)
3226         {
3227                 /* Bit reverse the entire word. */
3228                 guint16 lsb = reverse[(value >> 8) & 0xFF];
3229                 guint16 msb = reverse[value & 0xFF];
3230
3231                 value = ((msb << 8) | lsb) >> (16 - length);
3232         }
3233
3234         return value;
3235 }
3236
3237
3238 /* end udvm */
3239