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
sip_free_parsed_uri(sip_uri_t uri)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 *
sip_parse_uri(sip_str_t * uri_str,int * error)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 *
sip_get_uri_parsed(sip_header_value_t value,int * error)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
sip_is_sipuri(const struct sip_uri * uri)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 *
sip_check_get_param(const struct sip_uri * uri,int * error)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 *
sip_get_uri_scheme(const struct sip_uri * uri,int * error)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 *
sip_get_uri_user(const struct sip_uri * uri,int * error)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 *
sip_get_uri_password(const struct sip_uri * uri,int * error)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 *
sip_get_uri_host(const struct sip_uri * uri,int * error)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
sip_get_uri_port(const struct sip_uri * uri,int * error)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 *
sip_get_uri_params(const struct sip_uri * uri,int * error)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 *
sip_get_uri_headers(const struct sip_uri * uri,int * error)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 *
sip_get_uri_opaque(const struct sip_uri * uri,int * error)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 *
sip_get_uri_query(const struct sip_uri * uri,int * error)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 *
sip_get_uri_path(const struct sip_uri * uri,int * error)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 *
sip_get_uri_regname(const struct sip_uri * uri,int * error)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
sip_is_uri_teluser(const struct sip_uri * uri)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
sip_get_uri_errflags(const struct sip_uri * uri,int * error)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 *
sip_uri_errflags_to_str(int errflags)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