2 * Routines for Signaling Compression (SigComp) dissection.
3 * Copyright 2004, Anders Broman <anders.broman@ericsson.com>
5 * $Id: packet-sigcomp.c,v 1.3 2004/06/29 20:40:12 etxrab Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * http://www.ietf.org/rfc/rfc3320.txt?number=3320
26 * http://www.ietf.org/rfc/rfc3321.txt?number=3321
28 * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-impl-guide-02.txt
29 * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-sip-01.txt
42 #ifdef NEED_SNPRINTF_H
43 # include "snprintf.h"
46 #include <epan/packet.h>
49 /* Initialize the protocol and registered fields */
50 static int proto_sigcomp = -1;
51 static int hf_sigcomp_t_bit = -1;
52 static int hf_sigcomp_len = -1;
53 static int hf_sigcomp_returned_feedback_item = -1;
54 static int hf_sigcomp_returned_feedback_item_len = -1;
55 static int hf_sigcomp_code_len = -1;
56 static int hf_sigcomp_destination = -1;
57 static int hf_sigcomp_partial_state = -1;
58 static int hf_sigcomp_udvm_instr = -1;
59 static int hf_udvm_multitype_bytecode = -1;
60 static int hf_udvm_reference_bytecode = -1;
61 static int hf_udvm_literal_bytecode = -1;
62 static int hf_udvm_operand = -1;
63 static int hf_udvm_length = -1;
64 static int hf_udvm_destination = -1;
65 static int hf_udvm_at_address = -1;
66 static int hf_udvm_address = -1;
67 static int hf_udvm_literal_num = -1;
68 static int hf_udvm_value = -1;
69 static int hf_udvm_addr_value = -1;
70 static int hf_partial_identifier_start = -1;
71 static int hf_partial_identifier_length = -1;
72 static int hf_state_begin = -1;
73 static int hf_udvm_state_length = -1;
74 static int hf_udvm_state_length_addr = -1;
75 static int hf_udvm_state_address = -1;
76 static int hf_udvm_state_address_addr = -1;
77 static int hf_udvm_state_instr = -1;
78 static int hf_udvm_operand_1 = -1;
79 static int hf_udvm_operand_2 = -1;
80 static int hf_udvm_operand_2_addr = -1;
81 static int hf_udvm_j = -1;
82 static int hf_udvm_output_start = -1;
83 static int hf_udvm_output_start_addr = -1;
84 static int hf_udvm_output_length = -1;
85 static int hf_udvm_output_length_addr = -1;
86 static int hf_udvm_req_feedback_loc = -1;
87 static int hf_udvm_min_acc_len = -1;
88 static int hf_udvm_state_ret_pri = -1;
89 static int hf_udvm_ret_param_loc = -1;
90 static int hf_udvm_position = -1;
91 static int hf_udvm_ref_dest = -1;
92 static int hf_udvm_bits = -1;
93 static int hf_udvm_lower_bound = -1;
94 static int hf_udvm_upper_bound = -1;
95 static int hf_udvm_uncompressed = -1;
96 static int hf_udvm_offset = -1;
97 static int hf_udvm_start_value = -1;
99 /* Initialize the subtree pointers */
100 static gint ett_sigcomp = -1;
101 static gint ett_sigcomp_udvm = -1;
104 /* set the tcp port */
105 static guint SigCompUDPPort1 = 5555;
106 static guint SigCompUDPPort2 = 6666;
108 /* Default preference wether to display the bytecode in UDVM operands or not */
109 static gboolean display_udvm_bytecode = FALSE;
110 /* Default preference wether to dissect the UDVM code or not */
111 static gboolean dissect_udvm_code = TRUE;
114 static const value_string length_encoding_vals[] = {
115 { 0x00, "No partial state(Message type 2)" },
116 { 0x01, "6 bytes)" },
117 { 0x02, "9 bytes)" },
118 { 0x03, "12 bytes)" },
123 static const value_string destination_address_encoding_vals[] = {
124 { 0x00, "Reserved" },
143 static const value_string udvm_instruction_code_vals[] = {
144 { 0, "DECOMPRESSION-FAILURE" },
155 { 11, "SORT-ASCENDING" },
156 { 12, "SORT-DESCENDING" },
163 { 19, "COPY-LITERAL" },
164 { 20, "COPY-OFFSET" },
172 { 28, "INPUT-BYTES" },
173 { 29, "INPUT-BITS" },
174 { 30, "INPUT-HUFFMAN" },
175 { 31, "STATE-ACCESS" },
176 { 32, "STATE-CREATE" },
177 { 33, "STATE-FREE" },
179 { 35, "END-MESSAGE" },
183 * Figure 10: Bytecode for a multitype (%) operand
184 * Bytecode: Operand value: Range: HEX val
185 * 00nnnnnn N 0 - 63 0x00
186 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
187 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
188 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
189 * 111nnnnn N + 65504 65504 - 65535 0xe0
190 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
191 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
192 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
193 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
194 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
197 static const value_string display_bytecode_vals[] = {
198 { 0x00, "00nnnnnn, N, 0 - 63" },
199 { 0x40, "01nnnnnn, memory[2 * N],0 - 65535" },
200 { 0x86, "1000011n, 2 ^ (N + 6), 64 , 128" },
201 { 0x88, "10001nnn, 2 ^ (N + 8), 256,..., 32768" },
202 { 0xe0, "111nnnnn N + 65504, 65504 - 65535" },
203 { 0x90, "1001nnnn nnnnnnnn, N + 61440, 61440 - 65535" },
204 { 0xa0, "101nnnnn nnnnnnnn, N, 0 - 8191" },
205 { 0xc0, "110nnnnn nnnnnnnn, memory[N], 0 - 65535" },
206 { 0x80, "10000000 nnnnnnnn nnnnnnnn, N, 0 - 65535" },
207 { 0x81, "10000001 nnnnnnnn nnnnnnnn, memory[N], 0 - 65535" },
211 * 0nnnnnnn memory[2 * N] 0 - 65535
212 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
213 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
215 static const value_string display_ref_bytecode_vals[] = {
216 { 0x00, "0nnnnnnn memory[2 * N] 0 - 65535" },
217 { 0x80, "10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535" },
218 { 0xc0, "11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535" },
221 /* The simplest operand type is the literal (#), which encodes a
222 * constant integer from 0 to 65535 inclusive. A literal operand may
223 * require between 1 and 3 bytes depending on its value.
224 * Bytecode: Operand value: Range:
226 * 10nnnnnn nnnnnnnn N 0 - 16383
227 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
229 * Figure 8: Bytecode for a literal (#) operand
233 static const value_string display_lit_bytecode_vals[] = {
234 { 0x00, "0nnnnnnn N 0 - 127" },
235 { 0x80, "10nnnnnn nnnnnnnn N 0 - 16383" },
236 { 0xc0, "11000000 nnnnnnnn nnnnnnnn N 0 - 65535" },
240 static void dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, guint destination);
242 static int dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
243 gint offset,gboolean is_addr,gint *start_offset,
244 guint16 *value, gboolean *is_memory_address );
246 static int dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
247 gint offset, gint *start_offset, guint16 *value);
249 static int dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
250 gint offset, gint *start_offset, guint16 *value);
253 /* Code to actually dissect the packets */
255 dissect_sigcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
258 /* Set up structures needed to add the protocol subtree and manage it */
260 proto_item *ti, *udvm_item;
261 proto_tree *sigcomp_tree, *sigcomp_udvm_tree;
263 gint partial_state_len;
265 guint8 returned_feedback_field[128];
266 guint8 partial_state[9];
270 /* Is this a SigComp message or not ? */
271 octet = tvb_get_guint8(tvb, offset);
272 if ((octet & 0xf8) != 0xf8)
275 /* Make entries in Protocol column and Info column on summary display */
276 if (check_col(pinfo->cinfo, COL_PROTOCOL))
277 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
279 if (check_col(pinfo->cinfo, COL_INFO))
280 col_clear(pinfo->cinfo, COL_INFO);
285 /* create display subtree for the protocol */
286 ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, FALSE);
287 sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
289 /* add an item to the subtree, see section 1.6 for more information */
290 octet = tvb_get_guint8(tvb, offset);
292 /* A SigComp message takes one of two forms depending on whether it
293 * accesses a state item at the receiving endpoint. The two variants of
294 * a SigComp message are given in Figure 3. (The T-bit controls the
295 * format of the returned feedback item and is defined in Section 7.1.)
297 * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
298 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
299 * | 1 1 1 1 1 | T | len | | 1 1 1 1 1 | T | 0 |
300 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
302 * : returned feedback item : : returned feedback item :
304 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
306 * : partial state identifier : +---+---+---+---+---+---+---+---+
308 * | | | code_len | destination |
309 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
311 * : remaining SigComp message : : uploaded UDVM bytecode :
313 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
315 * : remaining SigComp message :
317 * +---+---+---+---+---+---+---+---+
321 proto_tree_add_item(sigcomp_tree,hf_sigcomp_t_bit, tvb, offset, 1, FALSE);
322 proto_tree_add_item(sigcomp_tree,hf_sigcomp_len, tvb, offset, 1, FALSE);
323 tbit = ( octet & 0x04)>>2;
324 partial_state_len = octet & 0x03;
326 if ( partial_state_len != 0 ){
328 * The len field encodes the number of transmitted bytes as follows:
330 * Encoding: Length of partial state identifier
337 partial_state_len = partial_state_len * 3 + 3;
342 if (check_col(pinfo->cinfo, COL_INFO))
343 col_add_fstr(pinfo->cinfo, COL_INFO, "Msg format 1");
347 * Returned feedback item exists
350 octet = tvb_get_guint8(tvb, offset);
351 /* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
352 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
353 * | 0 | returned_feedback_field | | 1 | returned_feedback_length |
354 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
356 * : returned_feedback_field :
358 * +---+---+---+---+---+---+---+---+
359 * Figure 4: Format of returned feedback item
362 if ( (octet & 0x80) != 0 ){
364 proto_tree_add_uint(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
365 tvb, offset, 1, len);
367 tvb_memcpy(tvb,returned_feedback_field,offset, len);
369 returned_feedback_field[0] = tvb_get_guint8(tvb, offset) & 0x7f;
371 proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
372 tvb, offset, len, returned_feedback_field);
373 offset = offset + len;
374 tvb_memcpy(tvb, partial_state, offset, partial_state_len);
375 proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_partial_state,
376 tvb, offset, partial_state_len, partial_state);
377 offset = offset + partial_state_len;
378 proto_tree_add_text(sigcomp_tree, tvb, offset, -1, "Remaining SigComp message %u bytes",
379 tvb_reported_length_remaining(tvb, offset));
387 if (check_col(pinfo->cinfo, COL_INFO))
388 col_add_fstr(pinfo->cinfo, COL_INFO, "Msg format 2");
391 * Returned feedback item exists
394 octet = tvb_get_guint8(tvb, offset);
395 if ( (octet & 0x80) != 0 ){
397 proto_tree_add_uint(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
398 tvb, offset, 1, len);
401 tvb_memcpy(tvb,returned_feedback_field,offset, len);
402 proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
403 tvb, offset, 1, returned_feedback_field);
404 offset = offset + len;
406 len = tvb_get_ntohs(tvb, offset) >> 4;
407 octet = tvb_get_guint8(tvb, (offset + 1));
408 destination = (octet & 0x0f);
409 if ( destination != 0 )
410 destination = 64 + ( destination * 64 );
411 proto_tree_add_uint(sigcomp_tree,hf_sigcomp_code_len, tvb, offset, 2, len);
412 proto_tree_add_item(sigcomp_tree,hf_sigcomp_destination, tvb, (offset+ 1), 1, FALSE);
415 udvm_item = proto_tree_add_text(sigcomp_tree, tvb, offset, len,
416 "Uploaded UDVM bytecode %u (0x%x) bytes", len, len);
417 sigcomp_udvm_tree = proto_item_add_subtree( udvm_item, ett_sigcomp_udvm);
419 udvm_tvb = tvb_new_subset(tvb, offset, len, len);
420 if ( dissect_udvm_code )
421 dissect_udvm_bytecode(udvm_tvb, sigcomp_udvm_tree, destination);
422 offset = offset + len;
424 proto_tree_add_text(sigcomp_tree, tvb, offset, -1, "Remaining SigComp message %u bytes",
425 tvb_reported_length_remaining(tvb, offset));
427 return tvb_length(tvb);
432 /* Continue adding tree items to process the packet here */
433 /* If this protocol has a sub-dissector call it here, see section 1.8 */
435 #define SIGCOMP_INSTR_DECOMPRESSION_FAILURE 0
436 #define SIGCOMP_INSTR_AND 1
437 #define SIGCOMP_INSTR_OR 2
438 #define SIGCOMP_INSTR_NOT 3
439 #define SIGCOMP_INSTR_LSHIFT 4
440 #define SIGCOMP_INSTR_RSHIFT 5
441 #define SIGCOMP_INSTR_ADD 6
442 #define SIGCOMP_INSTR_SUBTRACT 7
443 #define SIGCOMP_INSTR_MULTIPLY 8
444 #define SIGCOMP_INSTR_DIVIDE 9
445 #define SIGCOMP_INSTR_REMAINDER 10
446 #define SIGCOMP_INSTR_SORT_ASCENDING 11
447 #define SIGCOMP_INSTR_SORT_DESCENDING 12
448 #define SIGCOMP_INSTR_SHA_1 13
449 #define SIGCOMP_INSTR_LOAD 14
450 #define SIGCOMP_INSTR_MULTILOAD 15
451 #define SIGCOMP_INSTR_PUSH 16
452 #define SIGCOMP_INSTR_POP 17
453 #define SIGCOMP_INSTR_COPY 18
454 #define SIGCOMP_INSTR_COPY_LITERAL 19
455 #define SIGCOMP_INSTR_COPY_OFFSET 20
456 #define SIGCOMP_INSTR_MEMSET 21
457 #define SIGCOMP_INSTR_JUMP 22
458 #define SIGCOMP_INSTR_COMPARE 23
459 #define SIGCOMP_INSTR_CALL 24
460 #define SIGCOMP_INSTR_RETURN 25
461 #define SIGCOMP_INSTR_SWITCH 26
462 #define SIGCOMP_INSTR_CRC 27
463 #define SIGCOMP_INSTR_INPUT_BYTES 28
464 #define SIGCOMP_INSTR_INPUT_BITS 29
465 #define SIGCOMP_INSTR_INPUT_HUFFMAN 30
466 #define SIGCOMP_INSTR_STATE_ACCESS 31
467 #define SIGCOMP_INSTR_STATE_CREATE 32
468 #define SIGCOMP_INSTR_STATE_FREE 33
469 #define SIGCOMP_INSTR_OUTPUT 34
470 #define SIGCOMP_INSTR_END_MESSAGE 35
474 dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,guint start_address)
481 guint instruction_no = 0;
483 proto_item *item, *item2;
484 guint UDVM_address = start_address;
485 gboolean is_memory_address;
488 while (tvb_reported_length_remaining(udvm_tvb, offset) > 0) {
489 instruction = tvb_get_guint8(udvm_tvb, offset);
491 UDVM_address = start_address + offset;
494 item = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
495 "######### UDVM instruction %u at UDVM-address %u (0x%x) #########",
496 instruction_no,UDVM_address,UDVM_address);
497 PROTO_ITEM_SET_GENERATED(item);
498 proto_tree_add_item(sigcomp_udvm_tree, hf_sigcomp_udvm_instr, udvm_tvb, offset, 1, FALSE);
500 switch ( instruction ) {
502 case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */
504 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
505 len = offset - start_offset;
506 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
507 udvm_tvb, start_offset, len, value);
509 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
510 len = offset - start_offset;
511 if ( is_memory_address ){
512 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
513 udvm_tvb, start_offset, len, value);
515 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
516 udvm_tvb, start_offset, len, value);
520 case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */
522 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
523 len = offset - start_offset;
524 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
525 udvm_tvb, start_offset, len, value);
527 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
528 len = offset - start_offset;
529 if ( is_memory_address ){
530 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
531 udvm_tvb, start_offset, len, value);
533 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
534 udvm_tvb, start_offset, len, value);
538 case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */
540 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
541 len = offset - start_offset;
542 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
543 udvm_tvb, start_offset, len, value);
546 case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */
548 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
549 len = offset - start_offset;
550 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
551 udvm_tvb, start_offset, len, value);
553 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
554 len = offset - start_offset;
555 if ( is_memory_address ){
556 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
557 udvm_tvb, start_offset, len, value);
559 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
560 udvm_tvb, start_offset, len, value);
564 case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */
566 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
567 len = offset - start_offset;
568 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
569 udvm_tvb, start_offset, len, value);
571 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
572 len = offset - start_offset;
573 if ( is_memory_address ){
574 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
575 udvm_tvb, start_offset, len, value);
577 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
578 udvm_tvb, start_offset, len, value);
582 case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */
584 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
585 len = offset - start_offset;
586 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
587 udvm_tvb, start_offset, len, value);
589 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
590 len = offset - start_offset;
591 if ( is_memory_address ){
592 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
593 udvm_tvb, start_offset, len, value);
595 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
596 udvm_tvb, start_offset, len, value);
600 case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */
602 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
603 len = offset - start_offset;
604 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
605 udvm_tvb, start_offset, len, value);
607 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
608 len = offset - start_offset;
609 if ( is_memory_address ){
610 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
611 udvm_tvb, start_offset, len, value);
613 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
614 udvm_tvb, start_offset, len, value);
618 case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */
620 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
621 len = offset - start_offset;
622 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
623 udvm_tvb, start_offset, len, value);
625 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
626 len = offset - start_offset;
627 if ( is_memory_address ){
628 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
629 udvm_tvb, start_offset, len, value);
631 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
632 udvm_tvb, start_offset, len, value);
636 case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */
638 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
639 len = offset - start_offset;
640 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
641 udvm_tvb, start_offset, len, value);
643 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
644 len = offset - start_offset;
645 if ( is_memory_address ){
646 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
647 udvm_tvb, start_offset, len, value);
649 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
650 udvm_tvb, start_offset, len, value);
654 case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */
656 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
657 len = offset - start_offset;
658 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
659 udvm_tvb, start_offset, len, value);
661 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
662 len = offset - start_offset;
663 if ( is_memory_address ){
664 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
665 udvm_tvb, start_offset, len, value);
667 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
668 udvm_tvb, start_offset, len, value);
671 case SIGCOMP_INSTR_SORT_ASCENDING: /* 11 SORT-ASCENDING (%start, %n, %k) */
672 /* while programming stop while loop */
673 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
676 case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */
677 /* while programming stop while loop */
678 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
680 case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */
682 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
683 len = offset - start_offset;
684 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
685 udvm_tvb, start_offset, len, value);
688 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
689 len = offset - start_offset;
690 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
691 udvm_tvb, start_offset, len, value);
694 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
695 len = offset - start_offset;
696 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
697 udvm_tvb, start_offset, len, value);
700 case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */
702 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
703 len = offset - start_offset;
704 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
705 udvm_tvb, start_offset, len, value);
707 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
708 len = offset - start_offset;
709 if ( is_memory_address ){
710 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
711 udvm_tvb, start_offset, len, value);
713 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
714 udvm_tvb, start_offset, len, value);
718 case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
720 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
721 len = offset - start_offset;
722 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
723 udvm_tvb, start_offset, len, value);
725 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
726 len = offset - start_offset;
727 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
728 udvm_tvb, start_offset, len, value);
733 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
734 len = offset - start_offset;
735 if ( is_memory_address ){
736 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
737 udvm_tvb, start_offset, len, value);
739 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
740 udvm_tvb, start_offset, len, value);
745 case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */
747 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
748 len = offset - start_offset;
749 if ( is_memory_address ){
750 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
751 udvm_tvb, start_offset, len, value);
753 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
754 udvm_tvb, start_offset, len, value);
758 case SIGCOMP_INSTR_POP: /* 17 POP (%address) */
759 /* %address */ offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
761 len = offset - start_offset;
762 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
763 udvm_tvb, start_offset, len, value);
766 case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */
768 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
769 len = offset - start_offset;
770 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
771 udvm_tvb, start_offset, len, value);
774 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
775 len = offset - start_offset;
776 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
777 udvm_tvb, start_offset, len, value);
780 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
781 len = offset - start_offset;
782 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
783 udvm_tvb, start_offset, len, value);
786 case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */
788 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
789 len = offset - start_offset;
790 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
791 udvm_tvb, start_offset, len, value);
794 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
795 len = offset - start_offset;
796 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
797 udvm_tvb, start_offset, len, value);
800 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
801 len = offset - start_offset;
802 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
803 udvm_tvb, start_offset, len, value);
806 case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */
808 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
809 len = offset - start_offset;
810 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
811 udvm_tvb, start_offset, len, value);
814 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
815 len = offset - start_offset;
816 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
817 udvm_tvb, start_offset, len, value);
820 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
821 len = offset - start_offset;
822 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
823 udvm_tvb, start_offset, len, value);
825 case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */
828 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
829 len = offset - start_offset;
830 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
831 udvm_tvb, start_offset, len, value);
834 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE, &start_offset, &value, &is_memory_address);
835 len = offset - start_offset;
836 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
837 udvm_tvb, start_offset, len, value);
840 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
841 len = offset - start_offset;
842 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_start_value,
843 udvm_tvb, start_offset, len, value);
846 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
847 len = offset - start_offset;
848 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
849 udvm_tvb, start_offset, len, value);
853 case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */
855 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
856 len = offset - start_offset;
857 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
858 value = ( value + UDVM_address ) & 0xffff;
859 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
860 udvm_tvb, start_offset, len, value);
863 case SIGCOMP_INSTR_COMPARE: /* 23 */
864 /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
867 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
868 len = offset - start_offset;
869 if ( is_memory_address ){
870 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
871 udvm_tvb, start_offset, len, value);
873 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
874 udvm_tvb, start_offset, len, value);
878 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
879 len = offset - start_offset;
880 if ( is_memory_address ){
881 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
882 udvm_tvb, start_offset, len, value);
884 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
885 udvm_tvb, start_offset, len, value);
889 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
890 len = offset - start_offset;
891 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
892 value = ( value + UDVM_address ) & 0xffff;
893 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
894 udvm_tvb, start_offset, len, value);
897 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
898 len = offset - start_offset;
899 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
900 value = ( value + UDVM_address ) & 0xffff;
901 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
902 udvm_tvb, start_offset, len, value);
905 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
906 len = offset - start_offset;
907 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
908 value = ( value + UDVM_address ) & 0xffff;
909 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
910 udvm_tvb, start_offset, len, value);
913 case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/
915 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
916 len = offset - start_offset;
917 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
918 value = ( value + UDVM_address ) & 0xffff;
919 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
920 udvm_tvb, start_offset, len, value);
922 case SIGCOMP_INSTR_RETURN: /* 25 POP and return */
925 case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
927 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
928 len = offset - start_offset;
929 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
930 udvm_tvb, start_offset, len, value);
932 /* Number of addresses in the instruction */
935 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
936 len = offset - start_offset;
937 if ( is_memory_address ){
938 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
939 udvm_tvb, start_offset, len, value);
941 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
942 udvm_tvb, start_offset, len, value);
948 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
949 len = offset - start_offset;
950 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
951 value = ( value + UDVM_address ) & 0xffff;
952 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
953 udvm_tvb, start_offset, len, value);
956 case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */
958 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
959 len = offset - start_offset;
960 if ( is_memory_address ){
961 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
962 udvm_tvb, start_offset, len, value);
964 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
965 udvm_tvb, start_offset, len, value);
969 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
970 len = offset - start_offset;
971 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
972 udvm_tvb, start_offset, len, value);
975 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
976 len = offset - start_offset;
977 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
978 udvm_tvb, start_offset, len, value);
981 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
982 len = offset - start_offset;
983 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
984 value = ( value + UDVM_address ) & 0xffff;
985 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
986 udvm_tvb, start_offset, len, value);
990 case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */
992 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
993 len = offset - start_offset;
994 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
995 udvm_tvb, start_offset, len, value);
998 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
999 len = offset - start_offset;
1000 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1001 udvm_tvb, start_offset, len, value);
1004 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1005 len = offset - start_offset;
1006 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1007 value = ( value + UDVM_address ) & 0xffff;
1008 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1009 udvm_tvb, start_offset, len, value);
1011 case SIGCOMP_INSTR_INPUT_BITS:/* 29 INPUT-BITS (%length, %destination, @address) */
1013 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1014 len = offset - start_offset;
1015 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1016 udvm_tvb, start_offset, len, value);
1019 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1020 len = offset - start_offset;
1021 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1022 udvm_tvb, start_offset, len, value);
1025 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1026 len = offset - start_offset;
1027 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1028 value = ( value + UDVM_address ) & 0xffff;
1029 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1030 udvm_tvb, start_offset, len, value);
1032 case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */
1034 * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1,
1035 * %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n,
1036 * %upper_bound_n, %uncompressed_n)
1039 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1040 len = offset - start_offset;
1041 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1042 udvm_tvb, start_offset, len, value);
1045 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1046 len = offset - start_offset;
1047 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1048 value = ( value + UDVM_address ) & 0xffff;
1049 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1050 udvm_tvb, start_offset, len, value);
1052 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1053 len = offset - start_offset;
1054 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1055 udvm_tvb, start_offset, len, value);
1060 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1061 len = offset - start_offset;
1062 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_bits,
1063 udvm_tvb, start_offset, len, value);
1065 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1066 len = offset - start_offset;
1067 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_lower_bound,
1068 udvm_tvb, start_offset, len, value);
1069 /* %upper_bound_n */
1070 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1071 len = offset - start_offset;
1072 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_upper_bound,
1073 udvm_tvb, start_offset, len, value);
1074 /* %uncompressed_n */
1075 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1076 len = offset - start_offset;
1077 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_uncompressed,
1078 udvm_tvb, start_offset, len, value);
1082 case SIGCOMP_INSTR_STATE_ACCESS: /* 31 */
1083 /* STATE-ACCESS (%partial_identifier_start, %partial_identifier_length,
1084 * %state_begin, %state_length, %state_address, %state_instruction)
1088 * %partial_identifier_start
1090 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1091 len = offset - start_offset;
1092 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
1093 udvm_tvb, start_offset, len, value);
1096 * %partial_identifier_length
1098 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1099 len = offset - start_offset;
1100 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length,
1101 udvm_tvb, start_offset, len, value);
1105 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1106 len = offset - start_offset;
1107 proto_tree_add_uint(sigcomp_udvm_tree, hf_state_begin,
1108 udvm_tvb, start_offset, len, value);
1113 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1114 len = offset - start_offset;
1115 if ( is_memory_address ) {
1116 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1117 udvm_tvb, start_offset, len, value);
1119 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1120 udvm_tvb, start_offset, len, value);
1125 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1126 len = offset - start_offset;
1127 if ( is_memory_address ) {
1128 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1129 udvm_tvb, start_offset, len, value);
1131 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1132 udvm_tvb, start_offset, len, value);
1135 * %state_instruction
1137 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1138 len = offset - start_offset;
1139 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1140 udvm_tvb, start_offset, len, value);
1142 case SIGCOMP_INSTR_STATE_CREATE: /* 32 */
1144 * STATE-CREATE (%state_length, %state_address, %state_instruction,
1145 * %minimum_access_length, %state_retention_priority)
1151 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1152 len = offset - start_offset;
1153 if ( is_memory_address ) {
1154 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1155 udvm_tvb, start_offset, len, value);
1157 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1158 udvm_tvb, start_offset, len, value);
1163 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1164 len = offset - start_offset;
1165 if ( is_memory_address ) {
1166 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1167 udvm_tvb, start_offset, len, value);
1169 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1170 udvm_tvb, start_offset, len, value);
1173 * %state_instruction
1175 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1176 len = offset - start_offset;
1177 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1178 udvm_tvb, start_offset, len, value);
1180 * %minimum_access_length
1182 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1183 len = offset - start_offset;
1184 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len,
1185 udvm_tvb, start_offset, len, value);
1187 * %state_retention_priority
1189 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1190 len = offset - start_offset;
1191 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
1192 udvm_tvb, start_offset, len, value);
1195 case SIGCOMP_INSTR_STATE_FREE: /* 33 */
1197 * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
1200 * %partial_identifier_start
1202 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1203 len = offset - start_offset;
1204 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
1205 udvm_tvb, start_offset, len, value);
1208 * %partial_identifier_length
1210 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1211 len = offset - start_offset;
1212 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length,
1213 udvm_tvb, start_offset, len, value);
1215 case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */
1219 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1220 len = offset - start_offset;
1221 if ( is_memory_address ) {
1222 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start,
1223 udvm_tvb, start_offset, len, value);
1225 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start,
1226 udvm_tvb, start_offset, len, value);
1231 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1232 len = offset - start_offset;
1233 if ( is_memory_address ) {
1234 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length_addr,
1235 udvm_tvb, start_offset, len, value);
1237 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length,
1238 udvm_tvb, start_offset, len, value);
1241 case SIGCOMP_INSTR_END_MESSAGE: /* 35 */
1243 * END-MESSAGE (%requested_feedback_location,
1244 * %returned_parameters_location, %state_length, %state_address,
1245 * %state_instruction, %minimum_access_length,
1246 * %state_retention_priority)
1248 /* %requested_feedback_location */
1249 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1250 len = offset - start_offset;
1251 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_req_feedback_loc,
1252 udvm_tvb, start_offset, len, value);
1253 /* returned_parameters_location */
1254 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1255 len = offset - start_offset;
1256 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ret_param_loc,
1257 udvm_tvb, start_offset, len, value);
1261 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1262 len = offset - start_offset;
1263 if ( is_memory_address ) {
1264 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1265 udvm_tvb, start_offset, len, value);
1267 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1268 udvm_tvb, start_offset, len, value);
1273 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1274 len = offset - start_offset;
1275 if ( is_memory_address ) {
1276 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1277 udvm_tvb, start_offset, len, value);
1279 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1280 udvm_tvb, start_offset, len, value);
1283 * %state_instruction
1285 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1286 len = offset - start_offset;
1287 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1288 udvm_tvb, start_offset, len, value);
1290 * %minimum_access_length
1292 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1293 len = offset - start_offset;
1294 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len,
1295 udvm_tvb, start_offset, len, value);
1297 * %state_retention_priority
1299 if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1300 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1301 len = offset - start_offset;
1302 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
1303 udvm_tvb, start_offset, len, value);
1305 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
1306 "state_retention_priority = 0(Not in the uploaded code as UDVM buffer initalized to Zero");
1307 PROTO_ITEM_SET_GENERATED(item2);
1309 if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1310 len = tvb_reported_length_remaining(udvm_tvb, offset);
1311 UDVM_address = start_address + offset;
1312 proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, len,
1313 "Remaning %u bytes starting at UDVM addr %u (0x%x)- State information ?",len, UDVM_address, UDVM_address);
1315 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1319 /* while programming stop while loop */
1320 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1328 /* The simplest operand type is the literal (#), which encodes a
1329 * constant integer from 0 to 65535 inclusive. A literal operand may
1330 * require between 1 and 3 bytes depending on its value.
1331 * Bytecode: Operand value: Range:
1332 * 0nnnnnnn N 0 - 127
1333 * 10nnnnnn nnnnnnnn N 0 - 16383
1334 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
1336 * Figure 8: Bytecode for a literal (#) operand
1340 dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1341 gint offset, gint *start_offset, guint16 *value)
1346 guint display_bytecode;
1348 bytecode = tvb_get_guint8(udvm_tvb, offset);
1349 test_bits = bytecode >> 7;
1350 if (test_bits == 1){
1351 test_bits = bytecode >> 6;
1352 if (test_bits == 2){
1354 * 10nnnnnn nnnnnnnn N 0 - 16383
1356 display_bytecode = bytecode & 0xc0;
1357 if ( display_udvm_bytecode )
1358 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1359 udvm_tvb, offset, 1, display_bytecode);
1360 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
1362 *start_offset = offset;
1363 offset = offset + 2;
1367 * 111000000 nnnnnnnn nnnnnnnn N 0 - 65535
1369 display_bytecode = bytecode & 0xc0;
1370 if ( display_udvm_bytecode )
1371 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1372 udvm_tvb, offset, 1, display_bytecode);
1374 operand = tvb_get_ntohs(udvm_tvb, offset);
1376 *start_offset = offset;
1377 offset = offset + 2;
1382 * 0nnnnnnn N 0 - 127
1384 display_bytecode = bytecode & 0xc0;
1385 if ( display_udvm_bytecode )
1386 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1387 udvm_tvb, offset, 1, display_bytecode);
1388 operand = ( bytecode & 0x7f);
1390 *start_offset = offset;
1398 * The second operand type is the reference ($), which is always used to
1399 * access a 2-byte value located elsewhere in the UDVM memory. The
1400 * bytecode for a reference operand is decoded to be a constant integer
1401 * from 0 to 65535 inclusive, which is interpreted as the memory address
1402 * containing the actual value of the operand.
1403 * Bytecode: Operand value: Range:
1405 * 0nnnnnnn memory[2 * N] 0 - 65535
1406 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
1407 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
1409 * Figure 9: Bytecode for a reference ($) operand
1412 dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1413 gint offset, gint *start_offset, guint16 *value)
1418 guint display_bytecode;
1420 bytecode = tvb_get_guint8(udvm_tvb, offset);
1421 test_bits = bytecode >> 7;
1422 if (test_bits == 1){
1423 test_bits = bytecode >> 6;
1424 if (test_bits == 2){
1426 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
1428 display_bytecode = bytecode & 0xc0;
1429 if ( display_udvm_bytecode )
1430 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
1431 udvm_tvb, offset, 1, display_bytecode);
1432 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
1433 *value = (operand * 2);
1434 *start_offset = offset;
1435 offset = offset + 2;
1439 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
1441 display_bytecode = bytecode & 0xc0;
1442 if ( display_udvm_bytecode )
1443 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
1444 udvm_tvb, offset, 1, display_bytecode);
1446 operand = tvb_get_ntohs(udvm_tvb, offset);
1448 *start_offset = offset;
1449 offset = offset + 2;
1454 * 0nnnnnnn memory[2 * N] 0 - 65535
1456 display_bytecode = bytecode & 0xc0;
1457 if ( display_udvm_bytecode )
1458 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
1459 udvm_tvb, offset, 1, display_bytecode);
1460 operand = ( bytecode & 0x3f);
1461 *value = (operand * 2);
1462 *start_offset = offset;
1470 *The fourth operand type is the address (@). This operand is decoded
1471 * as a multitype operand followed by a further step: the memory address
1472 * of the UDVM instruction containing the address operand is added to
1473 * obtain the correct operand value. So if the operand value from
1474 * Figure 10 is D then the actual operand value of an address is
1475 * calculated as follows:
1477 * operand_value = (is_memory_address_of_instruction + D) modulo 2^16
1478 * TODO calculate correct value for operand in case of ADDR
1481 dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1482 gint offset, gboolean is_addr, gint *start_offset, guint16 *value, gboolean *is_memory_address )
1485 guint display_bytecode;
1490 * Figure 10: Bytecode for a multitype (%) operand
1491 * Bytecode: Operand value: Range: HEX val
1492 * 00nnnnnn N 0 - 63 0x00
1493 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
1494 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
1495 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
1496 * 111nnnnn N + 65504 65504 - 65535 0xe0
1497 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
1498 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
1499 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
1500 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
1501 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
1503 *is_memory_address = FALSE;
1504 bytecode = tvb_get_guint8(udvm_tvb, offset);
1505 test_bits = ( bytecode & 0xc0 ) >> 6;
1506 switch (test_bits ){
1511 display_bytecode = bytecode & 0xc0;
1512 if ( display_udvm_bytecode )
1513 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1514 udvm_tvb, offset, 1, display_bytecode);
1515 operand = ( bytecode & 0x3f);
1517 *start_offset = offset;
1522 * 01nnnnnn memory[2 * N] 0 - 65535
1524 display_bytecode = bytecode & 0xc0;
1525 if ( display_udvm_bytecode )
1526 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1527 udvm_tvb, offset, 1, display_bytecode);
1528 operand = ( bytecode & 0x3f) * 2;
1529 *is_memory_address = TRUE;
1531 *start_offset = offset;
1535 /* Check tree most significant bits */
1536 test_bits = ( bytecode & 0xe0 ) >> 5;
1537 if ( test_bits == 5 ){
1539 * 101nnnnn nnnnnnnn N 0 - 8191
1541 display_bytecode = bytecode & 0xe0;
1542 if ( display_udvm_bytecode )
1543 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1544 udvm_tvb, offset, 1, display_bytecode);
1545 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x1fff;
1547 *start_offset = offset;
1548 offset = offset + 2;
1550 test_bits = ( bytecode & 0xf0 ) >> 4;
1551 if ( test_bits == 9 ){
1553 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535
1555 display_bytecode = bytecode & 0xf0;
1556 if ( display_udvm_bytecode )
1557 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1558 udvm_tvb, offset, 1, display_bytecode);
1559 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x0fff) + 61440;
1560 *start_offset = offset;
1562 offset = offset + 2;
1564 test_bits = ( bytecode & 0x08 ) >> 3;
1565 if ( test_bits == 1){
1567 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768
1569 display_bytecode = bytecode & 0xf8;
1570 if ( display_udvm_bytecode )
1571 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1572 udvm_tvb, offset, 1, display_bytecode);
1573 result = (guint32)pow(2,( bytecode & 0x07) + 8);
1574 operand = result & 0xffff;
1575 *start_offset = offset;
1579 test_bits = ( bytecode & 0x0e ) >> 1;
1580 if ( test_bits == 3 ){
1582 * 1000 011n 2 ^ (N + 6) 64 , 128
1584 display_bytecode = bytecode & 0xfe;
1585 if ( display_udvm_bytecode )
1586 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1587 udvm_tvb, offset, 1, display_bytecode);
1588 result = (guint32)pow(2,( bytecode & 0x01) + 6);
1589 operand = result & 0xffff;
1590 *start_offset = offset;
1595 * 1000 0000 nnnnnnnn nnnnnnnn N 0 - 65535
1596 * 1000 0001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
1598 display_bytecode = bytecode;
1599 if ( display_udvm_bytecode )
1600 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1601 udvm_tvb, offset, 1, display_bytecode);
1602 if ( (bytecode & 0x01) == 1 )
1603 *is_memory_address = TRUE;
1605 operand = tvb_get_ntohs(udvm_tvb, offset);
1607 *start_offset = offset;
1618 test_bits = ( bytecode & 0x20 ) >> 5;
1619 if ( test_bits == 1 ){
1621 * 111nnnnn N + 65504 65504 - 65535
1623 display_bytecode = bytecode & 0xe0;
1624 if ( display_udvm_bytecode )
1625 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1626 udvm_tvb, offset, 1, display_bytecode);
1627 operand = ( bytecode & 0x1f) + 65504;
1628 *start_offset = offset;
1633 * 110nnnnn nnnnnnnn memory[N] 0 - 65535
1635 display_bytecode = bytecode & 0xe0;
1636 if ( display_udvm_bytecode )
1637 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
1638 udvm_tvb, offset, 1, display_bytecode);
1639 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x1fff);
1640 *is_memory_address = TRUE;
1641 *start_offset = offset;
1651 /* Register the protocol with Ethereal */
1654 /* If this dissector uses sub-dissector registration add a registration routine.
1655 This format is required because a script is used to find these routines and
1656 create the code that calls these routines.
1659 proto_reg_handoff_sigcomp(void)
1661 static dissector_handle_t sigcomp_handle;
1662 static int Initialized=FALSE;
1663 static int udp_port1 = 5555;
1664 static int udp_port2 = 6666;
1667 sigcomp_handle = new_create_dissector_handle(dissect_sigcomp,
1671 dissector_delete("udp.port", udp_port1, sigcomp_handle);
1672 dissector_delete("udp.port", udp_port2, sigcomp_handle);
1675 udp_port1 = SigCompUDPPort1;
1676 udp_port2 = SigCompUDPPort2;
1679 dissector_add("udp.port", SigCompUDPPort1, sigcomp_handle);
1680 dissector_add("udp.port", SigCompUDPPort2, sigcomp_handle);
1685 /* this format is require because a script is used to build the C function
1686 that calls all the protocol registration.
1690 proto_register_sigcomp(void)
1693 /* Setup list of header fields See Section 1.6.1 for details*/
1694 static hf_register_info hf[] = {
1695 { &hf_sigcomp_t_bit,
1696 { "T bit", "sigcomp.t.bit",
1697 FT_UINT8, BASE_DEC, NULL, 0x04,
1698 "Sigcomp T bit", HFILL }
1701 { "Partial state id. len.","sigcomp.length",
1702 FT_UINT8, BASE_HEX, VALS(&length_encoding_vals), 0x03,
1703 "Sigcomp length", HFILL }
1705 { &hf_sigcomp_returned_feedback_item,
1706 { "Returned_feedback item", "sigcomp.returned.feedback.item",
1707 FT_BYTES, BASE_HEX, NULL, 0x0,
1708 "Returned feedback item", HFILL }
1710 { &hf_sigcomp_partial_state,
1711 { "Partial state identifier", "sigcomp.partial.state.identifier",
1712 FT_BYTES, BASE_HEX, NULL, 0x0,
1713 "Partial state identifier", HFILL }
1715 { &hf_sigcomp_returned_feedback_item_len,
1716 { "Returned feedback item length", "sigcomp.returned.feedback.item.len",
1717 FT_UINT8, BASE_DEC, NULL, 0x0,
1718 "Returned feedback item length", HFILL }
1720 { &hf_sigcomp_code_len,
1721 { "Code length","sigcomp.code.len",
1722 FT_UINT16, BASE_HEX, NULL, 0x0,
1723 "Code length", HFILL }
1725 { &hf_sigcomp_destination,
1726 { "Destination","sigcomp.destination",
1727 FT_UINT8, BASE_HEX, VALS(&destination_address_encoding_vals), 0xf,
1728 "Destination", HFILL }
1730 { &hf_sigcomp_udvm_instr,
1731 { "UDVM instruction code","sigcomp.udvm.instr",
1732 FT_UINT8, BASE_DEC, VALS(&udvm_instruction_code_vals), 0x0,
1733 "UDVM instruction code", HFILL }
1735 { &hf_udvm_multitype_bytecode,
1736 { "UDVM bytecode", "sigcomp.udvm.multyt.bytecode",
1737 FT_UINT8, BASE_HEX, VALS(&display_bytecode_vals), 0x0,
1738 "UDVM bytecode", HFILL }
1740 { &hf_udvm_reference_bytecode,
1741 { "UDVM bytecode", "sigcomp.udvm.ref.bytecode",
1742 FT_UINT8, BASE_HEX, VALS(&display_ref_bytecode_vals), 0x0,
1743 "UDVM bytecode", HFILL }
1745 { &hf_udvm_literal_bytecode,
1746 { "UDVM bytecode", "sigcomp.udvm.lit.bytecode",
1747 FT_UINT8, BASE_HEX, VALS(&display_lit_bytecode_vals), 0x0,
1748 "UDVM bytecode", HFILL }
1751 { "UDVM operand", "sigcomp.udvm.operand",
1752 FT_UINT16, BASE_DEC, NULL, 0x0,
1753 "UDVM operand", HFILL }
1756 { " %Length", "sigcomp.udvm.length",
1757 FT_UINT16, BASE_DEC, NULL, 0x0,
1760 { &hf_udvm_destination,
1761 { " %Destination", "sigcomp.udvm.destination",
1762 FT_UINT16, BASE_DEC, NULL, 0x0,
1763 "Destination", HFILL }
1765 { &hf_udvm_at_address,
1766 { " @Address(mem_add_of_inst + D) mod 2^16)", "sigcomp.udvm.at.address",
1767 FT_UINT16, BASE_DEC, NULL, 0x0,
1771 { " %Address", "sigcomp.udvm.length",
1772 FT_UINT16, BASE_DEC, NULL, 0x0,
1775 { &hf_udvm_literal_num,
1776 { " #n", "sigcomp.udvm.literal-num",
1777 FT_UINT16, BASE_DEC, NULL, 0x0,
1778 "Literal number", HFILL }
1781 { " %Value", "sigcomp.udvm.value",
1782 FT_UINT16, BASE_DEC, NULL, 0x0,
1785 { &hf_udvm_addr_value,
1786 { " %Value[memory address]", "sigcomp.udvm.value",
1787 FT_UINT16, BASE_DEC, NULL, 0x0,
1790 { &hf_partial_identifier_start,
1791 { " %Partial identifier start", "sigcomp.udvm.partial.identifier.start",
1792 FT_UINT16, BASE_DEC, NULL, 0x0,
1793 "Partial identifier start", HFILL }
1795 { &hf_partial_identifier_length,
1796 { " %Partial identifier length", "sigcomp.udvm.partial.identifier.length",
1797 FT_UINT16, BASE_DEC, NULL, 0x0,
1798 "Partial identifier length", HFILL }
1801 { " %State begin", "sigcomp.udvm.state.begin",
1802 FT_UINT16, BASE_DEC, NULL, 0x0,
1803 "State begin", HFILL }
1805 { &hf_udvm_state_length,
1806 { " %State length", "sigcomp.udvm.state.length",
1807 FT_UINT16, BASE_DEC, NULL, 0x0,
1808 "State length", HFILL }
1811 { &hf_udvm_state_length_addr,
1812 { " %State length[memory address]", "sigcomp.udvm.state.length.addr",
1813 FT_UINT16, BASE_DEC, NULL, 0x0,
1814 "State length", HFILL }
1816 { &hf_udvm_state_address,
1817 { " %State address", "sigcomp.udvm.start.address",
1818 FT_UINT16, BASE_DEC, NULL, 0x0,
1819 "State address", HFILL }
1821 { &hf_udvm_state_address_addr,
1822 { " %State address[memory address]", "sigcomp.udvm.start.address.addr",
1823 FT_UINT16, BASE_DEC, NULL, 0x0,
1824 "State address", HFILL }
1826 { &hf_udvm_state_instr,
1827 { " %State instruction", "sigcomp.udvm.start.instr",
1828 FT_UINT16, BASE_DEC, NULL, 0x0,
1829 "State instruction", HFILL }
1831 { &hf_udvm_operand_1,
1832 { " $Operand 1[memory address]", "sigcomp.udvm.operand.1",
1833 FT_UINT16, BASE_DEC, NULL, 0x0,
1834 "Reference $ Operand 1", HFILL }
1836 { &hf_udvm_operand_2,
1837 { " %Operand 2", "sigcomp.udvm.operand.2",
1838 FT_UINT16, BASE_DEC, NULL, 0x0,
1839 "Operand 2", HFILL }
1841 { &hf_udvm_operand_2_addr,
1842 { " %Operand 2[memory address]", "sigcomp.udvm.operand.2.addr",
1843 FT_UINT16, BASE_DEC, NULL, 0x0,
1844 "Operand 2", HFILL }
1847 { " %j", "sigcomp.udvm.j",
1848 FT_UINT16, BASE_DEC, NULL, 0x0,
1851 { &hf_udvm_output_start,
1852 { " %Output_start", "sigcomp.output.start",
1853 FT_UINT16, BASE_DEC, NULL, 0x0,
1854 "Output start", HFILL }
1856 { &hf_udvm_output_start_addr,
1857 { " %Output_start[memory address]", "sigcomp.output.start.addr",
1858 FT_UINT16, BASE_DEC, NULL, 0x0,
1859 "Output start", HFILL }
1861 { &hf_udvm_output_length,
1862 { " %Output_length", "sigcomp.output.length",
1863 FT_UINT16, BASE_DEC, NULL, 0x0,
1864 "Output length", HFILL }
1866 { &hf_udvm_output_length_addr,
1867 { " %Output_length[memory address]", "sigcomp.output.length.addr",
1868 FT_UINT16, BASE_DEC, NULL, 0x0,
1869 "Output length", HFILL }
1871 { &hf_udvm_req_feedback_loc,
1872 { " %Requested feedback location", "sigcomp.req.feedback.loc",
1873 FT_UINT16, BASE_DEC, NULL, 0x0,
1874 "Requested feedback location", HFILL }
1876 { &hf_udvm_min_acc_len,
1877 { " %Minimum access length", "sigcomp.min.acc.len",
1878 FT_UINT16, BASE_DEC, NULL, 0x0,
1879 "Output length", HFILL }
1881 { &hf_udvm_state_ret_pri,
1882 { " %State retention priority", "sigcomp.udvm.state.ret.pri",
1883 FT_UINT16, BASE_DEC, NULL, 0x0,
1884 "Output length", HFILL }
1886 { &hf_udvm_ret_param_loc,
1887 { " %Returned parameters location", "sigcomp.ret.param.loc",
1888 FT_UINT16, BASE_DEC, NULL, 0x0,
1889 "Output length", HFILL }
1891 { &hf_udvm_position,
1892 { " %Position", "sigcomp.udvm.position",
1893 FT_UINT16, BASE_DEC, NULL, 0x0,
1896 { &hf_udvm_ref_dest,
1897 { " $Destination[memory address]", "sigcomp.udvm.ref.destination",
1898 FT_UINT16, BASE_DEC, NULL, 0x0,
1899 "(reference)Destination", HFILL }
1902 { " %Bits", "sigcomp.udvm.bits",
1903 FT_UINT16, BASE_DEC, NULL, 0x0,
1906 { &hf_udvm_lower_bound,
1907 { " %Lower bound", "sigcomp.udvm.lower.bound",
1908 FT_UINT16, BASE_DEC, NULL, 0x0,
1909 "Lower_bound", HFILL }
1911 { &hf_udvm_upper_bound,
1912 { " %Upper bound", "sigcomp.udvm.upper.bound",
1913 FT_UINT16, BASE_DEC, NULL, 0x0,
1914 "Upper bound", HFILL }
1916 { &hf_udvm_uncompressed,
1917 { " %Uncompressed", "sigcomp.udvm.uncompressed",
1918 FT_UINT16, BASE_DEC, NULL, 0x0,
1919 "Uncompressed", HFILL }
1921 { &hf_udvm_start_value,
1922 { " %Start value", "sigcomp.udvm.start.value",
1923 FT_UINT16, BASE_DEC, NULL, 0x0,
1924 "Start value", HFILL }
1927 { " %Offset", "sigcomp.udvm.offset",
1928 FT_UINT16, BASE_DEC, NULL, 0x0,
1933 /* Setup protocol subtree array */
1934 static gint *ett[] = {
1939 module_t *sigcomp_module;
1941 /* Register the protocol name and description */
1942 proto_sigcomp = proto_register_protocol("Signaling Compression",
1943 "SIGCOMP", "sigcomp");
1945 /* Required function calls to register the header fields and subtrees used */
1946 proto_register_field_array(proto_sigcomp, hf, array_length(hf));
1947 proto_register_subtree_array(ett, array_length(ett));
1949 /* Register a configuration option for port */
1950 sigcomp_module = prefs_register_protocol(proto_sigcomp,
1951 proto_reg_handoff_sigcomp);
1953 prefs_register_uint_preference(sigcomp_module, "udp.port",
1954 "Sigcomp UDP Port 1",
1955 "Set UDP port 1 for SigComp messages",
1959 prefs_register_uint_preference(sigcomp_module, "udp.port2",
1960 "Sigcomp UDP Port 2",
1961 "Set UDP port 2 for SigComp messages",
1964 prefs_register_bool_preference(sigcomp_module, "display.udvm.code",
1965 "Dissect the UDVM code",
1966 "Preference wether to Dissect the UDVM code or not",
1967 &dissect_udvm_code);
1969 prefs_register_bool_preference(sigcomp_module, "display.bytecode",
1970 "Display the bytecode of operands",
1971 "preference wether to display the bytecode in UDVM operands or not",
1972 &display_udvm_bytecode);