[comp.protocols.appletalk] Other problems with KFPS/KIP/CAP

brad@saturn.ucsc.edu.UUCP (07/31/87)

Inspired by the response to the last KIP/CAP problem... here's the
scenario:

---------------------------------------------------------------------------
	Berkeley 4.2BSD
	68020 (ISI) Machine
	128.114.130.10
	CAP 4.0 w/pat5.shar		Conection to the Internet
		|				|
	---------------------------------------------- Ethernet (128.114.130.*)
	      |				   |		Subnetted class B net
           KFPS-2		      Berkeley 4.3BSD
   (w/ old "prompt" program)	      VAX 11/780 (running nameserver)
   KIP 0287 w/ gw.srec.5	      128.114.130.3/128.114.129.1
	      |				   |
   -------------------- AppleTalk    ----------------- Ethernet 129 Subnet
     |	       | ... 			|	|...   (128.114.129.*)
LaserWriter  Mac+		     Various BSD Unix machines...

---------------------------------------------------------------------------

The problems:

	- running telnet (both the one distributed with the Kbox and
	  the one that came with KIP) using a machine name, times out
	  attempting to connect to the nameserver on the VAX.
	- telneting to a machine on the 129 (or any other) subnet
	  times out (while I can connect to anywhere else I've tried
	  on the Internet).

Following are the configuration files:

--------- atalk.local ---------
1.130 10 TWILIGHT
1.130 220 128.114.130.220
-------------------------------

--------- atalkatab ---------
1.130	H	128.114.130.220	TWILIGHT	#applesci net
2.200	KC	128.114.130.220	TWILIGHT	#CIS at net
	I128.114.130.0	I128.114.130.3		#ipbroad ipname
	I128.114.130.10	I128.114.130.10		#ipdebug ipfile
	L0 L0 L0 L0	S0 S0			#ipother unused unused
	LX0		S2	S6		#flags ipstatic ipdynamic
	S2.200	S1.130	"TWILIGHT"		#atneta atnete zonea
------------------------------

--------- cisce.config ---------
* Config file for KFPS, KIP version, 10/86.
*
* A future version of the 'prompt' program will recognize
* a line containing a 'dot format' address and convert those
* four decimal byte values to four hex bytes(?)
*
* These bytes are ignored but must be left as placeholders: 
0000 0000 FF FF FF 00 000000 000000
* 00FF 0008 FFFFFF 00 000000 000000
* Gateway name (in this example, "cisce")
636973636500000000000000000000000000000000
* File name (in this example, "at-gw.srec.3"): 
61742D67772E737265632E35000000000000000000
* reserved (this field should be 00FF): 
00FF
*
* Start of 'mandatory' parameters, the minimum information that
* must be supplied for the gateway to begin operation.
*
* IP address of myself, 'ipaddr'
* 128.114.130.220
807282DC
* IP addr of admin host
* 128.114.130.1
8072820A
* IP addr of default route (nearest 'real' gateway)
* 128.114.130.3
80728203
* ethernet hardware addr of KFPS;
* 080089 is the Kinetics manufacturer code,
* remaining bytes are the serial number of your box.
080089 F00698
* next value is a flag, if it is '1234' the remainder 
* of this file is considered valid;  any other value means
* that the remaining parameters will be obtained from atalkad.
0000
--------------------------------

In atalkatab I have also tried using "N0   128.114.130.0" on the
1.130 line, it has the same behavior as the file given.  The good
news is that most everything else that we've tried works: papif
(after some serious playing around), efsd (right away), and telnet
for those of us who are comfortable with finding IP addresses.

Another question I had is where can I get the program that will
decode the ".hqx" formatted files that Mac executables seem to be
distributed in.

Thanks,

Brad Smith
System Administrator
CIS/CE Boards, Univ. of Calif. Santa Cruz
Internet: brad@saturn.ucsc.edu
UUCP:     ...!ucbvax!ucscc!saturn!brad
Bitnet:   brad@ucsccrls

cck@CUNIXC.COLUMBIA.EDU (Charlie C. Kim) (08/01/87)

The first problem, with MacIP Telnet (MPW version or Lisa Pascal
version), is that it uses the old style ien116 server to do name
lookup - silly, but it was never modified to use the domain nameserver
and with the stuff coming from Stanford and NCSA, I don't think it's
worth the trouble to fix unless the licensing issues from those sites
really gets out of hand.  Just run the old ien116 server for a while
(copy tacked on to end of message).  If you're worried because it
doesn't do domain name services, then don't - it uses gethostbyname
which should use the resolv libraries to go the domain server if your
machine has them installed.  The sources for the MPW version of Telnet
(copy distributed by Kinetics and available at Stanford) are available
upon request (to me) if you want to take a hand at modifying the code
- be warned that simple changes can be quite frustrating due to the
"multi-tasking" with multiple interdependent (in terms of size) stacks.

