140cb5e5dSvi117747 /* 240cb5e5dSvi117747 * CDDL HEADER START 340cb5e5dSvi117747 * 440cb5e5dSvi117747 * The contents of this file are subject to the terms of the 540cb5e5dSvi117747 * Common Development and Distribution License (the "License"). 640cb5e5dSvi117747 * You may not use this file except in compliance with the License. 740cb5e5dSvi117747 * 840cb5e5dSvi117747 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 940cb5e5dSvi117747 * or http://www.opensolaris.org/os/licensing. 1040cb5e5dSvi117747 * See the License for the specific language governing permissions 1140cb5e5dSvi117747 * and limitations under the License. 1240cb5e5dSvi117747 * 1340cb5e5dSvi117747 * When distributing Covered Code, include this CDDL HEADER in each 1440cb5e5dSvi117747 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1540cb5e5dSvi117747 * If applicable, add the following below this CDDL HEADER, with the 1640cb5e5dSvi117747 * fields enclosed by brackets "[]" replaced with your own identifying 1740cb5e5dSvi117747 * information: Portions Copyright [yyyy] [name of copyright owner] 1840cb5e5dSvi117747 * 1940cb5e5dSvi117747 * CDDL HEADER END 2040cb5e5dSvi117747 */ 2140cb5e5dSvi117747 2240cb5e5dSvi117747 /* 23*2c2c4183Svi117747 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 2440cb5e5dSvi117747 * Use is subject to license terms. 2540cb5e5dSvi117747 */ 2640cb5e5dSvi117747 2740cb5e5dSvi117747 #pragma ident "%Z%%M% %I% %E% SMI" 2840cb5e5dSvi117747 29*2c2c4183Svi117747 #include <stdio.h> 30*2c2c4183Svi117747 #include <ctype.h> 31*2c2c4183Svi117747 #include <errno.h> 32*2c2c4183Svi117747 #include <pthread.h> 33*2c2c4183Svi117747 #include <strings.h> 34*2c2c4183Svi117747 #include <stdlib.h> 35*2c2c4183Svi117747 #include <sip.h> 36*2c2c4183Svi117747 3740cb5e5dSvi117747 #include "sip_msg.h" 3840cb5e5dSvi117747 #include "sip_miscdefs.h" 3940cb5e5dSvi117747 4040cb5e5dSvi117747 /* 4140cb5e5dSvi117747 * Returns number of digits in the given int 4240cb5e5dSvi117747 */ 4340cb5e5dSvi117747 static int 4440cb5e5dSvi117747 sip_num_of_digits(int num) 4540cb5e5dSvi117747 { 4640cb5e5dSvi117747 int num_of_bytes = 0; 4740cb5e5dSvi117747 4840cb5e5dSvi117747 do { 4940cb5e5dSvi117747 num_of_bytes += 1; 5040cb5e5dSvi117747 num = num / 10; 5140cb5e5dSvi117747 } while (num > 0); 5240cb5e5dSvi117747 return (num_of_bytes); 5340cb5e5dSvi117747 } 5440cb5e5dSvi117747 5540cb5e5dSvi117747 /* 5640cb5e5dSvi117747 * Return the int as a string 5740cb5e5dSvi117747 */ 5840cb5e5dSvi117747 static char * 5940cb5e5dSvi117747 sip_int_to_str(int i) 6040cb5e5dSvi117747 { 6140cb5e5dSvi117747 int count; 6240cb5e5dSvi117747 int t; 6340cb5e5dSvi117747 int x; 6440cb5e5dSvi117747 char *str; 6540cb5e5dSvi117747 6640cb5e5dSvi117747 if (i < 0) 6740cb5e5dSvi117747 return (NULL); 6840cb5e5dSvi117747 /* 6940cb5e5dSvi117747 * the following two loops convert int i to str 7040cb5e5dSvi117747 */ 7140cb5e5dSvi117747 count = 1; 7240cb5e5dSvi117747 t = i; 7340cb5e5dSvi117747 while ((t = t / 10) != 0) { 7440cb5e5dSvi117747 count++; 7540cb5e5dSvi117747 } 7640cb5e5dSvi117747 7740cb5e5dSvi117747 str = calloc(1, sizeof (char) * count + 1); 7840cb5e5dSvi117747 if (str == NULL) 7940cb5e5dSvi117747 return (NULL); 8040cb5e5dSvi117747 t = i; 8140cb5e5dSvi117747 for (x = 0; x < count; x++) { 8240cb5e5dSvi117747 int a; 8340cb5e5dSvi117747 a = t % 10; 8440cb5e5dSvi117747 str[count - 1 - x] = a + '0'; 8540cb5e5dSvi117747 t = t / 10; 8640cb5e5dSvi117747 } 8740cb5e5dSvi117747 str[count] = '\0'; 8840cb5e5dSvi117747 return (str); 8940cb5e5dSvi117747 } 9040cb5e5dSvi117747 9140cb5e5dSvi117747 /* 9240cb5e5dSvi117747 * Add quotes to the give str and return the quoted string 9340cb5e5dSvi117747 */ 9440cb5e5dSvi117747 static char * 9540cb5e5dSvi117747 sip_add_aquot_to_str(char *str, boolean_t *alloc) 9640cb5e5dSvi117747 { 9740cb5e5dSvi117747 char *new_str; 9840cb5e5dSvi117747 char *tmp = str; 9940cb5e5dSvi117747 int size; 10040cb5e5dSvi117747 10140cb5e5dSvi117747 while (isspace(*tmp)) 10240cb5e5dSvi117747 tmp++; 10340cb5e5dSvi117747 10440cb5e5dSvi117747 *alloc = B_FALSE; 10540cb5e5dSvi117747 if (*tmp != SIP_LAQUOT) { 10640cb5e5dSvi117747 size = strlen(str) + 2 * sizeof (char); 10740cb5e5dSvi117747 new_str = calloc(1, size + 1); 10840cb5e5dSvi117747 if (new_str == NULL) 10940cb5e5dSvi117747 return (NULL); 11040cb5e5dSvi117747 new_str[0] = SIP_LAQUOT; 11140cb5e5dSvi117747 new_str[1] = '\0'; 11240cb5e5dSvi117747 (void) strncat(new_str, str, strlen(str)); 11340cb5e5dSvi117747 (void) strncat(new_str, ">", 1); 11440cb5e5dSvi117747 new_str[size] = '\0'; 11540cb5e5dSvi117747 *alloc = B_TRUE; 11640cb5e5dSvi117747 return (new_str); 11740cb5e5dSvi117747 } 11840cb5e5dSvi117747 11940cb5e5dSvi117747 return (str); 12040cb5e5dSvi117747 } 12140cb5e5dSvi117747 12240cb5e5dSvi117747 /* 12340cb5e5dSvi117747 * Add an empty header 12440cb5e5dSvi117747 */ 12540cb5e5dSvi117747 static int 12640cb5e5dSvi117747 sip_add_empty_hdr(sip_msg_t sip_msg, char *hdr_name) 12740cb5e5dSvi117747 { 12840cb5e5dSvi117747 _sip_header_t *new_header; 12940cb5e5dSvi117747 int header_size; 13040cb5e5dSvi117747 _sip_msg_t *_sip_msg; 13140cb5e5dSvi117747 int csize = sizeof (char); 13240cb5e5dSvi117747 13340cb5e5dSvi117747 if (sip_msg == NULL || hdr_name == NULL) 13440cb5e5dSvi117747 return (EINVAL); 13540cb5e5dSvi117747 _sip_msg = (_sip_msg_t *)sip_msg; 13640cb5e5dSvi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 13740cb5e5dSvi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 13840cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 13940cb5e5dSvi117747 return (ENOTSUP); 14040cb5e5dSvi117747 } 14140cb5e5dSvi117747 14240cb5e5dSvi117747 header_size = strlen(hdr_name) + SIP_SPACE_LEN + csize; 14340cb5e5dSvi117747 14440cb5e5dSvi117747 new_header = sip_new_header(header_size); 14540cb5e5dSvi117747 if (new_header == NULL) { 14640cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 14740cb5e5dSvi117747 return (ENOMEM); 14840cb5e5dSvi117747 } 14940cb5e5dSvi117747 15040cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 15140cb5e5dSvi117747 "%s %c", hdr_name, SIP_HCOLON); 15240cb5e5dSvi117747 15340cb5e5dSvi117747 _sip_add_header(_sip_msg, new_header, B_TRUE, B_FALSE, hdr_name); 15440cb5e5dSvi117747 if (_sip_msg->sip_msg_buf != NULL) 15540cb5e5dSvi117747 _sip_msg->sip_msg_modified = B_TRUE; 15640cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 15740cb5e5dSvi117747 15840cb5e5dSvi117747 return (0); 15940cb5e5dSvi117747 } 16040cb5e5dSvi117747 16140cb5e5dSvi117747 /* 16240cb5e5dSvi117747 * Generic function to add a header with two strings to message 16340cb5e5dSvi117747 */ 16440cb5e5dSvi117747 static int 16540cb5e5dSvi117747 sip_add_2strs_to_msg(sip_msg_t sip_msg, char *hdr_name, char *str1, 16640cb5e5dSvi117747 boolean_t qstr1, char *str2, char *plist, char sep) 16740cb5e5dSvi117747 { 16840cb5e5dSvi117747 _sip_header_t *new_header; 16940cb5e5dSvi117747 int header_size; 17040cb5e5dSvi117747 _sip_msg_t *_sip_msg; 17140cb5e5dSvi117747 int csize = sizeof (char); 17240cb5e5dSvi117747 17340cb5e5dSvi117747 if (sip_msg == NULL || str1 == NULL || str2 == NULL || 17440cb5e5dSvi117747 (str1 != NULL && str1[0] == '\0') || 17540cb5e5dSvi117747 (str2 != NULL && str2[0] == '\0')) { 17640cb5e5dSvi117747 return (EINVAL); 17740cb5e5dSvi117747 } 17840cb5e5dSvi117747 _sip_msg = (_sip_msg_t *)sip_msg; 17940cb5e5dSvi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 18040cb5e5dSvi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 18140cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 18240cb5e5dSvi117747 return (ENOTSUP); 18340cb5e5dSvi117747 } 18440cb5e5dSvi117747 18540cb5e5dSvi117747 if (plist == NULL) { 18640cb5e5dSvi117747 header_size = strlen(hdr_name) + SIP_SPACE_LEN + csize + 18740cb5e5dSvi117747 SIP_SPACE_LEN + strlen(str1) + csize + strlen(str2) + 18840cb5e5dSvi117747 strlen(SIP_CRLF); 18940cb5e5dSvi117747 } else { 19040cb5e5dSvi117747 header_size = strlen(hdr_name) + SIP_SPACE_LEN + csize + 19140cb5e5dSvi117747 SIP_SPACE_LEN + strlen(str1) + csize + strlen(str2) + 19240cb5e5dSvi117747 csize + strlen(plist) + strlen(SIP_CRLF); 19340cb5e5dSvi117747 } 19440cb5e5dSvi117747 if (qstr1) 19540cb5e5dSvi117747 header_size += 2 * sizeof (char); 19640cb5e5dSvi117747 19740cb5e5dSvi117747 new_header = sip_new_header(header_size); 19840cb5e5dSvi117747 if (new_header == NULL) { 19940cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 20040cb5e5dSvi117747 return (ENOMEM); 20140cb5e5dSvi117747 } 20240cb5e5dSvi117747 20340cb5e5dSvi117747 if (plist == NULL) { 20440cb5e5dSvi117747 if (qstr1) { 20540cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, 20640cb5e5dSvi117747 header_size + 1, "%s %c \"%s\"%c%s%s", 20740cb5e5dSvi117747 hdr_name, SIP_HCOLON, str1, sep, str2, SIP_CRLF); 20840cb5e5dSvi117747 } else { 20940cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, 21040cb5e5dSvi117747 header_size + 1, "%s %c %s%c%s%s", 21140cb5e5dSvi117747 hdr_name, SIP_HCOLON, str1, sep, str2, SIP_CRLF); 21240cb5e5dSvi117747 } 21340cb5e5dSvi117747 } else { 21440cb5e5dSvi117747 if (qstr1) { 21540cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, 21640cb5e5dSvi117747 header_size + 1, 21740cb5e5dSvi117747 "%s %c \"%s\"%c%s%c%s%s", hdr_name, SIP_HCOLON, 21840cb5e5dSvi117747 str1, sep, str2, SIP_SEMI, plist, SIP_CRLF); 21940cb5e5dSvi117747 } else { 22040cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, 22140cb5e5dSvi117747 header_size + 1, "%s %c %s%c%s%c%s%s", 22240cb5e5dSvi117747 hdr_name, SIP_HCOLON, str1, sep, str2, SIP_SEMI, 22340cb5e5dSvi117747 plist, SIP_CRLF); 22440cb5e5dSvi117747 } 22540cb5e5dSvi117747 } 22640cb5e5dSvi117747 _sip_add_header(_sip_msg, new_header, B_TRUE, B_FALSE, NULL); 22740cb5e5dSvi117747 if (_sip_msg->sip_msg_buf != NULL) 22840cb5e5dSvi117747 _sip_msg->sip_msg_modified = B_TRUE; 22940cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 23040cb5e5dSvi117747 23140cb5e5dSvi117747 return (0); 23240cb5e5dSvi117747 } 23340cb5e5dSvi117747 23440cb5e5dSvi117747 /* 23540cb5e5dSvi117747 * Generic function to add a header with a string to message 23640cb5e5dSvi117747 */ 23740cb5e5dSvi117747 static int 23840cb5e5dSvi117747 sip_add_str_to_msg(sip_msg_t sip_msg, char *hdr_name, char *str, char *plist, 23940cb5e5dSvi117747 char param_sep) 24040cb5e5dSvi117747 { 24140cb5e5dSvi117747 _sip_header_t *new_header; 24240cb5e5dSvi117747 int header_size; 24340cb5e5dSvi117747 _sip_msg_t *_sip_msg; 24440cb5e5dSvi117747 int csize = sizeof (char); 24540cb5e5dSvi117747 24640cb5e5dSvi117747 if (sip_msg == NULL || str == NULL || (str != NULL && str[0] == '\0')) 24740cb5e5dSvi117747 return (EINVAL); 24840cb5e5dSvi117747 _sip_msg = (_sip_msg_t *)sip_msg; 24940cb5e5dSvi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 25040cb5e5dSvi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 25140cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 25240cb5e5dSvi117747 return (ENOTSUP); 25340cb5e5dSvi117747 } 25440cb5e5dSvi117747 25540cb5e5dSvi117747 if (plist == NULL) { 25640cb5e5dSvi117747 header_size = strlen(hdr_name) + SIP_SPACE_LEN + csize + 25740cb5e5dSvi117747 SIP_SPACE_LEN + + strlen(str) + strlen(SIP_CRLF); 25840cb5e5dSvi117747 } else { 25940cb5e5dSvi117747 header_size = strlen(hdr_name) + SIP_SPACE_LEN + csize + 26040cb5e5dSvi117747 SIP_SPACE_LEN + + strlen(str) + csize + strlen(plist) + 26140cb5e5dSvi117747 strlen(SIP_CRLF); 26240cb5e5dSvi117747 } 26340cb5e5dSvi117747 26440cb5e5dSvi117747 new_header = sip_new_header(header_size); 26540cb5e5dSvi117747 if (new_header == NULL) { 26640cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 26740cb5e5dSvi117747 return (ENOMEM); 26840cb5e5dSvi117747 } 26940cb5e5dSvi117747 if (plist == NULL) { 27040cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 27140cb5e5dSvi117747 "%s %c %s%s", hdr_name, SIP_HCOLON, str, SIP_CRLF); 27240cb5e5dSvi117747 } else { 27340cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 27440cb5e5dSvi117747 "%s %c %s%c%s%s", hdr_name, SIP_HCOLON, str, param_sep, 27540cb5e5dSvi117747 plist, SIP_CRLF); 27640cb5e5dSvi117747 } 27740cb5e5dSvi117747 _sip_add_header(_sip_msg, new_header, B_TRUE, B_FALSE, NULL); 27840cb5e5dSvi117747 if (_sip_msg->sip_msg_buf != NULL) 27940cb5e5dSvi117747 _sip_msg->sip_msg_modified = B_TRUE; 28040cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 28140cb5e5dSvi117747 28240cb5e5dSvi117747 return (0); 28340cb5e5dSvi117747 } 28440cb5e5dSvi117747 28540cb5e5dSvi117747 /* 28640cb5e5dSvi117747 * Add an header with an int to sip_msg 28740cb5e5dSvi117747 */ 28840cb5e5dSvi117747 static int 28940cb5e5dSvi117747 sip_add_int_to_msg(sip_msg_t sip_msg, char *hdr_name, int i, char *plist) 29040cb5e5dSvi117747 { 29140cb5e5dSvi117747 _sip_header_t *new_header; 29240cb5e5dSvi117747 int header_size; 29340cb5e5dSvi117747 _sip_msg_t *_sip_msg; 29440cb5e5dSvi117747 char *digit_str; 29540cb5e5dSvi117747 int csize = sizeof (char); 29640cb5e5dSvi117747 29740cb5e5dSvi117747 if (sip_msg == NULL || (hdr_name == NULL)) 29840cb5e5dSvi117747 return (EINVAL); 29940cb5e5dSvi117747 _sip_msg = (_sip_msg_t *)sip_msg; 30040cb5e5dSvi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 30140cb5e5dSvi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 30240cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 30340cb5e5dSvi117747 return (ENOTSUP); 30440cb5e5dSvi117747 } 30540cb5e5dSvi117747 30640cb5e5dSvi117747 /* 30740cb5e5dSvi117747 * the following two loops convert int i to str 30840cb5e5dSvi117747 */ 30940cb5e5dSvi117747 digit_str = sip_int_to_str(i); 31040cb5e5dSvi117747 if (digit_str == NULL) 31140cb5e5dSvi117747 return (EINVAL); 31240cb5e5dSvi117747 31340cb5e5dSvi117747 if (plist == NULL) { 31440cb5e5dSvi117747 header_size = strlen(hdr_name) + SIP_SPACE_LEN + csize + 31540cb5e5dSvi117747 SIP_SPACE_LEN + strlen(digit_str) + strlen(SIP_CRLF); 31640cb5e5dSvi117747 } else { 31740cb5e5dSvi117747 header_size = strlen(hdr_name) + SIP_SPACE_LEN + csize + 31840cb5e5dSvi117747 SIP_SPACE_LEN + strlen(digit_str) + csize + 31940cb5e5dSvi117747 strlen(plist) + strlen(SIP_CRLF); 32040cb5e5dSvi117747 } 32140cb5e5dSvi117747 32240cb5e5dSvi117747 new_header = sip_new_header(header_size); 32340cb5e5dSvi117747 if (new_header == NULL) { 32440cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 32540cb5e5dSvi117747 free(digit_str); 32640cb5e5dSvi117747 return (ENOMEM); 32740cb5e5dSvi117747 } 32840cb5e5dSvi117747 32940cb5e5dSvi117747 if (plist == NULL) { 33040cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 33140cb5e5dSvi117747 "%s %c %s%s", hdr_name, SIP_HCOLON, digit_str, SIP_CRLF); 33240cb5e5dSvi117747 } else { 33340cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 33440cb5e5dSvi117747 "%s %c %s%c%s%s", hdr_name, SIP_HCOLON, digit_str, 33540cb5e5dSvi117747 SIP_SEMI, plist, SIP_CRLF); 33640cb5e5dSvi117747 } 33740cb5e5dSvi117747 free(digit_str); 33840cb5e5dSvi117747 _sip_add_header(_sip_msg, new_header, B_TRUE, B_FALSE, NULL); 33940cb5e5dSvi117747 if (_sip_msg->sip_msg_buf != NULL) 34040cb5e5dSvi117747 _sip_msg->sip_msg_modified = B_TRUE; 34140cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 34240cb5e5dSvi117747 34340cb5e5dSvi117747 return (0); 34440cb5e5dSvi117747 } 34540cb5e5dSvi117747 34640cb5e5dSvi117747 /* 34740cb5e5dSvi117747 * Add a header with an int and string to sip_msg 34840cb5e5dSvi117747 */ 34940cb5e5dSvi117747 static int 35040cb5e5dSvi117747 sip_add_intstr_to_msg(sip_msg_t sip_msg, char *hdr_name, int i, char *s, 35140cb5e5dSvi117747 char *plist) 35240cb5e5dSvi117747 { 35340cb5e5dSvi117747 _sip_header_t *new_header; 35440cb5e5dSvi117747 int header_size; 35540cb5e5dSvi117747 _sip_msg_t *_sip_msg; 35640cb5e5dSvi117747 char *digit_str; 35740cb5e5dSvi117747 int csize = sizeof (char); 35840cb5e5dSvi117747 35940cb5e5dSvi117747 if (sip_msg == NULL || (hdr_name == NULL)) 36040cb5e5dSvi117747 return (EINVAL); 36140cb5e5dSvi117747 _sip_msg = (_sip_msg_t *)sip_msg; 36240cb5e5dSvi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 36340cb5e5dSvi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 36440cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 36540cb5e5dSvi117747 return (ENOTSUP); 36640cb5e5dSvi117747 } 36740cb5e5dSvi117747 36840cb5e5dSvi117747 /* 36940cb5e5dSvi117747 * the following two loops convert int i to str 37040cb5e5dSvi117747 */ 37140cb5e5dSvi117747 digit_str = sip_int_to_str(i); 37240cb5e5dSvi117747 if (digit_str == NULL) { 37340cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 37440cb5e5dSvi117747 return (EINVAL); 37540cb5e5dSvi117747 } 37640cb5e5dSvi117747 if (plist == NULL) { 37740cb5e5dSvi117747 header_size = strlen(hdr_name) + SIP_SPACE_LEN + csize + 37840cb5e5dSvi117747 SIP_SPACE_LEN + strlen(digit_str) + csize + strlen(s) + 37940cb5e5dSvi117747 strlen(SIP_CRLF); 38040cb5e5dSvi117747 } else { 38140cb5e5dSvi117747 header_size = strlen(hdr_name) + SIP_SPACE_LEN + csize + 38240cb5e5dSvi117747 SIP_SPACE_LEN + strlen(digit_str) + csize + strlen(s) + 38340cb5e5dSvi117747 csize + strlen(plist) + strlen(SIP_CRLF); 38440cb5e5dSvi117747 } 38540cb5e5dSvi117747 38640cb5e5dSvi117747 new_header = sip_new_header(header_size); 38740cb5e5dSvi117747 if (new_header == NULL) { 38840cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 38940cb5e5dSvi117747 free(digit_str); 39040cb5e5dSvi117747 return (ENOMEM); 39140cb5e5dSvi117747 } 39240cb5e5dSvi117747 39340cb5e5dSvi117747 if (plist == NULL) { 39440cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 39540cb5e5dSvi117747 "%s %c %s %s%s", hdr_name, SIP_HCOLON, digit_str, s, 39640cb5e5dSvi117747 SIP_CRLF); 39740cb5e5dSvi117747 } else { 39840cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 39940cb5e5dSvi117747 "%s %c %s %s%c%s%s", hdr_name, SIP_HCOLON, digit_str, 40040cb5e5dSvi117747 s, SIP_SEMI, plist, SIP_CRLF); 40140cb5e5dSvi117747 } 40240cb5e5dSvi117747 free(digit_str); 40340cb5e5dSvi117747 _sip_add_header(_sip_msg, new_header, B_TRUE, B_FALSE, NULL); 40440cb5e5dSvi117747 if (_sip_msg->sip_msg_buf != NULL) 40540cb5e5dSvi117747 _sip_msg->sip_msg_modified = B_TRUE; 40640cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 40740cb5e5dSvi117747 40840cb5e5dSvi117747 return (0); 40940cb5e5dSvi117747 } 41040cb5e5dSvi117747 41140cb5e5dSvi117747 /* 41240cb5e5dSvi117747 * Generic function to add Contact, From, To, Route or Record-Route header 41340cb5e5dSvi117747 */ 41440cb5e5dSvi117747 static int 41540cb5e5dSvi117747 sip_add_name_aspec(sip_msg_t sip_msg, char *display_name, char *uri, 41640cb5e5dSvi117747 char *tags, boolean_t add_aquot, char *header_name, char *params) 41740cb5e5dSvi117747 { 41840cb5e5dSvi117747 char *t = uri; 41940cb5e5dSvi117747 boolean_t qalloc = B_FALSE; 42040cb5e5dSvi117747 boolean_t palloc = B_FALSE; 42140cb5e5dSvi117747 int r; 42240cb5e5dSvi117747 42340cb5e5dSvi117747 if (sip_msg == NULL || uri == NULL || header_name == NULL) 42440cb5e5dSvi117747 return (EINVAL); 42540cb5e5dSvi117747 if (display_name != NULL && !add_aquot) 42640cb5e5dSvi117747 return (EINVAL); 42740cb5e5dSvi117747 if (add_aquot) { 42840cb5e5dSvi117747 t = sip_add_aquot_to_str(uri, &qalloc); 42940cb5e5dSvi117747 if (t == NULL) 43040cb5e5dSvi117747 return (ENOMEM); 43140cb5e5dSvi117747 } 43240cb5e5dSvi117747 if (tags != NULL) { 43340cb5e5dSvi117747 int plen; 43440cb5e5dSvi117747 43540cb5e5dSvi117747 if (params != NULL) 43640cb5e5dSvi117747 return (EINVAL); 43740cb5e5dSvi117747 43840cb5e5dSvi117747 plen = strlen(SIP_TAG) + strlen(tags) + 1; 43940cb5e5dSvi117747 params = malloc(plen); 44040cb5e5dSvi117747 if (params == NULL) 44140cb5e5dSvi117747 return (ENOMEM); 44240cb5e5dSvi117747 (void) snprintf(params, plen, "%s%s", SIP_TAG, tags); 44340cb5e5dSvi117747 params[plen - 1] = '\0'; 44440cb5e5dSvi117747 palloc = B_TRUE; 44540cb5e5dSvi117747 } 44640cb5e5dSvi117747 if (display_name == NULL) { 44740cb5e5dSvi117747 r = sip_add_2strs_to_msg(sip_msg, header_name, " ", B_FALSE, 44840cb5e5dSvi117747 t, params, SIP_SP); 44940cb5e5dSvi117747 } else { 45040cb5e5dSvi117747 r = sip_add_2strs_to_msg(sip_msg, header_name, display_name, 45140cb5e5dSvi117747 B_TRUE, t, params, SIP_SP); 45240cb5e5dSvi117747 } 45340cb5e5dSvi117747 if (qalloc) 45440cb5e5dSvi117747 free(t); 45540cb5e5dSvi117747 if (palloc) 45640cb5e5dSvi117747 free(params); 45740cb5e5dSvi117747 return (r); 45840cb5e5dSvi117747 } 45940cb5e5dSvi117747 46040cb5e5dSvi117747 /* 46140cb5e5dSvi117747 * Accept = "Accept" ":" (media-range [ accept-params ]) 46240cb5e5dSvi117747 * media-range = ( "X/X" | (type "/" "*") | (type "/" subtype))*(";" parameter) 46340cb5e5dSvi117747 * accept-params = ";" "q" "=" qvalue *(accept-extension) 46440cb5e5dSvi117747 * accept-extension = ";" token [ "=" (token | quoted-str) 46540cb5e5dSvi117747 * 46640cb5e5dSvi117747 * function take two char ptrs - type and subtype - if any of them is NULL 46740cb5e5dSvi117747 * the corresponding value will be set to "*" in header 46840cb5e5dSvi117747 */ 46940cb5e5dSvi117747 int 47040cb5e5dSvi117747 sip_add_accept(sip_msg_t sip_msg, char *type, char *subtype, char *m_par, 47140cb5e5dSvi117747 char *a_par) 47240cb5e5dSvi117747 { 47340cb5e5dSvi117747 int ret; 47440cb5e5dSvi117747 char *plist; 47540cb5e5dSvi117747 int size; 47640cb5e5dSvi117747 boolean_t alloc = B_FALSE; 47740cb5e5dSvi117747 47840cb5e5dSvi117747 if (type == NULL && subtype == NULL) { 47940cb5e5dSvi117747 ret = sip_add_empty_hdr(sip_msg, SIP_ACCEPT); 48040cb5e5dSvi117747 return (ret); 48140cb5e5dSvi117747 } 48240cb5e5dSvi117747 48340cb5e5dSvi117747 if ((m_par != NULL) && (a_par != NULL)) { 48440cb5e5dSvi117747 size = strlen(m_par) + strlen(a_par) + 2 * sizeof (char); 48540cb5e5dSvi117747 plist = calloc(1, size * sizeof (char)); 48640cb5e5dSvi117747 (void) strncpy(plist, m_par, strlen(m_par)); 48740cb5e5dSvi117747 (void) strncat(plist, ";", 1); 48840cb5e5dSvi117747 (void) strncat(plist, a_par, strlen(a_par)); 48940cb5e5dSvi117747 alloc = B_TRUE; 49040cb5e5dSvi117747 } else if (m_par != NULL) { 49140cb5e5dSvi117747 plist = m_par; 49240cb5e5dSvi117747 } else 49340cb5e5dSvi117747 plist = a_par; 49440cb5e5dSvi117747 49540cb5e5dSvi117747 if ((type != NULL) && (subtype != NULL)) { 49640cb5e5dSvi117747 ret = sip_add_2strs_to_msg(sip_msg, SIP_ACCEPT, type, B_FALSE, 49740cb5e5dSvi117747 subtype, plist, SIP_SLASH); 49840cb5e5dSvi117747 } else if (type != NULL) { 49940cb5e5dSvi117747 ret = sip_add_2strs_to_msg(sip_msg, SIP_ACCEPT, type, B_FALSE, 50040cb5e5dSvi117747 "*", plist, SIP_SLASH); 50140cb5e5dSvi117747 } else { 50240cb5e5dSvi117747 ret = EINVAL; 50340cb5e5dSvi117747 } 50440cb5e5dSvi117747 50540cb5e5dSvi117747 if (alloc == B_TRUE) 50640cb5e5dSvi117747 free(plist); 50740cb5e5dSvi117747 50840cb5e5dSvi117747 return (ret); 50940cb5e5dSvi117747 } 51040cb5e5dSvi117747 51140cb5e5dSvi117747 51240cb5e5dSvi117747 /* 51340cb5e5dSvi117747 * Accept-Encoding = "Accept-Encoding" ":" 1#(codings [ ";" "q" "=" qval]) 51440cb5e5dSvi117747 * codings = ( content-coding | "*" ) 51540cb5e5dSvi117747 * content-coding = token 51640cb5e5dSvi117747 * 51740cb5e5dSvi117747 * function take one char ptr, if NULL value will be set to "*" 51840cb5e5dSvi117747 */ 51940cb5e5dSvi117747 int 52040cb5e5dSvi117747 sip_add_accept_enc(sip_msg_t sip_msg, char *code, char *plist) 52140cb5e5dSvi117747 { 52240cb5e5dSvi117747 int ret; 52340cb5e5dSvi117747 52440cb5e5dSvi117747 if (code == NULL) { 52540cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_ACCEPT_ENCODE, "*", plist, 52640cb5e5dSvi117747 SIP_SEMI); 52740cb5e5dSvi117747 } else { 52840cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_ACCEPT_ENCODE, code, 52940cb5e5dSvi117747 plist, SIP_SEMI); 53040cb5e5dSvi117747 } 53140cb5e5dSvi117747 return (ret); 53240cb5e5dSvi117747 } 53340cb5e5dSvi117747 53440cb5e5dSvi117747 /* 53540cb5e5dSvi117747 * Accept-Language = "Accept-Language" ":" 1#( language-range [ ";" "q""=" val]) 53640cb5e5dSvi117747 * language-range = ( ( 1*8ALPHA *("-" 1*8ALPHA))|"*") 53740cb5e5dSvi117747 */ 53840cb5e5dSvi117747 int 53940cb5e5dSvi117747 sip_add_accept_lang(sip_msg_t sip_msg, char *lang, char *plist) 54040cb5e5dSvi117747 { 54140cb5e5dSvi117747 int ret; 54240cb5e5dSvi117747 54340cb5e5dSvi117747 if (lang == NULL) { 54440cb5e5dSvi117747 ret = sip_add_empty_hdr(sip_msg, SIP_ACCEPT_LANG); 54540cb5e5dSvi117747 return (ret); 54640cb5e5dSvi117747 } 54740cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_ACCEPT_LANG, lang, plist, 54840cb5e5dSvi117747 SIP_SEMI); 54940cb5e5dSvi117747 return (ret); 55040cb5e5dSvi117747 } 55140cb5e5dSvi117747 55240cb5e5dSvi117747 /* 55340cb5e5dSvi117747 * Alert-Info = "Alert-Info" ":" "<" URI ">" 55440cb5e5dSvi117747 */ 55540cb5e5dSvi117747 int 55640cb5e5dSvi117747 sip_add_alert_info(sip_msg_t sip_msg, char *alert, char *plist) 55740cb5e5dSvi117747 { 55840cb5e5dSvi117747 int ret; 55940cb5e5dSvi117747 char *tmp; 56040cb5e5dSvi117747 boolean_t alloc; 56140cb5e5dSvi117747 56240cb5e5dSvi117747 if (alert == NULL) 56340cb5e5dSvi117747 return (EINVAL); 56440cb5e5dSvi117747 tmp = sip_add_aquot_to_str(alert, &alloc); 56540cb5e5dSvi117747 if (tmp == NULL) 56640cb5e5dSvi117747 return (ENOMEM); 56740cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_ALERT_INFO, tmp, plist, SIP_SEMI); 56840cb5e5dSvi117747 if (alloc) 56940cb5e5dSvi117747 free(tmp); 57040cb5e5dSvi117747 return (ret); 57140cb5e5dSvi117747 } 57240cb5e5dSvi117747 57340cb5e5dSvi117747 /* 57440cb5e5dSvi117747 * Allow = "Allow" ":" method-name1[, method-name2..] 57540cb5e5dSvi117747 * method-name = "INVITE" | "ACK" | "OPTIONS" | "CANCEL" | "BYE" 57640cb5e5dSvi117747 */ 57740cb5e5dSvi117747 int 57840cb5e5dSvi117747 sip_add_allow(sip_msg_t sip_msg, sip_method_t method) 57940cb5e5dSvi117747 { 58040cb5e5dSvi117747 int ret; 58140cb5e5dSvi117747 58240cb5e5dSvi117747 if (method == 0 || method >= MAX_SIP_METHODS) 58340cb5e5dSvi117747 return (EINVAL); 58440cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_ALLOW, sip_methods[method].name, 58540cb5e5dSvi117747 NULL, (char)NULL); 58640cb5e5dSvi117747 return (ret); 58740cb5e5dSvi117747 } 58840cb5e5dSvi117747 58940cb5e5dSvi117747 /* 59040cb5e5dSvi117747 * Call-Info = "Call-Info" HCOLON info *(COMMA info) 59140cb5e5dSvi117747 * info = LAQUOT absoluteURI RAQUOT *( SEMI info-param) 59240cb5e5dSvi117747 * info-param = ( "purpose" EQUAL ( "icon" / "info" 59340cb5e5dSvi117747 * / "card" / token ) ) / generic-param 59440cb5e5dSvi117747 */ 59540cb5e5dSvi117747 int 59640cb5e5dSvi117747 sip_add_call_info(sip_msg_t sip_msg, char *uri, char *plist) 59740cb5e5dSvi117747 { 59840cb5e5dSvi117747 char *tmp; 59940cb5e5dSvi117747 boolean_t alloc; 60040cb5e5dSvi117747 int r; 60140cb5e5dSvi117747 60240cb5e5dSvi117747 if (uri == NULL) 60340cb5e5dSvi117747 return (EINVAL); 60440cb5e5dSvi117747 tmp = sip_add_aquot_to_str(uri, &alloc); 60540cb5e5dSvi117747 if (tmp == NULL) 60640cb5e5dSvi117747 return (ENOMEM); 60740cb5e5dSvi117747 r = sip_add_str_to_msg(sip_msg, SIP_CALL_INFO, tmp, plist, SIP_SEMI); 60840cb5e5dSvi117747 if (alloc) 60940cb5e5dSvi117747 free(tmp); 61040cb5e5dSvi117747 return (r); 61140cb5e5dSvi117747 } 61240cb5e5dSvi117747 61340cb5e5dSvi117747 /* 61440cb5e5dSvi117747 * Content-Disposition = "Content-Disposition" HCOLON 61540cb5e5dSvi117747 * disp-type *( SEMI disp-param ) 61640cb5e5dSvi117747 * disp-type = "render" / "session" / "icon" / "alert" 61740cb5e5dSvi117747 * / disp-extension-token 61840cb5e5dSvi117747 * disp-param = handling-param / generic-param 61940cb5e5dSvi117747 * handling-param = "handling" EQUAL 62040cb5e5dSvi117747 * ( "optional" / "required" 62140cb5e5dSvi117747 * / other-handling ) 62240cb5e5dSvi117747 * other-handling = token 62340cb5e5dSvi117747 * disp-extension-token = token 62440cb5e5dSvi117747 */ 62540cb5e5dSvi117747 int 62640cb5e5dSvi117747 sip_add_content_disp(sip_msg_t sip_msg, char *dis_type, char *plist) 62740cb5e5dSvi117747 { 62840cb5e5dSvi117747 int ret; 62940cb5e5dSvi117747 63040cb5e5dSvi117747 if (dis_type == NULL) 63140cb5e5dSvi117747 return (EINVAL); 63240cb5e5dSvi117747 63340cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_CONTENT_DIS, dis_type, plist, 63440cb5e5dSvi117747 SIP_SEMI); 63540cb5e5dSvi117747 return (ret); 63640cb5e5dSvi117747 } 63740cb5e5dSvi117747 63840cb5e5dSvi117747 /* 63940cb5e5dSvi117747 * Content-Encoding = ( "Content-Encoding" / "e" ) HCOLON 64040cb5e5dSvi117747 * content-coding *(COMMA content-coding) 64140cb5e5dSvi117747 * content-coding = token 64240cb5e5dSvi117747 */ 64340cb5e5dSvi117747 int 64440cb5e5dSvi117747 sip_add_content_enc(sip_msg_t sip_msg, char *code) 64540cb5e5dSvi117747 { 64640cb5e5dSvi117747 int ret; 64740cb5e5dSvi117747 64840cb5e5dSvi117747 if (code == NULL) 64940cb5e5dSvi117747 return (EINVAL); 65040cb5e5dSvi117747 65140cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_CONTENT_ENCODE, code, NULL, 65240cb5e5dSvi117747 (char)NULL); 65340cb5e5dSvi117747 return (ret); 65440cb5e5dSvi117747 } 65540cb5e5dSvi117747 65640cb5e5dSvi117747 /* 65740cb5e5dSvi117747 * Content-Language = "Content-Language" HCOLON 65840cb5e5dSvi117747 * language-tag *(COMMA language-tag) 65940cb5e5dSvi117747 * language-tag = primary-tag *( "-" subtag ) 66040cb5e5dSvi117747 * primary-tag = 1*8ALPHA 66140cb5e5dSvi117747 * subtag = 1*8ALPHA 66240cb5e5dSvi117747 */ 66340cb5e5dSvi117747 int 66440cb5e5dSvi117747 sip_add_content_lang(sip_msg_t sip_msg, char *lang) 66540cb5e5dSvi117747 { 66640cb5e5dSvi117747 int ret; 66740cb5e5dSvi117747 66840cb5e5dSvi117747 if (lang == NULL) 66940cb5e5dSvi117747 return (EINVAL); 67040cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_CONTENT_LANG, lang, NULL, 67140cb5e5dSvi117747 (char)NULL); 67240cb5e5dSvi117747 return (ret); 67340cb5e5dSvi117747 } 67440cb5e5dSvi117747 67540cb5e5dSvi117747 /* 67640cb5e5dSvi117747 * Date = "Date" HCOLON SIP-date 67740cb5e5dSvi117747 * SIP-date = rfc1123-date 67840cb5e5dSvi117747 * rfc1123-date = wkday "," SP date1 SP time SP "GMT" 67940cb5e5dSvi117747 * date1 = 2DIGIT SP month SP 4DIGIT 68040cb5e5dSvi117747 * ; day month year (e.g., 02 Jun 1982) 68140cb5e5dSvi117747 * time = 2DIGIT ":" 2DIGIT ":" 2DIGIT 68240cb5e5dSvi117747 * ; 00:00:00 - 23:59:59 68340cb5e5dSvi117747 * wkday = "Mon" / "Tue" / "Wed" 68440cb5e5dSvi117747 * / "Thu" / "Fri" / "Sat" / "Sun" 68540cb5e5dSvi117747 * month = "Jan" / "Feb" / "Mar" / "Apr" 68640cb5e5dSvi117747 * / "May" / "Jun" / "Jul" / "Aug" 68740cb5e5dSvi117747 * / "Sep" / "Oct" / "Nov" / "Dec" 68840cb5e5dSvi117747 */ 68940cb5e5dSvi117747 int 69040cb5e5dSvi117747 sip_add_date(sip_msg_t sip_msg, char *date) 69140cb5e5dSvi117747 { 69240cb5e5dSvi117747 int ret; 69340cb5e5dSvi117747 69440cb5e5dSvi117747 if (date == NULL) 69540cb5e5dSvi117747 return (EINVAL); 69640cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_DATE, date, NULL, (char)NULL); 69740cb5e5dSvi117747 return (ret); 69840cb5e5dSvi117747 } 69940cb5e5dSvi117747 70040cb5e5dSvi117747 /* 70140cb5e5dSvi117747 * Error-Info = "Error-Info" HCOLON error-uri *(COMMA error-uri) 70240cb5e5dSvi117747 * error-uri = LAQUOT absoluteURI RAQUOT *( SEMI generic-param ) 70340cb5e5dSvi117747 */ 70440cb5e5dSvi117747 int 70540cb5e5dSvi117747 sip_add_error_info(sip_msg_t sip_msg, char *uri, char *plist) 70640cb5e5dSvi117747 { 70740cb5e5dSvi117747 char *tmp; 70840cb5e5dSvi117747 boolean_t alloc; 70940cb5e5dSvi117747 int r; 71040cb5e5dSvi117747 71140cb5e5dSvi117747 if (uri == NULL) 71240cb5e5dSvi117747 return (EINVAL); 71340cb5e5dSvi117747 tmp = sip_add_aquot_to_str(uri, &alloc); 71440cb5e5dSvi117747 if (tmp == NULL) 71540cb5e5dSvi117747 return (EINVAL); 71640cb5e5dSvi117747 71740cb5e5dSvi117747 r = sip_add_str_to_msg(sip_msg, SIP_ERROR_INFO, tmp, plist, SIP_SEMI); 71840cb5e5dSvi117747 if (alloc) 71940cb5e5dSvi117747 free(tmp); 72040cb5e5dSvi117747 return (r); 72140cb5e5dSvi117747 } 72240cb5e5dSvi117747 72340cb5e5dSvi117747 /* 72440cb5e5dSvi117747 * Expires = "Expires" HCOLON delta-seconds 72540cb5e5dSvi117747 * delta-seconds = 1*DIGIT 72640cb5e5dSvi117747 */ 72740cb5e5dSvi117747 int 72840cb5e5dSvi117747 sip_add_expires(sip_msg_t sip_msg, int secs) 72940cb5e5dSvi117747 { 73040cb5e5dSvi117747 int ret; 73140cb5e5dSvi117747 73240cb5e5dSvi117747 if (sip_msg == NULL || (int)secs < 0) 73340cb5e5dSvi117747 return (EINVAL); 73440cb5e5dSvi117747 73540cb5e5dSvi117747 ret = sip_add_int_to_msg(sip_msg, SIP_EXPIRE, secs, NULL); 73640cb5e5dSvi117747 return (ret); 73740cb5e5dSvi117747 } 73840cb5e5dSvi117747 73940cb5e5dSvi117747 /* 74040cb5e5dSvi117747 * In-Reply-To = "In-Reply-To" HCOLON callid *(COMMA callid) 74140cb5e5dSvi117747 * callid = word [ "@" word ] 74240cb5e5dSvi117747 */ 74340cb5e5dSvi117747 int 74440cb5e5dSvi117747 sip_add_in_reply_to(sip_msg_t sip_msg, char *reply_id) 74540cb5e5dSvi117747 { 74640cb5e5dSvi117747 int r; 74740cb5e5dSvi117747 74840cb5e5dSvi117747 if (reply_id == NULL) 74940cb5e5dSvi117747 return (EINVAL); 75040cb5e5dSvi117747 r = sip_add_str_to_msg(sip_msg, SIP_IN_REPLY_TO, reply_id, NULL, 75140cb5e5dSvi117747 (char)NULL); 75240cb5e5dSvi117747 return (r); 75340cb5e5dSvi117747 } 75440cb5e5dSvi117747 75540cb5e5dSvi117747 /* 75640cb5e5dSvi117747 * RSeq = "RSeq" HCOLON response-num 75740cb5e5dSvi117747 */ 75840cb5e5dSvi117747 int 75940cb5e5dSvi117747 sip_add_rseq(sip_msg_t sip_msg, int resp_num) 76040cb5e5dSvi117747 { 76140cb5e5dSvi117747 int ret; 76240cb5e5dSvi117747 76340cb5e5dSvi117747 if (sip_msg == NULL || resp_num <= 0) 76440cb5e5dSvi117747 return (EINVAL); 76540cb5e5dSvi117747 ret = sip_add_int_to_msg(sip_msg, SIP_RSEQ, resp_num, NULL); 76640cb5e5dSvi117747 return (ret); 76740cb5e5dSvi117747 } 76840cb5e5dSvi117747 76940cb5e5dSvi117747 /* 77040cb5e5dSvi117747 * Min-Expires = "Min-Expires" HCOLON delta-seconds 77140cb5e5dSvi117747 */ 77240cb5e5dSvi117747 int 77340cb5e5dSvi117747 sip_add_min_expires(sip_msg_t sip_msg, int secs) 77440cb5e5dSvi117747 { 77540cb5e5dSvi117747 int ret; 77640cb5e5dSvi117747 77740cb5e5dSvi117747 if (sip_msg == NULL || (int)secs < 0) 77840cb5e5dSvi117747 return (EINVAL); 77940cb5e5dSvi117747 ret = sip_add_int_to_msg(sip_msg, SIP_MIN_EXPIRE, secs, NULL); 78040cb5e5dSvi117747 return (ret); 78140cb5e5dSvi117747 } 78240cb5e5dSvi117747 78340cb5e5dSvi117747 /* 78440cb5e5dSvi117747 * MIME-Version = "MIME-Version" HCOLON 1*DIGIT "." 1*DIGIT 78540cb5e5dSvi117747 */ 78640cb5e5dSvi117747 int 78740cb5e5dSvi117747 sip_add_mime_version(sip_msg_t sip_msg, char *version) 78840cb5e5dSvi117747 { 78940cb5e5dSvi117747 int ret; 79040cb5e5dSvi117747 79140cb5e5dSvi117747 if (version == NULL) 79240cb5e5dSvi117747 return (EINVAL); 79340cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_MIME_VERSION, version, NULL, 79440cb5e5dSvi117747 (char)NULL); 79540cb5e5dSvi117747 return (ret); 79640cb5e5dSvi117747 } 79740cb5e5dSvi117747 79840cb5e5dSvi117747 /* 79940cb5e5dSvi117747 * Organization = "Organization" HCOLON [TEXT-UTF8-TRIM] 80040cb5e5dSvi117747 */ 80140cb5e5dSvi117747 int 80240cb5e5dSvi117747 sip_add_org(sip_msg_t sip_msg, char *org) 80340cb5e5dSvi117747 { 80440cb5e5dSvi117747 int ret; 80540cb5e5dSvi117747 80640cb5e5dSvi117747 if (org == NULL) { 80740cb5e5dSvi117747 ret = sip_add_empty_hdr(sip_msg, SIP_ORGANIZATION); 80840cb5e5dSvi117747 } else { 80940cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_ORGANIZATION, org, NULL, 81040cb5e5dSvi117747 (char)NULL); 81140cb5e5dSvi117747 } 81240cb5e5dSvi117747 return (ret); 81340cb5e5dSvi117747 } 81440cb5e5dSvi117747 81540cb5e5dSvi117747 /* 81640cb5e5dSvi117747 * Priority = "Priority" HCOLON priority-value 81740cb5e5dSvi117747 * priority-value = "emergency" / "urgent" / "normal" 81840cb5e5dSvi117747 * / "non-urgent" / other-priority 81940cb5e5dSvi117747 * other-priority = token 82040cb5e5dSvi117747 */ 82140cb5e5dSvi117747 int 82240cb5e5dSvi117747 sip_add_priority(sip_msg_t sip_msg, char *prio) 82340cb5e5dSvi117747 { 82440cb5e5dSvi117747 int ret; 82540cb5e5dSvi117747 82640cb5e5dSvi117747 if (prio == NULL) 82740cb5e5dSvi117747 return (EINVAL); 82840cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_PRIORITY, prio, NULL, (char)NULL); 82940cb5e5dSvi117747 83040cb5e5dSvi117747 return (ret); 83140cb5e5dSvi117747 } 83240cb5e5dSvi117747 83340cb5e5dSvi117747 /* 83440cb5e5dSvi117747 * Reply-To = "Reply-To" HCOLON rplyto-spec 83540cb5e5dSvi117747 * rplyto-spec = ( name-addr / addr-spec ) 83640cb5e5dSvi117747 * *( SEMI rplyto-param ) 83740cb5e5dSvi117747 * rplyto-param = generic-param 83840cb5e5dSvi117747 */ 83940cb5e5dSvi117747 int 84040cb5e5dSvi117747 sip_add_reply_to(sip_msg_t sip_msg, char *uname, char *addr, char *plist, 84140cb5e5dSvi117747 boolean_t add_aquot) 84240cb5e5dSvi117747 { 84340cb5e5dSvi117747 return (sip_add_name_aspec(sip_msg, uname, addr, NULL, add_aquot, 84440cb5e5dSvi117747 SIP_REPLYTO, plist)); 84540cb5e5dSvi117747 } 84640cb5e5dSvi117747 84740cb5e5dSvi117747 84840cb5e5dSvi117747 /* 84940cb5e5dSvi117747 * Privacy-hdr = "Privacy" HCOLON priv-value *(";" priv-value) 85040cb5e5dSvi117747 * priv-value = "header" / "session" / "user" / "none" / "critical" 85140cb5e5dSvi117747 * / token 85240cb5e5dSvi117747 */ 85340cb5e5dSvi117747 int 85440cb5e5dSvi117747 sip_add_privacy(sip_msg_t sip_msg, char *priv_val) 85540cb5e5dSvi117747 { 85640cb5e5dSvi117747 int ret; 85740cb5e5dSvi117747 85840cb5e5dSvi117747 if (priv_val == NULL) 85940cb5e5dSvi117747 return (EINVAL); 86040cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_PRIVACY, priv_val, NULL, 86140cb5e5dSvi117747 (char)NULL); 86240cb5e5dSvi117747 return (ret); 86340cb5e5dSvi117747 } 86440cb5e5dSvi117747 86540cb5e5dSvi117747 /* 86640cb5e5dSvi117747 * Require = "Require" HCOLON option-tag *(COMMA option-tag) 86740cb5e5dSvi117747 * option-tag = token 86840cb5e5dSvi117747 */ 86940cb5e5dSvi117747 int 87040cb5e5dSvi117747 sip_add_require(sip_msg_t sip_msg, char *req) 87140cb5e5dSvi117747 { 87240cb5e5dSvi117747 int ret; 87340cb5e5dSvi117747 87440cb5e5dSvi117747 if (req == NULL) 87540cb5e5dSvi117747 return (EINVAL); 87640cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_REQUIRE, req, NULL, (char)NULL); 87740cb5e5dSvi117747 return (ret); 87840cb5e5dSvi117747 } 87940cb5e5dSvi117747 88040cb5e5dSvi117747 /* 88140cb5e5dSvi117747 * Retry-After = "Retry-After" HCOLON delta-seconds 88240cb5e5dSvi117747 * [ comment ] *( SEMI retry-param ) 88340cb5e5dSvi117747 * retry-param = ("duration" EQUAL delta-seconds) 88440cb5e5dSvi117747 * / generic-param 88540cb5e5dSvi117747 */ 88640cb5e5dSvi117747 int 88740cb5e5dSvi117747 sip_add_retry_after(sip_msg_t sip_msg, int secs, char *cmt, char *plist) 88840cb5e5dSvi117747 { 88940cb5e5dSvi117747 int r; 89040cb5e5dSvi117747 89140cb5e5dSvi117747 if (secs <= 0) 89240cb5e5dSvi117747 return (EINVAL); 89340cb5e5dSvi117747 89440cb5e5dSvi117747 if (cmt == NULL) { 89540cb5e5dSvi117747 r = sip_add_int_to_msg(sip_msg, SIP_RETRY_AFTER, secs, plist); 89640cb5e5dSvi117747 return (r); 89740cb5e5dSvi117747 } 89840cb5e5dSvi117747 89940cb5e5dSvi117747 r = sip_add_intstr_to_msg(sip_msg, SIP_RETRY_AFTER, secs, cmt, plist); 90040cb5e5dSvi117747 return (r); 90140cb5e5dSvi117747 } 90240cb5e5dSvi117747 90340cb5e5dSvi117747 /* 90440cb5e5dSvi117747 * Server = "Server" HCOLON server-val *(LWS server-val) 90540cb5e5dSvi117747 * server-val = product / comment 90640cb5e5dSvi117747 * product = token [SLASH product-version] 90740cb5e5dSvi117747 * product-version = token 90840cb5e5dSvi117747 */ 90940cb5e5dSvi117747 int 91040cb5e5dSvi117747 sip_add_server(sip_msg_t sip_msg, char *svr) 91140cb5e5dSvi117747 { 91240cb5e5dSvi117747 int ret; 91340cb5e5dSvi117747 91440cb5e5dSvi117747 if (svr == NULL) 91540cb5e5dSvi117747 return (EINVAL); 91640cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_SERVER, svr, NULL, (char)NULL); 91740cb5e5dSvi117747 return (ret); 91840cb5e5dSvi117747 } 91940cb5e5dSvi117747 92040cb5e5dSvi117747 /* 92140cb5e5dSvi117747 * Subject = ( "Subject" / "s" ) HCOLON [TEXT-UTF8-TRIM] 92240cb5e5dSvi117747 */ 92340cb5e5dSvi117747 int 92440cb5e5dSvi117747 sip_add_subject(sip_msg_t sip_msg, char *subject) 92540cb5e5dSvi117747 { 92640cb5e5dSvi117747 int ret; 92740cb5e5dSvi117747 92840cb5e5dSvi117747 if (subject == NULL) { 92940cb5e5dSvi117747 ret = sip_add_empty_hdr(sip_msg, SIP_SUBJECT); 93040cb5e5dSvi117747 } else { 93140cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_SUBJECT, subject, NULL, 93240cb5e5dSvi117747 (char)NULL); 93340cb5e5dSvi117747 } 93440cb5e5dSvi117747 return (ret); 93540cb5e5dSvi117747 } 93640cb5e5dSvi117747 93740cb5e5dSvi117747 /* 93840cb5e5dSvi117747 * Supported = ( "Supported" / "k" ) HCOLON 93940cb5e5dSvi117747 * [option-tag *(COMMA option-tag)] 94040cb5e5dSvi117747 */ 94140cb5e5dSvi117747 int 94240cb5e5dSvi117747 sip_add_supported(sip_msg_t sip_msg, char *support) 94340cb5e5dSvi117747 { 94440cb5e5dSvi117747 int ret; 94540cb5e5dSvi117747 94640cb5e5dSvi117747 if (support == NULL) { 94740cb5e5dSvi117747 ret = sip_add_empty_hdr(sip_msg, SIP_SUPPORT); 94840cb5e5dSvi117747 } else { 94940cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_SUPPORT, support, NULL, 95040cb5e5dSvi117747 (char)NULL); 95140cb5e5dSvi117747 } 95240cb5e5dSvi117747 return (ret); 95340cb5e5dSvi117747 } 95440cb5e5dSvi117747 95540cb5e5dSvi117747 /* 95640cb5e5dSvi117747 * Timestamp = "Timestamp" HCOLON 1*(DIGIT) 95740cb5e5dSvi117747 * [ "." *(DIGIT) ] [ LWS delay ] 95840cb5e5dSvi117747 * delay = *(DIGIT) [ "." *(DIGIT) ] 95940cb5e5dSvi117747 */ 96040cb5e5dSvi117747 int 96140cb5e5dSvi117747 sip_add_tstamp(sip_msg_t sip_msg, char *time, char *delay) 96240cb5e5dSvi117747 { 96340cb5e5dSvi117747 int ret; 96440cb5e5dSvi117747 96540cb5e5dSvi117747 if (delay == NULL) { 96640cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_TIMESTAMP, time, NULL, 96740cb5e5dSvi117747 (char)NULL); 96840cb5e5dSvi117747 } else { 96940cb5e5dSvi117747 ret = sip_add_2strs_to_msg(sip_msg, SIP_TIMESTAMP, time, 97040cb5e5dSvi117747 B_FALSE, delay, NULL, ' '); 97140cb5e5dSvi117747 } 97240cb5e5dSvi117747 return (ret); 97340cb5e5dSvi117747 } 97440cb5e5dSvi117747 97540cb5e5dSvi117747 /* 97640cb5e5dSvi117747 * Unsupported = "Unsupported" HCOLON option-tag *(COMMA option-tag) 97740cb5e5dSvi117747 */ 97840cb5e5dSvi117747 int 97940cb5e5dSvi117747 sip_add_unsupported(sip_msg_t sip_msg, char *unsupport) 98040cb5e5dSvi117747 { 98140cb5e5dSvi117747 int ret; 98240cb5e5dSvi117747 98340cb5e5dSvi117747 if (unsupport == NULL) 98440cb5e5dSvi117747 return (EINVAL); 98540cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_UNSUPPORT, unsupport, NULL, 98640cb5e5dSvi117747 (char)NULL); 98740cb5e5dSvi117747 return (ret); 98840cb5e5dSvi117747 } 98940cb5e5dSvi117747 99040cb5e5dSvi117747 /* 99140cb5e5dSvi117747 * User-Agent = "User-Agent" HCOLON server-val *(LWS server-val) 99240cb5e5dSvi117747 */ 99340cb5e5dSvi117747 int 99440cb5e5dSvi117747 sip_add_user_agent(sip_msg_t sip_msg, char *usr) 99540cb5e5dSvi117747 { 99640cb5e5dSvi117747 int r; 99740cb5e5dSvi117747 99840cb5e5dSvi117747 if (usr == NULL) 99940cb5e5dSvi117747 return (EINVAL); 100040cb5e5dSvi117747 r = sip_add_str_to_msg(sip_msg, SIP_USER_AGENT, usr, NULL, (char)NULL); 100140cb5e5dSvi117747 return (r); 100240cb5e5dSvi117747 } 100340cb5e5dSvi117747 100440cb5e5dSvi117747 /* 100540cb5e5dSvi117747 * Warning = "Warning" HCOLON warning-value *(COMMA warning-value) 100640cb5e5dSvi117747 * warning-value = warn-code SP warn-agent SP warn-text 100740cb5e5dSvi117747 * warn-code = 3DIGIT 100840cb5e5dSvi117747 * warn-agent = hostport / pseudonym 100940cb5e5dSvi117747 * ; the name or pseudonym of the server adding 101040cb5e5dSvi117747 * ; the Warning header, for use in debugging 101140cb5e5dSvi117747 * warn-text = quoted-string 101240cb5e5dSvi117747 * pseudonym = token 101340cb5e5dSvi117747 */ 101440cb5e5dSvi117747 int 101540cb5e5dSvi117747 sip_add_warning(sip_msg_t sip_msg, int code, char *addr, char *msg) 101640cb5e5dSvi117747 { 101740cb5e5dSvi117747 _sip_header_t *new_header; 101840cb5e5dSvi117747 int header_size; 101940cb5e5dSvi117747 _sip_msg_t *_sip_msg; 102040cb5e5dSvi117747 char *hdr_name = SIP_WARNING; 102140cb5e5dSvi117747 102240cb5e5dSvi117747 if (sip_msg == NULL || addr == NULL || msg == NULL || 102340cb5e5dSvi117747 addr[0] == '\0' || msg == '\0' || code < 100 || code > 999) { 102440cb5e5dSvi117747 return (EINVAL); 102540cb5e5dSvi117747 } 102640cb5e5dSvi117747 102740cb5e5dSvi117747 _sip_msg = (_sip_msg_t *)sip_msg; 102840cb5e5dSvi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 102940cb5e5dSvi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 103040cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 103140cb5e5dSvi117747 return (ENOTSUP); 103240cb5e5dSvi117747 } 103340cb5e5dSvi117747 103440cb5e5dSvi117747 header_size = strlen(hdr_name) + SIP_SPACE_LEN + sizeof (char) + 103540cb5e5dSvi117747 SIP_SPACE_LEN + sip_num_of_digits(code) + SIP_SPACE_LEN + 103640cb5e5dSvi117747 strlen(addr) + SIP_SPACE_LEN + sizeof (char) + strlen(msg) + 103740cb5e5dSvi117747 sizeof (char) + strlen(SIP_CRLF); 103840cb5e5dSvi117747 103940cb5e5dSvi117747 new_header = sip_new_header(header_size); 104040cb5e5dSvi117747 if (new_header == NULL) { 104140cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 104240cb5e5dSvi117747 return (ENOMEM); 104340cb5e5dSvi117747 } 104440cb5e5dSvi117747 104540cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 104640cb5e5dSvi117747 "%s %c %d %s \"%s\"%s", hdr_name, SIP_HCOLON, code, addr, 104740cb5e5dSvi117747 msg, SIP_CRLF); 104840cb5e5dSvi117747 _sip_add_header(_sip_msg, new_header, B_TRUE, B_FALSE, NULL); 104940cb5e5dSvi117747 if (_sip_msg->sip_msg_buf != NULL) 105040cb5e5dSvi117747 _sip_msg->sip_msg_modified = B_TRUE; 105140cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 105240cb5e5dSvi117747 105340cb5e5dSvi117747 return (0); 105440cb5e5dSvi117747 } 105540cb5e5dSvi117747 105640cb5e5dSvi117747 /* 105740cb5e5dSvi117747 * RAck = "RAck" HCOLON response-num LWS CSeq-num LWS Method 105840cb5e5dSvi117747 * response-num = 1*DIGIT 105940cb5e5dSvi117747 * CSeq-num = 1*DIGIT 106040cb5e5dSvi117747 */ 106140cb5e5dSvi117747 int 106240cb5e5dSvi117747 sip_add_rack(sip_msg_t sip_msg, int resp_num, int cseq, sip_method_t method) 106340cb5e5dSvi117747 { 106440cb5e5dSvi117747 _sip_header_t *new_header; 106540cb5e5dSvi117747 int header_size; 106640cb5e5dSvi117747 _sip_msg_t *_sip_msg; 106740cb5e5dSvi117747 char *hdr_name = SIP_RACK; 106840cb5e5dSvi117747 106940cb5e5dSvi117747 if (sip_msg == NULL || resp_num <= 0 || cseq < 0 || method <= 0 || 107040cb5e5dSvi117747 method >= MAX_SIP_METHODS) { 107140cb5e5dSvi117747 return (EINVAL); 107240cb5e5dSvi117747 } 107340cb5e5dSvi117747 107440cb5e5dSvi117747 _sip_msg = (_sip_msg_t *)sip_msg; 107540cb5e5dSvi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 107640cb5e5dSvi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 107740cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 107840cb5e5dSvi117747 return (ENOTSUP); 107940cb5e5dSvi117747 } 108040cb5e5dSvi117747 108140cb5e5dSvi117747 header_size = strlen(hdr_name) + SIP_SPACE_LEN + sizeof (char) + 108240cb5e5dSvi117747 SIP_SPACE_LEN + sip_num_of_digits(resp_num) + SIP_SPACE_LEN + 108340cb5e5dSvi117747 sip_num_of_digits(cseq) + SIP_SPACE_LEN + 108440cb5e5dSvi117747 strlen(sip_methods[method].name) + strlen(SIP_CRLF); 108540cb5e5dSvi117747 108640cb5e5dSvi117747 new_header = sip_new_header(header_size); 108740cb5e5dSvi117747 if (new_header == NULL) { 108840cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 108940cb5e5dSvi117747 return (ENOMEM); 109040cb5e5dSvi117747 } 109140cb5e5dSvi117747 109240cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 109340cb5e5dSvi117747 "%s %c %d %d %s%s", hdr_name, SIP_HCOLON, resp_num, cseq, 109440cb5e5dSvi117747 sip_methods[method].name, SIP_CRLF); 109540cb5e5dSvi117747 109640cb5e5dSvi117747 _sip_add_header(_sip_msg, new_header, B_TRUE, B_FALSE, NULL); 109740cb5e5dSvi117747 if (_sip_msg->sip_msg_buf != NULL) 109840cb5e5dSvi117747 _sip_msg->sip_msg_modified = B_TRUE; 109940cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 110040cb5e5dSvi117747 110140cb5e5dSvi117747 return (0); 110240cb5e5dSvi117747 110340cb5e5dSvi117747 } 110440cb5e5dSvi117747 110540cb5e5dSvi117747 /* 110640cb5e5dSvi117747 * Allow-Events = ( "Allow-Events" / "u" ) HCOLON event-type 110740cb5e5dSvi117747 * *(COMMA event-type) 110840cb5e5dSvi117747 */ 110940cb5e5dSvi117747 int 111040cb5e5dSvi117747 sip_add_allow_events(sip_msg_t sip_msg, char *t_event) 111140cb5e5dSvi117747 { 111240cb5e5dSvi117747 return (sip_add_str_to_msg(sip_msg, SIP_ALLOW_EVENTS, t_event, NULL, 111340cb5e5dSvi117747 (char)NULL)); 111440cb5e5dSvi117747 } 111540cb5e5dSvi117747 111640cb5e5dSvi117747 /* 111740cb5e5dSvi117747 * Event = ( "Event" / "o" ) HCOLON event-type 111840cb5e5dSvi117747 * *( SEMI event-param ) 111940cb5e5dSvi117747 * event-type = event-package *( "." event-template ) 112040cb5e5dSvi117747 * event-package = token-nodot 112140cb5e5dSvi117747 * event-template = token-nodot 112240cb5e5dSvi117747 * token-nodot = 1*( alphanum / "-" / "!" / "%" / "*" 112340cb5e5dSvi117747 * / "_" / "+" / "`" / "'" / "~" ) 112440cb5e5dSvi117747 * event-param = generic-param / ( "id" EQUAL token ) 112540cb5e5dSvi117747 */ 112640cb5e5dSvi117747 int 112740cb5e5dSvi117747 sip_add_event(sip_msg_t sip_msg, char *t_event, char *plist) 112840cb5e5dSvi117747 { 112940cb5e5dSvi117747 return (sip_add_str_to_msg(sip_msg, SIP_EVENT, t_event, plist, 113040cb5e5dSvi117747 SIP_SEMI)); 113140cb5e5dSvi117747 } 113240cb5e5dSvi117747 113340cb5e5dSvi117747 /* 113440cb5e5dSvi117747 * Subscription-State = "Subscription-State" HCOLON substate-value 113540cb5e5dSvi117747 * *( SEMI subexp-params ) 113640cb5e5dSvi117747 * substate-value = "active" / "pending" / "terminated" 113740cb5e5dSvi117747 * / extension-substate 113840cb5e5dSvi117747 * extension-substate = token 113940cb5e5dSvi117747 * subexp-params = ("reason" EQUAL event-reason-value) 114040cb5e5dSvi117747 * / ("expires" EQUAL delta-seconds)* 114140cb5e5dSvi117747 * / ("retry-after" EQUAL delta-seconds) 114240cb5e5dSvi117747 * / generic-param 114340cb5e5dSvi117747 * event-reason-value = "deactivated" 114440cb5e5dSvi117747 * / "probation" 114540cb5e5dSvi117747 * / "rejected" 114640cb5e5dSvi117747 * / "timeout" 114740cb5e5dSvi117747 * / "giveup" 114840cb5e5dSvi117747 * / "noresource" 114940cb5e5dSvi117747 * / event-reason-extension 115040cb5e5dSvi117747 * event-reason-extension = token 115140cb5e5dSvi117747 */ 115240cb5e5dSvi117747 int 115340cb5e5dSvi117747 sip_add_substate(sip_msg_t sip_msg, char *sub, char *plist) 115440cb5e5dSvi117747 { 115540cb5e5dSvi117747 return (sip_add_str_to_msg(sip_msg, SIP_SUBSCRIPTION_STATE, sub, plist, 115640cb5e5dSvi117747 SIP_SEMI)); 115740cb5e5dSvi117747 } 115840cb5e5dSvi117747 115940cb5e5dSvi117747 /* 116040cb5e5dSvi117747 * Authorization = "Authorization" HCOLON credentials 116140cb5e5dSvi117747 * credentials = ("Digest" LWS digest-response) 116240cb5e5dSvi117747 * / other-response 116340cb5e5dSvi117747 * digest-response = dig-resp *(COMMA dig-resp) 116440cb5e5dSvi117747 * dig-resp = username / realm / nonce / digest-uri 116540cb5e5dSvi117747 * / dresponse / algorithm / cnonce 116640cb5e5dSvi117747 * / opaque / message-qop 116740cb5e5dSvi117747 * / nonce-count / auth-param 116840cb5e5dSvi117747 * username = "username" EQUAL username-value 116940cb5e5dSvi117747 * username-value = quoted-string 117040cb5e5dSvi117747 * digest-uri = "uri" EQUAL LDQUOT digest-uri-value RDQUOT 117140cb5e5dSvi117747 * digest-uri-value = rquest-uri ; Equal to request-uri as specified 117240cb5e5dSvi117747 * by HTTP/1.1 117340cb5e5dSvi117747 * message-qop = "qop" EQUAL qop-value 117440cb5e5dSvi117747 * cnonce = "cnonce" EQUAL cnonce-value 117540cb5e5dSvi117747 * cnonce-value = nonce-value 117640cb5e5dSvi117747 * nonce-count = "nc" EQUAL nc-value 117740cb5e5dSvi117747 * nc-value = 8LHEX 117840cb5e5dSvi117747 * dresponse = "response" EQUAL request-digest 117940cb5e5dSvi117747 * request-digest = LDQUOT 32LHEX RDQUOT 118040cb5e5dSvi117747 * auth-param = auth-param-name EQUAL 118140cb5e5dSvi117747 * ( token / quoted-string ) 118240cb5e5dSvi117747 * auth-param-name = token 118340cb5e5dSvi117747 * other-response = auth-scheme LWS auth-param 118440cb5e5dSvi117747 * *(COMMA auth-param) 118540cb5e5dSvi117747 * auth-scheme = token 118640cb5e5dSvi117747 */ 118740cb5e5dSvi117747 int 118840cb5e5dSvi117747 sip_add_author(sip_msg_t sip_msg, char *scheme, char *param) 118940cb5e5dSvi117747 { 119040cb5e5dSvi117747 return (sip_add_str_to_msg(sip_msg, SIP_AUTHOR, scheme, param, SIP_SP)); 119140cb5e5dSvi117747 } 119240cb5e5dSvi117747 119340cb5e5dSvi117747 /* 119440cb5e5dSvi117747 * Authentication-Info = "Authentication-Info" HCOLON ainfo 119540cb5e5dSvi117747 * *(COMMA ainfo) 119640cb5e5dSvi117747 * ainfo = nextnonce / message-qop 119740cb5e5dSvi117747 * / response-auth / cnonce 119840cb5e5dSvi117747 * / nonce-count 119940cb5e5dSvi117747 * nextnonce = "nextnonce" EQUAL nonce-value 120040cb5e5dSvi117747 * response-auth = "rspauth" EQUAL response-digest 120140cb5e5dSvi117747 * response-digest = LDQUOT *LHEX RDQUOT 120240cb5e5dSvi117747 */ 120340cb5e5dSvi117747 int 120440cb5e5dSvi117747 sip_add_authen_info(sip_msg_t sip_msg, char *ainfo) 120540cb5e5dSvi117747 { 120640cb5e5dSvi117747 return (sip_add_str_to_msg(sip_msg, SIP_AUTHEN_INFO, ainfo, NULL, 120740cb5e5dSvi117747 (char)NULL)); 120840cb5e5dSvi117747 } 120940cb5e5dSvi117747 121040cb5e5dSvi117747 /* 121140cb5e5dSvi117747 * Proxy-Authenticate = "Proxy-Authenticate" HCOLON challenge 121240cb5e5dSvi117747 * challenge = ("Digest" LWS digest-cln *(COMMA digest-cln)) 121340cb5e5dSvi117747 * / other-challenge 121440cb5e5dSvi117747 * other-challenge = auth-scheme LWS auth-param 121540cb5e5dSvi117747 * *(COMMA auth-param) 121640cb5e5dSvi117747 * digest-cln = realm / domain / nonce 121740cb5e5dSvi117747 * / opaque / stale / algorithm 121840cb5e5dSvi117747 * / qop-options / auth-param 121940cb5e5dSvi117747 * realm = "realm" EQUAL realm-value 122040cb5e5dSvi117747 * realm-value = quoted-string 122140cb5e5dSvi117747 * domain = "domain" EQUAL LDQUOT URI 122240cb5e5dSvi117747 * *( 1*SP URI ) RDQUOT 122340cb5e5dSvi117747 * URI = absoluteURI / abs-path 122440cb5e5dSvi117747 * nonce = "nonce" EQUAL nonce-value 122540cb5e5dSvi117747 * nonce-value = quoted-string 122640cb5e5dSvi117747 * opaque = "opaque" EQUAL quoted-string 122740cb5e5dSvi117747 * stale = "stale" EQUAL ( "true" / "false" ) 122840cb5e5dSvi117747 * algorithm = "algorithm" EQUAL ( "MD5" / "MD5-sess" 122940cb5e5dSvi117747 * / token ) 123040cb5e5dSvi117747 * qop-options = "qop" EQUAL LDQUOT qop-value 123140cb5e5dSvi117747 * *("," qop-value) RDQUOT 123240cb5e5dSvi117747 * qop-value = "auth" / "auth-int" / token 123340cb5e5dSvi117747 */ 123440cb5e5dSvi117747 int 123540cb5e5dSvi117747 sip_add_proxy_authen(sip_msg_t sip_msg, char *pascheme, char *paparam) 123640cb5e5dSvi117747 { 123740cb5e5dSvi117747 return (sip_add_str_to_msg(sip_msg, SIP_PROXY_AUTHEN, pascheme, paparam, 123840cb5e5dSvi117747 SIP_SP)); 123940cb5e5dSvi117747 } 124040cb5e5dSvi117747 124140cb5e5dSvi117747 /* 124240cb5e5dSvi117747 * Proxy-Authorization = "Proxy-Authorization" HCOLON credentials 124340cb5e5dSvi117747 */ 124440cb5e5dSvi117747 int 124540cb5e5dSvi117747 sip_add_proxy_author(sip_msg_t sip_msg, char *paschem, char *paparam) 124640cb5e5dSvi117747 { 124740cb5e5dSvi117747 return (sip_add_str_to_msg(sip_msg, SIP_PROXY_AUTHOR, paschem, paparam, 124840cb5e5dSvi117747 SIP_SP)); 124940cb5e5dSvi117747 } 125040cb5e5dSvi117747 125140cb5e5dSvi117747 /* 125240cb5e5dSvi117747 * Proxy-Require = "Proxy-Require" HCOLON option-tag 125340cb5e5dSvi117747 * *(COMMA option-tag) 125440cb5e5dSvi117747 * option-tag = token 125540cb5e5dSvi117747 */ 125640cb5e5dSvi117747 int 125740cb5e5dSvi117747 sip_add_proxy_require(sip_msg_t sip_msg, char *opt) 125840cb5e5dSvi117747 { 125940cb5e5dSvi117747 return (sip_add_str_to_msg(sip_msg, SIP_PROXY_REQ, opt, NULL, 126040cb5e5dSvi117747 (char)NULL)); 126140cb5e5dSvi117747 } 126240cb5e5dSvi117747 126340cb5e5dSvi117747 /* 126440cb5e5dSvi117747 * WWW-Authenticate = "WWW-Authenticate" HCOLON challenge 126540cb5e5dSvi117747 * extension-header = header-name HCOLON header-value 126640cb5e5dSvi117747 * header-name = token 126740cb5e5dSvi117747 * header-value = *(TEXT-UTF8char / UTF8-CONT / LWS) 126840cb5e5dSvi117747 * message-body = *OCTET 126940cb5e5dSvi117747 */ 127040cb5e5dSvi117747 int 127140cb5e5dSvi117747 sip_add_www_authen(sip_msg_t sip_msg, char *wascheme, char *waparam) 127240cb5e5dSvi117747 { 127340cb5e5dSvi117747 return (sip_add_str_to_msg(sip_msg, SIP_WWW_AUTHEN, wascheme, waparam, 127440cb5e5dSvi117747 SIP_SP)); 127540cb5e5dSvi117747 } 127640cb5e5dSvi117747 127740cb5e5dSvi117747 /* 127840cb5e5dSvi117747 * Call-ID = ( "Call-ID" / "i" ) HCOLON callid 127940cb5e5dSvi117747 */ 128040cb5e5dSvi117747 int 128140cb5e5dSvi117747 sip_add_callid(sip_msg_t sip_msg, char *callid) 128240cb5e5dSvi117747 { 128340cb5e5dSvi117747 int ret; 128440cb5e5dSvi117747 boolean_t allocd = B_FALSE; 128540cb5e5dSvi117747 128640cb5e5dSvi117747 if (sip_msg == NULL || (callid != NULL && callid[0] == '\0')) 128740cb5e5dSvi117747 return (EINVAL); 128840cb5e5dSvi117747 if (callid == NULL) { 128940cb5e5dSvi117747 callid = (char *)sip_guid(); 129040cb5e5dSvi117747 if (callid == NULL) 129140cb5e5dSvi117747 return (ENOMEM); 129240cb5e5dSvi117747 allocd = B_TRUE; 129340cb5e5dSvi117747 } 129440cb5e5dSvi117747 ret = sip_add_str_to_msg(sip_msg, SIP_CALL_ID, callid, NULL, 129540cb5e5dSvi117747 (char)NULL); 129640cb5e5dSvi117747 if (allocd) 129740cb5e5dSvi117747 free(callid); 129840cb5e5dSvi117747 return (ret); 129940cb5e5dSvi117747 } 130040cb5e5dSvi117747 130140cb5e5dSvi117747 /* 130240cb5e5dSvi117747 * CSeq = "CSeq" HCOLON 1*DIGIT LWS Method 130340cb5e5dSvi117747 */ 130440cb5e5dSvi117747 int 130540cb5e5dSvi117747 sip_add_cseq(sip_msg_t sip_msg, sip_method_t method, uint32_t cseq) 130640cb5e5dSvi117747 { 130740cb5e5dSvi117747 int r; 130840cb5e5dSvi117747 130940cb5e5dSvi117747 if (sip_msg == NULL || (int)cseq < 0 || method == 0 || 131040cb5e5dSvi117747 method >= MAX_SIP_METHODS) { 131140cb5e5dSvi117747 return (EINVAL); 131240cb5e5dSvi117747 } 131340cb5e5dSvi117747 r = sip_add_intstr_to_msg(sip_msg, SIP_CSEQ, cseq, 131440cb5e5dSvi117747 sip_methods[method].name, NULL); 131540cb5e5dSvi117747 return (r); 131640cb5e5dSvi117747 } 131740cb5e5dSvi117747 131840cb5e5dSvi117747 /* 131940cb5e5dSvi117747 * Via = ( "Via" / "v" ) HCOLON via-parm *(COMMA via-parm) 132040cb5e5dSvi117747 * via-parm = sent-protocol LWS sent-by *( SEMI via-params ) 132140cb5e5dSvi117747 * via-params = via-ttl / via-maddr 132240cb5e5dSvi117747 * / via-received / via-branch 132340cb5e5dSvi117747 * / via-extension 132440cb5e5dSvi117747 * via-ttl = "ttl" EQUAL ttl 132540cb5e5dSvi117747 * via-maddr = "maddr" EQUAL host 132640cb5e5dSvi117747 * via-received = "received" EQUAL (IPv4address / IPv6address) 132740cb5e5dSvi117747 * via-branch = "branch" EQUAL token 132840cb5e5dSvi117747 * via-extension = generic-param 132940cb5e5dSvi117747 * sent-protocol = protocol-name SLASH protocol-version 133040cb5e5dSvi117747 * SLASH transport 133140cb5e5dSvi117747 * protocol-name = "SIP" / token 133240cb5e5dSvi117747 * protocol-version = token 133340cb5e5dSvi117747 * transport = "UDP" / "TCP" / "TLS" / "SCTP" 133440cb5e5dSvi117747 * / other-transport 133540cb5e5dSvi117747 * sent-by = host [ COLON port ] 133640cb5e5dSvi117747 * ttl = 1*3DIGIT ; 0 to 255 133740cb5e5dSvi117747 */ 133840cb5e5dSvi117747 _sip_header_t * 133940cb5e5dSvi117747 sip_create_via_hdr(char *sent_protocol_transport, char *sent_by_host, 134040cb5e5dSvi117747 int sent_by_port, char *via_params) 134140cb5e5dSvi117747 { 134240cb5e5dSvi117747 _sip_header_t *new_header; 134340cb5e5dSvi117747 int header_size; 134440cb5e5dSvi117747 int count; 134540cb5e5dSvi117747 134640cb5e5dSvi117747 header_size = strlen(SIP_VIA) + SIP_SPACE_LEN + sizeof (char) + 134740cb5e5dSvi117747 SIP_SPACE_LEN + strlen(SIP_VERSION) + sizeof (char) + 134840cb5e5dSvi117747 strlen(sent_protocol_transport) + SIP_SPACE_LEN + 134940cb5e5dSvi117747 strlen(sent_by_host) + strlen(SIP_CRLF); 135040cb5e5dSvi117747 135140cb5e5dSvi117747 if (sent_by_port > 0) { 135240cb5e5dSvi117747 header_size += SIP_SPACE_LEN + sizeof (char) + SIP_SPACE_LEN + 135340cb5e5dSvi117747 sip_num_of_digits(sent_by_port); 135440cb5e5dSvi117747 } 135540cb5e5dSvi117747 135640cb5e5dSvi117747 if (via_params != NULL) { 135740cb5e5dSvi117747 header_size += SIP_SPACE_LEN + sizeof (char) + 135840cb5e5dSvi117747 strlen(via_params); 135940cb5e5dSvi117747 } 136040cb5e5dSvi117747 new_header = sip_new_header(header_size); 136140cb5e5dSvi117747 if (new_header->sip_hdr_start == NULL) 136240cb5e5dSvi117747 return (NULL); 136340cb5e5dSvi117747 count = snprintf(new_header->sip_hdr_current, header_size + 1, 136440cb5e5dSvi117747 "%s %c %s/%s %s", 136540cb5e5dSvi117747 SIP_VIA, SIP_HCOLON, SIP_VERSION, sent_protocol_transport, 136640cb5e5dSvi117747 sent_by_host); 136740cb5e5dSvi117747 new_header->sip_hdr_current += count; 136840cb5e5dSvi117747 header_size -= count; 136940cb5e5dSvi117747 137040cb5e5dSvi117747 if (sent_by_port > 0) { 137140cb5e5dSvi117747 count = snprintf(new_header->sip_hdr_current, header_size + 1, 137240cb5e5dSvi117747 " %c %d", SIP_HCOLON, sent_by_port); 137340cb5e5dSvi117747 new_header->sip_hdr_current += count; 137440cb5e5dSvi117747 header_size -= count; 137540cb5e5dSvi117747 } 137640cb5e5dSvi117747 137740cb5e5dSvi117747 if (via_params != NULL) { 137840cb5e5dSvi117747 count = snprintf(new_header->sip_hdr_current, header_size + 1, 137940cb5e5dSvi117747 " %c%s", SIP_SEMI, via_params); 138040cb5e5dSvi117747 new_header->sip_hdr_current += count; 138140cb5e5dSvi117747 header_size -= count; 138240cb5e5dSvi117747 } 138340cb5e5dSvi117747 138440cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_current, header_size + 1, 138540cb5e5dSvi117747 "%s", SIP_CRLF); 138640cb5e5dSvi117747 return (new_header); 138740cb5e5dSvi117747 } 138840cb5e5dSvi117747 138940cb5e5dSvi117747 /* 139040cb5e5dSvi117747 * There can be multiple via headers we always append the header. 139140cb5e5dSvi117747 * We expect the via params to be a semi-colon separated list of parameters. 139240cb5e5dSvi117747 * We will add a semi-clone, before adding the list to the header. 139340cb5e5dSvi117747 */ 139440cb5e5dSvi117747 int 139540cb5e5dSvi117747 sip_add_via(sip_msg_t sip_msg, char *sent_protocol_transport, 139640cb5e5dSvi117747 char *sent_by_host, int sent_by_port, char *via_params) 139740cb5e5dSvi117747 { 139840cb5e5dSvi117747 _sip_header_t *new_header; 139940cb5e5dSvi117747 _sip_msg_t *_sip_msg; 140040cb5e5dSvi117747 140140cb5e5dSvi117747 if (sip_msg == NULL || sent_protocol_transport == NULL || 140240cb5e5dSvi117747 sent_by_host == NULL || sent_by_port < 0) { 140340cb5e5dSvi117747 return (EINVAL); 140440cb5e5dSvi117747 } 140540cb5e5dSvi117747 140640cb5e5dSvi117747 _sip_msg = (_sip_msg_t *)sip_msg; 140740cb5e5dSvi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 140840cb5e5dSvi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 140940cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 141040cb5e5dSvi117747 return (ENOTSUP); 141140cb5e5dSvi117747 } 141240cb5e5dSvi117747 141340cb5e5dSvi117747 new_header = sip_create_via_hdr(sent_protocol_transport, sent_by_host, 141440cb5e5dSvi117747 sent_by_port, via_params); 141540cb5e5dSvi117747 if (new_header == NULL) { 141640cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 141740cb5e5dSvi117747 return (ENOMEM); 141840cb5e5dSvi117747 } 141940cb5e5dSvi117747 _sip_add_header(_sip_msg, new_header, B_TRUE, B_FALSE, NULL); 142040cb5e5dSvi117747 if (_sip_msg->sip_msg_buf != NULL) 142140cb5e5dSvi117747 _sip_msg->sip_msg_modified = B_TRUE; 142240cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 142340cb5e5dSvi117747 return (0); 142440cb5e5dSvi117747 } 142540cb5e5dSvi117747 142640cb5e5dSvi117747 /* 142740cb5e5dSvi117747 * Max-Forwards = "Max-Forwards" HCOLON 1*DIGIT 142840cb5e5dSvi117747 */ 142940cb5e5dSvi117747 int 143040cb5e5dSvi117747 sip_add_maxforward(sip_msg_t sip_msg, uint_t maxforward) 143140cb5e5dSvi117747 { 143240cb5e5dSvi117747 if (sip_msg == NULL || (int)maxforward < 0) 143340cb5e5dSvi117747 return (EINVAL); 143440cb5e5dSvi117747 return (sip_add_int_to_msg(sip_msg, SIP_MAX_FORWARDS, maxforward, 143540cb5e5dSvi117747 NULL)); 143640cb5e5dSvi117747 } 143740cb5e5dSvi117747 143840cb5e5dSvi117747 /* 143940cb5e5dSvi117747 * Content-Type = ( "Content-Type" / "c" ) HCOLON media-type 144040cb5e5dSvi117747 * media-type = m-type SLASH m-subtype *(SEMI m-parameter) 144140cb5e5dSvi117747 * m-type = discrete-type / composite-type 144240cb5e5dSvi117747 * discrete-type = "text" / "image" / "audio" / "video" 144340cb5e5dSvi117747 * / "application" / extension-token 144440cb5e5dSvi117747 * composite-type = "message" / "multipart" / extension-token 144540cb5e5dSvi117747 * extension-token = ietf-token / x-token 144640cb5e5dSvi117747 * ietf-token = token 144740cb5e5dSvi117747 * x-token = "x-" token 144840cb5e5dSvi117747 * m-subtype = extension-token / iana-token 144940cb5e5dSvi117747 * iana-token = token 145040cb5e5dSvi117747 * m-parameter = m-attribute EQUAL m-value 145140cb5e5dSvi117747 * m-attribute = token 145240cb5e5dSvi117747 * m-value = token / quoted-string 145340cb5e5dSvi117747 */ 145440cb5e5dSvi117747 int 145540cb5e5dSvi117747 sip_add_content_type(sip_msg_t sip_msg, char *type, char *subtype) 145640cb5e5dSvi117747 { 145740cb5e5dSvi117747 if (sip_msg == NULL || type == NULL || subtype == NULL) 145840cb5e5dSvi117747 return (EINVAL); 145940cb5e5dSvi117747 return (sip_add_2strs_to_msg(sip_msg, SIP_CONTENT_TYPE, type, B_FALSE, 146040cb5e5dSvi117747 subtype, NULL, SIP_SLASH)); 146140cb5e5dSvi117747 } 146240cb5e5dSvi117747 146340cb5e5dSvi117747 /* 146440cb5e5dSvi117747 * Content-Length = ( "Content-Length" / "l" ) HCOLON 1*DIGIT 146540cb5e5dSvi117747 */ 146640cb5e5dSvi117747 int 146740cb5e5dSvi117747 sip_add_content_length(_sip_msg_t *_sip_msg, int length) 146840cb5e5dSvi117747 { 146940cb5e5dSvi117747 _sip_header_t *new_header; 147040cb5e5dSvi117747 int header_size; 147140cb5e5dSvi117747 147240cb5e5dSvi117747 if (_sip_msg == NULL || length < 0) 147340cb5e5dSvi117747 return (EINVAL); 147440cb5e5dSvi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 147540cb5e5dSvi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 147640cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 147740cb5e5dSvi117747 return (ENOTSUP); 147840cb5e5dSvi117747 } 147940cb5e5dSvi117747 148040cb5e5dSvi117747 header_size = strlen(SIP_CONTENT_LENGTH) + SIP_SPACE_LEN + 148140cb5e5dSvi117747 sizeof (char) + SIP_SPACE_LEN + sip_num_of_digits(length) + 148240cb5e5dSvi117747 strlen(SIP_CRLF) + strlen(SIP_CRLF); 148340cb5e5dSvi117747 148440cb5e5dSvi117747 new_header = sip_new_header(header_size); 148540cb5e5dSvi117747 if (new_header == NULL) { 148640cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 148740cb5e5dSvi117747 return (ENOMEM); 148840cb5e5dSvi117747 } 148940cb5e5dSvi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 149040cb5e5dSvi117747 "%s %c %u%s%s", SIP_CONTENT_LENGTH, SIP_HCOLON, length, 149140cb5e5dSvi117747 SIP_CRLF, SIP_CRLF); 149240cb5e5dSvi117747 149340cb5e5dSvi117747 _sip_add_header(_sip_msg, new_header, B_TRUE, B_FALSE, NULL); 149440cb5e5dSvi117747 if (_sip_msg->sip_msg_buf != NULL) 149540cb5e5dSvi117747 _sip_msg->sip_msg_modified = B_TRUE; 149640cb5e5dSvi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 149740cb5e5dSvi117747 return (0); 149840cb5e5dSvi117747 } 149940cb5e5dSvi117747 150040cb5e5dSvi117747 150140cb5e5dSvi117747 /* 150240cb5e5dSvi117747 * Contact = ("Contact" / "m" ) HCOLON 150340cb5e5dSvi117747 * ( STAR / (contact-param *(COMMA contact-param))) 150440cb5e5dSvi117747 * contact-param = (name-addr / addr-spec) *(SEMI contact-params) 150540cb5e5dSvi117747 * name-addr = [ display-name ] LAQUOT addr-spec RAQUOT 150640cb5e5dSvi117747 * addr-spec = SIP-URI / SIPS-URI / absoluteURI 150740cb5e5dSvi117747 * display-name = *(token LWS)/ quoted-string 150840cb5e5dSvi117747 * contact-params = c-p-q / c-p-expires 150940cb5e5dSvi117747 * / contact-extension 151040cb5e5dSvi117747 */ 151140cb5e5dSvi117747 int 151240cb5e5dSvi117747 sip_add_contact(sip_msg_t sip_msg, char *display_name, char *contact_uri, 151340cb5e5dSvi117747 boolean_t add_aquot, char *contact_params) 151440cb5e5dSvi117747 { 151540cb5e5dSvi117747 return (sip_add_name_aspec(sip_msg, display_name, contact_uri, NULL, 151640cb5e5dSvi117747 add_aquot, SIP_CONTACT, contact_params)); 151740cb5e5dSvi117747 } 151840cb5e5dSvi117747 151940cb5e5dSvi117747 /* 152040cb5e5dSvi117747 * From = ( "From" / "f" ) HCOLON from-spec 152140cb5e5dSvi117747 * from-spec = ( name-addr / addr-spec ) 152240cb5e5dSvi117747 * *( SEMI from-param ) 152340cb5e5dSvi117747 * from-param = tag-param / generic-param 152440cb5e5dSvi117747 * tag-param = "tag" EQUAL token 152540cb5e5dSvi117747 * 152640cb5e5dSvi117747 * Since there can be more than one tags, fromtags is a semi colon separated 152740cb5e5dSvi117747 * list of tags. 152840cb5e5dSvi117747 */ 152940cb5e5dSvi117747 int 153040cb5e5dSvi117747 sip_add_from(sip_msg_t sip_msg, char *display_name, char *from_uri, 153140cb5e5dSvi117747 char *fromtags, boolean_t add_aquot, char *from_params) 153240cb5e5dSvi117747 { 153340cb5e5dSvi117747 return (sip_add_name_aspec(sip_msg, display_name, from_uri, fromtags, 153440cb5e5dSvi117747 add_aquot, SIP_FROM, from_params)); 153540cb5e5dSvi117747 } 153640cb5e5dSvi117747 153740cb5e5dSvi117747 /* 153840cb5e5dSvi117747 * To = ( "To" / "t" ) HCOLON ( name-addr 153940cb5e5dSvi117747 * / addr-spec ) *( SEMI to-param ) 154040cb5e5dSvi117747 * to-param = tag-param / generic-param 154140cb5e5dSvi117747 */ 154240cb5e5dSvi117747 int 154340cb5e5dSvi117747 sip_add_to(sip_msg_t sip_msg, char *display_name, char *to_uri, 154440cb5e5dSvi117747 char *totags, boolean_t add_aquot, char *to_params) 154540cb5e5dSvi117747 { 154640cb5e5dSvi117747 return (sip_add_name_aspec(sip_msg, display_name, to_uri, totags, 154740cb5e5dSvi117747 add_aquot, SIP_TO, to_params)); 154840cb5e5dSvi117747 } 154940cb5e5dSvi117747 155040cb5e5dSvi117747 /* 155140cb5e5dSvi117747 * Route = "Route" HCOLON route-param *(COMMA route-param) 155240cb5e5dSvi117747 * route-param = name-addr *( SEMI rr-param ) 155340cb5e5dSvi117747 */ 155440cb5e5dSvi117747 int 155540cb5e5dSvi117747 sip_add_route(sip_msg_t sip_msg, char *display_name, char *uri, 155640cb5e5dSvi117747 char *route_params) 155740cb5e5dSvi117747 { 155840cb5e5dSvi117747 return (sip_add_name_aspec(sip_msg, display_name, uri, NULL, B_TRUE, 155940cb5e5dSvi117747 SIP_ROUTE, route_params)); 156040cb5e5dSvi117747 } 156140cb5e5dSvi117747 156240cb5e5dSvi117747 /* 156340cb5e5dSvi117747 * Record-Route = "Record-Route" HCOLON rec-route *(COMMA rec-route) 156440cb5e5dSvi117747 * rec-route = name-addr *( SEMI rr-param ) 156540cb5e5dSvi117747 * rr-param = generic-param 156640cb5e5dSvi117747 */ 156740cb5e5dSvi117747 int 156840cb5e5dSvi117747 sip_add_record_route(sip_msg_t sip_msg, char *display_name, char *uri, 156940cb5e5dSvi117747 char *route_params) 157040cb5e5dSvi117747 { 157140cb5e5dSvi117747 return (sip_add_name_aspec(sip_msg, display_name, uri, NULL, B_TRUE, 157240cb5e5dSvi117747 SIP_RECORD_ROUTE, route_params)); 157340cb5e5dSvi117747 } 157440cb5e5dSvi117747 157540cb5e5dSvi117747 157640cb5e5dSvi117747 /* 157740cb5e5dSvi117747 * PAssertedID = "P-Asserted-Identity" HCOLON PAssertedID-value 157840cb5e5dSvi117747 * *(COMMA PAssertedID-value) 157940cb5e5dSvi117747 * PAssertedID-value = name-addr / addr-spec 158040cb5e5dSvi117747 */ 158140cb5e5dSvi117747 int 158240cb5e5dSvi117747 sip_add_passertedid(sip_msg_t sip_msg, char *display_name, char *addr, 158340cb5e5dSvi117747 boolean_t add_aquot) 158440cb5e5dSvi117747 { 158540cb5e5dSvi117747 return (sip_add_name_aspec(sip_msg, display_name, addr, NULL, add_aquot, 158640cb5e5dSvi117747 SIP_PASSERTEDID, NULL)); 158740cb5e5dSvi117747 } 158840cb5e5dSvi117747 158940cb5e5dSvi117747 /* 159040cb5e5dSvi117747 * PPreferredID = "P-Preferred-Identity" HCOLON PPreferredID-value 159140cb5e5dSvi117747 * *(COMMA PPreferredID-value) 159240cb5e5dSvi117747 * PPreferredID-value = name-addr / addr-spec 159340cb5e5dSvi117747 */ 159440cb5e5dSvi117747 int 159540cb5e5dSvi117747 sip_add_ppreferredid(sip_msg_t sip_msg, char *display_name, char *addr, 159640cb5e5dSvi117747 boolean_t add_aquot) 159740cb5e5dSvi117747 { 159840cb5e5dSvi117747 return (sip_add_name_aspec(sip_msg, display_name, addr, NULL, add_aquot, 159940cb5e5dSvi117747 SIP_PPREFERREDID, NULL)); 160040cb5e5dSvi117747 } 1601