12882Svi117747 /* 22882Svi117747 * CDDL HEADER START 32882Svi117747 * 42882Svi117747 * The contents of this file are subject to the terms of the 52882Svi117747 * Common Development and Distribution License (the "License"). 62882Svi117747 * You may not use this file except in compliance with the License. 72882Svi117747 * 82882Svi117747 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92882Svi117747 * or http://www.opensolaris.org/os/licensing. 102882Svi117747 * See the License for the specific language governing permissions 112882Svi117747 * and limitations under the License. 122882Svi117747 * 132882Svi117747 * When distributing Covered Code, include this CDDL HEADER in each 142882Svi117747 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152882Svi117747 * If applicable, add the following below this CDDL HEADER, with the 162882Svi117747 * fields enclosed by brackets "[]" replaced with your own identifying 172882Svi117747 * information: Portions Copyright [yyyy] [name of copyright owner] 182882Svi117747 * 192882Svi117747 * CDDL HEADER END 202882Svi117747 */ 212882Svi117747 222882Svi117747 /* 23*3439Svi117747 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 242882Svi117747 * Use is subject to license terms. 252882Svi117747 */ 262882Svi117747 272882Svi117747 #pragma ident "%Z%%M% %I% %E% SMI" 282882Svi117747 29*3439Svi117747 #include <stdio.h> 30*3439Svi117747 #include <assert.h> 31*3439Svi117747 #include <errno.h> 32*3439Svi117747 #include <pthread.h> 33*3439Svi117747 #include <stdlib.h> 34*3439Svi117747 #include <string.h> 35*3439Svi117747 #include <sip.h> 36*3439Svi117747 372882Svi117747 #include "sip_msg.h" 382882Svi117747 #include "sip_miscdefs.h" 392882Svi117747 #include "sip_parse_generic.h" 402882Svi117747 412882Svi117747 sip_methods_t sip_methods[MAX_SIP_METHODS] = { 422882Svi117747 {"UNKNOWN", 7}, 432882Svi117747 {"INVITE", 6}, 442882Svi117747 {"ACK", 3}, 452882Svi117747 {"OPTIONS", 7}, 462882Svi117747 {"BYE", 3}, 472882Svi117747 {"CANCEL", 6}, 482882Svi117747 {"REGISTER", 8}, 492882Svi117747 {"REFER", 5}, 502882Svi117747 {"INFO", 4}, 512882Svi117747 {"SUBSCRIBE", 9}, 522882Svi117747 {"NOTIFY", 6}, 532882Svi117747 {"PRACK", 5} 542882Svi117747 }; 552882Svi117747 562882Svi117747 /* 572882Svi117747 * Built-In Header function table 582882Svi117747 */ 592882Svi117747 sip_header_function_t sip_header_function_table[] = { 602882Svi117747 {"Unknown", NULL, sip_parse_unknown_header, NULL, NULL, NULL}, 612882Svi117747 {"CONTACT", "m", sip_parse_cftr_header, NULL, NULL, 622882Svi117747 sip_free_cftr_header}, 632882Svi117747 {"FROM", "F", sip_parse_cftr_header, NULL, NULL, sip_free_cftr_header}, 642882Svi117747 {"TO", "T", sip_parse_cftr_header, NULL, NULL, sip_free_cftr_header}, 652882Svi117747 {"CONTENT-LENGTH", "l", sip_parse_clen_header, NULL, NULL, 662882Svi117747 sip_free_phdr}, 672882Svi117747 {"CONTENT-TYPE", "c", sip_parse_ctype_header, NULL, NULL, 682882Svi117747 sip_free_phdr}, 692882Svi117747 {"CALL-ID", "i", sip_parse_cid_header, NULL, NULL, sip_free_phdr}, 702882Svi117747 {"CSEQ", NULL, sip_parse_cseq_header, NULL, NULL, sip_free_phdr}, 712882Svi117747 {"VIA", "v", sip_parse_via_header, NULL, NULL, sip_free_phdr}, 722882Svi117747 {"Max-Forwards", NULL, sip_parse_maxf_header, NULL, NULL, 732882Svi117747 sip_free_phdr}, 742882Svi117747 {"RECORD-ROUTE", NULL, sip_parse_cftr_header, NULL, NULL, 752882Svi117747 sip_free_cftr_header}, 762882Svi117747 {"ROUTE", NULL, sip_parse_cftr_header, NULL, NULL, 772882Svi117747 sip_free_cftr_header}, 782882Svi117747 {"ACCEPT", NULL, sip_parse_acpt_header, NULL, NULL, sip_free_phdr}, 792882Svi117747 {"ACCEPT-ENCODING", NULL, sip_parse_acpt_encode_header, NULL, NULL, 802882Svi117747 sip_free_phdr}, 812882Svi117747 {"ACCEPT-LANGUAGE", NULL, sip_parse_acpt_lang_header, NULL, NULL, 822882Svi117747 sip_free_phdr}, 832882Svi117747 {"ALERT-INFO", NULL, sip_parse_alert_header, NULL, NULL, sip_free_phdr}, 842882Svi117747 {"ALLOW", NULL, sip_parse_allow_header, NULL, NULL, sip_free_phdr}, 852882Svi117747 {"CALL-INFO", NULL, sip_parse_callinfo_header, NULL, NULL, 862882Svi117747 sip_free_phdr}, 872882Svi117747 {"CONTENT-DISPOSITION", NULL, sip_parse_contentdis_header, NULL, NULL, 882882Svi117747 sip_free_phdr}, 892882Svi117747 {"CONTENT-ENCODING", "e", sip_parse_contentencode_header, NULL, NULL, 902882Svi117747 sip_free_phdr}, 912882Svi117747 {"CONTENT-LANGUAGE", NULL, sip_parse_contentlang_header, NULL, NULL, 922882Svi117747 sip_free_phdr}, 932882Svi117747 {"DATE", NULL, sip_parse_date_header, NULL, NULL, sip_free_phdr}, 942882Svi117747 {"ERROR-INFO", NULL, sip_parse_errorinfo_header, NULL, NULL, 952882Svi117747 sip_free_phdr}, 962882Svi117747 {"EXPIRES", NULL, sip_parse_expire_header, NULL, NULL, sip_free_phdr}, 972882Svi117747 {"IN-REPLY-TO", NULL, sip_parse_inreplyto_header, NULL, NULL, 982882Svi117747 sip_free_phdr}, 992882Svi117747 {"MIN-EXPIRES", NULL, sip_parse_minexpire_header, NULL, NULL, 1002882Svi117747 sip_free_phdr}, 1012882Svi117747 {"MIME-VERSION", NULL, sip_parse_mimeversion_header, NULL, NULL, 1022882Svi117747 sip_free_phdr}, 1032882Svi117747 {"ORGANIZATION", NULL, sip_parse_org_header, NULL, NULL, sip_free_phdr}, 1042882Svi117747 {"PRIORITY", NULL, sip_parse_priority_header, NULL, NULL, 1052882Svi117747 sip_free_phdr}, 1062882Svi117747 {"REQUIRE", NULL, sip_parse_require_header, NULL, NULL, sip_free_phdr}, 1072882Svi117747 {"REPLY-TO", NULL, sip_parse_replyto_header, NULL, NULL, sip_free_phdr}, 1082882Svi117747 {"RETRY-AFTER", NULL, sip_parse_retryaft_header, NULL, NULL, 1092882Svi117747 sip_free_phdr}, 1102882Svi117747 {"SERVER", NULL, sip_parse_server_header, NULL, NULL, sip_free_phdr}, 1112882Svi117747 {"SUBJECT", "s", sip_parse_subject_header, NULL, NULL, sip_free_phdr}, 1122882Svi117747 {"TIMESTAMP", NULL, sip_parse_timestamp_header, NULL, NULL, 1132882Svi117747 sip_free_phdr}, 1142882Svi117747 {"UNSUPPORTED", NULL, sip_parse_usupport_header, NULL, NULL, 1152882Svi117747 sip_free_phdr}, 1162882Svi117747 {"SUPPORTED", "k", sip_parse_support_header, NULL, NULL, sip_free_phdr}, 1172882Svi117747 {"USER-AGENT", NULL, sip_parse_useragt_header, NULL, NULL, 1182882Svi117747 sip_free_phdr}, 1192882Svi117747 {"WARNING", NULL, sip_parse_warn_header, NULL, NULL, sip_free_phdr}, 1202882Svi117747 {"ALLOW-EVENTS", "u", sip_parse_allow_events_header, NULL, NULL, 1212882Svi117747 sip_free_phdr}, 1222882Svi117747 {"EVENT", "o", sip_parse_event_header, NULL, NULL, sip_free_phdr}, 1232882Svi117747 {"SUBSCRIPTION-STATE", NULL, sip_parse_substate_header, NULL, NULL, 1242882Svi117747 sip_free_phdr}, 1252882Svi117747 {"AUTHORIZATION", NULL, sip_parse_author_header, NULL, NULL, 1262882Svi117747 sip_free_phdr}, 1272882Svi117747 {"AUTHENTICATION-INFO", NULL, sip_parse_ainfo_header, NULL, NULL, 1282882Svi117747 sip_free_phdr}, 1292882Svi117747 {"PROXY-AUTHORIZATION", NULL, sip_parse_pauthor_header, NULL, NULL, 1302882Svi117747 sip_free_phdr}, 1312882Svi117747 {"PROXY-AUTHENTICATE", NULL, sip_parse_pauthen_header, NULL, NULL, 1322882Svi117747 sip_free_phdr}, 1332882Svi117747 {"PROXY-REQUIRE", NULL, sip_parse_preq_header, NULL, NULL, 1342882Svi117747 sip_free_phdr}, 1352882Svi117747 {"WWW-AUTHENTICATE", NULL, sip_parse_wauthen_header, NULL, NULL, 1362882Svi117747 sip_free_phdr}, 1372882Svi117747 {"RSEQ", NULL, sip_parse_rseq, NULL, NULL, sip_free_phdr}, 1382882Svi117747 {"RACK", NULL, sip_parse_rack, NULL, NULL, sip_free_phdr}, 1392882Svi117747 {"P-ASSERTED-IDENTITY", NULL, sip_parse_passertedid, NULL, NULL, 1402882Svi117747 sip_free_phdr}, 1412882Svi117747 {"P-PREFERRED-IDENTITY", NULL, sip_parse_ppreferredid, NULL, NULL, 1422882Svi117747 sip_free_phdr}, 1432882Svi117747 {"PRIVACY", NULL, sip_parse_privacy_header, NULL, NULL, sip_free_phdr}, 1442882Svi117747 {NULL, NULL, NULL, NULL, NULL, NULL}, 1452882Svi117747 }; 1462882Svi117747 1472882Svi117747 #define MAX_SIP_HEADERS \ 1482882Svi117747 sizeof (sip_header_function_table) / sizeof (sip_header_function_t) 1492882Svi117747 1502882Svi117747 /* 1512882Svi117747 * External/application provided function table 1522882Svi117747 */ 1532882Svi117747 sip_header_function_t *sip_header_function_table_external = NULL; 1542882Svi117747 1552882Svi117747 /* 1562882Svi117747 * Free parameter list 1572882Svi117747 */ 1582882Svi117747 static void 1592882Svi117747 sip_free_params(sip_param_t *param_list) 1602882Svi117747 { 1612882Svi117747 sip_param_t *param, *next_param; 1622882Svi117747 1632882Svi117747 param = param_list; 1642882Svi117747 1652882Svi117747 while (param != NULL) { 1662882Svi117747 next_param = param->param_next; 1672882Svi117747 free(param); 1682882Svi117747 param = next_param; 1692882Svi117747 } 1702882Svi117747 } 1712882Svi117747 1722882Svi117747 /* 1732882Svi117747 * Common header free routine 1742882Svi117747 */ 1752882Svi117747 void 1762882Svi117747 sip_free_phdr(sip_parsed_header_t *header) 1772882Svi117747 { 1782882Svi117747 sip_hdr_value_t *value; 1792882Svi117747 sip_hdr_value_t *next_value; 1802882Svi117747 1812882Svi117747 if (header == NULL) 1822882Svi117747 return; 1832882Svi117747 value = (sip_hdr_value_t *)header->value; 1842882Svi117747 while (value != NULL) { 1852882Svi117747 sip_free_params(value->sip_param_list); 1862882Svi117747 next_value = value->sip_next_value; 1872882Svi117747 free(value); 1882882Svi117747 value = next_value; 1892882Svi117747 } 1902882Svi117747 free(header); 1912882Svi117747 } 1922882Svi117747 1932882Svi117747 /* 1942882Svi117747 * Free Contact/From/To header 1952882Svi117747 */ 1962882Svi117747 void 1972882Svi117747 sip_free_cftr_header(sip_parsed_header_t *header) 1982882Svi117747 { 1992882Svi117747 sip_hdr_value_t *value; 2002882Svi117747 sip_hdr_value_t *next_value; 2012882Svi117747 2022882Svi117747 if (header == NULL) 2032882Svi117747 return; 2042882Svi117747 value = (sip_hdr_value_t *)header->value; 2052882Svi117747 while (value != NULL) { 2062882Svi117747 next_value = value->sip_next_value; 2072882Svi117747 sip_free_params(value->sip_param_list); 2082882Svi117747 if (value->cftr_name != NULL) 2092882Svi117747 free(value->cftr_name); 2102882Svi117747 if (value->sip_value_parsed_uri != NULL) { 2112882Svi117747 sip_free_parsed_uri(value->sip_value_parsed_uri); 2122882Svi117747 value->sip_value_parsed_uri = NULL; 2132882Svi117747 } 2142882Svi117747 free(value); 2152882Svi117747 value = next_value; 2162882Svi117747 } 2172882Svi117747 free(header); 2182882Svi117747 } 2192882Svi117747 2202882Svi117747 /* 2212882Svi117747 * Return new header 2222882Svi117747 */ 2232882Svi117747 _sip_header_t * 2242882Svi117747 sip_new_header(int header_size) 2252882Svi117747 { 2262882Svi117747 _sip_header_t *new_header; 2272882Svi117747 2282882Svi117747 new_header = calloc(1, sizeof (_sip_header_t)); 2292882Svi117747 if (new_header == NULL) 2302882Svi117747 return (NULL); 2312882Svi117747 2322882Svi117747 /* 2332882Svi117747 * We are using snprintf which adds a null character 2342882Svi117747 * so allocate an extra byte which is not part of 2352882Svi117747 * the message header 2362882Svi117747 */ 2372882Svi117747 new_header->sip_hdr_start = calloc(1, header_size + 1); 2382882Svi117747 if (new_header->sip_hdr_start == NULL) { 2392882Svi117747 free(new_header); 2402882Svi117747 return (NULL); 2412882Svi117747 } 2422882Svi117747 new_header->sip_hdr_end = new_header->sip_hdr_start + header_size; 2432882Svi117747 new_header->sip_hdr_current = new_header->sip_hdr_start; 2442882Svi117747 new_header->sip_hdr_allocated = B_TRUE; 2452882Svi117747 return (new_header); 2462882Svi117747 } 2472882Svi117747 2482882Svi117747 /* 2492882Svi117747 * Free the given header 2502882Svi117747 */ 2512882Svi117747 void 2522882Svi117747 sip_free_header(_sip_header_t *sip_header) 2532882Svi117747 { 2542882Svi117747 if (sip_header->sip_hdr_allocated) { 2552882Svi117747 assert(sip_header->sip_hdr_start != NULL); 2562882Svi117747 free(sip_header->sip_hdr_start); 2572882Svi117747 } 2582882Svi117747 if (sip_header->sip_hdr_parsed != NULL) { 2592882Svi117747 assert(sip_header->sip_header_functions != NULL); 2602882Svi117747 if (sip_header->sip_header_functions->header_free != NULL) { 2612882Svi117747 sip_header->sip_header_functions->header_free( 2622882Svi117747 sip_header->sip_hdr_parsed); 2632882Svi117747 } 2642882Svi117747 } 2652882Svi117747 free(sip_header); 2662882Svi117747 } 2672882Svi117747 2682882Svi117747 /* 2692882Svi117747 * Return a copy of the header passed in. 2702882Svi117747 */ 2712882Svi117747 _sip_header_t * 2722882Svi117747 sip_dup_header(_sip_header_t *from) 2732882Svi117747 { 2742882Svi117747 size_t hdr_size; 2752882Svi117747 _sip_header_t *to; 2762882Svi117747 2772882Svi117747 hdr_size = from->sip_hdr_end - from->sip_hdr_start; 2782882Svi117747 to = sip_new_header(hdr_size); 2792882Svi117747 if (to == NULL) 2802882Svi117747 return (NULL); 2812882Svi117747 if (from->sip_header_state == SIP_HEADER_DELETED_VAL) { 2822882Svi117747 to->sip_hdr_end = to->sip_hdr_start + 2832882Svi117747 sip_copy_values(to->sip_hdr_start, from); 2842882Svi117747 } else { 2852882Svi117747 (void) memcpy(to->sip_hdr_start, from->sip_hdr_start, hdr_size); 2862882Svi117747 to->sip_hdr_end = to->sip_hdr_start + hdr_size; 2872882Svi117747 } 2882882Svi117747 to->sip_header_functions = from->sip_header_functions; 2892882Svi117747 return (to); 2902882Svi117747 } 2912882Svi117747 2922882Svi117747 /* 2932882Svi117747 * Copy header with extra_param, if any, to sip_msg 2942882Svi117747 */ 2952882Svi117747 int 2962882Svi117747 _sip_copy_header(_sip_msg_t *sip_msg, _sip_header_t *header, char *extra_param, 2972882Svi117747 boolean_t skip_crlf) 2982882Svi117747 { 2992882Svi117747 _sip_header_t *new_header; 3002882Svi117747 int hdrlen; 3012882Svi117747 int extra_len = 0; 3022882Svi117747 int ncrlf = 0; 3032882Svi117747 char *p; 3042882Svi117747 3052882Svi117747 #ifdef __solaris__ 3062882Svi117747 assert(mutex_held(&sip_msg->sip_msg_mutex)); 3072882Svi117747 #endif 3082882Svi117747 if (extra_param != NULL) { 3092882Svi117747 extra_len = SIP_SPACE_LEN + sizeof (char) + SIP_SPACE_LEN + 3102882Svi117747 strlen(extra_param); 3112882Svi117747 } 3122882Svi117747 /* 3132882Svi117747 * Just take one if there are more, i.e. if this is the last header 3142882Svi117747 * before the content. 3152882Svi117747 */ 3162882Svi117747 if (skip_crlf) { 3172882Svi117747 if (header->sip_hdr_end - strlen(SIP_CRLF) <= 3182882Svi117747 header->sip_hdr_start) { 3192882Svi117747 goto proceed; 3202882Svi117747 } 3212882Svi117747 p = header->sip_hdr_end - strlen(SIP_CRLF); 3222882Svi117747 while (strncmp(SIP_CRLF, p, strlen(SIP_CRLF)) == 0) { 3232882Svi117747 ncrlf++; 3242882Svi117747 if (p - strlen(SIP_CRLF) < header->sip_hdr_start) 3252882Svi117747 break; 3262882Svi117747 p -= strlen(SIP_CRLF); 3272882Svi117747 } 3282882Svi117747 /* 3292882Svi117747 * Take one CRLF. 3302882Svi117747 */ 3312882Svi117747 ncrlf = (ncrlf - 1) * strlen(SIP_CRLF); 3322882Svi117747 } 3332882Svi117747 proceed: 3342882Svi117747 hdrlen = header->sip_hdr_end - header->sip_hdr_start - ncrlf; 3352882Svi117747 new_header = sip_new_header(hdrlen + extra_len); 3362882Svi117747 if (new_header == NULL) 3372882Svi117747 return (ENOMEM); 3382882Svi117747 if (header->sip_header_state == SIP_HEADER_DELETED_VAL) { 3392882Svi117747 int len; 3402882Svi117747 3412882Svi117747 len = sip_copy_values(new_header->sip_hdr_start, header); 3422882Svi117747 new_header->sip_hdr_end = new_header->sip_hdr_start + len; 3432882Svi117747 hdrlen = hdrlen - len + extra_len; 3442882Svi117747 } else { 3452882Svi117747 (void) memcpy(new_header->sip_hdr_start, header->sip_hdr_start, 3462882Svi117747 hdrlen); 3472882Svi117747 new_header->sip_hdr_end = new_header->sip_hdr_start + hdrlen; 3482882Svi117747 hdrlen = extra_len; 3492882Svi117747 } 3502882Svi117747 if (extra_param != NULL) { 3512882Svi117747 /* 3522882Svi117747 * Find CR 3532882Svi117747 */ 3542882Svi117747 if (sip_find_cr(new_header) != 0) { 3552882Svi117747 sip_free_header(new_header); 3562882Svi117747 return (EINVAL); 3572882Svi117747 } 3582882Svi117747 hdrlen += new_header->sip_hdr_end - new_header->sip_hdr_current; 3592882Svi117747 (void) snprintf(new_header->sip_hdr_current, hdrlen + 1, 3602882Svi117747 " %c %s%s", SIP_SEMI, extra_param, SIP_CRLF); 3612882Svi117747 } 3622882Svi117747 3632882Svi117747 new_header->sip_hdr_end += extra_len; 3642882Svi117747 new_header->sip_header_functions = header->sip_header_functions; 3652882Svi117747 _sip_add_header(sip_msg, new_header, B_TRUE, B_FALSE, NULL); 3662882Svi117747 return (0); 3672882Svi117747 } 3682882Svi117747 3692882Svi117747 /* 3702882Svi117747 * Copy all "header_name" headers from _old_msg to _new_msg 3712882Svi117747 */ 3722882Svi117747 int 3732882Svi117747 _sip_find_and_copy_all_header(_sip_msg_t *_old_msg, _sip_msg_t *_new_msg, 3742882Svi117747 char *header_name) 3752882Svi117747 { 3762882Svi117747 _sip_header_t *header; 3772882Svi117747 int ret = 0; 3782882Svi117747 3792882Svi117747 if (_old_msg == NULL || _new_msg == NULL) 3802882Svi117747 return (EINVAL); 3812882Svi117747 #ifdef __solaris__ 3822882Svi117747 assert(mutex_held(&_old_msg->sip_msg_mutex)); 3832882Svi117747 #endif 3842882Svi117747 if (_old_msg != _new_msg) 3852882Svi117747 (void) pthread_mutex_lock(&_new_msg->sip_msg_mutex); 3862882Svi117747 header = sip_search_for_header(_old_msg, header_name, NULL); 3872882Svi117747 while (header != NULL) { 3882882Svi117747 ret = _sip_copy_header(_new_msg, header, NULL, B_TRUE); 3892882Svi117747 if (ret != 0) 3902882Svi117747 break; 3912882Svi117747 header = sip_search_for_header(_old_msg, header_name, header); 3922882Svi117747 } 3932882Svi117747 if (_old_msg != _new_msg) 3942882Svi117747 (void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex); 3952882Svi117747 return (ret); 3962882Svi117747 } 3972882Svi117747 3982882Svi117747 /* 3992882Svi117747 * Copy header_name from _old_msg to _new_msg with extra_parm. 4002882Svi117747 */ 4012882Svi117747 int 4022882Svi117747 _sip_find_and_copy_header(sip_msg_t _old_msg, sip_msg_t _new_msg, 4032882Svi117747 char *header_name, char *extra_param, boolean_t lock_newmsg) 4042882Svi117747 { 4052882Svi117747 _sip_header_t *header; 4062882Svi117747 int ret; 4072882Svi117747 4082882Svi117747 if (_old_msg == NULL || _new_msg == NULL) 4092882Svi117747 return (EINVAL); 4102882Svi117747 #ifdef __solaris__ 4112882Svi117747 assert(mutex_held(&_old_msg->sip_msg_mutex)); 4122882Svi117747 #endif 4132882Svi117747 header = sip_search_for_header(_old_msg, header_name, NULL); 4142882Svi117747 if (header == NULL) 4152882Svi117747 return (EINVAL); 4162882Svi117747 if (lock_newmsg) 4172882Svi117747 (void) pthread_mutex_lock(&_new_msg->sip_msg_mutex); 4182882Svi117747 ret = _sip_copy_header(_new_msg, header, extra_param, B_TRUE); 4192882Svi117747 if (lock_newmsg) 4202882Svi117747 (void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex); 4212882Svi117747 return (ret); 4222882Svi117747 } 4232882Svi117747 4242882Svi117747 /* 4252882Svi117747 * Copy all headers from old_msg to new_msg 4262882Svi117747 */ 4272882Svi117747 int 4282882Svi117747 sip_copy_all_headers(sip_msg_t old_msg, sip_msg_t new_msg) 4292882Svi117747 { 4302882Svi117747 _sip_header_t *header; 4312882Svi117747 _sip_msg_t *_old_msg; 4322882Svi117747 _sip_msg_t *_new_msg; 4332882Svi117747 int ret = 0; 4342882Svi117747 4352882Svi117747 if (old_msg == NULL || new_msg == NULL) 4362882Svi117747 return (EINVAL); 4372882Svi117747 _old_msg = (_sip_msg_t *)old_msg; 4382882Svi117747 _new_msg = (_sip_msg_t *)new_msg; 4392882Svi117747 4402882Svi117747 (void) pthread_mutex_lock(&_old_msg->sip_msg_mutex); 4412882Svi117747 (void) pthread_mutex_lock(&_new_msg->sip_msg_mutex); 4422882Svi117747 header = sip_search_for_header(_old_msg, NULL, NULL); 4432882Svi117747 while (header != NULL) { 4442882Svi117747 ret = _sip_copy_header(_new_msg, header, NULL, B_FALSE); 4452882Svi117747 if (ret != 0) 4462882Svi117747 goto done; 4472882Svi117747 header = sip_search_for_header(_old_msg, NULL, header); 4482882Svi117747 } 4492882Svi117747 done: 4502882Svi117747 (void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex); 4512882Svi117747 (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex); 4522882Svi117747 return (ret); 4532882Svi117747 } 4542882Svi117747 4552882Svi117747 /* 4562882Svi117747 * Copy start line from msg to sip_msg 4572882Svi117747 */ 4582882Svi117747 int 4592882Svi117747 sip_copy_start_line(sip_msg_t msg, sip_msg_t sip_msg) 4602882Svi117747 { 4612882Svi117747 int len; 4622882Svi117747 _sip_header_t *new_header; 4632882Svi117747 _sip_msg_t *_old_msg; 4642882Svi117747 _sip_msg_t *_sip_msg; 4652882Svi117747 4662882Svi117747 if (msg == NULL || sip_msg == NULL) 4672882Svi117747 return (EINVAL); 4682882Svi117747 _old_msg = (_sip_msg_t *)msg; 4692882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 4702882Svi117747 4712882Svi117747 (void) pthread_mutex_lock(&_old_msg->sip_msg_mutex); 4722882Svi117747 if (_old_msg->sip_msg_start_line == NULL) { 4732882Svi117747 (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex); 4742882Svi117747 return (EINVAL); 4752882Svi117747 } 4762882Svi117747 len = _old_msg->sip_msg_start_line->sip_hdr_end - 4772882Svi117747 _old_msg->sip_msg_start_line->sip_hdr_start; 4782882Svi117747 new_header = sip_new_header(len); 4792882Svi117747 if (new_header == NULL) { 4802882Svi117747 (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex); 4812882Svi117747 return (ENOMEM); 4822882Svi117747 } 4832882Svi117747 new_header->sip_hdr_sipmsg = _sip_msg; 4842882Svi117747 (void) pthread_mutex_lock(&sip_msg->sip_msg_mutex); 4852882Svi117747 _sip_msg->sip_msg_start_line = new_header; 4862882Svi117747 _sip_msg->sip_msg_len = len; 4872882Svi117747 (void) strncpy(_sip_msg->sip_msg_start_line->sip_hdr_start, 4882882Svi117747 _old_msg->sip_msg_start_line->sip_hdr_start, len); 4892882Svi117747 (void) sip_parse_first_line(_sip_msg->sip_msg_start_line, 4902882Svi117747 &_sip_msg->sip_msg_req_res); 4912882Svi117747 (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex); 4922882Svi117747 (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex); 4932882Svi117747 return (0); 4942882Svi117747 } 4952882Svi117747 4962882Svi117747 /* 4972882Svi117747 * Delete start line from sip_msg 4982882Svi117747 */ 4992882Svi117747 int 5002882Svi117747 sip_delete_start_line_locked(_sip_msg_t *_sip_msg) 5012882Svi117747 { 5022882Svi117747 _sip_header_t *header; 5032882Svi117747 _sip_header_t *next_header; 5042882Svi117747 5052882Svi117747 if (_sip_msg->sip_msg_start_line == NULL) 5062882Svi117747 return (EINVAL); 5072882Svi117747 5082882Svi117747 header = _sip_msg->sip_msg_start_line; 5092882Svi117747 while (header != NULL) { 5102882Svi117747 next_header = header->sip_hdr_next; 5112882Svi117747 _sip_msg->sip_msg_len -= (header->sip_hdr_end - 5122882Svi117747 header->sip_hdr_start); 5132882Svi117747 sip_free_header(header); 5142882Svi117747 header = next_header; 5152882Svi117747 } 5162882Svi117747 _sip_msg->sip_msg_start_line = NULL; 5172882Svi117747 5182882Svi117747 /* 5192882Svi117747 * Also delete the sip_msg_req_res info since we don't have a start 5202882Svi117747 * line. 5212882Svi117747 */ 5222882Svi117747 while (_sip_msg->sip_msg_req_res != NULL) { 5232882Svi117747 sip_message_type_t *sip_msg_type_ptr; 5242882Svi117747 5252882Svi117747 sip_msg_type_ptr = _sip_msg->sip_msg_req_res->sip_next; 5262882Svi117747 if (_sip_msg->sip_msg_req_res->is_request) { 5272882Svi117747 sip_request_t *reqline; 5282882Svi117747 5292882Svi117747 reqline = &_sip_msg->sip_msg_req_res->U.sip_request; 5302882Svi117747 if (reqline->sip_parse_uri != NULL) { 5312882Svi117747 sip_free_parsed_uri(reqline->sip_parse_uri); 5322882Svi117747 reqline->sip_parse_uri = NULL; 5332882Svi117747 } 5342882Svi117747 } 5352882Svi117747 free(_sip_msg->sip_msg_req_res); 5362882Svi117747 _sip_msg->sip_msg_req_res = sip_msg_type_ptr; 5372882Svi117747 } 5382882Svi117747 return (0); 5392882Svi117747 } 5402882Svi117747 5412882Svi117747 5422882Svi117747 /* 5432882Svi117747 * Delete start line from sip_msg 5442882Svi117747 */ 5452882Svi117747 int 5462882Svi117747 sip_delete_start_line(sip_msg_t sip_msg) 5472882Svi117747 { 5482882Svi117747 _sip_msg_t *_sip_msg; 5492882Svi117747 int ret; 5502882Svi117747 5512882Svi117747 if (sip_msg == NULL) 5522882Svi117747 return (EINVAL); 5532882Svi117747 5542882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 5552882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 5562882Svi117747 ret = sip_delete_start_line_locked(_sip_msg); 5572882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 5582882Svi117747 5592882Svi117747 return (ret); 5602882Svi117747 } 5612882Svi117747 5622882Svi117747 /* 5632882Svi117747 * Delete all headers from _sip_msg 5642882Svi117747 */ 5652882Svi117747 void 5662882Svi117747 sip_delete_all_headers(_sip_msg_t *_sip_msg) 5672882Svi117747 { 5682882Svi117747 _sip_header_t *header; 5692882Svi117747 5702882Svi117747 #ifdef __solaris__ 5712882Svi117747 assert(mutex_held(&_sip_msg->sip_msg_mutex)); 5722882Svi117747 #endif 5732882Svi117747 5742882Svi117747 header = _sip_msg->sip_msg_headers_start; 5752882Svi117747 while (header != NULL) { 5762882Svi117747 _sip_header_t *next_header; 5772882Svi117747 next_header = header->sip_hdr_next; 5782882Svi117747 sip_free_header(header); 5792882Svi117747 header = next_header; 5802882Svi117747 } 5812882Svi117747 _sip_msg->sip_msg_headers_start = NULL; 5822882Svi117747 _sip_msg->sip_msg_headers_end = NULL; 5832882Svi117747 } 5842882Svi117747 5852882Svi117747 /* 5862882Svi117747 * Delete and free the named header. If header_name is null 5872882Svi117747 * free all headers. 5882882Svi117747 */ 5892882Svi117747 void 5902882Svi117747 sip_delete_headers(sip_msg_t sip_msg, char *header_name) 5912882Svi117747 { 5922882Svi117747 _sip_header_t *header; 5932882Svi117747 _sip_msg_t *_sip_msg; 5942882Svi117747 5952882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 5962882Svi117747 #ifdef __solaris__ 5972882Svi117747 assert(mutex_held(&_sip_msg->sip_msg_mutex)); 5982882Svi117747 #endif 5992882Svi117747 header = sip_search_for_header(_sip_msg, header_name, NULL); 6002882Svi117747 if (header == NULL) 6012882Svi117747 return; 6022882Svi117747 while (header != NULL) { 6032882Svi117747 if (_sip_msg->sip_msg_headers_start == header) { 6042882Svi117747 _sip_msg->sip_msg_headers_start = header->sip_hdr_next; 6052882Svi117747 } else { 6062882Svi117747 header->sip_hdr_prev->sip_hdr_next = 6072882Svi117747 header->sip_hdr_next; 6082882Svi117747 } 6092882Svi117747 if (_sip_msg->sip_msg_headers_end == header) { 6102882Svi117747 _sip_msg->sip_msg_headers_end = header->sip_hdr_prev; 6112882Svi117747 } else { 6122882Svi117747 header->sip_hdr_next->sip_hdr_prev = 6132882Svi117747 header->sip_hdr_prev; 6142882Svi117747 } 6152882Svi117747 sip_free_header(header); 6162882Svi117747 if (header_name != NULL) 6172882Svi117747 return; 6182882Svi117747 else 6192882Svi117747 header = sip_search_for_header(_sip_msg, NULL, NULL); 6202882Svi117747 } 6212882Svi117747 } 6222882Svi117747 6232882Svi117747 /* 6242882Svi117747 * Add a header to sip_msg. If header_name is provided then the new header 6252882Svi117747 * is added before that header, if first is set, or after. If append is 6262882Svi117747 * set, then the header is added to the end of the header list. 6272882Svi117747 */ 6282882Svi117747 void 6292882Svi117747 _sip_add_header(_sip_msg_t *sip_msg, _sip_header_t *new_header, 6302882Svi117747 boolean_t append, boolean_t first, char *header_name) 6312882Svi117747 { 6322882Svi117747 _sip_header_t *header = NULL; 6332882Svi117747 6342882Svi117747 if (sip_msg == NULL || new_header == NULL) 6352882Svi117747 return; 6362882Svi117747 #ifdef __solaris__ 6372882Svi117747 assert(mutex_held(&sip_msg->sip_msg_mutex)); 6382882Svi117747 #endif 6392882Svi117747 new_header->sip_hdr_sipmsg = sip_msg; 6402882Svi117747 if (header_name != NULL) { 6412882Svi117747 _sip_header_t *header_tmp; 6422882Svi117747 6432882Svi117747 header = sip_search_for_header(sip_msg, header_name, NULL); 6442882Svi117747 header_tmp = header; 6452882Svi117747 if (!first) { 6462882Svi117747 while (header != NULL) { 6472882Svi117747 header_tmp = header; 6482882Svi117747 header = sip_search_for_header(sip_msg, 6492882Svi117747 header_name, header); 6502882Svi117747 } 6512882Svi117747 } 6522882Svi117747 header = header_tmp; 6532882Svi117747 if (header == NULL) 6542882Svi117747 append = B_TRUE; 6552882Svi117747 } 6562882Svi117747 6572882Svi117747 if (header != NULL) { 6582882Svi117747 if (append) { 6592882Svi117747 new_header->sip_hdr_prev = header; 6602882Svi117747 if (sip_msg->sip_msg_headers_end == header) { 6612882Svi117747 sip_msg->sip_msg_headers_end = new_header; 6622882Svi117747 new_header->sip_hdr_next = NULL; 6632882Svi117747 } else { 6642882Svi117747 header->sip_hdr_next->sip_hdr_prev = new_header; 6652882Svi117747 new_header->sip_hdr_next = header->sip_hdr_next; 6662882Svi117747 } 6672882Svi117747 header->sip_hdr_next = new_header; 6682882Svi117747 } else { 6692882Svi117747 new_header->sip_hdr_next = header; 6702882Svi117747 if (sip_msg->sip_msg_headers_start == header) { 6712882Svi117747 sip_msg->sip_msg_headers_start = new_header; 6722882Svi117747 new_header->sip_hdr_prev = NULL; 6732882Svi117747 } else { 6742882Svi117747 header->sip_hdr_prev->sip_hdr_next = new_header; 6752882Svi117747 new_header->sip_hdr_prev = header->sip_hdr_prev; 6762882Svi117747 } 6772882Svi117747 header->sip_hdr_prev = new_header; 6782882Svi117747 } 6792882Svi117747 } else { 6802882Svi117747 if (append) { 6812882Svi117747 if (sip_msg->sip_msg_headers_end != NULL) { 6822882Svi117747 sip_msg->sip_msg_headers_end->sip_hdr_next = 6832882Svi117747 new_header; 6842882Svi117747 } else { 6852882Svi117747 sip_msg->sip_msg_headers_start = new_header; 6862882Svi117747 } 6872882Svi117747 new_header->sip_hdr_prev = 6882882Svi117747 sip_msg->sip_msg_headers_end; 6892882Svi117747 new_header->sip_hdr_next = NULL; 6902882Svi117747 sip_msg->sip_msg_headers_end = new_header; 6912882Svi117747 } else { 6922882Svi117747 if (sip_msg->sip_msg_headers_start != NULL) { 6932882Svi117747 sip_msg->sip_msg_headers_start->sip_hdr_prev = 6942882Svi117747 new_header; 6952882Svi117747 } else { 6962882Svi117747 sip_msg->sip_msg_headers_end = new_header; 6972882Svi117747 } 6982882Svi117747 new_header->sip_hdr_next = 6992882Svi117747 sip_msg->sip_msg_headers_start; 7002882Svi117747 new_header->sip_hdr_prev = NULL; 7012882Svi117747 sip_msg->sip_msg_headers_start = new_header; 7022882Svi117747 } 7032882Svi117747 } 7042882Svi117747 sip_msg->sip_msg_len += new_header->sip_hdr_end - 7052882Svi117747 new_header->sip_hdr_start; 7062882Svi117747 } 7072882Svi117747 7082882Svi117747 /* 7092882Svi117747 * Scan through the function table and return the entry for the given header 7102882Svi117747 * type. 7112882Svi117747 */ 7122882Svi117747 sip_header_function_t * 7132882Svi117747 _sip_get_header_functions(sip_header_function_t *sip_header_function_table, 7142882Svi117747 _sip_header_t *sip_header, char *header_name) 7152882Svi117747 { 7162882Svi117747 int len; 7172882Svi117747 int i = 0; 7182882Svi117747 7192882Svi117747 if (sip_header == NULL && header_name == NULL) 7202882Svi117747 return (NULL); 7212882Svi117747 7222882Svi117747 /* 7232882Svi117747 * If header_name is NULL we first have to locate the name 7242882Svi117747 */ 7252882Svi117747 if (header_name == NULL) { 7262882Svi117747 if (sip_skip_white_space(sip_header) != 0) { 7272882Svi117747 return (NULL); 7282882Svi117747 } 7292882Svi117747 header_name = sip_header->sip_hdr_current; 7302882Svi117747 if (sip_find_separator(sip_header, SIP_HCOLON, (char)NULL, 7312882Svi117747 (char)NULL) != 0) { 7322882Svi117747 return (NULL); 7332882Svi117747 } 7342882Svi117747 len = sip_header->sip_hdr_current - header_name; 7352882Svi117747 } else { 7362882Svi117747 len = strlen(header_name); 7372882Svi117747 } 7382882Svi117747 7392882Svi117747 if (len > 0) { 7402882Svi117747 while (sip_header_function_table[i].header_name != NULL || 7412882Svi117747 sip_header_function_table[i].header_short_name != NULL) { 7422882Svi117747 if (sip_header_function_table[i].header_name != NULL && 7432882Svi117747 len == 7442882Svi117747 strlen(sip_header_function_table[i].header_name)) { 7452882Svi117747 if (strncasecmp(header_name, 7462882Svi117747 sip_header_function_table[i]. 7472882Svi117747 header_name, len) == 0) { 7482882Svi117747 break; 7492882Svi117747 } 7502882Svi117747 } else if (sip_header_function_table[i]. 7512882Svi117747 header_short_name != NULL && len == 7522882Svi117747 strlen(sip_header_function_table[i]. 7532882Svi117747 header_short_name)) { 7542882Svi117747 if (strncasecmp(header_name, 7552882Svi117747 sip_header_function_table[i]. 7562882Svi117747 header_short_name, len) == 0) { 7572882Svi117747 break; 7582882Svi117747 } 7592882Svi117747 } 7602882Svi117747 i++; 7612882Svi117747 } 7622882Svi117747 } 7632882Svi117747 7642882Svi117747 if (sip_header != NULL) 7652882Svi117747 sip_header->sip_hdr_current = sip_header->sip_hdr_start; 7662882Svi117747 if (sip_header_function_table[i].header_name == NULL) 7672882Svi117747 return (NULL); 7682882Svi117747 return (&sip_header_function_table[i]); 7692882Svi117747 } 7702882Svi117747 7712882Svi117747 /* 7722882Svi117747 * Return the entry from the function table for the given header 7732882Svi117747 */ 7742882Svi117747 sip_header_function_t * 7752882Svi117747 sip_get_header_functions(_sip_header_t *sip_header, char *header_name) 7762882Svi117747 { 7772882Svi117747 sip_header_function_t *func; 7782882Svi117747 sip_header_function_t *header_f_table = NULL; 7792882Svi117747 7802882Svi117747 if (sip_header_function_table_external != NULL) { 7812882Svi117747 header_f_table = _sip_get_header_functions( 7822882Svi117747 sip_header_function_table_external, 7832882Svi117747 sip_header, header_name); 7842882Svi117747 if (header_f_table != NULL) 7852882Svi117747 return (header_f_table); 7862882Svi117747 } 7872882Svi117747 func = _sip_get_header_functions(sip_header_function_table, sip_header, 7882882Svi117747 header_name); 7892882Svi117747 return (func); 7902882Svi117747 } 7912882Svi117747 7922882Svi117747 /* 7932882Svi117747 * Search for the header name passed in. 7942882Svi117747 */ 7952882Svi117747 _sip_header_t * 7962882Svi117747 sip_search_for_header(_sip_msg_t *sip_msg, char *header_name, 7972882Svi117747 _sip_header_t *old_header) 7982882Svi117747 { 7992882Svi117747 int len = 0; 8002882Svi117747 int full_len = 0; 8012882Svi117747 int compact_len = 0; 8022882Svi117747 _sip_header_t *header = NULL; 8032882Svi117747 char *compact_name = NULL; 8042882Svi117747 char *full_name = NULL; 8052882Svi117747 sip_header_function_t *header_f_table = NULL; 8062882Svi117747 8072882Svi117747 if (sip_msg == NULL) 8082882Svi117747 return (NULL); 8092882Svi117747 #ifdef __solaris__ 8102882Svi117747 assert(mutex_held(&sip_msg->sip_msg_mutex)); 8112882Svi117747 #endif 8122882Svi117747 8132882Svi117747 if (header_name != NULL) { 8142882Svi117747 header_f_table = sip_get_header_functions(NULL, header_name); 8152882Svi117747 if (header_f_table != NULL) { 8162882Svi117747 full_name = header_f_table->header_name; 8172882Svi117747 compact_name = header_f_table->header_short_name; 8182882Svi117747 if (full_name != NULL) 8192882Svi117747 full_len = strlen(full_name); 8202882Svi117747 if (compact_name != NULL) 8212882Svi117747 compact_len = strlen(compact_name); 8222882Svi117747 } else { 8232882Svi117747 header_f_table = &sip_header_function_table[0]; 8242882Svi117747 full_name = header_name; 8252882Svi117747 full_len = strlen(full_name); 8262882Svi117747 } 8272882Svi117747 } 8282882Svi117747 8292882Svi117747 if (old_header != NULL) 8302882Svi117747 header = old_header->sip_hdr_next; 8312882Svi117747 else 8322882Svi117747 header = sip_msg->sip_msg_headers_start; 8332882Svi117747 8342882Svi117747 while (header != NULL) { 8352882Svi117747 8362882Svi117747 if (header->sip_header_state == SIP_HEADER_DELETED) { 8372882Svi117747 header = header->sip_hdr_next; 8382882Svi117747 continue; 8392882Svi117747 } 8402882Svi117747 8412882Svi117747 if (compact_len == 0 && full_len == 0) 8422882Svi117747 break; 8432882Svi117747 8442882Svi117747 header->sip_hdr_current = header->sip_hdr_start; 8452882Svi117747 8462882Svi117747 if (sip_skip_white_space(header)) { 8472882Svi117747 header = header->sip_hdr_next; 8482882Svi117747 continue; 8492882Svi117747 } 8502882Svi117747 8512882Svi117747 len = header->sip_hdr_end - header->sip_hdr_current; 8522882Svi117747 8532882Svi117747 if (full_name != NULL && (full_len <= len) && 8542882Svi117747 strncasecmp(header->sip_hdr_current, full_name, 8552882Svi117747 full_len) == 0) { 8562882Svi117747 header->sip_hdr_current += full_len; 8572882Svi117747 if (sip_skip_white_space(header)) { 8582882Svi117747 header = header->sip_hdr_next; 8592882Svi117747 continue; 8602882Svi117747 } 8612882Svi117747 8622882Svi117747 if (*header->sip_hdr_current == SIP_HCOLON) { 8632882Svi117747 header_name = full_name; 8642882Svi117747 break; 8652882Svi117747 } 8662882Svi117747 } 8672882Svi117747 8682882Svi117747 if (compact_name != NULL && (compact_len <= len) && 8692882Svi117747 strncasecmp(header->sip_hdr_current, compact_name, 8702882Svi117747 compact_len) == 0) { 8712882Svi117747 header->sip_hdr_current += compact_len; 8722882Svi117747 if (sip_skip_white_space(header)) { 8732882Svi117747 header = header->sip_hdr_next; 8742882Svi117747 continue; 8752882Svi117747 } 8762882Svi117747 if (*header->sip_hdr_current == SIP_HCOLON) { 8772882Svi117747 header_name = compact_name; 8782882Svi117747 break; 8792882Svi117747 } 8802882Svi117747 } 8812882Svi117747 header = header->sip_hdr_next; 8822882Svi117747 } 8832882Svi117747 8842882Svi117747 if (header != NULL) { 8852882Svi117747 header->sip_hdr_current = header->sip_hdr_start; 8862882Svi117747 if (header_f_table == NULL) { 8872882Svi117747 header_f_table = 8882882Svi117747 sip_get_header_functions(header, header_name); 8892882Svi117747 if (header_f_table == NULL) 8902882Svi117747 header_f_table = &sip_header_function_table[0]; 8912882Svi117747 } 8922882Svi117747 8932882Svi117747 header->sip_header_functions = header_f_table; 8942882Svi117747 } 8952882Svi117747 return (header); 8962882Svi117747 } 8972882Svi117747 8982882Svi117747 /* 8992882Svi117747 * Return the start line as a string. Caller frees string 9002882Svi117747 */ 9012882Svi117747 char * 9022882Svi117747 _sip_startline_to_str(_sip_msg_t *sip_msg, int *error) 9032882Svi117747 { 9042882Svi117747 char *slstr; 9052882Svi117747 int len; 9062882Svi117747 9072882Svi117747 if (error != NULL) 9082882Svi117747 *error = 0; 9092882Svi117747 9102882Svi117747 if (sip_msg == NULL || sip_msg->sip_msg_start_line == NULL) { 9112882Svi117747 if (error != NULL) 9122882Svi117747 *error = EINVAL; 9132882Svi117747 return (NULL); 9142882Svi117747 } 9152882Svi117747 (void) pthread_mutex_lock(&sip_msg->sip_msg_mutex); 9162882Svi117747 len = sip_msg->sip_msg_start_line->sip_hdr_end - 9172882Svi117747 sip_msg->sip_msg_start_line->sip_hdr_start - 2; 9182882Svi117747 if ((slstr = malloc(len + 1)) == NULL) { 9192882Svi117747 (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex); 9202882Svi117747 if (error != NULL) 9212882Svi117747 *error = ENOMEM; 9222882Svi117747 return (NULL); 9232882Svi117747 } 9242882Svi117747 (void) strncpy(slstr, sip_msg->sip_msg_start_line->sip_hdr_start, len); 9252882Svi117747 (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex); 9262882Svi117747 slstr[len] = '\0'; 9272882Svi117747 return (slstr); 9282882Svi117747 } 9292882Svi117747 9302882Svi117747 /* 9312882Svi117747 * Return the given header as a string. Caller frees string 9322882Svi117747 */ 9332882Svi117747 char * 9342882Svi117747 sip_hdr_to_str(sip_header_t sip_header, int *error) 9352882Svi117747 { 9362882Svi117747 char *hdrstr; 9372882Svi117747 char *tmpptr; 9382882Svi117747 _sip_header_t *_sip_header; 9392882Svi117747 int len; 9402882Svi117747 9412882Svi117747 if (error != NULL) 9422882Svi117747 *error = 0; 9432882Svi117747 9442882Svi117747 if (sip_header == NULL) { 9452882Svi117747 if (error != NULL) 9462882Svi117747 *error = EINVAL; 9472882Svi117747 return (NULL); 9482882Svi117747 } 9492882Svi117747 _sip_header = (_sip_header_t *)sip_header; 9502882Svi117747 if (_sip_header->sip_header_state == SIP_HEADER_DELETED) { 9512882Svi117747 if (_sip_header->sip_hdr_sipmsg != NULL) { 9522882Svi117747 (void) pthread_mutex_unlock( 9532882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 9542882Svi117747 } 9552882Svi117747 if (error != NULL) 9562882Svi117747 *error = EINVAL; 9572882Svi117747 return (NULL); 9582882Svi117747 } 9592882Svi117747 if (_sip_header->sip_hdr_sipmsg != NULL) { 9602882Svi117747 (void) pthread_mutex_lock( 9612882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 9622882Svi117747 } 9632882Svi117747 len = _sip_header->sip_hdr_end - _sip_header->sip_hdr_start; 9642882Svi117747 hdrstr = malloc(len); 9652882Svi117747 if (hdrstr == NULL) { 9662882Svi117747 if (_sip_header->sip_hdr_sipmsg != NULL) { 9672882Svi117747 (void) pthread_mutex_unlock( 9682882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 9692882Svi117747 } 9702882Svi117747 if (error != NULL) 9712882Svi117747 *error = ENOMEM; 9722882Svi117747 return (NULL); 9732882Svi117747 } 9742882Svi117747 if (_sip_header->sip_header_state == SIP_HEADER_DELETED_VAL) { 9752882Svi117747 len = sip_copy_values(hdrstr, _sip_header); 9762882Svi117747 } else { 9772882Svi117747 (void) strncpy(hdrstr, _sip_header->sip_hdr_start, len); 9782882Svi117747 } 9792882Svi117747 if (_sip_header->sip_hdr_sipmsg != NULL) { 9802882Svi117747 (void) pthread_mutex_unlock( 9812882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 9822882Svi117747 } 9832882Svi117747 tmpptr = hdrstr + len; 9842882Svi117747 while (*tmpptr-- != '\n') { 9852882Svi117747 if (tmpptr == _sip_header->sip_hdr_start) { 9862882Svi117747 free(hdrstr); 9872882Svi117747 if (error != NULL) 9882882Svi117747 *error = EINVAL; 9892882Svi117747 return (NULL); 9902882Svi117747 } 9912882Svi117747 } 9922882Svi117747 *tmpptr = '\0'; 9932882Svi117747 return (hdrstr); 9942882Svi117747 } 9952882Svi117747 9962882Svi117747 /* 9972882Svi117747 * Given a param list find the named parameter. 9982882Svi117747 * Returns a pointer to the value or NULL. 9992882Svi117747 */ 10002882Svi117747 sip_param_t * 10012882Svi117747 sip_get_param_from_list(sip_param_t *param_list, char *param_name) 10022882Svi117747 { 10032882Svi117747 while (param_list != NULL) { 10042882Svi117747 if (param_list->param_name.sip_str_len == strlen(param_name) && 10052882Svi117747 strncasecmp(param_list->param_name.sip_str_ptr, param_name, 10062882Svi117747 strlen(param_name)) == 0) { 10072882Svi117747 return (param_list); 10082882Svi117747 } 10092882Svi117747 param_list = param_list->param_next; 10102882Svi117747 } 10112882Svi117747 return (NULL); 10122882Svi117747 } 1013