>- telneting to a machine on the 129 (or any other) subnet
>  times out (while I can connect to anywhere else I've tried
>  on the Internet).

Someone will surely correct me if I'm wrong on the following, but I'm
pretty sure this is pretty much the case.  The KIP code doesn't really
have full support for subnets.  It assumes that, for the connected
(class A,B,C) network (not the connected subnet), it can simply
attempt to "send" the packet directly (e.g.  arp, and send).  Packets
are sent to the default gateway otherwise (thus your internet
connections work).  Unfortunately, if your subnet gateways don't do
proxy arp (e.g. subnet arp hack), then this will not work correctly.
You have a number of alternatives:
	(a) install proxy arp code into your 4.3BSD gateway (easy -
code was published in comp.sources.unix (formerly mod.sources) in
Volume 4 as subnet.arp).  I have it installed in an Ultrix 2.0 system
and it works fine.  It's a great help in an environment where some of
the systems don't understand subnets.
	(b) hack the KIP code so it does the "right" thing.  In this
case, it would mean allowing a subnet mask in the configuration that
it could use to figure out (could use a simple convention like 0 mask
means no subnetting, etc.) if a packet was going to the connected
subnet.  Otherwise, it would route the packet to the default gateway
(problematic if this isn't the correct subnet gateway - hopefully ICMP
redirects would fix it.  Don't really want the RIP (routed) listener
code in the KFPS while it is so memory limited...).
	(c) assign the ethernet that the KFPS resides on a different
network number - thus, it will route correctly - this is the worst
possible solution that I could think of, but doesn't require any
hacking.

