home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / Telnet 2.5.src.ThinkC / source / MacTCP Driver / userd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-05  |  38.0 KB  |  1,685 lines  |  [TEXT/MPS ]

  1. /*
  2. *  USER.C
  3. *  Network library interface routines
  4. *  Generally called by the session layer
  5. *
  6. ****************************************************************************
  7. *                                                                          *
  8. *      part of:                                                            *
  9. *      TCP/IP kernel for NCSA Telnet                                       *
  10. *      by Tim Krauskopf                                                    *
  11. *                                                                          *
  12. *      National Center for Supercomputing Applications                     *
  13. *      152 Computing Applications Building                                 *
  14. *      605 E. Springfield Ave.                                             *
  15. *      Champaign, IL  61820                                                *
  16. *                                                                          *
  17. *    Copyright (c) 1987, Board of Trustees of the University of Illinois   *
  18. *                                                                          *
  19. ****************************************************************************
  20. *  Revisions:
  21. *  10/87  Initial source release, Tim Krauskopf
  22. *  2/88  typedef support for other compilers (TK)
  23. *  8/88  Gaige Paulsen - support for MacTCP drivers
  24. *  1/89  TK - conversion to new drivers, minor update for new calling convention
  25. *  6/89  TK - update to MacTCP 1.0 include files and use of GetMyIPAddr()
  26. *
  27. */
  28.  
  29. #include <Dialogs.h>
  30. #include <Devices.h>
  31. #include <Memory.h>
  32. #include "MacTCPCommonTypes.h"
  33. #include "TCPPB.h"
  34. #include "UDPPB.h"
  35.  
  36. /*#define MASTERDEF 1        /* BYU 2.4.16 */
  37. #include <stdio.h>
  38. #include <String.h>
  39. #include "protocol.h"
  40. #include "data.h"
  41. #include "configrec.h"
  42. #include "maclook.h"
  43. #include "menu.h"
  44. #include "tools.h"
  45. #include "getmyipaddr.h"    /* BYU LSC */
  46.  
  47. extern int                     /* BYU 2.4.15 */
  48.     net_okay;                /* BYU 2.4.15 */
  49.  
  50. extern short                /* BYU 2.4.15 */
  51.     slip_connection;        /* BYU 2.4.15 */
  52.  
  53. extern int                     /* BYU 2.4.16 */
  54.     EtherNet;                /* BYU 2.4.16 - Signify Drivers */
  55.  
  56. #define LOWWATER 600
  57.  
  58. pascal void TCPNotify();
  59. pascal void UDPNotify();
  60. long openComplete();
  61. long closeComplete();
  62. long sendComplete();
  63.  
  64. /*
  65.  * UDP Stuff
  66.  */
  67.  
  68. #define    UDPBUFSIZ    (1024*8)
  69. #define    getUPB(x,y,z,a)    (UDPiopb *)getPB(x,y,z,a)
  70.  
  71. typedef struct UDPRec {
  72.     StreamPtr stream;                /* Apple's lovely Stream Pointer */
  73.     char   *buffer;                    /* Where the immovable UDP buffer is */
  74.     uint    port;                    /* Which UDP port to use */
  75.     } UDPRec, *UDPRPtr;
  76.  
  77. UDPRPtr uport[ NPORTS];                /* our wonderful little thingies. */
  78.  
  79. /*
  80.  * TCP Stuff
  81.  */
  82. #define    noError    0
  83. #define TCPBUFSIZ    (1024*8)
  84. #define    MAX_FDS_ELEMS    32
  85. #define    MAX_SWDS_ELEMS    16
  86. #define MAX_FREE_PB        128
  87. #define MAX_FREE_SWDS    64
  88.  
  89. #define    Qcall    true
  90. #define    noQcall    false
  91.  
  92. #if 0                    /* BYU LSC */
  93. returnPB(TCPiopb *);
  94. #endif                    /* BYU LSC */
  95.  
  96. #define UNKNOWN_PORT_TYPE    0        /* BYU 2.4.16 */
  97. #define MACTCP_PORT_TYPE    1        /* BYU 2.4.16 */
  98. #define NCSA_PORT_TYPE        2        /* BYU 2.4.16 */
  99.  
  100. extern short porttype[];                /* BYU 2.4.16 */
  101.  
  102.  
  103. typedef    struct freeEntry {
  104.     int inuse;                        /* is this being used? */
  105.     Ptr    ptr;                        /* Pointer to the free entry */
  106.     } freeEntry;
  107.     
  108. typedef struct exfds {
  109.     int    inuse;                        /* Is this being used */
  110.     wdsEntry fds;                    /* The real data */
  111.     } exfds;
  112.     
  113. typedef struct StreamRec {
  114.     StreamPtr stream;                /* Apple's lovely Stream Pointer */
  115.     char   *buffer;                    /* Where the immovable TCP buffer is */
  116.     int        push;                    /* TRUE if we should push next data block */
  117.     char   *sbuffer;                /* Where the send buffer is */
  118.     wdsEntry    fds[MAX_FDS_ELEMS];    /* Free Data Structure list */
  119.     exfds    exFDS[MAX_FDS_ELEMS];    /* exFDS entries */
  120.     int        maxFDSused;                /* Max of the FDS's that have been used */
  121.     int        mseg;                    /* BYU 2.4.15 */
  122.     int        service;                /* BYU 2.4.15 */
  123.     int        type;                    /* BYU 2.4.15 - 0 = non-serial, 1 = serial or SLIP */
  124.     } StreamRec, *StreamRPtr;
  125.     
  126. short TCPd = 0;                        /* refnum of TCP drivers */
  127.  
  128. StreamRPtr streams[NPORTS];
  129.  
  130. int numPB=0;                        /* Number of PB's ever allocated  (Perf. mon. only ) */
  131. int numSWDS=0;                        /* Number of SWDS's ever alloc'd (PM Only) */
  132.  
  133. freeEntry    freePB[ MAX_FREE_PB];
  134. freeEntry    freeSWDS[ MAX_FREE_SWDS];
  135.  
  136. /**************************************************************************/
  137. wdsEntry *getSWDS
  138.   (
  139.     void
  140.   )
  141. {
  142.     int n=0;
  143.     
  144.     while (freeSWDS[n].inuse &&  n<MAX_FREE_SWDS) n++;
  145.     if (n >= MAX_FREE_SWDS)
  146.         return((wdsEntry *) 0L);
  147.     
  148.     freeSWDS[n].inuse=1;
  149.     if (freeSWDS[n].ptr==0L) {
  150.  
  151.         freeSWDS[n].ptr = NewPtr ( sizeof(wdsEntry) *MAX_SWDS_ELEMS);
  152.         numSWDS++;
  153. /*        sprintf(temp,"New SWDS(%d)",numSWDS);
  154.         putln(temp); */
  155.         }
  156.     return((wdsEntry *) freeSWDS[n].ptr);
  157. }
  158.  
  159. /**************************************************************************/
  160. returnSWDS( wds)
  161. wdsEntry *wds;
  162. {
  163.     int n=0;
  164.     
  165.     while (freeSWDS[n].ptr != (Ptr) wds && n<MAX_FREE_SWDS) n++;    /* BYU LSC */
  166.     if (n >= MAX_FREE_SWDS)
  167.         return(-1);
  168.     freeSWDS[n].inuse=0;
  169. }
  170.  
  171.  
  172. /**************************************************************************/
  173. TCPiopb *getPB( driver, call, stream, usernum)
  174. int driver, call, usernum;
  175. unsigned long stream;
  176. {
  177. /*#pragma unused(usernum)    /* BYU LSC */
  178.     TCPiopb *pbp;
  179.     int n=0;
  180.     int i;
  181.     
  182.     while (freePB[n].inuse &&  n<MAX_FREE_PB) n++;
  183.  
  184.  
  185.     if (n >= 100)    /* recycle memory so system doesn't get hammered */
  186.         {
  187.         for (i = 0;i < 100;i++)
  188.             {
  189.             if ((freePB[i].inuse) && !(((TCPiopb *)(freePB[i].ptr))->ioResult) )
  190.                 {
  191.                 returnPB((TCPiopb *)freePB[i].ptr); /* re-use this one */
  192.                 n--;                     /* so there is now one less */
  193.                 }
  194.             }
  195.         }
  196.  
  197.     if (n >= MAX_FREE_PB) return(0L);    /* hammer system */
  198.     
  199.     freePB[n].inuse = 1;                
  200.     if (freePB[n].ptr==0L) {
  201.         
  202.         freePB[n].ptr = NewPtr ( sizeof(TCPiopb)+sizeof(long) );    /* BYU LSC */
  203.         numPB++;
  204. /*        sprintf(temp,"New PB(%d)",numPB);
  205.         putln(temp); */
  206.         }
  207.     pbp = (TCPiopb *) freePB[n].ptr;        /* BYU LSC */
  208.  
  209.  
  210.     if (!pbp) {
  211.         putln("GETPB failed! panic! ");
  212.         quit();
  213.         }
  214.     
  215.     memset((char *) pbp, '\0', sizeof(TCPiopb)+sizeof(long));    /* BYU LSC - Default to all zeros */
  216.     
  217.     pbp->ioCRefNum = driver;
  218.     pbp->tcpStream=stream;
  219.     pbp->csCode = call;
  220.     
  221.     return(pbp);
  222. }
  223.  
  224. /**************************************************************************/
  225. clearPB( pbp, driver, call, stream, usernum)
  226. TCPiopb *pbp;
  227. int driver, call, usernum;
  228. unsigned long stream;
  229. {
  230. /*#pragma unused(usernum)    /* BYU LSC */
  231.     memset((char *) pbp, '\0', sizeof(TCPiopb)+sizeof(long));    /* BYU LSC - Default to all zeros */
  232.     
  233.     pbp->ioCRefNum = driver;
  234.     pbp->tcpStream=stream;
  235.     pbp->csCode = call;
  236.     
  237. }
  238.  
  239. returnPB( pbp)
  240. TCPiopb *pbp;
  241. {
  242.     int n=0;
  243.     
  244.     while (freePB[n].ptr != (Ptr) pbp && n<MAX_FREE_PB) n++;    /* BYU LSC */
  245.     if (n >= MAX_FREE_PB)
  246.         return(-1);
  247.     freePB[n].inuse=0;
  248.     
  249. }
  250.  
  251. /***************************************************************************/
  252. /*  Mnetread
  253. *   Read from a connection buffer into a user buffer.  
  254. *   Returns number of bytes read, < 0 on error
  255. * NOTE:
  256. *    current version very inefficient, but hopefully works.
  257. */
  258. Mnetread(pnum,buffer,n)                        /* BYU 2.4.16 */
  259.     int pnum,n;
  260.     char *buffer;
  261.     {
  262.     int i;
  263.     StreamRPtr p;
  264.     TCPiopb *pbp;
  265.     int inQ, reqdamt;
  266.  
  267.     if (pnum < 0 || pnum >= NPORTS)            /* BYU 2.4.15 */
  268.         return(-2);
  269.  
  270.     if (NULL == (p = streams[pnum]))
  271.         return(-2);
  272.     
  273.     
  274.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  275.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  276.         putln("TCPStatus failed(read)"); return(-1);
  277.         }
  278. #ifdef DEBUGHEADERS    
  279.     { char temp[100];
  280.         sprintf(temp, "Stat: %x(%d)->%x(%d) <%d,%d,%d> [%d,%d] {%d,%d}",
  281.             (int)pbp->csParam.status.remoteHost,
  282.             (int)pbp->csParam.status.remotePort,
  283.             (int)pbp->csParam.status.localHost,
  284.             (int)pbp->csParam.status.localPort,
  285.             (int)pbp->csParam.status.tosFlags,
  286.             (int)pbp->csParam.status.precedence,
  287.             (int)pbp->csParam.status.connectionState,
  288.             (int)pbp->csParam.status.sendWindow,
  289.             (int)pbp->csParam.status.rcvWindow,
  290.             (int)pbp->csParam.status.amtUnackedData,
  291.             (int)pbp->csParam.status.amtUnreadData);
  292.         putln(temp);
  293.     }
  294. #endif DEBUGHEADERS
  295.     
  296.     if (pbp->csParam.status.connectionState !=8) {
  297.         char temp[50];
  298.         sprintf(temp,"CState: %d is %d",(int)pnum, (int)pbp->csParam.status.connectionState);
  299.         putln(temp);
  300.         return(-1);                              /* Connection not established */
  301.         }
  302.     
  303.     inQ = pbp->csParam.status.amtUnreadData;
  304.     reqdamt = n >inQ ? inQ : n;
  305.     
  306.     clearPB( pbp, TCPd, TCPRcv, p->stream, pnum);
  307.     pbp->csParam.receive.rcvBuff = buffer;
  308.     pbp->csParam.receive.rcvBuffLen = reqdamt;
  309.     
  310.     if (reqdamt<1) {                                /* Drop out if no data */
  311.         returnPB(pbp);
  312.         return(0);
  313.         }
  314.     
  315.     if ((i = PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
  316.         char temp[100];
  317.         sprintf(temp,"TCPRcv failed (%d)",i);
  318.         putln( temp);
  319.         return(-1);
  320.         }
  321.         
  322.     reqdamt = pbp->csParam.receive.rcvBuffLen;
  323.     if (reqdamt<inQ) {
  324.         netputuev( CONCLASS, CONDATA, pnum);            /* more data to get */
  325.         }
  326.         
  327.     returnPB(pbp);                    /* Trash PB */
  328. #ifdef TESTINGPARMS
  329.     {
  330.         char temp[100];
  331.         sprintf(temp, "NETRead: %d from %d", reqdamt, pnum);
  332.         putln(temp);
  333.     }
  334. #endif TESTINGPARMS
  335.     return(reqdamt);
  336. }
  337.  
  338. /**************************************************************************/
  339. /* 
  340.  *    reclaim( p) -
  341.  *        reclaims buffer space to stream (from pointer p) into the FDS list 
  342.  */
  343.  
  344. reclaim(p)
  345. StreamRPtr p;
  346. {
  347.     int n=0, offset=0;
  348.     
  349.     while (offset < MAX_FDS_ELEMS && p->fds[offset].ptr != 0L) offset++;
  350.     
  351.     if (offset >= MAX_FDS_ELEMS) {
  352.         putln("Couldn't reclaim because offset was too large ");
  353.         return(0);
  354.         }
  355.     for (n=0 ; n<MAX_FDS_ELEMS && offset< MAX_FDS_ELEMS; n++) {
  356.         if (p->exFDS[ n].inuse) {
  357.             p->fds[ offset++]=p->exFDS[ n].fds;
  358.             p->exFDS[ n].inuse = 0;
  359.             }
  360.         }
  361. }
  362.  
  363. /**************************************************************************/
  364. /*
  365.  *     compressfds( fds)
  366.  *        compress an fds data structure to make everyone happy
  367.  */
  368.  
  369. compressfds( fds)
  370. wdsEntry *fds;
  371. {
  372.     int n,m,compressed;
  373.     
  374.     compressed = 0;
  375.     
  376.     while ( !compressed) {
  377.         compressed=1;
  378.         for (n=0; n< MAX_FDS_ELEMS; n++) {                /* Slow Forwards */
  379.             if (fds[n].ptr) {                                /* Do if N exists */
  380.                 for ( m = MAX_FDS_ELEMS -1; m>=0; m--) {    /* Fast Backwards */
  381.                     if (fds[m].ptr && (fds[m].ptr+fds[m].length == fds[n].ptr)) {
  382.                         fds[n].length+=fds[m].length;
  383.                         fds[n].ptr = fds[m].ptr;
  384.                         fds[m].ptr=0L;
  385.                         fds[m].length=0;
  386.                         compressed=0;
  387.                         }
  388. #ifdef CHECKBOTHWAYZ
  389.                     else 
  390.                     if (fds[n].ptr+fds[n].length == fds[m].ptr) {
  391.                         fds[m].length+=fds[n].length;
  392.                         fds[n].ptr=0L;
  393.                         fds[n].length=0;
  394.                         compressed=0;
  395.                         }
  396. #endif CHECKBOTHWAYZ
  397.                     }
  398.                 }
  399.             }
  400.         }
  401.     m=0;n=0;
  402.     
  403.     /* Close the gaps */
  404.     
  405.     while (n+m < MAX_FDS_ELEMS) {
  406.         while (fds[n+m].ptr ==0L && n+m< MAX_FDS_ELEMS) {
  407.             m++;            /* increase gap to valid entry */
  408.             }
  409.         if (n+m<MAX_FDS_ELEMS)
  410.             fds[n]=fds[n+m];
  411.         n++;
  412.         }
  413.     
  414.     /* Get rid of the empty spaces */
  415.     
  416.     n--;        /* for the next loop */
  417.     while (n < MAX_FDS_ELEMS) {
  418.         fds[n].ptr=0; fds[n++].length=0;
  419.         }
  420. }
  421.  
  422. /************************************************************************/
  423. /* Mnetwrite
  424. *  write something into the output queue, netsleep routine will come
  425. *  around and send the data, etc.
  426. *
  427. */
  428. int                                        /* BYU LSC */
  429. Mnetwrite(pnum,buffer,nsend)            /* BYU 2.4.16 */
  430.     int pnum,nsend;
  431.     char *buffer;
  432.     {
  433.     StreamRPtr p;
  434.     wdsEntry *swds;
  435.     int remaining, queued, n,m;
  436.     TCPiopb *pbp;
  437.  
  438.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  439.         return(-2);
  440.  
  441.     if ( (p = streams[pnum]) == NULL)
  442.         return(-2);
  443.     
  444.     if ( !nsend )
  445.         return(0);
  446.  
  447.     swds = getSWDS();
  448.     
  449.     reclaim( p);
  450.     compressfds( p->fds);
  451.  
  452.     n=0; remaining = nsend;
  453.     while (p->fds[n].ptr !=0 && remaining>0 ) {
  454.         swds[n].ptr = p->fds[n].ptr;
  455.         if ( p->fds[n].length > remaining) {
  456.             swds[n].length = remaining;
  457.             p->fds[n].length -= remaining;
  458.             p->fds[n].ptr += remaining;
  459.             remaining=0;
  460.             }
  461.         else {
  462.             swds[n].length =  p->fds[n].length;
  463.             remaining -= p->fds[n].length;
  464.             p->fds[n].length = 0;
  465.             p->fds[n].ptr = 0;
  466.             }
  467.         n++;
  468.         }
  469.     if (n>p->maxFDSused) p->maxFDSused=n;
  470.     
  471.     compressfds( p->fds);
  472.     queued = nsend-remaining;
  473.     
  474.     for (m=0; m<n; m++) {
  475.         memcpy((char *) swds[m].ptr, buffer, swds[m].length);    /* BYU LSC - Put data in WDS */
  476.         buffer +=swds[m].length;
  477.         }
  478.     swds[m].ptr =0L;
  479.     swds[m].length=0;
  480.     
  481.     pbp=getPB( TCPd, TCPSend, p->stream, pnum);            /* Make send call */
  482.     pbp->csParam.send.wdsPtr = (Ptr) swds;
  483.     pbp->csParam.send.pushFlag = p->push;
  484.  
  485.     pbp->ioCompletion = (TCPIOCompletionProc) sendComplete;                    /* Completion routine */
  486.  
  487.     p->push=0;
  488.  
  489.     if (PBControl((ParmBlkPtr) pbp, Qcall) != noError) {
  490.         putln("TCPSend failed to Q"); return(-1);
  491.         }
  492.  
  493. #ifdef TESTINGPARMS
  494.     putln("TCP Sent");
  495.     { char temp[100];
  496.         sprintf(temp, "TCP Sent: %d of %d on %d [%d/%d]", queued, nsend, pnum,n,p->maxFDSused);
  497.         putln(temp);
  498.     }
  499. #endif TESTINGPARMS
  500.     return(queued);
  501. }
  502.  
  503. /**************************************************************************/
  504. /*  Mnetpush
  505. *   attempt to push the rest of the data from the queue
  506. *   and then return whether the queue is empty or not (0 = empty)
  507. *   returns the number of bytes in the queue.
  508. */
  509. Mnetpush(pnum)                            /* BYU 2.4.16 */
  510.     int pnum;
  511.     {
  512.     StreamRPtr p;
  513.     TCPiopb *pbp;
  514.     int inQ;
  515.  
  516.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  517.         return(-2);
  518.  
  519.     if (NULL == (p = streams[pnum]))
  520.         return(-2);
  521.  
  522.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  523.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  524.         putln("TCPStatus failed(push)"); return(-1);
  525.         }
  526.     inQ = pbp->csParam.status.amtUnackedData;
  527.     returnPB( pbp);
  528.     
  529.     p->push=1;
  530.     
  531.     return(inQ);
  532.  
  533. }    
  534.  
  535. /**************************************************************************/
  536. /*  Mnetqlen
  537. *   return the number of bytes waiting to be read from the incoming queue.
  538. */
  539. Mnetqlen(pnum)                            /* BYU 2.4.16 */
  540.     int pnum;
  541.     {
  542.     StreamRPtr p;
  543.     TCPiopb *pbp;
  544.     int inQ;
  545.  
  546.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  547.         return(-2);
  548.  
  549.     if (NULL == (p = streams[pnum]))
  550.         return(-2);
  551.  
  552.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  553.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  554.         putln("TCPStatus failed(qlen)"); return(-1);
  555.         }
  556.     inQ = pbp->csParam.status.amtUnreadData;
  557.     returnPB( pbp);
  558.     
  559.     p->push = 1;
  560.     return(inQ);
  561. }
  562.  
  563. /**************************************************************************/
  564. /*  Mnetroom()
  565. *    return how much room is available in output buffer for a connection
  566. */
  567. Mnetroom(pnum)                            /* BYU 2.4.16 */
  568.     int pnum;
  569.     {
  570.     StreamRPtr p;
  571.     TCPiopb *pbp;
  572.     int inQ,n;
  573.  
  574.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  575.         return(-2);
  576.  
  577.     if (NULL == (p = streams[pnum]))
  578.         return(-2);
  579.  
  580.     reclaim( p);
  581.     compressfds( p->fds);
  582.  
  583. #ifdef OLDM
  584.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  585.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  586.         putln("TCPStatus failed(room)"); return(-1);
  587.         }
  588.     inQ = pbp->csParam.status.sendWindow -
  589.                 pbp->csParam.status.amtUnackedData;
  590.     returnPB( pbp);
  591. #else
  592. /*#pragma unused(pbp)    /* BYU LSC */
  593. #endif
  594.  
  595.     inQ = n = 0;
  596.     while (p->fds[n].ptr) {
  597.     
  598.         inQ += p->fds[n].length;                /* add up free list space */
  599.         n++;
  600.         }
  601.  
  602.     return(inQ);
  603. }
  604.  
  605. #if 0                                            /* BYU 2.4.16 */
  606. /**************************************************************************/
  607. /* netsegsize and neterrchange and netsetip and netgetip
  608. *
  609. *  set operating parameters to change them from the default values used.
  610. */
  611.  
  612. netsegsize(newsize)
  613.     int newsize;
  614.     {
  615.     int i;
  616.  
  617.     i = nnsegsize;
  618.     nnsegsize = newsize;
  619.  
  620.     return(i);
  621. }
  622.  
  623. /**************************************************************************/
  624. netquench(newcredit)
  625.     int newcredit;
  626.     {
  627.     int i;
  628.  
  629.     i = nncredit;
  630.     nncredit = newcredit;
  631.  
  632.     return(i);
  633. }
  634.  
  635. /**************************************************************************/
  636. netarptime(t)                    /* dlayer timeout in secs */
  637.     int t;
  638.     {
  639.     nndto = t;
  640. }
  641.  
  642. /**************************************************************************/
  643. void netsetip
  644.   (
  645.     unsigned char *st
  646.   )
  647.     {
  648. /*
  649. *  this is a no-op with the MacTCP driver
  650. */
  651. /*#pragma unused(st)    /* BYU LSC */
  652. }
  653. #endif                                            /* BYU 2.4.16 */
  654.  
  655. /**************************************************************************/
  656. int Mnetgetip                                    /* BYU 2.4.16 */
  657.   (
  658.     unsigned char *st
  659.   )
  660. {
  661.     struct IPParamBlock mypb;
  662.     /* long netmask; */
  663.  
  664.     putln("Attempting getmyipaddr");
  665.     
  666.     memset((char *) &mypb, '\0', sizeof(struct IPParamBlock));    /* BYU LSC - Default to all zeros */
  667.     
  668.     mypb.ioCRefNum = TCPd;            /* BYU LSC - TCP driver has to be open by now */
  669.     mypb.csCode = ipctlGetAddr;
  670.  
  671.     if (PBControl((ParmBlkPtr) &mypb, noQcall) != noError) {
  672.         putln("Getting my address failed"); 
  673.         return(-1);
  674.         }
  675.     
  676.     memcpy((char *) st, (char *) &mypb.ourAddress, 4);    /* BYU LSC - copy the address */
  677.     
  678.     /* netmask is here if we want it, too */
  679.     
  680.     return(0);
  681.  
  682. }
  683.  
  684. #if 0                                    /* BYU 2.4.16 */
  685. /**************************************************************************/
  686. netsetmask(st)
  687. unsigned char *st;
  688. {
  689.     movebytes(nnmask,st,4);
  690. }
  691.  
  692. /**************************************************************************/
  693. netgetmask(st)
  694. unsigned char *st;
  695. {
  696.     movebytes(st,nnmask,4);
  697. }
  698.  
  699. netfromport(port)            /* next "open" will use this port */
  700. int16 port;
  701. {
  702.     nnfromport = port;
  703.  
  704. }
  705. #endif                                    /* BYU 2.4.16 */
  706.  
  707. /**************************************************************************/
  708. /*  Mnetest?
  709. *  is a particular session established yet?
  710. *  Returns 0 if the connection is in the established state.
  711. */
  712. Mnetest(pnum)                            /* BYU 2.4.16 */
  713. int pnum;
  714. {
  715.     StreamRPtr p;
  716.     TCPiopb *pbp;
  717.     int inQ;
  718.  
  719.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  720.         return(-2);
  721.  
  722.     if (NULL == (p = streams[pnum]))
  723.         return(-2);
  724.  
  725.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  726.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  727.         putln("TCPStatus failed(est)");
  728.         inQ = -1;
  729.         }
  730.     else 
  731.         inQ = pbp->csParam.status.connectionState !=8;
  732.     returnPB( pbp);
  733.     
  734.     return(inQ);
  735.  
  736. }
  737.  
  738. /**************************************************************************/
  739. /*
  740.  * Returns an empty stream
  741.  */ 
  742. int                    /* BYU LSC */
  743. makestream()
  744. {
  745.     int    pnum;
  746.     StreamRPtr p;
  747.     TCPiopb *pbp;
  748.     int i;
  749.  
  750.     for ( pnum=0; (streams[pnum]!= NULL || porttype[pnum]) && pnum<NPORTS; pnum++);    /* BYU 2.4.16 */
  751.     
  752.     if (pnum >= NPORTS)
  753.         return(-2);
  754.  
  755.     p = streams[pnum] = (StreamRPtr) NewPtr(sizeof(StreamRec));
  756.  
  757.     if ((p->buffer = (char *) NewPtr( TCPBUFSIZ)) == (char *)NULL)
  758.         return(-1);
  759.     if ((p->sbuffer = (char *) NewPtr( TCPBUFSIZ)) == (char *)NULL)
  760.         return(-1);
  761.     
  762.     for (i=0; i<MAX_FDS_ELEMS; i++) {
  763.         p->fds[ i].length =0; p->fds[ i].ptr = 0L;
  764.         p->exFDS[ i].inuse=0; p->exFDS[ i].fds.length=0;p->exFDS[ i].fds.ptr=0L;
  765.         }
  766.     p->fds[0].length = TCPBUFSIZ;
  767.     p->fds[0].ptr = p->sbuffer;
  768.     p->maxFDSused=0;
  769.  
  770.     
  771.     pbp=getPB( TCPd, TCPCreate, (long) 0, pnum);    /* BYU LSC important - Make create call */
  772.     pbp->csParam.create.rcvBuff = p->buffer;
  773.     pbp->csParam.create.rcvBuffLen = TCPBUFSIZ;
  774.     pbp->csParam.create.notifyProc = TCPNotify;
  775.  
  776.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  777.         putln("TCPCreate failed"); return(-1);
  778.         }
  779.  
  780.     p->stream = pbp->tcpStream;
  781.     
  782.     putln("Made new stream");
  783.     returnPB(pbp);
  784.     return(pnum);
  785. }
  786.  
  787. /**************************************************************************/
  788. /*  Mnetlisten
  789. *   Listen to a TCP port number and make the connection automatically when
  790. *   the SYN packet comes in.  The TCP layer will notify the higher layers
  791. *   with a CONOPEN event.  Save the port number returned to refer to this
  792. *   connection.
  793. *
  794. *   usage:   portnum = netlisten(service);
  795. *            int service;
  796. *
  797. */
  798. int                                        /* BYU LSC */
  799. Mnetlisten(serv)                        /* BYU 2.4.16 */
  800. uint serv;
  801. {
  802.     int    pnum;
  803.     StreamRPtr p;
  804.     TCPiopb *pbp;
  805.  
  806.     if (!net_okay)                         /* BYU 2.4.15 */
  807.         return(-2);                        /* BYU 2.4.15 */
  808.  
  809.     pnum = makestream();
  810.  
  811.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  812.         return(-2);
  813.  
  814.     if (NULL == (p = streams[pnum]))
  815.         return(-2);
  816.  
  817.     pbp=getPB( TCPd, TCPPassiveOpen, p->stream, pnum);            /* Make Listen call */
  818.     
  819.     pbp->csParam.open.localPort = serv;
  820.     pbp->ioCompletion = (TCPIOCompletionProc) openComplete;        /* IO Completion for open */
  821.     
  822.     if (PBControl((ParmBlkPtr) pbp, Qcall) != noError) {
  823.         putln("TCPListen failed"); return(-1);
  824.         }
  825.  
  826.     return(pnum);                        /* BYU 2.4.16 */
  827. }
  828.  
  829. /***********************************************************************/
  830. /*  Mnetgetftp
  831. *  Provides the information that ftp needs to open a stream back to the
  832. *  originator of the command connection.  The other side's IP number
  833. *  and the port numbers to be used to calculate the default data connection
  834. *  number.  Returns values in an integer array for convenient use in 
  835. *  PORT commands.
  836. */
  837. Mnetgetftp(a,pnum)                                            /* BYU 2.4.16 */
  838. int a[];
  839. int pnum;
  840. {
  841.     StreamRPtr p;
  842.     TCPiopb *pbp;
  843.     long temp;
  844.     
  845.     if (pnum < 0)
  846.         return(-2);
  847.  
  848.     if (NULL == (p = streams[pnum]))
  849.         return(-2);
  850.  
  851.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  852.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  853.         putln("TCPStatus failed(getftp)"); return(-1);
  854.         }
  855.  
  856.     temp      = pbp->csParam.status.remoteHost;
  857.     a[0]= (temp>>24) & 0xff;
  858.     a[1]= (temp>>16) & 0xff;
  859.     a[2]= (temp>> 8) & 0xff;
  860.     a[3]= (temp    ) & 0xff;
  861.     temp    = pbp->csParam.status.localPort;
  862.     a[4]= (temp>> 8) & 0xff;
  863.     a[5]= (temp    ) & 0xff;
  864.     temp    = pbp->csParam.status.remotePort;
  865.     a[6]= (temp>> 8) & 0xff;
  866.     a[7]= (temp    ) & 0xff;
  867.  
  868.     returnPB( pbp);
  869. }
  870.  
  871.  
  872. /**************************************************************************/
  873. /*  Mnetxopen
  874. *   Open a network socket for the user.
  875. *
  876. */
  877. int Mnetxopen                                /* BYU 2.4.16 */
  878.   (
  879.     uint32 *machine,
  880.     uint service,
  881.     uint rto,
  882.     uint mtu,
  883.     uint mseg,
  884.     uint mwin
  885.   )
  886. {
  887. /*#pragma unused(rto, mtu, mseg, mwin)        /* BYU LSC */
  888.     int    pnum;
  889.     StreamRPtr p;
  890.     TCPiopb *pbp;
  891.     char temp[100];
  892.  
  893.     pnum = makestream();
  894.  
  895.     if (pnum < 0)
  896.         return(-2);
  897.  
  898.     if (NULL == (p = streams[pnum]))
  899.         return(-2);
  900.  
  901.     pbp=getPB( TCPd, TCPActiveOpen, p->stream, pnum);            /* Make Listen call */
  902.     
  903.     pbp->csParam.open.remoteHost = *machine;            /* IP # */
  904.     pbp->csParam.open.remotePort = service;                /* Port */
  905.     pbp->csParam.open.localPort = nnfromport;            /* My Port */
  906.     nnfromport=0;                                            /* Next one is random */
  907.     
  908.     pbp->ioCompletion = (TCPIOCompletionProc) openComplete;    /* IO Completion for open */
  909.     
  910.     if (PBControl((ParmBlkPtr) pbp, Qcall) != noError) {
  911.         putln("TCPOpen failed(Active)"); return(-1);
  912.         }
  913.     sprintf(temp,"TCPOpen on %d",pnum);
  914.     putln(temp);
  915.     return(pnum);                    /* BYU 2.4.16 */
  916. }
  917.  
  918.  
  919. #if 0                                /* BYU 2.4.15 - not used */
  920. /**************************************************************************/
  921. /*  netopen
  922. *   Netopen is a cheap way to open a connection without looking up any
  923. *   machine information.  Uses suitable default values for everything.
  924. */
  925. netopen(s,tport)
  926. unsigned char *s;
  927. uint tport;
  928. {
  929.  
  930.     return(netxopen((uint32 *) s,tport,MINRTO,TSENDSIZE,DEFSEG,DEFWINDOW));
  931. }
  932. #endif
  933.  
  934.  
  935. /**************************************************************************/
  936. /* Mnetclose
  937. *  Do appropriate actions to return connection state to SCLOSED which
  938. *  enables the memory for that port to be reused.
  939. *
  940. *    Specifically:
  941. *        o If status is closed, then release the data structures
  942. *        o If status is not close, perform bkgrd close which generates CLOSEDONE,
  943. *            which should make the session layer call us again
  944. */
  945. int Mnetclose                                /* BYU 2.4.16 */
  946.   (
  947.     int pnum
  948.   )
  949. {
  950.     StreamRPtr p;
  951.     TCPiopb *pbp;
  952.     int errorCode=0;
  953.     int status;
  954.     char temp[50];
  955.     static short count=0;
  956.  
  957.     if (pnum < 0 || pnum >= NPORTS)            /* is a valid port? */
  958.         return(-1);
  959.  
  960.     if ((p = streams[pnum]) == NULL)             /* nothing there */
  961.         return (1);
  962.  
  963.     pbp=getPB( TCPd, TCPStatus, p->stream, pnum);            /* Make status call */
  964.     if ((errorCode = PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
  965.         if ( errorCode == invalidStreamPtr) {
  966.             putln("TCPStatus failed because of bad stream pointer (close)");
  967.             return(-1);
  968.             }
  969.         else
  970.             {
  971.             status=0;
  972.             count =0;
  973.             }
  974.         }
  975.     else 
  976.         {
  977.         status = pbp->csParam.status.connectionState;            /* The connection Status */
  978.         if (count++ ==10) status=count =0;
  979.         }
  980.  
  981. /* */
  982.  
  983.     sprintf(temp,"the error Code is %i",(int)errorCode);
  984.     putln(temp);
  985.  
  986.     if (status < 18 && status >2 ) {                            /* We aren't closed yet ! */
  987.         char temp[50];
  988.         sprintf(temp, "TCPClose being attempted state ...[%d]",status);    /* Prolly because outstanding close */
  989.         putln(temp);
  990.         clearPB( pbp, TCPd, TCPClose, p->stream, pnum);            /* Make Close call */
  991.         pbp->ioCompletion = (TCPIOCompletionProc) closeComplete; /* IO Completion for close */
  992.         if ((errorCode=PBControl((ParmBlkPtr) pbp, Qcall)) != noError) {
  993.             char temp[50];
  994.             sprintf(temp, "TCPClose failed...[%d]",errorCode);    /* Prolly because outstanding close */
  995.             putln(temp);
  996.             putln("we have an error");
  997.             return (errorCode); /* */
  998.             }
  999.  
  1000.         return (0);                                            /* Return with OK */
  1001.         }
  1002.  
  1003.     /* IF we got here, we must be at closed state, so free memory */
  1004.  
  1005.     putln("TCP Being Released...... ");
  1006.     clearPB( pbp,TCPd, TCPRelease, p->stream, pnum);            /* Make Release call */
  1007.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1008.         putln("TCPRelease failed"); return(-1);
  1009.         }
  1010.     
  1011.     DisposPtr( p->buffer);                /* Free Receive Buffer */
  1012.     DisposPtr( p->sbuffer);                /* Free Send Buffer */
  1013.     DisposPtr((Ptr) p);                    /* Free Stream Structure */
  1014.     streams[pnum]=0L;
  1015.     porttype[pnum] = UNKNOWN_PORT_TYPE;    /* BYU 2.4.16 */
  1016.  
  1017.     returnPB(pbp);
  1018.     return(0);
  1019. }
  1020.  
  1021. /**************************************************************************/
  1022. /* netabort
  1023. *    Nuke the connection, NOW!
  1024. */
  1025. netabort(pnum)
  1026. int pnum;
  1027. {
  1028.     StreamRPtr p;
  1029.     TCPiopb *pbp;
  1030.     int errorCode=0;
  1031.  
  1032.     if (pnum < 0 || pnum >= NPORTS)            /* is a valid port? */
  1033.         return(-1);
  1034.  
  1035.     if ((p = streams[pnum]) != NULL) {            /* something there */
  1036.         pbp=getPB( TCPd, TCPAbort, p->stream, pnum);            /* Make Close call */
  1037.         if ((errorCode=PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
  1038.             char temp[50];
  1039.             sprintf(temp, "TCPAbort failed...[%d]",errorCode);
  1040.             putln(temp);
  1041.             }
  1042.         clearPB( pbp,TCPd, TCPRelease, p->stream, pnum);            /* Make Close call */
  1043.         if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1044.             putln("TCPRelease failed"); return(-1);
  1045.             }
  1046.         }
  1047.     else
  1048.         return(1);
  1049.     
  1050.     DisposPtr( p->buffer);                /* Free Receive Buffer */
  1051.     DisposPtr( p->sbuffer);                /* Free Send Buffer */
  1052.     DisposPtr((Ptr) p);                    /* Free Stream Structure */
  1053.     streams[pnum]=0L;
  1054.     porttype[pnum] = UNKNOWN_PORT_TYPE;    /* BYU 2.4.16 */
  1055.  
  1056.     returnPB(pbp);
  1057.     return(0);
  1058. }
  1059.  
  1060. /**************************************************************************/
  1061. /*  Mnetinit
  1062. *   Calls all of the various initialization routines that set up queueing
  1063. *   variables, static values, reads configuration files, etc.
  1064. */
  1065.  
  1066. int Mnetinit                                        /* BYU 2.4.16 */
  1067.   (
  1068.     void
  1069.   )
  1070. {
  1071.     int i;
  1072. extern Cursor *normcurs;
  1073.     
  1074.     for (i=0; i<NPORTS;i++)
  1075.         streams[i]= (StreamRPtr) 0;
  1076.         
  1077.     for (i=0; i<NPORTS;i++)
  1078.         uport[i]= (UDPRPtr) 0;
  1079.     
  1080.     if (OpenDriver("\p.IPP",&TCPd) != noError) {    /* BYU LSC */
  1081.         SetCursor(normcurs);
  1082.         putln( "Couldn't open IP driver ");
  1083.         OtherError((char *) "\pError opening TCP drivers.",(char *) "\pPossibly no dynamic addressing");    /* BYU LSC */
  1084.         EtherNet = -100;    /* BYU 2.4.16 - show serial connections only */
  1085. /*        quit();                /* BYU 2.4.16 */
  1086.         }
  1087.         
  1088.     return(0);                /* set up empty packets */
  1089. }
  1090.  
  1091. /**************************************************************************/
  1092. int UDPfindport( port)
  1093. int port;
  1094. {
  1095.     int pnum=0;
  1096.     
  1097.     while (pnum<NPORTS &&
  1098.             ( uport[pnum] ==(UDPRPtr)0L || port !=uport[pnum]->port))
  1099.         pnum++;
  1100.     if (pnum >=NPORTS)
  1101.         return(-1);
  1102.     else
  1103.         return(pnum);
  1104. }
  1105.  
  1106. /**************************************************************************/
  1107. /*
  1108.  * netuclose( port)             - close the udp port 
  1109.  */
  1110.  
  1111. netuclose( port)
  1112. int port;
  1113. {
  1114.     UDPRPtr p;
  1115.     UDPiopb *pbp;
  1116.     int pnum;
  1117.     
  1118.     pnum= UDPfindport( port);
  1119.     
  1120.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  1121.         return(-1);
  1122.     
  1123.     p=uport[pnum];
  1124.     
  1125.     pbp = getUPB( TCPd, UDPRelease, p->stream, 0);
  1126.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1127.         putln("UDPClose failed"); return(-1);
  1128.         }
  1129.     DisposPtr( p->buffer);
  1130.     DisposPtr((Ptr) uport[pnum]);
  1131.     uport[pnum]=0;                /* use me again */
  1132.     
  1133.     returnPB((TCPiopb *) pbp);    /* BYU LSC */
  1134. }
  1135.  
  1136. /*************************************************************************/
  1137. /*  Mnetshut
  1138. *   Close all the connections and turn off the hardware.
  1139. */
  1140. Mnetshut()                                        /* BYU 2.4.16 */
  1141.     {
  1142.     int i;
  1143.  
  1144.     for (i=0; i < NPORTS ; i++) 
  1145.         if (streams[i] != (StreamRPtr) NULL)
  1146.             netabort(i);                        /* Prolly should abort */
  1147.     for (i=0; i < NPORTS ; i++) 
  1148.         if (uport[i] != (UDPRPtr) NULL)
  1149.             netuclose(uport[i]->port);            /* Shut down UDP too... */
  1150. #ifdef SAFE
  1151.     CloseDriver( TCPd);
  1152. #endif SAFE
  1153. }
  1154.  
  1155. /**************************************************************************/
  1156. int findbystream( streamPtr)
  1157. StreamPtr streamPtr;
  1158. {
  1159.     int pnum=0;
  1160.     
  1161.     while (pnum<NPORTS &&
  1162.             ( (streams[pnum] ==(StreamRPtr)0L) || (streamPtr !=streams[pnum]->stream)))
  1163.         pnum++;
  1164.     if (pnum >=NPORTS)
  1165.         return(-1);
  1166.     else
  1167.         return(pnum);
  1168. }
  1169.  
  1170.  
  1171. /**************************************************************************/
  1172. pascal void TCPNotify( streamPtr, code, uptr, terminReason, icmpMsg)
  1173. StreamPtr streamPtr;
  1174. unsigned short /*enum  TCPEventCode*/ code;
  1175. unsigned short /*enum  TCPTerminationReason*/ terminReason;
  1176. struct ICMPReport *icmpMsg;
  1177. Ptr uptr;   /* user data pointer */
  1178. {
  1179. /*#pragma unused(uptr, terminReason, icmpMsg)    /* BYU LSC */
  1180.     StreamRPtr p;
  1181.     int pnum;
  1182.     
  1183.     pnum = findbystream(streamPtr);
  1184.     
  1185.     if (pnum < 0 || (p = streams[pnum]) == 0L)
  1186.         return;
  1187.     
  1188.     switch( code) {
  1189.         case TCPTerminate:
  1190.         case TCPClosing:
  1191.             netputevent(CONCLASS, CONCLOSE, pnum);
  1192.             break;
  1193.         case TCPULPTimeout:
  1194.             netputevent(CONCLASS, CONFAIL, pnum);
  1195.             break;
  1196.         case TCPDataArrival:
  1197.         case TCPUrgent:
  1198.             netputuev(CONCLASS, CONDATA, pnum);
  1199.             break;
  1200.         case TCPICMPReceived:
  1201.         default:
  1202.             break;
  1203.         }
  1204.     return;
  1205. }
  1206.  
  1207. /*************************************************************************/
  1208. /*  Mnetopen2
  1209. *   Send out repeat SYN on a connection which is not open yet
  1210. *   Checks, and only sends one if needed.
  1211. *   Returns 1 if the state is still SYNS and 0 if the connection has proceeded.
  1212. *   The timing is all handled at a higher layer.
  1213. */
  1214. int Mnetopen2                                            /* BYU 2.4.16 */
  1215.   (
  1216.     int pnum
  1217.   )
  1218. {
  1219.     return( netest(pnum));
  1220. }
  1221.  
  1222. /**************************************************************************/
  1223. long openComplete( pbp)
  1224. TCPiopb *pbp;
  1225. {
  1226.     StreamRPtr p;
  1227.     int pnum;
  1228.     
  1229.     pnum= findbystream(pbp->tcpStream);
  1230.     
  1231.     if (pnum < 0 || (p = streams[pnum]) == 0L) 
  1232.         return(-1L);
  1233.         
  1234.     if (pbp->ioResult !=noError) 
  1235.         netputevent(CONCLASS, CONFAIL, pnum);            /* Failure ... */
  1236.     else 
  1237.         netputevent(CONCLASS, CONOPEN, pnum);            /* Success ! */
  1238.  
  1239.     returnPB( pbp);
  1240.     return(0);
  1241. }
  1242.  
  1243. /**************************************************************************/
  1244. /*
  1245.  *    giveback( p, wds) -
  1246.  *        gives WDS entries back to the stream by putting them in the 
  1247.  *        mutually exclusive buffer.
  1248.  *    p -> stream
  1249.  *    wds -> wds array
  1250.  */
  1251. giveback( p, wds)
  1252. StreamRPtr p;
  1253. wdsEntry *wds;
  1254. {
  1255.     int n=0, m=0;
  1256.     
  1257.     while ( n< MAX_SWDS_ELEMS && wds[n].ptr !=0L) {
  1258.         while (m< MAX_FDS_ELEMS && p->exFDS[ m].inuse) m++;
  1259.         if (m> MAX_FDS_ELEMS)
  1260.             return(-1);                /* No room in the RECLAIMation center */
  1261.         else {
  1262.             p->exFDS[ m].inuse =1;
  1263.             p->exFDS[ m].fds = wds[n];
  1264.             m++;
  1265.             }
  1266.         n++;
  1267.         }
  1268. }
  1269.  
  1270.  
  1271. /**************************************************************************/
  1272. long sendComplete( pbp)
  1273. TCPiopb *pbp;
  1274. {
  1275.     StreamRPtr p;
  1276.     int pnum;
  1277.     wdsEntry *swds;
  1278.     int i=0,j=0;
  1279.  
  1280.     swds = (wdsEntry *) pbp->csParam.send.wdsPtr;    /* BYU LSC */
  1281.     
  1282.     pnum= findbystream(pbp->tcpStream);
  1283.     if (pnum < 0 || (p = streams[pnum]) == 0L)
  1284.         return(-1);
  1285.  
  1286.     returnSWDS( swds);
  1287.     returnPB( pbp);
  1288.  
  1289.     giveback( p, (wdsEntry *) pbp->csParam.send.wdsPtr);    /* BYU LSC - Give this back.... NOW */
  1290.     
  1291.     return(0);
  1292. }
  1293.  
  1294.  
  1295. /**************************************************************************/
  1296. long closeComplete( pbp)
  1297. TCPiopb *pbp;
  1298. {
  1299.     StreamRPtr p;
  1300.     int pnum;
  1301.     
  1302.     pnum= findbystream(pbp->tcpStream);
  1303.     
  1304.     if (pnum < 0 || (p = streams[pnum]) == 0L)
  1305.       {
  1306.         netputevent(SCLASS, CLOSEDONE+1, pnum);
  1307.         return(-1);
  1308.       }
  1309.         
  1310.     if (pbp->ioResult !=noError) 
  1311.         netputevent(SCLASS, CLOSEDONE+1, pnum);
  1312.     else 
  1313.         netputevent(SCLASS, CLOSEDONE, pnum);            /* Success ! */
  1314.  
  1315.     returnPB( pbp);
  1316.     return(0);
  1317. }
  1318.  
  1319.  
  1320.  
  1321. /*****************************************************************************
  1322.  *
  1323.  * Here lie the awful UDP routines, I put them here for the drivers from Apple.
  1324.  *
  1325.  */
  1326.  
  1327.  int UDPlisten =0;                /* what port the old routines listen for */
  1328.  
  1329.  
  1330. /****************************************************************************/
  1331. /*                    New UDP routines....                                    */
  1332. /****************************************************************************/
  1333.  
  1334. /**************************************************************************/
  1335. int                    /* BYU LSC */
  1336. makeuport( port)
  1337. int port;
  1338. {
  1339.     int    pnum;
  1340.     UDPRPtr p;
  1341.     UDPiopb *pbp;
  1342.     int i;
  1343.     
  1344.     for ( pnum=0; uport[pnum]!= NULL && pnum<NPORTS; pnum++);
  1345.     
  1346.     if (pnum >= NPORTS)
  1347.         return(-2);
  1348.  
  1349.     p = uport[pnum] = (UDPRPtr) NewPtr(sizeof(UDPRec));
  1350.  
  1351.     if ((p->buffer = (char *) NewPtr( UDPBUFSIZ)) == (char *)NULL)
  1352.         return(-1);
  1353.     
  1354.     
  1355.     pbp=getUPB( TCPd, UDPCreate, 0, pnum);            /* Make create call */
  1356.     
  1357.     pbp->csParam.create.rcvBuff  = p->buffer;
  1358.     pbp->csParam.create.rcvBuffLen= UDPBUFSIZ;
  1359.     pbp->csParam.create.notifyProc     = UDPNotify;
  1360.     pbp->csParam.create.localPort = port;
  1361.     
  1362.     if ((i=PBControl((ParmBlkPtr) pbp, noQcall)) != noError) {
  1363.         char temp[50];
  1364.         sprintf(temp, "UDPCreate failed (%d)",i);
  1365.         putln(temp);
  1366.         return(-1);
  1367.         }
  1368.     else {
  1369.         char temp[50];
  1370.         sprintf(temp, "UDPCreate successfull on %d(%d) [%x]",port,pnum,pbp->udpStream);
  1371.         putln(temp);
  1372.         }
  1373.     
  1374.     p->stream = pbp->udpStream;
  1375.     p->port = port;
  1376.     
  1377.     putln("Made a new UPORT");
  1378.     returnPB((TCPiopb *) pbp);        /* BYU LSC */
  1379.     return(pnum);
  1380. }
  1381.  
  1382. /**************************************************************************/
  1383. /*
  1384.  * netuopen (port)             - open the udp port "Port"
  1385.  */
  1386.  
  1387. int                 /* BYU LSC */
  1388. netuopen(port)
  1389. int port;
  1390. {
  1391.     return(makeuport( port));
  1392. }
  1393.  
  1394. /**************************************************************************/
  1395. /*
  1396.  *    netuget( port, buffer,len, who,where)
  1397.  *                    - read up to len bytes from port port into buffer buffer, noting
  1398.  *                        who it was from and where....
  1399.  */
  1400.  
  1401. netuget( port, buffer, len, who, where)
  1402. int port, len;
  1403. int *who, *where;
  1404. char *buffer;
  1405. {
  1406. /*#pragma unused(who, where)    /* BYU LSC */
  1407.     int pnum, length;
  1408.     UDPRPtr p;
  1409.     UDPiopb *pbp;
  1410.     
  1411.     pnum= UDPfindport( port);
  1412.     
  1413.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  1414.         return(-1);
  1415.     
  1416.     p=uport[pnum];
  1417.     
  1418.     pbp= getUPB( TCPd, UDPRead, p->stream, 0);
  1419.     pbp->csParam.receive.timeOut = 1;                            /* time out at one sec. */
  1420.     
  1421.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1422.         putln("UDPRead failed"); return(-1);
  1423.         }
  1424.     
  1425.     length = pbp->csParam.receive.rcvBuffLen;                /* look how BIG it is */
  1426.     length = length > len ? len:length;
  1427.     
  1428.     memcpy( buffer, pbp->csParam.receive.rcvBuff,length);
  1429.     
  1430.     pbp->csCode = UDPBfrReturn;                                /* Let my buffer go.. */
  1431.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1432.         putln("UDPReturn failed"); return(-1);
  1433.         }
  1434.         
  1435.     returnPB((TCPiopb *) pbp);        /* BYU LSC */
  1436.     
  1437.     return(length);
  1438. }
  1439.  
  1440. /**************************************************************************/
  1441. netuput( machine, port, myport, buffer, n)
  1442. long *machine;
  1443. char *buffer;
  1444. int port, myport;
  1445. int n;
  1446. {
  1447.     wdsEntry wds[2];
  1448.     UDPRPtr p;
  1449.     UDPiopb *pbp; int pnum;
  1450.     
  1451.     pnum= UDPfindport( myport);
  1452.     
  1453.     if (pnum < 0 || pnum >= NPORTS)        /* BYU 2.4.15 */
  1454.         return(-1);
  1455.     
  1456.     p=uport[pnum];
  1457.     
  1458.     pbp= getUPB( TCPd, UDPWrite, p->stream, 0);
  1459.     pbp->csParam.send.remoteHost = *machine;
  1460.     pbp->csParam.send.remotePort = port;
  1461.     pbp->csParam.send.checkSum   = 1;                    /* Do do that checksum that you do so well */
  1462.     pbp->csParam.send.wdsPtr = (Ptr) wds;
  1463. /*    pbp->csParam.send.remoteHost = *machine;    /* BYU - not needed, done above. */
  1464.     
  1465.     wds[0].ptr = buffer;
  1466.     wds[0].length=n;
  1467.     wds[1].ptr = (char *) 0L; wds[1].length=0;
  1468.     
  1469.     if (PBControl((ParmBlkPtr) pbp, noQcall) != noError) {
  1470.         putln("UDPReturn failed"); return(-1);
  1471.         }
  1472.         
  1473.     returnPB((TCPiopb *) pbp);                    /* BYU LSC */
  1474.     return(0);
  1475. }
  1476.  
  1477.  
  1478. /****************************************************************************/
  1479. /*  Mneturead
  1480. *   get the data from the UDP buffer
  1481. *   Returns the number of bytes transferred into your buffer, -1 if none here
  1482. *   This needs work.
  1483. */
  1484. int Mneturead                                    /* BYU 2.4.16 */
  1485.   (
  1486.     char *buffer
  1487.   )
  1488. {
  1489.     int who, where;
  1490.     
  1491.     if (!UDPlisten)
  1492.         return(-1);
  1493.         
  1494.     return( netuget( UDPlisten, buffer, 512, &who, &where));
  1495. }
  1496.  
  1497. /***************************************************************************/
  1498. /*  Mnetulisten
  1499. *   Specify which UDP port number to listen to.
  1500. *   Can only listen to one at a time.
  1501. */
  1502. int Mnetulisten                                    /* BYU 2.4.16 */
  1503.   (
  1504.     int port
  1505.   )
  1506. {
  1507.     char temp[50];
  1508.     int pnum;
  1509.  
  1510.     
  1511.     sprintf( temp, "UDP listening on ....%d", port);
  1512.     putln(temp);
  1513.     
  1514.     UDPlisten = port;
  1515.     
  1516.     if ( (pnum=UDPfindport( port))<0)
  1517.         pnum= netuopen(port);
  1518.     
  1519.     return (pnum);
  1520. }
  1521.  
  1522. /***************************************************************************/
  1523. /*  Mnetusend
  1524. *   send some data out in a UDP packet
  1525. *   uses the preinitialized data in the port packet ulist.udpout
  1526. *   
  1527. *   returns 0 on okay send, nonzero on error
  1528. */
  1529. void Mnetusend                                    /* BYU 2.4.16 */
  1530.   (
  1531.     unsigned char *machine,
  1532.     unsigned int port,
  1533.     unsigned int retport,
  1534.     unsigned char *buffer,
  1535.     int n
  1536.   )
  1537. {
  1538.     /* find if port is open */
  1539.     if ( UDPfindport( retport)<0)
  1540.         netuopen(retport);
  1541.     
  1542.     /* Send data */
  1543.     netuput((long *) machine, port, retport, (char *) buffer,n);        /* BYU LSC */
  1544. }
  1545.  
  1546. /**************************************************************************/
  1547. int ufindbystream( streamPtr)
  1548. StreamPtr streamPtr;
  1549. {
  1550.     int pnum=0;
  1551.     
  1552.     while (pnum<NPORTS &&
  1553.             ( uport[pnum] ==(UDPRPtr)0L || streamPtr !=uport[pnum]->stream))
  1554.         pnum++;
  1555.     if (pnum >=NPORTS)
  1556.         return(-1);
  1557.     else
  1558.         return(pnum);
  1559. }
  1560.  
  1561. /**************************************************************************/
  1562. pascal void UDPNotify( streamPtr, code, uptr, icmpMsg)
  1563. StreamPtr streamPtr;
  1564. unsigned short code;
  1565. struct ICMPReport *icmpMsg;
  1566. Ptr uptr;   /* user data */
  1567. {
  1568. /*#pragma unused(uptr, icmpMsg)        /* BYU LSC */
  1569.     UDPRPtr p;
  1570.     int pnum;
  1571.     
  1572.     pnum= ufindbystream(streamPtr);
  1573.     
  1574.     if (pnum < 0 || (p = uport[pnum]) == 0L)
  1575.         return;
  1576.     
  1577.     switch( code) {
  1578.         case UDPDataArrival:
  1579.             netputuev(USERCLASS,UDPDATA,p->port);        /* post that it is here */
  1580.         default:
  1581.             break;
  1582.         }
  1583.     return;
  1584. }
  1585.  
  1586. #if 0                                                    /* BYU 2.4.16 */
  1587. void netconfig
  1588.   (
  1589.     char *hardware
  1590.   )
  1591. {
  1592. /*#pragma unused(hardware)        /* BYU LSC */
  1593.     putln("I'm a driver TCP, I don't need hardware.....");
  1594.     initipnum(0);
  1595. }
  1596.  
  1597. void netarpme
  1598.   (
  1599.     char *s
  1600.   )
  1601. {
  1602. /*#pragma unused(s)        /* BYU LSC */
  1603.     putln("Drivers don't need arps, either.");
  1604. }
  1605.  
  1606. netsetgate(s)
  1607. char *s;
  1608. {
  1609. /*#pragma unused(s)        /* BYU LSC */
  1610.     putln("Yeah, right....");
  1611.     return
  1612.         0;
  1613. }
  1614.  
  1615. int netgetrarp
  1616.   (
  1617.     void
  1618.   )
  1619. {
  1620.     putln("RARP handled above me....");
  1621.     return
  1622.         0;
  1623. }
  1624.  
  1625.  
  1626. uint8 *getdlayer()
  1627. {
  1628.     putln("This shouldn't be called...");
  1629.     return(0L);
  1630. }
  1631.  
  1632.  
  1633. tcpsend()
  1634. {
  1635. }
  1636.  
  1637.  
  1638. demux()
  1639. {
  1640.     return(0);
  1641. }
  1642.  
  1643.  
  1644. /*************************************************************************/
  1645. /* neteventinit
  1646. *  load up the pointers for the event queue
  1647. *  makes a circular list to follow, required for error messages
  1648. */
  1649. void neteventinit
  1650.   (
  1651.     void
  1652.   )
  1653.     {
  1654.     int i;
  1655.  
  1656.     for (i=0; i < NEVENTS; i++)
  1657.         nnq[i].next = i+1;
  1658.  
  1659.     nnq[NEVENTS-1].next = -1;
  1660.  
  1661.     nnefirst = 0;
  1662.     nnelast = 0;
  1663.     nnefree = 1;
  1664. }
  1665.  
  1666. getATaddress()
  1667. {
  1668. }
  1669.  
  1670. KIPfindgate()
  1671. {
  1672. }
  1673.  
  1674. KIPgetns()
  1675. {
  1676. }
  1677.  
  1678. KIPgetdynam()
  1679. {
  1680. }
  1681.  
  1682. KIPregister()
  1683. {
  1684. }
  1685. #endif                                                    /* BYU 2.4.16 */