home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / ncsat.cpt / Telnet2.5 final / tcpip / user.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-05  |  20.4 KB  |  849 lines

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