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