1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <strings.h> 32 #include <errno.h> 33 #include <pthread.h> 34 #include <sip.h> 35 36 #include "sip_msg.h" 37 38 /* 39 * Generic function to get int or string value from a header 40 */ 41 static void * 42 sip_get_val_from_hdr(sip_hdr_value_t *val, int val_type, boolean_t stype, 43 int *error) 44 { 45 if (error != NULL) 46 *error = 0; 47 48 if (val == NULL || val->sip_value_state == SIP_VALUE_DELETED) { 49 if (error != NULL) 50 *error = EINVAL; 51 return (NULL); 52 } 53 54 if (val->sip_value_state == SIP_VALUE_BAD) 55 *error = EPROTO; 56 57 switch (val_type) { 58 case (SIP_INT_VAL): 59 return (&(val->int_val)); 60 case (SIP_STR_VAL): 61 return (&(val->str_val)); 62 case (SIP_STRS_VAL): 63 if (stype == B_TRUE) { 64 if (val->strs_val.s1.sip_str_ptr != NULL) 65 return (&(val->strs_val.s1)); 66 return (NULL); 67 } 68 if (val->strs_val.s2.sip_str_ptr != NULL) 69 return (&(val->strs_val.s2)); 70 return (NULL); 71 case (SIP_INTSTR_VAL): 72 if (stype == B_TRUE) { 73 if (val->intstr_str.sip_str_ptr != NULL) 74 return (&(val->intstr_str)); 75 else 76 return (NULL); 77 } 78 return (&(val->intstr_int)); 79 case (SIP_AUTH_VAL): 80 return (&(val->auth_val)); 81 } 82 if (error != NULL && *error == 0) 83 *error = EINVAL; 84 return (NULL); 85 } 86 87 /* 88 * Generic function to get value from a header given the value type and 89 * the string info (for multi-string values). 90 */ 91 static void * 92 sip_get_val_from_msg(sip_msg_t msg, char *hdr_name, int val_type, 93 boolean_t stype, boolean_t empty_val, int *error) 94 { 95 const _sip_header_t *header; 96 sip_hdr_value_t *value; 97 98 if (error != NULL) 99 *error = 0; 100 if (msg == NULL) { 101 if (error != NULL) 102 *error = EINVAL; 103 return (NULL); 104 } 105 106 header = sip_get_header(msg, hdr_name, NULL, error); 107 if (header == NULL) { 108 if (error != NULL) 109 *error = EINVAL; 110 return (NULL); 111 } 112 113 value = (sip_hdr_value_t *)sip_get_header_value(header, error); 114 if (value == NULL) { 115 if (error != NULL && empty_val == B_FALSE) 116 *error = EPROTO; 117 return (NULL); 118 } 119 return (sip_get_val_from_hdr(value, val_type, stype, error)); 120 } 121 122 /* 123 * Get the URI from the value 124 */ 125 const sip_str_t * 126 sip_get_cftruri_from_val(sip_header_value_t value, int *error) 127 { 128 sip_hdr_value_t *cftrvalue; 129 130 if (error != NULL) 131 *error = 0; 132 133 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 134 if (error != NULL) 135 *error = EINVAL; 136 return (NULL); 137 } 138 cftrvalue = (sip_hdr_value_t *)value; 139 /* 140 * If the value is BAD, update error to reflect it. 141 */ 142 if (error != NULL && value->value_state == SIP_VALUE_BAD) 143 *error = EPROTO; 144 return (&cftrvalue->cftr_uri); 145 } 146 147 /* 148 * Get display name from the value 149 */ 150 const sip_str_t * 151 sip_get_cftrname_from_val(sip_header_value_t value, int *error) 152 { 153 sip_hdr_value_t *cftrvalue; 154 155 if (error != NULL) 156 *error = 0; 157 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 158 if (error != NULL) 159 *error = EINVAL; 160 return (NULL); 161 } 162 cftrvalue = (sip_hdr_value_t *)value; 163 /* 164 * If the value is BAD, update error to reflect it. 165 */ 166 if (error != NULL && value->value_state == SIP_VALUE_BAD) 167 *error = EPROTO; 168 return (cftrvalue->cftr_name); 169 } 170 171 /* 172 * Contact header can have more than one value 173 * so we require a value to be passed in to get a value. 174 */ 175 const sip_str_t * 176 sip_get_contact_uri_str(sip_header_value_t value, int *error) 177 { 178 return (sip_get_cftruri_from_val(value, error)); 179 } 180 181 /* 182 * Contact header can have more than one value 183 * so we require a value to be passed in to get a value. 184 */ 185 const sip_str_t * 186 sip_get_contact_display_name(sip_header_value_t value, int *error) 187 { 188 return (sip_get_cftrname_from_val(value, error)); 189 } 190 191 /* 192 * Route header can have more than one value 193 * so we require a value to be passed in to get a value. 194 */ 195 const sip_str_t * 196 sip_get_route_uri_str(sip_header_value_t value, int *error) 197 { 198 return (sip_get_cftruri_from_val(value, error)); 199 } 200 201 /* 202 * Route header can have more than one value 203 * so we require a value to be passed in to get a value. 204 */ 205 const sip_str_t * 206 sip_get_route_display_name(sip_header_value_t value, int *error) 207 { 208 return (sip_get_cftrname_from_val(value, error)); 209 } 210 211 /* 212 * Get URI from the SIP message 213 */ 214 const sip_str_t * 215 sip_get_cftruri_from_msg(sip_msg_t sip_msg, int *error, char *hdrname) 216 { 217 const sip_hdr_value_t *value; 218 const struct sip_header *header; 219 220 if (error != NULL) 221 *error = 0; 222 if (sip_msg == NULL) { 223 if (error != NULL) 224 *error = EINVAL; 225 return (NULL); 226 } 227 228 header = sip_get_header(sip_msg, hdrname, NULL, error); 229 if (header == NULL) { 230 if (error != NULL) 231 *error = EINVAL; 232 return (NULL); 233 } 234 235 value = (sip_hdr_value_t *)sip_get_header_value(header, error); 236 if (value == NULL) { 237 if (error != NULL) 238 *error = EPROTO; 239 return (NULL); 240 } 241 /* 242 * If the value is BAD, update error to reflect it. 243 */ 244 if (error != NULL && value->sip_value_state == SIP_VALUE_BAD) 245 *error = EPROTO; 246 return (&value->cftr_uri); 247 } 248 249 /* 250 * Get display name from the SIP message 251 */ 252 const sip_str_t * 253 sip_get_cftrname_from_msg(sip_msg_t sip_msg, int *error, char *hdrname) 254 { 255 const sip_hdr_value_t *value; 256 const struct sip_header *header; 257 258 if (error != NULL) 259 *error = 0; 260 if (sip_msg == NULL) { 261 if (error != NULL) 262 *error = EINVAL; 263 return (NULL); 264 } 265 header = sip_get_header(sip_msg, hdrname, NULL, error); 266 if (header == NULL) { 267 if (error != NULL) 268 *error = EINVAL; 269 return (NULL); 270 } 271 272 value = (sip_hdr_value_t *)sip_get_header_value(header, error); 273 if (value == NULL) { 274 if (error != NULL) 275 *error = EPROTO; 276 return (NULL); 277 } 278 /* 279 * If the value is BAD, update error to reflect it. 280 */ 281 if (error != NULL && value->sip_value_state == SIP_VALUE_BAD) 282 *error = EPROTO; 283 return (value->cftr_name); 284 } 285 286 /* 287 * Get FROM URI 288 */ 289 const sip_str_t * 290 sip_get_from_uri_str(sip_msg_t sip_msg, int *error) 291 { 292 return (sip_get_cftruri_from_msg(sip_msg, error, SIP_FROM)); 293 } 294 295 /* 296 * Get FROM display name 297 */ 298 const sip_str_t * 299 sip_get_from_display_name(sip_msg_t sip_msg, int *error) 300 { 301 return (sip_get_cftrname_from_msg(sip_msg, error, SIP_FROM)); 302 } 303 304 /* 305 * Return the FROM tag 306 */ 307 const sip_str_t * 308 sip_get_from_tag(sip_msg_t sip_msg, int *error) 309 { 310 const sip_hdr_value_t *value; 311 const struct sip_header *header; 312 313 if (error != NULL) 314 *error = 0; 315 if (sip_msg == NULL) { 316 if (error != NULL) 317 *error = EINVAL; 318 return (NULL); 319 } 320 header = sip_get_header(sip_msg, SIP_FROM, NULL, error); 321 if (header == NULL) { 322 if (error != NULL) 323 *error = EINVAL; 324 return (NULL); 325 } 326 327 value = (sip_hdr_value_t *)sip_get_header_value(header, error); 328 if (value == NULL) { 329 if (error != NULL) 330 *error = EPROTO; 331 return (NULL); 332 } 333 /* 334 * If the value is BAD, update error to reflect it. 335 */ 336 if (error != NULL && value->sip_value_state == SIP_VALUE_BAD) 337 *error = EPROTO; 338 return (sip_get_param_value((sip_header_value_t)value, "tag", error)); 339 } 340 341 /* 342 * Get TO URI 343 */ 344 const sip_str_t * 345 sip_get_to_uri_str(sip_msg_t sip_msg, int *error) 346 { 347 return (sip_get_cftruri_from_msg(sip_msg, error, SIP_TO)); 348 } 349 350 /* 351 * Get TO display name 352 */ 353 const sip_str_t * 354 sip_get_to_display_name(sip_msg_t sip_msg, int *error) 355 { 356 return (sip_get_cftrname_from_msg(sip_msg, error, SIP_TO)); 357 } 358 359 /* 360 * Get TO tag 361 */ 362 const sip_str_t * 363 sip_get_to_tag(sip_msg_t sip_msg, int *error) 364 { 365 const sip_hdr_value_t *value; 366 const struct sip_header *header; 367 368 if (error != NULL) 369 *error = 0; 370 if (sip_msg == NULL) { 371 if (error != NULL) 372 *error = EINVAL; 373 return (NULL); 374 } 375 header = sip_get_header(sip_msg, SIP_TO, NULL, error); 376 if (header == NULL) { 377 if (error != NULL) 378 *error = EINVAL; 379 return (NULL); 380 } 381 382 value = (sip_hdr_value_t *)sip_get_header_value(header, error); 383 if (value == NULL) { 384 if (error != NULL) 385 *error = EPROTO; 386 return (NULL); 387 } 388 /* 389 * If the value is BAD, update error to reflect it. 390 */ 391 if (error != NULL && value->sip_value_state == SIP_VALUE_BAD) 392 *error = EPROTO; 393 return (sip_get_param_value((sip_header_value_t)value, "tag", error)); 394 } 395 396 /* 397 * Return the Call-Id 398 */ 399 const sip_str_t * 400 sip_get_callid(sip_msg_t sip_msg, int *error) 401 { 402 sip_str_t *r; 403 404 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CALL_ID, SIP_STR_VAL, 405 B_FALSE, B_TRUE, error); 406 return (r); 407 } 408 409 #define SIP_CSEQ_NUM 1 410 #define SIP_CSEQ_METHOD 2 411 412 /* 413 * Get number/method from the CSEQ header 414 */ 415 static void * 416 sip_get_cseq_val(sip_msg_t msg, int type, int *error) 417 { 418 const _sip_header_t *header; 419 sip_hdr_value_t *val; 420 421 if (error != NULL) 422 *error = 0; 423 424 if (msg == NULL) { 425 if (error != NULL) 426 *error = EINVAL; 427 return (NULL); 428 } 429 header = sip_get_header(msg, SIP_CSEQ, NULL, error); 430 if (header == NULL) { 431 if (error != NULL) 432 *error = EINVAL; 433 return (NULL); 434 } 435 val = (sip_hdr_value_t *)sip_get_header_value(header, error); 436 if (val == NULL) { 437 if (error != NULL) 438 *error = EPROTO; 439 return (NULL); 440 } 441 if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD) 442 *error = EPROTO; 443 444 switch (type) { 445 case SIP_CSEQ_NUM: 446 return (&(val->cseq_num)); 447 case SIP_CSEQ_METHOD: 448 return (&(val->cseq_method)); 449 } 450 if (error != NULL) 451 *error = EINVAL; 452 return (NULL); 453 } 454 455 /* 456 * Get CSEQ number 457 */ 458 int 459 sip_get_callseq_num(sip_msg_t sip_msg, int *error) 460 { 461 int *r; 462 463 r = (int *)sip_get_cseq_val(sip_msg, SIP_CSEQ_NUM, error); 464 return (r == NULL ? -1 : *r); 465 } 466 467 /* 468 * Get CSEQ method 469 */ 470 sip_method_t 471 sip_get_callseq_method(sip_msg_t sip_msg, int *error) 472 { 473 sip_method_t *r; 474 475 r = (sip_method_t *)sip_get_cseq_val(sip_msg, SIP_CSEQ_METHOD, error); 476 return (r == NULL ? -1 : *r); 477 } 478 479 /* 480 * Via header can have more than one value 481 * so we require a value to be passed in. 482 */ 483 const sip_str_t * 484 sip_get_via_sent_by_host(sip_header_value_t value, int *error) 485 { 486 sip_hdr_value_t *via_value; 487 488 if (error != NULL) 489 *error = 0; 490 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 491 if (error != NULL) 492 *error = EINVAL; 493 return (NULL); 494 } 495 via_value = (sip_hdr_value_t *)value; 496 if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL) 497 *error = EPROTO; 498 return (&via_value->via_sent_by_host); 499 } 500 501 /* 502 * Via header can have more than one value 503 * so we require a value to be passed in. 504 */ 505 int 506 sip_get_via_sent_by_port(sip_header_value_t value, int *error) 507 { 508 sip_hdr_value_t *via_value; 509 510 if (error != NULL) 511 *error = 0; 512 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 513 if (error != NULL) 514 *error = EINVAL; 515 return (-1); 516 } 517 via_value = (sip_hdr_value_t *)value; 518 if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL) 519 *error = EPROTO; 520 return (via_value->via_sent_by_port); 521 } 522 523 /* 524 * Return the protocol version from the VIA value 525 */ 526 const sip_str_t * 527 sip_get_via_sent_protocol_version(sip_header_value_t value, int *error) 528 { 529 sip_hdr_value_t *via_value; 530 531 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 532 if (error != NULL) 533 *error = EINVAL; 534 return (NULL); 535 } 536 via_value = (sip_hdr_value_t *)value; 537 if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL) 538 *error = EPROTO; 539 return (&via_value->via_protocol_vers); 540 } 541 542 /* 543 * Return the protocol name 544 */ 545 const sip_str_t * 546 sip_get_via_sent_protocol_name(sip_header_value_t value, int *error) 547 { 548 sip_hdr_value_t *via_value; 549 550 if (error != NULL) 551 *error = 0; 552 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 553 if (error != NULL) 554 *error = EINVAL; 555 return (NULL); 556 } 557 via_value = (sip_hdr_value_t *)value; 558 if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL) 559 *error = EPROTO; 560 return (&via_value->via_protocol_name); 561 } 562 563 /* 564 * Return the transport from the VIA value 565 */ 566 const sip_str_t * 567 sip_get_via_sent_transport(sip_header_value_t value, int *error) 568 { 569 sip_hdr_value_t *via_value; 570 571 if (error != NULL) 572 *error = 0; 573 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 574 if (error != NULL) 575 *error = EINVAL; 576 return (NULL); 577 } 578 via_value = (sip_hdr_value_t *)value; 579 if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL) 580 *error = EPROTO; 581 return (&via_value->via_protocol_transport); 582 } 583 584 /* 585 * get the branch id from the topmost VIA header 586 */ 587 char * 588 sip_get_branchid(sip_msg_t sip_msg, int *error) 589 { 590 _sip_header_t *header; 591 sip_parsed_header_t *parsed_header; 592 sip_hdr_value_t *via_value; 593 const sip_str_t *param_value; 594 char *bid; 595 _sip_msg_t *_sip_msg; 596 597 if (error != NULL) 598 *error = 0; 599 600 if (sip_msg == NULL) { 601 if (error != NULL) 602 *error = EINVAL; 603 return (NULL); 604 } 605 606 _sip_msg = (_sip_msg_t *)sip_msg; 607 608 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 609 header = sip_search_for_header(_sip_msg, SIP_VIA, NULL); 610 if (header == NULL) { 611 if (error != NULL) 612 *error = EINVAL; 613 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 614 return (NULL); 615 } 616 if (sip_parse_via_header(header, &parsed_header) != 0) { 617 if (error != NULL) 618 *error = EPROTO; 619 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 620 return (NULL); 621 } 622 if (parsed_header == NULL) { 623 if (error != NULL) 624 *error = EPROTO; 625 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 626 return (NULL); 627 } 628 via_value = (sip_hdr_value_t *)parsed_header->value; 629 if (via_value == NULL || via_value->sip_value_state == SIP_VALUE_BAD) { 630 if (error != NULL) 631 *error = EPROTO; 632 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 633 return (NULL); 634 } 635 param_value = sip_get_param_value((sip_header_value_t)via_value, 636 "branch", error); 637 638 if (param_value == NULL) { 639 if (error != NULL) 640 *error = EINVAL; 641 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 642 return (NULL); 643 } 644 645 bid = (char *)malloc(param_value->sip_str_len + 1); 646 if (bid == NULL) { 647 if (error != NULL) 648 *error = ENOMEM; 649 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 650 return (NULL); 651 } 652 (void) strncpy(bid, param_value->sip_str_ptr, 653 param_value->sip_str_len); 654 bid[param_value->sip_str_len] = '\0'; 655 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 656 return (bid); 657 } 658 659 /* 660 * adds branchid to the topmost VIA header, if a branchid already exists, 661 * returns error. 662 */ 663 int 664 sip_add_branchid_to_via(sip_msg_t sip_msg, char *branchid) 665 { 666 int err = 0; 667 char *param; 668 int plen; 669 sip_header_t via_hdr; 670 _sip_msg_t *_sip_msg; 671 672 if (sip_msg == NULL) 673 return (EINVAL); 674 /* 675 * If there is already a branchid param, error? 676 */ 677 if (sip_get_branchid(sip_msg, NULL) != NULL) 678 return (EINVAL); 679 _sip_msg = (_sip_msg_t *)sip_msg; 680 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 681 via_hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA, NULL); 682 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 683 if (via_hdr == NULL) 684 return (EINVAL); 685 plen = strlen(branchid) + strlen("branch=") + 1; 686 param = malloc(plen); 687 if (param == NULL) 688 return (ENOMEM); 689 (void) snprintf(param, plen, "branch=%s", branchid); 690 691 (void) sip_add_param(via_hdr, param, &err); 692 free(param); 693 694 return (err); 695 } 696 697 /* 698 * returns the number of VIA headers in the SIP message 699 */ 700 int 701 sip_get_num_via(sip_msg_t sip_msg, int *error) 702 { 703 _sip_msg_t *_sip_msg; 704 sip_header_t hdr; 705 int via_cnt = 0; 706 707 if (error != NULL) 708 *error = 0; 709 if (sip_msg == NULL) { 710 if (error != NULL) 711 *error = EINVAL; 712 return (via_cnt); 713 } 714 _sip_msg = (_sip_msg_t *)sip_msg; 715 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 716 hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA, NULL); 717 while (hdr != NULL) { 718 via_cnt++; 719 hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA, 720 hdr); 721 } 722 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 723 return (via_cnt); 724 } 725 726 /* 727 * Return Max-Forward value 728 */ 729 int 730 sip_get_maxforward(sip_msg_t sip_msg, int *error) 731 { 732 int *r; 733 734 r = (int *)sip_get_val_from_msg(sip_msg, SIP_MAX_FORWARDS, SIP_INT_VAL, 735 B_FALSE, B_FALSE, error); 736 if (r == NULL) 737 return (-1); 738 return (*r); 739 } 740 741 /* 742 * Get the content type 743 */ 744 const sip_str_t * 745 sip_get_content_type(sip_msg_t sip_msg, int *error) 746 { 747 sip_str_t *r; 748 749 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_TYPE, 750 SIP_STRS_VAL, B_TRUE, B_FALSE, error); 751 return (r); 752 } 753 754 /* 755 * Get the content sub-type 756 */ 757 const sip_str_t * 758 sip_get_content_sub_type(sip_msg_t sip_msg, int *error) 759 { 760 sip_str_t *r; 761 762 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_TYPE, 763 SIP_STRS_VAL, B_FALSE, B_FALSE, error); 764 return (r); 765 } 766 767 /* 768 * Return the content-length value 769 */ 770 int 771 sip_get_content_length(sip_msg_t sip_msg, int *error) 772 { 773 int *r; 774 775 r = (int *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_LENGTH, 776 SIP_INT_VAL, B_FALSE, B_FALSE, error); 777 if (r == NULL) 778 return (-1); 779 return (*r); 780 } 781 782 /* 783 * get allow-events 784 */ 785 const sip_str_t * 786 sip_get_allow_events(sip_header_value_t value, int *error) 787 { 788 sip_str_t *r; 789 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 790 791 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_TRUE, error); 792 return (r); 793 } 794 795 /* 796 * get event 797 */ 798 const sip_str_t * 799 sip_get_event(sip_msg_t sip_msg, int *error) 800 { 801 sip_str_t *r; 802 803 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_EVENT, SIP_STR_VAL, 804 B_FALSE, B_FALSE, error); 805 return (r); 806 } 807 808 /* 809 * get subscription state 810 */ 811 const sip_str_t * 812 sip_get_substate(sip_msg_t sip_msg, int *error) 813 { 814 sip_str_t *r; 815 816 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SUBSCRIPTION_STATE, 817 SIP_STR_VAL, B_FALSE, B_FALSE, error); 818 return (r); 819 } 820 821 /* 822 * get accept type 823 */ 824 const sip_str_t * 825 sip_get_accept_type(sip_header_value_t value, int *error) 826 { 827 sip_str_t *r; 828 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 829 830 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_TRUE, error); 831 return (r); 832 } 833 834 /* 835 * get accept subtype 836 */ 837 const sip_str_t * 838 sip_get_accept_sub_type(sip_header_value_t value, int *error) 839 { 840 sip_str_t *r; 841 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 842 843 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_FALSE, 844 error); 845 return (r); 846 } 847 848 /* 849 * accept-encode can have more than one value 850 */ 851 const sip_str_t * 852 sip_get_accept_enc(sip_header_value_t value, int *error) 853 { 854 sip_str_t *r; 855 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 856 857 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 858 return (r); 859 } 860 861 /* 862 * accept-language can have more than one value 863 */ 864 const sip_str_t * 865 sip_get_accept_lang(sip_header_value_t value, int *error) 866 { 867 sip_str_t *r; 868 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 869 870 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 871 return (r); 872 } 873 874 /* 875 * get URI from the alert-info header 876 */ 877 const sip_str_t * 878 sip_get_alert_info_uri(sip_header_value_t value, int *error) 879 { 880 sip_str_t *r; 881 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 882 883 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 884 return (r); 885 } 886 887 /* 888 * get method from allow header 889 */ 890 sip_method_t 891 sip_get_allow_method(sip_header_value_t value, int *error) 892 { 893 int *r; 894 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 895 896 r = (int *)sip_get_val_from_hdr(val, SIP_INT_VAL, B_FALSE, error); 897 return (r == NULL ? -1 : (sip_method_t)*r); 898 } 899 900 /* 901 * get URI from call-info header 902 */ 903 const sip_str_t * 904 sip_get_call_info_uri(sip_header_value_t value, int *error) 905 { 906 sip_str_t *r; 907 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 908 909 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 910 return (r); 911 } 912 913 /* 914 * get content-disposition value 915 */ 916 const sip_str_t * 917 sip_get_content_disp(sip_msg_t sip_msg, int *error) 918 { 919 sip_str_t *r; 920 921 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_DIS, 922 SIP_STR_VAL, B_FALSE, B_FALSE, error); 923 return (r); 924 } 925 926 /* 927 * get content-encoding value 928 */ 929 const sip_str_t * 930 sip_get_content_enc(sip_header_value_t value, int *error) 931 { 932 sip_str_t *r; 933 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 934 935 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 936 return (r); 937 } 938 939 /* 940 * get content-language value 941 */ 942 const sip_str_t * 943 sip_get_content_lang(sip_header_value_t value, int *error) 944 { 945 sip_str_t *r; 946 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 947 948 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 949 return (r); 950 } 951 952 /* 953 * sip_get_date_time, day, wkday, month, year 954 */ 955 #define D_TIME 0x01 956 #define D_DAY 0x02 957 #define D_MONTH 0x03 958 #define D_YEAR 0x04 959 #define D_WKDAY 0x05 960 #define D_TIMEZONE 0x06 961 962 /* 963 * get date information 964 */ 965 static void * 966 sip_get_date_val(sip_msg_t msg, int type, int *error) 967 { 968 const _sip_header_t *header; 969 sip_hdr_value_t *val; 970 971 if (error != NULL) 972 *error = 0; 973 if (msg == NULL) { 974 if (error != NULL) 975 *error = EINVAL; 976 return (NULL); 977 } 978 header = sip_get_header(msg, SIP_DATE, NULL, error); 979 if (header == NULL) { 980 if (error != NULL) 981 *error = EINVAL; 982 return (NULL); 983 } 984 985 val = (sip_hdr_value_t *)sip_get_header_value(header, error); 986 if (val == NULL) { 987 if (error != NULL) 988 *error = EPROTO; 989 return (NULL); 990 } 991 if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD) 992 *error = EPROTO; 993 switch (type) { 994 case (D_TIME): 995 return (&(val->date_t)); 996 case (D_DAY): 997 return (&(val->date_d)); 998 case (D_MONTH): 999 return (&(val->date_m)); 1000 case (D_YEAR): 1001 return (&(val->date_y)); 1002 case (D_WKDAY): 1003 return (&(val->date_wd)); 1004 case (D_TIMEZONE): 1005 return (&(val->date_tz)); 1006 } 1007 if (error != NULL) 1008 *error = EINVAL; 1009 return (NULL); 1010 } 1011 1012 /* 1013 * get time value 1014 */ 1015 const sip_str_t * 1016 sip_get_date_time(sip_msg_t sip_msg, int *error) 1017 { 1018 sip_str_t *r; 1019 1020 r = (sip_str_t *)sip_get_date_val(sip_msg, D_TIME, error); 1021 return (r); 1022 } 1023 1024 /* 1025 * get day 1026 */ 1027 int 1028 sip_get_date_day(sip_msg_t sip_msg, int *error) 1029 { 1030 int *r = NULL; 1031 1032 r = sip_get_date_val(sip_msg, D_DAY, error); 1033 return (r == NULL ? -1 : *(int *)r); 1034 } 1035 1036 /* 1037 * get month 1038 */ 1039 const sip_str_t * 1040 sip_get_date_month(sip_msg_t sip_msg, int *error) 1041 { 1042 sip_str_t *r; 1043 1044 r = (sip_str_t *)sip_get_date_val(sip_msg, D_MONTH, error); 1045 return (r); 1046 } 1047 1048 /* 1049 * get year 1050 */ 1051 int 1052 sip_get_date_year(sip_msg_t sip_msg, int *error) 1053 { 1054 int *r; 1055 1056 r = (int *)sip_get_date_val(sip_msg, D_YEAR, error); 1057 return (r == NULL ? -1 : *r); 1058 } 1059 1060 /* 1061 * get day of the week 1062 */ 1063 const sip_str_t * 1064 sip_get_date_wkday(sip_msg_t sip_msg, int *error) 1065 { 1066 sip_str_t *r; 1067 1068 r = (sip_str_t *)sip_get_date_val(sip_msg, D_WKDAY, error); 1069 return (r); 1070 } 1071 1072 /* 1073 * get the timezone 1074 */ 1075 const sip_str_t * 1076 sip_get_date_timezone(sip_msg_t sip_msg, int *error) 1077 { 1078 sip_str_t *r; 1079 1080 r = (sip_str_t *)sip_get_date_val(sip_msg, D_TIMEZONE, error); 1081 return (r); 1082 } 1083 1084 /* 1085 * get error-info URI 1086 */ 1087 const sip_str_t * 1088 sip_get_error_info_uri(sip_header_value_t value, int *error) 1089 { 1090 sip_str_t *r; 1091 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 1092 1093 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 1094 return (r); 1095 } 1096 1097 /* 1098 * get priv-value from privacy 1099 */ 1100 const sip_str_t * 1101 sip_get_priv_value(sip_header_value_t value, int *error) 1102 { 1103 sip_str_t *r; 1104 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 1105 1106 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 1107 return (r); 1108 } 1109 1110 /* 1111 * return expires value 1112 */ 1113 int 1114 sip_get_expires(sip_msg_t sip_msg, int *error) 1115 { 1116 int *r; 1117 1118 r = (int *)sip_get_val_from_msg(sip_msg, SIP_EXPIRE, SIP_INT_VAL, 1119 B_FALSE, B_FALSE, error); 1120 if (r == NULL) 1121 return (-1); 1122 return (*r); 1123 } 1124 1125 /* 1126 * get reply-to value 1127 */ 1128 const sip_str_t * 1129 sip_get_in_reply_to(sip_header_value_t value, int *error) 1130 { 1131 sip_str_t *r; 1132 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 1133 1134 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 1135 return (r); 1136 } 1137 1138 /* 1139 * get min-expires value 1140 */ 1141 int 1142 sip_get_min_expires(sip_msg_t sip_msg, int *error) 1143 { 1144 int *r; 1145 1146 r = (int *)sip_get_val_from_msg(sip_msg, SIP_MIN_EXPIRE, SIP_INT_VAL, 1147 B_FALSE, B_FALSE, error); 1148 if (r == NULL) 1149 return (-1); 1150 return (*r); 1151 } 1152 1153 /* 1154 * get mime-version 1155 */ 1156 const sip_str_t * 1157 sip_get_mime_version(sip_msg_t sip_msg, int *error) 1158 { 1159 sip_str_t *r; 1160 1161 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_MIME_VERSION, 1162 SIP_STR_VAL, B_FALSE, B_FALSE, error); 1163 return (r); 1164 } 1165 1166 /* 1167 * get organization value 1168 */ 1169 const sip_str_t * 1170 sip_get_org(sip_msg_t sip_msg, int *error) 1171 { 1172 sip_str_t *r; 1173 1174 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_ORGANIZATION, 1175 SIP_STR_VAL, B_FALSE, B_TRUE, error); 1176 return (r); 1177 } 1178 1179 /* 1180 * get priority value 1181 */ 1182 const sip_str_t * 1183 sip_get_priority(sip_msg_t sip_msg, int *error) 1184 { 1185 sip_str_t *r; 1186 1187 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_PRIORITY, 1188 SIP_STR_VAL, B_FALSE, B_FALSE, error); 1189 return (r); 1190 } 1191 1192 /* 1193 * get display name 1194 */ 1195 const sip_str_t * 1196 sip_get_pidentity_display_name(sip_header_value_t value, int *error) 1197 { 1198 sip_str_t *r; 1199 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 1200 1201 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_TRUE, error); 1202 1203 return (r); 1204 } 1205 1206 /* 1207 * get URI 1208 */ 1209 const sip_str_t * 1210 sip_get_pidenty_uri_str(sip_header_value_t value, int *error) 1211 { 1212 sip_str_t *r; 1213 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 1214 1215 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_FALSE, 1216 error); 1217 1218 return (r); 1219 } 1220 1221 /* 1222 * get display name from passerted-identity header 1223 */ 1224 const sip_str_t * 1225 sip_get_passertedid_display_name(sip_header_value_t value, int *error) 1226 { 1227 return (sip_get_pidentity_display_name(value, error)); 1228 } 1229 1230 /* 1231 * get URI from passerted-identity header 1232 */ 1233 const sip_str_t * 1234 sip_get_passertedid_uri_str(sip_header_value_t value, int *error) 1235 { 1236 return (sip_get_pidenty_uri_str(value, error)); 1237 } 1238 1239 /* 1240 * get display name from ppreferred-identity header 1241 */ 1242 const sip_str_t * 1243 sip_get_ppreferredid_display_name(sip_header_value_t value, int *error) 1244 { 1245 return (sip_get_pidentity_display_name(value, error)); 1246 } 1247 1248 /* 1249 * get URI from ppreferred-identity header 1250 */ 1251 const sip_str_t * 1252 sip_get_ppreferredid_uri_str(sip_header_value_t value, int *error) 1253 { 1254 return (sip_get_pidenty_uri_str(value, error)); 1255 } 1256 1257 #define SIP_RACK_RESP_NUM 1 1258 #define SIP_RACK_CSEQ_NUM 2 1259 #define SIP_RACK_METHOD 3 1260 1261 /* 1262 * Get rack information 1263 */ 1264 static void * 1265 sip_get_rack_val(sip_msg_t msg, int type, int *error) 1266 { 1267 const _sip_header_t *header; 1268 sip_hdr_value_t *val; 1269 1270 if (error != NULL) 1271 *error = 0; 1272 1273 if (msg == NULL) { 1274 if (error != NULL) 1275 *error = EINVAL; 1276 return (NULL); 1277 } 1278 header = sip_get_header(msg, SIP_RACK, NULL, error); 1279 if (header == NULL) { 1280 if (error != NULL) 1281 *error = EINVAL; 1282 return (NULL); 1283 } 1284 val = (sip_hdr_value_t *)sip_get_header_value(header, error); 1285 if (val == NULL) { 1286 if (error != NULL) 1287 *error = EPROTO; 1288 return (NULL); 1289 } 1290 if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD) 1291 *error = EPROTO; 1292 1293 switch (type) { 1294 case SIP_RACK_RESP_NUM: 1295 return (&(val->rack_resp)); 1296 case SIP_RACK_CSEQ_NUM: 1297 return (&(val->rack_cseq)); 1298 case SIP_RACK_METHOD: 1299 return (&(val->rack_method)); 1300 } 1301 if (error != NULL) 1302 *error = EINVAL; 1303 return (NULL); 1304 } 1305 1306 /* 1307 * get response number for rack 1308 */ 1309 int 1310 sip_get_rack_resp_num(sip_msg_t sip_msg, int *error) 1311 { 1312 int *r; 1313 1314 r = (int *)sip_get_rack_val(sip_msg, SIP_RACK_RESP_NUM, error); 1315 1316 return (r == NULL ? -1 : *r); 1317 } 1318 1319 /* 1320 * get sequence number for rack 1321 */ 1322 int 1323 sip_get_rack_cseq_num(sip_msg_t sip_msg, int *error) 1324 { 1325 int *r; 1326 1327 r = (int *)sip_get_rack_val(sip_msg, SIP_RACK_CSEQ_NUM, error); 1328 1329 return (r == NULL ? -1 : *r); 1330 } 1331 1332 /* 1333 * get method for rack 1334 */ 1335 sip_method_t 1336 sip_get_rack_method(sip_msg_t sip_msg, int *error) 1337 { 1338 sip_method_t *r; 1339 1340 r = (sip_method_t *)sip_get_rack_val(sip_msg, SIP_RACK_METHOD, error); 1341 1342 return (r == NULL ? -1 : *r); 1343 } 1344 1345 /* 1346 * get response number from rseq 1347 */ 1348 int 1349 sip_get_rseq_resp_num(sip_msg_t sip_msg, int *error) 1350 { 1351 int *r; 1352 1353 r = (int *)sip_get_val_from_msg(sip_msg, SIP_RSEQ, SIP_INT_VAL, 1354 B_FALSE, B_FALSE, error); 1355 1356 return (r == NULL ? -1 : *r); 1357 } 1358 1359 /* 1360 * get reply-to display name 1361 */ 1362 const sip_str_t * 1363 sip_get_replyto_display_name(sip_msg_t sip_msg, int *error) 1364 { 1365 sip_str_t *r; 1366 1367 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_REPLYTO, 1368 SIP_STRS_VAL, B_TRUE, B_FALSE, error); 1369 return (r); 1370 } 1371 1372 /* 1373 * get reply-to URI 1374 */ 1375 const sip_str_t * 1376 sip_get_replyto_uri_str(sip_msg_t sip_msg, int *error) 1377 { 1378 sip_str_t *r; 1379 1380 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_REPLYTO, 1381 SIP_STRS_VAL, B_FALSE, B_FALSE, error); 1382 1383 return (r); 1384 } 1385 1386 /* 1387 * get require value 1388 */ 1389 const sip_str_t * 1390 sip_get_require(sip_header_value_t value, int *error) 1391 { 1392 sip_str_t *r; 1393 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 1394 1395 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 1396 return (r); 1397 } 1398 1399 /* 1400 * get retry-after time 1401 */ 1402 int 1403 sip_get_retry_after_time(sip_msg_t sip_msg, int *error) 1404 { 1405 int *t; 1406 1407 t = (int *)sip_get_val_from_msg(sip_msg, SIP_RETRY_AFTER, 1408 SIP_INTSTR_VAL, B_FALSE, B_FALSE, error); 1409 if (t == NULL) 1410 return (-1); 1411 return (*t); 1412 } 1413 1414 /* 1415 * get retry-after comments 1416 */ 1417 const sip_str_t * 1418 sip_get_retry_after_cmts(sip_msg_t sip_msg, int *error) 1419 { 1420 sip_str_t *r; 1421 1422 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_RETRY_AFTER, 1423 SIP_INTSTR_VAL, B_TRUE, B_FALSE, error); 1424 return (r); 1425 } 1426 1427 /* 1428 * get subject 1429 */ 1430 const sip_str_t * 1431 sip_get_subject(sip_msg_t sip_msg, int *error) 1432 { 1433 sip_str_t *r; 1434 1435 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SUBJECT, SIP_STR_VAL, 1436 B_FALSE, B_TRUE, error); 1437 return (r); 1438 } 1439 1440 /* 1441 * get supported 1442 */ 1443 const sip_str_t * 1444 sip_get_supported(sip_header_value_t value, int *error) 1445 { 1446 sip_str_t *r; 1447 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 1448 1449 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 1450 return (r); 1451 } 1452 1453 /* 1454 * get timestamp delay 1455 */ 1456 const sip_str_t * 1457 sip_get_tstamp_delay(sip_msg_t sip_msg, int *error) 1458 { 1459 sip_str_t *t; 1460 1461 t = sip_get_val_from_msg(sip_msg, SIP_TIMESTAMP, SIP_STRS_VAL, B_FALSE, 1462 B_FALSE, error); 1463 return (t); 1464 } 1465 1466 /* 1467 * get timestamp 1468 */ 1469 const sip_str_t * 1470 sip_get_tstamp_value(sip_msg_t sip_msg, int *error) 1471 { 1472 sip_str_t *t; 1473 1474 t = sip_get_val_from_msg(sip_msg, SIP_TIMESTAMP, SIP_STRS_VAL, B_TRUE, 1475 B_FALSE, error); 1476 return (t); 1477 } 1478 1479 /* 1480 * get unsupported value 1481 */ 1482 const sip_str_t * 1483 sip_get_unsupported(sip_header_value_t value, int *error) 1484 { 1485 sip_str_t *r; 1486 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 1487 1488 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 1489 return (r); 1490 } 1491 1492 /* 1493 * get server value from message 1494 */ 1495 const sip_str_t * 1496 sip_get_server(sip_msg_t sip_msg, int *error) 1497 { 1498 sip_str_t *r; 1499 1500 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SERVER, SIP_STR_VAL, 1501 B_FALSE, B_FALSE, error); 1502 return (r); 1503 } 1504 1505 /* 1506 * get user-agent value 1507 */ 1508 const sip_str_t * 1509 sip_get_user_agent(sip_msg_t sip_msg, int *error) 1510 { 1511 sip_str_t *r; 1512 1513 r = sip_get_val_from_msg(sip_msg, SIP_USER_AGENT, SIP_STR_VAL, B_FALSE, 1514 B_FALSE, error); 1515 return (r); 1516 } 1517 1518 #define W_CODE 0x05 1519 #define W_AGENT 0x06 1520 #define W_TEXT 0x07 1521 1522 /* 1523 * get warning info 1524 */ 1525 static void * 1526 sip_get_warninfo(sip_header_value_t value, int info, int *error) 1527 { 1528 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 1529 1530 if (error != NULL) 1531 *error = 0; 1532 1533 if (val == NULL) { 1534 if (error != NULL) 1535 *error = EINVAL; 1536 return (NULL); 1537 } 1538 1539 if (val->sip_value_state == SIP_VALUE_BAD) { 1540 *error = EPROTO; 1541 return (NULL); 1542 } 1543 1544 switch (info) { 1545 case (W_CODE): 1546 return (&(val->warn_code)); 1547 case (W_AGENT): 1548 return (&(val->warn_agt)); 1549 case (W_TEXT): 1550 return (&(val->warn_text)); 1551 } 1552 if (error != NULL) 1553 *error = EINVAL; 1554 return (NULL); 1555 } 1556 1557 /* 1558 * get warning code 1559 */ 1560 int 1561 sip_get_warning_code(sip_header_value_t value, int *error) 1562 { 1563 int *c; 1564 1565 if (error != NULL) 1566 *error = 0; 1567 1568 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 1569 if (error != NULL) 1570 *error = EINVAL; 1571 return (-1); 1572 } 1573 c = (int *)sip_get_warninfo(value, W_CODE, error); 1574 if (c == NULL) 1575 return (-1); 1576 return (*c); 1577 } 1578 1579 /* 1580 * get warning agent 1581 */ 1582 const sip_str_t * 1583 sip_get_warning_agent(sip_header_value_t value, int *error) 1584 { 1585 sip_str_t *r; 1586 1587 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 1588 if (error != NULL) 1589 *error = EINVAL; 1590 return (NULL); 1591 } 1592 r = (sip_str_t *)sip_get_warninfo(value, W_AGENT, error); 1593 return (r); 1594 } 1595 1596 /* 1597 * get warning text 1598 */ 1599 const sip_str_t * 1600 sip_get_warning_text(sip_header_value_t value, int *error) 1601 { 1602 sip_str_t *r; 1603 1604 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 1605 if (error != NULL) 1606 *error = EINVAL; 1607 return (NULL); 1608 } 1609 r = (sip_str_t *)sip_get_warninfo(value, W_TEXT, error); 1610 return (r); 1611 } 1612 1613 /* 1614 * get authorization scheme 1615 */ 1616 const sip_str_t * 1617 sip_get_author_scheme(sip_msg_t sip_msg, int *error) 1618 { 1619 sip_str_t *r; 1620 1621 r = sip_get_val_from_msg(sip_msg, SIP_AUTHOR, SIP_AUTH_VAL, B_FALSE, 1622 B_FALSE, error); 1623 return (r); 1624 } 1625 1626 /* 1627 * get authentication parameter 1628 */ 1629 static const sip_str_t * 1630 sip_get_auth_param(sip_msg_t msg, char *hdr_name, char *pname, int *error) 1631 { 1632 const _sip_header_t *header; 1633 sip_hdr_value_t *value; 1634 sip_param_t *param; 1635 1636 if (error != NULL) 1637 *error = 0; 1638 1639 if (msg == NULL || pname == NULL || hdr_name == NULL) { 1640 if (error != NULL) 1641 *error = EINVAL; 1642 return (NULL); 1643 } 1644 1645 header = sip_get_header(msg, hdr_name, NULL, error); 1646 if (header == NULL) { 1647 if (error != NULL) 1648 *error = EINVAL; 1649 return (NULL); 1650 } 1651 1652 value = (sip_hdr_value_t *)sip_get_header_value(header, error); 1653 if (value == NULL) { 1654 if (error != NULL) 1655 *error = EPROTO; 1656 return (NULL); 1657 } 1658 1659 param = sip_get_param_from_list(value->auth_param, pname); 1660 if (param != NULL) 1661 return (¶m->param_value); 1662 return (NULL); 1663 } 1664 1665 /* 1666 * get authentication parameter 1667 */ 1668 const sip_str_t * 1669 sip_get_author_param(sip_msg_t sip_msg, char *name, int *error) 1670 { 1671 const sip_str_t *r; 1672 1673 r = sip_get_auth_param(sip_msg, SIP_AUTHOR, name, error); 1674 return (r); 1675 } 1676 1677 /* 1678 * get authentication info 1679 */ 1680 const sip_str_t * 1681 sip_get_authen_info(sip_header_value_t value, int *error) 1682 { 1683 sip_str_t *r; 1684 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 1685 1686 if (error != NULL) 1687 *error = 0; 1688 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 1689 if (error != NULL) 1690 *error = EINVAL; 1691 return (NULL); 1692 } 1693 r = sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 1694 return (r); 1695 } 1696 1697 /* 1698 * get proxy-authentication scheme 1699 */ 1700 const sip_str_t * 1701 sip_get_proxy_authen_scheme(sip_msg_t msg, int *error) 1702 { 1703 sip_str_t *r; 1704 1705 r = sip_get_val_from_msg(msg, SIP_PROXY_AUTHEN, SIP_AUTH_VAL, B_FALSE, 1706 B_FALSE, error); 1707 return (r); 1708 } 1709 1710 /* 1711 * get proxy authentication parameter 1712 */ 1713 const sip_str_t * 1714 sip_get_proxy_authen_param(sip_msg_t sip_msg, char *name, int *error) 1715 { 1716 const sip_str_t *r; 1717 1718 r = sip_get_auth_param(sip_msg, SIP_PROXY_AUTHEN, name, error); 1719 return (r); 1720 } 1721 1722 /* 1723 * get proxy-authorization scheme 1724 */ 1725 const sip_str_t * 1726 sip_get_proxy_author_scheme(sip_msg_t msg, int *error) 1727 { 1728 sip_str_t *r; 1729 1730 r = sip_get_val_from_msg(msg, SIP_PROXY_AUTHOR, SIP_AUTH_VAL, B_FALSE, 1731 B_FALSE, error); 1732 return (r); 1733 } 1734 1735 /* 1736 * get proxy-authorization parameter 1737 */ 1738 const sip_str_t * 1739 sip_get_proxy_author_param(sip_msg_t sip_msg, char *name, int *error) 1740 { 1741 const sip_str_t *r; 1742 1743 r = sip_get_auth_param(sip_msg, SIP_PROXY_AUTHOR, name, error); 1744 return (r); 1745 } 1746 1747 /* 1748 * get proxy-require 1749 */ 1750 const sip_str_t * 1751 sip_get_proxy_require(sip_header_value_t value, int *error) 1752 { 1753 sip_str_t *r; 1754 sip_hdr_value_t *val = (sip_hdr_value_t *)value; 1755 1756 if (error != NULL) 1757 *error = 0; 1758 if (value == NULL || value->value_state == SIP_VALUE_DELETED) { 1759 if (error != NULL) 1760 *error = EINVAL; 1761 return (NULL); 1762 } 1763 r = sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); 1764 return (r); 1765 } 1766 1767 /* 1768 * get www-authentication scheme 1769 */ 1770 const sip_str_t * 1771 sip_get_www_authen_scheme(sip_msg_t msg, int *error) 1772 { 1773 sip_str_t *r; 1774 1775 r = sip_get_val_from_msg(msg, SIP_WWW_AUTHEN, SIP_AUTH_VAL, B_FALSE, 1776 B_FALSE, error); 1777 return (r); 1778 } 1779 1780 /* 1781 * get www-authentication parameter 1782 */ 1783 const sip_str_t * 1784 sip_get_www_authen_param(sip_msg_t sip_msg, char *name, int *error) 1785 { 1786 const sip_str_t *r; 1787 1788 r = sip_get_auth_param(sip_msg, SIP_WWW_AUTHEN, name, error); 1789 return (r); 1790 } 1791