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