home *** CD-ROM | disk | FTP | other *** search
- /*
- * USER.C
- * Network library interface routines
- * Generally called by the session layer
- *
- ****************************************************************************
- * *
- * 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 *
- * *
- * Copyright (c) 1987, Board of Trustees of the University of Illinois *
- * *
- ****************************************************************************
- * Revisions:
- * 10/87 Initial source release, Tim Krauskopf
- * 2/88 typedef support for other compilers (TK)
- * 8/88 Gaige Paulsen - support for MacTCP drivers
- * 1/89 TK - conversion to new drivers, minor update for new calling convention
- * 6/89 TK - update to MacTCP 1.0 include files and use of GetMyIPAddr()
- *
- */
-
- #include <Dialogs.h>
- #include <Devices.h>
- #include <Memory.h>
- #include <MacTCPCommonTypes.h>
- #include <TCPPB.h>
- #include <UDPPB.h>
-
- /*#define MASTERDEF 1 /* BYU 2.4.16 */
- #include <stdio.h>
- #include <String.h>
- #include "protocol.h"
- #include "data.h"
- #include "configrec.h"
- #include "maclook.h"
- #include "menu.h"
- #include "tools.h"
- #include "user.h" /* BYU 2.4.16 MPW */
- #include <getmyipaddr.h>
-
- extern int /* BYU 2.4.15 */
- net_okay; /* BYU 2.4.15 */
-
- extern short /* BYU 2.4.15 */
- slip_connection; /* BYU 2.4.15 */
-
- extern int /* BYU 2.4.16 */
- EtherNet; /* BYU 2.4.16 - Signify Drivers */
-
- #define LOWWATER 600
-
- pascal void TCPNotify();
- pascal void UDPNotify();
- long openComplete();
- long closeComplete();
- long sendComplete();
-
- /*
- * UDP Stuff
- */
-
- #define UDPBUFSIZ (1024*8)
- #define getUPB(x,y,z,a) (UDPiopb *)getPB(x,y,z,a)
-
- typedef struct UDPRec {
- StreamPtr stream; /* Apple's lovely Stream Pointer */
- char *buffer; /* Where the immovable UDP buffer is */
- uint port; /* Which UDP port to use */
- } UDPRec, *UDPRPtr;
-
- UDPRPtr uport[ NPORTS]; /* our wonderful little thingies. */
-
- /*
- * TCP Stuff
- */
- #define noError 0
- #define TCPBUFSIZ (1024*8)
- #define MAX_FDS_ELEMS 32
- #define MAX_SWDS_ELEMS 8
- #define MAX_FREE_PB 128
- #define MAX_FREE_SWDS 64
-
- /* NCSA 2.5 */
- #define MAX_BEFORE_RECYCLE (MAX_FREE_PB - 5)
-
- #define Qcall true
- #define noQcall false
-
- returnPB(TCPiopb *);
-
- #define UNKNOWN_PORT_TYPE 0 /* BYU 2.4.16 */
- #define MACTCP_PORT_TYPE 1 /* BYU 2.4.16 */
- #define NCSA_PORT_TYPE 2 /* BYU 2.4.16 */
-
- extern short porttype[]; /* BYU 2.4.16 */
-
-
- typedef struct freeEntry {
- int inuse; /* is this being used? */
- Ptr ptr; /* Pointer to the free entry */
- } freeEntry;
-
- typedef struct exfds {
- int inuse; /* Is this being used */
- wdsEntry fds; /* The real data */
- } exfds;
-
- typedef struct StreamRec {
- StreamPtr stream; /* Apple's lovely Stream Pointer */
- char *buffer; /* Where the immovable TCP buffer is */
- int push; /* TRUE if we should push next data block */
- char *sbuffer; /* Where the send buffer is */
- wdsEntry fds[MAX_FDS_ELEMS]; /* Free Data Structure list */
- exfds exFDS[MAX_FDS_ELEMS]; /* exFDS entries */
- int maxFDSused; /* Max of the FDS's that have been used */
- int mseg; /* BYU 2.4.15 */
- int service; /* BYU 2.4.15 */
- int type; /* BYU 2.4.15 - 0 = non-serial, 1 = serial or SLIP */
- } StreamRec, *StreamRPtr;
-
- short TCPd = 0; /* refnum of TCP drivers */
-
- StreamRPtr streams[NPORTS];
-
- int numPB=0; /* Number of PB's ever allocated (Perf. mon. only ) */
- int numSWDS=0; /* Number of SWDS's ever alloc'd (PM Only) */
-
- freeEntry freePB[ MAX_FREE_PB];
- freeEntry freeSWDS[ MAX_FREE_SWDS];
-
- /**************************************************************************/
- wdsEntry *getSWDS
- (
- void
- )
- {
- int n=0;
-
- while (freeSWDS[n].inuse && n<MAX_FREE_SWDS) n++;
- if (n >= MAX_FREE_SWDS)
- return((wdsEntry *) 0L);
-
- freeSWDS[n].inuse=1;
- if (freeSWDS[n].ptr==0L) {
-
- freeSWDS[n].ptr = NewPtr ( sizeof(wdsEntry) *MAX_SWDS_ELEMS);
- numSWDS++;
- /* sprintf(temp,"New SWDS(%d)",numSWDS);
- putln(temp); */
- }
- return((wdsEntry *) freeSWDS[n].ptr);
- }
-
- /**************************************************************************/
- returnSWDS( wds)
- wdsEntry *wds;
- {
- int n=0;
-
- while (freeSWDS[n].ptr != wds && n<MAX_FREE_SWDS) n++;
- if (n >= MAX_FREE_SWDS)
- return(-1);
- freeSWDS[n].inuse=0;
- }
-
-
- /**************************************************************************/
- TCPiopb *getPB( driver, call, stream, usernum)
- int driver, call, usernum;
- unsigned long stream;
- {
- #pragma unused(usernum)
- TCPiopb *pbp;
- int n=0;
- int i;
-
- while (freePB[n].inuse && n<MAX_FREE_PB) n++;
-
-
- if (n >= 100) /* recycle memory so system doesn't get hammered */
- {
- for (i = 0;i < MAX_BEFORE_RECYCLE;i++) /* NCSA 2.5 */
- {
- if ((freePB[i].inuse) && !(((TCPiopb *)(freePB[i].ptr))->ioResult) )
- {
- returnPB((TCPiopb *)freePB[i].ptr); /* re-use this one */
- n--; /* so there is now one less */
- }
- }
- }
-
- if (n >= MAX_FREE_PB) return(0L); /* hammer system */
-
- freePB[n].inuse = 1;
- if (freePB[n].ptr==0L) {
-
- freePB[n].ptr = NewPtr ( sizeof(TCPiopb)+sizeof(int) );
- numPB++;
- /* sprintf(temp,"New PB(%d)",numPB);
- putln(temp); */
- }
- (Ptr) pbp = freePB[n].ptr;
-
-
- if (!pbp) {
- putln("GETPB failed! panic! ");
- quit();
- }
-
- memset( pbp, '\0', sizeof(TCPiopb)+sizeof(int)); /* Default to all zeros */
-
- pbp->ioCRefNum = driver;
- pbp->tcpStream=stream;
- pbp->csCode = call;
-
- return(pbp);
- }
-
- /**************************************************************************/
- clearPB( pbp, driver, call, stream, usernum)
- TCPiopb *pbp;
- int driver, call, usernum;
- unsigned long stream;
- {
- #pragma unused(usernum)
- memset( pbp, '\0', sizeof(TCPiopb)+sizeof(int)); /* Default to all zeros */
-
- pbp->ioCRefNum = driver;
- pbp->tcpStream=stream;
- pbp->csCode = call;
-
- }
-
- returnPB( pbp)
- TCPiopb *pbp;
- {
- int n=0;
-
- while (freePB[n].ptr != pbp && n<MAX_FREE_PB) n++;
- if (n >= MAX_FREE_PB)
- return(-1);
- freePB[n].inuse=0;
-
- }
-
- /***************************************************************************/
- /* Mnetread
- * Read from a connection buffer into a user buffer.
- * Returns number of bytes read, < 0 on error
- * NOTE:
- * current version very inefficient, but hopefully works.
- */
- Mnetread(pnum,buffer,n) /* BYU 2.4.16 */
- int pnum,n;
- char *buffer;
- {
- int i;
- StreamRPtr p;
- TCPiopb *pbp;
- int inQ, reqdamt;
-
- if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */
- return(-2);
-
- if (NULL == (p = streams[pnum]))
- return(-2);
-
-
- pbp=getPB( TCPd, TCPStatus, p->stream, pnum); /* Make status call */
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("TCPStatus failed(read)"); return(-1);
- }
- #ifdef DEBUGHEADERS
- { char temp[100];
- sprintf(temp, "Stat: %x(%d)->%x(%d) <%d,%d,%d> [%d,%d] {%d,%d}",
- (int)pbp->csParam.status.remoteHost,
- (int)pbp->csParam.status.remotePort,
- (int)pbp->csParam.status.localHost,
- (int)pbp->csParam.status.localPort,
- (int)pbp->csParam.status.tosFlags,
- (int)pbp->csParam.status.precedence,
- (int)pbp->csParam.status.connectionState,
- (int)pbp->csParam.status.sendWindow,
- (int)pbp->csParam.status.rcvWindow,
- (int)pbp->csParam.status.amtUnackedData,
- (int)pbp->csParam.status.amtUnreadData);
- putln(temp);
- }
- #endif DEBUGHEADERS
-
- if (pbp->csParam.status.connectionState !=8) {
- char temp[50];
- sprintf(temp,"CState: %d is %d",(int)pnum, (int)pbp->csParam.status.connectionState);
- putln(temp);
- return(-1); /* Connection not established */
- }
-
- inQ = pbp->csParam.status.amtUnreadData;
- reqdamt = n >inQ ? inQ : n;
-
- clearPB( pbp, TCPd, TCPRcv, p->stream, pnum);
- pbp->csParam.receive.rcvBuff = buffer;
- pbp->csParam.receive.rcvBuffLen = reqdamt;
-
- if (reqdamt<1) { /* Drop out if no data */
- returnPB(pbp);
- return(0);
- }
-
- if ((i = PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
- char temp[100];
- sprintf(temp,"TCPRcv failed (%d)",i);
- putln( temp);
- return(-1);
- }
-
- reqdamt = pbp->csParam.receive.rcvBuffLen;
- if (reqdamt<inQ) {
- netputuev( CONCLASS, CONDATA, pnum); /* more data to get */
- }
-
- returnPB(pbp); /* Trash PB */
- #ifdef TESTINGPARMS
- {
- char temp[100];
- sprintf(temp, "NETRead: %d from %d", reqdamt, pnum);
- putln(temp);
- }
- #endif TESTINGPARMS
- return(reqdamt);
- }
-
- /**************************************************************************/
- /*
- * reclaim( p) -
- * reclaims buffer space to stream (from pointer p) into the FDS list
- */
-
- reclaim(p)
- StreamRPtr p;
- {
- int n=0, offset=0;
-
- while (offset < MAX_FDS_ELEMS && p->fds[offset].ptr != 0L) offset++;
-
- if (offset >= MAX_FDS_ELEMS) {
- putln("Couldn't reclaim because offset was too large ");
- return(0);
- }
- for (n=0 ; n<MAX_FDS_ELEMS && offset< MAX_FDS_ELEMS; n++) {
- if (p->exFDS[ n].inuse) {
- p->fds[ offset++]=p->exFDS[ n].fds;
- p->exFDS[ n].inuse = 0;
- }
- }
- }
-
- /**************************************************************************/
- /*
- * compressfds( fds)
- * compress an fds data structure to make everyone happy
- */
-
- compressfds( fds)
- wdsEntry *fds;
- {
- int n,m,compressed;
-
- compressed = 0;
-
- while ( !compressed) {
- compressed=1;
- for (n=0; n< MAX_FDS_ELEMS; n++) { /* Slow Forwards */
- if (fds[n].ptr) { /* Do if N exists */
- for ( m = MAX_FDS_ELEMS -1; m>=0; m--) { /* Fast Backwards */
- if (fds[m].ptr && (fds[m].ptr+fds[m].length == fds[n].ptr)) {
- fds[n].length+=fds[m].length;
- fds[n].ptr = fds[m].ptr;
- fds[m].ptr=0L;
- fds[m].length=0;
- compressed=0;
- }
- #ifdef CHECKBOTHWAYZ
- else
- if (fds[n].ptr+fds[n].length == fds[m].ptr) {
- fds[m].length+=fds[n].length;
- fds[n].ptr=0L;
- fds[n].length=0;
- compressed=0;
- }
- #endif CHECKBOTHWAYZ
- }
- }
- }
- }
- m=0;n=0;
-
- /* Close the gaps */
-
- while (n+m < MAX_FDS_ELEMS) {
- while (fds[n+m].ptr ==0L && n+m< MAX_FDS_ELEMS) {
- m++; /* increase gap to valid entry */
- }
- if (n+m<MAX_FDS_ELEMS)
- fds[n]=fds[n+m];
- n++;
- }
-
- /* Get rid of the empty spaces */
-
- n--; /* for the next loop */
- while (n < MAX_FDS_ELEMS) {
- fds[n].ptr=0; fds[n++].length=0;
- }
- }
-
- /************************************************************************/
- /* Mnetwrite
- * write something into the output queue, netsleep routine will come
- * around and send the data, etc.
- *
- */
- int /* BYU 2.4.16 */
- Mnetwrite(pnum,buffer,nsend) /* BYU 2.4.16 */
- int pnum,nsend;
- char *buffer;
- {
- StreamRPtr p;
- wdsEntry *swds;
- int remaining, queued, n,m;
- TCPiopb *pbp;
-
- if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */
- return(-2);
-
- if ( (p = streams[pnum]) == NULL)
- return(-2);
-
- if ( !nsend )
- return(0);
-
- swds = getSWDS();
-
- reclaim( p);
- compressfds( p->fds);
-
- n=0; remaining = nsend;
- while (p->fds[n].ptr !=0 && remaining>0 ) {
- swds[n].ptr = p->fds[n].ptr;
- if ( p->fds[n].length > remaining) {
- swds[n].length = remaining;
- p->fds[n].length -= remaining;
- p->fds[n].ptr += remaining;
- remaining=0;
- }
- else {
- swds[n].length = p->fds[n].length;
- remaining -= p->fds[n].length;
- p->fds[n].length = 0;
- p->fds[n].ptr = 0;
- }
- n++;
- }
- if (n>p->maxFDSused) p->maxFDSused=n;
-
- compressfds( p->fds);
- queued = nsend-remaining;
-
- for (m=0; m<n; m++) {
- memcpy( swds[m].ptr, buffer, swds[m].length); /* Put data in WDS */
- buffer +=swds[m].length;
- }
- swds[m].ptr =0L;
- swds[m].length=0;
-
- pbp=getPB( TCPd, TCPSend, p->stream, pnum); /* Make send call */
- pbp->csParam.send.wdsPtr = (Ptr) swds;
- pbp->csParam.send.pushFlag = p->push;
-
- pbp->ioCompletion = (TCPIOCompletionProc) sendComplete; /* Completion routine */
-
- p->push=0;
-
- if (PBControl((ParmBlkPtr) pbp, Qcall) != noError) {
- putln("TCPSend failed to Q"); return(-1);
- }
-
- #ifdef TESTINGPARMS
- putln("TCP Sent");
- { char temp[100];
- sprintf(temp, "TCP Sent: %d of %d on %d [%d/%d]", queued, nsend, pnum,n,p->maxFDSused);
- putln(temp);
- }
- #endif TESTINGPARMS
- return(queued);
- }
-
- /**************************************************************************/
- /* Mnetpush
- * attempt to push the rest of the data from the queue
- * and then return whether the queue is empty or not (0 = empty)
- * returns the number of bytes in the queue.
- */
- Mnetpush(pnum) /* BYU 2.4.16 */
- int pnum;
- {
- StreamRPtr p;
- TCPiopb *pbp;
- int inQ;
-
- if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */
- return(-2);
-
- if (NULL == (p = streams[pnum]))
- return(-2);
-
- pbp=getPB( TCPd, TCPStatus, p->stream, pnum); /* Make status call */
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("TCPStatus failed(push)"); return(-1);
- }
- inQ = pbp->csParam.status.amtUnackedData;
- returnPB( pbp);
-
- p->push=1;
-
- return(inQ);
-
- }
-
- /**************************************************************************/
- /* Mnetqlen
- * return the number of bytes waiting to be read from the incoming queue.
- */
- Mnetqlen(pnum) /* BYU 2.4.16 */
- int pnum;
- {
- StreamRPtr p;
- TCPiopb *pbp;
- int inQ;
-
- if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */
- return(-2);
-
- if (NULL == (p = streams[pnum]))
- return(-2);
-
- pbp=getPB( TCPd, TCPStatus, p->stream, pnum); /* Make status call */
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("TCPStatus failed(qlen)"); return(-1);
- }
- inQ = pbp->csParam.status.amtUnreadData;
- returnPB( pbp);
-
- p->push = 1;
- return(inQ);
- }
-
- /**************************************************************************/
- /* Mnetroom()
- * return how much room is available in output buffer for a connection
- */
- Mnetroom(pnum) /* BYU 2.4.16 */
- int pnum;
- {
- StreamRPtr p;
- TCPiopb *pbp;
- int inQ,n;
-
- if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */
- return(-2);
-
- if (NULL == (p = streams[pnum]))
- return(-2);
-
- reclaim( p);
- compressfds( p->fds);
-
- #ifdef OLDM
- pbp=getPB( TCPd, TCPStatus, p->stream, pnum); /* Make status call */
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("TCPStatus failed(room)"); return(-1);
- }
- inQ = pbp->csParam.status.sendWindow -
- pbp->csParam.status.amtUnackedData;
- returnPB( pbp);
- #else
- #pragma unused(pbp)
- #endif
-
- inQ = n = 0;
- while (p->fds[n].ptr) {
-
- inQ += p->fds[n].length; /* add up free list space */
- n++;
- }
-
- return(inQ);
- }
-
- #if 0 /* BYU 2.4.16 */
- /**************************************************************************/
- /* netsegsize and neterrchange and netsetip and netgetip
- *
- * set operating parameters to change them from the default values used.
- */
-
- netsegsize(newsize)
- int newsize;
- {
- int i;
-
- i = nnsegsize;
- nnsegsize = newsize;
-
- return(i);
- }
-
- /**************************************************************************/
- netquench(newcredit)
- int newcredit;
- {
- int i;
-
- i = nncredit;
- nncredit = newcredit;
-
- return(i);
- }
-
- /**************************************************************************/
- netarptime(t) /* dlayer timeout in secs */
- int t;
- {
- nndto = t;
- }
-
- /**************************************************************************/
- void netsetip
- (
- unsigned char *st
- )
- {
- /*
- * this is a no-op with the MacTCP driver
- */
- #pragma unused(st)
- }
- #endif /* BYU 2.4.16 */
-
- /**************************************************************************/
- int Mnetgetip /* BYU 2.4.16 */
- (
- unsigned char *st
- )
- {
- struct IPParamBlock mypb;
- /* long netmask; */
-
- putln("Attempting getmyipaddr");
-
- memset( &mypb, '\0', sizeof(struct IPParamBlock)); /* Default to all zeros */
-
- mypb.ioCRefNum = TCPd; /* TCP driver has to be open by now */
- mypb.csCode = ipctlGetAddr;
-
- if (PBControl((ParmBlkPtr) &mypb, noQcall) != noError) {
- putln("Getting my address failed");
- return(-1);
- }
-
- memcpy(st, &mypb.ourAddress, 4); /* copy the address */
-
- /* netmask is here if we want it, too */
-
- return(0);
-
- }
-
-
- #if 0 /* BYU 2.4.16 */
- /**************************************************************************/
- netsetmask(st)
- unsigned char *st;
- {
- movebytes(nnmask,st,4);
- }
-
- /**************************************************************************/
- netgetmask(st)
- unsigned char *st;
- {
- movebytes(st,nnmask,4);
- }
-
- netfromport(port) /* next "open" will use this port */
- int16 port;
- {
- nnfromport = port;
-
- }
- #endif /* BYU 2.4.16 */
-
- /**************************************************************************/
- /* Mnetest?
- * is a particular session established yet?
- * Returns 0 if the connection is in the established state.
- */
- int /* BYU 2.4.16 */
- Mnetest(pnum) /* BYU 2.4.16 */
- int pnum;
- {
- StreamRPtr p;
- TCPiopb *pbp;
- int inQ;
-
- if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */
- return(-2);
-
- if (NULL == (p = streams[pnum]))
- return(-2);
-
- pbp=getPB( TCPd, TCPStatus, p->stream, pnum); /* Make status call */
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("TCPStatus failed(est)");
- inQ = -1;
- }
- else
- inQ = pbp->csParam.status.connectionState !=8;
- returnPB( pbp);
-
- return(inQ);
-
- }
-
- /**************************************************************************/
- /*
- * Returns an empty stream
- */
- int makestream() /* BYU 2.4.15 */
- {
- int pnum;
- StreamRPtr p;
- TCPiopb *pbp;
- int i;
-
-
- for ( pnum=0; (streams[pnum]!= NULL || porttype[pnum]) && pnum<NPORTS; pnum++); /* BYU 2.4.16 */
-
- if (pnum >= NPORTS)
- return(-2);
-
- p = streams[pnum] = (StreamRPtr) NewPtr(sizeof(StreamRec));
-
- if ((p->buffer = (char *) NewPtr( TCPBUFSIZ)) == (char *)NULL)
- return(-1);
- if ((p->sbuffer = (char *) NewPtr( TCPBUFSIZ)) == (char *)NULL)
- return(-1);
-
- for (i=0; i<MAX_FDS_ELEMS; i++) {
- p->fds[ i].length =0; p->fds[ i].ptr = 0L;
- p->exFDS[ i].inuse=0; p->exFDS[ i].fds.length=0;p->exFDS[ i].fds.ptr=0L;
- }
- p->fds[0].length = TCPBUFSIZ;
- p->fds[0].ptr = p->sbuffer;
- p->maxFDSused=0;
-
- pbp=getPB( TCPd, TCPCreate, 0, pnum); /* Make create call */
- pbp->csParam.create.rcvBuff = p->buffer;
- pbp->csParam.create.rcvBuffLen = TCPBUFSIZ;
- pbp->csParam.create.notifyProc = TCPNotify;
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("TCPCreate failed"); return(-1);
- }
-
- p->stream = pbp->tcpStream;
-
- putln("Made a new stream");
- returnPB(pbp);
- return(pnum);
- }
-
- /**************************************************************************/
- /* Mnetlisten
- * Listen to a TCP port number and make the connection automatically when
- * the SYN packet comes in. The TCP layer will notify the higher layers
- * with a CONOPEN event. Save the port number returned to refer to this
- * connection.
- *
- * usage: portnum = netlisten(service);
- * int service;
- *
- */
- int /* BYU 2.4.16 */
- Mnetlisten(serv) /* BYU 2.4.16 */
- uint serv;
- {
- int pnum;
- StreamRPtr p;
- TCPiopb *pbp;
-
- if (!net_okay) /* BYU 2.4.15 */
- return(-2); /* BYU 2.4.15 */
-
- pnum = makestream();
-
- if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */
- return(-2);
-
- if (NULL == (p = streams[pnum]))
- return(-2);
-
- pbp=getPB( TCPd, TCPPassiveOpen, p->stream, pnum); /* Make Listen call */
-
- pbp->csParam.open.localPort = serv;
- pbp->ioCompletion = (TCPIOCompletionProc) openComplete; /* IO Completion for open */
-
- if (PBControl((ParmBlkPtr) pbp, Qcall) != noError) {
- putln("TCPListen failed"); return(-1);
- }
-
- return(pnum);
- }
-
- /***********************************************************************/
- /* Mnetgetftp
- * Provides the information that ftp needs to open a stream back to the
- * originator of the command connection. The other side's IP number
- * and the port numbers to be used to calculate the default data connection
- * number. Returns values in an integer array for convenient use in
- * PORT commands.
- */
- Mnetgetftp(a,pnum) /* BYU 2.4.16 */
- int a[];
- int pnum;
- {
- StreamRPtr p;
- TCPiopb *pbp;
- long temp;
-
- if (pnum < 0)
- return(-2);
-
- if (NULL == (p = streams[pnum]))
- return(-2);
-
- pbp=getPB( TCPd, TCPStatus, p->stream, pnum); /* Make status call */
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("TCPStatus failed(getftp)"); return(-1);
- }
-
- temp = pbp->csParam.status.remoteHost;
- a[0]= (temp>>24) & 0xff;
- a[1]= (temp>>16) & 0xff;
- a[2]= (temp>> 8) & 0xff;
- a[3]= (temp ) & 0xff;
- temp = pbp->csParam.status.localPort;
- a[4]= (temp>> 8) & 0xff;
- a[5]= (temp ) & 0xff;
- temp = pbp->csParam.status.remotePort;
- a[6]= (temp>> 8) & 0xff;
- a[7]= (temp ) & 0xff;
-
- returnPB( pbp);
- }
-
-
- /**************************************************************************/
- /* Mnetxopen
- * Open a network socket for the user.
- *
- */
- int Mnetxopen /* BYU 2.4.16 */
- (
- uint32 *machine,
- uint service,
- uint rto,
- uint mtu,
- uint mseg,
- uint mwin
- )
- {
- #pragma unused(rto, mtu, mseg, mwin)
- int pnum;
- StreamRPtr p;
- TCPiopb *pbp;
- char temp[100];
-
- pnum = makestream();
-
- if (pnum < 0)
- return(-2);
-
- if (NULL == (p = streams[pnum]))
- return(-2);
-
- pbp=getPB( TCPd, TCPActiveOpen, p->stream, pnum); /* Make Listen call */
-
- pbp->csParam.open.remoteHost = *machine; /* IP # */
- pbp->csParam.open.remotePort = service; /* Port */
- pbp->csParam.open.localPort = nnfromport; /* My Port */
- nnfromport=0; /* Next one is random */
-
- pbp->ioCompletion = (TCPIOCompletionProc) openComplete; /* IO Completion for open */
-
- if (PBControl((ParmBlkPtr) pbp, Qcall) != noError) {
- putln("TCPOpen failed(Active)"); return(-1);
- }
- sprintf(temp,"TCPOpen on %d",pnum);
- putln(temp);
- return(pnum);
- }
-
- #if 0 /* BYU 2.4.15 - not used */
- /**************************************************************************/
- /* netopen
- * Netopen is a cheap way to open a connection without looking up any
- * machine information. Uses suitable default values for everything.
- */
- netopen(s,tport)
- unsigned char *s;
- uint tport;
- {
-
- return(netxopen((uint32 *) s,tport,MINRTO,TSENDSIZE,DEFSEG,DEFWINDOW));
- }
- #endif
-
-
- /**************************************************************************/
- /* Mnetclose
- * Do appropriate actions to return connection state to SCLOSED which
- * enables the memory for that port to be reused.
- *
- * Specifically:
- * o If status is closed, then release the data structures
- * o If status is not close, perform bkgrd close which generates CLOSEDONE,
- * which should make the session layer call us again
- */
- int Mnetclose /* BYU 2.4.16 */
- (
- int pnum
- )
- {
- StreamRPtr p;
- TCPiopb *pbp;
- int errorCode=0;
- int status;
- char temp[50];
- static short count=0;
-
- if (pnum < 0 || pnum > NPORTS) /* is a valid port? */
- return(-1);
-
- if ((p = streams[pnum]) == NULL) /* nothing there */
- return (1);
-
- pbp=getPB( TCPd, TCPStatus, p->stream, pnum); /* Make status call */
- if ((errorCode = PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
- if ( errorCode == invalidStreamPtr) {
- putln("TCPStatus failed because of bad stream pointer (close)");
- return(-1);
- }
- else
- {
- status=0;
- count =0;
- }
- }
- else
- {
- status = pbp->csParam.status.connectionState; /* The connection Status */
- if (count++ ==10) status=count =0;
- }
-
- /* */
-
- sprintf(temp,"the error Code is %i",(int)errorCode);
- putln(temp);
-
- if (status < 18 && status >2 ) { /* We aren't closed yet ! */
- char temp[50];
- sprintf(temp, "TCPClose being attempted state ...[%d]",status); /* Prolly because outstanding close */
- putln(temp);
- clearPB( pbp, TCPd, TCPClose, p->stream, pnum); /* Make Close call */
- pbp->ioCompletion = (TCPIOCompletionProc) closeComplete; /* IO Completion for close */
- if ((errorCode=PBControl((ParmBlkPtr) pbp, Qcall)) != noError) {
- char temp[50];
- sprintf(temp, "TCPClose failed...[%d]",errorCode); /* Prolly because outstanding close */
- putln(temp);
- putln("we have an error");
- return (errorCode); /* */
- }
-
- return (0); /* Return with OK */
- }
-
- /* IF we got here, we must be at closed state, so free memory */
-
- putln("TCP Being Released...... ");
- clearPB( pbp,TCPd, TCPRelease, p->stream, pnum); /* Make Release call */
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("TCPRelease failed"); return(-1);
- }
-
- DisposPtr( p->buffer); /* Free Receive Buffer */
- DisposPtr( p->sbuffer); /* Free Send Buffer */
- DisposPtr((Ptr) p); /* Free Stream Structure */
- streams[pnum]=0L;
- porttype[pnum] = UNKNOWN_PORT_TYPE; /* BYU 2.4.16 */
-
- returnPB(pbp);
- return(0);
- }
-
- /**************************************************************************/
- /* netabort
- * Nuke the connection, NOW!
- */
- netabort(pnum)
- int pnum;
- {
- StreamRPtr p;
- TCPiopb *pbp;
- int errorCode=0;
-
- if (pnum < 0 || pnum > NPORTS) /* is a valid port? */
- return(-1);
-
- if ((p = streams[pnum]) != NULL) { /* something there */
- pbp=getPB( TCPd, TCPAbort, p->stream, pnum); /* Make Close call */
- if ((errorCode=PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
- char temp[50];
- sprintf(temp, "TCPAbort failed...[%d]",errorCode);
- putln(temp);
- }
- clearPB( pbp,TCPd, TCPRelease, p->stream, pnum); /* Make Close call */
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("TCPRelease failed"); return(-1);
- }
- }
- else
- return(1);
-
- DisposPtr( p->buffer); /* Free Receive Buffer */
- DisposPtr( p->sbuffer); /* Free Send Buffer */
- DisposPtr((Ptr) p); /* Free Stream Structure */
- streams[pnum]=0L;
- porttype[pnum] = UNKNOWN_PORT_TYPE; /* BYU 2.4.16 */
-
- returnPB(pbp);
- return(0);
- }
-
- /**************************************************************************/
- /* Mnetinit
- * Calls all of the various initialization routines that set up queueing
- * variables, static values, reads configuration files, etc.
- */
-
- int Mnetinit /* BYU 2.4.16 */
- (
- void
- )
- {
- int i;
- extern Cursor *normcurs;
-
- for (i=0; i<NPORTS;i++)
- streams[i]= (StreamRPtr) 0;
-
- for (i=0; i<NPORTS;i++)
- uport[i]= (UDPRPtr) 0;
-
- if (opendriver(".IPP",&TCPd) != noError) {
- SetCursor(normcurs);
- putln( "Couldn't open IP driver ");
- OtherError("Error opening TCP drivers.","Possibly no dynamic addressing");
- EtherNet = -100; /* BYU 2.4.16 - show serial connections only */
- /* quit(); /* BYU 2.4.16 */
- }
-
- return(0); /* set up empty packets */
- }
-
- /**************************************************************************/
- int UDPfindport( port)
- int port;
- {
- int pnum=0;
-
- while (pnum<NPORTS &&
- ( uport[pnum] ==(UDPRPtr)0L || port !=uport[pnum]->port))
- pnum++;
- if (pnum >=NPORTS)
- return(-1);
- else
- return(pnum);
- }
-
- /**************************************************************************/
- /*
- * netuclose( port) - close the udp port
- */
-
- netuclose( port)
- int port;
- {
- UDPRPtr p;
- UDPiopb *pbp;
- int pnum;
-
- pnum= UDPfindport( port);
-
- if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */
- return(-1);
-
- p=uport[pnum];
-
- pbp = getUPB( TCPd, UDPRelease, p->stream, 0);
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("UDPClose failed"); return(-1);
- }
- DisposPtr( p->buffer);
- DisposPtr((Ptr) uport[pnum]);
- uport[pnum]=0; /* use me again */
-
- returnPB( pbp);
- }
-
- /*************************************************************************/
- /* Mnetshut
- * Close all the connections and turn off the hardware.
- */
- Mnetshut() /* BYU 2.4.16 */
- {
- int i;
-
- for (i=0; i < NPORTS ; i++)
- if (streams[i] != (StreamRPtr) NULL)
- netabort(i); /* Prolly should abort */
- for (i=0; i < NPORTS ; i++)
- if (uport[i] != (UDPRPtr) NULL)
- netuclose(uport[i]->port); /* Shut down UDP too... */
- #ifdef SAFE
- CloseDriver( TCPd);
- #endif SAFE
- }
-
- /**************************************************************************/
- int findbystream( streamPtr)
- StreamPtr streamPtr;
- {
- int pnum=0;
-
- while (pnum<NPORTS &&
- ( (streams[pnum] ==(StreamRPtr)0L) || (streamPtr !=streams[pnum]->stream)))
- pnum++;
- if (pnum >=NPORTS)
- return(-1);
- else
- return(pnum);
- }
-
-
- /**************************************************************************/
- pascal void TCPNotify( streamPtr, code, uptr, terminReason, icmpMsg)
- StreamPtr streamPtr;
- unsigned short /*enum TCPEventCode*/ code;
- unsigned short /*enum TCPTerminationReason*/ terminReason;
- struct ICMPReport *icmpMsg;
- Ptr uptr; /* user data pointer */
- {
- #pragma unused(uptr, terminReason, icmpMsg)
- StreamRPtr p;
- int pnum;
-
- pnum = findbystream(streamPtr);
-
- if (pnum < 0 || (p = streams[pnum]) == 0L)
- return;
-
- switch( code) {
- case TCPTerminate:
- case TCPClosing:
- netputevent(CONCLASS, CONCLOSE, pnum);
- break;
- case TCPULPTimeout:
- netputevent(CONCLASS, CONFAIL, pnum);
- break;
- case TCPDataArrival:
- case TCPUrgent:
- netputuev(CONCLASS, CONDATA, pnum);
- break;
- case TCPICMPReceived:
- default:
- break;
- }
- return;
- }
-
- /*************************************************************************/
- /* Mnetopen2
- * Send out repeat SYN on a connection which is not open yet
- * Checks, and only sends one if needed.
- * Returns 1 if the state is still SYNS and 0 if the connection has proceeded.
- * The timing is all handled at a higher layer.
- */
- int Mnetopen2 /* BYU 2.4.16 */
- (
- int pnum
- )
- {
- return( netest(pnum));
- }
-
- /**************************************************************************/
- long openComplete( pbp)
- TCPiopb *pbp;
- {
- StreamRPtr p;
- int pnum;
-
- pnum= findbystream(pbp->tcpStream);
-
- if (pnum < 0 || (p = streams[pnum]) == 0L)
- return(-1);
-
- if (pbp->ioResult !=noError)
- netputevent(CONCLASS, CONFAIL, pnum); /* Failure ... */
- else
- netputevent(CONCLASS, CONOPEN, pnum); /* Success ! */
-
- returnPB( pbp);
- return(0);
- }
-
- /**************************************************************************/
- /*
- * giveback( p, wds) -
- * gives WDS entries back to the stream by putting them in the
- * mutually exclusive buffer.
- * p -> stream
- * wds -> wds array
- */
- giveback( p, wds)
- StreamRPtr p;
- wdsEntry *wds;
- {
- int n=0, m=0;
-
- while ( n< MAX_SWDS_ELEMS && wds[n].ptr !=0L) {
- while (m< MAX_FDS_ELEMS && p->exFDS[ m].inuse) m++;
- if (m> MAX_FDS_ELEMS)
- return(-1); /* No room in the RECLAIMation center */
- else {
- p->exFDS[ m].inuse =1;
- p->exFDS[ m].fds = wds[n];
- m++;
- }
- n++;
- }
- }
-
-
- /**************************************************************************/
- long sendComplete( pbp)
- TCPiopb *pbp;
- {
- StreamRPtr p;
- int pnum;
- wdsEntry *swds;
- int i=0,j=0;
-
- (Ptr) swds = pbp->csParam.send.wdsPtr;
-
- pnum= findbystream(pbp->tcpStream);
- if (pnum < 0 || (p = streams[pnum]) == 0L)
- return(-1);
-
- returnSWDS( swds);
- returnPB( pbp);
-
- giveback( p, pbp->csParam.send.wdsPtr); /* Give this back.... NOW */
-
- return(0);
- }
-
-
- /**************************************************************************/
- long closeComplete( pbp)
- TCPiopb *pbp;
- {
- StreamRPtr p;
- int pnum;
-
- pnum= findbystream(pbp->tcpStream);
-
- if (pnum < 0 || (p = streams[pnum]) == 0L)
- {
- netputevent(SCLASS, CLOSEDONE+1, pnum);
- return(-1);
- }
-
- if (pbp->ioResult !=noError)
- netputevent(SCLASS, CLOSEDONE+1, pnum);
- else
- netputevent(SCLASS, CLOSEDONE, pnum); /* Success ! */
-
- returnPB( pbp);
- return(0);
- }
-
-
-
- /*****************************************************************************
- *
- * Here lie the awful UDP routines, I put them here for the drivers from Apple.
- *
- */
-
- int UDPlisten =0; /* what port the old routines listen for */
-
-
- /****************************************************************************/
- /* New UDP routines.... */
- /****************************************************************************/
-
- /**************************************************************************/
- makeuport( port)
- int port;
- {
- int pnum;
- UDPRPtr p;
- UDPiopb *pbp;
- int i;
-
- for ( pnum=0; uport[pnum]!= NULL && pnum<NPORTS; pnum++);
-
- if (pnum >= NPORTS)
- return(-2);
-
- p = uport[pnum] = (UDPRPtr) NewPtr(sizeof(UDPRec));
-
- if ((p->buffer = (char *) NewPtr( UDPBUFSIZ)) == (char *)NULL)
- return(-1);
-
-
- pbp=getUPB( TCPd, UDPCreate, 0, pnum); /* Make create call */
-
- pbp->csParam.create.rcvBuff = p->buffer;
- pbp->csParam.create.rcvBuffLen= UDPBUFSIZ;
- pbp->csParam.create.notifyProc = UDPNotify;
- pbp->csParam.create.localPort = port;
-
- if ((i=PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
- char temp[50];
- sprintf(temp, "UDPCreate failed (%d)",i);
- putln(temp);
- return(-1);
- }
- else {
- char temp[50];
- sprintf(temp, "UDPCreate successfull on %d(%d) [%x]",port,pnum,pbp->udpStream);
- putln(temp);
- }
-
- p->stream = pbp->udpStream;
- p->port = port;
-
- putln("Made a new UPORT");
- returnPB(pbp);
- return(pnum);
- }
-
- /**************************************************************************/
- /*
- * netuopen (port) - open the udp port "Port"
- */
-
- netuopen(port)
- int port;
- {
- return(makeuport( port));
- }
-
- /**************************************************************************/
- /*
- * netuget( port, buffer,len, who,where)
- * - read up to len bytes from port port into buffer buffer, noting
- * who it was from and where....
- */
-
- netuget( port, buffer, len, who, where)
- int port, len;
- int *who, *where;
- char *buffer;
- {
- #pragma unused(who, where)
- int pnum, length;
- UDPRPtr p;
- UDPiopb *pbp;
-
- pnum= UDPfindport( port);
-
- if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */
- return(-1);
-
- p=uport[pnum];
-
- pbp= getUPB( TCPd, UDPRead, p->stream, 0);
- pbp->csParam.receive.timeOut = 1; /* time out at one sec. */
-
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("UDPRead failed"); return(-1);
- }
-
- length = pbp->csParam.receive.rcvBuffLen; /* look how BIG it is */
- length = length > len ? len:length;
-
- memcpy( buffer, pbp->csParam.receive.rcvBuff,length);
-
- pbp->csCode = UDPBfrReturn; /* Let my buffer go.. */
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("UDPReturn failed"); return(-1);
- }
-
- returnPB( pbp);
-
- return(length);
- }
-
- /**************************************************************************/
- netuput( machine, port, myport, buffer, n)
- long *machine;
- char *buffer;
- int port, myport;
- int n;
- {
- wdsEntry wds[2];
- UDPRPtr p;
- UDPiopb *pbp; int pnum;
-
- pnum= UDPfindport( myport);
-
- if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */
- return(-1);
-
- p=uport[pnum];
-
- pbp= getUPB( TCPd, UDPWrite, p->stream, 0);
- pbp->csParam.send.remoteHost = *machine;
- pbp->csParam.send.remotePort = port;
- pbp->csParam.send.checkSum = 1; /* Do do that checksum that you do so well */
- pbp->csParam.send.wdsPtr = (Ptr) wds;
- /* pbp->csParam.send.remoteHost = *machine; /* BYU - not needed, done above. */
-
- wds[0].ptr = buffer;
- wds[0].length=n;
- wds[1].ptr = (char *) 0L; wds[1].length=0;
-
- if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
- putln("UDPReturn failed"); return(-1);
- }
-
- returnPB( pbp);
- return(0);
- }
-
-
- /****************************************************************************/
- /* Mneturead
- * get the data from the UDP buffer
- * Returns the number of bytes transferred into your buffer, -1 if none here
- * This needs work.
- */
- int Mneturead /* BYU 2.4.16 */
- (
- char *buffer
- )
- {
- int who, where;
-
- if (!UDPlisten)
- return(-1);
-
- return( netuget( UDPlisten, buffer, 512, &who, &where));
- }
-
- /***************************************************************************/
- /* Mnetulisten
- * Specify which UDP port number to listen to.
- * Can only listen to one at a time.
- */
- int Mnetulisten /* BYU 2.4.16 */
- (
- int port
- )
- {
- char temp[50];
- int pnum;
-
-
- sprintf( temp, "UDP listening on ....%d", port);
- putln(temp);
-
- UDPlisten = port;
-
- if ( (pnum=UDPfindport( port))<0)
- pnum= netuopen(port);
-
- return (pnum);
- }
-
- /***************************************************************************/
- /* Mnetusend
- * send some data out in a UDP packet
- * uses the preinitialized data in the port packet ulist.udpout
- *
- * returns 0 on okay send, nonzero on error
- */
- void Mnetusend /* BYU 2.4.16 */
- (
- unsigned char *machine,
- unsigned int port,
- unsigned int retport,
- unsigned char *buffer,
- int n
- )
- {
- /* find if port is open */
- if ( UDPfindport( retport)<0)
- netuopen(retport);
-
- /* Send data */
- netuput( machine, port, retport, buffer,n);
- }
-
- /**************************************************************************/
- int ufindbystream( streamPtr)
- StreamPtr streamPtr;
- {
- int pnum=0;
-
- while (pnum<NPORTS &&
- ( uport[pnum] ==(UDPRPtr)0L || streamPtr !=uport[pnum]->stream))
- pnum++;
- if (pnum >=NPORTS)
- return(-1);
- else
- return(pnum);
- }
-
- /**************************************************************************/
- pascal void UDPNotify( streamPtr, code, uptr, icmpMsg)
- StreamPtr streamPtr;
- unsigned short code;
- struct ICMPReport *icmpMsg;
- Ptr uptr; /* user data */
- {
- #pragma unused(uptr, icmpMsg)
- UDPRPtr p;
- int pnum;
-
- pnum= ufindbystream(streamPtr);
-
- if (pnum < 0 || (p = uport[pnum]) == 0L)
- return;
-
- switch( code) {
- case UDPDataArrival:
- netputuev(USERCLASS,UDPDATA,p->port); /* post that it is here */
- default:
- break;
- }
- return;
- }
-
- #if 0 /* BYU 2.4.16 */
- void netconfig
- (
- char *hardware
- )
- {
- #pragma unused(hardware)
- putln("I'm a driver TCP, I don't need hardware.....");
- initipnum(0);
- }
-
- void netarpme
- (
- char *s
- )
- {
- #pragma unused(s)
- putln("Drivers don't need arps, either.");
- }
-
- netsetgate(s)
- char *s;
- {
- #pragma unused(s)
- putln("Yeah, right....");
- return
- 0;
- }
-
- int netgetrarp
- (
- void
- )
- {
- putln("RARP handled above me....");
- return
- 0;
- }
-
- uint8 *getdlayer()
- {
- putln("This shouldn't be called...");
- return(0L);
- }
-
- tcpsend()
- {
- }
-
- demux()
- {
- return(0);
- }
-
- /*************************************************************************/
- /* neteventinit
- * load up the pointers for the event queue
- * makes a circular list to follow, required for error messages
- */
- void neteventinit
- (
- void
- )
- {
- int i;
-
- for (i=0; i < NEVENTS; i++)
- nnq[i].next = i+1;
-
- nnq[NEVENTS-1].next = -1;
-
- nnefirst = 0;
- nnelast = 0;
- nnefree = 1;
- }
-
- getATaddress()
- {
- }
-
- KIPfindgate()
- {
- }
-
- KIPgetns()
- {
- }
-
- KIPgetdynam()
- {
- }
-
- KIPregister()
- {
- }
- #endif /* BYU 2.4.16 */