HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-sigcomp.c
blob57f3acf249e596bc018e925dfa0d659ed9dfcf51
1 /* packet-sigcomp.c
2 * Routines for Signaling Compression (SigComp) dissection.
3 * Copyright 2004-2005, Anders Broman <anders.broman@ericsson.com>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * References:
25 * http://www.ietf.org/rfc/rfc3320.txt?number=3320
26 * http://www.ietf.org/rfc/rfc3321.txt?number=3321
27 * http://www.ietf.org/rfc/rfc4077.txt?number=4077
28 * Useful links :
29 * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-impl-guide-03.txt
30 * http://www.ietf.org/internet-drafts/draft-ietf-rohc-sigcomp-sip-01.txt
33 #include "config.h"
35 #include <math.h>
36 #include <glib.h>
38 #include <epan/packet.h>
39 #include <epan/prefs.h>
40 #include <epan/strutil.h>
41 #include <epan/expert.h>
42 #include <epan/wmem/wmem.h>
43 #include <epan/sigcomp-udvm.h>
44 #include <epan/sigcomp_state_hdlr.h>
46 /* Initialize the protocol and registered fields */
47 static int proto_sigcomp = -1;
48 static int proto_raw_sigcomp = -1;
49 static int hf_sigcomp_t_bit = -1;
50 static int hf_sigcomp_len = -1;
51 static int hf_sigcomp_returned_feedback_item = -1;
52 static int hf_sigcomp_returned_feedback_item_len = -1;
53 static int hf_sigcomp_code_len = -1;
54 static int hf_sigcomp_destination = -1;
55 static int hf_sigcomp_partial_state = -1;
56 static int hf_sigcomp_remaining_message_bytes = -1;
57 static int hf_sigcomp_compression_ratio = -1;
58 static int hf_sigcomp_udvm_bytecode = -1;
59 static int hf_sigcomp_udvm_instr = -1;
60 static int hf_udvm_multitype_bytecode = -1;
61 static int hf_udvm_reference_bytecode = -1;
62 static int hf_udvm_literal_bytecode = -1;
63 /* static int hf_udvm_operand = -1; */
64 static int hf_udvm_length = -1;
65 static int hf_udvm_addr_length = -1;
66 static int hf_udvm_destination = -1;
67 static int hf_udvm_addr_destination = -1;
68 static int hf_udvm_at_address = -1;
69 static int hf_udvm_address = -1;
70 static int hf_udvm_literal_num = -1;
71 static int hf_udvm_value = -1;
72 static int hf_udvm_addr_value = -1;
73 static int hf_partial_identifier_start = -1;
74 static int hf_partial_identifier_length = -1;
75 static int hf_state_begin = -1;
76 static int hf_udvm_state_length = -1;
77 static int hf_udvm_state_length_addr = -1;
78 static int hf_udvm_state_address = -1;
79 static int hf_udvm_state_address_addr = -1;
80 static int hf_udvm_state_instr = -1;
81 static int hf_udvm_operand_1 = -1;
82 static int hf_udvm_operand_2 = -1;
83 static int hf_udvm_operand_2_addr = -1;
84 static int hf_udvm_j = -1;
85 static int hf_udvm_addr_j = -1;
86 static int hf_udvm_output_start = -1;
87 static int hf_udvm_addr_output_start = -1;
88 static int hf_udvm_output_length = -1;
89 static int hf_udvm_output_length_addr = -1;
90 static int hf_udvm_req_feedback_loc = -1;
91 static int hf_udvm_min_acc_len = -1;
92 static int hf_udvm_state_ret_pri = -1;
93 static int hf_udvm_ret_param_loc = -1;
94 static int hf_udvm_position = -1;
95 static int hf_udvm_ref_dest = -1;
96 static int hf_udvm_bits = -1;
97 static int hf_udvm_lower_bound = -1;
98 static int hf_udvm_upper_bound = -1;
99 static int hf_udvm_uncompressed = -1;
100 static int hf_udvm_offset = -1;
101 static int hf_udvm_addr_offset = -1;
102 static int hf_udvm_start_value = -1;
103 static int hf_udvm_execution_trace = -1;
104 static int hf_sigcomp_nack_ver = -1;
105 static int hf_sigcomp_nack_reason_code = -1;
106 static int hf_sigcomp_nack_failed_op_code = -1;
107 static int hf_sigcomp_nack_pc = -1;
108 static int hf_sigcomp_nack_sha1 = -1;
109 static int hf_sigcomp_nack_state_id = -1;
110 static int hf_sigcomp_nack_memory_size = -1;
111 static int hf_sigcomp_nack_cycles_per_bit = -1;
113 /* Initialize the subtree pointers */
114 static gint ett_sigcomp = -1;
115 static gint ett_sigcomp_udvm = -1;
116 static gint ett_sigcomp_udvm_exe = -1;
117 static gint ett_raw_text = -1;
119 static expert_field ei_sigcomp_nack_failed_op_code = EI_INIT;
121 static dissector_handle_t sip_handle;
122 /* set the udp ports */
123 static guint SigCompUDPPort1 = 5555;
124 static guint SigCompUDPPort2 = 6666;
126 /* set the tcp ports */
127 static guint SigCompTCPPort1 = 5555;
128 static guint SigCompTCPPort2 = 6666;
130 /* Default preference whether to display the bytecode in UDVM operands or not */
131 static gboolean display_udvm_bytecode = FALSE;
132 /* Default preference whether to dissect the UDVM code or not */
133 static gboolean dissect_udvm_code = TRUE;
134 static gboolean display_raw_txt = FALSE;
135 /* Default preference whether to decompress the message or not */
136 static gboolean decompress = TRUE;
137 /* Default preference whether to print debug info at execution of UDVM
138 * 0 = No printout
139 * 1 = details level 1
140 * 2 = details level 2
141 * 3 = details level 3
142 * 4 = details level 4
144 static gint udvm_print_detail_level = 0;
146 /* Value strings */
147 static const value_string length_encoding_vals[] = {
148 { 0x00, "No partial state (Message type 2)" },
149 { 0x01, "(6 bytes)" },
150 { 0x02, "(9 bytes)" },
151 { 0x03, "(12 bytes)" },
152 { 0, NULL }
156 static const value_string destination_address_encoding_vals[] = {
157 { 0x00, "Reserved" },
158 { 0x01, "128" },
159 { 0x02, "192" },
160 { 0x03, "256" },
161 { 0x04, "320" },
162 { 0x05, "384" },
163 { 0x06, "448" },
164 { 0x07, "512" },
165 { 0x08, "576" },
166 { 0x09, "640" },
167 { 0x0a, "704" },
168 { 0x0b, "768" },
169 { 0x0c, "832" },
170 { 0x0d, "896" },
171 { 0x0e, "960" },
172 { 0x0F, "1024" },
173 { 0, NULL }
176 static const value_string udvm_instruction_code_vals[] = {
177 { 0, "DECOMPRESSION-FAILURE" },
178 { 1, "AND" },
179 { 2, "OR" },
180 { 3, "NOT" },
181 { 4, "LSHIFT" },
182 { 5, "RSHIFT" },
183 { 6, "ADD" },
184 { 7, "SUBTRACT" },
185 { 8, "MULTIPLY" },
186 { 9, "DIVIDE" },
187 { 10, "REMAINDER" },
188 { 11, "SORT-ASCENDING" },
189 { 12, "SORT-DESCENDING" },
190 { 13, "SHA-1" },
191 { 14, "LOAD" },
192 { 15, "MULTILOAD" },
193 { 16, "PUSH" },
194 { 17, "POP" },
195 { 18, "COPY" },
196 { 19, "COPY-LITERAL" },
197 { 20, "COPY-OFFSET" },
198 { 21, "MEMSET" },
199 { 22, "JUMP" },
200 { 23, "COMPARE" },
201 { 24, "CALL" },
202 { 25, "RETURN" },
203 { 26, "SWITCH" },
204 { 27, "CRC" },
205 { 28, "INPUT-BYTES" },
206 { 29, "INPUT-BITS" },
207 { 30, "INPUT-HUFFMAN" },
208 { 31, "STATE-ACCESS" },
209 { 32, "STATE-CREATE" },
210 { 33, "STATE-FREE" },
211 { 34, "OUTPUT" },
212 { 35, "END-MESSAGE" },
213 { 0, NULL }
215 /* RFC3320
216 * Figure 10: Bytecode for a multitype (%) operand
217 * Bytecode: Operand value: Range: HEX val
218 * 00nnnnnn N 0 - 63 0x00
219 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
220 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
221 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
222 * 111nnnnn N + 65504 65504 - 65535 0xe0
223 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
224 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
225 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
226 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
227 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
230 static const value_string display_bytecode_vals[] = {
231 { 0x00, "00nnnnnn, N, 0 - 63" },
232 { 0x40, "01nnnnnn, memory[2 * N],0 - 65535" },
233 { 0x86, "1000011n, 2 ^ (N + 6), 64 , 128" },
234 { 0x88, "10001nnn, 2 ^ (N + 8), 256,..., 32768" },
235 { 0xe0, "111nnnnn N + 65504, 65504 - 65535" },
236 { 0x90, "1001nnnn nnnnnnnn, N + 61440, 61440 - 65535" },
237 { 0xa0, "101nnnnn nnnnnnnn, N, 0 - 8191" },
238 { 0xc0, "110nnnnn nnnnnnnn, memory[N], 0 - 65535" },
239 { 0x80, "10000000 nnnnnnnn nnnnnnnn, N, 0 - 65535" },
240 { 0x81, "10000001 nnnnnnnn nnnnnnnn, memory[N], 0 - 65535" },
241 { 0, NULL }
243 /* RFC3320
244 * 0nnnnnnn memory[2 * N] 0 - 65535
245 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
246 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
248 static const value_string display_ref_bytecode_vals[] = {
249 { 0x00, "0nnnnnnn memory[2 * N] 0 - 65535" },
250 { 0x80, "10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535" },
251 { 0xc0, "11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535" },
252 { 0, NULL }
254 /* The simplest operand type is the literal (#), which encodes a
255 * constant integer from 0 to 65535 inclusive. A literal operand may
256 * require between 1 and 3 bytes depending on its value.
257 * Bytecode: Operand value: Range:
258 * 0nnnnnnn N 0 - 127
259 * 10nnnnnn nnnnnnnn N 0 - 16383
260 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
262 * Figure 8: Bytecode for a literal (#) operand
266 static const value_string display_lit_bytecode_vals[] = {
267 { 0x00, "0nnnnnnn N 0 - 127" },
268 { 0x80, "10nnnnnn nnnnnnnn N 0 - 16383" },
269 { 0xc0, "11000000 nnnnnnnn nnnnnnnn N 0 - 65535" },
270 { 0, NULL }
273 #define SIGCOMP_NACK_STATE_NOT_FOUND 1
274 #define SIGCOMP_NACK_CYCLES_EXHAUSTED 2
275 #define SIGCOMP_NACK_BYTECODES_TOO_LARGE 18
276 #define SIGCOMP_NACK_ID_NOT_UNIQUE 21
277 #define SIGCOMP_NACK_STATE_TOO_SHORT 23
279 static const value_string sigcomp_nack_reason_code_vals[] = {
280 { 1, "STATE_NOT_FOUND" }, /*1 State ID (6 - 20 bytes) */
281 { 2, "CYCLES_EXHAUSTED" }, /*2 Cycles Per Bit (1 byte) */
282 { 3, "USER_REQUESTED" },
283 { 4, "SEGFAULT" },
284 { 5, "TOO_MANY_STATE_REQUESTS" },
285 { 6, "INVALID_STATE_ID_LENGTH" },
286 { 7, "INVALID_STATE_PRIORITY" },
287 { 8, "OUTPUT_OVERFLOW" },
288 { 9, "STACK_UNDERFLOW" },
289 { 10, "BAD_INPUT_BITORDER" },
290 { 11, "DIV_BY_ZERO" },
291 { 12, "SWITCH_VALUE_TOO_HIGH" },
292 { 13, "TOO_MANY_BITS_REQUESTED" },
293 { 14, "INVALID_OPERAND" },
294 { 15, "HUFFMAN_NO_MATCH" },
295 { 16, "MESSAGE_TOO_SHORT" },
296 { 17, "INVALID_CODE_LOCATION" },
297 { 18, "BYTECODES_TOO_LARGE" }, /*18 Memory size (2 bytes) */
298 { 19, "INVALID_OPCODE" },
299 { 20, "INVALID_STATE_PROBE" },
300 { 21, "ID_NOT_UNIQUE" }, /*21 State ID (6 - 20 bytes) */
301 { 22, "MULTILOAD_OVERWRITTEN" },
302 { 23, "STATE_TOO_SHORT" }, /*23 State ID (6 - 20 bytes) */
303 { 24, "INTERNAL_ERROR" },
304 { 25, "FRAMING_ERROR" },
305 { 0, NULL }
309 static void dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree, guint destination);
311 static int dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
312 gint offset,gboolean is_addr,gint *start_offset,
313 guint16 *value, gboolean *is_memory_address );
315 static int dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
316 gint offset, gint *start_offset, guint16 *value);
318 static int dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
319 gint offset, gint *start_offset, guint16 *value);
320 static void tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree);
322 static int dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
324 static proto_tree *top_tree;
326 /* Initialize the state handler
329 static void
330 sigcomp_init_protocol(void)
332 sigcomp_init_udvm();
334 /* Sigcomp over TCP record marking used
335 * RFC 3320
336 * 4.2.2. Record Marking
338 * For a stream-based transport, the dispatcher delimits messages by
339 * parsing the compressed data stream for instances of 0xFF and taking
340 * the following actions:
341 * Occurs in data stream: Action:
343 * 0xFF 00 one 0xFF byte in the data stream
344 * 0xFF 01 same, but the next byte is quoted (could
345 * be another 0xFF)
346 * : :
347 * 0xFF 7F same, but the next 127 bytes are quoted
348 * 0xFF 80 to 0xFF FE (reserved for future standardization)
349 * 0xFF FF end of SigComp message
351 * In UDVM version 0x01, any occurrence of the combinations 0xFF80 to
352 * 0xFFFE that are not protected by quoting causes decompression
353 * failure; the decompressor SHOULD close the stream-based transport in
354 * this case.
358 * TODO: Reassembly, handle more than one message in a tcp segment.
361 static int
362 dissect_sigcomp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *_data _U_)
364 proto_item *ti;
365 proto_tree *sigcomp_tree;
366 tvbuff_t *unescaped_tvb;
368 guint8 *buff;
369 int offset = 0;
370 int length;
371 guint8 octet;
372 guint16 data;
373 int i;
374 int n;
375 gboolean end_off_message;
377 top_tree = tree;
379 /* Is this SIGCOMP ? */
380 data = tvb_get_ntohs(tvb, offset);
381 if(data == 0xffff){
382 /* delimiter */
383 offset = offset + 2;
384 octet = tvb_get_guint8(tvb,offset);
385 }else{
386 octet = tvb_get_guint8(tvb,offset);
388 if ((octet & 0xf8) != 0xf8)
389 return offset;
391 /* Search for delimiter 0xffff in the remain tvb buffer */
392 length = tvb_ensure_length_remaining(tvb, offset);
393 for(i=0; i<(length-1); ++i){
394 /* Loop end criteria is (length-1) because we take 2 bytes each loop */
395 data = tvb_get_ntohs(tvb, offset+i);
396 if (0xffff == data) break;
398 if (i >= (length-1)){
399 /* SIGCOMP may be subdissector of SIP, so we use
400 * pinfo->saved_can_desegment to determine whether do desegment
401 * as well as pinfo->can_desegment */
402 if (pinfo->can_desegment || pinfo->saved_can_desegment){
403 /* Delimiter oxffff was not found, not a complete SIGCOMP PDU */
404 pinfo->desegment_offset = offset;
405 pinfo->desegment_len=DESEGMENT_ONE_MORE_SEGMENT;
406 return -1;
410 /* Make entries in Protocol column and Info column on summary display */
411 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
413 col_clear(pinfo->cinfo, COL_INFO);
415 length = tvb_length_remaining(tvb,offset);
417 try_again:
418 /* create display subtree for the protocol */
419 ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, ENC_NA);
420 sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
421 i=0;
422 end_off_message = FALSE;
423 buff = (guint8 *)wmem_alloc(pinfo->pool, length-offset);
424 if (udvm_print_detail_level>2)
425 proto_tree_add_text(sigcomp_tree, tvb, offset, -1,"Starting to remove escape digits");
426 while ((offset < length) && (end_off_message == FALSE)){
427 octet = tvb_get_guint8(tvb,offset);
428 if ( octet == 0xff ){
429 if ( offset +1 >= length ){
430 /* if the tvb is short dont check for the second escape digit */
431 offset++;
432 continue;
434 if (udvm_print_detail_level>2)
435 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
436 " Escape digit found (0xFF)");
437 octet = tvb_get_guint8(tvb, offset+1);
438 if ( octet == 0){
439 buff[i] = 0xff;
440 offset = offset +2;
441 i++;
442 continue;
444 if ((octet > 0x7f) && (octet < 0xff )){
445 if (udvm_print_detail_level>2)
446 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
447 " Illegal escape code");
448 offset = offset + tvb_length_remaining(tvb,offset);
449 return offset;
451 if ( octet == 0xff){
452 if (udvm_print_detail_level>2)
453 proto_tree_add_text(sigcomp_tree, tvb, offset, 2,
454 " End of SigComp message indication found (0xFFFF)");
455 end_off_message = TRUE;
456 offset = offset+2;
457 continue;
459 buff[i] = 0xff;
460 if (udvm_print_detail_level>2)
461 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
462 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
463 i++;
464 offset = offset+2;
465 if (udvm_print_detail_level>2)
466 proto_tree_add_text(sigcomp_tree, tvb, offset, octet,
467 " Copying %u bytes literally",octet);
468 if( offset+octet >= length)
469 /* if the tvb is short dont copy further than the end */
470 octet = length - offset;
471 for ( n=0; n < octet; n++ ){
472 buff[i] = tvb_get_guint8(tvb, offset);
473 if (udvm_print_detail_level>2)
474 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
475 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
476 i++;
477 offset++;
479 continue;
481 buff[i] = octet;
482 if (udvm_print_detail_level>2)
483 proto_tree_add_text(sigcomp_tree, tvb, offset, 1,
484 " Addr: %u tvb value(0x%0x) ", i, buff[i]);
486 i++;
487 offset++;
489 unescaped_tvb = tvb_new_child_real_data(tvb, buff,i,i);
491 add_new_data_source(pinfo, unescaped_tvb, "Unescaped Data handed to the SigComp dissector");
493 proto_tree_add_text(sigcomp_tree, unescaped_tvb, 0, -1,"Data handed to the Sigcomp dissector");
494 if (end_off_message == TRUE){
495 dissect_sigcomp_common(unescaped_tvb, pinfo, sigcomp_tree);
496 }else{
497 proto_tree_add_text(sigcomp_tree, unescaped_tvb, 0, -1,"TCP Fragment, no end mark found");
499 if ( offset < length){
500 goto try_again;
503 return offset;
505 /* Code to actually dissect the packets */
506 static int
507 dissect_sigcomp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
509 proto_item *ti;
510 proto_tree *sigcomp_tree;
511 gint offset = 0;
512 gint8 octet;
514 /* If we got called from SIP this might be over TCP */
515 if ( pinfo->ptype == PT_TCP )
516 return dissect_sigcomp_tcp(tvb, pinfo, tree, NULL);
518 /* Is this a SigComp message or not ? */
519 octet = tvb_get_guint8(tvb, offset);
520 if ((octet & 0xf8) != 0xf8)
521 return 0;
523 /* Make entries in Protocol column and Info column on summary display */
524 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SIGCOMP");
526 col_clear(pinfo->cinfo, COL_INFO);
528 top_tree = tree;
530 /* create display subtree for the protocol */
531 ti = proto_tree_add_item(tree, proto_sigcomp, tvb, 0, -1, ENC_NA);
532 sigcomp_tree = proto_item_add_subtree(ti, ett_sigcomp);
534 return dissect_sigcomp_common(tvb, pinfo, sigcomp_tree);
536 /* Code to actually dissect the packets */
537 static int
538 dissect_sigcomp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sigcomp_tree)
541 /* Set up structures needed to add the protocol subtree and manage it */
542 tvbuff_t *udvm_tvb, *msg_tvb, *udvm2_tvb;
543 tvbuff_t *decomp_tvb = NULL;
544 proto_item *udvm_bytecode_item, *udvm_exe_item;
545 proto_tree *sigcomp_udvm_tree, *sigcomp_udvm_exe_tree;
546 gint offset = 0;
547 gint bytecode_offset;
548 guint16 partial_state_len;
549 guint octet;
550 guint8 returned_feedback_field[128];
551 guint8 partial_state[12];
552 guint tbit;
553 guint16 len = 0;
554 guint16 bytecode_len = 0;
555 guint destination;
556 gint msg_len = 0;
557 guint8 *buff;
558 guint16 p_id_start;
559 guint8 i;
560 guint16 state_begin;
561 guint16 state_length;
562 guint16 state_address;
563 guint16 state_instruction;
564 guint16 result_code;
565 gchar *partial_state_str;
566 guint8 nack_version;
570 /* add an item to the subtree, see section 1.6 for more information */
571 octet = tvb_get_guint8(tvb, offset);
573 /* A SigComp message takes one of two forms depending on whether it
574 * accesses a state item at the receiving endpoint. The two variants of
575 * a SigComp message are given in Figure 3. (The T-bit controls the
576 * format of the returned feedback item and is defined in Section 7.1.)
578 * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
579 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
580 * | 1 1 1 1 1 | T | len | | 1 1 1 1 1 | T | 0 |
581 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
582 * | | | |
583 * : returned feedback item : : returned feedback item :
584 * | | | |
585 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
586 * | | | code_len |
587 * : partial state identifier : +---+---+---+---+---+---+---+---+
589 * | | | code_len | destination |
590 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
591 * | | | |
592 * : remaining SigComp message : : uploaded UDVM bytecode :
593 * | | | |
594 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
595 * | |
596 * : remaining SigComp message :
597 * | |
598 * +---+---+---+---+---+---+---+---+
600 * RFC 4077:
601 * The format of the NACK message and the use of the fields within it
602 * are shown in Figure 1.
604 * 0 1 2 3 4 5 6 7
605 * +---+---+---+---+---+---+---+---+
606 * | 1 1 1 1 1 | T | 0 |
607 * +---+---+---+---+---+---+---+---+
608 * | |
609 * : returned feedback item :
610 * | |
611 * +---+---+---+---+---+---+---+---+
612 * | code_len = 0 |
613 * +---+---+---+---+---+---+---+---+
614 * | code_len = 0 | version = 1 |
615 * +---+---+---+---+---+---+---+---+
616 * | Reason Code |
617 * +---+---+---+---+---+---+---+---+
618 * | OPCODE of failed instruction |
619 * +---+---+---+---+---+---+---+---+
620 * | PC of failed instruction |
621 * | |
622 * +---+---+---+---+---+---+---+---+
623 * | |
624 * : SHA-1 Hash of failed message :
625 * | |
626 * +---+---+---+---+---+---+---+---+
627 * | |
628 * : Error Details :
629 * | |
630 * +---+---+---+---+---+---+---+---+
631 * Figure 1: SigComp NACK Message Format
634 proto_tree_add_item(sigcomp_tree,hf_sigcomp_t_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
635 proto_tree_add_item(sigcomp_tree,hf_sigcomp_len, tvb, offset, 1, ENC_BIG_ENDIAN);
636 tbit = ( octet & 0x04)>>2;
637 partial_state_len = octet & 0x03;
638 offset ++;
639 if ( partial_state_len != 0 ){
641 * The len field encodes the number of transmitted bytes as follows:
643 * Encoding: Length of partial state identifier
645 * 01 6 bytes
646 * 10 9 bytes
647 * 11 12 bytes
650 partial_state_len = partial_state_len * 3 + 3;
653 * Message format 1
655 col_set_str(pinfo->cinfo, COL_INFO, "Msg format 1");
657 if ( tbit == 1 ) {
659 * Returned feedback item exists
661 len = 1;
662 octet = tvb_get_guint8(tvb, offset);
663 /* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
664 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
665 * | 0 | returned_feedback_field | | 1 | returned_feedback_length |
666 * +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
667 * | |
668 * : returned_feedback_field :
669 * | |
670 * +---+---+---+---+---+---+---+---+
671 * Figure 4: Format of returned feedback item
674 if ( (octet & 0x80) != 0 ){
675 len = octet & 0x7f;
676 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
677 tvb, offset, 1, ENC_BIG_ENDIAN);
678 offset ++;
679 tvb_memcpy(tvb,returned_feedback_field,offset, len);
680 } else {
681 returned_feedback_field[0] = tvb_get_guint8(tvb, offset) & 0x7f;
683 proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
684 tvb, offset, len, returned_feedback_field);
685 offset = offset + len;
687 tvb_memcpy(tvb, partial_state, offset, partial_state_len);
688 partial_state_str = bytes_to_str(partial_state, partial_state_len);
689 proto_tree_add_string(sigcomp_tree,hf_sigcomp_partial_state,
690 tvb, offset, partial_state_len, partial_state_str);
691 offset = offset + partial_state_len;
692 msg_len = tvb_reported_length_remaining(tvb, offset);
694 if(msg_len>0){
695 proto_item *ti;
696 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_remaining_message_bytes, tvb,
697 offset, 0, msg_len);
698 PROTO_ITEM_SET_GENERATED(ti);
701 if ( decompress ) {
702 msg_tvb = tvb_new_subset(tvb, offset, msg_len, msg_len);
704 * buff = Where "state" will be stored
705 * p_id_start = Partial state identifier start pos in the buffer(buff)
706 * partial_state_len = Partial state identifier length
707 * state_begin = Where to start to read state from
708 * state_length = Length of state
709 * state_address = Address where to store the state in the buffer(buff)
710 * state_instruction =
711 * TRUE = Indicates that state_* is in the stored state
714 * Note: The allocated buffer must be zeroed or some strange effects might occur.
716 buff = (guint8 *)wmem_alloc0(pinfo->pool, UDVM_MEMORY_SIZE);
719 p_id_start = 0;
720 state_begin = 0;
721 /* These values will be loaded from the buffered state in sigcomp_state_hdlr
723 state_length = 0;
724 state_address = 0;
725 state_instruction =0;
727 i = 0;
728 while ( i < partial_state_len ){
729 buff[i] = partial_state[i];
730 i++;
733 /* begin partial state-id change cco@iptel.org */
734 #if 0
735 result_code = udvm_state_access(tvb, sigcomp_tree, buff, p_id_start, partial_state_len, state_begin, &state_length,
736 &state_address, &state_instruction, hf_sigcomp_partial_state);
737 #endif
738 result_code = udvm_state_access(tvb, sigcomp_tree, buff, p_id_start, STATE_MIN_ACCESS_LEN, state_begin, &state_length,
739 &state_address, &state_instruction, hf_sigcomp_partial_state);
741 /* end partial state-id change cco@iptel.org */
742 if ( result_code != 0 ){
743 proto_item *ti;
744 ti = proto_tree_add_text(sigcomp_tree, tvb, 0, -1,"Failed to Access state Wireshark UDVM diagnostic: %s.",
745 val_to_str(result_code, result_code_vals,"Unknown (%u)"));
746 PROTO_ITEM_SET_GENERATED(ti);
747 return tvb_length(tvb);
750 udvm_tvb = tvb_new_child_real_data(tvb, buff,state_length+state_address,state_length+state_address);
751 add_new_data_source(pinfo, udvm_tvb, "State/ExecutionTrace");
753 udvm2_tvb = tvb_new_subset(udvm_tvb, state_address, state_length, state_length);
754 udvm_exe_item = proto_tree_add_item(sigcomp_tree, hf_udvm_execution_trace,
755 udvm2_tvb, 0, state_length,
756 ENC_NA);
757 sigcomp_udvm_exe_tree = proto_item_add_subtree( udvm_exe_item, ett_sigcomp_udvm_exe);
759 decomp_tvb = decompress_sigcomp_message(udvm2_tvb, msg_tvb, pinfo,
760 sigcomp_udvm_exe_tree, state_address,
761 udvm_print_detail_level, hf_sigcomp_partial_state,
762 offset, state_length, partial_state_len, state_instruction);
765 if ( decomp_tvb ){
766 proto_item *ti;
767 guint32 compression_ratio =
768 (guint32)(((float)tvb_length(decomp_tvb) / (float)tvb_length(tvb)) * 100);
770 /* Celebrate success and show compression ratio achieved */
771 proto_tree_add_text(sigcomp_tree, decomp_tvb, 0, -1,"SigComp message Decompressed WOHO!!");
772 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_compression_ratio, decomp_tvb,
773 0, 0, compression_ratio);
774 PROTO_ITEM_SET_GENERATED(ti);
776 if ( display_raw_txt )
777 tvb_raw_text_add(decomp_tvb, top_tree);
779 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
780 col_set_fence(pinfo->cinfo,COL_PROTOCOL);
781 call_dissector(sip_handle, decomp_tvb, pinfo, top_tree);
783 }/* if decompress */
786 else{
788 * Message format 2
790 col_set_str(pinfo->cinfo, COL_INFO, "Msg format 2");
791 if ( tbit == 1 ) {
793 * Returned feedback item exists
795 len = 1;
796 octet = tvb_get_guint8(tvb, offset);
797 if ( (octet & 0x80) != 0 ){
798 len = octet & 0x7f;
799 proto_tree_add_item(sigcomp_tree,hf_sigcomp_returned_feedback_item_len,
800 tvb, offset, 1, ENC_BIG_ENDIAN);
801 offset ++;
803 tvb_memcpy(tvb,returned_feedback_field,offset, len);
804 proto_tree_add_bytes(sigcomp_tree,hf_sigcomp_returned_feedback_item,
805 tvb, offset, len, returned_feedback_field);
806 offset = offset + len;
808 len = tvb_get_ntohs(tvb, offset) >> 4;
809 nack_version = tvb_get_guint8(tvb, offset+1) & 0x0f;
810 if ((len == 0) && (nack_version == 1)){
811 /* NACK MESSAGE */
812 proto_item *reason_ti;
813 guint8 opcode;
814 offset++;
815 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
816 offset++;
817 octet = tvb_get_guint8(tvb, offset);
818 reason_ti = proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_reason_code, tvb, offset, 1, ENC_BIG_ENDIAN);
819 offset++;
820 opcode = tvb_get_guint8(tvb, offset);
821 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_failed_op_code, tvb, offset, 1, ENC_BIG_ENDIAN);
822 offset++;
824 /* Add expert item for NACK */
825 expert_add_info_format(pinfo, reason_ti, &ei_sigcomp_nack_failed_op_code,
826 "SigComp NACK (reason=%s, opcode=%s)",
827 val_to_str_const(octet, sigcomp_nack_reason_code_vals, "Unknown"),
828 val_to_str_const(opcode, udvm_instruction_code_vals, "Unknown"));
830 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_pc, tvb, offset, 2, ENC_BIG_ENDIAN);
831 offset = offset +2;
832 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_sha1, tvb, offset, 20, ENC_NA);
833 offset = offset +20;
835 /* Add NACK info to info column */
836 col_append_fstr(pinfo->cinfo, COL_INFO, " NACK reason=%s, opcode=%s",
837 val_to_str_const(octet, sigcomp_nack_reason_code_vals, "Unknown"),
838 val_to_str_const(opcode, udvm_instruction_code_vals, "Unknown"));
840 switch ( octet){
841 case SIGCOMP_NACK_STATE_NOT_FOUND:
842 case SIGCOMP_NACK_ID_NOT_UNIQUE:
843 case SIGCOMP_NACK_STATE_TOO_SHORT:
844 /* State ID (6 - 20 bytes) */
845 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_state_id, tvb, offset, -1, ENC_NA);
846 break;
847 case SIGCOMP_NACK_CYCLES_EXHAUSTED:
848 /* Cycles Per Bit (1 byte) */
849 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_cycles_per_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
850 break;
851 case SIGCOMP_NACK_BYTECODES_TOO_LARGE:
852 /* Memory size (2 bytes) */
853 proto_tree_add_item(sigcomp_tree,hf_sigcomp_nack_memory_size, tvb, offset, 2, ENC_BIG_ENDIAN);
854 break;
855 default:
856 break;
858 }else{
859 octet = tvb_get_guint8(tvb, (offset + 1));
860 destination = (octet & 0x0f);
861 if ( destination != 0 )
862 destination = 64 + ( destination * 64 );
863 proto_tree_add_item(sigcomp_tree,hf_sigcomp_code_len, tvb, offset, 2, ENC_BIG_ENDIAN);
864 proto_tree_add_item(sigcomp_tree,hf_sigcomp_destination, tvb, (offset+ 1), 1, ENC_BIG_ENDIAN);
865 offset = offset +2;
867 bytecode_len = len;
868 bytecode_offset = offset;
869 udvm_bytecode_item = proto_tree_add_item(sigcomp_tree, hf_sigcomp_udvm_bytecode, tvb,
870 bytecode_offset, bytecode_len, ENC_NA);
871 proto_item_append_text(udvm_bytecode_item,
872 " %u (0x%x) bytes", bytecode_len, bytecode_len);
873 sigcomp_udvm_tree = proto_item_add_subtree( udvm_bytecode_item, ett_sigcomp_udvm);
875 udvm_tvb = tvb_new_subset(tvb, offset, len, len);
876 if ( dissect_udvm_code )
877 dissect_udvm_bytecode(udvm_tvb, sigcomp_udvm_tree, destination);
879 offset = offset + len;
880 msg_len = tvb_reported_length_remaining(tvb, offset);
881 if (msg_len>0) {
882 proto_item *ti = proto_tree_add_text(sigcomp_tree, tvb, offset, -1,
883 "Remaining SigComp message %u bytes",
884 tvb_reported_length_remaining(tvb, offset));
885 PROTO_ITEM_SET_GENERATED(ti);
887 if ( decompress ){
889 msg_tvb = tvb_new_subset(tvb, offset, msg_len, msg_len);
891 udvm_exe_item = proto_tree_add_item(sigcomp_tree, hf_udvm_execution_trace,
892 tvb, bytecode_offset, bytecode_len,
893 ENC_NA);
894 sigcomp_udvm_exe_tree = proto_item_add_subtree( udvm_exe_item, ett_sigcomp_udvm_exe);
895 decomp_tvb = decompress_sigcomp_message(udvm_tvb, msg_tvb, pinfo,
896 sigcomp_udvm_exe_tree, destination,
897 udvm_print_detail_level, hf_sigcomp_partial_state,
898 offset, 0, 0, destination);
899 if ( decomp_tvb ){
900 proto_item *ti;
901 guint32 compression_ratio =
902 (guint32)(((float)tvb_length(decomp_tvb) / (float)tvb_length(tvb)) * 100);
904 /* Celebrate success and show compression ratio achieved */
905 proto_tree_add_text(sigcomp_tree, decomp_tvb, 0, -1,"SigComp message Decompressed WOHO!!");
906 ti = proto_tree_add_uint(sigcomp_tree, hf_sigcomp_compression_ratio, decomp_tvb,
907 0, 0, compression_ratio);
908 PROTO_ITEM_SET_GENERATED(ti);
910 if ( display_raw_txt )
911 tvb_raw_text_add(decomp_tvb, top_tree);
913 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
914 col_set_fence(pinfo->cinfo,COL_PROTOCOL);
915 call_dissector(sip_handle, decomp_tvb, pinfo, top_tree);
917 } /* if decompress */
918 }/*if len==0 */
921 return tvb_length(tvb);
925 #define SIGCOMP_INSTR_DECOMPRESSION_FAILURE 0
926 #define SIGCOMP_INSTR_AND 1
927 #define SIGCOMP_INSTR_OR 2
928 #define SIGCOMP_INSTR_NOT 3
929 #define SIGCOMP_INSTR_LSHIFT 4
930 #define SIGCOMP_INSTR_RSHIFT 5
931 #define SIGCOMP_INSTR_ADD 6
932 #define SIGCOMP_INSTR_SUBTRACT 7
933 #define SIGCOMP_INSTR_MULTIPLY 8
934 #define SIGCOMP_INSTR_DIVIDE 9
935 #define SIGCOMP_INSTR_REMAINDER 10
936 #define SIGCOMP_INSTR_SORT_ASCENDING 11
937 #define SIGCOMP_INSTR_SORT_DESCENDING 12
938 #define SIGCOMP_INSTR_SHA_1 13
939 #define SIGCOMP_INSTR_LOAD 14
940 #define SIGCOMP_INSTR_MULTILOAD 15
941 #define SIGCOMP_INSTR_PUSH 16
942 #define SIGCOMP_INSTR_POP 17
943 #define SIGCOMP_INSTR_COPY 18
944 #define SIGCOMP_INSTR_COPY_LITERAL 19
945 #define SIGCOMP_INSTR_COPY_OFFSET 20
946 #define SIGCOMP_INSTR_MEMSET 21
947 #define SIGCOMP_INSTR_JUMP 22
948 #define SIGCOMP_INSTR_COMPARE 23
949 #define SIGCOMP_INSTR_CALL 24
950 #define SIGCOMP_INSTR_RETURN 25
951 #define SIGCOMP_INSTR_SWITCH 26
952 #define SIGCOMP_INSTR_CRC 27
953 #define SIGCOMP_INSTR_INPUT_BYTES 28
954 #define SIGCOMP_INSTR_INPUT_BITS 29
955 #define SIGCOMP_INSTR_INPUT_HUFFMAN 30
956 #define SIGCOMP_INSTR_STATE_ACCESS 31
957 #define SIGCOMP_INSTR_STATE_CREATE 32
958 #define SIGCOMP_INSTR_STATE_FREE 33
959 #define SIGCOMP_INSTR_OUTPUT 34
960 #define SIGCOMP_INSTR_END_MESSAGE 35
963 static void
964 dissect_udvm_bytecode(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,guint start_address)
966 guint instruction;
967 gint offset = 0;
968 gint start_offset = 0;
969 gint len;
970 gint n;
971 guint instruction_no = 0;
972 guint16 value = 0;
973 proto_item *item, *item2;
974 guint UDVM_address = start_address;
975 gboolean is_memory_address;
976 guint16 msg_length = tvb_reported_length_remaining(udvm_tvb, offset);
979 while (msg_length > offset) {
980 instruction = tvb_get_guint8(udvm_tvb, offset);
981 instruction_no ++;
982 UDVM_address = start_address + offset;
985 item = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
986 "######### UDVM instruction %u at UDVM-address %u (0x%x) #########",
987 instruction_no,UDVM_address,UDVM_address);
988 PROTO_ITEM_SET_GENERATED(item);
989 proto_tree_add_item(sigcomp_udvm_tree, hf_sigcomp_udvm_instr, udvm_tvb, offset, 1, ENC_BIG_ENDIAN);
990 offset ++;
991 switch ( instruction ) {
993 case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */
994 /* $operand_1*/
995 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
996 len = offset - start_offset;
997 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
998 udvm_tvb, start_offset, len, value);
999 /* %operand_2*/
1000 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1001 len = offset - start_offset;
1002 if ( is_memory_address ){
1003 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1004 udvm_tvb, start_offset, len, value);
1005 }else{
1006 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1007 udvm_tvb, start_offset, len, value);
1009 break;
1011 case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */
1012 /* $operand_1*/
1013 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1014 len = offset - start_offset;
1015 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1016 udvm_tvb, start_offset, len, value);
1017 /* %operand_2*/
1018 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1019 len = offset - start_offset;
1020 if ( is_memory_address ){
1021 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1022 udvm_tvb, start_offset, len, value);
1023 }else{
1024 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1025 udvm_tvb, start_offset, len, value);
1027 break;
1029 case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */
1030 /* $operand_1*/
1031 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1032 len = offset - start_offset;
1033 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1034 udvm_tvb, start_offset, len, value);
1035 break;
1037 case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */
1038 /* $operand_1*/
1039 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1040 len = offset - start_offset;
1041 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1042 udvm_tvb, start_offset, len, value);
1043 /* %operand_2*/
1044 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1045 len = offset - start_offset;
1046 if ( is_memory_address ){
1047 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1048 udvm_tvb, start_offset, len, value);
1049 }else{
1050 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1051 udvm_tvb, start_offset, len, value);
1053 break;
1055 case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */
1056 /* $operand_1*/
1057 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1058 len = offset - start_offset;
1059 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1060 udvm_tvb, start_offset, len, value);
1061 /* %operand_2*/
1062 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1063 len = offset - start_offset;
1064 if ( is_memory_address ){
1065 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1066 udvm_tvb, start_offset, len, value);
1067 }else{
1068 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1069 udvm_tvb, start_offset, len, value);
1071 break;
1073 case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */
1074 /* $operand_1*/
1075 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1076 len = offset - start_offset;
1077 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1078 udvm_tvb, start_offset, len, value);
1079 /* %operand_2*/
1080 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1081 len = offset - start_offset;
1082 if ( is_memory_address ){
1083 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1084 udvm_tvb, start_offset, len, value);
1085 }else{
1086 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1087 udvm_tvb, start_offset, len, value);
1089 break;
1091 case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */
1092 /* $operand_1*/
1093 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1094 len = offset - start_offset;
1095 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1096 udvm_tvb, start_offset, len, value);
1097 /* %operand_2*/
1098 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1099 len = offset - start_offset;
1100 if ( is_memory_address ){
1101 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1102 udvm_tvb, start_offset, len, value);
1103 }else{
1104 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1105 udvm_tvb, start_offset, len, value);
1107 break;
1109 case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */
1110 /* $operand_1*/
1111 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1112 len = offset - start_offset;
1113 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1114 udvm_tvb, start_offset, len, value);
1115 /* %operand_2*/
1116 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1117 len = offset - start_offset;
1118 if ( is_memory_address ){
1119 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1120 udvm_tvb, start_offset, len, value);
1121 }else{
1122 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1123 udvm_tvb, start_offset, len, value);
1125 break;
1127 case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */
1128 /* $operand_1*/
1129 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1130 len = offset - start_offset;
1131 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1132 udvm_tvb, start_offset, len, value);
1133 /* %operand_2*/
1134 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1135 len = offset - start_offset;
1136 if ( is_memory_address ){
1137 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1138 udvm_tvb, start_offset, len, value);
1139 }else{
1140 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1141 udvm_tvb, start_offset, len, value);
1143 break;
1145 case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */
1146 /* $operand_1*/
1147 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1148 len = offset - start_offset;
1149 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_1,
1150 udvm_tvb, start_offset, len, value);
1151 /* %operand_2*/
1152 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1153 len = offset - start_offset;
1154 if ( is_memory_address ){
1155 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2_addr,
1156 udvm_tvb, start_offset, len, value);
1157 }else{
1158 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_operand_2,
1159 udvm_tvb, start_offset, len, value);
1161 break;
1162 case SIGCOMP_INSTR_SORT_ASCENDING: /* 11 SORT-ASCENDING (%start, %n, %k) */
1163 /* while programming stop while loop */
1164 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1165 break;
1167 case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */
1168 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1169 break;
1170 case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */
1171 /* %position */
1172 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1173 len = offset - start_offset;
1174 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1175 udvm_tvb, start_offset, len, value);
1177 /* %length, */
1178 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1179 len = offset - start_offset;
1180 if ( is_memory_address ){
1181 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1182 udvm_tvb, start_offset, len, value);
1183 }else{
1184 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1185 udvm_tvb, start_offset, len, value);
1188 /* $destination */
1189 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1190 len = offset - start_offset;
1191 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1192 udvm_tvb, start_offset, len, value);
1193 break;
1195 case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */
1196 /* %address */
1197 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
1198 len = offset - start_offset;
1199 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1200 udvm_tvb, start_offset, len, value);
1201 /* %value */
1202 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1203 len = offset - start_offset;
1204 if ( is_memory_address ){
1205 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1206 udvm_tvb, start_offset, len, value);
1207 }else{
1208 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1209 udvm_tvb, start_offset, len, value);
1211 break;
1213 case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
1214 /* %address */
1215 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1216 len = offset - start_offset;
1217 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1218 udvm_tvb, start_offset, len, value);
1219 /* #n */
1220 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1221 len = offset - start_offset;
1222 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1223 udvm_tvb, start_offset, len, value);
1224 n = value;
1225 while ( n > 0) {
1226 n = n -1;
1227 /* %value */
1228 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1229 len = offset - start_offset;
1230 if ( is_memory_address ){
1231 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1232 udvm_tvb, start_offset, len, value);
1233 }else{
1234 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1235 udvm_tvb, start_offset, len, value);
1238 break;
1240 case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */
1241 /* %value */
1242 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1243 len = offset - start_offset;
1244 if ( is_memory_address ){
1245 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1246 udvm_tvb, start_offset, len, value);
1247 }else{
1248 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1249 udvm_tvb, start_offset, len, value);
1251 break;
1253 case SIGCOMP_INSTR_POP: /* 17 POP (%address) */
1254 /* %address */
1255 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1257 len = offset - start_offset;
1258 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1259 udvm_tvb, start_offset, len, value);
1260 break;
1262 case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */
1263 /* %position */
1264 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1265 len = offset - start_offset;
1266 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1267 udvm_tvb, start_offset, len, value);
1269 /* %length, */
1270 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1271 len = offset - start_offset;
1272 if ( is_memory_address ){
1273 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1274 udvm_tvb, start_offset, len, value);
1275 }else{
1276 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1277 udvm_tvb, start_offset, len, value);
1280 /* $destination */
1281 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1282 len = offset - start_offset;
1283 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1284 udvm_tvb, start_offset, len, value);
1285 break;
1287 case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */
1288 /* %position */
1289 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1290 len = offset - start_offset;
1291 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1292 udvm_tvb, start_offset, len, value);
1294 /* %length, */
1295 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1296 len = offset - start_offset;
1297 if ( is_memory_address ){
1298 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1299 udvm_tvb, start_offset, len, value);
1300 }else{
1301 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1302 udvm_tvb, start_offset, len, value);
1305 /* $destination */
1306 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1307 len = offset - start_offset;
1308 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1309 udvm_tvb, start_offset, len, value);
1310 break;
1312 case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */
1313 /* %offset */
1314 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1315 len = offset - start_offset;
1316 if ( is_memory_address ){
1317 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_offset,
1318 udvm_tvb, start_offset, len, value);
1319 }else{
1320 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
1321 udvm_tvb, start_offset, len, value);
1324 /* %length, */
1325 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1326 len = offset - start_offset;
1327 if ( is_memory_address ){
1328 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1329 udvm_tvb, start_offset, len, value);
1330 }else{
1331 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1332 udvm_tvb, start_offset, len, value);
1335 /* $destination */
1336 offset = dissect_udvm_reference_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1337 len = offset - start_offset;
1338 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ref_dest,
1339 udvm_tvb, start_offset, len, value);
1340 break;
1341 case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */
1343 /* %address */
1344 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1345 len = offset - start_offset;
1346 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_address,
1347 udvm_tvb, start_offset, len, value);
1349 /* %length, */
1350 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE, &start_offset, &value, &is_memory_address);
1351 len = offset - start_offset;
1352 if ( is_memory_address ){
1353 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1354 udvm_tvb, start_offset, len, value);
1355 }else{
1356 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1357 udvm_tvb, start_offset, len, value);
1360 /* %start_value */
1361 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1362 len = offset - start_offset;
1363 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_start_value,
1364 udvm_tvb, start_offset, len, value);
1366 /* %offset */
1367 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1368 len = offset - start_offset;
1369 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_offset,
1370 udvm_tvb, start_offset, len, value);
1371 break;
1374 case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */
1375 /* @address */
1376 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1377 len = offset - start_offset;
1378 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1379 value = ( value + UDVM_address ) & 0xffff;
1380 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1381 udvm_tvb, start_offset, len, value);
1382 break;
1384 case SIGCOMP_INSTR_COMPARE: /* 23 */
1385 /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
1387 /* %value_1 */
1388 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1389 len = offset - start_offset;
1390 if ( is_memory_address ){
1391 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1392 udvm_tvb, start_offset, len, value);
1393 }else{
1394 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1395 udvm_tvb, start_offset, len, value);
1398 /* %value_2 */
1399 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1400 len = offset - start_offset;
1401 if ( is_memory_address ){
1402 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1403 udvm_tvb, start_offset, len, value);
1404 }else{
1405 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1406 udvm_tvb, start_offset, len, value);
1409 /* @address_1 */
1410 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1411 len = offset - start_offset;
1412 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1413 value = ( value + UDVM_address ) & 0xffff;
1414 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1415 udvm_tvb, start_offset, len, value);
1417 /* @address_2 */
1418 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1419 len = offset - start_offset;
1420 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1421 value = ( value + UDVM_address ) & 0xffff;
1422 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1423 udvm_tvb, start_offset, len, value);
1425 /* @address_3 */
1426 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1427 len = offset - start_offset;
1428 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1429 value = ( value + UDVM_address ) & 0xffff;
1430 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1431 udvm_tvb, start_offset, len, value);
1432 break;
1434 case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/
1435 /* @address */
1436 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1437 len = offset - start_offset;
1438 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1439 value = ( value + UDVM_address ) & 0xffff;
1440 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1441 udvm_tvb, start_offset, len, value);
1442 break;
1443 case SIGCOMP_INSTR_RETURN: /* 25 POP and return */
1445 break;
1447 case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
1448 /* #n */
1449 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1450 len = offset - start_offset;
1451 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1452 udvm_tvb, start_offset, len, value);
1454 /* Number of addresses in the instruction */
1455 n = value;
1456 /* %j */
1457 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1458 len = offset - start_offset;
1459 if ( is_memory_address ){
1460 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_j,
1461 udvm_tvb, start_offset, len, value);
1462 }else{
1463 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_j,
1464 udvm_tvb, start_offset, len, value);
1467 while ( n > 0) {
1468 n = n -1;
1469 /* @address_n-1 */
1470 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE,&start_offset, &value, &is_memory_address);
1471 len = offset - start_offset;
1472 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1473 value = ( value + UDVM_address ) & 0xffff;
1474 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1475 udvm_tvb, start_offset, len, value);
1477 break;
1478 case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */
1479 /* %value */
1480 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1481 len = offset - start_offset;
1482 if ( is_memory_address ){
1483 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_value,
1484 udvm_tvb, start_offset, len, value);
1485 }else{
1486 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_value,
1487 udvm_tvb, start_offset, len, value);
1490 /* %position */
1491 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1492 len = offset - start_offset;
1493 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_position,
1494 udvm_tvb, start_offset, len, value);
1496 /* %length */
1497 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1498 len = offset - start_offset;
1499 if ( is_memory_address ){
1500 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1501 udvm_tvb, start_offset, len, value);
1502 }else{
1503 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1504 udvm_tvb, start_offset, len, value);
1507 /* @address */
1508 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1509 len = offset - start_offset;
1510 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1511 value = ( value + UDVM_address ) & 0xffff;
1512 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1513 udvm_tvb, start_offset, len, value);
1514 break;
1517 case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */
1518 /* %length */
1519 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1520 len = offset - start_offset;
1521 if ( is_memory_address ){
1522 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1523 udvm_tvb, start_offset, len, value);
1524 }else{
1525 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1526 udvm_tvb, start_offset, len, value);
1529 /* %destination */
1530 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1531 len = offset - start_offset;
1532 if ( is_memory_address ){
1533 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
1534 udvm_tvb, start_offset, len, value);
1535 }else{
1536 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1537 udvm_tvb, start_offset, len, value);
1540 /* @address */
1541 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1542 len = offset - start_offset;
1543 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1544 value = ( value + UDVM_address ) & 0xffff;
1545 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1546 udvm_tvb, start_offset, len, value);
1547 break;
1548 case SIGCOMP_INSTR_INPUT_BITS:/* 29 INPUT-BITS (%length, %destination, @address) */
1549 /* %length */
1550 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1551 len = offset - start_offset;
1552 if ( is_memory_address ){
1553 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_length,
1554 udvm_tvb, start_offset, len, value);
1555 }else{
1556 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_length,
1557 udvm_tvb, start_offset, len, value);
1560 /* %destination */
1561 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1562 len = offset - start_offset;
1563 if ( is_memory_address ){
1564 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
1565 udvm_tvb, start_offset, len, value);
1566 }else{
1567 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1568 udvm_tvb, start_offset, len, value);
1571 /* @address */
1572 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1573 len = offset - start_offset;
1574 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1575 value = ( value + UDVM_address ) & 0xffff;
1576 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1577 udvm_tvb, start_offset, len, value);
1578 break;
1579 case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */
1581 * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1,
1582 * %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n,
1583 * %upper_bound_n, %uncompressed_n)
1585 /* %destination */
1586 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1587 len = offset - start_offset;
1588 if ( is_memory_address ){
1589 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_destination,
1590 udvm_tvb, start_offset, len, value);
1591 }else{
1592 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_destination,
1593 udvm_tvb, start_offset, len, value);
1595 /* @address */
1596 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1597 len = offset - start_offset;
1598 /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
1599 value = ( value + UDVM_address ) & 0xffff;
1600 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_at_address,
1601 udvm_tvb, start_offset, len, value);
1602 /* #n */
1603 offset = dissect_udvm_literal_operand(udvm_tvb, sigcomp_udvm_tree, offset, &start_offset, &value);
1604 len = offset - start_offset;
1605 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_num,
1606 udvm_tvb, start_offset, len, value);
1607 n = value;
1608 while ( n > 0) {
1609 n = n -1;
1610 /* %bits_n */
1611 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1612 len = offset - start_offset;
1613 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_bits,
1614 udvm_tvb, start_offset, len, value);
1615 /* %lower_bound_n*/
1616 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1617 len = offset - start_offset;
1618 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_lower_bound,
1619 udvm_tvb, start_offset, len, value);
1620 /* %upper_bound_n */
1621 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1622 len = offset - start_offset;
1623 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_upper_bound,
1624 udvm_tvb, start_offset, len, value);
1625 /* %uncompressed_n */
1626 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, FALSE,&start_offset, &value, &is_memory_address);
1627 len = offset - start_offset;
1628 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_uncompressed,
1629 udvm_tvb, start_offset, len, value);
1631 break;
1633 case SIGCOMP_INSTR_STATE_ACCESS: /* 31 */
1634 /* STATE-ACCESS (%partial_identifier_start, %partial_identifier_length,
1635 * %state_begin, %state_length, %state_address, %state_instruction)
1639 * %partial_identifier_start
1641 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1642 len = offset - start_offset;
1643 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
1644 udvm_tvb, start_offset, len, value);
1647 * %partial_identifier_length
1649 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1650 len = offset - start_offset;
1651 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length,
1652 udvm_tvb, start_offset, len, value);
1654 * %state_begin
1656 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1657 len = offset - start_offset;
1658 proto_tree_add_uint(sigcomp_udvm_tree, hf_state_begin,
1659 udvm_tvb, start_offset, len, value);
1662 * %state_length
1664 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1665 len = offset - start_offset;
1666 if ( is_memory_address ) {
1667 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1668 udvm_tvb, start_offset, len, value);
1669 }else{
1670 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1671 udvm_tvb, start_offset, len, value);
1674 * %state_address
1676 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value ,&is_memory_address);
1677 len = offset - start_offset;
1678 if ( is_memory_address ) {
1679 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1680 udvm_tvb, start_offset, len, value);
1681 }else{
1682 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1683 udvm_tvb, start_offset, len, value);
1686 * %state_instruction
1688 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1689 len = offset - start_offset;
1690 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1691 udvm_tvb, start_offset, len, value);
1692 break;
1693 case SIGCOMP_INSTR_STATE_CREATE: /* 32 */
1695 * STATE-CREATE (%state_length, %state_address, %state_instruction,
1696 * %minimum_access_length, %state_retention_priority)
1700 * %state_length
1702 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1703 len = offset - start_offset;
1704 if ( is_memory_address ) {
1705 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1706 udvm_tvb, start_offset, len, value);
1707 }else{
1708 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1709 udvm_tvb, start_offset, len, value);
1712 * %state_address
1714 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1715 len = offset - start_offset;
1716 if ( is_memory_address ) {
1717 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1718 udvm_tvb, start_offset, len, value);
1719 }else{
1720 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1721 udvm_tvb, start_offset, len, value);
1724 * %state_instruction
1726 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1727 len = offset - start_offset;
1728 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1729 udvm_tvb, start_offset, len, value);
1731 * %minimum_access_length
1733 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1734 len = offset - start_offset;
1735 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len,
1736 udvm_tvb, start_offset, len, value);
1738 * %state_retention_priority
1740 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1741 len = offset - start_offset;
1742 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
1743 udvm_tvb, start_offset, len, value);
1745 break;
1746 case SIGCOMP_INSTR_STATE_FREE: /* 33 */
1748 * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
1751 * %partial_identifier_start
1753 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1754 len = offset - start_offset;
1755 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_start,
1756 udvm_tvb, start_offset, len, value);
1759 * %partial_identifier_length
1761 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1762 len = offset - start_offset;
1763 proto_tree_add_uint(sigcomp_udvm_tree, hf_partial_identifier_length,
1764 udvm_tvb, start_offset, len, value);
1765 break;
1766 case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */
1768 * %output_start
1770 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1771 len = offset - start_offset;
1772 if ( is_memory_address ) {
1773 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_addr_output_start,
1774 udvm_tvb, start_offset, len, value);
1775 }else{
1776 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_start,
1777 udvm_tvb, start_offset, len, value);
1780 * %output_length
1782 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1783 len = offset - start_offset;
1784 if ( is_memory_address ) {
1785 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length_addr,
1786 udvm_tvb, start_offset, len, value);
1787 }else{
1788 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_output_length,
1789 udvm_tvb, start_offset, len, value);
1791 break;
1792 case SIGCOMP_INSTR_END_MESSAGE: /* 35 */
1794 * END-MESSAGE (%requested_feedback_location,
1795 * %returned_parameters_location, %state_length, %state_address,
1796 * %state_instruction, %minimum_access_length,
1797 * %state_retention_priority)
1799 /* %requested_feedback_location */
1800 if ((msg_length-1) < offset){
1801 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, 0, -1,
1802 "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1803 PROTO_ITEM_SET_GENERATED(item2);
1804 return;
1806 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1807 len = offset - start_offset;
1808 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_req_feedback_loc,
1809 udvm_tvb, start_offset, len, value);
1810 /* returned_parameters_location */
1811 if ((msg_length-1) < offset){
1812 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset-1, -1,
1813 "All remaining parameters = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1814 PROTO_ITEM_SET_GENERATED(item2);
1815 return;
1817 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1818 len = offset - start_offset;
1819 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_ret_param_loc,
1820 udvm_tvb, start_offset, len, value);
1822 * %state_length
1824 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1825 len = offset - start_offset;
1826 if ( is_memory_address ) {
1827 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length_addr,
1828 udvm_tvb, start_offset, len, value);
1829 }else{
1830 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_length,
1831 udvm_tvb, start_offset, len, value);
1834 * %state_address
1836 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1837 len = offset - start_offset;
1838 if ( is_memory_address ) {
1839 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address_addr,
1840 udvm_tvb, start_offset, len, value);
1841 }else{
1842 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_address,
1843 udvm_tvb, start_offset, len, value);
1846 * %state_instruction
1848 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1849 len = offset - start_offset;
1850 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_instr,
1851 udvm_tvb, start_offset, len, value);
1853 * %minimum_access_length
1855 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1856 len = offset - start_offset;
1857 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_min_acc_len,
1858 udvm_tvb, start_offset, len, value);
1860 * %state_retention_priority
1862 if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1863 offset = dissect_udvm_multitype_operand(udvm_tvb, sigcomp_udvm_tree, offset, TRUE, &start_offset, &value, &is_memory_address);
1864 len = offset - start_offset;
1865 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_state_ret_pri,
1866 udvm_tvb, start_offset, len, value);
1867 }else{
1868 item2 = proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, 1,
1869 "state_retention_priority = 0(Not in the uploaded code as UDVM buffer initialized to Zero");
1870 PROTO_ITEM_SET_GENERATED(item2);
1872 if ( tvb_reported_length_remaining(udvm_tvb, offset) != 0 ){
1873 len = tvb_reported_length_remaining(udvm_tvb, offset);
1874 UDVM_address = start_address + offset;
1875 proto_tree_add_text(sigcomp_udvm_tree, udvm_tvb, offset, len,
1876 "Remaining %u bytes starting at UDVM addr %u (0x%x)- State information ?",len, UDVM_address, UDVM_address);
1878 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1879 break;
1881 default:
1882 offset = offset + tvb_reported_length_remaining(udvm_tvb, offset);
1883 break;
1888 return;
1890 /* The simplest operand type is the literal (#), which encodes a
1891 * constant integer from 0 to 65535 inclusive. A literal operand may
1892 * require between 1 and 3 bytes depending on its value.
1893 * Bytecode: Operand value: Range:
1894 * 0nnnnnnn N 0 - 127
1895 * 10nnnnnn nnnnnnnn N 0 - 16383
1896 * 11000000 nnnnnnnn nnnnnnnn N 0 - 65535
1898 * Figure 8: Bytecode for a literal (#) operand
1901 static int
1902 dissect_udvm_literal_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1903 gint offset, gint *start_offset, guint16 *value)
1905 guint bytecode;
1906 guint16 operand;
1907 guint test_bits;
1908 guint display_bytecode;
1910 bytecode = tvb_get_guint8(udvm_tvb, offset);
1911 test_bits = bytecode >> 7;
1912 if (test_bits == 1){
1913 test_bits = bytecode >> 6;
1914 if (test_bits == 2){
1916 * 10nnnnnn nnnnnnnn N 0 - 16383
1918 display_bytecode = bytecode & 0xc0;
1919 if ( display_udvm_bytecode )
1920 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1921 udvm_tvb, offset, 1, display_bytecode);
1922 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
1923 *value = operand;
1924 *start_offset = offset;
1925 offset = offset + 2;
1927 }else{
1929 * 111000000 nnnnnnnn nnnnnnnn N 0 - 65535
1931 display_bytecode = bytecode & 0xc0;
1932 if ( display_udvm_bytecode )
1933 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1934 udvm_tvb, offset, 1, display_bytecode);
1935 offset ++;
1936 operand = tvb_get_ntohs(udvm_tvb, offset);
1937 *value = operand;
1938 *start_offset = offset;
1939 offset = offset + 2;
1942 }else{
1944 * 0nnnnnnn N 0 - 127
1946 display_bytecode = bytecode & 0xc0;
1947 if ( display_udvm_bytecode )
1948 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_literal_bytecode,
1949 udvm_tvb, offset, 1, display_bytecode);
1950 operand = ( bytecode & 0x7f);
1951 *value = operand;
1952 *start_offset = offset;
1953 offset ++;
1956 return offset;
1960 * The second operand type is the reference ($), which is always used to
1961 * access a 2-byte value located elsewhere in the UDVM memory. The
1962 * bytecode for a reference operand is decoded to be a constant integer
1963 * from 0 to 65535 inclusive, which is interpreted as the memory address
1964 * containing the actual value of the operand.
1965 * Bytecode: Operand value: Range:
1967 * 0nnnnnnn memory[2 * N] 0 - 65535
1968 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
1969 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
1971 * Figure 9: Bytecode for a reference ($) operand
1973 static int
1974 dissect_udvm_reference_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
1975 gint offset, gint *start_offset, guint16 *value)
1977 guint bytecode;
1978 guint16 operand;
1979 guint test_bits;
1980 guint display_bytecode;
1982 bytecode = tvb_get_guint8(udvm_tvb, offset);
1983 test_bits = bytecode >> 7;
1984 if (test_bits == 1){
1985 test_bits = bytecode >> 6;
1986 if (test_bits == 2){
1988 * 10nnnnnn nnnnnnnn memory[2 * N] 0 - 65535
1990 display_bytecode = bytecode & 0xc0;
1991 if ( display_udvm_bytecode )
1992 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
1993 udvm_tvb, offset, 1, display_bytecode);
1994 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x3fff;
1995 *value = (operand * 2);
1996 *start_offset = offset;
1997 offset = offset + 2;
1999 }else{
2001 * 11000000 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
2003 display_bytecode = bytecode & 0xc0;
2004 if ( display_udvm_bytecode )
2005 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
2006 udvm_tvb, offset, 1, display_bytecode);
2007 offset ++;
2008 operand = tvb_get_ntohs(udvm_tvb, offset);
2009 *value = operand;
2010 *start_offset = offset;
2011 offset = offset + 2;
2014 }else{
2016 * 0nnnnnnn memory[2 * N] 0 - 65535
2018 display_bytecode = bytecode & 0xc0;
2019 if ( display_udvm_bytecode )
2020 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_reference_bytecode,
2021 udvm_tvb, offset, 1, display_bytecode);
2022 operand = ( bytecode & 0x7f);
2023 *value = (operand * 2);
2024 *start_offset = offset;
2025 offset ++;
2028 return offset;
2032 *The fourth operand type is the address (@). This operand is decoded
2033 * as a multitype operand followed by a further step: the memory address
2034 * of the UDVM instruction containing the address operand is added to
2035 * obtain the correct operand value. So if the operand value from
2036 * Figure 10 is D then the actual operand value of an address is
2037 * calculated as follows:
2039 * operand_value = (is_memory_address_of_instruction + D) modulo 2^16
2040 * TODO calculate correct value for operand in case of ADDR
2042 static int
2043 dissect_udvm_multitype_operand(tvbuff_t *udvm_tvb, proto_tree *sigcomp_udvm_tree,
2044 gint offset, gboolean is_addr _U_, gint *start_offset, guint16 *value, gboolean *is_memory_address )
2046 guint bytecode;
2047 guint display_bytecode;
2048 guint16 operand;
2049 guint32 result;
2050 guint test_bits;
2051 /* RFC3320
2052 * Figure 10: Bytecode for a multitype (%) operand
2053 * Bytecode: Operand value: Range: HEX val
2054 * 00nnnnnn N 0 - 63 0x00
2055 * 01nnnnnn memory[2 * N] 0 - 65535 0x40
2056 * 1000011n 2 ^ (N + 6) 64 , 128 0x86
2057 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768 0x88
2058 * 111nnnnn N + 65504 65504 - 65535 0xe0
2059 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535 0x90
2060 * 101nnnnn nnnnnnnn N 0 - 8191 0xa0
2061 * 110nnnnn nnnnnnnn memory[N] 0 - 65535 0xc0
2062 * 10000000 nnnnnnnn nnnnnnnn N 0 - 65535 0x80
2063 * 10000001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535 0x81
2065 *is_memory_address = FALSE;
2066 bytecode = tvb_get_guint8(udvm_tvb, offset);
2067 test_bits = ( bytecode & 0xc0 ) >> 6;
2068 switch (test_bits ){
2069 case 0:
2071 * 00nnnnnn N 0 - 63
2073 display_bytecode = bytecode & 0xc0;
2074 if ( display_udvm_bytecode )
2075 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2076 udvm_tvb, offset, 1, display_bytecode);
2077 operand = ( bytecode & 0x3f);
2078 *value = operand;
2079 *start_offset = offset;
2080 offset ++;
2081 break;
2082 case 1:
2084 * 01nnnnnn memory[2 * N] 0 - 65535
2086 display_bytecode = bytecode & 0xc0;
2087 if ( display_udvm_bytecode )
2088 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2089 udvm_tvb, offset, 1, display_bytecode);
2090 operand = ( bytecode & 0x3f) * 2;
2091 *is_memory_address = TRUE;
2092 *value = operand;
2093 *start_offset = offset;
2094 offset ++;
2095 break;
2096 case 2:
2097 /* Check tree most significant bits */
2098 test_bits = ( bytecode & 0xe0 ) >> 5;
2099 if ( test_bits == 5 ){
2101 * 101nnnnn nnnnnnnn N 0 - 8191
2103 display_bytecode = bytecode & 0xe0;
2104 if ( display_udvm_bytecode )
2105 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2106 udvm_tvb, offset, 1, display_bytecode);
2107 operand = tvb_get_ntohs(udvm_tvb, offset) & 0x1fff;
2108 *value = operand;
2109 *start_offset = offset;
2110 offset = offset + 2;
2111 }else{
2112 test_bits = ( bytecode & 0xf0 ) >> 4;
2113 if ( test_bits == 9 ){
2115 * 1001nnnn nnnnnnnn N + 61440 61440 - 65535
2117 display_bytecode = bytecode & 0xf0;
2118 if ( display_udvm_bytecode )
2119 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2120 udvm_tvb, offset, 1, display_bytecode);
2121 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x0fff) + 61440;
2122 *start_offset = offset;
2123 *value = operand;
2124 offset = offset + 2;
2125 }else{
2126 test_bits = ( bytecode & 0x08 ) >> 3;
2127 if ( test_bits == 1){
2129 * 10001nnn 2 ^ (N + 8) 256 , ... , 32768
2131 display_bytecode = bytecode & 0xf8;
2132 if ( display_udvm_bytecode )
2133 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2134 udvm_tvb, offset, 1, display_bytecode);
2135 result = (guint32)pow(2,( bytecode & 0x07) + 8);
2136 operand = result & 0xffff;
2137 *start_offset = offset;
2138 *value = operand;
2139 offset ++;
2140 }else{
2141 test_bits = ( bytecode & 0x0e ) >> 1;
2142 if ( test_bits == 3 ){
2144 * 1000 011n 2 ^ (N + 6) 64 , 128
2146 display_bytecode = bytecode & 0xfe;
2147 if ( display_udvm_bytecode )
2148 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2149 udvm_tvb, offset, 1, display_bytecode);
2150 result = (guint32)pow(2,( bytecode & 0x01) + 6);
2151 operand = result & 0xffff;
2152 *start_offset = offset;
2153 *value = operand;
2154 offset ++;
2155 }else{
2157 * 1000 0000 nnnnnnnn nnnnnnnn N 0 - 65535
2158 * 1000 0001 nnnnnnnn nnnnnnnn memory[N] 0 - 65535
2160 display_bytecode = bytecode;
2161 if ( display_udvm_bytecode )
2162 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2163 udvm_tvb, offset, 1, display_bytecode);
2164 if ( (bytecode & 0x01) == 1 )
2165 *is_memory_address = TRUE;
2166 offset ++;
2167 operand = tvb_get_ntohs(udvm_tvb, offset);
2168 *value = operand;
2169 *start_offset = offset;
2170 offset = offset +2;
2177 break;
2179 case 3:
2180 test_bits = ( bytecode & 0x20 ) >> 5;
2181 if ( test_bits == 1 ){
2183 * 111nnnnn N + 65504 65504 - 65535
2185 display_bytecode = bytecode & 0xe0;
2186 if ( display_udvm_bytecode )
2187 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2188 udvm_tvb, offset, 1, display_bytecode);
2189 operand = ( bytecode & 0x1f) + 65504;
2190 *start_offset = offset;
2191 *value = operand;
2192 offset ++;
2193 }else{
2195 * 110nnnnn nnnnnnnn memory[N] 0 - 65535
2197 display_bytecode = bytecode & 0xe0;
2198 if ( display_udvm_bytecode )
2199 proto_tree_add_uint(sigcomp_udvm_tree, hf_udvm_multitype_bytecode,
2200 udvm_tvb, offset, 1, display_bytecode);
2201 operand = (tvb_get_ntohs(udvm_tvb, offset) & 0x1fff);
2202 *is_memory_address = TRUE;
2203 *start_offset = offset;
2204 *value = operand;
2205 offset = offset +2;
2208 default :
2209 break;
2211 return offset;
2214 static void
2215 tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree)
2217 proto_tree *raw_tree = NULL;
2218 proto_item *ti = NULL;
2219 int offset, next_offset, linelen;
2221 if(tree) {
2222 ti = proto_tree_add_item(tree, proto_raw_sigcomp, tvb, 0, -1, ENC_NA);
2223 raw_tree = proto_item_add_subtree(ti, ett_raw_text);
2226 offset = 0;
2228 while (tvb_offset_exists(tvb, offset)) {
2229 tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
2230 linelen = next_offset - offset;
2231 if(raw_tree) {
2232 proto_tree_add_text(raw_tree, tvb, offset, linelen,
2233 "%s", tvb_format_text(tvb, offset, linelen));
2235 offset = next_offset;
2239 /* Register the protocol with Wireshark */
2241 void
2242 proto_register_sigcomp(void)
2244 void proto_reg_handoff_sigcomp(void);
2246 /* Setup list of header fields See Section 1.6.1 for details*/
2247 static hf_register_info hf[] = {
2248 { &hf_sigcomp_t_bit,
2249 { "T bit", "sigcomp.t.bit",
2250 FT_UINT8, BASE_DEC, NULL, 0x04,
2251 "Sigcomp T bit", HFILL }
2253 { &hf_sigcomp_len,
2254 { "Partial state id length","sigcomp.length",
2255 FT_UINT8, BASE_HEX, VALS(length_encoding_vals), 0x03,
2256 "Sigcomp length", HFILL }
2258 { &hf_sigcomp_returned_feedback_item,
2259 { "Returned_feedback item", "sigcomp.returned.feedback.item",
2260 FT_BYTES, BASE_NONE, NULL, 0x0,
2261 "Returned feedback item", HFILL }
2263 { &hf_sigcomp_partial_state,
2264 { "Partial state identifier", "sigcomp.partial.state.identifier",
2265 FT_STRING, BASE_NONE, NULL, 0x0,
2266 NULL, HFILL }
2268 { &hf_sigcomp_remaining_message_bytes,
2269 { "Remaining SigComp message bytes", "sigcomp.remaining-bytes",
2270 FT_UINT32, BASE_DEC, NULL, 0x0,
2271 "Number of bytes remaining in message", HFILL }
2273 { &hf_sigcomp_compression_ratio,
2274 { "Compression ratio (%)", "sigcomp.compression-ratio",
2275 FT_UINT32, BASE_DEC, NULL, 0x0,
2276 "Compression ratio (decompressed / compressed) %", HFILL }
2278 { &hf_sigcomp_returned_feedback_item_len,
2279 { "Returned feedback item length", "sigcomp.returned.feedback.item.len",
2280 FT_UINT8, BASE_DEC, NULL, 0x7f,
2281 NULL, HFILL }
2283 { &hf_sigcomp_code_len,
2284 { "Code length","sigcomp.code.len",
2285 FT_UINT16, BASE_HEX, NULL, 0xfff0,
2286 NULL, HFILL }
2288 { &hf_sigcomp_destination,
2289 { "Destination","sigcomp.destination",
2290 FT_UINT8, BASE_HEX, VALS(destination_address_encoding_vals), 0xf,
2291 NULL, HFILL }
2293 { &hf_sigcomp_udvm_bytecode,
2294 { "Uploaded UDVM bytecode","sigcomp.udvm.byte-code",
2295 FT_NONE, BASE_NONE, NULL, 0x0,
2296 NULL, HFILL }
2298 { &hf_sigcomp_udvm_instr,
2299 { "UDVM instruction code","sigcomp.udvm.instr",
2300 FT_UINT8, BASE_DEC, VALS(udvm_instruction_code_vals), 0x0,
2301 NULL, HFILL }
2303 { &hf_udvm_execution_trace,
2304 { "UDVM execution trace","sigcomp.udvm.execution-trace",
2305 FT_NONE, BASE_NONE, NULL, 0x0,
2306 NULL, HFILL }
2308 { &hf_udvm_multitype_bytecode,
2309 { "UDVM bytecode", "sigcomp.udvm.multyt.bytecode",
2310 FT_UINT8, BASE_HEX, VALS(display_bytecode_vals), 0x0,
2311 NULL, HFILL }
2313 { &hf_udvm_reference_bytecode,
2314 { "UDVM bytecode", "sigcomp.udvm.ref.bytecode",
2315 FT_UINT8, BASE_HEX, VALS(display_ref_bytecode_vals), 0x0,
2316 NULL, HFILL }
2318 { &hf_udvm_literal_bytecode,
2319 { "UDVM bytecode", "sigcomp.udvm.lit.bytecode",
2320 FT_UINT8, BASE_HEX, VALS(display_lit_bytecode_vals), 0x0,
2321 NULL, HFILL }
2323 #if 0
2324 { &hf_udvm_operand,
2325 { "UDVM operand", "sigcomp.udvm.operand",
2326 FT_UINT16, BASE_DEC, NULL, 0x0,
2327 NULL, HFILL }
2329 #endif
2330 { &hf_udvm_length,
2331 { "%Length", "sigcomp.udvm.length",
2332 FT_UINT16, BASE_DEC, NULL, 0x0,
2333 "Length", HFILL }
2335 { &hf_udvm_addr_length,
2336 { "%Length[memory address]", "sigcomp.udvm.addr.length",
2337 FT_UINT16, BASE_DEC, NULL, 0x0,
2338 "Length", HFILL }
2340 { &hf_udvm_destination,
2341 { "%Destination", "sigcomp.udvm.destination",
2342 FT_UINT16, BASE_DEC, NULL, 0x0,
2343 "Destination", HFILL }
2345 { &hf_udvm_addr_destination,
2346 { "%Destination[memory address]", "sigcomp.udvm.addr.destination",
2347 FT_UINT16, BASE_DEC, NULL, 0x0,
2348 "Destination", HFILL }
2350 { &hf_udvm_at_address,
2351 { "@Address(mem_add_of_inst + D) mod 2^16)", "sigcomp.udvm.at.address",
2352 FT_UINT16, BASE_DEC, NULL, 0x0,
2353 "Address", HFILL }
2355 { &hf_udvm_address,
2356 { "%Address", "sigcomp.udvm.length",
2357 FT_UINT16, BASE_DEC, NULL, 0x0,
2358 "Address", HFILL }
2360 { &hf_udvm_literal_num,
2361 { "#n", "sigcomp.udvm.literal-num",
2362 FT_UINT16, BASE_DEC, NULL, 0x0,
2363 "Literal number", HFILL }
2365 { &hf_udvm_value,
2366 { "%Value", "sigcomp.udvm.value",
2367 FT_UINT16, BASE_DEC, NULL, 0x0,
2368 "Value", HFILL }
2370 { &hf_udvm_addr_value,
2371 { "%Value[memory address]", "sigcomp.udvm.value",
2372 FT_UINT16, BASE_DEC, NULL, 0x0,
2373 "Value", HFILL }
2375 { &hf_partial_identifier_start,
2376 { "%Partial identifier start", "sigcomp.udvm.partial.identifier.start",
2377 FT_UINT16, BASE_DEC, NULL, 0x0,
2378 "Partial identifier start", HFILL }
2380 { &hf_partial_identifier_length,
2381 { "%Partial identifier length", "sigcomp.udvm.partial.identifier.length",
2382 FT_UINT16, BASE_DEC, NULL, 0x0,
2383 "Partial identifier length", HFILL }
2385 { &hf_state_begin,
2386 { "%State begin", "sigcomp.udvm.state.begin",
2387 FT_UINT16, BASE_DEC, NULL, 0x0,
2388 "State begin", HFILL }
2390 { &hf_udvm_state_length,
2391 { "%State length", "sigcomp.udvm.state.length",
2392 FT_UINT16, BASE_DEC, NULL, 0x0,
2393 "State length", HFILL }
2396 { &hf_udvm_state_length_addr,
2397 { "%State length[memory address]", "sigcomp.udvm.state.length.addr",
2398 FT_UINT16, BASE_DEC, NULL, 0x0,
2399 "State length", HFILL }
2401 { &hf_udvm_state_address,
2402 { "%State address", "sigcomp.udvm.start.address",
2403 FT_UINT16, BASE_DEC, NULL, 0x0,
2404 "State address", HFILL }
2406 { &hf_udvm_state_address_addr,
2407 { "%State address[memory address]", "sigcomp.udvm.start.address.addr",
2408 FT_UINT16, BASE_DEC, NULL, 0x0,
2409 "State address", HFILL }
2411 { &hf_udvm_state_instr,
2412 { "%State instruction", "sigcomp.udvm.start.instr",
2413 FT_UINT16, BASE_DEC, NULL, 0x0,
2414 "State instruction", HFILL }
2416 { &hf_udvm_operand_1,
2417 { "$Operand 1[memory address]", "sigcomp.udvm.operand.1",
2418 FT_UINT16, BASE_DEC, NULL, 0x0,
2419 "Reference $ Operand 1", HFILL }
2421 { &hf_udvm_operand_2,
2422 { "%Operand 2", "sigcomp.udvm.operand.2",
2423 FT_UINT16, BASE_DEC, NULL, 0x0,
2424 "Operand 2", HFILL }
2426 { &hf_udvm_operand_2_addr,
2427 { "%Operand 2[memory address]", "sigcomp.udvm.operand.2.addr",
2428 FT_UINT16, BASE_DEC, NULL, 0x0,
2429 "Operand 2", HFILL }
2431 { &hf_udvm_j,
2432 { "%j", "sigcomp.udvm.j",
2433 FT_UINT16, BASE_DEC, NULL, 0x0,
2434 "j", HFILL }
2436 { &hf_udvm_addr_j,
2437 { "%j[memory address]", "sigcomp.udvm.addr.j",
2438 FT_UINT16, BASE_DEC, NULL, 0x0,
2439 "j", HFILL }
2441 { &hf_udvm_output_start,
2442 { "%Output_start", "sigcomp.output.start",
2443 FT_UINT16, BASE_DEC, NULL, 0x0,
2444 "Output start", HFILL }
2446 { &hf_udvm_addr_output_start,
2447 { "%Output_start[memory address]", "sigcomp.addr.output.start",
2448 FT_UINT16, BASE_DEC, NULL, 0x0,
2449 "Output start", HFILL }
2451 { &hf_udvm_output_length,
2452 { "%Output_length", "sigcomp.output.length",
2453 FT_UINT16, BASE_DEC, NULL, 0x0,
2454 "Output length", HFILL }
2456 { &hf_udvm_output_length_addr,
2457 { "%Output_length[memory address]", "sigcomp.output.length.addr",
2458 FT_UINT16, BASE_DEC, NULL, 0x0,
2459 "Output length", HFILL }
2461 { &hf_udvm_req_feedback_loc,
2462 { "%Requested feedback location", "sigcomp.req.feedback.loc",
2463 FT_UINT16, BASE_DEC, NULL, 0x0,
2464 "Requested feedback location", HFILL }
2466 { &hf_udvm_min_acc_len,
2467 { "%Minimum access length", "sigcomp.min.acc.len",
2468 FT_UINT16, BASE_DEC, NULL, 0x0,
2469 "Minimum access length", HFILL }
2471 { &hf_udvm_state_ret_pri,
2472 { "%State retention priority", "sigcomp.udvm.state.ret.pri",
2473 FT_UINT16, BASE_DEC, NULL, 0x0,
2474 "State retention priority", HFILL }
2476 { &hf_udvm_ret_param_loc,
2477 { "%Returned parameters location", "sigcomp.ret.param.loc",
2478 FT_UINT16, BASE_DEC, NULL, 0x0,
2479 "Returned parameters location", HFILL }
2481 { &hf_udvm_position,
2482 { "%Position", "sigcomp.udvm.position",
2483 FT_UINT16, BASE_DEC, NULL, 0x0,
2484 "Position", HFILL }
2486 { &hf_udvm_ref_dest,
2487 { "$Destination[memory address]", "sigcomp.udvm.ref.destination",
2488 FT_UINT16, BASE_DEC, NULL, 0x0,
2489 "(reference)Destination", HFILL }
2491 { &hf_udvm_bits,
2492 { "%Bits", "sigcomp.udvm.bits",
2493 FT_UINT16, BASE_DEC, NULL, 0x0,
2494 "Bits", HFILL }
2496 { &hf_udvm_lower_bound,
2497 { "%Lower bound", "sigcomp.udvm.lower.bound",
2498 FT_UINT16, BASE_DEC, NULL, 0x0,
2499 "Lower_bound", HFILL }
2501 { &hf_udvm_upper_bound,
2502 { "%Upper bound", "sigcomp.udvm.upper.bound",
2503 FT_UINT16, BASE_DEC, NULL, 0x0,
2504 "Upper bound", HFILL }
2506 { &hf_udvm_uncompressed,
2507 { "%Uncompressed", "sigcomp.udvm.uncompressed",
2508 FT_UINT16, BASE_DEC, NULL, 0x0,
2509 "Uncompressed", HFILL }
2511 { &hf_udvm_start_value,
2512 { "%Start value", "sigcomp.udvm.start.value",
2513 FT_UINT16, BASE_DEC, NULL, 0x0,
2514 "Start value", HFILL }
2516 { &hf_udvm_offset,
2517 { "%Offset", "sigcomp.udvm.offset",
2518 FT_UINT16, BASE_DEC, NULL, 0x0,
2519 "Offset", HFILL }
2521 { &hf_udvm_addr_offset,
2522 { "%Offset[memory address]", "sigcomp.udvm.addr.offset",
2523 FT_UINT16, BASE_DEC, NULL, 0x0,
2524 "Offset", HFILL }
2526 { &hf_sigcomp_nack_ver,
2527 { "NACK Version", "sigcomp.nack.ver",
2528 FT_UINT8, BASE_DEC, NULL, 0x0f,
2529 NULL, HFILL }
2531 { &hf_sigcomp_nack_reason_code,
2532 { "Reason Code", "sigcomp.nack.reason",
2533 FT_UINT8, BASE_DEC, VALS(sigcomp_nack_reason_code_vals), 0x0,
2534 "NACK Reason Code", HFILL }
2536 { &hf_sigcomp_nack_failed_op_code,
2537 { "OPCODE of failed instruction", "sigcomp.nack.failed_op_code",
2538 FT_UINT8, BASE_DEC, VALS(udvm_instruction_code_vals), 0x0,
2539 "NACK OPCODE of failed instruction", HFILL }
2541 { &hf_sigcomp_nack_pc,
2542 { "PC of failed instruction", "sigcomp.nack.pc",
2543 FT_UINT16, BASE_DEC, NULL, 0x0,
2544 "NACK PC of failed instruction", HFILL }
2546 { &hf_sigcomp_nack_sha1,
2547 { "SHA-1 Hash of failed message", "sigcomp.nack.sha1",
2548 FT_BYTES, BASE_NONE, NULL, 0x0,
2549 "NACK SHA-1 Hash of failed message", HFILL }
2551 { &hf_sigcomp_nack_state_id,
2552 { "State ID (6 - 20 bytes)", "sigcomp.nack.state_id",
2553 FT_BYTES, BASE_NONE, NULL, 0x0,
2554 "NACK State ID (6 - 20 bytes)", HFILL }
2556 { &hf_sigcomp_nack_cycles_per_bit,
2557 { "Cycles Per Bit", "sigcomp.nack.cycles_per_bit",
2558 FT_UINT8, BASE_DEC, NULL, 0x0,
2559 "NACK Cycles Per Bit", HFILL }
2561 { &hf_sigcomp_nack_memory_size,
2562 { "Memory size", "sigcomp.memory_size",
2563 FT_UINT16, BASE_DEC, NULL, 0x0,
2564 NULL, HFILL }
2568 /* Setup protocol subtree array */
2569 static gint *ett[] = {
2570 &ett_sigcomp,
2571 &ett_sigcomp_udvm,
2572 &ett_sigcomp_udvm_exe,
2574 static gint *ett_raw[] = {
2575 &ett_raw_text,
2578 static ei_register_info ei[] = {
2579 { &ei_sigcomp_nack_failed_op_code, { "sigcomp.nack.failed_op_code.expert", PI_SEQUENCE, PI_WARN, "SigComp NACK", EXPFILL }},
2582 module_t *sigcomp_module;
2583 expert_module_t* expert_sigcomp;
2585 static const enum_val_t udvm_detail_vals[] = {
2586 {"no-printout", "No-Printout", 0},
2587 {"low-detail", "Low-detail", 1},
2588 {"medium-detail", "Medium-detail", 2},
2589 {"high-detail", "High-detail", 3},
2590 {NULL, NULL, -1}
2594 /* Register the protocol name and description */
2595 proto_sigcomp = proto_register_protocol("Signaling Compression",
2596 "SIGCOMP", "sigcomp");
2597 proto_raw_sigcomp = proto_register_protocol("Decompressed SigComp message as raw text",
2598 "Raw_SigComp", "raw_sigcomp");
2600 new_register_dissector("sigcomp", dissect_sigcomp, proto_sigcomp);
2602 /* Required function calls to register the header fields and subtrees used */
2603 proto_register_field_array(proto_sigcomp, hf, array_length(hf));
2604 proto_register_subtree_array(ett, array_length(ett));
2605 proto_register_subtree_array(ett_raw, array_length(ett_raw));
2606 expert_sigcomp = expert_register_protocol(proto_sigcomp);
2607 expert_register_field_array(expert_sigcomp, ei, array_length(ei));
2609 /* Register a configuration option for port */
2610 sigcomp_module = prefs_register_protocol(proto_sigcomp,
2611 proto_reg_handoff_sigcomp);
2613 prefs_register_uint_preference(sigcomp_module, "udp.port",
2614 "Sigcomp UDP Port 1",
2615 "Set UDP port 1 for SigComp messages",
2617 &SigCompUDPPort1);
2619 prefs_register_uint_preference(sigcomp_module, "udp.port2",
2620 "Sigcomp UDP Port 2",
2621 "Set UDP port 2 for SigComp messages",
2623 &SigCompUDPPort2);
2624 prefs_register_uint_preference(sigcomp_module, "tcp.port",
2625 "Sigcomp TCP Port 1",
2626 "Set TCP port 1 for SigComp messages",
2628 &SigCompTCPPort1);
2630 prefs_register_uint_preference(sigcomp_module, "tcp.port2",
2631 "Sigcomp TCP Port 2",
2632 "Set TCP port 2 for SigComp messages",
2634 &SigCompTCPPort2);
2635 prefs_register_bool_preference(sigcomp_module, "display.udvm.code",
2636 "Dissect the UDVM code",
2637 "Preference whether to Dissect the UDVM code or not",
2638 &dissect_udvm_code);
2640 prefs_register_bool_preference(sigcomp_module, "display.bytecode",
2641 "Display the bytecode of operands",
2642 "preference whether to display the bytecode in "
2643 "UDVM operands or not",
2644 &display_udvm_bytecode);
2645 prefs_register_bool_preference(sigcomp_module, "decomp.msg",
2646 "Decompress message",
2647 "preference whether to decompress message or not",
2648 &decompress);
2649 prefs_register_bool_preference(sigcomp_module, "display.decomp.msg.as.txt",
2650 "Displays the decompressed message as text",
2651 "preference whether to display the decompressed message "
2652 "as raw text or not",
2653 &display_raw_txt);
2654 prefs_register_enum_preference(sigcomp_module, "show.udvm.execution",
2655 "Level of detail of UDVM execution:",
2656 "'No-Printout' = UDVM executes silently, then increasing detail "
2657 "about execution of UDVM instructions; "
2658 "Warning! CPU intense at high detail",
2659 &udvm_print_detail_level, udvm_detail_vals, FALSE);
2661 register_init_routine(&sigcomp_init_protocol);
2667 void
2668 proto_reg_handoff_sigcomp(void)
2670 static dissector_handle_t sigcomp_handle;
2671 static dissector_handle_t sigcomp_tcp_handle;
2672 static gboolean Initialized=FALSE;
2673 static guint udp_port1;
2674 static guint udp_port2;
2675 static guint tcp_port1;
2676 static guint tcp_port2;
2678 if (!Initialized) {
2679 sigcomp_handle = find_dissector("sigcomp");
2680 sigcomp_tcp_handle = new_create_dissector_handle(dissect_sigcomp_tcp,proto_sigcomp);
2681 sip_handle = find_dissector("sip");
2682 Initialized=TRUE;
2683 }else{
2684 dissector_delete_uint("udp.port", udp_port1, sigcomp_handle);
2685 dissector_delete_uint("udp.port", udp_port2, sigcomp_handle);
2686 dissector_delete_uint("tcp.port", tcp_port1, sigcomp_tcp_handle);
2687 dissector_delete_uint("tcp.port", tcp_port2, sigcomp_tcp_handle);
2690 udp_port1 = SigCompUDPPort1;
2691 udp_port2 = SigCompUDPPort2;
2692 tcp_port1 = SigCompTCPPort1;
2693 tcp_port2 = SigCompTCPPort2;
2696 dissector_add_uint("udp.port", SigCompUDPPort1, sigcomp_handle);
2697 dissector_add_uint("udp.port", SigCompUDPPort2, sigcomp_handle);
2698 dissector_add_uint("tcp.port", SigCompTCPPort1, sigcomp_tcp_handle);
2699 dissector_add_uint("tcp.port", SigCompTCPPort2, sigcomp_tcp_handle);