1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdlib.h> 29 #include <string.h> 30 #include <ctype.h> 31 #include <errno.h> 32 33 #include "sip_parse_uri.h" 34 35 void 36 sip_free_parsed_uri(sip_uri_t uri) 37 { 38 _sip_uri_t *_uri; 39 40 if (uri == NULL) 41 return; 42 43 _uri = (_sip_uri_t *)uri; 44 if (_uri->sip_uri_issip) { 45 sip_param_t *param; 46 sip_param_t *param_next; 47 48 param = _uri->sip_uri_params; 49 while (param != NULL) { 50 param_next = param->param_next; 51 free(param); 52 param = param_next; 53 } 54 } 55 free(_uri); 56 } 57 58 /* 59 * Parse the URI in uri_str 60 */ 61 struct sip_uri * 62 sip_parse_uri(sip_str_t *uri_str, int *error) 63 { 64 struct sip_uri *parsed_uri; 65 66 if (error != NULL) 67 *error = 0; 68 69 if (uri_str == NULL) { 70 if (error != NULL) 71 *error = EINVAL; 72 return (NULL); 73 } 74 parsed_uri = calloc(1, sizeof (_sip_uri_t)); 75 if (parsed_uri == NULL) { 76 if (error != NULL) 77 *error = ENOMEM; 78 return (NULL); 79 } 80 81 sip_uri_parse_it(parsed_uri, uri_str); 82 if (parsed_uri->sip_uri_errflags & SIP_URIERR_MEMORY) { 83 free(parsed_uri); 84 if (error != NULL) 85 *error = ENOMEM; 86 return (NULL); 87 } 88 if (parsed_uri->sip_uri_errflags != 0 && error != NULL) 89 *error = EPROTO; 90 return ((sip_uri_t)parsed_uri); 91 } 92 93 /* 94 * Get parsed URI 95 */ 96 const struct sip_uri * 97 sip_get_uri_parsed(sip_header_value_t value, int *error) 98 { 99 const struct sip_uri *ret = NULL; 100 101 if (error != NULL) 102 *error = 0; 103 if (value == NULL || value->sip_value_parse_uri == NULL || 104 value->value_state == SIP_VALUE_DELETED) { 105 if (error != NULL) 106 *error = EINVAL; 107 return (NULL); 108 } 109 ret = value->sip_value_parse_uri; 110 if (ret->sip_uri_errflags != 0 && error != NULL) 111 *error = EINVAL; 112 return ((sip_uri_t)ret); 113 } 114 115 /* 116 * Return TRUE if this is a SIP URI 117 */ 118 boolean_t 119 sip_is_sipuri(const struct sip_uri *uri) 120 { 121 _sip_uri_t *_uri; 122 123 if (uri == NULL) 124 return (B_FALSE); 125 _uri = (_sip_uri_t *)uri; 126 if ((_uri->sip_uri_errflags & SIP_URIERR_SCHEME) == 0 && 127 _uri->sip_uri_scheme.sip_str_len > 0 && _uri->sip_uri_issip) { 128 return (B_TRUE); 129 } 130 return (B_FALSE); 131 } 132 133 /* 134 * Some common checks 135 */ 136 static _sip_uri_t * 137 sip_check_get_param(const struct sip_uri *uri, int *error) 138 { 139 if (error != NULL) 140 *error = 0; 141 142 if (uri == NULL) { 143 if (error != NULL) 144 *error = EINVAL; 145 return (NULL); 146 } 147 return ((_sip_uri_t *)uri); 148 } 149 150 151 /* 152 * Return the URI scheme 153 */ 154 const sip_str_t * 155 sip_get_uri_scheme(const struct sip_uri *uri, int *error) 156 { 157 _sip_uri_t *_uri; 158 159 _uri = sip_check_get_param(uri, error); 160 if (_uri == NULL) 161 return (NULL); 162 163 if (((_uri->sip_uri_errflags & SIP_URIERR_SCHEME) != 0 || 164 _uri->sip_uri_scheme.sip_str_len == 0) && error != NULL) { 165 *error = EINVAL; 166 } 167 if (_uri->sip_uri_scheme.sip_str_len > 0) 168 return (&_uri->sip_uri_scheme); 169 return (NULL); 170 } 171 172 /* 173 * Return user name from URI 174 */ 175 const sip_str_t * 176 sip_get_uri_user(const struct sip_uri *uri, int *error) 177 { 178 _sip_uri_t *_uri; 179 180 _uri = sip_check_get_param(uri, error); 181 if (_uri == NULL) 182 return (NULL); 183 184 if ((_uri->sip_uri_errflags & SIP_URIERR_USER) != 0 && error != NULL) 185 *error = EINVAL; 186 if (uri->sip_uri_user.sip_str_len > 0) 187 return (&uri->sip_uri_user); 188 return (NULL); 189 } 190 191 /* 192 * Return password from URI 193 */ 194 const sip_str_t * 195 sip_get_uri_password(const struct sip_uri *uri, int *error) 196 { 197 _sip_uri_t *_uri; 198 199 _uri = sip_check_get_param(uri, error); 200 if (_uri == NULL) 201 return (NULL); 202 203 if ((_uri->sip_uri_errflags & SIP_URIERR_PASS) != 0 && error != NULL) 204 *error = EINVAL; 205 if (_uri->sip_uri_password.sip_str_len > 0) 206 return (&_uri->sip_uri_password); 207 return (NULL); 208 } 209 210 /* 211 * Get host from the URI 212 */ 213 const sip_str_t * 214 sip_get_uri_host(const struct sip_uri *uri, int *error) 215 { 216 _sip_uri_t *_uri; 217 218 _uri = sip_check_get_param(uri, error); 219 if (_uri == NULL) 220 return (NULL); 221 222 if ((_uri->sip_uri_errflags & SIP_URIERR_HOST) != 0 && error != NULL) 223 *error = EINVAL; 224 if (_uri->sip_uri_host.sip_str_len > 0) 225 return (&_uri->sip_uri_host); 226 return (NULL); 227 } 228 229 /* 230 * Get port from the URI 231 */ 232 int 233 sip_get_uri_port(const struct sip_uri *uri, int *error) 234 { 235 _sip_uri_t *_uri; 236 237 _uri = sip_check_get_param(uri, error); 238 if (_uri == NULL) 239 return (NULL); 240 241 if ((_uri->sip_uri_errflags & SIP_URIERR_PORT) != 0) { 242 if (error != NULL) 243 *error = EINVAL; 244 return (0); 245 } 246 return (_uri->sip_uri_port); 247 } 248 249 const sip_param_t * 250 sip_get_uri_params(const struct sip_uri *uri, int *error) 251 { 252 _sip_uri_t *_uri; 253 254 _uri = sip_check_get_param(uri, error); 255 if (_uri == NULL) 256 return (NULL); 257 258 if (!_uri->sip_uri_issip) { 259 if (error != NULL) 260 *error = EINVAL; 261 return (NULL); 262 } 263 264 if ((_uri->sip_uri_errflags & SIP_URIERR_PARAM) != 0 && error != NULL) 265 *error = EINVAL; 266 return (_uri->sip_uri_params); 267 } 268 269 /* 270 * Get headers from the URI 271 */ 272 const sip_str_t * 273 sip_get_uri_headers(const struct sip_uri *uri, int *error) 274 { 275 _sip_uri_t *_uri; 276 277 _uri = sip_check_get_param(uri, error); 278 if (_uri == NULL) 279 return (NULL); 280 281 if (!_uri->sip_uri_issip) { 282 if (error != NULL) 283 *error = EINVAL; 284 return (NULL); 285 } 286 if ((_uri->sip_uri_errflags & SIP_URIERR_HEADER) != 0 && error != NULL) 287 *error = EINVAL; 288 if (_uri->sip_uri_headers.sip_str_len > 0) 289 return (&_uri->sip_uri_headers); 290 return (NULL); 291 } 292 293 /* 294 * Return opaque value for an ABS URI 295 */ 296 const sip_str_t * 297 sip_get_uri_opaque(const struct sip_uri *uri, int *error) 298 { 299 _sip_uri_t *_uri; 300 301 _uri = sip_check_get_param(uri, error); 302 if (_uri == NULL) 303 return (NULL); 304 305 if (_uri->sip_uri_issip) { 306 if (error != NULL) 307 *error = EINVAL; 308 return (NULL); 309 } 310 if ((_uri->sip_uri_errflags & SIP_URIERR_OPAQUE) != 0 && error != NULL) 311 *error = EINVAL; 312 if (_uri->sip_uri_opaque.sip_str_len > 0) 313 return (&_uri->sip_uri_opaque); 314 return (NULL); 315 } 316 317 /* 318 * Return query from an absolute URI 319 */ 320 const sip_str_t * 321 sip_get_uri_query(const struct sip_uri *uri, int *error) 322 { 323 _sip_uri_t *_uri; 324 325 _uri = sip_check_get_param(uri, error); 326 if (_uri == NULL) 327 return (NULL); 328 329 if (_uri->sip_uri_issip) { 330 if (error != NULL) 331 *error = EINVAL; 332 return (NULL); 333 } 334 if ((_uri->sip_uri_errflags & SIP_URIERR_QUERY) != 0 && error != NULL) 335 *error = EINVAL; 336 if (_uri->sip_uri_query.sip_str_len > 0) 337 return (&_uri->sip_uri_query); 338 return (NULL); 339 } 340 341 /* 342 * Get path from an assolute URI 343 */ 344 const sip_str_t * 345 sip_get_uri_path(const struct sip_uri *uri, int *error) 346 { 347 _sip_uri_t *_uri; 348 349 _uri = sip_check_get_param(uri, error); 350 if (_uri == NULL) 351 return (NULL); 352 353 if (_uri->sip_uri_issip) { 354 if (error != NULL) 355 *error = EINVAL; 356 return (NULL); 357 } 358 if ((_uri->sip_uri_errflags & SIP_URIERR_PATH) != 0 && error != NULL) 359 *error = EINVAL; 360 if (_uri->sip_uri_path.sip_str_len > 0) 361 return (&_uri->sip_uri_path); 362 return (NULL); 363 } 364 365 /* 366 * Get the reg-name from absolute URI 367 */ 368 const sip_str_t * 369 sip_get_uri_regname(const struct sip_uri *uri, int *error) 370 { 371 _sip_uri_t *_uri; 372 373 _uri = sip_check_get_param(uri, error); 374 if (_uri == NULL) 375 return (NULL); 376 377 if (_uri->sip_uri_issip) { 378 if (error != NULL) 379 *error = EINVAL; 380 return (NULL); 381 } 382 if ((_uri->sip_uri_errflags & SIP_URIERR_REGNAME) != 0 && error != NULL) 383 *error = EINVAL; 384 if (_uri->sip_uri_regname.sip_str_len > 0) 385 return (&_uri->sip_uri_regname); 386 return (NULL); 387 } 388 389 /* 390 * Return TRUE if this is a teluser 391 */ 392 boolean_t 393 sip_is_uri_teluser(const struct sip_uri *uri) 394 { 395 _sip_uri_t *_uri; 396 397 if (uri == NULL) 398 return (B_FALSE); 399 400 _uri = (_sip_uri_t *)uri; 401 return (_uri->sip_uri_isteluser); 402 } 403 404 int 405 sip_get_uri_errflags(const struct sip_uri *uri, int *error) 406 { 407 _sip_uri_t *_uri; 408 409 _uri = sip_check_get_param(uri, error); 410 if (_uri == NULL) 411 return (0); 412 return (_uri->sip_uri_errflags); 413 } 414 415 /* 416 * the caller is responsible for freeing the returned string 417 */ 418 char * 419 sip_uri_errflags_to_str(int errflags) 420 { 421 char *err_info = NULL; 422 423 if (errflags == 0) 424 return (NULL); 425 426 err_info = (char *)malloc(SIP_URI_BUF_SIZE); 427 if (err_info == NULL) 428 return (NULL); 429 430 if (errflags & SIP_URIERR_NOURI) { 431 (void) strncpy(err_info, "Error : No URI", 432 strlen("Error : No URI")); 433 err_info[strlen("Error : No URI")] = '\0'; 434 return (err_info); 435 } 436 437 (void) strncpy(err_info, "Error(s) in", strlen("Error(s) in")); 438 err_info[strlen("Error(s) in")] = '\0'; 439 if (errflags & SIP_URIERR_SCHEME) 440 (void) strncat(err_info, " SCHEME,", strlen(" SCHEME,")); 441 if (errflags & SIP_URIERR_USER) 442 (void) strncat(err_info, " USER,", strlen(" USER,")); 443 if (errflags & SIP_URIERR_PASS) 444 (void) strncat(err_info, " PASSWORD,", strlen(" PASSWORD,")); 445 if (errflags & SIP_URIERR_HOST) 446 (void) strncat(err_info, " HOST,", strlen(" HOST,")); 447 if (errflags & SIP_URIERR_PORT) 448 (void) strncat(err_info, " PORT,", strlen(" PORT,")); 449 if (errflags & SIP_URIERR_PARAM) { 450 (void) strncat(err_info, " PARAMETERS,", 451 strlen(" PARAMETERS,")); 452 } 453 if (errflags & SIP_URIERR_HEADER) 454 (void) strncat(err_info, " HEADERS,", strlen(" HEADERS,")); 455 if (errflags & SIP_URIERR_OPAQUE) 456 (void) strncat(err_info, " OPAQUE,", strlen(" OPAQUE,")); 457 if (errflags & SIP_URIERR_QUERY) 458 (void) strncat(err_info, " QUERY,", strlen(" QUERY,")); 459 if (errflags & SIP_URIERR_PATH) 460 (void) strncat(err_info, " PATH,", strlen(" PATH,")); 461 if (errflags & SIP_URIERR_REGNAME) 462 (void) strncat(err_info, " REG-NAME,", strlen(" REG-NAME,")); 463 if (strlen(err_info) == strlen("Error(s) in")) { 464 free(err_info); 465 err_info = NULL; 466 } else { 467 err_info[strlen(err_info) - 1] = '\0'; 468 (void) strncat(err_info, " part(s)", strlen(" part(s)")); 469 } 470 return (err_info); 471 } 472