Text   |  XML   |  ReML   |   Visible Warnings:

Unreachable Call  at sigcomp-udvm.c:2778

No properties have been set. | edit properties
Jump to warning location ↓ warning details...
Show Events | Options

decompress_sigcomp_message

(/home/sate/Testcases/c/cve/wireshark-1.2.0/epan/sigcomp-udvm.c)expand/collapse
Show more  
 125  tvbuff_t*
 126  decompress_sigcomp_message(tvbuff_t *bytecode_tvb, tvbuff_t *message_tvb, packet_info *pinfo,
 127                                                     proto_tree *udvm_tree, gint udvm_mem_dest,
 128                                                     gint print_flags, gint hf_id,
 129                                                     gint header_len,
 130                                                     gint byte_code_state_len, gint byte_code_id_len,
 131                                                     gint udvm_start_ip)
 132  {
 133          tvbuff_t        *decomp_tvb;
 134          guint8          buff[UDVM_MEMORY_SIZE];
 135          char            string[2];
 136          guint8          *out_buff;              /* Largest allowed size for a message is 65535  */
 137          guint32         i = 0;
 138          guint16         n = 0;
 139          guint16         m = 0;
 140          guint16         x;
 141          guint           k = 0;
 142          guint16         H;
 143          guint16         oldH;
 144          guint           offset = 0;
 145          guint           result_dest;
 146          guint           code_length =0;
 147          guint8          current_instruction;
 148          guint           current_address;
 149          guint           operand_address;
 150          guint           input_address;
 151          guint16         output_address = 0;
 152          guint           next_operand_address;
 153          guint8          octet;
 154          guint8          msb;
 155          guint8          lsb;
 156          guint16         byte_copy_right;
 157          guint16         byte_copy_left;
 158          guint16         input_bit_order;
 159          guint16         stack_location;
 160          guint16         stack_fill;
 161          guint16         result;
 162          guint           msg_end = tvb_reported_length_remaining(message_tvb, 0);
 163          guint16         result_code = 0;
 164          guint16         old_input_bit_order = 0;
 165          guint16         remaining_bits = 0;
 166          guint16         input_bits = 0;
 167          guint8          bit_order = 0;
 168          gboolean        outside_huffman_boundaries = TRUE;
 169          gboolean        print_in_loop = FALSE;
 170          guint16         instruction_address;
 171          guint8          no_of_state_create = 0;
 172          guint16         state_length_buff[5];
 173          guint16         state_address_buff[5];
 174          guint16         state_instruction_buff[5];
 175          guint16         state_minimum_access_length_buff[5];
 176          guint16         state_state_retention_priority_buff[5];
 177          guint32         used_udvm_cycles = 0;
 178          guint           cycles_per_bit;
 179          guint           maximum_UDVM_cycles;
 180          guint8          *sha1buff;
 181          unsigned char sha1_digest_buf[STATE_BUFFER_SIZE];
 182          sha1_context ctx;
 183   
 184   
 185          /* UDVM operand variables */
 186          guint16 length;
 187          guint16 at_address;
 188
211
Show [ Lines 188 to 211 omitted. ]
 212          guint16 output_start;
 213          guint16 output_length;
 214          guint16 minimum_access_length;
 215          guint16 state_retention_priority;
 216          guint16 requested_feedback_location;
 217          guint16 returned_parameters_location;
 218          guint16 start_value;
 219   
 220   
 221          /* Set print parameters */
 222          print_level_1 = FALSE;
 223          print_level_2 = FALSE;
 224          print_level_3 = FALSE;
 225          show_instr_detail_level = 0;
 226   
 227   
 228   
 229          switch( print_flags ) {
 230                  case 0:
 231                          break;
 232   
 233                  case 1:
 234                          print_level_1 = TRUE;
 235                          show_instr_detail_level = 1;
 236                          break;
 237                  case 2:
 238                          print_level_1 = TRUE;
 239                          print_level_2 = TRUE;
 240                          show_instr_detail_level = 1;
 241                          break;
 242                  case 3:
 243                          print_level_1 = TRUE;
 244                          print_level_2 = TRUE;
 245                          print_level_3 = TRUE;
 246                          show_instr_detail_level = 2;
 247                          break;
 248                  default:
 249                          print_level_1 = TRUE;
 250                          show_instr_detail_level = 1;
 251                          break;
 252          }
 253   
 254   
 255   
 256   
 257   
 258          /* UDVM memory must be initialised to zero */
 259          memset(buff, 0, UDVM_MEMORY_SIZE);
 260          /* Set initial UDVM data
 261           *  The first 32 bytes of UDVM memory are then initialized to special 
 262           *  values as illustrated in Figure 5.
 263           *
 264           *                      0             7 8            15
 265           *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 266           *                     |       UDVM_memory_size        |  0 - 1 
 267           *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 268           *                     |        cycles_per_bit         |  2 - 3 
 269           *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 270           *                     |        SigComp_version        |  4 - 5 
 271           *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 272           *                     |    partial_state_ID_length    |  6 - 7 
 273           *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 274           *                     |         state_length          |  8 - 9 
 275           *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 276           *                     |                               |
 277           *                     :           reserved            :  10 - 31 
 278           *                     |                               |
 279           *                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 280           *
 281           *            Figure 5: Initializing Useful Values in UDVM memory
 282           */
 283          /* UDVM_memory_size  */
 284          buff[0] = (UDVM_MEMORY_SIZE >> 8) & 0x00FF;
 285          buff[1] = UDVM_MEMORY_SIZE & 0x00FF;
 286          /* cycles_per_bit */
 287          buff[2] = 0;
 288          buff[3] = 16;
 289          /* SigComp_version */
 290          buff[4] = 0;
 291          buff[5] = 1;
 292          /* partial_state_ID_length */
 293          buff[6] = (byte_code_id_len >> 8) & 0x00FF;
 294          buff[7] = byte_code_id_len & 0x00FF;
 295          /* state_length  */
 296          buff[8] = (byte_code_state_len >> 8) & 0x00FF;
 297          buff[9] = byte_code_state_len & 0x00FF;
 298   
 299          code_length = tvb_reported_length_remaining(bytecode_tvb, 0);
 300   
 301          cycles_per_bit = buff[2] << 8;
 302          cycles_per_bit = cycles_per_bit | buff[3];
 303          /*
 304           * maximum_UDVM_cycles = (8 * n + 1000) * cycles_per_bit 
 305           */
 306          maximum_UDVM_cycles = (( 8 * (header_len + msg_end) ) + 1000) * cycles_per_bit;
 307   
 308          proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,"maximum_UDVM_cycles(%u) = (( 8 * msg_end(%u) ) + 1000) * cycles_per_bit(%u)",maximum_UDVM_cycles,msg_end,cycles_per_bit);
 309          proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,"Message Length: %u,Byte code length: %u, Maximum UDVM cycles: %u",msg_end,code_length,maximum_UDVM_cycles);
 310   
 311          /* Load bytecode into UDVM starting at "udvm_mem_dest" */
 312          i = udvm_mem_dest;
 313          if ( print_level_3 )
 314                  proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,"Load bytecode into UDVM starting at %u",i);
 315          while ( code_length > offset && i < UDVM_MEMORY_SIZE ) {
 316                  buff[i] = tvb_get_guint8(bytecode_tvb, offset);
 317                  if ( print_level_3 )
 318                          proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,
 319                                                  "              Addr: %u Instruction code(0x%0x) ", i, buff[i]);
 320   
 321                  i++;
 322                  offset++;
 323   
 324          }
 325          /* Largest allowed size for a message is 65535  */
 326          out_buff = g_malloc(65535);
 327          /* Start executing code */
 328          current_address = udvm_start_ip;
 329          input_address = 0;
 330          operand_address = 0;
 331   
 332          proto_tree_add_text(udvm_tree, bytecode_tvb, offset, 1,"UDVM EXECUTION STARTED at Address: %u Message size %u",
 333                  current_address, msg_end);
 334   
 335  execute_next_instruction:
 336   
 337          if ( used_udvm_cycles > maximum_UDVM_cycles ){
 338                  result_code = 15;
 339                  goto decompression_failure;
 340          }
 341          current_instruction = buff[current_address];
 342   
 343          switch ( current_instruction ) {
 344          case SIGCOMP_INSTR_DECOMPRESSION_FAILURE:
 345                  used_udvm_cycles++;
 346                  if ( result_code == 0 )
 347                          result_code = 9;
 348                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 349                          "Addr: %u ## DECOMPRESSION-FAILURE(0)",
 350                          current_address);
 351                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Wireshark UDVM diagnostic: %s.",
 352                                      val_to_str(result_code, result_code_vals,"Unknown (%u)"));
 353                  if ( output_address > 0 ){
 354                          /* At least something got decompressed, show it */
 355                          decomp_tvb = tvb_new_child_real_data(message_tvb, out_buff,output_address,output_address);
 356                          /* Arrange that the allocated packet data copy be freed when the 
 357                           * tvbuff is freed.
 358                           */
 359                          tvb_set_free_cb( decomp_tvb, g_free );
 360                          /* Add the tvbuff to the list of tvbuffs to which the tvbuff we 
 361                           * were handed refers, so it'll get cleaned up when that tvbuff
 362                           * is cleaned up.
 363                           */
 364                          add_new_data_source(pinfo, decomp_tvb, "Decompressed SigComp message(Incomplete)");
 365                          proto_tree_add_text(udvm_tree, decomp_tvb, 0, -1,"SigComp message Decompression failure");
 366                  return decomp_tvb;
 367                  }
 368                  g_free(out_buff);
 369                  return NULL;
 370                  break;
 371   
 372          case SIGCOMP_INSTR_AND: /* 1 AND ($operand_1, %operand_2) */
 373                  used_udvm_cycles++;
 374                  if (show_instr_detail_level == 2 ){
 375                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 376                                  "Addr: %u ## AND(1) (operand_1, operand_2)",
 377                                  current_address);
 378                  }
 379                  /* $operand_1*/
 380                  operand_address = current_address + 1;
 381                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
 382                  if (show_instr_detail_level == 2 ){
 383                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
 384                                  operand_address, operand_1);
 385                  }
 386                  operand_address = next_operand_address;
 387                  /* %operand_2*/
 388                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
 389                  if (show_instr_detail_level == 2 ){
 390                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
 391                                  operand_address, operand_2);
 392                  }
 393                  if (show_instr_detail_level == 1)
 394                  {
 395                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 396                                  "Addr: %u ## AND (operand_1=%u, operand_2=%u)",
 397                                  current_address, operand_1, operand_2);
 398                  }
 399                  /* execute the instruction */
 400                  result = operand_1 & operand_2;
 401                  lsb = result & 0xff;
 402                  msb = result >> 8;
 403                  buff[result_dest] = msb;
 404                  buff[result_dest+1] = lsb;
 405                  if (print_level_1 ){
 406                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
 407                                  result, result_dest);
 408                  }
 409                  current_address = next_operand_address;
 410                  goto execute_next_instruction;
 411   
 412                  break;
 413   
 414          case SIGCOMP_INSTR_OR: /* 2 OR ($operand_1, %operand_2) */
 415                  used_udvm_cycles++;
 416                  if (show_instr_detail_level == 2 ){
 417                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 418                                  "Addr: %u ## OR(2) (operand_1, operand_2)",
 419                                  current_address);
 420                  }
 421                  /* $operand_1*/
 422                  operand_address = current_address + 1;
 423                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
 424                  if (show_instr_detail_level == 2 ){
 425                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
 426                                  operand_address, operand_1);
 427                  }
 428                  operand_address = next_operand_address;
 429                  /* %operand_2*/
 430                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
 431                  if (show_instr_detail_level == 2 ){
 432                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
 433                                  operand_address, operand_2);
 434                  }
 435                  if (show_instr_detail_level == 1)
 436                  {
 437                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 438                                  "Addr: %u ## OR (operand_1=%u, operand_2=%u)",
 439                                  current_address, operand_1, operand_2);
 440                  }
 441                  /* execute the instruction */
 442                  result = operand_1 | operand_2;
 443                  lsb = result & 0xff;
 444                  msb = result >> 8;
 445                  buff[result_dest] = msb;
 446                  buff[result_dest+1] = lsb;
 447                  if (print_level_1 ){
 448                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
 449                                  result, result_dest);
 450                  }
 451                  current_address = next_operand_address;
 452                  goto execute_next_instruction;
 453   
 454                  break;
 455   
 456          case SIGCOMP_INSTR_NOT: /* 3 NOT ($operand_1) */
 457                  used_udvm_cycles++;
 458                  if (show_instr_detail_level == 2 ){
 459                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 460                                  "Addr: %u ## NOT(3) ($operand_1)",
 461                                  current_address);
 462                  }
 463                  /* $operand_1*/
 464                  operand_address = current_address + 1;
 465                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
 466                  if (show_instr_detail_level == 2 ){
 467                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
 468                                  operand_address, operand_1);
 469                  }
 470                  if (show_instr_detail_level == 1)
 471                  {
 472                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 473                                  "Addr: %u ## NOT (operand_1=%u)",
 474                                  current_address, operand_1);
 475                  }
 476                  /* execute the instruction */
 477                  result = operand_1 ^ 0xffff;
 478                  lsb = result & 0xff;
 479                  msb = result >> 8;
 480                  buff[result_dest] = msb;
 481                  buff[result_dest+1] = lsb;
 482                  if (print_level_1 ){
 483                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
 484                                  result, result_dest);
 485                  }
 486                  current_address = next_operand_address;
 487                  goto execute_next_instruction;
 488                  break;
 489   
 490          case SIGCOMP_INSTR_LSHIFT: /* 4 LSHIFT ($operand_1, %operand_2) */
 491                  used_udvm_cycles++;
 492                  if (show_instr_detail_level == 2 ){
 493                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 494                                  "Addr: %u ## LSHIFT(4) ($operand_1, operand_2)",
 495                                  current_address);
 496                  }
 497                  /* $operand_1*/
 498                  operand_address = current_address + 1;
 499                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
 500                  if (show_instr_detail_level == 2 ){
 501                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
 502                                  operand_address, operand_1);
 503                  }
 504                  operand_address = next_operand_address;
 505                  /* %operand_2*/
 506                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
 507                  if (show_instr_detail_level == 2 ){
 508                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
 509                                  operand_address, operand_2);
 510                  }
 511                  if (show_instr_detail_level == 1)
 512                  {
 513                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 514                                  "Addr: %u ## LSHIFT (operand_1=%u, operand_2=%u)",
 515                                  current_address, operand_1, operand_2);
 516                  }
 517                  /* execute the instruction */
 518                  result = operand_1 << operand_2;
 519                  lsb = result & 0xff;
 520                  msb = result >> 8;
 521                  buff[result_dest] = msb;
 522                  buff[result_dest+1] = lsb;
 523                  if (print_level_1 ){
 524                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
 525                                  result, result_dest);
 526                  }
 527                  current_address = next_operand_address;
 528                  goto execute_next_instruction;
 529   
 530                  break;
 531          case SIGCOMP_INSTR_RSHIFT: /* 5 RSHIFT ($operand_1, %operand_2) */
 532                  used_udvm_cycles++;
 533                  if (show_instr_detail_level == 2 ){
 534                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 535                                  "Addr: %u ## RSHIFT(5) (operand_1, operand_2)",
 536                                  current_address);
 537                  }
 538                  /* $operand_1*/
 539                  operand_address = current_address + 1;
 540                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
 541                  if (show_instr_detail_level == 2 ){
 542                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
 543                                  operand_address, operand_1);
 544                  }
 545                  operand_address = next_operand_address;
 546                  /* %operand_2*/
 547                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
 548                  if (show_instr_detail_level == 2 ){
 549                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
 550                                  operand_address, operand_2);
 551                  }
 552                  if (show_instr_detail_level == 1)
 553                  {
 554                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 555                                  "Addr: %u ## RSHIFT (operand_1=%u, operand_2=%u)",
 556                                  current_address, operand_1, operand_2);
 557                  }
 558                  /* execute the instruction */
 559                  result = operand_1 >> operand_2;
 560                  lsb = result & 0xff;
 561                  msb = result >> 8;
 562                  buff[result_dest] = msb;
 563                  buff[result_dest+1] = lsb;
 564                  if (print_level_1 ){
 565                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
 566                                  result, result_dest);
 567                  }
 568                  current_address = next_operand_address;
 569                  goto execute_next_instruction;
 570                  break;
 571          case SIGCOMP_INSTR_ADD: /* 6 ADD ($operand_1, %operand_2) */
 572                  used_udvm_cycles++;
 573                  if (show_instr_detail_level == 2 ){
 574                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 575                                  "Addr: %u ## ADD(6) (operand_1, operand_2)",
 576                                  current_address);
 577                  }
 578                  /* $operand_1*/
 579                  operand_address = current_address + 1;
 580                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
 581                  if (show_instr_detail_level == 2 ){
 582                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
 583                                  operand_address, operand_1);
 584                  }
 585                  operand_address = next_operand_address;
 586                  /* %operand_2*/
 587                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
 588                  if (show_instr_detail_level == 2 ){
 589                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
 590                                  operand_address, operand_2);
 591                  }
 592                  if (show_instr_detail_level == 1)
 593                  {
 594                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 595                                  "Addr: %u ## ADD (operand_1=%u, operand_2=%u)",
 596                                  current_address, operand_1, operand_2);
 597                  }
 598                  /* execute the instruction */
 599                  result = operand_1 + operand_2;
 600                  lsb = result & 0xff;
 601                  msb = result >> 8;
 602                  buff[result_dest] = msb;
 603                  buff[result_dest+1] = lsb;
 604                  if (print_level_1 ){
 605                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"               Loading result %u at %u",
 606                                  result, result_dest);
 607                  }
 608                  current_address = next_operand_address;
 609                  goto execute_next_instruction;
 610   
 611          case SIGCOMP_INSTR_SUBTRACT: /* 7 SUBTRACT ($operand_1, %operand_2) */
 612                  used_udvm_cycles++;
 613                  if (show_instr_detail_level == 2 ){
 614                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 615                                  "Addr: %u ## SUBTRACT(7) (operand_1, operand_2)",
 616                                  current_address);
 617                  }
 618                  /* $operand_1*/
 619                  operand_address = current_address + 1;
 620                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
 621                  if (show_instr_detail_level == 2 ){
 622                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
 623                                  operand_address, operand_1);
 624                  }
 625                  operand_address = next_operand_address;
 626                  /* %operand_2*/
 627                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
 628                  if (show_instr_detail_level == 2 ){
 629                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
 630                                  operand_address, operand_2);
 631                  }
 632                  if (show_instr_detail_level == 1)
 633                  {
 634                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 635                                  "Addr: %u ## SUBTRACT (operand_1=%u, operand_2=%u)",
 636                                  current_address, operand_1, operand_2);
 637                  }
 638                  /* execute the instruction */
 639                  result = operand_1 - operand_2;
 640                  lsb = result & 0xff;
 641                  msb = result >> 8;
 642                  buff[result_dest] = msb;
 643                  buff[result_dest+1] = lsb;
 644                  if (print_level_1 ){
 645                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"               Loading result %u at %u",
 646                                  result, result_dest);
 647                  }
 648                  current_address = next_operand_address;
 649                  goto execute_next_instruction;
 650                  break;
 651   
 652          case SIGCOMP_INSTR_MULTIPLY: /* 8 MULTIPLY ($operand_1, %operand_2) */
 653                  used_udvm_cycles++;
 654                  if (show_instr_detail_level == 2 ){
 655                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 656                                  "Addr: %u ##MULTIPLY(8) (operand_1, operand_2)",
 657                                  current_address);
 658                  }
 659                  /* $operand_1*/
 660                  operand_address = current_address + 1;
 661                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
 662                  if (show_instr_detail_level == 2 ){
 663                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
 664                                  operand_address, operand_1);
 665                  }
 666                  operand_address = next_operand_address;
 667                  /* %operand_2*/
 668                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
 669                  if (show_instr_detail_level == 2 ){
 670                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
 671                                  operand_address, operand_2);
 672                  }
 673                  if (show_instr_detail_level == 1)
 674                  {
 675                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 676                                  "Addr: %u ## MULTIPLY (operand_1=%u, operand_2=%u)",
 677                                  current_address, operand_1, operand_2);
 678                  }
 679                  /*
 680                   * execute the instruction 
 681                   * MULTIPLY (m, n)  := m * n (modulo 2^16)
 682                   */
 683                  if ( operand_2 == 0){
 684                          result_code = 4;
 685                          goto decompression_failure;
 686                  }
 687                  result = operand_1 * operand_2;
 688                  lsb = result & 0xff;
 689                  msb = result >> 8;
 690                  buff[result_dest] = msb;
 691                  buff[result_dest+1] = lsb;
 692                  if (print_level_1 ){
 693                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
 694                                  result, result_dest);
 695                  }
 696                  current_address = next_operand_address;
 697                  goto execute_next_instruction;
 698                  break;
 699   
 700          case SIGCOMP_INSTR_DIVIDE: /* 9 DIVIDE ($operand_1, %operand_2) */
 701                  used_udvm_cycles++;
 702                  if (show_instr_detail_level == 2 ){
 703                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 704                                  "Addr: %u ## DIVIDE(9) (operand_1, operand_2)",
 705                                  current_address);
 706                  }
 707                  /* $operand_1*/
 708                  operand_address = current_address + 1;
 709                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
 710                  if (show_instr_detail_level == 2 ){
 711                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
 712                                  operand_address, operand_1);
 713                  }
 714                  operand_address = next_operand_address;
 715                  /* %operand_2*/
 716                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
 717                  if (show_instr_detail_level == 2 ){
 718                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
 719                                  operand_address, operand_2);
 720                  }
 721                  if (show_instr_detail_level == 1)
 722                  {
 723                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 724                                  "Addr: %u ## DIVIDE (operand_1=%u, operand_2=%u)",
 725                                  current_address, operand_1, operand_2);
 726                  }
 727                  /*
 728                   * execute the instruction 
 729                   * DIVIDE (m, n)    := floor(m / n)
 730                   * Decompression failure occurs if a DIVIDE or REMAINDER instruction 
 731                   * encounters an operand_2 that is zero.
 732                   */
 733                  if ( operand_2 == 0){
 734                          result_code = 4;
 735                          goto decompression_failure;
 736                  }
 737                  result = operand_1 / operand_2;
 738                  lsb = result & 0xff;
 739                  msb = result >> 8;
 740                  buff[result_dest] = msb;
 741                  buff[result_dest+1] = lsb;
 742                  if (print_level_1 ){
 743                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
 744                                  result, result_dest);
 745                  }
 746                  current_address = next_operand_address;
 747                  goto execute_next_instruction;
 748                  break;
 749   
 750          case SIGCOMP_INSTR_REMAINDER: /* 10 REMAINDER ($operand_1, %operand_2) */
 751                  used_udvm_cycles++;
 752                  if (show_instr_detail_level == 2 ){
 753                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 754                                  "Addr: %u ## REMAINDER(10) (operand_1, operand_2)",
 755                                  current_address);
 756                  }
 757                  /* $operand_1*/
 758                  operand_address = current_address + 1;
 759                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &operand_1, &result_dest);
 760                  if (show_instr_detail_level == 2 ){
 761                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_1 %u",
 762                                  operand_address, operand_1);
 763                  }
 764                  operand_address = next_operand_address;
 765                  /* %operand_2*/
 766                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &operand_2);
 767                  if (show_instr_detail_level == 2 ){
 768                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      operand_2 %u",
 769                                  operand_address, operand_2);
 770                  }
 771                  if (show_instr_detail_level == 1)
 772                  {
 773                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 774                                  "Addr: %u ## REMAINDER (operand_1=%u, operand_2=%u)",
 775                                  current_address, operand_1, operand_2);
 776                  }
 777                  /*
 778                   * execute the instruction 
 779                   * REMAINDER (m, n) := m - n * floor(m / n)
 780                   * Decompression failure occurs if a DIVIDE or REMAINDER instruction 
 781                   * encounters an operand_2 that is zero.
 782                   */
 783                  if ( operand_2 == 0){
 784                          result_code = 4;
 785                          goto decompression_failure;
 786                  }
 787                  result = operand_1 - operand_2 * (operand_1 / operand_2);
 788                  lsb = result & 0xff;
 789                  msb = result >> 8;
 790                  buff[result_dest] = msb;
 791                  buff[result_dest+1] = lsb;
 792                  if (print_level_1 ){
 793                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading result %u at %u",
 794                                  result, result_dest);
 795                  }
 796                  current_address = next_operand_address;
 797                  goto execute_next_instruction;
 798                  break;
 799          case SIGCOMP_INSTR_SORT_ASCENDING: /* 11 SORT-ASCENDING (%start, %n, %k) */
 800                  /*
 801                   *      used_udvm_cycles =  1 + k * (ceiling(log2(k)) + n)
 802                   */
 803                  if (print_level_1 ){
 804                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 805                                  "Addr: %u ## SORT-ASCENDING(11) (start, n, k))",
 806                                  current_address);
 807                  }
 808                  operand_address = current_address + 1;
 809                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Execution of this instruction is NOT implemented");
 810                  /*
 811                   *      used_udvm_cycles =  1 + k * (ceiling(log2(k)) + n)
 812                   */
 813                  break;
 814   
 815          case SIGCOMP_INSTR_SORT_DESCENDING: /* 12 SORT-DESCENDING (%start, %n, %k) */
 816                  if (print_level_1 ){
 817                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 818                                  "Addr: %u ## SORT-DESCENDING(12) (start, n, k))",
 819                                  current_address);
 820                  }
 821                  operand_address = current_address + 1;
 822                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Execution of this instruction is NOT implemented");
 823                  /*
 824                   *      used_udvm_cycles =  1 + k * (ceiling(log2(k)) + n)
 825                   */
 826                  break;
 827          case SIGCOMP_INSTR_SHA_1: /* 13 SHA-1 (%position, %length, %destination) */
 828                  if (print_level_1 ){
 829                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 830                                  "Addr: %u ## SHA-1(13) (position, length, destination)",
 831                                  current_address);
 832                  }
 833                  operand_address = current_address + 1;
 834                  /* %position */
 835                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
 836                  if (print_level_1 ){
 837                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      position %u",
 838                                  operand_address, position);
 839                  }
 840                  operand_address = next_operand_address;
 841   
 842                  /* %length */
 843                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
 844                  if (print_level_1 ){
 845                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
 846                                  operand_address, length);
 847                  }
 848                  operand_address = next_operand_address;
 849   
 850                  /* $destination */
 851                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &ref_destination, &result_dest);
 852                  if (print_level_1 ){
 853                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      $destination %u",
 854                                  operand_address, ref_destination);
 855                  }
 856                  current_address = next_operand_address;
 857                  used_udvm_cycles = used_udvm_cycles + 1 + length;
 858   
 859                  n = 0;
 860                  k = position;
 861                  byte_copy_right = buff[66] << 8;
 862                  byte_copy_right = byte_copy_right | buff[67];
 863                  byte_copy_left = buff[64] << 8;
 864                  byte_copy_left = byte_copy_left | buff[65];
 865   
 866                  if (print_level_2 ){
 867                          proto_tree_add_text(udvm_tree, message_tvb, 0, -1,
 868                                          "byte_copy_right = %u", byte_copy_right);
 869                  }
 870   
 871                  sha1_starts( &ctx );
 872   
 873                  while (n<length) {
 874                          guint16 handle_now = length;
 875   
 876                          if ( k < byte_copy_right && byte_copy_right <= k + (length-n) ){
 877                                  handle_now = byte_copy_right - position;
 878                          }
 879   
 880                          if (k + handle_now >= UDVM_MEMORY_SIZE)
 881                                  goto decompression_failure;
 882                          sha1_update( &ctx, &buff[k], handle_now );
 883   
 884                          k = ( k + handle_now ) & 0xffff;
 885                          n = ( n + handle_now ) & 0xffff;
 886   
 887                          if ( k >= byte_copy_right ) {
 888                                  k = byte_copy_left;
 889                          }
 890                  }
 891   
 892                  sha1_finish( &ctx, sha1_digest_buf );
 893   
 894                  k = ref_destination;
 895   
 896                  for ( n=0; n< STATE_BUFFER_SIZE; n++ ) {
 897   
 898                          buff[k] = sha1_digest_buf[n];
 899   
 900                          k = ( k + 1 ) & 0xffff;
 901                          n++;
 902   
 903                          if ( k == byte_copy_right ){
 904                                  k = byte_copy_left;
 905                          }
 906                  }
 907   
 908                  if (print_level_2 ){
 909                          proto_tree_add_text(udvm_tree, message_tvb, 0, -1,
 910                                          "Calculated SHA-1: %s",
 911                                          bytes_to_str(sha1_digest_buf, STATE_BUFFER_SIZE));
 912                  }
 913   
 914                  current_address = next_operand_address;
 915                  goto execute_next_instruction;
 916                  break;
 917   
 918          case SIGCOMP_INSTR_LOAD: /* 14 LOAD (%address, %value) */
 919                  if (show_instr_detail_level == 2 ){
 920                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 921                                  "Addr: %u ## LOAD(14) (%%address, %%value)",
 922                                  current_address);
 923                  }
 924                  operand_address = current_address + 1;
 925                  /* %address */
 926                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &address);
 927                  if (show_instr_detail_level == 2 ){
 928                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Address %u",
 929                                  operand_address, address);
 930                  }
 931                  operand_address = next_operand_address;
 932                  /* %value */
 933                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
 934                  if (show_instr_detail_level == 1)
 935                  {
 936                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 937                                  "Addr: %u ## LOAD (%%address=%u, %%value=%u)",
 938                                  current_address, address, value);
 939                  }
 940                  lsb = value & 0xff;
 941                  msb = value >> 8;
 942   
 943                  buff[address] = msb;
 944                  buff[address + 1] = lsb;
 945   
 946                  if (print_level_1 ){
 947                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
 948                                  operand_address, value);
 949                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"     Loading bytes at %u Value %u 0x%x",
 950                                          address, value, value);
 951                  }
 952                  used_udvm_cycles++;
 953                  current_address = next_operand_address;
 954                  goto execute_next_instruction;
 955                  break;
 956   
 957          case SIGCOMP_INSTR_MULTILOAD: /* 15 MULTILOAD (%address, #n, %value_0, ..., %value_n-1) */
 958                  /* RFC 3320:
 959                   * The MULTILOAD instruction sets a contiguous block of 2-byte words in
 960                   * the UDVM memory to specified values.
 961                   * Hmm what if the value to load only takes one byte ? Chose to always load two bytes.
 962                   */
 963                  if (show_instr_detail_level == 2 ){
 964                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 965                                  "Addr: %u ## MULTILOAD(15) (%%address, #n, value_0, ..., value_n-1)",
 966                                  current_address);
 967                  }
 968                  operand_address = current_address + 1;
 969                  /* %address */
 970                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &address);
 971                  if (show_instr_detail_level == 2 ){
 972                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Address %u",
 973                                  operand_address, address);
 974                  }
 975                  operand_address = next_operand_address;
 976   
 977                  /* #n */
 978                  next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
 979                  if (show_instr_detail_level == 2 ){
 980                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      n %u",
 981                                  operand_address, n);
 982                  }
 983                  if (show_instr_detail_level == 1)
 984                  {
 985                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 986                                  "Addr: %u ## MULTILOAD (%%address=%u, #n=%u, value_0, ..., value_%d)",
 987                                  current_address, address, n, n-1);
 988                  }
 989                  operand_address = next_operand_address;
 990                  used_udvm_cycles = used_udvm_cycles + 1 + n;
 991                  while ( n > 0) {
 992                          n = n - 1;
 993                          /* %value */
 994                          next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
 995                          lsb = value & 0xff;
 996                          msb = value >> 8;
 997   
 998                          if (address >= UDVM_MEMORY_SIZE - 1)
 999                                  goto decompression_failure;
 1000   
 1001                          buff[address] = msb;
 1002                          buff[address + 1] = lsb;
 1003                          /* debug 
 1004                          */
 1005                          length = next_operand_address - operand_address;
 1006   
 1007                          if (print_level_1 ){
 1008                                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1, "Addr: %u      Value %5u      - Loading bytes at %5u Value %5u 0x%x",
 1009                                  operand_address, value, address, value, value);
 1010                          }
 1011                          address = address + 2;
 1012                          operand_address = next_operand_address;
 1013                  }
 1014                  current_address = next_operand_address;
 1015                  goto execute_next_instruction;
 1016   
 1017                  break;
 1018   
 1019          case SIGCOMP_INSTR_PUSH: /* 16 PUSH (%value) */
 1020                  if (show_instr_detail_level == 2){
 1021                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1022                                  "Addr: %u ## PUSH(16) (value)",
 1023                                  current_address);
 1024                  }
 1025                  operand_address = current_address + 1;
 1026                  /* %value */
 1027                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
 1028                  if (show_instr_detail_level == 2){
 1029                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
 1030                                  operand_address, value);
 1031                  }
 1032                  if (show_instr_detail_level == 1)
 1033                  {
 1034                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1035                                  "Addr: %u ## PUSH (value=%u)",
 1036                                  current_address, value);
 1037                  }
 1038                  current_address = next_operand_address;
 1039   
 1040                  /* Push the value address onto the stack */
 1041                  stack_location = (buff[70] << 8) | buff[71];
 1042                  stack_fill = (buff[stack_location] << 8)
 1043                             | buff[(stack_location+1) & 0xFFFF];
 1044                  address = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
 1045   
 1046                  if (address >= UDVM_MEMORY_SIZE - 1)
 1047                          goto decompression_failure;
 1048   
 1049                  buff[address] = (value >> 8) & 0x00FF;
 1050                  buff[(address+1) & 0xFFFF] = value & 0x00FF;
 1051   
 1052                  if (stack_location >= UDVM_MEMORY_SIZE - 1)
 1053                          goto decompression_failure;
 1054   
 1055                  stack_fill = (stack_fill + 1) & 0xFFFF;
 1056                  buff[stack_location] = (stack_fill >> 8) & 0x00FF;
 1057                  buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
 1058   
 1059                  used_udvm_cycles++;
 1060                  goto execute_next_instruction;
 1061   
 1062                  break;
 1063   
 1064          case SIGCOMP_INSTR_POP: /* 17 POP (%address) */
 1065                  if (show_instr_detail_level == 2){
 1066                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1067                                  "Addr: %u ## POP(16) (value)",
 1068                                  current_address);
 1069                  }
 1070                  operand_address = current_address + 1;
 1071                  /* %value */
 1072                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
 1073                  if (show_instr_detail_level == 2){
 1074                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
 1075                                  operand_address, destination);
 1076                  }
 1077                  if (show_instr_detail_level == 1)
 1078                  {
 1079                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1080                                  "Addr: %u ## POP (address=%u)",
 1081                                  current_address, destination);
 1082                  }
 1083                  current_address = next_operand_address;
 1084   
 1085                  /* Pop value from the top of the stack */
 1086                  stack_location = (buff[70] << 8) | buff[71];
 1087                  stack_fill = (buff[stack_location] << 8)
 1088                             | buff[(stack_location+1) & 0xFFFF];
 1089                  if (stack_fill == 0)
 1090                  {
 1091                      result_code = 16;
 1092                      goto decompression_failure;
 1093                  }
 1094   
 1095                  if (stack_location >= UDVM_MEMORY_SIZE - 1)
 1096                          goto decompression_failure;
 1097   
 1098                  stack_fill = (stack_fill - 1) & 0xFFFF;
 1099                  buff[stack_location] = (stack_fill >> 8) & 0x00FF;
 1100                  buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
 1101   
 1102                  address = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
 1103   
 1104                  if (address >= UDVM_MEMORY_SIZE - 1)
 1105                          goto decompression_failure;
 1106   
 1107                  value = (buff[address] << 8)
 1108                             | buff[(address+1) & 0xFFFF];
 1109   
 1110                  /* ... and store the popped value. */
 1111                  if (destination >= UDVM_MEMORY_SIZE - 1)
 1112                          goto decompression_failure;
 1113                  buff[destination] = (value >> 8) & 0x00FF;
 1114                  buff[(destination+1) & 0xFFFF] = value & 0x00FF;
 1115   
 1116                  used_udvm_cycles++;
 1117                  goto execute_next_instruction;
 1118   
 1119                  break;
 1120   
 1121          case SIGCOMP_INSTR_COPY: /* 18 COPY (%position, %length, %destination) */
 1122                  if (show_instr_detail_level == 2 ){
 1123                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1124                                  "Addr: %u ## COPY(18) (position, length, destination)",
 1125                                  current_address);
 1126                  }
 1127                  operand_address = current_address + 1;
 1128                  /* %position */
 1129                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
 1130                  if (show_instr_detail_level == 2 ){
 1131                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      position %u",
 1132                                  operand_address, position);
 1133                  }
 1134                  operand_address = next_operand_address;
 1135   
 1136                  /* %length */
 1137                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
 1138                  if (show_instr_detail_level == 2 ){
 1139                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
 1140                                  operand_address, length);
 1141                  }
 1142                  operand_address = next_operand_address;
 1143   
 1144                  /* %destination */
 1145                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
 1146                  if (show_instr_detail_level == 2 ){
 1147                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Destination %u",
 1148                                  operand_address, destination);
 1149                  }
 1150                  if (show_instr_detail_level == 1)
 1151                  {
 1152                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1153                                  "Addr: %u ## COPY (position=%u, length=%u, destination=%u)",
 1154                                  current_address, position, length, destination);
 1155                  }
 1156                  current_address = next_operand_address;
 1157                  /*
 1158                   * 8.4.  Byte copying 
 1159                   * :
 1160                   * The string of bytes is copied in ascending order of memory address,
 1161                   * respecting the bounds set by byte_copy_left and byte_copy_right.
 1162                   * More precisely, if a byte is copied from/to Address m then the next 
 1163                   * byte is copied from/to Address n where n is calculated as follows:
 1164                   *
 1165                   * Set k := m + 1 (modulo 2^16)
 1166                   * If k = byte_copy_right then set n := byte_copy_left, else set n := k 
 1167                   *
 1168                   */
 1169   
 1170                  n = 0;
 1171                  k = destination;
 1172                  byte_copy_right = buff[66] << 8;
 1173                  byte_copy_right = byte_copy_right | buff[67];
 1174                  byte_copy_left = buff[64] << 8;
 1175                  byte_copy_left = byte_copy_left | buff[65];
 1176                  if (print_level_2 ){
 1177                          proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 1178                                                  "               byte_copy_right = %u", byte_copy_right);
 1179                  }
 1180   
 1181                  while ( n < length ){
 1182                          buff[k] = buff[position];
 1183                          if (print_level_2 ){
 1184                                  proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 1185                                          "               Copying value: %u (0x%x) to Addr: %u",
 1186                                          buff[position], buff[position], k);
 1187                          }
 1188                          position = ( position + 1 ) & 0xffff;
 1189                          k = ( k + 1 ) & 0xffff;
 1190                          n++;
 1191   
 1192                          /*
 1193                           * Check for circular buffer wrapping after the positions are 
 1194                           * incremented. If either started at BCR then they should continue 
 1195                           * to increment beyond BCR.
 1196                           */
 1197                          if ( k == byte_copy_right ){
 1198                                  k = byte_copy_left;
 1199                          }
 1200                          if ( position == byte_copy_right ){
 1201                                  position = byte_copy_left;
 1202                          }
 1203                  }
 1204                  used_udvm_cycles = used_udvm_cycles + 1 + length;
 1205                  goto execute_next_instruction;
 1206                  break;
 1207   
 1208          case SIGCOMP_INSTR_COPY_LITERAL: /* 19 COPY-LITERAL (%position, %length, $destination) */
 1209                  if (show_instr_detail_level == 2 ){
 1210                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1211                                  "Addr: %u ## COPY-LITERAL(19) (position, length, $destination)",
 1212                                  current_address);
 1213                  }
 1214                  operand_address = current_address + 1;
 1215                  /* %position */
 1216                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
 1217                  if (show_instr_detail_level == 2 ){
 1218                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      position %u",
 1219                                  operand_address, position);
 1220                  }
 1221                  operand_address = next_operand_address;
 1222   
 1223                  /* %length */
 1224                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
 1225                  if (show_instr_detail_level == 2 ){
 1226                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
 1227                                  operand_address, length);
 1228                  }
 1229                  operand_address = next_operand_address;
 1230   
 1231   
 1232                  /* $destination */
 1233                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &ref_destination, &result_dest);
 1234                  if (show_instr_detail_level == 2 ){
 1235                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      destination %u",
 1236                                  operand_address, ref_destination);
 1237                  }
 1238                  if (show_instr_detail_level == 1)
 1239                  {
 1240                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1241                                  "Addr: %u ## COPY-LITERAL (position=%u, length=%u, $destination=%u)",
 1242                                  current_address, position, length, destination);
 1243                  }
 1244                  current_address = next_operand_address;
 1245   
 1246   
 1247                  /*
 1248                   * 8.4.  Byte copying 
 1249                   * :
 1250                   * The string of bytes is copied in ascending order of memory address,
 1251                   * respecting the bounds set by byte_copy_left and byte_copy_right.
 1252                   * More precisely, if a byte is copied from/to Address m then the next 
 1253                   * byte is copied from/to Address n where n is calculated as follows:
 1254                   *
 1255                   * Set k := m + 1 (modulo 2^16)
 1256                   * If k = byte_copy_right then set n := byte_copy_left, else set n := k 
 1257                   *
 1258                   */
 1259   
 1260                  n = 0;
 1261                  k = ref_destination;
 1262                  byte_copy_right = buff[66] << 8;
 1263                  byte_copy_right = byte_copy_right | buff[67];
 1264                  byte_copy_left = buff[64] << 8;
 1265                  byte_copy_left = byte_copy_left | buff[65];
 1266                  if (print_level_2 ){
 1267                          proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 1268                                          "               byte_copy_right = %u", byte_copy_right);
 1269                  }
 1270                  while ( n < length ){
 1271   
 1272                          buff[k] = buff[position];
 1273                          if (print_level_2 ){
 1274                                  proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 1275                                          "               Copying value: %u (0x%x) to Addr: %u",
 1276                                          buff[position], buff[position], k);
 1277                          }
 1278                          position = ( position + 1 ) & 0xffff;
 1279                          k = ( k + 1 ) & 0xffff;
 1280                          n++;
 1281   
 1282                          /*
 1283                           * Check for circular buffer wrapping after the positions are 
 1284                           * incremented. It is important that k cannot be left set 
 1285                           * to BCR. Also, if either started at BCR then they should continue 
 1286                           * to increment beyond BCR.
 1287                           */
 1288                          if ( k == byte_copy_right ){
 1289                                  k = byte_copy_left;
 1290                          }
 1291                          if ( position == byte_copy_right ){
 1292                                  position = byte_copy_left;
 1293                          }
 1294                  }
 1295                  buff[result_dest] = k >> 8;
 1296                  buff[result_dest + 1] = k & 0x00ff;
 1297   
 1298                  used_udvm_cycles = used_udvm_cycles + 1 + length;
 1299                  goto execute_next_instruction;
 1300                  break;
 1301   
 1302          case SIGCOMP_INSTR_COPY_OFFSET: /* 20 COPY-OFFSET (%offset, %length, $destination) */
 1303                  if (show_instr_detail_level == 2 ){
 1304                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1305                                  "Addr: %u ## COPY-OFFSET(20) (offset, length, $destination)",
 1306                                  current_address);
 1307                  }
 1308                  operand_address = current_address + 1;
 1309                  /* %offset */
 1310                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &multy_offset);
 1311                  if (show_instr_detail_level == 2 ){
 1312                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      offset %u",
 1313                                  operand_address, multy_offset);
 1314                  }
 1315                  operand_address = next_operand_address;
 1316   
 1317                  /* %length */
 1318                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
 1319                  if (show_instr_detail_level == 2 ){
 1320                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
 1321                                  operand_address, length);
 1322                  }
 1323                  operand_address = next_operand_address;
 1324   
 1325   
 1326                  /* $destination */
 1327                  next_operand_address = dissect_udvm_reference_operand(buff, operand_address, &ref_destination, &result_dest);
 1328                  if (show_instr_detail_level == 2 ){
 1329                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      $destination %u",
 1330                                  operand_address, ref_destination);
 1331                  }
 1332   
 1333                  if (show_instr_detail_level == 1)
 1334                  {
 1335                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1336                                  "Addr: %u ## COPY-OFFSET (offset=%u, length=%u, $destination=%u)",
 1337                                  current_address, multy_offset, length, result_dest);
 1338                  }
 1339                  current_address = next_operand_address;
 1340   
 1341                  /* Execute the instruction:
 1342                   * To derive the value of the position operand, starting at the memory
 1343                   * address specified by destination, the UDVM counts backwards a total
 1344                   * of offset memory addresses.
 1345                   *
 1346                   * If the memory address specified in byte_copy_left is reached, the 
 1347                   * next memory address is taken to be (byte_copy_right - 1) modulo 2^16.
 1348                   */
 1349                  byte_copy_left = buff[64] << 8;
 1350                  byte_copy_left = byte_copy_left | buff[65];
 1351                  byte_copy_right = buff[66] << 8;
 1352                  byte_copy_right = byte_copy_right | buff[67];
 1353   
 1354                  /*
 1355                   * In order to work out the position, simple arithmetic is tricky
 1356                   * to apply because there some nasty corner cases. A simple loop 
 1357                   * is inefficient but the logic is simple.
 1358                   *
 1359                   * FUTURE: This could be optimised.
 1360                   */
 1361                  for (position = ref_destination, i = 0; i < multy_offset; i++)
 1362                  {
 1363                          if ( position == byte_copy_left )
 1364                          {
 1365                                  position = (byte_copy_right - 1) & 0xffff;
 1366                          }
 1367                          else 
 1368                          {
 1369                                  position = (position - 1) & 0xffff;
 1370                          }
 1371                  }
 1372   
 1373                  if (print_level_2 ){
 1374                          proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 1375                                          "               byte_copy_left = %u byte_copy_right = %u position= %u",
 1376                                          byte_copy_left, byte_copy_right, position);
 1377                          }
 1378                  /* The COPY-OFFSET instruction then behaves as a COPY-LITERAL
 1379                   * instruction, taking the value of the position operand to be the last 
 1380                   * memory address reached in the above step.
 1381                   */
 1382   
 1383                  /*
 1384                   * 8.4.  Byte copying 
 1385                   * :
 1386                   * The string of bytes is copied in ascending order of memory address,
 1387                   * respecting the bounds set by byte_copy_left and byte_copy_right.
 1388                   * More precisely, if a byte is copied from/to Address m then the next 
 1389                   * byte is copied from/to Address n where n is calculated as follows:
 1390                   *
 1391                   * Set k := m + 1 (modulo 2^16)
 1392                   * If k = byte_copy_right then set n := byte_copy_left, else set n := k 
 1393                   *
 1394                   */
 1395   
 1396                  n = 0;
 1397                  k = ref_destination;
 1398                  if (print_level_2 ){
 1399                          proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 1400                                          "               byte_copy_left = %u byte_copy_right = %u", byte_copy_left, byte_copy_right);
 1401                  }
 1402                  while ( n < length ){
 1403                          buff[k] = buff[position];
 1404                          if (print_level_2 ){
 1405                                  proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 1406                                          "               Copying value: %5u (0x%x) from Addr: %u to Addr: %u",
 1407                                          buff[position], buff[position],(position), k);
 1408                          }
 1409                          n++;
 1410                          k = ( k + 1 ) & 0xffff;
 1411                          position = ( position + 1 ) & 0xffff;
 1412   
 1413                          /*
 1414                           * Check for circular buffer wrapping after the positions are 
 1415                           * incremented. It is important that k cannot be left set 
 1416                           * to BCR. Also, if either started at BCR then they should continue 
 1417                           * to increment beyond BCR.
 1418                           */
 1419                          if ( k == byte_copy_right ){
 1420                                  k = byte_copy_left;
 1421                          }
 1422                          if ( position == byte_copy_right ){
 1423                                  position = byte_copy_left;
 1424                          }
 1425                  }
 1426                  buff[result_dest] = k >> 8;
 1427                  buff[result_dest + 1] = k & 0x00ff;
 1428                  used_udvm_cycles = used_udvm_cycles + 1 + length;
 1429                  goto execute_next_instruction;
 1430   
 1431                  break;
 1432          case SIGCOMP_INSTR_MEMSET: /* 21 MEMSET (%address, %length, %start_value, %offset) */
 1433                  if (show_instr_detail_level == 2 ){
 1434                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1435                                  "Addr: %u ## MEMSET(21) (address, length, start_value, offset)",
 1436                                  current_address);
 1437                  }
 1438                  operand_address = current_address + 1;
 1439   
 1440                  /* %address */
 1441                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &address);
 1442                  if (show_instr_detail_level == 2 ){
 1443                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Address %u",
 1444                                  operand_address, address);
 1445                  }
 1446                  operand_address = next_operand_address;
 1447   
 1448                  /*  %length, */
 1449                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
 1450                  if (show_instr_detail_level == 2 ){
 1451                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
 1452                                  operand_address, length);
 1453                  }
 1454                  operand_address = next_operand_address;
 1455                  /* %start_value */
 1456                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &start_value);
 1457                  if (show_instr_detail_level == 2 ){
 1458                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      start_value %u",
 1459                                  operand_address, start_value);
 1460                  }
 1461                  operand_address = next_operand_address;
 1462   
 1463                  /* %offset */
 1464                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &multy_offset);
 1465                  if (show_instr_detail_level == 2 ){
 1466                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      offset %u",
 1467                                  operand_address, multy_offset);
 1468                  }
 1469                  if (show_instr_detail_level == 1)
 1470                  {
 1471                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1472                                  "Addr: %u ## MEMSET (address=%u, length=%u, start_value=%u, offset=%u)",
 1473                                  current_address, address, length, start_value, multy_offset);
 1474                  }
 1475                  current_address = next_operand_address;
 1476                  /* exetute the instruction 
 1477                   * The sequence of values used by the MEMSET instruction is specified by
 1478                   * the following formula:
 1479                   *
 1480                   * Seq[n] := (start_value + n * offset) modulo 256
 1481                   */
 1482                  n = 0;
 1483                  k = address;
 1484                  byte_copy_right = buff[66] << 8;
 1485                  byte_copy_right = byte_copy_right | buff[67];
 1486                  byte_copy_left = buff[64] << 8;
 1487                  byte_copy_left = byte_copy_left | buff[65];
 1488                  if (print_level_2 ){
 1489                          proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 1490                                          "               byte_copy_left = %u byte_copy_right = %u", byte_copy_left, byte_copy_right);
 1491                  }
 1492                  while ( n < length ){
 1493                          if ( k == byte_copy_right ){
 1494                                  k = byte_copy_left;
 1495                          }
 1496                          buff[k] = (start_value + ( n * multy_offset)) & 0xff;
 1497                          if (print_level_2 ){
 1498                                  proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 1499                                          "     Storing value: %u (0x%x) at Addr: %u",
 1500                                          buff[k], buff[k], k);
 1501                          }
 1502                          k = ( k + 1 ) & 0xffff;
 1503                          n++;
 1504                  }/* end while */
 1505                  used_udvm_cycles = used_udvm_cycles + 1 + length;
 1506                  goto execute_next_instruction;
 1507                  break;
 1508   
 1509   
 1510          case SIGCOMP_INSTR_JUMP: /* 22 JUMP (@address) */
 1511                  if (show_instr_detail_level == 2 ){
 1512                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1513                                  "Addr: %u ## JUMP(22) (@address)",
 1514                                  current_address);
 1515                  }
 1516                  operand_address = current_address + 1;
 1517                  /* @address */
 1518                   /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
 1519                  next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
 1520                  if (show_instr_detail_level == 2 ){
 1521                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
 1522                                  operand_address, at_address);
 1523                  }
 1524                  if (show_instr_detail_level == 1)
 1525                  {
 1526                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1527                                  "Addr: %u ## JUMP (@address=%u)",
 1528                                  current_address, at_address);
 1529                  }
 1530                  current_address = at_address;
 1531                  used_udvm_cycles++;
 1532                  goto execute_next_instruction;
 1533                  break;
 1534   
 1535          case SIGCOMP_INSTR_COMPARE: /* 23 */
 1536                  /* COMPARE (%value_1, %value_2, @address_1, @address_2, @address_3)
 1537                   */
 1538                  if (show_instr_detail_level == 2 ){
 1539                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1540                                  "Addr: %u ## COMPARE(23) (value_1, value_2, @address_1, @address_2, @address_3)",
 1541                                  current_address);
 1542                  }
 1543                  operand_address = current_address + 1;
 1544   
 1545                  /* %value_1 */
 1546                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value_1);
 1547                  if (show_instr_detail_level == 2 ){
 1548                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
 1549                                          operand_address, value_1);
 1550                  }
 1551                  operand_address = next_operand_address;
 1552   
 1553                  /* %value_2 */
 1554                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value_2);
 1555                  if (show_instr_detail_level == 2 ){
 1556                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
 1557                                          operand_address, value_2);
 1558                  }
 1559                  operand_address = next_operand_address;
 1560   
 1561                  /* @address_1 */
 1562                   /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
 1563                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_1);
 1564                  at_address_1 = ( current_address + at_address_1) & 0xffff;
 1565                  if (show_instr_detail_level == 2 ){
 1566                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
 1567                                  operand_address, at_address_1);
 1568                  }
 1569                  operand_address = next_operand_address;
 1570   
 1571   
 1572                  /* @address_2 */
 1573                   /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
 1574                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_2);
 1575                  at_address_2 = ( current_address + at_address_2) & 0xffff;
 1576                  if (show_instr_detail_level == 2 ){
 1577                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
 1578                                  operand_address, at_address_2);
 1579                  }
 1580                  operand_address = next_operand_address;
 1581   
 1582                  /* @address_3 */
 1583                   /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
 1584                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_3);
 1585                  at_address_3 = ( current_address + at_address_3) & 0xffff;
 1586                  if (show_instr_detail_level == 2 ){
 1587                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
 1588                                  operand_address, at_address_3);
 1589                  }
 1590                  if (show_instr_detail_level == 1)
 1591                  {
 1592                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1593                                  "Addr: %u ## COMPARE (value_1=%u, value_2=%u, @address_1=%u, @address_2=%u, @address_3=%u)",
 1594                                  current_address, value_1, value_2, at_address_1, at_address_2, at_address_3);
 1595                  }
 1596                  /* execute the instruction 
 1597                   * If value_1 < value_2 then the UDVM continues instruction execution at
 1598                   * the memory address specified by address 1. If value_1 = value_2 then
 1599                   * it jumps to the address specified by address_2. If value_1 > value_2 
 1600                   * then it jumps to the address specified by address_3.
 1601                   */
 1602                  if ( value_1 < value_2 )
 1603                          current_address = at_address_1;
 1604                  if ( value_1 == value_2 )
 1605                          current_address = at_address_2;
 1606                  if ( value_1 > value_2 )
 1607                          current_address = at_address_3;
 1608                  used_udvm_cycles++;
 1609                  goto execute_next_instruction;
 1610                  break;
 1611   
 1612          case SIGCOMP_INSTR_CALL: /* 24 CALL (@address) (PUSH addr )*/
 1613                  if (show_instr_detail_level == 2){
 1614                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1615                                  "Addr: %u ## CALL(24) (@address) (PUSH addr )",
 1616                                  current_address);
 1617                  }
 1618                  operand_address = current_address + 1;
 1619                  /* @address */
 1620                  next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
 1621                  if (show_instr_detail_level == 2 ){
 1622                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
 1623                                  operand_address, at_address);
 1624                  }
 1625                  if (show_instr_detail_level == 1)
 1626                  {
 1627                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1628                                  "Addr: %u ## CALL (@address=%u)",
 1629                                  current_address, at_address);
 1630                  }
 1631                  current_address = next_operand_address;
 1632   
 1633                  /* Push the current address onto the stack */
 1634                  stack_location = (buff[70] << 8) | buff[71];
 1635                  stack_fill = (buff[stack_location] << 8)
 1636                             | buff[(stack_location+1) & 0xFFFF];
 1637                  address = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
 1638                  if (address >= UDVM_MEMORY_SIZE - 1)
 1639                          goto decompression_failure;
 1640                  buff[address] = (current_address >> 8) & 0x00FF;
 1641                  buff[(address+1) & 0xFFFF] = current_address & 0x00FF;
 1642   
 1643                  stack_fill = (stack_fill + 1) & 0xFFFF;
 1644                  if (stack_location >= UDVM_MEMORY_SIZE - 1)
 1645                          goto decompression_failure;
 1646                  buff[stack_location] = (stack_fill >> 8) & 0x00FF;
 1647                  buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
 1648   
 1649                  /* ... and jump to the destination address */
 1650                  current_address = at_address;
 1651   
 1652                  used_udvm_cycles++;
 1653                  goto execute_next_instruction;
 1654   
 1655                  break;
 1656   
 1657          case SIGCOMP_INSTR_RETURN: /* 25 POP and return */
 1658                  if (print_level_1 || show_instr_detail_level == 1){
 1659                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1660                                  "Addr: %u ## POP(25) and return",
 1661                                  current_address);
 1662                  }
 1663   
 1664                  /* Pop value from the top of the stack */
 1665                  stack_location = (buff[70] << 8) | buff[71];
 1666                  stack_fill = (buff[stack_location] << 8)
 1667                             | buff[(stack_location+1) & 0xFFFF];
 1668                  if (stack_fill == 0)
 1669                  {
 1670                      result_code = 16;
 1671                      goto decompression_failure;
 1672                  }
 1673   
 1674                  stack_fill = (stack_fill - 1) & 0xFFFF;
 1675                  if (stack_location >= UDVM_MEMORY_SIZE - 1)
 1676                          goto decompression_failure;
 1677                  buff[stack_location] = (stack_fill >> 8) & 0x00FF;
 1678                  buff[(stack_location+1) & 0xFFFF] = stack_fill & 0x00FF;
 1679   
 1680                  address = (stack_location + stack_fill * 2 + 2) & 0xFFFF;
 1681                  at_address = (buff[address] << 8)
 1682                             | buff[(address+1) & 0xFFFF];
 1683   
 1684                  /* ... and set the PC to the popped value */
 1685                  current_address = at_address;
 1686   
 1687                  used_udvm_cycles++;
 1688                  goto execute_next_instruction;
 1689   
 1690                  break;
 1691   
 1692          case SIGCOMP_INSTR_SWITCH: /* 26 SWITCH (#n, %j, @address_0, @address_1, ... , @address_n-1) */
 1693                  /*
 1694                   * When a SWITCH instruction is encountered the UDVM reads the value of
 1695                   * j. It then continues instruction execution at the address specified 
 1696                   * by address j.
 1697                   *
 1698                   * Decompression failure occurs if j specifies a value of n or more, or 
 1699                   * if the address lies beyond the overall UDVM memory size.
 1700                   */
 1701                  instruction_address = current_address;
 1702                  if (print_level_1 ){
 1703                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1704                                  "Addr: %u ## SWITCH (#n, j, @address_0, @address_1, ... , @address_n-1))",
 1705                                  current_address);
 1706                  }
 1707                  operand_address = current_address + 1;
 1708                  /* #n
 1709                   * Number of addresses in the instruction
 1710                   */
 1711                  next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
 1712                  if (print_level_1 ){
 1713                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      n %u",
 1714                                  operand_address, n);
 1715                  }
 1716                  operand_address = next_operand_address;
 1717                  /* %j */
 1718                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &j);
 1719                  if (print_level_1 ){
 1720                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      j %u",
 1721                                          operand_address, j);
 1722                  }
 1723                  operand_address = next_operand_address;
 1724                  m = 0;
 1725                  while ( m < n ){
 1726                          /* @address_n-1 */
 1727                          /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
 1728                          next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address_1);
 1729                          at_address_1 = ( instruction_address + at_address_1) & 0xffff;
 1730                          if (print_level_1 ){
 1731                                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
 1732                                          operand_address, at_address_1);
 1733                          }
 1734                          if ( j == m ){
 1735                                  current_address = at_address_1;
 1736                          }
 1737                          operand_address = next_operand_address;
 1738                          m++;
 1739                  }
 1740                  /* Check decompression failure */
 1741                  if ( ( j == n ) || ( j > n )){
 1742                          result_code = 5;
 1743                          goto decompression_failure;
 1744                  }
 1745                  if ( current_address > UDVM_MEMORY_SIZE ){
 1746                          result_code = 6;
 1747                          goto decompression_failure;
 1748                  }
 1749                  used_udvm_cycles = used_udvm_cycles + 1 + n;
 1750   
 1751                  goto execute_next_instruction;
 1752   
 1753                  break;
 1754          case SIGCOMP_INSTR_CRC: /* 27 CRC (%value, %position, %length, @address) */
 1755                  if (print_level_1 ){
 1756                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1757                                  "Addr: %u ## CRC (value, position, length, @address)",
 1758                                  current_address);
 1759                  }
 1760   
 1761                  operand_address = current_address + 1;
 1762   
 1763                  /* %value */
 1764                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &value);
 1765                  if (print_level_1 ){
 1766                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Value %u",
 1767                                  operand_address, value);
 1768                  }
 1769                  operand_address = next_operand_address;
 1770   
 1771                  /* %position */
 1772                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &position);
 1773                  if (print_level_1 ){
 1774                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      position %u",
 1775                                  operand_address, position);
 1776                  }
 1777                  operand_address = next_operand_address;
 1778   
 1779                  /* %length */
 1780                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
 1781                  if (print_level_1 ){
 1782                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
 1783                                  operand_address, length);
 1784                  }
 1785                  operand_address = next_operand_address;
 1786   
 1787                  /* @address */
 1788                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address);
 1789                  at_address = ( current_address + at_address) & 0xffff;
 1790                  if (print_level_1 ){
 1791                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
 1792                                  operand_address, at_address);
 1793                  }
 1794                   /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
 1795                  used_udvm_cycles = used_udvm_cycles + 1 + length;
 1796   
 1797                  n = 0;
 1798                  k = position;
 1799                  byte_copy_right = buff[66] << 8;
 1800                  byte_copy_right = byte_copy_right | buff[67];
 1801                  byte_copy_left = buff[64] << 8;
 1802                  byte_copy_left = byte_copy_left | buff[65];
 1803                  result = 0;
 1804   
 1805                  if (print_level_2 ){
 1806                          proto_tree_add_text(udvm_tree, message_tvb, 0, -1,
 1807                                          "byte_copy_right = %u", byte_copy_right);
 1808                  }
 1809   
 1810                  while (n<length) {
 1811   
 1812                          guint16 handle_now = length - n;
 1813   
 1814                          if ( k < byte_copy_right && byte_copy_right <= k + (length-n) ){
 1815                                  handle_now = byte_copy_right - k;
 1816                          }
 1817   
 1818                          if (k + handle_now >= UDVM_MEMORY_SIZE)
 1819                                  goto decompression_failure;
 1820                          result = crc16_ccitt_seed(&buff[k], handle_now, (guint16) (result ^ 0xffff));
 1821   
 1822                          k = ( k + handle_now ) & 0xffff;
 1823                          n = ( n + handle_now ) & 0xffff;
 1824   
 1825                          if ( k >= byte_copy_right ) {
 1826                                  k = byte_copy_left;
 1827                          }
 1828                  }
 1829   
 1830                  result = result ^ 0xffff;
 1831   
 1832                  if (print_level_1 ){
 1833                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1, "Calculated CRC %u", result);
 1834                  }
 1835                  if (result != value){
 1836                          current_address = at_address;
 1837                  }
 1838                  else {
 1839                          current_address = next_operand_address;
 1840                  }
 1841                  goto execute_next_instruction;
 1842                  break;
 1843   
 1844   
 1845          case SIGCOMP_INSTR_INPUT_BYTES: /* 28 INPUT-BYTES (%length, %destination, @address) */
 1846                  if (show_instr_detail_level == 2 ){
 1847                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1848                                  "Addr: %u ## INPUT-BYTES(28) length, destination, @address)",
 1849                                  current_address);
 1850                  }
 1851                  operand_address = current_address + 1;
 1852                  /* %length */
 1853                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
 1854                  if (show_instr_detail_level == 2 ){
 1855                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Length %u",
 1856                                  operand_address, length);
 1857                  }
 1858                  operand_address = next_operand_address;
 1859   
 1860                  /* %destination */
 1861                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
 1862                  if (show_instr_detail_level == 2 ){
 1863                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Destination %u",
 1864                                  operand_address, destination);
 1865                  }
 1866                  operand_address = next_operand_address;
 1867   
 1868                  /* @address */
 1869                   /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
 1870                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &at_address);
 1871                  at_address = ( current_address + at_address) & 0xffff;
 1872                  if (show_instr_detail_level == 2 ){
 1873                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
 1874                                  operand_address, at_address);
 1875                  }
 1876                  if (show_instr_detail_level == 1)
 1877                  {
 1878                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1879                                  "Addr: %u ## INPUT-BYTES length=%u, destination=%u, @address=%u)",
 1880                                  current_address, length, destination, at_address);
 1881                  }
 1882                  /* execute the instruction TODO insert checks
 1883                   * RFC 3320 :
 1884                   *
 1885                   *    0             7 8            15
 1886                   *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 1887                   *   |        byte_copy_left         |  64 - 65 
 1888                   *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 1889                   *   |        byte_copy_right        |  66 - 67 
 1890                   *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 1891                   *   |        input_bit_order        |  68 - 69 
 1892                   *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 1893                   *   |        stack_location         |  70 - 71 
 1894                   *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 1895                   *
 1896                   * Figure 7: Memory addresses of the UDVM registers
 1897                   * :
 1898                   * 8.4.  Byte copying 
 1899                   * :
 1900                   * The string of bytes is copied in ascending order of memory address,
 1901                   * respecting the bounds set by byte_copy_left and byte_copy_right.
 1902                   * More precisely, if a byte is copied from/to Address m then the next 
 1903                   * byte is copied from/to Address n where n is calculated as follows:
 1904                   *
 1905                   * Set k := m + 1 (modulo 2^16)
 1906                   * If k = byte_copy_right then set n := byte_copy_left, else set n := k 
 1907                   *
 1908                   */
 1909   
 1910                  n = 0;
 1911                  k = destination;
 1912                  byte_copy_right = buff[66] << 8;
 1913                  byte_copy_right = byte_copy_right | buff[67];
 1914                  byte_copy_left = buff[64] << 8;
 1915                  byte_copy_left = byte_copy_left | buff[65];
 1916                  if (print_level_1 ){
 1917                          proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 1918                                          "               byte_copy_right = %u", byte_copy_right);
 1919                  }
 1920                  /* clear out remaining bits if any */
 1921                  remaining_bits = 0;
 1922                  input_bits=0;
 1923                  /* operand_address used as dummy */
 1924                  while ( n < length ){
 1925                          if (input_address > ( msg_end - 1)){
 1926                                  current_address = at_address;
 1927                                  result_code = 14;
 1928                                  goto execute_next_instruction;
 1929                          }
 1930   
 1931                          if ( k == byte_copy_right ){
 1932                                  k = byte_copy_left;
 1933                          }
 1934                          octet = tvb_get_guint8(message_tvb, input_address);
 1935                          buff[k] = octet;
 1936                          if (print_level_1 ){
 1937                                  proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 1938                                          "               Loading value: %u (0x%x) at Addr: %u", octet, octet, k);
 1939                          }
 1940                          input_address++;
 1941                          /*
 1942                           * If the instruction requests data that lies beyond the end of the
 1943                           * SigComp message, no data is returned.  Instead the UDVM moves program
 1944                           * execution to the address specified by the address operand.
 1945                           */
 1946   
 1947   
 1948                          k = ( k + 1 ) & 0xffff;
 1949                          n++;
 1950                  }
 1951                  used_udvm_cycles = used_udvm_cycles + 1 + length;
 1952                  current_address = next_operand_address;
 1953                  goto execute_next_instruction;
 1954                  break;
 1955          case SIGCOMP_INSTR_INPUT_BITS:/* 29   INPUT-BITS (%length, %destination, @address) */
 1956                  /*
 1957                   * The length operand indicates the requested number of bits.
 1958                   * Decompression failure occurs if this operand does not lie between 0 
 1959                   * and 16 inclusive.
 1960                   *
 1961                   * The destination operand specifies the memory address to which the
 1962                   * compressed data should be copied.  Note that the requested bits are 
 1963                   * interpreted as a 2-byte integer ranging from 0 to 2^length - 1, as 
 1964                   * explained in Section 8.2.
 1965                   *
 1966                   * If the instruction requests data that lies beyond the end of the
 1967                   * SigComp message, no data is returned.  Instead the UDVM moves program
 1968                   * execution to the address specified by the address operand.
 1969                   */
 1970   
 1971                  if (show_instr_detail_level == 2 ){
 1972                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 1973                                  "Addr: %u ## INPUT-BITS(29) (length, destination, @address)",
 1974                                  current_address);
 1975                  }
 1976                  operand_address = current_address + 1;
 1977   
 1978                  /* %length */
 1979                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &length);
 1980                  if (show_instr_detail_level == 2 ){
 1981                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      length %u",
 1982                                  operand_address, length);
 1983                  }
 1984                  operand_address = next_operand_address;
 1985                  /* %destination */
 1986                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
 1987                  if (show_instr_detail_level == 2 ){
 1988                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Destination %u",
 1989                                  operand_address, destination);
 1990                  }
 1991                  operand_address = next_operand_address;
 1992   
 1993                  /* @address */
 1994                   /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
 1995                  next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
 1996                  if (show_instr_detail_level == 2 ){
 1997                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
 1998                                  operand_address, at_address);
 1999                  }
 2000                  if (show_instr_detail_level == 1)
 2001                  {
 2002                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2003                                  "Addr: %u ## INPUT-BITS length=%u, destination=%u, @address=%u)",
 2004                                  current_address, length, destination, at_address);
 2005                  }
 2006                  current_address = next_operand_address;
 2007   
 2008                  /*
 2009                   * Execute actual instr.
 2010                   * The input_bit_order register contains the following three flags:
 2011                   *
 2012                   *            0             7 8            15
 2013                   *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 2014                   *           |         reserved        |F|H|P|  68 - 69 
 2015                   *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 2016                   */
 2017                  input_bit_order = buff[68] << 8;
 2018                  input_bit_order = input_bit_order | buff[69];
 2019                  /*
 2020                   * If the instruction requests data that lies beyond the end of the
 2021                   * SigComp message, no data is returned.  Instead the UDVM moves program
 2022                   * execution to the address specified by the address operand.
 2023                   */
 2024   
 2025                  if ( length > 16 ){
 2026                          result_code = 7;
 2027                          goto decompression_failure;
 2028                  }
 2029                  if ( input_bit_order > 7 ){
 2030                          result_code = 8;
 2031                          goto decompression_failure;
 2032                  }
 2033   
 2034                  /*
 2035                   * Transfer F bit to bit_order to tell decomp dispatcher which bit order to use
 2036                   */
 2037                  bit_order = ( input_bit_order & 0x0004 ) >> 2;
 2038                  value = decomp_dispatch_get_bits( message_tvb, udvm_tree, bit_order,
 2039                                  buff, &old_input_bit_order, &remaining_bits,
 2040                                  &input_bits, &input_address, length, &result_code, msg_end);
 2041                  if ( result_code == 11 ){
 2042                          used_udvm_cycles = used_udvm_cycles + 1;
 2043                          current_address = at_address;
 2044                          goto execute_next_instruction;
 2045                  }
 2046                  msb = value >> 8;
 2047                  lsb = value & 0x00ff;
 2048                  if (destination >= UDVM_MEMORY_SIZE - 1)
 2049                          goto decompression_failure;
 2050                  buff[destination] = msb;
 2051                  buff[destination + 1]=lsb;
 2052                  if (print_level_1 ){
 2053                          proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 2054                          "               Loading value: %u (0x%x) at Addr: %u, remaining_bits: %u", value, value, destination, remaining_bits);
 2055                  }
 2056   
 2057                  used_udvm_cycles = used_udvm_cycles + 1;
 2058                  goto execute_next_instruction;
 2059                  break;
 2060          case SIGCOMP_INSTR_INPUT_HUFFMAN: /* 30 */
 2061                  /*
 2062                   * INPUT-HUFFMAN (%destination, @address, #n, %bits_1, %lower_bound_1,
 2063                   *  %upper_bound_1, %uncompressed_1, ... , %bits_n, %lower_bound_n,
 2064                   *  %upper_bound_n, %uncompressed_n)
 2065                   */
 2066                  if (show_instr_detail_level == 2 ){
 2067                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2068                                  "Addr: %u ## INPUT-HUFFMAN (destination, @address, #n, bits_1, lower_bound_1,upper_bound_1, uncompressed_1, ... , bits_n, lower_bound_n,upper_bound_n, uncompressed_n)",
 2069                                  current_address);
 2070                  }
 2071                  operand_address = current_address + 1;
 2072   
 2073                  /* %destination */
 2074                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &destination);
 2075                  if (show_instr_detail_level == 2 ){
 2076                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      Destination %u",
 2077                                  operand_address, destination);
 2078                  }
 2079                  operand_address = next_operand_address;
 2080   
 2081                  /* @address */
 2082                   /* operand_value = (memory_address_of_instruction + D) modulo 2^16 */
 2083                  next_operand_address = decode_udvm_address_operand(buff,operand_address, &at_address, current_address);
 2084                  if (show_instr_detail_level == 2 ){
 2085                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      @Address %u",
 2086                                  operand_address, at_address);
 2087                  }
 2088                  operand_address = next_operand_address;
 2089   
 2090                  /* #n */
 2091                  next_operand_address = decode_udvm_literal_operand(buff,operand_address, &n);
 2092                  if (show_instr_detail_level == 2 ){
 2093                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      n %u",
 2094                                  operand_address, n);
 2095                  }
 2096                  operand_address = next_operand_address;
 2097                  if (show_instr_detail_level == 1)
 2098                  {
 2099                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2100                                  "Addr: %u ## INPUT-HUFFMAN (destination=%u, @address=%u, #n=%u, bits_1, lower_1,upper_1, unc_1, ... , bits_%d, lower_%d,upper_%d, unc_%d)",
 2101                                  current_address, destination, at_address, n, n, n, n, n);
 2102                  }
 2103   
 2104                  used_udvm_cycles = used_udvm_cycles + 1 + n;
 2105   
 2106                  /*
 2107                   * Note that if n = 0 then the INPUT-HUFFMAN instruction is ignored and
 2108                   * program execution resumes at the following instruction.
 2109                   * Decompression failure occurs if (bits_1 + ... + bits_n) > 16.
 2110                   *
 2111                   * In all other cases, the behavior of the INPUT-HUFFMAN instruction is
 2112                   * defined below:
 2113                   *
 2114                   * 1. Set j := 1 and set H := 0.
 2115
2132
Show [ Lines 2115 to 2132 omitted. ]
 2133                  /*
 2134                   * The input_bit_order register contains the following three flags:
 2135                   *
 2136                   *            0             7 8            15
 2137                   *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 2138                   *           |         reserved        |F|H|P|  68 - 69 
 2139                   *           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 2140                   *
 2141                   * Transfer H bit to bit_order to tell decomp dispatcher which bit order to use
 2142                   */
 2143                  input_bit_order = buff[68] << 8;
 2144                  input_bit_order = input_bit_order | buff[69];
 2145                  bit_order = ( input_bit_order & 0x0002 ) >> 1;
 2146   
 2147                  j = 1;
 2148                  H = 0;
 2149                  m = n;
 2150                  outside_huffman_boundaries = TRUE;
 2151                  print_in_loop = print_level_3;
 2152                  while ( m > 0 ){
 2153                          /* %bits_n */
 2154                          next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &bits_n);
 2155                          if (print_in_loop ){
 2156                                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      bits_n %u",
 2157                                          operand_address, bits_n);
 2158                          }
 2159                          operand_address = next_operand_address;
 2160   
 2161                          /* %lower_bound_n */
 2162                          next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &lower_bound_n);
 2163                          if (print_in_loop ){
 2164                                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      lower_bound_n %u",
 2165                                          operand_address, lower_bound_n);
 2166                          }
 2167                          operand_address = next_operand_address;
 2168                          /* %upper_bound_n */
 2169                          next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &upper_bound_n);
 2170                          if (print_in_loop ){
 2171                                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      upper_bound_n %u",
 2172                                          operand_address, upper_bound_n);
 2173                          }
 2174                          operand_address = next_operand_address;
 2175                          /* %uncompressed_n */
 2176                          next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &uncompressed_n);
 2177                          if (print_in_loop ){
 2178                                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      uncompressed_n %u",
 2179                                          operand_address, uncompressed_n);
 2180                          }
 2181                          operand_address = next_operand_address;
 2182                          /* execute instruction */
 2183                          if ( outside_huffman_boundaries ) {
 2184                                  /*
 2185                                   * 2. Request bits_j compressed bits.  Interpret the returned bits as an 
 2186                                   *    integer k from 0 to 2^bits_j - 1, as explained in Section 8.2.
 2187                                   */
 2188                                  k = decomp_dispatch_get_bits( message_tvb, udvm_tree, bit_order,
 2189                                                  buff, &old_input_bit_order, &remaining_bits,
 2190                                                  &input_bits, &input_address, bits_n, &result_code, msg_end);
 2191                                  if ( result_code == 11 ){
 2192                                          /*
 2193                                          * 4. If data is requested that lies beyond the end of the SigComp
 2194                                          * message, terminate the INPUT-HUFFMAN instruction and move program
 2195                                          * execution to the memory address specified by the address operand.
 2196                                          */
 2197                                          current_address = at_address;
 2198                                          goto execute_next_instruction;
 2199                                  }
 2200   
 2201                                  /*
 2202                                   * 3. Set H := H * 2^bits_j + k.
 2203                                   * [In practice is a shift+OR operation.]
 2204                                   */
 2205                                  oldH = H;
 2206                                  H = (H << bits_n) | k;
 2207                                  if (print_level_3 ){
 2208                                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"               Set H(%u) := H(%u) * 2^bits_j(%u) + k(%u)",
 2209                                                   H ,oldH, 1<<bits_n,k);
 2210                                  }
 2211   
 2212                                  /*
 2213                                   * 5. If (H < lower_bound_j) or (H > upper_bound_j) then set j := j + 1.
 2214                                   * Then go back to Step 2, unless j > n in which case decompression 
 2215                                   * failure occurs.
 2216                                   */
 2217                                  if ((H < lower_bound_n) || (H > upper_bound_n)){
 2218                                          outside_huffman_boundaries = TRUE;
 2219                                  }else{
 2220                                          outside_huffman_boundaries = FALSE;
 2221                                          print_in_loop = FALSE;
 2222                                          /*
 2223                                           * 6. Copy (H + uncompressed_j - lower_bound_j) modulo 2^16 to the
 2224                                           * memory address specified by the destination operand.
 2225                                           */
 2226                                          if (print_level_2 ){
 2227                                                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2228                                                          "               H(%u) = H(%u) + uncompressed_n(%u) - lower_bound_n(%u)",
 2229                                                  (H + uncompressed_n - lower_bound_n ),H, uncompressed_n, lower_bound_n);
 2230                                          }
 2231                                          H = H + uncompressed_n - lower_bound_n;
 2232                                          msb = H >> 8;
 2233                                          lsb = H & 0x00ff;
 2234                                          if (destination >= UDVM_MEMORY_SIZE - 1)
 2235                                                  goto decompression_failure;
 2236                                          buff[destination] = msb;
 2237                                          buff[destination + 1]=lsb;
 2238                                          if (print_level_1 ){
 2239                                                  proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 2240                                          "               Loading H: %u (0x%x) at Addr: %u,j = %u remaining_bits: %u",
 2241                                                  H, H, destination,( n - m + 1 ), remaining_bits);
 2242                                          }
 2243   
 2244                                  }
 2245   
 2246   
 2247                          }
 2248                          m = m - 1;
 2249                  }
 2250                  if ( outside_huffman_boundaries ) {
 2251                          result_code = 10;
 2252                          goto decompression_failure;
 2253                  }
 2254   
 2255                  current_address = next_operand_address;
 2256                  goto execute_next_instruction;
 2257                  break;
 2258   
 2259          case SIGCOMP_INSTR_STATE_ACCESS: /* 31 */
 2260                  /*   STATE-ACCESS (%partial_identifier_start, %partial_identifier_length,
 2261                   * %state_begin, %state_length, %state_address, %state_instruction)
 2262                   */
 2263                  if (show_instr_detail_level == 2 ){
 2264                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2265                                  "Addr: %u ## STATE-ACCESS(31) (partial_identifier_start, partial_identifier_length,state_begin, state_length, state_address, state_instruction)",
 2266                                  current_address);
 2267                  }
 2268                  operand_address = current_address + 1;
 2269   
 2270                  /*
 2271                   * %partial_identifier_start
 2272                   */
 2273                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_start);
 2274                  if (show_instr_detail_level == 2 ){
 2275                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       partial_identifier_start %u",
 2276                                  operand_address, p_id_start);
 2277                  }
 2278                  operand_address = next_operand_address;
 2279   
 2280                  /*
 2281                   * %partial_identifier_length
 2282                   */
 2283                  operand_address = next_operand_address;
 2284                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_length);
 2285                  if (show_instr_detail_level == 2 ){
 2286                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       partial_identifier_length %u",
 2287                                  operand_address, p_id_length);
 2288                  }
 2289                  /*
 2290                   * %state_begin
 2291                   */
 2292                  operand_address = next_operand_address;
 2293                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_begin);
 2294                  if (show_instr_detail_level == 2 ){
 2295                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_begin %u",
 2296                                  operand_address, state_begin);
 2297                  }
 2298                  /*
 2299                   * %state_length
 2300                   */
 2301                  operand_address = next_operand_address;
 2302                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
 2303                  if (show_instr_detail_level == 2 ){
 2304                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_length %u",
 2305                                  operand_address, state_length);
 2306                  }
 2307                  /*
 2308                   * %state_address
 2309                   */
 2310                  operand_address = next_operand_address;
 2311                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
 2312                  if (show_instr_detail_level == 2 ){
 2313                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_address %u",
 2314                                  operand_address, state_address);
 2315                  }
 2316                  /*
 2317                   * %state_instruction
 2318                   */
 2319                  operand_address = next_operand_address;
 2320                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
 2321                  if (show_instr_detail_level == 2 ){
 2322                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_instruction %u",
 2323                                  operand_address, state_instruction);
 2324                  }
 2325                  if (show_instr_detail_level == 1)
 2326                  {
 2327                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2328                                  "Addr: %u ## STATE-ACCESS(31) (partial_identifier_start=%u, partial_identifier_length=%u,state_begin=%u, state_length=%u, state_address=%u, state_instruction=%u)",
 2329                                  current_address, p_id_start, p_id_length, state_begin, state_length, state_address, state_instruction);
 2330                  }
 2331                  current_address = next_operand_address;
 2332                  byte_copy_right = buff[66] << 8;
 2333                  byte_copy_right = byte_copy_right | buff[67];
 2334                  byte_copy_left = buff[64] << 8;
 2335                  byte_copy_left = byte_copy_left | buff[65];
 2336                  if (print_level_2 ){
 2337                          proto_tree_add_text(udvm_tree, message_tvb, input_address, 1,
 2338                                          "               byte_copy_right = %u, byte_copy_left = %u", byte_copy_right,byte_copy_left);
 2339                  }
 2340   
 2341                  result_code = udvm_state_access(message_tvb, udvm_tree, buff, p_id_start, p_id_length, state_begin, &state_length,
 2342                          &state_address, &state_instruction, hf_id);
 2343                  if ( result_code != 0 ){
 2344                          goto decompression_failure;
 2345                  }
 2346                  used_udvm_cycles = used_udvm_cycles + 1 + state_length;
 2347                  goto execute_next_instruction;
 2348                  break;
 2349          case SIGCOMP_INSTR_STATE_CREATE: /* 32 */
 2350                  /*
 2351                   * STATE-CREATE (%state_length, %state_address, %state_instruction,
 2352                   * %minimum_access_length, %state_retention_priority)
 2353                   */
 2354                  if (show_instr_detail_level == 2 ){
 2355                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2356                                  "Addr: %u ## STATE-CREATE(32) (state_length, state_address, state_instruction,minimum_access_length, state_retention_priority)",
 2357                                  current_address);
 2358                  }
 2359                  operand_address = current_address + 1;
 2360   
 2361                  /*
 2362                   * %state_length
 2363                   */
 2364                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
 2365                  if (show_instr_detail_level == 2 ){
 2366                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_length %u",
 2367                                  operand_address, state_length);
 2368                  }
 2369                  /*
 2370                   * %state_address
 2371                   */
 2372                  operand_address = next_operand_address;
 2373                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
 2374                  if (show_instr_detail_level == 2 ){
 2375                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_address %u",
 2376                                  operand_address, state_address);
 2377                  }
 2378                  /*
 2379                   * %state_instruction
 2380                   */
 2381                  operand_address = next_operand_address;
 2382                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
 2383                  if (show_instr_detail_level == 2 ){
 2384                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_instruction %u",
 2385                                  operand_address, state_instruction);
 2386                  }
 2387                  operand_address = next_operand_address;
 2388                  /*
 2389                   * %minimum_access_length
 2390                   */
 2391                  operand_address = next_operand_address;
 2392                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &minimum_access_length);
 2393                  if (show_instr_detail_level == 2 ){
 2394                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       minimum_access_length %u",
 2395                                  operand_address, minimum_access_length);
 2396                  }
 2397                  operand_address = next_operand_address;
 2398                  /*
 2399                   * %state_retention_priority
 2400                   */
 2401                  operand_address = next_operand_address;
 2402                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_retention_priority);
 2403                  if (show_instr_detail_level == 2 ){
 2404                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       state_retention_priority %u",
 2405                                  operand_address, state_retention_priority);
 2406                  }
 2407                  if (show_instr_detail_level == 1)
 2408                  {
 2409                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2410                                  "Addr: %u ## STATE-CREATE(32) (state_length=%u, state_address=%u, state_instruction=%u,minimum_access_length=%u, state_retention_priority=%u)",
 2411                                  current_address, state_length, state_address, state_instruction,minimum_access_length, state_retention_priority);
 2412                  }
 2413                  current_address = next_operand_address;
 2414                  /* Execute the instruction 
 2415                   * TODO Implement the instruction
 2416                   * RFC3320:
 2417                   *    Note that the new state item cannot be created until a valid 
 2418                   *    compartment identifier has been returned by the application.
 2419                   *    Consequently, when a STATE-CREATE instruction is encountered the UDVM 
 2420                   *    simply buffers the five supplied operands until the END-MESSAGE
 2421                   *    instruction is reached.  The steps taken at this point are described 
 2422                   *    in Section 9.4.9.
 2423                   *
 2424                   *   Decompression failure MUST occur if more than four state creation
 2425                   *   requests are made before the END-MESSAGE instruction is encountered.
 2426                   *   Decompression failure also occurs if the minimum_access_length does
 2427                   *   not lie between 6 and 20 inclusive, or if the 
 2428                   *   state_retention_priority is 65535.
 2429                   */
 2430                  no_of_state_create++;
 2431                  if ( no_of_state_create > 4 ){
 2432                          result_code = 12;
 2433                          goto decompression_failure;
 2434                  }
 2435                  if (( minimum_access_length < 6 ) || ( minimum_access_length > STATE_BUFFER_SIZE )){
 2436                          result_code = 1;
 2437                          goto decompression_failure;
 2438                  }
 2439                  if ( state_retention_priority == 65535 ){
 2440                          result_code = 13;
 2441                          goto decompression_failure;
 2442                  }
 2443                  state_length_buff[no_of_state_create] = state_length;
 2444                  state_address_buff[no_of_state_create] = state_address;
 2445                  state_instruction_buff[no_of_state_create] = state_instruction;
 2446                  state_minimum_access_length_buff[no_of_state_create] = minimum_access_length;
 2447                  state_state_retention_priority_buff[no_of_state_create] = state_retention_priority;
 2448                  used_udvm_cycles = used_udvm_cycles + 1 + state_length;
 2449                  /* Debug */
 2450                  byte_copy_right = buff[66] << 8;
 2451                  byte_copy_right = byte_copy_right | buff[67];
 2452                  byte_copy_left = buff[64] << 8;
 2453                  byte_copy_left = byte_copy_left | buff[65];
 2454                  n = 0;
 2455                  k = state_address;
 2456                  while ( n < state_length ){
 2457                          if ( k == byte_copy_right ){
 2458                                  k = byte_copy_left;
 2459                          }
 2460                          string[0]= buff[k];
 2461                          string[1]= '\0';
 2462                          if (print_level_3 ){
 2463                                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2464                                          "               Addr: %5u State value: %u (0x%x) ASCII(%s)",
 2465                                          k,buff[k],buff[k],format_text(string, 1));
 2466                          }
 2467                          k = ( k + 1 ) & 0xffff;
 2468                          n++;
 2469                  }
 2470                  /* End debug */
 2471   
 2472                  goto execute_next_instruction;
 2473                  break;
 2474          case SIGCOMP_INSTR_STATE_FREE: /* 33 */
 2475                  /*
 2476                   * STATE-FREE (%partial_identifier_start, %partial_identifier_length)
 2477                   */
 2478                  if (show_instr_detail_level == 2 ){
 2479                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2480                                  "Addr: %u ## STATE-FREE (partial_identifier_start, partial_identifier_length)",
 2481                                  current_address);
 2482                  }
 2483                  operand_address = current_address + 1;
 2484                  /*
 2485                   * %partial_identifier_start
 2486                   */
 2487                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_start);
 2488                  if (show_instr_detail_level == 2 ){
 2489                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       partial_identifier_start %u",
 2490                                  operand_address, p_id_start);
 2491                  }
 2492                  operand_address = next_operand_address;
 2493   
 2494                  /*
 2495                   * %partial_identifier_length
 2496                   */
 2497                  operand_address = next_operand_address;
 2498                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &p_id_length);
 2499                  if (show_instr_detail_level == 2 ){
 2500                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u       partial_identifier_length %u",
 2501                                  operand_address, p_id_length);
 2502                  }
 2503                  if (show_instr_detail_level == 1)
 2504                  {
 2505                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2506                                  "Addr: %u ## STATE-FREE (partial_identifier_start=%u, partial_identifier_length=%u)",
 2507                                  current_address, p_id_start, p_id_length);
 2508                  }
 2509                  current_address = next_operand_address;
 2510   
 2511                  /* Execute the instruction:
 2512                   * TODO implement it 
 2513                   */
 2514                  udvm_state_free(buff,p_id_start,p_id_length);
 2515                  used_udvm_cycles++;
 2516   
 2517                  goto execute_next_instruction;
 2518                  break;
 2519          case SIGCOMP_INSTR_OUTPUT: /* 34 OUTPUT (%output_start, %output_length) */
 2520                  if (show_instr_detail_level == 2 ){
 2521                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2522                                  "Addr: %u ## OUTPUT(34) (output_start, output_length)",
 2523                                  current_address);
 2524                  }
 2525                  operand_address = current_address + 1;
 2526                  /*
 2527                   * %output_start
 2528                   */
 2529                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &output_start);
 2530                  if (show_instr_detail_level == 2 ){
 2531                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      output_start %u",
 2532                                  operand_address, output_start);
 2533                  }
 2534                  operand_address = next_operand_address;
 2535                  /*
 2536                   * %output_length
 2537                   */
 2538                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &output_length);
 2539                  if (show_instr_detail_level == 2 ){
 2540                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      output_length %u",
 2541                                  operand_address, output_length);
 2542                  }
 2543                  if (show_instr_detail_level == 1)
 2544                  {
 2545                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2546                                  "Addr: %u ## OUTPUT (output_start=%u, output_length=%u)",
 2547                                  current_address, output_start, output_length);
 2548                  }
 2549                  current_address = next_operand_address;
 2550   
 2551                  /*
 2552                   * Execute instruction
 2553                   * 8.4.  Byte copying 
 2554                   * :
 2555                   * The string of bytes is copied in ascending order of memory address,
 2556                   * respecting the bounds set by byte_copy_left and byte_copy_right.
 2557                   * More precisely, if a byte is copied from/to Address m then the next 
 2558                   * byte is copied from/to Address n where n is calculated as follows:
 2559                   *
 2560                   * Set k := m + 1 (modulo 2^16)
 2561                   * If k = byte_copy_right then set n := byte_copy_left, else set n := k 
 2562                   *
 2563                   */
 2564   
 2565                  n = 0;
 2566                  k = output_start;
 2567                  byte_copy_right = buff[66] << 8;
 2568                  byte_copy_right = byte_copy_right | buff[67];
 2569                  byte_copy_left = buff[64] << 8;
 2570                  byte_copy_left = byte_copy_left | buff[65];
 2571                  if (print_level_3 ){
 2572                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2573                                          "               byte_copy_right = %u", byte_copy_right);
 2574                  }
 2575                  while ( n < output_length ){
 2576   
 2577                          if ( k == byte_copy_right ){
 2578                                  k = byte_copy_left;
 2579                          }
 2580                          out_buff[output_address] = buff[k];
 2581                          string[0]= buff[k];
 2582                          string[1]= '\0';
 2583                          if (print_level_3 ){
 2584                                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2585                                          "               Output value: %u (0x%x) ASCII(%s) from Addr: %u ,output to dispatcher position %u",
 2586                                          buff[k],buff[k],format_text(string,1), k,output_address);
 2587                          }
 2588                          k = ( k + 1 ) & 0xffff;
 2589                          output_address ++;
 2590                          n++;
 2591                  }
 2592                  used_udvm_cycles = used_udvm_cycles + 1 + output_length;
 2593                  goto execute_next_instruction;
 2594                  break;
 2595          case SIGCOMP_INSTR_END_MESSAGE: /* 35 */
 2596                  /*
 2597                   * END-MESSAGE (%requested_feedback_location,
 2598                   * %returned_parameters_location, %state_length, %state_address,
 2599                   * %state_instruction, %minimum_access_length,
 2600                   * %state_retention_priority)
 2601                   */
 2602                  if (show_instr_detail_level == 2 ){
 2603                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2604                                  "Addr: %u ## END-MESSAGE (requested_feedback_location,state_instruction, minimum_access_length,state_retention_priority)",
 2605                                  current_address);
 2606                  }
 2607                  operand_address = current_address + 1;
 2608   
 2609                  /* %requested_feedback_location */
 2610                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &requested_feedback_location);
 2611                  if (show_instr_detail_level == 2 ){
 2612                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      requested_feedback_location %u",
 2613                                  operand_address, requested_feedback_location);
 2614                  }
 2615                  operand_address = next_operand_address;
 2616                  /* returned_parameters_location */
 2617                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &returned_parameters_location);
 2618                  if (show_instr_detail_level == 2 ){
 2619                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      returned_parameters_location %u",
 2620                                  operand_address, returned_parameters_location);
 2621                  }
 2622                  operand_address = next_operand_address;
 2623                  /*
 2624                   * %state_length
 2625                   */
 2626                  operand_address = next_operand_address;
 2627                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_length);
 2628                  if (show_instr_detail_level == 2 ){
 2629                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      state_length %u",
 2630                                  operand_address, state_length);
 2631                  }
 2632                  /*
 2633                   * %state_address
 2634                   */
 2635                  operand_address = next_operand_address;
 2636                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_address);
 2637                  if (show_instr_detail_level == 2 ){
 2638                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      state_address %u",
 2639                                  operand_address, state_address);
 2640                  }
 2641                  /*
 2642                   * %state_instruction
 2643                   */
 2644                  operand_address = next_operand_address;
 2645                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_instruction);
 2646                  if (show_instr_detail_level == 2 ){
 2647                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      state_instruction %u",
 2648                                  operand_address, state_instruction);
 2649                  }
 2650   
 2651                  /*
 2652                   * %minimum_access_length
 2653                   */
 2654                  operand_address = next_operand_address;
 2655                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &minimum_access_length);
 2656                  if (show_instr_detail_level == 2 ){
 2657                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      minimum_access_length %u",
 2658                                  operand_address, minimum_access_length);
 2659                  }
 2660   
 2661                  /*
 2662                   * %state_retention_priority
 2663                   */
 2664                  operand_address = next_operand_address;
 2665                  next_operand_address = decode_udvm_multitype_operand(buff, operand_address, &state_retention_priority);
 2666                  if (show_instr_detail_level == 2 ){
 2667                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"Addr: %u      state_retention_priority %u",
 2668                                  operand_address, state_retention_priority);
 2669                  }
 2670                  if (show_instr_detail_level == 1)
 2671                  {
 2672                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,
 2673                                  "Addr: %u ## END-MESSAGE (requested_feedback_location=%u, returned_parameters_location=%u, state_length=%u, state_address=%u, state_instruction=%u, minimum_access_length=%u, state_retention_priority=%u)",
 2674                                  current_address, requested_feedback_location, returned_parameters_location, state_length, state_address, state_instruction, minimum_access_length,state_retention_priority);
 2675                  }
 2676                  current_address = next_operand_address;
 2677                  /* TODO: This isn't currently totaly correct as END_INSTRUCTION might not create state */
 2678                  no_of_state_create++;
 2679                  if ( no_of_state_create > 4 ){
 2680                          result_code = 12;
 2681                          goto decompression_failure;
 2682                  }
 2683                  state_length_buff[no_of_state_create] = state_length;
 2684                  state_address_buff[no_of_state_create] = state_address;
 2685                  state_instruction_buff[no_of_state_create] = state_instruction;
 2686                  /* Not used ? */
 2687                  state_minimum_access_length_buff[no_of_state_create] = minimum_access_length;
 2688                  state_state_retention_priority_buff[no_of_state_create] = state_retention_priority;
 2689   
 2690                  /* Execute the instruction 
 2691                   */
 2692                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"no_of_state_create %u",no_of_state_create);
 2693                  if ( no_of_state_create != 0 ){
 2694                          memset(sha1_digest_buf, 0, STATE_BUFFER_SIZE);
 2695                          n = 1;
 2696                          byte_copy_right = buff[66] << 8;
 2697                          byte_copy_right = byte_copy_right | buff[67];
 2698                          byte_copy_left = buff[64] << 8;
 2699                          byte_copy_left = byte_copy_left | buff[65];
 2700                          while ( n < no_of_state_create + 1 ){
 2701                                  sha1buff = g_malloc(state_length_buff[n]+8);
 2702                                  sha1buff[0] = state_length_buff[n] >> 8;
 2703                                  sha1buff[1] = state_length_buff[n] & 0xff;
 2704                                  sha1buff[2] = state_address_buff[n] >> 8;
 2705                                  sha1buff[3] = state_address_buff[n] & 0xff;
 2706                                  sha1buff[4] = state_instruction_buff[n] >> 8;
 2707                                  sha1buff[5] = state_instruction_buff[n] & 0xff;
 2708                                  sha1buff[6] = state_minimum_access_length_buff[n] >> 8;
 2709                                  sha1buff[7] = state_minimum_access_length_buff[n] & 0xff;
 2710                                  if (print_level_3 ){
 2711                                          for( x=0; x < 8; x++){
 2712                                                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"sha1buff %u 0x%x",
 2713                                                          x,sha1buff[x]);
 2714                                          }
 2715                                  }
 2716                                  k = state_address_buff[n];
 2717                                  for( x=0; x < state_length_buff[n]; x++)
 2718                                          {
 2719                                          if ( k == byte_copy_right ){
 2720                                                  k = byte_copy_left;
 2721                                          }
 2722                                          sha1buff[8+x] = buff[k];
 2723                                          k = ( k + 1 ) & 0xffff;
 2724                                          }
 2725   
 2726                                  sha1_starts( &ctx );
 2727                                  sha1_update( &ctx, (guint8 *) sha1buff, state_length_buff[n] + 8);
 2728                                  sha1_finish( &ctx, sha1_digest_buf );
 2729                                  if (print_level_3 ){
 2730                                          proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"SHA1 digest %s",bytes_to_str(sha1_digest_buf, STATE_BUFFER_SIZE));
 2731   
 2732                                  }
 2733  /* begin partial state-id change cco@iptel.org */
 2734  #if 0 
 2735                                  udvm_state_create(sha1buff, sha1_digest_buf, state_minimum_access_length_buff[n]);
 2736  #endif
 2737                                  udvm_state_create(sha1buff, sha1_digest_buf, STATE_MIN_ACCESS_LEN);
 2738  /* end partial state-id change cco@iptel.org */
 2739                                  proto_tree_add_text(udvm_tree,bytecode_tvb, 0, -1,"### Creating state ###");
 2740                                  proto_tree_add_string(udvm_tree,hf_id, bytecode_tvb, 0, 0, bytes_to_str(sha1_digest_buf, state_minimum_access_length_buff[n]));
 2741   
 2742                                  n++;
 2743   
 2744                          }
 2745                  }
 2746   
 2747   
 2748   
 2749                  /* At least something got decompressed, show it */
 2750                  decomp_tvb = tvb_new_child_real_data(message_tvb, out_buff,output_address,output_address);
 2751                  /* Arrange that the allocated packet data copy be freed when the 
 2752                   * tvbuff is freed.
 2753                   */
 2754                  tvb_set_free_cb( decomp_tvb, g_free );
 2755   
 2756                  add_new_data_source(pinfo, decomp_tvb, "Decompressed SigComp message");
 2757                  /*
 2758                  proto_tree_add_text(udvm_tree, decomp_tvb, 0, -1,"SigComp message Decompressed");
 2759                  */
 2760                  used_udvm_cycles = used_udvm_cycles + 1 + state_length;
 2761                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"maximum_UDVM_cycles %u used_udvm_cycles %u",
 2762                          maximum_UDVM_cycles, used_udvm_cycles);
 2763                  return decomp_tvb;
 2764                  break;
 2765   
 2766          default:
 2767              proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1," ### Addr %u Invalid instruction: %u (0x%x)",
 2768                          current_address,current_instruction,current_instruction);
 2769                  break;
 2770                  }
 2771                  g_free(out_buff);
 2772                  return NULL;
 2773  decompression_failure:
 2774   
 2775                  proto_tree_add_text(udvm_tree, bytecode_tvb, 0, -1,"DECOMPRESSION FAILURE: %s",
 2776                                      val_to_str(result_code, result_code_vals,"Unknown (%u)"));
 2777                  THROW(ReportedBoundsError);
 2778                  g_free(out_buff);
 2779                  return NULL;
 2780   
 2781  }
Show more  




Change Warning 2953.31517 : Unreachable Call

Priority:
State:
Finding:
Owner:
Note: