12882Svi117747 /*
22882Svi117747 * CDDL HEADER START
32882Svi117747 *
42882Svi117747 * The contents of this file are subject to the terms of the
52882Svi117747 * Common Development and Distribution License (the "License").
62882Svi117747 * You may not use this file except in compliance with the License.
72882Svi117747 *
82882Svi117747 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92882Svi117747 * or http://www.opensolaris.org/os/licensing.
102882Svi117747 * See the License for the specific language governing permissions
112882Svi117747 * and limitations under the License.
122882Svi117747 *
132882Svi117747 * When distributing Covered Code, include this CDDL HEADER in each
142882Svi117747 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152882Svi117747 * If applicable, add the following below this CDDL HEADER, with the
162882Svi117747 * fields enclosed by brackets "[]" replaced with your own identifying
172882Svi117747 * information: Portions Copyright [yyyy] [name of copyright owner]
182882Svi117747 *
192882Svi117747 * CDDL HEADER END
202882Svi117747 */
212882Svi117747
222882Svi117747 /*
23*3439Svi117747 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
242882Svi117747 * Use is subject to license terms.
252882Svi117747 */
262882Svi117747 #pragma ident "%Z%%M% %I% %E% SMI"
272882Svi117747
282882Svi117747 #include <stdlib.h>
292882Svi117747 #include <string.h>
302882Svi117747 #include <ctype.h>
31*3439Svi117747 #include <errno.h>
322882Svi117747
332882Svi117747 #include "sip_parse_uri.h"
342882Svi117747
352882Svi117747 void
sip_free_parsed_uri(sip_uri_t uri)362882Svi117747 sip_free_parsed_uri(sip_uri_t uri)
372882Svi117747 {
382882Svi117747 _sip_uri_t *_uri;
392882Svi117747
402882Svi117747 if (uri == NULL)
412882Svi117747 return;
422882Svi117747
432882Svi117747 _uri = (_sip_uri_t *)uri;
442882Svi117747 if (_uri->sip_uri_issip) {
452882Svi117747 sip_param_t *param;
462882Svi117747 sip_param_t *param_next;
472882Svi117747
482882Svi117747 param = _uri->sip_uri_params;
492882Svi117747 while (param != NULL) {
502882Svi117747 param_next = param->param_next;
512882Svi117747 free(param);
522882Svi117747 param = param_next;
532882Svi117747 }
542882Svi117747 }
552882Svi117747 free(_uri);
562882Svi117747 }
572882Svi117747
582882Svi117747 /*
592882Svi117747 * Parse the URI in uri_str
602882Svi117747 */
612882Svi117747 struct sip_uri *
sip_parse_uri(sip_str_t * uri_str,int * error)622882Svi117747 sip_parse_uri(sip_str_t *uri_str, int *error)
632882Svi117747 {
642882Svi117747 struct sip_uri *parsed_uri;
652882Svi117747
662882Svi117747 if (error != NULL)
672882Svi117747 *error = 0;
682882Svi117747
692882Svi117747 if (uri_str == NULL) {
702882Svi117747 if (error != NULL)
712882Svi117747 *error = EINVAL;
722882Svi117747 return (NULL);
732882Svi117747 }
742882Svi117747 parsed_uri = calloc(1, sizeof (_sip_uri_t));
752882Svi117747 if (parsed_uri == NULL) {
762882Svi117747 if (error != NULL)
772882Svi117747 *error = ENOMEM;
782882Svi117747 return (NULL);
792882Svi117747 }
802882Svi117747
812882Svi117747 sip_uri_parse_it(parsed_uri, uri_str);
822882Svi117747 if (parsed_uri->sip_uri_errflags & SIP_URIERR_MEMORY) {
832882Svi117747 free(parsed_uri);
842882Svi117747 if (error != NULL)
852882Svi117747 *error = ENOMEM;
862882Svi117747 return (NULL);
872882Svi117747 }
882882Svi117747 if (parsed_uri->sip_uri_errflags != 0 && error != NULL)
892882Svi117747 *error = EPROTO;
902882Svi117747 return ((sip_uri_t)parsed_uri);
912882Svi117747 }
922882Svi117747
932882Svi117747 /*
942882Svi117747 * Get parsed URI
952882Svi117747 */
962882Svi117747 const struct sip_uri *
sip_get_uri_parsed(sip_header_value_t value,int * error)972882Svi117747 sip_get_uri_parsed(sip_header_value_t value, int *error)
982882Svi117747 {
992882Svi117747 const struct sip_uri *ret = NULL;
1002882Svi117747
1012882Svi117747 if (error != NULL)
1022882Svi117747 *error = 0;
1032882Svi117747 if (value == NULL || value->sip_value_parse_uri == NULL ||
1042882Svi117747 value->value_state == SIP_VALUE_DELETED) {
1052882Svi117747 if (error != NULL)
1062882Svi117747 *error = EINVAL;
1072882Svi117747 return (NULL);
1082882Svi117747 }
1092882Svi117747 ret = value->sip_value_parse_uri;
1102882Svi117747 if (ret->sip_uri_errflags != 0 && error != NULL)
1112882Svi117747 *error = EINVAL;
1122882Svi117747 return ((sip_uri_t)ret);
1132882Svi117747 }
1142882Svi117747
1152882Svi117747 /*
1162882Svi117747 * Return TRUE if this is a SIP URI
1172882Svi117747 */
1182882Svi117747 boolean_t
sip_is_sipuri(const struct sip_uri * uri)1192882Svi117747 sip_is_sipuri(const struct sip_uri *uri)
1202882Svi117747 {
1212882Svi117747 _sip_uri_t *_uri;
1222882Svi117747
1232882Svi117747 if (uri == NULL)
1242882Svi117747 return (B_FALSE);
1252882Svi117747 _uri = (_sip_uri_t *)uri;
1262882Svi117747 if ((_uri->sip_uri_errflags & SIP_URIERR_SCHEME) == 0 &&
1272882Svi117747 _uri->sip_uri_scheme.sip_str_len > 0 && _uri->sip_uri_issip) {
1282882Svi117747 return (B_TRUE);
1292882Svi117747 }
1302882Svi117747 return (B_FALSE);
1312882Svi117747 }
1322882Svi117747
1332882Svi117747 /*
1342882Svi117747 * Some common checks
1352882Svi117747 */
1362882Svi117747 static _sip_uri_t *
sip_check_get_param(const struct sip_uri * uri,int * error)1372882Svi117747 sip_check_get_param(const struct sip_uri *uri, int *error)
1382882Svi117747 {
1392882Svi117747 if (error != NULL)
1402882Svi117747 *error = 0;
1412882Svi117747
1422882Svi117747 if (uri == NULL) {
1432882Svi117747 if (error != NULL)
1442882Svi117747 *error = EINVAL;
1452882Svi117747 return (NULL);
1462882Svi117747 }
1472882Svi117747 return ((_sip_uri_t *)uri);
1482882Svi117747 }
1492882Svi117747
1502882Svi117747
1512882Svi117747 /*
1522882Svi117747 * Return the URI scheme
1532882Svi117747 */
1542882Svi117747 const sip_str_t *
sip_get_uri_scheme(const struct sip_uri * uri,int * error)1552882Svi117747 sip_get_uri_scheme(const struct sip_uri *uri, int *error)
1562882Svi117747 {
1572882Svi117747 _sip_uri_t *_uri;
1582882Svi117747
1592882Svi117747 _uri = sip_check_get_param(uri, error);
1602882Svi117747 if (_uri == NULL)
1612882Svi117747 return (NULL);
1622882Svi117747
1632882Svi117747 if (((_uri->sip_uri_errflags & SIP_URIERR_SCHEME) != 0 ||
1642882Svi117747 _uri->sip_uri_scheme.sip_str_len == 0) && error != NULL) {
1652882Svi117747 *error = EINVAL;
1662882Svi117747 }
1672882Svi117747 if (_uri->sip_uri_scheme.sip_str_len > 0)
1682882Svi117747 return (&_uri->sip_uri_scheme);
1692882Svi117747 return (NULL);
1702882Svi117747 }
1712882Svi117747
1722882Svi117747 /*
1732882Svi117747 * Return user name from URI
1742882Svi117747 */
1752882Svi117747 const sip_str_t *
sip_get_uri_user(const struct sip_uri * uri,int * error)1762882Svi117747 sip_get_uri_user(const struct sip_uri *uri, int *error)
1772882Svi117747 {
1782882Svi117747 _sip_uri_t *_uri;
1792882Svi117747
1802882Svi117747 _uri = sip_check_get_param(uri, error);
1812882Svi117747 if (_uri == NULL)
1822882Svi117747 return (NULL);
1832882Svi117747
1842882Svi117747 if ((_uri->sip_uri_errflags & SIP_URIERR_USER) != 0 && error != NULL)
1852882Svi117747 *error = EINVAL;
1862882Svi117747 if (uri->sip_uri_user.sip_str_len > 0)
1872882Svi117747 return (&uri->sip_uri_user);
1882882Svi117747 return (NULL);
1892882Svi117747 }
1902882Svi117747
1912882Svi117747 /*
1922882Svi117747 * Return password from URI
1932882Svi117747 */
1942882Svi117747 const sip_str_t *
sip_get_uri_password(const struct sip_uri * uri,int * error)1952882Svi117747 sip_get_uri_password(const struct sip_uri *uri, int *error)
1962882Svi117747 {
1972882Svi117747 _sip_uri_t *_uri;
1982882Svi117747
1992882Svi117747 _uri = sip_check_get_param(uri, error);
2002882Svi117747 if (_uri == NULL)
2012882Svi117747 return (NULL);
2022882Svi117747
2032882Svi117747 if ((_uri->sip_uri_errflags & SIP_URIERR_PASS) != 0 && error != NULL)
2042882Svi117747 *error = EINVAL;
2052882Svi117747 if (_uri->sip_uri_password.sip_str_len > 0)
2062882Svi117747 return (&_uri->sip_uri_password);
2072882Svi117747 return (NULL);
2082882Svi117747 }
2092882Svi117747
2102882Svi117747 /*
2112882Svi117747 * Get host from the URI
2122882Svi117747 */
2132882Svi117747 const sip_str_t *
sip_get_uri_host(const struct sip_uri * uri,int * error)2142882Svi117747 sip_get_uri_host(const struct sip_uri *uri, int *error)
2152882Svi117747 {
2162882Svi117747 _sip_uri_t *_uri;
2172882Svi117747
2182882Svi117747 _uri = sip_check_get_param(uri, error);
2192882Svi117747 if (_uri == NULL)
2202882Svi117747 return (NULL);
2212882Svi117747
2222882Svi117747 if ((_uri->sip_uri_errflags & SIP_URIERR_HOST) != 0 && error != NULL)
2232882Svi117747 *error = EINVAL;
2242882Svi117747 if (_uri->sip_uri_host.sip_str_len > 0)
2252882Svi117747 return (&_uri->sip_uri_host);
2262882Svi117747 return (NULL);
2272882Svi117747 }
2282882Svi117747
2292882Svi117747 /*
2302882Svi117747 * Get port from the URI
2312882Svi117747 */
2322882Svi117747 int
sip_get_uri_port(const struct sip_uri * uri,int * error)2332882Svi117747 sip_get_uri_port(const struct sip_uri *uri, int *error)
2342882Svi117747 {
2352882Svi117747 _sip_uri_t *_uri;
2362882Svi117747
2372882Svi117747 _uri = sip_check_get_param(uri, error);
2382882Svi117747 if (_uri == NULL)
2392882Svi117747 return (NULL);
2402882Svi117747
2412882Svi117747 if ((_uri->sip_uri_errflags & SIP_URIERR_PORT) != 0) {
2422882Svi117747 if (error != NULL)
2432882Svi117747 *error = EINVAL;
2442882Svi117747 return (0);
2452882Svi117747 }
2462882Svi117747 return (_uri->sip_uri_port);
2472882Svi117747 }
2482882Svi117747
2492882Svi117747 const sip_param_t *
sip_get_uri_params(const struct sip_uri * uri,int * error)2502882Svi117747 sip_get_uri_params(const struct sip_uri *uri, int *error)
2512882Svi117747 {
2522882Svi117747 _sip_uri_t *_uri;
2532882Svi117747
2542882Svi117747 _uri = sip_check_get_param(uri, error);
2552882Svi117747 if (_uri == NULL)
2562882Svi117747 return (NULL);
2572882Svi117747
2582882Svi117747 if (!_uri->sip_uri_issip) {
2592882Svi117747 if (error != NULL)
2602882Svi117747 *error = EINVAL;
2612882Svi117747 return (NULL);
2622882Svi117747 }
2632882Svi117747
2642882Svi117747 if ((_uri->sip_uri_errflags & SIP_URIERR_PARAM) != 0 && error != NULL)
2652882Svi117747 *error = EINVAL;
2662882Svi117747 return (_uri->sip_uri_params);
2672882Svi117747 }
2682882Svi117747
2692882Svi117747 /*
2702882Svi117747 * Get headers from the URI
2712882Svi117747 */
2722882Svi117747 const sip_str_t *
sip_get_uri_headers(const struct sip_uri * uri,int * error)2732882Svi117747 sip_get_uri_headers(const struct sip_uri *uri, int *error)
2742882Svi117747 {
2752882Svi117747 _sip_uri_t *_uri;
2762882Svi117747
2772882Svi117747 _uri = sip_check_get_param(uri, error);
2782882Svi117747 if (_uri == NULL)
2792882Svi117747 return (NULL);
2802882Svi117747
2812882Svi117747 if (!_uri->sip_uri_issip) {
2822882Svi117747 if (error != NULL)
2832882Svi117747 *error = EINVAL;
2842882Svi117747 return (NULL);
2852882Svi117747 }
2862882Svi117747 if ((_uri->sip_uri_errflags & SIP_URIERR_HEADER) != 0 && error != NULL)
2872882Svi117747 *error = EINVAL;
2882882Svi117747 if (_uri->sip_uri_headers.sip_str_len > 0)
2892882Svi117747 return (&_uri->sip_uri_headers);
2902882Svi117747 return (NULL);
2912882Svi117747 }
2922882Svi117747
2932882Svi117747 /*
2942882Svi117747 * Return opaque value for an ABS URI
2952882Svi117747 */
2962882Svi117747 const sip_str_t *
sip_get_uri_opaque(const struct sip_uri * uri,int * error)2972882Svi117747 sip_get_uri_opaque(const struct sip_uri *uri, int *error)
2982882Svi117747 {
2992882Svi117747 _sip_uri_t *_uri;
3002882Svi117747
3012882Svi117747 _uri = sip_check_get_param(uri, error);
3022882Svi117747 if (_uri == NULL)
3032882Svi117747 return (NULL);
3042882Svi117747
3052882Svi117747 if (_uri->sip_uri_issip) {
3062882Svi117747 if (error != NULL)
3072882Svi117747 *error = EINVAL;
3082882Svi117747 return (NULL);
3092882Svi117747 }
3102882Svi117747 if ((_uri->sip_uri_errflags & SIP_URIERR_OPAQUE) != 0 && error != NULL)
3112882Svi117747 *error = EINVAL;
3122882Svi117747 if (_uri->sip_uri_opaque.sip_str_len > 0)
3132882Svi117747 return (&_uri->sip_uri_opaque);
3142882Svi117747 return (NULL);
3152882Svi117747 }
3162882Svi117747
3172882Svi117747 /*
3182882Svi117747 * Return query from an absolute URI
3192882Svi117747 */
3202882Svi117747 const sip_str_t *
sip_get_uri_query(const struct sip_uri * uri,int * error)3212882Svi117747 sip_get_uri_query(const struct sip_uri *uri, int *error)
3222882Svi117747 {
3232882Svi117747 _sip_uri_t *_uri;
3242882Svi117747
3252882Svi117747 _uri = sip_check_get_param(uri, error);
3262882Svi117747 if (_uri == NULL)
3272882Svi117747 return (NULL);
3282882Svi117747
3292882Svi117747 if (_uri->sip_uri_issip) {
3302882Svi117747 if (error != NULL)
3312882Svi117747 *error = EINVAL;
3322882Svi117747 return (NULL);
3332882Svi117747 }
3342882Svi117747 if ((_uri->sip_uri_errflags & SIP_URIERR_QUERY) != 0 && error != NULL)
3352882Svi117747 *error = EINVAL;
3362882Svi117747 if (_uri->sip_uri_query.sip_str_len > 0)
3372882Svi117747 return (&_uri->sip_uri_query);
3382882Svi117747 return (NULL);
3392882Svi117747 }
3402882Svi117747
3412882Svi117747 /*
3422882Svi117747 * Get path from an assolute URI
3432882Svi117747 */
3442882Svi117747 const sip_str_t *
sip_get_uri_path(const struct sip_uri * uri,int * error)3452882Svi117747 sip_get_uri_path(const struct sip_uri *uri, int *error)
3462882Svi117747 {
3472882Svi117747 _sip_uri_t *_uri;
3482882Svi117747
3492882Svi117747 _uri = sip_check_get_param(uri, error);
3502882Svi117747 if (_uri == NULL)
3512882Svi117747 return (NULL);
3522882Svi117747
3532882Svi117747 if (_uri->sip_uri_issip) {
3542882Svi117747 if (error != NULL)
3552882Svi117747 *error = EINVAL;
3562882Svi117747 return (NULL);
3572882Svi117747 }
3582882Svi117747 if ((_uri->sip_uri_errflags & SIP_URIERR_PATH) != 0 && error != NULL)
3592882Svi117747 *error = EINVAL;
3602882Svi117747 if (_uri->sip_uri_path.sip_str_len > 0)
3612882Svi117747 return (&_uri->sip_uri_path);
3622882Svi117747 return (NULL);
3632882Svi117747 }
3642882Svi117747
3652882Svi117747 /*
3662882Svi117747 * Get the reg-name from absolute URI
3672882Svi117747 */
3682882Svi117747 const sip_str_t *
sip_get_uri_regname(const struct sip_uri * uri,int * error)3692882Svi117747 sip_get_uri_regname(const struct sip_uri *uri, int *error)
3702882Svi117747 {
3712882Svi117747 _sip_uri_t *_uri;
3722882Svi117747
3732882Svi117747 _uri = sip_check_get_param(uri, error);
3742882Svi117747 if (_uri == NULL)
3752882Svi117747 return (NULL);
3762882Svi117747
3772882Svi117747 if (_uri->sip_uri_issip) {
3782882Svi117747 if (error != NULL)
3792882Svi117747 *error = EINVAL;
3802882Svi117747 return (NULL);
3812882Svi117747 }
3822882Svi117747 if ((_uri->sip_uri_errflags & SIP_URIERR_REGNAME) != 0 && error != NULL)
3832882Svi117747 *error = EINVAL;
3842882Svi117747 if (_uri->sip_uri_regname.sip_str_len > 0)
3852882Svi117747 return (&_uri->sip_uri_regname);
3862882Svi117747 return (NULL);
3872882Svi117747 }
3882882Svi117747
3892882Svi117747 /*
3902882Svi117747 * Return TRUE if this is a teluser
3912882Svi117747 */
3922882Svi117747 boolean_t
sip_is_uri_teluser(const struct sip_uri * uri)3932882Svi117747 sip_is_uri_teluser(const struct sip_uri *uri)
3942882Svi117747 {
3952882Svi117747 _sip_uri_t *_uri;
3962882Svi117747
3972882Svi117747 if (uri == NULL)
3982882Svi117747 return (B_FALSE);
3992882Svi117747
4002882Svi117747 _uri = (_sip_uri_t *)uri;
4012882Svi117747 return (_uri->sip_uri_isteluser);
4022882Svi117747 }
4032882Svi117747
4042882Svi117747 int
sip_get_uri_errflags(const struct sip_uri * uri,int * error)4052882Svi117747 sip_get_uri_errflags(const struct sip_uri *uri, int *error)
4062882Svi117747 {
4072882Svi117747 _sip_uri_t *_uri;
4082882Svi117747
4092882Svi117747 _uri = sip_check_get_param(uri, error);
4102882Svi117747 if (_uri == NULL)
4112882Svi117747 return (0);
4122882Svi117747 return (_uri->sip_uri_errflags);
4132882Svi117747 }
4142882Svi117747
4152882Svi117747 /*
4162882Svi117747 * the caller is responsible for freeing the returned string
4172882Svi117747 */
4182882Svi117747 char *
sip_uri_errflags_to_str(int errflags)4192882Svi117747 sip_uri_errflags_to_str(int errflags)
4202882Svi117747 {
4212882Svi117747 char *err_info = NULL;
4222882Svi117747
4232882Svi117747 if (errflags == 0)
4242882Svi117747 return (NULL);
4252882Svi117747
4262882Svi117747 err_info = (char *)malloc(SIP_URI_BUF_SIZE);
4272882Svi117747 if (err_info == NULL)
4282882Svi117747 return (NULL);
4292882Svi117747
4302882Svi117747 if (errflags & SIP_URIERR_NOURI) {
4312882Svi117747 (void) strncpy(err_info, "Error : No URI",
4322882Svi117747 strlen("Error : No URI"));
4332882Svi117747 err_info[strlen("Error : No URI")] = '\0';
4342882Svi117747 return (err_info);
4352882Svi117747 }
4362882Svi117747
4372882Svi117747 (void) strncpy(err_info, "Error(s) in", strlen("Error(s) in"));
4382882Svi117747 err_info[strlen("Error(s) in")] = '\0';
4392882Svi117747 if (errflags & SIP_URIERR_SCHEME)
4402882Svi117747 (void) strncat(err_info, " SCHEME,", strlen(" SCHEME,"));
4412882Svi117747 if (errflags & SIP_URIERR_USER)
4422882Svi117747 (void) strncat(err_info, " USER,", strlen(" USER,"));
4432882Svi117747 if (errflags & SIP_URIERR_PASS)
4442882Svi117747 (void) strncat(err_info, " PASSWORD,", strlen(" PASSWORD,"));
4452882Svi117747 if (errflags & SIP_URIERR_HOST)
4462882Svi117747 (void) strncat(err_info, " HOST,", strlen(" HOST,"));
4472882Svi117747 if (errflags & SIP_URIERR_PORT)
4482882Svi117747 (void) strncat(err_info, " PORT,", strlen(" PORT,"));
4492882Svi117747 if (errflags & SIP_URIERR_PARAM) {
4502882Svi117747 (void) strncat(err_info, " PARAMETERS,",
4512882Svi117747 strlen(" PARAMETERS,"));
4522882Svi117747 }
4532882Svi117747 if (errflags & SIP_URIERR_HEADER)
4542882Svi117747 (void) strncat(err_info, " HEADERS,", strlen(" HEADERS,"));
4552882Svi117747 if (errflags & SIP_URIERR_OPAQUE)
4562882Svi117747 (void) strncat(err_info, " OPAQUE,", strlen(" OPAQUE,"));
4572882Svi117747 if (errflags & SIP_URIERR_QUERY)
4582882Svi117747 (void) strncat(err_info, " QUERY,", strlen(" QUERY,"));
4592882Svi117747 if (errflags & SIP_URIERR_PATH)
4602882Svi117747 (void) strncat(err_info, " PATH,", strlen(" PATH,"));
4612882Svi117747 if (errflags & SIP_URIERR_REGNAME)
4622882Svi117747 (void) strncat(err_info, " REG-NAME,", strlen(" REG-NAME,"));
4632882Svi117747 if (strlen(err_info) == strlen("Error(s) in")) {
4642882Svi117747 free(err_info);
4652882Svi117747 err_info = NULL;
4662882Svi117747 } else {
4672882Svi117747 err_info[strlen(err_info) - 1] = '\0';
4682882Svi117747 (void) strncat(err_info, " part(s)", strlen(" part(s)"));
4692882Svi117747 }
4702882Svi117747 return (err_info);
4712882Svi117747 }
472