/*
* 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
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <strings.h>
#include <ctype.h>
#include <sip.h>
#include "sip_miscdefs.h"
#include "sip_msg.h"
#include "sip_parse_uri.h"
/*
* atoi function from a header
*/
int
{
*num = 0;
if (num_found)
break;
} else {
break;
}
}
if (!num_found)
return (EINVAL);
return (0);
}
/*
* Find the 'token'
*/
int
{
return (1);
}
/*
* sip_hdr_current points to the char
* after the token
*/
return (0);
}
}
return (1);
}
/*
* Find a carriage-return
*/
int
{
return (1);
}
return (0);
}
/*
* Find one of the separator provided, i.e. separator_1st or separator_2nd or
* separator_3rd.
*/
int
{
continue;
}
(separator_1st != (char)NULL &&
(separator_2nd != (char)NULL &&
(separator_3rd != (char)NULL &&
return (0);
}
/*
* If we have escape character, go to the next char
*/
}
return (1);
}
/*
* Return when we hit a white space
*/
int
{
return (0);
}
return (1);
}
/*
* Skip to the next non-whitespace
*/
int
{
return (0);
}
return (1);
}
/*
* Skip to the non-white space in the reverse direction
*/
int
{
return (0);
}
return (1);
}
/*
* get to the first non space after ':'
*/
int
{
return (1);
if (sip_skip_white_space(sip_header) != 0)
return (1);
return (0);
}
/*
* Skip the current value.
*/
int
{
if (quoted)
else
} else if (!quoted &&
/*
* value ends before the COMMA
*/
return (0);
}
}
if (quoted)
return (1);
return (0);
}
/*
* Parse the header into parameter list. Parameters start with a ';'
*/
int
{
char *tmp_ptr;
if (parsed_list == NULL)
return (0);
*parsed_list = NULL;
for (;;) {
/*
* First check if there are any params
*/
if (sip_skip_white_space(sip_header) != 0)
return (0);
return (0);
return (ENOMEM);
else
*parsed_list = new_param;
/*
* Let's get to the start of the param name
*/
if (sip_skip_white_space(sip_header) != 0)
return (EPROTO);
/*
* start of param name
*/
return (0);
}
/*
* End of param name
*/
if (sip_skip_white_space(sip_header) != 0 ||
return (0);
}
continue;
}
/*
* We are at EQUAL, lets go beyond that
*/
if (sip_skip_white_space(sip_header) != 0)
return (EPROTO);
}
/*
* start of param value
*/
return (EPROTO);
return (EPROTO);
}
if (quoted_name)
}
}
/*
* a header that only has "header_name : " is an empty header
* ":" must exist
* sip_hdr_current resets to sip_hdr_start before exit
*/
{
return (B_FALSE);
}
if (sip_skip_white_space(sip_header) == 0) {
return (B_FALSE);
}
return (B_TRUE);
}
/*
* Parsing an empty header, i.e. only has a ":"
*/
int
{
return (EINVAL);
/*
* check if already parsed
*/
return (0);
}
if (parsed_header == NULL)
return (ENOMEM);
*phdr = parsed_header;
return (0);
}
/*
* validate uri str and parse uri using uri_parse()
*/
static void
{
int error;
/*
* Parse uri
*/
if (sip_str->sip_str_len > 0) {
return;
if (error != 0 ||
}
}
}
/*
* Some basic common checks before parsing the headers
*/
int
{
return (EINVAL);
/*
* check if already parsed
*/
return (0);
}
if (sip_parse_goto_values(sip_header) != 0)
return (EPROTO);
return (0);
}
/*
* Parse SIP/2.0 string
*/
int
{
if (sip_skip_white_space(sip_header) != 0)
return (1);
return (1);
if (sip_skip_white_space(sip_header) != 0)
return (1);
if (sip_header->sip_hdr_current >=
return (1);
}
}
return (1);
return (1);
if (sip_header->sip_hdr_current >=
return (1);
}
}
return (0);
}
return (1);
}
/*
* parser1 parses hdr format
* header_name: val1[; par1=pval1;par2=pval2 ..][, val2[;parlist..] ]
* headers: Accept, Accept-Encode, Accept-lang, Allow, Content-disp,
* Content-Encode, Content-Lang, In-reply-to,
* Priority, Require, Supported, Unsupported
* Allow-Events, Event, Subscription-State
*/
int
{
int ret;
return (ret);
/*
* check if previously parsed
*/
return (0);
}
if (parsed_header == NULL)
return (ENOMEM);
return (ENOMEM);
}
if (last_value != NULL)
else
B_FALSE) == 0) {
char c = *hdr->sip_hdr_current;
/*
* nothing at the end except space
*/
if (sip_skip_white_space(hdr) != 0) {
goto end;
}
/*
* white space skipped
*/
c = *(hdr->sip_hdr_current);
}
/*
* only one string until COMMA, use sip_str_t
*/
if (c == SIP_COMMA) {
char *t = hdr->sip_hdr_current;
hdr->sip_hdr_current--;
(void) sip_reverse_skip_white_space(hdr);
hdr->sip_hdr_current = t;
goto get_next_val;
}
/*
* two strings, use sip_2strs_t
*/
(++hdr->sip_hdr_current);
char t = *(hdr->sip_hdr_current);
/*
* if COMMA, no param list, get next val
* if SEMI, need to set params list
*/
if (t == SIP_COMMA)
goto get_next_val;
} else { /* the last part */
goto end;
}
goto get_next_val;
}
/*
* c == SEMI, value contains single string
* only one string until SEMI, use sip_str_t
*/
if (c == SIP_SEMI) {
char *t = hdr->sip_hdr_current;
hdr->sip_hdr_current--;
/*
* get rid of SP at end of value field
*/
(void) sip_reverse_skip_white_space(hdr);
hdr->sip_hdr_current = t;
}
/*
* if SEMI exists in the value, set params list
* two situations, there is or not SLASH before SEMI
*/
} else if (ret != 0) {
return (ret);
}
goto get_next_val;
} else {
goto end;
}
break;
}
last_value = value;
(void) sip_skip_white_space(hdr);
}
end:
*phdr = parsed_header;
return (0);
}
/*
* header_name: int
* headers: Expires, Min-Expires
*/
/* ARGSUSED */
int
int val_type)
{
int ret = 0;
return (ret);
/*
* check if previously parsed
*/
return (0);
}
if (parsed_header == NULL)
return (ENOMEM);
return (ENOMEM);
}
if (ret != 0) {
}
*phdr = parsed_header;
return (0);
}
/*
* parser3 parses hdr format
* header_name: <val1>[, <val2>]
* Alert-Info, Call-Info, Error-Info, reply-to
*/
int
{
int ret;
return (ret);
/*
* check if previously parsed
*/
return (0);
}
if (parsed_header == NULL)
return (ENOMEM);
int r;
return (ENOMEM);
}
if (last_value != NULL)
else
if (type == SIP_STRS_VAL) {
char *cur;
/*
* record the position after LAQUOT
*/
/*
* get display name and store in str1
*/
/*
* record start pos of display name
*/
if (*hdr->sip_hdr_current ==
SIP_QUOTE) {
hdr->sip_hdr_current++;
tmp++;
if (sip_find_token(hdr,
SIP_QUOTE) != 0) {
goto get_next_val;
}
} else {
(void)
(hdr);
}
} else {
value->strs1_val_len = 0;
}
/*
* set current to the char after LAQUOT
*/
/*
* no RAQUOT
*/
value->strs1_val_len = 0;
value->strs2_val_len = 0;
goto get_next_val;
}
} else {
char *cur;
/*
* No display name - Only URI.
*/
value->strs1_val_len = 0;
if (sip_skip_white_space(hdr) != 0) {
} else if (*hdr->sip_hdr_current ==
SIP_COMMA) {
} else {
goto get_next_val;
}
} else {
}
}
if (parse_uri)
}
if (type == SIP_STR_VAL) {
/*
* alert-info, error-info, call-info
*/
value->str_val_len =
} else {
value->str_val_len = 0;
goto get_next_val;
}
hdr->sip_hdr_current--;
} else {
value->str_val_len = 0;
goto get_next_val;
}
if (parse_uri)
}
B_FALSE);
if (r != 0) {
goto end;
}
(void) sip_parse_params(hdr,
&(value->sip_param_list));
goto get_next_val;
}
hdr->sip_hdr_current--;
goto get_next_val;
}
break;
}
last_value = value;
(void) sip_skip_white_space(hdr);
}
end:
*phdr = parsed_header;
return (0);
}
/*
* parser4 parses hdr format, the whole field is one single str
* header: Subject, MIME-Version, Organization, Server, User-Agent
*/
int
{
int ret;
return (ret);
/*
* check if previously parsed
*/
return (0);
}
if (parsed_header == NULL)
return (ENOMEM);
return (ENOMEM);
}
/*
* get rid of CRLF at end
*/
*phdr = parsed_header;
return (0);
}
int
{
int ret;
return (ret);
/*
* check if previously parsed
*/
return (0);
}
if (parsed_header == NULL)
return (ENOMEM);
return (ENOMEM);
}
/*
* get auth_scheme
*/
if (sip_find_white_space(hdr)) {
return (EINVAL);
}
/*
* parse auth_param
*/
for (;;) {
char *tmp_cur;
char quoted_char = (char)0;
if (sip_skip_white_space(hdr) != 0) {
return (EPROTO);
}
return (ENOMEM);
if (first_param == B_FALSE)
else
B_FALSE) != 0) {
goto end;
}
/*
* End of param name
*/
if (sip_skip_white_space(hdr) != 0 ||
continue;
}
/*
* We are at EQUAL
*/
hdr->sip_hdr_current++;
if (sip_skip_white_space(hdr) != 0) {
return (EPROTO);
}
else {
}
hdr->sip_hdr_current++;
}
/*
* start of param value
*/
if (quoted_name) {
return (EPROTO);
}
}
goto end;
} else {
if (!quoted_name) {
char *t = hdr->sip_hdr_current;
hdr->sip_hdr_current--;
(void) sip_reverse_skip_white_space(hdr);
hdr->sip_hdr_current = t;
}
}
if (first_param == B_TRUE)
/*
* Parse uri
*/
if (pval_is_uri && parse_uri)
}
end:
*phdr = parsed_header;
return (0);
}
/*
* Return the URI in the request startline
*/
static int
{
int size = 0;
char *start_ptr;
if (sip_skip_white_space(sip_header) != 0)
return (EINVAL);
return (EINVAL);
}
if (size > 0) { /* Parse uri */
int error;
return (error);
}
return (0);
}
/*
*/
int
{
int ret;
return (EINVAL);
if (sip_skip_white_space(sip_header) != 0)
return (EPROTO);
/*
* There is nothing, return
*/
return (EPROTO);
}
#ifdef __solaris__
#endif
if (sip_msg_info == NULL)
return (ENOMEM);
/*
* let's see if it's a request or a response
*/
if (ret == 0) {
} else if (ret == 2) {
return (EPROTO);
}
if (sip_skip_white_space(sip_header) != 0) {
return (EPROTO);
}
if (!sip_is_request) {
/*
* check for status code.
*/
if (sip_skip_white_space(sip_header) != 0) {
return (EPROTO);
}
return (EPROTO);
}
if (sip_atoi(sip_header,
return (EPROTO);
}
return (EPROTO);
}
/*
* get reason phrase.
*/
if (sip_skip_white_space(sip_header) != 0) {
} else {
if (sip_find_cr(sip_header) != 0) {
return (EPROTO);
}
}
} else {
int i;
/*
* It's a request.
*/
for (i = 1; i < MAX_SIP_METHODS; i++) {
sip_methods[i].len) == 0) {
sip_msg_info->sip_req_method = i;
sip_methods[i].len;
return (EPROTO);
}
sip_msg_info)) != 0) {
return (ret);
}
/*
* Get SIP version
*/
if (ret != 0) {
return (EPROTO);
}
goto done;
}
}
return (EPROTO);
}
done:
*msg_info = sip_msg_info;
return (0);
}