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