157416Smarkm/* crypto/bio/bss_rtcp.c */ 257416Smarkm/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 357416Smarkm * All rights reserved. 457416Smarkm * 557416Smarkm * This package is an SSL implementation written 657416Smarkm * by Eric Young (eay@cryptsoft.com). 757416Smarkm * The implementation was written so as to conform with Netscapes SSL. 857416Smarkm * 957416Smarkm * This library is free for commercial and non-commercial use as long as 1057416Smarkm * the following conditions are aheared to. The following conditions 1157416Smarkm * apply to all code found in this distribution, be it the RC4, RSA, 1257416Smarkm * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1357416Smarkm * included with this distribution is covered by the same copyright terms 1457416Smarkm * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1557416Smarkm * 1657416Smarkm * Copyright remains Eric Young's, and as such any Copyright notices in 1757416Smarkm * the code are not to be removed. 1857416Smarkm * If this package is used in a product, Eric Young should be given attribution 1957416Smarkm * as the author of the parts of the library used. 2057416Smarkm * This can be in the form of a textual message at program startup or 2157416Smarkm * in documentation (online or textual) provided with the package. 2257416Smarkm * 2357416Smarkm * Redistribution and use in source and binary forms, with or without 2457416Smarkm * modification, are permitted provided that the following conditions 2557416Smarkm * are met: 2657416Smarkm * 1. Redistributions of source code must retain the copyright 2757416Smarkm * notice, this list of conditions and the following disclaimer. 2857416Smarkm * 2. Redistributions in binary form must reproduce the above copyright 2957416Smarkm * notice, this list of conditions and the following disclaimer in the 3057416Smarkm * documentation and/or other materials provided with the distribution. 3157416Smarkm * 3. All advertising materials mentioning features or use of this software 3257416Smarkm * must display the following acknowledgement: 3357416Smarkm * "This product includes cryptographic software written by 3457416Smarkm * Eric Young (eay@cryptsoft.com)" 3557416Smarkm * The word 'cryptographic' can be left out if the rouines from the library 3657416Smarkm * being used are not cryptographic related :-). 3757416Smarkm * 4. If you include any Windows specific code (or a derivative thereof) from 3857416Smarkm * the apps directory (application code) you must include an acknowledgement: 3957416Smarkm * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40233294Sstas * 4157416Smarkm * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4257416Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4357416Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4457416Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4557416Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4657416Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4757416Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4857416Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4957416Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5057416Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5157416Smarkm * SUCH DAMAGE. 5257416Smarkm * 5357416Smarkm * The licence and distribution terms for any publically available version or 5457416Smarkm * derivative of this code cannot be changed. i.e. this code cannot simply be 5557416Smarkm * copied and put under another distribution licence 5657416Smarkm * [including the GNU Public Licence.] 5757416Smarkm */ 5857416Smarkm 5957416Smarkm/*- 6057416Smarkm * Written by David L. Jones <jonesd@kcgl1.eng.ohio-state.edu> 6157416Smarkm * Date: 22-JUL-1996 6257416Smarkm * Revised: 25-SEP-1997 Update for 0.8.1, BIO_CTRL_SET -> BIO_C_SET_FD 6357416Smarkm */ 6457416Smarkm/* VMS */ 6557416Smarkm#include <stdio.h> 6657416Smarkm#include <stdlib.h> 6757416Smarkm#include <string.h> 6857416Smarkm#include <errno.h> 6957416Smarkm#include "cryptlib.h" 7057416Smarkm#include <openssl/bio.h> 7157416Smarkm 7257416Smarkm#include <iodef.h> /* VMS IO$_ definitions */ 7357416Smarkm#include <starlet.h> 7457416Smarkm 7557416Smarkmtypedef unsigned short io_channel; 7657416Smarkm/*************************************************************************/ 7757416Smarkmstruct io_status { 7857416Smarkm short status, count; 7957416Smarkm long flags; 8057416Smarkm}; 8157416Smarkm 8257416Smarkm/* Should have member alignment inhibited */ 8357416Smarkmstruct rpc_msg { 8457416Smarkm /* 'A'-app data. 'R'-remote client 'G'-global */ 8557416Smarkm char channel; 8657416Smarkm /* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */ 8757416Smarkm char function; 8857416Smarkm /* Amount of data returned or max to return */ 8957416Smarkm unsigned short int length; 9057416Smarkm /* variable data */ 9157416Smarkm char data[4092]; 9257416Smarkm}; 9357416Smarkm#define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092) 9457416Smarkm 9557416Smarkmstruct rpc_ctx { 9657416Smarkm int filled, pos; 9757416Smarkm struct rpc_msg msg; 9857416Smarkm}; 9957416Smarkm 10057416Smarkmstatic int rtcp_write(BIO *h, const char *buf, int num); 10157416Smarkmstatic int rtcp_read(BIO *h, char *buf, int size); 10257416Smarkmstatic int rtcp_puts(BIO *h, const char *str); 10357416Smarkmstatic int rtcp_gets(BIO *h, char *str, int size); 10457416Smarkmstatic long rtcp_ctrl(BIO *h, int cmd, long arg1, void *arg2); 10557416Smarkmstatic int rtcp_new(BIO *h); 10657416Smarkmstatic int rtcp_free(BIO *data); 10757416Smarkm 10857416Smarkmstatic BIO_METHOD rtcp_method = { 10957416Smarkm BIO_TYPE_FD, 11057416Smarkm "RTCP", 11157416Smarkm rtcp_write, 11257416Smarkm rtcp_read, 11357416Smarkm rtcp_puts, 11457416Smarkm rtcp_gets, 11557416Smarkm rtcp_ctrl, 11657416Smarkm rtcp_new, 11757416Smarkm rtcp_free, 11857416Smarkm NULL, 11957416Smarkm}; 12057416Smarkm 12157416SmarkmBIO_METHOD *BIO_s_rtcp(void) 12257416Smarkm{ 12357416Smarkm return (&rtcp_method); 12457416Smarkm} 12557416Smarkm 12657416Smarkm/*****************************************************************************/ 12757416Smarkm/* 12857416Smarkm * Decnet I/O routines. 12957416Smarkm */ 13057416Smarkm 13157416Smarkm#ifdef __DECC 13257416Smarkm# pragma message save 13357416Smarkm# pragma message disable DOLLARID 13457416Smarkm#endif 13557416Smarkm 13657416Smarkmstatic int get(io_channel chan, char *buffer, int maxlen, int *length) 13757416Smarkm{ 13857416Smarkm int status; 13957416Smarkm struct io_status iosb; 14057416Smarkm status = sys$qiow(0, chan, IO$_READVBLK, &iosb, 0, 0, 14157416Smarkm buffer, maxlen, 0, 0, 0, 0); 14257416Smarkm if ((status & 1) == 1) 14357416Smarkm status = iosb.status; 14457416Smarkm if ((status & 1) == 1) 14557416Smarkm *length = iosb.count; 14657416Smarkm return status; 14757416Smarkm} 14857416Smarkm 14957416Smarkmstatic int put(io_channel chan, char *buffer, int length) 15057416Smarkm{ 15157416Smarkm int status; 15257416Smarkm struct io_status iosb; 15357416Smarkm status = sys$qiow(0, chan, IO$_WRITEVBLK, &iosb, 0, 0, 15457416Smarkm buffer, length, 0, 0, 0, 0); 15557416Smarkm if ((status & 1) == 1) 15657416Smarkm status = iosb.status; 15757416Smarkm return status; 15857416Smarkm} 15957416Smarkm 16057416Smarkm#ifdef __DECC 16157416Smarkm# pragma message restore 16257416Smarkm#endif 16357416Smarkm 16457416Smarkm/***************************************************************************/ 16557416Smarkm 16657416Smarkmstatic int rtcp_new(BIO *bi) 16757416Smarkm{ 16857416Smarkm struct rpc_ctx *ctx; 16957416Smarkm bi->init = 1; 17057416Smarkm bi->num = 0; 17157416Smarkm bi->flags = 0; 17257416Smarkm bi->ptr = OPENSSL_malloc(sizeof(struct rpc_ctx)); 17357416Smarkm ctx = (struct rpc_ctx *)bi->ptr; 17457416Smarkm ctx->filled = 0; 17557416Smarkm ctx->pos = 0; 17657416Smarkm return (1); 17757416Smarkm} 17857416Smarkm 17957416Smarkmstatic int rtcp_free(BIO *a) 18057416Smarkm{ 18157416Smarkm if (a == NULL) 18257416Smarkm return (0); 18357416Smarkm if (a->ptr) 18457416Smarkm OPENSSL_free(a->ptr); 18557416Smarkm a->ptr = NULL; 18657416Smarkm return (1); 18757416Smarkm} 18857416Smarkm 18957416Smarkmstatic int rtcp_read(BIO *b, char *out, int outl) 19057416Smarkm{ 19157416Smarkm int status, length; 19257416Smarkm struct rpc_ctx *ctx; 19357416Smarkm /* 19457416Smarkm * read data, return existing. 19557416Smarkm */ 19657416Smarkm ctx = (struct rpc_ctx *)b->ptr; 19757416Smarkm if (ctx->pos < ctx->filled) { 19857416Smarkm length = ctx->filled - ctx->pos; 19957416Smarkm if (length > outl) 20057416Smarkm length = outl; 20157416Smarkm memmove(out, &ctx->msg.data[ctx->pos], length); 20257416Smarkm ctx->pos += length; 20357416Smarkm return length; 20457416Smarkm } 20557416Smarkm /* 20657416Smarkm * Requst more data from R channel. 20757416Smarkm */ 20857416Smarkm ctx->msg.channel = 'R'; 20957416Smarkm ctx->msg.function = 'G'; 21057416Smarkm ctx->msg.length = sizeof(ctx->msg.data); 21157416Smarkm status = put(b->num, (char *)&ctx->msg, RPC_HDR_SIZE); 21257416Smarkm if ((status & 1) == 0) { 21357416Smarkm return -1; 21457416Smarkm } 21557416Smarkm /* 21657416Smarkm * Read. 21757416Smarkm */ 21857416Smarkm ctx->pos = ctx->filled = 0; 21957416Smarkm status = get(b->num, (char *)&ctx->msg, sizeof(ctx->msg), &length); 22057416Smarkm if ((status & 1) == 0) 22157416Smarkm length = -1; 22257416Smarkm if (ctx->msg.channel != 'R' || ctx->msg.function != 'C') { 22357416Smarkm length = -1; 22457416Smarkm } 22557416Smarkm ctx->filled = length - RPC_HDR_SIZE; 22657416Smarkm 22757416Smarkm if (ctx->pos < ctx->filled) { 22857416Smarkm length = ctx->filled - ctx->pos; 22957416Smarkm if (length > outl) 23057416Smarkm length = outl; 23157416Smarkm memmove(out, ctx->msg.data, length); 23257416Smarkm ctx->pos += length; 23357416Smarkm return length; 23457416Smarkm } 23557416Smarkm 23657416Smarkm return length; 23757416Smarkm} 23857416Smarkm 23957416Smarkmstatic int rtcp_write(BIO *b, const char *in, int inl) 24057416Smarkm{ 24157416Smarkm int status, i, segment, length; 24257416Smarkm struct rpc_ctx *ctx; 24357416Smarkm /* 24457416Smarkm * Output data, send in chunks no larger that sizeof(ctx->msg.data). 24557416Smarkm */ 24657416Smarkm ctx = (struct rpc_ctx *)b->ptr; 24757416Smarkm for (i = 0; i < inl; i += segment) { 24857416Smarkm segment = inl - i; 24957416Smarkm if (segment > sizeof(ctx->msg.data)) 25057416Smarkm segment = sizeof(ctx->msg.data); 251233294Sstas ctx->msg.channel = 'R'; 252233294Sstas ctx->msg.function = 'P'; 253233294Sstas ctx->msg.length = segment; 254233294Sstas memmove(ctx->msg.data, &in[i], segment); 255233294Sstas status = put(b->num, (char *)&ctx->msg, segment + RPC_HDR_SIZE); 256233294Sstas if ((status & 1) == 0) { 257233294Sstas i = -1; 258233294Sstas break; 259233294Sstas } 260233294Sstas 261233294Sstas status = get(b->num, (char *)&ctx->msg, sizeof(ctx->msg), &length); 262233294Sstas if (((status & 1) == 0) || (length < RPC_HDR_SIZE)) { 26357416Smarkm i = -1; 264233294Sstas break; 26557416Smarkm } 26657416Smarkm if ((ctx->msg.channel != 'R') || (ctx->msg.function != 'C')) { 26757416Smarkm printf("unexpected response when confirming put %c %c\n", 26857416Smarkm ctx->msg.channel, ctx->msg.function); 26957416Smarkm 27057416Smarkm } 27157416Smarkm } 27257416Smarkm return (i); 27357416Smarkm} 27457416Smarkm 27557416Smarkmstatic long rtcp_ctrl(BIO *b, int cmd, long num, void *ptr) 27657416Smarkm{ 27757416Smarkm long ret = 1; 27857416Smarkm 27957416Smarkm switch (cmd) { 28057416Smarkm case BIO_CTRL_RESET: 28157416Smarkm case BIO_CTRL_EOF: 28257416Smarkm ret = 1; 28357416Smarkm break; 28457416Smarkm case BIO_C_SET_FD: 28557416Smarkm b->num = num; 28657416Smarkm ret = 1; 28757416Smarkm break; 28857416Smarkm case BIO_CTRL_SET_CLOSE: 28957416Smarkm case BIO_CTRL_FLUSH: 29057416Smarkm case BIO_CTRL_DUP: 29157416Smarkm ret = 1; 29257416Smarkm break; 29357416Smarkm case BIO_CTRL_GET_CLOSE: 29457416Smarkm case BIO_CTRL_INFO: 29557416Smarkm case BIO_CTRL_GET: 29657416Smarkm case BIO_CTRL_PENDING: 29757416Smarkm case BIO_CTRL_WPENDING: 29857416Smarkm default: 29957416Smarkm ret = 0; 30057416Smarkm break; 30157416Smarkm } 30257416Smarkm return (ret); 30357416Smarkm} 30457416Smarkm 30557416Smarkmstatic int rtcp_gets(BIO *bp, char *buf, int size) 30657416Smarkm{ 30757416Smarkm return (0); 30857416Smarkm} 30957416Smarkm 310233294Sstasstatic int rtcp_puts(BIO *bp, const char *str) 311233294Sstas{ 312233294Sstas int length; 31357416Smarkm if (str == NULL) 31457416Smarkm return (0); 31557416Smarkm length = strlen(str); 31657416Smarkm if (length == 0) 31757416Smarkm return (0); 31857416Smarkm return rtcp_write(bp, str, length); 31957416Smarkm} 32057416Smarkm