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

📄 sip_parse.c

📁 VoIP use SIP protocol interface
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * 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_parse.c	1.35	06/08/16 SMI"#include "sip_msg.h"#include "sip_miscdefs.h"#include "sip_parse_generic.h"/* Parse SIP/2.0 string */static intsip_get_protocol_version(_sip_header_t *sip_header,    sip_proto_version_t *sip_proto_version){	if (sip_skip_white_space(sip_header) != 0)		return (1);	if (!strncasecmp(sip_header->sip_hdr_current, SIP, strlen(SIP))) {		sip_proto_version->name.sip_str_ptr =		    sip_header->sip_hdr_current;		sip_proto_version->name.sip_str_len = strlen(SIP);		if (sip_find_token(sip_header, SIP_SLASH) != 0)			return (1);		if (sip_skip_white_space(sip_header) != 0)			return (1);		sip_proto_version->version.sip_str_ptr =		    sip_header->sip_hdr_current;		while (isdigit(*sip_header->sip_hdr_current)) {			sip_header->sip_hdr_current++;			if (sip_header->sip_hdr_current >=			    sip_header->sip_hdr_end) {				return (1);			}		}		if (*sip_header->sip_hdr_current != SIP_PERIOD)			return (1);		sip_header->sip_hdr_current++;		if (!isdigit(*sip_header->sip_hdr_current))			return (1);		while (isdigit(*sip_header->sip_hdr_current)) {			sip_header->sip_hdr_current++;			if (sip_header->sip_hdr_current >=			    sip_header->sip_hdr_end) {				return (1);			}		}		sip_proto_version->version.sip_str_len =		    sip_header->sip_hdr_current -		    sip_proto_version->version.sip_str_ptr;		return (0);	}	return (1);}/* * Warning = "Warning" HCOLON warning-value *(COMMA warning-value) * warning-value = warn-code SP warn-agent SP warn-text * warn-code = 3DIGIT * warn-agent = hostport | pseudonym ; *		 the name or pseudonym of the server adding; *		 the Warning header, for use in debugging * warn-text = quoted-string * pseudonym = token */intsip_parse_warn_header(_sip_header_t *sip_header, sip_parsed_header_t **header){	sip_parsed_header_t	*parsed_header;	int			ret;	sip_hdr_value_t		*value = NULL;	sip_hdr_value_t		*last_value = NULL;	if (sip_header == NULL || header == NULL)		return (EINVAL);	/* check if already parsed */	if (sip_header->sip_hdr_parsed != NULL) {		*header = sip_header->sip_hdr_parsed;		return (0);	}	*header = NULL;	assert(sip_header->sip_hdr_start == sip_header->sip_hdr_current);	if (sip_parse_goto_values(sip_header) != 0)		return (EPROTO);	parsed_header = calloc(1, sizeof (sip_parsed_header_t));	if (parsed_header == NULL)		return (ENOMEM);	parsed_header->sip_header = sip_header;	while (sip_header->sip_hdr_current < sip_header->sip_hdr_end) {		value = calloc(1, sizeof (sip_hdr_value_t));		if (value == NULL) {			sip_free_phdr(parsed_header);			return (ENOMEM);		}		if (last_value != NULL)			last_value->sip_next_value = value;		else			parsed_header->value = (sip_value_t *)value;		value->sip_value_start = sip_header->sip_hdr_current;		value->sip_value_header = parsed_header;		ret = sip_atoi(sip_header, &value->warn_code);		if (ret != 0 || value->warn_code < 100 ||		    value->warn_code > 999) {			value->sip_value_state = SIP_VALUE_BAD;			goto get_next_val;		}		if (sip_skip_white_space(sip_header) != 0) {			value->sip_value_state = SIP_VALUE_BAD;			goto get_next_val;		}		value->warn_agt_ptr = sip_header->sip_hdr_current;		if (sip_find_token(sip_header, SIP_QUOTE) == 0) {			/* get warning agent */			sip_header->sip_hdr_current--;			(void) sip_reverse_skip_white_space(sip_header);			value->warn_agt_len = sip_header->sip_hdr_current -			    value->warn_agt_ptr - 1;			if (value->warn_agt_len <= 0) {				value->warn_agt_ptr = NULL;				value->sip_value_state = SIP_VALUE_BAD;			}			if (sip_find_token(sip_header, SIP_QUOTE) != 0) {				value->sip_value_state = SIP_VALUE_BAD;				goto get_next_val;			}			value->warn_text_ptr =  sip_header->sip_hdr_current;			if (sip_find_token(sip_header, SIP_QUOTE) == 0) {				value->warn_text_len =				    sip_header->sip_hdr_current -					value->warn_text_ptr - 1;			} else {				value->sip_value_state = SIP_VALUE_BAD;				goto get_next_val;			}		} else			/* warning text must present */			value->sip_value_state = SIP_VALUE_BAD;get_next_val:		if (sip_find_token(sip_header, SIP_COMMA) != 0)			break;		value->sip_value_end = sip_header->sip_hdr_current - 1;		last_value = value;		(void) sip_skip_white_space(sip_header);	}	*header = parsed_header;	sip_header->sip_hdr_parsed = *header;	return (0);}/* * Date = "Date" HCOLON SIPdate * SIPdate = wkday "," SP date1 SP time SP "GMT" * date1 = 2DIGIT SP mnth SP 4DIGIT; day month year * time = 2DIGIT ":" 2DIGIT ":" 2DIGIT * wkday = "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun" * month = "Jan" | "Feb" etc */intsip_parse_date_header(_sip_header_t *sip_header, sip_parsed_header_t **header){	sip_parsed_header_t	*parsed_header;	int			 r;	sip_hdr_value_t		*value = NULL;	if (sip_header == NULL || header == NULL)		return (EINVAL);	/* check if already parsed */	if (sip_header->sip_hdr_parsed != NULL) {		*header = sip_header->sip_hdr_parsed;		return (0);	}	*header = NULL;	assert(sip_header->sip_hdr_start == sip_header->sip_hdr_current);	if (sip_parse_goto_values(sip_header) != 0)		return (EPROTO);	parsed_header = calloc(1, sizeof (sip_parsed_header_t));	if (parsed_header == NULL)		return (ENOMEM);	parsed_header->sip_header = sip_header;	value = calloc(1, sizeof (sip_hdr_value_t));	if (value == NULL) {		sip_free_phdr(parsed_header);		return (ENOMEM);	}	parsed_header->value = (sip_value_t *)value;	value->sip_value_start = sip_header->sip_hdr_current;	value->sip_value_header = parsed_header;	value->date_wd_ptr = sip_header->sip_hdr_current;	if (sip_find_token(sip_header, SIP_COMMA) == 0) {		value->date_wd_len = sip_header->sip_hdr_current -		    value->date_wd_ptr - 1;		sip_header->sip_hdr_current++;		if (sip_skip_white_space(sip_header) != 0) {			value->sip_value_state = SIP_VALUE_BAD;			return (EPROTO);		}	} else {		value->sip_value_state = SIP_VALUE_BAD;		return (EPROTO);	}	if (sip_skip_white_space(sip_header) != 0) {		value->sip_value_state = SIP_VALUE_BAD;		return (EPROTO);	}	r = sip_atoi(sip_header, &value->date_d);	if (r != 0) {		value->sip_value_state = SIP_VALUE_BAD;		return (EPROTO);	}	if (sip_skip_white_space(sip_header) != 0) {		value->sip_value_state = SIP_VALUE_BAD;		return (EPROTO);	}	value->date_m_ptr = sip_header->sip_hdr_current;	if (sip_find_token(sip_header, SIP_SP) == 0) {		value->date_m_len = sip_header->sip_hdr_current -		    value->date_m_ptr - 1;	} else {		value->sip_value_state = SIP_VALUE_BAD;		return (EPROTO);	}	r = sip_atoi(sip_header, &value->date_y);	if (r != 0) {		value->sip_value_state = SIP_VALUE_BAD;		return (EPROTO);	}	if (sip_skip_white_space(sip_header) != 0) {		value->sip_value_state = SIP_VALUE_BAD;		return (EPROTO);	}	value->date_t_ptr = sip_header->sip_hdr_current;	if (sip_find_token(sip_header, SIP_SP) == 0) {		value->date_t_len = sip_header->sip_hdr_current -		    value->date_t_ptr - 1;	} else {		value->sip_value_state = SIP_VALUE_BAD;		return (EPROTO);	}	value->date_tz_ptr =  sip_header->sip_hdr_current;	/* minus 2 to get rid of the CRLF */	value->date_tz_len = sip_header->sip_hdr_end -	    sip_header->sip_hdr_current - 2;	*header = parsed_header;	sip_header->sip_hdr_parsed = *header;	return (0);}intsip_parse_allow_events_header(_sip_header_t *sip_header,    sip_parsed_header_t **header){	int	r;	r = sip_parse_hdr_parser1(sip_header, header, (char)NULL);	sip_header->sip_hdr_parsed = *header;	return (r);}intsip_parse_event_header(_sip_header_t *sip_header, sip_parsed_header_t **header){	int	r;	r = sip_parse_hdr_parser1(sip_header, header, (char)NULL);	sip_header->sip_hdr_parsed = *header;	return (r);}intsip_parse_substate_header(_sip_header_t *sip_header,    sip_parsed_header_t **header){	int	r;	r = sip_parse_hdr_parser1(sip_header, header, (char)NULL);	sip_header->sip_hdr_parsed = *header;	return (r);}/* * Accept = "Accept" HCOLON [ accept-range *(COMMA accept-range) ] * accept-range = media-range *(SEMI accept-param) * media-range = ("* / *" |  (m-type SLASH "*") | (m-type SLASH m-subtype)) *		*(SEMI m-param) * accept-param = ("q" EQUAL qvalue) | generic-param * qvalue = ("0" ["." 0*3DIGIT]) | ("1" ["." 0*3DIGIT]) * generic-param = token [ EQUAL gen-value] * gen-value = token | host | quoted-str * * EXAMPLE: * Accept: application/sdp; level = 1, application/x-private, text/html */intsip_parse_acpt_header(_sip_header_t *sip_header, sip_parsed_header_t **header){	int	r;	if (!sip_is_empty_hdr(sip_header)) {		r = sip_parse_hdr_empty(sip_header, header);		return (r);	}	r = sip_parse_hdr_parser1(sip_header, header, SIP_SLASH);	sip_header->sip_hdr_parsed = *header;	return (r);}/* * SYNTAX: * Accept-Encoding = "Accept-Encoding" ":" 1#(codings [ ";" "q" "=" qval]) * codings = (content-coding | "*") * content-coding = token * * EXAMPLE: * Accept-Encoding: gzip; q = 1.0, identity; q = 0.5 */intsip_parse_acpt_encode_header(_sip_header_t *sip_header,	sip_parsed_header_t **header){	int	r;	r = sip_parse_hdr_parser1(sip_header, header, (char)NULL);	sip_header->sip_hdr_parsed = *header;	return (r);}/* * SYNTAX: * Accept-Language = "Accept-Language" ":" [ lang * (COMMA lang) ] * lang = lang-range *(SEMI accept-param) * lang-range = ((1*8ALPHA * ("-" 1*8ALPHA)) | "*" * * DEFAULT: * empty header field is eqivalent to "identity" * * EXAMPLE: * Accept-Language: da, en-gb; q = 0.8, en; q = 0.5 * */intsip_parse_acpt_lang_header(_sip_header_t *sip_header,	sip_parsed_header_t **header){	int	r;	if (!sip_is_empty_hdr(sip_header)) {		r = sip_parse_hdr_empty(sip_header, header);		return (r);	}	r = sip_parse_hdr_parser1(sip_header, header, (char)NULL);	sip_header->sip_hdr_parsed = *header;	return (r);}/* * SYNTAX: * Alert-Info = "Alert-Info" ":" alert-param *(COMMA alert-param) * alert-param = LAQUOT absoluteURI RAQUOT * (SEMI generic-param) * * EXAMPLE: * Alert-Info: < http://www.example.com/sounds/moo.waw > * */intsip_parse_alert_header(_sip_header_t *sip_header, sip_parsed_header_t **header){	int	r;	r = sip_parse_hdr_parser3(sip_header, header, SIP_STR_VAL, B_TRUE);	sip_header->sip_hdr_parsed = *header;	return (r);}/* * SYNTAX: * Allow = "Allow" ":" method-name1[, method-name2..] * * EXAMPLE: *  Allow: INVITE, ACK, CANCEL * */intsip_parse_allow_header(_sip_header_t *hdr, sip_parsed_header_t **phdr){	sip_parsed_header_t	*parsed_header;	sip_hdr_value_t		*value = NULL;	sip_hdr_value_t		*last_value = NULL;	int			len;	int			i;	if (hdr == NULL || phdr == NULL)		return (EINVAL);	/* check if previously parsed */	if (hdr->sip_hdr_parsed != NULL) {		*phdr = hdr->sip_hdr_parsed;		return (0);	}	*phdr = NULL;	assert(hdr->sip_hdr_start == hdr->sip_hdr_current);	if (sip_parse_goto_values(hdr) != 0)		return (EPROTO);	parsed_header = calloc(1, sizeof (sip_parsed_header_t));	if (parsed_header == NULL)		return (ENOMEM);	parsed_header->sip_header = hdr;	while (hdr->sip_hdr_current < hdr->sip_hdr_end) {		value = calloc(1, sizeof (sip_hdr_value_t));		if (value == NULL) {			sip_free_phdr(parsed_header);			return (ENOMEM);		}		if (last_value != NULL)			last_value->sip_next_value = value;		else			parsed_header->value = (sip_value_t *)value;		value->sip_value_start = hdr->sip_hdr_current;		value->sip_value_header = parsed_header;		if (sip_find_separator(hdr, SIP_COMMA, (char)NULL,		    (char)NULL) == 0) {			len = hdr->sip_hdr_current - value->sip_value_start;			for (i = 1; i < MAX_SIP_METHODS; i++) {				if (strncmp(sip_methods[i].name,				    value->sip_value_start, len) == 0)					break;			}			if (i >= MAX_SIP_METHODS) {				value->int_val = 0;				value->sip_value_state = SIP_VALUE_BAD;				goto next_val;			}			value->int_val = i;		} else {			len = hdr->sip_hdr_current - value->sip_value_start;			for (i = 1; i < MAX_SIP_METHODS; i++) {				if (strncmp(sip_methods[i].name,				    value->sip_value_start, len) == 0)					break;			}			if (i >= MAX_SIP_METHODS) {

⌨️ 快捷键说明

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