GSM A DTAP: add UMTS EVS to supported codecs list IE
[metze/wireshark/wip.git] / epan / dissectors / packet-sigcomp.c
index 61d886dc18a09f708f3d750e05f2ac17fde0a14a..0742f3370b068a0656fdfa1be0b75af30eedede8 100644 (file)
@@ -6,19 +6,7 @@
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0-or-later
  * References:
  * http://www.ietf.org/rfc/rfc3320.txt?number=3320
  * http://www.ietf.org/rfc/rfc3321.txt?number=3321
@@ -30,7 +18,6 @@
 
 #include "config.h"
 
-#include <math.h>
 #include <epan/packet.h>
 #include <epan/prefs.h>
 #include <epan/expert.h>
@@ -38,8 +25,9 @@
 #include <epan/strutil.h>
 #include <epan/exceptions.h>
 
-#include <wsutil/sha1.h>
+#include <wsutil/wsgcrypt.h>
 #include <wsutil/crc16.h>
+#include <wsutil/pow2.h>
 
 void proto_register_sigcomp(void);
 void proto_reg_handoff_sigcomp(void);
@@ -159,6 +147,7 @@ static gint ett_raw_text            = -1;
 
 static expert_field ei_sigcomp_nack_failed_op_code = EI_INIT;
 static expert_field ei_sigcomp_invalid_instruction = EI_INIT;
+static expert_field ei_sigcomp_invalid_shift_value = EI_INIT;
 /* Generated from convert_proto_tree_add_text.pl */
 static expert_field ei_sigcomp_tcp_fragment = EI_INIT;
 static expert_field ei_sigcomp_decompression_failure = EI_INIT;
@@ -168,21 +157,22 @@ static expert_field ei_sigcomp_sigcomp_message_decompression_failure = EI_INIT;
 static expert_field ei_sigcomp_execution_of_this_instruction_is_not_implemented = EI_INIT;
 
 static dissector_handle_t sip_handle;
-/* set the udp ports */
-static guint SigCompUDPPort1 = 5555;
-static guint SigCompUDPPort2 = 6666;
+static dissector_handle_t sigcomp_handle;
 
 /* set the tcp ports */
-static guint SigCompTCPPort1 = 5555;
-static guint SigCompTCPPort2 = 6666;
+#define SIGCOMP_TCP_PORT_RANGE "5555,6666" /* Not IANA registered */
 
 /* Default preference whether to display the bytecode in UDVM operands or not */
 static gboolean display_udvm_bytecode = FALSE;
 /* Default preference whether to dissect the UDVM code or not */
-static gboolean dissect_udvm_code = TRUE;
+/* WARNING: Setting this to true might result in the entire dissector being
+   disabled by default or removed completely. */
+static gboolean dissect_udvm_code = FALSE;
 static gboolean display_raw_txt = FALSE;
 /* Default preference whether to decompress the message or not */
-static gboolean decompress = TRUE;
+/* WARNING: Setting this to true might result in the entire dissector being
+   disabled by default or removed completely. */
+static gboolean decompress = FALSE;
 /* Default preference whether to print debug info at execution of UDVM
  * 0 = No printout
  * 1 = details level 1
@@ -1121,7 +1111,7 @@ static void udvm_state_create(guint8 *state_buff,guint8 *state_identifier,guint1
     if ( dummy_buff == NULL ) {
         g_hash_table_insert(state_buffer_table, g_strdup(partial_state_str), state_buff);
     } else {
-        /* The buffer allocated by sigcomp-udvm.c wasen't needed so free it
+        /* The buffer allocated by sigcomp-udvm.c wasn't needed so free it
          */
         g_free(state_buff);
 
@@ -1287,6 +1277,8 @@ decode_udvm_literal_operand(guint8 *buff,guint operand_address, guint16 *value)
     guint   offset = operand_address;
     guint8  temp_data;
 
