home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GRIPS 2: Government Rast…rocessing Software & Data
/
GRIPS_2.cdr
/
dos
/
ncsa_tel
/
contribu
/
byu_tel2.hqx
/
tcpip
/
mactools.c
< prev
next >
Wrap
Text File
|
1989-07-10
|
10KB
|
409 lines
/*
* mactools.c by Gaige B. Paulsen
*
* adapted from pctools.c by Tim Krauskopf
****************************************************************************
* *
* part of: *
* TCP/UDP/ICMP/IP Network kernel for NCSA Telnet *
* by Tim Krauskopf *
* *
* National Center for Supercomputing Applications *
* 152 Computing Applications Building *
* 605 E. Springfield Ave. *
* Champaign, IL 61820 *
* *
* *
****************************************************************************
*
* those generic tool-type things that only work on Macs.
* includes all hardware-level calls to Ethernet that are unique to the Mac
*
*/
#include "stdio.h"
#include "protocol.h"
#include "data.h"
#include <Files.h>
#include <AppleTalk.h>
#include <Events.h>
#include "ethertalk.h"
#include "atalk.h" /* Dlayer to atalk conversion */
#ifdef MPW
#define movmem(y,x,z) memcpy(x,y,z)
#endif
/*
* THE ALL-POWERFUL VARIABLE !!!!!!!!!!
*/
int EtherNet=0; /* Default to AppleTalk */
/**********************************************************************/
/* netarpme
* send an arp to my address. arpinterpret will notice any response.
* Checks for adapters which receive their own broadcast packets.
*/
netarpme(s)
char *s;
{
if (EtherNet) {
reqarp(s);
}
return(0);
}
/************************************************************************/
/* dlayersend
*
* usage: err = dlayersend(ptr,size)
* err = 0 for successful, non-zero error code otherwise
* ptr is to a dlayer packet header
* size is the number of bytes total
*
* This particular dlayer routine is for Ethernet. It will have to be
* replaced for any other dlayer.
*
* Assumes that dlayer-dependent initializations were made in protinit.c
* to help efficiency.
*
* Ethernet addresses are resolved at higher levels because they will only
* need to be resolved once per logical connection, instead of once per
* packet. Not too layer-like, but hopefully modular.
*
*/
dlayersend(ptr, size)
DLAYER *ptr;
int size;
{
if (EtherNet== 0)
return( ATdlayersend(ptr,size));
if (EtherNet==-2)
return( FNdlayersend(ptr,size));
else
return( ETdlayersend(ptr,size));
}
/*
* ATdlayersend (ptr, size)
* send size from ptr out the AT port
* All outgoing conversions done here !
*/
ATdlayersend(ptr,size) /*MAC: replaced */
ARPKT *ptr;
unsigned size;
{
char *todata;
int *destptr, ptype, tsize;
char wds[14], header[18];
MPPParamBlock pb;
static ATARPKT arpbuffer;
int err,lowadd,highadd;
ptype = AIP; /* Default to sending an IP Packet */
pb.DDPsocket=IPSock; /* Sorry.... */
pb.DDPchecksumFlag=FALSE; /* who knows why, but we don't */
pb.DDPwdsPointer=wds; /* Here we go..... */
pb.MPPcsCode=246; /* We want to send a packet */
todata=(char *)ptr + sizeof(DLAYER); /* Point at the real data... */
destptr=&ptr->d.dest[0]; /* Where is the destination ? */
tsize = size- sizeof(DLAYER); /* Get transmission size */
if (!memcmp( destptr, bseed, 6)) /* Watch for Broadcasts */
movmem(ATbseed, destptr, 4);
if (ptr->d.type == EARP) {
ptype=AARP; /* Arp packet */
arpbuffer.hrd = 3; /* ATalk */
arpbuffer.hln = 4;
arpbuffer.pln = 4;
arpbuffer.pro = ptr->pro;
arpbuffer.op = ptr->op;
movmem( &ptr->sha[0], &arpbuffer.sha[0], 4); /* Move addresses */
movmem( &ptr->spa[0], &arpbuffer.spa[0], 4);
movmem( &ptr->tha[0], &arpbuffer.tha[0], 4);
movmem( &ptr->tpa[0], &arpbuffer.tpa[0], 4);
todata= &arpbuffer;
todata+= sizeof(ATdlayer); /* New address to go from */
tsize = sizeof(ATARPKT)- sizeof(ATdlayer);
}
#ifdef MPW
BuildDDPwds( wds, header, todata, *((AddrBlock *)destptr), ptype, tsize );
#else
highadd= *destptr++; /* Get the address */
lowadd= *destptr++;
BuildDDPwds( wds, todata, tempptr, lowadd, highadd, ptype , tsize );
#endif
err=PWriteDDP( &pb, FALSE);
if (err!=0) putln("DDPW Error = %d");
#ifdef SENDNOTICE
else putln("send");
#endif
return(err);
}
/**********************************************************************/
/* demux
* find the packets in the buffer, determine their lowest level
* packet type and call the correct interpretation routines
*
* the 'all' parameter tells demux whether it should attempt to empty
* the input packet buffer or return after the first packet is dealt with.
*
* returns the number of packets demuxed
*/
demux(all)
int all;
{
if (EtherNet==0)
return( ATdemux(all));
if (EtherNet==-2)
return( FNdemux(all));
else
return( ETdemux(all));
}
ATdemux(all)
int all;
{
unsigned getcode;
int nmuxed,sizered, count;
ATARPKT *firstlook;
static ARPKT arpbuffer;
nmuxed = 0;
do { /* while all flag is on */
if (bufinfo.bufbig > 0) {
nmuxed++;
firstlook = (ATARPKT *)(bufinfo.bufread); /*MAC where packet is */
getcode = firstlook->d.type; /* where does it belong? */
count = firstlook->d.count;
movmem( firstlook->d.dest, arpbuffer.d.dest,4);
movmem( firstlook->d.me, arpbuffer.d.me ,4);
switch (getcode) { /* what to do with it? */
case AARP:
arpbuffer.d.type=EARP; /* Arp packet */
arpbuffer.hrd = 1; /* Enet */
arpbuffer.hln = 6;
arpbuffer.pln = 4;
arpbuffer.pro = firstlook->pro;
arpbuffer.op = firstlook->op;
movmem( &firstlook->sha[0], &arpbuffer.sha[0], 4); /* Move addresses */
movmem( &firstlook->spa[0], &arpbuffer.spa[0], 4);
movmem( &firstlook->tha[0], &arpbuffer.tha[0], 4);
movmem( &firstlook->tpa[0], &arpbuffer.tpa[0], 4);
#ifdef OLDM
putln("AARP");
#endif
arpinterpret(&arpbuffer); /* handle ARP packet */
break;
case AIP:
arpbuffer.d.type=EIP;
movmem( &arpbuffer, firstlook, sizeof(DLAYER) );
ipinterpret(firstlook);
break;
default:
break;
}
sizered = count + sizeof(DLAYER);
bufinfo.bufbig-=sizered;
bufinfo.bufread+=(sizered+1) & 0xFFFE;
if (bufinfo.bufbig<0) bufinfo.bufbig=0;
if (bufinfo.bufread>bufinfo.bufend) bufinfo.bufread=bufinfo.buforg;
}
else
all = 0;
} while (all); /* should we look for more to deal with? */
return(nmuxed); /* no packets anymore */
}
/*****************************************************************
* E T H E R N E T / E T H E R T A L K *
*****************************************************************/
struct ETHERWDSstruct {
short len1;
DLAYER *ptr1;
short len2;
DLAYER *ptr2;
short term;
} EWDS;
ETdlayersend(ptr,size) /*MAC: replaced */
DLAYER *ptr;
unsigned size;
{
EtParam ET;
int err;
EWDS.len1=size; /* Could it would it in a WDS? */
EWDS.ptr1=ptr;
EWDS.len2=0;
ET.address = &EWDS;
err=ETcall( &ET, EWrite);
if (err!=0) putln("ETW Error = %d");
#ifdef SENDNOTICE
else putln("send");
#endif
return(err);
}
/**********************************************************************/
/* ETdemux - Ethernet Version of DEMUX routine
*
* returns the number of packets demuxed
*/
ETdemux(all)
int all;
{
unsigned getcode;
int nmuxed,sizered;
typedef struct peek {
unsigned short count;
unsigned char dest[DADDLEN],
me[DADDLEN];
unsigned short type;
} Dpeek;
Dpeek *firstlook;
nmuxed = 0;
do { /* while all flag is on */
if (bufinfo.bufbig > 0) { /*MAC*/
nmuxed++;
firstlook = (Dpeek *)(bufinfo.bufread); /*MAC where packet is */
getcode = firstlook->type; /* where does it belong? */
switch (getcode) { /* what to do with it? */
case EARP:
case ERARP:
arpinterpret(firstlook->dest); /* handle [R]ARP packet */
break;
case EIP:
ipinterpret(firstlook->dest); /* handle IP packet */
break;
default:
break;
}
sizered=(firstlook->count+sizeof(Dpeek));
bufinfo.bufbig-=sizered;
#ifdef DEBUGONLY
{
char s[60];
sprintf(s,"buf: %d, pkt: %d",bufinfo.bufbig,sizered);
putln(s);
}
#endif
bufinfo.bufread+=(sizered+1) & 0xFFFE;
if (bufinfo.bufbig<0) bufinfo.bufbig=0;
if (bufinfo.bufread>bufinfo.bufend) bufinfo.bufread=bufinfo.buforg;
}
else {
if (ETdeafreset()) {
/* clear deaf flag, buffer overrun */
putln("warning: buffer deaf, restarting");
}
all = 0;
}
} while (all); /* should we look for more to deal with? */
return(nmuxed); /* no packets anymore */
}
initbuffer()
{
int i;
raw=malloc(17000); /* Added by GBP */
if (raw==NULL) return(-1);
bufinfo.bufpt = bufinfo.bufread = bufinfo.buforg
= raw; /* start at the beginning */
bufinfo.bufend = raw+14500; /* leave 2K breathing room, required */
bufinfo.buflim = 12000; /* another 2K breathing room */
bufinfo.bufbig = 0; /* Added by GBP */
if (EtherNet==0)
InitBufPtr(&bufinfo);
else if (EtherNet != -2)
ETInitBufPtr( &bufinfo);
return(0);
}
/***************************************************************************/
/* dlayerinit
* Do machine dependent initializations of whatever hardware we have
* (happens to be 3com ethernet board here )
*/
dlayerinit()
{
if (initbuffer())
return(-1);
if (EtherNet==0)
return(atopen());
if (EtherNet==-2)
return(FNopen());
else
return(ETopen(EtherNet)); /* Pass the Type along */
}
dlayershut()
{
if (EtherNet==0)
return(atclose());
if (EtherNet==-2)
return(FNclose());
else
return(ETclose());
}