1/**************************************************************************** 2 * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323 3 * conntrack/NAT module. 4 * 5 * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net> 6 * 7 * This source code is licensed under General Public License version 2. 8 * 9 * See ip_conntrack_helper_h323_asn1.h for details. 10 * 11 ****************************************************************************/ 12 13#ifdef __KERNEL__ 14#include <linux/kernel.h> 15#else 16#include <stdio.h> 17#endif 18#include <linux/netfilter/nf_conntrack_h323_asn1.h> 19 20/* Trace Flag */ 21#ifndef H323_TRACE 22#define H323_TRACE 0 23#endif 24 25#if H323_TRACE 26#define TAB_SIZE 4 27#define IFTHEN(cond, act) if(cond){act;} 28#ifdef __KERNEL__ 29#define PRINT printk 30#else 31#define PRINT printf 32#endif 33#define FNAME(name) name, 34#else 35#define IFTHEN(cond, act) 36#define PRINT(fmt, args...) 37#define FNAME(name) 38#endif 39 40/* ASN.1 Types */ 41#define NUL 0 42#define BOOL 1 43#define OID 2 44#define INT 3 45#define ENUM 4 46#define BITSTR 5 47#define NUMSTR 6 48#define NUMDGT 6 49#define TBCDSTR 6 50#define OCTSTR 7 51#define PRTSTR 7 52#define IA5STR 7 53#define GENSTR 7 54#define BMPSTR 8 55#define SEQ 9 56#define SET 9 57#define SEQOF 10 58#define SETOF 10 59#define CHOICE 11 60 61/* Constraint Types */ 62#define FIXD 0 63/* #define BITS 1-8 */ 64#define BYTE 9 65#define WORD 10 66#define CONS 11 67#define SEMI 12 68#define UNCO 13 69 70/* ASN.1 Type Attributes */ 71#define SKIP 0 72#define STOP 1 73#define DECODE 2 74#define EXT 4 75#define OPEN 8 76#define OPT 16 77 78 79/* ASN.1 Field Structure */ 80typedef struct field_t { 81#if H323_TRACE 82 char *name; 83#endif 84 unsigned char type; 85 unsigned char sz; 86 unsigned char lb; 87 unsigned char ub; 88 unsigned short attr; 89 unsigned short offset; 90 struct field_t *fields; 91} field_t; 92 93/* Bit Stream */ 94typedef struct { 95 unsigned char *buf; 96 unsigned char *beg; 97 unsigned char *end; 98 unsigned char *cur; 99 unsigned bit; 100} bitstr_t; 101 102/* Tool Functions */ 103#define INC_BIT(bs) if((++bs->bit)>7){bs->cur++;bs->bit=0;} 104#define INC_BITS(bs,b) if((bs->bit+=b)>7){bs->cur+=bs->bit>>3;bs->bit&=7;} 105#define BYTE_ALIGN(bs) if(bs->bit){bs->cur++;bs->bit=0;} 106#define CHECK_BOUND(bs,n) if(bs->cur+(n)>bs->end)return(H323_ERROR_BOUND) 107static unsigned get_len(bitstr_t * bs); 108static unsigned get_bit(bitstr_t * bs); 109static unsigned get_bits(bitstr_t * bs, unsigned b); 110static unsigned get_bitmap(bitstr_t * bs, unsigned b); 111static unsigned get_uint(bitstr_t * bs, int b); 112 113/* Decoder Functions */ 114static int decode_nul(bitstr_t * bs, field_t * f, char *base, int level); 115static int decode_bool(bitstr_t * bs, field_t * f, char *base, int level); 116static int decode_oid(bitstr_t * bs, field_t * f, char *base, int level); 117static int decode_int(bitstr_t * bs, field_t * f, char *base, int level); 118static int decode_enum(bitstr_t * bs, field_t * f, char *base, int level); 119static int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level); 120static int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level); 121static int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level); 122static int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level); 123static int decode_seq(bitstr_t * bs, field_t * f, char *base, int level); 124static int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level); 125static int decode_choice(bitstr_t * bs, field_t * f, char *base, int level); 126 127/* Decoder Functions Vector */ 128typedef int (*decoder_t) (bitstr_t *, field_t *, char *, int); 129static decoder_t Decoders[] = { 130 decode_nul, 131 decode_bool, 132 decode_oid, 133 decode_int, 134 decode_enum, 135 decode_bitstr, 136 decode_numstr, 137 decode_octstr, 138 decode_bmpstr, 139 decode_seq, 140 decode_seqof, 141 decode_choice, 142}; 143 144/**************************************************************************** 145 * H.323 Types 146 ****************************************************************************/ 147#include "nf_conntrack_h323_types.c" 148 149/**************************************************************************** 150 * Functions 151 ****************************************************************************/ 152/* Assume bs is aligned && v < 16384 */ 153unsigned get_len(bitstr_t * bs) 154{ 155 unsigned v; 156 157 v = *bs->cur++; 158 159 if (v & 0x80) { 160 v &= 0x3f; 161 v <<= 8; 162 v += *bs->cur++; 163 } 164 165 return v; 166} 167 168/****************************************************************************/ 169unsigned get_bit(bitstr_t * bs) 170{ 171 unsigned b = (*bs->cur) & (0x80 >> bs->bit); 172 173 INC_BIT(bs); 174 175 return b; 176} 177 178/****************************************************************************/ 179/* Assume b <= 8 */ 180unsigned get_bits(bitstr_t * bs, unsigned b) 181{ 182 unsigned v, l; 183 184 v = (*bs->cur) & (0xffU >> bs->bit); 185 l = b + bs->bit; 186 187 if (l < 8) { 188 v >>= 8 - l; 189 bs->bit = l; 190 } else if (l == 8) { 191 bs->cur++; 192 bs->bit = 0; 193 } else { /* l > 8 */ 194 195 v <<= 8; 196 v += *(++bs->cur); 197 v >>= 16 - l; 198 bs->bit = l - 8; 199 } 200 201 return v; 202} 203 204/****************************************************************************/ 205/* Assume b <= 32 */ 206unsigned get_bitmap(bitstr_t * bs, unsigned b) 207{ 208 unsigned v, l, shift, bytes; 209 210 if (!b) 211 return 0; 212 213 l = bs->bit + b; 214 215 if (l < 8) { 216 v = (unsigned) (*bs->cur) << (bs->bit + 24); 217 bs->bit = l; 218 } else if (l == 8) { 219 v = (unsigned) (*bs->cur++) << (bs->bit + 24); 220 bs->bit = 0; 221 } else { 222 for (bytes = l >> 3, shift = 24, v = 0; bytes; 223 bytes--, shift -= 8) 224 v |= (unsigned) (*bs->cur++) << shift; 225 226 if (l < 32) { 227 v |= (unsigned) (*bs->cur) << shift; 228 v <<= bs->bit; 229 } else if (l > 32) { 230 v <<= bs->bit; 231 v |= (*bs->cur) >> (8 - bs->bit); 232 } 233 234 bs->bit = l & 0x7; 235 } 236 237 v &= 0xffffffff << (32 - b); 238 239 return v; 240} 241 242/**************************************************************************** 243 * Assume bs is aligned and sizeof(unsigned int) == 4 244 ****************************************************************************/ 245unsigned get_uint(bitstr_t * bs, int b) 246{ 247 unsigned v = 0; 248 249 switch (b) { 250 case 4: 251 v |= *bs->cur++; 252 v <<= 8; 253 case 3: 254 v |= *bs->cur++; 255 v <<= 8; 256 case 2: 257 v |= *bs->cur++; 258 v <<= 8; 259 case 1: 260 v |= *bs->cur++; 261 break; 262 } 263 return v; 264} 265 266/****************************************************************************/ 267int decode_nul(bitstr_t * bs, field_t * f, char *base, int level) 268{ 269 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); 270 271 return H323_ERROR_NONE; 272} 273 274/****************************************************************************/ 275int decode_bool(bitstr_t * bs, field_t * f, char *base, int level) 276{ 277 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); 278 279 INC_BIT(bs); 280 281 CHECK_BOUND(bs, 0); 282 return H323_ERROR_NONE; 283} 284 285/****************************************************************************/ 286int decode_oid(bitstr_t * bs, field_t * f, char *base, int level) 287{ 288 int len; 289 290 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); 291 292 BYTE_ALIGN(bs); 293 CHECK_BOUND(bs, 1); 294 len = *bs->cur++; 295 bs->cur += len; 296 297 CHECK_BOUND(bs, 0); 298 return H323_ERROR_NONE; 299} 300 301/****************************************************************************/ 302int decode_int(bitstr_t * bs, field_t * f, char *base, int level) 303{ 304 unsigned len; 305 306 PRINT("%*.s%s", level * TAB_SIZE, " ", f->name); 307 308 switch (f->sz) { 309 case BYTE: /* Range == 256 */ 310 BYTE_ALIGN(bs); 311 bs->cur++; 312 break; 313 case WORD: /* 257 <= Range <= 64K */ 314 BYTE_ALIGN(bs); 315 bs->cur += 2; 316 break; 317 case CONS: /* 64K < Range < 4G */ 318 len = get_bits(bs, 2) + 1; 319 BYTE_ALIGN(bs); 320 if (base && (f->attr & DECODE)) { /* timeToLive */ 321 unsigned v = get_uint(bs, len) + f->lb; 322 PRINT(" = %u", v); 323 *((unsigned *) (base + f->offset)) = v; 324 } 325 bs->cur += len; 326 break; 327 case UNCO: 328 BYTE_ALIGN(bs); 329 CHECK_BOUND(bs, 2); 330 len = get_len(bs); 331 bs->cur += len; 332 break; 333 default: /* 2 <= Range <= 255 */ 334 INC_BITS(bs, f->sz); 335 break; 336 } 337 338 PRINT("\n"); 339 340 CHECK_BOUND(bs, 0); 341 return H323_ERROR_NONE; 342} 343 344/****************************************************************************/ 345int decode_enum(bitstr_t * bs, field_t * f, char *base, int level) 346{ 347 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); 348 349 if ((f->attr & EXT) && get_bit(bs)) { 350 INC_BITS(bs, 7); 351 } else { 352 INC_BITS(bs, f->sz); 353 } 354 355 CHECK_BOUND(bs, 0); 356 return H323_ERROR_NONE; 357} 358 359/****************************************************************************/ 360int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level) 361{ 362 unsigned len; 363 364 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); 365 366 BYTE_ALIGN(bs); 367 switch (f->sz) { 368 case FIXD: /* fixed length > 16 */ 369 len = f->lb; 370 break; 371 case WORD: /* 2-byte length */ 372 CHECK_BOUND(bs, 2); 373 len = (*bs->cur++) << 8; 374 len += (*bs->cur++) + f->lb; 375 break; 376 case SEMI: 377 CHECK_BOUND(bs, 2); 378 len = get_len(bs); 379 break; 380 default: 381 len = 0; 382 break; 383 } 384 385 bs->cur += len >> 3; 386 bs->bit = len & 7; 387 388 CHECK_BOUND(bs, 0); 389 return H323_ERROR_NONE; 390} 391 392/****************************************************************************/ 393int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level) 394{ 395 unsigned len; 396 397 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); 398 399 /* 2 <= Range <= 255 */ 400 len = get_bits(bs, f->sz) + f->lb; 401 402 BYTE_ALIGN(bs); 403 INC_BITS(bs, (len << 2)); 404 405 CHECK_BOUND(bs, 0); 406 return H323_ERROR_NONE; 407} 408 409/****************************************************************************/ 410int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level) 411{ 412 unsigned len; 413 414 PRINT("%*.s%s", level * TAB_SIZE, " ", f->name); 415 416 switch (f->sz) { 417 case FIXD: /* Range == 1 */ 418 if (f->lb > 2) { 419 BYTE_ALIGN(bs); 420 if (base && (f->attr & DECODE)) { 421 /* The IP Address */ 422 IFTHEN(f->lb == 4, 423 PRINT(" = %d.%d.%d.%d:%d", 424 bs->cur[0], bs->cur[1], 425 bs->cur[2], bs->cur[3], 426 bs->cur[4] * 256 + bs->cur[5])); 427 *((unsigned *) (base + f->offset)) = 428 bs->cur - bs->buf; 429 } 430 } 431 len = f->lb; 432 break; 433 case BYTE: /* Range == 256 */ 434 BYTE_ALIGN(bs); 435 CHECK_BOUND(bs, 1); 436 len = (*bs->cur++) + f->lb; 437 break; 438 case SEMI: 439 BYTE_ALIGN(bs); 440 CHECK_BOUND(bs, 2); 441 len = get_len(bs) + f->lb; 442 break; 443 default: /* 2 <= Range <= 255 */ 444 len = get_bits(bs, f->sz) + f->lb; 445 BYTE_ALIGN(bs); 446 break; 447 } 448 449 bs->cur += len; 450 451 PRINT("\n"); 452 453 CHECK_BOUND(bs, 0); 454 return H323_ERROR_NONE; 455} 456 457/****************************************************************************/ 458int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level) 459{ 460 unsigned len; 461 462 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); 463 464 switch (f->sz) { 465 case BYTE: /* Range == 256 */ 466 BYTE_ALIGN(bs); 467 CHECK_BOUND(bs, 1); 468 len = (*bs->cur++) + f->lb; 469 break; 470 default: /* 2 <= Range <= 255 */ 471 len = get_bits(bs, f->sz) + f->lb; 472 BYTE_ALIGN(bs); 473 break; 474 } 475 476 bs->cur += len << 1; 477 478 CHECK_BOUND(bs, 0); 479 return H323_ERROR_NONE; 480} 481 482/****************************************************************************/ 483int decode_seq(bitstr_t * bs, field_t * f, char *base, int level) 484{ 485 unsigned ext, bmp, i, opt, len = 0, bmp2, bmp2_len; 486 int err; 487 field_t *son; 488 unsigned char *beg = NULL; 489 490 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); 491 492 /* Decode? */ 493 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; 494 495 /* Extensible? */ 496 ext = (f->attr & EXT) ? get_bit(bs) : 0; 497 498 /* Get fields bitmap */ 499 bmp = get_bitmap(bs, f->sz); 500 if (base) 501 *(unsigned *) base = bmp; 502 503 /* Decode the root components */ 504 for (i = opt = 0, son = f->fields; i < f->lb; i++, son++) { 505 if (son->attr & STOP) { 506 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", 507 son->name); 508 return H323_ERROR_STOP; 509 } 510 511 if (son->attr & OPT) { /* Optional component */ 512 if (!((0x80000000U >> (opt++)) & bmp)) /* Not exist */ 513 continue; 514 } 515 516 /* Decode */ 517 if (son->attr & OPEN) { /* Open field */ 518 CHECK_BOUND(bs, 2); 519 len = get_len(bs); 520 CHECK_BOUND(bs, len); 521 if (!base || !(son->attr & DECODE)) { 522 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, 523 " ", son->name); 524 bs->cur += len; 525 continue; 526 } 527 beg = bs->cur; 528 529 /* Decode */ 530 if ((err = (Decoders[son->type]) (bs, son, base, 531 level + 1)) < 532 H323_ERROR_NONE) 533 return err; 534 535 bs->cur = beg + len; 536 bs->bit = 0; 537 } else if ((err = (Decoders[son->type]) (bs, son, base, 538 level + 1)) < 539 H323_ERROR_NONE) 540 return err; 541 } 542 543 /* No extension? */ 544 if (!ext) 545 return H323_ERROR_NONE; 546 547 /* Get the extension bitmap */ 548 bmp2_len = get_bits(bs, 7) + 1; 549 CHECK_BOUND(bs, (bmp2_len + 7) >> 3); 550 bmp2 = get_bitmap(bs, bmp2_len); 551 bmp |= bmp2 >> f->sz; 552 if (base) 553 *(unsigned *) base = bmp; 554 BYTE_ALIGN(bs); 555 556 /* Decode the extension components */ 557 for (opt = 0; opt < bmp2_len; opt++, i++, son++) { 558 if (i < f->ub && son->attr & STOP) { 559 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", 560 son->name); 561 return H323_ERROR_STOP; 562 } 563 564 if (!((0x80000000 >> opt) & bmp2)) /* Not present */ 565 continue; 566 567 /* Check Range */ 568 if (i >= f->ub) { /* Newer Version? */ 569 CHECK_BOUND(bs, 2); 570 len = get_len(bs); 571 CHECK_BOUND(bs, len); 572 bs->cur += len; 573 continue; 574 } 575 576 CHECK_BOUND(bs, 2); 577 len = get_len(bs); 578 CHECK_BOUND(bs, len); 579 if (!base || !(son->attr & DECODE)) { 580 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", 581 son->name); 582 bs->cur += len; 583 continue; 584 } 585 beg = bs->cur; 586 587 if ((err = (Decoders[son->type]) (bs, son, base, 588 level + 1)) < 589 H323_ERROR_NONE) 590 return err; 591 592 bs->cur = beg + len; 593 bs->bit = 0; 594 } 595 return H323_ERROR_NONE; 596} 597 598/****************************************************************************/ 599int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level) 600{ 601 unsigned count, effective_count = 0, i, len = 0; 602 int err; 603 field_t *son; 604 unsigned char *beg = NULL; 605 606 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); 607 608 /* Decode? */ 609 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; 610 611 /* Decode item count */ 612 switch (f->sz) { 613 case BYTE: 614 BYTE_ALIGN(bs); 615 CHECK_BOUND(bs, 1); 616 count = *bs->cur++; 617 break; 618 case WORD: 619 BYTE_ALIGN(bs); 620 CHECK_BOUND(bs, 2); 621 count = *bs->cur++; 622 count <<= 8; 623 count = *bs->cur++; 624 break; 625 case SEMI: 626 BYTE_ALIGN(bs); 627 CHECK_BOUND(bs, 2); 628 count = get_len(bs); 629 break; 630 default: 631 count = get_bits(bs, f->sz); 632 break; 633 } 634 count += f->lb; 635 636 /* Write Count */ 637 if (base) { 638 effective_count = count > f->ub ? f->ub : count; 639 *(unsigned *) base = effective_count; 640 base += sizeof(unsigned); 641 } 642 643 /* Decode nested field */ 644 son = f->fields; 645 if (base) 646 base -= son->offset; 647 for (i = 0; i < count; i++) { 648 if (son->attr & OPEN) { 649 BYTE_ALIGN(bs); 650 len = get_len(bs); 651 CHECK_BOUND(bs, len); 652 if (!base || !(son->attr & DECODE)) { 653 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, 654 " ", son->name); 655 bs->cur += len; 656 continue; 657 } 658 beg = bs->cur; 659 660 if ((err = (Decoders[son->type]) (bs, son, 661 i < 662 effective_count ? 663 base : NULL, 664 level + 1)) < 665 H323_ERROR_NONE) 666 return err; 667 668 bs->cur = beg + len; 669 bs->bit = 0; 670 } else 671 if ((err = (Decoders[son->type]) (bs, son, 672 i < 673 effective_count ? 674 base : NULL, 675 level + 1)) < 676 H323_ERROR_NONE) 677 return err; 678 679 if (base) 680 base += son->offset; 681 } 682 683 return H323_ERROR_NONE; 684} 685 686 687/****************************************************************************/ 688int decode_choice(bitstr_t * bs, field_t * f, char *base, int level) 689{ 690 unsigned type, ext, len = 0; 691 int err; 692 field_t *son; 693 unsigned char *beg = NULL; 694 695 PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); 696 697 /* Decode? */ 698 base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; 699 700 /* Decode the choice index number */ 701 if ((f->attr & EXT) && get_bit(bs)) { 702 ext = 1; 703 type = get_bits(bs, 7) + f->lb; 704 } else { 705 ext = 0; 706 type = get_bits(bs, f->sz); 707 if (type >= f->lb) 708 return H323_ERROR_RANGE; 709 } 710 711 /* Write Type */ 712 if (base) 713 *(unsigned *) base = type; 714 715 /* Check Range */ 716 if (type >= f->ub) { /* Newer version? */ 717 BYTE_ALIGN(bs); 718 len = get_len(bs); 719 CHECK_BOUND(bs, len); 720 bs->cur += len; 721 return H323_ERROR_NONE; 722 } 723 724 /* Transfer to son level */ 725 son = &f->fields[type]; 726 if (son->attr & STOP) { 727 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", son->name); 728 return H323_ERROR_STOP; 729 } 730 731 if (ext || (son->attr & OPEN)) { 732 BYTE_ALIGN(bs); 733 len = get_len(bs); 734 CHECK_BOUND(bs, len); 735 if (!base || !(son->attr & DECODE)) { 736 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", 737 son->name); 738 bs->cur += len; 739 return H323_ERROR_NONE; 740 } 741 beg = bs->cur; 742 743 if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) < 744 H323_ERROR_NONE) 745 return err; 746 747 bs->cur = beg + len; 748 bs->bit = 0; 749 } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) < 750 H323_ERROR_NONE) 751 return err; 752 753 return H323_ERROR_NONE; 754} 755 756/****************************************************************************/ 757int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras) 758{ 759 static field_t ras_message = { 760 FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT, 761 0, _RasMessage 762 }; 763 bitstr_t bs; 764 765 bs.buf = bs.beg = bs.cur = buf; 766 bs.end = buf + sz; 767 bs.bit = 0; 768 769 return decode_choice(&bs, &ras_message, (char *) ras, 0); 770} 771 772/****************************************************************************/ 773static int DecodeH323_UserInformation(unsigned char *buf, unsigned char *beg, 774 size_t sz, H323_UserInformation * uuie) 775{ 776 static field_t h323_userinformation = { 777 FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT, 778 0, _H323_UserInformation 779 }; 780 bitstr_t bs; 781 782 bs.buf = buf; 783 bs.beg = bs.cur = beg; 784 bs.end = beg + sz; 785 bs.bit = 0; 786 787 return decode_seq(&bs, &h323_userinformation, (char *) uuie, 0); 788} 789 790/****************************************************************************/ 791int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz, 792 MultimediaSystemControlMessage * 793 mscm) 794{ 795 static field_t multimediasystemcontrolmessage = { 796 FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4, 797 DECODE | EXT, 0, _MultimediaSystemControlMessage 798 }; 799 bitstr_t bs; 800 801 bs.buf = bs.beg = bs.cur = buf; 802 bs.end = buf + sz; 803 bs.bit = 0; 804 805 return decode_choice(&bs, &multimediasystemcontrolmessage, 806 (char *) mscm, 0); 807} 808 809/****************************************************************************/ 810int DecodeQ931(unsigned char *buf, size_t sz, Q931 * q931) 811{ 812 unsigned char *p = buf; 813 int len; 814 815 if (!p || sz < 1) 816 return H323_ERROR_BOUND; 817 818 /* Protocol Discriminator */ 819 if (*p != 0x08) { 820 PRINT("Unknown Protocol Discriminator\n"); 821 return H323_ERROR_RANGE; 822 } 823 p++; 824 sz--; 825 826 /* CallReferenceValue */ 827 if (sz < 1) 828 return H323_ERROR_BOUND; 829 len = *p++; 830 sz--; 831 if (sz < len) 832 return H323_ERROR_BOUND; 833 p += len; 834 sz -= len; 835 836 /* Message Type */ 837 if (sz < 1) 838 return H323_ERROR_BOUND; 839 q931->MessageType = *p++; 840 PRINT("MessageType = %02X\n", q931->MessageType); 841 if (*p & 0x80) { 842 p++; 843 sz--; 844 } 845 846 /* Decode Information Elements */ 847 while (sz > 0) { 848 if (*p == 0x7e) { /* UserUserIE */ 849 if (sz < 3) 850 break; 851 p++; 852 len = *p++ << 8; 853 len |= *p++; 854 sz -= 3; 855 if (sz < len) 856 break; 857 p++; 858 len--; 859 return DecodeH323_UserInformation(buf, p, len, 860 &q931->UUIE); 861 } 862 p++; 863 sz--; 864 if (sz < 1) 865 break; 866 len = *p++; 867 if (sz < len) 868 break; 869 p += len; 870 sz -= len; 871 } 872 873 PRINT("Q.931 UUIE not found\n"); 874 875 return H323_ERROR_BOUND; 876} 877