home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tel2305s.zip / ENGINE / PROTINIT.C < prev    next >
C/C++ Source or Header  |  1992-03-03  |  10KB  |  331 lines

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