home *** CD-ROM | disk | FTP | other *** search
/ GRIPS 2: Government Rast…rocessing Software & Data / GRIPS_2.cdr / dos / ncsa_tel / contribu / byu_tel2.hqx / tcpip / protinit.c < prev    next >
Text File  |  1989-05-06  |  9KB  |  303 lines

  1. /*
  2. *  Protinit.c
  3. *  initialize the template packets
  4. ****************************************************************************
  5. *                                                                          *
  6. *      part of:                                                            *
  7. *      TCP/UDP/ICMP/IP Network kernel for NCSA Telnet                      *
  8. *      by Tim Krauskopf                                                    *
  9. *                                                                          *
  10. *      National Center for Supercomputing Applications                     *
  11. *      152 Computing Applications Building                                 *
  12. *      605 E. Springfield Ave.                                             *
  13. *      Champaign, IL  61820                                                *
  14. *                                                                          *
  15. *    Copyright (c) 1987, Board of Trustees of the University of Illinois   *
  16. *                                                                          *
  17. ****************************************************************************
  18. *   'protinit' initializes packets to make them ready for transmission.
  19. *   For many purposes, pre-initialized packets are created for use by the
  20. *   protocol routines, especially to save time creating packets for
  21. *   transmit.
  22. *
  23. *   Assumes that 'myaddr' is already set to my Ethernet hardware address
  24. *   and any other similar protocol addresses are already initialized 
  25. *   (known) for the local station.
  26. *
  27. *   As this is a convenient place for it, this file contains many of the
  28. *   data declarations for packets which are mostly static (pre-allocated).
  29. */
  30. #include "stdio.h"
  31. #include "protocol.h"
  32. #include "data.h"
  33.  
  34. /************************************************************************/
  35. /*  main code for protinit()
  36. *   for each new type of protocol, put an initialization call here.
  37. *   There may be some requirement of order of initialization.
  38. */
  39. protinit()
  40.     {
  41.  
  42.     etherinit();
  43.     arpinit();  
  44.     ipinit();
  45.     tcpinit();
  46.     udpinit();
  47.  
  48.     return(0);
  49. }
  50.  
  51. /*************************************************************************/
  52. /*  Ethernet headers, initialize a default header to be used in 
  53. *   subsequent pre-initialized headers.  This does something similar for
  54. *   AppleTalk.
  55. */
  56.  
  57. etherinit()
  58.     {
  59.     movebytes(broadaddr,bseed,DADDLEN);
  60.     movebytes(blankd.dest,broadaddr,DADDLEN);    /* some are broadcast */
  61.     movebytes(blankd.me,nnmyaddr,DADDLEN);        /* always from me */
  62.  
  63.     blankd.type = EIP;                /* mostly IP packets */
  64.  
  65. }
  66.  
  67. /*************************************************************************/
  68. /*  ARP packets
  69. *
  70. *   a very limited type of packet goes out.  We currently only talk IP, so
  71. *   initialize as many fields as possible, most fields are already known.
  72. *
  73. *   Also initialize a reverse-arp packet to be sent out on request. (later)
  74. */
  75.  
  76. arpinit()
  77.     {
  78.     int i;
  79.  
  80.     movebytes(&arp.d,&blankd,sizeof(DLAYER));
  81.  
  82.     arp.d.type = EARP;                /* 0x0806 is ARP type */
  83.  
  84.     arp.hrd = intswap(HTYPE);            /*  Ether = 1 */
  85.     arp.pro = intswap(ARPPRO);            /* IP protocol = 0x0800 */
  86.     arp.hln = DADDLEN;                    /* Ethernet hardware length */
  87.     arp.pln = 4;                        /* IP length = 4 */
  88.     
  89.     movebytes(arp.sha,nnmyaddr,DADDLEN);    /* sender's hardware addr */
  90.     movebytes(arp.tha,broadaddr,DADDLEN);    /* target hardware addr */
  91.  
  92.     movebytes(arp.spa,nnipnum,4);        /* sender's IP addr */
  93.  
  94. /*
  95. *  initialize the ARP cache to 0 time, none are gateways to start
  96. */
  97.     for (i=0; i<CACHELEN; i++) {
  98.         arpc[i].tm = 0L;
  99.         arpc[i].gate = 0;
  100.     }
  101.  
  102. }
  103.  
  104.  
  105. /*************************************************************************/
  106. /*  Internet protocol
  107. *   initialize one packet to use for arbitrary internet transmission.
  108. *   Hopefully, most outgoing IP packets will be pre-initialized by TCP or
  109. *   UDP, but some operations may require a generic IP packet.
  110. */
  111. ipinit()
  112.     {
  113.     movebytes(&blankip.d,&blankd,sizeof(DLAYER));
  114.  
  115.     blankip.i.versionandhdrlen = 0x45;        /* smallest header, version 4 */
  116.     blankip.i.service = 0;                    /* normal service */
  117.  
  118.     blankip.i.tlen = 576;                        /* no data yet, maximum size */
  119.     blankip.i.ident = 0;
  120.     blankip.i.frags = 0;                        /* not a fragment of a packet */
  121.  
  122.     blankip.i.ttl = 100;                        /* 100 seconds should be enough */
  123.     blankip.i.protocol = PROTUDP;                /* default to UDP */
  124.  
  125.     blankip.i.check = 0;                        /* disable checksums for now */
  126.  
  127.     movebytes(blankip.i.ipsource,nnipnum,4);    /* my return address */
  128.     movebytes(blankip.i.ipdest,broadip,4);        /* to ? */
  129.  
  130. #ifdef notneedednow
  131. /*
  132. *  Make a blank ICMP packet for sending ICMP requests or responses
  133. */
  134.     movebytes(&blankicmp,&blankip,sizeof(DLAYER)+sizeof(IPLAYER));
  135.     blankicmp.i.protocol = PROTICMP;        
  136. #endif
  137.  
  138. /*
  139. *  create a mask which can determine whether a machine is on the same wire
  140. *  or not.  RFC950
  141. *  Only set the mask if not previously set.
  142. *  This mask may be replaced by a higher level request to set the subnet mask.
  143. */
  144.  
  145.     if (comparen(nnmask,"\0\0\0\0",4)) {            /* now blank */
  146.  
  147.         if (!(nnipnum[0] & 0x80))                    /* class A */
  148.             netsetmask(nnamask);
  149.         else if ((nnipnum[0] & 0xC0) == 0x80)        /* class B */
  150.             netsetmask(nnbmask);
  151.         else if ((nnipnum[0] & 0xC0) == 0xC0)        /* class C */
  152.             netsetmask(nncmask);
  153.     }
  154.  
  155. }
  156.  
  157. /**************************************************************************/
  158. /*  UDP initialization
  159. *   set up ulist for receive of UDP packets
  160. */
  161. udpinit()
  162.     {
  163.     ulist.stale = 1;
  164.     ulist.length = 0;
  165.  
  166.     movebytes(&ulist.udpout,&blankip,sizeof(DLAYER)+sizeof(IPLAYER));
  167.     ulist.udpout.i.protocol = PROTUDP;                /* UDP type */
  168.     ulist.tcps.z = 0;
  169.     ulist.tcps.proto = PROTUDP;
  170.     movebytes(ulist.tcps.source,nnipnum,4);
  171.     
  172. }
  173.  
  174. /**************************************************************************/
  175. /*  TCP stuff
  176. *     get ready for makeport()
  177. *   makeport() actually does the initialization when you open a port
  178. */
  179. tcpinit()
  180.     {
  181.     int i;
  182.  
  183.     for (i=0; i < NPORTS; i++)
  184.         portlist[i] = NULL;            /* no ports open yet */
  185. }
  186.  
  187.  
  188. /**************************************************************************/
  189. /*  makeport
  190. *
  191. *   This is the intialization for TCP based communication.  When a port
  192. *   needs to be created, this routine is called to do as much pre-initialization
  193. *   as possible to save overhead during operation.
  194. *
  195. *   This structure is created upon open of a port, either listening or 
  196. *   wanting to send.
  197. *
  198. *   A TCP port, in this implementation, includes all of the state data for the
  199. *   port connection, a complete packet for the TCP transmission, and two
  200. *   queues, one each for sending and receiving.  The data associated with
  201. *   the queues is in struct window.
  202. */
  203. makeport()
  204.     {
  205.     int i,j,retval;
  206.  
  207.     struct port *p,*q;
  208.  
  209. /*
  210. *  Check to see if any other connection is done with its port buffer space.
  211. *  Indicated by the connection state of SCLOSED
  212. */
  213.     p = NULL;
  214.     i = 0;
  215.     do {
  216.         q = portlist[i];
  217.         if (q != NULL && (q->state == SCLOSED ||
  218.         (q->state == STWAIT && q->out.lasttime + WAITTIME < time(NULL)))) 
  219.             p = q;
  220.         retval = i++;                    /* port # to return */
  221.     } while (p == NULL && i < NPORTS);
  222.  
  223. /*  
  224. * None available pre-allocated, get a new one, about 8.5 K with a 4K windowsize
  225. */
  226.     if (p == NULL) {
  227.         p = (struct port *)malloc(sizeof(struct port));
  228.  
  229.         for (i=0; portlist[i] != NULL; i++)
  230.             if (i >= NPORTS) {
  231.                 nnerror(500);
  232.                 return(-1);                /* out of room for ports */
  233.             }
  234.         portlist[i] = p;
  235.         retval = i;
  236.     }
  237.  
  238.     if (p == NULL) {
  239.         nnerror(505);
  240.         return(-1);
  241.     }
  242.  
  243.     movebytes(&p->tcpout,&blankip,sizeof(DLAYER)+sizeof(IPLAYER));
  244.                                             /* static initialization */
  245.  
  246.     p->tcpout.i.tlen = 0;
  247.     p->tcpout.t.urgent = 0;                    /* no urgent data */
  248.     p->tcpout.t.hlen = 20 << 2;                /* header length << 2 */
  249.     p->tcps.z = 0;
  250.     p->tcps.proto = PROTTCP;
  251.     movebytes(p->tcps.source,nnipnum,4);
  252.  
  253.     setupwindow(&p->in,WINDOWSIZE);        /* queuing parameters */
  254.     setupwindow(&p->out,WINDOWSIZE);
  255.  
  256.     do {
  257.  
  258.         i = time(NULL);
  259.         i |= 2048;              /* make sure it is at least this large */
  260.         i &= 0x3fff;            /* at least this small */
  261.  
  262.         for (j=0; j<NPORTS && i != portlist[j]->in.port ; j++)
  263.             ;
  264.  
  265.     } while (j < NPORTS);
  266.  
  267.     if ( nnfromport ) {            /* allow the from port to be forced */
  268.         i = nnfromport;
  269.         nnfromport = 0;
  270.     }
  271.  
  272.     p->in.port = i;
  273.  
  274.     p->tcpout.t.source = intswap(i);
  275.     p->tcpout.t.seq = longswap(p->out.nxt);
  276.     
  277.     p->state = SCLOSED;
  278.     p->credit = nncredit;
  279.     p->sendsize = TSENDSIZE;
  280.     p->rto = MINRTO;
  281.  
  282.     return(retval);
  283. }
  284.  
  285. setupwindow(w,wsize)
  286.     struct window *w;
  287.     unsigned int wsize;
  288.     {
  289.     w->endbuf = w->where + wsize;
  290.     w->base = w->endlim = w->where;
  291.     w->contain = 0;                        /* nothing here yet */
  292.     w->lasttime = time(NULL);
  293.     w->size = wsize;
  294.     w->push = 0;
  295.  
  296. /*
  297. *  base this on time of day clock, for uniqueness
  298. */
  299.     w->ack = w->nxt = ((w->lasttime << 12) & 0x0fffffff);
  300.  
  301. }
  302.  
  303.