+    if (operand_address >= UDVM_MEMORY_SIZE)
+        return -1;
     bytecode = buff[operand_address];
     test_bits = bytecode >> 7;
     if (test_bits == 1) {
@@ -1352,6 +1344,8 @@ dissect_udvm_reference_operand_memory(guint8 *buff,guint operand_address, guint1
     guint8  temp_data;
     guint16 temp_data16;
 
+    if (operand_address >= UDVM_MEMORY_SIZE)
+        return -1;
     bytecode = buff[operand_address];
     test_bits = bytecode >> 7;
     if (test_bits == 1) {
@@ -1399,7 +1393,7 @@ dissect_udvm_reference_operand_memory(guint8 *buff,guint operand_address, guint1
     }
 
     if (offset >= UDVM_MEMORY_SIZE || *result_dest >= UDVM_MEMORY_SIZE - 1 )
-        THROW(ReportedBoundsError);
+        return -1;
 
     return offset;
 }
@@ -1432,6 +1426,8 @@ decode_udvm_multitype_operand(guint8 *buff,guint operand_address, guint16 *value
 
     *value = 0;
 
+    if (operand_address >= UDVM_MEMORY_SIZE)
+        return -1;
     bytecode = buff[operand_address];
     test_bits = ( bytecode & 0xc0 ) >> 6;
     switch (test_bits ) {
@@ -1580,13 +1576,13 @@ decode_udvm_address_operand(guint8 *buff,guint operand_address, guint16 *value,g
 {
     guint32 result;
     guint16 value1;
-    guint   next_opreand_address;
+    gint   next_operand_address;
 
-    next_opreand_address = decode_udvm_multitype_operand(buff, operand_address, &value1);
+    next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value1);
     result = value1 & 0xffff;
     result = result + current_address;
     *value = result & 0xffff;
-    return next_opreand_address;
+    return next_operand_address;
 }
 
 
@@ -1670,7 +1666,7 @@ decomp_dispatch_get_bits(
     }
 
     /*
-     * Check we can suppy the required number of bits now, before we alter
+     * Check we can supply the required number of bits now, before we alter
      * the input buffer's state.
      */
     if (*remaining_bits + extra_bytes_available * 8 < length)
@@ -1716,7 +1712,7 @@ decomp_dispatch_get_bits(
         *input_bits &= 0x00FF;                 /* Leave just the remaining bits */
     }
 
-    if (bit_order != 0)
+    if ((bit_order != 0) && (length <= 16))
     {
         /* Bit reverse the entire word. */
         guint16 lsb = reverse[(value >> 8) & 0xFF];
@@ -1757,7 +1753,7 @@ decompress_sigcomp_message(tvbuff_t *bytecode_tvb, tvbuff_t *message_tvb, packet
     guint          operand_address;
     guint          input_address;
     guint16        output_address             = 0;
-    guint          next_operand_address;
+    gint           next_operand_address;
     guint8         octet;
     guint8         msb;
     guint8         lsb;
@@ -1787,8 +1783,8 @@ decompress_sigcomp_message(tvbuff_t *bytecode_tvb, tvbuff_t *message_tvb, packet
     guint          maximum_UDVM_cycles;
     guint8        *sha1buff;
     unsigned char  sha1_digest_buf[STATE_BUFFER_SIZE];
-    sha1_context   ctx;
-    proto_item    *addr_item = NULL;
+    gcry_md_hd_t   sha1_handle;
+    proto_item    *addr_item = NULL, *ti = NULL;
 
 
     /* UDVM operand variables */
@@ -1931,7 +1927,7 @@ decompress_sigcomp_message(tvbuff_t *bytecode_tvb, tvbuff_t *message_tvb, packet
                         "UDVM EXECUTION STARTED at Address: %u Message size %u", current_address, msg_end);
 
     /* Largest allowed size for a message is UDVM_MEMORY_SIZE = 65536  */
-    out_buff = (guint8 *)g_malloc(UDVM_MEMORY_SIZE);
+    out_buff = (guint8 *)wmem_alloc(pinfo->pool, UDVM_MEMORY_SIZE);
 
     /* Reset offset so proto_tree_add_xxx items below accurately reflect the bytes they represent */
     offset = 0;
@@ -1964,10 +1960,6 @@ execute_next_instruction:
         if ( output_address > 0 ) {
             /* At least something got decompressed, show it */
             decomp_tvb = tvb_new_child_real_data(message_tvb, out_buff,output_address,output_address);
-            /* Arrange that the allocated packet data copy be freed when the
-             * tvbuff is freed.
-             */
-            tvb_set_free_cb( decomp_tvb, g_free );
             /* Add the tvbuff to the list of tvbuffs to which the tvbuff we
              * were handed refers, so it'll get cleaned up when that tvbuff
              * is cleaned up.
@@ -1976,7 +1968,6 @@ execute_next_instruction:
             proto_tree_add_expert(udvm_tree, pinfo, &ei_sigcomp_sigcomp_message_decompression_failure, decomp_tvb, 0, -1);
             return decomp_tvb;
         }
-        g_free(out_buff);
         return NULL;
         break;
 
@@ -1988,6 +1979,8 @@ execute_next_instruction:
         /* $operand_1*/
         operand_address = current_address + 1;
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
@@ -1996,6 +1989,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %operand_2*/
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
@@ -2030,6 +2025,8 @@ execute_next_instruction:
         /* $operand_1*/
         operand_address = current_address + 1;
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
@@ -2038,6 +2035,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %operand_2*/
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
@@ -2072,6 +2071,8 @@ execute_next_instruction:
         /* $operand_1*/
         operand_address = current_address + 1;
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
@@ -2105,6 +2106,8 @@ execute_next_instruction:
         /* $operand_1*/
         operand_address = current_address + 1;
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
@@ -2113,10 +2116,16 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %operand_2*/
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
-            proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
+            ti = proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
         }
+        if (operand_2 > 15) {
+            expert_add_info(pinfo, ti, &ei_sigcomp_invalid_shift_value);
+            break;
+        }
         offset += (next_operand_address-operand_address);
         if (show_instr_detail_level == 1)
         {
@@ -2146,6 +2155,8 @@ execute_next_instruction:
         /* $operand_1*/
         operand_address = current_address + 1;
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
@@ -2154,10 +2165,16 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %operand_2*/
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
-            proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
+            ti = proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
         }
+        if (operand_2 > 15) {
+            expert_add_info(pinfo, ti, &ei_sigcomp_invalid_shift_value);
+            break;
+        }
         offset += (next_operand_address-operand_address);
         if (show_instr_detail_level == 1)
         {
@@ -2186,6 +2203,8 @@ execute_next_instruction:
         /* $operand_1*/
         operand_address = current_address + 1;
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
@@ -2194,6 +2213,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %operand_2*/
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
@@ -2226,6 +2247,8 @@ execute_next_instruction:
         /* $operand_1*/
         operand_address = current_address + 1;
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
@@ -2234,6 +2257,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %operand_2*/
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
@@ -2267,6 +2292,8 @@ execute_next_instruction:
         /* $operand_1*/
         operand_address = current_address + 1;
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
@@ -2275,6 +2302,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %operand_2*/
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
@@ -2315,6 +2344,8 @@ execute_next_instruction:
         /* $operand_1*/
         operand_address = current_address + 1;
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
@@ -2323,6 +2354,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %operand_2*/
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
@@ -2365,6 +2398,8 @@ execute_next_instruction:
         /* $operand_1*/
         operand_address = current_address + 1;
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &operand_1, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_1, bytecode_tvb, offset, (next_operand_address-operand_address), operand_1,
                                 "Addr: %u      operand_1 %u", operand_address, operand_1);
@@ -2373,6 +2408,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %operand_2*/
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_operand_2, bytecode_tvb, offset, (next_operand_address-operand_address), operand_2,
                                 "Addr: %u      operand_2 %u", operand_address, operand_2);
@@ -2435,6 +2472,8 @@ execute_next_instruction:
         operand_address = current_address + 1;
         /* %position */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (print_level_1 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_position, bytecode_tvb, offset, (next_operand_address-operand_address), position,
                                 "Addr: %u      position %u", operand_address, position);
@@ -2444,6 +2483,8 @@ execute_next_instruction:
 
         /* %length */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (print_level_1 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
                                 "Addr: %u      Length %u", operand_address, length);
@@ -2453,6 +2494,8 @@ execute_next_instruction:
 
         /* $destination */
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &ref_destination, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (print_level_1 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_ref_dest, bytecode_tvb, offset, (next_operand_address-operand_address), ref_destination,
                                 "Addr: %u      $destination %u", operand_address, ref_destination);
@@ -2472,7 +2515,9 @@ execute_next_instruction:
                                 NULL, "byte_copy_right = %u", byte_copy_right);
         }
 
-        sha1_starts( &ctx );
+        if (gcry_md_open(&sha1_handle, GCRY_MD_SHA1, 0)) {
+            goto decompression_failure;
+        }
 
         while (n<length) {
             guint16 handle_now = length;
@@ -2481,9 +2526,12 @@ execute_next_instruction:
                 handle_now = byte_copy_right - position;
             }
 
-            if (k + handle_now >= UDVM_MEMORY_SIZE)
+            if ((k + handle_now >= UDVM_MEMORY_SIZE) ||
+                (n + handle_now >= UDVM_MEMORY_SIZE)) {
+                gcry_md_close(sha1_handle);
                 goto decompression_failure;
-            sha1_update( &ctx, &buff[k], handle_now );
+            }
+            gcry_md_write(sha1_handle, &buff[k], handle_now);
 
             k = ( k + handle_now ) & 0xffff;
             n = ( n + handle_now ) & 0xffff;
@@ -2493,7 +2541,8 @@ execute_next_instruction:
             }
         }
 
-        sha1_finish( &ctx, sha1_digest_buf );
+        memcpy(sha1_digest_buf, gcry_md_read(sha1_handle, 0), HASH_SHA1_LENGTH);
+        gcry_md_close(sha1_handle);
 
         k = ref_destination;
 
@@ -2526,6 +2575,8 @@ execute_next_instruction:
         operand_address = current_address + 1;
         /* %address */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &addr);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_address, bytecode_tvb, offset, (next_operand_address-operand_address), addr,
                                 "Addr: %u      Address %u", operand_address, addr);
