40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * CDDL HEADER START
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * The contents of this file are subject to the terms of the
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Common Development and Distribution License (the "License").
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * You may not use this file except in compliance with the License.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * or http://www.opensolaris.org/os/licensing.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * See the License for the specific language governing permissions
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * and limitations under the License.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * When distributing Covered Code, include this CDDL HEADER in each
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * If applicable, add the following below this CDDL HEADER, with the
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * fields enclosed by brackets "[]" replaced with your own identifying
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * information: Portions Copyright [yyyy] [name of copyright owner]
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * CDDL HEADER END
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
2c2c41837e330b002c4220a39638150db504fe0evi * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Use is subject to license terms.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#pragma ident "%Z%%M% %I% %E% SMI"
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
2c2c41837e330b002c4220a39638150db504fe0evi#include <stdlib.h>
2c2c41837e330b002c4220a39638150db504fe0evi#include <assert.h>
2c2c41837e330b002c4220a39638150db504fe0evi#include <ctype.h>
2c2c41837e330b002c4220a39638150db504fe0evi#include <pthread.h>
2c2c41837e330b002c4220a39638150db504fe0evi#include <strings.h>
2c2c41837e330b002c4220a39638150db504fe0evi#include <sip.h>
2c2c41837e330b002c4220a39638150db504fe0evi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi#include "sip_miscdefs.h"
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Local version of case insensitive strstr().
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vistatic char *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_reass_strstr(const char *as1, const char *as2)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi const char *s1;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi const char *s2;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi const char *tptr;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char c;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi s1 = as1;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi s2 = as2;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (s2 == NULL || *s2 == '\0')
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return ((char *)s1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi c = *s2;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (*s1)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (tolower(*s1++) == c) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi tptr = s1;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while ((c = *++s2) == tolower(*s1++) && c)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi ;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (c == 0)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return ((char *)tptr - 1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi s1 = tptr;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi s2 = as2;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi c = *s2;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Get the value in the content-length field and add it to the header length
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * and return the total length. returns -1 if the length cannot be determined
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * or if the message does not contain the entire message.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vistatic int
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_get_msglen(char *p, size_t msglen)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int value = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int hlen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *c;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *e;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int base = 10;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *edge;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int digits = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi edge = p + msglen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if ((c = sip_reass_strstr(p, "content-length")) == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (-1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi hlen = c - p;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if ((hlen + strlen("content-length")) >= msglen)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (-1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi c += strlen("content-length");
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi e = c + 1;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (*e == ' ' || *e == ':') {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi e++;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (e == edge)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (-1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (*e != '\r' && *e != ' ') {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (e == edge)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (-1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (*e >= '0' && *e <= '9')
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi digits = *e - '0';
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi else
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (-1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi value = (value * base) + digits;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi e++;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi while (*e != '\r') {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi e++;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (e == edge)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (-1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi hlen = e - p + 4; /* 4 for 2 CRLFs ?? */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi value += hlen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (value);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi/*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * We have determined that msg does not contain a *single* complete message.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Add it to the reassembly list and check if we have a complete message.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * a NULL 'msg' means we are just checking if there are more complete
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * messages in the list that can be passed up.
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vichar *
40cb5e5daa7b80bb70fcf8dadfb20f9281566331visip_get_tcp_msg(sip_conn_object_t obj, char *msg, size_t *msglen)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi{
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_conn_obj_pvt_t *pvt_data;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi sip_reass_entry_t *reass;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi void **obj_val;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *msgbuf = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int splitlen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *splitbuf;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (msg != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(*msglen > 0);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi msgbuf = (char *)malloc(*msglen + 1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (msgbuf == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) strncpy(msgbuf, msg, *msglen);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi msgbuf[*msglen] = '\0';
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi msg = msgbuf;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi obj_val = (void *)obj;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi pvt_data = (sip_conn_obj_pvt_t *)*obj_val;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi /*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * connection object not initialized
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (pvt_data == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (msg == NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi value = sip_get_msglen(msg, *msglen);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (value == *msglen) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (msg);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (msgbuf != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(msgbuf);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_lock(&pvt_data->sip_conn_obj_reass_lock);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reass = pvt_data->sip_conn_obj_reass;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(reass != NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (reass->sip_reass_msg == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(reass->sip_reass_msglen == 0);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (msg == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi &pvt_data->sip_conn_obj_reass_lock);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi value = sip_get_msglen(msg, *msglen);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (value == *msglen) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi &pvt_data->sip_conn_obj_reass_lock);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (msg);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reass->sip_reass_msg = msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reass->sip_reass_msglen = *msglen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (value != -1 && value < reass->sip_reass_msglen)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi goto tryone;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&pvt_data->sip_conn_obj_reass_lock);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi } else if (msg != NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi /*
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi * Resize, not optimal
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi */
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi int newlen = reass->sip_reass_msglen + *msglen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi char *newmsg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(strlen(reass->sip_reass_msg) == reass->sip_reass_msglen);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi newmsg = malloc(newlen + 1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (newmsg == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi &pvt_data->sip_conn_obj_reass_lock);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (msgbuf != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(msgbuf);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) strncpy(newmsg, reass->sip_reass_msg,
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reass->sip_reass_msglen);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi newmsg[reass->sip_reass_msglen] = '\0';
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) strncat(newmsg, msg, *msglen);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi newmsg[newlen] = '\0';
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi assert(strlen(newmsg) == newlen);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reass->sip_reass_msglen = newlen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(msg);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(reass->sip_reass_msg);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reass->sip_reass_msg = newmsg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi value = sip_get_msglen(reass->sip_reass_msg, reass->sip_reass_msglen);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (value == -1 || value > reass->sip_reass_msglen) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&pvt_data->sip_conn_obj_reass_lock);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vitryone:
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (value == reass->sip_reass_msglen) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi msg = reass->sip_reass_msg;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *msglen = reass->sip_reass_msglen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reass->sip_reass_msg = NULL;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reass->sip_reass_msglen = 0;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&pvt_data->sip_conn_obj_reass_lock);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (msg);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi splitlen = reass->sip_reass_msglen - value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi msg = (char *)malloc(value + 1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi splitbuf = (char *)malloc(splitlen + 1);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (msg == NULL || splitbuf == NULL) {
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (msg != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(msg);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi if (splitbuf != NULL)
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(splitbuf);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&pvt_data->sip_conn_obj_reass_lock);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (NULL);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi }
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) strncpy(msg, reass->sip_reass_msg, value);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi msg[value] = '\0';
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) strncpy(splitbuf, reass->sip_reass_msg + value, splitlen);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi splitbuf[splitlen] = '\0';
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi free(reass->sip_reass_msg);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reass->sip_reass_msg = splitbuf;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi reass->sip_reass_msglen = splitlen;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi (void) pthread_mutex_unlock(&pvt_data->sip_conn_obj_reass_lock);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi *msglen = value;
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi return (msg);
40cb5e5daa7b80bb70fcf8dadfb20f9281566331vi}