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