home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / NETWORK / TEL23SRC.ZIP / NET / ENET / NET.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-21  |  14.8 KB  |  543 lines

  1. /*
  2. *  net.c
  3. *****************************************************************************
  4. *                                                                              *
  5. *      part of:                                                                *
  6. *      TCP/UDP/ICMP/IP Network kernel for NCSA Telnet                        *
  7. *      by Tim Krauskopf                                                        *
  8. *                                                                              *
  9. *      National Center for Supercomputing Applications                         *
  10. *      152 Computing Applications Building                                     *
  11. *      605 E. Springfield Ave.                                                 *
  12. *      Champaign, IL  61820                                                    *
  13. *                                                                              *
  14. *****************************************************************************
  15. *
  16. *  those generic tool-type things that only work on PCs.
  17. *  includes all hardware-level calls to Ethernet that are unique to the PC
  18. *
  19. *  Function pointers for Ether calls
  20. */
  21.  
  22. /*#define DEBUG*/
  23.  
  24. #ifdef NETD
  25. # include <conio.h>
  26. #else
  27. #ifdef DEBUG
  28. # include <conio.h>
  29. #endif
  30. #endif
  31. #include "debug.h"
  32. #include <stdio.h>
  33. #include <string.h>
  34. #ifdef MEMORY_DEBUG
  35. #include "memdebug.h"
  36. #endif
  37. #include "protocol.h"
  38. #include "data.h"
  39. #include "hostform.h"
  40. #include "externs.h"
  41.  
  42. int SQwait=0;
  43. int OKpackets=0;
  44.  
  45. /*
  46. *   defined in assembly language file for interrupt driven Ether buffering
  47. *
  48. */
  49.  
  50. extern unsigned char rstat;        /* last status from read */
  51. extern char *bufpt,                /* current buffer pointer */
  52.     *bufend,                    /* pointer to end of buffer */
  53.     *bufread,                    /* pointer to where program is reading */
  54.     *buforg;                    /* pointer to beginning of buffer */
  55.  
  56. extern int bufbig,                /* number of bytes currently in buffer */
  57.     buflim;                        /* max number of bytes in buffer */
  58.  
  59. struct config def;
  60.  
  61. /*
  62. *  Declare each and every Ethernet driver.
  63. *  To add a driver, pick a unique 2 char prefix and declare your own
  64. *  routines.  I want to keep the same parameters for EVERY driver.
  65. *  If your driver needs additional parameters, then see netconfig() below 
  66. *  for an indication of where to put custom board code.
  67. */
  68. extern int E1etopen(),E1getaddr(),E1setaddr(),E1recv(),E1xmit(),E1etupdate(),E1etclose();
  69. extern int E3etopen(),E3getaddr(),E3setaddr(),E3recv(),E3xmit(),E3etupdate(),E3etclose();
  70. extern int E5etopen(),E5getaddr(),E5setaddr(),E5recv(),E5xmit(),E5etupdate(),E5etclose(),E5etdma();
  71. extern int ATetopen(),ATgetaddr(),ATrecv(),ATxmit(),ATetupdate(),ATetclose();
  72. extern int M5etopen(),M5getaddr(),M5recv(),M5xmit(),M5etupdate(),M5etclose();
  73. extern int M9etopen(),M9getaddr(),M9recv(),M9xmit(),M9etupdate(),M9etclose();
  74. extern int U1etopen(),U1getaddr(),U1recv(),U1xmit(),U1etupdate(),U1etclose();
  75. extern int U2etopen(),U2getaddr(),U2recv(),U2xmit(),U2etupdate(),U2etclose();
  76. extern int WDetopen(),WDgetaddr(),WDrecv(),WDxmit(),WDetupdate(),WDetclose();
  77. extern int WAetopen(),WAgetaddr(),WArecv(),WAxmit(),WAetupdate(),WAetclose();
  78. extern int E2etopen(),E2getaddr(),E2recv(),E2xmit(),E2etupdate(),E2etclose();
  79. extern int LTopen(),LTgetaddr(),LTrecv(),LTxmit(),LTupdate(),LTclose();
  80. extern int pketopen(),pkgetaddr(),pkxmit(),pketclose();
  81.     extern void pkrecv(),pketupdate();
  82. extern int E4etopen(),E4getaddr(),E4recv(),E4xmit(),E4etupdate(),E4etclose();
  83. extern int DNetopen(),DNgetaddr(),DNxmit(),DNetclose();
  84.     extern void DNrecv(),DNetupdate();
  85. extern int ILetopen(),ILgetaddr(),ILxmit(),ILetclose();
  86.     extern void ILrecv(),ILetupdate();
  87.  
  88. #ifdef __WATCOMC__
  89. static int cdecl
  90. #else
  91. static int 
  92. #endif /* __WATCOMC__ */
  93.     (*etopen)(unsigned char *s,unsigned int irq,unsigned int addr,
  94.       unsigned int ioaddr)=NULL,                     /* open the device */
  95.     (*getaddr)(unsigned char *s,unsigned int addr,
  96.       unsigned int ioaddr)=NULL,                    /* get the Ether address */
  97.     (*setaddr)(char *s,int addr,int ioaddr)=NULL,    /* set the Ether address */
  98.     (*etclose)(void )=NULL,                            /* shut down network */
  99.     (*xmit)(DLAYER *packet,int count)=NULL;            /* transmit a packet */
  100. #ifdef __WATCOMC__
  101. static void cdecl
  102. #else
  103. static void
  104. #endif /* __WATCOMC__ */
  105.     (*recv)(void )=NULL,                         /* load a packet from queue  */
  106.     (*etupdate)(void )=NULL;                    /* update pointers in buffer */
  107.  
  108. /**********************************************************************/
  109. /*  statcheck
  110. *   look at the connection status of the memory buffers to see if the
  111. *   allocation schemes are working.  Only used as a debug tool.
  112. */
  113.  
  114. void statcheck(void )
  115. {
  116.     int i;
  117.     struct port *p;
  118.  
  119.     for(i=0; i<20; i++) {
  120.         printf("\n%d > ",i);
  121.         p=portlist[i];
  122.         if(p!=NULL) 
  123.             printf("state: %d  %5u  %5u  %10ld  %5d  %5d",
  124.                     p->state,intswap(p->tcpout.t.source),
  125.                     intswap(p->tcpout.t.dest),p->out.lasttime,p->rto,
  126.                     p->out.contain);
  127.       }    /* end for */
  128. }
  129.  
  130. /*************************************************************************/
  131. /*  config network parameters
  132. *   Set IRQ and DMA parameters for initialization of the 3com adaptor
  133. */
  134. static uint nnirq=3,nnaddr=0xd000,nnioaddr=0x300;
  135.  
  136. int netparms(irq,address,ioaddr)
  137. uint irq,address,ioaddr;
  138. {
  139.     BUG("netparms");
  140.  
  141.     nnirq=irq;
  142.     nnaddr=address;
  143.     nnioaddr=ioaddr;
  144. #ifdef DEBUG
  145.     printf("nnmyaddr=%X;nnaddr=%X;nnioaddr=%X\n",nnmyaddr,nnaddr,nnioaddr);
  146.     printf("press a key\n");
  147.     getch();
  148. #endif
  149.     return(0);
  150. }
  151.  
  152. /**********************************************************************/
  153. /* netconfig
  154. *  load the function pointers for network access
  155. *  Currently setaddr() is not used, so it isn't loaded.
  156. *
  157. *  Note that netparms is called BEFORE netconfig.  So if you have any
  158. *  really special variables to set for your board that involve
  159. *  irq,address and ioaddr, you can add calls to your special routines
  160. *  in this section.
  161. *
  162. *  Some drivers will do the interrupt driver and board initialization
  163. *  in etopen() and some will do it in getaddr().
  164. */
  165. void netconfig(s)
  166. char *s;
  167. {
  168.  
  169.     Sgetconfig(&def);                /* get information provided in hosts file */
  170.  
  171.     if(!strncmp(s,"iso",3) || !strncmp(s,"bicc",4)) {
  172.         etopen=ILetopen;
  173.         xmit=ILxmit;
  174.         recv=ILrecv;
  175.         getaddr=ILgetaddr;
  176.         etupdate=ILetupdate;
  177.         etclose=ILetclose;
  178.       } /* end if */
  179.     else if(!strncmp(s,"3c505",5) || !strncmp(s,"505",3)) {
  180.         etopen=E5etopen;
  181.         xmit=E5xmit;
  182.         recv=E5recv;
  183.         getaddr=E5getaddr;
  184.         etupdate=E5etupdate;
  185.         etclose=E5etclose;
  186.       } /* end if */
  187.     else if(!strncmp(s,"decnet",6) || !strncmp(s,"dn",2)) {
  188.         etopen=DNetopen;
  189.         xmit=DNxmit;
  190.         recv=DNrecv;
  191.         getaddr=DNgetaddr;
  192.         etupdate=DNetupdate;
  193.         etclose=DNetclose;
  194.       }    /* end if */
  195.     else if(!strncmp(s,"star10",6) || !strncmp(s,"starlan",7)) {
  196.         etopen=ATetopen;
  197.         xmit=ATxmit;
  198.         recv=ATrecv;
  199.         getaddr=ATgetaddr;
  200.         etupdate=ATetupdate;
  201.         etclose=ATetclose;
  202.       }    /* end if */
  203.     else if(!strncmp(s,"packet",6)) {
  204.         BUG("packetdriver - setting to pk funcs");
  205.         etopen=pketopen;
  206.         xmit=pkxmit;
  207.         recv=pkrecv;
  208.         getaddr=pkgetaddr;
  209.         etupdate=pketupdate;
  210.         etclose=pketclose;
  211.       }
  212.     else if(!strncmp(s,"ni9",3) || !strncmp(s,"92",2)) {
  213.         etopen=M9etopen;
  214.         xmit=M9xmit;
  215.         recv=M9recv;
  216.         getaddr=M9getaddr;
  217.         etupdate=M9etupdate;
  218.         etclose=M9etclose;
  219.     }
  220.     else if(!strncmp(s,"ni5",3) || !strncmp(s,"mi",2)) {
  221.         etopen=M5etopen;
  222.         xmit=M5xmit;
  223.         recv=M5recv;
  224.         getaddr=M5getaddr;
  225.         etupdate=M5etupdate;
  226.         etclose=M5etclose;
  227. /*
  228. *   special initialization call would go here
  229. */
  230.     }
  231.     else if(!strncmp(s,"nicps",5)) {
  232.         etopen=U2etopen;
  233.         xmit=U2xmit;
  234.         recv=U2recv;
  235.         getaddr=U2getaddr;
  236.         etupdate=U2etupdate;
  237.         etclose=U2etclose;
  238.     }
  239.     else if(!strncmp(s,"nicpc",5) || !strncmp(s,"pcnic",5)) {
  240.         etopen=U1etopen;
  241.         xmit=U1xmit;
  242.         recv=U1recv;
  243.         getaddr=U1getaddr;
  244.         etupdate=U1etupdate;
  245.         etclose=U1etclose;
  246.     }
  247.     else if(!strncmp(s,"wd8003a",7) || !strncmp(s,"8003a",5)) {
  248.         etopen=WAetopen;
  249.         xmit=WAxmit;
  250.         recv=WArecv;
  251.         getaddr=WAgetaddr;
  252.         etupdate=WAetupdate;
  253.         etclose=WAetclose;
  254.     }
  255.     else if(!strncmp(s,"wd",2) || !strncmp(s,"800",3)) {
  256.         etopen=WDetopen;
  257.         xmit=WDxmit;
  258.         recv=WDrecv;
  259.         getaddr=WDgetaddr;
  260.         etupdate=WDetupdate;
  261.         etclose=WDetclose;
  262.     }
  263.     else if(!strncmp(s,"3c523",5) || !strncmp(s,"523",3)) {
  264.         etopen=E2etopen;
  265.         xmit=E2xmit;
  266.         recv=E2recv;
  267.         getaddr=E2getaddr;
  268.         etupdate=E2etupdate;
  269.         etclose=E2etclose;
  270.     }
  271.     else if( !strncmp(s,"3c503",5) || !strncmp(s,"503",3)) {
  272.         etopen=E4etopen;
  273.         xmit=E4xmit;
  274.         recv=E4recv;
  275.         getaddr=E4getaddr;
  276.         etupdate=E4etupdate;
  277.         etclose=E4etclose;
  278.         E4setwire(def.wire*2);
  279.     }
  280.     else if(!strncmp(s,"ltalk",5) || !strncmp(s,"atalk",5) || !strncmp(s,"apple",5)) {
  281.         extern unsigned int LTalk_vector;
  282.  
  283.         nnkip=1;                    /* turn kip arping on */
  284.         LTalk_vector=nnirq;
  285.         etopen=LTopen;
  286.         xmit=LTxmit;
  287.         recv=LTrecv;
  288.         getaddr=LTgetaddr;
  289.         etupdate=LTupdate;
  290.         etclose=LTclose;
  291.     }
  292.     else if(!strncmp(s,"r501",4)) {        /* special reserve driver */
  293.         etopen=E3etopen;
  294.         xmit=E3xmit;
  295.         recv=E3recv;
  296.         getaddr=E3getaddr;
  297.         etupdate=E3etupdate;
  298.         etclose=E3etclose;
  299.     }
  300.     else {        /* default choice */
  301.         etopen=E1etopen;
  302.         xmit=E1xmit;
  303.         recv=E1recv;
  304.         getaddr=E1getaddr;
  305.         etupdate=E1etupdate;
  306.         etclose=E1etclose;
  307.     }
  308. }
  309.  
  310. /**********************************************************************/
  311. /*  netarpme
  312. *   send an arp to my address.  arpinterpret will notice any response.
  313. *   Checks for adapters which receive their own broadcast packets.
  314. */
  315. int netarpme(s)
  316. char *s;
  317. {
  318.     if(etopen==U2etopen)
  319.         return(0);
  320.     if(etopen==U1etopen)
  321.         return(0);
  322.     if(etopen==LTopen)        /* not needed for Local Talk */
  323.         return(0);
  324.     reqarp(s);        /* send it */
  325.     return(0);
  326. }
  327.  
  328. /**********************************************************************/
  329. int initbuffer()
  330. {
  331.     bufpt=bufread=buforg=raw;    /*  start at the beginning */
  332.     BUG("initbuffer");
  333.  
  334.     bufbig=0;
  335. #ifdef _TURBOC_
  336.     bufend=&raw[7500];            /* leave 2K breathing room, required */
  337.     buflim=5000;                /* another 2K breathing room */
  338. #else
  339.     bufend=&raw[14500];            /* leave 2K breathing room, required */
  340.     buflim=12000;                /* another 2K breathing room */
  341. #endif
  342.  
  343.     BUG("before getaddr");
  344. #ifdef DEBUG
  345.     printf("nnmyaddr=%X;nnaddr=%X;nnioaddr=%X\n",nnmyaddr,nnaddr,nnioaddr);
  346.     printf("getaddr = %p\n",getaddr);
  347.     printf("press a key\n");
  348.     getch();
  349. #endif
  350.  
  351.     BUG("about to getaddr");
  352. /* QAK was if-def'ed out */
  353.     (*getaddr)(nnmyaddr,nnaddr,nnioaddr);
  354.     BUG("after getaddr");
  355.  
  356. #ifdef NETD
  357.     printf("Addr=%x.%x.%x.%x.%x.%x\n",nnmyaddr[0],nnmyaddr[1],nnmyaddr[2],
  358.         nnmyaddr[3],nnmyaddr[4],nnmyaddr[5]);
  359. #endif
  360.     return(0);
  361. }
  362.  
  363. /**********************************************************************/
  364. /*   demux
  365. *      find the packets in the buffer, determine their lowest level
  366. *  packet type and call the correct interpretation routines
  367. *
  368. *  the 'all' parameter tells demux whether it should attempt to empty
  369. *  the input packet buffer or return after the first packet is dealt with.
  370. *
  371. *  returns the number of packets demuxed
  372. */
  373. int demux(all)
  374. int all;
  375. {
  376.     uint16 getcode;
  377.     int nmuxed;
  378.     DLAYER *firstlook;
  379.  
  380.     nmuxed=0;
  381.     if(!etupdate)                    /* check that network is hooked up */
  382.         return(0);
  383.     do {                            /* while all flag is on */
  384.         (*recv)();                    /* NULL operation for 3COM */
  385. #ifdef NETD
  386.         printf("After Masking!\n");
  387.         printf("pt->%p, read->%p, end->%p\n",bufpt,bufread,bufend);
  388.         printf("\n HAHA \n");
  389.         printf("bufbig = %d\n", bufbig);
  390.         getch();
  391. #endif
  392.         if(bufbig>0) {
  393.             nmuxed++;
  394.             firstlook=(DLAYER *)(bufread+2);     /* where packet is */
  395. #ifdef NETD
  396.             printf("dest=%x.%x.%x.%x.%x.%x, me=%x.%x.%x.%x.%x.%x, type=%d\n",
  397.                     (unsigned int)firstlook->dest[0],(unsigned int)firstlook->dest[1],(unsigned int)firstlook->dest[2],
  398.                     (unsigned int)firstlook->dest[3],(unsigned int)firstlook->dest[4],(unsigned int)firstlook->dest[5],
  399.                     (unsigned int)firstlook->me[0],(unsigned int)firstlook->me[1],(unsigned int)firstlook->me[2],
  400.                     (unsigned int)firstlook->me[3],(unsigned int)firstlook->me[4],(unsigned int)firstlook->me[5],
  401.                     firstlook->type);
  402.             printf("big=%d,  size=%d\n",bufbig,(int)(bufpt - bufread));
  403.             getch();
  404.  
  405. #endif
  406.             getcode=firstlook->type;        /* where does it belong? */
  407.             switch(getcode) {                /* what to do with it? */
  408.                 case EARP:
  409.                 case ERARP:
  410. #ifdef    NETD
  411.                     printf("arp\n");
  412. #endif
  413.                     arpinterpret((ARPKT *)firstlook);    /* handle ARP packet */
  414.                     break;
  415.  
  416.                 case EIP:
  417. #ifdef    NETD
  418.                     printf("ip\n");
  419. #endif
  420.                     ipinterpret((IPKT *)firstlook);
  421.                     break;
  422.  
  423.                 default:
  424. #ifdef    NETD
  425.                     printf("garbage\n");
  426. #endif
  427.                     break;
  428.               }    /* end switch */
  429.             (*etupdate)();        /* update read pointers in buffer, free packet */
  430.           }    /* end if */
  431.         else 
  432.             all=0;
  433.       }    while(all);        /* should we look for more to deal with? */
  434.     return(nmuxed);        /* no packets anymore */
  435. }
  436.  
  437. /************************************************************************/
  438. /*  dlayersend
  439. *
  440. *  usage:   err=dlayersend(ptr,size)
  441. *      err=0 for successful, non-zero error code otherwise
  442. *      ptr is to a dlayer packet header
  443. *      size is the number of bytes total
  444. *
  445. *  This particular dlayer routine is for Ethernet.  It will have to be
  446. *  replaced for any other dlayer.
  447. *
  448. *  Ethernet addresses are resolved at higher levels because they will only
  449. *  need to be resolved once per logical connection, instead of once per
  450. *  packet.  Not too layer-like, but hopefully modular.
  451. *
  452. */
  453.  
  454. int dlayersend(ptr,size)
  455. DLAYER *ptr;
  456. unsigned size;
  457. {
  458.     int ret,i;
  459.  
  460. #ifdef OLD_WAY
  461.     if(size<60)
  462.         size=60;
  463.     if(size&0x01)
  464.         size+=1;
  465. #else
  466.     unsigned char *c;
  467.  
  468.     c=(unsigned char *)ptr;
  469.     *(c+size++)=0;        /* NULL pad last char */
  470.     *(c+size++)=0;        /* NULL pad last char */
  471. #endif
  472.  
  473.     for(i=0;i<SQwait;i++);
  474.     if((++OKpackets)>10){
  475.         SQwait -= 10;
  476.         OKpackets = 0;
  477.     }
  478.     if (SQwait < 10) SQwait = 10;
  479.  
  480.     ret=(*xmit)((DLAYER *)ptr,size);    /* send it out, pass back return code */
  481.                                     /* xmit checks for size < 60 */
  482. /*
  483. *   automatic, immediate retry once
  484. */
  485.     if(ret) {
  486.         if(ret == (*xmit)((DLAYER *)ptr,size))
  487.             nnerror(100);        /* post user error message */
  488.     }
  489.     return(ret);
  490. }
  491.  
  492. /***************************************************************************/
  493. /* dlayerinit
  494. *  Do machine dependent initializations of whatever hardware we have
  495. *  (happens to be ethernet board here ) 
  496. */
  497. int dlayerinit(void )
  498. {
  499.     int my_var;
  500.     BUG("dlayerinit");
  501. #ifdef DEBUG    
  502.     printf("etopen = %p\n",etopen);
  503. #endif
  504.     if(initbuffer() || !etopen)
  505.         return(-10);
  506.  
  507. #ifdef NETD
  508. printf("dlayerinit(): after initbuffer()\n");
  509. printf("etopen=%p\n",etopen);
  510. printf("nnirq=%x, nnaddr=%x, nnioaddr=%x\n",(uint16)nnirq,(uint16)nnaddr,(uint16)nnioaddr);
  511. getch();
  512. #endif
  513. /*
  514.  * Call (*etopen) first to be sure any board/driver initializations are taken care of
  515.  */
  516.     my_var = ((*etopen)(nnmyaddr,nnirq,nnaddr,nnioaddr));
  517. #ifdef NETD
  518.     printf("my_var is %d\n", my_var);
  519.     getch();
  520. #endif
  521.     return my_var;
  522. }
  523.  
  524. void dlayershut(void )
  525. {
  526.     if(etclose)
  527.         (*etclose)();
  528. }
  529.  
  530. /***************************************************************************/
  531. /*  pcgetaddr
  532. *   return results from indirect getaddr call.
  533. *   This is a pc-specific request for the 48-bit address which was added
  534. *   so that the user program could print the value.
  535. */
  536. void pcgetaddr(s,x,y)
  537. char *s;
  538. int x,y;
  539. {
  540.     if(getaddr)
  541.         (*getaddr)(s,x,y);
  542. }
  543.