1*2882Svi117747 /* 2*2882Svi117747 * CDDL HEADER START 3*2882Svi117747 * 4*2882Svi117747 * The contents of this file are subject to the terms of the 5*2882Svi117747 * Common Development and Distribution License (the "License"). 6*2882Svi117747 * You may not use this file except in compliance with the License. 7*2882Svi117747 * 8*2882Svi117747 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*2882Svi117747 * or http://www.opensolaris.org/os/licensing. 10*2882Svi117747 * See the License for the specific language governing permissions 11*2882Svi117747 * and limitations under the License. 12*2882Svi117747 * 13*2882Svi117747 * When distributing Covered Code, include this CDDL HEADER in each 14*2882Svi117747 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*2882Svi117747 * If applicable, add the following below this CDDL HEADER, with the 16*2882Svi117747 * fields enclosed by brackets "[]" replaced with your own identifying 17*2882Svi117747 * information: Portions Copyright [yyyy] [name of copyright owner] 18*2882Svi117747 * 19*2882Svi117747 * CDDL HEADER END 20*2882Svi117747 */ 21*2882Svi117747 22*2882Svi117747 /* 23*2882Svi117747 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*2882Svi117747 * Use is subject to license terms. 25*2882Svi117747 */ 26*2882Svi117747 27*2882Svi117747 #pragma ident "%Z%%M% %I% %E% SMI" 28*2882Svi117747 29*2882Svi117747 #include "sip_parse_uri.h" 30*2882Svi117747 #include "sip_msg.h" 31*2882Svi117747 #include "sip_miscdefs.h" 32*2882Svi117747 #include "sip_parse_generic.h" 33*2882Svi117747 34*2882Svi117747 sip_methods_t sip_methods[MAX_SIP_METHODS] = { 35*2882Svi117747 {"UNKNOWN", 7}, 36*2882Svi117747 {"INVITE", 6}, 37*2882Svi117747 {"ACK", 3}, 38*2882Svi117747 {"OPTIONS", 7}, 39*2882Svi117747 {"BYE", 3}, 40*2882Svi117747 {"CANCEL", 6}, 41*2882Svi117747 {"REGISTER", 8}, 42*2882Svi117747 {"REFER", 5}, 43*2882Svi117747 {"INFO", 4}, 44*2882Svi117747 {"SUBSCRIBE", 9}, 45*2882Svi117747 {"NOTIFY", 6}, 46*2882Svi117747 {"PRACK", 5} 47*2882Svi117747 }; 48*2882Svi117747 49*2882Svi117747 /* 50*2882Svi117747 * Built-In Header function table 51*2882Svi117747 */ 52*2882Svi117747 sip_header_function_t sip_header_function_table[] = { 53*2882Svi117747 {"Unknown", NULL, sip_parse_unknown_header, NULL, NULL, NULL}, 54*2882Svi117747 {"CONTACT", "m", sip_parse_cftr_header, NULL, NULL, 55*2882Svi117747 sip_free_cftr_header}, 56*2882Svi117747 {"FROM", "F", sip_parse_cftr_header, NULL, NULL, sip_free_cftr_header}, 57*2882Svi117747 {"TO", "T", sip_parse_cftr_header, NULL, NULL, sip_free_cftr_header}, 58*2882Svi117747 {"CONTENT-LENGTH", "l", sip_parse_clen_header, NULL, NULL, 59*2882Svi117747 sip_free_phdr}, 60*2882Svi117747 {"CONTENT-TYPE", "c", sip_parse_ctype_header, NULL, NULL, 61*2882Svi117747 sip_free_phdr}, 62*2882Svi117747 {"CALL-ID", "i", sip_parse_cid_header, NULL, NULL, sip_free_phdr}, 63*2882Svi117747 {"CSEQ", NULL, sip_parse_cseq_header, NULL, NULL, sip_free_phdr}, 64*2882Svi117747 {"VIA", "v", sip_parse_via_header, NULL, NULL, sip_free_phdr}, 65*2882Svi117747 {"Max-Forwards", NULL, sip_parse_maxf_header, NULL, NULL, 66*2882Svi117747 sip_free_phdr}, 67*2882Svi117747 {"RECORD-ROUTE", NULL, sip_parse_cftr_header, NULL, NULL, 68*2882Svi117747 sip_free_cftr_header}, 69*2882Svi117747 {"ROUTE", NULL, sip_parse_cftr_header, NULL, NULL, 70*2882Svi117747 sip_free_cftr_header}, 71*2882Svi117747 {"ACCEPT", NULL, sip_parse_acpt_header, NULL, NULL, sip_free_phdr}, 72*2882Svi117747 {"ACCEPT-ENCODING", NULL, sip_parse_acpt_encode_header, NULL, NULL, 73*2882Svi117747 sip_free_phdr}, 74*2882Svi117747 {"ACCEPT-LANGUAGE", NULL, sip_parse_acpt_lang_header, NULL, NULL, 75*2882Svi117747 sip_free_phdr}, 76*2882Svi117747 {"ALERT-INFO", NULL, sip_parse_alert_header, NULL, NULL, sip_free_phdr}, 77*2882Svi117747 {"ALLOW", NULL, sip_parse_allow_header, NULL, NULL, sip_free_phdr}, 78*2882Svi117747 {"CALL-INFO", NULL, sip_parse_callinfo_header, NULL, NULL, 79*2882Svi117747 sip_free_phdr}, 80*2882Svi117747 {"CONTENT-DISPOSITION", NULL, sip_parse_contentdis_header, NULL, NULL, 81*2882Svi117747 sip_free_phdr}, 82*2882Svi117747 {"CONTENT-ENCODING", "e", sip_parse_contentencode_header, NULL, NULL, 83*2882Svi117747 sip_free_phdr}, 84*2882Svi117747 {"CONTENT-LANGUAGE", NULL, sip_parse_contentlang_header, NULL, NULL, 85*2882Svi117747 sip_free_phdr}, 86*2882Svi117747 {"DATE", NULL, sip_parse_date_header, NULL, NULL, sip_free_phdr}, 87*2882Svi117747 {"ERROR-INFO", NULL, sip_parse_errorinfo_header, NULL, NULL, 88*2882Svi117747 sip_free_phdr}, 89*2882Svi117747 {"EXPIRES", NULL, sip_parse_expire_header, NULL, NULL, sip_free_phdr}, 90*2882Svi117747 {"IN-REPLY-TO", NULL, sip_parse_inreplyto_header, NULL, NULL, 91*2882Svi117747 sip_free_phdr}, 92*2882Svi117747 {"MIN-EXPIRES", NULL, sip_parse_minexpire_header, NULL, NULL, 93*2882Svi117747 sip_free_phdr}, 94*2882Svi117747 {"MIME-VERSION", NULL, sip_parse_mimeversion_header, NULL, NULL, 95*2882Svi117747 sip_free_phdr}, 96*2882Svi117747 {"ORGANIZATION", NULL, sip_parse_org_header, NULL, NULL, sip_free_phdr}, 97*2882Svi117747 {"PRIORITY", NULL, sip_parse_priority_header, NULL, NULL, 98*2882Svi117747 sip_free_phdr}, 99*2882Svi117747 {"REQUIRE", NULL, sip_parse_require_header, NULL, NULL, sip_free_phdr}, 100*2882Svi117747 {"REPLY-TO", NULL, sip_parse_replyto_header, NULL, NULL, sip_free_phdr}, 101*2882Svi117747 {"RETRY-AFTER", NULL, sip_parse_retryaft_header, NULL, NULL, 102*2882Svi117747 sip_free_phdr}, 103*2882Svi117747 {"SERVER", NULL, sip_parse_server_header, NULL, NULL, sip_free_phdr}, 104*2882Svi117747 {"SUBJECT", "s", sip_parse_subject_header, NULL, NULL, sip_free_phdr}, 105*2882Svi117747 {"TIMESTAMP", NULL, sip_parse_timestamp_header, NULL, NULL, 106*2882Svi117747 sip_free_phdr}, 107*2882Svi117747 {"UNSUPPORTED", NULL, sip_parse_usupport_header, NULL, NULL, 108*2882Svi117747 sip_free_phdr}, 109*2882Svi117747 {"SUPPORTED", "k", sip_parse_support_header, NULL, NULL, sip_free_phdr}, 110*2882Svi117747 {"USER-AGENT", NULL, sip_parse_useragt_header, NULL, NULL, 111*2882Svi117747 sip_free_phdr}, 112*2882Svi117747 {"WARNING", NULL, sip_parse_warn_header, NULL, NULL, sip_free_phdr}, 113*2882Svi117747 {"ALLOW-EVENTS", "u", sip_parse_allow_events_header, NULL, NULL, 114*2882Svi117747 sip_free_phdr}, 115*2882Svi117747 {"EVENT", "o", sip_parse_event_header, NULL, NULL, sip_free_phdr}, 116*2882Svi117747 {"SUBSCRIPTION-STATE", NULL, sip_parse_substate_header, NULL, NULL, 117*2882Svi117747 sip_free_phdr}, 118*2882Svi117747 {"AUTHORIZATION", NULL, sip_parse_author_header, NULL, NULL, 119*2882Svi117747 sip_free_phdr}, 120*2882Svi117747 {"AUTHENTICATION-INFO", NULL, sip_parse_ainfo_header, NULL, NULL, 121*2882Svi117747 sip_free_phdr}, 122*2882Svi117747 {"PROXY-AUTHORIZATION", NULL, sip_parse_pauthor_header, NULL, NULL, 123*2882Svi117747 sip_free_phdr}, 124*2882Svi117747 {"PROXY-AUTHENTICATE", NULL, sip_parse_pauthen_header, NULL, NULL, 125*2882Svi117747 sip_free_phdr}, 126*2882Svi117747 {"PROXY-REQUIRE", NULL, sip_parse_preq_header, NULL, NULL, 127*2882Svi117747 sip_free_phdr}, 128*2882Svi117747 {"WWW-AUTHENTICATE", NULL, sip_parse_wauthen_header, NULL, NULL, 129*2882Svi117747 sip_free_phdr}, 130*2882Svi117747 {"RSEQ", NULL, sip_parse_rseq, NULL, NULL, sip_free_phdr}, 131*2882Svi117747 {"RACK", NULL, sip_parse_rack, NULL, NULL, sip_free_phdr}, 132*2882Svi117747 {"P-ASSERTED-IDENTITY", NULL, sip_parse_passertedid, NULL, NULL, 133*2882Svi117747 sip_free_phdr}, 134*2882Svi117747 {"P-PREFERRED-IDENTITY", NULL, sip_parse_ppreferredid, NULL, NULL, 135*2882Svi117747 sip_free_phdr}, 136*2882Svi117747 {"PRIVACY", NULL, sip_parse_privacy_header, NULL, NULL, sip_free_phdr}, 137*2882Svi117747 {NULL, NULL, NULL, NULL, NULL, NULL}, 138*2882Svi117747 }; 139*2882Svi117747 140*2882Svi117747 #define MAX_SIP_HEADERS \ 141*2882Svi117747 sizeof (sip_header_function_table) / sizeof (sip_header_function_t) 142*2882Svi117747 143*2882Svi117747 /* 144*2882Svi117747 * External/application provided function table 145*2882Svi117747 */ 146*2882Svi117747 sip_header_function_t *sip_header_function_table_external = NULL; 147*2882Svi117747 148*2882Svi117747 /* 149*2882Svi117747 * Free parameter list 150*2882Svi117747 */ 151*2882Svi117747 static void 152*2882Svi117747 sip_free_params(sip_param_t *param_list) 153*2882Svi117747 { 154*2882Svi117747 sip_param_t *param, *next_param; 155*2882Svi117747 156*2882Svi117747 param = param_list; 157*2882Svi117747 158*2882Svi117747 while (param != NULL) { 159*2882Svi117747 next_param = param->param_next; 160*2882Svi117747 free(param); 161*2882Svi117747 param = next_param; 162*2882Svi117747 } 163*2882Svi117747 } 164*2882Svi117747 165*2882Svi117747 /* 166*2882Svi117747 * Common header free routine 167*2882Svi117747 */ 168*2882Svi117747 void 169*2882Svi117747 sip_free_phdr(sip_parsed_header_t *header) 170*2882Svi117747 { 171*2882Svi117747 sip_hdr_value_t *value; 172*2882Svi117747 sip_hdr_value_t *next_value; 173*2882Svi117747 174*2882Svi117747 if (header == NULL) 175*2882Svi117747 return; 176*2882Svi117747 value = (sip_hdr_value_t *)header->value; 177*2882Svi117747 while (value != NULL) { 178*2882Svi117747 sip_free_params(value->sip_param_list); 179*2882Svi117747 next_value = value->sip_next_value; 180*2882Svi117747 free(value); 181*2882Svi117747 value = next_value; 182*2882Svi117747 } 183*2882Svi117747 free(header); 184*2882Svi117747 } 185*2882Svi117747 186*2882Svi117747 /* 187*2882Svi117747 * Free Contact/From/To header 188*2882Svi117747 */ 189*2882Svi117747 void 190*2882Svi117747 sip_free_cftr_header(sip_parsed_header_t *header) 191*2882Svi117747 { 192*2882Svi117747 sip_hdr_value_t *value; 193*2882Svi117747 sip_hdr_value_t *next_value; 194*2882Svi117747 195*2882Svi117747 if (header == NULL) 196*2882Svi117747 return; 197*2882Svi117747 value = (sip_hdr_value_t *)header->value; 198*2882Svi117747 while (value != NULL) { 199*2882Svi117747 next_value = value->sip_next_value; 200*2882Svi117747 sip_free_params(value->sip_param_list); 201*2882Svi117747 if (value->cftr_name != NULL) 202*2882Svi117747 free(value->cftr_name); 203*2882Svi117747 if (value->sip_value_parsed_uri != NULL) { 204*2882Svi117747 sip_free_parsed_uri(value->sip_value_parsed_uri); 205*2882Svi117747 value->sip_value_parsed_uri = NULL; 206*2882Svi117747 } 207*2882Svi117747 free(value); 208*2882Svi117747 value = next_value; 209*2882Svi117747 } 210*2882Svi117747 free(header); 211*2882Svi117747 } 212*2882Svi117747 213*2882Svi117747 /* 214*2882Svi117747 * Return new header 215*2882Svi117747 */ 216*2882Svi117747 _sip_header_t * 217*2882Svi117747 sip_new_header(int header_size) 218*2882Svi117747 { 219*2882Svi117747 _sip_header_t *new_header; 220*2882Svi117747 221*2882Svi117747 new_header = calloc(1, sizeof (_sip_header_t)); 222*2882Svi117747 if (new_header == NULL) 223*2882Svi117747 return (NULL); 224*2882Svi117747 225*2882Svi117747 /* 226*2882Svi117747 * We are using snprintf which adds a null character 227*2882Svi117747 * so allocate an extra byte which is not part of 228*2882Svi117747 * the message header 229*2882Svi117747 */ 230*2882Svi117747 new_header->sip_hdr_start = calloc(1, header_size + 1); 231*2882Svi117747 if (new_header->sip_hdr_start == NULL) { 232*2882Svi117747 free(new_header); 233*2882Svi117747 return (NULL); 234*2882Svi117747 } 235*2882Svi117747 new_header->sip_hdr_end = new_header->sip_hdr_start + header_size; 236*2882Svi117747 new_header->sip_hdr_current = new_header->sip_hdr_start; 237*2882Svi117747 new_header->sip_hdr_allocated = B_TRUE; 238*2882Svi117747 return (new_header); 239*2882Svi117747 } 240*2882Svi117747 241*2882Svi117747 /* 242*2882Svi117747 * Free the given header 243*2882Svi117747 */ 244*2882Svi117747 void 245*2882Svi117747 sip_free_header(_sip_header_t *sip_header) 246*2882Svi117747 { 247*2882Svi117747 if (sip_header->sip_hdr_allocated) { 248*2882Svi117747 assert(sip_header->sip_hdr_start != NULL); 249*2882Svi117747 free(sip_header->sip_hdr_start); 250*2882Svi117747 } 251*2882Svi117747 if (sip_header->sip_hdr_parsed != NULL) { 252*2882Svi117747 assert(sip_header->sip_header_functions != NULL); 253*2882Svi117747 if (sip_header->sip_header_functions->header_free != NULL) { 254*2882Svi117747 sip_header->sip_header_functions->header_free( 255*2882Svi117747 sip_header->sip_hdr_parsed); 256*2882Svi117747 } 257*2882Svi117747 } 258*2882Svi117747 free(sip_header); 259*2882Svi117747 } 260*2882Svi117747 261*2882Svi117747 /* 262*2882Svi117747 * Return a copy of the header passed in. 263*2882Svi117747 */ 264*2882Svi117747 _sip_header_t * 265*2882Svi117747 sip_dup_header(_sip_header_t *from) 266*2882Svi117747 { 267*2882Svi117747 size_t hdr_size; 268*2882Svi117747 _sip_header_t *to; 269*2882Svi117747 270*2882Svi117747 hdr_size = from->sip_hdr_end - from->sip_hdr_start; 271*2882Svi117747 to = sip_new_header(hdr_size); 272*2882Svi117747 if (to == NULL) 273*2882Svi117747 return (NULL); 274*2882Svi117747 if (from->sip_header_state == SIP_HEADER_DELETED_VAL) { 275*2882Svi117747 to->sip_hdr_end = to->sip_hdr_start + 276*2882Svi117747 sip_copy_values(to->sip_hdr_start, from); 277*2882Svi117747 } else { 278*2882Svi117747 (void) memcpy(to->sip_hdr_start, from->sip_hdr_start, hdr_size); 279*2882Svi117747 to->sip_hdr_end = to->sip_hdr_start + hdr_size; 280*2882Svi117747 } 281*2882Svi117747 to->sip_header_functions = from->sip_header_functions; 282*2882Svi117747 return (to); 283*2882Svi117747 } 284*2882Svi117747 285*2882Svi117747 /* 286*2882Svi117747 * Copy header with extra_param, if any, to sip_msg 287*2882Svi117747 */ 288*2882Svi117747 int 289*2882Svi117747 _sip_copy_header(_sip_msg_t *sip_msg, _sip_header_t *header, char *extra_param, 290*2882Svi117747 boolean_t skip_crlf) 291*2882Svi117747 { 292*2882Svi117747 _sip_header_t *new_header; 293*2882Svi117747 int hdrlen; 294*2882Svi117747 int extra_len = 0; 295*2882Svi117747 int ncrlf = 0; 296*2882Svi117747 char *p; 297*2882Svi117747 298*2882Svi117747 #ifdef __solaris__ 299*2882Svi117747 assert(mutex_held(&sip_msg->sip_msg_mutex)); 300*2882Svi117747 #endif 301*2882Svi117747 if (extra_param != NULL) { 302*2882Svi117747 extra_len = SIP_SPACE_LEN + sizeof (char) + SIP_SPACE_LEN + 303*2882Svi117747 strlen(extra_param); 304*2882Svi117747 } 305*2882Svi117747 /* 306*2882Svi117747 * Just take one if there are more, i.e. if this is the last header 307*2882Svi117747 * before the content. 308*2882Svi117747 */ 309*2882Svi117747 if (skip_crlf) { 310*2882Svi117747 if (header->sip_hdr_end - strlen(SIP_CRLF) <= 311*2882Svi117747 header->sip_hdr_start) { 312*2882Svi117747 goto proceed; 313*2882Svi117747 } 314*2882Svi117747 p = header->sip_hdr_end - strlen(SIP_CRLF); 315*2882Svi117747 while (strncmp(SIP_CRLF, p, strlen(SIP_CRLF)) == 0) { 316*2882Svi117747 ncrlf++; 317*2882Svi117747 if (p - strlen(SIP_CRLF) < header->sip_hdr_start) 318*2882Svi117747 break; 319*2882Svi117747 p -= strlen(SIP_CRLF); 320*2882Svi117747 } 321*2882Svi117747 /* 322*2882Svi117747 * Take one CRLF. 323*2882Svi117747 */ 324*2882Svi117747 ncrlf = (ncrlf - 1) * strlen(SIP_CRLF); 325*2882Svi117747 } 326*2882Svi117747 proceed: 327*2882Svi117747 hdrlen = header->sip_hdr_end - header->sip_hdr_start - ncrlf; 328*2882Svi117747 new_header = sip_new_header(hdrlen + extra_len); 329*2882Svi117747 if (new_header == NULL) 330*2882Svi117747 return (ENOMEM); 331*2882Svi117747 if (header->sip_header_state == SIP_HEADER_DELETED_VAL) { 332*2882Svi117747 int len; 333*2882Svi117747 334*2882Svi117747 len = sip_copy_values(new_header->sip_hdr_start, header); 335*2882Svi117747 new_header->sip_hdr_end = new_header->sip_hdr_start + len; 336*2882Svi117747 hdrlen = hdrlen - len + extra_len; 337*2882Svi117747 } else { 338*2882Svi117747 (void) memcpy(new_header->sip_hdr_start, header->sip_hdr_start, 339*2882Svi117747 hdrlen); 340*2882Svi117747 new_header->sip_hdr_end = new_header->sip_hdr_start + hdrlen; 341*2882Svi117747 hdrlen = extra_len; 342*2882Svi117747 } 343*2882Svi117747 if (extra_param != NULL) { 344*2882Svi117747 /* 345*2882Svi117747 * Find CR 346*2882Svi117747 */ 347*2882Svi117747 if (sip_find_cr(new_header) != 0) { 348*2882Svi117747 sip_free_header(new_header); 349*2882Svi117747 return (EINVAL); 350*2882Svi117747 } 351*2882Svi117747 hdrlen += new_header->sip_hdr_end - new_header->sip_hdr_current; 352*2882Svi117747 (void) snprintf(new_header->sip_hdr_current, hdrlen + 1, 353*2882Svi117747 " %c %s%s", SIP_SEMI, extra_param, SIP_CRLF); 354*2882Svi117747 } 355*2882Svi117747 356*2882Svi117747 new_header->sip_hdr_end += extra_len; 357*2882Svi117747 new_header->sip_header_functions = header->sip_header_functions; 358*2882Svi117747 _sip_add_header(sip_msg, new_header, B_TRUE, B_FALSE, NULL); 359*2882Svi117747 return (0); 360*2882Svi117747 } 361*2882Svi117747 362*2882Svi117747 /* 363*2882Svi117747 * Copy all "header_name" headers from _old_msg to _new_msg 364*2882Svi117747 */ 365*2882Svi117747 int 366*2882Svi117747 _sip_find_and_copy_all_header(_sip_msg_t *_old_msg, _sip_msg_t *_new_msg, 367*2882Svi117747 char *header_name) 368*2882Svi117747 { 369*2882Svi117747 _sip_header_t *header; 370*2882Svi117747 int ret = 0; 371*2882Svi117747 372*2882Svi117747 if (_old_msg == NULL || _new_msg == NULL) 373*2882Svi117747 return (EINVAL); 374*2882Svi117747 #ifdef __solaris__ 375*2882Svi117747 assert(mutex_held(&_old_msg->sip_msg_mutex)); 376*2882Svi117747 #endif 377*2882Svi117747 if (_old_msg != _new_msg) 378*2882Svi117747 (void) pthread_mutex_lock(&_new_msg->sip_msg_mutex); 379*2882Svi117747 header = sip_search_for_header(_old_msg, header_name, NULL); 380*2882Svi117747 while (header != NULL) { 381*2882Svi117747 ret = _sip_copy_header(_new_msg, header, NULL, B_TRUE); 382*2882Svi117747 if (ret != 0) 383*2882Svi117747 break; 384*2882Svi117747 header = sip_search_for_header(_old_msg, header_name, header); 385*2882Svi117747 } 386*2882Svi117747 if (_old_msg != _new_msg) 387*2882Svi117747 (void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex); 388*2882Svi117747 return (ret); 389*2882Svi117747 } 390*2882Svi117747 391*2882Svi117747 /* 392*2882Svi117747 * Copy header_name from _old_msg to _new_msg with extra_parm. 393*2882Svi117747 */ 394*2882Svi117747 int 395*2882Svi117747 _sip_find_and_copy_header(sip_msg_t _old_msg, sip_msg_t _new_msg, 396*2882Svi117747 char *header_name, char *extra_param, boolean_t lock_newmsg) 397*2882Svi117747 { 398*2882Svi117747 _sip_header_t *header; 399*2882Svi117747 int ret; 400*2882Svi117747 401*2882Svi117747 if (_old_msg == NULL || _new_msg == NULL) 402*2882Svi117747 return (EINVAL); 403*2882Svi117747 #ifdef __solaris__ 404*2882Svi117747 assert(mutex_held(&_old_msg->sip_msg_mutex)); 405*2882Svi117747 #endif 406*2882Svi117747 header = sip_search_for_header(_old_msg, header_name, NULL); 407*2882Svi117747 if (header == NULL) 408*2882Svi117747 return (EINVAL); 409*2882Svi117747 if (lock_newmsg) 410*2882Svi117747 (void) pthread_mutex_lock(&_new_msg->sip_msg_mutex); 411*2882Svi117747 ret = _sip_copy_header(_new_msg, header, extra_param, B_TRUE); 412*2882Svi117747 if (lock_newmsg) 413*2882Svi117747 (void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex); 414*2882Svi117747 return (ret); 415*2882Svi117747 } 416*2882Svi117747 417*2882Svi117747 /* 418*2882Svi117747 * Copy all headers from old_msg to new_msg 419*2882Svi117747 */ 420*2882Svi117747 int 421*2882Svi117747 sip_copy_all_headers(sip_msg_t old_msg, sip_msg_t new_msg) 422*2882Svi117747 { 423*2882Svi117747 _sip_header_t *header; 424*2882Svi117747 _sip_msg_t *_old_msg; 425*2882Svi117747 _sip_msg_t *_new_msg; 426*2882Svi117747 int ret = 0; 427*2882Svi117747 428*2882Svi117747 if (old_msg == NULL || new_msg == NULL) 429*2882Svi117747 return (EINVAL); 430*2882Svi117747 _old_msg = (_sip_msg_t *)old_msg; 431*2882Svi117747 _new_msg = (_sip_msg_t *)new_msg; 432*2882Svi117747 433*2882Svi117747 (void) pthread_mutex_lock(&_old_msg->sip_msg_mutex); 434*2882Svi117747 (void) pthread_mutex_lock(&_new_msg->sip_msg_mutex); 435*2882Svi117747 header = sip_search_for_header(_old_msg, NULL, NULL); 436*2882Svi117747 while (header != NULL) { 437*2882Svi117747 ret = _sip_copy_header(_new_msg, header, NULL, B_FALSE); 438*2882Svi117747 if (ret != 0) 439*2882Svi117747 goto done; 440*2882Svi117747 header = sip_search_for_header(_old_msg, NULL, header); 441*2882Svi117747 } 442*2882Svi117747 done: 443*2882Svi117747 (void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex); 444*2882Svi117747 (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex); 445*2882Svi117747 return (ret); 446*2882Svi117747 } 447*2882Svi117747 448*2882Svi117747 /* 449*2882Svi117747 * Copy start line from msg to sip_msg 450*2882Svi117747 */ 451*2882Svi117747 int 452*2882Svi117747 sip_copy_start_line(sip_msg_t msg, sip_msg_t sip_msg) 453*2882Svi117747 { 454*2882Svi117747 int len; 455*2882Svi117747 _sip_header_t *new_header; 456*2882Svi117747 _sip_msg_t *_old_msg; 457*2882Svi117747 _sip_msg_t *_sip_msg; 458*2882Svi117747 459*2882Svi117747 if (msg == NULL || sip_msg == NULL) 460*2882Svi117747 return (EINVAL); 461*2882Svi117747 _old_msg = (_sip_msg_t *)msg; 462*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 463*2882Svi117747 464*2882Svi117747 (void) pthread_mutex_lock(&_old_msg->sip_msg_mutex); 465*2882Svi117747 if (_old_msg->sip_msg_start_line == NULL) { 466*2882Svi117747 (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex); 467*2882Svi117747 return (EINVAL); 468*2882Svi117747 } 469*2882Svi117747 len = _old_msg->sip_msg_start_line->sip_hdr_end - 470*2882Svi117747 _old_msg->sip_msg_start_line->sip_hdr_start; 471*2882Svi117747 new_header = sip_new_header(len); 472*2882Svi117747 if (new_header == NULL) { 473*2882Svi117747 (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex); 474*2882Svi117747 return (ENOMEM); 475*2882Svi117747 } 476*2882Svi117747 new_header->sip_hdr_sipmsg = _sip_msg; 477*2882Svi117747 (void) pthread_mutex_lock(&sip_msg->sip_msg_mutex); 478*2882Svi117747 _sip_msg->sip_msg_start_line = new_header; 479*2882Svi117747 _sip_msg->sip_msg_len = len; 480*2882Svi117747 (void) strncpy(_sip_msg->sip_msg_start_line->sip_hdr_start, 481*2882Svi117747 _old_msg->sip_msg_start_line->sip_hdr_start, len); 482*2882Svi117747 (void) sip_parse_first_line(_sip_msg->sip_msg_start_line, 483*2882Svi117747 &_sip_msg->sip_msg_req_res); 484*2882Svi117747 (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex); 485*2882Svi117747 (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex); 486*2882Svi117747 return (0); 487*2882Svi117747 } 488*2882Svi117747 489*2882Svi117747 /* 490*2882Svi117747 * Delete start line from sip_msg 491*2882Svi117747 */ 492*2882Svi117747 int 493*2882Svi117747 sip_delete_start_line_locked(_sip_msg_t *_sip_msg) 494*2882Svi117747 { 495*2882Svi117747 _sip_header_t *header; 496*2882Svi117747 _sip_header_t *next_header; 497*2882Svi117747 498*2882Svi117747 if (_sip_msg->sip_msg_start_line == NULL) 499*2882Svi117747 return (EINVAL); 500*2882Svi117747 501*2882Svi117747 header = _sip_msg->sip_msg_start_line; 502*2882Svi117747 while (header != NULL) { 503*2882Svi117747 next_header = header->sip_hdr_next; 504*2882Svi117747 _sip_msg->sip_msg_len -= (header->sip_hdr_end - 505*2882Svi117747 header->sip_hdr_start); 506*2882Svi117747 sip_free_header(header); 507*2882Svi117747 header = next_header; 508*2882Svi117747 } 509*2882Svi117747 _sip_msg->sip_msg_start_line = NULL; 510*2882Svi117747 511*2882Svi117747 /* 512*2882Svi117747 * Also delete the sip_msg_req_res info since we don't have a start 513*2882Svi117747 * line. 514*2882Svi117747 */ 515*2882Svi117747 while (_sip_msg->sip_msg_req_res != NULL) { 516*2882Svi117747 sip_message_type_t *sip_msg_type_ptr; 517*2882Svi117747 518*2882Svi117747 sip_msg_type_ptr = _sip_msg->sip_msg_req_res->sip_next; 519*2882Svi117747 if (_sip_msg->sip_msg_req_res->is_request) { 520*2882Svi117747 sip_request_t *reqline; 521*2882Svi117747 522*2882Svi117747 reqline = &_sip_msg->sip_msg_req_res->U.sip_request; 523*2882Svi117747 if (reqline->sip_parse_uri != NULL) { 524*2882Svi117747 sip_free_parsed_uri(reqline->sip_parse_uri); 525*2882Svi117747 reqline->sip_parse_uri = NULL; 526*2882Svi117747 } 527*2882Svi117747 } 528*2882Svi117747 free(_sip_msg->sip_msg_req_res); 529*2882Svi117747 _sip_msg->sip_msg_req_res = sip_msg_type_ptr; 530*2882Svi117747 } 531*2882Svi117747 return (0); 532*2882Svi117747 } 533*2882Svi117747 534*2882Svi117747 535*2882Svi117747 /* 536*2882Svi117747 * Delete start line from sip_msg 537*2882Svi117747 */ 538*2882Svi117747 int 539*2882Svi117747 sip_delete_start_line(sip_msg_t sip_msg) 540*2882Svi117747 { 541*2882Svi117747 _sip_msg_t *_sip_msg; 542*2882Svi117747 int ret; 543*2882Svi117747 544*2882Svi117747 if (sip_msg == NULL) 545*2882Svi117747 return (EINVAL); 546*2882Svi117747 547*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 548*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 549*2882Svi117747 ret = sip_delete_start_line_locked(_sip_msg); 550*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 551*2882Svi117747 552*2882Svi117747 return (ret); 553*2882Svi117747 } 554*2882Svi117747 555*2882Svi117747 /* 556*2882Svi117747 * Delete all headers from _sip_msg 557*2882Svi117747 */ 558*2882Svi117747 void 559*2882Svi117747 sip_delete_all_headers(_sip_msg_t *_sip_msg) 560*2882Svi117747 { 561*2882Svi117747 _sip_header_t *header; 562*2882Svi117747 563*2882Svi117747 #ifdef __solaris__ 564*2882Svi117747 assert(mutex_held(&_sip_msg->sip_msg_mutex)); 565*2882Svi117747 #endif 566*2882Svi117747 567*2882Svi117747 header = _sip_msg->sip_msg_headers_start; 568*2882Svi117747 while (header != NULL) { 569*2882Svi117747 _sip_header_t *next_header; 570*2882Svi117747 next_header = header->sip_hdr_next; 571*2882Svi117747 sip_free_header(header); 572*2882Svi117747 header = next_header; 573*2882Svi117747 } 574*2882Svi117747 _sip_msg->sip_msg_headers_start = NULL; 575*2882Svi117747 _sip_msg->sip_msg_headers_end = NULL; 576*2882Svi117747 } 577*2882Svi117747 578*2882Svi117747 /* 579*2882Svi117747 * Delete and free the named header. If header_name is null 580*2882Svi117747 * free all headers. 581*2882Svi117747 */ 582*2882Svi117747 void 583*2882Svi117747 sip_delete_headers(sip_msg_t sip_msg, char *header_name) 584*2882Svi117747 { 585*2882Svi117747 _sip_header_t *header; 586*2882Svi117747 _sip_msg_t *_sip_msg; 587*2882Svi117747 588*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 589*2882Svi117747 #ifdef __solaris__ 590*2882Svi117747 assert(mutex_held(&_sip_msg->sip_msg_mutex)); 591*2882Svi117747 #endif 592*2882Svi117747 header = sip_search_for_header(_sip_msg, header_name, NULL); 593*2882Svi117747 if (header == NULL) 594*2882Svi117747 return; 595*2882Svi117747 while (header != NULL) { 596*2882Svi117747 if (_sip_msg->sip_msg_headers_start == header) { 597*2882Svi117747 _sip_msg->sip_msg_headers_start = header->sip_hdr_next; 598*2882Svi117747 } else { 599*2882Svi117747 header->sip_hdr_prev->sip_hdr_next = 600*2882Svi117747 header->sip_hdr_next; 601*2882Svi117747 } 602*2882Svi117747 if (_sip_msg->sip_msg_headers_end == header) { 603*2882Svi117747 _sip_msg->sip_msg_headers_end = header->sip_hdr_prev; 604*2882Svi117747 } else { 605*2882Svi117747 header->sip_hdr_next->sip_hdr_prev = 606*2882Svi117747 header->sip_hdr_prev; 607*2882Svi117747 } 608*2882Svi117747 sip_free_header(header); 609*2882Svi117747 if (header_name != NULL) 610*2882Svi117747 return; 611*2882Svi117747 else 612*2882Svi117747 header = sip_search_for_header(_sip_msg, NULL, NULL); 613*2882Svi117747 } 614*2882Svi117747 } 615*2882Svi117747 616*2882Svi117747 /* 617*2882Svi117747 * Add a header to sip_msg. If header_name is provided then the new header 618*2882Svi117747 * is added before that header, if first is set, or after. If append is 619*2882Svi117747 * set, then the header is added to the end of the header list. 620*2882Svi117747 */ 621*2882Svi117747 void 622*2882Svi117747 _sip_add_header(_sip_msg_t *sip_msg, _sip_header_t *new_header, 623*2882Svi117747 boolean_t append, boolean_t first, char *header_name) 624*2882Svi117747 { 625*2882Svi117747 _sip_header_t *header = NULL; 626*2882Svi117747 627*2882Svi117747 if (sip_msg == NULL || new_header == NULL) 628*2882Svi117747 return; 629*2882Svi117747 #ifdef __solaris__ 630*2882Svi117747 assert(mutex_held(&sip_msg->sip_msg_mutex)); 631*2882Svi117747 #endif 632*2882Svi117747 new_header->sip_hdr_sipmsg = sip_msg; 633*2882Svi117747 if (header_name != NULL) { 634*2882Svi117747 _sip_header_t *header_tmp; 635*2882Svi117747 636*2882Svi117747 header = sip_search_for_header(sip_msg, header_name, NULL); 637*2882Svi117747 header_tmp = header; 638*2882Svi117747 if (!first) { 639*2882Svi117747 while (header != NULL) { 640*2882Svi117747 header_tmp = header; 641*2882Svi117747 header = sip_search_for_header(sip_msg, 642*2882Svi117747 header_name, header); 643*2882Svi117747 } 644*2882Svi117747 } 645*2882Svi117747 header = header_tmp; 646*2882Svi117747 if (header == NULL) 647*2882Svi117747 append = B_TRUE; 648*2882Svi117747 } 649*2882Svi117747 650*2882Svi117747 if (header != NULL) { 651*2882Svi117747 if (append) { 652*2882Svi117747 new_header->sip_hdr_prev = header; 653*2882Svi117747 if (sip_msg->sip_msg_headers_end == header) { 654*2882Svi117747 sip_msg->sip_msg_headers_end = new_header; 655*2882Svi117747 new_header->sip_hdr_next = NULL; 656*2882Svi117747 } else { 657*2882Svi117747 header->sip_hdr_next->sip_hdr_prev = new_header; 658*2882Svi117747 new_header->sip_hdr_next = header->sip_hdr_next; 659*2882Svi117747 } 660*2882Svi117747 header->sip_hdr_next = new_header; 661*2882Svi117747 } else { 662*2882Svi117747 new_header->sip_hdr_next = header; 663*2882Svi117747 if (sip_msg->sip_msg_headers_start == header) { 664*2882Svi117747 sip_msg->sip_msg_headers_start = new_header; 665*2882Svi117747 new_header->sip_hdr_prev = NULL; 666*2882Svi117747 } else { 667*2882Svi117747 header->sip_hdr_prev->sip_hdr_next = new_header; 668*2882Svi117747 new_header->sip_hdr_prev = header->sip_hdr_prev; 669*2882Svi117747 } 670*2882Svi117747 header->sip_hdr_prev = new_header; 671*2882Svi117747 } 672*2882Svi117747 } else { 673*2882Svi117747 if (append) { 674*2882Svi117747 if (sip_msg->sip_msg_headers_end != NULL) { 675*2882Svi117747 sip_msg->sip_msg_headers_end->sip_hdr_next = 676*2882Svi117747 new_header; 677*2882Svi117747 } else { 678*2882Svi117747 sip_msg->sip_msg_headers_start = new_header; 679*2882Svi117747 } 680*2882Svi117747 new_header->sip_hdr_prev = 681*2882Svi117747 sip_msg->sip_msg_headers_end; 682*2882Svi117747 new_header->sip_hdr_next = NULL; 683*2882Svi117747 sip_msg->sip_msg_headers_end = new_header; 684*2882Svi117747 } else { 685*2882Svi117747 if (sip_msg->sip_msg_headers_start != NULL) { 686*2882Svi117747 sip_msg->sip_msg_headers_start->sip_hdr_prev = 687*2882Svi117747 new_header; 688*2882Svi117747 } else { 689*2882Svi117747 sip_msg->sip_msg_headers_end = new_header; 690*2882Svi117747 } 691*2882Svi117747 new_header->sip_hdr_next = 692*2882Svi117747 sip_msg->sip_msg_headers_start; 693*2882Svi117747 new_header->sip_hdr_prev = NULL; 694*2882Svi117747 sip_msg->sip_msg_headers_start = new_header; 695*2882Svi117747 } 696*2882Svi117747 } 697*2882Svi117747 sip_msg->sip_msg_len += new_header->sip_hdr_end - 698*2882Svi117747 new_header->sip_hdr_start; 699*2882Svi117747 } 700*2882Svi117747 701*2882Svi117747 /* 702*2882Svi117747 * Scan through the function table and return the entry for the given header 703*2882Svi117747 * type. 704*2882Svi117747 */ 705*2882Svi117747 sip_header_function_t * 706*2882Svi117747 _sip_get_header_functions(sip_header_function_t *sip_header_function_table, 707*2882Svi117747 _sip_header_t *sip_header, char *header_name) 708*2882Svi117747 { 709*2882Svi117747 int len; 710*2882Svi117747 int i = 0; 711*2882Svi117747 712*2882Svi117747 if (sip_header == NULL && header_name == NULL) 713*2882Svi117747 return (NULL); 714*2882Svi117747 715*2882Svi117747 /* 716*2882Svi117747 * If header_name is NULL we first have to locate the name 717*2882Svi117747 */ 718*2882Svi117747 if (header_name == NULL) { 719*2882Svi117747 if (sip_skip_white_space(sip_header) != 0) { 720*2882Svi117747 return (NULL); 721*2882Svi117747 } 722*2882Svi117747 header_name = sip_header->sip_hdr_current; 723*2882Svi117747 if (sip_find_separator(sip_header, SIP_HCOLON, (char)NULL, 724*2882Svi117747 (char)NULL) != 0) { 725*2882Svi117747 return (NULL); 726*2882Svi117747 } 727*2882Svi117747 len = sip_header->sip_hdr_current - header_name; 728*2882Svi117747 } else { 729*2882Svi117747 len = strlen(header_name); 730*2882Svi117747 } 731*2882Svi117747 732*2882Svi117747 if (len > 0) { 733*2882Svi117747 while (sip_header_function_table[i].header_name != NULL || 734*2882Svi117747 sip_header_function_table[i].header_short_name != NULL) { 735*2882Svi117747 if (sip_header_function_table[i].header_name != NULL && 736*2882Svi117747 len == 737*2882Svi117747 strlen(sip_header_function_table[i].header_name)) { 738*2882Svi117747 if (strncasecmp(header_name, 739*2882Svi117747 sip_header_function_table[i]. 740*2882Svi117747 header_name, len) == 0) { 741*2882Svi117747 break; 742*2882Svi117747 } 743*2882Svi117747 } else if (sip_header_function_table[i]. 744*2882Svi117747 header_short_name != NULL && len == 745*2882Svi117747 strlen(sip_header_function_table[i]. 746*2882Svi117747 header_short_name)) { 747*2882Svi117747 if (strncasecmp(header_name, 748*2882Svi117747 sip_header_function_table[i]. 749*2882Svi117747 header_short_name, len) == 0) { 750*2882Svi117747 break; 751*2882Svi117747 } 752*2882Svi117747 } 753*2882Svi117747 i++; 754*2882Svi117747 } 755*2882Svi117747 } 756*2882Svi117747 757*2882Svi117747 if (sip_header != NULL) 758*2882Svi117747 sip_header->sip_hdr_current = sip_header->sip_hdr_start; 759*2882Svi117747 if (sip_header_function_table[i].header_name == NULL) 760*2882Svi117747 return (NULL); 761*2882Svi117747 return (&sip_header_function_table[i]); 762*2882Svi117747 } 763*2882Svi117747 764*2882Svi117747 /* 765*2882Svi117747 * Return the entry from the function table for the given header 766*2882Svi117747 */ 767*2882Svi117747 sip_header_function_t * 768*2882Svi117747 sip_get_header_functions(_sip_header_t *sip_header, char *header_name) 769*2882Svi117747 { 770*2882Svi117747 sip_header_function_t *func; 771*2882Svi117747 sip_header_function_t *header_f_table = NULL; 772*2882Svi117747 773*2882Svi117747 if (sip_header_function_table_external != NULL) { 774*2882Svi117747 header_f_table = _sip_get_header_functions( 775*2882Svi117747 sip_header_function_table_external, 776*2882Svi117747 sip_header, header_name); 777*2882Svi117747 if (header_f_table != NULL) 778*2882Svi117747 return (header_f_table); 779*2882Svi117747 } 780*2882Svi117747 func = _sip_get_header_functions(sip_header_function_table, sip_header, 781*2882Svi117747 header_name); 782*2882Svi117747 return (func); 783*2882Svi117747 } 784*2882Svi117747 785*2882Svi117747 /* 786*2882Svi117747 * Search for the header name passed in. 787*2882Svi117747 */ 788*2882Svi117747 _sip_header_t * 789*2882Svi117747 sip_search_for_header(_sip_msg_t *sip_msg, char *header_name, 790*2882Svi117747 _sip_header_t *old_header) 791*2882Svi117747 { 792*2882Svi117747 int len = 0; 793*2882Svi117747 int full_len = 0; 794*2882Svi117747 int compact_len = 0; 795*2882Svi117747 _sip_header_t *header = NULL; 796*2882Svi117747 char *compact_name = NULL; 797*2882Svi117747 char *full_name = NULL; 798*2882Svi117747 sip_header_function_t *header_f_table = NULL; 799*2882Svi117747 800*2882Svi117747 if (sip_msg == NULL) 801*2882Svi117747 return (NULL); 802*2882Svi117747 #ifdef __solaris__ 803*2882Svi117747 assert(mutex_held(&sip_msg->sip_msg_mutex)); 804*2882Svi117747 #endif 805*2882Svi117747 806*2882Svi117747 if (header_name != NULL) { 807*2882Svi117747 header_f_table = sip_get_header_functions(NULL, header_name); 808*2882Svi117747 if (header_f_table != NULL) { 809*2882Svi117747 full_name = header_f_table->header_name; 810*2882Svi117747 compact_name = header_f_table->header_short_name; 811*2882Svi117747 if (full_name != NULL) 812*2882Svi117747 full_len = strlen(full_name); 813*2882Svi117747 if (compact_name != NULL) 814*2882Svi117747 compact_len = strlen(compact_name); 815*2882Svi117747 } else { 816*2882Svi117747 header_f_table = &sip_header_function_table[0]; 817*2882Svi117747 full_name = header_name; 818*2882Svi117747 full_len = strlen(full_name); 819*2882Svi117747 } 820*2882Svi117747 } 821*2882Svi117747 822*2882Svi117747 if (old_header != NULL) 823*2882Svi117747 header = old_header->sip_hdr_next; 824*2882Svi117747 else 825*2882Svi117747 header = sip_msg->sip_msg_headers_start; 826*2882Svi117747 827*2882Svi117747 while (header != NULL) { 828*2882Svi117747 829*2882Svi117747 if (header->sip_header_state == SIP_HEADER_DELETED) { 830*2882Svi117747 header = header->sip_hdr_next; 831*2882Svi117747 continue; 832*2882Svi117747 } 833*2882Svi117747 834*2882Svi117747 if (compact_len == 0 && full_len == 0) 835*2882Svi117747 break; 836*2882Svi117747 837*2882Svi117747 header->sip_hdr_current = header->sip_hdr_start; 838*2882Svi117747 839*2882Svi117747 if (sip_skip_white_space(header)) { 840*2882Svi117747 header = header->sip_hdr_next; 841*2882Svi117747 continue; 842*2882Svi117747 } 843*2882Svi117747 844*2882Svi117747 len = header->sip_hdr_end - header->sip_hdr_current; 845*2882Svi117747 846*2882Svi117747 if (full_name != NULL && (full_len <= len) && 847*2882Svi117747 strncasecmp(header->sip_hdr_current, full_name, 848*2882Svi117747 full_len) == 0) { 849*2882Svi117747 header->sip_hdr_current += full_len; 850*2882Svi117747 if (sip_skip_white_space(header)) { 851*2882Svi117747 header = header->sip_hdr_next; 852*2882Svi117747 continue; 853*2882Svi117747 } 854*2882Svi117747 855*2882Svi117747 if (*header->sip_hdr_current == SIP_HCOLON) { 856*2882Svi117747 header_name = full_name; 857*2882Svi117747 break; 858*2882Svi117747 } 859*2882Svi117747 } 860*2882Svi117747 861*2882Svi117747 if (compact_name != NULL && (compact_len <= len) && 862*2882Svi117747 strncasecmp(header->sip_hdr_current, compact_name, 863*2882Svi117747 compact_len) == 0) { 864*2882Svi117747 header->sip_hdr_current += compact_len; 865*2882Svi117747 if (sip_skip_white_space(header)) { 866*2882Svi117747 header = header->sip_hdr_next; 867*2882Svi117747 continue; 868*2882Svi117747 } 869*2882Svi117747 if (*header->sip_hdr_current == SIP_HCOLON) { 870*2882Svi117747 header_name = compact_name; 871*2882Svi117747 break; 872*2882Svi117747 } 873*2882Svi117747 } 874*2882Svi117747 header = header->sip_hdr_next; 875*2882Svi117747 } 876*2882Svi117747 877*2882Svi117747 if (header != NULL) { 878*2882Svi117747 header->sip_hdr_current = header->sip_hdr_start; 879*2882Svi117747 if (header_f_table == NULL) { 880*2882Svi117747 header_f_table = 881*2882Svi117747 sip_get_header_functions(header, header_name); 882*2882Svi117747 if (header_f_table == NULL) 883*2882Svi117747 header_f_table = &sip_header_function_table[0]; 884*2882Svi117747 } 885*2882Svi117747 886*2882Svi117747 header->sip_header_functions = header_f_table; 887*2882Svi117747 } 888*2882Svi117747 return (header); 889*2882Svi117747 } 890*2882Svi117747 891*2882Svi117747 /* 892*2882Svi117747 * Return the start line as a string. Caller frees string 893*2882Svi117747 */ 894*2882Svi117747 char * 895*2882Svi117747 _sip_startline_to_str(_sip_msg_t *sip_msg, int *error) 896*2882Svi117747 { 897*2882Svi117747 char *slstr; 898*2882Svi117747 int len; 899*2882Svi117747 900*2882Svi117747 if (error != NULL) 901*2882Svi117747 *error = 0; 902*2882Svi117747 903*2882Svi117747 if (sip_msg == NULL || sip_msg->sip_msg_start_line == NULL) { 904*2882Svi117747 if (error != NULL) 905*2882Svi117747 *error = EINVAL; 906*2882Svi117747 return (NULL); 907*2882Svi117747 } 908*2882Svi117747 (void) pthread_mutex_lock(&sip_msg->sip_msg_mutex); 909*2882Svi117747 len = sip_msg->sip_msg_start_line->sip_hdr_end - 910*2882Svi117747 sip_msg->sip_msg_start_line->sip_hdr_start - 2; 911*2882Svi117747 if ((slstr = malloc(len + 1)) == NULL) { 912*2882Svi117747 (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex); 913*2882Svi117747 if (error != NULL) 914*2882Svi117747 *error = ENOMEM; 915*2882Svi117747 return (NULL); 916*2882Svi117747 } 917*2882Svi117747 (void) strncpy(slstr, sip_msg->sip_msg_start_line->sip_hdr_start, len); 918*2882Svi117747 (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex); 919*2882Svi117747 slstr[len] = '\0'; 920*2882Svi117747 return (slstr); 921*2882Svi117747 } 922*2882Svi117747 923*2882Svi117747 /* 924*2882Svi117747 * Return the given header as a string. Caller frees string 925*2882Svi117747 */ 926*2882Svi117747 char * 927*2882Svi117747 sip_hdr_to_str(sip_header_t sip_header, int *error) 928*2882Svi117747 { 929*2882Svi117747 char *hdrstr; 930*2882Svi117747 char *tmpptr; 931*2882Svi117747 _sip_header_t *_sip_header; 932*2882Svi117747 int len; 933*2882Svi117747 934*2882Svi117747 if (error != NULL) 935*2882Svi117747 *error = 0; 936*2882Svi117747 937*2882Svi117747 if (sip_header == NULL) { 938*2882Svi117747 if (error != NULL) 939*2882Svi117747 *error = EINVAL; 940*2882Svi117747 return (NULL); 941*2882Svi117747 } 942*2882Svi117747 _sip_header = (_sip_header_t *)sip_header; 943*2882Svi117747 if (_sip_header->sip_header_state == SIP_HEADER_DELETED) { 944*2882Svi117747 if (_sip_header->sip_hdr_sipmsg != NULL) { 945*2882Svi117747 (void) pthread_mutex_unlock( 946*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 947*2882Svi117747 } 948*2882Svi117747 if (error != NULL) 949*2882Svi117747 *error = EINVAL; 950*2882Svi117747 return (NULL); 951*2882Svi117747 } 952*2882Svi117747 if (_sip_header->sip_hdr_sipmsg != NULL) { 953*2882Svi117747 (void) pthread_mutex_lock( 954*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 955*2882Svi117747 } 956*2882Svi117747 len = _sip_header->sip_hdr_end - _sip_header->sip_hdr_start; 957*2882Svi117747 hdrstr = malloc(len); 958*2882Svi117747 if (hdrstr == NULL) { 959*2882Svi117747 if (_sip_header->sip_hdr_sipmsg != NULL) { 960*2882Svi117747 (void) pthread_mutex_unlock( 961*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 962*2882Svi117747 } 963*2882Svi117747 if (error != NULL) 964*2882Svi117747 *error = ENOMEM; 965*2882Svi117747 return (NULL); 966*2882Svi117747 } 967*2882Svi117747 if (_sip_header->sip_header_state == SIP_HEADER_DELETED_VAL) { 968*2882Svi117747 len = sip_copy_values(hdrstr, _sip_header); 969*2882Svi117747 } else { 970*2882Svi117747 (void) strncpy(hdrstr, _sip_header->sip_hdr_start, len); 971*2882Svi117747 } 972*2882Svi117747 if (_sip_header->sip_hdr_sipmsg != NULL) { 973*2882Svi117747 (void) pthread_mutex_unlock( 974*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 975*2882Svi117747 } 976*2882Svi117747 tmpptr = hdrstr + len; 977*2882Svi117747 while (*tmpptr-- != '\n') { 978*2882Svi117747 if (tmpptr == _sip_header->sip_hdr_start) { 979*2882Svi117747 free(hdrstr); 980*2882Svi117747 if (error != NULL) 981*2882Svi117747 *error = EINVAL; 982*2882Svi117747 return (NULL); 983*2882Svi117747 } 984*2882Svi117747 } 985*2882Svi117747 *tmpptr = '\0'; 986*2882Svi117747 return (hdrstr); 987*2882Svi117747 } 988*2882Svi117747 989*2882Svi117747 /* 990*2882Svi117747 * Given a param list find the named parameter. 991*2882Svi117747 * Returns a pointer to the value or NULL. 992*2882Svi117747 */ 993*2882Svi117747 sip_param_t * 994*2882Svi117747 sip_get_param_from_list(sip_param_t *param_list, char *param_name) 995*2882Svi117747 { 996*2882Svi117747 while (param_list != NULL) { 997*2882Svi117747 if (param_list->param_name.sip_str_len == strlen(param_name) && 998*2882Svi117747 strncasecmp(param_list->param_name.sip_str_ptr, param_name, 999*2882Svi117747 strlen(param_name)) == 0) { 1000*2882Svi117747 return (param_list); 1001*2882Svi117747 } 1002*2882Svi117747 param_list = param_list->param_next; 1003*2882Svi117747 } 1004*2882Svi117747 return (NULL); 1005*2882Svi117747 } 1006