140cb5e5dSvi117747 /*
240cb5e5dSvi117747  * CDDL HEADER START
340cb5e5dSvi117747  *
440cb5e5dSvi117747  * The contents of this file are subject to the terms of the
540cb5e5dSvi117747  * Common Development and Distribution License (the "License").
640cb5e5dSvi117747  * You may not use this file except in compliance with the License.
740cb5e5dSvi117747  *
840cb5e5dSvi117747  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
940cb5e5dSvi117747  * or http://www.opensolaris.org/os/licensing.
1040cb5e5dSvi117747  * See the License for the specific language governing permissions
1140cb5e5dSvi117747  * and limitations under the License.
1240cb5e5dSvi117747  *
1340cb5e5dSvi117747  * When distributing Covered Code, include this CDDL HEADER in each
1440cb5e5dSvi117747  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1540cb5e5dSvi117747  * If applicable, add the following below this CDDL HEADER, with the
1640cb5e5dSvi117747  * fields enclosed by brackets "[]" replaced with your own identifying
1740cb5e5dSvi117747  * information: Portions Copyright [yyyy] [name of copyright owner]
1840cb5e5dSvi117747  *
1940cb5e5dSvi117747  * CDDL HEADER END
2040cb5e5dSvi117747  */
2140cb5e5dSvi117747 
2240cb5e5dSvi117747 /*
23*2c2c4183Svi117747  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2440cb5e5dSvi117747  * Use is subject to license terms.
2540cb5e5dSvi117747  */
2640cb5e5dSvi117747 
2740cb5e5dSvi117747 #pragma ident	"%Z%%M%	%I%	%E% SMI"
2840cb5e5dSvi117747 
29*2c2c4183Svi117747 #include <stdio.h>
30*2c2c4183Svi117747 #include <stdlib.h>
31*2c2c4183Svi117747 #include <strings.h>
32*2c2c4183Svi117747 #include <errno.h>
33*2c2c4183Svi117747 #include <pthread.h>
34*2c2c4183Svi117747 #include <sip.h>
35*2c2c4183Svi117747 
3640cb5e5dSvi117747 #include "sip_msg.h"
3740cb5e5dSvi117747 
3840cb5e5dSvi117747 /*
3940cb5e5dSvi117747  * Generic function to get int or string value from a header
4040cb5e5dSvi117747  */
4140cb5e5dSvi117747 static void *
4240cb5e5dSvi117747 sip_get_val_from_hdr(sip_hdr_value_t *val, int val_type, boolean_t stype,
4340cb5e5dSvi117747     int *error)
4440cb5e5dSvi117747 {
4540cb5e5dSvi117747 	if (error != NULL)
4640cb5e5dSvi117747 		*error = 0;
4740cb5e5dSvi117747 
4840cb5e5dSvi117747 	if (val == NULL || val->sip_value_state == SIP_VALUE_DELETED) {
4940cb5e5dSvi117747 		if (error != NULL)
5040cb5e5dSvi117747 			*error = EINVAL;
5140cb5e5dSvi117747 		return (NULL);
5240cb5e5dSvi117747 	}
5340cb5e5dSvi117747 
5440cb5e5dSvi117747 	if (val->sip_value_state == SIP_VALUE_BAD)
5540cb5e5dSvi117747 		*error = EPROTO;
5640cb5e5dSvi117747 
5740cb5e5dSvi117747 	switch (val_type) {
5840cb5e5dSvi117747 		case (SIP_INT_VAL):
5940cb5e5dSvi117747 			return (&(val->int_val));
6040cb5e5dSvi117747 		case (SIP_STR_VAL):
6140cb5e5dSvi117747 			return (&(val->str_val));
6240cb5e5dSvi117747 		case (SIP_STRS_VAL):
6340cb5e5dSvi117747 			if (stype == B_TRUE) {
6440cb5e5dSvi117747 				if (val->strs_val.s1.sip_str_ptr != NULL)
6540cb5e5dSvi117747 					return (&(val->strs_val.s1));
6640cb5e5dSvi117747 				return (NULL);
6740cb5e5dSvi117747 			}
6840cb5e5dSvi117747 			if (val->strs_val.s2.sip_str_ptr != NULL)
6940cb5e5dSvi117747 				return (&(val->strs_val.s2));
7040cb5e5dSvi117747 			return (NULL);
7140cb5e5dSvi117747 		case (SIP_INTSTR_VAL):
7240cb5e5dSvi117747 			if (stype == B_TRUE) {
7340cb5e5dSvi117747 				if (val->intstr_str.sip_str_ptr != NULL)
7440cb5e5dSvi117747 					return (&(val->intstr_str));
7540cb5e5dSvi117747 				else
7640cb5e5dSvi117747 					return (NULL);
7740cb5e5dSvi117747 			}
7840cb5e5dSvi117747 			return (&(val->intstr_int));
7940cb5e5dSvi117747 		case (SIP_AUTH_VAL):
8040cb5e5dSvi117747 			return (&(val->auth_val));
8140cb5e5dSvi117747 	}
8240cb5e5dSvi117747 	if (error != NULL && *error == 0)
8340cb5e5dSvi117747 		*error = EINVAL;
8440cb5e5dSvi117747 	return (NULL);
8540cb5e5dSvi117747 }
8640cb5e5dSvi117747 
8740cb5e5dSvi117747 /*
8840cb5e5dSvi117747  * Generic function to get value from a header given the value type and
8940cb5e5dSvi117747  * the string info (for multi-string values).
9040cb5e5dSvi117747  */
9140cb5e5dSvi117747 static void *
9240cb5e5dSvi117747 sip_get_val_from_msg(sip_msg_t msg, char *hdr_name, int val_type,
9340cb5e5dSvi117747     boolean_t stype, boolean_t empty_val, int *error)
9440cb5e5dSvi117747 {
9540cb5e5dSvi117747 	const _sip_header_t	*header;
9640cb5e5dSvi117747 	sip_hdr_value_t		*value;
9740cb5e5dSvi117747 
9840cb5e5dSvi117747 	if (error != NULL)
9940cb5e5dSvi117747 		*error = 0;
10040cb5e5dSvi117747 	if (msg == NULL) {
10140cb5e5dSvi117747 		if (error != NULL)
10240cb5e5dSvi117747 			*error = EINVAL;
10340cb5e5dSvi117747 		return (NULL);
10440cb5e5dSvi117747 	}
10540cb5e5dSvi117747 
10640cb5e5dSvi117747 	header = sip_get_header(msg, hdr_name, NULL, error);
10740cb5e5dSvi117747 	if (header == NULL) {
10840cb5e5dSvi117747 		if (error != NULL)
10940cb5e5dSvi117747 			*error = EINVAL;
11040cb5e5dSvi117747 		return (NULL);
11140cb5e5dSvi117747 	}
11240cb5e5dSvi117747 
11340cb5e5dSvi117747 	value = (sip_hdr_value_t *)sip_get_header_value(header, error);
11440cb5e5dSvi117747 	if (value == NULL) {
11540cb5e5dSvi117747 		if (error != NULL && empty_val == B_FALSE)
11640cb5e5dSvi117747 			*error = EPROTO;
11740cb5e5dSvi117747 		return (NULL);
11840cb5e5dSvi117747 	}
11940cb5e5dSvi117747 	return (sip_get_val_from_hdr(value, val_type, stype, error));
12040cb5e5dSvi117747 }
12140cb5e5dSvi117747 
12240cb5e5dSvi117747 /*
12340cb5e5dSvi117747  * Get the URI from the value
12440cb5e5dSvi117747  */
12540cb5e5dSvi117747 const sip_str_t *
12640cb5e5dSvi117747 sip_get_cftruri_from_val(sip_header_value_t value, int *error)
12740cb5e5dSvi117747 {
12840cb5e5dSvi117747 	sip_hdr_value_t	*cftrvalue;
12940cb5e5dSvi117747 
13040cb5e5dSvi117747 	if (error != NULL)
13140cb5e5dSvi117747 		*error = 0;
13240cb5e5dSvi117747 
13340cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
13440cb5e5dSvi117747 		if (error != NULL)
13540cb5e5dSvi117747 			*error = EINVAL;
13640cb5e5dSvi117747 		return (NULL);
13740cb5e5dSvi117747 	}
13840cb5e5dSvi117747 	cftrvalue = (sip_hdr_value_t *)value;
13940cb5e5dSvi117747 	/*
14040cb5e5dSvi117747 	 * If the value is BAD, update error to reflect it.
14140cb5e5dSvi117747 	 */
14240cb5e5dSvi117747 	if (error != NULL && value->value_state == SIP_VALUE_BAD)
14340cb5e5dSvi117747 		*error = EPROTO;
14440cb5e5dSvi117747 	return (&cftrvalue->cftr_uri);
14540cb5e5dSvi117747 }
14640cb5e5dSvi117747 
14740cb5e5dSvi117747 /*
14840cb5e5dSvi117747  * Get display name from the value
14940cb5e5dSvi117747  */
15040cb5e5dSvi117747 const sip_str_t *
15140cb5e5dSvi117747 sip_get_cftrname_from_val(sip_header_value_t value, int *error)
15240cb5e5dSvi117747 {
15340cb5e5dSvi117747 	sip_hdr_value_t *cftrvalue;
15440cb5e5dSvi117747 
15540cb5e5dSvi117747 	if (error != NULL)
15640cb5e5dSvi117747 		*error = 0;
15740cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
15840cb5e5dSvi117747 		if (error != NULL)
15940cb5e5dSvi117747 			*error = EINVAL;
16040cb5e5dSvi117747 		return (NULL);
16140cb5e5dSvi117747 	}
16240cb5e5dSvi117747 	cftrvalue = (sip_hdr_value_t *)value;
16340cb5e5dSvi117747 	/*
16440cb5e5dSvi117747 	 * If the value is BAD, update error to reflect it.
16540cb5e5dSvi117747 	 */
16640cb5e5dSvi117747 	if (error != NULL && value->value_state == SIP_VALUE_BAD)
16740cb5e5dSvi117747 		*error = EPROTO;
16840cb5e5dSvi117747 	return (cftrvalue->cftr_name);
16940cb5e5dSvi117747 }
17040cb5e5dSvi117747 
17140cb5e5dSvi117747 /*
17240cb5e5dSvi117747  * Contact header can have more than one value
17340cb5e5dSvi117747  * so we require a value to be passed in to get a value.
17440cb5e5dSvi117747  */
17540cb5e5dSvi117747 const sip_str_t *
17640cb5e5dSvi117747 sip_get_contact_uri_str(sip_header_value_t value, int *error)
17740cb5e5dSvi117747 {
17840cb5e5dSvi117747 	return (sip_get_cftruri_from_val(value, error));
17940cb5e5dSvi117747 }
18040cb5e5dSvi117747 
18140cb5e5dSvi117747 /*
18240cb5e5dSvi117747  * Contact header can have more than one value
18340cb5e5dSvi117747  * so we require a value to be passed in to get a value.
18440cb5e5dSvi117747  */
18540cb5e5dSvi117747 const sip_str_t *
18640cb5e5dSvi117747 sip_get_contact_display_name(sip_header_value_t value, int *error)
18740cb5e5dSvi117747 {
18840cb5e5dSvi117747 	return (sip_get_cftrname_from_val(value, error));
18940cb5e5dSvi117747 }
19040cb5e5dSvi117747 
19140cb5e5dSvi117747 /*
19240cb5e5dSvi117747  * Route header can have more than one value
19340cb5e5dSvi117747  * so we require a value to be passed in to get a value.
19440cb5e5dSvi117747  */
19540cb5e5dSvi117747 const sip_str_t *
19640cb5e5dSvi117747 sip_get_route_uri_str(sip_header_value_t value, int *error)
19740cb5e5dSvi117747 {
19840cb5e5dSvi117747 	return (sip_get_cftruri_from_val(value, error));
19940cb5e5dSvi117747 }
20040cb5e5dSvi117747 
20140cb5e5dSvi117747 /*
20240cb5e5dSvi117747  * Route header can have more than one value
20340cb5e5dSvi117747  * so we require a value to be passed in to get a value.
20440cb5e5dSvi117747  */
20540cb5e5dSvi117747 const sip_str_t *
20640cb5e5dSvi117747 sip_get_route_display_name(sip_header_value_t value, int *error)
20740cb5e5dSvi117747 {
20840cb5e5dSvi117747 	return (sip_get_cftrname_from_val(value, error));
20940cb5e5dSvi117747 }
21040cb5e5dSvi117747 
21140cb5e5dSvi117747 /*
21240cb5e5dSvi117747  * Get URI from the SIP message
21340cb5e5dSvi117747  */
21440cb5e5dSvi117747 const sip_str_t *
21540cb5e5dSvi117747 sip_get_cftruri_from_msg(sip_msg_t sip_msg, int *error, char *hdrname)
21640cb5e5dSvi117747 {
21740cb5e5dSvi117747 	const sip_hdr_value_t	*value;
21840cb5e5dSvi117747 	const struct sip_header	*header;
21940cb5e5dSvi117747 
22040cb5e5dSvi117747 	if (error != NULL)
22140cb5e5dSvi117747 		*error = 0;
22240cb5e5dSvi117747 	if (sip_msg == NULL) {
22340cb5e5dSvi117747 		if (error != NULL)
22440cb5e5dSvi117747 			*error = EINVAL;
22540cb5e5dSvi117747 		return (NULL);
22640cb5e5dSvi117747 	}
22740cb5e5dSvi117747 
22840cb5e5dSvi117747 	header = sip_get_header(sip_msg, hdrname, NULL, error);
22940cb5e5dSvi117747 	if (header == NULL) {
23040cb5e5dSvi117747 		if (error != NULL)
23140cb5e5dSvi117747 			*error = EINVAL;
23240cb5e5dSvi117747 		return (NULL);
23340cb5e5dSvi117747 	}
23440cb5e5dSvi117747 
23540cb5e5dSvi117747 	value = (sip_hdr_value_t *)sip_get_header_value(header, error);
23640cb5e5dSvi117747 	if (value == NULL) {
23740cb5e5dSvi117747 		if (error != NULL)
23840cb5e5dSvi117747 			*error = EPROTO;
23940cb5e5dSvi117747 		return (NULL);
24040cb5e5dSvi117747 	}
24140cb5e5dSvi117747 	/*
24240cb5e5dSvi117747 	 * If the value is BAD, update error to reflect it.
24340cb5e5dSvi117747 	 */
24440cb5e5dSvi117747 	if (error != NULL && value->sip_value_state == SIP_VALUE_BAD)
24540cb5e5dSvi117747 		*error = EPROTO;
24640cb5e5dSvi117747 	return (&value->cftr_uri);
24740cb5e5dSvi117747 }
24840cb5e5dSvi117747 
24940cb5e5dSvi117747 /*
25040cb5e5dSvi117747  * Get display name from the SIP message
25140cb5e5dSvi117747  */
25240cb5e5dSvi117747 const sip_str_t *
25340cb5e5dSvi117747 sip_get_cftrname_from_msg(sip_msg_t sip_msg, int *error, char *hdrname)
25440cb5e5dSvi117747 {
25540cb5e5dSvi117747 	const sip_hdr_value_t		*value;
25640cb5e5dSvi117747 	const struct  sip_header	*header;
25740cb5e5dSvi117747 
25840cb5e5dSvi117747 	if (error != NULL)
25940cb5e5dSvi117747 		*error = 0;
26040cb5e5dSvi117747 	if (sip_msg == NULL) {
26140cb5e5dSvi117747 		if (error != NULL)
26240cb5e5dSvi117747 			*error = EINVAL;
26340cb5e5dSvi117747 		return (NULL);
26440cb5e5dSvi117747 	}
26540cb5e5dSvi117747 	header = sip_get_header(sip_msg, hdrname, NULL, error);
26640cb5e5dSvi117747 	if (header == NULL) {
26740cb5e5dSvi117747 		if (error != NULL)
26840cb5e5dSvi117747 			*error = EINVAL;
26940cb5e5dSvi117747 		return (NULL);
27040cb5e5dSvi117747 	}
27140cb5e5dSvi117747 
27240cb5e5dSvi117747 	value = (sip_hdr_value_t *)sip_get_header_value(header, error);
27340cb5e5dSvi117747 	if (value == NULL) {
27440cb5e5dSvi117747 		if (error != NULL)
27540cb5e5dSvi117747 			*error = EPROTO;
27640cb5e5dSvi117747 		return (NULL);
27740cb5e5dSvi117747 	}
27840cb5e5dSvi117747 	/*
27940cb5e5dSvi117747 	 * If the value is BAD, update error to reflect it.
28040cb5e5dSvi117747 	 */
28140cb5e5dSvi117747 	if (error != NULL && value->sip_value_state == SIP_VALUE_BAD)
28240cb5e5dSvi117747 		*error = EPROTO;
28340cb5e5dSvi117747 	return (value->cftr_name);
28440cb5e5dSvi117747 }
28540cb5e5dSvi117747 
28640cb5e5dSvi117747 /*
28740cb5e5dSvi117747  * Get FROM URI
28840cb5e5dSvi117747  */
28940cb5e5dSvi117747 const sip_str_t *
29040cb5e5dSvi117747 sip_get_from_uri_str(sip_msg_t sip_msg, int *error)
29140cb5e5dSvi117747 {
29240cb5e5dSvi117747 	return (sip_get_cftruri_from_msg(sip_msg, error, SIP_FROM));
29340cb5e5dSvi117747 }
29440cb5e5dSvi117747 
29540cb5e5dSvi117747 /*
29640cb5e5dSvi117747  * Get FROM display name
29740cb5e5dSvi117747  */
29840cb5e5dSvi117747 const sip_str_t *
29940cb5e5dSvi117747 sip_get_from_display_name(sip_msg_t sip_msg, int *error)
30040cb5e5dSvi117747 {
30140cb5e5dSvi117747 	return (sip_get_cftrname_from_msg(sip_msg, error, SIP_FROM));
30240cb5e5dSvi117747 }
30340cb5e5dSvi117747 
30440cb5e5dSvi117747 /*
30540cb5e5dSvi117747  * Return the FROM tag
30640cb5e5dSvi117747  */
30740cb5e5dSvi117747 const sip_str_t *
30840cb5e5dSvi117747 sip_get_from_tag(sip_msg_t sip_msg, int *error)
30940cb5e5dSvi117747 {
31040cb5e5dSvi117747 	const sip_hdr_value_t	*value;
31140cb5e5dSvi117747 	const struct sip_header	*header;
31240cb5e5dSvi117747 
31340cb5e5dSvi117747 	if (error != NULL)
31440cb5e5dSvi117747 		*error = 0;
31540cb5e5dSvi117747 	if (sip_msg == NULL) {
31640cb5e5dSvi117747 		if (error != NULL)
31740cb5e5dSvi117747 			*error = EINVAL;
31840cb5e5dSvi117747 		return (NULL);
31940cb5e5dSvi117747 	}
32040cb5e5dSvi117747 	header = sip_get_header(sip_msg, SIP_FROM, NULL, error);
32140cb5e5dSvi117747 	if (header == NULL) {
32240cb5e5dSvi117747 		if (error != NULL)
32340cb5e5dSvi117747 			*error = EINVAL;
32440cb5e5dSvi117747 		return (NULL);
32540cb5e5dSvi117747 	}
32640cb5e5dSvi117747 
32740cb5e5dSvi117747 	value = (sip_hdr_value_t *)sip_get_header_value(header, error);
32840cb5e5dSvi117747 	if (value == NULL) {
32940cb5e5dSvi117747 		if (error != NULL)
33040cb5e5dSvi117747 			*error = EPROTO;
33140cb5e5dSvi117747 		return (NULL);
33240cb5e5dSvi117747 	}
33340cb5e5dSvi117747 	/*
33440cb5e5dSvi117747 	 * If the value is BAD, update error to reflect it.
33540cb5e5dSvi117747 	 */
33640cb5e5dSvi117747 	if (error != NULL && value->sip_value_state == SIP_VALUE_BAD)
33740cb5e5dSvi117747 		*error = EPROTO;
33840cb5e5dSvi117747 	return (sip_get_param_value((sip_header_value_t)value, "tag", error));
33940cb5e5dSvi117747 }
34040cb5e5dSvi117747 
34140cb5e5dSvi117747 /*
34240cb5e5dSvi117747  * Get TO URI
34340cb5e5dSvi117747  */
34440cb5e5dSvi117747 const sip_str_t *
34540cb5e5dSvi117747 sip_get_to_uri_str(sip_msg_t sip_msg, int *error)
34640cb5e5dSvi117747 {
34740cb5e5dSvi117747 	return (sip_get_cftruri_from_msg(sip_msg, error, SIP_TO));
34840cb5e5dSvi117747 }
34940cb5e5dSvi117747 
35040cb5e5dSvi117747 /*
35140cb5e5dSvi117747  * Get TO display name
35240cb5e5dSvi117747  */
35340cb5e5dSvi117747 const sip_str_t *
35440cb5e5dSvi117747 sip_get_to_display_name(sip_msg_t sip_msg, int *error)
35540cb5e5dSvi117747 {
35640cb5e5dSvi117747 	return (sip_get_cftrname_from_msg(sip_msg, error, SIP_TO));
35740cb5e5dSvi117747 }
35840cb5e5dSvi117747 
35940cb5e5dSvi117747 /*
36040cb5e5dSvi117747  * Get TO tag
36140cb5e5dSvi117747  */
36240cb5e5dSvi117747 const sip_str_t *
36340cb5e5dSvi117747 sip_get_to_tag(sip_msg_t sip_msg, int *error)
36440cb5e5dSvi117747 {
36540cb5e5dSvi117747 	const sip_hdr_value_t	*value;
36640cb5e5dSvi117747 	const struct sip_header	*header;
36740cb5e5dSvi117747 
36840cb5e5dSvi117747 	if (error != NULL)
36940cb5e5dSvi117747 		*error = 0;
37040cb5e5dSvi117747 	if (sip_msg == NULL) {
37140cb5e5dSvi117747 		if (error != NULL)
37240cb5e5dSvi117747 			*error = EINVAL;
37340cb5e5dSvi117747 		return (NULL);
37440cb5e5dSvi117747 	}
37540cb5e5dSvi117747 	header = sip_get_header(sip_msg, SIP_TO, NULL, error);
37640cb5e5dSvi117747 	if (header == NULL) {
37740cb5e5dSvi117747 		if (error != NULL)
37840cb5e5dSvi117747 			*error = EINVAL;
37940cb5e5dSvi117747 		return (NULL);
38040cb5e5dSvi117747 	}
38140cb5e5dSvi117747 
38240cb5e5dSvi117747 	value = (sip_hdr_value_t *)sip_get_header_value(header, error);
38340cb5e5dSvi117747 	if (value == NULL) {
38440cb5e5dSvi117747 		if (error != NULL)
38540cb5e5dSvi117747 			*error = EPROTO;
38640cb5e5dSvi117747 		return (NULL);
38740cb5e5dSvi117747 	}
38840cb5e5dSvi117747 	/*
38940cb5e5dSvi117747 	 * If the value is BAD, update error to reflect it.
39040cb5e5dSvi117747 	 */
39140cb5e5dSvi117747 	if (error != NULL && value->sip_value_state == SIP_VALUE_BAD)
39240cb5e5dSvi117747 		*error = EPROTO;
39340cb5e5dSvi117747 	return (sip_get_param_value((sip_header_value_t)value, "tag", error));
39440cb5e5dSvi117747 }
39540cb5e5dSvi117747 
39640cb5e5dSvi117747 /*
39740cb5e5dSvi117747  * Return the Call-Id
39840cb5e5dSvi117747  */
39940cb5e5dSvi117747 const sip_str_t *
40040cb5e5dSvi117747 sip_get_callid(sip_msg_t sip_msg, int *error)
40140cb5e5dSvi117747 {
40240cb5e5dSvi117747 	sip_str_t	*r;
40340cb5e5dSvi117747 
40440cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CALL_ID, SIP_STR_VAL,
40540cb5e5dSvi117747 	    B_FALSE, B_TRUE, error);
40640cb5e5dSvi117747 	return (r);
40740cb5e5dSvi117747 }
40840cb5e5dSvi117747 
40940cb5e5dSvi117747 #define	SIP_CSEQ_NUM	1
41040cb5e5dSvi117747 #define	SIP_CSEQ_METHOD	2
41140cb5e5dSvi117747 
41240cb5e5dSvi117747 /*
41340cb5e5dSvi117747  * Get number/method from the CSEQ header
41440cb5e5dSvi117747  */
41540cb5e5dSvi117747 static void *
41640cb5e5dSvi117747 sip_get_cseq_val(sip_msg_t msg, int type, int *error)
41740cb5e5dSvi117747 {
41840cb5e5dSvi117747 	const _sip_header_t	*header;
41940cb5e5dSvi117747 	sip_hdr_value_t		*val;
42040cb5e5dSvi117747 
42140cb5e5dSvi117747 	if (error != NULL)
42240cb5e5dSvi117747 		*error = 0;
42340cb5e5dSvi117747 
42440cb5e5dSvi117747 	if (msg == NULL)  {
42540cb5e5dSvi117747 		if (error != NULL)
42640cb5e5dSvi117747 			*error = EINVAL;
42740cb5e5dSvi117747 		return (NULL);
42840cb5e5dSvi117747 	}
42940cb5e5dSvi117747 	header = sip_get_header(msg, SIP_CSEQ, NULL, error);
43040cb5e5dSvi117747 	if (header == NULL) {
43140cb5e5dSvi117747 		if (error != NULL)
43240cb5e5dSvi117747 			*error = EINVAL;
43340cb5e5dSvi117747 		return (NULL);
43440cb5e5dSvi117747 	}
43540cb5e5dSvi117747 	val = (sip_hdr_value_t *)sip_get_header_value(header, error);
43640cb5e5dSvi117747 	if (val == NULL) {
43740cb5e5dSvi117747 		if (error != NULL)
43840cb5e5dSvi117747 			*error = EPROTO;
43940cb5e5dSvi117747 		return (NULL);
44040cb5e5dSvi117747 	}
44140cb5e5dSvi117747 	if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD)
44240cb5e5dSvi117747 		*error = EPROTO;
44340cb5e5dSvi117747 
44440cb5e5dSvi117747 	switch (type) {
44540cb5e5dSvi117747 		case SIP_CSEQ_NUM:
44640cb5e5dSvi117747 			return (&(val->cseq_num));
44740cb5e5dSvi117747 		case SIP_CSEQ_METHOD:
44840cb5e5dSvi117747 			return (&(val->cseq_method));
44940cb5e5dSvi117747 	}
45040cb5e5dSvi117747 	if (error != NULL)
45140cb5e5dSvi117747 		*error = EINVAL;
45240cb5e5dSvi117747 	return (NULL);
45340cb5e5dSvi117747 }
45440cb5e5dSvi117747 
45540cb5e5dSvi117747 /*
45640cb5e5dSvi117747  * Get CSEQ number
45740cb5e5dSvi117747  */
45840cb5e5dSvi117747 int
45940cb5e5dSvi117747 sip_get_callseq_num(sip_msg_t sip_msg, int *error)
46040cb5e5dSvi117747 {
46140cb5e5dSvi117747 	int	*r;
46240cb5e5dSvi117747 
46340cb5e5dSvi117747 	r = (int *)sip_get_cseq_val(sip_msg, SIP_CSEQ_NUM, error);
46440cb5e5dSvi117747 	return (r == NULL ? -1 : *r);
46540cb5e5dSvi117747 }
46640cb5e5dSvi117747 
46740cb5e5dSvi117747 /*
46840cb5e5dSvi117747  * Get CSEQ method
46940cb5e5dSvi117747  */
47040cb5e5dSvi117747 sip_method_t
47140cb5e5dSvi117747 sip_get_callseq_method(sip_msg_t sip_msg, int *error)
47240cb5e5dSvi117747 {
47340cb5e5dSvi117747 	sip_method_t	*r;
47440cb5e5dSvi117747 
47540cb5e5dSvi117747 	r = (sip_method_t *)sip_get_cseq_val(sip_msg, SIP_CSEQ_METHOD, error);
47640cb5e5dSvi117747 	return (r == NULL ? -1 : *r);
47740cb5e5dSvi117747 }
47840cb5e5dSvi117747 
47940cb5e5dSvi117747 /*
48040cb5e5dSvi117747  * Via header can have more than one value
48140cb5e5dSvi117747  * so we require a value to be passed in.
48240cb5e5dSvi117747  */
48340cb5e5dSvi117747 const sip_str_t *
48440cb5e5dSvi117747 sip_get_via_sent_by_host(sip_header_value_t value, int *error)
48540cb5e5dSvi117747 {
48640cb5e5dSvi117747 	sip_hdr_value_t	*via_value;
48740cb5e5dSvi117747 
48840cb5e5dSvi117747 	if (error != NULL)
48940cb5e5dSvi117747 		*error = 0;
49040cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
49140cb5e5dSvi117747 		if (error != NULL)
49240cb5e5dSvi117747 			*error = EINVAL;
49340cb5e5dSvi117747 		return (NULL);
49440cb5e5dSvi117747 	}
49540cb5e5dSvi117747 	via_value = (sip_hdr_value_t *)value;
49640cb5e5dSvi117747 	if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL)
49740cb5e5dSvi117747 		*error = EPROTO;
49840cb5e5dSvi117747 	return (&via_value->via_sent_by_host);
49940cb5e5dSvi117747 }
50040cb5e5dSvi117747 
50140cb5e5dSvi117747 /*
50240cb5e5dSvi117747  * Via header can have more than one value
50340cb5e5dSvi117747  * so we require a value to be passed in.
50440cb5e5dSvi117747  */
50540cb5e5dSvi117747 int
50640cb5e5dSvi117747 sip_get_via_sent_by_port(sip_header_value_t value, int *error)
50740cb5e5dSvi117747 {
50840cb5e5dSvi117747 	sip_hdr_value_t	*via_value;
50940cb5e5dSvi117747 
51040cb5e5dSvi117747 	if (error != NULL)
51140cb5e5dSvi117747 		*error = 0;
51240cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
51340cb5e5dSvi117747 		if (error != NULL)
51440cb5e5dSvi117747 			*error = EINVAL;
51540cb5e5dSvi117747 		return (-1);
51640cb5e5dSvi117747 	}
51740cb5e5dSvi117747 	via_value = (sip_hdr_value_t *)value;
51840cb5e5dSvi117747 	if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL)
51940cb5e5dSvi117747 		*error = EPROTO;
52040cb5e5dSvi117747 	return (via_value->via_sent_by_port);
52140cb5e5dSvi117747 }
52240cb5e5dSvi117747 
52340cb5e5dSvi117747 /*
52440cb5e5dSvi117747  * Return the protocol version from the VIA value
52540cb5e5dSvi117747  */
52640cb5e5dSvi117747 const sip_str_t *
52740cb5e5dSvi117747 sip_get_via_sent_protocol_version(sip_header_value_t value, int *error)
52840cb5e5dSvi117747 {
52940cb5e5dSvi117747 	sip_hdr_value_t *via_value;
53040cb5e5dSvi117747 
53140cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
53240cb5e5dSvi117747 		if (error != NULL)
53340cb5e5dSvi117747 			*error = EINVAL;
53440cb5e5dSvi117747 		return (NULL);
53540cb5e5dSvi117747 	}
53640cb5e5dSvi117747 	via_value = (sip_hdr_value_t *)value;
53740cb5e5dSvi117747 	if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL)
53840cb5e5dSvi117747 		*error = EPROTO;
53940cb5e5dSvi117747 	return (&via_value->via_protocol_vers);
54040cb5e5dSvi117747 }
54140cb5e5dSvi117747 
54240cb5e5dSvi117747 /*
54340cb5e5dSvi117747  * Return the protocol name
54440cb5e5dSvi117747  */
54540cb5e5dSvi117747 const sip_str_t *
54640cb5e5dSvi117747 sip_get_via_sent_protocol_name(sip_header_value_t value, int *error)
54740cb5e5dSvi117747 {
54840cb5e5dSvi117747 	sip_hdr_value_t	*via_value;
54940cb5e5dSvi117747 
55040cb5e5dSvi117747 	if (error != NULL)
55140cb5e5dSvi117747 		*error = 0;
55240cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
55340cb5e5dSvi117747 		if (error != NULL)
55440cb5e5dSvi117747 			*error = EINVAL;
55540cb5e5dSvi117747 		return (NULL);
55640cb5e5dSvi117747 	}
55740cb5e5dSvi117747 	via_value = (sip_hdr_value_t *)value;
55840cb5e5dSvi117747 	if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL)
55940cb5e5dSvi117747 		*error = EPROTO;
56040cb5e5dSvi117747 	return (&via_value->via_protocol_name);
56140cb5e5dSvi117747 }
56240cb5e5dSvi117747 
56340cb5e5dSvi117747 /*
56440cb5e5dSvi117747  * Return the transport from the VIA value
56540cb5e5dSvi117747  */
56640cb5e5dSvi117747 const sip_str_t *
56740cb5e5dSvi117747 sip_get_via_sent_transport(sip_header_value_t value, int *error)
56840cb5e5dSvi117747 {
56940cb5e5dSvi117747 	sip_hdr_value_t	*via_value;
57040cb5e5dSvi117747 
57140cb5e5dSvi117747 	if (error != NULL)
57240cb5e5dSvi117747 		*error = 0;
57340cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
57440cb5e5dSvi117747 		if (error != NULL)
57540cb5e5dSvi117747 			*error = EINVAL;
57640cb5e5dSvi117747 		return (NULL);
57740cb5e5dSvi117747 	}
57840cb5e5dSvi117747 	via_value = (sip_hdr_value_t *)value;
57940cb5e5dSvi117747 	if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL)
58040cb5e5dSvi117747 		*error = EPROTO;
58140cb5e5dSvi117747 	return (&via_value->via_protocol_transport);
58240cb5e5dSvi117747 }
58340cb5e5dSvi117747 
58440cb5e5dSvi117747 /*
58540cb5e5dSvi117747  * get the branch id from the topmost VIA header
58640cb5e5dSvi117747  */
58740cb5e5dSvi117747 char *
58840cb5e5dSvi117747 sip_get_branchid(sip_msg_t sip_msg, int *error)
58940cb5e5dSvi117747 {
59040cb5e5dSvi117747 	_sip_header_t		*header;
59140cb5e5dSvi117747 	sip_parsed_header_t	*parsed_header;
59240cb5e5dSvi117747 	sip_hdr_value_t		*via_value;
59340cb5e5dSvi117747 	const sip_str_t		*param_value;
59440cb5e5dSvi117747 	char			*bid;
59540cb5e5dSvi117747 	_sip_msg_t		*_sip_msg;
59640cb5e5dSvi117747 
59740cb5e5dSvi117747 	if (error != NULL)
59840cb5e5dSvi117747 		*error = 0;
59940cb5e5dSvi117747 
60040cb5e5dSvi117747 	if (sip_msg == NULL) {
60140cb5e5dSvi117747 		if (error != NULL)
60240cb5e5dSvi117747 			*error = EINVAL;
60340cb5e5dSvi117747 		return (NULL);
60440cb5e5dSvi117747 	}
60540cb5e5dSvi117747 
60640cb5e5dSvi117747 	_sip_msg = (_sip_msg_t *)sip_msg;
60740cb5e5dSvi117747 
60840cb5e5dSvi117747 	(void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex);
60940cb5e5dSvi117747 	header = sip_search_for_header(_sip_msg, SIP_VIA, NULL);
61040cb5e5dSvi117747 	if (header == NULL) {
61140cb5e5dSvi117747 		if (error != NULL)
61240cb5e5dSvi117747 			*error = EINVAL;
61340cb5e5dSvi117747 		(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
61440cb5e5dSvi117747 		return (NULL);
61540cb5e5dSvi117747 	}
61640cb5e5dSvi117747 	if (sip_parse_via_header(header, &parsed_header) != 0) {
61740cb5e5dSvi117747 		if (error != NULL)
61840cb5e5dSvi117747 			*error = EPROTO;
61940cb5e5dSvi117747 		(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
62040cb5e5dSvi117747 		return (NULL);
62140cb5e5dSvi117747 	}
62240cb5e5dSvi117747 	if (parsed_header == NULL) {
62340cb5e5dSvi117747 		if (error != NULL)
62440cb5e5dSvi117747 			*error = EPROTO;
62540cb5e5dSvi117747 		(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
62640cb5e5dSvi117747 		return (NULL);
62740cb5e5dSvi117747 	}
62840cb5e5dSvi117747 	via_value = (sip_hdr_value_t *)parsed_header->value;
62940cb5e5dSvi117747 	if (via_value == NULL || via_value->sip_value_state == SIP_VALUE_BAD) {
63040cb5e5dSvi117747 		if (error != NULL)
63140cb5e5dSvi117747 			*error = EPROTO;
63240cb5e5dSvi117747 		(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
63340cb5e5dSvi117747 		return (NULL);
63440cb5e5dSvi117747 	}
63540cb5e5dSvi117747 	param_value = sip_get_param_value((sip_header_value_t)via_value,
63640cb5e5dSvi117747 	    "branch", error);
63740cb5e5dSvi117747 
63840cb5e5dSvi117747 	if (param_value == NULL) {
63940cb5e5dSvi117747 		if (error != NULL)
64040cb5e5dSvi117747 			*error = EINVAL;
64140cb5e5dSvi117747 		(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
64240cb5e5dSvi117747 		return (NULL);
64340cb5e5dSvi117747 	}
64440cb5e5dSvi117747 
64540cb5e5dSvi117747 	bid = (char *)malloc(param_value->sip_str_len + 1);
64640cb5e5dSvi117747 	if (bid == NULL) {
64740cb5e5dSvi117747 		if (error != NULL)
64840cb5e5dSvi117747 			*error = ENOMEM;
64940cb5e5dSvi117747 		(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
65040cb5e5dSvi117747 		return (NULL);
65140cb5e5dSvi117747 	}
65240cb5e5dSvi117747 	(void) strncpy(bid, param_value->sip_str_ptr,
65340cb5e5dSvi117747 	    param_value->sip_str_len);
65440cb5e5dSvi117747 	bid[param_value->sip_str_len] = '\0';
65540cb5e5dSvi117747 	(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
65640cb5e5dSvi117747 	return (bid);
65740cb5e5dSvi117747 }
65840cb5e5dSvi117747 
65940cb5e5dSvi117747 /*
66040cb5e5dSvi117747  * adds branchid to the topmost VIA header, if a branchid already exists,
66140cb5e5dSvi117747  * returns error.
66240cb5e5dSvi117747  */
66340cb5e5dSvi117747 int
66440cb5e5dSvi117747 sip_add_branchid_to_via(sip_msg_t sip_msg, char *branchid)
66540cb5e5dSvi117747 {
66640cb5e5dSvi117747 	int		err = 0;
66740cb5e5dSvi117747 	char		*param;
66840cb5e5dSvi117747 	int		plen;
66940cb5e5dSvi117747 	sip_header_t	via_hdr;
67040cb5e5dSvi117747 	_sip_msg_t	*_sip_msg;
67140cb5e5dSvi117747 
67240cb5e5dSvi117747 	if (sip_msg == NULL)
67340cb5e5dSvi117747 		return (EINVAL);
67440cb5e5dSvi117747 	/*
67540cb5e5dSvi117747 	 * If there is already a branchid param, error?
67640cb5e5dSvi117747 	 */
67740cb5e5dSvi117747 	if (sip_get_branchid(sip_msg, NULL) != NULL)
67840cb5e5dSvi117747 		return (EINVAL);
67940cb5e5dSvi117747 	_sip_msg = (_sip_msg_t *)sip_msg;
68040cb5e5dSvi117747 	(void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex);
68140cb5e5dSvi117747 	via_hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA, NULL);
68240cb5e5dSvi117747 	(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
68340cb5e5dSvi117747 	if (via_hdr == NULL)
68440cb5e5dSvi117747 		return (EINVAL);
68540cb5e5dSvi117747 	plen = strlen(branchid) + strlen("branch=") + 1;
68640cb5e5dSvi117747 	param = malloc(plen);
68740cb5e5dSvi117747 	if (param == NULL)
68840cb5e5dSvi117747 		return (ENOMEM);
68940cb5e5dSvi117747 	(void) snprintf(param, plen, "branch=%s", branchid);
69040cb5e5dSvi117747 
69140cb5e5dSvi117747 	(void) sip_add_param(via_hdr, param, &err);
69240cb5e5dSvi117747 	free(param);
69340cb5e5dSvi117747 
69440cb5e5dSvi117747 	return (err);
69540cb5e5dSvi117747 }
69640cb5e5dSvi117747 
69740cb5e5dSvi117747 /*
69840cb5e5dSvi117747  * returns the number of VIA headers in the SIP message
69940cb5e5dSvi117747  */
70040cb5e5dSvi117747 int
70140cb5e5dSvi117747 sip_get_num_via(sip_msg_t sip_msg, int *error)
70240cb5e5dSvi117747 {
70340cb5e5dSvi117747 	_sip_msg_t	*_sip_msg;
70440cb5e5dSvi117747 	sip_header_t	hdr;
70540cb5e5dSvi117747 	int		via_cnt = 0;
70640cb5e5dSvi117747 
70740cb5e5dSvi117747 	if (error != NULL)
70840cb5e5dSvi117747 		*error = 0;
70940cb5e5dSvi117747 	if (sip_msg == NULL) {
71040cb5e5dSvi117747 		if (error != NULL)
71140cb5e5dSvi117747 			*error = EINVAL;
71240cb5e5dSvi117747 		return (via_cnt);
71340cb5e5dSvi117747 	}
71440cb5e5dSvi117747 	_sip_msg = (_sip_msg_t *)sip_msg;
71540cb5e5dSvi117747 	(void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex);
71640cb5e5dSvi117747 	hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA, NULL);
71740cb5e5dSvi117747 	while (hdr != NULL) {
71840cb5e5dSvi117747 		via_cnt++;
71940cb5e5dSvi117747 		hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA,
72040cb5e5dSvi117747 		    hdr);
72140cb5e5dSvi117747 	}
72240cb5e5dSvi117747 	(void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
72340cb5e5dSvi117747 	return (via_cnt);
72440cb5e5dSvi117747 }
72540cb5e5dSvi117747 
72640cb5e5dSvi117747 /*
72740cb5e5dSvi117747  * Return Max-Forward value
72840cb5e5dSvi117747  */
72940cb5e5dSvi117747 int
73040cb5e5dSvi117747 sip_get_maxforward(sip_msg_t sip_msg, int *error)
73140cb5e5dSvi117747 {
73240cb5e5dSvi117747 	int	*r;
73340cb5e5dSvi117747 
73440cb5e5dSvi117747 	r = (int *)sip_get_val_from_msg(sip_msg, SIP_MAX_FORWARDS, SIP_INT_VAL,
73540cb5e5dSvi117747 	    B_FALSE, B_FALSE, error);
73640cb5e5dSvi117747 	if (r == NULL)
73740cb5e5dSvi117747 		return (-1);
73840cb5e5dSvi117747 	return (*r);
73940cb5e5dSvi117747 }
74040cb5e5dSvi117747 
74140cb5e5dSvi117747 /*
74240cb5e5dSvi117747  * Get the content type
74340cb5e5dSvi117747  */
74440cb5e5dSvi117747 const sip_str_t *
74540cb5e5dSvi117747 sip_get_content_type(sip_msg_t sip_msg, int *error)
74640cb5e5dSvi117747 {
74740cb5e5dSvi117747 	sip_str_t	*r;
74840cb5e5dSvi117747 
74940cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_TYPE,
75040cb5e5dSvi117747 	    SIP_STRS_VAL, B_TRUE, B_FALSE, error);
75140cb5e5dSvi117747 	return (r);
75240cb5e5dSvi117747 }
75340cb5e5dSvi117747 
75440cb5e5dSvi117747 /*
75540cb5e5dSvi117747  * Get the content sub-type
75640cb5e5dSvi117747  */
75740cb5e5dSvi117747 const sip_str_t *
75840cb5e5dSvi117747 sip_get_content_sub_type(sip_msg_t sip_msg, int *error)
75940cb5e5dSvi117747 {
76040cb5e5dSvi117747 	sip_str_t	*r;
76140cb5e5dSvi117747 
76240cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_TYPE,
76340cb5e5dSvi117747 	    SIP_STRS_VAL, B_FALSE, B_FALSE, error);
76440cb5e5dSvi117747 	return (r);
76540cb5e5dSvi117747 }
76640cb5e5dSvi117747 
76740cb5e5dSvi117747 /*
76840cb5e5dSvi117747  * Return the content-length value
76940cb5e5dSvi117747  */
77040cb5e5dSvi117747 int
77140cb5e5dSvi117747 sip_get_content_length(sip_msg_t sip_msg, int *error)
77240cb5e5dSvi117747 {
77340cb5e5dSvi117747 	int	*r;
77440cb5e5dSvi117747 
77540cb5e5dSvi117747 	r = (int *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_LENGTH,
77640cb5e5dSvi117747 	    SIP_INT_VAL, B_FALSE, B_FALSE, error);
77740cb5e5dSvi117747 	if (r == NULL)
77840cb5e5dSvi117747 		return (-1);
77940cb5e5dSvi117747 	return (*r);
78040cb5e5dSvi117747 }
78140cb5e5dSvi117747 
78240cb5e5dSvi117747 /*
78340cb5e5dSvi117747  * get allow-events
78440cb5e5dSvi117747  */
78540cb5e5dSvi117747 const sip_str_t *
78640cb5e5dSvi117747 sip_get_allow_events(sip_header_value_t value, int *error)
78740cb5e5dSvi117747 {
78840cb5e5dSvi117747 	sip_str_t	*r;
78940cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
79040cb5e5dSvi117747 
79140cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_TRUE, error);
79240cb5e5dSvi117747 	return (r);
79340cb5e5dSvi117747 }
79440cb5e5dSvi117747 
79540cb5e5dSvi117747 /*
79640cb5e5dSvi117747  * get event
79740cb5e5dSvi117747  */
79840cb5e5dSvi117747 const sip_str_t *
79940cb5e5dSvi117747 sip_get_event(sip_msg_t sip_msg, int *error)
80040cb5e5dSvi117747 {
80140cb5e5dSvi117747 	sip_str_t	*r;
80240cb5e5dSvi117747 
80340cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_EVENT, SIP_STR_VAL,
80440cb5e5dSvi117747 	    B_FALSE, B_FALSE, error);
80540cb5e5dSvi117747 	return (r);
80640cb5e5dSvi117747 }
80740cb5e5dSvi117747 
80840cb5e5dSvi117747 /*
80940cb5e5dSvi117747  * get subscription state
81040cb5e5dSvi117747  */
81140cb5e5dSvi117747 const sip_str_t *
81240cb5e5dSvi117747 sip_get_substate(sip_msg_t sip_msg, int *error)
81340cb5e5dSvi117747 {
81440cb5e5dSvi117747 	sip_str_t	*r;
81540cb5e5dSvi117747 
81640cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SUBSCRIPTION_STATE,
81740cb5e5dSvi117747 	    SIP_STR_VAL, B_FALSE, B_FALSE, error);
81840cb5e5dSvi117747 	return (r);
81940cb5e5dSvi117747 }
82040cb5e5dSvi117747 
82140cb5e5dSvi117747 /*
82240cb5e5dSvi117747  * get accept type
82340cb5e5dSvi117747  */
82440cb5e5dSvi117747 const sip_str_t *
82540cb5e5dSvi117747 sip_get_accept_type(sip_header_value_t value, int *error)
82640cb5e5dSvi117747 {
82740cb5e5dSvi117747 	sip_str_t	*r;
82840cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
82940cb5e5dSvi117747 
83040cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_TRUE, error);
83140cb5e5dSvi117747 	return (r);
83240cb5e5dSvi117747 }
83340cb5e5dSvi117747 
83440cb5e5dSvi117747 /*
83540cb5e5dSvi117747  * get accept subtype
83640cb5e5dSvi117747  */
83740cb5e5dSvi117747 const sip_str_t *
83840cb5e5dSvi117747 sip_get_accept_sub_type(sip_header_value_t value, int *error)
83940cb5e5dSvi117747 {
84040cb5e5dSvi117747 	sip_str_t	*r;
84140cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
84240cb5e5dSvi117747 
84340cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_FALSE,
84440cb5e5dSvi117747 	    error);
84540cb5e5dSvi117747 	return (r);
84640cb5e5dSvi117747 }
84740cb5e5dSvi117747 
84840cb5e5dSvi117747 /*
84940cb5e5dSvi117747  * accept-encode can have more than one value
85040cb5e5dSvi117747  */
85140cb5e5dSvi117747 const sip_str_t *
85240cb5e5dSvi117747 sip_get_accept_enc(sip_header_value_t value, int *error)
85340cb5e5dSvi117747 {
85440cb5e5dSvi117747 	sip_str_t	*r;
85540cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
85640cb5e5dSvi117747 
85740cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
85840cb5e5dSvi117747 	return (r);
85940cb5e5dSvi117747 }
86040cb5e5dSvi117747 
86140cb5e5dSvi117747 /*
86240cb5e5dSvi117747  * accept-language can have more than one value
86340cb5e5dSvi117747  */
86440cb5e5dSvi117747 const sip_str_t *
86540cb5e5dSvi117747 sip_get_accept_lang(sip_header_value_t value, int *error)
86640cb5e5dSvi117747 {
86740cb5e5dSvi117747 	sip_str_t	*r;
86840cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
86940cb5e5dSvi117747 
87040cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
87140cb5e5dSvi117747 	return (r);
87240cb5e5dSvi117747 }
87340cb5e5dSvi117747 
87440cb5e5dSvi117747 /*
87540cb5e5dSvi117747  * get URI from the alert-info header
87640cb5e5dSvi117747  */
87740cb5e5dSvi117747 const sip_str_t *
87840cb5e5dSvi117747 sip_get_alert_info_uri(sip_header_value_t value, int *error)
87940cb5e5dSvi117747 {
88040cb5e5dSvi117747 	sip_str_t	*r;
88140cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
88240cb5e5dSvi117747 
88340cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
88440cb5e5dSvi117747 	return (r);
88540cb5e5dSvi117747 }
88640cb5e5dSvi117747 
88740cb5e5dSvi117747 /*
88840cb5e5dSvi117747  * get method from allow header
88940cb5e5dSvi117747  */
89040cb5e5dSvi117747 sip_method_t
89140cb5e5dSvi117747 sip_get_allow_method(sip_header_value_t value, int *error)
89240cb5e5dSvi117747 {
89340cb5e5dSvi117747 	int		*r;
89440cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
89540cb5e5dSvi117747 
89640cb5e5dSvi117747 	r = (int *)sip_get_val_from_hdr(val, SIP_INT_VAL, B_FALSE, error);
89740cb5e5dSvi117747 	return (r == NULL ? -1 : (sip_method_t)*r);
89840cb5e5dSvi117747 }
89940cb5e5dSvi117747 
90040cb5e5dSvi117747 /*
90140cb5e5dSvi117747  * get URI from call-info header
90240cb5e5dSvi117747  */
90340cb5e5dSvi117747 const sip_str_t *
90440cb5e5dSvi117747 sip_get_call_info_uri(sip_header_value_t value, int *error)
90540cb5e5dSvi117747 {
90640cb5e5dSvi117747 	sip_str_t	*r;
90740cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
90840cb5e5dSvi117747 
90940cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
91040cb5e5dSvi117747 	return (r);
91140cb5e5dSvi117747 }
91240cb5e5dSvi117747 
91340cb5e5dSvi117747 /*
91440cb5e5dSvi117747  * get content-disposition value
91540cb5e5dSvi117747  */
91640cb5e5dSvi117747 const sip_str_t *
91740cb5e5dSvi117747 sip_get_content_disp(sip_msg_t sip_msg, int *error)
91840cb5e5dSvi117747 {
91940cb5e5dSvi117747 	sip_str_t	*r;
92040cb5e5dSvi117747 
92140cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_DIS,
92240cb5e5dSvi117747 	    SIP_STR_VAL, B_FALSE, B_FALSE, error);
92340cb5e5dSvi117747 	return (r);
92440cb5e5dSvi117747 }
92540cb5e5dSvi117747 
92640cb5e5dSvi117747 /*
92740cb5e5dSvi117747  * get content-encoding value
92840cb5e5dSvi117747  */
92940cb5e5dSvi117747 const sip_str_t *
93040cb5e5dSvi117747 sip_get_content_enc(sip_header_value_t value, int *error)
93140cb5e5dSvi117747 {
93240cb5e5dSvi117747 	sip_str_t	*r;
93340cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
93440cb5e5dSvi117747 
93540cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
93640cb5e5dSvi117747 	return (r);
93740cb5e5dSvi117747 }
93840cb5e5dSvi117747 
93940cb5e5dSvi117747 /*
94040cb5e5dSvi117747  * get content-language value
94140cb5e5dSvi117747  */
94240cb5e5dSvi117747 const sip_str_t *
94340cb5e5dSvi117747 sip_get_content_lang(sip_header_value_t value, int *error)
94440cb5e5dSvi117747 {
94540cb5e5dSvi117747 	sip_str_t	*r;
94640cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
94740cb5e5dSvi117747 
94840cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
94940cb5e5dSvi117747 	return (r);
95040cb5e5dSvi117747 }
95140cb5e5dSvi117747 
95240cb5e5dSvi117747 /*
95340cb5e5dSvi117747  * sip_get_date_time, day, wkday, month, year
95440cb5e5dSvi117747  */
95540cb5e5dSvi117747 #define	D_TIME		0x01
95640cb5e5dSvi117747 #define	D_DAY		0x02
95740cb5e5dSvi117747 #define	D_MONTH		0x03
95840cb5e5dSvi117747 #define	D_YEAR		0x04
95940cb5e5dSvi117747 #define	D_WKDAY		0x05
96040cb5e5dSvi117747 #define	D_TIMEZONE	0x06
96140cb5e5dSvi117747 
96240cb5e5dSvi117747 /*
96340cb5e5dSvi117747  * get date information
96440cb5e5dSvi117747  */
96540cb5e5dSvi117747 static void *
96640cb5e5dSvi117747 sip_get_date_val(sip_msg_t msg, int type, int *error)
96740cb5e5dSvi117747 {
96840cb5e5dSvi117747 	const _sip_header_t	*header;
96940cb5e5dSvi117747 	sip_hdr_value_t		*val;
97040cb5e5dSvi117747 
97140cb5e5dSvi117747 	if (error != NULL)
97240cb5e5dSvi117747 		*error = 0;
97340cb5e5dSvi117747 	if (msg == NULL) {
97440cb5e5dSvi117747 		if (error != NULL)
97540cb5e5dSvi117747 			*error = EINVAL;
97640cb5e5dSvi117747 		return (NULL);
97740cb5e5dSvi117747 	}
97840cb5e5dSvi117747 	header = sip_get_header(msg, SIP_DATE, NULL, error);
97940cb5e5dSvi117747 	if (header == NULL) {
98040cb5e5dSvi117747 		if (error != NULL)
98140cb5e5dSvi117747 			*error = EINVAL;
98240cb5e5dSvi117747 		return (NULL);
98340cb5e5dSvi117747 	}
98440cb5e5dSvi117747 
98540cb5e5dSvi117747 	val = (sip_hdr_value_t *)sip_get_header_value(header, error);
98640cb5e5dSvi117747 	if (val == NULL) {
98740cb5e5dSvi117747 		if (error != NULL)
98840cb5e5dSvi117747 			*error = EPROTO;
98940cb5e5dSvi117747 		return (NULL);
99040cb5e5dSvi117747 	}
99140cb5e5dSvi117747 	if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD)
99240cb5e5dSvi117747 		*error = EPROTO;
99340cb5e5dSvi117747 	switch (type) {
99440cb5e5dSvi117747 		case (D_TIME):
99540cb5e5dSvi117747 			return (&(val->date_t));
99640cb5e5dSvi117747 		case (D_DAY):
99740cb5e5dSvi117747 			return (&(val->date_d));
99840cb5e5dSvi117747 		case (D_MONTH):
99940cb5e5dSvi117747 			return (&(val->date_m));
100040cb5e5dSvi117747 		case (D_YEAR):
100140cb5e5dSvi117747 			return (&(val->date_y));
100240cb5e5dSvi117747 		case (D_WKDAY):
100340cb5e5dSvi117747 			return (&(val->date_wd));
100440cb5e5dSvi117747 		case (D_TIMEZONE):
100540cb5e5dSvi117747 			return (&(val->date_tz));
100640cb5e5dSvi117747 	}
100740cb5e5dSvi117747 	if (error != NULL)
100840cb5e5dSvi117747 		*error = EINVAL;
100940cb5e5dSvi117747 	return (NULL);
101040cb5e5dSvi117747 }
101140cb5e5dSvi117747 
101240cb5e5dSvi117747 /*
101340cb5e5dSvi117747  * get time value
101440cb5e5dSvi117747  */
101540cb5e5dSvi117747 const sip_str_t *
101640cb5e5dSvi117747 sip_get_date_time(sip_msg_t sip_msg, int *error)
101740cb5e5dSvi117747 {
101840cb5e5dSvi117747 	sip_str_t	*r;
101940cb5e5dSvi117747 
102040cb5e5dSvi117747 	r = (sip_str_t *)sip_get_date_val(sip_msg, D_TIME, error);
102140cb5e5dSvi117747 	return (r);
102240cb5e5dSvi117747 }
102340cb5e5dSvi117747 
102440cb5e5dSvi117747 /*
102540cb5e5dSvi117747  * get day
102640cb5e5dSvi117747  */
102740cb5e5dSvi117747 int
102840cb5e5dSvi117747 sip_get_date_day(sip_msg_t sip_msg, int *error)
102940cb5e5dSvi117747 {
103040cb5e5dSvi117747 	int	*r = NULL;
103140cb5e5dSvi117747 
103240cb5e5dSvi117747 	r = sip_get_date_val(sip_msg, D_DAY, error);
103340cb5e5dSvi117747 	return (r == NULL ? -1 : *(int *)r);
103440cb5e5dSvi117747 }
103540cb5e5dSvi117747 
103640cb5e5dSvi117747 /*
103740cb5e5dSvi117747  * get month
103840cb5e5dSvi117747  */
103940cb5e5dSvi117747 const sip_str_t *
104040cb5e5dSvi117747 sip_get_date_month(sip_msg_t sip_msg, int *error)
104140cb5e5dSvi117747 {
104240cb5e5dSvi117747 	sip_str_t	*r;
104340cb5e5dSvi117747 
104440cb5e5dSvi117747 	r = (sip_str_t *)sip_get_date_val(sip_msg, D_MONTH, error);
104540cb5e5dSvi117747 	return (r);
104640cb5e5dSvi117747 }
104740cb5e5dSvi117747 
104840cb5e5dSvi117747 /*
104940cb5e5dSvi117747  * get year
105040cb5e5dSvi117747  */
105140cb5e5dSvi117747 int
105240cb5e5dSvi117747 sip_get_date_year(sip_msg_t sip_msg, int *error)
105340cb5e5dSvi117747 {
105440cb5e5dSvi117747 	int	*r;
105540cb5e5dSvi117747 
105640cb5e5dSvi117747 	r = (int *)sip_get_date_val(sip_msg, D_YEAR, error);
105740cb5e5dSvi117747 	return (r == NULL ? -1 : *r);
105840cb5e5dSvi117747 }
105940cb5e5dSvi117747 
106040cb5e5dSvi117747 /*
106140cb5e5dSvi117747  * get day of the week
106240cb5e5dSvi117747  */
106340cb5e5dSvi117747 const sip_str_t *
106440cb5e5dSvi117747 sip_get_date_wkday(sip_msg_t sip_msg, int *error)
106540cb5e5dSvi117747 {
106640cb5e5dSvi117747 	sip_str_t	*r;
106740cb5e5dSvi117747 
106840cb5e5dSvi117747 	r = (sip_str_t *)sip_get_date_val(sip_msg, D_WKDAY, error);
106940cb5e5dSvi117747 	return (r);
107040cb5e5dSvi117747 }
107140cb5e5dSvi117747 
107240cb5e5dSvi117747 /*
107340cb5e5dSvi117747  * get the timezone
107440cb5e5dSvi117747  */
107540cb5e5dSvi117747 const sip_str_t *
107640cb5e5dSvi117747 sip_get_date_timezone(sip_msg_t sip_msg, int *error)
107740cb5e5dSvi117747 {
107840cb5e5dSvi117747 	sip_str_t	*r;
107940cb5e5dSvi117747 
108040cb5e5dSvi117747 	r = (sip_str_t *)sip_get_date_val(sip_msg, D_TIMEZONE, error);
108140cb5e5dSvi117747 	return (r);
108240cb5e5dSvi117747 }
108340cb5e5dSvi117747 
108440cb5e5dSvi117747 /*
108540cb5e5dSvi117747  * get error-info URI
108640cb5e5dSvi117747  */
108740cb5e5dSvi117747 const sip_str_t *
108840cb5e5dSvi117747 sip_get_error_info_uri(sip_header_value_t value, int *error)
108940cb5e5dSvi117747 {
109040cb5e5dSvi117747 	sip_str_t	*r;
109140cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
109240cb5e5dSvi117747 
109340cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
109440cb5e5dSvi117747 	return (r);
109540cb5e5dSvi117747 }
109640cb5e5dSvi117747 
109740cb5e5dSvi117747 /*
109840cb5e5dSvi117747  * get priv-value from privacy
109940cb5e5dSvi117747  */
110040cb5e5dSvi117747 const sip_str_t *
110140cb5e5dSvi117747 sip_get_priv_value(sip_header_value_t value, int *error)
110240cb5e5dSvi117747 {
110340cb5e5dSvi117747 	sip_str_t	*r;
110440cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
110540cb5e5dSvi117747 
110640cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
110740cb5e5dSvi117747 	return (r);
110840cb5e5dSvi117747 }
110940cb5e5dSvi117747 
111040cb5e5dSvi117747 /*
111140cb5e5dSvi117747  * return expires value
111240cb5e5dSvi117747  */
111340cb5e5dSvi117747 int
111440cb5e5dSvi117747 sip_get_expires(sip_msg_t sip_msg, int *error)
111540cb5e5dSvi117747 {
111640cb5e5dSvi117747 	int	*r;
111740cb5e5dSvi117747 
111840cb5e5dSvi117747 	r = (int *)sip_get_val_from_msg(sip_msg, SIP_EXPIRE, SIP_INT_VAL,
111940cb5e5dSvi117747 	    B_FALSE, B_FALSE, error);
112040cb5e5dSvi117747 	if (r == NULL)
112140cb5e5dSvi117747 		return (-1);
112240cb5e5dSvi117747 	return (*r);
112340cb5e5dSvi117747 }
112440cb5e5dSvi117747 
112540cb5e5dSvi117747 /*
112640cb5e5dSvi117747  * get reply-to value
112740cb5e5dSvi117747  */
112840cb5e5dSvi117747 const sip_str_t *
112940cb5e5dSvi117747 sip_get_in_reply_to(sip_header_value_t value, int *error)
113040cb5e5dSvi117747 {
113140cb5e5dSvi117747 	sip_str_t	*r;
113240cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
113340cb5e5dSvi117747 
113440cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
113540cb5e5dSvi117747 	return (r);
113640cb5e5dSvi117747 }
113740cb5e5dSvi117747 
113840cb5e5dSvi117747 /*
113940cb5e5dSvi117747  * get min-expires value
114040cb5e5dSvi117747  */
114140cb5e5dSvi117747 int
114240cb5e5dSvi117747 sip_get_min_expires(sip_msg_t sip_msg, int *error)
114340cb5e5dSvi117747 {
114440cb5e5dSvi117747 	int	*r;
114540cb5e5dSvi117747 
114640cb5e5dSvi117747 	r = (int *)sip_get_val_from_msg(sip_msg, SIP_MIN_EXPIRE, SIP_INT_VAL,
114740cb5e5dSvi117747 	    B_FALSE, B_FALSE, error);
114840cb5e5dSvi117747 	if (r == NULL)
114940cb5e5dSvi117747 		return (-1);
115040cb5e5dSvi117747 	return (*r);
115140cb5e5dSvi117747 }
115240cb5e5dSvi117747 
115340cb5e5dSvi117747 /*
115440cb5e5dSvi117747  * get mime-version
115540cb5e5dSvi117747  */
115640cb5e5dSvi117747 const sip_str_t *
115740cb5e5dSvi117747 sip_get_mime_version(sip_msg_t sip_msg, int *error)
115840cb5e5dSvi117747 {
115940cb5e5dSvi117747 	sip_str_t	*r;
116040cb5e5dSvi117747 
116140cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_MIME_VERSION,
116240cb5e5dSvi117747 	    SIP_STR_VAL, B_FALSE, B_FALSE, error);
116340cb5e5dSvi117747 	return (r);
116440cb5e5dSvi117747 }
116540cb5e5dSvi117747 
116640cb5e5dSvi117747 /*
116740cb5e5dSvi117747  * get organization value
116840cb5e5dSvi117747  */
116940cb5e5dSvi117747 const sip_str_t *
117040cb5e5dSvi117747 sip_get_org(sip_msg_t sip_msg, int *error)
117140cb5e5dSvi117747 {
117240cb5e5dSvi117747 	sip_str_t	*r;
117340cb5e5dSvi117747 
117440cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_ORGANIZATION,
117540cb5e5dSvi117747 	    SIP_STR_VAL, B_FALSE, B_TRUE, error);
117640cb5e5dSvi117747 	return (r);
117740cb5e5dSvi117747 }
117840cb5e5dSvi117747 
117940cb5e5dSvi117747 /*
118040cb5e5dSvi117747  * get priority value
118140cb5e5dSvi117747  */
118240cb5e5dSvi117747 const sip_str_t *
118340cb5e5dSvi117747 sip_get_priority(sip_msg_t sip_msg, int *error)
118440cb5e5dSvi117747 {
118540cb5e5dSvi117747 	sip_str_t	*r;
118640cb5e5dSvi117747 
118740cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_PRIORITY,
118840cb5e5dSvi117747 	    SIP_STR_VAL, B_FALSE, B_FALSE, error);
118940cb5e5dSvi117747 	return (r);
119040cb5e5dSvi117747 }
119140cb5e5dSvi117747 
119240cb5e5dSvi117747 /*
119340cb5e5dSvi117747  * get display name
119440cb5e5dSvi117747  */
119540cb5e5dSvi117747 const sip_str_t *
119640cb5e5dSvi117747 sip_get_pidentity_display_name(sip_header_value_t value, int *error)
119740cb5e5dSvi117747 {
119840cb5e5dSvi117747 	sip_str_t	*r;
119940cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
120040cb5e5dSvi117747 
120140cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_TRUE, error);
120240cb5e5dSvi117747 
120340cb5e5dSvi117747 	return (r);
120440cb5e5dSvi117747 }
120540cb5e5dSvi117747 
120640cb5e5dSvi117747 /*
120740cb5e5dSvi117747  * get URI
120840cb5e5dSvi117747  */
120940cb5e5dSvi117747 const sip_str_t *
121040cb5e5dSvi117747 sip_get_pidenty_uri_str(sip_header_value_t value, int *error)
121140cb5e5dSvi117747 {
121240cb5e5dSvi117747 	sip_str_t	*r;
121340cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
121440cb5e5dSvi117747 
121540cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_FALSE,
121640cb5e5dSvi117747 	    error);
121740cb5e5dSvi117747 
121840cb5e5dSvi117747 	return (r);
121940cb5e5dSvi117747 }
122040cb5e5dSvi117747 
122140cb5e5dSvi117747 /*
122240cb5e5dSvi117747  * get display name from passerted-identity header
122340cb5e5dSvi117747  */
122440cb5e5dSvi117747 const sip_str_t *
122540cb5e5dSvi117747 sip_get_passertedid_display_name(sip_header_value_t value, int *error)
122640cb5e5dSvi117747 {
122740cb5e5dSvi117747 	return (sip_get_pidentity_display_name(value, error));
122840cb5e5dSvi117747 }
122940cb5e5dSvi117747 
123040cb5e5dSvi117747 /*
123140cb5e5dSvi117747  * get URI from passerted-identity header
123240cb5e5dSvi117747  */
123340cb5e5dSvi117747 const sip_str_t *
123440cb5e5dSvi117747 sip_get_passertedid_uri_str(sip_header_value_t value, int *error)
123540cb5e5dSvi117747 {
123640cb5e5dSvi117747 	return (sip_get_pidenty_uri_str(value, error));
123740cb5e5dSvi117747 }
123840cb5e5dSvi117747 
123940cb5e5dSvi117747 /*
124040cb5e5dSvi117747  * get display name from ppreferred-identity header
124140cb5e5dSvi117747  */
124240cb5e5dSvi117747 const sip_str_t *
124340cb5e5dSvi117747 sip_get_ppreferredid_display_name(sip_header_value_t value, int *error)
124440cb5e5dSvi117747 {
124540cb5e5dSvi117747 	return (sip_get_pidentity_display_name(value, error));
124640cb5e5dSvi117747 }
124740cb5e5dSvi117747 
124840cb5e5dSvi117747 /*
124940cb5e5dSvi117747  * get URI from ppreferred-identity header
125040cb5e5dSvi117747  */
125140cb5e5dSvi117747 const sip_str_t *
125240cb5e5dSvi117747 sip_get_ppreferredid_uri_str(sip_header_value_t value, int *error)
125340cb5e5dSvi117747 {
125440cb5e5dSvi117747 	return (sip_get_pidenty_uri_str(value, error));
125540cb5e5dSvi117747 }
125640cb5e5dSvi117747 
125740cb5e5dSvi117747 #define	SIP_RACK_RESP_NUM	1
125840cb5e5dSvi117747 #define	SIP_RACK_CSEQ_NUM	2
125940cb5e5dSvi117747 #define	SIP_RACK_METHOD		3
126040cb5e5dSvi117747 
126140cb5e5dSvi117747 /*
126240cb5e5dSvi117747  * Get rack information
126340cb5e5dSvi117747  */
126440cb5e5dSvi117747 static void *
126540cb5e5dSvi117747 sip_get_rack_val(sip_msg_t msg, int type, int *error)
126640cb5e5dSvi117747 {
126740cb5e5dSvi117747 	const _sip_header_t	*header;
126840cb5e5dSvi117747 	sip_hdr_value_t		*val;
126940cb5e5dSvi117747 
127040cb5e5dSvi117747 	if (error != NULL)
127140cb5e5dSvi117747 		*error = 0;
127240cb5e5dSvi117747 
127340cb5e5dSvi117747 	if (msg == NULL)  {
127440cb5e5dSvi117747 		if (error != NULL)
127540cb5e5dSvi117747 			*error = EINVAL;
127640cb5e5dSvi117747 		return (NULL);
127740cb5e5dSvi117747 	}
127840cb5e5dSvi117747 	header = sip_get_header(msg, SIP_RACK, NULL, error);
127940cb5e5dSvi117747 	if (header == NULL) {
128040cb5e5dSvi117747 		if (error != NULL)
128140cb5e5dSvi117747 			*error = EINVAL;
128240cb5e5dSvi117747 		return (NULL);
128340cb5e5dSvi117747 	}
128440cb5e5dSvi117747 	val = (sip_hdr_value_t *)sip_get_header_value(header, error);
128540cb5e5dSvi117747 	if (val == NULL) {
128640cb5e5dSvi117747 		if (error != NULL)
128740cb5e5dSvi117747 			*error = EPROTO;
128840cb5e5dSvi117747 		return (NULL);
128940cb5e5dSvi117747 	}
129040cb5e5dSvi117747 	if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD)
129140cb5e5dSvi117747 		*error = EPROTO;
129240cb5e5dSvi117747 
129340cb5e5dSvi117747 	switch (type) {
129440cb5e5dSvi117747 		case SIP_RACK_RESP_NUM:
129540cb5e5dSvi117747 			return (&(val->rack_resp));
129640cb5e5dSvi117747 		case SIP_RACK_CSEQ_NUM:
129740cb5e5dSvi117747 			return (&(val->rack_cseq));
129840cb5e5dSvi117747 		case SIP_RACK_METHOD:
129940cb5e5dSvi117747 			return (&(val->rack_method));
130040cb5e5dSvi117747 	}
130140cb5e5dSvi117747 	if (error != NULL)
130240cb5e5dSvi117747 		*error = EINVAL;
130340cb5e5dSvi117747 	return (NULL);
130440cb5e5dSvi117747 }
130540cb5e5dSvi117747 
130640cb5e5dSvi117747 /*
130740cb5e5dSvi117747  * get response number for rack
130840cb5e5dSvi117747  */
130940cb5e5dSvi117747 int
131040cb5e5dSvi117747 sip_get_rack_resp_num(sip_msg_t sip_msg, int *error)
131140cb5e5dSvi117747 {
131240cb5e5dSvi117747 	int	*r;
131340cb5e5dSvi117747 
131440cb5e5dSvi117747 	r = (int *)sip_get_rack_val(sip_msg, SIP_RACK_RESP_NUM, error);
131540cb5e5dSvi117747 
131640cb5e5dSvi117747 	return (r == NULL ? -1 : *r);
131740cb5e5dSvi117747 }
131840cb5e5dSvi117747 
131940cb5e5dSvi117747 /*
132040cb5e5dSvi117747  * get sequence number for rack
132140cb5e5dSvi117747  */
132240cb5e5dSvi117747 int
132340cb5e5dSvi117747 sip_get_rack_cseq_num(sip_msg_t sip_msg, int *error)
132440cb5e5dSvi117747 {
132540cb5e5dSvi117747 	int	*r;
132640cb5e5dSvi117747 
132740cb5e5dSvi117747 	r = (int *)sip_get_rack_val(sip_msg, SIP_RACK_CSEQ_NUM, error);
132840cb5e5dSvi117747 
132940cb5e5dSvi117747 	return (r == NULL ? -1 : *r);
133040cb5e5dSvi117747 }
133140cb5e5dSvi117747 
133240cb5e5dSvi117747 /*
133340cb5e5dSvi117747  * get method for rack
133440cb5e5dSvi117747  */
133540cb5e5dSvi117747 sip_method_t
133640cb5e5dSvi117747 sip_get_rack_method(sip_msg_t sip_msg, int *error)
133740cb5e5dSvi117747 {
133840cb5e5dSvi117747 	sip_method_t	*r;
133940cb5e5dSvi117747 
134040cb5e5dSvi117747 	r = (sip_method_t *)sip_get_rack_val(sip_msg, SIP_RACK_METHOD, error);
134140cb5e5dSvi117747 
134240cb5e5dSvi117747 	return (r == NULL ? -1 : *r);
134340cb5e5dSvi117747 }
134440cb5e5dSvi117747 
134540cb5e5dSvi117747 /*
134640cb5e5dSvi117747  * get response number from rseq
134740cb5e5dSvi117747  */
134840cb5e5dSvi117747 int
134940cb5e5dSvi117747 sip_get_rseq_resp_num(sip_msg_t sip_msg, int *error)
135040cb5e5dSvi117747 {
135140cb5e5dSvi117747 	int	*r;
135240cb5e5dSvi117747 
135340cb5e5dSvi117747 	r = (int *)sip_get_val_from_msg(sip_msg, SIP_RSEQ, SIP_INT_VAL,
135440cb5e5dSvi117747 	    B_FALSE, B_FALSE, error);
135540cb5e5dSvi117747 
135640cb5e5dSvi117747 	return (r == NULL ? -1 : *r);
135740cb5e5dSvi117747 }
135840cb5e5dSvi117747 
135940cb5e5dSvi117747 /*
136040cb5e5dSvi117747  * get reply-to display name
136140cb5e5dSvi117747  */
136240cb5e5dSvi117747 const sip_str_t *
136340cb5e5dSvi117747 sip_get_replyto_display_name(sip_msg_t sip_msg, int *error)
136440cb5e5dSvi117747 {
136540cb5e5dSvi117747 	sip_str_t	*r;
136640cb5e5dSvi117747 
136740cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_REPLYTO,
136840cb5e5dSvi117747 	    SIP_STRS_VAL, B_TRUE, B_FALSE, error);
136940cb5e5dSvi117747 	return (r);
137040cb5e5dSvi117747 }
137140cb5e5dSvi117747 
137240cb5e5dSvi117747 /*
137340cb5e5dSvi117747  * get reply-to URI
137440cb5e5dSvi117747  */
137540cb5e5dSvi117747 const sip_str_t *
137640cb5e5dSvi117747 sip_get_replyto_uri_str(sip_msg_t sip_msg, int *error)
137740cb5e5dSvi117747 {
137840cb5e5dSvi117747 	sip_str_t	*r;
137940cb5e5dSvi117747 
138040cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_REPLYTO,
138140cb5e5dSvi117747 	    SIP_STRS_VAL, B_FALSE, B_FALSE, error);
138240cb5e5dSvi117747 
138340cb5e5dSvi117747 	return (r);
138440cb5e5dSvi117747 }
138540cb5e5dSvi117747 
138640cb5e5dSvi117747 /*
138740cb5e5dSvi117747  * get require value
138840cb5e5dSvi117747  */
138940cb5e5dSvi117747 const sip_str_t *
139040cb5e5dSvi117747 sip_get_require(sip_header_value_t value, int *error)
139140cb5e5dSvi117747 {
139240cb5e5dSvi117747 	sip_str_t	*r;
139340cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
139440cb5e5dSvi117747 
139540cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
139640cb5e5dSvi117747 	return (r);
139740cb5e5dSvi117747 }
139840cb5e5dSvi117747 
139940cb5e5dSvi117747 /*
140040cb5e5dSvi117747  * get retry-after time
140140cb5e5dSvi117747  */
140240cb5e5dSvi117747 int
140340cb5e5dSvi117747 sip_get_retry_after_time(sip_msg_t sip_msg, int *error)
140440cb5e5dSvi117747 {
140540cb5e5dSvi117747 	int	*t;
140640cb5e5dSvi117747 
140740cb5e5dSvi117747 	t = (int *)sip_get_val_from_msg(sip_msg, SIP_RETRY_AFTER,
140840cb5e5dSvi117747 	    SIP_INTSTR_VAL, B_FALSE, B_FALSE, error);
140940cb5e5dSvi117747 	if (t == NULL)
141040cb5e5dSvi117747 		return (-1);
141140cb5e5dSvi117747 	return (*t);
141240cb5e5dSvi117747 }
141340cb5e5dSvi117747 
141440cb5e5dSvi117747 /*
141540cb5e5dSvi117747  * get retry-after comments
141640cb5e5dSvi117747  */
141740cb5e5dSvi117747 const sip_str_t *
141840cb5e5dSvi117747 sip_get_retry_after_cmts(sip_msg_t sip_msg, int *error)
141940cb5e5dSvi117747 {
142040cb5e5dSvi117747 	sip_str_t	*r;
142140cb5e5dSvi117747 
142240cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_RETRY_AFTER,
142340cb5e5dSvi117747 	    SIP_INTSTR_VAL, B_TRUE, B_FALSE, error);
142440cb5e5dSvi117747 	return (r);
142540cb5e5dSvi117747 }
142640cb5e5dSvi117747 
142740cb5e5dSvi117747 /*
142840cb5e5dSvi117747  * get subject
142940cb5e5dSvi117747  */
143040cb5e5dSvi117747 const sip_str_t *
143140cb5e5dSvi117747 sip_get_subject(sip_msg_t sip_msg, int *error)
143240cb5e5dSvi117747 {
143340cb5e5dSvi117747 	sip_str_t	*r;
143440cb5e5dSvi117747 
143540cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SUBJECT, SIP_STR_VAL,
143640cb5e5dSvi117747 	    B_FALSE, B_TRUE, error);
143740cb5e5dSvi117747 	return (r);
143840cb5e5dSvi117747 }
143940cb5e5dSvi117747 
144040cb5e5dSvi117747 /*
144140cb5e5dSvi117747  * get supported
144240cb5e5dSvi117747  */
144340cb5e5dSvi117747 const sip_str_t *
144440cb5e5dSvi117747 sip_get_supported(sip_header_value_t value, int *error)
144540cb5e5dSvi117747 {
144640cb5e5dSvi117747 	sip_str_t	*r;
144740cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
144840cb5e5dSvi117747 
144940cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
145040cb5e5dSvi117747 	return (r);
145140cb5e5dSvi117747 }
145240cb5e5dSvi117747 
145340cb5e5dSvi117747 /*
145440cb5e5dSvi117747  * get timestamp delay
145540cb5e5dSvi117747  */
145640cb5e5dSvi117747 const sip_str_t *
145740cb5e5dSvi117747 sip_get_tstamp_delay(sip_msg_t sip_msg, int *error)
145840cb5e5dSvi117747 {
145940cb5e5dSvi117747 	sip_str_t	*t;
146040cb5e5dSvi117747 
146140cb5e5dSvi117747 	t = sip_get_val_from_msg(sip_msg, SIP_TIMESTAMP, SIP_STRS_VAL, B_FALSE,
146240cb5e5dSvi117747 	    B_FALSE, error);
146340cb5e5dSvi117747 	return (t);
146440cb5e5dSvi117747 }
146540cb5e5dSvi117747 
146640cb5e5dSvi117747 /*
146740cb5e5dSvi117747  * get timestamp
146840cb5e5dSvi117747  */
146940cb5e5dSvi117747 const sip_str_t *
147040cb5e5dSvi117747 sip_get_tstamp_value(sip_msg_t sip_msg, int *error)
147140cb5e5dSvi117747 {
147240cb5e5dSvi117747 	sip_str_t	*t;
147340cb5e5dSvi117747 
147440cb5e5dSvi117747 	t = sip_get_val_from_msg(sip_msg, SIP_TIMESTAMP, SIP_STRS_VAL, B_TRUE,
147540cb5e5dSvi117747 	    B_FALSE, error);
147640cb5e5dSvi117747 	return (t);
147740cb5e5dSvi117747 }
147840cb5e5dSvi117747 
147940cb5e5dSvi117747 /*
148040cb5e5dSvi117747  * get unsupported value
148140cb5e5dSvi117747  */
148240cb5e5dSvi117747 const sip_str_t *
148340cb5e5dSvi117747 sip_get_unsupported(sip_header_value_t value, int *error)
148440cb5e5dSvi117747 {
148540cb5e5dSvi117747 	sip_str_t	*r;
148640cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
148740cb5e5dSvi117747 
148840cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
148940cb5e5dSvi117747 	return (r);
149040cb5e5dSvi117747 }
149140cb5e5dSvi117747 
149240cb5e5dSvi117747 /*
149340cb5e5dSvi117747  * get server value from message
149440cb5e5dSvi117747  */
149540cb5e5dSvi117747 const sip_str_t *
149640cb5e5dSvi117747 sip_get_server(sip_msg_t sip_msg, int *error)
149740cb5e5dSvi117747 {
149840cb5e5dSvi117747 	sip_str_t	*r;
149940cb5e5dSvi117747 
150040cb5e5dSvi117747 	r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SERVER, SIP_STR_VAL,
150140cb5e5dSvi117747 	    B_FALSE, B_FALSE, error);
150240cb5e5dSvi117747 	return (r);
150340cb5e5dSvi117747 }
150440cb5e5dSvi117747 
150540cb5e5dSvi117747 /*
150640cb5e5dSvi117747  * get user-agent value
150740cb5e5dSvi117747  */
150840cb5e5dSvi117747 const sip_str_t *
150940cb5e5dSvi117747 sip_get_user_agent(sip_msg_t sip_msg, int *error)
151040cb5e5dSvi117747 {
151140cb5e5dSvi117747 	sip_str_t	*r;
151240cb5e5dSvi117747 
151340cb5e5dSvi117747 	r = sip_get_val_from_msg(sip_msg, SIP_USER_AGENT, SIP_STR_VAL, B_FALSE,
151440cb5e5dSvi117747 	    B_FALSE, error);
151540cb5e5dSvi117747 	return (r);
151640cb5e5dSvi117747 }
151740cb5e5dSvi117747 
151840cb5e5dSvi117747 #define	W_CODE	0x05
151940cb5e5dSvi117747 #define	W_AGENT	0x06
152040cb5e5dSvi117747 #define	W_TEXT	0x07
152140cb5e5dSvi117747 
152240cb5e5dSvi117747 /*
152340cb5e5dSvi117747  * get warning info
152440cb5e5dSvi117747  */
152540cb5e5dSvi117747 static void *
152640cb5e5dSvi117747 sip_get_warninfo(sip_header_value_t value, int info, int *error)
152740cb5e5dSvi117747 {
152840cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
152940cb5e5dSvi117747 
153040cb5e5dSvi117747 	if (error != NULL)
153140cb5e5dSvi117747 		*error = 0;
153240cb5e5dSvi117747 
153340cb5e5dSvi117747 	if (val == NULL) {
153440cb5e5dSvi117747 		if (error != NULL)
153540cb5e5dSvi117747 			*error = EINVAL;
153640cb5e5dSvi117747 		return (NULL);
153740cb5e5dSvi117747 	}
153840cb5e5dSvi117747 
153940cb5e5dSvi117747 	if (val->sip_value_state == SIP_VALUE_BAD) {
154040cb5e5dSvi117747 		*error = EPROTO;
154140cb5e5dSvi117747 		return (NULL);
154240cb5e5dSvi117747 	}
154340cb5e5dSvi117747 
154440cb5e5dSvi117747 	switch (info) {
154540cb5e5dSvi117747 		case (W_CODE):
154640cb5e5dSvi117747 			return (&(val->warn_code));
154740cb5e5dSvi117747 		case (W_AGENT):
154840cb5e5dSvi117747 			return (&(val->warn_agt));
154940cb5e5dSvi117747 		case (W_TEXT):
155040cb5e5dSvi117747 			return (&(val->warn_text));
155140cb5e5dSvi117747 	}
155240cb5e5dSvi117747 	if (error != NULL)
155340cb5e5dSvi117747 		*error = EINVAL;
155440cb5e5dSvi117747 	return (NULL);
155540cb5e5dSvi117747 }
155640cb5e5dSvi117747 
155740cb5e5dSvi117747 /*
155840cb5e5dSvi117747  * get warning code
155940cb5e5dSvi117747  */
156040cb5e5dSvi117747 int
156140cb5e5dSvi117747 sip_get_warning_code(sip_header_value_t value, int *error)
156240cb5e5dSvi117747 {
156340cb5e5dSvi117747 	int	*c;
156440cb5e5dSvi117747 
156540cb5e5dSvi117747 	if (error != NULL)
156640cb5e5dSvi117747 		*error = 0;
156740cb5e5dSvi117747 
156840cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
156940cb5e5dSvi117747 		if (error != NULL)
157040cb5e5dSvi117747 			*error = EINVAL;
157140cb5e5dSvi117747 		return (-1);
157240cb5e5dSvi117747 	}
157340cb5e5dSvi117747 	c = (int *)sip_get_warninfo(value, W_CODE, error);
157440cb5e5dSvi117747 	if (c == NULL)
157540cb5e5dSvi117747 		return (-1);
157640cb5e5dSvi117747 	return (*c);
157740cb5e5dSvi117747 }
157840cb5e5dSvi117747 
157940cb5e5dSvi117747 /*
158040cb5e5dSvi117747  * get warning agent
158140cb5e5dSvi117747  */
158240cb5e5dSvi117747 const sip_str_t *
158340cb5e5dSvi117747 sip_get_warning_agent(sip_header_value_t value, int *error)
158440cb5e5dSvi117747 {
158540cb5e5dSvi117747 	sip_str_t	*r;
158640cb5e5dSvi117747 
158740cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
158840cb5e5dSvi117747 		if (error != NULL)
158940cb5e5dSvi117747 			*error = EINVAL;
159040cb5e5dSvi117747 		return (NULL);
159140cb5e5dSvi117747 	}
159240cb5e5dSvi117747 	r = (sip_str_t *)sip_get_warninfo(value, W_AGENT, error);
159340cb5e5dSvi117747 	return (r);
159440cb5e5dSvi117747 }
159540cb5e5dSvi117747 
159640cb5e5dSvi117747 /*
159740cb5e5dSvi117747  * get warning text
159840cb5e5dSvi117747  */
159940cb5e5dSvi117747 const sip_str_t *
160040cb5e5dSvi117747 sip_get_warning_text(sip_header_value_t value, int *error)
160140cb5e5dSvi117747 {
160240cb5e5dSvi117747 	sip_str_t	*r;
160340cb5e5dSvi117747 
160440cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
160540cb5e5dSvi117747 		if (error != NULL)
160640cb5e5dSvi117747 			*error = EINVAL;
160740cb5e5dSvi117747 		return (NULL);
160840cb5e5dSvi117747 	}
160940cb5e5dSvi117747 	r = (sip_str_t *)sip_get_warninfo(value, W_TEXT, error);
161040cb5e5dSvi117747 	return (r);
161140cb5e5dSvi117747 }
161240cb5e5dSvi117747 
161340cb5e5dSvi117747 /*
161440cb5e5dSvi117747  * get authorization scheme
161540cb5e5dSvi117747  */
161640cb5e5dSvi117747 const sip_str_t *
161740cb5e5dSvi117747 sip_get_author_scheme(sip_msg_t sip_msg, int *error)
161840cb5e5dSvi117747 {
161940cb5e5dSvi117747 	sip_str_t	*r;
162040cb5e5dSvi117747 
162140cb5e5dSvi117747 	r = sip_get_val_from_msg(sip_msg, SIP_AUTHOR, SIP_AUTH_VAL, B_FALSE,
162240cb5e5dSvi117747 	    B_FALSE, error);
162340cb5e5dSvi117747 	return (r);
162440cb5e5dSvi117747 }
162540cb5e5dSvi117747 
162640cb5e5dSvi117747 /*
162740cb5e5dSvi117747  * get authentication parameter
162840cb5e5dSvi117747  */
162940cb5e5dSvi117747 static const sip_str_t *
163040cb5e5dSvi117747 sip_get_auth_param(sip_msg_t msg, char *hdr_name, char *pname, int *error)
163140cb5e5dSvi117747 {
163240cb5e5dSvi117747 	const _sip_header_t	*header;
163340cb5e5dSvi117747 	sip_hdr_value_t		*value;
163440cb5e5dSvi117747 	sip_param_t		*param;
163540cb5e5dSvi117747 
163640cb5e5dSvi117747 	if (error != NULL)
163740cb5e5dSvi117747 		*error = 0;
163840cb5e5dSvi117747 
163940cb5e5dSvi117747 	if (msg == NULL || pname == NULL || hdr_name == NULL) {
164040cb5e5dSvi117747 		if (error != NULL)
164140cb5e5dSvi117747 			*error = EINVAL;
164240cb5e5dSvi117747 		return (NULL);
164340cb5e5dSvi117747 	}
164440cb5e5dSvi117747 
164540cb5e5dSvi117747 	header = sip_get_header(msg, hdr_name, NULL, error);
164640cb5e5dSvi117747 	if (header == NULL) {
164740cb5e5dSvi117747 		if (error != NULL)
164840cb5e5dSvi117747 			*error = EINVAL;
164940cb5e5dSvi117747 		return (NULL);
165040cb5e5dSvi117747 	}
165140cb5e5dSvi117747 
165240cb5e5dSvi117747 	value = (sip_hdr_value_t *)sip_get_header_value(header, error);
165340cb5e5dSvi117747 	if (value == NULL) {
165440cb5e5dSvi117747 		if (error != NULL)
165540cb5e5dSvi117747 			*error = EPROTO;
165640cb5e5dSvi117747 		return (NULL);
165740cb5e5dSvi117747 	}
165840cb5e5dSvi117747 
165940cb5e5dSvi117747 	param = sip_get_param_from_list(value->auth_param, pname);
166040cb5e5dSvi117747 	if (param != NULL)
166140cb5e5dSvi117747 		return (&param->param_value);
166240cb5e5dSvi117747 	return (NULL);
166340cb5e5dSvi117747 }
166440cb5e5dSvi117747 
166540cb5e5dSvi117747 /*
166640cb5e5dSvi117747  * get authentication parameter
166740cb5e5dSvi117747  */
166840cb5e5dSvi117747 const sip_str_t *
166940cb5e5dSvi117747 sip_get_author_param(sip_msg_t sip_msg, char *name, int *error)
167040cb5e5dSvi117747 {
167140cb5e5dSvi117747 	const sip_str_t	*r;
167240cb5e5dSvi117747 
167340cb5e5dSvi117747 	r = sip_get_auth_param(sip_msg, SIP_AUTHOR, name, error);
167440cb5e5dSvi117747 	return (r);
167540cb5e5dSvi117747 }
167640cb5e5dSvi117747 
167740cb5e5dSvi117747 /*
167840cb5e5dSvi117747  * get authentication info
167940cb5e5dSvi117747  */
168040cb5e5dSvi117747 const sip_str_t *
168140cb5e5dSvi117747 sip_get_authen_info(sip_header_value_t value, int *error)
168240cb5e5dSvi117747 {
168340cb5e5dSvi117747 	sip_str_t	*r;
168440cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
168540cb5e5dSvi117747 
168640cb5e5dSvi117747 	if (error != NULL)
168740cb5e5dSvi117747 		*error = 0;
168840cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
168940cb5e5dSvi117747 		if (error != NULL)
169040cb5e5dSvi117747 			*error = EINVAL;
169140cb5e5dSvi117747 		return (NULL);
169240cb5e5dSvi117747 	}
169340cb5e5dSvi117747 	r = sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
169440cb5e5dSvi117747 	return (r);
169540cb5e5dSvi117747 }
169640cb5e5dSvi117747 
169740cb5e5dSvi117747 /*
169840cb5e5dSvi117747  * get proxy-authentication scheme
169940cb5e5dSvi117747  */
170040cb5e5dSvi117747 const sip_str_t *
170140cb5e5dSvi117747 sip_get_proxy_authen_scheme(sip_msg_t msg, int *error)
170240cb5e5dSvi117747 {
170340cb5e5dSvi117747 	sip_str_t	*r;
170440cb5e5dSvi117747 
170540cb5e5dSvi117747 	r = sip_get_val_from_msg(msg, SIP_PROXY_AUTHEN, SIP_AUTH_VAL, B_FALSE,
170640cb5e5dSvi117747 	    B_FALSE, error);
170740cb5e5dSvi117747 	return (r);
170840cb5e5dSvi117747 }
170940cb5e5dSvi117747 
171040cb5e5dSvi117747 /*
171140cb5e5dSvi117747  * get proxy authentication parameter
171240cb5e5dSvi117747  */
171340cb5e5dSvi117747 const sip_str_t *
171440cb5e5dSvi117747 sip_get_proxy_authen_param(sip_msg_t sip_msg, char *name, int *error)
171540cb5e5dSvi117747 {
171640cb5e5dSvi117747 	const sip_str_t	*r;
171740cb5e5dSvi117747 
171840cb5e5dSvi117747 	r = sip_get_auth_param(sip_msg, SIP_PROXY_AUTHEN, name, error);
171940cb5e5dSvi117747 	return (r);
172040cb5e5dSvi117747 }
172140cb5e5dSvi117747 
172240cb5e5dSvi117747 /*
172340cb5e5dSvi117747  * get proxy-authorization scheme
172440cb5e5dSvi117747  */
172540cb5e5dSvi117747 const sip_str_t *
172640cb5e5dSvi117747 sip_get_proxy_author_scheme(sip_msg_t msg, int *error)
172740cb5e5dSvi117747 {
172840cb5e5dSvi117747 	sip_str_t	*r;
172940cb5e5dSvi117747 
173040cb5e5dSvi117747 	r = sip_get_val_from_msg(msg, SIP_PROXY_AUTHOR, SIP_AUTH_VAL, B_FALSE,
173140cb5e5dSvi117747 	    B_FALSE, error);
173240cb5e5dSvi117747 	return (r);
173340cb5e5dSvi117747 }
173440cb5e5dSvi117747 
173540cb5e5dSvi117747 /*
173640cb5e5dSvi117747  * get proxy-authorization parameter
173740cb5e5dSvi117747  */
173840cb5e5dSvi117747 const sip_str_t *
173940cb5e5dSvi117747 sip_get_proxy_author_param(sip_msg_t sip_msg, char *name, int *error)
174040cb5e5dSvi117747 {
174140cb5e5dSvi117747 	const sip_str_t	*r;
174240cb5e5dSvi117747 
174340cb5e5dSvi117747 	r = sip_get_auth_param(sip_msg, SIP_PROXY_AUTHOR, name, error);
174440cb5e5dSvi117747 	return (r);
174540cb5e5dSvi117747 }
174640cb5e5dSvi117747 
174740cb5e5dSvi117747 /*
174840cb5e5dSvi117747  * get proxy-require
174940cb5e5dSvi117747  */
175040cb5e5dSvi117747 const sip_str_t *
175140cb5e5dSvi117747 sip_get_proxy_require(sip_header_value_t value, int *error)
175240cb5e5dSvi117747 {
175340cb5e5dSvi117747 	sip_str_t	*r;
175440cb5e5dSvi117747 	sip_hdr_value_t	*val = (sip_hdr_value_t *)value;
175540cb5e5dSvi117747 
175640cb5e5dSvi117747 	if (error != NULL)
175740cb5e5dSvi117747 		*error = 0;
175840cb5e5dSvi117747 	if (value == NULL || value->value_state == SIP_VALUE_DELETED) {
175940cb5e5dSvi117747 		if (error != NULL)
176040cb5e5dSvi117747 			*error = EINVAL;
176140cb5e5dSvi117747 		return (NULL);
176240cb5e5dSvi117747 	}
176340cb5e5dSvi117747 	r = sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error);
176440cb5e5dSvi117747 	return (r);
176540cb5e5dSvi117747 }
176640cb5e5dSvi117747 
176740cb5e5dSvi117747 /*
176840cb5e5dSvi117747  * get www-authentication scheme
176940cb5e5dSvi117747  */
177040cb5e5dSvi117747 const sip_str_t *
177140cb5e5dSvi117747 sip_get_www_authen_scheme(sip_msg_t msg, int *error)
177240cb5e5dSvi117747 {
177340cb5e5dSvi117747 	sip_str_t	*r;
177440cb5e5dSvi117747 
177540cb5e5dSvi117747 	r = sip_get_val_from_msg(msg, SIP_WWW_AUTHEN, SIP_AUTH_VAL, B_FALSE,
177640cb5e5dSvi117747 	    B_FALSE, error);
177740cb5e5dSvi117747 	return (r);
177840cb5e5dSvi117747 }
177940cb5e5dSvi117747 
178040cb5e5dSvi117747 /*
178140cb5e5dSvi117747  * get www-authentication parameter
178240cb5e5dSvi117747  */
178340cb5e5dSvi117747 const sip_str_t *
178440cb5e5dSvi117747 sip_get_www_authen_param(sip_msg_t sip_msg, char *name, int *error)
178540cb5e5dSvi117747 {
178640cb5e5dSvi117747 	const sip_str_t	*r;
178740cb5e5dSvi117747 
178840cb5e5dSvi117747 	r = sip_get_auth_param(sip_msg, SIP_WWW_AUTHEN, name, error);
178940cb5e5dSvi117747 	return (r);
179040cb5e5dSvi117747 }
1791