@@ -2534,6 +2585,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %value */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2)
         {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_value, bytecode_tvb, offset, (next_operand_address-operand_address), value,
@@ -2570,6 +2623,8 @@ execute_next_instruction:
         operand_address = current_address + 1;
         /* %address */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &addr);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_address, bytecode_tvb, offset, (next_operand_address-operand_address), addr,
                                 "Addr: %u      Address %u", operand_address, addr);
@@ -2579,6 +2634,8 @@ execute_next_instruction:
 
         /* #n */
         next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_literal_num, bytecode_tvb, offset, (next_operand_address-operand_address), n,
                                 "Addr: %u      n %u", operand_address, n);
@@ -2596,6 +2653,8 @@ execute_next_instruction:
             n = n - 1;
             /* %value */
             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
+            if (next_operand_address < 0)
+                goto decompression_failure;
             lsb = value & 0xff;
             msb = value >> 8;
 
@@ -2628,6 +2687,8 @@ execute_next_instruction:
         operand_address = current_address + 1;
         /* %value */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_value, bytecode_tvb, offset, (next_operand_address-operand_address), value,
                                 "Addr: %u      Value %u", operand_address, value);
@@ -2672,6 +2733,8 @@ execute_next_instruction:
         operand_address = current_address + 1;
         /* %value */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_address, bytecode_tvb, offset, (next_operand_address-operand_address), destination,
                                 "Addr: %u      Value %u", operand_address, destination);
@@ -2728,6 +2791,8 @@ execute_next_instruction:
         operand_address = current_address + 1;
         /* %position */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_position, bytecode_tvb, offset, (next_operand_address-operand_address), position,
                                 "Addr: %u      position %u", operand_address, position);
@@ -2737,6 +2802,8 @@ execute_next_instruction:
 
         /* %length */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
                                 "Addr: %u      Length %u", operand_address, length);
@@ -2746,6 +2813,8 @@ execute_next_instruction:
 
         /* %destination */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_ref_dest, bytecode_tvb, offset, (next_operand_address-operand_address), destination,
                                 "Addr: %u      Destination %u", operand_address, destination);
@@ -2817,6 +2886,8 @@ execute_next_instruction:
         operand_address = current_address + 1;
         /* %position */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_position, bytecode_tvb, offset, (next_operand_address-operand_address), position,
                                 "Addr: %u      position %u", operand_address, position);
@@ -2826,6 +2897,8 @@ execute_next_instruction:
 
         /* %length */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
                                 "Addr: %u      Length %u", operand_address, length);
@@ -2836,6 +2909,8 @@ execute_next_instruction:
 
         /* $destination */
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &ref_destination, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_ref_dest, bytecode_tvb, offset, (next_operand_address-operand_address), ref_destination,
                                 "Addr: %u      destination %u", operand_address, ref_destination);
@@ -2913,6 +2988,8 @@ execute_next_instruction:
         operand_address = current_address + 1;
         /* %offset */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &multy_offset);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_offset, bytecode_tvb, offset, (next_operand_address-operand_address), multy_offset,
                                 "Addr: %u      offset %u", operand_address, multy_offset);
