bss_rtcp.c revision 59191
1204076Spjd/* crypto/bio/bss_rtcp.c */ 2204076Spjd/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3204076Spjd * All rights reserved. 4204076Spjd * 5204076Spjd * This package is an SSL implementation written 6204076Spjd * by Eric Young (eay@cryptsoft.com). 7204076Spjd * The implementation was written so as to conform with Netscapes SSL. 8204076Spjd * 9204076Spjd * This library is free for commercial and non-commercial use as long as 10204076Spjd * the following conditions are aheared to. The following conditions 11204076Spjd * apply to all code found in this distribution, be it the RC4, RSA, 12204076Spjd * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13204076Spjd * included with this distribution is covered by the same copyright terms 14204076Spjd * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15204076Spjd * 16204076Spjd * Copyright remains Eric Young's, and as such any Copyright notices in 17204076Spjd * the code are not to be removed. 18204076Spjd * If this package is used in a product, Eric Young should be given attribution 19204076Spjd * as the author of the parts of the library used. 20204076Spjd * This can be in the form of a textual message at program startup or 21204076Spjd * in documentation (online or textual) provided with the package. 22204076Spjd * 23204076Spjd * Redistribution and use in source and binary forms, with or without 24204076Spjd * modification, are permitted provided that the following conditions 25204076Spjd * are met: 26204076Spjd * 1. Redistributions of source code must retain the copyright 27204076Spjd * notice, this list of conditions and the following disclaimer. 28204076Spjd * 2. Redistributions in binary form must reproduce the above copyright 29204076Spjd * notice, this list of conditions and the following disclaimer in the 30204076Spjd * documentation and/or other materials provided with the distribution. 31204076Spjd * 3. All advertising materials mentioning features or use of this software 32204076Spjd * must display the following acknowledgement: 33204076Spjd * "This product includes cryptographic software written by 34204076Spjd * Eric Young (eay@cryptsoft.com)" 35204076Spjd * The word 'cryptographic' can be left out if the rouines from the library 36204076Spjd * being used are not cryptographic related :-). 37204076Spjd * 4. If you include any Windows specific code (or a derivative thereof) from 38204076Spjd * the apps directory (application code) you must include an acknowledgement: 39204076Spjd * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40204076Spjd * 41204076Spjd * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42204076Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43229509Strociny * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44204076Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45229509Strociny * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46229509Strociny * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47229509Strociny * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48229509Strociny * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49229509Strociny * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50229509Strociny * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51229509Strociny * SUCH DAMAGE. 52204076Spjd * 53204076Spjd * The licence and distribution terms for any publically available version or 54204076Spjd * derivative of this code cannot be changed. i.e. this code cannot simply be 55219864Spjd * copied and put under another distribution licence 56204076Spjd * [including the GNU Public Licence.] 57204076Spjd */ 58204076Spjd 59204076Spjd/* Written by David L. Jones <jonesd@kcgl1.eng.ohio-state.edu> 60204076Spjd * Date: 22-JUL-1996 61204076Spjd * Revised: 25-SEP-1997 Update for 0.8.1, BIO_CTRL_SET -> BIO_C_SET_FD 62204076Spjd */ 63204076Spjd/* VMS */ 64204076Spjd#include <stdio.h> 65204076Spjd#include <stdlib.h> 66204076Spjd#include <string.h> 67204076Spjd#include <errno.h> 68204076Spjd#include "cryptlib.h" 69204076Spjd#include <openssl/bio.h> 70204076Spjd 71204076Spjd#include <iodef.h> /* VMS IO$_ definitions */ 72204076Spjd#include <starlet.h> 73204076Spjd 74204076Spjdtypedef unsigned short io_channel; 75204076Spjd/*************************************************************************/ 76204076Spjdstruct io_status { short status, count; long flags; }; 77204076Spjd 78204076Spjdstruct rpc_msg { /* Should have member alignment inhibited */ 79204076Spjd char channel; /* 'A'-app data. 'R'-remote client 'G'-global */ 80204076Spjd char function; /* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */ 81204076Spjd unsigned short int length; /* Amount of data returned or max to return */ 82204076Spjd char data[4092]; /* variable data */ 83204076Spjd}; 84204076Spjd#define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092) 85204076Spjd 86204076Spjdstruct rpc_ctx { 87204076Spjd int filled, pos; 88204076Spjd struct rpc_msg msg; 89204076Spjd}; 90204076Spjd 91204076Spjdstatic int rtcp_write(BIO *h,char *buf,int num); 92204076Spjdstatic int rtcp_read(BIO *h,char *buf,int size); 93204076Spjdstatic int rtcp_puts(BIO *h,char *str); 94204076Spjdstatic int rtcp_gets(BIO *h,char *str,int size); 95204076Spjdstatic long rtcp_ctrl(BIO *h,int cmd,long arg1,char *arg2); 96204076Spjdstatic int rtcp_new(BIO *h); 97204076Spjdstatic int rtcp_free(BIO *data); 98204076Spjd 99204076Spjdstatic BIO_METHOD rtcp_method= 100204076Spjd { 101204076Spjd BIO_TYPE_FD, 102229509Strociny "RTCP", 103204076Spjd rtcp_write, 104229509Strociny rtcp_read, 105204076Spjd rtcp_puts, 106204076Spjd rtcp_gets, 107204076Spjd rtcp_ctrl, 108204076Spjd rtcp_new, 109204076Spjd rtcp_free, 110204076Spjd NULL, 111204076Spjd }; 112204076Spjd 113229509StrocinyBIO_METHOD *BIO_s_rtcp(void) 114204076Spjd { 115229509Strociny return(&rtcp_method); 116204076Spjd } 117204076Spjd/*****************************************************************************/ 118204076Spjd/* Decnet I/O routines. 119204076Spjd */ 120204076Spjd 121204076Spjd#ifdef __DECC 122204076Spjd#pragma message save 123204076Spjd#pragma message disable DOLLARID 124204076Spjd#endif 125204076Spjd 126204076Spjdstatic int get ( io_channel chan, char *buffer, int maxlen, int *length ) 127204076Spjd{ 128204076Spjd int status; 129204076Spjd struct io_status iosb; 130204076Spjd status = sys$qiow ( 0, chan, IO$_READVBLK, &iosb, 0, 0, 131229509Strociny buffer, maxlen, 0, 0, 0, 0 ); 132204076Spjd if ( (status&1) == 1 ) status = iosb.status; 133204076Spjd if ( (status&1) == 1 ) *length = iosb.count; 134204076Spjd return status; 135204076Spjd} 136204076Spjd 137204076Spjdstatic int put ( io_channel chan, char *buffer, int length ) 138204076Spjd{ 139204076Spjd int status; 140204076Spjd struct io_status iosb; 141204076Spjd status = sys$qiow ( 0, chan, IO$_WRITEVBLK, &iosb, 0, 0, 142204076Spjd buffer, length, 0, 0, 0, 0 ); 143204076Spjd if ( (status&1) == 1 ) status = iosb.status; 144204076Spjd return status; 145204076Spjd} 146204076Spjd 147204076Spjd#ifdef __DECC 148229509Strociny#pragma message restore 149229509Strociny#endif 150229509Strociny 151229509Strociny/***************************************************************************/ 152229509Strociny 153229509Strocinystatic int rtcp_new(BIO *bi) 154229509Strociny{ 155204076Spjd struct rpc_ctx *ctx; 156204076Spjd bi->init=1; 157204076Spjd bi->num=0; 158204076Spjd bi->flags = 0; 159204076Spjd bi->ptr=Malloc(sizeof(struct rpc_ctx)); 160204076Spjd ctx = (struct rpc_ctx *) bi->ptr; 161204076Spjd ctx->filled = 0; 162204076Spjd ctx->pos = 0; 163204076Spjd return(1); 164204076Spjd} 165204076Spjd 166204076Spjdstatic int rtcp_free(BIO *a) 167204076Spjd{ 168204076Spjd if (a == NULL) return(0); 169204076Spjd if ( a->ptr ) Free ( a->ptr ); 170204076Spjd a->ptr = NULL; 171204076Spjd return(1); 172204076Spjd} 173204076Spjd 174204076Spjdstatic int rtcp_read(BIO *b, char *out, int outl) 175204076Spjd{ 176204076Spjd int status, length; 177204076Spjd struct rpc_ctx *ctx; 178204076Spjd /* 179204076Spjd * read data, return existing. 180204076Spjd */ 181204076Spjd ctx = (struct rpc_ctx *) b->ptr; 182204076Spjd if ( ctx->pos < ctx->filled ) { 183204076Spjd length = ctx->filled - ctx->pos; 184204076Spjd if ( length > outl ) length = outl; 185204076Spjd memmove ( out, &ctx->msg.data[ctx->pos], length ); 186204076Spjd ctx->pos += length; 187204076Spjd return length; 188204076Spjd } 189204076Spjd /* 190204076Spjd * Requst more data from R channel. 191204076Spjd */ 192204076Spjd ctx->msg.channel = 'R'; 193204076Spjd ctx->msg.function = 'G'; 194204076Spjd ctx->msg.length = sizeof(ctx->msg.data); 195204076Spjd status = put ( b->num, (char *) &ctx->msg, RPC_HDR_SIZE ); 196204076Spjd if ( (status&1) == 0 ) { 197204076Spjd return -1; 198204076Spjd } 199204076Spjd /* 200204076Spjd * Read. 201204076Spjd */ 202204076Spjd ctx->pos = ctx->filled = 0; 203204076Spjd status = get ( b->num, (char *) &ctx->msg, sizeof(ctx->msg), &length ); 204204076Spjd if ( (status&1) == 0 ) length = -1; 205204076Spjd if ( ctx->msg.channel != 'R' || ctx->msg.function != 'C' ) { 206204076Spjd length = -1; 207204076Spjd } 208204076Spjd ctx->filled = length - RPC_HDR_SIZE; 209204076Spjd 210204076Spjd if ( ctx->pos < ctx->filled ) { 211204076Spjd length = ctx->filled - ctx->pos; 212204076Spjd if ( length > outl ) length = outl; 213204076Spjd memmove ( out, ctx->msg.data, length ); 214223654Strociny ctx->pos += length; 215204076Spjd return length; 216204076Spjd } 217204076Spjd 218204076Spjd return length; 219204076Spjd} 220204076Spjd 221204076Spjdstatic int rtcp_write(BIO *b, char *in, int inl) 222231017Strociny{ 223204076Spjd int status, i, segment, length; 224204076Spjd struct rpc_ctx *ctx; 225204076Spjd /* 226223654Strociny * Output data, send in chunks no larger that sizeof(ctx->msg.data). 227204076Spjd */ 228204076Spjd ctx = (struct rpc_ctx *) b->ptr; 229204076Spjd for ( i = 0; i < inl; i += segment ) { 230204076Spjd segment = inl - i; 231204076Spjd if ( segment > sizeof(ctx->msg.data) ) segment = sizeof(ctx->msg.data); 232204076Spjd ctx->msg.channel = 'R'; 233204076Spjd ctx->msg.function = 'P'; 234229509Strociny ctx->msg.length = segment; 235204076Spjd memmove ( ctx->msg.data, &in[i], segment ); 236204076Spjd status = put ( b->num, (char *) &ctx->msg, segment + RPC_HDR_SIZE ); 237229509Strociny if ((status&1) == 0 ) { i = -1; break; } 238204076Spjd 239204076Spjd status = get ( b->num, (char *) &ctx->msg, sizeof(ctx->msg), &length ); 240204076Spjd if ( ((status&1) == 0) || (length < RPC_HDR_SIZE) ) { i = -1; break; } 241204076Spjd if ( (ctx->msg.channel != 'R') || (ctx->msg.function != 'C') ) { 242204076Spjd printf("unexpected response when confirming put %c %c\n", 243204076Spjd ctx->msg.channel, ctx->msg.function ); 244204076Spjd 245204076Spjd } 246204076Spjd } 247223654Strociny return(i); 248223654Strociny} 249204076Spjd 250204076Spjdstatic long rtcp_ctrl(BIO *b, int cmd, long num, char *ptr) 251204076Spjd { 252204076Spjd long ret=1; 253204076Spjd 254204076Spjd switch (cmd) 255204076Spjd { 256204076Spjd case BIO_CTRL_RESET: 257204076Spjd case BIO_CTRL_EOF: 258204076Spjd ret = 1; 259204076Spjd break; 260204076Spjd case BIO_C_SET_FD: 261204076Spjd b->num = num; 262204076Spjd ret = 1; 263204076Spjd break; 264204076Spjd case BIO_CTRL_SET_CLOSE: 265204076Spjd case BIO_CTRL_FLUSH: 266204076Spjd case BIO_CTRL_DUP: 267204076Spjd ret=1; 268204076Spjd break; 269204076Spjd case BIO_CTRL_GET_CLOSE: 270229509Strociny case BIO_CTRL_INFO: 271204076Spjd case BIO_CTRL_GET: 272204076Spjd case BIO_CTRL_PENDING: 273204076Spjd case BIO_CTRL_WPENDING: 274204076Spjd default: 275204076Spjd ret=0; 276204076Spjd break; 277204076Spjd } 278204076Spjd return(ret); 279204076Spjd } 280229509Strociny 281204076Spjdstatic int rtcp_gets(BIO *bp, char *buf, int size) 282204076Spjd { 283204076Spjd return(0); 284204076Spjd } 285204076Spjd 286204076Spjdstatic int rtcp_puts(BIO *bp, char *str) 287204076Spjd{ 288204076Spjd int length; 289204076Spjd if (str == NULL) return(0); 290204076Spjd length = strlen ( str ); 291204076Spjd if ( length == 0 ) return (0); 292204076Spjd return rtcp_write ( bp,str, length ); 293204076Spjd} 294204076Spjd 295204076Spjd