/* packet-sigcomp.c * Routines for Signaling Compression (SigComp) dissection. * Copyright 2004, Anders Broman * * $Id: packet-sigcomp.c,v 1.3 2004/06/29 20:40:12 etxrab Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * References: * http://www.ietf.org/rfc/rfc3320.txt?number=3320 * http://www.ietf.org/rfc/rfc3321.txt?number=3321 * Useful links : * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-impl-guide-02.txt * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-sip-01.txt */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #ifdef NEED_SNPRINTF_H # include "snprintf.h" #endif #include #include "prefs.h" /* Initialize the protocol and registered fields */ static int proto_sigcomp = -1; static int hf_sigcomp_t_bit = -1; static int hf_sigcomp_len = -1; static int hf_sigcomp_returned_feedback_item = -1; static int hf_sigcomp_returned_feedback_item_len = -1; static int hf_sigcomp_code_len = -1; static int hf_sigcomp_destination = -1; static int hf_sigcomp_partial_state = -1; static int hf_sigcomp_udvm_instr = -1; static int hf_udvm_multitype_bytecode = -1; static int hf_udvm_reference_bytecode = -1; static int hf_udvm_literal_bytecode = -1; static int hf_udvm_operand = -1; static int hf_udvm_length = -1; static int hf_udvm_destination = -1; static int hf_udvm_at_address = -1; static int hf_udvm_address = -1; static int hf_udvm_literal_num = -1; static int hf_udvm_value = -1; static int hf_udvm_addr_value = -1; static int hf_partial_identifier_start = -1; static int hf_partial_identifier_length = -1; static int hf_state_begin = -1; static int hf_udvm_state_length = -1; static int hf_udvm_state_length_addr = -1; static int hf_udvm_state_address = -1; static int hf_udvm_state_address_addr = -1; static int hf_udvm_state_instr = -1; static int hf_udvm_operand_1 = -1; static int hf_udvm_operand_2 = -1; static int hf_udvm_operand_2_addr = -1; static int hf_udvm_j = -1; static int hf_udvm_output_start = -1; static int hf_udvm_output_start_addr = -1; static int hf_udvm_output_length = -1; static int hf_udvm_output_length_addr = -1; static int hf_udvm_req_feedback_loc = -1; static int hf_udvm_min_acc_len = -1; static int hf_udvm_state_ret_pri = -1; static int hf_udvm_ret_param_loc = -1; static int hf_udvm_position = -1; static int hf_udvm_ref_dest = -1; static int hf_udvm_bits = -1; static int hf_udvm_lower_bound = -1; static int hf_udvm_upper_bound = -1; static int hf_udvm_uncompressed = -1; static int hf_udvm_offset = -1; static int hf_udvm_start_value = -1; /* Initialize the subtree pointers */ static gint ett_sigcomp = -1; static gint ett_sigcomp_udvm = -1; /* set the tcp port */ static guint SigCompUDPPort1 = 5555; static guint SigCompUDPPort2 = 6666; /* Default preference wether to display the bytecode in UDVM operands or not */ static gboolean display_udvm_bytecode = FALSE; /* Default preference wether to dissect the UDVM code or not */ static gboolean dissect_udvm_code = TRUE; /* Value strings */ static const value_string length_encoding_vals[] = { { 0x00, "No partial state(Message type 2)" }, { 0x01, "6 bytes)" }, { 0x02, "9 bytes)" }, { 0x03, "12 bytes)" }, { 0, NULL } }; static const value_string destination_address_encoding_vals[] = { { 0x00, "Reserved" }, { 0x01, "128" }, { 0x02, "192" }, { 0x03, "256" }, { 0x04, "320" }, { 0x05, "384" }, { 0x06, "448" }, { 0x07, "512" }, { 0x08, "576" }, { 0x09, "640" }, { 0x0a, "704" }, { 0x0b, "768" }, { 0x0c, "832" }, { 0x0d, "896" }, { 0x0e, "960" }, { 0x0F, "1024" }, { 0, NULL } }; static const value_string udvm_instruction_code_vals[] = { { 0, "DECOMPRESSION-FAILURE" }, { 1, "AND" }, { 2, "OR" }, { 3, "NOT" }, { 4, "LSHIFT" }, { 5, "RSHIFT" }, { 6, "ADD" }, { 7, "SUBTRACT" }, { 8, "MULTIPLY" }, { 9, "DIVIDE" }, { 10, "REMAINDER" }, { 11, "SORT-ASCENDING" }, { 12, "SORT-DESCENDING" }, { 13, "SHA-1" }, { 14, "LOAD" }, { 15, "MULTILOAD" }, { 16, "PUSH" }, { 17, "POP" }, { 18, "COPY" }, { 19, "COPY-LITERAL" }, { 20, "COPY-OFFSET" }, { 21, "MEMSET" }, { 22, "JUMP" }, { 23, "COMPARE" }, { 24, "CALL" }, { 25, "RETURN" }, { 26, "SWITCH" }, { 27, "CRC" }, { 28, "INPUT-BYTES" }, { 29, "INPUT-BITS" }, { 30, "INPUT-HUFFMAN" }, { 31, "STATE-ACCESS" }, { 32, "STATE-CREATE" }, { 33, "STATE-FREE" }, { 34, "OUTPUT" }, { 35, "END-MESSAGE" }, { 0, NULL } }; /* RFC3320 * Figure 10: Bytecode for a multitype (%) operand * Bytecode: Operand value: Range: HEX val * 00nnnnnn N 0 - 63 0x00 * 01nnnnnn memory[2 * N] 0 - 65535 0x40 * 1000011n 2 ^ (N + 6) 64 , 128 0x86 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88 * 111nnnnn N + 65504 65504 - 65535 0xe0 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81 */ static const value_string display_bytecode_vals[] = { { 0x00, "00nnnnnn, N, 0 - 63" }, { 0x40, "01nnnnnn, memory[2 * N],0 - 65535" }, { 0x86, "1000011n, 2 ^ (N + 6), 64 , 128" }, { 0x88, "10001nnn, 2 ^ (N + 8), 256,..., 32768" }, { 0xe0, "111nnnnn N + 65504, 65504 - 65535" }, { 0x90, "1001nnnn nnnnnnnn, N + 61440, 61440 - 65535" }, { 0xa0, "101nnnnn nnnnnnnn, N, 0 - 8191" }, { 0xc0, "110nnnnn nnnnnnnn, memory[N], 0 - 65535" }, { 0x80, "10000000 nnnnnnnn nnnnnnnn, N, 0 - 65535" }, { 0x81, "10000001 nnnnnnnn nnnnnnnn, memory[N], 0 - 65535" }, { 0, NULL } }; /* RFC3320 * 0nnnnnnn memory[2 * N] 0 - 65535 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 */ static const value_string display_ref_bytecode_vals[] = { { 0x00, "0nnnnnnn memory[2 * N] 0 - 65535" }, { 0x80, "10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535" }, { 0xc0, "11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535" }, { 0, NULL } }; /* The simplest operand type is the literal (#), which encodes a * constant integer from 0 to 65535 inclusive. A literal operand may * require between 1 and 3 bytes depending on its value. * Bytecode: Operand value: Range: * 0nnnnnnn N 0 - 127 * 10nnnnnn nnnnnnnn N 0 - 16383 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535 * * Figure 8: Bytecode for a literal (#) operand * */ static const value_string display_lit_bytecode_vals[] = { { 0x00, "0nnnnnnn N 0 - 127" }, { 0x80, "10nnnnnn nnnnnnnn N 0 - 16383" }, { 0xc0, "11000000 nnnnnnnn nnnnnnnn N 0 - 65535" }, { 0, NULL } }; static void dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, guint destination); static int dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, gint offset,gboolean is_addr,gint *start_offset, guint16 *value, gboolean *is_memory_address ); static int dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, gint offset, gint *start_offset, guint16 *value); static int dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, gint offset, gint *start_offset, guint16 *value); /* Code to actually dissect the packets */ static int dissect_sigcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ tvbuff_t *udvm_tvb; proto_item *ti, *udvm_item; proto_tree *sigcomp_tree, *sigcomp_udvm_tree; gint offset = 0; gint partial_state_len; guint octet; guint8 returned_feedback_field[128]; guint8 partial_state[9]; guint tbit; guint16 len = 0; guint destination; /* Is this a SigComp message or not ? */ octet = tvb_get_guint8(tvb, offset); if ((octet & 0xf8) != 0xf8) return 0; /* Make entries in Protocol column and Info column on summary display */ if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP"); if (check_col(pinfo->cinfo, COL_INFO)) col_clear(pinfo->cinfo, COL_INFO); /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, FALSE); sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp); /* add an item to the subtree, see section 1.6 for more information */ octet = tvb_get_guint8(tvb, offset); /* A SigComp message takes one of two forms depending on whether it * accesses a state item at the receiving endpoint. The two variants of * a SigComp message are given in Figure 3. (The T-bit controls the * format of the returned feedback item and is defined in Section 7.1.) * * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ * | 1 1 1 1 1 | T | len | | 1 1 1 1 1 | T | 0 | * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ * | | | | * : returned feedback item : : returned feedback item : * | | | | * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ * | | | code_len | * : partial state identifier : +---+---+---+---+---+---+---+---+ * * | | | code_len | destination | * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ * | | | | * : remaining SigComp message : : uploaded UDVM bytecode : * | | | | * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ * | | * : remaining SigComp message : * | | * +---+---+---+---+---+---+---+---+ * */ proto_tree_add_item(sigcomp_tree,hf_sigcomp_t_bit, tvb, offset, 1, FALSE); proto_tree_add_item(sigcomp_tree,hf_sigcomp_len, tvb, offset, 1, FALSE); tbit = ( octet & 0x04)>>2; partial_state_len = octet & 0x03; offset ++; if ( partial_state_len != 0 ){ /* * The len field encodes the number of transmitted bytes as follows: * * Encoding: Length of partial state identifier * * 01 6 bytes * 10 9 bytes * 11 12 bytes * */ partial_state_len = partial_state_len * 3 + 3; /* * Message format 1 */ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Msg format 1"); if ( tbit == 1 ) { /* * Returned feedback item exists */ len = 1; octet = tvb_get_guint8(tvb, offset); /* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ * | 0 | returned_feedback_field | | 1 | returned_feedback_length | * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+ * | | * : returned_feedback_field : * | | * +---+---+---+---+---+---+---+---+ * Figure 4: Format of returned feedback item */ if ( (octet & 0x80) != 0 ){ len = octet & 0x7f; proto_tree_add_uint(sigcomp_tree,hf_sigcomp_returned_feedback_item_len, tvb, offset, 1, len); offset ++; tvb_memcpy(tvb,returned_feedback_field,offset, len); } else { returned_feedback_field[0] = tvb_get_guint8(tvb, offset) & 0x7f; } proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item, tvb, offset, len, returned_feedback_field); offset = offset + len; tvb_memcpy(tvb, partial_state, offset, partial_state_len); proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_partial_state, tvb, offset, partial_state_len, partial_state); offset = offset + partial_state_len; proto_tree_add_text(sigcomp_tree, tvb, offset, -1, "Remaining SigComp message %u bytes", tvb_reported_length_remaining(tvb, offset)); } } else{ /* * Message format 2 */ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Msg format 2"); if ( tbit == 1 ) { /* * Returned feedback item exists */ len = 1; octet = tvb_get_guint8(tvb, offset); if ( (octet & 0x80) != 0 ){ len = octet & 0x7f; proto_tree_add_uint(sigcomp_tree,hf_sigcomp_returned_feedback_item_len, tvb, offset, 1, len); offset ++; } tvb_memcpy(tvb,returned_feedback_field,offset, len); proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item, tvb, offset, 1, returned_feedback_field); offset = offset + len; } len = tvb_get_ntohs(tvb, offset) >> 4; octet = tvb_get_guint8(tvb, (offset + 1)); destination = (octet & 0x0f); if ( destination != 0 ) destination = 64 + ( destination * 64 ); proto_tree_add_uint(sigcomp_tree,hf_sigcomp_code_len, tvb, offset, 2, len); proto_tree_add_item(sigcomp_tree,hf_sigcomp_destination, tvb, (offset+ 1), 1, FALSE); offset = offset +2; udvm_item = proto_tree_add_text(sigcomp_tree, tvb, offset, len, "Uploaded UDVM bytecode %u (0x%x) bytes", len, len); sigcomp_udvm_tree = proto_item_add_subtree( udvm_item, ett_sigcomp_udvm); udvm_tvb = tvb_new_subset(tvb, offset, len, len); if ( dissect_udvm_code ) dissect_udvm_bytecode(udvm_tvb, sigcomp_udvm_tree, destination); offset = offset + len; proto_tree_add_text(sigcomp_tree, tvb, offset, -1, "Remaining SigComp message %u bytes", tvb_reported_length_remaining(tvb, offset)); } return tvb_length(tvb); } /* Continue adding tree items to process the packet here */ /* If this protocol has a sub-dissector call it here, see section 1.8 */ #define SIGCOMP_INSTR_DECOMPRESSION_FAILURE 0 #define SIGCOMP_INSTR_AND 1 #define SIGCOMP_INSTR_OR 2 #define SIGCOMP_INSTR_NOT 3 #define SIGCOMP_INSTR_LSHIFT 4 #define SIGCOMP_INSTR_RSHIFT 5 #define SIGCOMP_INSTR_ADD 6 #define SIGCOMP_INSTR_SUBTRACT 7 #define SIGCOMP_INSTR_MULTIPLY 8 #define SIGCOMP_INSTR_DIVIDE 9 #define SIGCOMP_INSTR_REMAINDER 10 #define SIGCOMP_INSTR_SORT_ASCENDING 11 #define SIGCOMP_INSTR_SORT_DESCENDING 12 #define SIGCOMP_INSTR_SHA_1 13 #define SIGCOMP_INSTR_LOAD 14 #define SIGCOMP_INSTR_MULTILOAD 15 #define SIGCOMP_INSTR_PUSH 16 #define SIGCOMP_INSTR_POP 17 #define SIGCOMP_INSTR_COPY 18 #define SIGCOMP_INSTR_COPY_LITERAL 19 #define SIGCOMP_INSTR_COPY_OFFSET 20 #define SIGCOMP_INSTR_MEMSET 21 #define SIGCOMP_INSTR_JUMP 22 #define SIGCOMP_INSTR_COMPARE 23 #define SIGCOMP_INSTR_CALL 24 #define SIGCOMP_INSTR_RETURN 25 #define SIGCOMP_INSTR_SWITCH 26 #define SIGCOMP_INSTR_CRC 27 #define SIGCOMP_INSTR_INPUT_BYTES 28 #define SIGCOMP_INSTR_INPUT_BITS 29 #define SIGCOMP_INSTR_INPUT_HUFFMAN 30 #define SIGCOMP_INSTR_STATE_ACCESS 31 #define SIGCOMP_INSTR_STATE_CREATE 32 #define SIGCOMP_INSTR_STATE_FREE 33 #define SIGCOMP_INSTR_OUTPUT 34 #define SIGCOMP_INSTR_END_MESSAGE 35 static void dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,guint start_address) { guint instruction; gint offset = 0; gint start_offset; gint len; gint n; guint instruction_no = 0; guint16 value = 0; proto_item *item, *item2; guint UDVM_address = start_address; gboolean is_memory_address; while (tvb_reported_length_remaining(udvm_tvb, offset) > 0) { instruction = tvb_get_guint8(udvm_tvb, offset); instruction_no ++; UDVM_address = start_address + offset; ; item = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1, "######### UDVM instruction %u at UDVM-address %u (0x%x) #########", instruction_no,UDVM_address,UDVM_address); PROTO_ITEM_SET_GENERATED(item); proto_tree_add_item(sigcomp_udvm_tree, hf_sigcomp_udvm_instr, udvm_tvb, offset, 1, FALSE); offset ++; switch ( instruction ) { case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */ /* $operand_1*/ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, udvm_tvb, start_offset, len, value); /* %operand_2*/ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */ /* $operand_1*/ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, udvm_tvb, start_offset, len, value); /* %operand_2*/ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */ /* $operand_1*/ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */ /* $operand_1*/ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, udvm_tvb, start_offset, len, value); /* %operand_2*/ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */ /* $operand_1*/ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, udvm_tvb, start_offset, len, value); /* %operand_2*/ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */ /* $operand_1*/ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, udvm_tvb, start_offset, len, value); /* %operand_2*/ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */ /* $operand_1*/ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, udvm_tvb, start_offset, len, value); /* %operand_2*/ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */ /* $operand_1*/ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, udvm_tvb, start_offset, len, value); /* %operand_2*/ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */ /* $operand_1*/ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, udvm_tvb, start_offset, len, value); /* %operand_2*/ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */ /* $operand_1*/ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1, udvm_tvb, start_offset, len, value); /* %operand_2*/ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_SORT_ASCENDING: /* 11 SORT-ASCENDING (%start, %n, %k) */ /* while programming stop while loop */ offset = offset + tvb_reported_length_remaining(udvm_tvb, offset); break; case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */ /* while programming stop while loop */ offset = offset + tvb_reported_length_remaining(udvm_tvb, offset); break; case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */ /* %position */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position, udvm_tvb, start_offset, len, value); /* %length, */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, udvm_tvb, start_offset, len, value); /* $destination */ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */ /* %address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address, udvm_tvb, start_offset, len, value); /* %value */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */ /* %address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address, udvm_tvb, start_offset, len, value); /* #n */ offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num, udvm_tvb, start_offset, len, value); n = value; while ( n > 0) { n = n -1; /* %value */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, udvm_tvb, start_offset, len, value); } } break; case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */ /* %value */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_POP: /* 17 POP (%address) */ /* %address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */ /* %position */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position, udvm_tvb, start_offset, len, value); /* %length, */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, udvm_tvb, start_offset, len, value); /* $destination */ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */ /* %position */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position, udvm_tvb, start_offset, len, value); /* %length, */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, udvm_tvb, start_offset, len, value); /* $destination */ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */ /* %offset */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset, udvm_tvb, start_offset, len, value); /* %length, */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, udvm_tvb, start_offset, len, value); /* $destination */ offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */ /* %address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address, udvm_tvb, start_offset, len, value); /* %length, */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, udvm_tvb, start_offset, len, value); /* %start_value */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_start_value, udvm_tvb, start_offset, len, value); /* %offset */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */ /* @address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */ value = ( value + UDVM_address ) & 0xffff; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_COMPARE: /* 23 */ /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3) */ /* %value_1 */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, udvm_tvb, start_offset, len, value); } /* %value_2 */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, udvm_tvb, start_offset, len, value); } /* @address_1 */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */ value = ( value + UDVM_address ) & 0xffff; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, udvm_tvb, start_offset, len, value); /* @address_2 */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */ value = ( value + UDVM_address ) & 0xffff; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, udvm_tvb, start_offset, len, value); /* @address_3 */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */ value = ( value + UDVM_address ) & 0xffff; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/ /* @address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */ value = ( value + UDVM_address ) & 0xffff; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_RETURN: /* 25 POP and return */ break; case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */ /* #n */ offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num, udvm_tvb, start_offset, len, value); /* Number of addresses in the instruction */ n = value; /* %j */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, udvm_tvb, start_offset, len, value); } while ( n > 0) { n = n -1; /* @address_n-1 */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address); len = offset - start_offset; /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */ value = ( value + UDVM_address ) & 0xffff; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */ /* %value */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ){ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value, udvm_tvb, start_offset, len, value); } /* %position */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position, udvm_tvb, start_offset, len, value); /* %length */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, udvm_tvb, start_offset, len, value); /* @address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */ value = ( value + UDVM_address ) & 0xffff; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */ /* %length */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, udvm_tvb, start_offset, len, value); /* %destination */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination, udvm_tvb, start_offset, len, value); /* @address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */ value = ( value + UDVM_address ) & 0xffff; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_INPUT_BITS:/* 29 INPUT-BITS (%length, %destination, @address) */ /* %length */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length, udvm_tvb, start_offset, len, value); /* %destination */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination, udvm_tvb, start_offset, len, value); /* @address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */ value = ( value + UDVM_address ) & 0xffff; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */ /* * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1, * %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n, * %upper_bound_n, %uncompressed_n) */ /* %destination */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination, udvm_tvb, start_offset, len, value); /* @address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */ value = ( value + UDVM_address ) & 0xffff; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address, udvm_tvb, start_offset, len, value); /* #n */ offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num, udvm_tvb, start_offset, len, value); n = value; while ( n > 0) { n = n -1; /* %bits_n */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_bits, udvm_tvb, start_offset, len, value); /* %lower_bound_n*/ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_lower_bound, udvm_tvb, start_offset, len, value); /* %upper_bound_n */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_upper_bound, udvm_tvb, start_offset, len, value); /* %uncompressed_n */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_uncompressed, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_STATE_ACCESS: /* 31 */ /* STATE-ACCESS (%partial_identifier_start, %partial_identifier_length, * %state_begin, %state_length, %state_address, %state_instruction) */ /* * %partial_identifier_start */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start, udvm_tvb, start_offset, len, value); /* * %partial_identifier_length */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length, udvm_tvb, start_offset, len, value); /* * %state_begin */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_state_begin, udvm_tvb, start_offset, len, value); /* * %state_length */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ) { proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length, udvm_tvb, start_offset, len, value); } /* * %state_address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address); len = offset - start_offset; if ( is_memory_address ) { proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address, udvm_tvb, start_offset, len, value); } /* * %state_instruction */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_STATE_CREATE: /* 32 */ /* * STATE-CREATE (%state_length, %state_address, %state_instruction, * %minimum_access_length, %state_retention_priority) */ /* * %state_length */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ) { proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length, udvm_tvb, start_offset, len, value); } /* * %state_address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ) { proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address, udvm_tvb, start_offset, len, value); } /* * %state_instruction */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr, udvm_tvb, start_offset, len, value); /* * %minimum_access_length */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len, udvm_tvb, start_offset, len, value); /* * %state_retention_priority */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_STATE_FREE: /* 33 */ /* * STATE-FREE (%partial_identifier_start, %partial_identifier_length) */ /* * %partial_identifier_start */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start, udvm_tvb, start_offset, len, value); /* * %partial_identifier_length */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length, udvm_tvb, start_offset, len, value); break; case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */ /* * %output_start */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ) { proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start, udvm_tvb, start_offset, len, value); } /* * %output_length */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ) { proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length, udvm_tvb, start_offset, len, value); } break; case SIGCOMP_INSTR_END_MESSAGE: /* 35 */ /* * END-MESSAGE (%requested_feedback_location, * %returned_parameters_location, %state_length, %state_address, * %state_instruction, %minimum_access_length, * %state_retention_priority) */ /* %requested_feedback_location */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_req_feedback_loc, udvm_tvb, start_offset, len, value); /* returned_parameters_location */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ret_param_loc, udvm_tvb, start_offset, len, value); /* * %state_length */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ) { proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length, udvm_tvb, start_offset, len, value); } /* * %state_address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; if ( is_memory_address ) { proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr, udvm_tvb, start_offset, len, value); }else{ proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address, udvm_tvb, start_offset, len, value); } /* * %state_instruction */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr, udvm_tvb, start_offset, len, value); /* * %minimum_access_length */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len, udvm_tvb, start_offset, len, value); /* * %state_retention_priority */ if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address); len = offset - start_offset; proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri, udvm_tvb, start_offset, len, value); }else{ item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1, "state_retention_priority = 0(Not in the uploaded code as UDVM buffer initalized to Zero"); PROTO_ITEM_SET_GENERATED(item2); } if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){ len = tvb_reported_length_remaining(udvm_tvb, offset); UDVM_address = start_address + offset; proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, len, "Remaning %u bytes starting at UDVM addr %u (0x%x)- State information ?",len, UDVM_address, UDVM_address); } offset = offset + tvb_reported_length_remaining(udvm_tvb, offset); break; default: /* while programming stop while loop */ offset = offset + tvb_reported_length_remaining(udvm_tvb, offset); break; } } return; } /* The simplest operand type is the literal (#), which encodes a * constant integer from 0 to 65535 inclusive. A literal operand may * require between 1 and 3 bytes depending on its value. * Bytecode: Operand value: Range: * 0nnnnnnn N 0 - 127 * 10nnnnnn nnnnnnnn N 0 - 16383 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535 * * Figure 8: Bytecode for a literal (#) operand * */ static int dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, gint offset, gint *start_offset, guint16 *value) { guint bytecode; guint16 operand; guint test_bits; guint display_bytecode; bytecode = tvb_get_guint8(udvm_tvb, offset); test_bits = bytecode >> 7; if (test_bits == 1){ test_bits = bytecode >> 6; if (test_bits == 2){ /* * 10nnnnnn nnnnnnnn N 0 - 16383 */ display_bytecode = bytecode & 0xc0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode, udvm_tvb, offset, 1, display_bytecode); operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff; *value = operand; *start_offset = offset; offset = offset + 2; }else{ /* * 111000000 nnnnnnnn nnnnnnnn N 0 - 65535 */ display_bytecode = bytecode & 0xc0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode, udvm_tvb, offset, 1, display_bytecode); offset ++; operand = tvb_get_ntohs(udvm_tvb, offset); *value = operand; *start_offset = offset; offset = offset + 2; } }else{ /* * 0nnnnnnn N 0 - 127 */ display_bytecode = bytecode & 0xc0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode, udvm_tvb, offset, 1, display_bytecode); operand = ( bytecode & 0x7f); *value = operand; *start_offset = offset; offset ++; } return offset; } /* * The second operand type is the reference ($), which is always used to * access a 2-byte value located elsewhere in the UDVM memory. The * bytecode for a reference operand is decoded to be a constant integer * from 0 to 65535 inclusive, which is interpreted as the memory address * containing the actual value of the operand. * Bytecode: Operand value: Range: * * 0nnnnnnn memory[2 * N] 0 - 65535 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 * * Figure 9: Bytecode for a reference ($) operand */ static int dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, gint offset, gint *start_offset, guint16 *value) { guint bytecode; guint16 operand; guint test_bits; guint display_bytecode; bytecode = tvb_get_guint8(udvm_tvb, offset); test_bits = bytecode >> 7; if (test_bits == 1){ test_bits = bytecode >> 6; if (test_bits == 2){ /* * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535 */ display_bytecode = bytecode & 0xc0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode, udvm_tvb, offset, 1, display_bytecode); operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff; *value = (operand * 2); *start_offset = offset; offset = offset + 2; }else{ /* * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 */ display_bytecode = bytecode & 0xc0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode, udvm_tvb, offset, 1, display_bytecode); offset ++; operand = tvb_get_ntohs(udvm_tvb, offset); *value = operand; *start_offset = offset; offset = offset + 2; } }else{ /* * 0nnnnnnn memory[2 * N] 0 - 65535 */ display_bytecode = bytecode & 0xc0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode, udvm_tvb, offset, 1, display_bytecode); operand = ( bytecode & 0x3f); *value = (operand * 2); *start_offset = offset; offset ++; } return offset; } /* *The fourth operand type is the address (@). This operand is decoded * as a multitype operand followed by a further step: the memory address * of the UDVM instruction containing the address operand is added to * obtain the correct operand value. So if the operand value from * Figure 10 is D then the actual operand value of an address is * calculated as follows: * * operand_value = (is_memory_address_of_instruction + D) modulo 2^16 * TODO calculate correct value for operand in case of ADDR */ static int dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, gint offset, gboolean is_addr, gint *start_offset, guint16 *value, gboolean *is_memory_address ) { guint bytecode; guint display_bytecode; guint16 operand; guint32 result; guint test_bits; /* RFC3320 * Figure 10: Bytecode for a multitype (%) operand * Bytecode: Operand value: Range: HEX val * 00nnnnnn N 0 - 63 0x00 * 01nnnnnn memory[2 * N] 0 - 65535 0x40 * 1000011n 2 ^ (N + 6) 64 , 128 0x86 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88 * 111nnnnn N + 65504 65504 - 65535 0xe0 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81 */ *is_memory_address = FALSE; bytecode = tvb_get_guint8(udvm_tvb, offset); test_bits = ( bytecode & 0xc0 ) >> 6; switch (test_bits ){ case 0: /* * 00nnnnnn N 0 - 63 */ display_bytecode = bytecode & 0xc0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode, udvm_tvb, offset, 1, display_bytecode); operand = ( bytecode & 0x3f); *value = operand; *start_offset = offset; offset ++; break; case 1: /* * 01nnnnnn memory[2 * N] 0 - 65535 */ display_bytecode = bytecode & 0xc0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode, udvm_tvb, offset, 1, display_bytecode); operand = ( bytecode & 0x3f) * 2; *is_memory_address = TRUE; *value = operand; *start_offset = offset; offset ++; break; case 2: /* Check tree most significant bits */ test_bits = ( bytecode & 0xe0 ) >> 5; if ( test_bits == 5 ){ /* * 101nnnnn nnnnnnnn N 0 - 8191 */ display_bytecode = bytecode & 0xe0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode, udvm_tvb, offset, 1, display_bytecode); operand = tvb_get_ntohs(udvm_tvb, offset) & 0x1fff; *value = operand; *start_offset = offset; offset = offset + 2; }else{ test_bits = ( bytecode & 0xf0 ) >> 4; if ( test_bits == 9 ){ /* * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 */ display_bytecode = bytecode & 0xf0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode, udvm_tvb, offset, 1, display_bytecode); operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x0fff) + 61440; *start_offset = offset; *value = operand; offset = offset + 2; }else{ test_bits = ( bytecode & 0x08 ) >> 3; if ( test_bits == 1){ /* * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 */ display_bytecode = bytecode & 0xf8; 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); operand = result & 0xffff; *start_offset = offset; *value = operand; offset ++; }else{ test_bits = ( bytecode & 0x0e ) >> 1; if ( test_bits == 3 ){ /* * 1000 011n 2 ^ (N + 6) 64 , 128 */ display_bytecode = bytecode & 0xfe; 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); operand = result & 0xffff; *start_offset = offset; *value = operand; offset ++; }else{ /* * 1000 0000 nnnnnnnn nnnnnnnn N 0 - 65535 * 1000 0001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 */ display_bytecode = bytecode; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode, udvm_tvb, offset, 1, display_bytecode); if ( (bytecode & 0x01) == 1 ) *is_memory_address = TRUE; offset ++; operand = tvb_get_ntohs(udvm_tvb, offset); *value = operand; *start_offset = offset; offset = offset +2; } } } } break; case 3: test_bits = ( bytecode & 0x20 ) >> 5; if ( test_bits == 1 ){ /* * 111nnnnn N + 65504 65504 - 65535 */ display_bytecode = bytecode & 0xe0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode, udvm_tvb, offset, 1, display_bytecode); operand = ( bytecode & 0x1f) + 65504; *start_offset = offset; *value = operand; offset ++; }else{ /* * 110nnnnn nnnnnnnn memory[N] 0 - 65535 */ display_bytecode = bytecode & 0xe0; if ( display_udvm_bytecode ) proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode, udvm_tvb, offset, 1, display_bytecode); operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x1fff); *is_memory_address = TRUE; *start_offset = offset; *value = operand; offset = offset +2; } default : break; } return offset; } /* Register the protocol with Ethereal */ /* If this dissector uses sub-dissector registration add a registration routine. This format is required because a script is used to find these routines and create the code that calls these routines. */ void proto_reg_handoff_sigcomp(void) { static dissector_handle_t sigcomp_handle; static int Initialized=FALSE; static int udp_port1 = 5555; static int udp_port2 = 6666; if (!Initialized) { sigcomp_handle = new_create_dissector_handle(dissect_sigcomp, proto_sigcomp); Initialized=TRUE; }else{ dissector_delete("udp.port", udp_port1, sigcomp_handle); dissector_delete("udp.port", udp_port2, sigcomp_handle); } udp_port1 = SigCompUDPPort1; udp_port2 = SigCompUDPPort2; dissector_add("udp.port", SigCompUDPPort1, sigcomp_handle); dissector_add("udp.port", SigCompUDPPort2, sigcomp_handle); } /* this format is require because a script is used to build the C function that calls all the protocol registration. */ void proto_register_sigcomp(void) { /* Setup list of header fields See Section 1.6.1 for details*/ static hf_register_info hf[] = { { &hf_sigcomp_t_bit, { "T bit", "sigcomp.t.bit", FT_UINT8, BASE_DEC, NULL, 0x04, "Sigcomp T bit", HFILL } }, { &hf_sigcomp_len, { "Partial state id. len.","sigcomp.length", FT_UINT8, BASE_HEX, VALS(&length_encoding_vals), 0x03, "Sigcomp length", HFILL } }, { &hf_sigcomp_returned_feedback_item, { "Returned_feedback item", "sigcomp.returned.feedback.item", FT_BYTES, BASE_HEX, NULL, 0x0, "Returned feedback item", HFILL } }, { &hf_sigcomp_partial_state, { "Partial state identifier", "sigcomp.partial.state.identifier", FT_BYTES, BASE_HEX, NULL, 0x0, "Partial state identifier", HFILL } }, { &hf_sigcomp_returned_feedback_item_len, { "Returned feedback item length", "sigcomp.returned.feedback.item.len", FT_UINT8, BASE_DEC, NULL, 0x0, "Returned feedback item length", HFILL } }, { &hf_sigcomp_code_len, { "Code length","sigcomp.code.len", FT_UINT16, BASE_HEX, NULL, 0x0, "Code length", HFILL } }, { &hf_sigcomp_destination, { "Destination","sigcomp.destination", FT_UINT8, BASE_HEX, VALS(&destination_address_encoding_vals), 0xf, "Destination", HFILL } }, { &hf_sigcomp_udvm_instr, { "UDVM instruction code","sigcomp.udvm.instr", FT_UINT8, BASE_DEC, VALS(&udvm_instruction_code_vals), 0x0, "UDVM instruction code", HFILL } }, { &hf_udvm_multitype_bytecode, { "UDVM bytecode", "sigcomp.udvm.multyt.bytecode", FT_UINT8, BASE_HEX, VALS(&display_bytecode_vals), 0x0, "UDVM bytecode", HFILL } }, { &hf_udvm_reference_bytecode, { "UDVM bytecode", "sigcomp.udvm.ref.bytecode", FT_UINT8, BASE_HEX, VALS(&display_ref_bytecode_vals), 0x0, "UDVM bytecode", HFILL } }, { &hf_udvm_literal_bytecode, { "UDVM bytecode", "sigcomp.udvm.lit.bytecode", FT_UINT8, BASE_HEX, VALS(&display_lit_bytecode_vals), 0x0, "UDVM bytecode", HFILL } }, { &hf_udvm_operand, { "UDVM operand", "sigcomp.udvm.operand", FT_UINT16, BASE_DEC, NULL, 0x0, "UDVM operand", HFILL } }, { &hf_udvm_length, { " %Length", "sigcomp.udvm.length", FT_UINT16, BASE_DEC, NULL, 0x0, "Length", HFILL } }, { &hf_udvm_destination, { " %Destination", "sigcomp.udvm.destination", FT_UINT16, BASE_DEC, NULL, 0x0, "Destination", HFILL } }, { &hf_udvm_at_address, { " @Address(mem_add_of_inst + D) mod 2^16)", "sigcomp.udvm.at.address", FT_UINT16, BASE_DEC, NULL, 0x0, "Address", HFILL } }, { &hf_udvm_address, { " %Address", "sigcomp.udvm.length", FT_UINT16, BASE_DEC, NULL, 0x0, "Address", HFILL } }, { &hf_udvm_literal_num, { " #n", "sigcomp.udvm.literal-num", FT_UINT16, BASE_DEC, NULL, 0x0, "Literal number", HFILL } }, { &hf_udvm_value, { " %Value", "sigcomp.udvm.value", FT_UINT16, BASE_DEC, NULL, 0x0, "Value", HFILL } }, { &hf_udvm_addr_value, { " %Value[memory address]", "sigcomp.udvm.value", FT_UINT16, BASE_DEC, NULL, 0x0, "Value", HFILL } }, { &hf_partial_identifier_start, { " %Partial identifier start", "sigcomp.udvm.partial.identifier.start", FT_UINT16, BASE_DEC, NULL, 0x0, "Partial identifier start", HFILL } }, { &hf_partial_identifier_length, { " %Partial identifier length", "sigcomp.udvm.partial.identifier.length", FT_UINT16, BASE_DEC, NULL, 0x0, "Partial identifier length", HFILL } }, { &hf_state_begin, { " %State begin", "sigcomp.udvm.state.begin", FT_UINT16, BASE_DEC, NULL, 0x0, "State begin", HFILL } }, { &hf_udvm_state_length, { " %State length", "sigcomp.udvm.state.length", FT_UINT16, BASE_DEC, NULL, 0x0, "State length", HFILL } }, { &hf_udvm_state_length_addr, { " %State length[memory address]", "sigcomp.udvm.state.length.addr", FT_UINT16, BASE_DEC, NULL, 0x0, "State length", HFILL } }, { &hf_udvm_state_address, { " %State address", "sigcomp.udvm.start.address", FT_UINT16, BASE_DEC, NULL, 0x0, "State address", HFILL } }, { &hf_udvm_state_address_addr, { " %State address[memory address]", "sigcomp.udvm.start.address.addr", FT_UINT16, BASE_DEC, NULL, 0x0, "State address", HFILL } }, { &hf_udvm_state_instr, { " %State instruction", "sigcomp.udvm.start.instr", FT_UINT16, BASE_DEC, NULL, 0x0, "State instruction", HFILL } }, { &hf_udvm_operand_1, { " $Operand 1[memory address]", "sigcomp.udvm.operand.1", FT_UINT16, BASE_DEC, NULL, 0x0, "Reference $ Operand 1", HFILL } }, { &hf_udvm_operand_2, { " %Operand 2", "sigcomp.udvm.operand.2", FT_UINT16, BASE_DEC, NULL, 0x0, "Operand 2", HFILL } }, { &hf_udvm_operand_2_addr, { " %Operand 2[memory address]", "sigcomp.udvm.operand.2.addr", FT_UINT16, BASE_DEC, NULL, 0x0, "Operand 2", HFILL } }, { &hf_udvm_j, { " %j", "sigcomp.udvm.j", FT_UINT16, BASE_DEC, NULL, 0x0, "j", HFILL } }, { &hf_udvm_output_start, { " %Output_start", "sigcomp.output.start", FT_UINT16, BASE_DEC, NULL, 0x0, "Output start", HFILL } }, { &hf_udvm_output_start_addr, { " %Output_start[memory address]", "sigcomp.output.start.addr", FT_UINT16, BASE_DEC, NULL, 0x0, "Output start", HFILL } }, { &hf_udvm_output_length, { " %Output_length", "sigcomp.output.length", FT_UINT16, BASE_DEC, NULL, 0x0, "Output length", HFILL } }, { &hf_udvm_output_length_addr, { " %Output_length[memory address]", "sigcomp.output.length.addr", FT_UINT16, BASE_DEC, NULL, 0x0, "Output length", HFILL } }, { &hf_udvm_req_feedback_loc, { " %Requested feedback location", "sigcomp.req.feedback.loc", FT_UINT16, BASE_DEC, NULL, 0x0, "Requested feedback location", HFILL } }, { &hf_udvm_min_acc_len, { " %Minimum access length", "sigcomp.min.acc.len", FT_UINT16, BASE_DEC, NULL, 0x0, "Output length", HFILL } }, { &hf_udvm_state_ret_pri, { " %State retention priority", "sigcomp.udvm.state.ret.pri", FT_UINT16, BASE_DEC, NULL, 0x0, "Output length", HFILL } }, { &hf_udvm_ret_param_loc, { " %Returned parameters location", "sigcomp.ret.param.loc", FT_UINT16, BASE_DEC, NULL, 0x0, "Output length", HFILL } }, { &hf_udvm_position, { " %Position", "sigcomp.udvm.position", FT_UINT16, BASE_DEC, NULL, 0x0, "Position", HFILL } }, { &hf_udvm_ref_dest, { " $Destination[memory address]", "sigcomp.udvm.ref.destination", FT_UINT16, BASE_DEC, NULL, 0x0, "(reference)Destination", HFILL } }, { &hf_udvm_bits, { " %Bits", "sigcomp.udvm.bits", FT_UINT16, BASE_DEC, NULL, 0x0, "Bits", HFILL } }, { &hf_udvm_lower_bound, { " %Lower bound", "sigcomp.udvm.lower.bound", FT_UINT16, BASE_DEC, NULL, 0x0, "Lower_bound", HFILL } }, { &hf_udvm_upper_bound, { " %Upper bound", "sigcomp.udvm.upper.bound", FT_UINT16, BASE_DEC, NULL, 0x0, "Upper bound", HFILL } }, { &hf_udvm_uncompressed, { " %Uncompressed", "sigcomp.udvm.uncompressed", FT_UINT16, BASE_DEC, NULL, 0x0, "Uncompressed", HFILL } }, { &hf_udvm_start_value, { " %Start value", "sigcomp.udvm.start.value", FT_UINT16, BASE_DEC, NULL, 0x0, "Start value", HFILL } }, { &hf_udvm_offset, { " %Offset", "sigcomp.udvm.offset", FT_UINT16, BASE_DEC, NULL, 0x0, "Offset", HFILL } }, }; /* Setup protocol subtree array */ static gint *ett[] = { &ett_sigcomp, &ett_sigcomp_udvm, }; module_t *sigcomp_module; /* Register the protocol name and description */ proto_sigcomp = proto_register_protocol("Signaling Compression", "SIGCOMP", "sigcomp"); /* Required function calls to register the header fields and subtrees used */ proto_register_field_array(proto_sigcomp, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); /* 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_bool_preference(sigcomp_module, "display.udvm.code", "Dissect the UDVM code", "Preference wether to Dissect the UDVM code or not", &dissect_udvm_code); prefs_register_bool_preference(sigcomp_module, "display.bytecode", "Display the bytecode of operands", "preference wether to display the bytecode in UDVM operands or not", &display_udvm_bytecode); }