40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * CDDL HEADER START
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * The contents of this file are subject to the terms of the
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Common Development and Distribution License (the "License").
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * You may not use this file except in compliance with the License.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * or http://www.opensolaris.org/os/licensing.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * See the License for the specific language governing permissions
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * and limitations under the License.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * When distributing Covered Code, include this CDDL HEADER in each
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * If applicable, add the following below this CDDL HEADER, with the
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * fields enclosed by brackets "[]" replaced with your own identifying
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * information: Portions Copyright [yyyy] [name of copyright owner]
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * CDDL HEADER END
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
2c2c41837e330b002c4220a39638150db504fe0evi * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Use is subject to license terms.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#pragma ident "%Z%%M% %I% %E% SMI"
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
2c2c41837e330b002c4220a39638150db504fe0evi#include <stdio.h>
2c2c41837e330b002c4220a39638150db504fe0evi#include <assert.h>
2c2c41837e330b002c4220a39638150db504fe0evi#include <errno.h>
2c2c41837e330b002c4220a39638150db504fe0evi#include <pthread.h>
2c2c41837e330b002c4220a39638150db504fe0evi#include <stdlib.h>
2c2c41837e330b002c4220a39638150db504fe0evi#include <string.h>
2c2c41837e330b002c4220a39638150db504fe0evi#include <sip.h>
2c2c41837e330b002c4220a39638150db504fe0evi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#include "sip_msg.h"
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#include "sip_miscdefs.h"
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#include "sip_parse_generic.h"
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_methods_t sip_methods[MAX_SIP_METHODS] = {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"UNKNOWN", 7},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"INVITE", 6},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ACK", 3},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"OPTIONS", 7},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"BYE", 3},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CANCEL", 6},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"REGISTER", 8},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"REFER", 5},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"INFO", 4},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"SUBSCRIBE", 9},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"NOTIFY", 6},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"PRACK", 5}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi};
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Built-In Header function table
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_header_function_t sip_header_function_table[] = {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"Unknown", NULL, sip_parse_unknown_header, NULL, NULL, NULL},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CONTACT", "m", sip_parse_cftr_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_cftr_header},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"FROM", "F", sip_parse_cftr_header, NULL, NULL, sip_free_cftr_header},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"TO", "T", sip_parse_cftr_header, NULL, NULL, sip_free_cftr_header},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CONTENT-LENGTH", "l", sip_parse_clen_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CONTENT-TYPE", "c", sip_parse_ctype_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CALL-ID", "i", sip_parse_cid_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CSEQ", NULL, sip_parse_cseq_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"VIA", "v", sip_parse_via_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"Max-Forwards", NULL, sip_parse_maxf_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"RECORD-ROUTE", NULL, sip_parse_cftr_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_cftr_header},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ROUTE", NULL, sip_parse_cftr_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_cftr_header},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ACCEPT", NULL, sip_parse_acpt_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ACCEPT-ENCODING", NULL, sip_parse_acpt_encode_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ACCEPT-LANGUAGE", NULL, sip_parse_acpt_lang_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ALERT-INFO", NULL, sip_parse_alert_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ALLOW", NULL, sip_parse_allow_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CALL-INFO", NULL, sip_parse_callinfo_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CONTENT-DISPOSITION", NULL, sip_parse_contentdis_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CONTENT-ENCODING", "e", sip_parse_contentencode_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CONTENT-LANGUAGE", NULL, sip_parse_contentlang_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"DATE", NULL, sip_parse_date_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ERROR-INFO", NULL, sip_parse_errorinfo_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"EXPIRES", NULL, sip_parse_expire_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"IN-REPLY-TO", NULL, sip_parse_inreplyto_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"MIN-EXPIRES", NULL, sip_parse_minexpire_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"MIME-VERSION", NULL, sip_parse_mimeversion_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ORGANIZATION", NULL, sip_parse_org_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"PRIORITY", NULL, sip_parse_priority_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"REQUIRE", NULL, sip_parse_require_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"REPLY-TO", NULL, sip_parse_replyto_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"RETRY-AFTER", NULL, sip_parse_retryaft_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"SERVER", NULL, sip_parse_server_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"SUBJECT", "s", sip_parse_subject_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"TIMESTAMP", NULL, sip_parse_timestamp_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"UNSUPPORTED", NULL, sip_parse_usupport_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"SUPPORTED", "k", sip_parse_support_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"USER-AGENT", NULL, sip_parse_useragt_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"WARNING", NULL, sip_parse_warn_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ALLOW-EVENTS", "u", sip_parse_allow_events_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"EVENT", "o", sip_parse_event_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"SUBSCRIPTION-STATE", NULL, sip_parse_substate_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"AUTHORIZATION", NULL, sip_parse_author_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"AUTHENTICATION-INFO", NULL, sip_parse_ainfo_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"PROXY-AUTHORIZATION", NULL, sip_parse_pauthor_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"PROXY-AUTHENTICATE", NULL, sip_parse_pauthen_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"PROXY-REQUIRE", NULL, sip_parse_preq_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"WWW-AUTHENTICATE", NULL, sip_parse_wauthen_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"RSEQ", NULL, sip_parse_rseq, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"RACK", NULL, sip_parse_rack, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"P-ASSERTED-IDENTITY", NULL, sip_parse_passertedid, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"P-PREFERRED-IDENTITY", NULL, sip_parse_ppreferredid, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"PRIVACY", NULL, sip_parse_privacy_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {NULL, NULL, NULL, NULL, NULL, NULL},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi};
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#define MAX_SIP_HEADERS \
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sizeof (sip_header_function_table) / sizeof (sip_header_function_t)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * External/application provided function table
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_header_function_t *sip_header_function_table_external = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Free parameter list
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vistatic void
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_free_params(sip_param_t *param_list)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_param_t *param, *next_param;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi param = param_list;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (param != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi next_param = param->param_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(param);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi param = next_param;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Common header free routine
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vivoid
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_free_phdr(sip_parsed_header_t *header)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_hdr_value_t *value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_hdr_value_t *next_value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi value = (sip_hdr_value_t *)header->value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (value != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_params(value->sip_param_list);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi next_value = value->sip_next_value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(value);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi value = next_value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Free Contact/From/To header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vivoid
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_free_cftr_header(sip_parsed_header_t *header)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_hdr_value_t *value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_hdr_value_t *next_value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi value = (sip_hdr_value_t *)header->value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (value != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi next_value = value->sip_next_value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_params(value->sip_param_list);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (value->cftr_name != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(value->cftr_name);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (value->sip_value_parsed_uri != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_parsed_uri(value->sip_value_parsed_uri);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi value->sip_value_parsed_uri = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(value);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi value = next_value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Return new header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_header_t *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_new_header(int header_size)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header = calloc(1, sizeof (_sip_header_t));
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (new_header == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi /*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * We are using snprintf which adds a null character
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * so allocate an extra byte which is not part of
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * the message header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_start = calloc(1, header_size + 1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (new_header->sip_hdr_start == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(new_header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_end = new_header->sip_hdr_start + header_size;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_current = new_header->sip_hdr_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_allocated = B_TRUE;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (new_header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Free the given header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vivoid
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_free_header(_sip_header_t *sip_header)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_header->sip_hdr_allocated) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(sip_header->sip_hdr_start != NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(sip_header->sip_hdr_start);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_header->sip_hdr_parsed != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(sip_header->sip_header_functions != NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_header->sip_header_functions->header_free != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_header->sip_header_functions->header_free(
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_header->sip_hdr_parsed);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(sip_header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Return a copy of the header passed in.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_header_t *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_dup_header(_sip_header_t *from)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi size_t hdr_size;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *to;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi hdr_size = from->sip_hdr_end - from->sip_hdr_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi to = sip_new_header(hdr_size);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (to == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (from->sip_header_state == SIP_HEADER_DELETED_VAL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi to->sip_hdr_end = to->sip_hdr_start +
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_copy_values(to->sip_hdr_start, from);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) memcpy(to->sip_hdr_start, from->sip_hdr_start, hdr_size);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi to->sip_hdr_end = to->sip_hdr_start + hdr_size;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi to->sip_header_functions = from->sip_header_functions;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (to);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Copy header with extra_param, if any, to sip_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331viint
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_copy_header(_sip_msg_t *sip_msg, _sip_header_t *header, char *extra_param,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi boolean_t skip_crlf)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int hdrlen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int extra_len = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int ncrlf = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *p;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#ifdef __solaris__
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(mutex_held(&sip_msg->sip_msg_mutex));
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#endif
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (extra_param != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi extra_len = SIP_SPACE_LEN + sizeof (char) + SIP_SPACE_LEN +
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi strlen(extra_param);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi /*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Just take one if there are more, i.e. if this is the last header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * before the content.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (skip_crlf) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header->sip_hdr_end - strlen(SIP_CRLF) <=
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_start) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi goto proceed;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi p = header->sip_hdr_end - strlen(SIP_CRLF);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (strncmp(SIP_CRLF, p, strlen(SIP_CRLF)) == 0) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi ncrlf++;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (p - strlen(SIP_CRLF) < header->sip_hdr_start)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi break;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi p -= strlen(SIP_CRLF);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi /*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Take one CRLF.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi ncrlf = (ncrlf - 1) * strlen(SIP_CRLF);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331viproceed:
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi hdrlen = header->sip_hdr_end - header->sip_hdr_start - ncrlf;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header = sip_new_header(hdrlen + extra_len);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (new_header == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (ENOMEM);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header->sip_header_state == SIP_HEADER_DELETED_VAL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi len = sip_copy_values(new_header->sip_hdr_start, header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_end = new_header->sip_hdr_start + len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi hdrlen = hdrlen - len + extra_len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) memcpy(new_header->sip_hdr_start, header->sip_hdr_start,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi hdrlen);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_end = new_header->sip_hdr_start + hdrlen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi hdrlen = extra_len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (extra_param != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi /*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Find CR
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_find_cr(new_header) != 0) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_header(new_header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (EINVAL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi hdrlen += new_header->sip_hdr_end - new_header->sip_hdr_current;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) snprintf(new_header->sip_hdr_current, hdrlen + 1,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi " %c %s%s", SIP_SEMI, extra_param, SIP_CRLF);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_end += extra_len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_header_functions = header->sip_header_functions;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_add_header(sip_msg, new_header, B_TRUE, B_FALSE, NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (0);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Copy all "header_name" headers from _old_msg to _new_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331viint
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_find_and_copy_all_header(_sip_msg_t *_old_msg, _sip_msg_t *_new_msg,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *header_name)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int ret = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_old_msg == NULL || _new_msg == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (EINVAL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#ifdef __solaris__
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(mutex_held(&_old_msg->sip_msg_mutex));
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#endif
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_old_msg != _new_msg)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_lock(&_new_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(_old_msg, header_name, NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (header != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi ret = _sip_copy_header(_new_msg, header, NULL, B_TRUE);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (ret != 0)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi break;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(_old_msg, header_name, header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_old_msg != _new_msg)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (ret);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Copy header_name from _old_msg to _new_msg with extra_parm.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331viint
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_find_and_copy_header(sip_msg_t _old_msg, sip_msg_t _new_msg,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *header_name, char *extra_param, boolean_t lock_newmsg)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int ret;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_old_msg == NULL || _new_msg == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (EINVAL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#ifdef __solaris__
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(mutex_held(&_old_msg->sip_msg_mutex));
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#endif
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(_old_msg, header_name, NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (EINVAL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (lock_newmsg)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_lock(&_new_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi ret = _sip_copy_header(_new_msg, header, extra_param, B_TRUE);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (lock_newmsg)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (ret);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Copy all headers from old_msg to new_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331viint
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_copy_all_headers(sip_msg_t old_msg, sip_msg_t new_msg)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg_t *_old_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg_t *_new_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int ret = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (old_msg == NULL || new_msg == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (EINVAL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _old_msg = (_sip_msg_t *)old_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _new_msg = (_sip_msg_t *)new_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_lock(&_old_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_lock(&_new_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(_old_msg, NULL, NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (header != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi ret = _sip_copy_header(_new_msg, header, NULL, B_FALSE);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (ret != 0)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi goto done;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(_old_msg, NULL, header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vidone:
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (ret);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Copy start line from msg to sip_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331viint
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_copy_start_line(sip_msg_t msg, sip_msg_t sip_msg)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg_t *_old_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg_t *_sip_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (msg == NULL || sip_msg == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (EINVAL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _old_msg = (_sip_msg_t *)msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg = (_sip_msg_t *)sip_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_lock(&_old_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_old_msg->sip_msg_start_line == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (EINVAL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi len = _old_msg->sip_msg_start_line->sip_hdr_end -
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _old_msg->sip_msg_start_line->sip_hdr_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header = sip_new_header(len);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (new_header == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (ENOMEM);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_sipmsg = _sip_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg->sip_msg_start_line = new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg->sip_msg_len = len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) strncpy(_sip_msg->sip_msg_start_line->sip_hdr_start,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _old_msg->sip_msg_start_line->sip_hdr_start, len);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) sip_parse_first_line(_sip_msg->sip_msg_start_line,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi &_sip_msg->sip_msg_req_res);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (0);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Delete start line from sip_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331viint
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_delete_start_line_locked(_sip_msg_t *_sip_msg)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *next_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_msg->sip_msg_start_line == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (EINVAL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = _sip_msg->sip_msg_start_line;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (header != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi next_header = header->sip_hdr_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg->sip_msg_len -= (header->sip_hdr_end -
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_start);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_header(header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = next_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg->sip_msg_start_line = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi /*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Also delete the sip_msg_req_res info since we don't have a start
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * line.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (_sip_msg->sip_msg_req_res != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_message_type_t *sip_msg_type_ptr;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg_type_ptr = _sip_msg->sip_msg_req_res->sip_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_msg->sip_msg_req_res->is_request) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_request_t *reqline;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reqline = &_sip_msg->sip_msg_req_res->U.sip_request;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (reqline->sip_parse_uri != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_parsed_uri(reqline->sip_parse_uri);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reqline->sip_parse_uri = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(_sip_msg->sip_msg_req_res);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg->sip_msg_req_res = sip_msg_type_ptr;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (0);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Delete start line from sip_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331viint
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_delete_start_line(sip_msg_t sip_msg)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg_t *_sip_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int ret;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_msg == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (EINVAL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg = (_sip_msg_t *)sip_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi ret = sip_delete_start_line_locked(_sip_msg);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (ret);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Delete all headers from _sip_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vivoid
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_delete_all_headers(_sip_msg_t *_sip_msg)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#ifdef __solaris__
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(mutex_held(&_sip_msg->sip_msg_mutex));
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#endif
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = _sip_msg->sip_msg_headers_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (header != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *next_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi next_header = header->sip_hdr_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_header(header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = next_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg->sip_msg_headers_start = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg->sip_msg_headers_end = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Delete and free the named header. If header_name is null
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * free all headers.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vivoid
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_delete_headers(sip_msg_t sip_msg, char *header_name)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg_t *_sip_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg = (_sip_msg_t *)sip_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#ifdef __solaris__
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(mutex_held(&_sip_msg->sip_msg_mutex));
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#endif
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(_sip_msg, header_name, NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (header != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_msg->sip_msg_headers_start == header) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg->sip_msg_headers_start = header->sip_hdr_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_prev->sip_hdr_next =
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_msg->sip_msg_headers_end == header) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_msg->sip_msg_headers_end = header->sip_hdr_prev;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_next->sip_hdr_prev =
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_prev;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_free_header(header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header_name != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi else
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(_sip_msg, NULL, NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Add a header to sip_msg. If header_name is provided then the new header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * is added before that header, if first is set, or after. If append is
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * set, then the header is added to the end of the header list.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vivoid
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_add_header(_sip_msg_t *sip_msg, _sip_header_t *new_header,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi boolean_t append, boolean_t first, char *header_name)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *header = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_msg == NULL || new_header == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#ifdef __solaris__
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(mutex_held(&sip_msg->sip_msg_mutex));
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#endif
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_sipmsg = sip_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header_name != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *header_tmp;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(sip_msg, header_name, NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_tmp = header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (!first) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (header != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_tmp = header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(sip_msg,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_name, header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = header_tmp;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi append = B_TRUE;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (append) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_prev = header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_msg->sip_msg_headers_end == header) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_headers_end = new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_next = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_next->sip_hdr_prev = new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_next = header->sip_hdr_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_next = new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_next = header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_msg->sip_msg_headers_start == header) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_headers_start = new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_prev = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_prev->sip_hdr_next = new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_prev = header->sip_hdr_prev;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_prev = new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (append) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_msg->sip_msg_headers_end != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_headers_end->sip_hdr_next =
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_headers_start = new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_prev =
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_headers_end;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_next = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_headers_end = new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_msg->sip_msg_headers_start != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_headers_start->sip_hdr_prev =
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_headers_end = new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_next =
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_headers_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_prev = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_headers_start = new_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_len += new_header->sip_hdr_end -
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Scan through the function table and return the entry for the given header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * type.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_header_function_t *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_get_header_functions(sip_header_function_t *sip_header_function_table,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *sip_header, char *header_name)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int i = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_header == NULL && header_name == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi /*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * If header_name is NULL we first have to locate the name
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header_name == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_skip_white_space(sip_header) != 0) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_name = sip_header->sip_hdr_current;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_find_separator(sip_header, SIP_HCOLON, (char)NULL,
df4705eab9c873eae60bada4f2138e6f22a76e11gm (char)NULL, B_FALSE) != 0) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi len = sip_header->sip_hdr_current - header_name;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi len = strlen(header_name);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (len > 0) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (sip_header_function_table[i].header_name != NULL ||
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_header_function_table[i].header_short_name != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_header_function_table[i].header_name != NULL &&
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi len ==
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi strlen(sip_header_function_table[i].header_name)) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (strncasecmp(header_name,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_header_function_table[i].
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_name, len) == 0) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi break;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else if (sip_header_function_table[i].
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_short_name != NULL && len ==
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi strlen(sip_header_function_table[i].
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_short_name)) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (strncasecmp(header_name,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_header_function_table[i].
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_short_name, len) == 0) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi break;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi i++;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_header != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_header->sip_hdr_current = sip_header->sip_hdr_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_header_function_table[i].header_name == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (&sip_header_function_table[i]);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Return the entry from the function table for the given header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_header_function_t *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_get_header_functions(_sip_header_t *sip_header, char *header_name)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_header_function_t *func;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_header_function_t *header_f_table = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_header_function_table_external != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_f_table = _sip_get_header_functions(
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_header_function_table_external,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_header, header_name);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header_f_table != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (header_f_table);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi func = _sip_get_header_functions(sip_header_function_table, sip_header,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_name);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (func);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Search for the header name passed in.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_header_t *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_search_for_header(_sip_msg_t *sip_msg, char *header_name,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *old_header)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int len = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int full_len = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int compact_len = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *header = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *compact_name = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *full_name = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_header_function_t *header_f_table = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_msg == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#ifdef __solaris__
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(mutex_held(&sip_msg->sip_msg_mutex));
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#endif
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header_name != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_f_table = sip_get_header_functions(NULL, header_name);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header_f_table != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi full_name = header_f_table->header_name;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi compact_name = header_f_table->header_short_name;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (full_name != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi full_len = strlen(full_name);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (compact_name != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi compact_len = strlen(compact_name);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_f_table = &sip_header_function_table[0];
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi full_name = header_name;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi full_len = strlen(full_name);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (old_header != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = old_header->sip_hdr_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi else
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_msg->sip_msg_headers_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (header != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header->sip_header_state == SIP_HEADER_DELETED) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = header->sip_hdr_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi continue;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (compact_len == 0 && full_len == 0)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi break;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_current = header->sip_hdr_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_skip_white_space(header)) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = header->sip_hdr_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi continue;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi len = header->sip_hdr_end - header->sip_hdr_current;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (full_name != NULL && (full_len <= len) &&
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi strncasecmp(header->sip_hdr_current, full_name,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi full_len) == 0) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_current += full_len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_skip_white_space(header)) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = header->sip_hdr_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi continue;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (*header->sip_hdr_current == SIP_HCOLON) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_name = full_name;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi break;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (compact_name != NULL && (compact_len <= len) &&
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi strncasecmp(header->sip_hdr_current, compact_name,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi compact_len) == 0) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_current += compact_len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_skip_white_space(header)) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = header->sip_hdr_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi continue;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (*header->sip_hdr_current == SIP_HCOLON) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_name = compact_name;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi break;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = header->sip_hdr_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_hdr_current = header->sip_hdr_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header_f_table == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_f_table =
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_get_header_functions(header, header_name);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header_f_table == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_f_table = &sip_header_function_table[0];
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header->sip_header_functions = header_f_table;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Return the start line as a string. Caller frees string
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vichar *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_startline_to_str(_sip_msg_t *sip_msg, int *error)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *slstr;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (error != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *error = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_msg == NULL || sip_msg->sip_msg_start_line == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (error != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *error = EINVAL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi len = sip_msg->sip_msg_start_line->sip_hdr_end -
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_msg->sip_msg_start_line->sip_hdr_start - 2;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if ((slstr = malloc(len + 1)) == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (error != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *error = ENOMEM;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) strncpy(slstr, sip_msg->sip_msg_start_line->sip_hdr_start, len);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi slstr[len] = '\0';
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (slstr);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Return the given header as a string. Caller frees string
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vichar *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_hdr_to_str(sip_header_t sip_header, int *error)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *hdrstr;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *tmpptr;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header_t *_sip_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (error != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *error = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_header == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (error != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *error = EINVAL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi _sip_header = (_sip_header_t *)sip_header;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_header->sip_header_state == SIP_HEADER_DELETED) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_header->sip_hdr_sipmsg != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi &_sip_header->sip_hdr_sipmsg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (error != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *error = EINVAL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_header->sip_hdr_sipmsg != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_lock(
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi &_sip_header->sip_hdr_sipmsg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi len = _sip_header->sip_hdr_end - _sip_header->sip_hdr_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi hdrstr = malloc(len);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (hdrstr == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_header->sip_hdr_sipmsg != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi &_sip_header->sip_hdr_sipmsg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (error != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *error = ENOMEM;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_header->sip_header_state == SIP_HEADER_DELETED_VAL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi len = sip_copy_values(hdrstr, _sip_header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) strncpy(hdrstr, _sip_header->sip_hdr_start, len);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_header->sip_hdr_sipmsg != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi &_sip_header->sip_hdr_sipmsg->sip_msg_mutex);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi tmpptr = hdrstr + len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (*tmpptr-- != '\n') {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (tmpptr == _sip_header->sip_hdr_start) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(hdrstr);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (error != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *error = EINVAL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *tmpptr = '\0';
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (hdrstr);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Given a param list find the named parameter.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Returns a pointer to the value or NULL.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_param_t *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_get_param_from_list(sip_param_t *param_list, char *param_name)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (param_list != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (param_list->param_name.sip_str_len == strlen(param_name) &&
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi strncasecmp(param_list->param_name.sip_str_ptr, param_name,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi strlen(param_name)) == 0) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (param_list);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi param_list = param_list->param_next;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}