@@ -2922,6 +2999,8 @@ execute_next_instruction:
 
         /* %length */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
                                 "Addr: %u      Length %u", operand_address, length);
@@ -2932,6 +3011,8 @@ execute_next_instruction:
 
         /* $destination */
         next_operand_address = dissect_udvm_reference_operand_memory(buff, operand_address, &ref_destination, &result_dest);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_ref_dest, bytecode_tvb, offset, (next_operand_address-operand_address), ref_destination,
                                 "Addr: %u      $destination %u", operand_address, ref_destination);
@@ -3046,6 +3127,8 @@ execute_next_instruction:
 
         /* %address */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &addr);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_address, bytecode_tvb, offset, (next_operand_address-operand_address), addr,
                                 "Addr: %u      Address %u", operand_address, addr);
@@ -3055,6 +3138,8 @@ execute_next_instruction:
 
         /*  %length, */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
                                 "Addr: %u      Length %u", operand_address, length);
@@ -3063,6 +3148,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %start_value */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &start_value);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_start_value, bytecode_tvb, offset, (next_operand_address-operand_address), start_value,
                                 "Addr: %u      start_value %u", operand_address, start_value);
@@ -3072,6 +3159,8 @@ execute_next_instruction:
 
         /* %offset */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &multy_offset);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_offset, bytecode_tvb, offset, (next_operand_address-operand_address), multy_offset,
                                 "Addr: %u      offset %u", operand_address, multy_offset);
@@ -3084,7 +3173,7 @@ execute_next_instruction:
                                 current_address, addr, length, start_value, multy_offset);
         }
         current_address = next_operand_address;
-        /* exetute the instruction
+        /* execute the instruction
          * The sequence of values used by the MEMSET instruction is specified by
          * the following formula:
          *
@@ -3127,6 +3216,8 @@ execute_next_instruction:
         /* @address */
         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
         next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
                                 "Addr: %u      @Address %u", operand_address, at_address);
@@ -3153,6 +3244,8 @@ execute_next_instruction:
 
         /* %value_1 */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value_1);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_value, bytecode_tvb, offset, (next_operand_address-operand_address), value_1,
                                 "Addr: %u      Value %u", operand_address, value_1);
@@ -3162,6 +3255,8 @@ execute_next_instruction:
 
         /* %value_2 */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value_2);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_value, bytecode_tvb, offset, (next_operand_address-operand_address), value_2,
                                 "Addr: %u      Value %u", operand_address, value_2);
@@ -3172,6 +3267,8 @@ execute_next_instruction:
         /* @address_1 */
         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_1);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         at_address_1 = ( current_address + at_address_1) & 0xffff;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address_1,
@@ -3184,6 +3281,8 @@ execute_next_instruction:
         /* @address_2 */
         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_2);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         at_address_2 = ( current_address + at_address_2) & 0xffff;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address_2,
@@ -3195,6 +3294,8 @@ execute_next_instruction:
         /* @address_3 */
         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_3);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         at_address_3 = ( current_address + at_address_3) & 0xffff;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address_3,
@@ -3230,6 +3331,8 @@ execute_next_instruction:
         operand_address = current_address + 1;
         /* @address */
         next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
                                 "Addr: %u      @Address %u", operand_address, at_address);
@@ -3312,6 +3415,8 @@ execute_next_instruction:
          * Number of addresses in the instruction
          */
         next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (print_level_2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_literal_num, bytecode_tvb, offset, (next_operand_address-operand_address), n,
                                 "Addr: %u      n %u", operand_address, n);
@@ -3320,6 +3425,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %j */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &j);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (print_level_2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_j, bytecode_tvb, offset, (next_operand_address-operand_address), j,
                                 "Addr: %u      j %u", operand_address, j);
@@ -3331,6 +3438,8 @@ execute_next_instruction:
             /* @address_n-1 */
             /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_1);
+            if (next_operand_address < 0)
+                goto decompression_failure;
             at_address_1 = ( instruction_address + at_address_1) & 0xffff;
             if (print_level_2 ) {
                 proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address_1,
@@ -3367,6 +3476,8 @@ execute_next_instruction:
 
         /* %value */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (print_level_2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_value, bytecode_tvb, offset, (next_operand_address-operand_address), value,
                                 "Addr: %u      Value %u", operand_address, value);
@@ -3376,6 +3487,8 @@ execute_next_instruction:
 
         /* %position */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (print_level_2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_position, bytecode_tvb, offset, (next_operand_address-operand_address), position,
                                 "Addr: %u      position %u", operand_address, position);
@@ -3385,6 +3498,8 @@ execute_next_instruction:
 
         /* %length */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (print_level_2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
                                 "Addr: %u      Length %u", operand_address, length);
@@ -3394,6 +3509,8 @@ execute_next_instruction:
 
         /* @address */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         at_address = ( current_address + at_address) & 0xffff;
         if (print_level_2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
@@ -3460,6 +3577,8 @@ execute_next_instruction:
         operand_address = current_address + 1;
         /* %length */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
                                 "Addr: %u      Length %u", operand_address, length);
@@ -3469,6 +3588,8 @@ execute_next_instruction:
 
         /* %destination */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_destination, bytecode_tvb, offset, (next_operand_address-operand_address), destination,
                                 "Addr: %u      Destination %u", operand_address, destination);
@@ -3479,6 +3600,8 @@ execute_next_instruction:
         /* @address */
         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         at_address = ( current_address + at_address) & 0xffff;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
@@ -3588,6 +3711,8 @@ execute_next_instruction:
 
         /* %length */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_length, bytecode_tvb, offset, (next_operand_address-operand_address), length,
                                 "Addr: %u      length %u", operand_address, length);