efsd will be "depreciated" in the next distribution of CAP (this means
it will be there someplace, but won't be compiled by default, etc).
efsd isn't as good as the Aufs (though it is much simpler) and the
file handling is different (and I don't feel up to making them match
up).  The client code has two major flaws:
	(a) compiled with Sumacc C compiler - this means that it
doesn't work on a Mac II because the Sumacc C runtime libraries builds
trap on the fly - this causes major problems on a instruction cached
68020.
	(b) doesn't support multiple external file systems correctly -
thus it doesn't work with AppleShare, TOPS, etc.

Improved documentation on installing papif will be included in any
future distributions of CAP.  If you need help, send me mail and I
will send you the new installation notes.

hqx files are output from "binhex".  Currently, there are two major
versions of Binhex - version 5 and version 4.  You can get version 4
(and the hqx file for version 5) from sumex.stanford.edu in the
directory ps:<info-mac>.  The version 4 executable is available as
binhex.rsrc - make sure you type "tenex" before transfering the file
since sumex is a tops-20 machine.  You can download to your mac using
telnet/tftp or kermit.  Note: I think version 5 is shareware.

Charlie C. Kim
User Services
Columbia University

ien116 name server.  add the following line to your /etc/services file:
>	name		42/udp		nameserver	# pcip

Note: there's a bunch of ifdefs for MACIP - these are for the version
you get from Kinetics which is probably the old copy compiled under
Lisa Pascal.  It had a bug dealing with word alignment and the ifdefs
try to get around it.  Ignore them and just compile the code.  You
need to run this from "root".  Also, it's probably worth redoing this
code to work with the 4.3 inetd someday (if that someday is before the
MacIP code is outdated).

/*
 * Copyright, 1984 The Regents of the University of California.  This software
 * was produced under a U.S. Government contract, W-7405-ENG-36, by the 
 * Los Alamos National Laboratory, which is operated by the University of
 * California for the U.S. Department of Energy.   The U.S. Government is 
 * licensed to use, reproduce, and distribute this software.  Permission
 * is granted to the public to copy and use this software without charge, 
 * provided that this notice and any statement of authorship are reproduced
 * on all copies.  Neither the Government nor the University makes any warranty
 * expressed or implied, or assumes any liability or responsibility for
 * the use of this software.
 *
 * $Header: named.c,v 1.1 84/11/21 17:29:59 tomlin Exp $
 *
 * $State: Exp $
 *
 * $Log:	named.c,v $
 * Revision 1.1  84/11/21  17:29:59  tomlin
 * Initial revision
 * 
 */

#ifndef lint
static char	rcsid[] = "$Header: named.c,v 1.1 84/11/21 17:29:59 root Exp $";
#endif lint

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/file.h>

#include <net/if.h>
#include <netinet/in.h>

#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <netdb.h>
#include <strings.h>

struct	sockaddr_in sin = { AF_INET };

typedef struct	namerequest {
	char nr_nameoctet;
	char nr_namelen;
	char nr_namestr[1024];	/* 1024 is arbitrary */
};

unsigned char	*replybuf;
unsigned char	*malloc();

#define ERRORMESSAGE	"Unknown machine"

extern	errno;

char	myname[32];
struct	servent *sp;
int	s = -1;

main()
{
	struct sockaddr_in from;
	struct hostent *hp;

	sp = getservbyname("name", "udp");
	if (sp == 0) {
		fprintf(stderr, "named: udp/name: unknown service\n");
		exit(1);
	}
#ifndef DEBUG
	if (fork())
		exit(0);
	{ int s;
	  for (s = 0; s < 10; s++)
		(void) close(s);
	  (void) open("/", 0);
	  (void) dup2(0, 1);
	  (void) dup2(0, 2);
	  s = open("/dev/tty", 2);
	  if (s >= 0) {
		ioctl(s, TIOCNOTTY, 0);
		(void) close(s);
	  }
	}
#endif
	if (getuid()) {
		fprintf(stderr, "named: not super user\n");
		exit(1);
	}

	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("named: socket");
		exit(1);
	}
	/*
	 * Establish host name as returned by system.
	 */
	if (gethostname(myname, sizeof (myname) - 1) < 0) {
		perror("gethostname");
		exit(1);
	}
	hp = gethostbyname(myname);
	if (hp == NULL) {
		fprintf(stderr, "%s: don't know my own name\n", myname);
		exit(1);
	}
	sin.sin_family = hp->h_addrtype;
	sin.sin_port = sp->s_port;
	if (bind(s, &sin, sizeof (sin)) < 0) {
		perror("named: bind");
		exit(1);
	}
	for (;;) {
		int			cc, i, len = sizeof (from);
		struct namerequest	request;
		struct hostent		*rh;

		cc = recvfrom(s, (char *)&request, sizeof (request), 0,
			&from, &len);
		if (cc <= 0) {
			if (cc < 0 && errno != EINTR)
				perror("named: recv");
			continue;
		}
		if (from.sin_port != sp->s_port) {
			fprintf(stderr, "named: %d: bad from port, continuing...\n",
				ntohs(from.sin_port));
			/* continue; */
		}
		request.nr_namestr[request.nr_namelen] = '\0';
#ifdef DEBUG
		fprintf(stderr,"Requesting \"%s\"\n",request.nr_namestr);
		fprintf(stderr,"Packet len is %d, name len is %d\n",
			cc, request.nr_namelen);
#endif
		rh = gethostbyname(request.nr_namestr);
		if (rh == NULL) {
			fprintf(stderr, "%s: unknown machine\n", request.nr_namestr);
			/* 3 = error type + length + error code */
			replybuf=malloc(cc+3+sizeof (ERRORMESSAGE));
			bcopy(&request, replybuf, cc);
			i=cc;
			replybuf[i++]=(unsigned char)3;	/* 3 denotes an error */
			replybuf[i++]=(unsigned char)strlen(ERRORMESSAGE);
			bcopy(ERRORMESSAGE, &replybuf[i], strlen(ERRORMESSAGE));
			i+=strlen(ERRORMESSAGE);
			(void) sendto(s, (char *)replybuf, i, 0, &from, len);
			free(replybuf);
			continue;
		}
#ifndef NOMACIP
/* patch for mac since one below screws up */
#ifdef notdef
		if (request.nr_namelen != (cc - 2))
		  request.nr_namelen = cc - 2;
#endif
#endif
		/* 6 = addr type + len + internet addr */
#ifdef NOMACIP
		replybuf=malloc(cc+6);
		bcopy(&request, replybuf, cc);
		i=cc;
#else
/* doing this causes the mac to crash ??? */
		/* MACIP sends a null terminated name, but doesn't count the */
		/* null in the name length, so code is confused - easy patch */
		/* use nr_namelen + 2 (for octect, length) (+ 6 for response)*/
		i = request.nr_namelen + 2;
fprintf(stderr,"Awk at %d\n",i);
		if ((i%2) == 1 ) {
		  i++;
		  request.nr_namelen++;
		}
		replybuf=malloc(i + 6);
		bcopy(&request, replybuf, i);
#endif
		replybuf[i++]=(unsigned char)2;	/* 2 denotes an addr */
		replybuf[i++]=(unsigned char)rh->h_length;
		bcopy(rh->h_addr, &replybuf[i], rh->h_length);
		i+=(rh->h_length);
#ifdef DEBUG
		fprintf(stderr,"Replying with address %x, (pkt len %d)\n",
			rh->h_addr, i);
#endif
#ifndef NOMACIP
	{
	  int j;
	  for (j=0; j < 2; j++)
		(void) sendto(s, (char *)replybuf, i, 0, &from, len);
	}
#endif
		free(replybuf);
	}
}