This is some code that interfaces NCSA Telnet 2.2 with Microsoft C extentions, as provided by Jyrki Kuoppala, with the BICC ISOLAN 411x cards. Instead of taking over the whole card, the port is made to work through the BICC Multi Protocol Software, enabling NCSA Telnet TCP/IP to coexist with other network protocols, like Novells IPX. This port was initially made for the Institute of Social Research and the Institute of Applied Social Research for use on their Novell net, but since others might have interrest in this, I decided to put it on the net. The port has been in heavy use since the late spring of 1989 and should be fairly good. No known bugs at this point, but the code still has a flavour of an easy hack (it has not been changed due to the good proverb : "If it ain't broke, don't fix it"). The code has been written in a way so as if to make as few and as small changes to NCSA TELNET as possible. The program has been run towards a HP9000/825 and a Interactive 386/ix. Regarding the ownership of this code, it's still the authors property and will remain so even after the code has been posted to the net. But, the code can be used freely, as long as it's not being used commersially and all changes to the code are reported to me, so I can update and maintain this program. If somebody wants to use this code in commersial programs or put them under another licence, I must be consulted first. I'm not really opposed to this, but I won't let anybody change the copyright as they please. Please note that this code IS NOT A PART OF NCSA TELNET. If some people at NCSA finds it interresting, it might be at some point. This is written to indicate that neither NCSA nor I would commit ourselves to supporting this port in the future. But, when 2.3 appears, I will do my best to make this port work there as well. The port consists of two new files, ISO.C and MULTI.ASM which together make up the BICC support. I have also included PCTOOLS.C to show how the BICC support is wedged into NCSA TELNET (I assume I've done it the normal way). This program must be compiled with the symbol ISOLAN defined (all changes to the original code is #ifdef'ed). I've also included the updated MAKEFILE, adapted to MS C by Jyrki Kuoppala and changed by me to support the BICC port. I've used Microsoft C 5.1 for the port, but I believe I've kept ANSI-specific stuff out of it, so earlier versions should be able to compile it with few or no alterations. BTW: I've also rewritten the 3COM 501 driver for NCSA in C to make it easier to understand and maintain. With my crude tests, I cannot find any notable changes in speed, but the tests were done on an PC AT and maybe speed problems would be more appearant on a plain 4.77 MHz PC. I would suggest that drivers should, as long as speed allows it, be written in C, since this would also enhance portability of the drivers themselves and maybe the system as a whole. Please mail all questions and comments to: ingea@ifi.uio.no or during holydays to: inge%beatnix@ifi.uio.no Happy hacking! Inge Arnesen, University of Oslo, Norway #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # iso.c # multi.asm # pctools.c # makefile # This archive created: Wed Jan 17 14:14:32 1990 export PATH; PATH=/bin:$PATH echo shar: extracting "'iso.c'" '(15525 characters)' if test -f 'iso.c' then echo shar: will not over-write existing file "'iso.c'" else sed 's/^ X//' << \SHAR_EOF > 'iso.c' X/**************************************************************************** X * BICC 411x Multi Protocol Software code * X * Inge Arnesen 1989 * X * * X * Module to interface NCSA Telnet to the BICC 411x cards through the * X * ISOLAN Multi Protocol Software. This enables NCSA Telnet to coexist * X * with Novell Netware. * X * * X * THIS IS NOT A PART OF NCSA TELNET * X * * X **************************************************************************** X * * X * * X * (C) Inge Arnesen * X * Institute of Social Research * X * Munthesgt. 31 * X * N-0260 Oslo, NORWAY * X * * X * * X * DISCLAIMER: This code is not property of the institute, but of * X * the author himself. No responsibility is claimed * X * for anything whatsoever due to the use of this code! * X * * X **************************************************************************** X * * X * Created : 89.05.27 by Inge Arnesen * X * Last modified: 89.05.29 by Inge Arnesen * X * * X * History: 89.05.29 Initial alpha version * X * 89.07.01 Beta started - no changes * X * 89.10.06 Final release - no changes * X * * X **************************************************************************** X X ILrecv - Polled receive (dummy) X ILetopen - Initialize Ethernet SW X ILetclose - Close down Ethernet SW X ILgetaddr - Get Ethernet cards address (must be initialized first) X ILetaddr - Set Ethernet cards address (dummy) X ILxmit - Send data across the Ethernet X ILetupdate - Update buffer pointers X X X COMPILE: X cl -Ze -Zp -Gs iso.c X Options are: Enable language extentions, pack structure members, X Remove calls to Stack probe routine X X */ X/* Standard include files */ X#include /* Microsoft 'C' Include file */ X#include /* Microsoft 'C' Include file */ X#include /* Microsoft 'C' Include file */ X#include /* Microsoft 'C' Include file */ X#include /* Microsoft 'C' Include file */ X X/* NCSA include files */ X#include "protocol.h" X#include "data.h" X X/* X * Command codes for ISOLAN MPS SW X */ X X#define STATUS 0xB3 /* XPORT & SFB */ X X#define FAST_TIMER 0xF0 /* XPORT & SFB */ X#define L_ACTIVATE 0xF2 /* XPORT & SFB */ X#define L_DEACTIVATE 0xF3 /* XPORT & SFB */ X#define L_DATA_SEND 0xF4 /* XPORT & SFB */ X#define M_ACTIVATE 0xFA /* XPORT & SFB */ X#define M_DEACTIVATE 0xFB /* XPORT & SFB */ X X#define L_ACTIVATE_CONF 0x03 /* Returned Event Code */ X#define L_DEACTIVATE_CONF 0x05 /* Returned Event Code */ X#define L_DATA_IND 0x08 /* Returned Event Code, LLC Data */ X#define M_DATA_IND 0x0a /* Returned Event Code, Blue Book MAC Data */ X#define M_ACTIVATE_CONF 0x12 /* Returned Event Code */ X#define M_DEACTIVATE_CONF 0x14 /* Returned Event Code */ X X#define FALSE 0 X#define TRUE 1 X X#define BUF_SIZE 1504 X#define MAX_VC 32 X X X/* X * DATA STRUCTURES X */ X Xunion adr_ptr X{ X char far *pt; X struct X { X unsigned short start_type; X unsigned short end_type; X } type; X struct mps_status *status; X}; X Xstruct tcb /* Transfer Control Block */ X{ X unsigned char tcbcommand; /* command code */ X unsigned char tcbcid; /* command identity */ X unsigned char tcbvcid; /* virtual circuit id */ X unsigned short tcblength; /* buffer length */ X union adr_ptr tcbbaddr; /* address of data */ X unsigned char tcbexpedited; /* expedited data flag */ X unsigned char tcbcancelable; /* cancelable flag */ X unsigned char tcbladdr[16]; /* local network address */ X unsigned char tcbraddr[16]; /* remote address */ X unsigned short (far *tcbasync)(); /* address of async notification routine*/ X unsigned long tcblnet; /* local network number */ X unsigned long tcbrnet; /* remote network number */ X unsigned char tcbrto; /* call timeout */ X unsigned char tcbsto; /* not used */ X unsigned char tcbres2[8]; /* reserved */ X unsigned char tcbcmdex; /* command code extension */ X unsigned short tcbstatus; /* Blue Book MAC type */ X}; X X Xstruct acb /* Asynchronous Control Block */ X{ X unsigned char acbcid; /* return cid from TCB */ X unsigned char acbvcid; /* return vcid from TCB */ X unsigned char acberr; /* error code */ X unsigned char acbcmd; /* return command from TCB */ X unsigned short acblen; /* actual length of message */ X unsigned char acbraddr[16]; /* remote network address */ X unsigned long acbrnet; /* remote network number */ X unsigned char acbladdr[16]; /* local network address */ X unsigned long acblnet; /* local network number */ X unsigned short acbstatus; /* Blue Book MAC type */ X unsigned char acbeventcode; /* copy of board event code */ X union adr_ptr acbbaddr; /* address of data */ X unsigned char acbexpedited; /* expedited data flag */ X}; X Xstruct recany_rec /* receive any record */ X{ X unsigned char recany_count; X unsigned char recany_list[MAX_VC]; X}; X X Xstruct mps_status X{ X unsigned char address[16]; X unsigned long network; X unsigned char status; X unsigned char version; X unsigned int maxcon; X unsigned int maxcom; X unsigned long pack_sent; X unsigned long pack_rec; X unsigned int pack_lost; X unsigned int pack_abort; X unsigned int pack_frame; X unsigned int pack_crc; X unsigned char address_mask[16]; X unsigned int board_segment; X unsigned int board_offset; X unsigned int gen_tsel; X unsigned int broad_tsel; X unsigned char reserved[0x3e]; X}; X Xextern void ANR_ENTRY(); Xunsigned int anr_c(); Xstruct mps_status stat_buf; X X Xextern unsigned char rstat; /* last status from read */ Xextern unsigned char *bufpt; /* current buffer pointer */ Xextern unsigned char *buforg; /* pointer to beginning of buffer */ Xextern unsigned char *bufend; /* pointer to end of buffer */ Xextern unsigned char *bufread; /* pointer to where program is reading */ Xextern unsigned int bufbig; /* integer, how many bytes we have */ Xextern unsigned int buflim; /* integer, max bytes we can have */ X X XILgetaddr(ethaddr, memaddr, ioaddr) Xunsigned char ethaddr[DADDLEN]; Xunsigned int memaddr, ioaddr; X{ X int i; X struct tcb t, *h; X union REGS inregs, outregs; X struct SREGS segregs; X X /* Then send status request */ X t.tcbcommand = STATUS; X t.tcbcid = STATUS; X t.tcbbaddr.status= &stat_buf; X t.tcblength = sizeof(struct mps_status); X t.tcblnet= 0xffffffff; X X t.tcbasync= (void *)ANR_ENTRY; X X /* X * now issue the int5b, es:bx point at the tcb X * X */ X h= &t; X segregs.es= FP_SEG(h); X inregs.x.bx= FP_OFF(h); X int86x(0x5B, &inregs, &outregs, &segregs); X X for (i= 9; i < 15; i++) X ethaddr[i - 9]= stat_buf.address[i]; X} X XILrecv() X{ X} X XILetupdate() X{ X /* Update all the pointers etc. */ X bufbig-= *((int *)bufread) + sizeof( int ); X bufread+= *((int *)bufread) + sizeof(int); X if(bufread >= bufend) X bufread= buforg; X} X X X Xint ILxmit(pack, size) XDLAYER *pack; Xint size; X{ X struct tcb t, *h; X int i; X union REGS inregs, outregs; X struct SREGS segregs; X X t.tcbraddr[2] = 0; X t.tcbraddr[3] = 0; X t.tcbraddr[7] = 0; X t.tcbraddr[8] = 0; /* LSAP */ X t.tcbraddr[9] = pack->dest[0]; /* ETHADDR */ X t.tcbraddr[10] = pack->dest[1]; X t.tcbraddr[11] = pack->dest[2]; X t.tcbraddr[12] = pack->dest[3]; X t.tcbraddr[13] = pack->dest[4]; X t.tcbraddr[14] = pack->dest[5]; /*--to here--*/ X t.tcbraddr[15] = 0; X t.tcbcommand = L_DATA_SEND; X X t.tcbstatus = intswap(pack->type); X for (i = 0; i < 16; ++i) X t.tcbladdr[i] = 0; X X t.tcbasync= 0; /* No ANR */ X X /* setup pointer to data buffer */ X t.tcbbaddr.pt = (char far *)pack + sizeof(DLAYER); X t.tcblength = size - sizeof(DLAYER); X /* X * now issue the int5b, es:bx point at the tcb X * X */ X h= &t; X segregs.es= FP_SEG(h); X inregs.x.bx= FP_OFF(h); X int86x(0x5B, &inregs, &outregs, &segregs); X return(outregs.h.al); X} X XILetopen(ethaddr, ioirq, memaddr, ioaddr) Xunsigned char ethaddr[DADDLEN]; Xunsigned int memaddr, ioaddr; X{ X struct tcb t, *h; X int i; X union REGS inregs, outregs; X struct SREGS segregs; X X X t.tcbcommand = L_ACTIVATE; X t.tcbcid = L_ACTIVATE; X X for (i = 0; i < 16; ++i) X t.tcbladdr[i] = 0; X X t.tcbasync= (void *)ANR_ENTRY; X X /* X * now issue the int5b, es:bx point at the tcb X * X */ X h= &t; X segregs.es= FP_SEG(h); X inregs.x.bx= FP_OFF(h); X int86x(0x5B, &inregs, &outregs, &segregs); X X return(outregs.h.al); X} X XILetclose() X{ X union REGS inregs, outregs; X struct SREGS segregs; X struct tcb t, *h; X int i; X X t.tcbcommand = L_DEACTIVATE; X t.tcbcid = 0; /* Not used */ X X for (i = 0; i < 16; ++i) X t.tcbladdr[i] = 0; X X /* X * now issue the int5b, es:bx point at the tcb X * X */ X h= &t; X segregs.es= FP_SEG(h); X inregs.x.bx= FP_OFF(h); X int86x(0x5B, &inregs, &outregs, &segregs); X return(outregs.h.al); X} X X X/* X * Note: anr_c returns zero to the Multi Protocol Handler X * X * Inside the ANR, Operating System calls must not be made, nor must X * space be grabbed from the Heap. The use of Automatic variables X * is allowed, but make sure the stack is large enough. X */ X Xunsigned int anr_c(acb_ptr) Xstruct acb *acb_ptr; X{ X int i; X int mine= TRUE; /* We suspect all packets of coming from this card */ X /* Loop back is supported on link level */ X /* If its mine, drop it like a hot potato */ X X char far *buffer_pt; /* buffer pointer */ X X if(acb_ptr->acbcmd != STATUS) X { X switch(acb_ptr->acbeventcode) X { X case L_ACTIVATE_CONF: X break; X case L_DATA_IND: X case M_DATA_IND: X /* If it is not one of mine, mark it as such */ X for(i= 0; i < 6 ; i++) X if(acb_ptr->acbraddr[i+9] != nnmyaddr[i]) X { X mine= FALSE; X break; X } X if (!mine) X { X /* with llc and mac commands, it's neccessary to copy */ X /* the received data. */ X X buffer_pt = acb_ptr->acbbaddr.pt; X /* The above instruction in theory should not be needed */ X /* but is in practise */ X X if(bufbig <= buflim) /* Enough room in the buffer ? */ X { X if(bufpt >= bufend) /* Wrap around ? */ X { X bufpt= buforg; X } X /* Size of packet inc. DLAYER first in buffer */ X *((int *)bufpt)= acb_ptr->acblen + sizeof(DLAYER); X bufpt+= 2; X ((DLAYER *)bufpt)->type= intswap(acb_ptr->acbstatus); X for(i= 0; i < 6 ; i++) X { X ((DLAYER *)bufpt)->dest[i]= X acb_ptr->acbladdr[i+9]; X ((DLAYER *)bufpt)->me[i]= X acb_ptr->acbraddr[i+9]; X } X bufpt+= sizeof(DLAYER); X movedata(FP_SEG( buffer_pt ), FP_OFF( buffer_pt ), X FP_SEG(bufpt), FP_OFF(bufpt), acb_ptr->acblen); X bufpt+= acb_ptr->acblen; X bufbig+= acb_ptr->acblen + sizeof(DLAYER) + sizeof(int); X } X /* else we are going to drop packets ! */ X } X break; X } X } X return(0); X} X SHAR_EOF if test 15525 -ne "`wc -c < 'iso.c'`" then echo shar: error transmitting "'iso.c'" '(should have been 15525 characters)' fi fi # end of overwriting check echo shar: extracting "'multi.asm'" '(1909 characters)' if test -f 'multi.asm' then echo shar: will not over-write existing file "'multi.asm'" else sed 's/^ X//' << \SHAR_EOF > 'multi.asm' XTITLE 'MULTI.ASM' X; X; These assembler routine provide an interface between the code X; written in 'C' and the Multi Protocol Handler. X; X X.model large X X; X; Data Structures X; X.data X X; X; The Asynchronous Notification Routine Stack X; X; Size of stack is XSTACK_SIZE EQU 100h X; X DW STACK_SIZE DUP (?) XSTACK_START DW ? X X; X; Area to save Multi Protocol Handler Stack Pointer X; XSS_SAVE DW ? XSP_SAVE DW ? X; X X; X; Start of Code X; X X X.code X XEXTRN _anr_c : FAR X XPUBLIC _ANR_ENTRY X X_ANR_ENTRY PROC X X; X; This routine is the ANR entry point. It is called by the X; Multi Protocol Handler, via a far call. Before calling the main X; ANR routine (written in 'C'), it sets up the Data Segment, saves X; the Multi Protocol Handler's stack, and allocates a new stack. X; Before returning to the Multi Protocol Handler, it restores its X; stack. X; X; The ANR routine (written in 'C') must not make use of the heap, X; nor should it try to access to access automatic variables declared X; in main(), because the stack it has been allocated is NOT the same X; as the standard 'C' stack. X; X X MOV AX, DGROUP ; Get Data Segement X MOV DS, AX ; Set up DS X X MOV SS_SAVE, SS ; Save Stack Pointers X MOV SP_SAVE, SP ; X X MOV SS, AX ; Set up Stack Segment X LEA SP, STACK_START ; X X PUSH ES ; The address of the ACB is passed as X PUSH BX ; a far pointer. X X CLD X X CALL _anr_c ; Call 'C' ANR routine X ; _ANR_C returns a parameter in AX X X MOV SS, SS_SAVE ; Restore Stack Pointers X MOV SP, SP_SAVE X X RET X_ANR_ENTRY ENDP X X END X SHAR_EOF if test 1909 -ne "`wc -c < 'multi.asm'`" then echo shar: error transmitting "'multi.asm'" '(should have been 1909 characters)' fi fi # end of overwriting check echo shar: extracting "'pctools.c'" '(11904 characters)' if test -f 'pctools.c' then echo shar: will not over-write existing file "'pctools.c'" else sed 's/^ X//' << \SHAR_EOF > 'pctools.c' X/* X* pctools.c X**************************************************************************** X* * X* part of: * X* TCP/UDP/ICMP/IP Network kernel for NCSA Telnet * X* by Tim Krauskopf * X* * X* National Center for Supercomputing Applications * X* 152 Computing Applications Building * X* 605 E. Springfield Ave. * X* Champaign, IL 61820 * X* * X**************************************************************************** X* X* those generic tool-type things that only work on PCs. X* includes all hardware-level calls to Ethernet that are unique to the PC X* X* Function pointers for Ether calls X*/ X#include "stdio.h" X#include "protocol.h" X#include "data.h" X X/* X* defined in assembly language file for interrupt driven Ether buffering X* X*/ X#ifdef MSC Xextern unsigned char rstat; /* status from last read */ Xextern char *bufpt,*bufend,*bufread,*buforg; Xextern int bufbig,buflim; X#else Xunsigned char rstat; /* status from last read */ Xchar *bufpt,*bufend,*bufread,*buforg; Xint bufbig,buflim; X#endif /* MSC */ X X/* X* Declare each and every Ethernet driver. X* To add a driver, pick a unique 2 char prefix and declare your own X* routines. I want to keep the same parameters for EVERY driver. X* If your driver needs additional parameters, then see netconfig() below X* for an indication of where to put custom board code. X*/ Xextern int E1etopen(),E1getaddr(),E1setaddr(),E1recv(),E1xmit(),E1etupdate(),E1etclose(); Xextern int E3etopen(),E3getaddr(),E3setaddr(),E3recv(),E3xmit(),E3etupdate(),E3etclose(); Xextern int M5etopen(),M5getaddr(),M5recv(),M5xmit(),M5etupdate(),M5etclose(); Xextern int U1etopen(),U1getaddr(),U1recv(),U1xmit(),U1etupdate(),U1etclose(); Xextern int U2etopen(),U2getaddr(),U2recv(),U2xmit(),U2etupdate(),U2etclose(); Xextern int WDetopen(),WDgetaddr(),WDrecv(),WDxmit(),WDetupdate(),WDetclose(); Xextern int E2etopen(),E2getaddr(),E2recv(),E2xmit(),E2etupdate(),E2etclose(); X#ifdef ISOLAN Xextern int ILetopen(),ILgetaddr(),ILrecv(),ILxmit(),ILetupdate(),ILetclose(); X#endif X Xstatic int (*etopen)()=NULL, /* open the device */ X (*getaddr)()=NULL, /* get the Ether address */ X (*setaddr)()=NULL, /* set the Ether address to use */ X (*recv)()=NULL, /* load a packet from queue */ X (*etupdate)()=NULL, /* update pointers in buffer */ X (*etclose)()=NULL, /* shut down network */ X (*xmit)()=NULL; /* transmit a packet */ X X X/**********************************************************************/ X/* statcheck X* look at the connection status of the memory buffers to see if the X* allocation schemes are working. Only used as a debug tool. X*/ Xstatcheck() X { X int i; X struct port *p; X X for (i=0; i<20; i++) { X printf("\n%d > ",i); X p = portlist[i]; X if (p != NULL) X printf("state: %d %5u %5u %10ld %5d %5d", X p->state,intswap(p->tcpout.t.source), X intswap(p->tcpout.t.dest),p->out.lasttime,p->rto, X p->out.contain); X } X} X X/*************************************************************************/ X/* config network parameters X* Set IRQ and DMA parameters for initialization of the 3com adaptor X*/ Xstatic int nnirq=3,nnaddr=0xd000,nnioaddr=0x300; X Xnetparms(irq,address,ioaddr) X int irq,address,ioaddr; X { X X nnirq = irq; X nnaddr = address; X nnioaddr = ioaddr; X X return(0); X} X X/**********************************************************************/ X/* netconfig X* load the function pointers for network access X* Currently setaddr() is not used, so it isn't loaded. X* X* Note that netparms is called BEFORE netconfig. So if you have any X* really special variables to set for your board that involve X* irq,address and ioaddr, you can add calls to your special routines X* in this section. X* X* Some drivers will do the interrupt driver and board initialization X* in etopen() and some will do it in getaddr(). X*/ Xnetconfig(s) X char *s; X { X X if (!strncmp(s,"ni5",3) || !strncmp(s,"mi",2)) { X etopen = M5etopen; X xmit = M5xmit; X recv = M5recv; X getaddr = M5getaddr; X etupdate = M5etupdate; X etclose = M5etclose; X/* X* special initialization call would go here X*/ X } X else if (!strncmp(s,"nicps",5)) { X etopen = U2etopen; X xmit = U2xmit; X recv = U2recv; X getaddr = U2getaddr; X etupdate = U2etupdate; X etclose = U2etclose; X } X else if (!strncmp(s,"nicpc",5) || !strncmp(s,"pcnic",5)) { X etopen = U1etopen; X xmit = U1xmit; X recv = U1recv; X getaddr = U1getaddr; X etupdate = U1etupdate; X etclose = U1etclose; X } X else if (!strncmp(s,"wd",2) || !strncmp(s,"800",3)) { X etopen = WDetopen; X xmit = WDxmit; X recv = WDrecv; X getaddr = WDgetaddr; X etupdate = WDetupdate; X etclose = WDetclose; X } X else if (!strncmp(s,"3c523",5) || !strncmp(s,"523",3)) { X etopen = E2etopen; X xmit = E2xmit; X recv = E2recv; X getaddr = E2getaddr; X etupdate = E2etupdate; X etclose = E2etclose; X } X else if (!strncmp(s,"r501",4)) { /* special reserve driver */ X etopen = E3etopen; X xmit = E3xmit; X recv = E3recv; X getaddr = E3getaddr; X etupdate = E3etupdate; X etclose = E3etclose; X } X#ifdef ISOLAN X else if (!strncmp(s,"iso",3)) { X etopen = ILetopen; X xmit = ILxmit; X recv = ILrecv; X getaddr = ILgetaddr; X etupdate = ILetupdate; X etclose = ILetclose; X } X#endif X else if (!strncmp(s,"3c",2) || 1) { /* default choice */ X etopen = E1etopen; X xmit = E1xmit; X recv = E1recv; X getaddr = E1getaddr; X etupdate = E1etupdate; X etclose = E1etclose; X } X X} X X/**********************************************************************/ X/* netarpme X* send an arp to my address. arpinterpret will notice any response. X* Checks for adapters which receive their own broadcast packets. X*/ Xnetarpme(s) X char *s; X { X X if (etopen == U2etopen) X return(0); X if (etopen == U1etopen) X return(0); X X reqarp(s); /* send it */ X X return(0); X} X X X/**********************************************************************/ X Xinitbuffer() X { X X bufpt = bufread = buforg = raw; /* start at the beginning */ X X bufend = &raw[14500]; /* leave 2K breathing room, required */ X buflim = 12000; /* another 2K breathing room */ X X (*getaddr)(nnmyaddr,nnaddr,nnioaddr); X X return(0); X} X X/**********************************************************************/ X/* demux X* find the packets in the buffer, determine their lowest level X* packet type and call the correct interpretation routines X* X* the 'all' parameter tells demux whether it should attempt to empty X* the input packet buffer or return after the first packet is dealt with. X* X* returns the number of packets demuxed X*/ Xdemux(all) X int all; X { X uint16 getcode; X int nmuxed; X DLAYER *firstlook; X X nmuxed = 0; X if (!etupdate) /* check that network is hooked up */ X return(0); X X do { /* while all flag is on */ X X (*recv)(); /* NULL operation for 3COM */ X X if (bufbig > 0) { X X nmuxed++; X firstlook = (DLAYER *)(bufread+2); /* where packet is */ X X getcode = firstlook->type; /* where does it belong? */ X X switch (getcode) { /* what to do with it? */ X case EARP: X case ERARP: X arpinterpret(firstlook); /* handle ARP packet */ X break; X case EIP: X ipinterpret(firstlook); X break; X default: X break; X } X X (*etupdate)(); /* update read pointers in buffer, free packet */ X X } X else X all = 0; X X X } while (all); /* should we look for more to deal with? */ X X X return(nmuxed); /* no packets anymore */ X X} X X/************************************************************************/ X/* dlayersend X* X* usage: err = dlayersend(ptr,size) X* err = 0 for successful, non-zero error code otherwise X* ptr is to a dlayer packet header X* size is the number of bytes total X* X* This particular dlayer routine is for Ethernet. It will have to be X* replaced for any other dlayer. X* X* Ethernet addresses are resolved at higher levels because they will only X* need to be resolved once per logical connection, instead of once per X* packet. Not too layer-like, but hopefully modular. X* X*/ X Xdlayersend(ptr,size) X DLAYER *ptr; X unsigned size; X { X int ret; X X ret = (*xmit)(ptr,size); /* send it out, pass back return code */ X /* xmit checks for size < 60 */ X X/* X* automatic, immediate retry once X*/ X if (ret) { X if (ret == (*xmit)(ptr,size)) X nnerror(100); /* post user error message */ X } X X return(ret); X} X X/***************************************************************************/ X/* dlayerinit X* Do machine dependent initializations of whatever hardware we have X* (happens to be ethernet board here ) X*/ Xdlayerinit() X { X X if (initbuffer() || !etopen) X return(-1); X X return((*etopen)(nnmyaddr,nnirq,nnaddr,nnioaddr)); X} X Xdlayershut() X { X if (etclose) X (*etclose)(); X} X X/***************************************************************************/ X/* pcgetaddr X* return results from indirect getaddr call. X* This is a pc-specific request for the 48-bit address which was added X* so that the user program could print the value. X*/ Xpcgetaddr(s,x,y) X char *s; X int x,y; X { X if (getaddr) X (*getaddr)(s,x,y); X} SHAR_EOF if test 11904 -ne "`wc -c < 'pctools.c'`" then echo shar: error transmitting "'pctools.c'" '(should have been 11904 characters)' fi fi # end of overwriting check echo shar: extracting "'makefile'" '(4342 characters)' if test -f 'makefile' then echo shar: will not over-write existing file "'makefile'" else sed 's/^ X//' << \SHAR_EOF > 'makefile' X# Makefile for NCSA telnet version 2.2S with added features by jkp@hutcs.hut.fi X# Author: Jyrki Kuoppala (jkp@hutcs.hut.fi) X# Last modified: 89.05.25 by Inge Arnesen (ingea@ifi.uio.no) X X# Assumes that you have LIB and INCLUDE environment variables X# set to proper values for your compiler X X# I haven't tested the lattice version of makefile. X# All knowledge I have about lattice is from the 'compile.bat' X# script, so you should probably study the flags and change them X# if necessary X X# Change the value of CC to lc if you have lattice, cl if msc. X# It should be enough, but probably you need to change lattice part X# Or, just say 'gmake CC=lc' or 'gmake CC=cl' X XCC=cl X#CC=lc X X# Use this if backspace mapping doesn't work with you. X# If you use it, however, ^H isn't ^H if mapping is on. X X#BUGSPACE=-DBugspace X X#ifeq ($(CC),cl) X# Use this for MSC 5.0. Stack-checking is suppressed ; the interrupt X# routine setup doesn't work with it and I don't like the compiler generating X# code I haven't asked for anyhow :-) XCFLAGS= -c -Otl -AL -DMSC -Itek -Ivs -Ienet -Iftp -I. -Gs -Zpi -DISOLAN XASFLAGS=-Itek -Ivs -Ienet -DMicrosoft $(BUGSPACE) X#else X# For lattice, untested X# remove -qd: if you don't have a ram disk called d: X#CFLAGS= -ml -qd: X#ASFLAGS=-Itek -Ivs -Ienet -DLattice $(BUGSPACE) X#endif X XVPATH=.\vs:.\tek:.\enet:.\ftp X XAS=masm XLIB=lib XLIBFLAGS= XLINK=link XSTACK=/stack:4096 XLINKFLAGS=/CO XRM=command /c del X X#LDFLAGS=/Fencsa /AL X X#.SUFFIXES: .c .o .obj .exe .asm X X.c.obj: X $(CC) $(CFLAGS) /Fo$*.obj $< X X.asm.obj: X $(AS) $(ASFLAGS) $<, $*.obj ; X Xall: minitel.exe telpass.exe telbin.exe finger.exe ftpbin.exe X Xtcp1m.lib : tcp.obj ip.obj dlayer.obj tools.obj multi.obj iso.obj pctools.obj enet\net8003.obj \ X enet\net3com.obj enet\net501.obj enet\net5210.obj enet\net523.obj \ X enet\netzyp.obj enet\netub.obj \ X protinit.obj user.obj ipasm.obj X $(RM) tcp1m.lib X $(LIB) $(LIBFLAGS) tcp1m.lib +tcp +ip +dlayer +tools +iso+multi+pctools ; X $(LIB) $(LIBFLAGS) tcp1m.lib+protinit+user+ipasm+\ X enet\net8003+enet\net3com+enet\netzyp+enet\net501+enet\net5210+enet\net523+enet\netub ; X Xsessm.lib : util.obj pcutil.obj bkgr.obj confile.obj X $(RM) sessm.lib X $(LIB) $(LIBFLAGS) sessm.lib +util +pcutil +bkgr +confile ; X Xvs.lib: vs\vsinterf.obj vs\vsem.obj vs\vsintern.obj X $(RM) vs.lib X $(LIB) $(LIBFLAGS) vs.lib +vs\vsinterf +vs\vsintern +vs\vsem ; X Xtek.lib: tek\vgtek.obj tek\tekstor.obj tek\egaset.obj tek\rg0.obj tek\rge.obj tek\rgc.obj \ X tek\rgh.obj tek\rgp.obj tek\rghp.obj tek\rg9.obj X $(RM) tek.lib X $(LIB) $(LIBFLAGS) tek.lib +tek\vgtek +tek\tekstor +tek\rg0 +tek\rge +tek\rgc \ X +tek\rgh +tek\rgp +tek\rghp +tek\rg9 +tek\egaset ; X Xtelbin.exe : look.obj ncsaio.obj rspc.obj tek.lib sessm.lib tcp1m.lib vs.lib X $(LINK) $(LINKFLAGS) $(STACK) look+ncsaio+rspc,telbin,nul,tek+tcp1m+sessm+vs ; X Xtelpass.exe : telpass.obj ncsaio.obj X $(LINK) $(LINKFLAGS) telpass+ncsaio,telpass,nul ; X Xftpbin.exe : ftp\ftpbin.obj ncsaio.obj tcp1m.lib sessm.lib X $(LINK) $(LINKFLAGS) ftp\ftpbin+ncsaio,ftpbin,nul,tcp1m+sessm ; X Xminitel.exe : minitel.obj ncsaio.obj tcp1m.lib sessm.lib X $(LINK) $(LINKFLAGS) minitel+ncsaio,minitel,nul,tcp1m+sessm ; X Xfinger.exe : finger.obj ncsaio.obj tcp1m.lib sessm.lib X $(LINK) $(LINKFLAGS) finger+ncsaio,finger,nul,tcp1m+sessm ; X Xtar: X (cd .. ; tar cf hackedsrc.tar source ) X Xclean: X $(RM) *.obj X $(RM) make.out X $(RM) *.exe X $(RM) *.lib X $(RM) *.bak X Xftpbin.obj : ftp\ftpbin.c ftp\ftppi.h X Xbkgr.obj: bkgr.c whatami.h hostform.h Xconfile.obj: confile.c whatami.h hostform.h Xdlayer.obj: dlayer.c protocol.h data.h Xfinger.obj: finger.c whatami.h hostform.h Xip.obj: ip.c protocol.h data.h Xlook.obj: look.c whatami.h nkeys.h windat.h hostform.h Xminitel.obj: minitel.c whatami.h hostform.h Xiso.obj: iso.c protocol.h data.h X Xmulti.obj: multi.asm X masm -Zi -Ml multi.asm; X Xpctools.obj: pctools.c protocol.h data.h Xpcutil.obj: pcutil.c whatami.h Xprotinit.obj: protinit.c protocol.h data.h whatami.h Xrspc.obj: rspc.c whatami.h windat.h vskeys.h nkeys.h Xtcp.obj: tcp.c protocol.h data.h Xtools.obj: tools.c protocol.h data.h Xuser.obj: user.c protocol.h data.h Xutil.obj: util.c whatami.h hostform.h SHAR_EOF if test 4342 -ne "`wc -c < 'makefile'`" then echo shar: error transmitting "'makefile'" '(should have been 4342 characters)' fi fi # end of overwriting check # End of shell archive exit 0