@@ -3596,6 +3721,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* %destination */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_destination, bytecode_tvb, offset, (next_operand_address-operand_address), destination,
                                 "Addr: %u      Destination %u", operand_address, destination);
@@ -3606,6 +3733,8 @@ execute_next_instruction:
         /* @address */
         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
         next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
                                 "Addr: %u      @Address %u", operand_address, at_address);
@@ -3683,6 +3812,8 @@ execute_next_instruction:
 
         /* %destination */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_destination, bytecode_tvb, offset, (next_operand_address-operand_address), destination,
                                 "Addr: %u      Destination %u", operand_address, destination);
@@ -3693,6 +3824,8 @@ execute_next_instruction:
         /* @address */
         /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
         next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_at_address, bytecode_tvb, offset, (next_operand_address-operand_address), at_address,
                                 "Addr: %u      @Address %u", operand_address, at_address);
@@ -3702,6 +3835,8 @@ execute_next_instruction:
 
         /* #n */
         next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_literal_num, bytecode_tvb, offset, (next_operand_address-operand_address), n,
                                 "Addr: %u      n %u", operand_address, n);
@@ -3766,15 +3901,22 @@ execute_next_instruction:
         while ( m > 0 ) {
             /* %bits_n */
             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &bits_n);
+            if (next_operand_address < 0)
+                goto decompression_failure;
             if (print_in_loop ) {
                 proto_tree_add_uint_format(udvm_tree, hf_udvm_bits, bytecode_tvb, offset, (next_operand_address-operand_address), bits_n,
                                     "Addr: %u      bits_n %u", operand_address, bits_n);
             }
+            if (bits_n > 31)
+                break;
+
             offset += (next_operand_address-operand_address);
             operand_address = next_operand_address;
 
             /* %lower_bound_n */
             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &lower_bound_n);
+            if (next_operand_address < 0)
+                goto decompression_failure;
             if (print_in_loop ) {
                 proto_tree_add_uint_format(udvm_tree, hf_udvm_lower_bound, bytecode_tvb, offset, (next_operand_address-operand_address), lower_bound_n,
                                     "Addr: %u      lower_bound_n %u", operand_address, lower_bound_n);
@@ -3783,6 +3925,8 @@ execute_next_instruction:
             operand_address = next_operand_address;
             /* %upper_bound_n */
             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &upper_bound_n);
+            if (next_operand_address < 0)
+                goto decompression_failure;
             if (print_in_loop ) {
                 proto_tree_add_uint_format(udvm_tree, hf_udvm_upper_bound, bytecode_tvb, offset, (next_operand_address-operand_address), upper_bound_n,
                                     "Addr: %u      upper_bound_n %u", operand_address, upper_bound_n);
@@ -3791,6 +3935,8 @@ execute_next_instruction:
             operand_address = next_operand_address;
             /* %uncompressed_n */
             next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &uncompressed_n);
+            if (next_operand_address < 0)
+                goto decompression_failure;
             if (print_in_loop ) {
                 proto_tree_add_uint_format(udvm_tree, hf_udvm_uncompressed, bytecode_tvb, offset, (next_operand_address-operand_address), uncompressed_n,
                                     "Addr: %u      uncompressed_n %u", operand_address, uncompressed_n);
@@ -3889,6 +4035,8 @@ execute_next_instruction:
          * %partial_identifier_start
          */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_start);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_partial_identifier_start, bytecode_tvb, offset, (next_operand_address-operand_address), p_id_start,
                                 "Addr: %u       partial_identifier_start %u", operand_address, p_id_start);
@@ -3900,6 +4048,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_partial_identifier_length, bytecode_tvb, offset, (next_operand_address-operand_address), p_id_length,
                                 "Addr: %u       partial_identifier_length %u", operand_address, p_id_length);
@@ -3910,6 +4060,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_begin);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_state_begin, bytecode_tvb, offset, (next_operand_address-operand_address), state_begin,
                                 "Addr: %u       state_begin %u", operand_address, state_begin);
@@ -3920,6 +4072,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_length, bytecode_tvb, offset, (next_operand_address-operand_address), state_length,
                                 "Addr: %u       state_length %u", operand_address, state_length);
@@ -3930,6 +4084,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_address, bytecode_tvb, offset, (next_operand_address-operand_address), state_address,
                                 "Addr: %u       state_address %u", operand_address, state_address);
@@ -3940,6 +4096,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_instr, bytecode_tvb, offset, (next_operand_address-operand_address), state_instruction,
                                 "Addr: %u       state_instruction %u", operand_address, state_instruction);
@@ -3984,6 +4142,8 @@ execute_next_instruction:
          * %state_length
          */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_length, bytecode_tvb, offset, (next_operand_address-operand_address), state_length,
                                 "Addr: %u       state_length %u", operand_address, state_length);
@@ -3994,6 +4154,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_address, bytecode_tvb, offset, (next_operand_address-operand_address), state_address,
                                 "Addr: %u       state_address %u", operand_address, state_address);
@@ -4004,6 +4166,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_instr, bytecode_tvb, offset, (next_operand_address-operand_address), state_instruction,
                                 "Addr: %u       state_instruction %u", operand_address, state_instruction);
@@ -4014,6 +4178,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &minimum_access_length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_min_acc_len, bytecode_tvb, offset, (next_operand_address-operand_address), minimum_access_length,
                                 "Addr: %u       minimum_access_length %u", operand_address, minimum_access_length);
@@ -4024,6 +4190,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_retention_priority);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_ret_pri, bytecode_tvb, offset, (next_operand_address-operand_address), state_retention_priority,
                                 "Addr: %u       state_retention_priority %u", operand_address, state_retention_priority);
