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
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <strings.h>
32 #include <errno.h>
33 #include <pthread.h>
34 #include <sip.h>
35
36 #include "sip_msg.h"
37
38 /*
39 * Generic function to get int or string value from a header
40 */
41 static void *
sip_get_val_from_hdr(sip_hdr_value_t * val,int val_type,boolean_t stype,int * error)42 sip_get_val_from_hdr(sip_hdr_value_t *val, int val_type, boolean_t stype,
43 int *error)
44 {
45 if (error != NULL)
46 *error = 0;
47
48 if (val == NULL || val->sip_value_state == SIP_VALUE_DELETED) {
49 if (error != NULL)
50 *error = EINVAL;
51 return (NULL);
52 }
53
54 if (val->sip_value_state == SIP_VALUE_BAD)
55 *error = EPROTO;
56
57 switch (val_type) {
58 case (SIP_INT_VAL):
59 return (&(val->int_val));
60 case (SIP_STR_VAL):
61 return (&(val->str_val));
62 case (SIP_STRS_VAL):
63 if (stype == B_TRUE) {
64 if (val->strs_val.s1.sip_str_ptr != NULL)
65 return (&(val->strs_val.s1));
66 return (NULL);
67 }
68 if (val->strs_val.s2.sip_str_ptr != NULL)
69 return (&(val->strs_val.s2));
70 return (NULL);
71 case (SIP_INTSTR_VAL):
72 if (stype == B_TRUE) {
73 if (val->intstr_str.sip_str_ptr != NULL)
74 return (&(val->intstr_str));
75 else
76 return (NULL);
77 }
78 return (&(val->intstr_int));
79 case (SIP_AUTH_VAL):
80 return (&(val->auth_val));
81 }
82 if (error != NULL && *error == 0)
83 *error = EINVAL;
84 return (NULL);
85 }
86
87 /*
88 * Generic function to get value from a header given the value type and
89 * the string info (for multi-string values).
90 */
91 static void *
sip_get_val_from_msg(sip_msg_t msg,char * hdr_name,int val_type,boolean_t stype,boolean_t empty_val,int * error)92 sip_get_val_from_msg(sip_msg_t msg, char *hdr_name, int val_type,
93 boolean_t stype, boolean_t empty_val, int *error)
94 {
95 const _sip_header_t *header;
96 sip_hdr_value_t *value;
97
98 if (error != NULL)
99 *error = 0;
100 if (msg == NULL) {
101 if (error != NULL)
102 *error = EINVAL;
103 return (NULL);
104 }
105
106 header = sip_get_header(msg, hdr_name, NULL, error);
107 if (header == NULL) {
108 if (error != NULL)
109 *error = EINVAL;
110 return (NULL);
111 }
112
113 value = (sip_hdr_value_t *)sip_get_header_value(header, error);
114 if (value == NULL) {
115 if (error != NULL && empty_val == B_FALSE)
116 *error = EPROTO;
117 return (NULL);
118 }
119 return (sip_get_val_from_hdr(value, val_type, stype, error));
120 }
121
122 /*
123 * Get the URI from the value
124 */
125 const sip_str_t *
sip_get_cftruri_from_val(sip_header_value_t value,int * error)126 sip_get_cftruri_from_val(sip_header_value_t value, int *error)
127 {
128 sip_hdr_value_t *cftrvalue;
129
130 if (error != NULL)
131 *error = 0;
132
133 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
134 if (error != NULL)
135 *error = EINVAL;
136 return (NULL);
137 }
138 cftrvalue = (sip_hdr_value_t *)value;
139 /*
140 * If the value is BAD, update error to reflect it.
141 */
142 if (error != NULL && value->value_state == SIP_VALUE_BAD)
143 *error = EPROTO;
144 return (&cftrvalue->cftr_uri);
145 }
146
147 /*
148 * Get display name from the value
149 */
150 const sip_str_t *
sip_get_cftrname_from_val(sip_header_value_t value,int * error)151 sip_get_cftrname_from_val(sip_header_value_t value, int *error)
152 {
153 sip_hdr_value_t *cftrvalue;
154
155 if (error != NULL)
156 *error = 0;
157 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
158 if (error != NULL)
159 *error = EINVAL;
160 return (NULL);
161 }
162 cftrvalue = (sip_hdr_value_t *)value;
163 /*
164 * If the value is BAD, update error to reflect it.
165 */
166 if (error != NULL && value->value_state == SIP_VALUE_BAD)
167 *error = EPROTO;
168 return (cftrvalue->cftr_name);
169 }
170
171 /*
172 * Contact header can have more than one value
173 * so we require a value to be passed in to get a value.
174 */
175 const sip_str_t *
sip_get_contact_uri_str(sip_header_value_t value,int * error)176 sip_get_contact_uri_str(sip_header_value_t value, int *error)
177 {
178 return (sip_get_cftruri_from_val(value, error));
179 }
180
181 /*
182 * Contact header can have more than one value
183 * so we require a value to be passed in to get a value.
184 */
185 const sip_str_t *
sip_get_contact_display_name(sip_header_value_t value,int * error)186 sip_get_contact_display_name(sip_header_value_t value, int *error)
187 {
188 return (sip_get_cftrname_from_val(value, error));
189 }
190
191 /*
192 * Route header can have more than one value
193 * so we require a value to be passed in to get a value.
194 */
195 const sip_str_t *
sip_get_route_uri_str(sip_header_value_t value,int * error)196 sip_get_route_uri_str(sip_header_value_t value, int *error)
197 {
198 return (sip_get_cftruri_from_val(value, error));
199 }
200
201 /*
202 * Route header can have more than one value
203 * so we require a value to be passed in to get a value.
204 */
205 const sip_str_t *
sip_get_route_display_name(sip_header_value_t value,int * error)206 sip_get_route_display_name(sip_header_value_t value, int *error)
207 {
208 return (sip_get_cftrname_from_val(value, error));
209 }
210
211 /*
212 * Get URI from the SIP message
213 */
214 const sip_str_t *
sip_get_cftruri_from_msg(sip_msg_t sip_msg,int * error,char * hdrname)215 sip_get_cftruri_from_msg(sip_msg_t sip_msg, int *error, char *hdrname)
216 {
217 const sip_hdr_value_t *value;
218 const struct sip_header *header;
219
220 if (error != NULL)
221 *error = 0;
222 if (sip_msg == NULL) {
223 if (error != NULL)
224 *error = EINVAL;
225 return (NULL);
226 }
227
228 header = sip_get_header(sip_msg, hdrname, NULL, error);
229 if (header == NULL) {
230 if (error != NULL)
231 *error = EINVAL;
232 return (NULL);
233 }
234
235 value = (sip_hdr_value_t *)sip_get_header_value(header, error);
236 if (value == NULL) {
237 if (error != NULL)
238 *error = EPROTO;
239 return (NULL);
240 }
241 /*
242 * If the value is BAD, update error to reflect it.
243 */
244 if (error != NULL && value->sip_value_state == SIP_VALUE_BAD)
245 *error = EPROTO;
246 return (&value->cftr_uri);
247 }
248
249 /*
250 * Get display name from the SIP message
251 */
252 const sip_str_t *
sip_get_cftrname_from_msg(sip_msg_t sip_msg,int * error,char * hdrname)253 sip_get_cftrname_from_msg(sip_msg_t sip_msg, int *error, char *hdrname)
254 {
255 const sip_hdr_value_t *value;
256 const struct sip_header *header;
257
258 if (error != NULL)
259 *error = 0;
260 if (sip_msg == NULL) {
261 if (error != NULL)
262 *error = EINVAL;
263 return (NULL);
264 }
265 header = sip_get_header(sip_msg, hdrname, NULL, error);
266 if (header == NULL) {
267 if (error != NULL)
268 *error = EINVAL;
269 return (NULL);
270 }
271
272 value = (sip_hdr_value_t *)sip_get_header_value(header, error);
273 if (value == NULL) {
274 if (error != NULL)
275 *error = EPROTO;
276 return (NULL);
277 }
278 /*
279 * If the value is BAD, update error to reflect it.
280 */
281 if (error != NULL && value->sip_value_state == SIP_VALUE_BAD)
282 *error = EPROTO;
283 return (value->cftr_name);
284 }
285
286 /*
287 * Get FROM URI
288 */
289 const sip_str_t *
sip_get_from_uri_str(sip_msg_t sip_msg,int * error)290 sip_get_from_uri_str(sip_msg_t sip_msg, int *error)
291 {
292 return (sip_get_cftruri_from_msg(sip_msg, error, SIP_FROM));
293 }
294
295 /*
296 * Get FROM display name
297 */
298 const sip_str_t *
sip_get_from_display_name(sip_msg_t sip_msg,int * error)299 sip_get_from_display_name(sip_msg_t sip_msg, int *error)
300 {
301 return (sip_get_cftrname_from_msg(sip_msg, error, SIP_FROM));
302 }
303
304 /*
305 * Return the FROM tag
306 */
307 const sip_str_t *
sip_get_from_tag(sip_msg_t sip_msg,int * error)308 sip_get_from_tag(sip_msg_t sip_msg, int *error)
309 {
310 const sip_hdr_value_t *value;
311 const struct sip_header *header;
312
313 if (error != NULL)
314 *error = 0;
315 if (sip_msg == NULL) {
316 if (error != NULL)
317 *error = EINVAL;
318 return (NULL);
319 }
320 header = sip_get_header(sip_msg, SIP_FROM, NULL, error);
321 if (header == NULL) {
322 if (error != NULL)
323 *error = EINVAL;
324 return (NULL);
325 }
326
327 value = (sip_hdr_value_t *)sip_get_header_value(header, error);
328 if (value == NULL) {
329 if (error != NULL)
330 *error = EPROTO;
331 return (NULL);
332 }
333 /*
334 * If the value is BAD, update error to reflect it.
335 */
336 if (error != NULL && value->sip_value_state == SIP_VALUE_BAD)
337 *error = EPROTO;
338 return (sip_get_param_value((sip_header_value_t)value, "tag", error));
339 }
340
341 /*
342 * Get TO URI
343 */
344 const sip_str_t *
sip_get_to_uri_str(sip_msg_t sip_msg,int * error)345 sip_get_to_uri_str(sip_msg_t sip_msg, int *error)
346 {
347 return (sip_get_cftruri_from_msg(sip_msg, error, SIP_TO));
348 }
349
350 /*
351 * Get TO display name
352 */
353 const sip_str_t *
sip_get_to_display_name(sip_msg_t sip_msg,int * error)354 sip_get_to_display_name(sip_msg_t sip_msg, int *error)
355 {
356 return (sip_get_cftrname_from_msg(sip_msg, error, SIP_TO));
357 }
358
359 /*
360 * Get TO tag
361 */
362 const sip_str_t *
sip_get_to_tag(sip_msg_t sip_msg,int * error)363 sip_get_to_tag(sip_msg_t sip_msg, int *error)
364 {
365 const sip_hdr_value_t *value;
366 const struct sip_header *header;
367
368 if (error != NULL)
369 *error = 0;
370 if (sip_msg == NULL) {
371 if (error != NULL)
372 *error = EINVAL;
373 return (NULL);
374 }
375 header = sip_get_header(sip_msg, SIP_TO, NULL, error);
376 if (header == NULL) {
377 if (error != NULL)
378 *error = EINVAL;
379 return (NULL);
380 }
381
382 value = (sip_hdr_value_t *)sip_get_header_value(header, error);
383 if (value == NULL) {
384 if (error != NULL)
385 *error = EPROTO;
386 return (NULL);
387 }
388 /*
389 * If the value is BAD, update error to reflect it.
390 */
391 if (error != NULL && value->sip_value_state == SIP_VALUE_BAD)
392 *error = EPROTO;
393 return (sip_get_param_value((sip_header_value_t)value, "tag", error));
394 }
395
396 /*
397 * Return the Call-Id
398 */
399 const sip_str_t *
sip_get_callid(sip_msg_t sip_msg,int * error)400 sip_get_callid(sip_msg_t sip_msg, int *error)
401 {
402 sip_str_t *r;
403
404 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CALL_ID, SIP_STR_VAL,
405 B_FALSE, B_TRUE, error);
406 return (r);
407 }
408
409 #define SIP_CSEQ_NUM 1
410 #define SIP_CSEQ_METHOD 2
411
412 /*
413 * Get number/method from the CSEQ header
414 */
415 static void *
sip_get_cseq_val(sip_msg_t msg,int type,int * error)416 sip_get_cseq_val(sip_msg_t msg, int type, int *error)
417 {
418 const _sip_header_t *header;
419 sip_hdr_value_t *val;
420
421 if (error != NULL)
422 *error = 0;
423
424 if (msg == NULL) {
425 if (error != NULL)
426 *error = EINVAL;
427 return (NULL);
428 }
429 header = sip_get_header(msg, SIP_CSEQ, NULL, error);
430 if (header == NULL) {
431 if (error != NULL)
432 *error = EINVAL;
433 return (NULL);
434 }
435 val = (sip_hdr_value_t *)sip_get_header_value(header, error);
436 if (val == NULL) {
437 if (error != NULL)
438 *error = EPROTO;
439 return (NULL);
440 }
441 if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD)
442 *error = EPROTO;
443
444 switch (type) {
445 case SIP_CSEQ_NUM:
446 return (&(val->cseq_num));
447 case SIP_CSEQ_METHOD:
448 return (&(val->cseq_method));
449 }
450 if (error != NULL)
451 *error = EINVAL;
452 return (NULL);
453 }
454
455 /*
456 * Get CSEQ number
457 */
458 int
sip_get_callseq_num(sip_msg_t sip_msg,int * error)459 sip_get_callseq_num(sip_msg_t sip_msg, int *error)
460 {
461 int *r;
462
463 r = (int *)sip_get_cseq_val(sip_msg, SIP_CSEQ_NUM, error);
464 return (r == NULL ? -1 : *r);
465 }
466
467 /*
468 * Get CSEQ method
469 */
470 sip_method_t
sip_get_callseq_method(sip_msg_t sip_msg,int * error)471 sip_get_callseq_method(sip_msg_t sip_msg, int *error)
472 {
473 sip_method_t *r;
474
475 r = (sip_method_t *)sip_get_cseq_val(sip_msg, SIP_CSEQ_METHOD, error);
476 return (r == NULL ? -1 : *r);
477 }
478
479 /*
480 * Via header can have more than one value
481 * so we require a value to be passed in.
482 */
483 const sip_str_t *
sip_get_via_sent_by_host(sip_header_value_t value,int * error)484 sip_get_via_sent_by_host(sip_header_value_t value, int *error)
485 {
486 sip_hdr_value_t *via_value;
487
488 if (error != NULL)
489 *error = 0;
490 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
491 if (error != NULL)
492 *error = EINVAL;
493 return (NULL);
494 }
495 via_value = (sip_hdr_value_t *)value;
496 if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL)
497 *error = EPROTO;
498 return (&via_value->via_sent_by_host);
499 }
500
501 /*
502 * Via header can have more than one value
503 * so we require a value to be passed in.
504 */
505 int
sip_get_via_sent_by_port(sip_header_value_t value,int * error)506 sip_get_via_sent_by_port(sip_header_value_t value, int *error)
507 {
508 sip_hdr_value_t *via_value;
509
510 if (error != NULL)
511 *error = 0;
512 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
513 if (error != NULL)
514 *error = EINVAL;
515 return (-1);
516 }
517 via_value = (sip_hdr_value_t *)value;
518 if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL)
519 *error = EPROTO;
520 return (via_value->via_sent_by_port);
521 }
522
523 /*
524 * Return the protocol version from the VIA value
525 */
526 const sip_str_t *
sip_get_via_sent_protocol_version(sip_header_value_t value,int * error)527 sip_get_via_sent_protocol_version(sip_header_value_t value, int *error)
528 {
529 sip_hdr_value_t *via_value;
530
531 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
532 if (error != NULL)
533 *error = EINVAL;
534 return (NULL);
535 }
536 via_value = (sip_hdr_value_t *)value;
537 if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL)
538 *error = EPROTO;
539 return (&via_value->via_protocol_vers);
540 }
541
542 /*
543 * Return the protocol name
544 */
545 const sip_str_t *
sip_get_via_sent_protocol_name(sip_header_value_t value,int * error)546 sip_get_via_sent_protocol_name(sip_header_value_t value, int *error)
547 {
548 sip_hdr_value_t *via_value;
549
550 if (error != NULL)
551 *error = 0;
552 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
553 if (error != NULL)
554 *error = EINVAL;
555 return (NULL);
556 }
557 via_value = (sip_hdr_value_t *)value;
558 if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL)
559 *error = EPROTO;
560 return (&via_value->via_protocol_name);
561 }
562
563 /*
564 * Return the transport from the VIA value
565 */
566 const sip_str_t *
sip_get_via_sent_transport(sip_header_value_t value,int * error)567 sip_get_via_sent_transport(sip_header_value_t value, int *error)
568 {
569 sip_hdr_value_t *via_value;
570
571 if (error != NULL)
572 *error = 0;
573 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
574 if (error != NULL)
575 *error = EINVAL;
576 return (NULL);
577 }
578 via_value = (sip_hdr_value_t *)value;
579 if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL)
580 *error = EPROTO;
581 return (&via_value->via_protocol_transport);
582 }
583
584 /*
585 * get the branch id from the topmost VIA header
586 */
587 char *
sip_get_branchid(sip_msg_t sip_msg,int * error)588 sip_get_branchid(sip_msg_t sip_msg, int *error)
589 {
590 _sip_header_t *header;
591 sip_parsed_header_t *parsed_header;
592 sip_hdr_value_t *via_value;
593 const sip_str_t *param_value;
594 char *bid;
595 _sip_msg_t *_sip_msg;
596
597 if (error != NULL)
598 *error = 0;
599
600 if (sip_msg == NULL) {
601 if (error != NULL)
602 *error = EINVAL;
603 return (NULL);
604 }
605
606 _sip_msg = (_sip_msg_t *)sip_msg;
607
608 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex);
609 header = sip_search_for_header(_sip_msg, SIP_VIA, NULL);
610 if (header == NULL) {
611 if (error != NULL)
612 *error = EINVAL;
613 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
614 return (NULL);
615 }
616 if (sip_parse_via_header(header, &parsed_header) != 0) {
617 if (error != NULL)
618 *error = EPROTO;
619 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
620 return (NULL);
621 }
622 if (parsed_header == NULL) {
623 if (error != NULL)
624 *error = EPROTO;
625 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
626 return (NULL);
627 }
628 via_value = (sip_hdr_value_t *)parsed_header->value;
629 if (via_value == NULL || via_value->sip_value_state == SIP_VALUE_BAD) {
630 if (error != NULL)
631 *error = EPROTO;
632 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
633 return (NULL);
634 }
635 param_value = sip_get_param_value((sip_header_value_t)via_value,
636 "branch", error);
637
638 if (param_value == NULL) {
639 if (error != NULL)
640 *error = EINVAL;
641 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
642 return (NULL);
643 }
644
645 bid = (char *)malloc(param_value->sip_str_len + 1);
646 if (bid == NULL) {
647 if (error != NULL)
648 *error = ENOMEM;
649 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
650 return (NULL);
651 }
652 (void) strncpy(bid, param_value->sip_str_ptr,
653 param_value->sip_str_len);
654 bid[param_value->sip_str_len] = '\0';
655 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
656 return (bid);
657 }
658
659 /*
660 * adds branchid to the topmost VIA header, if a branchid already exists,
661 * returns error.
662 */
663 int
sip_add_branchid_to_via(sip_msg_t sip_msg,char * branchid)664 sip_add_branchid_to_via(sip_msg_t sip_msg, char *branchid)
665 {
666 int err = 0;
667 char *param;
668 int plen;
669 sip_header_t via_hdr;
670 _sip_msg_t *_sip_msg;
671
672 if (sip_msg == NULL)
673 return (EINVAL);
674 /*
675 * If there is already a branchid param, error?
676 */
677 if (sip_get_branchid(sip_msg, NULL) != NULL)
678 return (EINVAL);
679 _sip_msg = (_sip_msg_t *)sip_msg;
680 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex);
681 via_hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA, NULL);
682 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
683 if (via_hdr == NULL)
684 return (EINVAL);
685 plen = strlen(branchid) + strlen("branch=") + 1;
686 param = malloc(plen);
687 if (param == NULL)
688 return (ENOMEM);
689 (void) snprintf(param, plen, "branch=%s", branchid);
690
691 (void) sip_add_param(via_hdr, param, &err);
692 free(param);
693
694 return (err);
695 }
696
697 /*
698 * returns the number of VIA headers in the SIP message
699 */
700 int
sip_get_num_via(sip_msg_t sip_msg,int * error)701 sip_get_num_via(sip_msg_t sip_msg, int *error)
702 {
703 _sip_msg_t *_sip_msg;
704 sip_header_t hdr;
705 int via_cnt = 0;
706
707 if (error != NULL)
708 *error = 0;
709 if (sip_msg == NULL) {
710 if (error != NULL)
711 *error = EINVAL;
712 return (via_cnt);
713 }
714 _sip_msg = (_sip_msg_t *)sip_msg;
715 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex);
716 hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA, NULL);
717 while (hdr != NULL) {
718 via_cnt++;
719 hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA,
720 hdr);
721 }
722 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
723 return (via_cnt);
724 }
725
726 /*
727 * Return Max-Forward value
728 */
729 int
sip_get_maxforward(sip_msg_t sip_msg,int * error)730 sip_get_maxforward(sip_msg_t sip_msg, int *error)
731 {
732 int *r;
733
734 r = (int *)sip_get_val_from_msg(sip_msg, SIP_MAX_FORWARDS, SIP_INT_VAL,
735 B_FALSE, B_FALSE, error);
736 if (r == NULL)
737 return (-1);
738 return (*r);
739 }
740
741 /*
742 * Get the content type
743 */
744 const sip_str_t *
sip_get_content_type(sip_msg_t sip_msg,int * error)745 sip_get_content_type(sip_msg_t sip_msg, int *error)
746 {
747 sip_str_t *r;
748
749 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_TYPE,
750 SIP_STRS_VAL, B_TRUE, B_FALSE, error);
751 return (r);
752 }
753
754 /*
755 * Get the content sub-type
756 */
757 const sip_str_t *
sip_get_content_sub_type(sip_msg_t sip_msg,int * error)758 sip_get_content_sub_type(sip_msg_t sip_msg, int *error)
759 {
760 sip_str_t *r;
761
762 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_TYPE,
763 SIP_STRS_VAL, B_FALSE, B_FALSE, error);
764 return (r);
765 }
766
767 /*
768 * Return the content-length value
769 */
770 int
sip_get_content_length(sip_msg_t sip_msg,int * error)771 sip_get_content_length(sip_msg_t sip_msg, int *error)
772 {
773 int *r;
774
775 r = (int *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_LENGTH,
776 SIP_INT_VAL, B_FALSE, B_FALSE, error);
777 if (r == NULL)
778 return (-1);
779 return (*r);
780 }
781
782 /*
783 * get allow-events
784 */
785 const sip_str_t *
sip_get_allow_events(sip_header_value_t value,int * error)786 sip_get_allow_events(sip_header_value_t value, int *error)
787 {
788 sip_str_t *r;
789 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
790
791 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_TRUE, error);
792 return (r);
793 }
794
795 /*
796 * get event
797 */
798 const sip_str_t *
sip_get_event(sip_msg_t sip_msg,int * error)799 sip_get_event(sip_msg_t sip_msg, int *error)
800 {
801 sip_str_t *r;
802
803 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_EVENT, SIP_STR_VAL,
804 B_FALSE, B_FALSE, error);
805 return (r);
806 }
807
808 /*
809 * get subscription state
810 */
811 const sip_str_t *
sip_get_substate(sip_msg_t sip_msg,int * error)812 sip_get_substate(sip_msg_t sip_msg, int *error)
813 {
814 sip_str_t *r;
815
816 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SUBSCRIPTION_STATE,
817 SIP_STR_VAL, B_FALSE, B_FALSE, error);
818 return (r);
819 }
820
821 /*
822 * get accept type
823 */
824 const sip_str_t *
sip_get_accept_type(sip_header_value_t value,int * error)825 sip_get_accept_type(sip_header_value_t value, int *error)
826 {
827 sip_str_t *r;
828 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
829
830 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_TRUE, error);
831 return (r);
832 }
833
834 /*
835 * get accept subtype
836 */
837 const sip_str_t *
sip_get_accept_sub_type(sip_header_value_t value,int * error)838 sip_get_accept_sub_type(sip_header_value_t value, int *error)
839 {
840 sip_str_t *r;
841 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
842
843 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_FALSE,
844 error);
845 return (r);
846 }
847
848 /*
849 * accept-encode can have more than one value
850 */
851 const sip_str_t *
sip_get_accept_enc(sip_header_value_t value,int * error)852 sip_get_accept_enc(sip_header_value_t value, int *error)
853 {
854 sip_str_t *r;
855 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
856
857 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
858 return (r);
859 }
860
861 /*
862 * accept-language can have more than one value
863 */
864 const sip_str_t *
sip_get_accept_lang(sip_header_value_t value,int * error)865 sip_get_accept_lang(sip_header_value_t value, int *error)
866 {
867 sip_str_t *r;
868 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
869
870 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
871 return (r);
872 }
873
874 /*
875 * get URI from the alert-info header
876 */
877 const sip_str_t *
sip_get_alert_info_uri(sip_header_value_t value,int * error)878 sip_get_alert_info_uri(sip_header_value_t value, int *error)
879 {
880 sip_str_t *r;
881 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
882
883 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
884 return (r);
885 }
886
887 /*
888 * get method from allow header
889 */
890 sip_method_t
sip_get_allow_method(sip_header_value_t value,int * error)891 sip_get_allow_method(sip_header_value_t value, int *error)
892 {
893 int *r;
894 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
895
896 r = (int *)sip_get_val_from_hdr(val, SIP_INT_VAL, B_FALSE, error);
897 return (r == NULL ? -1 : (sip_method_t)*r);
898 }
899
900 /*
901 * get URI from call-info header
902 */
903 const sip_str_t *
sip_get_call_info_uri(sip_header_value_t value,int * error)904 sip_get_call_info_uri(sip_header_value_t value, int *error)
905 {
906 sip_str_t *r;
907 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
908
909 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
910 return (r);
911 }
912
913 /*
914 * get content-disposition value
915 */
916 const sip_str_t *
sip_get_content_disp(sip_msg_t sip_msg,int * error)917 sip_get_content_disp(sip_msg_t sip_msg, int *error)
918 {
919 sip_str_t *r;
920
921 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_DIS,
922 SIP_STR_VAL, B_FALSE, B_FALSE, error);
923 return (r);
924 }
925
926 /*
927 * get content-encoding value
928 */
929 const sip_str_t *
sip_get_content_enc(sip_header_value_t value,int * error)930 sip_get_content_enc(sip_header_value_t value, int *error)
931 {
932 sip_str_t *r;
933 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
934
935 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
936 return (r);
937 }
938
939 /*
940 * get content-language value
941 */
942 const sip_str_t *
sip_get_content_lang(sip_header_value_t value,int * error)943 sip_get_content_lang(sip_header_value_t value, int *error)
944 {
945 sip_str_t *r;
946 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
947
948 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
949 return (r);
950 }
951
952 /*
953 * sip_get_date_time, day, wkday, month, year
954 */
955 #define D_TIME 0x01
956 #define D_DAY 0x02
957 #define D_MONTH 0x03
958 #define D_YEAR 0x04
959 #define D_WKDAY 0x05
960 #define D_TIMEZONE 0x06
961
962 /*
963 * get date information
964 */
965 static void *
sip_get_date_val(sip_msg_t msg,int type,int * error)966 sip_get_date_val(sip_msg_t msg, int type, int *error)
967 {
968 const _sip_header_t *header;
969 sip_hdr_value_t *val;
970
971 if (error != NULL)
972 *error = 0;
973 if (msg == NULL) {
974 if (error != NULL)
975 *error = EINVAL;
976 return (NULL);
977 }
978 header = sip_get_header(msg, SIP_DATE, NULL, error);
979 if (header == NULL) {
980 if (error != NULL)
981 *error = EINVAL;
982 return (NULL);
983 }
984
985 val = (sip_hdr_value_t *)sip_get_header_value(header, error);
986 if (val == NULL) {
987 if (error != NULL)
988 *error = EPROTO;
989 return (NULL);
990 }
991 if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD)
992 *error = EPROTO;
993 switch (type) {
994 case (D_TIME):
995 return (&(val->date_t));
996 case (D_DAY):
997 return (&(val->date_d));
998 case (D_MONTH):
999 return (&(val->date_m));
1000 case (D_YEAR):
1001 return (&(val->date_y));
1002 case (D_WKDAY):
1003 return (&(val->date_wd));
1004 case (D_TIMEZONE):
1005 return (&(val->date_tz));
1006 }
1007 if (error != NULL)
1008 *error = EINVAL;
1009 return (NULL);
1010 }
1011
1012 /*
1013 * get time value
1014 */
1015 const sip_str_t *
sip_get_date_time(sip_msg_t sip_msg,int * error)1016 sip_get_date_time(sip_msg_t sip_msg, int *error)
1017 {
1018 sip_str_t *r;
1019
1020 r = (sip_str_t *)sip_get_date_val(sip_msg, D_TIME, error);
1021 return (r);
1022 }
1023
1024 /*
1025 * get day
1026 */
1027 int
sip_get_date_day(sip_msg_t sip_msg,int * error)1028 sip_get_date_day(sip_msg_t sip_msg, int *error)
1029 {
1030 int *r = NULL;
1031
1032 r = sip_get_date_val(sip_msg, D_DAY, error);
1033 return (r == NULL ? -1 : *(int *)r);
1034 }
1035
1036 /*
1037 * get month
1038 */
1039 const sip_str_t *
sip_get_date_month(sip_msg_t sip_msg,int * error)1040 sip_get_date_month(sip_msg_t sip_msg, int *error)
1041 {
1042 sip_str_t *r;
1043
1044 r = (sip_str_t *)sip_get_date_val(sip_msg, D_MONTH, error);
1045 return (r);
1046 }
1047
1048 /*
1049 * get year
1050 */
1051 int
sip_get_date_year(sip_msg_t sip_msg,int * error)1052 sip_get_date_year(sip_msg_t sip_msg, int *error)
1053 {
1054 int *r;
1055
1056 r = (int *)sip_get_date_val(sip_msg, D_YEAR, error);
1057 return (r == NULL ? -1 : *r);
1058 }
1059
1060 /*
1061 * get day of the week
1062 */
1063 const sip_str_t *
sip_get_date_wkday(sip_msg_t sip_msg,int * error)1064 sip_get_date_wkday(sip_msg_t sip_msg, int *error)
1065 {
1066 sip_str_t *r;
1067
1068 r = (sip_str_t *)sip_get_date_val(sip_msg, D_WKDAY, error);
1069 return (r);
1070 }
1071
1072 /*
1073 * get the timezone
1074 */
1075 const sip_str_t *
sip_get_date_timezone(sip_msg_t sip_msg,int * error)1076 sip_get_date_timezone(sip_msg_t sip_msg, int *error)
1077 {
1078 sip_str_t *r;
1079
1080 r = (sip_str_t *)sip_get_date_val(sip_msg, D_TIMEZONE, error);
1081 return (r);
1082 }
1083
1084 /*
1085 * get error-info URI
1086 */
1087 const sip_str_t *
sip_get_error_info_uri(sip_header_value_t value,int * error)1088 sip_get_error_info_uri(sip_header_value_t value, int *error)
1089 {
1090 sip_str_t *r;
1091 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
1092
1093 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
1094 return (r);
1095 }
1096
1097 /*
1098 * get priv-value from privacy
1099 */
1100 const sip_str_t *
sip_get_priv_value(sip_header_value_t value,int * error)1101 sip_get_priv_value(sip_header_value_t value, int *error)
1102 {
1103 sip_str_t *r;
1104 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
1105
1106 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
1107 return (r);
1108 }
1109
1110 /*
1111 * return expires value
1112 */
1113 int
sip_get_expires(sip_msg_t sip_msg,int * error)1114 sip_get_expires(sip_msg_t sip_msg, int *error)
1115 {
1116 int *r;
1117
1118 r = (int *)sip_get_val_from_msg(sip_msg, SIP_EXPIRE, SIP_INT_VAL,
1119 B_FALSE, B_FALSE, error);
1120 if (r == NULL)
1121 return (-1);
1122 return (*r);
1123 }
1124
1125 /*
1126 * get reply-to value
1127 */
1128 const sip_str_t *
sip_get_in_reply_to(sip_header_value_t value,int * error)1129 sip_get_in_reply_to(sip_header_value_t value, int *error)
1130 {
1131 sip_str_t *r;
1132 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
1133
1134 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
1135 return (r);
1136 }
1137
1138 /*
1139 * get min-expires value
1140 */
1141 int
sip_get_min_expires(sip_msg_t sip_msg,int * error)1142 sip_get_min_expires(sip_msg_t sip_msg, int *error)
1143 {
1144 int *r;
1145
1146 r = (int *)sip_get_val_from_msg(sip_msg, SIP_MIN_EXPIRE, SIP_INT_VAL,
1147 B_FALSE, B_FALSE, error);
1148 if (r == NULL)
1149 return (-1);
1150 return (*r);
1151 }
1152
1153 /*
1154 * get mime-version
1155 */
1156 const sip_str_t *
sip_get_mime_version(sip_msg_t sip_msg,int * error)1157 sip_get_mime_version(sip_msg_t sip_msg, int *error)
1158 {
1159 sip_str_t *r;
1160
1161 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_MIME_VERSION,
1162 SIP_STR_VAL, B_FALSE, B_FALSE, error);
1163 return (r);
1164 }
1165
1166 /*
1167 * get organization value
1168 */
1169 const sip_str_t *
sip_get_org(sip_msg_t sip_msg,int * error)1170 sip_get_org(sip_msg_t sip_msg, int *error)
1171 {
1172 sip_str_t *r;
1173
1174 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_ORGANIZATION,
1175 SIP_STR_VAL, B_FALSE, B_TRUE, error);
1176 return (r);
1177 }
1178
1179 /*
1180 * get priority value
1181 */
1182 const sip_str_t *
sip_get_priority(sip_msg_t sip_msg,int * error)1183 sip_get_priority(sip_msg_t sip_msg, int *error)
1184 {
1185 sip_str_t *r;
1186
1187 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_PRIORITY,
1188 SIP_STR_VAL, B_FALSE, B_FALSE, error);
1189 return (r);
1190 }
1191
1192 /*
1193 * get display name
1194 */
1195 const sip_str_t *
sip_get_pidentity_display_name(sip_header_value_t value,int * error)1196 sip_get_pidentity_display_name(sip_header_value_t value, int *error)
1197 {
1198 sip_str_t *r;
1199 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
1200
1201 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_TRUE, error);
1202
1203 return (r);
1204 }
1205
1206 /*
1207 * get URI
1208 */
1209 const sip_str_t *
sip_get_pidenty_uri_str(sip_header_value_t value,int * error)1210 sip_get_pidenty_uri_str(sip_header_value_t value, int *error)
1211 {
1212 sip_str_t *r;
1213 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
1214
1215 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_FALSE,
1216 error);
1217
1218 return (r);
1219 }
1220
1221 /*
1222 * get display name from passerted-identity header
1223 */
1224 const sip_str_t *
sip_get_passertedid_display_name(sip_header_value_t value,int * error)1225 sip_get_passertedid_display_name(sip_header_value_t value, int *error)
1226 {
1227 return (sip_get_pidentity_display_name(value, error));
1228 }
1229
1230 /*
1231 * get URI from passerted-identity header
1232 */
1233 const sip_str_t *
sip_get_passertedid_uri_str(sip_header_value_t value,int * error)1234 sip_get_passertedid_uri_str(sip_header_value_t value, int *error)
1235 {
1236 return (sip_get_pidenty_uri_str(value, error));
1237 }
1238
1239 /*
1240 * get display name from ppreferred-identity header
1241 */
1242 const sip_str_t *
sip_get_ppreferredid_display_name(sip_header_value_t value,int * error)1243 sip_get_ppreferredid_display_name(sip_header_value_t value, int *error)
1244 {
1245 return (sip_get_pidentity_display_name(value, error));
1246 }
1247
1248 /*
1249 * get URI from ppreferred-identity header
1250 */
1251 const sip_str_t *
sip_get_ppreferredid_uri_str(sip_header_value_t value,int * error)1252 sip_get_ppreferredid_uri_str(sip_header_value_t value, int *error)
1253 {
1254 return (sip_get_pidenty_uri_str(value, error));
1255 }
1256
1257 #define SIP_RACK_RESP_NUM 1
1258 #define SIP_RACK_CSEQ_NUM 2
1259 #define SIP_RACK_METHOD 3
1260
1261 /*
1262 * Get rack information
1263 */
1264 static void *
sip_get_rack_val(sip_msg_t msg,int type,int * error)1265 sip_get_rack_val(sip_msg_t msg, int type, int *error)
1266 {
1267 const _sip_header_t *header;
1268 sip_hdr_value_t *val;
1269
1270 if (error != NULL)
1271 *error = 0;
1272
1273 if (msg == NULL) {
1274 if (error != NULL)
1275 *error = EINVAL;
1276 return (NULL);
1277 }
1278 header = sip_get_header(msg, SIP_RACK, NULL, error);
1279 if (header == NULL) {
1280 if (error != NULL)
1281 *error = EINVAL;
1282 return (NULL);
1283 }
1284 val = (sip_hdr_value_t *)sip_get_header_value(header, error);
1285 if (val == NULL) {
1286 if (error != NULL)
1287 *error = EPROTO;
1288 return (NULL);
1289 }
1290 if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD)
1291 *error = EPROTO;
1292
1293 switch (type) {
1294 case SIP_RACK_RESP_NUM:
1295 return (&(val->rack_resp));
1296 case SIP_RACK_CSEQ_NUM:
1297 return (&(val->rack_cseq));
1298 case SIP_RACK_METHOD:
1299 return (&(val->rack_method));
1300 }
1301 if (error != NULL)
1302 *error = EINVAL;
1303 return (NULL);
1304 }
1305
1306 /*
1307 * get response number for rack
1308 */
1309 int
sip_get_rack_resp_num(sip_msg_t sip_msg,int * error)1310 sip_get_rack_resp_num(sip_msg_t sip_msg, int *error)
1311 {
1312 int *r;
1313
1314 r = (int *)sip_get_rack_val(sip_msg, SIP_RACK_RESP_NUM, error);
1315
1316 return (r == NULL ? -1 : *r);
1317 }
1318
1319 /*
1320 * get sequence number for rack
1321 */
1322 int
sip_get_rack_cseq_num(sip_msg_t sip_msg,int * error)1323 sip_get_rack_cseq_num(sip_msg_t sip_msg, int *error)
1324 {
1325 int *r;
1326
1327 r = (int *)sip_get_rack_val(sip_msg, SIP_RACK_CSEQ_NUM, error);
1328
1329 return (r == NULL ? -1 : *r);
1330 }
1331
1332 /*
1333 * get method for rack
1334 */
1335 sip_method_t
sip_get_rack_method(sip_msg_t sip_msg,int * error)1336 sip_get_rack_method(sip_msg_t sip_msg, int *error)
1337 {
1338 sip_method_t *r;
1339
1340 r = (sip_method_t *)sip_get_rack_val(sip_msg, SIP_RACK_METHOD, error);
1341
1342 return (r == NULL ? -1 : *r);
1343 }
1344
1345 /*
1346 * get response number from rseq
1347 */
1348 int
sip_get_rseq_resp_num(sip_msg_t sip_msg,int * error)1349 sip_get_rseq_resp_num(sip_msg_t sip_msg, int *error)
1350 {
1351 int *r;
1352
1353 r = (int *)sip_get_val_from_msg(sip_msg, SIP_RSEQ, SIP_INT_VAL,
1354 B_FALSE, B_FALSE, error);
1355
1356 return (r == NULL ? -1 : *r);
1357 }
1358
1359 /*
1360 * get reply-to display name
1361 */
1362 const sip_str_t *
sip_get_replyto_display_name(sip_msg_t sip_msg,int * error)1363 sip_get_replyto_display_name(sip_msg_t sip_msg, int *error)
1364 {
1365 sip_str_t *r;
1366
1367 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_REPLYTO,
1368 SIP_STRS_VAL, B_TRUE, B_FALSE, error);
1369 return (r);
1370 }
1371
1372 /*
1373 * get reply-to URI
1374 */
1375 const sip_str_t *
sip_get_replyto_uri_str(sip_msg_t sip_msg,int * error)1376 sip_get_replyto_uri_str(sip_msg_t sip_msg, int *error)
1377 {
1378 sip_str_t *r;
1379
1380 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_REPLYTO,
1381 SIP_STRS_VAL, B_FALSE, B_FALSE, error);
1382
1383 return (r);
1384 }
1385
1386 /*
1387 * get require value
1388 */
1389 const sip_str_t *
sip_get_require(sip_header_value_t value,int * error)1390 sip_get_require(sip_header_value_t value, int *error)
1391 {
1392 sip_str_t *r;
1393 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
1394
1395 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
1396 return (r);
1397 }
1398
1399 /*
1400 * get retry-after time
1401 */
1402 int
sip_get_retry_after_time(sip_msg_t sip_msg,int * error)1403 sip_get_retry_after_time(sip_msg_t sip_msg, int *error)
1404 {
1405 int *t;
1406
1407 t = (int *)sip_get_val_from_msg(sip_msg, SIP_RETRY_AFTER,
1408 SIP_INTSTR_VAL, B_FALSE, B_FALSE, error);
1409 if (t == NULL)
1410 return (-1);
1411 return (*t);
1412 }
1413
1414 /*
1415 * get retry-after comments
1416 */
1417 const sip_str_t *
sip_get_retry_after_cmts(sip_msg_t sip_msg,int * error)1418 sip_get_retry_after_cmts(sip_msg_t sip_msg, int *error)
1419 {
1420 sip_str_t *r;
1421
1422 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_RETRY_AFTER,
1423 SIP_INTSTR_VAL, B_TRUE, B_FALSE, error);
1424 return (r);
1425 }
1426
1427 /*
1428 * get subject
1429 */
1430 const sip_str_t *
sip_get_subject(sip_msg_t sip_msg,int * error)1431 sip_get_subject(sip_msg_t sip_msg, int *error)
1432 {
1433 sip_str_t *r;
1434
1435 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SUBJECT, SIP_STR_VAL,
1436 B_FALSE, B_TRUE, error);
1437 return (r);
1438 }
1439
1440 /*
1441 * get supported
1442 */
1443 const sip_str_t *
sip_get_supported(sip_header_value_t value,int * error)1444 sip_get_supported(sip_header_value_t value, int *error)
1445 {
1446 sip_str_t *r;
1447 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
1448
1449 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
1450 return (r);
1451 }
1452
1453 /*
1454 * get timestamp delay
1455 */
1456 const sip_str_t *
sip_get_tstamp_delay(sip_msg_t sip_msg,int * error)1457 sip_get_tstamp_delay(sip_msg_t sip_msg, int *error)
1458 {
1459 sip_str_t *t;
1460
1461 t = sip_get_val_from_msg(sip_msg, SIP_TIMESTAMP, SIP_STRS_VAL, B_FALSE,
1462 B_FALSE, error);
1463 return (t);
1464 }
1465
1466 /*
1467 * get timestamp
1468 */
1469 const sip_str_t *
sip_get_tstamp_value(sip_msg_t sip_msg,int * error)1470 sip_get_tstamp_value(sip_msg_t sip_msg, int *error)
1471 {
1472 sip_str_t *t;
1473
1474 t = sip_get_val_from_msg(sip_msg, SIP_TIMESTAMP, SIP_STRS_VAL, B_TRUE,
1475 B_FALSE, error);
1476 return (t);
1477 }
1478
1479 /*
1480 * get unsupported value
1481 */
1482 const sip_str_t *
sip_get_unsupported(sip_header_value_t value,int * error)1483 sip_get_unsupported(sip_header_value_t value, int *error)
1484 {
1485 sip_str_t *r;
1486 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
1487
1488 r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
1489 return (r);
1490 }
1491
1492 /*
1493 * get server value from message
1494 */
1495 const sip_str_t *
sip_get_server(sip_msg_t sip_msg,int * error)1496 sip_get_server(sip_msg_t sip_msg, int *error)
1497 {
1498 sip_str_t *r;
1499
1500 r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SERVER, SIP_STR_VAL,
1501 B_FALSE, B_FALSE, error);
1502 return (r);
1503 }
1504
1505 /*
1506 * get user-agent value
1507 */
1508 const sip_str_t *
sip_get_user_agent(sip_msg_t sip_msg,int * error)1509 sip_get_user_agent(sip_msg_t sip_msg, int *error)
1510 {
1511 sip_str_t *r;
1512
1513 r = sip_get_val_from_msg(sip_msg, SIP_USER_AGENT, SIP_STR_VAL, B_FALSE,
1514 B_FALSE, error);
1515 return (r);
1516 }
1517
1518 #define W_CODE 0x05
1519 #define W_AGENT 0x06
1520 #define W_TEXT 0x07
1521
1522 /*
1523 * get warning info
1524 */
1525 static void *
sip_get_warninfo(sip_header_value_t value,int info,int * error)1526 sip_get_warninfo(sip_header_value_t value, int info, int *error)
1527 {
1528 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
1529
1530 if (error != NULL)
1531 *error = 0;
1532
1533 if (val == NULL) {
1534 if (error != NULL)
1535 *error = EINVAL;
1536 return (NULL);
1537 }
1538
1539 if (val->sip_value_state == SIP_VALUE_BAD) {
1540 *error = EPROTO;
1541 return (NULL);
1542 }
1543
1544 switch (info) {
1545 case (W_CODE):
1546 return (&(val->warn_code));
1547 case (W_AGENT):
1548 return (&(val->warn_agt));
1549 case (W_TEXT):
1550 return (&(val->warn_text));
1551 }
1552 if (error != NULL)
1553 *error = EINVAL;
1554 return (NULL);
1555 }
1556
1557 /*
1558 * get warning code
1559 */
1560 int
sip_get_warning_code(sip_header_value_t value,int * error)1561 sip_get_warning_code(sip_header_value_t value, int *error)
1562 {
1563 int *c;
1564
1565 if (error != NULL)
1566 *error = 0;
1567
1568 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
1569 if (error != NULL)
1570 *error = EINVAL;
1571 return (-1);
1572 }
1573 c = (int *)sip_get_warninfo(value, W_CODE, error);
1574 if (c == NULL)
1575 return (-1);
1576 return (*c);
1577 }
1578
1579 /*
1580 * get warning agent
1581 */
1582 const sip_str_t *
sip_get_warning_agent(sip_header_value_t value,int * error)1583 sip_get_warning_agent(sip_header_value_t value, int *error)
1584 {
1585 sip_str_t *r;
1586
1587 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
1588 if (error != NULL)
1589 *error = EINVAL;
1590 return (NULL);
1591 }
1592 r = (sip_str_t *)sip_get_warninfo(value, W_AGENT, error);
1593 return (r);
1594 }
1595
1596 /*
1597 * get warning text
1598 */
1599 const sip_str_t *
sip_get_warning_text(sip_header_value_t value,int * error)1600 sip_get_warning_text(sip_header_value_t value, int *error)
1601 {
1602 sip_str_t *r;
1603
1604 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
1605 if (error != NULL)
1606 *error = EINVAL;
1607 return (NULL);
1608 }
1609 r = (sip_str_t *)sip_get_warninfo(value, W_TEXT, error);
1610 return (r);
1611 }
1612
1613 /*
1614 * get authorization scheme
1615 */
1616 const sip_str_t *
sip_get_author_scheme(sip_msg_t sip_msg,int * error)1617 sip_get_author_scheme(sip_msg_t sip_msg, int *error)
1618 {
1619 sip_str_t *r;
1620
1621 r = sip_get_val_from_msg(sip_msg, SIP_AUTHOR, SIP_AUTH_VAL, B_FALSE,
1622 B_FALSE, error);
1623 return (r);
1624 }
1625
1626 /*
1627 * get authentication parameter
1628 */
1629 static const sip_str_t *
sip_get_auth_param(sip_msg_t msg,char * hdr_name,char * pname,int * error)1630 sip_get_auth_param(sip_msg_t msg, char *hdr_name, char *pname, int *error)
1631 {
1632 const _sip_header_t *header;
1633 sip_hdr_value_t *value;
1634 sip_param_t *param;
1635
1636 if (error != NULL)
1637 *error = 0;
1638
1639 if (msg == NULL || pname == NULL || hdr_name == NULL) {
1640 if (error != NULL)
1641 *error = EINVAL;
1642 return (NULL);
1643 }
1644
1645 header = sip_get_header(msg, hdr_name, NULL, error);
1646 if (header == NULL) {
1647 if (error != NULL)
1648 *error = EINVAL;
1649 return (NULL);
1650 }
1651
1652 value = (sip_hdr_value_t *)sip_get_header_value(header, error);
1653 if (value == NULL) {
1654 if (error != NULL)
1655 *error = EPROTO;
1656 return (NULL);
1657 }
1658
1659 param = sip_get_param_from_list(value->auth_param, pname);
1660 if (param != NULL)
1661 return (¶m->param_value);
1662 return (NULL);
1663 }
1664
1665 /*
1666 * get authentication parameter
1667 */
1668 const sip_str_t *
sip_get_author_param(sip_msg_t sip_msg,char * name,int * error)1669 sip_get_author_param(sip_msg_t sip_msg, char *name, int *error)
1670 {
1671 const sip_str_t *r;
1672
1673 r = sip_get_auth_param(sip_msg, SIP_AUTHOR, name, error);
1674 return (r);
1675 }
1676
1677 /*
1678 * get authentication info
1679 */
1680 const sip_str_t *
sip_get_authen_info(sip_header_value_t value,int * error)1681 sip_get_authen_info(sip_header_value_t value, int *error)
1682 {
1683 sip_str_t *r;
1684 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
1685
1686 if (error != NULL)
1687 *error = 0;
1688 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
1689 if (error != NULL)
1690 *error = EINVAL;
1691 return (NULL);
1692 }
1693 r = sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
1694 return (r);
1695 }
1696
1697 /*
1698 * get proxy-authentication scheme
1699 */
1700 const sip_str_t *
sip_get_proxy_authen_scheme(sip_msg_t msg,int * error)1701 sip_get_proxy_authen_scheme(sip_msg_t msg, int *error)
1702 {
1703 sip_str_t *r;
1704
1705 r = sip_get_val_from_msg(msg, SIP_PROXY_AUTHEN, SIP_AUTH_VAL, B_FALSE,
1706 B_FALSE, error);
1707 return (r);
1708 }
1709
1710 /*
1711 * get proxy authentication parameter
1712 */
1713 const sip_str_t *
sip_get_proxy_authen_param(sip_msg_t sip_msg,char * name,int * error)1714 sip_get_proxy_authen_param(sip_msg_t sip_msg, char *name, int *error)
1715 {
1716 const sip_str_t *r;
1717
1718 r = sip_get_auth_param(sip_msg, SIP_PROXY_AUTHEN, name, error);
1719 return (r);
1720 }
1721
1722 /*
1723 * get proxy-authorization scheme
1724 */
1725 const sip_str_t *
sip_get_proxy_author_scheme(sip_msg_t msg,int * error)1726 sip_get_proxy_author_scheme(sip_msg_t msg, int *error)
1727 {
1728 sip_str_t *r;
1729
1730 r = sip_get_val_from_msg(msg, SIP_PROXY_AUTHOR, SIP_AUTH_VAL, B_FALSE,
1731 B_FALSE, error);
1732 return (r);
1733 }
1734
1735 /*
1736 * get proxy-authorization parameter
1737 */
1738 const sip_str_t *
sip_get_proxy_author_param(sip_msg_t sip_msg,char * name,int * error)1739 sip_get_proxy_author_param(sip_msg_t sip_msg, char *name, int *error)
1740 {
1741 const sip_str_t *r;
1742
1743 r = sip_get_auth_param(sip_msg, SIP_PROXY_AUTHOR, name, error);
1744 return (r);
1745 }
1746
1747 /*
1748 * get proxy-require
1749 */
1750 const sip_str_t *
sip_get_proxy_require(sip_header_value_t value,int * error)1751 sip_get_proxy_require(sip_header_value_t value, int *error)
1752 {
1753 sip_str_t *r;
1754 sip_hdr_value_t *val = (sip_hdr_value_t *)value;
1755
1756 if (error != NULL)
1757 *error = 0;
1758 if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
1759 if (error != NULL)
1760 *error = EINVAL;
1761 return (NULL);
1762 }
1763 r = sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
1764 return (r);
1765 }
1766
1767 /*
1768 * get www-authentication scheme
1769 */
1770 const sip_str_t *
sip_get_www_authen_scheme(sip_msg_t msg,int * error)1771 sip_get_www_authen_scheme(sip_msg_t msg, int *error)
1772 {
1773 sip_str_t *r;
1774
1775 r = sip_get_val_from_msg(msg, SIP_WWW_AUTHEN, SIP_AUTH_VAL, B_FALSE,
1776 B_FALSE, error);
1777 return (r);
1778 }
1779
1780 /*
1781 * get www-authentication parameter
1782 */
1783 const sip_str_t *
sip_get_www_authen_param(sip_msg_t sip_msg,char * name,int * error)1784 sip_get_www_authen_param(sip_msg_t sip_msg, char *name, int *error)
1785 {
1786 const sip_str_t *r;
1787
1788 r = sip_get_auth_param(sip_msg, SIP_WWW_AUTHEN, name, error);
1789 return (r);
1790 }
1791