140cb5e5dSvi /*
240cb5e5dSvi  * CDDL HEADER START
340cb5e5dSvi  *
440cb5e5dSvi  * The contents of this file are subject to the terms of the
540cb5e5dSvi  * Common Development and Distribution License (the "License").
640cb5e5dSvi  * You may not use this file except in compliance with the License.
740cb5e5dSvi  *
840cb5e5dSvi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
940cb5e5dSvi  * or http://www.opensolaris.org/os/licensing.
1040cb5e5dSvi  * See the License for the specific language governing permissions
1140cb5e5dSvi  * and limitations under the License.
1240cb5e5dSvi  *
1340cb5e5dSvi  * When distributing Covered Code, include this CDDL HEADER in each
1440cb5e5dSvi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1540cb5e5dSvi  * If applicable, add the following below this CDDL HEADER, with the
1640cb5e5dSvi  * fields enclosed by brackets "[]" replaced with your own identifying
1740cb5e5dSvi  * information: Portions Copyright [yyyy] [name of copyright owner]
1840cb5e5dSvi  *
1940cb5e5dSvi  * CDDL HEADER END
2040cb5e5dSvi  */
2140cb5e5dSvi 
2240cb5e5dSvi /*
232c2c4183Svi  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2440cb5e5dSvi  * Use is subject to license terms.
2540cb5e5dSvi  */
2640cb5e5dSvi #include <stdlib.h>
2740cb5e5dSvi #include <string.h>
2840cb5e5dSvi #include <ctype.h>
292c2c4183Svi #include <errno.h>
3040cb5e5dSvi 
3140cb5e5dSvi #include "sip_parse_uri.h"
3240cb5e5dSvi 
3340cb5e5dSvi void
sip_free_parsed_uri(sip_uri_t uri)3440cb5e5dSvi sip_free_parsed_uri(sip_uri_t uri)
3540cb5e5dSvi {
3640cb5e5dSvi 	_sip_uri_t	*_uri;
3740cb5e5dSvi 
3840cb5e5dSvi 	if (uri == NULL)
3940cb5e5dSvi 		return;
4040cb5e5dSvi 
4140cb5e5dSvi 	_uri = (_sip_uri_t *)uri;
4240cb5e5dSvi 	if (_uri->sip_uri_issip) {
4340cb5e5dSvi 		sip_param_t	*param;
4440cb5e5dSvi 		sip_param_t	*param_next;
4540cb5e5dSvi 
4640cb5e5dSvi 		param = _uri->sip_uri_params;
4740cb5e5dSvi 		while (param != NULL) {
4840cb5e5dSvi 			param_next = param->param_next;
4940cb5e5dSvi 			free(param);
5040cb5e5dSvi 			param = param_next;
5140cb5e5dSvi 		}
5240cb5e5dSvi 	}
5340cb5e5dSvi 	free(_uri);
5440cb5e5dSvi }
5540cb5e5dSvi 
5640cb5e5dSvi /*
5740cb5e5dSvi  * Parse the URI in uri_str
5840cb5e5dSvi  */
5940cb5e5dSvi struct sip_uri *
sip_parse_uri(sip_str_t * uri_str,int * error)6040cb5e5dSvi sip_parse_uri(sip_str_t *uri_str, int *error)
6140cb5e5dSvi {
6240cb5e5dSvi 	struct sip_uri	*parsed_uri;
6340cb5e5dSvi 
6440cb5e5dSvi 	if (error != NULL)
6540cb5e5dSvi 		*error = 0;
6640cb5e5dSvi 
6740cb5e5dSvi 	if (uri_str == NULL) {
6840cb5e5dSvi 		if (error != NULL)
6940cb5e5dSvi 			*error = EINVAL;
7040cb5e5dSvi 		return (NULL);
7140cb5e5dSvi 	}
7240cb5e5dSvi 	parsed_uri = calloc(1, sizeof (_sip_uri_t));
7340cb5e5dSvi 	if (parsed_uri == NULL) {
7440cb5e5dSvi 		if (error != NULL)
7540cb5e5dSvi 			*error = ENOMEM;
7640cb5e5dSvi 		return (NULL);
7740cb5e5dSvi 	}
7840cb5e5dSvi 
7940cb5e5dSvi 	sip_uri_parse_it(parsed_uri, uri_str);
8040cb5e5dSvi 	if (parsed_uri->sip_uri_errflags & SIP_URIERR_MEMORY) {
8140cb5e5dSvi 		free(parsed_uri);
8240cb5e5dSvi 		if (error != NULL)
8340cb5e5dSvi 			*error = ENOMEM;
8440cb5e5dSvi 		return (NULL);
8540cb5e5dSvi 	}
8640cb5e5dSvi 	if (parsed_uri->sip_uri_errflags != 0 && error != NULL)
8740cb5e5dSvi 		*error = EPROTO;
8840cb5e5dSvi 	return ((sip_uri_t)parsed_uri);
8940cb5e5dSvi }
9040cb5e5dSvi 
9140cb5e5dSvi /*
9240cb5e5dSvi  * Get parsed URI
9340cb5e5dSvi  */
9440cb5e5dSvi const struct sip_uri *
sip_get_uri_parsed(sip_header_value_t value,int * error)9540cb5e5dSvi sip_get_uri_parsed(sip_header_value_t value, int *error)
9640cb5e5dSvi {
9740cb5e5dSvi 	const struct sip_uri	*ret = NULL;
9840cb5e5dSvi 
9940cb5e5dSvi 	if (error != NULL)
10040cb5e5dSvi 		*error = 0;
10140cb5e5dSvi 	if (value == NULL || value->sip_value_parse_uri == NULL ||
10240cb5e5dSvi 	    value->value_state == SIP_VALUE_DELETED) {
10340cb5e5dSvi 		if (error != NULL)
10440cb5e5dSvi 			*error = EINVAL;
10540cb5e5dSvi 		return (NULL);
10640cb5e5dSvi 	}
10740cb5e5dSvi 	ret = value->sip_value_parse_uri;
10840cb5e5dSvi 	if (ret->sip_uri_errflags != 0 && error != NULL)
10940cb5e5dSvi 		*error = EINVAL;
11040cb5e5dSvi 	return ((sip_uri_t)ret);
11140cb5e5dSvi }
11240cb5e5dSvi 
11340cb5e5dSvi /*
11440cb5e5dSvi  * Return TRUE if this is a SIP URI
11540cb5e5dSvi  */
11640cb5e5dSvi boolean_t
sip_is_sipuri(const struct sip_uri * uri)11740cb5e5dSvi sip_is_sipuri(const struct sip_uri *uri)
11840cb5e5dSvi {
11940cb5e5dSvi 	_sip_uri_t	*_uri;
12040cb5e5dSvi 
12140cb5e5dSvi 	if (uri == NULL)
12240cb5e5dSvi 		return (B_FALSE);
12340cb5e5dSvi 	_uri = (_sip_uri_t *)uri;
12440cb5e5dSvi 	if ((_uri->sip_uri_errflags & SIP_URIERR_SCHEME) == 0 &&
12540cb5e5dSvi 	    _uri->sip_uri_scheme.sip_str_len > 0 && _uri->sip_uri_issip) {
12640cb5e5dSvi 		return (B_TRUE);
12740cb5e5dSvi 	}
12840cb5e5dSvi 	return (B_FALSE);
12940cb5e5dSvi }
13040cb5e5dSvi 
13140cb5e5dSvi /*
13240cb5e5dSvi  * Some common checks
13340cb5e5dSvi  */
13440cb5e5dSvi static _sip_uri_t *
sip_check_get_param(const struct sip_uri * uri,int * error)13540cb5e5dSvi sip_check_get_param(const struct sip_uri *uri, int *error)
13640cb5e5dSvi {
13740cb5e5dSvi 	if (error != NULL)
13840cb5e5dSvi 		*error = 0;
13940cb5e5dSvi 
14040cb5e5dSvi 	if (uri == NULL) {
14140cb5e5dSvi 		if (error != NULL)
14240cb5e5dSvi 			*error = EINVAL;
14340cb5e5dSvi 		return (NULL);
14440cb5e5dSvi 	}
14540cb5e5dSvi 	return ((_sip_uri_t *)uri);
14640cb5e5dSvi }
14740cb5e5dSvi 
14840cb5e5dSvi 
14940cb5e5dSvi /*
15040cb5e5dSvi  * Return the URI scheme
15140cb5e5dSvi  */
15240cb5e5dSvi const sip_str_t *
sip_get_uri_scheme(const struct sip_uri * uri,int * error)15340cb5e5dSvi sip_get_uri_scheme(const struct sip_uri *uri, int *error)
15440cb5e5dSvi {
15540cb5e5dSvi 	_sip_uri_t	*_uri;
15640cb5e5dSvi 
15740cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
15840cb5e5dSvi 	if (_uri == NULL)
15940cb5e5dSvi 		return (NULL);
16040cb5e5dSvi 
16140cb5e5dSvi 	if (((_uri->sip_uri_errflags & SIP_URIERR_SCHEME) != 0 ||
16240cb5e5dSvi 	    _uri->sip_uri_scheme.sip_str_len == 0) && error != NULL) {
16340cb5e5dSvi 		*error = EINVAL;
16440cb5e5dSvi 	}
16540cb5e5dSvi 	if (_uri->sip_uri_scheme.sip_str_len > 0)
16640cb5e5dSvi 		return (&_uri->sip_uri_scheme);
16740cb5e5dSvi 	return (NULL);
16840cb5e5dSvi }
16940cb5e5dSvi 
17040cb5e5dSvi /*
17140cb5e5dSvi  *  Return user name from URI
17240cb5e5dSvi  */
17340cb5e5dSvi const sip_str_t *
sip_get_uri_user(const struct sip_uri * uri,int * error)17440cb5e5dSvi sip_get_uri_user(const struct sip_uri *uri, int *error)
17540cb5e5dSvi {
17640cb5e5dSvi 	_sip_uri_t	*_uri;
17740cb5e5dSvi 
17840cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
17940cb5e5dSvi 	if (_uri == NULL)
18040cb5e5dSvi 		return (NULL);
18140cb5e5dSvi 
18240cb5e5dSvi 	if ((_uri->sip_uri_errflags & SIP_URIERR_USER) != 0 && error != NULL)
18340cb5e5dSvi 		*error = EINVAL;
18440cb5e5dSvi 	if (uri->sip_uri_user.sip_str_len > 0)
18540cb5e5dSvi 		return (&uri->sip_uri_user);
18640cb5e5dSvi 	return (NULL);
18740cb5e5dSvi }
18840cb5e5dSvi 
18940cb5e5dSvi /*
19040cb5e5dSvi  *  Return password from URI
19140cb5e5dSvi  */
19240cb5e5dSvi const sip_str_t *
sip_get_uri_password(const struct sip_uri * uri,int * error)19340cb5e5dSvi sip_get_uri_password(const struct sip_uri *uri, int *error)
19440cb5e5dSvi {
19540cb5e5dSvi 	_sip_uri_t	*_uri;
19640cb5e5dSvi 
19740cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
19840cb5e5dSvi 	if (_uri == NULL)
19940cb5e5dSvi 		return (NULL);
20040cb5e5dSvi 
20140cb5e5dSvi 	if ((_uri->sip_uri_errflags & SIP_URIERR_PASS) != 0 && error != NULL)
20240cb5e5dSvi 		*error = EINVAL;
20340cb5e5dSvi 	if (_uri->sip_uri_password.sip_str_len > 0)
20440cb5e5dSvi 		return (&_uri->sip_uri_password);
20540cb5e5dSvi 	return (NULL);
20640cb5e5dSvi }
20740cb5e5dSvi 
20840cb5e5dSvi /*
20940cb5e5dSvi  * Get host from the URI
21040cb5e5dSvi  */
21140cb5e5dSvi const sip_str_t *
sip_get_uri_host(const struct sip_uri * uri,int * error)21240cb5e5dSvi sip_get_uri_host(const struct sip_uri *uri, int *error)
21340cb5e5dSvi {
21440cb5e5dSvi 	_sip_uri_t	*_uri;
21540cb5e5dSvi 
21640cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
21740cb5e5dSvi 	if (_uri == NULL)
21840cb5e5dSvi 		return (NULL);
21940cb5e5dSvi 
22040cb5e5dSvi 	if ((_uri->sip_uri_errflags & SIP_URIERR_HOST) != 0 && error != NULL)
22140cb5e5dSvi 		*error = EINVAL;
22240cb5e5dSvi 	if (_uri->sip_uri_host.sip_str_len > 0)
22340cb5e5dSvi 		return (&_uri->sip_uri_host);
22440cb5e5dSvi 	return (NULL);
22540cb5e5dSvi }
22640cb5e5dSvi 
22740cb5e5dSvi /*
22840cb5e5dSvi  * Get port from the URI
22940cb5e5dSvi  */
23040cb5e5dSvi int
sip_get_uri_port(const struct sip_uri * uri,int * error)23140cb5e5dSvi sip_get_uri_port(const struct sip_uri *uri, int *error)
23240cb5e5dSvi {
23340cb5e5dSvi 	_sip_uri_t	*_uri;
23440cb5e5dSvi 
23540cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
23640cb5e5dSvi 	if (_uri == NULL)
237*559f8b54SToomas Soome 		return (0);
23840cb5e5dSvi 
23940cb5e5dSvi 	if ((_uri->sip_uri_errflags & SIP_URIERR_PORT) != 0) {
24040cb5e5dSvi 		if (error != NULL)
24140cb5e5dSvi 			*error = EINVAL;
24240cb5e5dSvi 		return (0);
24340cb5e5dSvi 	}
24440cb5e5dSvi 	return (_uri->sip_uri_port);
24540cb5e5dSvi }
24640cb5e5dSvi 
24740cb5e5dSvi const sip_param_t *
sip_get_uri_params(const struct sip_uri * uri,int * error)24840cb5e5dSvi sip_get_uri_params(const struct sip_uri *uri, int *error)
24940cb5e5dSvi {
25040cb5e5dSvi 	_sip_uri_t		*_uri;
25140cb5e5dSvi 
25240cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
25340cb5e5dSvi 	if (_uri == NULL)
25440cb5e5dSvi 		return (NULL);
25540cb5e5dSvi 
25640cb5e5dSvi 	if (!_uri->sip_uri_issip) {
25740cb5e5dSvi 		if (error != NULL)
25840cb5e5dSvi 			*error = EINVAL;
25940cb5e5dSvi 		return (NULL);
26040cb5e5dSvi 	}
26140cb5e5dSvi 
26240cb5e5dSvi 	if ((_uri->sip_uri_errflags & SIP_URIERR_PARAM) != 0 && error != NULL)
26340cb5e5dSvi 		*error = EINVAL;
26440cb5e5dSvi 	return (_uri->sip_uri_params);
26540cb5e5dSvi }
26640cb5e5dSvi 
26740cb5e5dSvi /*
26840cb5e5dSvi  * Get headers from the URI
26940cb5e5dSvi  */
27040cb5e5dSvi const sip_str_t *
sip_get_uri_headers(const struct sip_uri * uri,int * error)27140cb5e5dSvi sip_get_uri_headers(const struct sip_uri *uri, int *error)
27240cb5e5dSvi {
27340cb5e5dSvi 	_sip_uri_t	*_uri;
27440cb5e5dSvi 
27540cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
27640cb5e5dSvi 	if (_uri == NULL)
27740cb5e5dSvi 		return (NULL);
27840cb5e5dSvi 
27940cb5e5dSvi 	if (!_uri->sip_uri_issip) {
28040cb5e5dSvi 		if (error != NULL)
28140cb5e5dSvi 			*error = EINVAL;
28240cb5e5dSvi 		return (NULL);
28340cb5e5dSvi 	}
28440cb5e5dSvi 	if ((_uri->sip_uri_errflags & SIP_URIERR_HEADER) != 0 && error != NULL)
28540cb5e5dSvi 		*error = EINVAL;
28640cb5e5dSvi 	if (_uri->sip_uri_headers.sip_str_len > 0)
28740cb5e5dSvi 		return (&_uri->sip_uri_headers);
28840cb5e5dSvi 	return (NULL);
28940cb5e5dSvi }
29040cb5e5dSvi 
29140cb5e5dSvi /*
29240cb5e5dSvi  *  Return opaque value for an ABS URI
29340cb5e5dSvi  */
29440cb5e5dSvi const sip_str_t *
sip_get_uri_opaque(const struct sip_uri * uri,int * error)29540cb5e5dSvi sip_get_uri_opaque(const struct sip_uri *uri, int *error)
29640cb5e5dSvi {
29740cb5e5dSvi 	_sip_uri_t	*_uri;
29840cb5e5dSvi 
29940cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
30040cb5e5dSvi 	if (_uri == NULL)
30140cb5e5dSvi 		return (NULL);
30240cb5e5dSvi 
30340cb5e5dSvi 	if (_uri->sip_uri_issip) {
30440cb5e5dSvi 		if (error != NULL)
30540cb5e5dSvi 			*error = EINVAL;
30640cb5e5dSvi 		return (NULL);
30740cb5e5dSvi 	}
30840cb5e5dSvi 	if ((_uri->sip_uri_errflags & SIP_URIERR_OPAQUE) != 0 && error != NULL)
30940cb5e5dSvi 		*error = EINVAL;
31040cb5e5dSvi 	if (_uri->sip_uri_opaque.sip_str_len > 0)
31140cb5e5dSvi 		return (&_uri->sip_uri_opaque);
31240cb5e5dSvi 	return (NULL);
31340cb5e5dSvi }
31440cb5e5dSvi 
31540cb5e5dSvi /*
31640cb5e5dSvi  * Return query from an absolute URI
31740cb5e5dSvi  */
31840cb5e5dSvi const sip_str_t *
sip_get_uri_query(const struct sip_uri * uri,int * error)31940cb5e5dSvi sip_get_uri_query(const struct sip_uri *uri, int *error)
32040cb5e5dSvi {
32140cb5e5dSvi 	_sip_uri_t	*_uri;
32240cb5e5dSvi 
32340cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
32440cb5e5dSvi 	if (_uri == NULL)
32540cb5e5dSvi 		return (NULL);
32640cb5e5dSvi 
32740cb5e5dSvi 	if (_uri->sip_uri_issip) {
32840cb5e5dSvi 		if (error != NULL)
32940cb5e5dSvi 			*error = EINVAL;
33040cb5e5dSvi 		return (NULL);
33140cb5e5dSvi 	}
33240cb5e5dSvi 	if ((_uri->sip_uri_errflags & SIP_URIERR_QUERY) != 0 && error != NULL)
33340cb5e5dSvi 		*error = EINVAL;
33440cb5e5dSvi 	if (_uri->sip_uri_query.sip_str_len > 0)
33540cb5e5dSvi 		return (&_uri->sip_uri_query);
33640cb5e5dSvi 	return (NULL);
33740cb5e5dSvi }
33840cb5e5dSvi 
33940cb5e5dSvi /*
34040cb5e5dSvi  *  Get path from an assolute URI
34140cb5e5dSvi  */
34240cb5e5dSvi const sip_str_t *
sip_get_uri_path(const struct sip_uri * uri,int * error)34340cb5e5dSvi sip_get_uri_path(const struct sip_uri *uri, int *error)
34440cb5e5dSvi {
34540cb5e5dSvi 	_sip_uri_t	*_uri;
34640cb5e5dSvi 
34740cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
34840cb5e5dSvi 	if (_uri == NULL)
34940cb5e5dSvi 		return (NULL);
35040cb5e5dSvi 
35140cb5e5dSvi 	if (_uri->sip_uri_issip) {
35240cb5e5dSvi 		if (error != NULL)
35340cb5e5dSvi 			*error = EINVAL;
35440cb5e5dSvi 		return (NULL);
35540cb5e5dSvi 	}
35640cb5e5dSvi 	if ((_uri->sip_uri_errflags & SIP_URIERR_PATH) != 0 && error != NULL)
35740cb5e5dSvi 		*error = EINVAL;
35840cb5e5dSvi 	if (_uri->sip_uri_path.sip_str_len > 0)
35940cb5e5dSvi 		return (&_uri->sip_uri_path);
36040cb5e5dSvi 	return (NULL);
36140cb5e5dSvi }
36240cb5e5dSvi 
36340cb5e5dSvi /*
36440cb5e5dSvi  * Get the reg-name from absolute URI
36540cb5e5dSvi  */
36640cb5e5dSvi const sip_str_t	*
sip_get_uri_regname(const struct sip_uri * uri,int * error)36740cb5e5dSvi sip_get_uri_regname(const struct sip_uri *uri, int *error)
36840cb5e5dSvi {
36940cb5e5dSvi 	_sip_uri_t	*_uri;
37040cb5e5dSvi 
37140cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
37240cb5e5dSvi 	if (_uri == NULL)
37340cb5e5dSvi 		return (NULL);
37440cb5e5dSvi 
37540cb5e5dSvi 	if (_uri->sip_uri_issip) {
37640cb5e5dSvi 		if (error != NULL)
37740cb5e5dSvi 			*error = EINVAL;
37840cb5e5dSvi 		return (NULL);
37940cb5e5dSvi 	}
38040cb5e5dSvi 	if ((_uri->sip_uri_errflags & SIP_URIERR_REGNAME) != 0 && error != NULL)
38140cb5e5dSvi 		*error = EINVAL;
38240cb5e5dSvi 	if (_uri->sip_uri_regname.sip_str_len > 0)
38340cb5e5dSvi 		return (&_uri->sip_uri_regname);
38440cb5e5dSvi 	return (NULL);
38540cb5e5dSvi }
38640cb5e5dSvi 
38740cb5e5dSvi /*
38840cb5e5dSvi  * Return TRUE if this is a teluser
38940cb5e5dSvi  */
39040cb5e5dSvi boolean_t
sip_is_uri_teluser(const struct sip_uri * uri)39140cb5e5dSvi sip_is_uri_teluser(const struct sip_uri *uri)
39240cb5e5dSvi {
39340cb5e5dSvi 	_sip_uri_t	*_uri;
39440cb5e5dSvi 
39540cb5e5dSvi 	if (uri == NULL)
39640cb5e5dSvi 		return (B_FALSE);
39740cb5e5dSvi 
39840cb5e5dSvi 	_uri = (_sip_uri_t *)uri;
39940cb5e5dSvi 	return (_uri->sip_uri_isteluser);
40040cb5e5dSvi }
40140cb5e5dSvi 
40240cb5e5dSvi int
sip_get_uri_errflags(const struct sip_uri * uri,int * error)40340cb5e5dSvi sip_get_uri_errflags(const struct sip_uri *uri, int *error)
40440cb5e5dSvi {
40540cb5e5dSvi 	_sip_uri_t	*_uri;
40640cb5e5dSvi 
40740cb5e5dSvi 	_uri = sip_check_get_param(uri, error);
40840cb5e5dSvi 	if (_uri == NULL)
40940cb5e5dSvi 		return (0);
41040cb5e5dSvi 	return (_uri->sip_uri_errflags);
41140cb5e5dSvi }
41240cb5e5dSvi 
41340cb5e5dSvi /*
41440cb5e5dSvi  * the caller is responsible for freeing the returned string
41540cb5e5dSvi  */
41640cb5e5dSvi char *
sip_uri_errflags_to_str(int errflags)41740cb5e5dSvi sip_uri_errflags_to_str(int errflags)
41840cb5e5dSvi {
41940cb5e5dSvi 	char	*err_info = NULL;
42040cb5e5dSvi 
42140cb5e5dSvi 	if (errflags == 0)
42240cb5e5dSvi 		return (NULL);
42340cb5e5dSvi 
42440cb5e5dSvi 	err_info = (char *)malloc(SIP_URI_BUF_SIZE);
42540cb5e5dSvi 	if (err_info == NULL)
42640cb5e5dSvi 		return (NULL);
42740cb5e5dSvi 
42840cb5e5dSvi 	if (errflags & SIP_URIERR_NOURI) {
42940cb5e5dSvi 		(void) strncpy(err_info, "Error : No URI",
43040cb5e5dSvi 		    strlen("Error : No URI"));
43140cb5e5dSvi 		err_info[strlen("Error : No URI")] = '\0';
43240cb5e5dSvi 		return (err_info);
43340cb5e5dSvi 	}
43440cb5e5dSvi 
43540cb5e5dSvi 	(void) strncpy(err_info, "Error(s) in", strlen("Error(s) in"));
43640cb5e5dSvi 	err_info[strlen("Error(s) in")] = '\0';
43740cb5e5dSvi 	if (errflags & SIP_URIERR_SCHEME)
43840cb5e5dSvi 		(void) strncat(err_info, " SCHEME,", strlen(" SCHEME,"));
43940cb5e5dSvi 	if (errflags & SIP_URIERR_USER)
44040cb5e5dSvi 		(void) strncat(err_info, " USER,", strlen(" USER,"));
44140cb5e5dSvi 	if (errflags & SIP_URIERR_PASS)
44240cb5e5dSvi 		(void) strncat(err_info, " PASSWORD,", strlen(" PASSWORD,"));
44340cb5e5dSvi 	if (errflags & SIP_URIERR_HOST)
44440cb5e5dSvi 		(void) strncat(err_info, " HOST,", strlen(" HOST,"));
44540cb5e5dSvi 	if (errflags & SIP_URIERR_PORT)
44640cb5e5dSvi 		(void) strncat(err_info, " PORT,", strlen(" PORT,"));
44740cb5e5dSvi 	if (errflags & SIP_URIERR_PARAM) {
44840cb5e5dSvi 		(void) strncat(err_info, " PARAMETERS,",
44940cb5e5dSvi 		    strlen(" PARAMETERS,"));
45040cb5e5dSvi 	}
45140cb5e5dSvi 	if (errflags & SIP_URIERR_HEADER)
45240cb5e5dSvi 		(void) strncat(err_info, " HEADERS,", strlen(" HEADERS,"));
45340cb5e5dSvi 	if (errflags & SIP_URIERR_OPAQUE)
45440cb5e5dSvi 		(void) strncat(err_info, " OPAQUE,", strlen(" OPAQUE,"));
45540cb5e5dSvi 	if (errflags & SIP_URIERR_QUERY)
45640cb5e5dSvi 		(void) strncat(err_info, " QUERY,", strlen(" QUERY,"));
45740cb5e5dSvi 	if (errflags & SIP_URIERR_PATH)
45840cb5e5dSvi 		(void) strncat(err_info, " PATH,", strlen(" PATH,"));
45940cb5e5dSvi 	if (errflags & SIP_URIERR_REGNAME)
46040cb5e5dSvi 		(void) strncat(err_info, " REG-NAME,", strlen(" REG-NAME,"));
46140cb5e5dSvi 	if (strlen(err_info) == strlen("Error(s) in")) {
46240cb5e5dSvi 		free(err_info);
46340cb5e5dSvi 		err_info = NULL;
46440cb5e5dSvi 	} else {
46540cb5e5dSvi 		err_info[strlen(err_info) - 1] = '\0';
46640cb5e5dSvi 		(void) strncat(err_info, " part(s)", strlen(" part(s)"));
46740cb5e5dSvi 	}
46840cb5e5dSvi 	return (err_info);
46940cb5e5dSvi }
470