@@ -4087,7 +4255,7 @@ execute_next_instruction:
             if (print_level_3 ) {
                 proto_tree_add_uint_format(udvm_tree, hf_sigcomp_state_value, bytecode_tvb, 0, 0, buff[k],
                                     "               Addr: %5u State value: %u (0x%x) ASCII(%s)",
-                                    k,buff[k],buff[k],format_text(string, 1));
+                                    k,buff[k],buff[k],format_text(wmem_packet_scope(), string, 1));
             }
             k = ( k + 1 ) & 0xffff;
             n++;
@@ -4109,6 +4277,8 @@ execute_next_instruction:
          * %partial_identifier_start
          */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_start);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_partial_identifier_start, bytecode_tvb, offset, (next_operand_address-operand_address), p_id_start,
                                 "Addr: %u       partial_identifier_start %u", operand_address, p_id_start);
@@ -4120,6 +4290,8 @@ execute_next_instruction:
          * %partial_identifier_length
          */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_partial_identifier_length, bytecode_tvb, offset, (next_operand_address-operand_address), p_id_length,
                                 "Addr: %u       partial_identifier_length %u", operand_address, p_id_length);
@@ -4150,6 +4322,8 @@ execute_next_instruction:
          * %output_start
          */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &output_start);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_output_start, bytecode_tvb, offset, (next_operand_address-operand_address), output_start,
                                 "Addr: %u      output_start %u", operand_address, output_start);
@@ -4160,6 +4334,8 @@ execute_next_instruction:
          * %output_length
          */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &output_length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_output_length, bytecode_tvb, offset, (next_operand_address-operand_address), output_length,
                                 "Addr: %u      output_length %u", operand_address, output_length);
@@ -4208,7 +4384,7 @@ execute_next_instruction:
             if (print_level_3 ) {
                 proto_tree_add_uint_format(udvm_tree, hf_sigcomp_output_value, bytecode_tvb, 0, -1, buff[k],
                                     "               Output value: %u (0x%x) ASCII(%s) from Addr: %u ,output to dispatcher position %u",
-                                    buff[k],buff[k],format_text(string,1), k,output_address);
+                                    buff[k],buff[k],format_text(wmem_packet_scope(), string,1), k,output_address);
             }
             k = ( k + 1 ) & 0xffff;
             output_address ++;
@@ -4232,6 +4408,8 @@ execute_next_instruction:
 
         /* %requested_feedback_location */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &requested_feedback_location);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_req_feedback_loc, bytecode_tvb, offset, (next_operand_address-operand_address), requested_feedback_location,
                                 "Addr: %u      requested_feedback_location %u",
@@ -4241,6 +4419,8 @@ execute_next_instruction:
         operand_address = next_operand_address;
         /* returned_parameters_location */
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &returned_parameters_location);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_ret_param_loc, bytecode_tvb, offset, (next_operand_address-operand_address), returned_parameters_location,
                                 "Addr: %u      returned_parameters_location %u", operand_address, returned_parameters_location);
@@ -4251,6 +4431,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_length, bytecode_tvb, offset, (next_operand_address-operand_address), state_length,
                                 "Addr: %u      state_length %u", operand_address, state_length);
@@ -4261,6 +4443,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_address, bytecode_tvb, offset, (next_operand_address-operand_address), state_address,
                                 "Addr: %u      state_address %u", operand_address, state_address);
@@ -4271,6 +4455,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_instr, bytecode_tvb, offset, (next_operand_address-operand_address), state_instruction,
                                 "Addr: %u      state_instruction %u", operand_address, state_instruction);
@@ -4282,6 +4468,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &minimum_access_length);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_min_acc_len, bytecode_tvb, offset, (next_operand_address-operand_address), minimum_access_length,
                                 "Addr: %u      minimum_access_length %u", operand_address, minimum_access_length);
@@ -4293,6 +4481,8 @@ execute_next_instruction:
          */
         operand_address = next_operand_address;
         next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_retention_priority);
+        if (next_operand_address < 0)
+            goto decompression_failure;
         if (show_instr_detail_level == 2 ) {
             proto_tree_add_uint_format(udvm_tree, hf_udvm_state_ret_pri, bytecode_tvb, offset, (next_operand_address-operand_address), state_retention_priority,
                                 "Addr: %u      state_retention_priority %u", operand_address, state_retention_priority);
@@ -4304,7 +4494,7 @@ execute_next_instruction:
                                 "Addr: %u ## END-MESSAGE (requested_feedback_location=%u, returned_parameters_location=%u, state_length=%u, state_address=%u, state_instruction=%u, minimum_access_length=%u, state_retention_priority=%u)",
                                 current_address, requested_feedback_location, returned_parameters_location, state_length, state_address, state_instruction, minimum_access_length,state_retention_priority);
         }
-        /* TODO: This isn't currently totaly correct as END_INSTRUCTION might not create state */
+        /* TODO: This isn't currently totally correct as END_INSTRUCTION might not create state */
         no_of_state_create++;
         if ( no_of_state_create > 4 ) {
             result_code = 12;
@@ -4350,12 +4540,9 @@ execute_next_instruction:
                     k = ( k + 1 ) & 0xffff;
                 }
 
-                sha1_starts( &ctx );
-                sha1_update( &ctx, (guint8 *) sha1buff, state_length_buff[n] + 8);
-                sha1_finish( &ctx, sha1_digest_buf );
+                gcry_md_hash_buffer(GCRY_MD_SHA1, sha1_digest_buf, (guint8 *) sha1buff, state_length_buff[n] + 8);
                 if (print_level_3 ) {
                     proto_tree_add_bytes_with_length(udvm_tree, hf_sigcomp_sha1_digest, bytecode_tvb, 0, -1, sha1_digest_buf, STATE_BUFFER_SIZE);
-
                 }
 /* begin partial state-id change cco@iptel.org */
 #if 0
