diff options
Diffstat (limited to 'usr/src/lib/libsip/common/sip_hdrs_ui.c')
-rw-r--r-- | usr/src/lib/libsip/common/sip_hdrs_ui.c | 1785 |
1 files changed, 1785 insertions, 0 deletions
diff --git a/usr/src/lib/libsip/common/sip_hdrs_ui.c b/usr/src/lib/libsip/common/sip_hdrs_ui.c new file mode 100644 index 0000000000..a10a787fe2 --- /dev/null +++ b/usr/src/lib/libsip/common/sip_hdrs_ui.c @@ -0,0 +1,1785 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "sip_parse_uri.h" +#include "sip_msg.h" +#include "sip_miscdefs.h" + +/* + * Generic function to get int or string value from a header + */ +static void * +sip_get_val_from_hdr(sip_hdr_value_t *val, int val_type, boolean_t stype, + int *error) +{ + if (error != NULL) + *error = 0; + + if (val == NULL || val->sip_value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + if (val->sip_value_state == SIP_VALUE_BAD) + *error = EPROTO; + + switch (val_type) { + case (SIP_INT_VAL): + return (&(val->int_val)); + case (SIP_STR_VAL): + return (&(val->str_val)); + case (SIP_STRS_VAL): + if (stype == B_TRUE) { + if (val->strs_val.s1.sip_str_ptr != NULL) + return (&(val->strs_val.s1)); + return (NULL); + } + if (val->strs_val.s2.sip_str_ptr != NULL) + return (&(val->strs_val.s2)); + return (NULL); + case (SIP_INTSTR_VAL): + if (stype == B_TRUE) { + if (val->intstr_str.sip_str_ptr != NULL) + return (&(val->intstr_str)); + else + return (NULL); + } + return (&(val->intstr_int)); + case (SIP_AUTH_VAL): + return (&(val->auth_val)); + } + if (error != NULL && *error == 0) + *error = EINVAL; + return (NULL); +} + +/* + * Generic function to get value from a header given the value type and + * the string info (for multi-string values). + */ +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) +{ + const _sip_header_t *header; + sip_hdr_value_t *value; + + if (error != NULL) + *error = 0; + if (msg == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + header = sip_get_header(msg, hdr_name, NULL, error); + if (header == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + value = (sip_hdr_value_t *)sip_get_header_value(header, error); + if (value == NULL) { + if (error != NULL && empty_val == B_FALSE) + *error = EPROTO; + return (NULL); + } + return (sip_get_val_from_hdr(value, val_type, stype, error)); +} + +/* + * Get the URI from the value + */ +const sip_str_t * +sip_get_cftruri_from_val(sip_header_value_t value, int *error) +{ + sip_hdr_value_t *cftrvalue; + + if (error != NULL) + *error = 0; + + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + cftrvalue = (sip_hdr_value_t *)value; + /* + * If the value is BAD, update error to reflect it. + */ + if (error != NULL && value->value_state == SIP_VALUE_BAD) + *error = EPROTO; + return (&cftrvalue->cftr_uri); +} + +/* + * Get display name from the value + */ +const sip_str_t * +sip_get_cftrname_from_val(sip_header_value_t value, int *error) +{ + sip_hdr_value_t *cftrvalue; + + if (error != NULL) + *error = 0; + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + cftrvalue = (sip_hdr_value_t *)value; + /* + * If the value is BAD, update error to reflect it. + */ + if (error != NULL && value->value_state == SIP_VALUE_BAD) + *error = EPROTO; + return (cftrvalue->cftr_name); +} + +/* + * Contact header can have more than one value + * so we require a value to be passed in to get a value. + */ +const sip_str_t * +sip_get_contact_uri_str(sip_header_value_t value, int *error) +{ + return (sip_get_cftruri_from_val(value, error)); +} + +/* + * Contact header can have more than one value + * so we require a value to be passed in to get a value. + */ +const sip_str_t * +sip_get_contact_display_name(sip_header_value_t value, int *error) +{ + return (sip_get_cftrname_from_val(value, error)); +} + +/* + * Route header can have more than one value + * so we require a value to be passed in to get a value. + */ +const sip_str_t * +sip_get_route_uri_str(sip_header_value_t value, int *error) +{ + return (sip_get_cftruri_from_val(value, error)); +} + +/* + * Route header can have more than one value + * so we require a value to be passed in to get a value. + */ +const sip_str_t * +sip_get_route_display_name(sip_header_value_t value, int *error) +{ + return (sip_get_cftrname_from_val(value, error)); +} + +/* + * Get URI from the SIP message + */ +const sip_str_t * +sip_get_cftruri_from_msg(sip_msg_t sip_msg, int *error, char *hdrname) +{ + const sip_hdr_value_t *value; + const struct sip_header *header; + + if (error != NULL) + *error = 0; + if (sip_msg == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + header = sip_get_header(sip_msg, hdrname, NULL, error); + if (header == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + value = (sip_hdr_value_t *)sip_get_header_value(header, error); + if (value == NULL) { + if (error != NULL) + *error = EPROTO; + return (NULL); + } + /* + * If the value is BAD, update error to reflect it. + */ + if (error != NULL && value->sip_value_state == SIP_VALUE_BAD) + *error = EPROTO; + return (&value->cftr_uri); +} + +/* + * Get display name from the SIP message + */ +const sip_str_t * +sip_get_cftrname_from_msg(sip_msg_t sip_msg, int *error, char *hdrname) +{ + const sip_hdr_value_t *value; + const struct sip_header *header; + + if (error != NULL) + *error = 0; + if (sip_msg == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + header = sip_get_header(sip_msg, hdrname, NULL, error); + if (header == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + value = (sip_hdr_value_t *)sip_get_header_value(header, error); + if (value == NULL) { + if (error != NULL) + *error = EPROTO; + return (NULL); + } + /* + * If the value is BAD, update error to reflect it. + */ + if (error != NULL && value->sip_value_state == SIP_VALUE_BAD) + *error = EPROTO; + return (value->cftr_name); +} + +/* + * Get FROM URI + */ +const sip_str_t * +sip_get_from_uri_str(sip_msg_t sip_msg, int *error) +{ + return (sip_get_cftruri_from_msg(sip_msg, error, SIP_FROM)); +} + +/* + * Get FROM display name + */ +const sip_str_t * +sip_get_from_display_name(sip_msg_t sip_msg, int *error) +{ + return (sip_get_cftrname_from_msg(sip_msg, error, SIP_FROM)); +} + +/* + * Return the FROM tag + */ +const sip_str_t * +sip_get_from_tag(sip_msg_t sip_msg, int *error) +{ + const sip_hdr_value_t *value; + const struct sip_header *header; + + if (error != NULL) + *error = 0; + if (sip_msg == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + header = sip_get_header(sip_msg, SIP_FROM, NULL, error); + if (header == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + value = (sip_hdr_value_t *)sip_get_header_value(header, error); + if (value == NULL) { + if (error != NULL) + *error = EPROTO; + return (NULL); + } + /* + * If the value is BAD, update error to reflect it. + */ + if (error != NULL && value->sip_value_state == SIP_VALUE_BAD) + *error = EPROTO; + return (sip_get_param_value((sip_header_value_t)value, "tag", error)); +} + +/* + * Get TO URI + */ +const sip_str_t * +sip_get_to_uri_str(sip_msg_t sip_msg, int *error) +{ + return (sip_get_cftruri_from_msg(sip_msg, error, SIP_TO)); +} + +/* + * Get TO display name + */ +const sip_str_t * +sip_get_to_display_name(sip_msg_t sip_msg, int *error) +{ + return (sip_get_cftrname_from_msg(sip_msg, error, SIP_TO)); +} + +/* + * Get TO tag + */ +const sip_str_t * +sip_get_to_tag(sip_msg_t sip_msg, int *error) +{ + const sip_hdr_value_t *value; + const struct sip_header *header; + + if (error != NULL) + *error = 0; + if (sip_msg == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + header = sip_get_header(sip_msg, SIP_TO, NULL, error); + if (header == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + value = (sip_hdr_value_t *)sip_get_header_value(header, error); + if (value == NULL) { + if (error != NULL) + *error = EPROTO; + return (NULL); + } + /* + * If the value is BAD, update error to reflect it. + */ + if (error != NULL && value->sip_value_state == SIP_VALUE_BAD) + *error = EPROTO; + return (sip_get_param_value((sip_header_value_t)value, "tag", error)); +} + +/* + * Return the Call-Id + */ +const sip_str_t * +sip_get_callid(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CALL_ID, SIP_STR_VAL, + B_FALSE, B_TRUE, error); + return (r); +} + +#define SIP_CSEQ_NUM 1 +#define SIP_CSEQ_METHOD 2 + +/* + * Get number/method from the CSEQ header + */ +static void * +sip_get_cseq_val(sip_msg_t msg, int type, int *error) +{ + const _sip_header_t *header; + sip_hdr_value_t *val; + + if (error != NULL) + *error = 0; + + if (msg == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + header = sip_get_header(msg, SIP_CSEQ, NULL, error); + if (header == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + val = (sip_hdr_value_t *)sip_get_header_value(header, error); + if (val == NULL) { + if (error != NULL) + *error = EPROTO; + return (NULL); + } + if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD) + *error = EPROTO; + + switch (type) { + case SIP_CSEQ_NUM: + return (&(val->cseq_num)); + case SIP_CSEQ_METHOD: + return (&(val->cseq_method)); + } + if (error != NULL) + *error = EINVAL; + return (NULL); +} + +/* + * Get CSEQ number + */ +int +sip_get_callseq_num(sip_msg_t sip_msg, int *error) +{ + int *r; + + r = (int *)sip_get_cseq_val(sip_msg, SIP_CSEQ_NUM, error); + return (r == NULL ? -1 : *r); +} + +/* + * Get CSEQ method + */ +sip_method_t +sip_get_callseq_method(sip_msg_t sip_msg, int *error) +{ + sip_method_t *r; + + r = (sip_method_t *)sip_get_cseq_val(sip_msg, SIP_CSEQ_METHOD, error); + return (r == NULL ? -1 : *r); +} + +/* + * Via header can have more than one value + * so we require a value to be passed in. + */ +const sip_str_t * +sip_get_via_sent_by_host(sip_header_value_t value, int *error) +{ + sip_hdr_value_t *via_value; + + if (error != NULL) + *error = 0; + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + via_value = (sip_hdr_value_t *)value; + if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL) + *error = EPROTO; + return (&via_value->via_sent_by_host); +} + +/* + * Via header can have more than one value + * so we require a value to be passed in. + */ +int +sip_get_via_sent_by_port(sip_header_value_t value, int *error) +{ + sip_hdr_value_t *via_value; + + if (error != NULL) + *error = 0; + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (-1); + } + via_value = (sip_hdr_value_t *)value; + if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL) + *error = EPROTO; + return (via_value->via_sent_by_port); +} + +/* + * Return the protocol version from the VIA value + */ +const sip_str_t * +sip_get_via_sent_protocol_version(sip_header_value_t value, int *error) +{ + sip_hdr_value_t *via_value; + + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + via_value = (sip_hdr_value_t *)value; + if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL) + *error = EPROTO; + return (&via_value->via_protocol_vers); +} + +/* + * Return the protocol name + */ +const sip_str_t * +sip_get_via_sent_protocol_name(sip_header_value_t value, int *error) +{ + sip_hdr_value_t *via_value; + + if (error != NULL) + *error = 0; + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + via_value = (sip_hdr_value_t *)value; + if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL) + *error = EPROTO; + return (&via_value->via_protocol_name); +} + +/* + * Return the transport from the VIA value + */ +const sip_str_t * +sip_get_via_sent_transport(sip_header_value_t value, int *error) +{ + sip_hdr_value_t *via_value; + + if (error != NULL) + *error = 0; + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + via_value = (sip_hdr_value_t *)value; + if (via_value->sip_value_state == SIP_VALUE_BAD && error != NULL) + *error = EPROTO; + return (&via_value->via_protocol_transport); +} + +/* + * get the branch id from the topmost VIA header + */ +char * +sip_get_branchid(sip_msg_t sip_msg, int *error) +{ + _sip_header_t *header; + sip_parsed_header_t *parsed_header; + sip_hdr_value_t *via_value; + const sip_str_t *param_value; + char *bid; + _sip_msg_t *_sip_msg; + + if (error != NULL) + *error = 0; + + if (sip_msg == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + _sip_msg = (_sip_msg_t *)sip_msg; + + (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); + header = sip_search_for_header(_sip_msg, SIP_VIA, NULL); + if (header == NULL) { + if (error != NULL) + *error = EINVAL; + (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); + return (NULL); + } + if (sip_parse_via_header(header, &parsed_header) != 0) { + if (error != NULL) + *error = EPROTO; + (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); + return (NULL); + } + if (parsed_header == NULL) { + if (error != NULL) + *error = EPROTO; + (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); + return (NULL); + } + via_value = (sip_hdr_value_t *)parsed_header->value; + if (via_value == NULL || via_value->sip_value_state == SIP_VALUE_BAD) { + if (error != NULL) + *error = EPROTO; + (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); + return (NULL); + } + param_value = sip_get_param_value((sip_header_value_t)via_value, + "branch", error); + + if (param_value == NULL) { + if (error != NULL) + *error = EINVAL; + (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); + return (NULL); + } + + bid = (char *)malloc(param_value->sip_str_len + 1); + if (bid == NULL) { + if (error != NULL) + *error = ENOMEM; + (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); + return (NULL); + } + (void) strncpy(bid, param_value->sip_str_ptr, + param_value->sip_str_len); + bid[param_value->sip_str_len] = '\0'; + (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); + return (bid); +} + +/* + * adds branchid to the topmost VIA header, if a branchid already exists, + * returns error. + */ +int +sip_add_branchid_to_via(sip_msg_t sip_msg, char *branchid) +{ + int err = 0; + char *param; + int plen; + sip_header_t via_hdr; + _sip_msg_t *_sip_msg; + + if (sip_msg == NULL) + return (EINVAL); + /* + * If there is already a branchid param, error? + */ + if (sip_get_branchid(sip_msg, NULL) != NULL) + return (EINVAL); + _sip_msg = (_sip_msg_t *)sip_msg; + (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); + via_hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA, NULL); + (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); + if (via_hdr == NULL) + return (EINVAL); + plen = strlen(branchid) + strlen("branch=") + 1; + param = malloc(plen); + if (param == NULL) + return (ENOMEM); + (void) snprintf(param, plen, "branch=%s", branchid); + + (void) sip_add_param(via_hdr, param, &err); + free(param); + + return (err); +} + +/* + * returns the number of VIA headers in the SIP message + */ +int +sip_get_num_via(sip_msg_t sip_msg, int *error) +{ + _sip_msg_t *_sip_msg; + sip_header_t hdr; + int via_cnt = 0; + + if (error != NULL) + *error = 0; + if (sip_msg == NULL) { + if (error != NULL) + *error = EINVAL; + return (via_cnt); + } + _sip_msg = (_sip_msg_t *)sip_msg; + (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); + hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA, NULL); + while (hdr != NULL) { + via_cnt++; + hdr = (sip_header_t)sip_search_for_header(_sip_msg, SIP_VIA, + hdr); + } + (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); + return (via_cnt); +} + +/* + * Return Max-Forward value + */ +int +sip_get_maxforward(sip_msg_t sip_msg, int *error) +{ + int *r; + + r = (int *)sip_get_val_from_msg(sip_msg, SIP_MAX_FORWARDS, SIP_INT_VAL, + B_FALSE, B_FALSE, error); + if (r == NULL) + return (-1); + return (*r); +} + +/* + * Get the content type + */ +const sip_str_t * +sip_get_content_type(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_TYPE, + SIP_STRS_VAL, B_TRUE, B_FALSE, error); + return (r); +} + +/* + * Get the content sub-type + */ +const sip_str_t * +sip_get_content_sub_type(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_TYPE, + SIP_STRS_VAL, B_FALSE, B_FALSE, error); + return (r); +} + +/* + * Return the content-length value + */ +int +sip_get_content_length(sip_msg_t sip_msg, int *error) +{ + int *r; + + r = (int *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_LENGTH, + SIP_INT_VAL, B_FALSE, B_FALSE, error); + if (r == NULL) + return (-1); + return (*r); +} + +/* + * get allow-events + */ +const sip_str_t * +sip_get_allow_events(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_TRUE, error); + return (r); +} + +/* + * get event + */ +const sip_str_t * +sip_get_event(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_EVENT, SIP_STR_VAL, + B_FALSE, B_FALSE, error); + return (r); +} + +/* + * get subscription state + */ +const sip_str_t * +sip_get_substate(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SUBSCRIPTION_STATE, + SIP_STR_VAL, B_FALSE, B_FALSE, error); + return (r); +} + +/* + * get accept type + */ +const sip_str_t * +sip_get_accept_type(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_TRUE, error); + return (r); +} + +/* + * get accept subtype + */ +const sip_str_t * +sip_get_accept_sub_type(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_FALSE, + error); + return (r); +} + +/* + * accept-encode can have more than one value + */ +const sip_str_t * +sip_get_accept_enc(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * accept-language can have more than one value + */ +const sip_str_t * +sip_get_accept_lang(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * get URI from the alert-info header + */ +const sip_str_t * +sip_get_alert_info_uri(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * get method from allow header + */ +sip_method_t +sip_get_allow_method(sip_header_value_t value, int *error) +{ + int *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (int *)sip_get_val_from_hdr(val, SIP_INT_VAL, B_FALSE, error); + return (r == NULL ? -1 : (sip_method_t)*r); +} + +/* + * get URI from call-info header + */ +const sip_str_t * +sip_get_call_info_uri(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * get content-disposition value + */ +const sip_str_t * +sip_get_content_disp(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_CONTENT_DIS, + SIP_STR_VAL, B_FALSE, B_FALSE, error); + return (r); +} + +/* + * get content-encoding value + */ +const sip_str_t * +sip_get_content_enc(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * get content-language value + */ +const sip_str_t * +sip_get_content_lang(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * sip_get_date_time, day, wkday, month, year + */ +#define D_TIME 0x01 +#define D_DAY 0x02 +#define D_MONTH 0x03 +#define D_YEAR 0x04 +#define D_WKDAY 0x05 +#define D_TIMEZONE 0x06 + +/* + * get date information + */ +static void * +sip_get_date_val(sip_msg_t msg, int type, int *error) +{ + const _sip_header_t *header; + sip_hdr_value_t *val; + + if (error != NULL) + *error = 0; + if (msg == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + header = sip_get_header(msg, SIP_DATE, NULL, error); + if (header == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + val = (sip_hdr_value_t *)sip_get_header_value(header, error); + if (val == NULL) { + if (error != NULL) + *error = EPROTO; + return (NULL); + } + if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD) + *error = EPROTO; + switch (type) { + case (D_TIME): + return (&(val->date_t)); + case (D_DAY): + return (&(val->date_d)); + case (D_MONTH): + return (&(val->date_m)); + case (D_YEAR): + return (&(val->date_y)); + case (D_WKDAY): + return (&(val->date_wd)); + case (D_TIMEZONE): + return (&(val->date_tz)); + } + if (error != NULL) + *error = EINVAL; + return (NULL); +} + +/* + * get time value + */ +const sip_str_t * +sip_get_date_time(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_date_val(sip_msg, D_TIME, error); + return (r); +} + +/* + * get day + */ +int +sip_get_date_day(sip_msg_t sip_msg, int *error) +{ + int *r = NULL; + + r = sip_get_date_val(sip_msg, D_DAY, error); + return (r == NULL ? -1 : *(int *)r); +} + +/* + * get month + */ +const sip_str_t * +sip_get_date_month(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_date_val(sip_msg, D_MONTH, error); + return (r); +} + +/* + * get year + */ +int +sip_get_date_year(sip_msg_t sip_msg, int *error) +{ + int *r; + + r = (int *)sip_get_date_val(sip_msg, D_YEAR, error); + return (r == NULL ? -1 : *r); +} + +/* + * get day of the week + */ +const sip_str_t * +sip_get_date_wkday(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_date_val(sip_msg, D_WKDAY, error); + return (r); +} + +/* + * get the timezone + */ +const sip_str_t * +sip_get_date_timezone(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_date_val(sip_msg, D_TIMEZONE, error); + return (r); +} + +/* + * get error-info URI + */ +const sip_str_t * +sip_get_error_info_uri(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * get priv-value from privacy + */ +const sip_str_t * +sip_get_priv_value(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * return expires value + */ +int +sip_get_expires(sip_msg_t sip_msg, int *error) +{ + int *r; + + r = (int *)sip_get_val_from_msg(sip_msg, SIP_EXPIRE, SIP_INT_VAL, + B_FALSE, B_FALSE, error); + if (r == NULL) + return (-1); + return (*r); +} + +/* + * get reply-to value + */ +const sip_str_t * +sip_get_in_reply_to(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * get min-expires value + */ +int +sip_get_min_expires(sip_msg_t sip_msg, int *error) +{ + int *r; + + r = (int *)sip_get_val_from_msg(sip_msg, SIP_MIN_EXPIRE, SIP_INT_VAL, + B_FALSE, B_FALSE, error); + if (r == NULL) + return (-1); + return (*r); +} + +/* + * get mime-version + */ +const sip_str_t * +sip_get_mime_version(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_MIME_VERSION, + SIP_STR_VAL, B_FALSE, B_FALSE, error); + return (r); +} + +/* + * get organization value + */ +const sip_str_t * +sip_get_org(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_ORGANIZATION, + SIP_STR_VAL, B_FALSE, B_TRUE, error); + return (r); +} + +/* + * get priority value + */ +const sip_str_t * +sip_get_priority(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_PRIORITY, + SIP_STR_VAL, B_FALSE, B_FALSE, error); + return (r); +} + +/* + * get display name + */ +const sip_str_t * +sip_get_pidentity_display_name(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_TRUE, error); + + return (r); +} + +/* + * get URI + */ +const sip_str_t * +sip_get_pidenty_uri_str(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STRS_VAL, B_FALSE, + error); + + return (r); +} + +/* + * get display name from passerted-identity header + */ +const sip_str_t * +sip_get_passertedid_display_name(sip_header_value_t value, int *error) +{ + return (sip_get_pidentity_display_name(value, error)); +} + +/* + * get URI from passerted-identity header + */ +const sip_str_t * +sip_get_passertedid_uri_str(sip_header_value_t value, int *error) +{ + return (sip_get_pidenty_uri_str(value, error)); +} + +/* + * get display name from ppreferred-identity header + */ +const sip_str_t * +sip_get_ppreferredid_display_name(sip_header_value_t value, int *error) +{ + return (sip_get_pidentity_display_name(value, error)); +} + +/* + * get URI from ppreferred-identity header + */ +const sip_str_t * +sip_get_ppreferredid_uri_str(sip_header_value_t value, int *error) +{ + return (sip_get_pidenty_uri_str(value, error)); +} + +#define SIP_RACK_RESP_NUM 1 +#define SIP_RACK_CSEQ_NUM 2 +#define SIP_RACK_METHOD 3 + +/* + * Get rack information + */ +static void * +sip_get_rack_val(sip_msg_t msg, int type, int *error) +{ + const _sip_header_t *header; + sip_hdr_value_t *val; + + if (error != NULL) + *error = 0; + + if (msg == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + header = sip_get_header(msg, SIP_RACK, NULL, error); + if (header == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + val = (sip_hdr_value_t *)sip_get_header_value(header, error); + if (val == NULL) { + if (error != NULL) + *error = EPROTO; + return (NULL); + } + if (error != NULL && val->sip_value.value_state == SIP_VALUE_BAD) + *error = EPROTO; + + switch (type) { + case SIP_RACK_RESP_NUM: + return (&(val->rack_resp)); + case SIP_RACK_CSEQ_NUM: + return (&(val->rack_cseq)); + case SIP_RACK_METHOD: + return (&(val->rack_method)); + } + if (error != NULL) + *error = EINVAL; + return (NULL); +} + +/* + * get response number for rack + */ +int +sip_get_rack_resp_num(sip_msg_t sip_msg, int *error) +{ + int *r; + + r = (int *)sip_get_rack_val(sip_msg, SIP_RACK_RESP_NUM, error); + + return (r == NULL ? -1 : *r); +} + +/* + * get sequence number for rack + */ +int +sip_get_rack_cseq_num(sip_msg_t sip_msg, int *error) +{ + int *r; + + r = (int *)sip_get_rack_val(sip_msg, SIP_RACK_CSEQ_NUM, error); + + return (r == NULL ? -1 : *r); +} + +/* + * get method for rack + */ +sip_method_t +sip_get_rack_method(sip_msg_t sip_msg, int *error) +{ + sip_method_t *r; + + r = (sip_method_t *)sip_get_rack_val(sip_msg, SIP_RACK_METHOD, error); + + return (r == NULL ? -1 : *r); +} + +/* + * get response number from rseq + */ +int +sip_get_rseq_resp_num(sip_msg_t sip_msg, int *error) +{ + int *r; + + r = (int *)sip_get_val_from_msg(sip_msg, SIP_RSEQ, SIP_INT_VAL, + B_FALSE, B_FALSE, error); + + return (r == NULL ? -1 : *r); +} + +/* + * get reply-to display name + */ +const sip_str_t * +sip_get_replyto_display_name(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_REPLYTO, + SIP_STRS_VAL, B_TRUE, B_FALSE, error); + return (r); +} + +/* + * get reply-to URI + */ +const sip_str_t * +sip_get_replyto_uri_str(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_REPLYTO, + SIP_STRS_VAL, B_FALSE, B_FALSE, error); + + return (r); +} + +/* + * get require value + */ +const sip_str_t * +sip_get_require(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * get retry-after time + */ +int +sip_get_retry_after_time(sip_msg_t sip_msg, int *error) +{ + int *t; + + t = (int *)sip_get_val_from_msg(sip_msg, SIP_RETRY_AFTER, + SIP_INTSTR_VAL, B_FALSE, B_FALSE, error); + if (t == NULL) + return (-1); + return (*t); +} + +/* + * get retry-after comments + */ +const sip_str_t * +sip_get_retry_after_cmts(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_RETRY_AFTER, + SIP_INTSTR_VAL, B_TRUE, B_FALSE, error); + return (r); +} + +/* + * get subject + */ +const sip_str_t * +sip_get_subject(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SUBJECT, SIP_STR_VAL, + B_FALSE, B_TRUE, error); + return (r); +} + +/* + * get supported + */ +const sip_str_t * +sip_get_supported(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * get timestamp delay + */ +const sip_str_t * +sip_get_tstamp_delay(sip_msg_t sip_msg, int *error) +{ + sip_str_t *t; + + t = sip_get_val_from_msg(sip_msg, SIP_TIMESTAMP, SIP_STRS_VAL, B_FALSE, + B_FALSE, error); + return (t); +} + +/* + * get timestamp + */ +const sip_str_t * +sip_get_tstamp_value(sip_msg_t sip_msg, int *error) +{ + sip_str_t *t; + + t = sip_get_val_from_msg(sip_msg, SIP_TIMESTAMP, SIP_STRS_VAL, B_TRUE, + B_FALSE, error); + return (t); +} + +/* + * get unsupported value + */ +const sip_str_t * +sip_get_unsupported(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + r = (sip_str_t *)sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * get server value from message + */ +const sip_str_t * +sip_get_server(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = (sip_str_t *)sip_get_val_from_msg(sip_msg, SIP_SERVER, SIP_STR_VAL, + B_FALSE, B_FALSE, error); + return (r); +} + +/* + * get user-agent value + */ +const sip_str_t * +sip_get_user_agent(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = sip_get_val_from_msg(sip_msg, SIP_USER_AGENT, SIP_STR_VAL, B_FALSE, + B_FALSE, error); + return (r); +} + +#define W_CODE 0x05 +#define W_AGENT 0x06 +#define W_TEXT 0x07 + +/* + * get warning info + */ +static void * +sip_get_warninfo(sip_header_value_t value, int info, int *error) +{ + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + if (error != NULL) + *error = 0; + + if (val == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + if (val->sip_value_state == SIP_VALUE_BAD) { + *error = EPROTO; + return (NULL); + } + + switch (info) { + case (W_CODE): + return (&(val->warn_code)); + case (W_AGENT): + return (&(val->warn_agt)); + case (W_TEXT): + return (&(val->warn_text)); + } + if (error != NULL) + *error = EINVAL; + return (NULL); +} + +/* + * get warning code + */ +int +sip_get_warning_code(sip_header_value_t value, int *error) +{ + int *c; + + if (error != NULL) + *error = 0; + + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (-1); + } + c = (int *)sip_get_warninfo(value, W_CODE, error); + if (c == NULL) + return (-1); + return (*c); +} + +/* + * get warning agent + */ +const sip_str_t * +sip_get_warning_agent(sip_header_value_t value, int *error) +{ + sip_str_t *r; + + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + r = (sip_str_t *)sip_get_warninfo(value, W_AGENT, error); + return (r); +} + +/* + * get warning text + */ +const sip_str_t * +sip_get_warning_text(sip_header_value_t value, int *error) +{ + sip_str_t *r; + + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + r = (sip_str_t *)sip_get_warninfo(value, W_TEXT, error); + return (r); +} + +/* + * get authorization scheme + */ +const sip_str_t * +sip_get_author_scheme(sip_msg_t sip_msg, int *error) +{ + sip_str_t *r; + + r = sip_get_val_from_msg(sip_msg, SIP_AUTHOR, SIP_AUTH_VAL, B_FALSE, + B_FALSE, error); + return (r); +} + +/* + * get authentication parameter + */ +static const sip_str_t * +sip_get_auth_param(sip_msg_t msg, char *hdr_name, char *pname, int *error) +{ + const _sip_header_t *header; + sip_hdr_value_t *value; + sip_param_t *param; + + if (error != NULL) + *error = 0; + + if (msg == NULL || pname == NULL || hdr_name == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + header = sip_get_header(msg, hdr_name, NULL, error); + if (header == NULL) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + + value = (sip_hdr_value_t *)sip_get_header_value(header, error); + if (value == NULL) { + if (error != NULL) + *error = EPROTO; + return (NULL); + } + + param = sip_get_param_from_list(value->auth_param, pname); + if (param != NULL) + return (¶m->param_value); + return (NULL); +} + +/* + * get authentication parameter + */ +const sip_str_t * +sip_get_author_param(sip_msg_t sip_msg, char *name, int *error) +{ + const sip_str_t *r; + + r = sip_get_auth_param(sip_msg, SIP_AUTHOR, name, error); + return (r); +} + +/* + * get authentication info + */ +const sip_str_t * +sip_get_authen_info(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + if (error != NULL) + *error = 0; + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + r = sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * get proxy-authentication scheme + */ +const sip_str_t * +sip_get_proxy_authen_scheme(sip_msg_t msg, int *error) +{ + sip_str_t *r; + + r = sip_get_val_from_msg(msg, SIP_PROXY_AUTHEN, SIP_AUTH_VAL, B_FALSE, + B_FALSE, error); + return (r); +} + +/* + * get proxy authentication parameter + */ +const sip_str_t * +sip_get_proxy_authen_param(sip_msg_t sip_msg, char *name, int *error) +{ + const sip_str_t *r; + + r = sip_get_auth_param(sip_msg, SIP_PROXY_AUTHEN, name, error); + return (r); +} + +/* + * get proxy-authorization scheme + */ +const sip_str_t * +sip_get_proxy_author_scheme(sip_msg_t msg, int *error) +{ + sip_str_t *r; + + r = sip_get_val_from_msg(msg, SIP_PROXY_AUTHOR, SIP_AUTH_VAL, B_FALSE, + B_FALSE, error); + return (r); +} + +/* + * get proxy-authorization parameter + */ +const sip_str_t * +sip_get_proxy_author_param(sip_msg_t sip_msg, char *name, int *error) +{ + const sip_str_t *r; + + r = sip_get_auth_param(sip_msg, SIP_PROXY_AUTHOR, name, error); + return (r); +} + +/* + * get proxy-require + */ +const sip_str_t * +sip_get_proxy_require(sip_header_value_t value, int *error) +{ + sip_str_t *r; + sip_hdr_value_t *val = (sip_hdr_value_t *)value; + + if (error != NULL) + *error = 0; + if (value == NULL || value->value_state == SIP_VALUE_DELETED) { + if (error != NULL) + *error = EINVAL; + return (NULL); + } + r = sip_get_val_from_hdr(val, SIP_STR_VAL, B_FALSE, error); + return (r); +} + +/* + * get www-authentication scheme + */ +const sip_str_t * +sip_get_www_authen_scheme(sip_msg_t msg, int *error) +{ + sip_str_t *r; + + r = sip_get_val_from_msg(msg, SIP_WWW_AUTHEN, SIP_AUTH_VAL, B_FALSE, + B_FALSE, error); + return (r); +} + +/* + * get www-authentication parameter + */ +const sip_str_t * +sip_get_www_authen_param(sip_msg_t sip_msg, char *name, int *error) +{ + const sip_str_t *r; + + r = sip_get_auth_param(sip_msg, SIP_WWW_AUTHEN, name, error); + return (r); +} |