home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.wwiv.com
/
ftp.wwiv.com.zip
/
ftp.wwiv.com
/
pub
/
PPPBCKP
/
SRC15B24.ZIP
/
WATTSRC.ZIP
/
SRC
/
PCRECV.C
< prev
next >
Wrap
Text File
|
1994-11-28
|
5KB
|
199 lines
#include <wattcp.h>
#include <mem.h>
#define RECV_USED 0xf7e3d2b1L
#define RECV_UNUSED 0xe6d2c1afL
typedef struct {
longword recv_sig;
byte *recv_bufs;
word recv_bufnum; /* for udp */
word recv_len; /* for tcp */
} recv_data;
typedef struct {
longword buf_sig;
longword buf_hisip;
word buf_hisport;
int buf_len;
byte buf_data[ 1500 ];
} recv_buf;
/*
* recvd - gets upcalled when data arrives
*/
static int _recvdaemon( sock_type *s, byte *data, int len, tcp_PseudoHeader *ph, void *h)
{
recv_data *r;
recv_buf *p;
tcp_Socket *t;
int i;
udp_Header *uh;
/* check for length problem */
if ( !len || (len >= 1500 )) return( 0 );
switch ( s->udp.ip_type ) {
case UDP_PROTO :r = (recv_data*)(s->udp.rdata);
uh = (udp_Header *) h;
if (r->recv_sig != RECV_USED ) {
outs("ERROR: udp recv data conflict");
return( 0 );
}
p = (recv_buf *)(r->recv_bufs);
/* find a buffer */
for ( i = 0; i < r->recv_bufnum ; ++i , ++p) {
switch ( p->buf_sig ) {
case RECV_USED : break;
case RECV_UNUSED :
/* take this one */
p->buf_sig = RECV_USED;
p->buf_len = len;
p->buf_hisip = ph->src;
p->buf_hisport = uh->srcPort;
movmem( data, p->buf_data, len );
return( 0 );
default :
outs("ERROR: sock_recv_init data err");
return( 0 );
}
}
break;
case TCP_PROTO :
t= (tcp_Socket*)s;
r = (recv_data*)(t->rdata);
if (r->recv_sig != RECV_USED ) {
outs("ERROR: udp recv data conflict");
return( 0 );
}
/* stick it on the end if you can */
i = t->maxrdatalen - t->rdatalen;
if ( i > 1 ) {
/* we can accept some of this */
if ( len > i ) len = i;
movmem( data, &r->recv_bufs[t->rdatalen], len );
t->rdatalen += len;
return( len );
}
break;
}
return( 0 ); /* didn't take none */
}
int sock_recv_init( sock_type *s, void *space, word len )
{
/* tcp_Socket *t; */
recv_buf *p;
recv_data *r;
int i;
/* clear data area */
memset( p = space, 0, len );
s->udp.dataHandler = (dataHandler_t)_recvdaemon;
/* clear table */
memset( r = (recv_data*) s->udp.rddata, 0, tcp_MaxBufSize );
r->recv_sig = RECV_USED;
r->recv_bufs = (byte *) p;
r->recv_bufnum = len / sizeof( recv_buf );
r->recv_len = len;
if (s->udp.ip_type == UDP_PROTO )
for ( i = 0 ; i < r->recv_bufnum ; ++i, ++p )
p->buf_sig = RECV_UNUSED;
return( 0 );
}
int sock_recv_from( sock_type *s, long *hisip, word *hisport, char *buffer, int len, word flags )
{
tcp_Socket *t;
recv_data *r;
recv_buf *p;
int i;
flags=flags; /* get rid of warning */
r = (recv_data *) s->udp.rdata;
if (r->recv_sig != RECV_USED )
return( -1 );
switch ( s->udp.ip_type ) {
case UDP_PROTO :
p = (recv_buf *) r->recv_bufs;
/* find a buffer */
for ( i = 0; i < r->recv_bufnum ; ++i , ++p) {
switch ( p->buf_sig ) {
case RECV_UNUSED:
break;
case RECV_USED :
p->buf_sig = RECV_USED;
if ( len > p->buf_len ) len = p->buf_len;
movmem( p->buf_data, buffer, len );
if (hisip) *hisip = p->buf_hisip;
if (hisport) *hisport = p->buf_hisport;
p->buf_sig = RECV_UNUSED;
return( len );
default :
outs("ERROR: sock_recv_init data err");
return( 0 );
}
}
return( 0 );
case TCP_PROTO :
t = (tcp_Socket *) s;
if ( len > t->rdatalen ) len = t->rdatalen;
if ( len )
movmem( r->recv_bufs, buffer, len );
return( len );
}
return( 0 );
}
int sock_recv( sock_type *s, char *buffer, int len, word flags )
{
tcp_Socket *t;
recv_data *r;
recv_buf *p;
int i;
flags=flags; /* get rid of warning */
r = (recv_data *) s->udp.rdata;
if (r->recv_sig != RECV_USED )
return( -1 );
switch ( s->udp.ip_type ) {
case UDP_PROTO :
p = (recv_buf *) r->recv_bufs;
/* find a buffer */
for ( i = 0; i < r->recv_bufnum ; ++i , ++p) {
switch ( p->buf_sig ) {
case RECV_UNUSED:
break;
case RECV_USED :
p->buf_sig = RECV_USED;
if ( len > p->buf_len ) len = p->buf_len;
movmem( p->buf_data, buffer, len );
p->buf_sig = RECV_UNUSED;
return( len );
default :
outs("ERROR: sock_recv_init data err");
return( 0 );
}
}
return( 0 );
case TCP_PROTO :
t = (tcp_Socket*) s;
if ( len > t->rdatalen ) len = t->rdatalen;
if ( len )
movmem( r->recv_bufs, buffer, len );
return( len );
}
return( 0 );
}