⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sip_headers.c

📁 VoIP use SIP protocol interface
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END *//* * Copyright 2006 Sun Microsystems, Inc.  All rights reserved. * Use is subject to license terms. */#pragma ident	"@(#)sip_headers.c	1.40	06/08/17 SMI"#include "sip_msg.h"#include "sip_miscdefs.h"#include "sip_parse_generic.h"sip_methods_t sip_methods[MAX_SIP_METHODS] = {	{"UNKNOWN", 7},	{"INVITE", 6},	{"ACK", 3},	{"OPTIONS", 7},	{"BYE", 3},	{"CANCEL", 6},	{"REGISTER", 8},	{"REFER", 5},	{"INFO", 4},	{"SUBSCRIBE", 9},	{"NOTIFY", 6},	{"PRACK", 5}};#define	MAX_SIP_HEADERS 54/* Built-In Header function table */sip_header_function_t sip_header_function_table[MAX_SIP_HEADERS] = {{"Unknown", NULL, sip_parse_unknown_header, NULL, NULL, NULL},{"CONTACT", "m", sip_parse_cftr_header, NULL, NULL, sip_free_cftr_header},{"FROM", "F", sip_parse_cftr_header, NULL, NULL, sip_free_cftr_header},{"TO", "T", sip_parse_cftr_header, NULL, NULL, sip_free_cftr_header},{"CONTENT-LENGTH", "l", sip_parse_clen_header, NULL, NULL, sip_free_phdr},{"CONTENT-TYPE", "c", sip_parse_ctype_header, NULL, NULL, sip_free_phdr},{"CALL-ID", "i", sip_parse_cid_header, NULL, NULL, sip_free_phdr},{"CSEQ", NULL, sip_parse_cseq_header, NULL, NULL, sip_free_phdr},{"VIA", "v", sip_parse_via_header, NULL, NULL, sip_free_phdr},{"Max-Forwards", NULL, sip_parse_maxf_header, NULL, NULL, sip_free_phdr},{"RECORD-ROUTE", NULL, sip_parse_cftr_header, NULL, NULL, sip_free_phdr},{"ROUTE", NULL, sip_parse_cftr_header, NULL, NULL, sip_free_phdr},{"ACCEPT", NULL, sip_parse_acpt_header, NULL, NULL, sip_free_phdr},{"ACCEPT-ENCODING", NULL, sip_parse_acpt_encode_header, NULL, NULL,sip_free_phdr},{"ACCEPT-LANGUAGE", NULL, sip_parse_acpt_lang_header, NULL, NULL,sip_free_phdr},{"ALERT-INFO", NULL, sip_parse_alert_header, NULL, NULL, sip_free_phdr},{"ALLOW", NULL, sip_parse_allow_header, NULL, NULL, sip_free_phdr},{"CALL-INFO", NULL, sip_parse_callinfo_header, NULL, NULL, sip_free_phdr},{"CONTENT-DISPOSITION", NULL, sip_parse_contentdis_header, NULL, NULL,sip_free_phdr},{"CONTENT-ENCODING", "e", sip_parse_contentencode_header, NULL, NULL,sip_free_phdr},{"CONTENT-LANGUAGE", NULL, sip_parse_contentlang_header, NULL, NULL,sip_free_phdr},{"DATE", NULL, sip_parse_date_header, NULL, NULL, sip_free_phdr},{"ERROR-INFO", NULL, sip_parse_errorinfo_header, NULL, NULL, sip_free_phdr},{"EXPIRES", NULL, sip_parse_expire_header, NULL, NULL, sip_free_phdr},{"IN-REPLY-TO", NULL, sip_parse_inreplyto_header, NULL, NULL, sip_free_phdr},{"MIN-EXPIRES", NULL, sip_parse_minexpire_header, NULL, NULL, sip_free_phdr},{"MIME-VERSION", NULL, sip_parse_mimeversion_header, NULL, NULL, sip_free_phdr},{"ORGANIZATION", NULL, sip_parse_org_header, NULL, NULL, sip_free_phdr},{"PRIORITY", NULL, sip_parse_priority_header, NULL, NULL, sip_free_phdr},{"REQUIRE", NULL, sip_parse_require_header, NULL, NULL, sip_free_phdr},{"REPLY-TO", NULL, sip_parse_replyto_header, NULL, NULL, sip_free_phdr},{"RETRY-AFTER", NULL, sip_parse_retryaft_header, NULL, NULL, sip_free_phdr},{"SERVER", NULL, sip_parse_server_header, NULL, NULL, sip_free_phdr},{"SUBJECT", "s", sip_parse_subject_header, NULL, NULL, sip_free_phdr},{"TIMESTAMP", NULL, sip_parse_timestamp_header, NULL, NULL, sip_free_phdr},{"UNSUPPORTED", NULL, sip_parse_usupport_header, NULL, NULL, sip_free_phdr},{"SUPPORTED", "k", sip_parse_support_header, NULL, NULL, sip_free_phdr},{"USER-AGENT", NULL, sip_parse_useragt_header, NULL, NULL, sip_free_phdr},{"WARNING", NULL, sip_parse_warn_header, NULL, NULL, sip_free_phdr},{"ALLOW-EVENTS", "u", sip_parse_allow_events_header, NULL, NULL, sip_free_phdr},{"EVENT", "o", sip_parse_event_header, NULL, NULL, sip_free_phdr},{"SUBSCRIPTION-STATE", NULL, sip_parse_substate_header, NULL, NULL,sip_free_phdr},{"AUTHORIZATION", NULL, sip_parse_author_header, NULL, NULL, sip_free_phdr},{"AUTHENTICATION-INFO", NULL, sip_parse_ainfo_header, NULL, NULL,sip_free_phdr},{"PROXY-AUTHORIZATION", NULL, sip_parse_pauthor_header, NULL, NULL,sip_free_phdr},{"PROXY-AUTHENTICATE", NULL, sip_parse_pauthen_header, NULL, NULL,sip_free_phdr},{"PROXY-REQUIRE", NULL, sip_parse_preq_header, NULL, NULL, sip_free_phdr},{"WWW-AUTHENTICATE", NULL, sip_parse_wauthen_header, NULL, NULL, sip_free_phdr},{"RSEQ", NULL, sip_parse_rseq, NULL, NULL, sip_free_phdr},{"RACK", NULL, sip_parse_rack, NULL, NULL, sip_free_phdr},{"P-ASSERTED-IDENTITY", NULL, sip_parse_passertedid, NULL, NULL, sip_free_phdr},{"P-PREFERRED-IDENTITY", NULL, sip_parse_ppreferredid, NULL, NULL,sip_free_phdr},{"PRIVACY", NULL, sip_parse_privacy_header, NULL, NULL, sip_free_phdr},{NULL, NULL, NULL, NULL, NULL, NULL},};/* External/application provided function table */sip_header_function_t *sip_header_function_table_external = NULL;/* Free parameter list */static voidsip_free_params(sip_param_t *param_list){	sip_param_t *param, *next_param;	param = param_list;	while (param != NULL) {		next_param = param->param_next;		free(param);		param = next_param;	}}/* Common header free routine */voidsip_free_phdr(sip_parsed_header_t *header){	sip_hdr_value_t	*value;	sip_hdr_value_t	*next_value;	if (header == NULL)		return;	value = (sip_hdr_value_t *)header->value;	while (value != NULL) {		sip_free_params(value->sip_param_list);		next_value = value->sip_next_value;		free(value);		value = next_value;	}	free(header);}/* Free Contact/From/To header */voidsip_free_cftr_header(sip_parsed_header_t *header){	sip_hdr_value_t	*value;	sip_hdr_value_t	*next_value;	if (header == NULL)		return;	value = (sip_hdr_value_t *)header->value;	while (value != NULL) {		next_value = value->sip_next_value;		sip_free_params(value->sip_param_list);		if (value->cftr_name != NULL)			free(value->cftr_name);		if (value->sip_value_parsed_uri != NULL) {			sip_free_parsed_uri(value->sip_value_parsed_uri);			value->sip_value_parsed_uri = NULL;		}		free(value);		value = next_value;	}	free(header);}/* Return new header */_sip_header_t *sip_new_header(int header_size){	_sip_header_t *new_header;	new_header = calloc(1, sizeof (_sip_header_t));	if (new_header == NULL)		return (NULL);	/*	 * We are using snprintf which adds a null character	 * so allocate an extra byte which is not part of	 * the message header	 */	new_header->sip_hdr_start = calloc(1, header_size + 1);	if (new_header->sip_hdr_start == NULL) {		free(new_header);		return (NULL);	}	new_header->sip_hdr_end = new_header->sip_hdr_start + header_size;	new_header->sip_hdr_current = new_header->sip_hdr_start;	new_header->sip_hdr_allocated = B_TRUE;	return (new_header);}/* Free the given header */voidsip_free_header(_sip_header_t *sip_header){	if (sip_header->sip_hdr_allocated) {		assert(sip_header->sip_hdr_start != NULL);		free(sip_header->sip_hdr_start);	}	if (sip_header->sip_hdr_parsed != NULL) {		assert(sip_header->sip_header_functions != NULL);		if (sip_header->sip_header_functions->header_free != NULL) {			sip_header->sip_header_functions->header_free(			    sip_header->sip_hdr_parsed);		}	}	free(sip_header);}/* Return a copy of the header passed in.  */_sip_header_t *sip_dup_header(_sip_header_t *from){	size_t		hdr_size;	_sip_header_t	*to;	hdr_size = from->sip_hdr_end - from->sip_hdr_start;	to = sip_new_header(hdr_size);	if (to == NULL)		return (NULL);	if (from->sip_header_state == SIP_HEADER_DELETED_VAL) {		int	len;		len = sip_copy_values(to->sip_hdr_start, from);		to->sip_hdr_end = to->sip_hdr_start + len;	} else {		(void) memcpy(to->sip_hdr_start, from->sip_hdr_start, hdr_size);		to->sip_hdr_end = to->sip_hdr_start + hdr_size;	}	to->sip_header_functions = from->sip_header_functions;	return (to);}/* Copy header with extra_param, if any, to sip_msg */int_sip_copy_header(_sip_msg_t *sip_msg, _sip_header_t *header, char *extra_param,    boolean_t skip_crlf){	_sip_header_t	*new_header;	int		hdrlen;	int		extra_len = 0;	int		ncrlf = 0;	char		*p;#ifdef	__solaris__	assert(mutex_held(&sip_msg->sip_msg_mutex));#endif	if (extra_param != NULL) {		extra_len = SIP_SPACE + sizeof (char) + SIP_SPACE +		    strlen(extra_param);	}	/*	 * Just take one if there are more, i.e. if this is the last header	 * before the content.	 */	if (skip_crlf) {		if (header->sip_hdr_end - strlen(SIP_CRLF) <=		    header->sip_hdr_start) {			goto proceed;		}		p = header->sip_hdr_end - strlen(SIP_CRLF);		while (strncmp(SIP_CRLF, p, strlen(SIP_CRLF)) == 0) {			ncrlf++;			if (p - strlen(SIP_CRLF) < header->sip_hdr_start)				break;			p -= strlen(SIP_CRLF);		}		/* Take one */		ncrlf = (ncrlf - 1) * strlen(SIP_CRLF);	}proceed:	hdrlen = header->sip_hdr_end - header->sip_hdr_start - ncrlf;	new_header = sip_new_header(hdrlen + extra_len);	if (new_header == NULL)		return (ENOMEM);	if (header->sip_header_state == SIP_HEADER_DELETED_VAL) {		int	len;		len = sip_copy_values(new_header->sip_hdr_start, header);		new_header->sip_hdr_end = new_header->sip_hdr_start + len;		hdrlen = hdrlen - len + extra_len;	} else {		(void) memcpy(new_header->sip_hdr_start, header->sip_hdr_start,		    hdrlen);		new_header->sip_hdr_end = new_header->sip_hdr_start + hdrlen;		hdrlen = extra_len;	}	if (extra_param != NULL) {		/* Find CR */		if (sip_find_cr(new_header) != 0) {			sip_free_header(new_header);			return (EINVAL);		}		hdrlen += new_header->sip_hdr_end - new_header->sip_hdr_current;		(void) snprintf(new_header->sip_hdr_current, hdrlen + 1,		    " %c %s%s", SIP_SEMI, extra_param, SIP_CRLF);	}	new_header->sip_hdr_end += extra_len;	new_header->sip_header_functions = header->sip_header_functions;	_sip_add_header(sip_msg, new_header, B_TRUE, B_FALSE, NULL);	return (0);}/* Copy all "header_name" headers from _old_msg to _new_msg */int_sip_find_and_copy_all_header(_sip_msg_t *_old_msg, _sip_msg_t *_new_msg,    char *header_name){	_sip_header_t	*header;	int		ret = 0;	if (_old_msg == NULL || _new_msg == NULL)		return (EINVAL);#ifdef	__solaris__	assert(mutex_held(&_old_msg->sip_msg_mutex));#endif	if (_old_msg != _new_msg)		(void) pthread_mutex_lock(&_new_msg->sip_msg_mutex);	header = sip_search_for_header(_old_msg, header_name, NULL);	while (header != NULL) {		ret = _sip_copy_header(_new_msg, header, NULL, B_TRUE);		if (ret != 0)			break;		header = sip_search_for_header(_old_msg, header_name, header);	}	if (_old_msg != _new_msg)		(void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex);	return (ret);}/* Copy header_name from _old_msg to _new_msg with extra_parm, if any */int_sip_find_and_copy_header(sip_msg_t _old_msg, sip_msg_t _new_msg,    char *header_name, char *extra_param){	_sip_header_t	*header;	int		ret;	if (_old_msg == NULL || _new_msg == NULL)		return (EINVAL);#ifdef	__solaris__	assert(mutex_held(&_old_msg->sip_msg_mutex));#endif	header = sip_search_for_header(_old_msg, header_name, NULL);	if (header == NULL)		return (EINVAL);	if (_old_msg != _new_msg)		(void) pthread_mutex_lock(&_new_msg->sip_msg_mutex);	ret = _sip_copy_header(_new_msg, header, extra_param, B_TRUE);	if (_old_msg != _new_msg)		(void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex);	return (ret);}/* Copy all headers from old_msg to new_msg */intsip_copy_all_headers(sip_msg_t old_msg, sip_msg_t new_msg){	_sip_header_t	*header;	_sip_msg_t	*_old_msg;	_sip_msg_t	*_new_msg;	int		ret = 0;	if (old_msg == NULL || new_msg == NULL)		return (EINVAL);	_old_msg = (_sip_msg_t *)old_msg;	_new_msg = (_sip_msg_t *)new_msg;	(void) pthread_mutex_lock(&_old_msg->sip_msg_mutex);	(void) pthread_mutex_lock(&_new_msg->sip_msg_mutex);	header = sip_search_for_header(_old_msg, NULL, NULL);	while (header != NULL) {		ret = _sip_copy_header(_new_msg, header, NULL, B_FALSE);		if (ret != 0)			goto done;		header = sip_search_for_header(_old_msg, NULL, header);	}done:	(void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex);	(void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex);	return (ret);}/* Copy start line from msg to sip_msg */intsip_copy_start_line(sip_msg_t msg, sip_msg_t sip_msg){	int		len;	_sip_header_t	*new_header;	_sip_msg_t	*_old_msg;	_sip_msg_t	*_sip_msg;	if (msg == NULL || sip_msg == NULL)		return (EINVAL);	_old_msg = (_sip_msg_t *)msg;	_sip_msg = (_sip_msg_t *)sip_msg;	(void) pthread_mutex_lock(&_old_msg->sip_msg_mutex);	if (_old_msg->sip_msg_start_line == NULL) {		(void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex);		return (EINVAL);	}	len = _old_msg->sip_msg_start_line->sip_hdr_end -	    _old_msg->sip_msg_start_line->sip_hdr_start;	new_header = sip_new_header(len);	if (new_header == NULL) {		(void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex);		return (ENOMEM);	}	new_header->sip_hdr_sipmsg = _sip_msg;	(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);	_sip_msg->sip_msg_start_line = new_header;	_sip_msg->sip_msg_len = len;	(void) strncpy(_sip_msg->sip_msg_start_line->sip_hdr_start,	    _old_msg->sip_msg_start_line->sip_hdr_start, len);	(void) sip_parse_first_line(_sip_msg->sip_msg_start_line,	    &_sip_msg->sip_msg_req_res);	(void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex);	(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);	return (0);}/* Delete start line from sip_msg */intsip_delete_start_line(sip_msg_t sip_msg){	_sip_header_t	*header;	_sip_msg_t	*_sip_msg;	if (sip_msg == NULL)		return (EINVAL);	_sip_msg = (_sip_msg_t *)sip_msg;	(void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex);	if (_sip_msg->sip_msg_start_line == NULL) {		(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);		return (EINVAL);	}	header = _sip_msg->sip_msg_start_line;	while (header != NULL) {		_sip_header_t	*next_header;		next_header = header->sip_hdr_next;		sip_free_header(header);		header = next_header;	}	_sip_msg->sip_msg_start_line = NULL;	/*	 * Also delete the sip_msg_req_res info since we don't have a start	 * line.	 */	while (_sip_msg->sip_msg_req_res != NULL) {		sip_message_type_t	*sip_msg_type_ptr;		sip_msg_type_ptr = _sip_msg->sip_msg_req_res->sip_next;		free(_sip_msg->sip_msg_req_res);		_sip_msg->sip_msg_req_res = sip_msg_type_ptr;	}	(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);	return (0);}/* Delete all headers from _sip_msg */voidsip_delete_all_headers(_sip_msg_t *_sip_msg){	_sip_header_t *header;#ifdef	__solaris__	assert(mutex_held(&_sip_msg->sip_msg_mutex));#endif	header = _sip_msg->sip_msg_headers_start;	while (header != NULL) {		_sip_header_t *next_header;		next_header = header->sip_hdr_next;		sip_free_header(header);		header = next_header;	}	_sip_msg->sip_msg_headers_start = NULL;	_sip_msg->sip_msg_headers_end = NULL;}/* * Delete and free the named header. If header_name is null * free all headers. */voidsip_delete_headers(sip_msg_t sip_msg, char *header_name){	_sip_header_t *header;	_sip_msg_t *_sip_msg;	_sip_msg = (_sip_msg_t *)sip_msg;#ifdef	__solaris__	assert(mutex_held(&_sip_msg->sip_msg_mutex));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -