[comp.protocols.appletalk] CAP 6.0 patch 25

djh@cs.mu.oz.au (David Hornsby) (05/29/91)

The enclosed shar file contains CAP 6.0 patch 25. It is also
available from rutgers.edu (soon) and munnari.OZ.AU (now).

Patch 25 contains the changes necessary to run CAP with
Native EtherTalk *Phase 2* on a SUN workstation using the
NIT interface ONLY.

The necessary code changes to provide Phase 2 on the "enet"
interface are in progress and will be posted when available.
The ULTRIX packet filter code is also under way. There is no
firm time scale for either of these yet ... just asap.

The new Phase 2 code is included at compile-time only, so no
dynamic selection is possible at this stage. To use, ask for
Native EtherTalk and Phase 2 compatibility at Configure time
and rebuild CAP completely. Startup is identical to Phase 1,
IE:

	aarpd le0 zoneName
	atis
	sleep 15
	aufs -n etc

If "zoneName" is invalid for the Phase 2 network, aarpd will
print a diagnostic message and exit. le0 is the appropriate
interface name.

THIS CODE HAS BEEN TESTED BUT ONLY ON SMALL NETWORKS.
IT IS PROVIDED AS IS WITHOUT ANY GUARANTEE ETC. ETC.
If you have problems, please document and send to

	cap@munnari.OZ.AU

More CAP feature patches next week ...

Enjoy, 

 - David.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  cap60.patch025
# Wrapped by djh@munnari.OZ.AU on Thu May 30 02:14:10 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'cap60.patch025' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cap60.patch025'\"
else
echo shar: Extracting \"'cap60.patch025'\" \(77341 characters\)
sed "s/^X//" >'cap60.patch025' <<'END_OF_FILE'
XPatch #:	25
XType:		operational change
XPriority:	none
XModification:	Add EtherTalk Phase 2 support
XSubmitted:	David Hornsby <djh@munnari.OZ.AU>
XArchived:	munnari.OZ.AU	mac/cap.patches/cap60.patch025
XSummary:	many changes !
XFile:		cap60/CAP60.README
XFile:		cap60/Configure
XFile:		cap60/README
XFile:		cap60/support/uab/aarp.c
XFile:		cap60/support/ethertalk/aarpd.c
XFile:		cap60/support/ethertalk/aarpd.h
XFile:		cap60/support/ethertalk/aarpd_clnt.c
XFile:		cap60/support/ethertalk/aarpd_svc.c
XFile:		cap60/support/ethertalk/aarptest.c
XFile:		cap60/support/ethertalk/abelap.c
XFile:		cap60/lib/cap/abnbp.c
XFile:		cap60/lib/cap/atalkdbm.c
XFile:		cap60/lib/cap/atalkdbm.h
XFile:		cap60/etc/atis.c
XFile:		cap60/samples/atlook.c
XFile:		cap60/support/ethertalk/ethertalk.c
XFile:		cap60/support/uab/ethertalk.h
XFile:		cap60/etc/nisaux.c
XFile:		cap60/support/ethertalk/rtmptest.c
XFile:		cap60/support/ethertalk/snitp.c
X
X*** CAP60.README.orig	Fri Mar 15 00:57:25 1991
X--- CAP60.README	Wed May 29 22:19:23 1991
X***************
X*** 51,58 ****
X  CAP and AppleTalk Phase 2
X  -------------------------
X  
X! CAP does not currently support EtherTalk Phase 2. However, it is possible
X! to use CAP in a Phase 2 environment.
X  
X  Traditionally, the CAP transport mechanism uses UDP/IP packets. This is
X  called IPTalk (also known as KIP) and is a "non-extended" (1 net number
X--- 51,60 ----
X  CAP and AppleTalk Phase 2
X  -------------------------
X  
X! CAP 6.0 (to patch level 25 or greater) supports EtherTalk Phase 2 using
X! the SunOS NIT interface [soon also on the enet interface and ULTRIX packet
X! filter interface]. It also is possible to use CAP in a Phase 2 environment
X! with IPTalk as indicated below.
X  
X  Traditionally, the CAP transport mechanism uses UDP/IP packets. This is
X  called IPTalk (also known as KIP) and is a "non-extended" (1 net number
X***************
X*** 98,106 ****
X  earlier versions of the gateway code will happily translate from IPTalk to
X  either Phase 1 or LocalTalk.
X  
X- If you don't have a hardware gateway at all, you can currently only use CAP
X- with UAB or Native EtherTalk (both Phase 1) and other *Phase 1 ONLY* nodes.
X- 
X  Bug Fixes
X  ---------
X  
X--- 100,105 ----
X***************
X*** 197,203 ****
X  
X  XENIX:				(-Dxenix5 (handled by Configure))
X  
X! 	file.1,file.2,file.3	Chip Salzenberg <chip@ateng.com>
X  
X  	Support for CAP on SCO XENIX System V.
X  
X--- 196,202 ----
X  
X  XENIX:				(-Dxenix5 (handled by Configure))
X  
X! 	file.1,file.2,file.3	Chip Salzenberg <chip@tct.com>
X  
X  	Support for CAP on SCO XENIX System V.
X  
X*** Configure.orig	Wed May 29 19:31:31 1991
X--- Configure		Wed May 29 22:24:11 1991
X***************
X*** 1,7 ****
X  #!/bin/sh
X! # $Author: djh $ $Date: 1991/05/29 09:31:20 $
X! # $Header: /mac/src/cap60/RCS/Configure,v 2.9 1991/05/29 09:31:20 djh Exp djh $
X! # $Revision: 2.9 $
X  # CAP configuration shell script.  This ain't perfect, but it's a start.
X  # Execute with /bin/sh Configure if your system won't run it (ksh is okay too)
X  # 
X--- 1,7 ----
X  #!/bin/sh
X! # $Author: djh $ $Date: 1991/05/29 12:23:59 $
X! # $Header: /mac/src/cap60/RCS/Configure,v 2.10 1991/05/29 12:23:59 djh Rel djh $
X! # $Revision: 2.10 $
X  # CAP configuration shell script.  This ain't perfect, but it's a start.
X  # Execute with /bin/sh Configure if your system won't run it (ksh is okay too)
X  # 
X***************
X*** 257,263 ****
X--- 257,265 ----
X  etherprogs="define([etherprogs],[])"
X  etherpobjs="define([etherpobjs],[])"
X  lapobj="define([lapobj],[abkip.o abddp.o abnbp.o atalkdbm.o])"
X+ usingphase2="# define([usephase2],1)"
X  result=0
X+ usephase2=0
X  uabsupport=0
X  ethersupport=0
X  case ${os} in
X***************
X*** 360,374 ****
X        		  echo "OK, setting things up for Native EtherTalk."
X      		  etherpobjs="define([etherpobjs],[senetp.o])";;
X    	  "sunos")
X!   		  echo $newl "Have you installed the 'enet' driver (no) ? "
X!       		  read ans
X!       		  if [ -z "${ans}" ]; then
X    	  		ans="no"
X!       		  fi
X!   		  case ${ans} in
X    			"yes"|"y") result=1;;
X    			*) result=0;;
X!   		  esac
X    		  if [ $result -eq 0 ]; then
X    			echo "OK, using the NIT ethernet interface."
X      		  	etherpobjs="define([etherpobjs],[snitp.o])"
X--- 362,390 ----
X        		  echo "OK, setting things up for Native EtherTalk."
X      		  etherpobjs="define([etherpobjs],[senetp.o])";;
X    	  "sunos")
X! 		  echo $newl "Do you want Phase 2 compatibility (no) ? "
X! 		  read ans
X! 		  if [ -z "${ans}" ]; then
X! 			ans="no"
X! 		  fi
X! 		  case ${ans} in
X! 		    "yes"|"y")
X! 		      result=0
X! 		      usephase2=1;;
X! 		    *)
X! 		      echo "Using EtherTalk Phase 1"
X! 		      echo
X! 		      echo $newl "Have you installed the 'enet' driver (no) ? "
X!       		      read ans
X!       		      if [ -z "${ans}" ]; then
X    	  		ans="no"
X!       		      fi
X!   		      case ${ans} in
X    			"yes"|"y") result=1;;
X    			*) result=0;;
X!   		      esac
X! 		      ;;
X! 		  esac
X    		  if [ $result -eq 0 ]; then
X    			echo "OK, using the NIT ethernet interface."
X      		  	etherpobjs="define([etherpobjs],[snitp.o])"
X***************
X*** 383,388 ****
X--- 399,407 ----
X  if [ $useauxappletalk -ne 0 ]; then
X    labobj="define([lapobj],[abauxddp.o abauxnbp.o])"
X  fi
X+ if [ $usephase2 -ne 0 ]; then
X+   usingphase2="define([usephase2],1)"
X+ fi
X  echo
X  echo "CAP can be configured for various optional features."
X  echo "For more information, refer to the file 'CAP60.README'."
X***************
X*** 754,759 ****
X--- 773,781 ----
X  echo "${etherprogs}"
X  echo "${etherpobjs}"
X  echo
X+ echo "# And this determines if Phase 2 packets are used"
X+ echo "${usingphase2}"
X+ echo
X  echo "# The following selects byteswapping or otherwise"
X  echo "${byteswapping}"
X  echo
X***************
X*** 950,955 ****
X--- 972,978 ----
X  		[Unknown]))
X  define([cflags],ifdef([selfdefinetypes],[-D_TYPES],[]))
X  define([cflags],concat(cflags,ifdef([usebyteswap],[ -DBYTESWAPPED],[])))
X+ define([cflags],concat(cflags,ifdef([usephase2],[ -DPHASE2],[])))
X  define([bigcflags],ifelse(os,[hpux],[+Nd2000 +Ns2000]))
X  # The encore optimiser is slightly over zealous
X  ifelse(os,[encore],[define([cflags],concat(cflags,[ -Dencore]))],[
X*** README.orig		Wed May 29 19:23:06 1991
X--- README		Wed May 29 22:26:51 1991
X***************
X*** 3,9 ****
X  	       (For use with AppleTalk/Ethernet bridge)
X  
X  	o RELEASE NOTES
X! 	o CAP Distribution 6.0, Patch Level 24, May 1991
X  
X  Introduction
X  ------------
X--- 3,9 ----
X  	       (For use with AppleTalk/Ethernet bridge)
X  
X  	o RELEASE NOTES
X! 	o CAP Distribution 6.0, Patch Level 25, May 1991
X  
X  Introduction
X  ------------
X***************
X*** 85,93 ****
X       * Cayman Gatorbox
X       * Shiva FastPath
X  
X!  o This CAP version supports native EtherTalk on certain hosts. A gateway
X!    as listed above is only required to access LocalTalk services. Phase 1
X!    only is available at this stage.
X  
X   o baseline host system: Ultrix 2.0-1.  Most will work under BSD 4.2,
X     BSD 4.3, Ultrix 1.0-1.2, Sun OS 3.2 or higher, ACIS 4.2, A/UX, IBM
X--- 85,93 ----
X       * Cayman Gatorbox
X       * Shiva FastPath
X  
X!  o This CAP version supports native EtherTalk (Phase 1 or Phase 2) on
X!    certain hosts. A gateway as listed above is only required to access
X!    LocalTalk services.
X  
X   o baseline host system: Ultrix 2.0-1.  Most will work under BSD 4.2,
X     BSD 4.3, Ultrix 1.0-1.2, Sun OS 3.2 or higher, ACIS 4.2, A/UX, IBM
X*** support/uab/aarp.c.orig	Wed Mar 13 21:08:31 1991
X--- support/uab/aarp.c		Wed May 29 22:28:53 1991
X***************
X*** 1,6 ****
X! static char rcsid[] = "$Author: djh $ $Date: 91/03/13 20:07:35 $";
X! static char rcsident[] = "$Header: aarp.c,v 2.2 91/03/13 20:07:35 djh Exp $";
X! static char revision[] = "$Revision: 2.2 $";
X  
X  /*
X   * aarp.c - AppleTalk Address Resolution Protocol handler
X--- 1,6 ----
X! static char rcsid[] = "$Author: djh $ $Date: 1991/05/29 12:28:45 $";
X! static char rcsident[] = "$Header: /mac/src/cap60/support/uab/RCS/aarp.c,v 2.3 1991/05/29 12:28:45 djh Rel djh $";
X! static char revision[] = "$Revision: 2.3 $";
X  
X  /*
X   * aarp.c - AppleTalk Address Resolution Protocol handler
X***************
X*** 20,26 ****
X   * Edit History:
X   *
X   *  April 3, 1988  CCKim Created
X!  *  Aug 26, 1988 Moved into seperate module from ethertalk
X   *
X  */
X  
X--- 20,27 ----
X   * Edit History:
X   *
X   *  April 3, 1988  CCKim Created
X!  *  Aug 26,  1988  Moved into separate module from ethertalk
X!  *  April 28,1991  djh Added Phase 2 support
X   *
X  */
X  
X***************
X*** 64,69 ****
X--- 65,73 ----
X  export AARP_ENTRY *aarptab_find();
X  export caddr_t aarp_init();
X  export int aarp_get_host_addr();
X+ #ifdef PHASE2
X+ export int aarp_set_host_addr();
X+ #endif PHASE2
X  export int aarp_resolve();
X  export int aarp_insert();
X  export int aarp_acquire_etalk_node();
X***************
X*** 76,82 ****
X--- 80,90 ----
X  private struct ai_host_node *host_node();
X  
X  /* pointers to host ethernet and broadcast addresess */
X+ #ifdef PHASE2
X+ private u_char b_eaddr[EHRD] = {0x09, 0x00, 0x07, 0xff, 0xff, 0xff};
X+ #else  PHASE2
X  private u_char b_eaddr[EHRD] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
X+ #endif PHASE2
X  
X  /* list of all the node ids: DUMP ONLY  */
X  private AARP_ENTRY *aarptab_node_list;
X***************
X*** 95,102 ****
X  struct ethertalkaddr *k;
X  AARP_ENTRY *node;
X  {
X!   /* EtherTalk II fixup */
X    return(k->node - node->aae_pa.node);
X  }
X  
X  /* compress an ethertalk node addresses */
X--- 103,113 ----
X  struct ethertalkaddr *k;
X  AARP_ENTRY *node;
X  {
X! #ifdef PHASE2
X!   return(bcmp(k, &node->aae_pa, ETPL));
X! #else  PHASE2
X    return(k->node - node->aae_pa.node);
X+ #endif PHASE2
X  }
X  
X  /* compress an ethertalk node addresses */
X***************
X*** 104,110 ****
X  aarptab_compress(k)
X  struct ethertalkaddr *k;
X  {
X!   /* EtherTalk II fixup */
X    return(k->node);
X  }
X  
X--- 115,123 ----
X  aarptab_compress(k)
X  struct ethertalkaddr *k;
X  {
X! #ifdef PHASE2
X!   /* ZZ */
X! #endif PHASE2
X    return(k->node);
X  }
X  
X***************
X*** 201,209 ****
X    if (r == NULL)
X      return(NULL);
X    if (r->aae_flags == 0) {
X!     /* EtherTalk II */
X!     logit(LOG_LOTS, "New AARP mapping for node %d, bkt %d, dist %d\n",
X! 	r->aae_pa.node);
X      r->aae_aarptab = aih->ai_aarptab;	/* remember */
X    } else {
X      if (aih->ai_accesses++ > AI_AARPTAB_EVAL_POINT)
X--- 214,225 ----
X    if (r == NULL)
X      return(NULL);
X    if (r->aae_flags == 0) {
X! #ifdef PHASE2
X!     logit(LOG_LOTS, "New AARP mapping for node %d/%d.%d",
X! 		r->aae_pa.node, r->aae_pa.dummy[1], r->aae_pa.dummy[2]);
X! #else  PHASE2
X!     logit(LOG_LOTS, "New AARP mapping for node %d", r->aae_pa.node);
X! #endif PHASE2
X      r->aae_aarptab = aih->ai_aarptab;	/* remember */
X    } else {
X      if (aih->ai_accesses++ > AI_AARPTAB_EVAL_POINT)
X***************
X*** 224,231 ****
X  {
X  
X    aa->aae_flags = 0;		/* not okay */
X!   /* EtherTalk II */
X    logit(LOG_LOTS, "deleting arp entry: node %d", aa->aae_pa.node);
X    en = (AARP_ENTRY *)h_delete(aih->ai_aarptab, aa->aae_pa.node);
X    if (en != aa) {
X      logit(LOG_BASE, "when deleting arp entry, freed entry was %x, wanted %x",
X--- 240,251 ----
X  {
X  
X    aa->aae_flags = 0;		/* not okay */
X! #ifdef PHASE2
X!   logit(LOG_LOTS, "deleting arp entry: node %d/%d.%d",
X!  		 aa->aae_pa.node, aa->aae_pa.dummy[1], aa->aae_pa.dummy[2]);
X! #else  PHASE2
X    logit(LOG_LOTS, "deleting arp entry: node %d", aa->aae_pa.node);
X+ #endif PHASE2
X    en = (AARP_ENTRY *)h_delete(aih->ai_aarptab, aa->aae_pa.node);
X    if (en != aa) {
X      logit(LOG_BASE, "when deleting arp entry, freed entry was %x, wanted %x",
X***************
X*** 234,240 ****
X    aa->aae_next = aarptab_free_list;
X    aarptab_free_list = aa;	/* mark */
X  }
X! #endif
X  
X  /* scan arp table and see if anything needs going */
X  aarptab_scan()
X--- 254,260 ----
X    aa->aae_next = aarptab_free_list;
X    aarptab_free_list = aa;	/* mark */
X  }
X! #endif notdef
X  
X  /* scan arp table and see if anything needs going */
X  aarptab_scan()
X***************
X*** 245,254 ****
X    np = NULL, n = aarptab_node_list;
X    while (n) {
X      if (n->aae_ttl <= 0) {
X        logit(LOG_LOTS, "deleting arp entry: node %d", n->aae_pa.node);
X        en = (AARP_ENTRY *)h_delete(n->aae_aarptab, &n->aae_pa);
X        if (en != n) {
X! 	logit(LOG_BASE, "when deleting arp entry, freed entry was %x, wanted %x",
X  	    en, n);
X        }
X        if (np)
X--- 265,279 ----
X    np = NULL, n = aarptab_node_list;
X    while (n) {
X      if (n->aae_ttl <= 0) {
X+ #ifdef PHASE2
X+       logit(LOG_LOTS, "deleting arp entry: node %d/%d.%d",
X+ 		n->aae_pa.node, n->aae_pa.dummy[1], n->aae_pa.dummy[2]);
X+ #else  PHASE2
X        logit(LOG_LOTS, "deleting arp entry: node %d", n->aae_pa.node);
X+ #endif PHASE2
X        en = (AARP_ENTRY *)h_delete(n->aae_aarptab, &n->aae_pa);
X        if (en != n) {
X! 	logit(LOG_BASE,"when deleting arp entry, freed entry was %x, wanted %x",
X  	    en, n);
X        }
X        if (np)
X***************
X*** 327,333 ****
X    if ((pi_get_ethernet_address(ph, aih->ai_eaddr)) < 0)
X      goto giveup;
X  
X!   logit(LOG_BASE,"Ethernet address for %s%d is %02x:%02x:%02x:%02x:%02x:%02x\n",
X        dev, devno, 
X        aih->ai_eaddr[0], aih->ai_eaddr[1], aih->ai_eaddr[2],
X        aih->ai_eaddr[3], aih->ai_eaddr[4], aih->ai_eaddr[5]);
X--- 352,358 ----
X    if ((pi_get_ethernet_address(ph, aih->ai_eaddr)) < 0)
X      goto giveup;
X  
X!   logit(LOG_BASE,"Ethernet address for %s%d is %02x:%02x:%02x:%02x:%02x:%02x",
X        dev, devno, 
X        aih->ai_eaddr[0], aih->ai_eaddr[1], aih->ai_eaddr[2],
X        aih->ai_eaddr[3], aih->ai_eaddr[4], aih->ai_eaddr[5]);
X***************
X*** 365,376 ****
X        aih->ai_nodes[which].aihn_state == AI_NODE_OKAY) {
X      *pa = aih->ai_nodes[which].aihn_pa; /* copy it */
X      /* should we count pa node address? */
X!     return(1);			/* one byte handled for now */
X    }
X    return(-1);
X  }
X  
X  /*
X   * returns -1: can't be resolved
X   *          0: resolving, come back later
X   *          1: resolved
X--- 390,429 ----
X        aih->ai_nodes[which].aihn_state == AI_NODE_OKAY) {
X      *pa = aih->ai_nodes[which].aihn_pa; /* copy it */
X      /* should we count pa node address? */
X! #ifdef PHASE2
X!     return(4);
X! #else  PHASE2
X!     return(1);
X! #endif PHASE2
X    }
X    return(-1);
X  }
X  
X+ #ifdef PHASE2
X  /*
X+  * set a host node address
X+  *
X+ */
X+ export int
X+ aarp_set_host_addr(aih, pa)
X+ AI_HANDLE *aih;
X+ struct ethertalkaddr *pa;
X+ {
X+   int i = aih->ai_numnode;
X+   struct ai_host_node *an = aih->ai_nodes;
X+ 
X+   for ( ; i ; an++, i--)
X+     if (an->aihn_state == AI_NODE_OKAY)
X+       an->aihn_pa = *pa;
X+ 
X+   if (i == 0)
X+   	return(0);
X+ 
X+   return(-1);
X+ }
X+ #endif PHASE2
X+ 
X+ /*
X   * returns -1: can't be resolved
X   *          0: resolving, come back later
X   *          1: resolved
X***************
X*** 446,453 ****
X    struct timeval *tv;
X  
X    /* check to make sure ha isn't broadcast (or multicast)! */
X!   /* EtherTalk II fixup */
X    logit(LOG_LOTS, "Got mapping for %d", pa->node);
X    dumpether(LOG_LOTS, "  Address", ha);
X  
X    aa = aarptab_get(aih, pa); /* find it or get a new one */
X--- 499,514 ----
X    struct timeval *tv;
X  
X    /* check to make sure ha isn't broadcast (or multicast)! */
X!   if (bcmp(ha, b_eaddr) == 0)
X!     return(FALSE);
X! #ifdef PHASE2
X!   if (ha[0] == 0x09 && ha[1] == 0x00 && ha[2] == 0x07 && ha[3] == 0x00)
X!     return(FALSE); /* zone multicast address */
X!   logit(LOG_LOTS,"Got mapping for %d/%d.%d",
X! 			pa->node, pa->dummy[1], pa->dummy[2]);
X! #else  PHASE2
X    logit(LOG_LOTS, "Got mapping for %d", pa->node);
X+ #endif PHASE2
X    dumpether(LOG_LOTS, "  Address", ha);
X  
X    aa = aarptab_get(aih, pa); /* find it or get a new one */
X***************
X*** 455,462 ****
X      if (aa->aae_flags & (AARP_PERM)) /* don't reset these */
X        return(FALSE);
X      if (hard)
X!       /* EtherTalk II fixup */
X        logit(LOG_LOTS, "Resetting an old mapping for node %d", pa->node);
X    }
X    /* if arp entry is in cache and we aren't doing a hard update */
X    /* and the hardware addresses don't match, don't do an update */
X--- 516,527 ----
X      if (aa->aae_flags & (AARP_PERM)) /* don't reset these */
X        return(FALSE);
X      if (hard)
X! #ifdef PHASE2
X!       logit(LOG_LOTS, "Resetting an old mapping for node %d/%d.%d",
X! 			pa->node, pa->dummy[1], pa->dummy[2]);
X! #else  PHASE2
X        logit(LOG_LOTS, "Resetting an old mapping for node %d", pa->node);
X+ #endif PHASE2
X    }
X    /* if arp entry is in cache and we aren't doing a hard update */
X    /* and the hardware addresses don't match, don't do an update */
X***************
X*** 463,470 ****
X    if ((aa->aae_flags & AARP_OKAY) && !hard) {
X      if (bcmp((caddr_t)aa->aae_eaddr, (caddr_t)ha, EHRD) != 0) {
X        logit(LOG_BASE, "AARP RESET - ethernet address mismatch");
X!       /* EtherTalk II fixup */
X        logit(LOG_BASE,"node number is %d", pa->node);
X        dumpether(LOG_BASE, "incoming address", ha);
X        dumpether(LOG_BASE, "cached address",aa->aae_eaddr);
X        aa->aae_flags &= ~AARP_OKAY; /* there we go */
X--- 528,539 ----
X    if ((aa->aae_flags & AARP_OKAY) && !hard) {
X      if (bcmp((caddr_t)aa->aae_eaddr, (caddr_t)ha, EHRD) != 0) {
X        logit(LOG_BASE, "AARP RESET - ethernet address mismatch");
X! #ifdef PHASE2
X!       logit(LOG_BASE,"node number is %d/%d.%d",
X! 			pa->node, pa->dummy[1], pa->dummy[2]);
X! #else  PHASE2
X        logit(LOG_BASE,"node number is %d", pa->node);
X+ #endif PHASE2
X        dumpether(LOG_BASE, "incoming address", ha);
X        dumpether(LOG_BASE, "cached address",aa->aae_eaddr);
X        aa->aae_flags &= ~AARP_OKAY; /* there we go */
X***************
X*** 501,508 ****
X        ntohs(arp.arp_pro) != ETHERTYPE_APPLETALK || /* not appletalk? */
X        arp.arp_hln != EHRD ||	/* wrong hrdwr length */
X        arp.arp_pln != ETPL) {	/* wrong protocol length? */
X!     /* maybe log? */
X!     return;			/* yes, to one, kill packet */
X    }
X  
X    dpa = (struct ethertalkaddr *)arp.arp_tpa; /* reformat */
X--- 570,578 ----
X        ntohs(arp.arp_pro) != ETHERTYPE_APPLETALK || /* not appletalk? */
X        arp.arp_hln != EHRD ||	/* wrong hrdwr length */
X        arp.arp_pln != ETPL) {	/* wrong protocol length? */
X!     logit(5, "AARP drop!: %d %d %d %d",
X! 	arp.arp_hrd, arp.arp_pro, arp.arp_hln, arp.arp_pln);
X!     return;
X    }
X  
X    dpa = (struct ethertalkaddr *)arp.arp_tpa; /* reformat */
X***************
X*** 521,528 ****
X      return;
X    }
X    if (host_node(aih, spa, AI_NODE_OKAY)) {
X!     /* EtherTalk II fixup */
X      logit(LOG_BASE, "Address conflict %d\n", spa->node);
X    }
X  
X    switch (ntohs(arp.arp_op)) {
X--- 591,602 ----
X      return;
X    }
X    if (host_node(aih, spa, AI_NODE_OKAY)) {
X! #ifdef PHASE2
X!     logit(LOG_BASE, "Address conflict %d/%d.%d\n",
X! 			spa->node, spa->dummy[1], spa->dummy[2]);
X! #else  PHASE2
X      logit(LOG_BASE, "Address conflict %d\n", spa->node);
X+ #endif PHASE2
X    }
X  
X    switch (ntohs(arp.arp_op)) {
X***************
X*** 613,621 ****
X    int i;
X      
X    /* bad node */
X-   /* EtherTalk II fixup */
X    if (initial_node->node == 0 || initial_node->node == 255)
X      return(1);
X    if (aarptab_find(aih, initial_node) || host_node(aih, initial_node, 0)) {
X      /* callback ? */
X      return(1);
X--- 687,698 ----
X    int i;
X      
X    /* bad node */
X    if (initial_node->node == 0 || initial_node->node == 255)
X      return(1);
X+ #ifdef PHASE2
X+   if (initial_node->node == 254)	/* reserved */
X+     return(1);
X+ #endif PHASE2
X    if (aarptab_find(aih, initial_node) || host_node(aih, initial_node, 0)) {
X      /* callback ? */
X      return(1);
X***************
X*** 679,684 ****
X--- 756,764 ----
X    struct timeval tv;
X    struct ai_host_node *ahn;
X    AI_HANDLE *aih = aphandle->aaph_aih;
X+ #ifdef PHASE2
X+   char abuf[sizeof(struct ether_arp)+8];
X+ #endif PHASE2
X  
X    /* either of these can be running or both - both really doesn't */
X    /* make much sense though */
X***************
X*** 723,730 ****
X--- 803,816 ----
X      tv.tv_sec = AARP_PROBE_TIMEOUT_SEC;
X      tv.tv_usec = AARP_PROBE_TIMEOUT_USEC;
X    }
X+ #ifdef PHASE2
X+   /* make room for the rest of the ELAP header */
X+   bcopy(&aphandle->aaph_arp, abuf+8, sizeof(struct ether_arp));
X+   if (pi_write(aih->ai_ph, abuf, sizeof(abuf), b_eaddr) < 0) 
X+ #else  PHASE2
X    if (pi_write(aih->ai_ph,&aphandle->aaph_arp, sizeof(struct ether_arp),
X  		    b_eaddr) < 0) 
X+ #endif PHASE2
X      logit(LOG_BASE|L_UERR, "pi_write failed: aarp driver");
X    /* setup timeout to next (relative timeout) */
X    relTimeout(probe_and_request_driver, aphandle, &tv, TRUE);
X***************
X*** 782,787 ****
X--- 868,876 ----
X  struct ether_arp *arp;
X  {
X    caddr_t sha, tha;
X+ #ifdef PHASE2
X+   char abuf[sizeof(struct ether_arp)+8];
X+ #endif PHASE2
X  
X    sha = (caddr_t)&arp->arp_sha;	/* need & because can be struct */
X    tha = (caddr_t)&arp->arp_tha;
X***************
X*** 792,798 ****
X--- 881,892 ----
X    bcopy((caddr_t)aih->ai_eaddr, sha, EHRD);
X    /* copy in our node */
X    bcopy((caddr_t)pa, (caddr_t)arp->arp_spa, ETPL);
X+ #ifdef PHASE2
X+   bcopy(arp, abuf+8, sizeof(struct ether_arp));
X+   if (pi_write(aih->ai_ph, abuf, sizeof(abuf), tha) < 0) {
X+ #else  PHASE2
X    if (pi_write(aih->ai_ph, arp, sizeof(*arp), tha) < 0) {
X+ #endif PHASE2
X      logit(LOG_LOG|L_UERR, "etsend");
X    }
X  }
X***************
X*** 808,813 ****
X--- 902,912 ----
X  {
X    AARP_ENTRY *aa;
X    struct aarp_aphandle *ap;
X+ #ifdef PHASE2
X+   int forcePROBE = tpa->dummy[0];
X+   /* can you say 'hack' */
X+   tpa->dummy[0] = 0;
X+ #endif PHASE2
X  
X    if ((aa = aarptab_get(aih, tpa)) == NULL) /* get new */
X      return;
X***************
X*** 824,830 ****
X--- 923,933 ----
X  
X    /* establish arp packet */
X    bzero(&ap->aaph_arp, sizeof(ap->aaph_arp));
X+ #ifdef PHASE2
X+   ap->aaph_arp.arp_op = htons((forcePROBE) ? ARPOP_PROBE : ARPOP_REQUEST);
X+ #else  PHASE2
X    ap->aaph_arp.arp_op = htons(ARPOP_REQUEST);
X+ #endif PHASE2
X    ap->aaph_arp.arp_hrd = htons(ARPHRD_ETHER);
X    ap->aaph_arp.arp_pro = htons(ETHERTYPE_APPLETALK);
X    ap->aaph_arp.arp_hln = EHRD;
X***************
X*** 850,855 ****
X--- 953,962 ----
X    }
X  #endif
X    bcopy((caddr_t)tpa, (caddr_t)ap->aaph_arp.arp_tpa, sizeof(*tpa));
X+ #ifdef PHASE2
X+   if (forcePROBE)
X+     bcopy((caddr_t)tpa, (caddr_t)ap->aaph_arp.arp_spa, sizeof(*tpa));
X+ #endif PHASE2
X  
X    ap->aaph_ae = aa;		/* remember this for later */
X    ap->aaph_tries = AARP_REQUEST_TRY;
X***************
X*** 881,889 ****
X      if (ai_nodes->aihn_state) {
X        if (flag && ai_nodes->aihn_state != flag)
X  	continue;
X!       /* EtherTalk II fixup */
X        if (ai_nodes->aihn_pa.node && ai_nodes->aihn_pa.node == n->node)
X  	return(ai_nodes);
X      }
X    return(NULL);
X  }
X--- 988,1003 ----
X      if (ai_nodes->aihn_state) {
X        if (flag && ai_nodes->aihn_state != flag)
X  	continue;
X! #ifdef PHASE2
X!       if (ai_nodes->aihn_pa.node
X!        && ai_nodes->aihn_pa.dummy[1] == n->dummy[1]
X!        && ai_nodes->aihn_pa.dummy[2] == n->dummy[2]
X!        && ai_nodes->aihn_pa.node == n->node)
X! 	return(ai_nodes);
X! #else  PHASE2
X        if (ai_nodes->aihn_pa.node && ai_nodes->aihn_pa.node == n->node)
X  	return(ai_nodes);
X+ #endif PHASE2
X      }
X    return(NULL);
X  }
X*** support/ethertalk/aarpd.c.orig	Mon Apr  8 20:40:23 1991
X--- support/ethertalk/aarpd.c		Wed May 29 22:30:30 1991
X***************
X*** 7,12 ****
X--- 7,13 ----
X   *	16/02/91: add support for CAP 6.0 atalkdbm routines, back out
X   *	of shared memory in favour of RPC based [SG]etBridgeAddress()
X   *	Add the SVC descriptors to the low level scheduler.
X+  *	28/04/91: Add Phase 2 support, SetNetRange()
X   */
X  
X  #include <stdio.h>
X***************
X*** 13,18 ****
X--- 14,24 ----
X  #include <errno.h>
X  #include <sys/file.h>
X  #include <sys/types.h>
X+ #ifdef PHASE2
X+ #include <sys/socket.h>
X+ #include <sys/sockio.h>
X+ #include <net/if.h>
X+ #endif PHASE2
X  #include <arpa/inet.h>
X  #include <netat/appletalk.h>
X  #include <rpc/rpc.h>
X***************
X*** 34,39 ****
X--- 40,50 ----
X  extern word this_net;			/* this host node		*/
X  extern byte nis_node;			/* atis running here		*/
X  extern word nis_net;			/* atis running here		*/
X+ #ifdef PHASE2
X+ extern word net_range_start;		/* phase 2 network range start	*/
X+ extern word net_range_end;		/* phase 2 network range end	*/
X+ extern int etalk_set_mynode();		/* update our node address	*/
X+ #endif PHASE2
X  
X  extern short lap_proto;			/* our LAP mechanism		*/
X  
X***************
X*** 48,53 ****
X--- 59,68 ----
X  u_char *rtmp_getbaddr_svc();		/* get the bridge address	*/
X  u_char *rtmp_setbaddr_svc();		/* set the bridge address	*/
X  
X+ #ifdef PHASE2
X+ struct ifreq ifreq;
X+ #endif PHASE2
X+ 
X  main(argc, argv)
X  int argc;
X  char *argv[];
X***************
X*** 82,87 ****
X--- 97,107 ----
X  
X  	nis_net = this_net = 0;		/* assume that we don't know */
X    	bridge_addr.s_addr = inet_addr("127.0.0.1");
X+ #ifdef PHASE2
X+ 	this_net = 0xff00;		/* the startup range */
X+ 	net_range_start = 0;		/* the total range */
X+ 	net_range_end = 0xfffe;
X+ #endif PHASE2
X  
X  	baddr.node = bridge_node;	/* set bridge addr hint */
X  	baddr.net = bridge_net;
X***************
X*** 157,164 ****
X  		exit(1);
X  	}
X  
X! 	set_svc_listen(); /* add RPC descriptors to scheduler */
X  
X  	if (!dbug.db_flgs && (dlevel == 0))
X  		disassociate();
X  
X--- 177,188 ----
X  		exit(1);
X  	}
X  
X! 	set_svc_listen();	/* add RPC descriptors to scheduler */
X  
X+ #ifdef PHASE2
X+ 	getNetInfo();		/* find out about our network */
X+ #endif PHASE2
X+ 
X  	if (!dbug.db_flgs && (dlevel == 0))
X  		disassociate();
X  
X***************
X*** 176,181 ****
X--- 200,207 ----
X  void
X  init_enet()
X  {
X+   struct ethertalkaddr *ea, *etalk_mynode();
X+ 
X    id.id_ld = &ethertalk_lap_description;
X    id.id_local = NULL;
X    id.id_isabridge = 0;
X***************
X*** 189,197 ****
X    init_fdlistening();  		/* low level scheduler	*/
X    etalk_init(&id, FALSE);	/* set up EtherTalk	*/
X  
X!   this_node = nis_node = etalk_mynode(&id);
X    if (dbug.db_flgs || (dlevel != 0))
X      printf("acquired node number %d\n", this_node);
X  }
X  
X  disassociate()
X--- 215,233 ----
X    init_fdlistening();  		/* low level scheduler	*/
X    etalk_init(&id, FALSE);	/* set up EtherTalk	*/
X  
X!   ea = etalk_mynode(&id);
X!   this_node = nis_node = ea->node;
X! #ifdef PHASE2
X!   this_net = nis_net = (ea->dummy[1] << 8) | ea->dummy[2];
X! #endif PHASE2
X! 
X    if (dbug.db_flgs || (dlevel != 0))
X+ #ifdef PHASE2
X+     printf("acquired node number %d/%d.%d\n",
X+ 		this_node, (this_net >> 8) & 0xff, this_net & 0xff);
X+ #else  PHASE2
X      printf("acquired node number %d\n", this_node);
X+ #endif PHASE2
X  }
X  
X  disassociate()
X***************
X*** 229,235 ****
X--- 265,276 ----
X  {
X    u_char *ea;
X  
X+ #ifdef PHASE2
X+   struct ethertalkaddr *pa = (struct ethertalkaddr *) node;
X+   logit(2, "request for %d/%d.%d", pa->node, pa->dummy[1], pa->dummy[2]);
X+ #else  PHASE2
X    logit(2, "request for %d", *node);
X+ #endif PHASE2
X    ea = etalk_resolve(&id, *node);
X    return((ea) ? ea : null_ether);
X  }
X***************
X*** 244,250 ****
X    int *i;
X    struct svc_req *rqstp;
X  {
X!   logit(2, "request for bridge address");
X    return((u_char *) &baddr);
X  }
X  
X--- 285,291 ----
X    int *i;
X    struct svc_req *rqstp;
X  {
X!   logit(2, "request for bridge address: %d.%d", baddr.net, baddr.node);
X    return((u_char *) &baddr);
X  }
X  
X***************
X*** 268,274 ****
X--- 309,387 ----
X    return((u_char *) &baddr);
X  }
X  
X+ #ifdef PHASE2
X  /*
X+  * Set the network range (Phase 2). Check that the current
X+  * node number is free for use in the new range by aarping
X+  * for the new address to see if anybody responds.
X+  *
X+  * (could be called from atis, which is listening to
X+  * RTMP packets or for an arriving GetNetInfo packet)
X+  *
X+  */
X+ 
X+ u_char *
X+ range_set_svc(range, rqstp)
X+   unsigned long *range;
X+   struct svc_req *rqstp;
X+ {
X+   int attempts, totalattempts;
X+   static struct ethertalkaddr eaddr;
X+   short new_net, new_net_start, new_net_end;
X+ 
X+   new_net_start = (*range >> 16) & 0xffff;
X+   new_net_end   = (*range & 0xffff);
X+   new_net = new_net_start;
X+   logit(5, "Changing network range: %04x-%04x -> %04x-%04x",
X+     net_range_start, net_range_end, new_net_start, new_net_end);
X+   eaddr.dummy[0] = 0;
X+   eaddr.dummy[1] = (htons(new_net) >> 8) & 0xff;
X+   eaddr.dummy[2] = (htons(new_net) & 0xff);
X+   eaddr.node = this_node;
X+   /* probe a few times for the new address */
X+   totalattempts = 0;
X+   for (attempts = 0 ; attempts < 20 ; attempts++) {
X+     logit(5, "Probing for %d/%d.%d", eaddr.node,
X+ 		eaddr.dummy[1], eaddr.dummy[2]);
X+     /* this is a hack, just sending aarp probes doesn't */
X+     /* work so we alternate them with aarp requests :-( */
X+     eaddr.dummy[0] = ((attempts & 0x01) == 0);
X+     if (etalk_resolve(&id, *(long *)&eaddr) != NULL) {
X+       logit(5, "Node number %d already in use!", eaddr.node);
X+       /* oops, pick another */
X+       if (++eaddr.node >= 0xfe) /* reserved */
X+ 	eaddr.node = 1;
X+       attempts = 0; /* same again */
X+       if (++totalattempts > 252) {
X+         /* oh dear, have to try another net */
X+ 	if (++new_net > new_net_end) {
X+ 	  logit(5, "OOPS: no spare nodes available on net!!");
X+ 	  return(NULL);
X+ 	}
X+         eaddr.dummy[1] = (htons(new_net) >> 8) & 0xff;
X+         eaddr.dummy[2] = (htons(new_net) & 0xff);
X+ 	totalattempts = 0;
X+       }
X+     }
X+     abSleep(1, FALSE); /* allow protocols to run */
X+   }
X+   eaddr.dummy[0] = 0;
X+   /* adopt it by updating our internal tables */
X+   if (etalk_set_mynode(&id, &eaddr) < 0) {
X+     logit(5, "Couldn't update net and node numbers");
X+     return(NULL);
X+   }
X+   logit(5, "Adopting %d/%d.%d", eaddr.node, eaddr.dummy[1], eaddr.dummy[2]);
X+   net_range_start = new_net_start;
X+   net_range_end = new_net_end;
X+   this_net = nis_net = new_net;
X+   this_node = nis_node = eaddr.node;
X+   etalkdbupdate(NULL);
X+   return((u_char *) range);
X+ }
X+ #endif PHASE2
X+ 
X+ /*
X   * add the RPC descriptors to the low level scheduler
X   *
X   */
X***************
X*** 312,314 ****
X--- 425,580 ----
X    	for (;;)
X  	  abSleep(sectotick(30), TRUE);
X  }
X+ 
X+ #ifdef PHASE2
X+ 
X+ #define ZIPQuery	1
X+ #define ZIPReply	2
X+ #define ZIPEReply	8
X+ #define ZIPGetInfoReq	5
X+ #define ZIPGetInfoRepl	6
X+ 
X+ #define ZIPATTEMPTS	4
X+ 
X+ #define ZIPZoneBad	0x80
X+ #define ZIPNoMultiCast	0x40
X+ #define ZIPSingleZone	0x20
X+ 
X+ private int zisSkt;
X+ private int heardFrom;
X+ private char zmcaddr[6];
X+ private char defzone[34];
X+ private u_short range_start;
X+ private u_short range_end;
X+ 
X+ /*
X+  * This is the ZIP ZIS listener
X+  * (at present we are only interested
X+  * in receiving one GetNetInfo packet
X+  * and that only at startup)
X+  *
X+  */
X+ 
X+ void
X+ zis_listener(skt, type, zis, len, addr)
X+ u_char skt;
X+ u_char type;
X+ u_char *zis;
X+ int len;
X+ AddrBlock *addr;
X+ {
X+   int x;
X+   unsigned long range;
X+   u_char *range_set_svc();
X+ 
X+   if (heardFrom)
X+     return; /* drop it */
X+ 
X+   if (type == ddpATP)
X+     return; /* drop it */
X+ 
X+   if (type != ddpZIP) {
X+     logit(3, "ZIS listener - bad packet");
X+     return; /* drop it */
X+   }
X+ 
X+   defzone[0] = '\0';
X+ 
X+   switch (*zis) {
X+     case ZIPQuery:
X+     case ZIPReply:
X+     case ZIPEReply:
X+     case ZIPGetInfoReq:
X+       break; /* drop it */
X+     case ZIPGetInfoRepl:
X+       heardFrom = 1;
X+       range_start = (zis[2] << 8) | zis[3];
X+       range_end   = (zis[4] << 8) | zis[5];
X+       if ((x = zis[6]) < sizeof(defzone)) {
X+         bcopy(&zis[7], defzone, x);
X+ 	defzone[x] = '\0';
X+       }
X+       x += 7;	/* multicast address */
X+       if (zis[x] != sizeof(zmcaddr)) {
X+ 	fprintf(stderr, "Bogus Multicast Address length %d\n", zis[x]);
X+ 	exit(1);
X+       }
X+       bcopy(&zis[x+1], zmcaddr, sizeof(zmcaddr));
X+       logit(3, "GetNetInfo reply packet arrived:");
X+       logit(3, "%sFlags 0x%02x, rangeStart %04x, rangeEnd %04x",
X+ 		"    ", zis[1], range_start, range_end);
X+       logit(3, "%sZone %s (len %d), MCZAddr %x:%x:%x:%x:%x:%x",
X+ 		"    ", defzone, zis[6], (u_char) zmcaddr[0],
X+ 		    (u_char) zmcaddr[1], (u_char) zmcaddr[2],
X+ 		    (u_char) zmcaddr[3], (u_char) zmcaddr[4],
X+ 		    (u_char) zmcaddr[5]);
X+       if (zis[1] & ZIPZoneBad) {
X+         x += 7;
X+ 	if (zis[x] < sizeof(defzone)) {
X+ 	  bcopy(&zis[x+1], defzone, zis[x]);
X+ 	  defzone[zis[x]] = '\0';
X+ 	}
X+ 	fprintf(stderr, "Zone \"%s\" unknown, network default is \"%s\"\n",
X+ 		GetMyZone(), defzone);
X+ 	exit(1);
X+       }
X+       range = ((range_start << 16) | (range_end & 0xffff));
X+       if (range_set_svc(&range, 0L) == NULL) {
X+         fprintf(stderr, "Can't change network range!\n");
X+         exit(1);
X+       }
X+       strncpy(ifreq.ifr_name, interface, sizeof(ifreq.ifr_name));
X+       if (pi_addmulti(-1, zmcaddr, (caddr_t)&ifreq) < 0) {
X+         fprintf(stderr, "Can't add zone multicast address!\n");
X+         exit(1);
X+       }
X+       break;
X+   }
X+ }
X+ 
X+ /*
X+  * open the ZIS socket, start the listener, probe for netinfo
X+  *
X+  */
X+ 
X+ int
X+ getNetInfo()
X+ {
X+   void zis_listener();
X+   ABusRecord ddpr;
X+   u_char zipbuf[48];
X+   char *GetMyZone();
X+   int count;
X+ 
X+   abInit(FALSE);
X+   heardFrom = 0;
X+   zisSkt = ddpZIP;
X+   if (DDPOpenSocket(&zisSkt, zis_listener) != noErr) {
X+     logit(0, "Failed to start ZIS listener!");
X+     exit(1);
X+   }
X+   zipbuf[0] = ZIPGetInfoReq; zipbuf[1] = 0x0;
X+   zipbuf[2] = 0x0; zipbuf[3] = 0x0;
X+   zipbuf[4] = 0x0; zipbuf[5] = 0x0;
X+   strncpy(&zipbuf[7], GetMyZone(), sizeof(zipbuf)-8);
X+   zipbuf[6] = strlen(&zipbuf[7]);
X+   ddpr.abResult = 0;
X+   ddpr.proto.ddp.ddpAddress.net  = 0x0000;	/* local net	*/
X+   ddpr.proto.ddp.ddpAddress.node = 0xff;	/* broadcast	*/
X+   ddpr.proto.ddp.ddpAddress.skt  = zisSkt;	/* to ZIS at GW	*/
X+   ddpr.proto.ddp.ddpSocket = zisSkt;		/* from our ZIS	*/
X+   ddpr.proto.ddp.ddpType = ddpZIP;
X+   ddpr.proto.ddp.ddpDataPtr = (u_char *) zipbuf;
X+   ddpr.proto.ddp.ddpReqCount = zipbuf[6] + 7;
X+   for (count = 0 ; count < ZIPATTEMPTS ; count++) {
X+     logit(3, "sending GetNetInfo request ...");
X+     DDPWrite(&ddpr, FALSE);			/* send it to GW    */
X+     abSleep(sectotick(4), FALSE);		/* wait for a reply */
X+     if (heardFrom) break;			/* don't ask again  */
X+   }
X+   /* abSleep(sectotick(10), FALSE);		/* time to re-init  */
X+   if (!heardFrom)
X+     heardFrom = 1;				/* ignore it later  */
X+   logit(3, "AARPD .... Running");
X+ }
X+ #endif PHASE2
X*** support/ethertalk/aarpd.h.orig	Thu Feb 28 23:46:12 1991
X--- support/ethertalk/aarpd.h		Wed May 29 22:31:28 1991
X***************
X*** 6,11 ****
X--- 6,12 ----
X  #define AARP_RESOLVE ((u_long)1)
X  #define RTMP_GETBADDR ((u_long)2)
X  #define RTMP_SETBADDR ((u_long)3)
X+ #define NET_RANGE_SET ((u_long)4)
X  
X  #define INTFSIZE	50
X  #define INTZONESIZE	40
X*** support/ethertalk/aarpd_clnt.c.orig	Thu Mar 14 15:32:00 1991
X--- support/ethertalk/aarpd_clnt.c	Wed May 29 22:33:07 1991
X***************
X*** 4,9 ****
X--- 4,10 ----
X   * Created: Charles Hedrick, Rutgers University <hedrick@rutgers.edu>
X   * Modified: David Hornsby, Melbourne University <djh@munnari.OZ.AU>
X   *	16/02/91: add rtmp_[sg]etbaddr_clnt()
X+  *	28/04/91: add range_set_clnt()
X   */
X  
X  #include <rpc/rpc.h>
X***************
X*** 69,71 ****
X--- 70,92 ----
X  	}
X  	return (res);
X  }
X+ 
X+ #ifdef PHASE2
X+ /*
X+  * Set the network range
X+  */
X+ 
X+ u_char *
X+ range_set_clnt(argp, clnt)
X+ 	int *argp;
X+ 	CLIENT *clnt;
X+ {
X+ 	static bridgeaddr res;	/* convenient size */
X+ 	bzero((char *)res, sizeof(res));
X+ 	if (clnt_call(clnt, NET_RANGE_SET, xdr_int, argp, xdr_bridgeaddr,
X+ 	    res, TIMEOUT) != RPC_SUCCESS) {
X+ 		return (NULL);
X+ 	}
X+ 	return (res);
X+ }
X+ #endif PHASE2
X*** support/ethertalk/aarpd_svc.c.orig	Thu Mar 14 15:32:58 1991
X--- support/ethertalk/aarpd_svc.c	Wed May 29 22:36:29 1991
X***************
X*** 4,9 ****
X--- 4,10 ----
X   * Created: Charles Hedrick, Rutgers University <hedrick@rutgers.edu>
X   * Modified: David Hornsby, Melbourne University <djh@munnari.OZ.AU>
X   *	16/02/91: add RTMP_[SG]ETBADDR
X+  *	28/04/91: add NET_RANGE_SET
X   *
X   */
X  
X***************
X*** 17,22 ****
X--- 18,26 ----
X  extern char *aarp_resolve_svc();
X  extern char *rtmp_getbaddr_svc();
X  extern char *rtmp_setbaddr_svc();
X+ #ifdef PHASE2
X+ extern char *range_set_svc();
X+ #endif PHASE2
X  
X  void
X  aarpdprog(rqstp, transp)
X***************
X*** 52,57 ****
X--- 56,69 ----
X  		xdr_result = xdr_bridgeaddr;
X  		local = (char *(*)()) rtmp_setbaddr_svc;
X  		break;
X+ 
X+ #ifdef PHASE2
X+ 	case NET_RANGE_SET:
X+ 		xdr_argument = xdr_int;
X+ 		xdr_result = xdr_bridgeaddr;
X+ 		local = (char *(*)()) range_set_svc;
X+ 		break;
X+ #endif PHASE2
X  		
X  	default:
X  		svcerr_noproc(transp);
X*** support/ethertalk/aarptest.c.orig	Wed Mar 13 21:12:20 1991
X--- support/ethertalk/aarptest.c	Wed May 29 22:38:32 1991
X***************
X*** 9,14 ****
X--- 9,16 ----
X  #include <rpc/rpc.h>
X  #include <sys/file.h>
X  #include <sys/types.h>
X+ #include <netat/appletalk.h>
X+ #include "../uab/ethertalk.h"
X  #include "aarpd.h"
X  
X  extern u_char *aarp_resolve_clnt();
X***************
X*** 23,29 ****
X  {
X    CLIENT *cl;
X    u_char *ether;
X!   int node;
X  #ifdef pyr
X    int sock;
X    struct timeval tv;
X--- 25,31 ----
X  {
X    CLIENT *cl;
X    u_char *ether;
X!   struct ethertalkaddr node;
X  #ifdef pyr
X    int sock;
X    struct timeval tv;
X***************
X*** 48,54 ****
X    }
X  
X    if (argc > 1) {
X!     node = atoi(argv[1]);
X      ether = aarp_resolve_clnt(&node, cl);
X      if (ether == NULL) {
X        clnt_perror(cl, "localhost");
X--- 50,65 ----
X    }
X  
X    if (argc > 1) {
X! #ifdef PHASE2
X!     if (argc > 2) {
X!       node.dummy[0] = 0;
X!       node.dummy[1] = (htons(atoi(argv[2])) >> 8) & 0xff;
X!       node.dummy[2] = (htons(atoi(argv[2])) & 0xff);
X!     }
X! #else  PHASE2
X!     node.dummy[0] = node.dummy[1] = node.dummy[2] = 0;
X! #endif PHASE2
X!     node.node = atoi(argv[1]) & 0xff;
X      ether = aarp_resolve_clnt(&node, cl);
X      if (ether == NULL) {
X        clnt_perror(cl, "localhost");
X*** support/ethertalk/abelap.c.orig	Wed Mar 13 21:10:47 1991
X--- support/ethertalk/abelap.c		Wed May 29 22:39:44 1991
X***************
X*** 1,7 ****
X  /*
X!  * $Author: djh $ $Date: 91/03/13 20:09:38 $
X!  * $Header: abelap.c,v 2.2 91/03/13 20:09:38 djh Exp $
X!  * $Revision: 2.2 $
X  */
X  
X  /*
X--- 1,7 ----
X  /*
X!  * $Author: djh $ $Date: 1991/05/29 12:39:38 $
X!  * $Header: /mac/src/cap60/support/ethertalk/RCS/abelap.c,v 2.3 1991/05/29 12:39:38 djh Rel djh $
X!  * $Revision: 2.3 $
X  */
X  
X  /*
X***************
X*** 17,22 ****
X--- 17,23 ----
X   *
X   *  June 14, 1986    Schilit	Created.
X   *  June 18, 1986    CCKim      Chuck's handler runs protocol
X+  *  April 28,1991    djh	Add Phase 2 support
X   *
X   */
X  /*
X***************
X*** 31,36 ****
X--- 32,39 ----
X   *     Return bridge addresses
X   *  OSErr SetBridgeAddress(AddrBlock *addr)
X   *     Set bridge addresses
X+  *  OSErr SetNetRange(u_short range_start, u_short range_end)
X+  *     Set Network Range (Phase 2)
X   *  int abInit(boolean dispay_message)
X   *     Initialize AppleTalk
X   *  int abOpen(int *returnsocket, int wantsocket, struct iovec iov[], iovlen)
X***************
X*** 83,91 ****
X--- 86,102 ----
X  extern byte	this_node,	bridge_node,	nis_node;
X  extern char	this_zone[34],	async_zone[34],	interface[50];
X  
X+ #ifdef PHASE2
X+ extern word net_range_start, net_range_end;
X+ #endif PHASE2
X+ 
X  extern struct in_addr bridge_addr;
X  
X+ #ifdef PHASE2			/* not a dynamic choice yet ...	*/
X+ short lap_proto = LAP_ETALK;	/* default to EtherTalk Phase 2 */
X+ #else  PHASE2
X  short lap_proto = LAP_ETALK;	/* default to EtherTalk Phase 1 */
X+ #endif PHASE2
X  
X  /*
X   * Configuration defines
X***************
X*** 117,123 ****
X--- 128,138 ----
X  private u_char *lasteaddr;
X  private u_char eaddrbuf[16];
X  
X+ #ifdef PHASE2
X+ u_char etherbroad[6] = {0x09, 0x00, 0x07, 0xff, 0xff, 0xff};
X+ #else  PHASE2
X  u_char etherbroad[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
X+ #endif PHASE2
X  
X  private struct sockaddr_in from_sin; /* network struct of last packet rec. */
X  private struct sockaddr_in abfsin; /* apple bus foreign socketaddr/internet */
X***************
X*** 538,550 ****
X    lastnet = -1;
X    lastnode = -1;
X  
X!   if ((cc = pi_reada(fd, pack, packsize, eaddrbuf)) < 0) {
X      return(-1);
X!   }
X    lasteaddr = eaddrbuf + 6;
X  
X    if (cc <= lapSize)  /* not much use if only lap */
X      return(-1);
X    pos = lapSize;
X    cc -= pos;
X    iov++;
X--- 553,566 ----
X    lastnet = -1;
X    lastnode = -1;
X  
X!   if ((cc = pi_reada(fd, pack, packsize, eaddrbuf)) <= 0)
X      return(-1);
X!  
X    lasteaddr = eaddrbuf + 6;
X  
X    if (cc <= lapSize)  /* not much use if only lap */
X      return(-1);
X+ 
X    pos = lapSize;
X    cc -= pos;
X    iov++;
X***************
X*** 552,566 ****
X  
X    bcopy(pack, &laph, lapSize);
X  
X!   if (laph.src == 0xff) {		/* bad, bad, bad */
X      return(-1);
X!   }
X    /* lap dest isn't right */
X    /* fixup point */
X  
X!   if (laph.dst != 0xff && laph.dst != this_node) {
X      return(-1);
X-   }
X  
X  #ifdef undef
X    /* pick out source for aarp table management if not self */
X--- 568,581 ----
X  
X    bcopy(pack, &laph, lapSize);
X  
X!   if (laph.src == 0xff)		/* bad, bad, bad */
X      return(-1);
X! 
X    /* lap dest isn't right */
X    /* fixup point */
X  
X!   if (laph.dst != 0xff && laph.dst != this_node)
X      return(-1);
X  
X  #ifdef undef
X    /* pick out source for aarp table management if not self */
X***************
X*** 673,678 ****
X--- 688,694 ----
X    int fd;
X    unsigned char *eaddr;
X    int destnode;
X+   int destnet;
X    AARP_ENTRY *ae;
X    struct ethertalkaddr etaddr;
X    AddrBlock baddr;
X***************
X*** 718,736 ****
X        perror("abwrite");
X      return(err);
X    }
X    if ((lap_proto == LAP_ETALK)
X    && (ddp->dstNet != this_net || ddp->dstNode != this_node)) {
X      eaddr = NULL;
X      if (ddp->dstNet == this_net) {
X        destnode = ddp->dstNode;
X      } else {
X        if (ddp->dstNet == lastnet && ddp->dstNode == lastnode) {
X          destnode = lastlnode;
X          eaddr = lasteaddr;
X        } else {
X! 	if (GetBridgeAddress(&baddr) == noErr && baddr.node)
X            destnode = baddr.node;
X!         else
X            return(-1);
X        }
X      }
X--- 734,768 ----
X        perror("abwrite");
X      return(err);
X    }
X+ #ifdef PHASE2
X+   /* delete the unwanted LAP header */
X+   iov[IOV_LAP_LVL].iov_len = 0;
X+ #endif PHASE2
X    if ((lap_proto == LAP_ETALK)
X    && (ddp->dstNet != this_net || ddp->dstNode != this_node)) {
X      eaddr = NULL;
X+ #ifdef PHASE2
X+     if ((ddp->dstNet == 0 && ddp->dstNode == 0xff) /* local broadcast */
X+      || (ddp->dstNet >= net_range_start && ddp->dstNet <= net_range_end)
X+      || (ddp->dstNet >= 0xff00 && ddp->dstNet <= 0xfffe)) { /* startup */
X+       destnode = ddp->dstNode;
X+       destnet = ddp->dstNet;
X+     } else {
X+ #else  PHASE2
X      if (ddp->dstNet == this_net) {
X        destnode = ddp->dstNode;
X+       destnet = ddp->dstNet;
X      } else {
X+ #endif PHASE2
X        if (ddp->dstNet == lastnet && ddp->dstNode == lastnode) {
X          destnode = lastlnode;
X+ 	destnet = lastnet;
X          eaddr = lasteaddr;
X        } else {
X! 	if (GetBridgeAddress(&baddr) == noErr && baddr.node) {
X            destnode = baddr.node;
X! 	  destnet = baddr.net;
X!         } else
X            return(-1);
X        }
X      }
X***************
X*** 741,747 ****
X--- 773,785 ----
X        if (destnode == 0xff)
X  	eaddr = etherbroad;
X        else {
X+ #ifdef PHASE2
X+ 	etaddr.dummy[0] = 0;
X+ 	etaddr.dummy[1] = (htons(destnet) >> 8) & 0xff;
X+ 	etaddr.dummy[2] = (htons(destnet) & 0xff);
X+ #else  PHASE2
X  	etaddr.dummy[0] = etaddr.dummy[1] = etaddr.dummy[2] = 0;
X+ #endif PHASE2
X  	etaddr.node = destnode;
X  	if ((ae = aarptab_find(&aih, &etaddr)) != NULL &&
X  	    ae->aae_flags & AARP_OKAY) {
X***************
X*** 754,760 ****
X      }
X  
X      if (! eaddr) {
X!       eaddr = aarp_resolve_clnt(&destnode, cl);
X        if (eaddr == NULL) {
X  	clnt_perror(cl, "localhost");
X  	return(-1);
X--- 792,798 ----
X      }
X  
X      if (! eaddr) {
X!       eaddr = aarp_resolve_clnt(&etaddr, cl);
X        if (eaddr == NULL) {
X  	clnt_perror(cl, "localhost");
X  	return(-1);
X***************
X*** 839,841 ****
X--- 877,906 ----
X        bridge_node = addr->node;
X        return(noErr);
X  }
X+ 
X+ #ifdef PHASE2
X+ /*
X+  * Set Network Range (via RPC for Native EtherTalk)
X+  *
X+  */
X+ 
X+ OSErr
X+ SetNetRange(range_start, range_end)
X+ u_short range_start, range_end;
X+ {
X+       AddrBlock *baddr;
X+       long range;
X+ 
X+       if (lap_proto == LAP_ETALK) {
X+ 	range = range_start & 0xffff;	/* host byte order */
X+ 	range <<= 16;
X+ 	range |= range_end & 0xffff;	/* host byte order */
X+         baddr = (AddrBlock *) range_set_clnt(&range, cl);
X+         if (baddr == NULL)
X+ 	  clnt_perror(cl, "localhost");
X+       }
X+       this_net = nis_net = net_range_start = range_start;
X+       net_range_end = range_end;
X+       return(noErr);
X+ }
X+ #endif PHASE2
X*** lib/cap/abnbp.c.orig	Wed Mar 13 21:00:37 1991
X--- lib/cap/abnbp.c		Wed May 29 22:41:01 1991
X***************
X*** 1,7 ****
X  /*
X!  * $Author: djh $ $Date: 91/03/13 20:00:06 $
X!  * $Header: abnbp.c,v 2.2 91/03/13 20:00:06 djh Exp $
X!  * $Revision: 2.2 $
X  */
X  
X  /*
X--- 1,7 ----
X  /*
X!  * $Author: djh $ $Date: 1991/05/29 12:40:53 $
X!  * $Header: /mac/src/cap60/lib/cap/RCS/abnbp.c,v 2.3 1991/05/29 12:40:53 djh Rel djh $
X!  * $Revision: 2.3 $
X  */
X  
X  /*
X***************
X*** 20,25 ****
X--- 20,26 ----
X   *  July  1, 1986    Schilit	rewrite with async and NBPConfirm
X   *  July  9, 1986    CCKim	Clean up and rewrite create_entity
X   *  July 15, 1986    CCKim	Add nbpregister, nbpdelete
X+  *  April 28,1991    djh	Added Phase 2 support
X   *
X   */
X  
X***************
X*** 370,375 ****
X--- 371,395 ----
X      break;
X    }
X    nsize = c2pkt_ename(nbpr->nbpEntityPtr,nbp.tuple[0].name);
X+ #ifdef PHASE2
X+   { char *q, *GetMyZone();
X+     /* add the zone name for outgoing NBP lookups  */
X+     if (nbpr->abOpcode == tNBPLookUp && nsize >= 2) {
X+       q = (char *) &nbp.tuple[0].name[nsize-2];
X+       if (*q == 0x01 && *(q+1) == '*') {	/* zone "*"  */
X+         strcpy(q+1, GetMyZone());
X+         *q = strlen(q+1);
X+         nsize += (*q - 1);
X+       } else {
X+         if (*(q+1) == '\0') {			/* null zone */
X+           strcpy(q+2, GetMyZone());
X+           *(q+1) = strlen(q+2);
X+           nsize += *(q+1);
X+         }
X+       }
X+     }
X+   }
X+ #endif PHASE2
X    ddpr->ddpReqCount = nbpBaseSize+nsize;
X    DDPWrite(&ddp);		/* write it out... */
X  }
X*** lib/cap/atalkdbm.c.orig	Thu Apr 11 22:00:56 1991
X--- lib/cap/atalkdbm.c		Wed May 29 22:42:09 1991
X***************
X*** 1,10 ****
X  /*
X!  * $Date: 91/04/11 22:00:15 $
X!  * $Header: atalkdbm.c,v 2.5 91/04/11 22:00:15 djh Exp $
X!  * $Revision: 2.5 $
X   *
X   * mods for async appletalk support, /etc/etalk.local for EtherTalk and
X   * changes for quoted zone names: djh@munnari.OZ.AU, 27/11/90
X   *
X  */
X  
X--- 1,11 ----
X  /*
X!  * $Date: 1991/05/29 12:42:02 $
X!  * $Header: /mac/src/cap60/lib/cap/RCS/atalkdbm.c,v 2.6 1991/05/29 12:42:02 djh Rel djh $
X!  * $Revision: 2.6 $
X   *
X   * mods for async appletalk support, /etc/etalk.local for EtherTalk and
X   * changes for quoted zone names: djh@munnari.OZ.AU, 27/11/90
X+  * Phase 2 support: djh@munnari.OZ.AU, 28/04/91
X   *
X  */
X  
X***************
X*** 52,57 ****
X--- 53,62 ----
X  u_char	this_node=0,	bridge_node=0,	nis_node=0;
X  char	this_zone[34],	async_zone[34],	interface[50];
X  
X+ #ifdef PHASE2
X+ u_short net_range_start = 0, net_range_end = 0xfffe;
X+ #endif PHASE2
X+ 
X  struct	in_addr bridge_addr;
X  
X  char enet_device[50];
X***************
X*** 338,346 ****
X--- 343,361 ----
X      if (lap_proto == LAP_MKIP)
X        fprintf(fp, "# Generated by UAB\n#\n");
X      if (lap_proto == LAP_ETALK)
X+ #ifdef PHASE2
X+       fprintf(fp, "# Generated by native EtherTalk (Phase 2)\n#\n");
X+ #else  PHASE2
X        fprintf(fp, "# Generated by native EtherTalk (Phase 1)\n#\n");
X+ #endif PHASE2
X      if (*interface != '\0')
X        fprintf(fp, "%-12s\t\"%s\"\n", ETH_INTERFACE, interface);
X+ #ifdef PHASE2
X+     fprintf(fp, "%-12s\t%2d.%02d\n", ETH_NET_START,
X+       ((ntohs(net_range_start) >> 8) & 0xff), (ntohs(net_range_start) & 0xff));
X+     fprintf(fp, "%-12s\t%2d.%02d\n", ETH_NET_END,
X+       ((ntohs(net_range_end) >> 8) & 0xff), (ntohs(net_range_end) & 0xff));
X+ #endif PHASE2
X      fprintf(fp, "%-12s\t%2d.%02d\n", ETH_THIS_NET,
X        ((ntohs(this_net) >> 8) & 0xff), (ntohs(this_net) & 0xff));
X      fprintf(fp, "%-12s\t%d\n", ETH_THIS_NODE, (this_node & 0xff));
X***************
X*** 378,383 ****
X--- 393,404 ----
X  
X    if (strcmp(name, ETH_INTERFACE) == 0)
X      strncpy(interface, value, sizeof(interface));
X+ #ifdef PHASE2
X+   else if (strcmp(name, ETH_NET_START) == 0)
X+     net_range_start = htons(atnetshort(value));
X+   else if (strcmp(name, ETH_NET_END) == 0)
X+     net_range_end = htons(atnetshort(value));
X+ #endif PHASE2
X    else if (strcmp(name, ETH_THIS_NET) == 0)
X      this_net = htons(atnetshort(value));
X    else if (strcmp(name, ETH_THIS_NODE) == 0)
X*** lib/cap/atalkdbm.h.orig	Thu Feb 28 23:43:18 1991
X--- lib/cap/atalkdbm.h		Wed May 29 22:43:17 1991
X***************
X*** 18,20 ****
X--- 18,24 ----
X  #define ETH_ASYNC_NET	"asyncNet"
X  #define ETH_ASYNC_ZONE	"asyncZone"
X  #define ETH_INTERFACE	"interface"
X+ #ifdef PHASE2
X+ #define ETH_NET_START	"netRangeStart"
X+ #define ETH_NET_END	"netRangeEnd"
X+ #endif PHASE2
X*** etc/atis.c.orig	Wed Mar 13 20:48:53 1991
X--- etc/atis.c		Wed May 29 22:44:18 1991
X***************
X*** 1,6 ****
X! static char rcsid[] = "$Author: djh $ $Date: 91/03/13 19:47:20 $";
X! static char rcsident[] = "$Header: atis.c,v 2.2 91/03/13 19:47:20 djh Exp $";
X! static char revision[] = "$Revision: 2.2 $";
X  
X  /*
X   * atis.c - a simple appletalk information server
X--- 1,6 ----
X! static char rcsid[] = "$Author: djh $ $Date: 1991/05/29 12:44:11 $";
X! static char rcsident[] = "$Header: /mac/src/cap60/etc/RCS/atis.c,v 2.3 1991/05/29 12:44:11 djh Rel djh $";
X! static char revision[] = "$Revision: 2.3 $";
X  
X  /*
X   * atis.c - a simple appletalk information server
X***************
X*** 24,29 ****
X--- 24,30 ----
X   *   July 10, 1986    CCKim	Created
X   *   August 2, 1986   CCKim     Add dump and load functionality
X   *   December 17, 1986 CCKim	Revise to rev1086 of UDP code
X+  *   April 28, 1991   djh	Add Phase 2 support
X   *
X  */
X  
X***************
X*** 82,87 ****
X--- 83,92 ----
X  
X  extern short lap_proto;		/* identifies the "LAP" level */
X  
X+ #ifdef PHASE2
X+ extern u_short this_net, nis_net, net_range_start, net_range_end;
X+ #endif PHASE2
X+ 
X  #ifndef ETCDIR
X  # define ETCDIR "/etc"
X  #endif
X***************
X*** 719,725 ****
X  rtmp_listener(skt, type, pkt, len, addr)
X  u_char skt;
X  u_char type;
X! char *pkt;
X  int len;
X  AddrBlock *addr;
X  {
X--- 724,730 ----
X  rtmp_listener(skt, type, pkt, len, addr)
X  u_char skt;
X  u_char type;
X! u_char *pkt;
X  int len;
X  AddrBlock *addr;
X  {
X***************
X*** 731,736 ****
X--- 736,744 ----
X    static time_t current_time;
X    static u_short current_node;
X    static int current_goodness = -1;
X+ #ifdef PHASE2
X+   u_short new_net_range_start, new_net_range_end, increment;
X+ #endif PHASE2
X  
X    if (type != ddpRTMP) {
X      logit(1, "Got non-rtmp pkt in rtmplistener");
X***************
X*** 737,743 ****
X      return;	/* drop packet */
X    }
X  
X!   net = *(u_short *)pkt;
X    logit(5, "Got RTMP pkt net %d from %d.%d", net, addr->net, addr->node);
X  
X    if (addr->net == 0 && net != 0) {
X--- 745,751 ----
X      return;	/* drop packet */
X    }
X  
X!   net = (pkt[0] << 8) | pkt[1];
X    logit(5, "Got RTMP pkt net %d from %d.%d", net, addr->net, addr->node);
X  
X    if (addr->net == 0 && net != 0) {
X***************
X*** 746,752 ****
X--- 754,764 ----
X      logit(1, "Gleaned network number %d from bridge %d", net, addr->node);
X    }
X  
X+ #ifdef PHASE2
X+   if (net >= net_range_start && net <= net_range_end) {
X+ #else  PHASE2
X    if (net == addr->net) {
X+ #endif PHASE2
X  /*
X   * Compute the goodness of this router.  We prefer routers that do
X   * split horizon, and among them, those that have the most routes.
X***************
X*** 772,779 ****
X--- 784,823 ----
X  /*
X   * go to beginning of routing triples
X   */
X+ #ifdef PHASE2
X+     pkt += 4;
X+     len -= 4;
X+     if (pkt[0] == 0 && pkt[1] == 0 && pkt[2] == 0x82) {	/* non-extended net */
X+       new_net_range_start = net;
X+       new_net_range_end   = net;
X+       increment = 0;
X+     } else if (pkt[5] == 0x82) {			/* extended network */
X+       new_net_range_start = (pkt[0] << 8) | pkt[1];
X+       new_net_range_end   = (pkt[3] << 8) | pkt[4];
X+       pkt += 3; len -= 3;
X+       increment = 3;
X+     } else {
X+       logit(2, "RTMP: unknown format packet, dropped!");
X+       return;
X+     }
X+     pkt += 3; len -= 3;
X+ #ifdef notdef
X+     /* ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ */
X+     /* we should be doing this, in case the router was down when */
X+     /* we started up. However, doing so will proably confuse our */
X+     /* clients too much. We should also do it to ensure that the */
X+     /* correct zone multicast address gets enabled on the intrfc */
X+     /* ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ */
X+     if (net_range_start == 0x00 && net_range_end == 0xfffe) {
X+       this_net = nis_net = net_range_start = new_net_range_start;
X+       net_range_end = new_net_range_end;
X+       SetNetRange(net_range_start, net_range_end);
X+     }
X+ #endif notdef
X+ #else  PHASE2
X      pkt += 7;
X      len -= 7;
X+ #endif PHASE2
X  /*
X   * loop over routing triples, counting them.
X   * If we find our own network, this router isn't doing split horizon.
X***************
X*** 789,794 ****
X--- 833,842 ----
X        goodness++;
X        len -= 3;
X        pkt += 3;
X+ #ifdef PHASE2
X+       len -= increment;
X+       pkt += increment;
X+ #endif PHASE2
X      }
X      logit (8, "Router %d.%d has goodness %d", addr->net, addr->node, goodness);
X      now = time(NULL);
X*** samples/atlook.c.orig	Thu Mar 14 14:59:27 1991
X--- samples/atlook.c		Wed May 29 22:45:55 1991
X***************
X*** 1,6 ****
X! static char rcsid[] = "$Author: djh $ $Date: 91/03/14 13:58:44 $";
X! static char rcsident[] = "$Header: atlook.c,v 2.2 91/03/14 13:58:44 djh Exp $";
X! static char revision[] = "$Revision: 2.2 $";
X  
X  /*
X   * atlook - UNIX AppleTalk test program: lookup entities
X--- 1,6 ----
X! static char rcsid[] = "$Author: djh $ $Date: 1991/05/29 12:45:49 $";
X! static char rcsident[] = "$Header: /mac/src/cap60/samples/RCS/atlook.c,v 2.3 1991/05/29 12:45:49 djh Rel djh $";
X! static char revision[] = "$Revision: 2.3 $";
X  
X  /*
X   * atlook - UNIX AppleTalk test program: lookup entities
X***************
X*** 280,285 ****
X--- 280,288 ----
X  {
X    int i;
X    EntityName en;			/* network entity name */
X+ #ifdef PHASE2
X+   char *GetMyZone();
X+ #endif PHASE2
X  
X    abInit(TRUE);				/* initialize appletalk driver */
X    nbpInit();				/* initialize nbp */
X***************
X*** 292,298 ****
X--- 295,305 ----
X      deftype = "LaserWriter";
X    strcpy(en.objStr.s,"=");		/* create default entity */
X    strcpy(en.typeStr.s,deftype);		/*  to lookup... */
X+ #ifdef PHASE2
X+   strcpy(en.zoneStr.s,GetMyZone());
X+ #else  PHASE2
X    strcpy(en.zoneStr.s,"*");
X+ #endif PHASE2
X  
X  
X    if (i == argc) {
X*** support/ethertalk/ethertalk.c.orig	Thu Mar 14 21:06:29 1991
X--- support/ethertalk/ethertalk.c	Wed May 29 22:47:09 1991
X***************
X*** 1,6 ****
X! static char rcsid[] = "$Author: djh $ $Date: 91/03/14 20:06:11 $";
X! static char rcsident[] = "$Header: ethertalk.c,v 2.2 91/03/14 20:06:11 djh Exp $";
X! static char revision[] = "$Revision: 2.2 $";
X  
X  /*
X   * ethertalk.c - ethertalk interface
X--- 1,6 ----
X! static char rcsid[] = "$Author: djh $ $Date: 1991/05/29 12:47:04 $";
X! static char rcsident[] = "$Header: /mac/src/cap60/support/ethertalk/RCS/ethertalk.c,v 2.3 1991/05/29 12:47:04 djh Rel djh $";
X! static char revision[] = "$Revision: 2.3 $";
X  
X  /*
X   * ethertalk.c - ethertalk interface
X***************
X*** 21,26 ****
X--- 21,27 ----
X   * Edit History:
X   *
X   *  April 3, 1988  CCKim Created
X+  *  April 28, '91  djh   Added Phase 2 support
X   *
X  */
X  
X***************
X*** 62,67 ****
X--- 63,71 ----
X  private int etalk_tables();
X  
X  extern byte this_node;
X+ #ifdef PHASE2
X+ extern u_short this_net;
X+ #endif PHASE2
X  
X  /* describe our interface to the world */
X  private char *ethertalk_lap_keywords[] = {
X***************
X*** 158,164 ****
X--- 162,172 ----
X    eh->eh_state = ELAP_WAITING;	/* mark waiting */
X  
X    /* acquire node address */
X+ #ifdef PHASE2
X+   if ( this_node <= 0 || this_node >= 254)
X+ #else  PHASE2
X    if ( this_node <= 0 || this_node >= 255)
X+ #endif PHASE2
X      hostid = 0xff & gethostid();	/* use last byte of hostid as hint */
X    else
X      hostid = this_node;
X***************
X*** 190,198 ****
X    struct ethertalkaddr pa;
X    int n;
X  
X    pa.dummy[0] = pa.dummy[1] = pa.dummy[2] = 0;
X!   /* EtherTalk II fixup */
X!   pa.node = hint;		/* use fourth byte of eaddr as guess */
X    while ((n=aarp_acquire_etalk_node(eh->eh_ah, &pa, who, eh)) != 0) {
X      if (n < 0) {
X        /* error */
X--- 198,211 ----
X    struct ethertalkaddr pa;
X    int n;
X  
X+ #ifdef PHASE2
X+   pa.dummy[0] = 0;  /* always zero */
X+   pa.dummy[1] = (htons(this_net) >> 8) & 0xff;
X+   pa.dummy[2] = (htons(this_net) & 0xff);
X+ #else  PHASE2
X    pa.dummy[0] = pa.dummy[1] = pa.dummy[2] = 0;
X! #endif PHASE2
X!   pa.node = hint;
X    while ((n=aarp_acquire_etalk_node(eh->eh_ah, &pa, who, eh)) != 0) {
X      if (n < 0) {
X        /* error */
X***************
X*** 220,226 ****
X--- 233,243 ----
X    IDESC_TYPE *id = eh->eh_id;	/* get interface description */
X  
X    if (result < 0) {
X+ #ifdef PHASE2
X+     if ((result = etalk_getnode(eh,(rand()%253)+1, etalk_initfinish)) < 0) {
X+ #else  PHASE2
X      if ((result = etalk_getnode(eh,(rand()%254)+1, etalk_initfinish)) < 0) {
X+ #endif PHASE2
X        logit(LOG_LOG, "could not acquire node on interface %s%d",
X  	  id->id_intf, id->id_intfno);
X        eh->eh_state = ELAP_BAD;
X***************
X*** 235,244 ****
X      eh->eh_state = ELAP_BAD;	/* mark bad */
X      return;
X    }
X!   eh->eh_enode.n_size = 8*nodesize; /* 8 bits */
X!   eh->eh_enode.n_bytes = nodesize; /* 1 byte */
X!   /* EtherTalk II fixup */
X    eh->eh_enode.n_id[0] = pa.node; /* this is it */
X  
X    flags = PORT_WANTSLONGDDP;
X    if (!pi_delivers_self_broadcasts())
X--- 252,267 ----
X      eh->eh_state = ELAP_BAD;	/* mark bad */
X      return;
X    }
X!   eh->eh_enode.n_size = 8*nodesize; /* 8 or 32 bits */
X!   eh->eh_enode.n_bytes = nodesize;  /* 1 or 4 bytes */
X! #ifdef PHASE2
X!   eh->eh_enode.n_id[0] = pa.dummy[0];
X!   eh->eh_enode.n_id[1] = pa.dummy[1];
X!   eh->eh_enode.n_id[2] = pa.dummy[2];
X!   eh->eh_enode.n_id[3] = pa.node;
X! #else  PHASE2
X    eh->eh_enode.n_id[0] = pa.node; /* this is it */
X+ #endif PHASE2
X  
X    flags = PORT_WANTSLONGDDP;
X    if (!pi_delivers_self_broadcasts())
X***************
X*** 246,252 ****
X    if (id->id_isabridge)
X      flags |= PORT_FULLRTMP;
X  
X!   eh->eh_state = ELAP_BAD;
X    logit(LOG_PRIMARY,"acquired node %d on interface %s%d",
X  	pa.node, id->id_intf, id->id_intfno);
X  }
X--- 269,275 ----
X    if (id->id_isabridge)
X      flags |= PORT_FULLRTMP;
X  
X!   eh->eh_state = ELAP_READY;
X    logit(LOG_PRIMARY,"acquired node %d on interface %s%d",
X  	pa.node, id->id_intf, id->id_intfno);
X  }
X***************
X*** 261,285 ****
X  
X    eh = (E_HANDLE *)id->id_ifuse;
X  
X!   /* EtherTalk II fixup */
X    tpa.dummy[0] = tpa.dummy[1] = tpa.dummy[2] = 0;
X    tpa.node = node;
X  
X!   if (aarp_resolve(eh->eh_ah, &tpa, node == 0xff, &eaddr) <= 0) {
X!     logit (2, "etalk_resolve: node %d try again later", node);
X      return(NULL);
X    }
X    return(eaddr);
X  }
X  
X! export etalk_mynode(id)
X  IDESC_TYPE *id;
X  {
X    E_HANDLE *eh;
X  
X    eh = (E_HANDLE *)id->id_ifuse;
X  
X!   return (eh->eh_enode.n_id[0]);
X  }
X  
X  /*
X--- 284,340 ----
X  
X    eh = (E_HANDLE *)id->id_ifuse;
X  
X! #ifdef PHASE2
X!   bcopy(&node, &tpa, ETPL);
X! #else  PHASE2
X    tpa.dummy[0] = tpa.dummy[1] = tpa.dummy[2] = 0;
X    tpa.node = node;
X+ #endif PHASE2
X  
X!   if (aarp_resolve(eh->eh_ah, &tpa, tpa.node == 0xff, &eaddr) <= 0) {
X! #ifdef PHASE2
X!     logit (2, "etalk_resolve: node %d/%d.%d try again later",
X! 		tpa.node, tpa.dummy[1], tpa.dummy[2]);
X! #else  PHASE2
X!     logit (2, "etalk_resolve: node %d try again later", tpa.node);
X! #endif PHASE2
X      return(NULL);
X    }
X    return(eaddr);
X  }
X  
X! #ifdef PHASE2
X! export int etalk_set_mynode(id, eaddr)
X  IDESC_TYPE *id;
X+ struct ethertalkaddr *eaddr;
X  {
X    E_HANDLE *eh;
X+   int hostid = eaddr->node;
X  
X    eh = (E_HANDLE *)id->id_ifuse;
X+   return(aarp_set_host_addr(eh->eh_ah, eaddr));
X+ }
X+ #endif PHASE2
X  
X! export struct ethertalkaddr *etalk_mynode(id)
X! IDESC_TYPE *id;
X! {
X!   E_HANDLE *eh;
X!   static struct ethertalkaddr ea;
X! 
X!   eh = (E_HANDLE *)id->id_ifuse;
X! #ifdef PHASE2
X!   ea.dummy[0] = eh->eh_enode.n_id[0];
X!   ea.dummy[1] = eh->eh_enode.n_id[1];
X!   ea.dummy[2] = eh->eh_enode.n_id[2];
X!   ea.node = eh->eh_enode.n_id[3];
X! #else  PHASE2
X!   ea.dummy[0] = 0;
X!   ea.dummy[1] = 0;
X!   ea.dummy[2] = 0;
X!   ea.node = eh->eh_enode.n_id[0];
X! #endif PHASE2
X!   return (&ea);
X  }
X  
X  /*
X***************
X*** 292,305 ****
X  word ddpnet;
X  byte ddpnode;
X  {
X!   /* EtherTalk II fixup */
X!   /* think this is okay */
X    static NODE node = { 1, 8 }; /* initialize */
X    int myddpnet = PORT_DDPNET(port);
X  
X    if (ddpnet != 0 && myddpnet != ddpnet) /* only allow this net! */
X      return(NULL);
X    node.n_id[0] = ddpnode;	/* make node */
X    return(&node);
X  }
X  
X--- 347,371 ----
X  word ddpnet;
X  byte ddpnode;
X  {
X! #ifdef PHASE2
X!   static NODE node = { 4, 32}; /* initialize */
X! #else  PHASE2
X    static NODE node = { 1, 8 }; /* initialize */
X+ #endif PHASE2
X    int myddpnet = PORT_DDPNET(port);
X  
X    if (ddpnet != 0 && myddpnet != ddpnet) /* only allow this net! */
X      return(NULL);
X+ 
X+ #ifdef PHASE2
X+   node.n_id[0] = 0;
X+   node.n_id[1] = (htons(ddpnet) >> 8) & 0xff;
X+   node.n_id[2] = (htons(ddpnet) & 0xff);
X+   node.n_id[3] = ddpnode;
X+ #else  PHASE2
X    node.n_id[0] = ddpnode;	/* make node */
X+ #endif PHASE2
X+ 
X    return(&node);
X  }
X  
X***************
X*** 310,318 ****
X  PORT_T port;
X  NODE *node;
X  {
X-   /* EtherTalk II fixup */
X    if (node->n_size == 8)	/* 8 bits? */
X      return(node->n_id[0]);
X    return(0);
X  }
X  
X--- 376,387 ----
X  PORT_T port;
X  NODE *node;
X  {
X    if (node->n_size == 8)	/* 8 bits? */
X      return(node->n_id[0]);
X+ #ifdef PHASE2
X+   if (node->n_size == 32)	/* 32 bits? */
X+     return(node->n_id[3]);
X+ #endif PHASE2
X    return(0);
X  }
X  
X***************
X*** 361,379 ****
X      stats[ES_ERR_OUTPUT]++;		/* can't */
X      return(-1);
X    }
X-   /* source is always us! */
X-   lap.src = eh->eh_enode.n_id[0]; /* get source node */
X-   lap.dst = dstnode->n_id[0];	/* get dest node */
X    lap.type = laptype;
X!   /* EtherTalk II fixup */
X    tpa.dummy[0] = tpa.dummy[1] = tpa.dummy[2] = 0;
X    tpa.node = dstnode->n_id[0];
X  
X    if (aarp_resolve(eh->eh_ah, &tpa, lap.dst == 0xff, &eaddr) <= 0) {
X      stats[ES_RESOLVE_ERR_OUTPUT]++;
X      return(-1);
X    }
X    iov[0].iov_len = lapSize;
X    iov[0].iov_base = (caddr_t)&lap;
X    iov[1].iov_len = hsize;
X    iov[1].iov_base = (caddr_t)header;
X--- 430,462 ----
X      stats[ES_ERR_OUTPUT]++;		/* can't */
X      return(-1);
X    }
X    lap.type = laptype;
X! #ifdef PHASE2
X!   tpa.dummy[0] = dstnode->n_id[0];
X!   tpa.dummy[1] = dstnode->n_id[1];
X!   tpa.dummy[2] = dstnode->n_id[2];
X!   tpa.node = dstnode->n_id[3];
X!   lap.dst = dstnode->n_id[3];	/* get dest node */
X!   /* source is always us! */
X!   lap.src = eh->eh_enode.n_id[3]; /* get source node */
X! #else  PHASE2
X    tpa.dummy[0] = tpa.dummy[1] = tpa.dummy[2] = 0;
X    tpa.node = dstnode->n_id[0];
X+   lap.dst = dstnode->n_id[0];	/* get dest node */
X+   /* source is always us! */
X+   lap.src = eh->eh_enode.n_id[0]; /* get source node */
X+ #endif PHASE2
X  
X    if (aarp_resolve(eh->eh_ah, &tpa, lap.dst == 0xff, &eaddr) <= 0) {
X      stats[ES_RESOLVE_ERR_OUTPUT]++;
X      return(-1);
X    }
X+ #ifdef PHASE2
X+   /* delete LAP hdr */
X+   iov[0].iov_len = 0;
X+ #else  PHASE2
X    iov[0].iov_len = lapSize;
X+ #endif PHASE2
X    iov[0].iov_base = (caddr_t)&lap;
X    iov[1].iov_len = hsize;
X    iov[1].iov_base = (caddr_t)header;
X*** support/uab/ethertalk.h.orig	Thu Feb 28 23:45:54 1991
X--- support/uab/ethertalk.h		Wed May 29 22:48:28 1991
X***************
X*** 1,7 ****
X  /*
X!  * $Author: djh $ $Date: 91/02/15 23:07:30 $
X!  * $Header: ethertalk.h,v 2.1 91/02/15 23:07:30 djh Rel $
X!  * $Revision: 2.1 $
X  */
X  
X  /*
X--- 1,7 ----
X  /*
X!  * $Author: djh $ $Date: 1991/05/29 12:48:21 $
X!  * $Header: /mac/src/cap60/support/uab/RCS/ethertalk.h,v 2.2 1991/05/29 12:48:21 djh Rel djh $
X!  * $Revision: 2.2 $
X  */
X  
X  /*
X***************
X*** 21,26 ****
X--- 21,27 ----
X   * Edit History:
X   *
X   *  August 1988  CCKim Created
X+  *  April  1991  djh   Added Phase 2 support
X   *
X  */
X  
X*** etc/nisaux.c.orig	Wed Mar 13 20:50:27 1991
X--- etc/nisaux.c	Wed May 29 22:50:28 1991
X***************
X*** 1,7 ****
X  /*
X!  * $Author: djh $ $Date: 91/03/13 19:50:02 $
X!  * $Header: nisaux.c,v 2.2 91/03/13 19:50:02 djh Exp $
X!  * $Revision: 2.2 $
X  */
X  
X  /*
X--- 1,7 ----
X  /*
X!  * $Author: djh $ $Date: 1991/05/29 12:50:14 $
X!  * $Header: /mac/src/cap60/etc/RCS/nisaux.c,v 2.3 1991/05/29 12:50:14 djh Rel djh $
X!  * $Revision: 2.3 $
X  */
X  
X  /*
X***************
X*** 89,95 ****
X--- 89,99 ----
X        return(nbpSR_access);
X      }
X    
X+ #ifdef PHASE2
X+   strcpy((char *)en->zoneStr.s, GetMyZone()); /* keep our name in table */
X+ #else  PHASE2
X    strcpy((char *)en->zoneStr.s, "*"); /* replace zone name with * in records */
X+ #endif PHASE2
X  
X    /* scan the list - see if we should be in the list at all. */
X    for (newenum = 0, i = 0; i < numnve; i++) {
X*** support/ethertalk/rtmptest.c.orig	Wed Mar 13 21:13:25 1991
X--- support/ethertalk/rtmptest.c	Wed May 29 22:51:28 1991
X***************
X*** 50,57 ****
X    }
X  
X    if (argc == 3) {
X!     baddr.net = atoi(argv[1]);
X!     baddr.node = atoi(argv[2]);
X      addr = rtmp_setbaddr_clnt(&baddr, cl);
X      if (addr == NULL) {
X        clnt_perror(cl, "localhost");
X--- 50,57 ----
X    }
X  
X    if (argc == 3) {
X!     baddr.node = atoi(argv[1]);
X!     baddr.net = atoi(argv[2]);
X      addr = rtmp_setbaddr_clnt(&baddr, cl);
X      if (addr == NULL) {
X        clnt_perror(cl, "localhost");
X*** support/ethertalk/snitp.c.orig	Wed May 29 23:00:55 1991
X--- support/ethertalk/snitp.c		Wed May 29 23:03:27 1991
X***************
X*** 1,6 ****
X! static char rcsid[] = "$Author: djh $ $Date: 1991/05/18 07:51:28 $";
X! static char rcsident[] = "$Header: /mac/src/cap60/support/ethertalk/RCS/snitp.c,v 2.2 1991/05/18 07:51:28 djh Exp djh $";
X! static char revision[] = "$Revision: 2.2 $";
X  
X  /*
X   * snitp.c - Simple "protocol" level interface to Streams based NIT
X--- 1,6 ----
X! static char rcsid[] = "$Author: djh $ $Date: 1991/05/29 13:03:15 $";
X! static char rcsident[] = "$Header: /mac/src/cap60/support/ethertalk/RCS/snitp.c,v 2.3 1991/05/29 13:03:15 djh Rel djh $";
X! static char revision[] = "$Revision: 2.3 $";
X  
X  /*
X   * snitp.c - Simple "protocol" level interface to Streams based NIT
X***************
X*** 23,28 ****
X--- 23,29 ----
X   * Edit History:
X   *
X   *  July 1988  CCKim Created
X+  *  April '91  djh   Add Phase 2 support
X   *
X  */
X  
X***************
X*** 65,70 ****
X--- 66,75 ----
X  
X  extern char interface[50];
X  
X+ #ifdef PHASE2
X+ u_char e_broad[EHRD] = {0x09, 0x00, 0x07, 0xff, 0xff, 0xff};
X+ #endif PHASE2
X+ 
X  /*
X   * setup for particular device devno
X   * all pi_open's will go this device
X***************
X*** 112,122 ****
X    eph = &ephlist[i];		/* find handle */
X  
X    strncpy(eph->ifr.ifr_name, interface, sizeof eph->ifr.ifr_name);
X-   eph->ifr.ifr_name[sizeof eph->ifr.ifr_name - 1] = ' ';
X  
X!   if ((s = init_nit(1024, protocol, socket, &eph->ifr)) < 0) {
X      return(-1);
X-   }
X  
X    eph->inuse = TRUE;
X    eph->fd = s;
X--- 117,125 ----
X    eph = &ephlist[i];		/* find handle */
X  
X    strncpy(eph->ifr.ifr_name, interface, sizeof eph->ifr.ifr_name);
X  
X!   if ((s = init_nit(1024, protocol, socket, &eph->ifr)) < 0)
X      return(-1);
X  
X    eph->inuse = TRUE;
X    eph->fd = s;
X***************
X*** 172,187 ****
X      return(-1);
X    }
X    
X!   si.ic_timout = INFTIM;
X!   
X!   if (setup_pf(s, protocol, socket) < 0)
X      return(-1);
X  #define NOBUF
X  #ifndef NOBUF
X    setup_buf(s, chunksize);
X! #endif  
X    /* bind */
X!   si.ic_cmd = NIOCBIND;		/* bind */
X    si.ic_timout = 10;
X    si.ic_len = sizeof(*ifr);
X    si.ic_dp = (caddr_t)ifr;
X--- 175,190 ----
X      return(-1);
X    }
X    
X!   if (setup_pf(s, protocol, socket) < 0)
X      return(-1);
X+ 
X  #define NOBUF
X  #ifndef NOBUF
X    setup_buf(s, chunksize);
X! #endif  NOBUF
X! 
X    /* bind */
X!   si.ic_cmd = NIOCBIND;		/* bind to underlying interface */
X    si.ic_timout = 10;
X    si.ic_len = sizeof(*ifr);
X    si.ic_dp = (caddr_t)ifr;
X***************
X*** 190,203 ****
X      return(-1);
X    }
X    
X    /* flush read queue */
X    ioctl(s, I_FLUSH, (char *)FLUSHR);
X    return(s);
X  }
X  
X! #ifndef NOBUF
X  /*
X!  * setup buffering (not wanted)
X   *
X  */
X  setup_buf(s, chunksize)
X--- 193,258 ----
X      return(-1);
X    }
X    
X+ #ifdef PHASE2
X+   /* enable our multicast broadcast address */
X+   if (pi_addmulti(s, e_broad, ifr) < 0) {
X+     perror("/dev/nit");
X+     return(-1);
X+   }
X+ #endif PHASE2
X+ 
X    /* flush read queue */
X    ioctl(s, I_FLUSH, (char *)FLUSHR);
X    return(s);
X  }
X  
X! #ifdef PHASE2
X  /*
X!  * add a multicast address to the interface
X!  */
X! int
X! pi_addmulti(s, multi, ifr)
X! int s;
X! char *multi;
X! struct ifreq *ifr;
X! {
X!   struct strioctl si;
X! 
X!   if (s < 0) {
X!     /* get a new clone */
X!     if ((s = open("/dev/nit", O_RDWR)) < 0) {
X!       perror("open: /dev/nit");
X!       return(-1);
X!     }
X!     /* set up messages */
X!     if (ioctl(s, I_SRDOPT, (char *)RMSGD) < 0) { /* want messages */
X!       perror("ioctl: discretem");
X!       return(-1);
X!     }
X!     /* bind */
X!     si.ic_cmd = NIOCBIND;		/* bind to underlying interface */
X!     si.ic_timout = 10;
X!     si.ic_len = sizeof(*ifr);
X!     si.ic_dp = (caddr_t)ifr;
X!     if (ioctl(s, I_STR, (caddr_t)&si) < 0) {
X!       perror("/dev/nit");
X!       return(-1);
X!     }
X!     /* flush read queue */
X!     ioctl(s, I_FLUSH, (char *)FLUSHR);
X!   }
X!   ifr->ifr_addr.sa_family = AF_UNSPEC;
X!   bcopy(multi, ifr->ifr_addr.sa_data, EHRD);
X!   if (ioctl(s, SIOCADDMULTI, (caddr_t)ifr) < 0) {
X!     perror("/dev/nit");
X!     return(-1);
X!   }
X!   return(s);
X! }
X! #endif PHASE2
X! 
X! /*
X!  * setup buffering
X   *
X  */
X  setup_buf(s, chunksize)
X***************
X*** 210,220 ****
X    /* Push and configure the buffering module. */
X    if (ioctl(s, I_PUSH, "nbuf") < 0) {
X      perror("ioctl: nbuf");
X    }
X!   timeout.tv_sec = 0;
X!   timeout.tv_usec = 200;
X    si.ic_cmd = NIOCSTIME;
X-   si.ic_timout = 10;
X    si.ic_len = sizeof timeout;
X    si.ic_dp = (char *)&timeout;
X    if (ioctl(s, I_STR, (char *)&si) < 0) {
X--- 265,277 ----
X    /* Push and configure the buffering module. */
X    if (ioctl(s, I_PUSH, "nbuf") < 0) {
X      perror("ioctl: nbuf");
X+     return(-1);
X    }
X!   si.ic_timout = INFTIM;
X! 
X!   timeout.tv_sec = 1;
X!   timeout.tv_usec = 0;
X    si.ic_cmd = NIOCSTIME;
X    si.ic_len = sizeof timeout;
X    si.ic_dp = (char *)&timeout;
X    if (ioctl(s, I_STR, (char *)&si) < 0) {
X***************
X*** 223,229 ****
X    }
X    
X    si.ic_cmd = NIOCSCHUNK;
X-   
X    si.ic_len = sizeof chunksize;
X    si.ic_dp = (char *)&chunksize;
X    if (ioctl(s, I_STR, (char *)&si)) {
X--- 280,285 ----
X***************
X*** 230,237 ****
X      perror("ioctl: chunk size");
X      return(-1);
X    }
X  }
X- #endif
X  
X  /*
X   * establish protocol filter
X--- 286,293 ----
X      perror("ioctl: chunk size");
X      return(-1);
X    }
X+   return(0);
X  }
X  
X  /*
X   * establish protocol filter
X***************
X*** 250,260 ****
X--- 306,330 ----
X    struct strioctl si;
X  #define s_offset(structp, element) (&(((structp)0)->element))
X    offset = ((int)s_offset(struct ether_header *, ether_type))/sizeof(u_short);
X+ #ifdef PHASE2
X+   offset += 4;	/* shorts: 2 bytes length + 6 bytes of 802.2 and SNAP */
X+ #endif PHASE2
X    *fwp++ = ENF_PUSHWORD + offset;
X    *fwp++ = ENF_PUSHLIT | (sock >= 0 ? ENF_CAND : ENF_EQ);
X    *fwp++ = htons(prot);
X    pf.Pf_FilterLen = 3;
X    if (sock >= 0) {
X+ #ifdef PHASE2
X+     *fwp++ = ENF_PUSHWORD + offset + 6;
X+     *fwp++ = ENF_PUSHLIT | ENF_AND;
X+     *fwp++ = htons(0xff00);   /* now have dest socket */
X+     *fwp++ = ENF_PUSHLIT | ENF_COR;
X+     *fwp++ = htons((sock & 0xff) << 8);
X+ /* if not wanted, fail it */
X+     *fwp++ = ENF_PUSHLIT ;
X+     *fwp++ = 0;
X+     pf.Pf_FilterLen += 7;
X+ #else  PHASE2
X  /* short form */
X      *fwp++ = ENF_PUSHWORD + offset + 2;
X      *fwp++ = ENF_PUSHLIT | ENF_AND;
X***************
X*** 279,285 ****
X      *fwp++ = ENF_PUSHLIT ;
X      *fwp++ = 0;
X      pf.Pf_FilterLen += 20;
X! 
X    }    
X  
X    si.ic_cmd = NIOCSETF;
X--- 349,355 ----
X      *fwp++ = ENF_PUSHLIT ;
X      *fwp++ = 0;
X      pf.Pf_FilterLen += 20;
X! #endif PHASE2
X    }    
X  
X    si.ic_cmd = NIOCSETF;
X***************
X*** 374,389 ****
X  caddr_t buf;
X  int bufsiz;
X  {
X!   struct iovec iov[2];
X    struct ethernet_addresses ea;
X    int cc;
X  
X    iov[0].iov_base = (caddr_t)&ea;
X    iov[0].iov_len = sizeof(ea);
X    iov[1].iov_base = (caddr_t)buf;
X    iov[1].iov_len = bufsiz;
X    cc = pi_readv(edx, iov, 2);
X    return(cc - sizeof(ea));
X  }
X  
X  pi_reada(fd, buf, bufsiz, eaddr)
X--- 444,473 ----
X  caddr_t buf;
X  int bufsiz;
X  {
X!   struct iovec iov[3];
X    struct ethernet_addresses ea;
X+ #ifdef PHASE2
X+   char header[8];
X+ #endif PHASE2
X    int cc;
X  
X+ #ifdef PHASE2
X    iov[0].iov_base = (caddr_t)&ea;
X    iov[0].iov_len = sizeof(ea);
X+   iov[1].iov_base = (caddr_t)header; /* consume 802.2 hdr & SNAP */
X+   iov[1].iov_len = sizeof(header);
X+   iov[2].iov_base = (caddr_t)buf;
X+   iov[2].iov_len = bufsiz;
X+   cc = pi_readv(edx, iov, 3);
X+   return(cc - sizeof(ea) - sizeof(header));
X+ #else  PHASE2
X+   iov[0].iov_base = (caddr_t)&ea;
X+   iov[0].iov_len = sizeof(ea);
X    iov[1].iov_base = (caddr_t)buf;
X    iov[1].iov_len = bufsiz;
X    cc = pi_readv(edx, iov, 2);
X    return(cc - sizeof(ea));
X+ #endif PHASE2
X  }
X  
X  pi_reada(fd, buf, bufsiz, eaddr)
X***************
X*** 392,411 ****
X  int bufsiz;
X  char *eaddr;
X  {
X!   struct iovec iov[2];
X    int cc;
X  
X    iov[0].iov_base = (caddr_t)eaddr;
X    iov[0].iov_len = 14;
X    iov[1].iov_base = (caddr_t)buf;
X    iov[1].iov_len = bufsiz;
X  
X    if ((cc = readv(fd, iov, 2)) < 0) {
X      perror("abread");
X      return(cc);
X    }
X! 
X    return(cc - 14);
X  }
X  
X  export int
X--- 476,518 ----
X  int bufsiz;
X  char *eaddr;
X  {
X!   struct iovec iov[3];
X! #ifdef PHASE2
X!   char header[5];	/* must be 5! */
X! #endif PHASE2
X    int cc;
X  
X+ #ifdef PHASE2
X    iov[0].iov_base = (caddr_t)eaddr;
X    iov[0].iov_len = 14;
X+   iov[1].iov_base = (caddr_t)header;	/* consume 802.2 hdr & SNAP but */
X+   iov[1].iov_len = sizeof(header);	/* make room for our fake LAP header */
X+   iov[2].iov_base = (caddr_t)buf;
X+   iov[2].iov_len = bufsiz;
X+ #else  PHASE2
X+   iov[0].iov_base = (caddr_t)eaddr;
X+   iov[0].iov_len = 14;
X    iov[1].iov_base = (caddr_t)buf;
X    iov[1].iov_len = bufsiz;
X+ #endif PHASE2
X  
X+ #ifdef PHASE2
X+   if ((cc = readv(fd, iov, 3)) < 0) {
X+ #else  PHASE2
X    if ((cc = readv(fd, iov, 2)) < 0) {
X+ #endif PHASE2
X      perror("abread");
X      return(cc);
X    }
X! #ifdef PHASE2
X!   /* make a fake LAP header to fool the higher levels	*/
X!   buf[0] = buf[11];		/* destination node ID	*/
X!   buf[1] = buf[12];		/* source node ID	*/
X!   buf[2] = 0x02;		/* always long DDP	*/
X!   return(cc - 14 - sizeof(header));
X! #else  PHASE2
X    return(cc - 14);
X+ #endif PHASE2
X  }
X  
X  export int
X***************
X*** 419,424 ****
X--- 526,534 ----
X    struct ether_header *eh;
X    struct strbuf pbuf, dbuf;
X    struct sockaddr sa;
X+ #ifdef PHASE2
X+   char *q;
X+ #endif PHASE2
X  
X    if (edx < 1 || edx > MAXOPENPROT || eaddr == NULL)
X      return(-1);
X***************
X*** 427,436 ****
X    if (!eph->inuse)
X      return(-1);
X  
X!   sa.sa_family = AF_UNSPEC;	/* by def. */
X!   eh = (struct ether_header *)sa.sa_data;		/* make pointer */
X    bcopy(eaddr, &eh->ether_dhost, sizeof(eh->ether_dhost));
X!   eh->ether_type = htons(eph->protocol);
X    pbuf.len = sizeof(sa);
X    pbuf.buf = (char *)&sa;
X    dbuf.len = buflen;
X--- 537,564 ----
X    if (!eph->inuse)
X      return(-1);
X  
X!   sa.sa_family = AF_UNSPEC;			/* by definition */
X!   eh = (struct ether_header *)sa.sa_data;	/* make pointer */
X    bcopy(eaddr, &eh->ether_dhost, sizeof(eh->ether_dhost));
X! #ifdef PHASE2
X!   eh->ether_type = htons(buflen);
X!   /*
X!    * Fill in the remainder of the 802.2 and SNAP header bytes.
X!    * Clients have to leave 8 bytes free at the start of buf as
X!    * NIT won't let us send any more than 14 bytes of header :-(
X!    */
X!   q = (char *) buf;
X!   *q++ = 0xaa;		/* destination SAP	*/
X!   *q++ = 0xaa;		/* source SAP		*/
X!   *q++ = 0x03;		/* control byte		*/
X!   *q++ = (eph->protocol == 0x809b) ? 0x08 : 0x00;
X!   *q++ = 0x00;		/* always zero		*/
X!   *q++ = (eph->protocol == 0x809b) ? 0x07 : 0x00;
X!   *q++ = (htons(eph->protocol) >> 8) & 0xff;
X!   *q++ = (htons(eph->protocol) & 0xff);
X! #else  PHASE2
X!   eh->ether_type = htons(eph->protocol);
X! #endif PHASE2
X    pbuf.len = sizeof(sa);
X    pbuf.buf = (char *)&sa;
X    dbuf.len = buflen;
X***************
X*** 460,466 ****
X--- 588,598 ----
X    if (!ephlist[edx-1].inuse)
X      return(-1);
X  
X+ #ifdef PHASE2	/* leave room for rest of ELAP hdr */
X+   for (len = 8, p = ebuf+8, i = 0 ; i < iovlen ; i++)
X+ #else  PHASE2
X    for (len = 0, p = ebuf, i = 0 ; i < iovlen ; i++)
X+ #endif PHASE2
X      if (iov[i].iov_base && iov[i].iov_len >= 0) {
X        bcopy(iov[i].iov_base, p, iov[i].iov_len);
X        p += iov[i].iov_len;	/* advance */
END_OF_FILE
if test 77341 -ne `wc -c <'cap60.patch025'`; then
    echo shar: \"'cap60.patch025'\" unpacked with wrong size!
fi
# end of 'cap60.patch025'
fi
echo shar: End of shell archive.
exit 0