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 / NCSA Driver / user.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-06  |  20.4 KB  |  846 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. *
  24. */
  25. #define MASTERDEF 1
  26.  
  27. #include <stdio.h>
  28. #include <string.h>
  29.  
  30. #include <Events.h>
  31.  
  32. #include "protocol.h"
  33. #include "data.h"
  34. #include "dlayer.h"
  35. #include "mactools.h"
  36. #include "protinit.h"
  37. #include "tcp.h"
  38. #include "tools.h"
  39.  
  40. extern int                     /* BYU 2.4.16 */
  41.     EtherNet;                /* BYU 2.4.16 - Signify Drivers */
  42.  
  43. extern int net_okay;            /* BYU serial */
  44.  
  45. extern short slip_connection;    /* BYU 2.4.15 */
  46.  
  47. #define LOWWATER 600
  48.  
  49. #define UNKNOWN_PORT_TYPE    0        /* BYU 2.4.16 */
  50. #define MACTCP_PORT_TYPE    1        /* BYU 2.4.16 */
  51. #define NCSA_PORT_TYPE        2        /* BYU 2.4.16 */
  52.  
  53. short porttype[NPORTS];                /* BYU 2.4.16 - 1 = MacTCP or 2 = NCSA */
  54.  
  55. /***************************************************************************/
  56. int netporttype(int pnum) {                        /* BYU 2.4.16 */
  57.     if (porttype[pnum] == NCSA_PORT_TYPE)        /* BYU 2.4.16 */
  58.         return(portlist[pnum]->type);            /* BYU 2.4.16 */
  59.     else                                        /* BYU 2.4.16 */
  60.         return(NOT_FROM_SLIP);                    /* BYU 2.4.16 */
  61. }                                                /* BYU 2.4.16 */
  62.  
  63. /***************************************************************************/
  64. /*  netread
  65. *   Read from a connection buffer into a user buffer.  
  66. *   Returns number of bytes read, < 0 on error
  67. */
  68. int netread
  69.   (
  70.     int pnum,
  71.     char *buffer,            /* BYU LSC - was "void" */
  72.     int n
  73.   )
  74. /*    int pnum,n;                /* BYU LSC */
  75. /*    char *buffer;            /* BYU LSC */
  76.     {
  77.     int howmany,i;
  78.     struct port *p;
  79.  
  80.     if (pnum < 0 || pnum >= NPORTS)
  81.         return(-2);
  82.  
  83.     if (porttype[pnum] == MACTCP_PORT_TYPE)        /* BYU 2.4.16 */
  84.         return(Mnetread(pnum,buffer,n));        /* BYU 2.4.16 */
  85.         
  86.     if (NULL == (p = portlist[pnum]))
  87.         return(-2);
  88.  
  89.     if (p->state != SEST) {                 /* foreign or netclose */
  90.         if (p->state == SCWAIT) {            /* ready for me to close my side? */
  91.             if (!p->in.contain) {
  92.                 p->tcpout.t.flags = TFIN | TACK;
  93.                 tcpsend(p,0);
  94.                 p->state = SLAST;
  95.                 return(-1);
  96.             }
  97.             /* else, still data to be read */
  98.         }
  99.         else
  100.             return(-1);
  101.     }
  102.  
  103.     howmany = dequeue(&p->in,buffer,n);            /* read from tcp buffer */
  104.  
  105.     i = p->in.size;                                /* how much before? */
  106.  
  107.     p->in.size += howmany;                        /* increment leftover room  */
  108.  
  109.     if (i < LOWWATER && p->in.size >= LOWWATER) /* we passed mark */
  110.         p->out.lasttime = 0L;
  111.  
  112.     if (p->in.contain)                            /* if still data to be read */
  113.         netputuev(CONCLASS,CONDATA,pnum);        /* don't forget it */
  114.  
  115.     return(howmany);
  116.  
  117. } /* netread */
  118.  
  119. /************************************************************************/
  120. /* netwrite
  121. *  write something into the output queue, netsleep routine will come
  122. *  around and send the data, etc.
  123. *
  124. */
  125. int netwrite
  126.   (
  127.     int pnum,
  128.     void *buffer,
  129.     int n
  130.   )
  131.     {
  132.     int nsent,before;
  133.     struct port *p;
  134.  
  135.     if (pnum < 0 || pnum >= NPORTS)
  136.         return(-2);
  137.  
  138.     if (porttype[pnum] == MACTCP_PORT_TYPE)        /* BYU 2.4.16 */
  139.         return(Mnetwrite(pnum,buffer,n));        /* BYU 2.4.16 */
  140.  
  141.     p = portlist[pnum];
  142.  
  143.     if (p == NULL)
  144.         return(-2);
  145.  
  146.     if ((p->type == 1) && (!slip_connection)) {        /* BYU 2.4.15 */
  147.         write_serial(buffer,n);                        /* BYU 2.4.15 */
  148.         return(n);                                    /* BYU 2.4.15 */
  149.     }                                                /* BYU 2.4.15 */
  150.  
  151.     if (p->state != SEST)            /* must be established connection */
  152.         return(-1);
  153.  
  154.     before = p->out.contain;
  155.  
  156.     nsent = enqueue(&p->out,buffer,n);
  157.  
  158.     if (!before)                    /* if this is something new, */
  159.         p->out.lasttime = 0L;        /* cause timeout to be true */
  160.  
  161.     return(nsent);
  162.  
  163. } /* netwrite */
  164.  
  165. /**************************************************************************/
  166. /*  netpush
  167. *   attempt to push the rest of the data from the queue
  168. *   and then return whether the queue is empty or not (0 = empty)
  169. *   returns the number of bytes in the queue.
  170. */
  171. int netpush
  172.   (
  173.     int pnum
  174.   )
  175.     {
  176.     struct port *p;
  177.  
  178.     if (pnum < 0 || pnum >= NPORTS)
  179.         return(-2);
  180.  
  181.     if (porttype[pnum] == MACTCP_PORT_TYPE)        /* BYU 2.4.16 */
  182.         return(Mnetpush(pnum));                    /* BYU 2.4.16 */
  183.  
  184.     if (NULL == (p = portlist[pnum]))
  185.         return(-2);
  186.  
  187.     p->out.push = 1;
  188.  
  189.     return(p->out.contain);
  190.  
  191. } /* netpush */
  192.  
  193. /**************************************************************************/
  194. /*  netqlen
  195. *   return the number of bytes waiting to be read from the incoming queue.
  196. */
  197. netqlen(pnum)
  198.     int pnum;
  199.     {
  200.     
  201.     if (pnum < 0 || pnum >= NPORTS)                /* BYU serial */
  202.         return(-2);                                /* BYU serial */
  203.  
  204.     if (porttype[pnum] == MACTCP_PORT_TYPE)        /* BYU 2.4.16 */
  205.         return(Mnetqlen(pnum));                    /* BYU 2.4.16 */
  206.  
  207.     if (portlist[pnum] == NULL)
  208.         return(-2);
  209.  
  210.     return(portlist[pnum]->in.contain);
  211.  
  212. }
  213.  
  214. /**************************************************************************/
  215. /*  netroom()
  216. *    return how much room is available in output buffer for a connection
  217. */
  218. int netroom
  219.   (
  220.     int pnum
  221.   )
  222.     {
  223.     
  224.     if (pnum < 0 || pnum >= NPORTS)        /* BYU serial */
  225.         return(-2);                        /* BYU serial */
  226.  
  227.     if (porttype[pnum] == MACTCP_PORT_TYPE)        /* BYU 2.4.16 */
  228.         return(Mnetroom(pnum));                    /* BYU 2.4.16 */
  229.  
  230.     if (portlist[pnum] == NULL || portlist[pnum]->state != SEST)
  231.         return(-2);
  232.  
  233.     return(WINDOWSIZE - portlist[pnum]->out.contain);
  234.  
  235. }
  236.  
  237. /**************************************************************************/
  238. /* netsegsize and neterrchange and netsetip and netgetip
  239. *
  240. *  set operating parameters to change them from the default values used.
  241. */
  242.  
  243. netsegsize(newsize)
  244.     int newsize;
  245.     {
  246.     int i;
  247.  
  248.     i = nnsegsize;
  249.     nnsegsize = newsize;
  250.  
  251.     return(i);
  252. }
  253.  
  254. netquench(newcredit)
  255.     int newcredit;
  256.     {
  257.     int i;
  258.  
  259.     i = nncredit;
  260.     nncredit = newcredit;
  261.  
  262.     return(i);
  263. }
  264.  
  265. void netarptime                    /* dlayer timeout in secs */ 
  266.   (
  267.     int t
  268.   )
  269.     {
  270.     nndto = t;
  271. }
  272.  
  273. void netsetip
  274.   (
  275.     unsigned char *st
  276.   )
  277.     {
  278. /*
  279. *  change all dependent locations relating to the IP number
  280. *  don't worry about open connections, they must be closed by higher layer
  281. */
  282.     movebytes(nnipnum,st,4);
  283.  
  284. /*    movebytes(arp.d.me,nnipnum,4);    this is a bug - not needed */
  285.  
  286.     movebytes(arp.spa,nnipnum,4);
  287.     movebytes(blankip.i.ipsource,nnipnum,4);
  288.     movebytes(ulist.tcps.source,nnipnum,4);
  289.     movebytes(ulist.udpout.i.ipsource,nnipnum,4);
  290.  
  291. }
  292.  
  293. void netgetip
  294.   (
  295.     unsigned char *st
  296.   )
  297.   {
  298.     if (EtherNet == -99)            /* BYU 2.4.16 */
  299.         Mnetgetip(st);                /* BYU 2.4.16 */
  300.     else                            /* BYU 2.4.16 */
  301.         movebytes(st,nnipnum,4);    /* BYU 2.4.16 */
  302.   }
  303.  
  304. void netsetmask
  305.   (
  306.     unsigned char *st
  307.   )
  308.   {
  309.     movebytes(nnmask,st,4);
  310.   }
  311.  
  312. void netgetmask
  313.   (
  314.     unsigned char *st
  315.   )
  316.     {
  317.     movebytes(st,nnmask,4);
  318. }
  319.  
  320. void netfromport            /* next "open" will use this port */
  321.   (
  322.     int16 port
  323.   )
  324.     {
  325.     nnfromport = port;
  326.  
  327. }
  328.  
  329. /**************************************************************************/
  330. /*  netest?
  331. *  is a particular session established yet?
  332. *  Returns 0 if the connection is in the established state.
  333. */
  334. int netest
  335.   (
  336.     int pn
  337.   )
  338.     {
  339.     struct port *p;
  340.  
  341.     if (pn < 0 || pn >= NPORTS)
  342.         return(-2);
  343.  
  344.     if (porttype[pn] == MACTCP_PORT_TYPE)        /* BYU 2.4.16 */
  345.         return(Mnetest(pn));                    /* BYU 2.4.16 */
  346.  
  347.     if (NULL == (p = portlist[pn]))
  348.         return(-2);
  349.  
  350.     if (p->state == SEST)
  351.         return(0);
  352.  
  353.     else if (p->state == SCWAIT) {
  354.             if (!p->in.contain) {
  355.                 p->tcpout.t.flags = TFIN | TACK;
  356.                 tcpsend(p,0);
  357.                 p->state = SLAST;
  358.                 return(-1);
  359.             }
  360.             else 
  361.                 return(0);                /* still more data to be read */
  362.     }
  363.  
  364.     return(-1);
  365.  
  366. } /* netest */
  367.  
  368. /**************************************************************************/
  369. /*  netlisten
  370. *   Listen to a TCP port number and make the connection automatically when
  371. *   the SYN packet comes in.  The TCP layer will notify the higher layers
  372. *   with a CONOPEN event.  Save the port number returned to refer to this
  373. *   connection.
  374. *
  375. *   usage:   portnum = netlisten(service);
  376. *            int service;
  377. *
  378. */
  379. int netlisten
  380.   (
  381.     uint serv,                            /* BYU 2.4.15 */
  382.     short connectiontype                /* BYU 2.4.15 */
  383.   )
  384.     {
  385.     int    pnum;
  386.     struct port *prt;
  387.     uint16 nn;
  388.  
  389.     if (!net_okay)                         /* BYU serial */
  390.         return(-2);                        /* BYU serial */
  391.  
  392.     if (EtherNet == -99 && connectiontype == 0) {            /* BYU 2.4.16 */
  393.         pnum = Mnetlisten(serv);                            /* BYU 2.4.16 */
  394.         if (pnum >= 0)                                        /* BYU 2.4.16 */
  395.             porttype[pnum] = MACTCP_PORT_TYPE;                /* BYU 2.4.16 */
  396.         return(pnum);                                        /* BYU 2.4.16 */
  397.     }                                                        /* BYU 2.4.16 */
  398.  
  399.     pnum = makeport(connectiontype);    /* BYU 2.4.15 */
  400.  
  401.     if (pnum < 0 || pnum >= NPORTS)        /* BYU serial */
  402.         return(-2);
  403.  
  404.     if (NULL == (prt = portlist[pnum]))
  405.         return(-2);
  406.  
  407.     if (EtherNet == -99) {                        /* BYU 2.4.16 */
  408.         porttype[pnum] = NCSA_PORT_TYPE;        /* BYU 2.4.16 */
  409.         prt->type = 1;                            /* BYU 2.4.16 */
  410.     } else {                                    /* BYU 2.4.16 */
  411.         porttype[pnum] = UNKNOWN_PORT_TYPE;        /* BYU 2.4.16 */
  412.         prt->type = 0;                            /* BYU 2.4.16 */
  413.     }                                            /* BYU 2.4.16 */
  414.  
  415.     prt->in.port = serv;
  416.     prt->out.port = 0;                        /* accept any outside port #*/
  417.     prt->in.lasttime = time(NULL);            /* set time we started */
  418.  
  419.     prt->state = SLISTEN;
  420.     prt->credit = 512;                        /* default value until changed */
  421.     prt->tcpout.i.protocol = PROTTCP;
  422.     prt->tcpout.t.source = intswap(serv);    /* set service here too */
  423.  
  424. /*
  425. *  install maximum segment size which will be sent out in the first
  426. *  ACK-SYN packet
  427. */
  428.     prt->tcpout.x.options[0] = 2;
  429.     prt->tcpout.x.options[1] = 4;
  430.     /* install maximum segment size */
  431.     nn = intswap(nnsegsize);
  432.     memmove(&prt->tcpout.x.options[2],&nn,2);    /* BYU LSC */
  433.  
  434.     return(pnum);
  435. } /* netlisten */
  436.  
  437. /***********************************************************************/
  438. /*  netgetftp
  439. *  Provides the information that ftp needs to open a stream back to the
  440. *  originator of the command connection.  The other side's IP number
  441. *  and the port numbers to be used to calculate the default data connection
  442. *  number.  Returns values in an integer array for convenient use in 
  443. *  PORT commands.
  444. */
  445. void netgetftp
  446.   (
  447.     int a[],
  448.     int pnum
  449.   )
  450.     {
  451.     struct port *p;
  452.     uint i;
  453.  
  454.     if (porttype[pnum] == MACTCP_PORT_TYPE) {    /* BYU 2.4.16 */
  455.         Mnetgetftp(a,pnum);                        /* BYU 2.4.16 */
  456.         return;                                    /* BYU 2.4.16 */
  457.     }                                            /* BYU 2.4.16 */
  458.  
  459.     p = portlist[pnum];
  460.  
  461.     a[0] = p->tcpout.i.ipdest[0];
  462.     a[1] = p->tcpout.i.ipdest[1];
  463.     a[2] = p->tcpout.i.ipdest[2];
  464.     a[3] = p->tcpout.i.ipdest[3];
  465.     i = intswap(p->tcpout.t.source);
  466.     a[4] = i >> 8;
  467.     a[5] = i & 255;
  468.     i = intswap(p->tcpout.t.dest);
  469.     a[6] = i >> 8;
  470.     a[7] = i & 255;
  471.  
  472. } /* netgetftp */
  473.  
  474. /**************************************************************************/
  475. /* netclose
  476. *  Do appropriate actions to return connection state to SCLOSED which
  477. *  enables the memory for that port to be reused.
  478. */
  479. int netclose
  480.   (
  481.     int pnum
  482.   )
  483.     {
  484.     struct port *p;
  485.  
  486.     if (pnum < 0 || pnum >= NPORTS)                /* BYU 2.4.16 - is a valid port? */
  487.         return(-1);
  488.  
  489.     if (porttype[pnum] == MACTCP_PORT_TYPE)        /* BYU 2.4.16 */
  490.         return(Mnetclose(pnum));                /* BYU 2.4.16 */
  491.  
  492. #if 1                                            /* BYU 2.4.15 */
  493.     p = portlist[pnum];                            /* BYU 2.4.15 */
  494.     if ((p->type == 1) && (!slip_connection)) {    /* BYU 2.4.15 */
  495.         close_serial();                            /* BYU 2.4.15 */
  496.         return(0);                                /* BYU 2.4.15 */
  497.     } else if ((p = portlist[pnum]) != NULL) {    /* BYU 2.4.15 - something there */
  498. #else                                            /* BYU 2.4.15 */
  499.     if ((p = portlist[pnum]) != NULL) {            /* something there */
  500. #endif                                            /* BYU 2.4.15 */
  501.         switch (p->state) {
  502.             case SLISTEN:                /* we don't care anymore */
  503.             case SSYNS:
  504.                 p->state = SCLOSED;
  505.                 break;
  506.             case SEST:                    /* must initiate close */
  507.                 /* send FIN */
  508.                 p->tcpout.t.flags = TACK | TFIN;
  509.                 tcpsend(p,0);
  510.                 p->state = SFW1;            /* wait for ACK of FIN */
  511.                 break;                        /* do nothing for now ?*/
  512.  
  513.             case SCWAIT:                    /* other side already closed */
  514.                 p->tcpout.t.flags = TFIN | TACK;
  515.                 tcpsend(p,0);
  516.                 p->state = SLAST;
  517.                 break;
  518.  
  519.             case STWAIT:                    /* time out yet? */
  520.                 if (portlist[pnum]->out.lasttime + WAITTIME < time(NULL)) 
  521.                     p->state = SCLOSED;
  522.                 break;
  523.  
  524.             case SLAST:                    /* five minute time out */
  525.                 if (portlist[pnum]->out.lasttime + LASTTIME < time(NULL)) 
  526.                     p->state = SCLOSED;
  527.                 break;
  528.             default:
  529.                 break;
  530.         }
  531.     }
  532.     else
  533.         return(1);
  534.     return(0);
  535. } /* netclose */
  536.  
  537. /**********************************************************************/
  538.  
  539. int doconnect
  540.   (
  541.     int pnum,
  542.     int service,
  543.     int mseg
  544.   )
  545.     {
  546.     uint16 seg;
  547.     struct port *p;
  548.  
  549.     p = portlist[pnum];
  550.  
  551.     p->tcpout.i.protocol = PROTTCP;                /* this will be TCP socket */
  552.     p->tcpout.t.dest = intswap(service);        /* for example, telnet=23 */
  553.     p->out.port = service;                        /* service is same as port num*/
  554.     p->tcpout.t.flags = TSYN;                    /* want to start up sequence */
  555.     p->tcpout.t.ack = 0;                        /* beginning has no ACK */
  556.  
  557.     p->state = SSYNS;                            /* syn sent */
  558. /*
  559. *  install maximum segment size which will be sent out in the first
  560. *  ACK-SYN packet
  561. */
  562.     p->tcpout.x.options[0] = 2;
  563.     p->tcpout.x.options[1] = 4;
  564.     /* install maximum segment size */
  565.     seg = intswap(mseg);
  566.     memmove(&p->tcpout.x.options[2],&seg,2);    /* BYU LSC */
  567.  
  568.     p->tcpout.t.hlen=96;                    /* include one more word in hdr */
  569.     tcpsend(p,4);                            /* send opening volley */
  570.     p->tcpout.t.hlen=80;                    /* normal hdr len */
  571.  
  572. /*    savenxt = p->out.nxt; */
  573.     p->out.nxt += 1;                        /* ack should be for next byte */
  574.  
  575.     return(pnum);                            /* do not wait for connect */
  576. } /* doconnect */
  577.  
  578. /**************************************************************************/
  579. /*  netxopen
  580. *   Open a network socket for the user.
  581. *
  582. */
  583. int netxopen
  584.   (
  585.     uint8 *machine,
  586.     uint service,
  587.     uint rto,
  588.     uint mtu,
  589.     uint mseg,
  590.     uint mwin,                /* BYU 2.4.15 */
  591.     short connectionType    /* BYU 2.4.15 */
  592.   )
  593.     {
  594.     struct port *p;
  595.     int pnum,ret,i;
  596.     uint8 *pc,*hiset;
  597.  
  598.     if (EtherNet == -99 && connectionType == 0) {                    /* BYU 2.4.16 */
  599.         pnum = Mnetxopen(machine,service,rto,mtu,mseg,mwin);        /* BYU 2.4.16 */
  600.         if (pnum >= 0)                                                /* BYU 2.4.16 */
  601.             porttype[pnum] = MACTCP_PORT_TYPE;                        /* BYU 2.4.16 */
  602.         return(pnum);                                                /* BYU 2.4.16 */
  603.     }                                                                /* BYU 2.4.16 */
  604.  
  605. /*
  606. *  check the IP number and don't allow broadcast addresses.
  607. *
  608. *  If the AND of the original and the mask does not change the value then
  609. *  the host portion is all zeros.
  610. *  If the OR of the original and the inverse mask does not change the value
  611. *  then the host portion is all ones.
  612. */
  613.     ret = 0;                        /* assume all are the same */
  614.     for (i=0; i<4; i++)
  615.         if (machine[i] != (machine[i] & nnmask[i]))
  616.             ret = 1;
  617.  
  618.     if (!ret) {                        /* if all are the same, reject broadcast addr */
  619.         nnerror(506);
  620.         return(-4);
  621.     }
  622.     
  623.     ret = 0;
  624.     for (i=0; i<4; i++) 
  625.         if (machine[i] != (uint8)(machine[i] | (~nnmask[i])))
  626.             ret = 1;
  627.         
  628.     if (!ret) {                        /* if all are the same, reject broadcast addr */
  629.         nnerror(506);
  630.         return(-4);
  631.     }
  632.  
  633.     netsleep(0);                    /* make sure no waiting packets */
  634.     pnum = makeport(connectionType);/* BYU 2.4.15 */
  635.  
  636.     if (pnum < 0)
  637.         return(-3);
  638.  
  639.     porttype[pnum] = NCSA_PORT_TYPE;    /* BYU 2.4.16 */
  640.  
  641.     p = portlist[pnum];                /* create a new port */
  642. /*
  643. *  make a copy of the ip number that we are trying for
  644. */
  645.     movebytes(p->tcpout.i.ipdest,machine,4);
  646.     movebytes(p->tcps.dest,machine,4);        /* pseudo header needs it */
  647.  
  648. /*
  649. *  get the hardware address for that host, or use the one for the gateway
  650. *  all handled by 'netdlayer' by ARPs.
  651. */
  652.     if (!connectionType) {                        /* BYU 2.4.15 */
  653.         pc = netdlayer(machine);                /* we have ether? */
  654.  
  655.         if (pc == NULL) {                        /* cannot connect to local machine */
  656.             nnerror(504);
  657.             return(-2);
  658.         }
  659.  
  660.         movebytes(p->tcpout.d.dest,pc,DADDLEN);        /* load it up */
  661.     }                                                /* BYU 2.4.15 */
  662.  
  663. /*
  664. *   Add in machine specific settings for performance tuning
  665. */
  666.     if (rto > MINRTO)
  667.         p->rto = rto;            /* starting retrans timeout */
  668.     if (mtu < TMAXSIZE)            /* largest packet space we have */
  669.         p->sendsize = mtu;        /* maximum transmit size for that computer */
  670.     if (mwin < WINDOWSIZE)        /* buffer size is the limit */
  671.         p->credit = mwin;        /* most data that we can receive at once */
  672.  
  673. /* Connection type:  0 is non-serial, 1 is serial or SLIP */        /* BYU 2.4.15 */
  674.     p->mseg = mseg;                                                    /* BYU 2.4.15 */
  675.     p->service = service;                                            /* BYU 2.4.15 */
  676.     p->type = connectionType;                                        /* BYU 2.4.15 */
  677.     if ((connectionType == 1) && !slip_connection) {                /* BYU 2.4.15 */
  678.         p->state = SEST;                                                /* BYU 2.4.15 */
  679.         pnum = open_serial(pnum);                                    /* BYU 2.4.15 */
  680.         return(pnum);                                                /* BYU 2.4.15 */
  681.     }                                                                /* BYU 2.4.15 */
  682.  
  683. #ifdef MAC
  684.     if (nnemac) {
  685. #endif
  686. /*
  687. *   quick check to see if someone else is using your IP number
  688. *   Some boards receive their own broadcasts and cannot use this check.
  689. *   The Mac will only use this check if it is using EtherTalk.
  690. */
  691.         i = cachelook(nnipnum,0,0);                /* don't bother to ARP */
  692.         if (i >= 0)    {                /* if it is not -1, we are in trouble */
  693.             hiset = (uint8 *)arpc[i].hrd;
  694.             pc = (uint8 *) neterrstring(-1);    /* BYU LSC */
  695.             sprintf((char *) pc,"Conflict with Ethernet hardware address: %2x:%2x:%2x:%2x:%2x:%2x",    /* BYU LSC */
  696.             hiset[0],hiset[1],hiset[2],hiset[3],hiset[4],hiset[5]);
  697.             nnerror(-1);
  698.             nnerror(102);
  699.             netclose(pnum);
  700.             return(-3);
  701.         }
  702. #ifdef MAC
  703.     }
  704. #endif
  705.  
  706. /*
  707. *  make the connection, if you can, we will get an event notification later
  708. *  if it connects.  Timeouts must be done at a higher layer.
  709. */
  710.     ret = doconnect(pnum,service,mseg);
  711.  
  712.     return(ret);
  713. } /* netxopen */
  714.  
  715. #if 0                    /* BYU 2.4.15 - not used */
  716. /**************************************************************************/
  717. /*  netopen
  718. *   Netopen is a cheap way to open a connection without looking up any
  719. *   machine information.  Uses suitable default values for everything.
  720. */
  721. netopen(s,tport)
  722.     unsigned char *s;
  723.     uint tport;
  724.     {
  725.  
  726.     return(netxopen(s,tport,MINRTO,TSENDSIZE,DEFSEG,DEFWINDOW));
  727. }
  728. #endif                    /* BYU 2.4.15 */
  729.  
  730. /*************************************************************************/
  731. /*  netopen2
  732. *   Send out repeat SYN on a connection which is not open yet
  733. *   Checks, and only sends one if needed.
  734. *   Returns 1 if the state is still SYNS and 0 if the connection has proceeded.
  735. *   The timing is all handled at a higher layer.
  736. */
  737. int netopen2
  738.   (
  739.     int pnum
  740.   )
  741.     {
  742.     struct port *p;
  743.  
  744.     if (pnum < 0 || pnum >= NPORTS)                /* BYU 2.4.16 */
  745.         return(-1);
  746.  
  747.     if (porttype[pnum] == MACTCP_PORT_TYPE)        /* BYU 2.4.16 */
  748.         return(Mnetopen2(pnum));                /* BYU 2.4.16 */
  749.  
  750.     if (NULL == (p = portlist[pnum]))
  751.         return(-2);
  752.  
  753.     if (p->state != SSYNS)
  754.             return(0);                /* done our job */
  755. /*
  756. *  The connection has not proceeded to further states, try retransmission
  757. */
  758.  
  759.     p->out.nxt--;
  760.     p->tcpout.t.hlen=96;        /* include one more word in hdr */
  761.     tcpsend(p,4);                /* try sending again */
  762.     p->tcpout.t.hlen=80;            /* normal hdr len */
  763.     p->out.nxt++;
  764.  
  765.     return(1);
  766. } /* netopen2 */
  767.  
  768. /**************************************************************************/
  769. /*  netinit
  770. *   Calls all of the various initialization routines that set up queueing
  771. *   variables, static values, reads configuration files, etc.
  772. */
  773.  
  774. int netinit
  775.   (
  776.     void
  777.   )
  778.     {
  779.     int ret;
  780.  
  781.     if (EtherNet == -99)         /* BYU 2.4.16 */
  782.         Mnetinit();                /* BYU 2.4.16 - initialization for MacTCP */
  783.  
  784. /*
  785. *   Initializes all buffers and hardware for data link layer.
  786. *   Machine/board dependent.
  787. */
  788.     ret = dlayerinit();
  789.  
  790.     if (ret) {
  791.         nnerror(101);
  792.         return(ret);
  793.     }
  794. /*
  795. *  initialize the template packets needed for transmission
  796. */
  797.     ret = protinit();
  798.  
  799.     return(ret);                /* set up empty packets */
  800. } /* netinit */
  801.  
  802. /*************************************************************************/
  803. /*  netshut
  804. *   Close all the connections and turn off the hardware.
  805. */
  806. void netshut
  807.   (
  808.     void
  809.   )
  810.   {
  811.     int i;
  812.  
  813.     if (EtherNet == -99)                /* BYU 2.4.16 */
  814.         Mnetshut();                        /* BYU 2.4.16 - for MacTCP */
  815.  
  816.     for (i=0; i < NPORTS ; i++) 
  817.         if (portlist[i] != NULL)
  818.             netclose(i);
  819.  
  820.     netsleep(1);
  821.  
  822.     dlayershut();
  823.   }
  824.  
  825. /*************************************************************************/
  826. /* neteventinit
  827. *  load up the pointers for the event queue
  828. *  makes a circular list to follow, required for error messages
  829. */
  830. void neteventinit
  831.   (
  832.     void
  833.   )
  834.     {
  835.     int i;
  836.  
  837.     for (i=0; i < NEVENTS; i++)
  838.         nnq[i].next = i+1;
  839.  
  840.     nnq[NEVENTS-1].next = -1;
  841.  
  842.     nnefirst = 0;
  843.     nnelast = 0;
  844.     nnefree = 1;
  845. } /* neteventinit */
  846.