home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
t
/
tel2305s.zip
/
ENGINE
/
UDP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-22
|
4KB
|
157 lines
/*
* UDP.C
*
* UDP Protocol Routines
*
***************************************************************************
* *
* part of: *
* TCP/IP kernel for NCSA Telnet *
* by Tim Krauskopf *
* *
* National Center for Supercomputing Applications *
* 152 Computing Applications Building *
* 605 E. Springfield Ave. *
* Champaign, IL 61820 *
* *
***************************************************************************
*
* Revision history:
*
* 5/88 split out of ip.c for 2.3 release, JKM
*
*/
/*
* Includes
*/
#include <stdio.h>
#include "protocol.h"
#include "data.h"
#include "externs.h"
/*
* udpinterpret ( p, ulen )
*
* Take an incoming UDP packet and make the available to the user level
* routines. Currently keeps the last packet coming in to a port.
*
* Limitations :
*
* Can only listen to one UDP port at a time, only saves the last packet
* received on that port. Port numbers should be assigned like TCP ports.
*
*/
int udpinterpret(UDPKT *p,int ulen)
{
uint hischeck,mycheck;
/*
* did we want this data ? If not, then let it go, no comment
* If we want it, copy the relevent information into our structure
*/
if(intswap(p->u.dest)!=ulist.listen)
return(1);
/*
* first compute the checksum to see if it is a valid packet
*/
hischeck=p->u.check;
p->u.check=0;
if (hischeck) {
movebytes(tcps.source,p->i.ipsource,8);
tcps.z=0;
tcps.proto=p->i.protocol;
tcps.tcplen=intswap(ulen);
mycheck=tcpcheck((char *)&tcps,(char *)&p->u,ulen);
if(hischeck!=mycheck) {
netposterr(700);
return(2);
}
p->u.check=hischeck; /* put it back */
}
ulen-=8; /* account for header */
if(ulen>UMAXLEN) /* most data that we can accept */
ulen=UMAXLEN;
movebytes(ulist.who,p->i.ipsource,4);
movebytes(ulist.data,p->data,ulen);
ulist.length=ulen;
ulist.stale=0;
netputuev(USERCLASS,UDPDATA,ulist.listen); /* post that it is here */
return(0);
}
/*
* neturead ( buffer )
*
* Get the data from the UDP buffer and transfer it into your buffer.
*
* Returns the number of bytes transferred or -1 of none available
*
*/
int neturead(char *buffer)
{
if(ulist.stale)
return(-1);
movebytes(buffer,ulist.data,ulist.length);
ulist.stale=1;
return((int)ulist.length);
}
/*
* netulisten ( port )
*
* Specify which UDP port number to listen to -- can only listen to one port
* at a time.
*
*/
void netulisten(int port)
{
ulist.listen=port;
}
/*
* netusend ( machine, port, retport, buffer, n )
*
* Send some data out in a udp packet ( uses the preinitialized data in the
* port packet *ulist.udpout* )
*
* Returns 0 on ok send, non-zero for an error
*
*/
int netusend(uint8 *machine,uint16 port,uint16 retport,uint8 *buffer,int n)
{
unsigned char *pc;
if(n>UMAXLEN)
n=UMAXLEN;
/*
* make sure that we have the right dlayer address
*/
if(!comparen(machine,ulist.udpout.i.ipdest,4)) {
pc=netdlayer(machine);
if(pc==NULL)
return(-2);
movebytes(ulist.udpout.d.dest,pc,DADDLEN);
movebytes(ulist.udpout.i.ipdest,machine,4);
movebytes(ulist.tcps.dest,machine,4);
}
ulist.udpout.u.dest=intswap(port);
ulist.udpout.u.source=intswap(retport);
ulist.tcps.tcplen=ulist.udpout.u.length=intswap(n+sizeof(UDPLAYER));
movenbytes(ulist.udpout.data,buffer,n);
/*
* put in checksum
*/
ulist.udpout.u.check=0;
ulist.udpout.u.check=tcpcheck((char *)&ulist.tcps,(char *)&ulist.udpout.u,n+sizeof(UDPLAYER));
/*
* iplayer for send
*/
ulist.udpout.i.tlen=intswap(n+sizeof(IPLAYER)+sizeof(UDPLAYER));
ulist.udpout.i.ident=intswap(nnipident++);
ulist.udpout.i.check=0;
ulist.udpout.i.check=ipcheck((char *)&ulist.udpout.i,10);
/*
* send it
*/
return(dlayersend((DLAYER *)&ulist.udpout,sizeof(DLAYER)+sizeof(IPLAYER)+sizeof(UDPLAYER)+n));
}