bugfix to a bug reported by Ian Schorr:
[obnox/wireshark/wip.git] / packet-sigcomp.c
1 /* packet-sigcomp.c
2  * Routines for Signaling Compression (SigComp) dissection.
3  * Copyright 2004, Anders Broman <anders.broman@ericsson.com>
4  *
5  * $Id: packet-sigcomp.c,v 1.3 2004/06/29 20:40:12 etxrab Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24  * References:
25  * http://www.ietf.org/rfc/rfc3320.txt?number=3320
26  * http://www.ietf.org/rfc/rfc3321.txt?number=3321
27  * Useful links :
28  * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-impl-guide-02.txt
29  * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-sip-01.txt
30  */
31
32 #ifdef HAVE_CONFIG_H
33 # include "config.h"
34 #endif
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <math.h>
40 #include <glib.h>
41
42 #ifdef NEED_SNPRINTF_H
43 # include "snprintf.h"
44 #endif
45
46 #include <epan/packet.h>
47 #include "prefs.h"
48
49 /* Initialize the protocol and registered fields */
50 static int proto_sigcomp                                                        = -1;
51 static int hf_sigcomp_t_bit                                                     = -1;
52 static int hf_sigcomp_len                                                       = -1;
53 static int hf_sigcomp_returned_feedback_item            = -1;
54 static int hf_sigcomp_returned_feedback_item_len        = -1;
55 static int hf_sigcomp_code_len                                          = -1;
56 static int hf_sigcomp_destination                                       = -1;
57 static int hf_sigcomp_partial_state                                     = -1;
58 static int hf_sigcomp_udvm_instr                                        = -1;
59 static int hf_udvm_multitype_bytecode                           = -1;
60 static int hf_udvm_reference_bytecode                           = -1;
61 static int hf_udvm_literal_bytecode                                     = -1;
62 static int hf_udvm_operand                                                      = -1;
63 static int hf_udvm_length                                                       = -1;
64 static int hf_udvm_destination                                          = -1;
65 static int hf_udvm_at_address                                           = -1;
66 static int hf_udvm_address                                                      = -1;
67 static int hf_udvm_literal_num                                          = -1;
68 static int hf_udvm_value                                                        = -1;
69 static int hf_udvm_addr_value                                           = -1;
70 static int hf_partial_identifier_start                          = -1;
71 static int hf_partial_identifier_length                         = -1;
72 static int hf_state_begin                                                       = -1;
73 static int hf_udvm_state_length                                         = -1;
74 static int hf_udvm_state_length_addr                            = -1;
75 static int hf_udvm_state_address                                        = -1;
76 static int hf_udvm_state_address_addr                           = -1;
77 static int hf_udvm_state_instr                                          = -1;
78 static int hf_udvm_operand_1                                            = -1;
79 static int hf_udvm_operand_2                                            = -1;
80 static int hf_udvm_operand_2_addr                                       = -1;
81 static int hf_udvm_j                                                            = -1;
82 static int hf_udvm_output_start                                         = -1;
83 static int hf_udvm_output_start_addr                            = -1;
84 static int hf_udvm_output_length                                        = -1;
85 static int hf_udvm_output_length_addr                           = -1;
86 static int hf_udvm_req_feedback_loc                                     = -1;
87 static int hf_udvm_min_acc_len                                          = -1;
88 static int hf_udvm_state_ret_pri                                        = -1;
89 static int hf_udvm_ret_param_loc                                        = -1;
90 static int hf_udvm_position                                                     = -1;
91 static int hf_udvm_ref_dest                                                     = -1;
92 static int hf_udvm_bits                                                         = -1;
93 static int hf_udvm_lower_bound                                          = -1;
94 static int hf_udvm_upper_bound                                          = -1;
95 static int hf_udvm_uncompressed                                         = -1;
96 static int hf_udvm_offset                                                       = -1;
97 static int hf_udvm_start_value                                          = -1;
98
99 /* Initialize the subtree pointers */
100 static gint ett_sigcomp                 = -1;
101 static gint ett_sigcomp_udvm    = -1;
102
103
104 /* set the tcp port */
105 static guint SigCompUDPPort1 = 5555;
106 static guint SigCompUDPPort2 = 6666;
107
108 /* Default preference wether to display the bytecode in UDVM operands or not */
109 static gboolean display_udvm_bytecode = FALSE;
110 /* Default preference wether to dissect the UDVM code or not */
111 static gboolean dissect_udvm_code = TRUE;
112
113 /* Value strings */
114 static const value_string length_encoding_vals[] = {
115         { 0x00, "No partial state(Message type 2)" },
116         { 0x01, "6 bytes)" },
117         { 0x02, "9 bytes)" },
118         { 0x03, "12 bytes)" },
119         { 0,    NULL }
120 };
121
122
123 static const value_string destination_address_encoding_vals[] = {
124         { 0x00, "Reserved" },
125         { 0x01, "128" },
126         { 0x02, "192" },
127         { 0x03, "256" },
128         { 0x04, "320" },
129         { 0x05, "384" },
130         { 0x06, "448" },
131         { 0x07, "512" },
132         { 0x08, "576" },
133         { 0x09, "640" },
134         { 0x0a, "704" },
135         { 0x0b, "768" },
136         { 0x0c, "832" },
137         { 0x0d, "896" },
138         { 0x0e, "960" },
139         { 0x0F, "1024" },
140         { 0,    NULL }
141 };
142
143 static const value_string udvm_instruction_code_vals[] = {
144         { 0,    "DECOMPRESSION-FAILURE" },
145         { 1,    "AND" },
146         { 2,    "OR" },
147         { 3,    "NOT" },
148         { 4,    "LSHIFT" },
149         { 5,    "RSHIFT" },
150         { 6,    "ADD" },
151         { 7,    "SUBTRACT" },
152         { 8,    "MULTIPLY" },
153         { 9,    "DIVIDE" },
154         { 10,   "REMAINDER" },
155         { 11,   "SORT-ASCENDING" },
156         { 12,   "SORT-DESCENDING" },
157         { 13,   "SHA-1" },
158         { 14,   "LOAD" },
159         { 15,   "MULTILOAD" },
160         { 16,   "PUSH" },
161         { 17,   "POP" },
162         { 18,   "COPY" },
163         { 19,   "COPY-LITERAL" },
164         { 20,   "COPY-OFFSET" },
165         { 21,   "MEMSET" },
166         { 22,   "JUMP" },
167         { 23,   "COMPARE" },
168         { 24,   "CALL" },
169         { 25,   "RETURN" },
170         { 26,   "SWITCH" },
171         { 27,   "CRC" },
172         { 28,   "INPUT-BYTES" },
173         { 29,   "INPUT-BITS" },
174         { 30,   "INPUT-HUFFMAN" },
175         { 31,   "STATE-ACCESS" },
176         { 32,   "STATE-CREATE" },
177         { 33,   "STATE-FREE" },
178         { 34,   "OUTPUT" },
179         { 35,   "END-MESSAGE" },
180         { 0,    NULL }
181 };
182         /* RFC3320
183          * Figure 10: Bytecode for a multitype (%) operand
184          * Bytecode:                       Operand value:      Range:               HEX val
185          * 00nnnnnn                        N                   0 - 63                           0x00
186          * 01nnnnnn                        memory[2 * N]       0 - 65535                        0x40
187          * 1000011n                        2 ^ (N + 6)        64 , 128                          0x86    
188          * 10001nnn                        2 ^ (N + 8)    256 , ... , 32768                     0x88
189          * 111nnnnn                        N + 65504       65504 - 65535                        0xe0
190          * 1001nnnn nnnnnnnn               N + 61440       61440 - 65535                        0x90
191          * 101nnnnn nnnnnnnn               N                   0 - 8191                         0xa0
192          * 110nnnnn nnnnnnnn               memory[N]           0 - 65535                        0xc0
193          * 10000000 nnnnnnnn nnnnnnnn      N                   0 - 65535                        0x80
194          * 10000001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535                        0x81
195          */
196
197 static const value_string display_bytecode_vals[] = {
198         { 0x00, "00nnnnnn, N, 0 - 63" },
199         { 0x40, "01nnnnnn, memory[2 * N],0 - 65535" },
200         { 0x86, "1000011n, 2 ^ (N + 6), 64 , 128" },
201         { 0x88, "10001nnn, 2 ^ (N + 8), 256,..., 32768" },
202         { 0xe0, "111nnnnn N + 65504, 65504 - 65535" },
203         { 0x90, "1001nnnn nnnnnnnn, N + 61440, 61440 - 65535" },
204         { 0xa0, "101nnnnn nnnnnnnn, N, 0 - 8191" },
205         { 0xc0, "110nnnnn nnnnnnnn, memory[N], 0 - 65535" },
206         { 0x80, "10000000 nnnnnnnn nnnnnnnn, N, 0 - 65535" },
207         { 0x81, "10000001 nnnnnnnn nnnnnnnn, memory[N], 0 - 65535" },
208         { 0,    NULL }
209 };
210 /* RFC3320
211  * 0nnnnnnn                        memory[2 * N]       0 - 65535
212  * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
213  * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
214  */
215 static const value_string display_ref_bytecode_vals[] = {
216         { 0x00, "0nnnnnnn memory[2 * N] 0 - 65535" },
217         { 0x80, "10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535" },
218         { 0xc0, "11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535" },
219         { 0,    NULL }
220 };
221  /*  The simplest operand type is the literal (#), which encodes a
222   * constant integer from 0 to 65535 inclusive.  A literal operand may
223   * require between 1 and 3 bytes depending on its value.
224   * Bytecode:                       Operand value:      Range:
225   * 0nnnnnnn                        N                   0 - 127
226   * 10nnnnnn nnnnnnnn               N                   0 - 16383
227   * 11000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
228   *
229   *            Figure 8: Bytecode for a literal (#) operand
230   *
231   */
232
233 static const value_string display_lit_bytecode_vals[] = {
234         { 0x00, "0nnnnnnn N 0 - 127" },
235         { 0x80, "10nnnnnn nnnnnnnn N 0 - 16383" },
236         { 0xc0, "11000000 nnnnnnnn nnnnnnnn N 0 - 65535" },
237         { 0,    NULL }
238 };
239
240 static void dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, guint destination);
241
242 static int dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, 
243                                                                                   gint offset,gboolean is_addr,gint *start_offset,
244                                                                                   guint16 *value, gboolean *is_memory_address );
245
246 static int dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, 
247                                                            gint offset, gint *start_offset, guint16 *value);
248
249 static int dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, 
250                                                            gint offset, gint *start_offset, guint16 *value);
251
252
253 /* Code to actually dissect the packets */
254 static int
255 dissect_sigcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
256 {
257
258 /* Set up structures needed to add the protocol subtree and manage it */
259         tvbuff_t *udvm_tvb;
260         proto_item *ti, *udvm_item;
261         proto_tree *sigcomp_tree, *sigcomp_udvm_tree;
262         gint offset = 0;
263         gint partial_state_len;
264         guint octet;
265         guint8 returned_feedback_field[128];
266         guint8 partial_state[9];
267         guint tbit;
268         guint16 len = 0;
269         guint destination;
270 /* Is this a SigComp message or not ? */
271         octet = tvb_get_guint8(tvb, offset);
272         if ((octet  & 0xf8) != 0xf8)
273          return 0;
274
275 /* Make entries in Protocol column and Info column on summary display */
276         if (check_col(pinfo->cinfo, COL_PROTOCOL)) 
277                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
278
279         if (check_col(pinfo->cinfo, COL_INFO)) 
280                 col_clear(pinfo->cinfo, COL_INFO);
281
282
283
284
285 /* create display subtree for the protocol */
286         ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, FALSE);
287         sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
288
289 /* add an item to the subtree, see section 1.6 for more information */
290         octet = tvb_get_guint8(tvb, offset);
291
292 /*       A SigComp message takes one of two forms depending on whether it
293  *  accesses a state item at the receiving endpoint.  The two variants of
294  *  a SigComp message are given in Figure 3.  (The T-bit controls the
295  *  format of the returned feedback item and is defined in Section 7.1.)
296  *
297  *   0   1   2   3   4   5   6   7       0   1   2   3   4   5   6   7
298  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
299  * | 1   1   1   1   1 | T |  len  |   | 1   1   1   1   1 | T |   0   |
300  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
301  * |                               |   |                               |
302  * :    returned feedback item     :   :    returned feedback item     :
303  * |                               |   |                               |
304  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
305  * |                               |   |           code_len            |
306  * :   partial state identifier    :   +---+---+---+---+---+---+---+---+
307  *
308  * |                               |   |   code_len    |  destination  |
309  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
310  * |                               |   |                               |
311  * :   remaining SigComp message   :   :    uploaded UDVM bytecode     :
312  * |                               |   |                               |
313  * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
314  *                                     |                               |
315  *                                     :   remaining SigComp message   :
316  *                                     |                               |
317  *                                     +---+---+---+---+---+---+---+---+
318  *
319  */
320
321         proto_tree_add_item(sigcomp_tree,hf_sigcomp_t_bit, tvb, offset, 1, FALSE);
322         proto_tree_add_item(sigcomp_tree,hf_sigcomp_len, tvb, offset, 1, FALSE);
323         tbit = ( octet & 0x04)>>2;
324         partial_state_len = octet & 0x03;
325         offset ++;
326         if ( partial_state_len != 0 ){
327                 /*
328                  * The len field encodes the number of transmitted bytes as follows:
329                  *
330                  *   Encoding:   Length of partial state identifier
331                  *
332                  *   01          6 bytes
333                  *       10          9 bytes
334                  *       11          12 bytes
335                  * 
336                  */
337                 partial_state_len = partial_state_len * 3 + 3;
338
339                 /*
340                  * Message format 1
341                  */
342         if (check_col(pinfo->cinfo, COL_INFO))
343                 col_add_fstr(pinfo->cinfo, COL_INFO, "Msg format 1");
344
345                 if ( tbit == 1 ) {
346                         /*
347                          * Returned feedback item exists
348                          */
349                         len = 1;
350                         octet = tvb_get_guint8(tvb, offset);
351                         /* 0   1   2   3   4   5   6   7       0   1   2   3   4   5   6   7
352                          * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
353                          * | 0 |  returned_feedback_field  |   | 1 | returned_feedback_length  |
354                          * +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+
355              *                                                 |                               |
356              *                                                                     :    returned_feedback_field    :
357              *                                                                     |                               |
358              *                                                                     +---+---+---+---+---+---+---+---+
359                          * Figure 4: Format of returned feedback item
360                          */
361
362                         if ( (octet & 0x80) != 0 ){
363                                 len = octet & 0x7f;
364                                 proto_tree_add_uint(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
365                                         tvb, offset, 1, len);
366                                 offset ++;
367                                 tvb_memcpy(tvb,returned_feedback_field,offset, len);
368                         } else {
369                                 returned_feedback_field[0] = tvb_get_guint8(tvb, offset) & 0x7f;
370                         }
371                         proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
372                                 tvb, offset, len, returned_feedback_field);
373                         offset = offset + len;
374                         tvb_memcpy(tvb, partial_state, offset, partial_state_len);
375                         proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_partial_state,
376                                 tvb, offset, partial_state_len, partial_state);
377                         offset = offset + partial_state_len;
378                         proto_tree_add_text(sigcomp_tree, tvb, offset, -1, "Remaining SigComp message %u bytes",
379                                 tvb_reported_length_remaining(tvb, offset));
380                 }
381
382         }
383         else{
384                 /*
385                  * Message format 2
386                  */
387         if (check_col(pinfo->cinfo, COL_INFO))
388                 col_add_fstr(pinfo->cinfo, COL_INFO, "Msg format 2");
389                 if ( tbit == 1 ) {
390                         /*
391                          * Returned feedback item exists
392                          */
393                         len = 1;
394                         octet = tvb_get_guint8(tvb, offset);
395                         if ( (octet & 0x80) != 0 ){
396                                 len = octet & 0x7f;
397                                 proto_tree_add_uint(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
398                                         tvb, offset, 1, len);
399                                 offset ++;
400                         }
401                         tvb_memcpy(tvb,returned_feedback_field,offset, len);
402                         proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
403                                 tvb, offset, 1, returned_feedback_field);
404                         offset = offset + len;
405                 }
406                 len = tvb_get_ntohs(tvb, offset) >> 4;
407                 octet =  tvb_get_guint8(tvb, (offset + 1));
408                 destination = (octet & 0x0f);
409                 if ( destination != 0 )
410                         destination = 64 + ( destination * 64 );
411                 proto_tree_add_uint(sigcomp_tree,hf_sigcomp_code_len, tvb, offset, 2, len);
412                 proto_tree_add_item(sigcomp_tree,hf_sigcomp_destination, tvb, (offset+ 1), 1, FALSE);
413                 offset = offset +2;
414
415                 udvm_item = proto_tree_add_text(sigcomp_tree, tvb, offset, len, 
416                         "Uploaded UDVM bytecode %u (0x%x) bytes", len, len);
417                 sigcomp_udvm_tree = proto_item_add_subtree( udvm_item, ett_sigcomp_udvm);
418
419                 udvm_tvb = tvb_new_subset(tvb, offset, len, len);
420                 if ( dissect_udvm_code )
421                         dissect_udvm_bytecode(udvm_tvb, sigcomp_udvm_tree, destination); 
422                                 offset = offset + len;
423
424                 proto_tree_add_text(sigcomp_tree, tvb, offset, -1, "Remaining SigComp message %u bytes",
425                         tvb_reported_length_remaining(tvb, offset));
426         }
427         return tvb_length(tvb);
428 }
429
430                 
431
432 /* Continue adding tree items to process the packet here */
433 /* If this protocol has a sub-dissector call it here, see section 1.8 */
434
435 #define SIGCOMP_INSTR_DECOMPRESSION_FAILURE     0
436 #define SIGCOMP_INSTR_AND                       1
437 #define SIGCOMP_INSTR_OR                        2
438 #define SIGCOMP_INSTR_NOT                       3
439 #define SIGCOMP_INSTR_LSHIFT                    4
440 #define SIGCOMP_INSTR_RSHIFT                    5
441 #define SIGCOMP_INSTR_ADD                       6
442 #define SIGCOMP_INSTR_SUBTRACT                  7
443 #define SIGCOMP_INSTR_MULTIPLY                  8
444 #define SIGCOMP_INSTR_DIVIDE                    9
445 #define SIGCOMP_INSTR_REMAINDER                 10
446 #define SIGCOMP_INSTR_SORT_ASCENDING            11
447 #define SIGCOMP_INSTR_SORT_DESCENDING           12
448 #define SIGCOMP_INSTR_SHA_1                     13
449 #define SIGCOMP_INSTR_LOAD                      14
450 #define SIGCOMP_INSTR_MULTILOAD                 15
451 #define SIGCOMP_INSTR_PUSH                      16
452 #define SIGCOMP_INSTR_POP                       17
453 #define SIGCOMP_INSTR_COPY                      18
454 #define SIGCOMP_INSTR_COPY_LITERAL              19
455 #define SIGCOMP_INSTR_COPY_OFFSET               20
456 #define SIGCOMP_INSTR_MEMSET                    21
457 #define SIGCOMP_INSTR_JUMP                      22
458 #define SIGCOMP_INSTR_COMPARE                   23
459 #define SIGCOMP_INSTR_CALL                      24
460 #define SIGCOMP_INSTR_RETURN                    25
461 #define SIGCOMP_INSTR_SWITCH                    26
462 #define SIGCOMP_INSTR_CRC                       27
463 #define SIGCOMP_INSTR_INPUT_BYTES               28
464 #define SIGCOMP_INSTR_INPUT_BITS                29
465 #define SIGCOMP_INSTR_INPUT_HUFFMAN             30
466 #define SIGCOMP_INSTR_STATE_ACCESS              31
467 #define SIGCOMP_INSTR_STATE_CREATE              32
468 #define SIGCOMP_INSTR_STATE_FREE                33
469 #define SIGCOMP_INSTR_OUTPUT                    34
470 #define SIGCOMP_INSTR_END_MESSAGE               35      
471
472
473 static void
474 dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,guint start_address)
475 {
476         guint instruction;
477         gint offset = 0;
478         gint start_offset;
479         gint len;
480         gint n;
481         guint instruction_no = 0;
482         guint16 value = 0;
483         proto_item *item, *item2;
484         guint UDVM_address = start_address;
485         gboolean is_memory_address; 
486
487
488         while (tvb_reported_length_remaining(udvm_tvb, offset) > 0) { 
489                 instruction = tvb_get_guint8(udvm_tvb, offset);
490                 instruction_no ++;
491                 UDVM_address = start_address + offset;
492 ;
493
494                 item = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
495                                         "######### UDVM instruction %u at UDVM-address %u (0x%x) #########",
496                                         instruction_no,UDVM_address,UDVM_address);
497                 PROTO_ITEM_SET_GENERATED(item);
498                 proto_tree_add_item(sigcomp_udvm_tree, hf_sigcomp_udvm_instr, udvm_tvb, offset, 1, FALSE);
499                 offset ++;
500                 switch ( instruction ) {
501
502                 case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */
503                         /* $operand_1*/
504                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
505                         len = offset - start_offset;
506                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, 
507                                 udvm_tvb, start_offset, len, value);
508                         /* %operand_2*/
509                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
510                         len = offset - start_offset;
511                         if ( is_memory_address ){
512                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, 
513                                         udvm_tvb, start_offset, len, value);
514                         }else{
515                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, 
516                                         udvm_tvb, start_offset, len, value);
517                         }
518                         break;
519
520                 case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */
521                         /* $operand_1*/
522                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
523                         len = offset - start_offset;
524                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, 
525                                 udvm_tvb, start_offset, len, value);
526                         /* %operand_2*/
527                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
528                         len = offset - start_offset;
529                         if ( is_memory_address ){
530                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, 
531                                         udvm_tvb, start_offset, len, value);
532                         }else{
533                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, 
534                                         udvm_tvb, start_offset, len, value);
535                         }
536                         break;
537
538                 case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */
539                         /* $operand_1*/
540                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
541                         len = offset - start_offset;
542                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, 
543                                 udvm_tvb, start_offset, len, value);
544                         break;
545
546                 case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */
547                         /* $operand_1*/
548                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
549                         len = offset - start_offset;
550                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, 
551                                 udvm_tvb, start_offset, len, value);
552                         /* %operand_2*/
553                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
554                         len = offset - start_offset;
555                         if ( is_memory_address ){
556                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, 
557                                         udvm_tvb, start_offset, len, value);
558                         }else{
559                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, 
560                                         udvm_tvb, start_offset, len, value);
561                         }
562                         break;
563
564                 case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */
565                         /* $operand_1*/
566                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
567                         len = offset - start_offset;
568                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, 
569                                 udvm_tvb, start_offset, len, value);
570                         /* %operand_2*/
571                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
572                         len = offset - start_offset;
573                         if ( is_memory_address ){
574                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, 
575                                         udvm_tvb, start_offset, len, value);
576                         }else{
577                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, 
578                                         udvm_tvb, start_offset, len, value);
579                         }
580                         break;
581
582                 case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */
583                         /* $operand_1*/
584                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
585                         len = offset - start_offset;
586                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, 
587                                 udvm_tvb, start_offset, len, value);
588                         /* %operand_2*/
589                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
590                         len = offset - start_offset;
591                         if ( is_memory_address ){
592                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, 
593                                         udvm_tvb, start_offset, len, value);
594                         }else{
595                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, 
596                                         udvm_tvb, start_offset, len, value);
597                         }
598                         break;
599
600                 case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */
601                         /* $operand_1*/
602                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
603                         len = offset - start_offset;
604                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, 
605                                 udvm_tvb, start_offset, len, value);
606                         /* %operand_2*/
607                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
608                         len = offset - start_offset;
609                         if ( is_memory_address ){
610                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, 
611                                         udvm_tvb, start_offset, len, value);
612                         }else{
613                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, 
614                                         udvm_tvb, start_offset, len, value);
615                         }
616                         break;
617
618                 case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */
619                         /* $operand_1*/
620                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
621                         len = offset - start_offset;
622                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, 
623                                 udvm_tvb, start_offset, len, value);
624                         /* %operand_2*/
625                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
626                         len = offset - start_offset;
627                         if ( is_memory_address ){
628                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, 
629                                         udvm_tvb, start_offset, len, value);
630                         }else{
631                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, 
632                                         udvm_tvb, start_offset, len, value);
633                         }
634                         break;
635
636                 case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */
637                         /* $operand_1*/
638                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
639                         len = offset - start_offset;
640                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, 
641                                 udvm_tvb, start_offset, len, value);
642                         /* %operand_2*/
643                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
644                         len = offset - start_offset;
645                         if ( is_memory_address ){
646                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, 
647                                         udvm_tvb, start_offset, len, value);
648                         }else{
649                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, 
650                                         udvm_tvb, start_offset, len, value);
651                         }
652                         break;
653
654                 case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */
655                         /* $operand_1*/
656                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
657                         len = offset - start_offset;
658                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, 
659                                 udvm_tvb, start_offset, len, value);
660                         /* %operand_2*/
661                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
662                         len = offset - start_offset;
663                         if ( is_memory_address ){
664                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, 
665                                         udvm_tvb, start_offset, len, value);
666                         }else{
667                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, 
668                                         udvm_tvb, start_offset, len, value);
669                         }
670                         break;
671                 case SIGCOMP_INSTR_SORT_ASCENDING: /* 11 SORT-ASCENDING (%start, %n, %k) */
672                                                 /* while programming stop while loop */
673                         offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
674                         break;
675
676                 case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */
677                         /* while programming stop while loop */
678                         offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
679                         break;
680                 case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */
681                         /* %position */
682                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
683                         len = offset - start_offset;
684                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position, 
685                                 udvm_tvb, start_offset, len, value);
686
687                         /*  %length, */
688                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
689                         len = offset - start_offset;
690                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, 
691                                 udvm_tvb, start_offset, len, value);
692
693                         /* $destination */
694                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
695                         len = offset - start_offset;
696                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest, 
697                                 udvm_tvb, start_offset, len, value);
698                         break;
699
700                 case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */
701                         /* %address */
702                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
703                         len = offset - start_offset;
704                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address, 
705                                 udvm_tvb, start_offset, len, value);
706                         /* %value */
707                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
708                         len = offset - start_offset;
709                         if ( is_memory_address ){
710                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, 
711                                         udvm_tvb, start_offset, len, value);
712                         }else{
713                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, 
714                                         udvm_tvb, start_offset, len, value);
715                         }
716                         break;
717
718                 case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
719                         /* %address */
720                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
721                         len = offset - start_offset;
722                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address, 
723                                 udvm_tvb, start_offset, len, value);
724                         /* #n */
725                         offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
726                         len = offset - start_offset;
727                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num, 
728                                 udvm_tvb, start_offset, len, value);
729                         n = value;
730                         while ( n > 0) {
731                                 n = n -1;
732                                 /* %value */
733                                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
734                                 len = offset - start_offset;
735                                 if ( is_memory_address ){
736                                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, 
737                                                 udvm_tvb, start_offset, len, value);
738                                 }else{
739                                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, 
740                                                 udvm_tvb, start_offset, len, value);
741                                 }
742                         }
743                         break;
744                          
745                 case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */
746                         /* %value */
747                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
748                         len = offset - start_offset;
749                         if ( is_memory_address ){
750                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, 
751                                         udvm_tvb, start_offset, len, value);
752                         }else{
753                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, 
754                                         udvm_tvb, start_offset, len, value);
755                         }
756                         break;
757
758                 case SIGCOMP_INSTR_POP: /* 17 POP (%address) */
759                         /* %address */                  offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
760
761                         len = offset - start_offset;
762                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address, 
763                                 udvm_tvb, start_offset, len, value);
764                         break;
765
766                 case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */
767                         /* %position */
768                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
769                         len = offset - start_offset;
770                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position, 
771                                 udvm_tvb, start_offset, len, value);
772
773                         /*  %length, */
774                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
775                         len = offset - start_offset;
776                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, 
777                                 udvm_tvb, start_offset, len, value);
778
779                         /* $destination */
780                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
781                         len = offset - start_offset;
782                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest, 
783                                 udvm_tvb, start_offset, len, value);
784                         break;
785
786                 case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */
787                         /* %position */
788                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
789                         len = offset - start_offset;
790                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position, 
791                                 udvm_tvb, start_offset, len, value);
792
793                         /*  %length, */
794                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
795                         len = offset - start_offset;
796                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, 
797                                 udvm_tvb, start_offset, len, value);
798
799                         /* $destination */
800                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
801                         len = offset - start_offset;
802                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest, 
803                                 udvm_tvb, start_offset, len, value);
804                         break;
805  
806                 case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */
807                         /* %offset */
808                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
809                         len = offset - start_offset;
810                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset, 
811                                 udvm_tvb, start_offset, len, value);
812
813                         /*  %length, */
814                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
815                         len = offset - start_offset;
816                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, 
817                                 udvm_tvb, start_offset, len, value);
818
819                         /* $destination */
820                         offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
821                         len = offset - start_offset;
822                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest, 
823                                 udvm_tvb, start_offset, len, value);
824                         break;
825                 case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */
826
827                         /* %address */
828                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
829                         len = offset - start_offset;
830                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address, 
831                                 udvm_tvb, start_offset, len, value);
832
833                         /*  %length, */
834                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE, &start_offset, &value, &is_memory_address);
835                         len = offset - start_offset;
836                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, 
837                                 udvm_tvb, start_offset, len, value);
838
839                         /* %start_value */
840                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
841                         len = offset - start_offset;
842                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_start_value, 
843                                 udvm_tvb, start_offset, len, value);
844
845                         /* %offset */
846                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
847                         len = offset - start_offset;
848                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset, 
849                                 udvm_tvb, start_offset, len, value);
850                         break;
851
852
853                 case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */
854                         /* @address */
855                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
856                         len = offset - start_offset;
857                          /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
858                         value = ( value + UDVM_address ) & 0xffff;
859                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, 
860                                 udvm_tvb, start_offset, len, value);
861                         break;
862
863                 case SIGCOMP_INSTR_COMPARE: /* 23 */
864                         /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
865                          */
866                         /* %value_1 */
867                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
868                         len = offset - start_offset;
869                         if ( is_memory_address ){
870                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, 
871                                         udvm_tvb, start_offset, len, value);
872                         }else{
873                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, 
874                                         udvm_tvb, start_offset, len, value);
875                         }
876
877                         /* %value_2 */
878                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
879                         len = offset - start_offset;
880                         if ( is_memory_address ){
881                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, 
882                                         udvm_tvb, start_offset, len, value);
883                         }else{
884                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, 
885                                         udvm_tvb, start_offset, len, value);
886                         }
887
888                         /* @address_1 */
889                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
890                         len = offset - start_offset;
891                          /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
892                         value = ( value + UDVM_address ) & 0xffff;
893                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, 
894                                 udvm_tvb, start_offset, len, value);
895
896                         /* @address_2 */
897                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
898                         len = offset - start_offset;
899                          /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
900                         value = ( value + UDVM_address ) & 0xffff;
901                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, 
902                                 udvm_tvb, start_offset, len, value);
903
904                         /* @address_3 */
905                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
906                         len = offset - start_offset;
907                          /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
908                         value = ( value + UDVM_address ) & 0xffff;
909                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, 
910                                 udvm_tvb, start_offset, len, value);
911                         break;
912
913                 case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/
914                         /* @address */
915                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
916                         len = offset - start_offset;
917                          /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
918                         value = ( value + UDVM_address ) & 0xffff;
919                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, 
920                                 udvm_tvb, start_offset, len, value);
921                         break;
922                 case SIGCOMP_INSTR_RETURN: /* 25 POP and return */
923                 break;
924
925                 case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
926                         /* #n */
927                         offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
928                         len = offset - start_offset;
929                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num, 
930                                 udvm_tvb, start_offset, len, value);
931
932                         /* Number of addresses in the instruction */
933                         n = value;
934                         /* %j */
935                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
936                         len = offset - start_offset;
937                         if ( is_memory_address ){
938                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, 
939                                         udvm_tvb, start_offset, len, value);
940                         }else{
941                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, 
942                                         udvm_tvb, start_offset, len, value);
943                         }
944
945                         while ( n > 0) {
946                                 n = n -1;
947                                 /* @address_n-1 */
948                                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
949                                 len = offset - start_offset;
950                                  /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
951                                 value = ( value + UDVM_address ) & 0xffff;
952                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, 
953                                         udvm_tvb, start_offset, len, value);
954                         }
955                         break;
956                 case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */
957                         /* %value */
958                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
959                         len = offset - start_offset;
960                         if ( is_memory_address ){
961                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, 
962                                         udvm_tvb, start_offset, len, value);
963                         }else{
964                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, 
965                                         udvm_tvb, start_offset, len, value);
966                         }
967
968                         /* %position */
969                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
970                         len = offset - start_offset;
971                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position, 
972                                 udvm_tvb, start_offset, len, value);
973
974                         /* %length */
975                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
976                         len = offset - start_offset;
977                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, 
978                                 udvm_tvb, start_offset, len, value);
979
980                         /* @address */
981                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
982                         len = offset - start_offset;
983                          /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
984                         value = ( value + UDVM_address ) & 0xffff;
985                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, 
986                                 udvm_tvb, start_offset, len, value);
987                         break;
988
989
990                 case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */
991                         /* %length */
992                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
993                         len = offset - start_offset;
994                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, 
995                                 udvm_tvb, start_offset, len, value);
996
997                         /* %destination */
998                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
999                         len = offset - start_offset;
1000                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination, 
1001                                 udvm_tvb, start_offset, len, value);
1002
1003                         /* @address */
1004                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1005                         len = offset - start_offset;
1006                          /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1007                         value = ( value + UDVM_address ) & 0xffff;
1008                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, 
1009                                 udvm_tvb, start_offset, len, value);
1010                         break;
1011                 case SIGCOMP_INSTR_INPUT_BITS:/* 29   INPUT-BITS (%length, %destination, @address) */
1012                         /* %length */
1013                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1014                         len = offset - start_offset;
1015                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, 
1016                                 udvm_tvb, start_offset, len, value);
1017
1018                         /* %destination */
1019                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1020                         len = offset - start_offset;
1021                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination, 
1022                                 udvm_tvb, start_offset, len, value);
1023
1024                         /* @address */
1025                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1026                         len = offset - start_offset;
1027                          /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1028                         value = ( value + UDVM_address ) & 0xffff;
1029                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, 
1030                                 udvm_tvb, start_offset, len, value);
1031                         break;
1032                 case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */
1033                         /*
1034                          * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1,
1035                          *  %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n,
1036                          *  %upper_bound_n, %uncompressed_n)
1037                          */
1038                         /* %destination */
1039                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1040                         len = offset - start_offset;
1041                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination, 
1042                                 udvm_tvb, start_offset, len, value);
1043
1044                         /* @address */
1045                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1046                         len = offset - start_offset;
1047                          /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1048                         value = ( value + UDVM_address ) & 0xffff;
1049                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, 
1050                                 udvm_tvb, start_offset, len, value);
1051                         /* #n */
1052                         offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1053                         len = offset - start_offset;
1054                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num, 
1055                                 udvm_tvb, start_offset, len, value);
1056                         n = value;
1057                         while ( n > 0) {
1058                                 n = n -1;
1059                                 /* %bits_n */
1060                                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1061                                 len = offset - start_offset;
1062                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_bits, 
1063                                         udvm_tvb, start_offset, len, value);
1064                                 /* %lower_bound_n*/
1065                                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1066                                 len = offset - start_offset;
1067                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_lower_bound, 
1068                                         udvm_tvb, start_offset, len, value);
1069                                 /* %upper_bound_n */
1070                                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1071                                 len = offset - start_offset;
1072                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_upper_bound, 
1073                                         udvm_tvb, start_offset, len, value);
1074                                 /* %uncompressed_n */
1075                                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1076                                 len = offset - start_offset;
1077                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_uncompressed, 
1078                                         udvm_tvb, start_offset, len, value);
1079                         }
1080                         break;
1081
1082                 case SIGCOMP_INSTR_STATE_ACCESS: /* 31 */
1083                         /*   STATE-ACCESS (%partial_identifier_start, %partial_identifier_length,
1084                          * %state_begin, %state_length, %state_address, %state_instruction)
1085                          */
1086
1087                         /* 
1088                          * %partial_identifier_start
1089                          */
1090                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1091                         len = offset - start_offset;
1092                         proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start, 
1093                                 udvm_tvb, start_offset, len, value);
1094
1095                         /*
1096                          * %partial_identifier_length
1097                          */
1098                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1099                         len = offset - start_offset;
1100                         proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length, 
1101                                 udvm_tvb, start_offset, len, value);
1102                         /*
1103                          * %state_begin
1104                          */
1105                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1106                         len = offset - start_offset;
1107                         proto_tree_add_uint(sigcomp_udvm_tree, hf_state_begin, 
1108                                 udvm_tvb, start_offset, len, value);
1109
1110                         /*
1111                          * %state_length
1112                          */
1113                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1114                         len = offset - start_offset;
1115                         if ( is_memory_address ) {
1116                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr, 
1117                                         udvm_tvb, start_offset, len, value);
1118                         }else{
1119                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length, 
1120                                         udvm_tvb, start_offset, len, value);
1121                         }
1122                         /*
1123                          * %state_address
1124                          */
1125                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1126                         len = offset - start_offset;
1127                         if ( is_memory_address ) {
1128                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr, 
1129                                         udvm_tvb, start_offset, len, value);
1130                         }else{
1131                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address, 
1132                                         udvm_tvb, start_offset, len, value);
1133                         }
1134                         /*
1135                          * %state_instruction
1136                          */
1137                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1138                         len = offset - start_offset;
1139                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr, 
1140                                 udvm_tvb, start_offset, len, value);
1141                         break;
1142                 case SIGCOMP_INSTR_STATE_CREATE: /* 32 */
1143                         /*
1144                          * STATE-CREATE (%state_length, %state_address, %state_instruction,
1145                          * %minimum_access_length, %state_retention_priority)
1146                          */
1147
1148                         /*
1149                          * %state_length
1150                          */
1151                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1152                         len = offset - start_offset;
1153                         if ( is_memory_address ) {
1154                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr, 
1155                                         udvm_tvb, start_offset, len, value);
1156                         }else{
1157                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length, 
1158                                         udvm_tvb, start_offset, len, value);
1159                         }
1160                         /*
1161                          * %state_address
1162                          */
1163                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1164                         len = offset - start_offset;
1165                         if ( is_memory_address ) {
1166                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr, 
1167                                         udvm_tvb, start_offset, len, value);
1168                         }else{
1169                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address, 
1170                                         udvm_tvb, start_offset, len, value);
1171                         }
1172                         /*
1173                          * %state_instruction
1174                          */
1175                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1176                         len = offset - start_offset;
1177                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr, 
1178                                 udvm_tvb, start_offset, len, value);
1179                         /*
1180                          * %minimum_access_length
1181                          */
1182                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1183                         len = offset - start_offset;
1184                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len, 
1185                                 udvm_tvb, start_offset, len, value);
1186                         /*
1187                          * %state_retention_priority
1188                          */
1189                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1190                         len = offset - start_offset;
1191                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri, 
1192                                 udvm_tvb, start_offset, len, value);
1193
1194                         break;
1195                 case SIGCOMP_INSTR_STATE_FREE: /* 33 */
1196                         /*
1197                          * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
1198                          */
1199                         /* 
1200                          * %partial_identifier_start
1201                          */
1202                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1203                         len = offset - start_offset;
1204                         proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start, 
1205                                 udvm_tvb, start_offset, len, value);
1206
1207                         /*
1208                          * %partial_identifier_length
1209                          */
1210                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1211                         len = offset - start_offset;
1212                         proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length, 
1213                                 udvm_tvb, start_offset, len, value);
1214                         break;
1215                 case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */
1216                         /* 
1217                          * %output_start
1218                          */
1219                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1220                         len = offset - start_offset;
1221                         if ( is_memory_address ) {
1222                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start, 
1223                                         udvm_tvb, start_offset, len, value);
1224                         }else{
1225                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start, 
1226                                         udvm_tvb, start_offset, len, value);
1227                         }
1228                         /* 
1229                          * %output_length
1230                          */
1231                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1232                         len = offset - start_offset;
1233                         if ( is_memory_address ) {
1234                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length_addr, 
1235                                         udvm_tvb, start_offset, len, value);
1236                         }else{
1237                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length, 
1238                                         udvm_tvb, start_offset, len, value);
1239                         }
1240                         break;
1241                 case SIGCOMP_INSTR_END_MESSAGE: /* 35 */
1242                         /*
1243                          * END-MESSAGE (%requested_feedback_location,
1244                          * %returned_parameters_location, %state_length, %state_address,
1245                          * %state_instruction, %minimum_access_length,
1246                          * %state_retention_priority)
1247                          */
1248                         /* %requested_feedback_location */
1249                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1250                         len = offset - start_offset;
1251                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_req_feedback_loc, 
1252                                 udvm_tvb, start_offset, len, value);
1253                         /* returned_parameters_location */
1254                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1255                         len = offset - start_offset;
1256                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ret_param_loc, 
1257                                 udvm_tvb, start_offset, len, value);
1258                         /*
1259                          * %state_length
1260                          */
1261                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1262                         len = offset - start_offset;
1263                         if ( is_memory_address ) {
1264                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr, 
1265                                         udvm_tvb, start_offset, len, value);
1266                         }else{
1267                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length, 
1268                                         udvm_tvb, start_offset, len, value);
1269                         }
1270                         /*
1271                          * %state_address
1272                          */
1273                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1274                         len = offset - start_offset;
1275                         if ( is_memory_address ) {
1276                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr, 
1277                                         udvm_tvb, start_offset, len, value);
1278                         }else{
1279                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address, 
1280                                         udvm_tvb, start_offset, len, value);
1281                         }
1282                         /*
1283                          * %state_instruction
1284                          */
1285                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1286                         len = offset - start_offset;
1287                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr, 
1288                                 udvm_tvb, start_offset, len, value);
1289                         /*
1290                          * %minimum_access_length
1291                          */
1292                         offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1293                         len = offset - start_offset;
1294                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len, 
1295                                 udvm_tvb, start_offset, len, value);
1296                         /*
1297                          * %state_retention_priority
1298                          */
1299                         if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1300                                 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1301                                 len = offset - start_offset;
1302                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri, 
1303                                         udvm_tvb, start_offset, len, value);
1304                         }else{
1305                                 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
1306                                                 "state_retention_priority = 0(Not in the uploaded code as UDVM buffer initalized to Zero");
1307                                 PROTO_ITEM_SET_GENERATED(item2);
1308                         }
1309                         if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1310                                 len = tvb_reported_length_remaining(udvm_tvb, offset);
1311                                 UDVM_address = start_address + offset;
1312                                 proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, len,
1313                                                 "Remaning %u bytes starting at UDVM addr %u (0x%x)- State information ?",len, UDVM_address, UDVM_address);
1314                         }
1315                         offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);                      
1316                         break;
1317
1318                 default:
1319                         /* while programming stop while loop */
1320                         offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);                      
1321                         break;
1322                 }
1323
1324                 
1325         } 
1326         return;
1327 }
1328  /*  The simplest operand type is the literal (#), which encodes a
1329   * constant integer from 0 to 65535 inclusive.  A literal operand may
1330   * require between 1 and 3 bytes depending on its value.
1331   * Bytecode:                       Operand value:      Range:
1332   * 0nnnnnnn                        N                   0 - 127
1333   * 10nnnnnn nnnnnnnn               N                   0 - 16383
1334   * 11000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
1335   *
1336   *            Figure 8: Bytecode for a literal (#) operand
1337   *
1338   */
1339 static int
1340 dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, 
1341                                                            gint offset, gint *start_offset, guint16 *value)
1342 {
1343         guint bytecode;
1344         guint16 operand;
1345         guint test_bits;
1346         guint display_bytecode;
1347
1348         bytecode = tvb_get_guint8(udvm_tvb, offset);
1349         test_bits = bytecode >> 7;
1350         if (test_bits == 1){
1351                 test_bits = bytecode >> 6;
1352                 if (test_bits == 2){
1353                         /*
1354                          * 10nnnnnn nnnnnnnn               N                   0 - 16383
1355                          */
1356                         display_bytecode = bytecode & 0xc0;
1357                         if ( display_udvm_bytecode )
1358                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1359                                         udvm_tvb, offset, 1, display_bytecode);
1360                         operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
1361                         *value = operand;
1362                         *start_offset = offset;
1363                         offset = offset + 2;
1364
1365                 }else{
1366                         /*
1367                          * 111000000 nnnnnnnn nnnnnnnn      N                   0 - 65535
1368                          */
1369                         display_bytecode = bytecode & 0xc0;
1370                         if ( display_udvm_bytecode )
1371                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1372                                         udvm_tvb, offset, 1, display_bytecode);
1373                         offset ++;
1374                         operand = tvb_get_ntohs(udvm_tvb, offset);
1375                         *value = operand;
1376                         *start_offset = offset;
1377                         offset = offset + 2;
1378
1379                 }
1380         }else{
1381                 /*
1382                  * 0nnnnnnn                        N                   0 - 127
1383                  */
1384                 display_bytecode = bytecode & 0xc0;
1385                 if ( display_udvm_bytecode )
1386                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1387                                 udvm_tvb, offset, 1, display_bytecode);
1388                 operand = ( bytecode & 0x7f);
1389                 *value = operand;
1390                 *start_offset = offset;
1391                 offset ++;
1392         }
1393
1394         return offset;
1395
1396 }
1397 /*
1398  * The second operand type is the reference ($), which is always used to
1399  * access a 2-byte value located elsewhere in the UDVM memory.  The
1400  * bytecode for a reference operand is decoded to be a constant integer
1401  * from 0 to 65535 inclusive, which is interpreted as the memory address
1402  * containing the actual value of the operand.
1403  * Bytecode:                       Operand value:      Range:
1404  *
1405  * 0nnnnnnn                        memory[2 * N]       0 - 65535
1406  * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
1407  * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
1408  *
1409  *            Figure 9: Bytecode for a reference ($) operand
1410  */
1411 static int
1412 dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, 
1413                                                            gint offset, gint *start_offset, guint16 *value)
1414 {
1415         guint bytecode;
1416         guint16 operand;
1417         guint test_bits;
1418         guint display_bytecode;
1419
1420         bytecode = tvb_get_guint8(udvm_tvb, offset);
1421         test_bits = bytecode >> 7;
1422         if (test_bits == 1){
1423                 test_bits = bytecode >> 6;
1424                 if (test_bits == 2){
1425                         /*
1426                          * 10nnnnnn nnnnnnnn               memory[2 * N]       0 - 65535
1427                          */
1428                         display_bytecode = bytecode & 0xc0;
1429                         if ( display_udvm_bytecode )
1430                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
1431                                         udvm_tvb, offset, 1, display_bytecode);
1432                         operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
1433                         *value = (operand * 2);
1434                         *start_offset = offset;
1435                         offset = offset + 2;
1436
1437                 }else{
1438                         /*
1439                          * 11000000 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
1440                          */
1441                         display_bytecode = bytecode & 0xc0;
1442                         if ( display_udvm_bytecode )
1443                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
1444                                         udvm_tvb, offset, 1, display_bytecode);
1445                         offset ++;
1446                         operand = tvb_get_ntohs(udvm_tvb, offset);
1447                         *value = operand;
1448                         *start_offset = offset;
1449                         offset = offset + 2;
1450
1451                 }
1452         }else{
1453                 /*
1454                  * 0nnnnnnn                        memory[2 * N]       0 - 65535
1455                  */
1456                 display_bytecode = bytecode & 0xc0;
1457                 if ( display_udvm_bytecode )
1458                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
1459                                 udvm_tvb, offset, 1, display_bytecode);
1460                 operand = ( bytecode & 0x3f);
1461                 *value = (operand * 2);
1462                 *start_offset = offset;
1463                 offset ++;
1464         }
1465
1466         return offset;
1467 }
1468
1469 /*
1470  *The fourth operand type is the address (@).  This operand is decoded
1471  * as a multitype operand followed by a further step: the memory address
1472  * of the UDVM instruction containing the address operand is added to
1473  * obtain the correct operand value.  So if the operand value from
1474  * Figure 10 is D then the actual operand value of an address is
1475  * calculated as follows:
1476  *
1477  * operand_value = (is_memory_address_of_instruction + D) modulo 2^16
1478  * TODO calculate correct value for operand in case of ADDR
1479  */
1480 static int
1481 dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, 
1482                                                            gint offset, gboolean is_addr, gint *start_offset, guint16 *value, gboolean *is_memory_address )
1483 {
1484         guint bytecode;
1485         guint display_bytecode;
1486         guint16 operand;
1487         guint32 result;
1488         guint test_bits;
1489         /* RFC3320
1490          * Figure 10: Bytecode for a multitype (%) operand
1491          * Bytecode:                       Operand value:      Range:               HEX val
1492          * 00nnnnnn                        N                   0 - 63                           0x00
1493          * 01nnnnnn                        memory[2 * N]       0 - 65535                        0x40
1494          * 1000011n                        2 ^ (N + 6)        64 , 128                          0x86    
1495          * 10001nnn                        2 ^ (N + 8)    256 , ... , 32768                     0x88
1496          * 111nnnnn                        N + 65504       65504 - 65535                        0xe0
1497          * 1001nnnn nnnnnnnn               N + 61440       61440 - 65535                        0x90
1498          * 101nnnnn nnnnnnnn               N                   0 - 8191                         0xa0
1499          * 110nnnnn nnnnnnnn               memory[N]           0 - 65535                        0xc0
1500          * 10000000 nnnnnnnn nnnnnnnn      N                   0 - 65535                        0x80
1501          * 10000001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535                        0x81
1502          */
1503         *is_memory_address = FALSE; 
1504         bytecode = tvb_get_guint8(udvm_tvb, offset);
1505         test_bits = ( bytecode & 0xc0 ) >> 6;
1506         switch (test_bits ){
1507         case 0:
1508                 /*  
1509                  * 00nnnnnn                        N                   0 - 63
1510                  */
1511                 display_bytecode = bytecode & 0xc0;
1512                 if ( display_udvm_bytecode )
1513                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1514                         udvm_tvb, offset, 1, display_bytecode);
1515                 operand = ( bytecode & 0x3f);
1516                 *value = operand;
1517                 *start_offset = offset;
1518                 offset ++;
1519                 break;
1520         case 1:
1521                 /*  
1522                  * 01nnnnnn                        memory[2 * N]       0 - 65535
1523                  */
1524                 display_bytecode = bytecode & 0xc0;
1525                 if ( display_udvm_bytecode )
1526                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1527                                 udvm_tvb, offset, 1, display_bytecode);
1528                 operand = ( bytecode & 0x3f) * 2;
1529                 *is_memory_address = TRUE;
1530                 *value = operand;
1531                 *start_offset = offset;
1532                 offset ++;
1533                 break;
1534         case 2:
1535                 /* Check tree most significant bits */
1536                 test_bits = ( bytecode & 0xe0 ) >> 5;
1537                 if ( test_bits == 5 ){
1538                 /*
1539                  * 101nnnnn nnnnnnnn               N                   0 - 8191
1540                  */
1541                         display_bytecode = bytecode & 0xe0;
1542                         if ( display_udvm_bytecode )
1543                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1544                                         udvm_tvb, offset, 1, display_bytecode);
1545                         operand = tvb_get_ntohs(udvm_tvb, offset) & 0x1fff;
1546                         *value = operand;
1547                         *start_offset = offset;
1548                         offset = offset + 2;
1549                 }else{
1550                         test_bits = ( bytecode & 0xf0 ) >> 4;
1551                         if ( test_bits == 9 ){
1552                 /*
1553                  * 1001nnnn nnnnnnnn               N + 61440       61440 - 65535
1554                  */
1555                                 display_bytecode = bytecode & 0xf0;
1556                                 if ( display_udvm_bytecode )
1557                                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1558                                                         udvm_tvb, offset, 1, display_bytecode);
1559                                 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x0fff) + 61440;
1560                                 *start_offset = offset;
1561                                 *value = operand;
1562                                 offset = offset + 2;
1563                         }else{
1564                                 test_bits = ( bytecode & 0x08 ) >> 3;
1565                                 if ( test_bits == 1){
1566                 /*
1567                  * 10001nnn                        2 ^ (N + 8)    256 , ... , 32768
1568                  */
1569                                         display_bytecode = bytecode & 0xf8;
1570                                         if ( display_udvm_bytecode )
1571                                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1572                                                                 udvm_tvb, offset, 1, display_bytecode);
1573                                         result = (guint32)pow(2,( bytecode & 0x07) + 8);
1574                                         operand = result & 0xffff;
1575                                         *start_offset = offset;
1576                                         *value = operand;
1577                                         offset ++;
1578                                 }else{
1579                                         test_bits = ( bytecode & 0x0e ) >> 1;
1580                                         if ( test_bits == 3 ){
1581                                                 /*
1582                                                  * 1000 011n                        2 ^ (N + 6)        64 , 128
1583                                                  */
1584                                                 display_bytecode = bytecode & 0xfe;
1585                                                 if ( display_udvm_bytecode )
1586                                                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1587                                                                 udvm_tvb, offset, 1, display_bytecode);
1588                                                 result = (guint32)pow(2,( bytecode & 0x01) + 6);
1589                                                 operand = result & 0xffff;
1590                                                 *start_offset = offset;
1591                                                 *value = operand;
1592                                                 offset ++;
1593                                         }else{
1594                                         /*
1595                                          * 1000 0000 nnnnnnnn nnnnnnnn      N                   0 - 65535
1596                                          * 1000 0001 nnnnnnnn nnnnnnnn      memory[N]           0 - 65535
1597                                          */
1598                                                 display_bytecode = bytecode;
1599                                                 if ( display_udvm_bytecode )
1600                                                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1601                                                                 udvm_tvb, offset, 1, display_bytecode);
1602                                                 if ( (bytecode & 0x01) == 1 )
1603                                                         *is_memory_address = TRUE;
1604                                                 offset ++;
1605                                                 operand = tvb_get_ntohs(udvm_tvb, offset);
1606                                                 *value = operand;
1607                                                 *start_offset = offset;
1608                                                 offset = offset +2;
1609                                         }
1610
1611
1612                                 }
1613                         }
1614                 }
1615                 break;
1616
1617         case 3:
1618                 test_bits = ( bytecode & 0x20 ) >> 5;
1619                 if ( test_bits == 1 ){
1620                 /*
1621                  * 111nnnnn                        N + 65504       65504 - 65535
1622                  */
1623                         display_bytecode = bytecode & 0xe0;
1624                         if ( display_udvm_bytecode )
1625                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1626                                                 udvm_tvb, offset, 1, display_bytecode);
1627                         operand = ( bytecode & 0x1f) + 65504;
1628                         *start_offset = offset;
1629                         *value = operand;
1630                         offset ++;
1631                 }else{
1632                 /*
1633                  * 110nnnnn nnnnnnnn               memory[N]           0 - 65535
1634                  */
1635                         display_bytecode = bytecode & 0xe0;
1636                         if ( display_udvm_bytecode )
1637                                 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1638                                                 udvm_tvb, offset, 1, display_bytecode);
1639                         operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x1fff);
1640                         *is_memory_address = TRUE;
1641                         *start_offset = offset;
1642                         *value = operand;
1643                         offset = offset +2;
1644                 }
1645                         
1646         default :
1647                 break;
1648         }
1649         return offset;
1650 }
1651 /* Register the protocol with Ethereal */
1652
1653
1654 /* If this dissector uses sub-dissector registration add a registration routine.
1655    This format is required because a script is used to find these routines and
1656    create the code that calls these routines.
1657 */
1658 void
1659 proto_reg_handoff_sigcomp(void)
1660 {
1661         static dissector_handle_t sigcomp_handle;
1662         static int Initialized=FALSE;
1663         static int udp_port1 = 5555;
1664         static int udp_port2 = 6666;
1665
1666         if (!Initialized) {
1667                 sigcomp_handle = new_create_dissector_handle(dissect_sigcomp,
1668                         proto_sigcomp);
1669                 Initialized=TRUE;
1670         }else{
1671                 dissector_delete("udp.port", udp_port1, sigcomp_handle);
1672                 dissector_delete("udp.port", udp_port2, sigcomp_handle);
1673         }
1674
1675         udp_port1 = SigCompUDPPort1;
1676         udp_port2 = SigCompUDPPort2;
1677
1678
1679         dissector_add("udp.port", SigCompUDPPort1, sigcomp_handle);
1680         dissector_add("udp.port", SigCompUDPPort2, sigcomp_handle);
1681
1682
1683 }
1684
1685 /* this format is require because a script is used to build the C function
1686    that calls all the protocol registration.
1687 */
1688
1689 void
1690 proto_register_sigcomp(void)
1691 {                 
1692
1693 /* Setup list of header fields  See Section 1.6.1 for details*/
1694         static hf_register_info hf[] = {
1695                 { &hf_sigcomp_t_bit,
1696                         { "T bit", "sigcomp.t.bit",
1697                         FT_UINT8, BASE_DEC, NULL, 0x04,          
1698                         "Sigcomp T bit", HFILL }
1699                 },
1700                 { &hf_sigcomp_len,
1701                         { "Partial state id. len.","sigcomp.length",
1702                         FT_UINT8, BASE_HEX, VALS(&length_encoding_vals), 0x03,          
1703                         "Sigcomp length", HFILL }
1704                 },
1705                 { &hf_sigcomp_returned_feedback_item,
1706                         { "Returned_feedback item", "sigcomp.returned.feedback.item",
1707                         FT_BYTES, BASE_HEX, NULL, 0x0,          
1708                         "Returned feedback item", HFILL }
1709                 },
1710                 { &hf_sigcomp_partial_state,
1711                         { "Partial state identifier", "sigcomp.partial.state.identifier",
1712                         FT_BYTES, BASE_HEX, NULL, 0x0,          
1713                         "Partial state identifier", HFILL }
1714                 },
1715                 { &hf_sigcomp_returned_feedback_item_len,
1716                         { "Returned feedback item length", "sigcomp.returned.feedback.item.len",
1717                         FT_UINT8, BASE_DEC, NULL, 0x0,          
1718                         "Returned feedback item length", HFILL }
1719                 },
1720                 { &hf_sigcomp_code_len,
1721                         { "Code length","sigcomp.code.len",
1722                         FT_UINT16, BASE_HEX, NULL, 0x0,          
1723                         "Code length", HFILL }
1724                 },
1725                 { &hf_sigcomp_destination,
1726                         { "Destination","sigcomp.destination",
1727                         FT_UINT8, BASE_HEX, VALS(&destination_address_encoding_vals), 0xf,          
1728                         "Destination", HFILL }
1729                 },
1730                 { &hf_sigcomp_udvm_instr,
1731                         { "UDVM instruction code","sigcomp.udvm.instr",
1732                         FT_UINT8, BASE_DEC, VALS(&udvm_instruction_code_vals), 0x0,          
1733                         "UDVM instruction code", HFILL }
1734                 },
1735                 { &hf_udvm_multitype_bytecode,
1736                         { "UDVM bytecode", "sigcomp.udvm.multyt.bytecode",
1737                         FT_UINT8, BASE_HEX, VALS(&display_bytecode_vals), 0x0,          
1738                         "UDVM bytecode", HFILL }
1739                 },
1740                 { &hf_udvm_reference_bytecode,
1741                         { "UDVM bytecode", "sigcomp.udvm.ref.bytecode",
1742                         FT_UINT8, BASE_HEX, VALS(&display_ref_bytecode_vals), 0x0,          
1743                         "UDVM bytecode", HFILL }
1744                 },
1745                 { &hf_udvm_literal_bytecode,
1746                         { "UDVM bytecode", "sigcomp.udvm.lit.bytecode",
1747                         FT_UINT8, BASE_HEX, VALS(&display_lit_bytecode_vals), 0x0,          
1748                         "UDVM bytecode", HFILL }
1749                 },
1750                 { &hf_udvm_operand,
1751                         { "UDVM operand", "sigcomp.udvm.operand",
1752                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1753                         "UDVM operand", HFILL }
1754                 },
1755                 { &hf_udvm_length,
1756                         { " %Length", "sigcomp.udvm.length",
1757                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1758                         "Length", HFILL }
1759                 },
1760                 { &hf_udvm_destination,
1761                         { " %Destination", "sigcomp.udvm.destination",
1762                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1763                         "Destination", HFILL }
1764                 },
1765                 { &hf_udvm_at_address,
1766                         { " @Address(mem_add_of_inst + D) mod 2^16)", "sigcomp.udvm.at.address",
1767                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1768                         "Address", HFILL }
1769                 },
1770                 { &hf_udvm_address,
1771                         { " %Address", "sigcomp.udvm.length",
1772                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1773                         "Address", HFILL }
1774                 },
1775                 { &hf_udvm_literal_num,
1776                         { " #n", "sigcomp.udvm.literal-num",
1777                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1778                         "Literal number", HFILL }
1779                 },
1780                 { &hf_udvm_value,
1781                         { " %Value", "sigcomp.udvm.value",
1782                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1783                         "Value", HFILL }
1784                 },
1785                 { &hf_udvm_addr_value,
1786                         { " %Value[memory address]", "sigcomp.udvm.value",
1787                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1788                         "Value", HFILL }
1789                 },
1790                 { &hf_partial_identifier_start,
1791                         { " %Partial identifier start", "sigcomp.udvm.partial.identifier.start",
1792                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1793                         "Partial identifier start", HFILL }
1794                 },
1795                 { &hf_partial_identifier_length,
1796                         { " %Partial identifier length", "sigcomp.udvm.partial.identifier.length",
1797                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1798                         "Partial identifier length", HFILL }
1799                 },
1800                 { &hf_state_begin,
1801                         { " %State begin", "sigcomp.udvm.state.begin",
1802                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1803                         "State begin", HFILL }
1804                 },
1805                 { &hf_udvm_state_length,
1806                         { " %State length", "sigcomp.udvm.state.length",
1807                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1808                         "State length", HFILL }
1809                 },
1810
1811                 { &hf_udvm_state_length_addr,
1812                         { " %State length[memory address]", "sigcomp.udvm.state.length.addr",
1813                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1814                         "State length", HFILL }
1815                 },
1816                 { &hf_udvm_state_address,
1817                         { " %State address", "sigcomp.udvm.start.address",
1818                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1819                         "State address", HFILL }
1820                 },
1821                 { &hf_udvm_state_address_addr,
1822                         { " %State address[memory address]", "sigcomp.udvm.start.address.addr",
1823                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1824                         "State address", HFILL }
1825                 },
1826                 { &hf_udvm_state_instr,
1827                         { " %State instruction", "sigcomp.udvm.start.instr",
1828                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1829                         "State instruction", HFILL }
1830                 },
1831                 { &hf_udvm_operand_1,
1832                         { " $Operand 1[memory address]", "sigcomp.udvm.operand.1",
1833                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1834                         "Reference $ Operand 1", HFILL }
1835                 },
1836                 { &hf_udvm_operand_2,
1837                         { " %Operand 2", "sigcomp.udvm.operand.2",
1838                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1839                         "Operand 2", HFILL }
1840                 },
1841                 { &hf_udvm_operand_2_addr,
1842                         { " %Operand 2[memory address]", "sigcomp.udvm.operand.2.addr",
1843                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1844                         "Operand 2", HFILL }
1845                 },
1846                 { &hf_udvm_j,
1847                         { " %j", "sigcomp.udvm.j",
1848                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1849                         "j", HFILL }
1850                 },
1851                 { &hf_udvm_output_start,
1852                         { " %Output_start", "sigcomp.output.start",
1853                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1854                         "Output start", HFILL }
1855                 },
1856                 { &hf_udvm_output_start_addr,
1857                         { " %Output_start[memory address]", "sigcomp.output.start.addr",
1858                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1859                         "Output start", HFILL }
1860                 },
1861                 { &hf_udvm_output_length,
1862                         { " %Output_length", "sigcomp.output.length",
1863                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1864                         "Output length", HFILL }
1865                 },
1866                 { &hf_udvm_output_length_addr,
1867                         { " %Output_length[memory address]", "sigcomp.output.length.addr",
1868                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1869                         "Output length", HFILL }
1870                 },
1871                 { &hf_udvm_req_feedback_loc,
1872                         { " %Requested feedback location", "sigcomp.req.feedback.loc",
1873                         FT_UINT16, BASE_DEC, NULL, 0x0,
1874                         "Requested feedback location", HFILL }
1875                 },
1876                 { &hf_udvm_min_acc_len,
1877                         { " %Minimum access length", "sigcomp.min.acc.len",
1878                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1879                         "Output length", HFILL }
1880                 },
1881                 { &hf_udvm_state_ret_pri,
1882                         { " %State retention priority", "sigcomp.udvm.state.ret.pri",
1883                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1884                         "Output length", HFILL }
1885                 },
1886                 { &hf_udvm_ret_param_loc,
1887                         { " %Returned parameters location", "sigcomp.ret.param.loc",
1888                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1889                         "Output length", HFILL }
1890                 },
1891                 { &hf_udvm_position,
1892                         { " %Position", "sigcomp.udvm.position",
1893                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1894                         "Position", HFILL }
1895                 },
1896                 { &hf_udvm_ref_dest,
1897                         { " $Destination[memory address]", "sigcomp.udvm.ref.destination",
1898                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1899                         "(reference)Destination", HFILL }
1900                 },
1901                 { &hf_udvm_bits,
1902                         { " %Bits", "sigcomp.udvm.bits",
1903                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1904                         "Bits", HFILL }
1905                 },
1906                 { &hf_udvm_lower_bound,
1907                         { " %Lower bound", "sigcomp.udvm.lower.bound",
1908                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1909                         "Lower_bound", HFILL }
1910                 },
1911                 { &hf_udvm_upper_bound,
1912                         { " %Upper bound", "sigcomp.udvm.upper.bound",
1913                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1914                         "Upper bound", HFILL }
1915                 },
1916                 { &hf_udvm_uncompressed,
1917                         { " %Uncompressed", "sigcomp.udvm.uncompressed",
1918                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1919                         "Uncompressed", HFILL }
1920                 },
1921                 { &hf_udvm_start_value,
1922                         { " %Start value", "sigcomp.udvm.start.value",
1923                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1924                         "Start value", HFILL }
1925                 },
1926                 { &hf_udvm_offset,
1927                         { " %Offset", "sigcomp.udvm.offset",
1928                         FT_UINT16, BASE_DEC, NULL, 0x0,          
1929                         "Offset", HFILL }
1930                 },
1931         };
1932
1933 /* Setup protocol subtree array */
1934         static gint *ett[] = {
1935                 &ett_sigcomp,
1936                 &ett_sigcomp_udvm,
1937         };
1938
1939         module_t *sigcomp_module;
1940
1941 /* Register the protocol name and description */
1942         proto_sigcomp = proto_register_protocol("Signaling Compression",
1943             "SIGCOMP", "sigcomp");
1944
1945 /* Required function calls to register the header fields and subtrees used */
1946         proto_register_field_array(proto_sigcomp, hf, array_length(hf));
1947         proto_register_subtree_array(ett, array_length(ett));
1948
1949 /* Register a configuration option for port */
1950         sigcomp_module = prefs_register_protocol(proto_sigcomp,
1951                                                                                           proto_reg_handoff_sigcomp);
1952
1953         prefs_register_uint_preference(sigcomp_module, "udp.port",
1954                                                                    "Sigcomp UDP Port 1",
1955                                                                    "Set UDP port 1 for SigComp messages",
1956                                                                    10,
1957                                                                    &SigCompUDPPort1);
1958
1959         prefs_register_uint_preference(sigcomp_module, "udp.port2",
1960                                                                    "Sigcomp UDP Port 2",
1961                                                                    "Set UDP port 2 for SigComp messages",
1962                                                                    10,
1963                                                                    &SigCompUDPPort2);
1964         prefs_register_bool_preference(sigcomp_module, "display.udvm.code",
1965                                                                    "Dissect the UDVM code",
1966                                                                    "Preference wether to Dissect the UDVM code or not",
1967                                                                    &dissect_udvm_code);
1968
1969         prefs_register_bool_preference(sigcomp_module, "display.bytecode",
1970                                                                    "Display the bytecode of operands",
1971                                                                    "preference wether to display the bytecode in UDVM operands or not",
1972                                                                    &display_udvm_bytecode);
1973
1974
1975 }