home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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>
- #ifdef MEMORY_DEBUG
- #include "memdebug.h"
- #endif
- #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 ( p, ulen )
- 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(buffer)
- 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 ( port )
- 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(machine,port,retport,buffer,n)
- unsigned char *machine,*buffer;
- unsigned int port,retport;
- 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));
- }