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