home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / NCSATELN / TEL23SRC.ZIP / NET / ENET / LTALK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-23  |  21.8 KB  |  769 lines

  1. /*
  2.  * National Center for Supercomputing Applications (NCSA) Telnet source code
  3.  *
  4.  * February 10, 1989
  5.  * (C) Copyright 1989 Planning Research Corporation
  6.  *
  7.  * Permission is granted to any individual or institution to use, copy,
  8.  * modify, or redistribute this software and its documentation provided this
  9.  * notice and the copyright notices are retained.  This software may not be
  10.  * distributed for profit, either in original form or in derivative works.
  11.  * Planning Research Corporation makes no representations about the
  12.  * suitability of this software for any purpose.
  13.  *
  14.  * PLANNING RESEARCH CORPORATION GIVES NO WARRANTY, EITHER EXPRESS OR IMPLIED,
  15.  * FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT
  16.  * LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A
  17.  * PARTICULAR PURPOSE.
  18.  */
  19.  
  20. /*
  21.  * Revision History:
  22.  *
  23.  * Date            Initials        Comment
  24.  * ----            --------        -------
  25.  * 02-10-89        JGN@PRC            Initial version.
  26.  * 03-04-89     TKK@NCSA        KIP code added.
  27.  * 10-20-90        QAK@NCSA        Twiddled for version 2.3
  28.  *
  29.  * Initials        Name            Organization
  30.  * --------        ----            ------------
  31.  * JGN@PRC        Jim Noble        Planning Research Corporation
  32.  * TKK@NCSA     Tim Krauskopf    National Center for Supercomputing Applications
  33.  * QAK@NCSA        Quincey Koziol    National Center for Supercomputing Applications
  34.  *
  35. */
  36.  
  37. #define KIPPER
  38. #define LTALK_MASTER
  39.  
  40. #if defined(MSC) && !defined(__TURBOC__)
  41. #define movmem(from,to,len)    memmove(to,from,len)
  42. #endif
  43.  
  44. #include <dos.h>
  45. #include <stdio.h>
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #ifdef MSC
  49. #ifdef __TURBOC__
  50. #include <mem.h>
  51. #include <alloc.h>
  52. #else
  53. #include <malloc.h>
  54. #endif
  55. #endif
  56. #ifdef MEMORY_DEBUG
  57. #include "memdebug.h"
  58. #endif
  59. #include "protocol.h"
  60. #include "data.h"
  61. #include "ltalk.h"
  62. #ifdef KIPPER
  63. #include "kip.h"
  64. #endif
  65. #include "externs.h"
  66.  
  67. struct at_vector {
  68.     char name[9];
  69.     unsigned char    vers_minor,
  70.         vers_major,
  71.         driver_type,
  72.         reserved[4];
  73. };
  74.  
  75. extern unsigned char rstat;        /* last status from read */
  76. extern char *buforg;    /* pointer to beginning of buffer space */
  77. extern char *bufend;    /* pointer to end of buffer space (like EOT mark) */
  78. extern char *bufread;    /* pointer to packet program is working on */
  79. extern char *bufpt;        /* pointer to space for next packet */
  80. extern int   buflim;    /* number of useable bytes in buffer space */
  81. extern int   bufbig;    /* number of bytes in use in buffer space */
  82.  
  83. extern listen1();        /* ASM part of first-half DDP socket listener */
  84.  
  85. unsigned listen_ds;        /* Allows the ASM part of the socket listeners to */
  86.                         /* determine the data segment of the C part of the */
  87.                         /* socket listeners */
  88.  
  89. unsigned int LTalk_vector;    /* Interrupt vector to use to make AppleTalk driver calls */
  90.  
  91. static char ltinit=0,        /* has this driver been initialized yet? */
  92.         KIPzone[32]={"*"},    /* the zone to send KIP queries to */
  93.         *entity;            /* storage for entities to pass to driver */
  94. #ifdef KIPPER
  95. static IPGP    *gatedata;        /* configuration record to/from KIP server */
  96. #endif
  97. static BDSElement *bds;        /* buffer list for ATP request */
  98. static ATPParams *atp_pb;    /* ATP request parameter block */
  99. static NBPTabEntry mynbp;    /* storage for my own MBP registration */
  100. static NBPParams *nbp_pb;    /* NBP parameter block */
  101. extern int nnkip;            /* are we running KIP? */
  102.  
  103. static AddrBlk myaddr;        /* my network, node, socket */
  104. static ATARPKT arpbuffer;    /* alternate format for arps req'd for LocalTalk */
  105.  
  106. #define SHOW_MESSAGE        1        /* Display LTalk_call error messages */
  107. #define HIDE_MESSAGE        0        /* Don't display LTalk_call error messages */
  108. #define LTIP                22        /* DDP protocol type for IP */
  109. #define LTARP                23        /* DDP protocol type for ARP */
  110. #define IPSock                72        /* DDP socket for LocalTalk */
  111.  
  112. #define MAX_ADDR_TRIES        100        /* Maximum tries to get the addres */
  113.  
  114. static void    LTalk_error (char *caller,int status);        /* Displays AppleTalk driver error messages */
  115. static int LTalk_call(InfoParams *pb,char *caller,int display);    /* Makes AppleTalk driver calls */
  116. int     LTopen(AddrBlk *s,int irq,int addr,int ioaddr);  /* Initializes AppleTalk driver and opens DDP socket */
  117. void    LTgetaddr(AddrBlk *s,int addr,int ioaddr);     /* Returns our AppleTalk network and node numbers */
  118. int     LTxmit(DLAYER *ptr,unsigned int size);    /* Transmit a packet on the DDP socket */
  119. void    LTrecv(void );    /* Preprocesses an already received packet */
  120. void    LTupdate(void );    /* Releases a packet after processing */
  121. void    LTclose(void ); /* Closes the DDP socket */
  122. void    listen1_c();   /* C part of DDP 1st-half listener */
  123. void    listen2_c();   /* C part of DDP 2nd-half listener */
  124.  
  125. /*
  126.  * LTalk_error
  127.  *
  128.  * Display an AppleTalk driver error message.
  129.  */
  130. static void LTalk_error(char *caller,int status)
  131. {
  132.     fputs(caller,stderr);
  133.     fputs(":  ", stderr);
  134.  
  135.     switch(status) {    /* Provide text for the errors that we might get */
  136.         case ATNOTINITIALIZED:
  137.             fputs("AppleTalk driver not initialized.",stderr);
  138.             break;
  139.  
  140.         case BAD_PARAMETER:
  141.             fputs("Illegal parameter or parameters.",stderr);
  142.             break;
  143.  
  144.         case BAD_SYNC_CALL:
  145.             fputs("Synchronous command was called at a time when the driver cannot handle it.",stderr);
  146.             break;
  147.  
  148.         case CALLNOTSUPPORTED:
  149.             fputs("Requested call not supported.",stderr);
  150.             break;
  151.  
  152.         case DDP_CANCELLED:
  153.             fputs("DDP transaction cancelled.",stderr);
  154.             break;
  155.  
  156.         case DDP_LENERR:
  157.             fputs("DDP data too long.",stderr);
  158.             break;
  159.  
  160.         case DDP_SKTERR:
  161.             fputs("Used unopen socket.",stderr);
  162.             break;
  163.  
  164.         case HARDWARE_ERROR:
  165.             fputs("Unrecoverable hardware error.",stderr);
  166.             break;
  167.  
  168.         case MAXCOLISERR:
  169.             fputs("Too many collisions detected.",stderr);
  170.             break;
  171.  
  172.         case MAXDEFERERR:
  173.             fputs("32 deferrals encountered (ALAP).",stderr);
  174.             break;
  175.  
  176.         case MEMORY_CORRUPTED:
  177.             fputs("Internal memory pool corrupted.  Reload driver.",stderr);
  178.             break;
  179.  
  180.         case NOBRDGERR:
  181.             fputs("No bridge found.",stderr);
  182.             break;
  183.  
  184.         case NO_MEM_ERROR:
  185.             fputs("Not enough memory to perform requested operation.",stderr);
  186.             break;
  187.  
  188.         case SOFTWARE_ERROR:
  189.             fputs("Internal software error.  Reinitialize driver.",stderr);
  190.             break;
  191.  
  192.         case STACKERROR:
  193.             fputs("Too many levels of nesting to complete call.",stderr);
  194.             break;
  195.  
  196.         default:    /* Handle anything else that might come up */
  197.             fprintf(stderr,"Unknown AppleTalk driver error %d.",status);
  198.       }    /* end switch */
  199.     fputs("\n",stderr);
  200. }    /* end LTalk_error() */
  201.  
  202. /*
  203.  * LTalk_call
  204.  *
  205.  * Make an AppleTalk driver call.  Return the driver error code.
  206.  */
  207. static int LTalk_call(InfoParams *pb,char *caller,int display)
  208. {
  209.     union REGS    rgisters;
  210.     struct SREGS    segments;
  211.     int        status;
  212.  
  213.     rgisters.x.bx=FP_OFF(pb);
  214.     segments.ds=FP_SEG(pb);
  215.     int86x(LTalk_vector,&rgisters,&rgisters,&segments);
  216.     status=pb->atd_status;
  217.     if(status!=NOERR && display)
  218.         LTalk_error(caller,status);
  219.     return status;
  220. }    /* end LTalk_call() */
  221.  
  222. /*
  223.  * LTopen
  224.  *
  225.  * Check if AppleTalk driver is installed, initialize driver, open DDP socket
  226.  * for IP packets, fill in network address parameter ('s') and return.  The
  227.  * return value is 0 if successful and a non-zero driver error code if
  228.  * something failed.  On entry the 'irq' parameter contains the 'interrupt=xx'
  229.  * value from the configuration file and specifies the interrupt to use when
  230.  * making driver calls.  The 'addr' and 'ioaddr' parameters are unused by this
  231.  * routine.
  232.  */
  233. int LTopen(AddrBlk *s,int irq,int addr,int ioaddr)
  234. {
  235.     char        buffr[100];
  236.     char        buffr2[100];
  237.     DDPParams    ddp_pb;
  238.     InfoParams    info_pb;
  239.     struct SREGS segregs;
  240.     int            status;
  241.     int         count;        /* counter for the number of tries to get the address */
  242.  
  243.     if(ltinit)                                /* we are initialized already */
  244.         return(0);
  245.  
  246.     /* Interrupt vector to use to make AppleTalk driver calls */
  247.     LTalk_vector=irq;
  248.  
  249.     if(strncmp("AppleTalk",(*((char **)((unsigned long)(LTalk_vector*4))))-16,9))
  250.     {
  251.         status=ATNOTINITIALIZED;
  252.         LTalk_error("LTopen",status);
  253.         fputs("...AppleTalk driver not installed\n",stderr);
  254.         return(status);
  255.     }    /* end if */
  256.  
  257.     /* Initialize AppleTalk driver */
  258.     info_pb.atd_command=ATInit;
  259.     info_pb.atd_compfun=(CPTR) 0;
  260.     info_pb.inf_nodeid=0;
  261.  
  262.     status=LTalk_call(&info_pb,"LTopen",SHOW_MESSAGE);
  263.     if(status!=NOERR)
  264.         return(status);
  265.  
  266.     ltinit=1;                                /* flag we are open */
  267.  
  268.     /*
  269.      * Store current DS register in listen_ds so that listen1 and listen2
  270.      * (asm) can set DS register before calling listen1_c and listen2_c (C).
  271.      */
  272.     segread(&segregs);
  273.     listen_ds=segregs.ds;
  274.  
  275.     /* Open a DDP socket */
  276.     ddp_pb.atd_command=DDPOpenSocket;
  277.     ddp_pb.atd_compfun=(CPTR) 0;
  278.     ddp_pb.ddp_socket=IPSock;        /* we use 72 like everyone else */
  279.     ddp_pb.ddp_bptr=(DPTR)listen1;    /* interrupt listener */
  280.  
  281.     status=LTalk_call((InfoParams *)&ddp_pb,"LTopen",SHOW_MESSAGE);
  282.     if(status!=NOERR)
  283.         return(status);
  284.  
  285.     myaddr.socket=ddp_pb.ddp_socket;    /* keep a copy, always=72 */
  286.  
  287. /*
  288. * Get the AppleTalk network and node numbers
  289. * Store a copy of the values in our structure for use by other routines.
  290. */
  291.     info_pb.atd_command=ATGetNetInfo;
  292.     info_pb.atd_status=-1;
  293.     info_pb.atd_compfun=NULL;
  294.     info_pb.inf_bptr=NULL;
  295.     info_pb.inf_buffsize=0;
  296.  
  297.     /* repeat this a few times if the network returns 0 */
  298.     for(count=0; count<MAX_ADDR_TRIES; count++) {
  299.         status=LTalk_call(&info_pb,"LTgetaddr",SHOW_MESSAGE);
  300.         if(status!=NOERR) {
  301.             myaddr.network=0;
  302.             myaddr.nodeid=0;
  303.             status=ATNOTINITIALIZED;
  304.             return(status);
  305.           }    /* end if */
  306.         else {
  307.             myaddr.network=info_pb.inf_network;
  308.             myaddr.nodeid=info_pb.inf_nodeid;
  309.           }    /* end else */
  310.         if(myaddr.network!=0)
  311.             break;
  312.       }    /* end for */
  313.     if(myaddr.network==0) {
  314.         sprintf(buffr2,"Error getting network number");
  315.         printf(buffr2);
  316. /*        n_puts(buffr2); */
  317.         return(-1);
  318.       }    /* end if */
  319.  
  320.     sprintf(buffr2,"Network: %u,  Node: %u",intswap(myaddr.network),myaddr.nodeid);
  321.     printf(buffr2);
  322. /*    n_puts(buffr2);*/
  323.  
  324.     broadaddr[0]=0;
  325.     broadaddr[1]=0;
  326.     broadaddr[2]=0xff;
  327.     broadaddr[3]=0x48;
  328.     bseed[0]=0;
  329.     bseed[1]=0;
  330.     bseed[2]=0xff;
  331.     bseed[3]=0x48;
  332.  
  333.  
  334. #ifdef KIPPER
  335.     if(nndto<1)            /* don't bother with KIP */
  336.         return(0);
  337.     if(nndto<2)            /* minimum value */
  338.         nndto=2;
  339.  
  340.     if(NULL==(entity=malloc(100)))
  341.         return(-1);
  342.     if(NULL==(nbp_pb=malloc(sizeof(NBPParams))))
  343.         return(-1);
  344.     if(NULL==(gatedata=malloc(sizeof(IPGP))))
  345.         return(-1);
  346.     if(NULL==(bds=malloc(sizeof(BDSElement))))
  347.         return(-1);
  348.     if(NULL==(atp_pb=malloc(sizeof(ATPParams))))
  349.         return(-1);
  350.  
  351.     nnkip=1;
  352.  
  353. /*
  354. *  Look for a KIP gateway with NBP
  355. */
  356.     sprintf(entity,"\001=\011IPGATEWAY%c%s",strlen(KIPzone),KIPzone);
  357.     sprintf(buffr,"%c%c%c%c",0,0,0,0);  /* set the buffer to 0 */
  358.  
  359.     nbp_pb->atd_command=NBPLookup;
  360.     nbp_pb->atd_compfun=NULL;
  361.     nbp_pb->nbp_toget=1;
  362.     nbp_pb->nbp_bptr=buffr;
  363.     nbp_pb->nbp_buffsize=100;
  364.     nbp_pb->nbp_interval=(unsigned char)(nndto/2);
  365.     nbp_pb->nbp_retry=3;
  366.     nbp_pb->nbp_entptr=entity;
  367.  
  368.     status=LTalk_call((InfoParams *)nbp_pb,"NBPLook",HIDE_MESSAGE);
  369.     if(status!=NOERR)
  370.         return(0);        /* cannot find KIP is not an error */
  371.     sprintf(buffr2,"IPGATEWAY at Net %u.%u Node %u Skt %u\n",
  372.         (int)(((unsigned char *)buffr)[0]),
  373.         (int)(((unsigned char *)buffr)[1]),
  374.         (int)(((unsigned char *)buffr)[2]),
  375.         (int)(((unsigned char *)buffr)[3]));
  376.     printf(buffr2);
  377. /*    n_puts(buffr2); */
  378.  
  379. /*
  380. *  get the parameters from the KIP server.
  381. *  This obtains a dynamically assigned IP address if it can get one.
  382. */
  383.     atp_pb->atd_command=ATPSndRequest;
  384.     atp_pb->atd_compfun=NULL;
  385.  
  386. #ifdef OLD_WAY
  387.     gatedata->opcode=longswap(1L);    /* Motorola byte order */
  388. #else
  389.     gatedata->opcode=0x1000000L;  /* Motorola byte order */
  390. #endif
  391.     gatedata->ipaddress=0;
  392.  
  393.     movmem(buffr,&atp_pb->atp_addr,sizeof(AddrBlk));
  394.     bds->bds_bptr=(DPTR)gatedata;
  395.     bds->bds_buffsize=sizeof(IPGP);
  396.     atp_pb->atp_bdsptr=bds;
  397.     atp_pb->atp_bptr=(DPTR)gatedata;
  398.     atp_pb->atp_buffsize=sizeof(IPGP);
  399.     atp_pb->atp_flags=32;
  400.     atp_pb->atp_interval=5;
  401.     atp_pb->atp_retry=5;
  402.     atp_pb->atp_bdsbuffs=1;
  403.  
  404.     status=LTalk_call((InfoParams *)atp_pb,"ATPget",SHOW_MESSAGE);
  405.     if(status!=NOERR)
  406.         return(status);
  407.  
  408. /*    if(longswap(gatedata->opcode)>0) */    /* if we didn't get an error */
  409.         netsetip((unsigned char *)&gatedata->ipaddress);    /* set the ipaddress */
  410. /*
  411. *  NBP register our IP number.
  412. *  We aren't allowed to register outside of our zone, so we don't
  413. *  use KIPzone in the entity.
  414. */
  415.     nbp_pb->atd_command=NBPRegister;
  416.     nbp_pb->atd_compfun=NULL;
  417.     nbp_pb->nbp_bptr=(DPTR)&mynbp;
  418.     nbp_pb->nbp_interval=1;
  419.     nbp_pb->nbp_retry=3;
  420.  
  421.     mynbp.tab_nxtentry=NULL;
  422.     mynbp.tab_tuple.tup_address.socket=72;
  423.     sprintf(buffr,"%d.%d.%d.%d",
  424.         (unsigned char)*((char *)&gatedata->ipaddress+0),
  425.         (unsigned char)*((char *)&gatedata->ipaddress+1),
  426.         (unsigned char)*((char *)&gatedata->ipaddress+2),
  427.         (unsigned char)*((char *)&gatedata->ipaddress+3));
  428.  
  429.     sprintf(mynbp.tab_tuple.tup_entname,"%c%s\011IPADDRESS\001*",strlen(buffr),buffr);
  430.  
  431.     status=LTalk_call((InfoParams *)nbp_pb,"NBPRegister",SHOW_MESSAGE);
  432.     if(status!=NOERR)
  433.         return(status);
  434. #endif
  435.     return (NOERR);
  436. }    /* end LTopen() */
  437.  
  438. /*
  439.  * LTgetaddr
  440.  *
  441.  * Return the AppleTalk network address in parameter 's'.  Parameters 'addr'
  442.  * and 'ioaddr' are unused by this routine.
  443.  */
  444. void LTgetaddr(AddrBlk *s,int addr,int ioaddr)
  445. {
  446.     int count=10,
  447.         open_status;
  448.  
  449.     s->network=0;
  450.     s->nodeid=0;
  451.     s->socket=0;
  452.  
  453. #ifdef NEW_WAY
  454.     while(count--) {
  455.         open_status=LTopen(s,LTalk_vector,addr,ioaddr);    /*  Make sure we are initialized */
  456.         if(open_status<0)
  457.             LTclose();
  458.         else
  459.             break;
  460.       }    /* end while */
  461. #else
  462.     open_status=LTopen(s,LTalk_vector,addr,ioaddr);
  463. #endif
  464.  
  465.     if(open_status<0)
  466.         return;
  467.  
  468.     s->network=myaddr.network;        /* copy from stored values */
  469.     s->nodeid=myaddr.nodeid;
  470.     s->socket=myaddr.socket;
  471. }    /* end LTgetaddr() */
  472.  
  473. /*
  474.  * LTxmit
  475.  *
  476.  * Transmit IP packet at *ptr on DDP socket and return AppleTalk driver error
  477.  * code.  The return value is 0 for success and non-zero for failure.
  478.  * Ethernet packet types must be converted to DDP types.  The DLAYER header is
  479.  * not transmitted.
  480.  */
  481. int LTxmit(DLAYER *ptr,unsigned int size)
  482. {
  483.     DDPParams        ddp_pb;
  484.     int            status;
  485. /*
  486. *  First set up fields for xmit, if any of them have to change
  487. *  from the initial values, we'll change them.
  488. */
  489.     /* Transmit data (skipping DLAYER header) */
  490.     ddp_pb.atd_command=DDPWrite;
  491.     ddp_pb.atd_compfun=(CPTR) 0;
  492.     ddp_pb.ddp_addr=*((AddrBlk *)(ptr->dest));
  493.     ddp_pb.ddp_socket=IPSock;
  494.     ddp_pb.ddp_bptr=(char *)ptr+sizeof(DLAYER);
  495.     ddp_pb.ddp_buffsize=size-sizeof(DLAYER);
  496.     ddp_pb.ddp_chksum=0;
  497.  
  498.  
  499.     /* Convert packet type from Ethernet types to DDP types */
  500.     if(ptr->type==EIP)
  501.         ddp_pb.ddp_type=LTIP;
  502.     else if(ptr->type==EARP) {
  503.         ARPKT *aptr;
  504.  
  505.         ddp_pb.ddp_type=LTARP;
  506.         aptr=(ARPKT *)ptr;
  507. #ifdef OLD_WAY
  508.         arpbuffer.hrd=intswap(3);        /* appletalk == 3 */
  509. #else
  510.         arpbuffer.hrd=0x0300;            /* appletalk == 3 */
  511. #endif
  512.         arpbuffer.hln=4;            /* Ltalk length */
  513.         arpbuffer.pln=4;            /* IP length */
  514.         arpbuffer.pro=aptr->pro;        /* copy in command fields */
  515.         arpbuffer.op=aptr->op;
  516.  
  517.         movmem(aptr->sha,arpbuffer.sha,4);    /* re-align ARP fields */
  518.         movmem(aptr->spa,arpbuffer.spa,4);
  519.         movmem(aptr->tha,arpbuffer.tha,4);
  520.         movmem(aptr->tpa,arpbuffer.tpa,4);
  521.  
  522.         /* install new ARP format */
  523.           ddp_pb.ddp_bptr=((char *)&arpbuffer)+sizeof(ATdlayer);
  524.         ddp_pb.ddp_buffsize=sizeof(ATARPKT)-sizeof(ATdlayer);
  525.       }    /* end if */
  526.     status=LTalk_call((InfoParams *)&ddp_pb,"LTxmit",SHOW_MESSAGE);
  527.     return(status);
  528. }    /* end LTxmit() */
  529.  
  530. #ifdef KIPPER
  531. /******************************************************************/
  532. /* KIParp
  533. *  send the special KIParp request and return result.
  534. *  1=OK, less than zero=error.
  535. */
  536. int KIParp(unsigned char ipnum[4],AddrBlk *addrloc)
  537. {
  538.     char buffr[100];
  539.     int status;
  540.  
  541.     nbp_pb->atd_command=NBPLookup;
  542.     nbp_pb->atd_compfun=NULL;
  543.     nbp_pb->nbp_toget=1;
  544.     nbp_pb->nbp_bptr=buffr;
  545.     nbp_pb->nbp_buffsize=100;
  546.     nbp_pb->nbp_interval=1;
  547.     nbp_pb->nbp_retry=2;
  548.     nbp_pb->nbp_entptr=entity;
  549.  
  550.     sprintf(buffr,"%u.%u.%u.%u",ipnum[0],ipnum[1],ipnum[2],ipnum[3]);
  551.     sprintf(entity,"%c%s\011IPADDRESS%c%s",strlen(buffr),buffr,strlen(KIPzone),KIPzone);
  552.  
  553.     status=LTalk_call((InfoParams *)nbp_pb,"NBPFind",SHOW_MESSAGE);
  554.     if(status!=NOERR)
  555.         return(status);
  556.  
  557.     movmem(buffr,addrloc,4);        /* give back address */
  558.     return(1);
  559. }    /* end KIParp() */
  560.  
  561. /******************************************************************/
  562. /* KIPsetzone
  563. *  set the zone string for KIP lookups.
  564. */
  565. void KIPsetzone(char *s)
  566. {
  567.     strncpy(KIPzone,s,32);
  568.     KIPzone[31]='\0';
  569. }    /* end KIPsetzone() */
  570. #endif
  571.  
  572. /*
  573.  * LTrecv
  574.  *
  575.  * Change DDP packet type of next packet in the queue to Ethernet packet type.
  576.  */
  577. void LTrecv(void )
  578. {
  579.     DLAYER        *dlptr;
  580.  
  581.     if(bufbig>0) {        /* Make DDP packet types look like Ethernet types */
  582.         dlptr=(DLAYER *) (bufread+sizeof(int));
  583.         if(dlptr->type==LTIP)
  584.             dlptr->type=EIP;
  585.         else if(dlptr->type==LTARP) {
  586. /*
  587. *  yes, I realize that this is an in-place modification of
  588. *  the packet buffer which lengthens it.  It is tricky, but it
  589. *  is planned that way.
  590. */
  591.             ARPKT *eptr;
  592.             ATARPKT *atptr;
  593.  
  594.             dlptr->type=EARP;
  595.             eptr=(ARPKT *)dlptr;
  596.             atptr=(ATARPKT *)dlptr;
  597. #ifdef OLD_WAY
  598.             eptr->hrd=intswap(1);    /* We are faking Ethernet */
  599. #else
  600.             eptr->hrd=0x0100;        /* We are faking Ethernet */
  601. #endif
  602.             eptr->hln=6;        /* Ethernet length */
  603.             eptr->pln=4;        /* IP length */
  604.             eptr->pro=atptr->pro;    /* copy in command fields */
  605.             eptr->op=atptr->op;
  606.             movmem(atptr->tpa,eptr->tpa,4);
  607.             movmem(atptr->tha,eptr->tha,4);
  608.             movmem(atptr->spa,eptr->spa,4);
  609.             movmem(atptr->sha,eptr->sha,4);    /* re-align ARP fields */
  610.             eptr->tha[4]=0;
  611.             eptr->tha[5]=0;
  612.             eptr->sha[4]=0;
  613.             eptr->sha[5]=0;
  614.           }    /* end if */
  615.       }    /* end if */
  616. }    /* end LTrecv() */
  617.  
  618. /*
  619.  * LTupdate
  620.  *
  621.  * Release next packet in the queue.
  622.  */
  623. void LTupdate(void )
  624. {
  625.     int    pkt_size;
  626.  
  627.     /* Adjust pointers to deallocate packet in buffer */
  628.     pkt_size=*((int *)bufread)+sizeof(int);
  629.  
  630. /* printf("s: %d, r: %ld, q: %d\n",pkt_size,(long)bufread,bufbig); */
  631.  
  632.     bufread+=pkt_size;
  633.     if(bufread>=bufend)
  634.         bufread=buforg;
  635.     bufbig -= pkt_size;
  636. }    /* end LTupdate() */
  637.  
  638. /*
  639.  * LTclose
  640.  *
  641.  * Close the DDP socket for IP packets.
  642.  */
  643. void LTclose(void)
  644. {
  645.     DDPParams        ddp_pb;
  646.  
  647.     if(nnkip) {
  648.         nbp_pb->atd_command=NBPRemove;
  649.         nbp_pb->atd_compfun=NULL;
  650.         nbp_pb->nbp_entptr=mynbp.tab_tuple.tup_entname;
  651.         nbp_pb->nbp_interval=1;
  652.         nbp_pb->nbp_retry=3;
  653.  
  654.         LTalk_call((InfoParams *)nbp_pb,"NBPRemove",SHOW_MESSAGE);
  655.       }    /* end if */
  656.  
  657.     /* Close the DDP socket */
  658.     ddp_pb.atd_command=DDPCloseSocket;
  659.     ddp_pb.atd_compfun=(CPTR) 0;
  660.     ddp_pb.ddp_socket=IPSock;
  661.  
  662.     LTalk_call((InfoParams *)&ddp_pb,"LTclose",SHOW_MESSAGE);
  663. }    /* end LTclose() */
  664.  
  665. /*
  666.  * First-half DDP socket listener (C part)
  667.  *
  668.  * The first-half of the listener is called with the following inputs:
  669.  *
  670.  *         socket        Socket
  671.  *         datalen        Length of data
  672.  *         header        Pointer to (LAP & DDP) header
  673.  *
  674.  * The first-half of the listener must decide whether to keep or discard the
  675.  * data.  If the packet is to be discarded, the first-half listener must return
  676.  * with *bufflen equal to zero; in this case, the second-half of the listener
  677.  * will not be called.
  678.  *
  679.  * If the data is to be retained, the first-half listener must return with
  680.  * the following values:
  681.  *
  682.  *         *bptr Pointer to buffer for packet data
  683.  *         *bufflen Size of the buffer at *bptr
  684.  */
  685.  
  686. /* #pragma check_stack (off) */
  687.  
  688. void listen1_c(unsigned char socket,unsigned int datalen,unsigned char header[],unsigned int *bufflen,unsigned char *bptr[])
  689. {
  690.     static unsigned char    DDP_type,nethi,netlo,sock,nodeid;
  691.     static DLAYER            *dlptr;
  692.     static int                *intptr;
  693.  
  694.     *bufflen=0;                    /* Reject packet initially */
  695.     if(socket==IPSock) {        /* Is it for our socket? */
  696.                         /* Yes... */
  697.         if(header[2]==1) {            /* Get the DDP Protocol Type field */
  698.             DDP_type=header[7];        /* Short format DDP header */
  699.             nethi=(unsigned char)*(((char *)(unsigned long)myaddr.network)+1);
  700.             netlo=(unsigned char)*((char *)(unsigned long)myaddr.network);
  701.             nodeid=myaddr.nodeid;
  702.             sock=header[6];
  703.           }    /* end if */
  704.         else if(header[2]==2) {
  705.             DDP_type=header[15];           /* Long format DDP header */
  706.             nethi=header[9];
  707.             netlo=header[10];
  708.             nodeid=header[12];
  709.             sock=header[14];
  710.           }    /* end if */
  711.         else
  712.             DDP_type=0;            /* Not DDP packet; reject it */
  713.         if(DDP_type==LTIP || DDP_type==LTARP) { /* Is it an IP or ARP packet? */
  714.                         /* Yes... */
  715.             unsigned char *p;
  716.  
  717.             datalen+=4;            /* leave room for play */
  718.             if(bufbig<=buflim) {        /* Is there room in the buffer? */
  719.                     /* Yes... */
  720.                 *bufflen=datalen;    /* Accept whole packet */
  721.                 if(bufend<=bufpt)
  722.                     bufpt=buforg;
  723.                 intptr=(int *)bufpt;              /* Put packet at bufpt */
  724.                 *intptr=datalen+sizeof(DLAYER); /* Size of packet plus
  725.                                                         dummy DLAYER header */
  726.                 dlptr=(DLAYER *)++intptr;
  727.                 p=(char *)dlptr;
  728.                 dlptr->type=DDP_type;              /* Remember packet type */
  729.                 *bptr=(char *)++dlptr;        /* Put IP packet after dummy
  730.                                                    DLAYER header */
  731.                 /*  fill in addresses */
  732.                 *p++=(unsigned char)(myaddr.network&0xff);
  733.                 *p++=(unsigned char)(myaddr.network>>8);
  734.                 *p++=myaddr.nodeid;
  735.                 *p++=myaddr.socket;
  736.                 *p++=0;
  737.                 *p++=0;
  738.                 *p++=netlo;        /* fake src address */
  739.                 *p++=nethi;
  740.                 *p++=nodeid;
  741.                 *p++=sock;
  742.                 *p++=0;
  743.                 *p++=0;
  744.               }    /* end if */
  745.           }    /* end if */
  746.       }    /* end if */
  747. }    /* end listen1_c() */
  748.  
  749. /*
  750.  * Second-half DDP socket listener (C part)
  751.  *
  752.  * The second-half of the listener is called (through a FAR CALL) with
  753.  * the following inputs:
  754.  *
  755.  *         bptr        Pointer to buffer containing data
  756.  *         bufflen    Number of bytes of data in buffer at bptr
  757.  *
  758.  * The second-half listener may enable interrupts, and should exit with a FAR
  759.  * RETURN.
  760.  */
  761. void listen2_c(unsigned int bufflen,DLAYER *bptr)
  762. {
  763.     /* Calculate total size of new packet, leave 4 for good measure */
  764.  
  765.     bufflen+=sizeof(DLAYER)+sizeof(int)+4;
  766.     bufpt=&bufpt[bufflen];    /* Add total packet size to bufpt and bufbig */
  767.     bufbig+=bufflen;
  768. }    /* end listen2_c() */
  769.