summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsip/common/sip_gids.c
diff options
context:
space:
mode:
authorvi117747 <none@none>2006-10-07 14:26:26 -0700
committervi117747 <none@none>2006-10-07 14:26:26 -0700
commit40cb5e5daa7b80bb70fcf8dadfb20f9281566331 (patch)
treedc95663e296c5dbf3cb8faa561e53416978eb4dc /usr/src/lib/libsip/common/sip_gids.c
parent56a424cca6b3f91f31bdab72a4626c48c779fe8b (diff)
downloadillumos-gate-40cb5e5daa7b80bb70fcf8dadfb20f9281566331.tar.gz
PSARC 2006/402 SIP Library Integration
6461142 Integrate SIP in Solaris
Diffstat (limited to 'usr/src/lib/libsip/common/sip_gids.c')
-rw-r--r--usr/src/lib/libsip/common/sip_gids.c302
1 files changed, 302 insertions, 0 deletions
diff --git a/usr/src/lib/libsip/common/sip_gids.c b/usr/src/lib/libsip/common/sip_gids.c
new file mode 100644
index 0000000000..f1ecfd726b
--- /dev/null
+++ b/usr/src/lib/libsip/common/sip_gids.c
@@ -0,0 +1,302 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <time.h>
+#include <sys/errno.h>
+#ifdef __linux__
+#include <sasl/sasl.h>
+#include <sasl/saslplug.h>
+#else
+#include <sys/md5.h>
+#endif
+
+#include "sip_parse_uri.h"
+#include "sip_msg.h"
+#include "sip_miscdefs.h"
+
+void sip_md5_hash(char *, int, char *, int, char *, int, char *, int,
+ char *, int, char *, int, uchar_t *);
+
+#define SIP_RANDOM_LEN 20
+
+/*
+ * Wrapper around /dev/urandom
+ */
+static int
+sip_get_random(char *buf, int buflen)
+{
+ static int devrandom = -1;
+
+ if (devrandom == -1 &&
+ (devrandom = open("/dev/urandom", O_RDONLY)) == -1) {
+ return (-1);
+ }
+
+ if (read(devrandom, buf, buflen) == -1)
+ return (-1);
+ return (0);
+}
+
+/*
+ * Get MD5 hash of call_id, from_tag, to_tag using key
+ */
+void
+sip_md5_hash(char *str1, int lstr1, char *str2, int lstr2, char *str3,
+ int lstr3, char *str4, int lstr4, char *str5, int lstr5,
+ char *str6, int lstr6, uchar_t *digest)
+{
+ MD5_CTX ctx;
+
+#ifdef __linux__
+ _sasl_MD5Init(&ctx);
+
+ _sasl_MD5Update(&ctx, (uchar_t *)&sip_hash_salt, sizeof (uint64_t));
+
+ if (str1 != NULL)
+ _sasl_MD5Update(&ctx, (uchar_t *)str1, lstr1);
+
+ if (str2 != NULL)
+ _sasl_MD5Update(&ctx, (uchar_t *)str2, lstr2);
+
+ if (str3 != NULL)
+ _sasl_MD5Update(&ctx, (uchar_t *)str3, lstr3);
+
+ if (str4 != NULL)
+ _sasl_MD5Update(&ctx, (uchar_t *)str4, lstr4);
+
+ if (str5 != NULL)
+ _sasl_MD5Update(&ctx, (uchar_t *)str5, lstr5);
+
+ if (str6 != NULL)
+ _sasl_MD5Update(&ctx, (uchar_t *)str6, lstr6);
+
+ _sasl_MD5Final(digest, &ctx);
+#else /* solaris */
+ MD5Init(&ctx);
+
+ MD5Update(&ctx, (uchar_t *)&sip_hash_salt, sizeof (uint64_t));
+
+ if (str1 != NULL)
+ MD5Update(&ctx, (uchar_t *)str1, lstr1);
+
+ if (str2 != NULL)
+ MD5Update(&ctx, (uchar_t *)str2, lstr2);
+
+ if (str3 != NULL)
+ MD5Update(&ctx, (uchar_t *)str3, lstr3);
+
+ if (str4 != NULL)
+ MD5Update(&ctx, (uchar_t *)str4, lstr4);
+
+ if (str5 != NULL)
+ MD5Update(&ctx, (uchar_t *)str5, lstr5);
+
+ if (str6 != NULL)
+ MD5Update(&ctx, (uchar_t *)str6, lstr6);
+
+ MD5Final(digest, &ctx);
+#endif
+}
+
+/*
+ * generate a guid (globally unique id)
+ */
+char *
+sip_guid()
+{
+ int i;
+ uint8_t *r;
+ uint32_t random;
+ uint32_t time;
+ char *guid;
+ int guidlen;
+#ifdef __linux__
+ struct timespec tspec;
+#endif
+
+ guid = (char *)malloc(SIP_RANDOM_LEN + 1);
+ if (guid == NULL)
+ return (NULL);
+ /*
+ * Get a 32-bit random #
+ */
+ if (sip_get_random((char *)&random, sizeof (random)) != 0)
+ return (NULL);
+#ifdef __linux__
+ if (clock_gettime(CLOCK_REALTIME, &tspec) != 0)
+ return (NULL);
+ time = (uint32_t)tspec.tv_nsec;
+#else
+ /*
+ * Get 32-bits from gethrtime()
+ */
+ time = (uint32_t)gethrtime();
+#endif
+ (void) snprintf(guid, SIP_RANDOM_LEN + 1, "%u%u", random, time);
+ guidlen = strlen(guid);
+
+ /*
+ * just throw in some alphabets too
+ */
+ r = (uint8_t *)malloc(guidlen);
+ if (sip_get_random((char *)r, guidlen) != 0) {
+ free(guid);
+ return (NULL);
+ }
+ for (i = 0; i < guidlen; i++) {
+ if ((r[i] >= 65 && r[i] <= 90) ||
+ (r[i] >= 97 && r[i] <= 122)) {
+ guid[i] = r[i];
+ }
+ }
+ free(r);
+ return (guid);
+}
+
+/*
+ * Generate branchid for a transaction
+ */
+char *
+sip_branchid(sip_msg_t sip_msg)
+{
+ char *guid;
+ char *branchid;
+ _sip_header_t *via;
+ unsigned char md5_hash[16];
+ _sip_header_t *to;
+ _sip_header_t *from;
+ _sip_header_t *callid;
+ _sip_msg_t *_sip_msg;
+ int cseq;
+ MD5_CTX ctx;
+ size_t len;
+ int hdrlen;
+ int i;
+
+ if (sip_msg == NULL) {
+generate_bid:
+ if ((branchid = (char *)malloc(SIP_BRANCHID_LEN + 1)) == NULL)
+ return (NULL);
+ guid = sip_guid();
+ if (guid == NULL) {
+ free(branchid);
+ return (NULL);
+ }
+ (void) snprintf(branchid, SIP_BRANCHID_LEN + 1, "z9hG4bK%s",
+ guid);
+ free(guid);
+ return (branchid);
+ }
+ _sip_msg = (_sip_msg_t *)sip_msg;
+ (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex);
+ via = sip_search_for_header(_sip_msg, SIP_VIA, NULL);
+ if (via == NULL) {
+ (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
+ goto generate_bid;
+ }
+ to = sip_search_for_header(_sip_msg, SIP_TO, NULL);
+ from = sip_search_for_header(_sip_msg, SIP_FROM, NULL);
+ callid = sip_search_for_header(_sip_msg, SIP_CALL_ID, NULL);
+ (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex);
+ cseq = sip_get_callseq_num(_sip_msg, NULL);
+ if (to == NULL || from == NULL || callid == NULL || cseq == -1)
+ return (NULL);
+ if (_sip_msg->sip_msg_req_res == NULL ||
+ _sip_msg->sip_msg_req_res->U.sip_request.sip_request_uri.
+ sip_str_ptr == NULL) {
+ return (NULL);
+ }
+ len = 2 * sizeof (md5_hash) + 1;
+ if ((branchid = malloc(len)) == NULL)
+ return (NULL);
+#ifdef __linux__
+ _sasl_MD5Init(&ctx);
+ hdrlen = via->sip_hdr_end - via->sip_hdr_start;
+ _sasl_MD5Update(&ctx, (uchar_t *)via->sip_hdr_start, hdrlen);
+ hdrlen = to->sip_hdr_end - to->sip_hdr_start;
+ _sasl_MD5Update(&ctx, (uchar_t *)to->sip_hdr_start, hdrlen);
+ hdrlen = from->sip_hdr_end - from->sip_hdr_start;
+ _sasl_MD5Update(&ctx, (uchar_t *)from->sip_hdr_start, hdrlen);
+ hdrlen = callid->sip_hdr_end - callid->sip_hdr_start;
+ _sasl_MD5Update(&ctx, (uchar_t *)callid->sip_hdr_start, hdrlen);
+ _sasl_MD5Update(&ctx, (uchar_t *)_sip_msg->sip_msg_req_res->
+ U.sip_request.sip_request_uri.sip_str_ptr,
+ _sip_msg->sip_msg_req_res->U.sip_request.
+ sip_request_uri.sip_str_len);
+ _sasl_MD5Update(&ctx, (uchar_t *)&cseq, sizeof (int));
+ _sasl_MD5Final(md5_hash, &ctx);
+#else /* solaris */
+ MD5Init(&ctx);
+ hdrlen = via->sip_hdr_end - via->sip_hdr_start;
+ MD5Update(&ctx, (uchar_t *)via->sip_hdr_start, hdrlen);
+ hdrlen = to->sip_hdr_end - to->sip_hdr_start;
+ MD5Update(&ctx, (uchar_t *)to->sip_hdr_start, hdrlen);
+ hdrlen = from->sip_hdr_end - from->sip_hdr_start;
+ MD5Update(&ctx, (uchar_t *)from->sip_hdr_start, hdrlen);
+ hdrlen = callid->sip_hdr_end - callid->sip_hdr_start;
+ MD5Update(&ctx, (uchar_t *)callid->sip_hdr_start, hdrlen);
+ MD5Update(&ctx, (uchar_t *)_sip_msg->sip_msg_req_res->
+ U.sip_request.sip_request_uri.sip_str_ptr,
+ _sip_msg->sip_msg_req_res->U.sip_request.
+ sip_request_uri.sip_str_len);
+ MD5Update(&ctx, (uchar_t *)&cseq, sizeof (int));
+ MD5Final(md5_hash, &ctx);
+#endif
+ for (i = 0; i < sizeof (md5_hash); i++) {
+ (void) snprintf(&branchid[2 * i], len - (2 * i), "%02x",
+ md5_hash[i]);
+ }
+ return (branchid);
+}
+
+uint32_t
+sip_get_cseq()
+{
+ time_t tval;
+
+ tval = time(NULL);
+
+ return ((uint32_t)tval);
+}
+
+uint32_t
+sip_get_rseq()
+{
+ time_t tval;
+
+ tval = time(NULL);
+
+ return ((uint32_t)tval);
+}