@@ -4375,10 +4562,6 @@ execute_next_instruction:
 
         /* At least something got decompressed, show it */
         decomp_tvb = tvb_new_child_real_data(message_tvb, out_buff,output_address,output_address);
-        /* Arrange that the allocated packet data copy be freed when the
-         * tvbuff is freed.
-         */
-        tvb_set_free_cb( decomp_tvb, g_free );
 
         add_new_data_source(pinfo, decomp_tvb, "Decompressed SigComp message");
         proto_tree_add_item(udvm_tree, hf_sigcomp_sigcomp_message_decompressed, decomp_tvb, 0, -1, ENC_NA);
@@ -4394,14 +4577,11 @@ execute_next_instruction:
                             "Addr %u Invalid instruction: %u (0x%x)", current_address,current_instruction,current_instruction);
         break;
     }
-    g_free(out_buff);
     return NULL;
 decompression_failure:
 
     proto_tree_add_expert_format(udvm_tree, pinfo, &ei_sigcomp_decompression_failure, bytecode_tvb, 0, -1,
                         "DECOMPRESSION FAILURE: %s", val_to_str(result_code, result_code_vals,"Unknown (%u)"));
-    g_free(out_buff);
-    THROW(ReportedBoundsError);
     return NULL;
 
 }
@@ -4494,7 +4674,7 @@ dissect_sigcomp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *_
 
     col_clear(pinfo->cinfo, COL_INFO);
 
-    length = tvb_captured_length_remaining(tvb,offset);
+    length = tvb_reported_length(tvb);
 
 try_again:
     /* create display subtree for the protocol */
@@ -4908,8 +5088,8 @@ dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sigcomp_tr
 
             proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_pc, tvb, offset, 2, ENC_BIG_ENDIAN);
             offset = offset +2;
-            proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_sha1, tvb, offset, SHA1_DIGEST_LEN, ENC_NA);
-            offset = offset +SHA1_DIGEST_LEN;
+            proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_sha1, tvb, offset, HASH_SHA1_LENGTH, ENC_NA);
+            offset = offset + HASH_SHA1_LENGTH;
 
             /* Add NACK info to info column */
             col_append_fstr(pinfo->cinfo, COL_INFO, "  NACK reason=%s, opcode=%s",
@@ -6164,7 +6344,7 @@ dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree
                     if ( display_udvm_bytecode )
                         proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
                                 udvm_tvb, offset, 1, display_bytecode);
-                    result = (guint32)pow(2,( bytecode & 0x07) + 8);
+                    result = pow2(guint32, (bytecode & 0x07) + 8);
                     operand = result & 0xffff;
                     *start_offset = offset;
                     *value = operand;
@@ -6179,7 +6359,7 @@ dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree
                         if ( display_udvm_bytecode )
                             proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
                                 udvm_tvb, offset, 1, display_bytecode);
-                        result = (guint32)pow(2,( bytecode & 0x01) + 6);
+                        result = pow2(guint32, (bytecode & 0x01) + 6);
                         operand = result & 0xffff;
                         *start_offset = offset;
                         *value = operand;
