home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
hamradio
/
wattcp.zip
/
PCRECV.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-27
|
5KB
|
194 lines
#include <wattcp.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
*/
_recvdaemon( udp_Socket *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->ip_type ) {
case UDP_PROTO :r = (recv_data*)(s->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 );
}
}
return( 0 );
case TCP_PROTO :
t=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[s->rdatalen], len );
s->rdatalen += len;
return( len );
}
return( 0 ); /* didn't take none */
}
}
sock_recv_init( udp_Socket *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->dataHandler = _recvdaemon;
/* clear table */
memset( r = s->rddata, 0, tcp_MaxBufSize );
r->recv_sig = RECV_USED;
r->recv_bufs = p;
r->recv_bufnum = len / sizeof( recv_buf );
r->recv_len = len;
if (s->ip_type == UDP_PROTO )
for ( i = 0 ; i < r->recv_bufnum ; ++i, ++p )
p->buf_sig = RECV_UNUSED;
return( 0 );
}
int sock_recv_from( udp_Socket *s, long *hisip, word *hisport, char *buffer, int len, word flags )
{
tcp_Socket *t;
recv_data *r;
recv_buf *p;
int i;
r = s->rdata;
if (r->recv_sig != RECV_USED )
return( -1 );
switch ( s->ip_type ) {
case UDP_PROTO :
p = 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 = s;
if ( len > t->rdatalen ) len = t->rdatalen;
if ( len )
movmem( r->recv_bufs, buffer, len );
return( len );
}
}
int sock_recv( udp_Socket *s, char *buffer, int len, word flags )
{
tcp_Socket *t;
recv_data *r;
recv_buf *p;
int i;
r = s->rdata;
if (r->recv_sig != RECV_USED )
return( -1 );
switch ( s->ip_type ) {
case UDP_PROTO :
p = 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 = s;
if ( len > t->rdatalen ) len = t->rdatalen;
if ( len )
movmem( r->recv_bufs, buffer, len );
return( len );
}
}