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