@@ -6630,7 +6810,7 @@ proto_register_sigcomp(void)
         { &hf_sigcomp_illegal_escape_code, { "Illegal escape code", "sigcomp.illegal_escape_code", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
         { &hf_sigcomp_end_of_sigcomp_message_indication_found, { "End of SigComp message indication found", "sigcomp.end_of_sigcomp_message_indication_found", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
         { &hf_sigcomp_addr_value, { "Addr", "sigcomp.addr", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
-        { &hf_sigcomp_copying_bytes_literally, { "Copying bytes literally", "sigcomp.copying_bytes_literally", FT_BYTES, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+        { &hf_sigcomp_copying_bytes_literally, { "Copying bytes literally", "sigcomp.copying_bytes_literally", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
         { &hf_sigcomp_data_for_sigcomp_dissector, { "Data handed to the Sigcomp dissector", "sigcomp.data_for_sigcomp_dissector", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
         { &hf_sigcomp_remaining_sigcomp_message, { "Remaining SigComp message", "sigcomp.remaining_sigcomp_message", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
         { &hf_sigcomp_sha1buff, { "sha1buff", "sigcomp.sha1buff", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
@@ -6656,10 +6836,11 @@ proto_register_sigcomp(void)
     static ei_register_info ei[] = {
         { &ei_sigcomp_nack_failed_op_code, { "sigcomp.nack.failed_op_code.expert", PI_SEQUENCE, PI_WARN, "SigComp NACK", EXPFILL }},
         { &ei_sigcomp_invalid_instruction, { "sigcomp.invalid_instruction", PI_PROTOCOL, PI_WARN, "Invalid instruction", EXPFILL }},
+        { &ei_sigcomp_invalid_shift_value, { "sigcomp.invalid_shift_value", PI_PROTOCOL, PI_WARN, "Invalid shift value", EXPFILL }},
         /* Generated from convert_proto_tree_add_text.pl */
         { &ei_sigcomp_sigcomp_message_decompression_failure, { "sigcomp.message_decompression_failure", PI_PROTOCOL, PI_WARN, "SigComp message Decompression failure", EXPFILL }},
         { &ei_sigcomp_execution_of_this_instruction_is_not_implemented, { "sigcomp.execution_of_this_instruction_is_not_implemented", PI_UNDECODED, PI_WARN, "Execution of this instruction is NOT implemented", EXPFILL }},
-        { &ei_sigcomp_decompression_failure, { "sigcomp.decompression_failure", PI_PROTOCOL, PI_WARN, "DECOMPRESSION FAILURE", EXPFILL }},
+        { &ei_sigcomp_decompression_failure, { "sigcomp.decompression_failure_expert", PI_PROTOCOL, PI_WARN, "DECOMPRESSION FAILURE", EXPFILL }},
         { &ei_sigcomp_tcp_fragment, { "sigcomp.tcp_fragment", PI_MALFORMED, PI_ERROR, "TCP Fragment", EXPFILL }},
         { &ei_sigcomp_failed_to_access_state_wireshark_udvm_diagnostic, { "sigcomp.failed_to_access_state_wireshark_udvm_diagnostic", PI_PROTOCOL, PI_WARN, "Failed to Access state Wireshark UDVM diagnostic", EXPFILL }},
         { &ei_sigcomp_all_remaining_parameters_zero, { "sigcomp.all_remaining_parameters", PI_PROTOCOL, PI_NOTE, "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero", EXPFILL }},
@@ -6678,12 +6859,10 @@ proto_register_sigcomp(void)
 
 
 /* Register the protocol name and description */
-    proto_sigcomp = proto_register_protocol("Signaling Compression",
-                                            "SIGCOMP", "sigcomp");
-    proto_raw_sigcomp = proto_register_protocol("Decompressed SigComp message as raw text",
-                                                "Raw_SigComp", "raw_sigcomp");
+    proto_sigcomp = proto_register_protocol("Signaling Compression", "SIGCOMP", "sigcomp");
+    proto_raw_sigcomp = proto_register_protocol("Decompressed SigComp message as raw text", "Raw_SigComp", "raw_sigcomp");
 
-    new_register_dissector("sigcomp", dissect_sigcomp, proto_sigcomp);
+    sigcomp_handle = register_dissector("sigcomp", dissect_sigcomp, proto_sigcomp);
 
 /* Required function calls to register the header fields and subtrees used */
     proto_register_field_array(proto_sigcomp, hf, array_length(hf));
@@ -6693,31 +6872,8 @@ proto_register_sigcomp(void)
     expert_register_field_array(expert_sigcomp, ei, array_length(ei));
 
 /* Register a configuration option for port */
-    sigcomp_module = prefs_register_protocol(proto_sigcomp,
-                                              proto_reg_handoff_sigcomp);
-
-    prefs_register_uint_preference(sigcomp_module, "udp.port",
-                                   "Sigcomp UDP Port 1",
-                                   "Set UDP port 1 for SigComp messages",
-                                   10,
-                                   &SigCompUDPPort1);
-
-    prefs_register_uint_preference(sigcomp_module, "udp.port2",
-                                   "Sigcomp UDP Port 2",
-                                   "Set UDP port 2 for SigComp messages",
-                                   10,
-                                   &SigCompUDPPort2);
-    prefs_register_uint_preference(sigcomp_module, "tcp.port",
-                                   "Sigcomp TCP Port 1",
-                                   "Set TCP port 1 for SigComp messages",
-                                   10,
-                                   &SigCompTCPPort1);
-
-    prefs_register_uint_preference(sigcomp_module, "tcp.port2",
-                                   "Sigcomp TCP Port 2",
-                                   "Set TCP port 2 for SigComp messages",
-                                   10,
-                                   &SigCompTCPPort2);
+    sigcomp_module = prefs_register_protocol(proto_sigcomp, NULL);
+
     prefs_register_bool_preference(sigcomp_module, "display.udvm.code",
                                    "Dissect the UDVM code",
                                    "Preference whether to Dissect the UDVM code or not",
@@ -6754,37 +6910,12 @@ proto_register_sigcomp(void)
 void
 proto_reg_handoff_sigcomp(void)
 {
-    static dissector_handle_t sigcomp_handle;
-    static dissector_handle_t sigcomp_tcp_handle;
-    static gboolean Initialized = FALSE;
-    static guint udp_port1;
-    static guint udp_port2;
-    static guint tcp_port1;
-    static guint tcp_port2;
-
-    if (!Initialized) {
-        sigcomp_handle = find_dissector("sigcomp");
-        sigcomp_tcp_handle = new_create_dissector_handle(dissect_sigcomp_tcp,proto_sigcomp);
-        sip_handle = find_dissector("sip");
-        Initialized=TRUE;
-    } else {
-        dissector_delete_uint("udp.port", udp_port1, sigcomp_handle);
-        dissector_delete_uint("udp.port", udp_port2, sigcomp_handle);
-        dissector_delete_uint("tcp.port", tcp_port1, sigcomp_tcp_handle);
-        dissector_delete_uint("tcp.port", tcp_port2, sigcomp_tcp_handle);
-    }
-
-    udp_port1 = SigCompUDPPort1;
-    udp_port2 = SigCompUDPPort2;
-    tcp_port1 = SigCompTCPPort1;
-    tcp_port2 = SigCompTCPPort2;
-
-
-    dissector_add_uint("udp.port", SigCompUDPPort1, sigcomp_handle);
-    dissector_add_uint("udp.port", SigCompUDPPort2, sigcomp_handle);
-    dissector_add_uint("tcp.port", SigCompTCPPort1, sigcomp_tcp_handle);
-    dissector_add_uint("tcp.port", SigCompTCPPort2, sigcomp_tcp_handle);
+    dissector_handle_t sigcomp_tcp_handle;
 
+    sigcomp_tcp_handle = create_dissector_handle(dissect_sigcomp_tcp,proto_sigcomp);
+    sip_handle = find_dissector_add_dependency("sip",proto_sigcomp);
+    dissector_add_uint_range_with_preference("tcp.port", SIGCOMP_TCP_PORT_RANGE, sigcomp_tcp_handle);
+    dissector_add_uint_range_with_preference("udp.port", SIGCOMP_TCP_PORT_RANGE, sigcomp_handle);
 }
 
 /*