bss_rtcp.c revision 55714
1/* crypto/bio/bss_rtcp.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59/* Written by David L. Jones <jonesd@kcgl1.eng.ohio-state.edu> 60 * Date: 22-JUL-1996 61 * Revised: 25-SEP-1997 Update for 0.8.1, BIO_CTRL_SET -> BIO_C_SET_FD 62 */ 63/* VMS */ 64#include <stdio.h> 65#include <stdlib.h> 66#include <string.h> 67#include <errno.h> 68#include "cryptlib.h" 69#include <openssl/bio.h> 70 71#include <iodef.h> /* VMS IO$_ definitions */ 72#include <starlet.h> 73 74typedef unsigned short io_channel; 75/*************************************************************************/ 76struct io_status { short status, count; long flags; }; 77 78struct rpc_msg { /* Should have member alignment inhibited */ 79 char channel; /* 'A'-app data. 'R'-remote client 'G'-global */ 80 char function; /* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */ 81 unsigned short int length; /* Amount of data returned or max to return */ 82 char data[4092]; /* variable data */ 83}; 84#define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092) 85 86struct rpc_ctx { 87 int filled, pos; 88 struct rpc_msg msg; 89}; 90 91static int rtcp_write(BIO *h,char *buf,int num); 92static int rtcp_read(BIO *h,char *buf,int size); 93static int rtcp_puts(BIO *h,char *str); 94static int rtcp_gets(BIO *h,char *str,int size); 95static long rtcp_ctrl(BIO *h,int cmd,long arg1,char *arg2); 96static int rtcp_new(BIO *h); 97static int rtcp_free(BIO *data); 98 99static BIO_METHOD rtcp_method= 100 { 101 BIO_TYPE_FD, 102 "RTCP", 103 rtcp_write, 104 rtcp_read, 105 rtcp_puts, 106 rtcp_gets, 107 rtcp_ctrl, 108 rtcp_new, 109 rtcp_free, 110 }; 111 112BIO_METHOD *BIO_s_rtcp(void) 113 { 114 return(&rtcp_method); 115 } 116/*****************************************************************************/ 117/* Decnet I/O routines. 118 */ 119 120#ifdef __DECC 121#pragma message save 122#pragma message disable DOLLARID 123#endif 124 125static int get ( io_channel chan, char *buffer, int maxlen, int *length ) 126{ 127 int status; 128 struct io_status iosb; 129 status = sys$qiow ( 0, chan, IO$_READVBLK, &iosb, 0, 0, 130 buffer, maxlen, 0, 0, 0, 0 ); 131 if ( (status&1) == 1 ) status = iosb.status; 132 if ( (status&1) == 1 ) *length = iosb.count; 133 return status; 134} 135 136static int put ( io_channel chan, char *buffer, int length ) 137{ 138 int status; 139 struct io_status iosb; 140 status = sys$qiow ( 0, chan, IO$_WRITEVBLK, &iosb, 0, 0, 141 buffer, length, 0, 0, 0, 0 ); 142 if ( (status&1) == 1 ) status = iosb.status; 143 return status; 144} 145 146#ifdef __DECC 147#pragma message restore 148#endif 149 150/***************************************************************************/ 151 152static int rtcp_new(BIO *bi) 153{ 154 struct rpc_ctx *ctx; 155 bi->init=1; 156 bi->num=0; 157 bi->flags = 0; 158 bi->ptr=Malloc(sizeof(struct rpc_ctx)); 159 ctx = (struct rpc_ctx *) bi->ptr; 160 ctx->filled = 0; 161 ctx->pos = 0; 162 return(1); 163} 164 165static int rtcp_free(BIO *a) 166{ 167 if (a == NULL) return(0); 168 if ( a->ptr ) Free ( a->ptr ); 169 a->ptr = NULL; 170 return(1); 171} 172 173static int rtcp_read(BIO *b, char *out, int outl) 174{ 175 int status, length; 176 struct rpc_ctx *ctx; 177 /* 178 * read data, return existing. 179 */ 180 ctx = (struct rpc_ctx *) b->ptr; 181 if ( ctx->pos < ctx->filled ) { 182 length = ctx->filled - ctx->pos; 183 if ( length > outl ) length = outl; 184 memmove ( out, &ctx->msg.data[ctx->pos], length ); 185 ctx->pos += length; 186 return length; 187 } 188 /* 189 * Requst more data from R channel. 190 */ 191 ctx->msg.channel = 'R'; 192 ctx->msg.function = 'G'; 193 ctx->msg.length = sizeof(ctx->msg.data); 194 status = put ( b->num, (char *) &ctx->msg, RPC_HDR_SIZE ); 195 if ( (status&1) == 0 ) { 196 return -1; 197 } 198 /* 199 * Read. 200 */ 201 ctx->pos = ctx->filled = 0; 202 status = get ( b->num, (char *) &ctx->msg, sizeof(ctx->msg), &length ); 203 if ( (status&1) == 0 ) length = -1; 204 if ( ctx->msg.channel != 'R' || ctx->msg.function != 'C' ) { 205 length = -1; 206 } 207 ctx->filled = length - RPC_HDR_SIZE; 208 209 if ( ctx->pos < ctx->filled ) { 210 length = ctx->filled - ctx->pos; 211 if ( length > outl ) length = outl; 212 memmove ( out, ctx->msg.data, length ); 213 ctx->pos += length; 214 return length; 215 } 216 217 return length; 218} 219 220static int rtcp_write(BIO *b, char *in, int inl) 221{ 222 int status, i, segment, length; 223 struct rpc_ctx *ctx; 224 /* 225 * Output data, send in chunks no larger that sizeof(ctx->msg.data). 226 */ 227 ctx = (struct rpc_ctx *) b->ptr; 228 for ( i = 0; i < inl; i += segment ) { 229 segment = inl - i; 230 if ( segment > sizeof(ctx->msg.data) ) segment = sizeof(ctx->msg.data); 231 ctx->msg.channel = 'R'; 232 ctx->msg.function = 'P'; 233 ctx->msg.length = segment; 234 memmove ( ctx->msg.data, &in[i], segment ); 235 status = put ( b->num, (char *) &ctx->msg, segment + RPC_HDR_SIZE ); 236 if ((status&1) == 0 ) { i = -1; break; } 237 238 status = get ( b->num, (char *) &ctx->msg, sizeof(ctx->msg), &length ); 239 if ( ((status&1) == 0) || (length < RPC_HDR_SIZE) ) { i = -1; break; } 240 if ( (ctx->msg.channel != 'R') || (ctx->msg.function != 'C') ) { 241 printf("unexpected response when confirming put %c %c\n", 242 ctx->msg.channel, ctx->msg.function ); 243 244 } 245 } 246 return(i); 247} 248 249static long rtcp_ctrl(BIO *b, int cmd, long num, char *ptr) 250 { 251 long ret=1; 252 253 switch (cmd) 254 { 255 case BIO_CTRL_RESET: 256 case BIO_CTRL_EOF: 257 ret = 1; 258 break; 259 case BIO_C_SET_FD: 260 b->num = num; 261 ret = 1; 262 break; 263 case BIO_CTRL_SET_CLOSE: 264 case BIO_CTRL_FLUSH: 265 case BIO_CTRL_DUP: 266 ret=1; 267 break; 268 case BIO_CTRL_GET_CLOSE: 269 case BIO_CTRL_INFO: 270 case BIO_CTRL_GET: 271 case BIO_CTRL_PENDING: 272 case BIO_CTRL_WPENDING: 273 default: 274 ret=0; 275 break; 276 } 277 return(ret); 278 } 279 280static int rtcp_gets(BIO *bp, char *buf, int size) 281 { 282 return(0); 283 } 284 285static int rtcp_puts(BIO *bp, char *str) 286{ 287 int length; 288 if (str == NULL) return(0); 289 length = strlen ( str ); 290 if ( length == 0 ) return (0); 291 return rtcp_write ( bp,str, length ); 292} 293 294