40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * CDDL HEADER START
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 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * See the License for the specific language governing permissions
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * and limitations under the License.
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 * CDDL HEADER END
2c2c41837e330b002c4220a39638150db504fe0evi * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Use is subject to license terms.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#pragma ident "%Z%%M% %I% %E% SMI"
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Built-In Header function table
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"Unknown", NULL, sip_parse_unknown_header, NULL, NULL, NULL},
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 {"CONTENT-TYPE", "c", sip_parse_ctype_header, NULL, NULL,
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 {"RECORD-ROUTE", NULL, sip_parse_cftr_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ACCEPT", NULL, sip_parse_acpt_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ACCEPT-ENCODING", NULL, sip_parse_acpt_encode_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ACCEPT-LANGUAGE", NULL, sip_parse_acpt_lang_header, NULL, NULL,
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 {"CONTENT-DISPOSITION", NULL, sip_parse_contentdis_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CONTENT-ENCODING", "e", sip_parse_contentencode_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"CONTENT-LANGUAGE", NULL, sip_parse_contentlang_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"DATE", NULL, sip_parse_date_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ERROR-INFO", NULL, sip_parse_errorinfo_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"EXPIRES", NULL, sip_parse_expire_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"IN-REPLY-TO", NULL, sip_parse_inreplyto_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"MIN-EXPIRES", NULL, sip_parse_minexpire_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"MIME-VERSION", NULL, sip_parse_mimeversion_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ORGANIZATION", NULL, sip_parse_org_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"PRIORITY", NULL, sip_parse_priority_header, NULL, NULL,
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 {"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 {"UNSUPPORTED", NULL, sip_parse_usupport_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"SUPPORTED", "k", sip_parse_support_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"USER-AGENT", NULL, sip_parse_useragt_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"WARNING", NULL, sip_parse_warn_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"ALLOW-EVENTS", "u", sip_parse_allow_events_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"EVENT", "o", sip_parse_event_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"SUBSCRIPTION-STATE", NULL, sip_parse_substate_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"AUTHORIZATION", NULL, sip_parse_author_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"AUTHENTICATION-INFO", NULL, sip_parse_ainfo_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"PROXY-AUTHORIZATION", NULL, sip_parse_pauthor_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"PROXY-AUTHENTICATE", NULL, sip_parse_pauthen_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"PROXY-REQUIRE", NULL, sip_parse_preq_header, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"WWW-AUTHENTICATE", NULL, sip_parse_wauthen_header, NULL, NULL,
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 {"P-PREFERRED-IDENTITY", NULL, sip_parse_ppreferredid, NULL, NULL,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi {"PRIVACY", NULL, sip_parse_privacy_header, NULL, NULL, sip_free_phdr},
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sizeof (sip_header_function_table) / sizeof (sip_header_function_t)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * External/application provided function table
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_header_function_t *sip_header_function_table_external = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Free parameter list
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vistatic void
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Common header free routine
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Free Contact/From/To header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Return new header
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 new_header->sip_hdr_end = new_header->sip_hdr_start + header_size;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Free the given header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_header->sip_header_functions->header_free != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Return a copy of the header passed in.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) memcpy(to->sip_hdr_start, from->sip_hdr_start, hdr_size);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (to);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Copy header with extra_param, if any, to sip_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_copy_header(_sip_msg_t *sip_msg, _sip_header_t *header, char *extra_param,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi extra_len = SIP_SPACE_LEN + sizeof (char) + SIP_SPACE_LEN +
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Just take one if there are more, i.e. if this is the last header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * before the content.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Take one CRLF.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi hdrlen = header->sip_hdr_end - header->sip_hdr_start - ncrlf;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (header->sip_header_state == SIP_HEADER_DELETED_VAL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi len = sip_copy_values(new_header->sip_hdr_start, header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_end = new_header->sip_hdr_start + len;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) memcpy(new_header->sip_hdr_start, header->sip_hdr_start,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi new_header->sip_hdr_end = new_header->sip_hdr_start + hdrlen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi hdrlen += new_header->sip_hdr_end - new_header->sip_hdr_current;
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 * Copy all "header_name" headers from _old_msg to _new_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_find_and_copy_all_header(_sip_msg_t *_old_msg, _sip_msg_t *_new_msg,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(_old_msg, header_name, NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(_old_msg, header_name, header);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Copy header_name from _old_msg to _new_msg with extra_parm.
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 header = sip_search_for_header(_old_msg, header_name, NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi ret = _sip_copy_header(_new_msg, header, extra_param, B_TRUE);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Copy all headers from old_msg to new_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_copy_all_headers(sip_msg_t old_msg, sip_msg_t new_msg)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Copy start line from msg to sip_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) strncpy(_sip_msg->sip_msg_start_line->sip_hdr_start,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) sip_parse_first_line(_sip_msg->sip_msg_start_line,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (0);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Delete start line from sip_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Also delete the sip_msg_req_res info since we don't have a start
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (0);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Delete start line from sip_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Delete all headers from _sip_msg
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Delete and free the named header. If header_name is null
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * free all headers.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(_sip_msg, header_name, NULL);
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_sip_add_header(_sip_msg_t *sip_msg, _sip_header_t *new_header,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header = sip_search_for_header(sip_msg, header_name, NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Scan through the function table and return the entry for the given header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi_sip_get_header_functions(sip_header_function_t *sip_header_function_table,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int i = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * If header_name is NULL we first have to locate the name
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_find_separator(sip_header, SIP_HCOLON, (char)NULL,
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 * Return the entry from the function table for the given header
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_get_header_functions(_sip_header_t *sip_header, char *header_name)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi func = _sip_get_header_functions(sip_header_function_table, sip_header,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Search for the header name passed in.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_search_for_header(_sip_msg_t *sip_msg, char *header_name,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi header_f_table = sip_get_header_functions(NULL, header_name);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Return the start line as a string. Caller frees string
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (sip_msg == NULL || sip_msg->sip_msg_start_line == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) strncpy(slstr, sip_msg->sip_msg_start_line->sip_hdr_start, len);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Return the given header as a string. Caller frees string
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_header->sip_header_state == SIP_HEADER_DELETED) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi len = _sip_header->sip_hdr_end - _sip_header->sip_hdr_start;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (_sip_header->sip_header_state == SIP_HEADER_DELETED_VAL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Given a param list find the named parameter.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Returns a pointer to the value or NULL.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_get_param_from_list(sip_param_t *param_list, char *param_name)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (param_list->param_name.sip_str_len == strlen(param_name) &&