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