diff -ur --new-file old/atm/CHANGES new/atm/CHANGES
--- old/atm/CHANGES	Fri Oct 18 18:38:10 1996
+++ new/atm/CHANGES	Wed Nov 13 23:23:02 1996
@@ -1,3 +1,60 @@
+Version 0.21 to 0.22 (13-NOV-1996)
+====================
+
+Bug fixes
+---------
+
+ - (dummy) depend target was missing in atm/man (reported by Bernd Wolf)
+ - net/atm/arequipa.c:make_aq_vcc didn't set ATM_VF_AQINUSE, thereby allowing
+   race conditions to slip through
+ - fixed a few potential race conditions when activating Arequipa
+ - text2qos didn't complain if unit was omitted after multiplier, allowing
+   misleading settings like pcr=50M (that's 19.2 Gbps)
+ - SSCOP: took wrong branch if POLL_AFTER_RETRANSMISSION was enabled (fix by
+   Jonathan Larmour)
+ - SSCOP: rel_ind for ENDAK and BGREJ PDU in sscop_inconn was sent with "user"
+   = 1 (must be 0 for "Source := SSCOP")
+ - initialize_vr_mr now initializes vr_mr to a constant value (instead of
+   garbage plus constant value)
+ - atm_recvmsg now ignores msg->msg_name, as it should by POSIX 1003.1g (fix by
+   Mike Wooten)
+ - atm_sendmsg now fails with EISCONN instead of with EINVAL if msg->msg_name
+   is set, as it should by POSIX 1003.1g (reported by Mike Wooten)
+ - atm_recvmsg and atm_sendmsg now return ENOTCONN if not connected and
+   EOPNOTSUP if flags are passed, as they should by POSIX 1003.1g
+ - the QOS zeppelin uses for its connections can now be set with the option -q
+ - atmarpd didn't include the QOS in PVC entries, so atmarp -a complained about
+   them
+
+New features
+------------
+
+ - kernel changes to support tcpdump with LANE (by Marko Kiiskila)
+ - patch for tcpdump 3.0.4 (installed as tcpdump_atm) to support Classical IP
+   and LANE (by Marko Kiiskila)
+ - patch for BIND 4.9.5 to support ANS (ATM Name Service) functionality (by
+   Marko Kiiskila)
+ - added hierarchy extra/ for packages for which only patches are contained in
+   the ATM on Linux distribution
+ - enhanced text2atm to use ANS if local lookups fail (atm2text will be updated
+   later)
+ - wrote script extra/hosts2ans.pl to convert hosts.atm file to ANS zone files
+
+Other changes
+-------------
+
+ - changed ATM_VF_AQINUSE to ATM_VF_AQDANG and changed aq_list membership to
+   be for dangling VCs only
+ - added the new command-line options to ttcp_atm's online help (finally !)
+ - atm_sendmsg now returns error codes from the driver's send function
+   (suggested by Jonathan Larmour)
+ - text2qos now performs a syntax check if NULL is passed in the qos argument
+ - various minor LANE cleanup (Marko Kiiskila)
+ - upgraded to the latest version of t2a.pl
+ - {A2T,T2A}_REMOTE is obsolete; instead, {A2T,T2A}_LOCAL should be used if
+   ANS lookups are _not_ desired
+
+
 Version 0.20 to 0.21 (18-OCT-1996)
 ====================
 
diff -ur --new-file old/atm/CREDITS new/atm/CREDITS
--- old/atm/CREDITS	Thu Sep 12 16:19:06 1996
+++ new/atm/CREDITS	Tue Nov 12 17:39:42 1996
@@ -1,4 +1,4 @@
-Although most of the files carry just one name, many other people have
+Although many of the files carry just one name, many other people have
 contributed to the project in various ways, e.g. by scrutinizing parts
 of the implementation or by designing and implementing prototypes of
 major system components. Their ideas significantly influenced the
diff -ur --new-file old/atm/Makefile new/atm/Makefile
--- old/atm/Makefile	Wed Oct 16 22:13:02 1996
+++ new/atm/Makefile	Wed Nov 13 17:05:49 1996
@@ -1,7 +1,7 @@
 # "qgen" and "saal" _must_ appear before "sigd"
 # "lib" must appear before anything else
 
-DIRS=lib maint ip test debug qgen saal sigd arpd ilmid led lane aqd man #ans
+DIRS=lib maint ip test debug qgen saal sigd arpd ilmid led lane aqd man #extra
 
 all:
 		for n in $(DIRS); do $(MAKE) -C $$n || exit; done
diff -ur --new-file old/atm/README new/atm/README
--- old/atm/README	Tue Oct 15 22:57:48 1996
+++ new/atm/README	Tue Nov 12 17:39:16 1996
@@ -1,4 +1,4 @@
-ATM on Linux, release 0.21 (pre-alpha) by Werner Almesberger, EPFL LRC
+ATM on Linux, release 0.22 (pre-alpha) by Werner Almesberger, EPFL LRC
 ====================================== werner.almesberger@lrc.di.epfl.ch
 
 This is experimental software. There are known major bugs and certainly
@@ -27,6 +27,7 @@
   ATMARP as defined in RFC1577 (client and server)
   LAN Emulation (client and server side)
   Arequipa (Application REQUested IP over ATM)
+  ANS (ATM Name Service)
 
 The API is based on the Linux ATM API proposed on the linux-atm mailing
 list.
diff -ur --new-file old/atm/Rules.make new/atm/Rules.make
--- old/atm/Rules.make	Wed Oct 16 22:17:29 1996
+++ new/atm/Rules.make	Tue Nov  5 21:19:37 1996
@@ -81,7 +81,7 @@
 		  $(PROCLIST)
 
 uninstall:
-		@process() { if [ ! -z "$$3" ]; then dir=$$2; shift; \
+		@process() { if [ ! -z "$$3" ]; then dir=$$2; shift 2; \
 		  echo "cd $$dir; rm -f $$*"; \
 		  cd $$dir; rm -f $$*; fi }; \
 		  $(PROCLIST)
diff -ur --new-file old/atm/USAGE new/atm/USAGE
--- old/atm/USAGE	Fri Oct 18 15:05:33 1996
+++ new/atm/USAGE	Wed Nov 13 23:19:59 1996
@@ -1,4 +1,4 @@
-Usage instructions  -  ATM on Linux, release 0.21 (pre-alpha)
+Usage instructions  -  ATM on Linux, release 0.22 (pre-alpha)
 -------------------------------------------------------------
 
 For updates of ATM on Linux, please check the Web page at  
@@ -17,7 +17,7 @@
 In order to install this package, you need 
 
   - the package itself  
-    ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.21.tar.gz  
+    ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.22.tar.gz  
   - the Linux kernel, version 2.0.14, e.g. from  
     ftp://ftp.cs.helsinki.fi/pub/Software/Linux/Kernel/v2.0/linux-2.0.14.tar.gz  
   - Perl, version 4 or 5 
@@ -33,7 +33,7 @@
 all the files listed above there. Then extract the ATM on Linux 
 distribution:
 
-tar xfz atm-0.21.tar.gz
+tar xfz atm-0.22.tar.gz
 
 and the kernel source:
 
@@ -65,6 +65,7 @@
   atm/lib/  Libraries for applications and demons 
   atm/doc/  Documentation in LaTeX and conversion tools 
   atm/man/  Miscellaneous man pages 
+  atm/extra/  Extra packages (tcpdump and ans) 
 
 
 Kernel configuration
@@ -172,6 +173,33 @@
 /usr/local/sbin, respectively. Libraries and header files are installed in 
 /usr/lib and /usr/include, respectively. Man pages are installed in 
 /usr/local/man.
+
+
+Extra packages
+--------------
+
+Some programs are based on large packages that are already distributed 
+outside of the ATM context. For such packages, only patches are contained 
+in the ATM on Linux distribution. The complete packages can be obtained 
+either from the original source (described in atm/extra/extra.html) or from  
+ftp://lrcftp.epfl.ch/pub/linux/atm/extra/ .
+
+The packages are automatically downloaded, patched, and built by running  
+make <package_name>  in the atm/extra/ directory (requires that the Lynx 
+Web browser is installed).
+
+Currently, the following extra packages are available: 
+
+  tcpdump  dumps network traffic (enhanced for ATM) 
+  ans  ATM name server (based on named 4.9.5) 
+
+Building tcpdump requires that csh is installed. Note that text2atm 
+automatically uses ANS if available, so ans only needs to be installed on 
+systems providing name server functionality or if ATM-aware maintenance 
+tools (nslookup, etc.) are needed.
+
+A script hosts2ans.pl to convert a /etc/hosts.atm file to ANS zone files is 
+provided in atm/extra/. Its use is described at the beginning of the file.
 
 
 Device setup
diff -ur --new-file old/atm/VERSION new/atm/VERSION
--- old/atm/VERSION	Tue Oct 15 22:57:35 1996
+++ new/atm/VERSION	Wed Nov 13 23:24:57 1996
@@ -1 +1 @@
-0.21
+0.22
diff -ur --new-file old/atm/arpd/arp.c new/atm/arpd/arp.c
--- old/atm/arpd/arp.c	Wed Oct 16 21:34:27 1996
+++ new/atm/arpd/arp.c	Wed Nov 13 16:59:22 1996
@@ -705,6 +705,7 @@
     entry = alloc_entry(0);
     entry->state = as_valid;
     entry->ip = ip;
+    entry->qos = *qos;
     entry->flags = flags;
     entry->itf = itf;
     vcc = alloc_t(VCC);
diff -ur --new-file old/atm/atm.patch new/atm/atm.patch
--- old/atm/atm.patch	Fri Oct 18 18:38:33 1996
+++ new/atm/atm.patch	Wed Nov 13 23:42:36 1996
@@ -20,7 +20,7 @@
  	ls *.o > .allmods; \
  	echo $$MODULES | tr ' ' '\n' | sort | comm -23 .allmods - > .misc; \
 --- ref/Documentation/Configure.help	Wed Aug  7 08:45:41 1996
-+++ work/Documentation/Configure.help	Fri Oct  4 13:14:30 1996
++++ work/Documentation/Configure.help	Fri Oct  4 14:14:30 1996
 @@ -670,6 +670,14 @@
    say "386" or "486" here even if running on a Pentium or PPro
    machine. If you don't know what to do, say "386".
@@ -149,7 +149,7 @@
  SCSI support?
  CONFIG_SCSI
 --- ref/kernel/ksyms.c	Thu Jul 18 13:28:48 1996
-+++ work/kernel/ksyms.c	Fri Oct  4 13:14:32 1996
++++ work/kernel/ksyms.c	Fri Oct  4 14:14:32 1996
 @@ -63,6 +63,12 @@
  #ifdef __SMP__
  #include <linux/smp.h>
@@ -207,7 +207,7 @@
  	X(get_write_access),
  	X(put_write_access),
 --- ref/arch/i386/config.in	Mon May 13 06:17:23 1996
-+++ work/arch/i386/config.in	Fri Oct  4 13:14:31 1996
++++ work/arch/i386/config.in	Fri Oct  4 14:14:31 1996
 @@ -43,6 +43,8 @@
  	 486		CONFIG_M486	\
  	 Pentium	CONFIG_M586	\
@@ -266,7 +266,7 @@
  endif
  
  ifeq ($(CONFIG_AP1000),y)
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/drivers/atm/Config.in	Thu Sep 26 18:58:10 1996
 @@ -0,0 +1,22 @@
 +#
@@ -311,7 +311,7 @@
 +  bool '  LANE support' CONFIG_ATM_LANE y
 +fi
  endmenu
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/drivers/atm/Makefile	Thu Aug 29 13:50:20 1996
 @@ -0,0 +1,47 @@
 +# File: drivers/atm/Makefile
@@ -361,7 +361,7 @@
 +EXTRA_CFLAGS=-g
 +
 +include $(TOPDIR)/Rules.make
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/drivers/atm/atmdev_init.c	Wed Aug 21 10:55:36 1996
 @@ -0,0 +1,47 @@
 +/* drivers/atm/atmdev_init.c - ATM device driver initialization */
@@ -411,8 +411,8 @@
 +#endif
 +	return devs;
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/drivers/atm/atmtcp.c	Fri Oct  4 13:02:24 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/drivers/atm/atmtcp.c	Fri Oct  4 14:02:24 1996
 @@ -0,0 +1,317 @@
 +/* drivers/atm/atmtcp.c - ATM over TCP "device" driver */
 + 
@@ -731,9 +731,9 @@
 +}
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/drivers/atm/eni.c	Sun Oct 13 18:45:49 1996
-@@ -0,0 +1,1952 @@
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/drivers/atm/eni.c	Fri Nov  8 16:38:53 1996
+@@ -0,0 +1,1960 @@
 +/* drivers/atm/eni.c - Efficient Networks ENI155P device driver */
 + 
 +/* Written 1995,1996 by Werner Almesberger, EPFL LRC */
@@ -1159,6 +1159,10 @@
 +	j = j >> 1;
 +	dma_wr = eni_dev->reg[MID_DMA_WR_RX];
 +	dma_rd = eni_dev->reg[MID_DMA_RD_RX];
++	/*
++	 * Can I move the dma_wr pointer by 2j+1 positions without overwriting
++	 * data that hasn't been read (position of dma_rd) yet ?
++	 */
 +	if (!NEPMOK(dma_wr,j+j+1,dma_rd,NR_DMA_RX)) { /* @@@ +1 is ugly */
 +		printk(KERN_WARNING DEV_LABEL "(itf %d): RX DMA full\n",
 +		    vcc->dev->number);
@@ -1692,9 +1696,13 @@
 +		size = ((size-(size % ATM_CELL_PAYLOAD)) >> 2)+TX_DESCR_SIZE;
 +						/* add segmentation header */
 +	}
++	/*
++	 * Can I move tx_pos by size bytes without getting closer than TX_GAP
++	 * to the read pointer ? TX_GAP means to leave some space for what
++	 * the manual calls "too close".
++	 */
 +	if (!NEPMOK(tx->tx_pos,size+TX_GAP,
 +	    eni_dev->reg[MID_TX_RDPTR(tx->index)],tx->words)) {
-+	    /* leave some space for "too close" */
 +		DPRINTK(DEV_LABEL "(itf %d): TX full (size %ld)\n",
 +		    vcc->dev->number,size);
 +		return enq_next;
@@ -2686,8 +2694,8 @@
 +}
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/drivers/atm/eni.h	Thu Oct 17 15:49:41 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/drivers/atm/eni.h	Wed Nov 13 11:38:13 1996
 @@ -0,0 +1,113 @@
 +/* drivers/atm/eni.h - Efficient Networks ENI155P device driver declarations */
 + 
@@ -2802,7 +2810,7 @@
 +#endif /* __KERNEL__ */
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/drivers/atm/midway.h	Wed Aug 21 10:55:38 1996
 @@ -0,0 +1,265 @@
 +/* drivers/atm/midway.h - Efficient Networks Midway (SAR) description */
@@ -3070,7 +3078,7 @@
 +#define MID_DT_HWORD	0x2
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/drivers/atm/suni.c	Thu Sep 26 22:48:49 1996
 @@ -0,0 +1,298 @@
 +/* drivers/atm/suni.c - PMC SUNI (PHY) driver */
@@ -3371,8 +3379,8 @@
 +}
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/drivers/atm/suni.h	Thu Oct 17 15:49:41 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/drivers/atm/suni.h	Wed Nov 13 11:38:13 1996
 @@ -0,0 +1,219 @@
 +/* drivers/atm/suni.h - PMC SUNI (PHY) declarations */
 + 
@@ -3593,7 +3601,7 @@
 +#endif
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/drivers/atm/tonga.h	Wed Aug 21 10:55:39 1996
 @@ -0,0 +1,20 @@
 +/* drivers/atm/tonga.h - Efficient Networks Tonga (PCI bridge) declarations */
@@ -3616,7 +3624,7 @@
 +#define SEPROM_ESI_BASE	64	/* start of ESI in serial EEPROM */
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/drivers/atm/uPD98401.h	Wed Aug 21 10:55:39 1996
 @@ -0,0 +1,292 @@
 +/* drivers/atm/uPD98401.h - NEC uPD98401 (SAR) declarations */
@@ -3911,7 +3919,7 @@
 +#define uPD98401_RXLT_ENBL	0x8000	   /* Enable */
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/drivers/atm/uPD98402.h	Wed Aug 21 10:55:39 1996
 @@ -0,0 +1,106 @@
 +/* drivers/atm/uPD98402.h - NEC uPD98402 (PHY) declarations */
@@ -4020,7 +4028,7 @@
 +int uPD98402_init(struct atm_dev *dev);
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/drivers/atm/uPD98402.c	Thu Aug 29 15:19:33 1996
 @@ -0,0 +1,228 @@
 +/* drivers/atm/uPD98402.c - NEC uPD98402 (PHY) declarations */
@@ -4251,8 +4259,8 @@
 +}
 + 
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/drivers/atm/zatm.c	Sun Oct 13 18:47:54 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/drivers/atm/zatm.c	Sun Oct 13 19:47:54 1996
 @@ -0,0 +1,1844 @@
 +/* drivers/atm/zatm.c - ZeitNet ZN122x device driver */
 + 
@@ -6098,8 +6106,8 @@
 +}
 + 
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/drivers/atm/zatm.h	Thu Oct 17 15:50:09 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/drivers/atm/zatm.h	Wed Nov 13 11:38:42 1996
 @@ -0,0 +1,172 @@
 +/* drivers/atm/zatm.h - ZeitNet ZN122x device driver declarations */
 +
@@ -6273,7 +6281,7 @@
 +
 +#endif __KERNEL__
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/drivers/atm/zeprom.h	Wed Aug 21 10:55:41 1996
 @@ -0,0 +1,34 @@
 +/* drivers/atm/zeprom.h - ZeitNet ZN122x EEPROM (NM93C46) declarations */
@@ -6310,8 +6318,8 @@
 +/* No other commands are needed. */
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/drivers/atm/tneta1570.h	Thu Oct 17 15:50:31 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/drivers/atm/tneta1570.h	Wed Nov 13 11:39:04 1996
 @@ -0,0 +1,390 @@
 +/* drivers/atm/tneta1570.h - TI TNETA1570 (SAR) declarations */
 + 
@@ -6703,8 +6711,8 @@
 +
 +#endif __KERNEL__
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/drivers/atm/tneta1570.c	Wed Oct  9 11:26:38 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/drivers/atm/tneta1570.c	Wed Oct  9 12:26:38 1996
 @@ -0,0 +1,1625 @@
 +/* drivers/atm/tneta1570.c - ti tneta1570 atm driver 
 + * 
@@ -8331,7 +8339,7 @@
 +/* not yet */
 +}
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/drivers/atm/fore200.c	Wed Aug 21 10:55:43 1996
 @@ -0,0 +1,26 @@
 +/* drivers/atm/fore200.c - This is just a test, not a real driver */
@@ -8360,8 +8368,8 @@
 +	}
 +	return 0;
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/atm.h	Wed Oct  9 20:21:33 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/include/linux/atm.h	Thu Nov  7 16:06:56 1996
 @@ -0,0 +1,216 @@
 +/* atm.h - general ATM declarations */
 + 
@@ -8579,8 +8587,8 @@
 +#endif /* __KERNEL__ */
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/atmclip.h	Thu Oct 17 15:51:54 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/include/linux/atmclip.h	Wed Nov 13 11:48:45 1996
 @@ -0,0 +1,37 @@
 +/* atmclip.h - Classical IP over ATM */
 + 
@@ -8619,8 +8627,8 @@
 +#endif /* __KERNEL__ */
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/atmdev.h	Thu Oct 17 15:49:26 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/include/linux/atmdev.h	Wed Nov 13 11:52:05 1996
 @@ -0,0 +1,255 @@
 +/* atmdev.h - ATM device driver declarations */
 + 
@@ -8747,8 +8755,8 @@
 +#define ATM_VF_META	128	/* SVC socket isn't used for normal data
 +				   traffic and doesn't depend on signaling
 +				   to be available */
-+#define ATM_VF_AQREL	256	/* Arequipa socket is being released */
-+#define ATM_VF_AQINUSE	512	/* socket is available for Arequipa use */
++#define ATM_VF_AQREL	256	/* Arequipa VC is being released */
++#define ATM_VF_AQDANG	512	/* VC is in Arequipa's dangling list */
 +#define ATM_VF_SCRX	ATM_SC_RX /* 1024; allow single-copy in the RX dir. */
 +#define ATM_VF_SCTX	ATM_SC_TX /* 2048; allow single-copy in the TX dir. */
 +
@@ -8877,8 +8885,8 @@
 +#endif /* __KERNEL__ */
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/atmsap.h	Tue Oct  1 17:24:29 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/include/linux/atmsap.h	Wed Nov  6 18:36:55 1996
 @@ -0,0 +1,124 @@
 +/* atmsap.h - ATM Service Access Point addressing definitions */
 +
@@ -8901,14 +8909,14 @@
 +/* BEGIN_L2 */
 +#define ATM_L2_NONE	0	/* L2 not specified */
 +#define ATM_L2_ISO1745  0x01	/* Basic mode ISO 1745 */
-+#define ATM_L2_Q291	0x02	/* ITU-T Q.291 */
++#define ATM_L2_Q291	0x02	/* ITU-T Q.291 (Rec. I.441) */
 +#define ATM_L2_X25_LL	0x06	/* ITU-T X.25, link layer */
 +#define ATM_L2_X25_ML	0x07	/* ITU-T X.25, multilink */
-+#define ATM_L2_LAPB	0x08	/* Extended LAPB, half-duplex */
-+#define ATM_L2_HDLC_ARM	0x09	/* HDLC ARM (ISO 4335) */
-+#define ATM_L2_HDLC_NRM	0x0a	/* HDLC NRM (ISO 4335) */
-+#define ATM_L2_HDLC_ABM	0x0b	/* HDLC ABM (ISO 4335) */
-+#define ATM_L2_ISO8802	0x0c	/* LAN LLC (ISO 8802/2) */
++#define ATM_L2_LAPB	0x08	/* Extended LAPB, half-duplex (Rec. T.71) */
++#define ATM_L2_HDLC_ARM	0x09	/* HDLC ARM (ISO/IEC 4335) */
++#define ATM_L2_HDLC_NRM	0x0a	/* HDLC NRM (ISO/IEC 4335) */
++#define ATM_L2_HDLC_ABM	0x0b	/* HDLC ABM (ISO/IEC 4335) */
++#define ATM_L2_ISO8802	0x0c	/* LAN LLC (ISO/IEC 8802/2) */
 +#define ATM_L2_X75	0x0d	/* ITU-T X.75, SLP */
 +#define ATM_L2_Q922	0x0e	/* ITU-T Q.922 */
 +#define ATM_L2_USER	0x10	/* user-specified */
@@ -8924,8 +8932,8 @@
 +#define ATM_L3_NONE	0	/* L3 not specified */
 +#define ATM_L3_X25	0x06	/* ITU-T X.25, packet layer */
 +#define ATM_L3_ISO8208	0x07	/* ISO/IEC 8208 */
-+#define ATM_L3_X223	0x08	/* ITU-T X.223/ISO 8878 */
-+#define ATM_L3_ISO8473	0x09	/* ISO/IEC 8473 */
++#define ATM_L3_X223	0x08	/* ITU-T X.223 | ISO/IEC 8878 */
++#define ATM_L3_ISO8473	0x09	/* ITU-T X.223 | ISO/IEC 8473 */
 +#define ATM_L3_T70	0x0a	/* ITU-T T.70 minimum network layer */
 +#define ATM_L3_TR9577	0x0b	/* ISO/IEC TR 9577 */
 +#define ATM_L3_USER	0x10	/* user-specified */
@@ -9005,7 +9013,7 @@
 +
 +#endif
 --- ref/include/linux/skbuff.h	Tue Aug 20 17:09:42 1996
-+++ work/include/linux/skbuff.h	Tue Oct 15 13:28:32 1996
++++ work/include/linux/skbuff.h	Wed Nov 13 11:55:46 1996
 @@ -112,6 +112,21 @@
  	unsigned char 	*end;			/* End pointer					*/
  	void 		(*destructor)(struct sk_buff *);	/* Destruct function		*/
@@ -9028,7 +9036,7 @@
  };
  
  #ifdef CONFIG_SKB_LARGE
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/include/linux/sonet.h	Wed Aug 21 10:55:45 1996
 @@ -0,0 +1,52 @@
 +/* sonet.h - SONET/SHD physical layer control */
@@ -9083,8 +9091,8 @@
 +#define SONET_FRSENSE_SIZE 6		/* C1[3],H1[3] (0xff for unknown) */
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/atmsvc.h	Tue Oct 15 15:19:20 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/include/linux/atmsvc.h	Thu Nov  7 16:08:51 1996
 @@ -0,0 +1,51 @@
 +/* atmsvc.h - ATM signaling kernel-demon interface definitions */
 + 
@@ -9137,7 +9145,7 @@
 +  (tp).max_pcr : (tp).min_pcr ? (tp).min_pcr : ATM_MAX_PCR)
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/include/linux/atmioc.h	Wed Aug 21 10:55:45 1996
 @@ -0,0 +1,32 @@
 +/* atmioc.h - ranges for ATM-related ioctl numbers */
@@ -9195,7 +9203,7 @@
  endif
  
  ifeq ($(CONFIG_INET),y)
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/net/atm/Makefile	Wed Aug 21 10:55:46 1996
 @@ -0,0 +1,54 @@
 +#
@@ -9252,7 +9260,7 @@
 +
 +
 +include $(TOPDIR)/Rules.make
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/net/atm/clip.c	Mon Sep  9 14:04:35 1996
 @@ -0,0 +1,116 @@
 +/* net/atm/clip.c - Classical IP over ATM */
@@ -9371,9 +9379,9 @@
 +	DPRINTK("registered %s,0x%lx\n",dev->name,(unsigned long) vcc);
 +	return CLIP(dev)->number;
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/common.c	Wed Oct 16 16:47:38 1996
-@@ -0,0 +1,932 @@
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/common.c	Fri Nov  8 17:40:50 1996
+@@ -0,0 +1,933 @@
 +/* net/atm/common.c - ATM sockets (common part for PVC and SVC) */
 +
 +/* Written 1995,1996 by Werner Almesberger, EPFL LRC */
@@ -9721,8 +9729,8 @@
 +	void *buff;
 +	int size;
 +
-+	if (sock->state != SS_CONNECTED || flags || m->msg_name)
-+		return -EINVAL;
++	if (sock->state != SS_CONNECTED) return -ENOTCONN;
++	if (flags) return -EOPNOTSUPP;
 +	if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
 +	buff = m->msg_iov->iov_base;
 +	size = m->msg_iov->iov_len;
@@ -9790,13 +9798,14 @@
 +{
 +	struct atm_vcc *vcc;
 +	struct sk_buff *skb;
-+	int eff;
++	int eff,error;
 +
 +	const void *buff;
 +	int size;
 +
-+	if (sock->state != SS_CONNECTED || flags || m->msg_name)
-+		return -EINVAL;
++	if (sock->state != SS_CONNECTED) return -ENOTCONN;
++	if (flags) return -EOPNOTSUPP;
++	if (m->msg_name) return -EISCONN;
 +	if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
 +	buff = m->msg_iov->iov_base;
 +	size = m->msg_iov->iov_len;
@@ -9835,9 +9844,9 @@
 +			atomic_add(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse);
 +			skb->atm.iovcnt = res;
 +			skb_device_lock(skb);
-+			vcc->dev->ops->send(vcc,skb);
++			error = vcc->dev->ops->send(vcc,skb);
 +			/* FIXME: security: may send up to 3 "garbage" bytes */
-+			return size;
++			return error ? error : size;
 +		}
 +	}
 +#endif
@@ -9870,11 +9879,11 @@
 +                printk("send %d:%s\n",vcc->vci,buf);
 +        }
 +#endif
-+	vcc->dev->ops->send(vcc,skb);
++	error = vcc->dev->ops->send(vcc,skb);
 +#if 0 /* experimental */
 +	while (vcc->dev->sending) sleep_on(&vcc->sleep);
 +#endif
-+	return size;
++	return error ? error : size;
 +}
 +
 +
@@ -10306,7 +10315,7 @@
 +	if (!vcc->dev || !vcc->dev->ops->getsockopt) return -EINVAL;
 +	return vcc->dev->ops->getsockopt(vcc,level,optname,optval,optlen);
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/net/atm/common.h	Wed Aug 21 10:55:47 1996
 @@ -0,0 +1,32 @@
 +/* net/atm/common.h - ATM sockets (common part for PVC and SVC) */
@@ -10341,7 +10350,7 @@
 +void svc_callback(struct atm_vcc *vcc);
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/net/atm/dev.c	Wed Aug 21 10:55:47 1996
 @@ -0,0 +1,38 @@
 +/* net/atm/dev.c - ATM device registeration */
@@ -10382,8 +10391,8 @@
 +{
 +	free_atm_dev(dev);
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/pvc.c	Fri Oct  4 13:25:32 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/pvc.c	Fri Oct  4 14:25:32 1996
 @@ -0,0 +1,175 @@
 +/* net/atm/pvc.c - ATM PVC sockets */
 +
@@ -10560,7 +10569,7 @@
 +	(void) atm_init_arequipa();
 +#endif
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/net/atm/static.c	Wed Aug 21 10:55:47 1996
 @@ -0,0 +1,114 @@
 +/* net/atm/static.c - Staticly allocated resources */
@@ -10677,8 +10686,8 @@
 +	for (i = 0; i < MAX_ATM_VCC; i++)
 +		if (atm_vcc[i].family) fn(atm_vcc+i);
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/static.h	Thu Oct 17 15:51:54 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/static.h	Wed Nov 13 11:48:45 1996
 @@ -0,0 +1,29 @@
 +/* net/atm/static.h - Staticly allocated resources */
 +
@@ -10709,8 +10718,8 @@
 +void for_all_vccs(void (*fn)(struct atm_vcc *vcc));
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/svc.c	Thu Oct 17 14:00:17 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/svc.c	Thu Oct 17 15:00:17 1996
 @@ -0,0 +1,604 @@
 +/* net/atm/svc.c - ATM SVC sockets */
 +
@@ -11316,9 +11325,9 @@
 +		return;
 +	}
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/signaling.c	Thu Oct 17 13:55:23 1996
-@@ -0,0 +1,219 @@
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/signaling.c	Mon Oct 28 19:03:19 1996
+@@ -0,0 +1,215 @@
 +/* net/atm/signaling.c - ATM signaling */
 +
 +/* Written 1995,1996 by Werner Almesberger, EPFL LRC */
@@ -11454,10 +11463,6 @@
 +	else msg->pvc = *pvc;
 +	while (!sigd) {
 +#ifdef WAIT_FOR_DEMON
-+/*
-+ * Don't ever enable this as Arequipa depends on being able to send a
-+ * message to the signaling demon from an interrupt.
-+ */
 +		if (silence < jiffies) {
 +			printk(KERN_INFO "atmsvc: waiting for signaling demon "
 +			    "...\n");
@@ -11538,8 +11543,8 @@
 +	wake_up(&sigd_sleep);
 +	return 0;
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/signaling.h	Thu Oct 17 15:51:54 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/signaling.h	Wed Nov 13 11:48:45 1996
 @@ -0,0 +1,25 @@
 +/* net/atm/signaling.h - ATM signaling */
 + 
@@ -11566,8 +11571,8 @@
 +int sigd_attach(struct atm_vcc *vcc);
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/atmarp.c	Sun Oct 13 18:41:26 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/atmarp.c	Sun Oct 13 19:41:26 1996
 @@ -0,0 +1,605 @@
 +/* atmarp.c - RFC1577 ATM ARP */
 +
@@ -12174,8 +12179,8 @@
 +	register_netdevice_notifier(&clip_dev_notifier);
 +	return 0;
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/atmarp.h	Thu Oct 17 15:51:54 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/atmarp.h	Wed Nov 13 11:48:45 1996
 @@ -0,0 +1,53 @@
 +/* net/atm/atmarp.h - RFC1577 ATM ARP */
 + 
@@ -12230,8 +12235,8 @@
 +int atmarp_encap(struct atm_vcc *vcc,int mode);
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/ipcommon.h	Thu Oct 17 15:52:38 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/ipcommon.h	Wed Nov 13 11:49:38 1996
 @@ -0,0 +1,73 @@
 +/* net/atm/ipcommon.h - Common items for all ways of doing IP over ATM */
 +
@@ -12306,7 +12311,7 @@
 +int ipcom_pick_number(int number);
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/net/atm/ipcommon.c	Mon Sep  9 20:07:49 1996
 @@ -0,0 +1,214 @@
 +/* net/atm/ipcommon.c - Common items for all ways of doing IP over ATM */
@@ -12523,9 +12528,9 @@
 +        }
 +	return number;
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/arequipa.c	Fri Oct 18 17:59:09 1996
-@@ -0,0 +1,426 @@
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/arequipa.c	Thu Oct 31 11:55:24 1996
+@@ -0,0 +1,438 @@
 +/* net/atm/arequipa.c - Application requested IP over ATM */
 + 
 +/* Written 1996 by Jean-Michel Pittet and Werner Almesberger, EPFL LRC */
@@ -12585,7 +12590,7 @@
 +};
 +
 +
-+static struct atm_vcc *aq_list = NULL;
++static struct atm_vcc *aq_list = NULL; /* dangling Arequipa VCs */
 +static unsigned long aq_generation = 0;
 +
 +
@@ -12595,11 +12600,11 @@
 +
 +	save_flags(flags);
 +	cli();
-+	if (!(vcc->flags & ATM_VF_AQINUSE)) {
++	if (!(vcc->flags & ATM_VF_AQDANG)) {
 +		restore_flags(flags);
 +		return;
 +	}
-+	vcc->flags &= ~ATM_VF_AQINUSE;
++	vcc->flags &= ~ATM_VF_AQDANG;
 +	if (vcc->aq_prev) vcc->aq_prev->aq_next = vcc->aq_next;
 +	else aq_list = vcc->aq_next;
 +	if (vcc->aq_next) vcc->aq_next->aq_prev = vcc->aq_prev;
@@ -12719,7 +12724,7 @@
 +}
 +
 +
-+static void make_aq_vcc(struct socket *lower)
++static void make_aq_vcc(struct socket *lower,int incoming)
 +{
 +	struct atm_vcc *vcc;
 +	unsigned long flags;
@@ -12732,9 +12737,12 @@
 +	vcc->push = atm_push_arequipa;
 +	vcc->peek = atm_peek_clip;
 +	vcc->push_oam = NULL;
-+	vcc->aq_next = aq_list;
-+	vcc->aq_prev = NULL;
-+	aq_list = vcc;
++	if (incoming) {
++	    vcc->flags |= ATM_VF_AQDANG;
++	    vcc->aq_next = aq_list;
++	    vcc->aq_prev = NULL;
++	    aq_list = vcc;
++	}
 +	vcc->generation = aq_generation++;
 +	restore_flags(flags);
 +	lower->file->f_count++;
@@ -12743,6 +12751,7 @@
 +
 +static int arequipa_attach_unchecked(struct socket *lower,struct sock *upper)
 +{
++	unsigned long flags;
 +	struct rtable *rt;
 +	int error;
 +
@@ -12753,7 +12762,10 @@
 +	}
 +	error = check_aq_vcc(lower);
 +	if (error) return error;
++	save_flags(flags);
++	cli();
 +	if (ATM_SD(lower)->upper) {
++		restore_flags(flags);
 +		printk(KERN_WARNING "arequipa_attach_unchecked: lower is "
 +		    "already attached\n");
 +		return -EISCONN;
@@ -12764,6 +12776,7 @@
 +	ATM_SD(lower)->upper = upper;
 +	rt = upper->ip_route_cache; /* revalidate cache */
 +	upper->ip_route_cache = NULL;
++	restore_flags(flags);
 +	set_rt_cache(upper,rt);
 +	/*
 +	 * The next statement violates RFC1122, because it may change MSS when
@@ -12816,6 +12829,7 @@
 +
 +int arequipa_preset(struct socket *lower,struct sock *upper)
 +{
++	unsigned long flags;
 +	int error;
 +
 +	if (upper->state == TCP_LISTEN) return -EPROTO;
@@ -12825,8 +12839,11 @@
 +	}
 +	error = arequipa_expect(upper,1);
 +	if (error) return error;
++	save_flags(flags);
++	cli();
 +	error = arequipa_attach_unchecked(lower,upper);
-+	if (!error) make_aq_vcc(lower);
++	if (!error) make_aq_vcc(lower,0);
++	restore_flags(flags);
 +	return error;
 +}
 +
@@ -12839,7 +12856,7 @@
 +	error = check_aq_vcc(lower);
 +	if (error) return error;
 +	ATM_SD(lower)->upper = NULL;
-+	make_aq_vcc(lower);
++	make_aq_vcc(lower,1);
 +	DPRINTK("aq_incoming %d\n",lower->file->f_count);
 +	return 0;
 +}
@@ -12952,7 +12969,7 @@
 +        return 0;
 +
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/net/atm/tunable.h	Wed Aug 21 10:55:50 1996
 @@ -0,0 +1,26 @@
 +/* net/atm/tunable.h - Tunable parameters of ATM support */
@@ -12982,7 +12999,7 @@
 +
 +#endif
 --- ref/net/ipv4/af_inet.c	Sun Aug  4 11:56:25 1996
-+++ work/net/ipv4/af_inet.c	Thu Oct 17 11:32:11 1996
++++ work/net/ipv4/af_inet.c	Thu Oct 17 12:32:11 1996
 @@ -105,6 +105,14 @@
  #include <linux/kerneld.h>
  #endif
@@ -13082,7 +13099,7 @@
  #endif
    { NULL,	NULL		}			/* End marker			*/
  };
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/net/atm/mmuio.c	Wed Aug 21 10:55:51 1996
 @@ -0,0 +1,455 @@
 +/* net/atm/mmuio.c - MMU-supported high-speed I/O */
@@ -13540,8 +13557,8 @@
 +}
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/mmuio.h	Tue Oct 15 13:41:12 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/include/linux/mmuio.h	Wed Nov 13 11:48:45 1996
 @@ -0,0 +1,25 @@
 +/* mmuio.h - MMU-supported high-speed I/O */
 +
@@ -13568,7 +13585,7 @@
 +#endif
 +
 +#endif
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/net/atm/raw.c	Wed Aug 21 10:55:52 1996
 @@ -0,0 +1,139 @@
 +/* net/atm/raw.c - Raw AAL0 and AAL5 transports */
@@ -13710,7 +13727,7 @@
 +	vcc->push_oam = NULL;
 +	return 0;
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/net/atm/protocols.h	Wed Aug 21 10:55:52 1996
 @@ -0,0 +1,17 @@
 +/* net/atm/protocols.h - ATM protocol handler entry points */
@@ -13731,7 +13748,7 @@
 +
 +#endif
 --- ref/include/linux/netdevice.h	Tue Aug 20 17:11:35 1996
-+++ work/include/linux/netdevice.h	Tue Oct 15 13:28:32 1996
++++ work/include/linux/netdevice.h	Wed Nov 13 11:55:46 1996
 @@ -185,6 +185,8 @@
    int			  (*set_mac_address)(struct device *dev, void *addr);
  #define HAVE_PRIVATE_IOCTL
@@ -13750,8 +13767,8 @@
  extern void		tr_setup(struct device *dev);
  extern int		ether_config(struct device *dev, struct ifmap *map);
  /* Support for loadable net-drivers */
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/atmarp.h	Thu Oct 10 22:21:34 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/include/linux/atmarp.h	Thu Nov  7 16:08:51 1996
 @@ -0,0 +1,99 @@
 +/* atmarp.h - ATM ARP protocol and kernel-demon interface definitions */
 + 
@@ -13890,7 +13907,7 @@
  
  	if (sk->users) {
 --- ref/net/ipv4/tcp.c	Sun Aug  4 12:56:54 1996
-+++ work/net/ipv4/tcp.c	Fri Oct 18 17:59:46 1996
++++ work/net/ipv4/tcp.c	Fri Oct 18 18:59:46 1996
 @@ -1936,6 +1936,9 @@
  	int atype;
  	struct tcphdr *t1;
@@ -13991,7 +14008,7 @@
  		/* Tell the sender its packet died... */
  		icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, dev);
 --- ref/include/linux/proc_fs.h	Tue Aug 20 17:09:42 1996
-+++ work/include/linux/proc_fs.h	Tue Oct 15 13:28:32 1996
++++ work/include/linux/proc_fs.h	Wed Nov 13 11:53:41 1996
 @@ -34,6 +34,7 @@
  	PROC_KSYMS,
  	PROC_DMA,	
@@ -14113,7 +14130,7 @@
  			case PROC_KCORE:
  				inode->i_mode = S_IFREG | S_IRUSR;
  				inode->i_op = &proc_kcore_inode_operations;
---- /dev/null	Mon Jul 18 01:46:18 1994
+--- /dev/null	Tue Jan  1 05:00:00 1980
 +++ work/net/atm/proc.c	Thu Sep 26 22:12:08 1996
 @@ -0,0 +1,501 @@
 +/* net/atm/proc.c - ATM /proc interface */
@@ -14676,7 +14693,7 @@
  	/*
  	 * can't register TGA yet, because PCI bus probe has *not* taken
 --- ref/init/main.c	Mon May 20 19:33:57 1996
-+++ work/init/main.c	Fri Oct  4 13:16:14 1996
++++ work/init/main.c	Fri Oct  4 14:16:14 1996
 @@ -172,9 +172,14 @@
  #endif
  
@@ -14845,8 +14862,8 @@
  /*
   *	Called once on startup.
   */
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/atmlec.h	Thu Oct 10 19:13:50 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/include/linux/atmlec.h	Thu Nov  7 16:08:51 1996
 @@ -0,0 +1,64 @@
 +/*
 + * 
@@ -14912,9 +14929,9 @@
 +        unsigned char receive;    /* 1= receive vcc, 0 = send_vcc */
 +};
 +#endif /* _ATMLEC_H_ */
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/lec.c	Thu Sep 26 22:12:05 1996
-@@ -0,0 +1,642 @@
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/lec.c	Mon Nov 11 13:32:16 1996
+@@ -0,0 +1,641 @@
 +/*
 + * lec.c: Lan Emulation driver 
 + * Marko Kiiskila carnil@cs.tut.fi
@@ -15459,7 +15476,6 @@
 +                }
 +                skb->dev = dev;
 +                skb->mac.raw = (unsigned char *)skb->data;
-+                skb->mac.ethernet = (struct ethhdr *)skb_pull(skb, 2);     
 +                if (*hdr->h_dest&1) {
 +                        if (memcmp(hdr->h_dest,dev->broadcast, ETH_ALEN)==0)
 +                                skb->pkt_type=PACKET_BROADCAST;
@@ -15473,7 +15489,7 @@
 +                        skb->protocol = hdr->h_type;
 +                else 
 +                        skb->protocol = htons(ETH_P_802_2);
-+                skb->h.raw = skb_pull(skb, ETH_HLEN);
++                skb->h.raw = skb_pull(skb, LEC_HEADER_LEN);
 +                netif_rx(skb);
 +                priv->stats.rx_packets++;
 +        }
@@ -15557,8 +15573,8 @@
 +
 +        return i;
 +}
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/lec.h	Thu Oct 17 15:51:54 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/lec.h	Wed Nov 13 11:48:45 1996
 @@ -0,0 +1,107 @@
 +/*
 + *
@@ -15667,9 +15683,9 @@
 +void lec_push(struct atm_vcc *vcc, struct sk_buff *skb);
 +#endif _LEC_H_
 +
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/lec_arpc.c	Thu Sep 26 22:24:46 1996
-@@ -0,0 +1,1048 @@
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/lec_arpc.c	Mon Nov 11 13:36:12 1996
+@@ -0,0 +1,1055 @@
 +#include <linux/types.h>
 +#include <linux/sched.h>
 +#include <linux/timer.h>
@@ -16676,15 +16692,19 @@
 +{
 +        struct lec_arp_table *entry, *prev;
 +        struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
++        unsigned long flags;
 +  
 +        lec_arp_lock(priv);
 +        entry = priv->lec_arp_empty_ones;
 +        if (vcc == entry->vcc) {
++                save_flags(flags);
++                cli();
 +                del_timer(&entry->timer);
 +                memcpy(entry->mac_addr, hdr->h_source, ETH_ALEN);
 +                entry->status = ESI_FORWARD_DIRECT;
 +                entry->last_used = jiffies;
 +                priv->lec_arp_empty_ones = entry->next;
++                restore_flags(flags);
 +                /* We might have got an entry */
 +                if ((prev=lec_arp_find(priv,hdr->h_source))) {
 +                        lec_arp_remove(priv->lec_arp_tables, prev);
@@ -16705,11 +16725,14 @@
 +                lec_arp_unlock(priv);
 +                return;
 +        }
++        save_flags(flags);
++        cli();
 +        del_timer(&entry->timer);
 +        memcpy(entry->mac_addr, hdr->h_source, ETH_ALEN);
 +        entry->status = ESI_FORWARD_DIRECT;
 +        entry->last_used = jiffies;
 +        prev->next = entry->next;
++        restore_flags(flags);
 +        if ((prev = lec_arp_find(priv, hdr->h_source))) {
 +                lec_arp_remove(priv->lec_arp_tables,prev);
 +                kfree(prev);
@@ -16718,8 +16741,8 @@
 +        lec_arp_unlock(priv);  
 +}
 +
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/lec_arpc.h	Thu Oct 17 15:51:54 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/net/atm/lec_arpc.h	Wed Nov 13 11:48:45 1996
 @@ -0,0 +1,102 @@
 +/*
 + * Lec arp cache
@@ -16824,7 +16847,7 @@
 +
 +#endif
 --- ref/include/net/route.h	Tue Aug 20 17:14:55 1996
-+++ work/include/net/route.h	Thu Oct 17 15:51:08 1996
++++ work/include/net/route.h	Wed Nov 13 11:55:46 1996
 @@ -26,6 +26,7 @@
  #define _ROUTE_H
  
@@ -16888,7 +16911,7 @@
  
  #endif	/* _ROUTE_H */
 --- ref/include/net/sock.h	Tue Aug 20 17:11:40 1996
-+++ work/include/net/sock.h	Fri Oct 18 17:57:05 1996
++++ work/include/net/sock.h	Wed Nov 13 11:55:46 1996
 @@ -189,6 +189,9 @@
  				zapped,	/* In ax25 & ipx means not linked */
  				broadcast,
@@ -16955,13 +16978,13 @@
 +	struct socket		*arequipa;   /* dedicated link layer socket,
 +						NULL if not connected */
 +	struct rtable		*aq_route;   /* buffer for fake route, NULL
-+						if neither present nor expect */
++						if neither preset nor expect */
 +#endif
  
  /*
   *	This part is used for the timeout functions (timer.c). 
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/arequipa.h	Thu Oct 17 15:51:54 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/include/linux/arequipa.h	Wed Nov 13 11:51:22 1996
 @@ -0,0 +1,46 @@
 +/* arequipa.h - Arequipa interface definitions */
 + 
@@ -17010,7 +17033,7 @@
 +
 +#endif
 --- ref/net/ipv4/tcp_input.c	Thu Aug  1 14:25:59 1996
-+++ work/net/ipv4/tcp_input.c	Fri Oct 18 18:01:29 1996
++++ work/net/ipv4/tcp_input.c	Fri Oct 18 19:01:29 1996
 @@ -36,6 +36,11 @@
  #include <linux/random.h>
  #include <net/tcp.h>
@@ -17141,14 +17164,14 @@
  		/*
  		 * We may need to add it to the backlog here. 
 --- ref/net/ipv4/Config.in	Fri Jul 19 07:24:05 1996
-+++ work/net/ipv4/Config.in	Tue Oct 15 13:16:49 1996
++++ work/net/ipv4/Config.in	Tue Oct 15 14:16:49 1996
 @@ -42,3 +42,4 @@
  #bool 'IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF
  bool 'IP: Drop source routed frames' CONFIG_IP_NOSR
  bool 'IP: Allow large windows (not recommended if <16Mb of memory)' CONFIG_SKB_LARGE
 +bool 'IP: Window scale option' CONFIG_SCALED_WINDOWS
 --- ref/include/net/tcp.h	Tue Aug 20 17:14:55 1996
-+++ work/include/net/tcp.h	Thu Oct 17 15:51:08 1996
++++ work/include/net/tcp.h	Wed Nov 13 11:53:38 1996
 @@ -23,16 +23,26 @@
  
  /*
@@ -17213,7 +17236,7 @@
  
  /*
 --- ref/net/core/sock.c	Sat Aug 17 19:28:10 1996
-+++ work/net/core/sock.c	Wed Oct 16 08:19:51 1996
++++ work/net/core/sock.c	Wed Oct 16 09:19:51 1996
 @@ -172,22 +172,32 @@
  			sk->broadcast=valbool;
  			return 0;
@@ -17252,7 +17275,7 @@
  			return(0);
  
 --- ref/net/ipv4/tcp_output.c	Wed Aug  7 08:37:34 1996
-+++ work/net/ipv4/tcp_output.c	Fri Oct 18 17:56:18 1996
++++ work/net/ipv4/tcp_output.c	Fri Oct 18 18:56:18 1996
 @@ -69,7 +69,22 @@
  		minwin = sk->mtu;
  	maxwin = sk->window_clamp;
@@ -17318,8 +17341,8 @@
  	newsk->prot->queue_xmit(newsk, ndev, buff, 0);
  	tcp_reset_xmit_timer(newsk, TIME_WRITE , TCP_TIMEOUT_INIT);
  	skb->sk = newsk;
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/bigphysarea.h	Fri Oct  4 13:14:31 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/include/linux/bigphysarea.h	Fri Oct  4 14:14:31 1996
 @@ -0,0 +1,25 @@
 +/* linux/mm/bigphysarea.h, M. Welsh (mdw@cs.cornell.edu)
 + * Copyright (c) 1996 by Matt Welsh.
@@ -17347,7 +17370,7 @@
 +
 +#endif __LINUX_BIGPHYSAREA_H
 --- ref/mm/Makefile	Fri Mar 22 11:56:56 1996
-+++ work/mm/Makefile	Fri Oct  4 13:14:32 1996
++++ work/mm/Makefile	Fri Oct  4 14:14:32 1996
 @@ -12,4 +12,8 @@
  	    kmalloc.o vmalloc.o \
  	    swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o
@@ -17357,8 +17380,8 @@
 +endif
 +
  include $(TOPDIR)/Rules.make
---- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/mm/bigphysarea.c	Fri Oct  4 13:14:32 1996
+--- /dev/null	Tue Jan  1 05:00:00 1980
++++ work/mm/bigphysarea.c	Fri Oct  4 14:14:32 1996
 @@ -0,0 +1,113 @@
 +/* linux/mm/bigphysarea.c, M. Welsh (mdw@cs.cornell.edu)
 + * Copyright (c) 1996 by Matt Welsh.
diff -ur --new-file old/atm/doc/t2a.pl new/atm/doc/t2a.pl
--- old/atm/doc/t2a.pl	Fri May 31 15:40:05 1996
+++ new/atm/doc/t2a.pl	Tue Nov 12 19:12:49 1996
@@ -195,11 +195,20 @@
 $t =~ tr/-/-/s;
 $t =~ s/\n\n+/$B1/g;
 while ($t =~ /\\cite{([^}]+)}/) {
-    $ref = $1;
-    $bibref[++$citation] = $ref;
-    $t = $`."[$citation]".$';
-    die "unmatched ref $ref" unless $t =~ /\\bibitem{$ref}/;
-    $t = $`."\\item[\[$citation\]] ".$';
+    $t = $`."[";
+    $after = $';
+    for (split(",",$1)) {
+	if (defined $cite{$_}) { $t .= "$cite{$_},"; }
+	else {
+	    $cite{$_} = ++$citation;
+	    $bibref[$citation] = $_;
+	    $t .= "$citation,";
+	    die "unmatched ref $_" unless $after =~ /\\bibitem{$_}/;
+	    $after = $`."\\item[\[$citation\]] ".$';
+	}
+    }
+    $t =~ s/,$//;
+    $t .= "]$after";
 }
 $t =~
   s/\\begin{thebibliography}{[^}]*}/\\section{References}\\begin{description}/;
@@ -327,13 +336,34 @@
 $t !~ /[$X]/ || die "\item problem (2)";
 $t !~ /[$B$E]/ || die "\\begin/\\end{description} mismatch";
 #
+# process figures
+#
+print STDERR "[".length($t)."] Removing figures\n";
+while ($t =~ /\\begin{figure}\s*/) { $t = $`.$B.$'; }
+while ($t =~ /\\end{figure}\s*/) { $t = $`.$E.$'; }
+while ($t =~ /$B[^$B$E]*$E/) {
+    ($a,$b,$c) = ($`,$&,$');
+    $t = $a."[ Figure";
+    if ($b =~ /\\label{([^}]*)}/) {
+	$l{$1} = ++$figref;
+	$t .= " $figref";
+    }
+    if ($b =~ /\\caption{([^}]*)}/) {
+	$t .= ": $1";
+    }
+    $t .= " ]".$c;
+}
+
+#
 # process sections and labels
 #
 print STDERR "[".length($t)."] Processing sections and labels\n";
+$t =~ s/\\begin{abstract}/\\section{Abstract}/g;
+$t =~ s/\\end{abstract}//g;
 $LB = "\005";	# they don't necessarily have to be unique
 $SC = "\006";
 while ($t =~ /\\label{/) { $t = $`.$LB."{".$'; }
-while ($t =~ /\\((sub)*)section{/) { $t = $`.$SC.$1."{".$'; }
+while ($t =~ /\\((sub)*)section\*?{/) { $t = $`.$SC.$1."{".$'; }
 $l = "";
 while (1) {
     if ($t =~ /^([^$LB$SC]*)$LB\{([^{}]*)\}/) {
diff -ur --new-file old/atm/doc/usage.tex new/atm/doc/usage.tex
--- old/atm/doc/usage.tex	Thu Oct 17 14:50:16 1996
+++ new/atm/doc/usage.tex	Wed Nov 13 21:55:07 1996
@@ -1,7 +1,7 @@
 %%def%:=
 
 %:\begin{verbatim}
-%:Usage instructions  -  ATM on Linux, release 0.21 (pre-alpha)
+%:Usage instructions  -  ATM on Linux, release 0.22 (pre-alpha)
 %:-------------------------------------------------------------
 %:
 %:\end{verbatim}
@@ -38,14 +38,14 @@
 
 \title{ATM on Linux \\
   User's guide \\
-  Release 0.21 (pre-alpha)}
+  Release 0.22 (pre-alpha)}
 \author{Werner Almesberger \\
   {\tt werner.almesberger@lrc.di.epfl.ch} \\
   \\
   Laboratoire de R\'eseaux de Communication (LRC) \\
   EPFL, CH-1015 Lausanne, Switzerland}
  
-\date{October 15, 1996}
+\date{November 13, 1996}
 
 \begin{document}
 \maketitle
@@ -81,7 +81,7 @@
 In order to install this package, you need
 \begin{itemize}
   \item the package itself
-    \url{ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.21.tar.gz}
+    \url{ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.22.tar.gz}
   \item the Linux kernel, version 2.0.14, e.g. from
 \url{ftp://ftp.cs.helsinki.fi/pub/Software/Linux/Kernel/v2.0/linux-2.0.14.tar.gz}
   \item Perl, version 4 or 5
@@ -98,7 +98,7 @@
 distribution:
 
 \begin{verbatim}
-tar xfz atm-0.21.tar.gz
+tar xfz atm-0.22.tar.gz
 \end{verbatim}
 
 and the kernel source:
@@ -139,6 +139,7 @@
   \item[\path{atm/lib/}] Libraries for applications and demons
   \item[\path{atm/doc/}] Documentation in \LaTeX\ and conversion tools
   \item[\path{atm/man/}] Miscellaneous man pages
+  \item[\path{atm/extra/}] Extra packages (\name{tcpdump} and \name{ans})
 \end{description}
 
 
@@ -258,6 +259,36 @@
 Libraries and header files are installed in
 \path{/usr/lib} and \path{/usr/include}, respectively. Man pages are
 installed in \path{/usr/local/man}.
+
+
+\subsection{Extra packages}
+
+Some programs are based on large packages that are already distributed
+outside of the ATM context. For such packages, only patches are contained
+in the ATM on Linux distribution. The complete packages can be obtained
+either from the original source (described in \path{atm/extra/extra.html})
+or from \url{ftp://lrcftp.epfl.ch/pub/linux/atm/extra/}.
+
+The packages are automatically downloaded, patched, and built by running
+\raw{make \meta{package\_name}} in the \path{atm/extra/} directory
+(requires that the \name{Lynx} Web browser is installed).
+
+Currently, the following extra packages are available:
+\begin{description}
+  \item[\name{tcpdump}] dumps network traffic (enhanced for ATM)
+  \item[\name{ans}] ATM name server (based on \name{named} 4.9.5)
+\end{description}
+
+Building \name{tcpdump} requires that \name{csh} is installed.
+Note that \name{text2atm} automatically uses ANS if available, so
+\name{ans} only needs to be installed on systems providing
+name server functionality or if ATM-aware maintenance tools
+(\name{nslookup}, etc.) are needed.
+
+A script \name{hosts2ans.pl} to convert a \path{/etc/hosts.atm} file to
+ANS zone files is provided in \path{atm/extra/}. Its use is described at
+the beginning of the file.
+
 
 %------------------------------------------------------------------------------
 
diff -ur --new-file old/atm/doc/usage.txt new/atm/doc/usage.txt
--- old/atm/doc/usage.txt	Fri Oct 18 15:05:33 1996
+++ new/atm/doc/usage.txt	Wed Nov 13 23:19:59 1996
@@ -1,4 +1,4 @@
-Usage instructions  -  ATM on Linux, release 0.21 (pre-alpha)
+Usage instructions  -  ATM on Linux, release 0.22 (pre-alpha)
 -------------------------------------------------------------
 
 For updates of ATM on Linux, please check the Web page at  
@@ -17,7 +17,7 @@
 In order to install this package, you need 
 
   - the package itself  
-    ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.21.tar.gz  
+    ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.22.tar.gz  
   - the Linux kernel, version 2.0.14, e.g. from  
     ftp://ftp.cs.helsinki.fi/pub/Software/Linux/Kernel/v2.0/linux-2.0.14.tar.gz  
   - Perl, version 4 or 5 
@@ -33,7 +33,7 @@
 all the files listed above there. Then extract the ATM on Linux 
 distribution:
 
-tar xfz atm-0.21.tar.gz
+tar xfz atm-0.22.tar.gz
 
 and the kernel source:
 
@@ -65,6 +65,7 @@
   atm/lib/  Libraries for applications and demons 
   atm/doc/  Documentation in LaTeX and conversion tools 
   atm/man/  Miscellaneous man pages 
+  atm/extra/  Extra packages (tcpdump and ans) 
 
 
 Kernel configuration
@@ -172,6 +173,33 @@
 /usr/local/sbin, respectively. Libraries and header files are installed in 
 /usr/lib and /usr/include, respectively. Man pages are installed in 
 /usr/local/man.
+
+
+Extra packages
+--------------
+
+Some programs are based on large packages that are already distributed 
+outside of the ATM context. For such packages, only patches are contained 
+in the ATM on Linux distribution. The complete packages can be obtained 
+either from the original source (described in atm/extra/extra.html) or from  
+ftp://lrcftp.epfl.ch/pub/linux/atm/extra/ .
+
+The packages are automatically downloaded, patched, and built by running  
+make <package_name>  in the atm/extra/ directory (requires that the Lynx 
+Web browser is installed).
+
+Currently, the following extra packages are available: 
+
+  tcpdump  dumps network traffic (enhanced for ATM) 
+  ans  ATM name server (based on named 4.9.5) 
+
+Building tcpdump requires that csh is installed. Note that text2atm 
+automatically uses ANS if available, so ans only needs to be installed on 
+systems providing name server functionality or if ATM-aware maintenance 
+tools (nslookup, etc.) are needed.
+
+A script hosts2ans.pl to convert a /etc/hosts.atm file to ANS zone files is 
+provided in atm/extra/. Its use is described at the beginning of the file.
 
 
 Device setup
diff -ur --new-file old/atm/extra/Makefile new/atm/extra/Makefile
--- old/atm/extra/Makefile	Thu Jan  1 01:00:00 1970
+++ new/atm/extra/Makefile	Wed Nov 13 17:11:58 1996
@@ -0,0 +1,50 @@
+TCPDUMPSRC=tcpdump-3.0.4-1.tar.gz
+TCPDUMPDIR=tcpdump-3.0.4
+TCPDUMPPATCH=tcpdump-3.0.4-1.patch
+ANSSRC=bind-4.9.5-REL.tar.gz
+ANSDIR=bind-4.9.5
+ANSPATCH=bind-4.9.5-REL.patch
+DIR=ftp://lrcftp.epfl.ch/pub/linux/atm/extra
+
+include ../Rules.make
+
+all:		tcpdump ans
+
+install:
+		[ ! -d $(TCPDUMPDIR) ] || $(MAKE) install-tcpdump
+		[ ! -d $(ANSDIR) ] || $(MAKE) install-ans
+
+tcpdump:
+		[ -f $(TCPDUMPSRC) ] || \
+		  lynx -dump $(DIR)/$(TCPDUMPSRC) >$(TCPDUMPSRC)
+		[ -d $(TCPDUMPDIR) ] || tar xfz $(TCPDUMPSRC)
+		[ -f $(TCPDUMPDIR)/.patched ] || { \
+		  cd $(TCPDUMPDIR) && patch -p1 -s <../$(TCPDUMPPATCH) && \
+		  touch .patched \
+		}
+		[ -f $(TCPDUMPDIR)/.compiled ] || { \
+		  cd $(TCPDUMPDIR) && ./debian.rules && touch .compiled \
+		}
+		
+install-tcpdump:
+		[ -f $(TCPDUMPDIR)/.compiled ] || $(MAKE) tcpdump
+		install -c -m 755 $(TCPDUMPDIR)/$(TCPDUMPDIR)/tcpdump \
+		  $(INSTSYSBIN)/tcpdump_atm
+
+ans:
+		[ -f $(ANSSRC) ] || \
+		  lynx -dump $(DIR)/$(ANSSRC) >$(ANSSRC)
+		[ -d $(ANSDIR) ] || { mkdir $(ANSDIR) && cd $(ANSDIR) && \
+		  tar xfz ../$(ANSSRC) }
+		[ -f $(ANSDIR)/.patched ] || { \
+		  cd $(ANSDIR) && \
+		  patch -p1 -s --remove-empty-files <../$(ANSPATCH) && \
+		  touch .patched \
+		}
+		[ -f $(ANSDIR)/.compiled ] || { \
+		  cd $(ANSDIR) && make && touch .compiled \
+		}
+
+install-ans:
+		[ -f $(ANSDIR)/.compiled ] || $(MAKE) ans
+		cd $(ANSDIR) && make install	# brute-force
diff -ur --new-file old/atm/extra/bind-4.9.5-REL.patch new/atm/extra/bind-4.9.5-REL.patch
--- old/atm/extra/bind-4.9.5-REL.patch	Thu Jan  1 01:00:00 1970
+++ new/atm/extra/bind-4.9.5-REL.patch	Tue Nov 12 17:37:55 1996
@@ -0,0 +1,1998 @@
+diff -urN bindtmp/Makefile bind/Makefile
+--- bindtmp/Makefile	Mon Nov 11 08:36:41 1996
++++ bind/Makefile	Tue Nov 12 16:52:35 1996
+@@ -111,20 +111,20 @@
+ 
+ #(Linux - on modern systems, all you need to do is rename or remove
+ # compat/include/sys/cdefs.h.  See doc/info/Linux for more information.)
+-#CC = gcc $(CPPFLAGS)
+-#CDEBUG = -g
+-#CPPFLAGS = -DSYSV
+-#LEX=flex -8 -I
+-#INSTALL_COMPAT = install-compat
+-#LIBS = -lfl
+-#DESTEXEC = /usr/sbin
+-#DESTMAN = /usr/man
+-#MANDIR = man
+-#MANROFF = cat
+-#DESTHELP = /usr/lib
+-#CATEXT = $$$$N
+-#PS = ps -p
+-#IOT = IOT
++CC = gcc $(CPPFLAGS)
++CDEBUG = -g
++CPPFLAGS = -DSYSV -DATM
++LEX=flex -8 -I
++INSTALL_COMPAT = install-compat
++LIBS = -lfl -latm
++DESTEXEC = /usr/sbin
++DESTMAN = /usr/man
++MANDIR = man
++MANROFF = cat
++DESTHELP = /usr/lib
++CATEXT = $$$$N
++PS = ps -p
++IOT = IOT
+ #uncomment next line to build a shared library version of libresolv
+ #SHRES = shres/linux
+ #uncomment next line to build tools and named with shared libresolv
+diff -urN bindtmp/compat/include/sys/cdefs.h bind/compat/include/sys/cdefs.h
+--- bindtmp/compat/include/sys/cdefs.h	Sat Sep 21 01:35:02 1996
++++ bind/compat/include/sys/cdefs.h	Thu Jan  1 02:00:00 1970
+@@ -1,141 +0,0 @@
+-/*
+- * Copyright (c) 1991, 1993
+- *	The Regents of the University of California.  All rights reserved.
+- *
+- * This code is derived from software contributed to Berkeley by
+- * Berkeley Software Design, Inc.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- *    notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- *    notice, this list of conditions and the following disclaimer in the
+- *    documentation and/or other materials provided with the distribution.
+- * 3. All advertising materials mentioning features or use of this software
+- *    must display the following acknowledgement:
+- *	This product includes software developed by the University of
+- *	California, Berkeley and its contributors.
+- * 4. Neither the name of the University nor the names of its contributors
+- *    may be used to endorse or promote products derived from this software
+- *    without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+- * SUCH DAMAGE.
+- *
+- *	@(#)cdefs.h	8.7 (Berkeley) 1/21/94
+- */
+-
+-#ifndef	_CDEFS_H_
+-#define	_CDEFS_H_
+-
+-/* POSIX.2 feature test macro: enable POSIX.1 and/or more */
+-#if _POSIX_C_SOURCE == 1 || _POSIX_C_SOURCE == 2
+-#define	_POSIX_SOURCE
+-#endif
+-
+-#if defined(_POSIX_SOURCE) || defined(__STRICT_ANSI__)
+-#define	_ANSI_SOURCE
+-#endif
+-
+-#if defined(__cplusplus)
+-#define	__BEGIN_DECLS	extern "C" {
+-#define	__END_DECLS	};
+-#else
+-#define	__BEGIN_DECLS
+-#define	__END_DECLS
+-#endif
+-
+-/*
+- * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+- * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+- * The __CONCAT macro is a bit tricky -- make sure you don't put spaces
+- * in between its arguments.  __CONCAT can also concatenate double-quoted
+- * strings produced by the __STRING macro, but this only works with ANSI C.
+- */
+-#if defined(__STDC__) || defined(__cplusplus)
+-#define	__P(protos)	protos		/* full-blown ANSI C */
+-#define	__CONCAT(x,y)	x ## y
+-#define	__STRING(x)	#x
+-
+-#define	__const		const		/* define reserved names to standard */
+-#define	__signed	signed
+-#define	__volatile	volatile
+-#if defined(__cplusplus)
+-#define	__inline	inline		/* convert to C++ keyword */
+-#else
+-#ifndef __GNUC__
+-#define	__inline			/* delete GCC keyword */
+-#endif /* !__GNUC__ */
+-#endif /* !__cplusplus */
+-
+-#else	/* !(__STDC__ || __cplusplus) */
+-#define	__P(protos)	()		/* traditional C preprocessor */
+-#define	__CONCAT(x,y)	x/**/y
+-#define	__STRING(x)	"x"
+-
+-#ifndef __GNUC__
+-#define	__const				/* delete pseudo-ANSI C keywords */
+-#define	__inline
+-#define	__signed
+-#define	__volatile
+-/*
+- * In non-ANSI C environments, new programs will want ANSI-only C keywords
+- * deleted from the program and old programs will want them left alone.
+- * When using a compiler other than gcc, programs using the ANSI C keywords
+- * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
+- * When using "gcc -traditional", we assume that this is the intent; if
+- * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
+- */
+-#ifndef	NO_ANSI_KEYWORDS
+-#define	const				/* delete ANSI C keywords */
+-#define	inline
+-#define	signed
+-#define	volatile
+-#endif
+-#endif	/* !__GNUC__ */
+-#endif	/* !(__STDC__ || __cplusplus) */
+-
+-/*
+- * GCC1 and some versions of GCC2 declare dead (non-returning) and
+- * pure (no side effects) functions using "volatile" and "const";
+- * unfortunately, these then cause warnings under "-ansi -pedantic".
+- * GCC2 uses a new, peculiar __attribute__((attrs)) style.  All of
+- * these work for GNU C++ (modulo a slight glitch in the C++ grammar
+- * in the distribution version of 2.5.5).
+- */
+-#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 5
+-#define	__attribute__(x)	/* delete __attribute__ if non-gcc or gcc1 */
+-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+-#define	__dead		__volatile
+-#define	__pure		__const
+-#endif
+-#endif
+-/* The following lines were added for newer versions of GNU C
+- *   Ed Lewis - Sept 1996 lewis@tis.com
+- */    
+-#if __GNUC__ == 2 &&  __GNUC_MINOR__ >= 5 || __GNUC__ >= 3
+-#define __dead
+-#define __dead2     __attribute__((noreturn))
+-#define __pure
+-#define __pure2     __attribute__((const))
+-#endif
+-
+-
+-/* Delete pseudo-keywords wherever they are not available or needed. */
+-#ifndef __dead
+-#define	__dead
+-#define	__pure
+-#endif
+-
+-#endif /* !_CDEFS_H_ */
+diff -urN bindtmp/compat/include/sys/cdefs.h.moved bind/compat/include/sys/cdefs.h.moved
+--- bindtmp/compat/include/sys/cdefs.h.moved	Thu Jan  1 02:00:00 1970
++++ bind/compat/include/sys/cdefs.h.moved	Sat Sep 21 01:35:02 1996
+@@ -0,0 +1,141 @@
++/*
++ * Copyright (c) 1991, 1993
++ *	The Regents of the University of California.  All rights reserved.
++ *
++ * This code is derived from software contributed to Berkeley by
++ * Berkeley Software Design, Inc.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *	This product includes software developed by the University of
++ *	California, Berkeley and its contributors.
++ * 4. Neither the name of the University nor the names of its contributors
++ *    may be used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ *
++ *	@(#)cdefs.h	8.7 (Berkeley) 1/21/94
++ */
++
++#ifndef	_CDEFS_H_
++#define	_CDEFS_H_
++
++/* POSIX.2 feature test macro: enable POSIX.1 and/or more */
++#if _POSIX_C_SOURCE == 1 || _POSIX_C_SOURCE == 2
++#define	_POSIX_SOURCE
++#endif
++
++#if defined(_POSIX_SOURCE) || defined(__STRICT_ANSI__)
++#define	_ANSI_SOURCE
++#endif
++
++#if defined(__cplusplus)
++#define	__BEGIN_DECLS	extern "C" {
++#define	__END_DECLS	};
++#else
++#define	__BEGIN_DECLS
++#define	__END_DECLS
++#endif
++
++/*
++ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
++ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
++ * The __CONCAT macro is a bit tricky -- make sure you don't put spaces
++ * in between its arguments.  __CONCAT can also concatenate double-quoted
++ * strings produced by the __STRING macro, but this only works with ANSI C.
++ */
++#if defined(__STDC__) || defined(__cplusplus)
++#define	__P(protos)	protos		/* full-blown ANSI C */
++#define	__CONCAT(x,y)	x ## y
++#define	__STRING(x)	#x
++
++#define	__const		const		/* define reserved names to standard */
++#define	__signed	signed
++#define	__volatile	volatile
++#if defined(__cplusplus)
++#define	__inline	inline		/* convert to C++ keyword */
++#else
++#ifndef __GNUC__
++#define	__inline			/* delete GCC keyword */
++#endif /* !__GNUC__ */
++#endif /* !__cplusplus */
++
++#else	/* !(__STDC__ || __cplusplus) */
++#define	__P(protos)	()		/* traditional C preprocessor */
++#define	__CONCAT(x,y)	x/**/y
++#define	__STRING(x)	"x"
++
++#ifndef __GNUC__
++#define	__const				/* delete pseudo-ANSI C keywords */
++#define	__inline
++#define	__signed
++#define	__volatile
++/*
++ * In non-ANSI C environments, new programs will want ANSI-only C keywords
++ * deleted from the program and old programs will want them left alone.
++ * When using a compiler other than gcc, programs using the ANSI C keywords
++ * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
++ * When using "gcc -traditional", we assume that this is the intent; if
++ * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
++ */
++#ifndef	NO_ANSI_KEYWORDS
++#define	const				/* delete ANSI C keywords */
++#define	inline
++#define	signed
++#define	volatile
++#endif
++#endif	/* !__GNUC__ */
++#endif	/* !(__STDC__ || __cplusplus) */
++
++/*
++ * GCC1 and some versions of GCC2 declare dead (non-returning) and
++ * pure (no side effects) functions using "volatile" and "const";
++ * unfortunately, these then cause warnings under "-ansi -pedantic".
++ * GCC2 uses a new, peculiar __attribute__((attrs)) style.  All of
++ * these work for GNU C++ (modulo a slight glitch in the C++ grammar
++ * in the distribution version of 2.5.5).
++ */
++#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 5
++#define	__attribute__(x)	/* delete __attribute__ if non-gcc or gcc1 */
++#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
++#define	__dead		__volatile
++#define	__pure		__const
++#endif
++#endif
++/* The following lines were added for newer versions of GNU C
++ *   Ed Lewis - Sept 1996 lewis@tis.com
++ */    
++#if __GNUC__ == 2 &&  __GNUC_MINOR__ >= 5 || __GNUC__ >= 3
++#define __dead
++#define __dead2     __attribute__((noreturn))
++#define __pure
++#define __pure2     __attribute__((const))
++#endif
++
++
++/* Delete pseudo-keywords wherever they are not available or needed. */
++#ifndef __dead
++#define	__dead
++#define	__pure
++#endif
++
++#endif /* !_CDEFS_H_ */
+diff -urN bindtmp/include/arpa/nameser.h bind/include/arpa/nameser.h
+--- bindtmp/include/arpa/nameser.h	Tue Oct  8 07:51:02 1996
++++ bind/include/arpa/nameser.h	Mon Nov 11 22:15:36 1996
+@@ -204,6 +204,12 @@
+ #define C_ANY		255		/* wildcard match */
+ 
+ /*
++ * Values for ATM format
++ */
++#define ATMA_AESA        0
++#define ATMA_E164        1
++
++/*
+  * Flags field of the KEY RR rdata
+  */
+ #define	KEYFLAG_TYPEMASK	0xC000	/* Mask for "type" bits */
+diff -urN bindtmp/include/atmresolv.h bind/include/atmresolv.h
+--- bindtmp/include/atmresolv.h	Thu Jan  1 02:00:00 1970
++++ bind/include/atmresolv.h	Mon Nov 11 22:16:35 1996
+@@ -0,0 +1,58 @@
++/*
++ *
++ * Header for resolver funcs and defines used
++ *
++ * $Id$
++ *
++ */
++
++#ifndef _ATMRESOLV_H_
++#define _ATMRESOLV_H_
++#include <arpa/nameser.h>
++#include <resolv.h>
++#if defined(linux)
++#include <linux/atm.h>
++
++/* Path to resolver file */
++#define _PATH_ATMRESCONF        _PATH_RESCONF
++
++/*
++ * Global defines and variables for resolver stub.
++ */
++
++#define RES_MAX_CELL_RATE       3584    /* Max cell rate of connection */
++
++struct __atmres_state {
++  int            nscount;                /* number of name servers */
++  struct sockaddr_atmsvc  
++                 nsaddr_list[MAXNS];
++};
++
++#define nsaddr nsaddr_list[0]
++
++/*
++ * Resolver options (keep these in synch with res_debug.c, please)
++ */
++#define RES_ATMINIT     0x00001000      /* ATM resolver initialized */
++
++extern struct __atmres_state _atmres;
++extern int _queryatm;
++
++#else
++#define ATM_ESA_LEN 20
++#define ATM_E164_LEN 12
++#define ATM_AFI_DCC     0x39            /* DCC ATM Format */
++#define ATM_AFI_ICD     0x47            /* ICD ATM Format */
++#define ATM_AFI_E164    0x45            /* E.164 ATM Format */
++#endif
++
++/* New parameters for h_addrtype in gethostbyaddr */
++#define AF_ATMNSAP              3
++#define AF_ATME164              8
++
++struct hostent *gethostbyname_atmnsap(const char *name);
++struct hostent *gethostbyname_e164(const char *name);
++
++/* Protos */
++int atmres_init(void);
++#endif /* _ATMRESOLV_H_ */
+diff -urN bindtmp/named/Makefile bind/named/Makefile
+--- bindtmp/named/Makefile	Sun Sep 22 03:13:10 1996
++++ bind/named/Makefile	Mon Nov 11 22:17:33 1996
+@@ -97,17 +97,18 @@
+ 
+ CFLAGS = ${CDEBUG} -I${INCL} -I${COMPINCL} ${DEFS}
+ 
+-HDRS=	db_defs.h db_glob.h ns_defs.h ns_glob.h named.h pathnames.h tree.h
++HDRS=	db_defs.h db_glob.h ns_defs.h ns_glob.h named.h pathnames.h tree.h \
++	atm_itf.h
+ SRCS=	db_dump.c db_load.c db_lookup.c db_reload.c db_save.c db_update.c \
+ 	db_secure.c db_glue.c \
+ 	ns_forw.c ns_init.c ns_main.c ns_maint.c ns_req.c ns_resp.c \
+ 	ns_sort.c ns_stats.c ns_validate.c ns_ncache.c \
+-	storage.c tree.c ns_udp.c
++	storage.c tree.c ns_udp.c atm_itf.c
+ OBJS=	db_dump.o db_load.o db_lookup.o db_reload.o db_save.o db_update.o \
+ 	db_secure.o db_glue.o \
+ 	ns_forw.o ns_init.o ns_main.o ns_maint.o ns_req.o ns_resp.o \
+ 	ns_sort.o ns_stats.o ns_validate.o ns_ncache.o \
+-	storage.o tree.o ns_udp.o
++	storage.o tree.o ns_udp.o atm_itf.o
+ XFERSRCS=  named-xfer.c
+ XFEROBJ=   named-xfer.o db_glue.o storage.o version.o
+ 
+diff -urN bindtmp/named/atm_itf.c bind/named/atm_itf.c
+--- bindtmp/named/atm_itf.c	Thu Jan  1 02:00:00 1970
++++ bind/named/atm_itf.c	Tue Nov 12 09:28:46 1996
+@@ -0,0 +1,115 @@
++/*
++ * Marko Kiiskila carnil@cs.tut.fi 
++ * 
++ * Copyright (c) 1996
++ * Tampere University of Technology - Telecommunications Laboratory
++ * All rights reserved.
++ *
++ * Permission to use, copy, modify and distribute this
++ * software and its documentation is hereby granted,
++ * provided that both the copyright notice and this
++ * permission notice appear in all copies of the software,
++ * derivative works or modified versions, and any portions
++ * thereof, that both notices appear in supporting
++ * documentation, and that the use of this software is
++ * acknowledged in any publications resulting from using
++ * the software.
++ * 
++ * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
++ * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
++ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
++ * SOFTWARE.
++ * 
++ */
++
++/*
++ *
++ * Source file for ATM interface in Linux
++ *
++ */
++#include <unistd.h>
++#include <stdio.h>
++#include <errno.h>
++#include <sys/socket.h>
++#include <string.h>
++#include <netinet/in.h>
++#include <arpa/nameser.h>
++
++#include "named.h"
++#include <sys/syslog.h>
++extern int errno;
++
++#if defined(linux) && defined(ATM)
++
++#include <linux/atm.h>
++#include <linux/atmsap.h>
++
++#endif /* (defined(linux) && ATM) */
++#include "atm_itf.h"
++
++#if defined(linux) && defined(ATM)
++
++/* Listening ATM socket */
++int atm_vs;
++
++/* From ATM address */
++struct sockaddr_atmsvc from_atmaddr;
++
++int 
++open_atm_stream(void)
++{
++  struct sockaddr_atmsvc server;
++  int s;
++  unsigned char appl_id[] = { 0x00, 0xa0, 0x3e, 0x00, 0x00, 0x00, 0x01 };
++  struct atm_qos conqos;
++
++  s = socket(PF_ATMSVC, SOCK_DGRAM, ATM_AAL5);
++  if (s<0) {
++    syslog(LOG_ERR, "ATM socket failed: %m\n");
++    return -errno;
++  }
++  memset(&server, 0, sizeof(server));
++  server.sas_family = AF_ATMSVC;
++  server.sas_addr.bhli.hl_type = ATM_HL_VENDOR;
++  memcpy(server.sas_addr.bhli.hl_info, appl_id, 7);
++
++  memset(&conqos, 0, sizeof(conqos));
++  conqos.txtp.traffic_class = conqos.rxtp.traffic_class = ATM_UBR;
++  conqos.txtp.max_sdu = conqos.rxtp.max_sdu = 512;
++  if (setsockopt(s,SOL_ATM,SO_ATMQOS,&conqos,sizeof(conqos)) < 0) {
++    syslog(LOG_ERR, "ATM setsockopt SO_ATMQOS failed: %m\n");
++    close(s);
++    return -errno;
++  }
++  if (bind(s, (struct sockaddr *)&server, sizeof(struct sockaddr_atmsvc))<0) {
++    syslog(LOG_ERR, "ATM socket bind failed: %m\n");
++    close(s);
++    return -errno;
++  }
++
++  if (listen(s, QLEN) <0) {
++    syslog(LOG_ERR, "ATM socket listen failed: %m\n");
++    close(s);
++    return -errno;
++  }
++  return s;
++}
++
++int
++close_atm_stream(int s)
++{
++  return (close(s));
++}
++
++int
++is_qstream_atm(struct qstream *to_test)
++{
++  return (to_test->s_atmfrom.sas_family);
++}
++
++#endif /* (defined(linux) && ATM) */
++/*
++ *
++ * $Log$
++ *
++ */
+diff -urN bindtmp/named/atm_itf.h bind/named/atm_itf.h
+--- bindtmp/named/atm_itf.h	Thu Jan  1 02:00:00 1970
++++ bind/named/atm_itf.h	Mon Nov 11 22:18:00 1996
+@@ -0,0 +1,55 @@
++/*
++ * Marko Kiiskila carnil@cs.tut.fi 
++ * 
++ * Copyright (c) 1996
++ * Tampere University of Technology - Telecommunications Laboratory
++ * All rights reserved.
++ *
++ * Permission to use, copy, modify and distribute this
++ * software and its documentation is hereby granted,
++ * provided that both the copyright notice and this
++ * permission notice appear in all copies of the software,
++ * derivative works or modified versions, and any portions
++ * thereof, that both notices appear in supporting
++ * documentation, and that the use of this software is
++ * acknowledged in any publications resulting from using
++ * the software.
++ * 
++ * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
++ * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
++ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
++ * SOFTWARE.
++ * 
++ */
++
++/*
++ *
++ * Include file for ATM interface in Linux
++ *
++ */
++#ifndef _ATM_ITF_H_
++#define _ATM_ITF_H_
++#if defined(linux) && defined(ATM)
++#include <linux/atm.h>
++#include <linux/atmsap.h>
++
++#define MAX_CELL_RATE 3084
++#define QLEN 5
++
++/* Listening ATM socket */
++extern int atm_vs;
++
++/* From ATM address */
++extern struct sockaddr_atmsvc from_atmaddr;
++
++/* Protos */
++int open_atm_stream(void);
++int close_atm_stream(int s);
++int is_qstream_atm(struct qstream *to_test);
++#endif /* defined(linux) && defined(ATM) */
++#endif /* _ATM_ITF_H_ */
++/*
++ *
++ * $Log$
++ *
++ */
+diff -urN bindtmp/named/db_dump.c bind/named/db_dump.c
+--- bindtmp/named/db_dump.c	Tue Oct  8 07:51:03 1996
++++ bind/named/db_dump.c	Tue Nov 12 16:36:04 1996
+@@ -569,6 +569,20 @@
+ 							    dp->d_data, NULL),
+ 					     fp);
+ 				break;
++#if defined(ATM)
++                       case T_ATMA:
++                         if (dp->d_size == 21) {
++			   int i;
++
++                           (void) fputs("AESA ",fp);
++			   for (i=1;i<dp->d_size;i++)
++			     (void)fprintf(fp,"%2.2x",dp->d_data[i]&0xff);
++                         } else {
++                           (void) fputs("E164 ", fp);
++                           (void) fputs(dp->d_data+1, fp);
++                         }
++                         break;
++#endif /* defined (ATM) */
+ 			case T_AAAA: {
+ 				char t[sizeof
+ 				"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"
+diff -urN bindtmp/named/db_load.c bind/named/db_load.c
+--- bindtmp/named/db_load.c	Mon Nov 11 08:36:50 1996
++++ bind/named/db_load.c	Mon Nov 11 22:21:56 1996
+@@ -103,6 +103,10 @@
+ 
+ #include "named.h"
+ 
++#if defined(ATM)
++#include <atmresolv.h>
++#endif /* defined(ATM) */
++
+ #define ALLOW_LONG_TXT_RDATA
+ 
+ static int		gettoken __P((register FILE *, const char *)),
+@@ -807,6 +811,33 @@
+ 				if (n == 0)
+ 					goto err;
+ 				break;
++#if defined(ATM)
++                       case T_ATMA:
++                         if (*buf=='+') { /* E.164 */
++                           cp = buf+1;
++                           data[0] = ATMA_E164;
++                           n=1;
++                           while (*cp != '\0' && *cp != '\n' &&
++                                  n <= ATM_E164_LEN) {
++                             if (isdigit(*cp))
++                               data[n++] = *cp++;
++                             else if (*cp++ != '.')
++                               goto err;
++                           }
++                           if (n-1 > ATM_E164_LEN || n == 0)
++                             goto err;
++                           endline(fp);
++                         } else { /* NSAP */
++                           data[0] = ATMA_AESA;
++                           n = inet_nsap_addr(buf, (u_char *)data+1,
++                                              (sizeof data) -1);
++                           if (n != ATM_ESA_LEN)
++                             goto err;
++                           n++;
++                           endline(fp);
++                         }
++                         break;
++#endif /* defined (ATM) */
+ 
+ 			case T_NSAP:
+ 				n = inet_nsap_addr(buf, (u_char *)data,
+diff -urN bindtmp/named/db_update.c bind/named/db_update.c
+--- bindtmp/named/db_update.c	Tue Oct  8 07:51:04 1996
++++ bind/named/db_update.c	Mon Nov 11 22:22:34 1996
+@@ -684,6 +684,9 @@
+ 	case T_GID:
+ 	case T_WKS:
+ 	case T_NULL:
++#if defined(ATM)
++       case T_ATMA:
++#endif /* defined(ATM) */
+ 	case T_NSAP:
+ 	case T_AAAA:
+ 	case T_LOC:
+diff -urN bindtmp/named/named-xfer.c bind/named/named-xfer.c
+--- bindtmp/named/named-xfer.c	Mon Nov 11 08:36:50 1996
++++ bind/named/named-xfer.c	Mon Nov 11 22:24:56 1996
+@@ -1266,6 +1266,9 @@
+ 	case T_X25:
+ 	case T_ISDN:
+ 	case T_LOC:
++#if defined(ATM)
++       case T_ATMA:
++#endif /* defined(ATM) */
+ 	case T_NSAP:
+ 	case T_AAAA:
+ 	case T_UID:
+@@ -1696,6 +1699,12 @@
+ 	case T_NSAP:
+ 		fprintf(dbfp, "%s\n", inet_nsap_ntoa(n, cp, NULL));
+ 		break;
++
++#if defined(ATM)
++       case T_ATMA:
++         fprintf(dbfp, "ATM RR\n");
++         break;
++#endif /* defined(ATM) */
+ 
+ 	case T_AAAA: {
+ 		char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+diff -urN bindtmp/named/ns_defs.h bind/named/ns_defs.h
+--- bindtmp/named/ns_defs.h	Mon Nov 11 08:36:50 1996
++++ bind/named/ns_defs.h	Mon Nov 11 22:26:22 1996
+@@ -188,6 +188,12 @@
+ 	int		nretry;		/* # of times addr retried */
+ };
+ 
++#if defined(ATM)
++#if defined(linux)
++#include <linux/atm.h>
++#endif /* defined(linux) */
++#endif /* defined(ATM) */
++
+ /*
+  * Structure for recording info on forwarded or generated queries.
+  */
+@@ -259,6 +265,12 @@
+ 	struct qstream	*s_next;	/* next stream */
+ 	struct sockaddr_in
+ 			s_from;		/* address query came from */
++#if defined(ATM)
++#if defined(linux)
++        struct sockaddr_atmsvc
++                       s_atmfrom;      /* ATM address query came from */
++#endif /* defined(linux) */
++#endif /* defined(ATM) */
+ 	u_int32_t	s_time;		/* time stamp of last transaction */
+ 	int		s_refcnt;	/* number of outstanding queries */
+ 	u_int16_t	s_tempsize;	/* temporary for size from net */
+diff -urN bindtmp/named/ns_forw.c bind/named/ns_forw.c
+--- bindtmp/named/ns_forw.c	Tue Oct  8 07:51:04 1996
++++ bind/named/ns_forw.c	Mon Nov 11 22:27:23 1996
+@@ -128,7 +128,10 @@
+ 	qp->q_domain = strdup(tmpdomain);
+ 	if (!qp->q_domain)
+ 		panic(ENOMEM, "ns_forw: strdup failed");
+-	qp->q_from = *fp;	/* nslookup wants to know this */
++	if (fp)
++	  qp->q_from = *fp;	/* nslookup wants to know this */
++	else
++	  memset(&qp->q_from, 0, sizeof(qp->q_from));
+ 	n = nslookup(nsp, qp, dname, "ns_forw");
+ 	if (n < 0) {
+ 		dprintf(2, (ddt, "forw: nslookup reports danger\n"));
+diff -urN bindtmp/named/ns_main.c bind/named/ns_main.c
+--- bindtmp/named/ns_main.c	Mon Nov 11 08:36:51 1996
++++ bind/named/ns_main.c	Mon Nov 11 22:37:42 1996
+@@ -111,6 +111,10 @@
+ #include "named.h"
+ #undef MAIN_PROGRAM
+ 
++#if defined(ATM)
++#include "atm_itf.h"
++#endif /* defined(ATM) */
++
+ #undef nsaddr
+ 
+ 				/* UDP receive, TCP send buffer size */
+@@ -402,6 +406,40 @@
+ 		exit(1);
+ 	}
+ 
++#if defined(ATM)
++#if defined(linux)
++       /* ATM socket creation */
++       for(n=0;;n++) {
++         if ((atm_vs=open_atm_stream())<0) {
++           syslog(LOG_ERR, "ATM socket failure\n");
++           if (errno != EADDRINUSE || errno != ENOENT || n > 1) {
++             if (errno == EADDRINUSE) {
++               syslog(LOG_NOTICE,
++                      "There may be an ATM name server already running\n");
++             } else if (errno == ENOENT) {
++               syslog(LOG_NOTICE,
++                      "ATM signalling demon might not be running\n");
++             }
++             syslog(LOG_ERR, "exiting");
++           }
++#if defined(WANT_PIDFILE) && defined(PID_FIX)
++           /* put old pid back */
++           if (atoi(oldpid) && (fp = fopen(PidFile, "w"))) {
++             fprintf(fp, "%s", oldpid);
++             (void) my_fclose(fp);
++             _exit(1);
++           }
++#endif /*WANT_PIDFILE && PID_FIX */
++           exit(1);
++         } else
++           break;
++         /* Retry opening the socket a few times */
++         close_atm_stream(atm_vs);
++         sleep(3);
++       }
++#endif /* defined (linux) */
++#endif /* defined (ATM) */
++
+   	/*
+ 	 * named would be terminated if one of these is sent and no handler.
+ 	 */
+@@ -421,6 +459,11 @@
+ 	 */
+ 	FD_ZERO(&mask);
+ 	FD_SET(vs, &mask);
++#if defined(ATM)
++#if defined(linux)
++       FD_SET(atm_vs, &mask);
++#endif /* defined(linux) */
++#endif /* defined(ATM) */
+ 	getnetconf();
+ 
+ 	/*
+@@ -782,6 +825,11 @@
+ 			gettime(&tt);
+ 			sp->s_time = tt.tv_sec;	/* last transaction time */
+ 			sp->s_from = from_addr;	/* address to respond to */
++#if defined(ATM)
++#if defined(linux)
++                       memset(&sp->s_atmfrom, 0, sizeof(sp->s_atmfrom));
++#endif /* defined(linux) */
++#endif /* defined(ATM) */
+ 			sp->s_bufp = (u_char *)&sp->s_tempsize;
+ 			FD_SET(rfd, &mask);
+ 			FD_SET(rfd, &tmpmask);
+@@ -792,6 +840,83 @@
+ 				       sin_ntoa(&sp->s_from), rfd);
+ #endif
+ 		}
++#if defined(ATM)
++#if defined(linux)
++		/*
++		** Process ATM stream connection.
++		**
++		** Note that a "continue" in here takes us back to the select()
++		** which, if our accept() failed, will bring us back here.
++		*/
++		if (FD_ISSET(atm_vs, &tmpmask)) {
++			
++			int from_len = sizeof(from_atmaddr);
++			rfd = accept(atm_vs,
++				     (struct sockaddr *)&from_atmaddr,
++				     &from_len);
++			if (rfd < 0 && errno == EINTR)
++				continue;
++			if (rfd < 0 && errno == EMFILE && streamq) {
++				maxctime = 0;
++				candidate = NULL;
++				for (sp = streamq; sp; sp = nextsp) {
++					nextsp = sp->s_next;
++					if (sp->s_refcnt)
++						continue;
++					gettime(&tt);
++					lasttime = tt.tv_sec - sp->s_time;
++					if (lasttime >= VQEXPIRY)
++						sqrm(sp);
++					else if (lasttime > maxctime) {
++						candidate = sp;
++						maxctime = lasttime;
++					}
++				}
++				if (candidate)
++					sqrm(candidate);
++				continue;
++			}
++			if (rfd < 0 && (errno == ENOENT || errno == EUNATCH)) {
++				syslog(LOG_INFO, "ATM signalling died!\n");
++				(void)my_close(atm_vs);
++				FD_CLR(atm_vs, &mask);
++				continue;
++			}
++			if (rfd < 0) {
++				syslog(LOG_INFO, "accept: %m");
++				continue;
++			}
++			if (getpeername(rfd, 
++					(struct sockaddr*)&from_atmaddr, 
++					&from_len) != 0) {
++				syslog(LOG_INFO,
++				  "getpeername(rfd, &from_atmaddr, &from):%m");
++				(void) my_close(rfd);
++				continue;
++			}
++			if ((sp = sqadd()) == QSTREAM_NULL) {
++				(void) my_close(rfd);
++				continue;
++			}
++			sp->s_rfd = rfd;        /* stream file descriptor */
++			sp->s_size = -1;        /* amount of data to receive */
++			gettime(&tt);
++			sp->s_time = tt.tv_sec; /* last transaction time */
++			
++			memset(&sp->s_from,0,sizeof(sp->s_from));
++			memcpy(&sp->s_atmfrom, &from_atmaddr,
++			       sizeof(from_atmaddr));
++			/* address to respond to */
++			sp->s_bufp = (u_char *)&sp->s_tempsize;
++			FD_SET(rfd, &mask);
++			FD_SET(rfd, &tmpmask);
++			dprintf(1, (ddt,
++				    "\nATM connection from [%s] (fd %d)\n",
++				    "ATMADDRESS", rfd));
++			
++		}
++#endif /* defined(linux) */
++#endif /* defined(ATM) */
+ 		if (streamq)
+ 			dprintf(3, (ddt, "streamq = 0x%lx\n",
+ 				    (u_long)streamq));
+@@ -799,6 +924,29 @@
+ 			nextsp = sp->s_next;
+ 			if (!FD_ISSET(sp->s_rfd, &tmpmask))
+ 				continue;
++#if defined(ATM)
++#if defined(linux)
++			/*
++			 * ATM streams process packets as datagrams,
++			 * so read()'s have to be done accordingly.
++			 */
++			if (is_qstream_atm(sp)) {
++				n = read(sp->s_rfd, (char*)buf,
++					 MIN(PACKETSZ, sizeof(buf)));
++				if ((n <0) && (errno == EAGAIN)) {
++					sq_query(sp);
++					errno = 0;
++					continue;
++				}
++				if (n <=0) {
++					sqrm(sp);
++					continue;
++				}
++				sq_query(sp);
++				ns_req(buf, n, PACKETSZ, sp, NULL, -1);
++			} else {
++#endif /* defined(linux) */
++#endif /* defined(ATM) */
+ 			dprintf(5, (ddt,
+ 				  "sp x%lx rfd %d size %d time %d next x%lx\n",
+ 				    (u_long)sp, sp->s_rfd, sp->s_size,
+@@ -932,6 +1080,11 @@
+ 				}
+ 				continue;
+ 			}
++#if defined(ATM)
++#if defined(linux)
++                       }
++#endif /* defined(linux) */
++#endif /* defined(ATM) */
+ 		}
+ 	}
+ 	/* NOTREACHED */
+diff -urN bindtmp/named/ns_req.c bind/named/ns_req.c
+--- bindtmp/named/ns_req.c	Tue Oct  8 07:51:05 1996
++++ bind/named/ns_req.c	Mon Nov 11 22:43:30 1996
+@@ -96,6 +96,13 @@
+ 
+ #include "named.h"
+ 
++#if defined(ATM)
++#if defined(linux)
++#include "atm_itf.h"
++#endif /* defined(linux) */
++#endif /* defined(ATM) */
++
++
+ struct addinfo {
+ 	char		*a_dname;		/* domain name */
+ 	char		*a_rname;		/* referred by */
+@@ -243,12 +250,17 @@
+ 
+ #ifdef DEBUG
+ #ifdef SORT_RESPONSE
++#if defined(linux) && defined(ATM)
++	sortmsgtxt = "   ";
++#else
+ 	sortmsgtxt = local(from) == NULL ? "Remote" : "Local";
++#endif /* defined(linux) && defined(ATM) */
+ #else /*SORT*/
+ 	sortmsgtxt = "(not sorting)";
+ #endif /*SORT*/
+ 	dprintf(1, (ddt, "ns_req: answer -> %s fd=%d id=%d size=%d %s\n",
+-		    sin_ntoa(from), (qsp == QSTREAM_NULL) ? dfd : qsp->s_rfd,
++		    from?sin_ntoa(from):"(null)", 
++		    (qsp == QSTREAM_NULL) ? dfd : qsp->s_rfd,
+ 		    ntohs(hp->id), cp - msg, sortmsgtxt));
+ 	if (debug >= 10)
+ 		fp_nquery(msg, cp - msg, ddt);
+@@ -272,6 +284,13 @@
+ 			nameserIncr(from->sin_addr, nssSentNaAns);
+ #endif
+ 	} else {
++#if defined(ATM)
++#if defined(linux)
++	  if (is_qstream_atm(qsp))
++	    write(qsp->s_rfd, msg, cp-msg);
++	  else
++#endif /* defined(linux) */
++#endif /* defined(ATM) */
+ 		(void) writemsg(qsp->s_rfd, msg, cp - msg);
+ 		sq_done(qsp);
+ 	}
+@@ -507,10 +526,14 @@
+ 	 */
+ 	if (type == T_AXFR) {
+ 		/* refuse request if not a TCP connection */
++#if defined(ATM) && defined(linux)
++         if (qsp == QSTREAM_NULL || is_qstream_atm(qsp)) {
++#else
+ 		if (qsp == QSTREAM_NULL) {
++#endif
+ 			syslog(LOG_INFO,
+-			       "rejected UDP AXFR from %s for \"%s\"",
+-			       sin_ntoa(from), *dnbuf ? dnbuf : ".");
++			       "rejected UDP/ATM AXFR from %s for \"%s\"",
++			       from?sin_ntoa(from):"ATM",*dnbuf ? dnbuf : ".");
+ 			return (Refuse);
+ 		}
+ 		/* the position of this is subtle. */
+@@ -716,7 +739,7 @@
+ 		    foundname, count, founddata, cname));
+ 
+ #ifdef SORT_RESPONSE
+-	if ((lp = local(from)) != NULL) 
++	if (from && (lp = local(from)) != NULL) 
+ 		sort_response(answers, count, lp, *cpp);
+ #endif
+ #ifdef BIND_NOTIFY
+diff -urN bindtmp/named/ns_resp.c bind/named/ns_resp.c
+--- bindtmp/named/ns_resp.c	Mon Nov 11 08:36:51 1996
++++ bind/named/ns_resp.c	Mon Nov 11 22:46:48 1996
+@@ -1329,6 +1329,9 @@
+ 	case T_TXT:
+ 	case T_X25:
+ 	case T_ISDN:
++#if defined(ATM)
++       case T_ATMA:
++#endif
+ 	case T_NSAP:
+ 	case T_AAAA:
+ 	case T_LOC:
+@@ -1773,6 +1776,11 @@
+ 			return (1);
+ 		}
+ 	} else {
++#if defined(ATM) && defined(linux)
++	  if (is_qstream_atm(qp->q_stream))
++	    (void) write(qp->q_stream->s_rfd, (u_char*)msg, msglen);
++	  else
++#endif /* defined(ATM) && defined(linux) */
+ 		(void) writemsg(qp->q_stream->s_rfd, (u_char*)msg, msglen);
+ 		sq_done(qp->q_stream);
+ 	}
+diff -urN bindtmp/res/Makefile bind/res/Makefile
+--- bindtmp/res/Makefile	Fri Aug  9 01:49:48 1996
++++ bind/res/Makefile	Mon Nov 11 22:47:54 1996
+@@ -73,13 +73,13 @@
+ 
+ CFLAGS=	${CDEBUG} -I${INCL} -I${COMPINCL} ${DEFS} ${LOCDEFS}
+ 
+-SRCS=	base64.c herror.c res_debug.c res_data.c \
++SRCS=	base64.c herror.c res_debug.c res_data.c atm_init.c \
+ 	res_comp.c res_init.c res_mkquery.c res_query.c res_send.c \
+ 	getnetbyaddr.c getnetbyname.c getnetent.c getnetnamadr.c \
+ 	gethnamaddr.c sethostent.c nsap_addr.c hostnamelen.c inet_addr.c \
+ 	inet_ntop.c inet_neta.c inet_pton.c inet_net_ntop.c inet_net_pton.c
+ 
+-OBJS=	base64.o herror.o res_debug.o res_data.o \
++OBJS=	base64.o herror.o res_debug.o res_data.o atm_init.o \
+ 	res_comp.o res_init.o res_mkquery.o res_query.o res_send.o \
+ 	getnetbyaddr.o getnetbyname.o getnetent.o getnetnamadr.o \
+ 	gethnamaddr.o sethostent.o nsap_addr.o hostnamelen.o inet_addr.o \
+diff -urN bindtmp/res/atm_init.c bind/res/atm_init.c
+--- bindtmp/res/atm_init.c	Thu Jan  1 02:00:00 1970
++++ bind/res/atm_init.c	Mon Nov 11 22:47:40 1996
+@@ -0,0 +1,205 @@
++/*
++ * Marko Kiiskila carnil@cs.tut.fi 
++ * 
++ * Copyright (c) 1996
++ * Tampere University of Technology - Telecommunications Laboratory
++ * All rights reserved.
++ *
++ * Permission to use, copy, modify and distribute this
++ * software and its documentation is hereby granted,
++ * provided that both the copyright notice and this
++ * permission notice appear in all copies of the software,
++ * derivative works or modified versions, and any portions
++ * thereof, that both notices appear in supporting
++ * documentation, and that the use of this software is
++ * acknowledged in any publications resulting from using
++ * the software.
++ * 
++ * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
++ * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
++ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
++ * SOFTWARE.
++ * -
++ * Portions Copyright (c) 1985, 1989, 1993
++ *    The Regents of the University of California.  All rights reserved.
++ * 
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *      This product includes software developed by the University of
++ *      California, Berkeley and its contributors.
++ * 4. Neither the name of the University nor the names of its contributors
++ *    may be used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ * 
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ * -
++ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
++ * 
++ * Permission to use, copy, modify, and distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies, and that
++ * the name of Digital Equipment Corporation not be used in advertising or
++ * publicity pertaining to distribution of the document or software without
++ * specific, written prior permission.
++ * 
++ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
++ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
++ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
++ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
++ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
++ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
++ * SOFTWARE.
++ * -
++ * --Copyright--
++ */
++
++/*
++ * 
++ * Resolver initialization
++ *
++ * $Id$
++ *
++ */
++#if defined(ATM) && defined(linux)
++#include <sys/time.h>
++#include <unistd.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <atm.h>
++#include <netinet/in.h>
++
++#include <atmresolv.h>
++
++#define MATCH(line, name) \
++(!strncmp(line, name, sizeof(name) - 1) && \
++ (line[sizeof(name) - 1] == ' ' || \
++  line[sizeof(name) - 1] == '\t'))
++
++/*
++ * Resolver state default settings.
++ */
++
++struct __atmres_state _atmres;
++int _queryatm = 0;
++
++static unsigned short
++atmres_randomid(void)
++{
++        struct timeval now;
++
++        gettimeofday(&now, NULL);
++        return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
++}
++
++/*
++ * Set up default settings.  If the configuration file exist, the values
++ * there will have precedence. Otherwise, the server address is set to
++ * WKS. Here should also be request for ILMI to find out ANS server address.
++ *
++ * Return 0 if completes successfully, -1 on error
++ */
++int
++atmres_init(void)
++{
++  FILE *fp;
++  register char *cp, **pp;
++  register int n;
++  char buf[BUFSIZ];
++  int nserv = 0;    /* number of nameserver records read from file */
++  int haveenv = 0;
++  int havesearch = 0;
++  unsigned char appl_id[] = { 0x00, 0xa0, 0x3e, 0x00, 0x00, 0x00, 0x01 };
++  struct sockaddr_atmsvc tmp;
++
++  memset(&_atmres.nsaddr, 0, sizeof(struct sockaddr_atmsvc));
++  _atmres.nsaddr.sas_family = AF_ATMSVC;
++  _atmres.nsaddr.sas_addr.bhli.hl_type = ATM_HL_VENDOR;
++  memcpy(_atmres.nsaddr.sas_addr.bhli.hl_info, appl_id, 7);
++  _atmres.nscount = 1;
++
++  /* ANS WKS addr */
++  _atmres.nsaddr.sas_addr.prv[0] = 0x02;
++  _atmres.nsaddr.sas_addr.prv[1] = 0xc5;
++  _atmres.nsaddr.sas_addr.prv[2] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[3] = 0x79;
++  _atmres.nsaddr.sas_addr.prv[4] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[5] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[6] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[7] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[8] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[9] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[10] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[11] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[12] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[13] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[14] = 0xa0;
++  _atmres.nsaddr.sas_addr.prv[15] = 0x3e;
++  _atmres.nsaddr.sas_addr.prv[16] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[17] = 0x00;
++  _atmres.nsaddr.sas_addr.prv[18] = 0x02;
++  _atmres.nsaddr.sas_addr.prv[19] = 0x00;
++
++    
++  if ((fp = fopen(_PATH_ATMRESCONF, "r")) != NULL) {
++    /* read the config file */
++    while (fgets(buf, sizeof(buf), fp) != NULL) {
++      /* skip comments */
++      if (*buf == ';' || *buf == '#')
++	continue;
++      /* read nameservers to query */
++      if (MATCH(buf, "ans") && nserv < MAXNS) {
++	cp = buf + sizeof("ans") - 1;
++	while (*cp == ' ' || *cp == '\t')
++	  cp++;
++	
++	while (buf[strlen(buf)-1] == '\n' ||
++	       buf[strlen(buf)-1] == ' ' ||
++	       buf[strlen(buf)-1] == '\t')
++	  buf[strlen(buf)-1] = '\0';
++	memset(&tmp, 0, sizeof(struct sockaddr_atmsvc));
++	if (text2atm(cp, (struct sockaddr*)&tmp, 
++		     sizeof(struct sockaddr_atmsvc), T2A_SVC) < 0)
++	  continue;
++	else {
++	  _atmres.nsaddr_list[nserv] = tmp;
++	  _atmres.nsaddr_list[nserv].sas_family = AF_ATMSVC;
++	  _atmres.nsaddr_list[nserv].sas_addr.bhli.hl_type = ATM_HL_VENDOR;
++	  memcpy(_atmres.nsaddr_list[nserv].sas_addr.bhli.hl_info, appl_id, 7);
++	  nserv++;
++	}
++	continue;
++      }
++    }
++    if (nserv > 1)
++      _atmres.nscount = nserv;
++    fclose(fp);
++  }    
++  return 0;
++}
++#endif
++
++/*
++ *
++ * $Log$
++ * 
++ */
+diff -urN bindtmp/res/gethnamaddr.c bind/res/gethnamaddr.c
+--- bindtmp/res/gethnamaddr.c	Sat Sep 28 09:51:07 1996
++++ bind/res/gethnamaddr.c	Mon Nov 11 23:15:42 1996
+@@ -89,6 +89,10 @@
+ # include <../conf/options.h>
+ #endif
+ 
++#if defined(ATM)
++#include <atmresolv.h>
++#endif
++
+ #ifdef SPRINTF_CHAR
+ # define SPRINTF(x) strlen(sprintf/**/x)
+ #else
+@@ -175,6 +179,9 @@
+ 	host.h_name = NULL;
+ 	eom = answer->buf + anslen;
+ 	switch (qtype) {
++#if defined(ATM)
++       case T_ATMA:
++#endif
+ 	case T_A:
+ 	case T_AAAA:
+ 		name_ok = res_hnok;
+@@ -204,7 +211,11 @@
+ 		return (NULL);
+ 	}
+ 	cp += n + QFIXEDSZ;
++#if defined(ATM)
++	if (qtype == T_A || qtype == T_AAAA || qtype == T_ATMA) {
++#else
+ 	if (qtype == T_A || qtype == T_AAAA) {
++#endif /* defined(ATM) */
+ 		/* res_send() has already verified that the query name is the
+ 		 * same as the one we sent; this just gets the expanded name
+ 		 * (i.e., with the succeeding search-domain tacked on).
+@@ -333,6 +344,56 @@
+ 			h_errno = NETDB_SUCCESS;
+ 			return (&host);
+ #endif
++#if defined(ATM)
++		case T_ATMA:
++		  if (strcasecmp(host.h_name, bp) != 0) {
++		    syslog(LOG_NOTICE|LOG_AUTH,
++			   AskedForGot, host.h_name, bp);
++		    cp += n;
++		    continue;
++		  }
++		  if ((host.h_length == ATM_ESA_LEN &&
++		       (n != ATM_ESA_LEN+1 ||
++			*cp != ATMA_AESA)) ||
++		      (host.h_length  == ATM_E164_LEN &&
++		       (n != ATM_E164_LEN +1 ||
++			*cp != ATMA_E164))) {
++		    cp += n;
++		    h_errno = NO_DATA;
++		    if (ancount==0 && !haveanswer)
++		      return (NULL);
++		    continue;
++		  }
++		  if (haveanswer) {
++		    if (n != host.h_length +1) {
++		      cp += n;
++		      continue;
++		    }
++		  } else {
++		    register int nn;
++		    
++		    host.h_name = bp;
++		    nn = strlen(bp) +1;
++		    bp += nn;
++		    buflen -= nn;
++		  }
++		  if (bp + n > &hostbuf[sizeof hostbuf]) {
++		    dprintf("size (%d) too big\n", n);
++		    had_error++;
++		    continue;
++		  }
++		  if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
++		    if (!toobig++)
++		      dprintf("Too many addresses (%d)\n",
++			      MAXADDRS);
++		    cp += n;
++		    continue;
++		  }
++		  bcopy(cp+1, *hap++ = bp, n-1);
++		  bp += n;
++		  cp += n;
++		  break;
++#endif /* defined(ATM) */
+ 		case T_A:
+ 		case T_AAAA:
+ 			if (strcasecmp(host.h_name, bp) != 0) {
+@@ -410,6 +471,42 @@
+ 	return (NULL);
+ }
+ 
++#if defined(ATM)
++struct hostent *
++gethostbyname_e164(const char *name)
++{
++  struct hostent *hp;
++#if defined(linux)
++  int old_queryatm;
++  
++  old_queryatm = _queryatm;
++  _queryatm =1;
++#endif /* defined (linux) */
++  hp =gethostbyname2(name, AF_ATME164);
++#if defined(linux)
++  _queryatm = old_queryatm;
++#endif /* defined(linux) */
++  return hp;
++}
++
++struct hostent *
++gethostbyname_atmnsap(const char *name)
++{
++  struct hostent *hp;
++#if defined(linux)
++  int old_queryatm;
++  
++  old_queryatm = _queryatm;
++  _queryatm =1;
++#endif /* defined(linux) */
++  hp = gethostbyname2(name, AF_ATMNSAP);
++#if defined(linux)
++  _queryatm = old_queryatm;
++#endif /* defined(linux) */
++  return hp;
++}
++#endif /* defined(ATM) */
++
+ struct hostent *
+ gethostbyname(name)
+ 	const char *name;
+@@ -445,6 +542,16 @@
+ 	}
+ 
+ 	switch (af) {
++#if defined(ATM)
++	case AF_ATMNSAP:
++	  size = ATM_ESA_LEN;
++	  type = T_ATMA;
++	  break;
++	case AF_ATME164:
++	  size = ATM_E164_LEN;
++	  type = T_ATMA;
++	  break;
++#endif /* defined(ATM) */
+ 	case AF_INET:
+ 		size = INADDRSZ;
+ 		type = T_A;
+@@ -565,6 +672,12 @@
+ 	char hname2[MAXDNAME+1];
+ #endif /*SUNSECURITY*/
+ 	extern struct hostent *_gethtbyaddr();
++
++#if defined(ATM) && defined(linux)
++       int old_queryatm;
++ 
++       old_queryatm = _queryatm;
++#endif /*defined(ATM) && defined(linux)*/
+ 	
+ 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ 		h_errno = NETDB_INTERNAL;
+@@ -586,6 +699,20 @@
+ 	case AF_INET6:
+ 		size = IN6ADDRSZ;
+ 		break;
++#if defined(ATM)
++	case AF_ATMNSAP:
++	  size = ATM_ESA_LEN;
++#if defined(linux)
++	  _queryatm = 1;
++#endif /* defined(linux) */
++	  break;
++	case AF_ATME164:
++	  size = ATM_E164_LEN;
++#if defined(linux)
++	  _queryatm = 1;
++#endif /*defined(linux) */
++	  break;
++#endif /* defined(ATM) */
+ 	default:
+ 		errno = EAFNOSUPPORT;
+ 		h_errno = NETDB_INTERNAL;
+@@ -613,10 +740,50 @@
+ 		}
+ 		strcpy(qp, "ip6.int");
+ 		break;
++#if defined(ATM)
++        case AF_ATMNSAP:
++          qp =qbuf;
++          qp += SPRINTF((qbuf,"%2.2x.%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", 
++                         uaddr[19] & 0xff, uaddr[13] & 0xff,
++                         uaddr[14] & 0xff, uaddr[15] & 0xff,
++                         uaddr[16] & 0xff, uaddr[17] & 0xff,
++                         uaddr[18] & 0xff));
++          if (uaddr[0] == ATM_AFI_DCC || uaddr[0] == ATM_AFI_ICD) {
++            for (n = 12; n > 2; n--)
++              qp += SPRINTF((qp, ".%x.%x", uaddr[n] & 0xf,
++                             (uaddr[n] >> 4) & 0xf));
++            qp += SPRINTF((qp,".%2.2x%2.2x.%2.2x.AESA.ATMA.INT",
++                           uaddr[1] & 0xff, uaddr[2] & 0xff,
++                           uaddr[0] & 0xff));
++          } else if (uaddr[0] == ATM_AFI_E164) {
++            for (n = 12; n > 8; n--)
++              qp += SPRINTF((qp, ".%x.%x", uaddr[n] & 0xf,
++                             (uaddr[n] >> 4) & 0xf));
++            qp += SPRINTF((qp, "."));
++            for (n = 1; n < 9; n++)
++              qp += SPRINTF((qp, "%2.2x", uaddr[n] & 0xff));
++            qp += SPRINTF((qp, "%2.2x.AESA.ATMA.INT", uaddr[0] & 0xff));
++          } else {
++            errno = EAFNOSUPPORT;
++            h_errno = NETDB_INTERNAL;
++            return (NULL);
++          }
++          break;
++        case AF_ATME164:
++          qp =qbuf;
++          for (n=11;n > 2;n--)
++            qp += SPRINTF((qp, "%c.",uaddr[n] & 0xff));
++          qp += SPRINTF((qp,"%c%c%c.E164.ATMA.INT",uaddr[0],uaddr[1],
++                         uaddr[2]));
++          break;
++#endif
+ 	default:
+ 		abort();
+ 	}
+ 	n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
++#if defined(ATM) && defined(linux)
++        _queryatm = old_queryatm;
++#endif
+ 	if (n < 0) {
+ 		dprintf("res_query failed (%d)\n", n);
+ 		if (errno == ECONNREFUSED)
+diff -urN bindtmp/res/res_debug.c bind/res/res_debug.c
+--- bindtmp/res/res_debug.c	Mon Nov 11 08:36:52 1996
++++ bind/res/res_debug.c	Mon Nov 11 22:57:12 1996
+@@ -659,7 +659,9 @@
+ 				putc(' ', file);
+ 		}
+ 		break;
+-
++#if defined(ATM)
++       case T_ATMA:
++#endif
+ 	case T_NSAP:
+ 		(void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
+ 		cp += dlen;
+@@ -922,7 +924,7 @@
+ 	{T_EID,		"EID",		"endpoint identifier (unimplemented)"},
+ 	{T_NIMLOC,	"NIMLOC",	"NIMROD locator (unimplemented)"},
+ 	{T_SRV,		"SRV",		"server selection"},
+-	{T_ATMA,	"ATMA",		"ATM address (unimplemented)"},
++	{T_ATMA,	"ATMA",		"ATM address"},
+ 	{T_IXFR,	"IXFR",		"incremental zone transfer"},
+ 	{T_AXFR,	"AXFR",		"zone transfer"},
+ 	{T_MAILB,	"MAILB",	"mailbox-related data (deprecated)"},
+diff -urN bindtmp/res/res_query.c bind/res/res_query.c
+--- bindtmp/res/res_query.c	Sun Sep 22 03:13:31 1996
++++ bind/res/res_query.c	Mon Nov 11 22:58:17 1996
+@@ -80,6 +80,10 @@
+ # include <../conf/options.h>
+ #endif
+ 
++#if defined(ATM) && defined(linux)
++#include <atmresolv.h>
++#endif
++
+ #if PACKETSZ > 1024
+ #define MAXPACKET	PACKETSZ
+ #else
+@@ -131,6 +135,11 @@
+ 		h_errno = NO_RECOVERY;
+ 		return (n);
+ 	}
++#if defined(ATM) && defined(linux)
++	if (_queryatm)
++	  n = atm_res_send(buf, n, answer, anslen);
++	else
++#endif /* defined(ATM) && defined(linux) */
+ 	n = res_send(buf, n, answer, anslen);
+ 	if (n < 0) {
+ #ifdef DEBUG
+diff -urN bindtmp/res/res_send.c bind/res/res_send.c
+--- bindtmp/res/res_send.c	Tue Oct  8 07:51:06 1996
++++ bind/res/res_send.c	Mon Nov 11 23:03:29 1996
+@@ -94,6 +94,16 @@
+ # include <../conf/options.h>
+ #endif
+ 
++#if defined(ATM) && defined(linux)
++#include <linux/atmdev.h>
++#include <atmresolv.h>
++
++static int atms = -1;   /* ATM socket used for communications */
++
++void _atmres_close __P((void));
++
++#endif /* defined(ATM) && defined(linux) */
++
+ static int s = -1;	/* socket used for communications */
+ static int connected = 0;	/* is the socket connected */
+ static int vc = 0;	/* is the socket a virtual ciruit? */
+@@ -761,6 +771,257 @@
+ 		errno = terrno;
+ 	return (-1);
+ }
++
++#if defined(ATM) && defined(linux)
++
++static int
++atm_getouraddr(int ss, struct sockaddr_atmsvc *addr)
++{
++  struct atmif_sioc req;
++  
++  req.number = 0;
++  req.arg = addr;
++  req.length = sizeof(struct sockaddr_atmsvc);
++  
++  if (ioctl(ss, ATM_GETADDR, &req) <0) {
++    Perror(stderr, "ioctl ATM_GETADDR failed", errno);      
++    return -1;
++  }
++  return 0;
++}
++
++int
++atm_res_send(const unsigned char *buf, int buflen, 
++            unsigned char *ans, int anssiz)
++{
++  HEADER *anhp = (HEADER *) ans;
++  int try, ns, terrno, gotsomewhere, connreset, resplen, n;
++  unsigned short badns;  /* XXX NSMAX can't exceed #/bits in this var */
++  int truncated;
++  unsigned char *cp;
++  struct sockaddr_atmsvc us;
++  struct atm_qos conqos;
++  
++  if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
++    return -1;
++  }
++  
++  if ((_res.options & RES_ATMINIT) == 0 && atmres_init() == -1) {
++    return -1;
++  }
++  
++  gotsomewhere = 0;
++  connreset = 0;
++  terrno = ETIMEDOUT;
++  badns = 0;
++  
++  
++  /*
++   * Send request, RETRY times, or until successful
++   */
++  
++  for (try = 0; try < _res.retry; try++) {
++    for (ns = 0; ns < _atmres.nscount; ns++) {
++      struct sockaddr_atmsvc *nsap = &_atmres.nsaddr_list[ns];
++      struct timeval timeout;
++      fd_set dsmask;
++    same_ns:
++      if (badns & (1 << ns)) {
++       _atmres_close();
++       goto next_ns;
++      }
++      
++      if (_res.options & RES_DEBUG) {
++       char buffer[50];
++
++       for(n=0;n<ATM_ESA_LEN;n++) {
++         sprintf(&buffer[n*3], "%2.2x ", nsap->sas_addr.prv[n]);
++       }
++       Dprint(_res.options & RES_DEBUG,
++              (stdout, ";; Querying server (# %d) address = %s\n",
++               ns + 1, buffer));
++      }
++      /*
++       * Use virtual circuit;
++       * at most one attempt per server.
++       */
++      try = _res.retry;
++      truncated = 0;
++      if (atms < 0) {
++       atms = socket(PF_ATMSVC, SOCK_DGRAM, ATM_AAL5);
++       if (atms < 0) {
++         terrno = errno;
++         Perror(stderr, "socket", errno);
++         return (-1);
++       }
++       errno = 0;
++       memset(&us, 0, sizeof(us));
++       atm_getouraddr(atms, &us);
++       memset(&conqos, 0, sizeof(conqos));
++       conqos.txtp.traffic_class = conqos.rxtp.traffic_class = ATM_UBR;
++       conqos.txtp.max_sdu = conqos.rxtp.max_sdu = 512;
++       if (setsockopt(atms,SOL_ATM,SO_ATMQOS,&conqos,sizeof(conqos)) < 0) {
++         terrno = errno;
++         Perror(stderr,"setsockopt SO_ATMQOS",errno);
++         _atmres_close();
++         return(-1);
++       }
++
++       if (bind(atms, (struct sockaddr *)&us,
++                sizeof(struct sockaddr_atmsvc))<0) {
++         terrno = errno;
++         Aerror(stderr, "bind", errno, &us);
++         _atmres_close();
++         return(-1);
++       }
++
++       if (connect(atms, (struct sockaddr *)nsap, 
++                   sizeof(struct sockaddr_atmsvc))
++           <0) {
++         terrno = errno;
++         Aerror(stderr, "connect", errno, nsap);
++         badns |= (1 << ns);
++         _atmres_close();
++         goto next_ns;
++       }
++      }
++      
++      /*
++       * Send length & message
++       */
++      if (write(atms, buf, buflen)<0) {
++       terrno = errno;
++       Perror(stderr, "write failed", errno);
++       badns |= (1 << ns);
++       _atmres_close();
++       goto next_ns;
++      }      
++      /*
++       * Wait for reply
++       */
++      timeout.tv_sec = (_res.retrans << try);
++      if (try > 0)
++       timeout.tv_sec /= _atmres.nscount;
++      if ((long) timeout.tv_sec <= 0)
++       timeout.tv_sec = 1;
++      timeout.tv_usec = 0;
++    wait:
++      FD_ZERO(&dsmask);
++      FD_SET(atms, &dsmask);
++      n = select(atms+1, &dsmask, (fd_set *)NULL,
++                (fd_set *)NULL, &timeout);
++      if (n < 0) {
++       Perror(stderr, "select", errno);
++       _atmres_close();
++       goto next_ns;
++      }
++      if (n == 0) {
++       /*
++        * timeout
++        */
++       Dprint(_res.options & RES_DEBUG,
++              (stdout, ";; timeout\n"));
++       gotsomewhere = 1;
++       _atmres_close();
++       goto next_ns;
++      }
++      errno = 0;
++      
++      cp = ans;
++      resplen = read(atms, (char *)cp, (int)anssiz);
++      if (resplen <= 0) {
++       terrno = errno;
++       Perror(stderr, "read failed", errno);
++       _atmres_close();
++       /*
++        * A long running process might get its ATM
++        * connection reset if the network sent one.
++        * Requery the server instead of
++        * trying a new one.  When there is only one
++        * server, this means that a query might work
++        * instead of failing.  We only allow one reset
++        * per query to prevent looping.
++        */
++       if (terrno == ECONNRESET && !connreset) {
++         connreset = 1;
++         _atmres_close();
++         goto same_ns;
++       }
++       _atmres_close();
++       goto next_ns;
++      }
++      gotsomewhere = 1;
++      
++      if (!res_queriesmatch(buf, buf + buflen,
++                           ans, ans + anssiz)) {
++       /*
++        * response contains wrong query? ignore it.
++        * XXX - potential security hazard could
++        *       be detected here.
++        */
++       DprintQ((_res.options & RES_DEBUG) ||
++               (_res.pfcode & RES_PRF_REPLY),
++               (stdout, ";; wrong query name:\n"),
++               ans, resplen);
++       goto wait;
++      }
++      if (anhp->rcode == SERVFAIL ||
++         anhp->rcode == NOTIMP ||
++         anhp->rcode == REFUSED) {
++       DprintQ(_res.options & RES_DEBUG,
++               (stdout, "server rejected query:\n"),
++               ans, resplen);
++       badns |= (1 << ns);
++       _atmres_close();
++       /* don't retry if called from dig */
++       if (!_res.pfcode)
++         goto next_ns;
++      }
++      Dprint((_res.options & RES_DEBUG) ||
++            ((_res.pfcode & RES_PRF_REPLY) &&
++             (_res.pfcode & RES_PRF_HEAD1)),
++            (stdout, ";; got answer:\n"));
++      DprintQ((_res.options & RES_DEBUG) ||
++             (_res.pfcode & RES_PRF_REPLY),
++             (stdout, " "),
++             ans, resplen);
++      /*
++       * If using virtual circuits, we assume that the first server
++       * is preferred over the rest (i.e. it is on the local
++       * machine) and only keep that one open.
++       * If we have temporarily opened a virtual circuit,
++       * or if we haven't been asked to keep a socket open,
++       * close the socket.
++       */
++      if ((ns != 0) || !(_res.options & RES_STAYOPEN)) {
++       _atmres_close();
++      }
++      return (resplen);
++    next_ns: ;
++    } /*foreach ns*/
++  } /*foreach retry*/
++  _atmres_close();
++  errno = terrno;
++  return (-1);
++}
++
++/*
++ * This routine is for closing the socket if a virtual circuit is used and
++ * the program wants to close it.  This provides support for endhostent()
++ * which expects to close the socket.
++ *
++ * This routine is not expected to be user visible.
++ */
++void
++_atmres_close()
++{
++  if (atms >= 0) {
++    (void) close(atms);
++    atms = -1;
++  }
++}
++
++#endif /* defined(ATM) && defined(linux) */
+ 
+ /*
+  * This routine is for closing the socket if a virtual circuit is used and
+diff -urN bindtmp/res/sethostent.c bind/res/sethostent.c
+--- bindtmp/res/sethostent.c	Sat Sep 28 09:51:07 1996
++++ bind/res/sethostent.c	Mon Nov 11 23:03:57 1996
+@@ -58,4 +58,7 @@
+ {
+ 	_res.options &= ~(RES_STAYOPEN | RES_USEVC);
+ 	res_close();
++#if defined(ATM) && defined(linux)
++       _atmres_close();
++#endif
+ }
+diff -urN bindtmp/shres/linux/Makefile bind/shres/linux/Makefile
+--- bindtmp/shres/linux/Makefile	Sat Sep 28 09:32:58 1996
++++ bind/shres/linux/Makefile	Mon Nov 11 23:05:02 1996
+@@ -3,13 +3,13 @@
+ CFLAGS=	${CDEBUG} -I../${INCL} -I../${COMPINCL} ${DEFS} ${LOCDEFS}
+ # What is USE_OPTIONS_H for? -u@q.net
+ LOCDEFS= -DUSE_OPTIONS_H
+-SRCS=	base64.c herror.c res_debug.c res_data.c \
++SRCS=	base64.c herror.c res_debug.c res_data.c atm_init.c \
+ 	res_comp.c res_init.c res_mkquery.c res_query.c res_send.c \
+ 	getnetbyaddr.c getnetbyname.c getnetent.c getnetnamadr.c \
+ 	gethnamaddr.c sethostent.c nsap_addr.c inet_ntop.c inet_pton.c \
+ 	inet_addr.c strerror.c
+ 
+-OBJS=	base64.o herror.o res_debug.o res_data.o \
++OBJS=	base64.o herror.o res_debug.o res_data.o atm_init.o \
+ 	res_comp.o res_init.o res_mkquery.o res_query.o res_send.o \
+ 	getnetbyaddr.o getnetbyname.o getnetent.o getnetnamadr.o \
+ 	gethnamaddr.o sethostent.o nsap_addr.o inet_ntop.o inet_pton.o \
+@@ -42,6 +42,7 @@
+ libresolv.so: ${OBJS}
+ 	$(SHLD) -o $@ $(OBJS)
+ 
++atm_init.o: ../../res/atm_init.c
+ base64.o: ../../res/base64.c
+ herror.o: ../../res/herror.c
+ res_comp.o: ../../res/res_comp.c
+diff -urN bindtmp/tools/host.c bind/tools/host.c
+--- bindtmp/tools/host.c	Tue Oct  8 07:51:08 1996
++++ bind/tools/host.c	Mon Nov 11 23:08:02 1996
+@@ -401,6 +401,11 @@
+ 			case T_UNSPEC:
+ 				fprintf(stderr,"any Unspecified Format data.\n");
+ 				break;
++#if defined(ATM)
++		        case T_ATMA:
++				fprintf(stderr, "an ATM address\n");
++				break;
++#endif
+ 			default:
+ 				fprintf(stderr,"the information you requested.\n");
+ 				break;
+@@ -906,7 +911,20 @@
+ 			cp += INT32SZ;
+ 		}
+ 		break;
+-
++#if defined(ATM)
++	case T_ATMA:
++		if (doprint) {
++			int i;
++			if (*cp == ATMA_AESA)
++				fprintf(file, " NSAP ");
++			else if (*cp == ATMA_E164)
++				fprintf(file, " E164 ");
++			for (i=1;i<dlen;i++)
++				fprintf(file, "%2.2x", cp[i]);
++		}
++		cp += dlen;
++		break;
++#endif /* defined(ATM) */
+ 	case T_WKS:
+ 		if (dlen < INT32SZ + 1)
+ 			break;
+diff -urN bindtmp/tools/nslookup/debug.c bind/tools/nslookup/debug.c
+--- bindtmp/tools/nslookup/debug.c	Tue Oct  8 07:51:08 1996
++++ bind/tools/nslookup/debug.c	Mon Nov 11 23:09:13 1996
+@@ -551,6 +551,19 @@
+ 		cp += dlen;
+   		break;
+ 
++#if defined(ATM)
++	case T_ATMA: {
++		int i;
++		
++		fprintf(file, "\tatm = %s",*cp==ATMA_E164?"E164":"NSAP");
++		for(i=1;i<dlen;i++)
++			fprintf(file, " %2.2x", cp[i]&0xff);
++		fprintf(file,"\n");
++		cp+=dlen;
++		break;
++	}
++#endif /* defined(ATM) */
++
+ 	case T_AAAA: {
+ 		char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+ 
+diff -urN bindtmp/tools/nslookup/list.c bind/tools/nslookup/list.c
+--- bindtmp/tools/nslookup/list.c	Tue Oct  8 07:51:08 1996
++++ bind/tools/nslookup/list.c	Mon Nov 11 23:10:38 1996
+@@ -753,6 +753,21 @@
+ 		cp += dlen;
+ 		break;
+ 
++#if defined(ATM)
++	    case T_ATMA: {
++		    int i;
++		    
++		    if (*cp++ == ATMA_E164)          
++			    fprintf(file, " E164");
++		    else
++			    fprintf(file, " NSAP");
++		    for(i=1;i<dlen;i++) 
++			    fprintf(file, " %2.2x", *cp++);
++		    cp++;
++		    break;
++	    }
++#endif
++
+ 	    case T_AAAA: {
+ 		char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+ 
+diff -urN bindtmp/tools/nslookup/nslookup.help bind/tools/nslookup/nslookup.help
+--- bindtmp/tools/nslookup/nslookup.help	Tue Oct  8 07:51:08 1996
++++ bind/tools/nslookup/nslookup.help	Mon Nov 11 23:10:52 1996
+@@ -16,7 +16,7 @@
+     root=NAME	- set root server to NAME
+     retry=X	- set number of retries to X
+     timeout=X	- set initial time-out interval to X seconds
+-    querytype=X	- set query type, e.g., A,ANY,CNAME,HINFO,MX,PX,NS,PTR,SOA,TXT,WKS,SRV,NAPTR
++    querytype=X	- set query type, e.g., A,ANY,CNAME,HINFO,MX,PX,NS,PTR,SOA,TXT,WKS,SRV,NAPTR,ATMA
+     port=X	- set port number to send query on
+     type=X	- synonym for querytype
+     class=X	- set query class to one of IN (Internet), CHAOS, HESIOD or ANY
diff -ur --new-file old/atm/extra/extra.html new/atm/extra/extra.html
--- old/atm/extra/extra.html	Thu Jan  1 01:00:00 1970
+++ new/atm/extra/extra.html	Mon Nov 11 18:42:25 1996
@@ -0,0 +1,26 @@
+<HTML>
+<HEAD>
+<TITLE>Extra packages</TITLE>
+</HEAD>
+<BODY>
+<H1>Extra packages</H1>
+
+The ATM on Linux distribution contains support and/or patches for several
+other packages which are not directly contained in the distribution. Copies
+of those packages are also available from
+<A HREF=ftp://lrcftp.epfl.ch/pub/linux/atm/extra/>
+  <SAMP>ftp://lrcftp.epfl.ch/pub/linux/atm/extra/</SAMP></A>. Please see
+the USAGE file for patch and build instructions.
+<P>
+
+<A HREF=ftp://ftp.debian.org/debian/Debian-1.1.13/source/net/tcpdump_3.0.4-1.tar.gz>
+  <SAMP>tcpdump-3.0.4-1</SAMP> from the Debian 1.1.13 distribution</A>
+<BR>
+<A HREF=ftp://ftp.vix.com/pub/bind/release/4.9.5/bind-4.9.5-REL.tar.gz>
+  BIND version 4.9.5-REL</A>
+<P>
+<HR>
+<P>
+<ADDRESS><A HREF=http://lrcwww.epfl.ch/~almesber/>Werner Almesberger</A>,
+11-NOV-1996</ADDRESS>
+</BODY>
diff -ur --new-file old/atm/extra/hosts2ans.pl new/atm/extra/hosts2ans.pl
--- old/atm/extra/hosts2ans.pl	Thu Jan  1 01:00:00 1970
+++ new/atm/extra/hosts2ans.pl	Wed Nov 13 19:33:06 1996
@@ -0,0 +1,71 @@
+#!/usr/bin/perl
+#
+# Usage:
+#
+# hosts2ans.pl [-r] [ domain [ host [ email ] ] ] </etc/hosts.atm >zonefile
+#
+# Where  domain    is the name of the domain to create, e.g. lrc.epfl.ch (if
+#		   omitted,  hostname -d  is used)
+#	 host	   is the name of the primary DNS server of that domain, e.g.
+#		   lrcpcs.epfl.ch (if omitted,  hostname -f  is used)
+#	 email	   is the e-mail address of the DNS administrator of that
+#		   domain, e.g. root@lrc.epfl.ch (if omitted, root@host is used)
+#	 zonefile  is the name of the output file, e.g. lrc.zone
+#
+# Trailing dots in domain, host, and email are silently removed.
+#
+# With -r, the reverse mapping (PTR) is created. Otherwise, the forward mapping
+# (ATMA) is created.
+#
+# Example: host2ans.pl lrc.epfl.ch </etc/hosts.atm >/etc/named/lrc.zone
+
+if ($ARGV[0] eq "-r") {
+    shift(@ARGV);
+    $rev = 1;
+}
+$master = $tmp = `hostname -f` unless defined($master = $ARGV[1]);
+$master =~ s/\n//;
+$master =~ s/\.$//;
+($domain = $master) =~ s/^[^.]*\.// unless defined($domain = $ARGV[0]);
+$domain =~ s/\.$//;
+$email = "root\@$master" unless defined($email = $ARGV[2]);
+$email =~ s/@/\./;
+$email =~ s/\.$//;
+print "; ".($rev ? "Reverse mapping" : "Authoritative data")." for $domain".
+  "\n\n";
+print "@\t\tIN\tSOA\t$master. $email. (\n";
+@t = localtime(time);
+$t[5] += 1900 if $t[5] < 100; # Perl bug ?
+printf("\t\t\t\t%04d%02d%02d%02d\t; Serial\n",$t[5],$t[4],$t[3],$t[2]);
+print "\t\t\t\t10800\t\t; Refresh (3h)\n";
+print "\t\t\t\t3600\t\t; Retry (1h)\n";
+print "\t\t\t\t3600000\t\t; Expire (1000h)\n";
+print "\t\t\t\t86400 )\t\t; Minimum (24h)\n";
+print "\t\tIN\tNS\t$master.\n";
+print "localhost\tIN\tA\t127.0.0.1\n" unless $rev;
+while (<STDIN>) {
+    chop;
+    s/#.*//;
+    s/\s+$//;
+    s/^\s+//;
+    next if /^$/;
+    ($addr,$host) = split(/\s+/);
+    $addr =~ s/\.//g;
+    $host =~ s/\..*//;
+    $host =~ s/\.$//;
+    if ($rev) {
+	$pfx = substr($addr,0,26);
+	$tail = substr($addr,26,14);
+	if ($pfx ne $origin) {
+	    $origin = $pfx;
+	    $single = substr($pfx,6,20);
+	    print "\$ORIGIN ".join(".",reverse split("",substr($pfx,6,20))).
+	      ".".substr($pfx,2,4).".".substr($pfx,0,2).".AESA.atm.int.\n";
+	}
+	print substr($tail,12,2).".".substr($tail,0,12)."\tIN\tPTR\t$host.".
+	  $domain.".\n";
+    }
+    else {
+	print $host.(length($host) < 8 ? "\t" : "")."\tIN\tATMA\t$addr\n";
+    }
+}
diff -ur --new-file old/atm/extra/tcpdump-3.0.4-1.patch new/atm/extra/tcpdump-3.0.4-1.patch
--- old/atm/extra/tcpdump-3.0.4-1.patch	Thu Jan  1 01:00:00 1970
+++ new/atm/extra/tcpdump-3.0.4-1.patch	Mon Nov 11 19:00:24 1996
@@ -0,0 +1,470 @@
+diff -ur --new-file tcpdump-3.0.4-orig/COPYRIGHT.TUT tcpdump-3.0.4-atm/COPYRIGHT.TUT
+--- tcpdump-3.0.4-orig/COPYRIGHT.TUT	Thu Jan  1 01:00:00 1970
++++ tcpdump-3.0.4-atm/COPYRIGHT.TUT	Mon Nov 11 18:57:43 1996
+@@ -0,0 +1,21 @@
++/*
++ * Marko Kiiskila carnil@cs.tut.fi 
++ * 
++ * Tampere University of Technology - Telecommunications Laboratory
++ *
++ * Permission to use, copy, modify and distribute this
++ * software and its documentation is hereby granted,
++ * provided that both the copyright notice and this
++ * permission notice appear in all copies of the software,
++ * derivative works or modified versions, and any portions
++ * thereof, that both notices appear in supporting
++ * documentation, and that the use of this software is
++ * acknowledged in any publications resulting from using
++ * the software.
++ * 
++ * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
++ * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
++ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
++ * SOFTWARE.
++ * 
++ */
+diff -ur --new-file tcpdump-3.0.4-orig/libpcap-0.0.6/bpf/net/bpf.h tcpdump-3.0.4-atm/libpcap-0.0.6/bpf/net/bpf.h
+--- tcpdump-3.0.4-orig/libpcap-0.0.6/bpf/net/bpf.h	Thu Jun  9 04:04:26 1994
++++ tcpdump-3.0.4-atm/libpcap-0.0.6/bpf/net/bpf.h	Mon Nov 11 18:57:43 1996
+@@ -169,6 +169,8 @@
+ #define DLT_SLIP	8	/* Serial Line IP */
+ #define DLT_PPP		9	/* Point-to-point Protocol */
+ #define DLT_FDDI	10	/* FDDI */
++#define DLT_LANE8023    11      /* LANE 802.3(Ethernet) */
++#define DLT_CIP         12      /* ATM Classical IP */
+ 
+ /*
+  * The instruction encondings.
+diff -ur --new-file tcpdump-3.0.4-orig/libpcap-0.0.6/configure tcpdump-3.0.4-atm/libpcap-0.0.6/configure
+--- tcpdump-3.0.4-orig/libpcap-0.0.6/configure	Fri May  3 19:41:19 1996
++++ tcpdump-3.0.4-atm/libpcap-0.0.6/configure	Mon Nov 11 18:57:18 1996
+@@ -1,4 +1,4 @@
+-#!/bin/csh -f
++#!/bin/csh -fx
+ set bison
+ set ethers
+ set flex
+diff -ur --new-file tcpdump-3.0.4-orig/libpcap-0.0.6/gencode.c tcpdump-3.0.4-atm/libpcap-0.0.6/gencode.c
+--- tcpdump-3.0.4-orig/libpcap-0.0.6/gencode.c	Tue Jun 21 04:07:54 1994
++++ tcpdump-3.0.4-atm/libpcap-0.0.6/gencode.c	Mon Nov 11 18:57:44 1996
+@@ -492,6 +492,16 @@
+ 		return;
+ #endif
+ 
++	case DLT_LANE8023:
++	  off_linktype = 14;
++	  off_nl = 16;
++	  return;
++
++	case DLT_CIP:
++	  off_linktype = 6;
++	  off_nl = 8;
++	  return;
++
+ 	case DLT_IEEE802:
+ 		off_linktype = 20;
+ 		off_nl = 22;
+diff -ur --new-file tcpdump-3.0.4-orig/libpcap-0.0.6/pcap-linux.c tcpdump-3.0.4-atm/libpcap-0.0.6/pcap-linux.c
+--- tcpdump-3.0.4-orig/libpcap-0.0.6/pcap-linux.c	Fri May  3 20:36:31 1996
++++ tcpdump-3.0.4-atm/libpcap-0.0.6/pcap-linux.c	Mon Nov 11 18:57:44 1996
+@@ -145,6 +145,10 @@
+     p->linktype = DLT_EN10MB;		/* Why on earth does linux do this? */
+   else if (strncmp("dummy", device, 5) == 0)
+     p->linktype = DLT_EN10MB;
++  else if (strncmp("lec", device, 3) == 0)
++    p->linktype = DLT_LANE8023;
++  else if (strncmp("atm", device, 3) == 0)
++    p->linktype = DLT_CIP;
+   else {
+     sprintf(ebuf, "pcap_open_live (pcap-linux.c): unknown device %s\n",device);
+     goto bad;
+diff -ur --new-file tcpdump-3.0.4-orig/tcpdump-3.0.4/Makefile.in tcpdump-3.0.4-atm/tcpdump-3.0.4/Makefile.in
+--- tcpdump-3.0.4-orig/tcpdump-3.0.4/Makefile.in	Fri May  3 21:15:11 1996
++++ tcpdump-3.0.4-atm/tcpdump-3.0.4/Makefile.in	Mon Nov 11 18:57:45 1996
+@@ -122,7 +122,7 @@
+ 	print-snmp.c print-ntp.c print-null.c print-egp.c print-ospf.c \
+ 	print-fddi.c print-llc.c print-sunrpc.c \
+ 	print-wb.c print-decnet.c print-isoclns.c print-ipx.c \
+-	util.c bpf_dump.c parsenfsfh.c
++	util.c bpf_dump.c parsenfsfh.c print-lane.c print-cip.c
+ GEN =	version.c
+ 
+ SRC =	$(CSRC) $(GEN)
+@@ -139,7 +139,7 @@
+ #have-broken-make#	print-null.o print-egp.o print-ospf.o print-fddi.o \
+ #have-broken-make#	print-llc.o print-sunrpc.o print-wb.o print-decnet.o \
+ #have-broken-make#	print-isoclns.o print-ipx.o util.o \
+-#have-broken-make#	bpf_dump.o parsenfsfh.o \
++#have-broken-make#	bpf_dump.o parsenfsfh.o print-lane.o print-cip.o \
+ #have-broken-make#	version.o
+ 
+ HDR =	addrtoname.h appletalk.h bootp.h decnet.h \
+diff -ur --new-file tcpdump-3.0.4-orig/tcpdump-3.0.4/interface.h tcpdump-3.0.4-atm/tcpdump-3.0.4/interface.h
+--- tcpdump-3.0.4-orig/tcpdump-3.0.4/interface.h	Wed Jun 15 05:21:41 1994
++++ tcpdump-3.0.4-atm/tcpdump-3.0.4/interface.h	Mon Nov 11 18:57:45 1996
+@@ -103,6 +103,8 @@
+ extern void null_if_print(u_char *, const struct pcap_pkthdr *, const u_char*);
+ extern void ppp_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+ extern void sl_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
++extern void lane_if_print(u_char *, const struct pcap_pkthdr *,const u_char *);
++extern void cip_if_print(u_char *, const struct pcap_pkthdr *,const u_char *);
+ 
+ extern void arp_print(const u_char *, int, int);
+ extern void ip_print(const u_char *, int);
+diff -ur --new-file tcpdump-3.0.4-orig/tcpdump-3.0.4/lane.h tcpdump-3.0.4-atm/tcpdump-3.0.4/lane.h
+--- tcpdump-3.0.4-orig/tcpdump-3.0.4/lane.h	Thu Jan  1 01:00:00 1970
++++ tcpdump-3.0.4-atm/tcpdump-3.0.4/lane.h	Mon Nov 11 18:57:45 1996
+@@ -0,0 +1,29 @@
++/*
++ * Marko Kiiskila carnil@cs.tut.fi 
++ * 
++ * Tampere University of Technology - Telecommunications Laboratory
++ *
++ * Permission to use, copy, modify and distribute this
++ * software and its documentation is hereby granted,
++ * provided that both the copyright notice and this
++ * permission notice appear in all copies of the software,
++ * derivative works or modified versions, and any portions
++ * thereof, that both notices appear in supporting
++ * documentation, and that the use of this software is
++ * acknowledged in any publications resulting from using
++ * the software.
++ * 
++ * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
++ * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
++ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
++ * SOFTWARE.
++ * 
++ */
++
++struct lecdatahdr_8023 {
++  u_short le_header;
++  u_char h_dest[ETH_ALEN];
++  u_char h_source[ETH_ALEN];
++  u_short h_type;
++};
++
+diff -ur --new-file tcpdump-3.0.4-orig/tcpdump-3.0.4/print-cip.c tcpdump-3.0.4-atm/tcpdump-3.0.4/print-cip.c
+--- tcpdump-3.0.4-orig/tcpdump-3.0.4/print-cip.c	Thu Jan  1 01:00:00 1970
++++ tcpdump-3.0.4-atm/tcpdump-3.0.4/print-cip.c	Mon Nov 11 18:57:45 1996
+@@ -0,0 +1,155 @@
++/*
++ * Marko Kiiskila carnil@cs.tut.fi 
++ * 
++ * Tampere University of Technology - Telecommunications Laboratory
++ *
++ * Permission to use, copy, modify and distribute this
++ * software and its documentation is hereby granted,
++ * provided that both the copyright notice and this
++ * permission notice appear in all copies of the software,
++ * derivative works or modified versions, and any portions
++ * thereof, that both notices appear in supporting
++ * documentation, and that the use of this software is
++ * acknowledged in any publications resulting from using
++ * the software.
++ * 
++ * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
++ * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
++ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
++ * SOFTWARE.
++ * 
++ */
++
++#include <sys/param.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++
++#include <net/if.h>
++
++#include <netinet/in.h>
++#include <netinet/if_ether.h>
++#include <netinet/in_systm.h>
++#include <netinet/ip.h>
++#include <netinet/ip_var.h>
++#include <netinet/udp.h>
++#include <netinet/udp_var.h>
++#include <netinet/tcp.h>
++#include <netinet/tcpip.h>
++
++#include <stdio.h>
++#include <pcap.h>
++
++#include "interface.h"
++#include "addrtoname.h"
++
++const u_char *packetp;
++const u_char *snapend;
++
++#define RFC1483LLC_LEN 8 
++
++static unsigned char rfcllc[] = {
++  0xaa,   /* DSAP: non-ISO */
++  0xaa,   /* SSAP: non-ISO */
++  0x03,   /* Ctrl: Unnumbered Information Command PDU */
++  0x00,   /* OUI: EtherType */
++  0x00,
++  0x00 };
++
++static inline void
++cip_print(register const u_char *bp, int length)
++{
++  int i;
++
++  if (memcmp(rfcllc, bp, sizeof(rfcllc))) {
++    if (qflag) {
++      for(i=0;i<RFC1483LLC_LEN;i++)
++	(void)printf("%2.2x ",bp[i]);
++    } else {
++      for(i=0;i<RFC1483LLC_LEN-2;i++)
++	(void)printf("%2.2x ",bp[i]);
++      etherproto_string(((u_short*)bp)[3]);
++    } 
++  } else {
++    if (qflag)
++      (void)printf("(null encapsulation)");
++    else {
++      (void)printf("(null encap)");
++      etherproto_string(ETH_P_IP);
++    }
++  }
++}
++
++/*
++ * This is the top level routine of the printer.  'p' is the points
++ * to the raw header of the packet, 'tvp' is the timestamp,
++ * 'length' is the length of the packet off the wire, and 'caplen'
++ * is the number of bytes actually captured.
++ */
++void
++cip_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
++{
++	int caplen = h->caplen;
++	int length = h->len;
++	u_short ether_type;
++	extern u_short extracted_ethertype;
++	u_short *bp;
++
++	ts_print(&h->ts);
++
++	if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) {
++		printf("[|cip]");
++		goto out;
++	}
++
++	if (eflag)
++	  cip_print(p, length);
++
++	/*
++	 * Some printers want to get back at the ethernet addresses,
++	 * and/or check that they're not walking off the end of the packet.
++	 * Rather than pass them all the way down, we set these globals.
++	 */
++	packetp = p;
++	snapend = p + caplen;
++
++	if (memcmp(rfcllc, p, sizeof(rfcllc))==0) {
++	  length -= RFC1483LLC_LEN;
++	  caplen -= RFC1483LLC_LEN;
++	  bp = (u_short*)p;
++	  p += RFC1483LLC_LEN;
++	  ether_type = ntohs(bp[3]);
++	} else
++	  ether_type = ETH_P_IP;
++
++	/*
++	 * Is it (gag) an 802.3 encapsulation?
++	 */
++	extracted_ethertype = 0;
++	if (ether_type < ETHERMTU) {
++		/* Try to print the LLC-layer header & higher layers */
++		if (llc_print(p, length, caplen, NULL, NULL)==0) {
++			/* ether_type not known, print raw packet */
++			if (!eflag)
++				cip_print((u_char *)bp, length);
++			if (extracted_ethertype) {
++				printf("(LLC %s) ",
++			       etherproto_string(htons(extracted_ethertype)));
++			}
++			if (!xflag && !qflag)
++				default_print(p, caplen);
++		}
++	} else if (ether_encap_print(ether_type, p, length, caplen) == 0) {
++		/* ether_type not known, print raw packet */
++		if (!eflag)
++			cip_print((u_char *)bp, length + RFC1483LLC_LEN);
++		if (!xflag && !qflag)
++			default_print(p, caplen);
++	}
++	if (xflag)
++		default_print(p, caplen);
++ out:
++	putchar('\n');
++}
++
++
+diff -ur --new-file tcpdump-3.0.4-orig/tcpdump-3.0.4/print-lane.c tcpdump-3.0.4-atm/tcpdump-3.0.4/print-lane.c
+--- tcpdump-3.0.4-orig/tcpdump-3.0.4/print-lane.c	Thu Jan  1 01:00:00 1970
++++ tcpdump-3.0.4-atm/tcpdump-3.0.4/print-lane.c	Mon Nov 11 18:57:46 1996
+@@ -0,0 +1,141 @@
++/*
++ * Marko Kiiskila carnil@cs.tut.fi 
++ * 
++ * Tampere University of Technology - Telecommunications Laboratory
++ *
++ * Permission to use, copy, modify and distribute this
++ * software and its documentation is hereby granted,
++ * provided that both the copyright notice and this
++ * permission notice appear in all copies of the software,
++ * derivative works or modified versions, and any portions
++ * thereof, that both notices appear in supporting
++ * documentation, and that the use of this software is
++ * acknowledged in any publications resulting from using
++ * the software.
++ * 
++ * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
++ * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
++ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
++ * SOFTWARE.
++ * 
++ */
++
++#include <sys/param.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++
++#include <net/if.h>
++
++#include <netinet/in.h>
++#include <netinet/if_ether.h>
++#include <netinet/in_systm.h>
++#include <netinet/ip.h>
++#include <netinet/ip_var.h>
++#include <netinet/udp.h>
++#include <netinet/udp_var.h>
++#include <netinet/tcp.h>
++#include <netinet/tcpip.h>
++
++#include <stdio.h>
++#include <pcap.h>
++
++#include "interface.h"
++#include "addrtoname.h"
++#include "lane.h"
++
++const u_char *packetp;
++const u_char *snapend;
++
++static inline void
++lane_print(register const u_char *bp, int length)
++{
++	register const struct lecdatahdr_8023 *ep;
++
++	ep = (const struct lecdatahdr_8023 *)bp;
++	if (qflag)
++		(void)printf("lecid:%d %s %s %d: ",
++			     ntohs(ep->le_header),
++			     etheraddr_string(ep->h_source),
++			     etheraddr_string(ep->h_dest),
++			     length);
++	else
++		(void)printf("lecid:%d %s %s %s %d: ",
++			     ntohs(ep->le_header),
++			     etheraddr_string(ep->h_source),
++			     etheraddr_string(ep->h_dest),
++			     etherproto_string(ep->h_type),
++			     length);
++}
++
++/*
++ * This is the top level routine of the printer.  'p' is the points
++ * to the ether header of the packet, 'tvp' is the timestamp,
++ * 'length' is the length of the packet off the wire, and 'caplen'
++ * is the number of bytes actually captured.
++ */
++void
++lane_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
++{
++	int caplen = h->caplen;
++	int length = h->len;
++	struct lecdatahdr_8023 *ep;
++	u_short ether_type;
++	extern u_short extracted_ethertype;
++
++	ts_print(&h->ts);
++
++	if (caplen < sizeof(struct lecdatahdr_8023)) {
++		printf("[|lane]");
++		goto out;
++	}
++
++	if (eflag)
++	  lane_print(p, length);
++
++	/*
++	 * Some printers want to get back at the ethernet addresses,
++	 * and/or check that they're not walking off the end of the packet.
++	 * Rather than pass them all the way down, we set these globals.
++	 */
++	packetp = p;
++	snapend = p + caplen;
++
++	length -= sizeof(struct lecdatahdr_8023);
++	caplen -= sizeof(struct lecdatahdr_8023);
++	ep = (struct lecdatahdr_8023 *)p;
++	p += sizeof(struct lecdatahdr_8023);
++
++	ether_type = ntohs(ep->h_type);
++
++	/*
++	 * Is it (gag) an 802.3 encapsulation?
++	 */
++	extracted_ethertype = 0;
++	if (ether_type < ETHERMTU) {
++		/* Try to print the LLC-layer header & higher layers */
++		if (llc_print(p, length, caplen, ep->h_source,ep->h_dest)==0) {
++			/* ether_type not known, print raw packet */
++			if (!eflag)
++				lane_print((u_char *)ep, length);
++			if (extracted_ethertype) {
++				printf("(LLC %s) ",
++			       etherproto_string(htons(extracted_ethertype)));
++			}
++			if (!xflag && !qflag)
++				default_print(p, caplen);
++		}
++	} else if (ether_encap_print(ether_type, p, length, caplen) == 0) {
++		/* ether_type not known, print raw packet */
++		if (!eflag)
++			lane_print((u_char *)ep, length + sizeof(*ep));
++		if (!xflag && !qflag)
++			default_print(p, caplen);
++	}
++	if (xflag)
++		default_print(p, caplen);
++ out:
++	putchar('\n');
++}
++
++
+diff -ur --new-file tcpdump-3.0.4-orig/tcpdump-3.0.4/tcpdump.c tcpdump-3.0.4-atm/tcpdump-3.0.4/tcpdump.c
+--- tcpdump-3.0.4-orig/tcpdump-3.0.4/tcpdump.c	Tue Apr 25 12:30:24 1995
++++ tcpdump-3.0.4-atm/tcpdump-3.0.4/tcpdump.c	Mon Nov 11 18:57:46 1996
+@@ -82,6 +82,8 @@
+ 
+ static struct printer printers[] = {
+ 	{ ether_if_print,	DLT_EN10MB },
++	{ lane_if_print,        DLT_LANE8023 },
++	{ cip_if_print,         DLT_CIP },
+ 	{ sl_if_print,		DLT_SLIP },
+ 	{ ppp_if_print,		DLT_PPP },
+ 	{ fddi_if_print,	DLT_FDDI },
+@@ -97,7 +99,6 @@
+ 	for (p = printers; p->f; ++p)
+ 		if (type == p->type)
+ 			return p->f;
+-
+ 	error("unknown data link type 0x%x", type);
+ 	/* NOTREACHED */
+ }
diff -ur --new-file old/atm/led/cm_sap.h new/atm/led/cm_sap.h
--- old/atm/led/cm_sap.h	Tue Sep 17 06:47:12 1996
+++ new/atm/led/cm_sap.h	Mon Nov 11 15:38:04 1996
@@ -410,7 +410,6 @@
                         SAP_RCV_CALLBACK           rcv_callback,
                         SAP_VC_NOTIFY_CALLBACK     vc_notify_callback,
                         SAP_CONNECT_CALLBACK       svc_connect_callback,
-                        SAP_LINK_STATUS_CALLBACK   link_status_callback,
                         SAP_XMT_DONE_CALLBACK      xmt_done_callback,
 			int itf_num,
                         const char                *p_sap_text,
diff -ur --new-file old/atm/led/conn.c new/atm/led/conn.c
--- old/atm/led/conn.c	Tue Oct  1 17:35:54 1996
+++ new/atm/led/conn.c	Mon Nov 11 16:06:58 1996
@@ -47,6 +47,7 @@
 
 #include <linux/atm.h>
 #include <linux/atmdev.h>
+#include <atm.h>
 
 /* Digital includes */
 #include "codes.h"
@@ -114,7 +115,6 @@
   SAP_RCV_CALLBACK rcv_callback;
   SAP_VC_NOTIFY_CALLBACK vc_notify_callback;
   SAP_CONNECT_CALLBACK svc_connect_callback;
-  SAP_LINK_STATUS_CALLBACK link_status_callback;
   SAP_XMT_DONE_CALLBACK xmt_done_callback;
   char *p_sap_text;
   unsigned long xmt_packet_count;
@@ -140,7 +140,6 @@
 		SAP_RCV_CALLBACK rcv_callback, 
 		SAP_VC_NOTIFY_CALLBACK vc_notify_callback,
 		SAP_CONNECT_CALLBACK svc_connect_callback,
-		SAP_LINK_STATUS_CALLBACK link_status_callback,
 		SAP_XMT_DONE_CALLBACK xmt_done_callback,
 		int itf_num,
 		const char *p_sap_text, HANDLE *p_sap_handle)
@@ -158,7 +157,6 @@
   client->rcv_callback = rcv_callback;
   client->vc_notify_callback = vc_notify_callback;
   client->svc_connect_callback = svc_connect_callback;
-  client->link_status_callback = link_status_callback;
   client->xmt_done_callback = xmt_done_callback;
 
   /* Allocate space etc for text string */
@@ -875,7 +873,7 @@
 
 int
 conn_create_listensocket(HANDLE sap_handle, HANDLE conn_context,
-			 unsigned short blli_codepoint, int max_cell_rate,
+			 unsigned short blli_codepoint, const char *qos_spec,
 			 HANDLE *p_conn_handle)
 {
   int fd, ret, len;
@@ -895,8 +893,6 @@
 
   conn_info->conqos.txtp.traffic_class = ATM_UBR;
   conn_info->conqos.rxtp.traffic_class = ATM_UBR;
-  conn_info->conqos.txtp.max_pcr = max_cell_rate;  
-  conn_info->conqos.rxtp.max_pcr = max_cell_rate;
 
   switch (blli_codepoint) {
   case BLLI_CONTROL:
@@ -913,6 +909,10 @@
   default:
     EVENT(EM_ASSERT,("Unknown BLLI codepoint:%x\n",blli_codepoint));
   }
+
+  if (qos_spec)
+    if (text2qos(qos_spec,&conn_info->conqos,T2Q_DEFAULTS) < 0)
+      EVENT(EM_ASSERT,("text2qos failed in conn_create_listensocket\n"));
 
   /* Set traffic parameters */
   if (setsockopt(fd,SOL_ATM,SO_ATMQOS, &(conn_info->conqos), 
diff -ur --new-file old/atm/led/conn.h new/atm/led/conn.h
--- old/atm/led/conn.h	Thu Aug 15 23:16:25 1996
+++ new/atm/led/conn.h	Mon Nov 11 16:04:28 1996
@@ -19,7 +19,7 @@
 int conn_check_incoming(fd_set *fds);
 int conn_create_listensocket(HANDLE sap_context, HANDLE conn_context,
 			     unsigned short blli_codepoint,
-			     int max_cell_rate,
+			     const char *qos_spec,
 			     HANDLE *p_conn_handle);
 int conn_set_kernel_socket(int fd);
 /*
diff -ur --new-file old/atm/led/lec_ctrl.c new/atm/led/lec_ctrl.c
--- old/atm/led/lec_ctrl.c	Tue Oct  1 17:34:41 1996
+++ new/atm/led/lec_ctrl.c	Mon Nov 11 16:07:15 1996
@@ -66,6 +66,8 @@
 #include <assert.h>
 #include <unistd.h>
 
+#include <atm.h>
+
 /* Include General Headers. */
 
 #include "g_types.h"    /* General Purpose Types                 */
@@ -232,10 +234,9 @@
  *  bus_addr
  *    The ATM Address of the BUS being contacted.
  *
- *  max_cell_rate
- *    The maximum cell rate supported by the physical adapter.  This
- *    information is required to properly generate SVC information elements.
- *    This data is obtained from the UME.
+ *  qos_spec
+ *    The QOS specification string for SVCs. NULL if default values (i.e. UBR
+ *    at link speeed) should be used. This data is obtained from the UME.
  *
  *  current_tran_id
  *    Current transaction ID to be used for the next LE Control frame.
@@ -285,7 +286,7 @@
    HANDLE            reg_timer;
    SM_STATE_HISTORY  sm_state_history[SM_STATE_HISTORY_DEPTH];
    UINT8             sm_state_history_index;
-   UINT32            max_cell_rate;
+   const char       *qos_spec;
    UINT32            current_tran_id;
    UINT8             vc_ready_mask;
    UINT32            illegal_frame_rcv_count;
@@ -430,9 +431,9 @@
   p_conn_info->conqos.txtp.traffic_class = ATM_UBR;
   p_conn_info->conqos.rxtp.traffic_class = ATM_UBR;
    
-      /* Set the peak cell rate to p_elan->max_cell_rate */
-  p_conn_info->conqos.txtp.max_pcr = p_elan->max_cell_rate;
-  p_conn_info->conqos.rxtp.max_pcr = p_elan->max_cell_rate;
+  if (p_elan->qos_spec)
+    if (text2qos(p_elan->qos_spec,&p_conn_info->conqos,T2Q_DEFAULTS) < 0)
+      EVENT(EM_ASSERT,("text2qos failed in lc_conn_info_make\n"));
 
   if (pmp==TRUE) {
     /* Asdf */
@@ -2247,6 +2248,7 @@
                     HANDLE  sap_handle,
                     HANDLE  direct_conn_context,
                     HANDLE  mcast_conn_context,
+		    const char *qos_spec,
                     HANDLE  ctrl_conn_context)
 {
   LC_CONTEXT        *p_context;
@@ -2255,7 +2257,7 @@
   p_elan    = (LC_ELAN_CONTEXT *) lc_elan_handle;
   p_context = (LC_CONTEXT      *) p_elan->lc_handle;
   
-  p_elan->max_cell_rate   = (155200000 / 8) / 53;
+  p_elan->qos_spec = qos_spec;
   
   p_elan->sap_handle            = sap_handle;
   p_elan->direct_conn_context   = direct_conn_context;
@@ -2526,46 +2528,6 @@
       }
 
    return FALSE;
-   }
-
-/*++
-* ======================
-* = lc_sap_link_status =
-* ======================
---*/
-void lc_sap_link_status (HANDLE          lc_elan_handle,
-                         ATM_LINK_STATE  link_state)
-   {
-   LC_ELAN_CONTEXT *p_elan;
-
-   p_elan = (LC_ELAN_CONTEXT *) lc_elan_handle;
-
-   /* Handle the cases in which the link is going down (i.e. the signaling
-    * function has disconnected.
-    */
-   if ((p_elan->link_state  == LINK_SIG_UP) &&
-       (link_state          != LINK_SIG_UP))
-      {
-      p_elan->link_state = link_state;
-      lc_elan_reset ((HANDLE) p_elan);
-      }
-
-   /* Handle the cases in which the link is coming up. */
-
-   if ((p_elan->link_state  != LINK_SIG_UP) &&
-       (link_state          == LINK_SIG_UP))
-      {
-      p_elan->link_state = link_state;
-      lc_join_start ((HANDLE) p_elan,
-                     p_elan->sap_handle,
-                     p_elan->direct_conn_context,
-                     p_elan->mcast_conn_context,
-                     p_elan->ctrl_conn_context);
-      }
-
-   /* Assign the link status for the cases not covered above. */
-
-   p_elan->link_state = link_state;
    }
 
 
diff -ur --new-file old/atm/led/lec_ctrl.h new/atm/led/lec_ctrl.h
--- old/atm/led/lec_ctrl.h	Tue Aug  6 16:33:08 1996
+++ new/atm/led/lec_ctrl.h	Mon Nov 11 15:59:22 1996
@@ -388,6 +388,7 @@
                     HANDLE  data_sap_handle,
                     HANDLE  direct_conn_context,
                     HANDLE  mcast_conn_context,
+		    const char *qos_spec,
                     HANDLE  ctrl_conn_context);
 
 /*++
@@ -446,21 +447,6 @@
                  UINT32     user_data,
                  AAL_DATA  *p_aal_data,
                  void     **pp_packet);
-
-/*++
-* ======================
-* = lc_sap_link_status =
-* ======================
-*
-* Overview:
-*   SAP link status notification callback to be used when registering with the
-*   CM as a SAP.
-*
-*   Refer to cm_sap.h for the full description of this function.
-*
---*/
-void lc_sap_link_status (HANDLE          lc_elan_handle,
-                         ATM_LINK_STATE  link_state);
 
 /* 
  * Forwards address deletion request to lec_arp module.
diff -ur --new-file old/atm/led/main.c new/atm/led/main.c
--- old/atm/led/main.c	Tue Sep 17 06:57:21 1996
+++ new/atm/led/main.c	Mon Nov 11 16:08:29 1996
@@ -37,6 +37,8 @@
 #include <string.h>
 #include <getopt.h>
 
+#include <atm.h>
+
 /* Digital includes */
 #include "codes.h"
 #include "g_types.h"
@@ -257,7 +259,8 @@
 static void
 usage(const char *progname)
 {
-  printf("Usage: %s [-c LECS_address]|[-s LES_address] [-e esi] [-n VLAN_name] [-m mesg_mask][-i interface_number]\n",progname);
+  printf("Usage: %s [-c LECS_address]|[-s LES_address] [-e esi] [-n VLAN_name]"
+    " [-m mesg_mask] [-i interface_number] [-q qos_spec]\n",progname);
 }
 
 static int
@@ -314,9 +317,10 @@
   HANDLE current_timer;
   ADDR_ATM *listen_address = NULL;
   int itf_num = 0;
+  const char *qos_spec = NULL;
 
   while(poll_ret != -1) {
-    poll_ret = getopt(argc, argv, "c:e:n:s:m:l:i:");
+    poll_ret = getopt(argc, argv, "c:e:n:s:m:l:i:q:");
     switch(poll_ret) {
     case 'c':
       if (atm_set) {
@@ -384,6 +388,14 @@
       }
       EVENT(EM_MSG,("Interface number set to %d\n",itf_num));
       break;
+    case 'q':
+      if (text2qos(optarg,NULL,0) < 0) {
+	EVENT(EM_SERR,("Invalid QOS specification\n"));
+	usage(argv[0]);
+	exit(-1);
+      }
+      qos_spec = optarg;
+      break;
     case -1:
       break;
     default:
@@ -510,7 +522,6 @@
 			     ld_rcv_callback,
 			     lc_sap_vc_notify,
 			     lc_sap_connect,
-			     lc_sap_link_status,
 			     ld_xmt_done_callback,
 			     itf_num,
 			     "LAN Emulation Convergence",
@@ -534,7 +545,7 @@
     if (conn_create_listensocket(p_elan->sap_handle,
 				 p_elan->lc_elan_handle,
 				 BLLI_CONTROL,
-				 (155200000 / 8) / 53, 
+				 qos_spec,
 				 NULL)<0) {
       EVENT(EM_NERR,("Creating Control blli codepoint failed\n"));
       return STATUS_K_ATM_RESOURCES;
@@ -542,7 +553,7 @@
     if (conn_create_listensocket(p_elan->sap_handle,
 				 p_elan->lc_elan_handle,
 				 BLLI_BUS_802_3,
-				 (155200000 / 8) / 53, 
+				 qos_spec,
 				 NULL)<0) {
       EVENT(EM_NERR, ("Creating Bus 802_3 blli codepoint failed\n"));
       return STATUS_K_ATM_RESOURCES;
@@ -551,7 +562,7 @@
     if (conn_create_listensocket(p_elan->sap_handle,
 				 p_elan->lc_elan_handle,
 				 BLLI_DIRECT_802_3,
-				 (155200000 / 8) / 53, 
+				 qos_spec,
 				 NULL)<0) {
       EVENT(EM_NERR, ("Creating Data direct 802_3 blli codepoint failed\n"));
       return STATUS_K_ATM_RESOURCES;
@@ -564,6 +575,7 @@
 		   p_elan->sap_handle,
 		   (HANDLE) &p_elan->direct_conn_context,
 		   (HANDLE) &p_elan->mcast_conn_context,
+		   qos_spec,
 		   (HANDLE) &p_elan->ctrl_conn_context);
 
 
diff -ur --new-file old/atm/led/zeppelin.8 new/atm/led/zeppelin.8
--- old/atm/led/zeppelin.8	Tue Sep 17 05:34:25 1996
+++ new/atm/led/zeppelin.8	Mon Nov 11 16:10:28 1996
@@ -1,4 +1,4 @@
-.TH zeppelin 8 "Sep 17, 1996" "Linux" "Maintenance Commands"
+.TH zeppelin 8 "Nov 11, 1996" "Linux" "Maintenance Commands"
 .SH NAME
 zeppelin \- ATM LAN Emulation client demon (LED) Zeppelin
 .SH SYNOPSIS
@@ -9,6 +9,7 @@
 .RB [ \-n\ \fIVLAN_name\fP ]
 .RB [ \-m\ \fImesg_mask\fP ]
 .RB [ \-i\ \fIinterface_number\fP ]
+.RB [ \-q\ \fIqos_spec\fP ]
 .SH DESCRIPTION
 A LAN Emulation Client is an entity in an ATM endstation that performs 
 data forwarding, address resolution and other control functions. It 
@@ -50,6 +51,9 @@
 Linux LEC supports up to 4 network interfaces. This number tells
 zeppelin to which of these to attach. Network interfaces are
 numbered from "lec0" to "lec3".
+.IP \fB\-i\ \fIqos_spec\fP
+Set the specified quality of service (see qos(7) for the syntax) for outgoing
+calls. UBR at link speed is used by default.
 .SH BUGS
 Supports only IEEE 802.3 / Ethernet type of ELANs.
 .PP
@@ -57,5 +61,5 @@
 .SH AUTHOR
 Marko Kiiskila, TUT <carnil@cs.tut.fi>
 .SH "SEE ALSO"
-lecs(8), atmsigd(8), les(8)
+lecs(8), atmsigd(8), les(8), qos(7)
 .\"{{{}}}
diff -ur --new-file old/atm/lib/Makefile new/atm/lib/Makefile
--- old/atm/lib/Makefile	Thu Oct 10 22:51:38 1996
+++ new/atm/lib/Makefile	Wed Nov 13 17:04:19 1996
@@ -1,5 +1,5 @@
 ATM_OBJS=text2atm.o atm2text.o atmequal.o sdu2cell.o text2qos.o qos2text.o \
-  qosequal.o
+  qosequal.o ans_l.o
 ATMD_OBJS=common.o diag.o timer.o
 AQ_OBJS=arequipa.o
 PGMS=#test
@@ -22,3 +22,6 @@
 
 libarequipa.a:		$(AQ_OBJS)
 			ar rcs libarequipa.a $(AQ_OBJS)
+
+ans_l.o:		ans.o
+			ld -r -o ans_l.o ans.o -L/usr/lib -lresolv
diff -ur --new-file old/atm/lib/ans.c new/atm/lib/ans.c
--- old/atm/lib/ans.c	Thu Jan  1 01:00:00 1970
+++ new/atm/lib/ans.c	Wed Nov 13 17:03:50 1996
@@ -0,0 +1,125 @@
+/* ans.c - Interface for text2atm and atm2text to ANS */
+
+/* Written 1996 by Werner Almesberger, EPFL-LRC */
+
+
+/*
+ * This stuff is a temporary hack to avoid using gethostbyname_insap and such
+ * without doing the "full upgrade" to getaddrinfo/getnameinfo. This also
+ * serves as an exercise for me to get all the details right before I propose
+ * a patch that would eventually end up in libc (and that should therefore be
+ * as stable as possible).
+ */
+
+
+#include <string.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <linux/atm.h>
+
+#include "atm.h"
+#include "atmres.h"
+
+
+#define MAX_ANSWER 2048
+#define MAX_NAME   1024
+
+
+#define GET16(pos) (((pos)[0] << 8) | (pos)[1])
+
+
+static int ans(const char *text,int wanted,void *result,int res_len)
+{
+    unsigned char answer[MAX_ANSWER];
+    unsigned char name[MAX_NAME];
+    unsigned char *pos,*data,*found;
+    int answer_len,name_len,data_len,found_len;
+    int questions,answers;
+
+    if ((answer_len = res_search(text,C_IN,wanted,answer,MAX_ANSWER)) < 0)
+	return TRY_OTHER;
+    /*
+     * Response header: id, flags, #queries, #answers, #authority,
+     * #additional (all 16 bits)
+     */
+    pos = answer+12;
+    if (answer[3] & 15) return TRY_OTHER; /* rcode != 0 */
+    questions = GET16(answer+4);
+    if (questions != 1) return TRY_OTHER; /* trouble ... */
+    answers = GET16(answer+6);
+    if (answers < 1) return TRY_OTHER;
+    /*
+     * Query: name, type (16), class (16)
+     */
+    if ((name_len = dn_expand(answer,answer+answer_len,pos,name,MAX_NAME)) < 0)
+	return TRY_OTHER;
+    pos += name_len;
+    if (GET16(pos) != T_ATMA || GET16(pos+2) != C_IN) return TRY_OTHER;
+    pos += 4;
+    /*
+     * Iterate over answers until we find something we like, giving priority
+     * to ATMA_AESA (until signaling is fixed to work with E.164 too)
+     */
+    found = NULL;
+    while (answers--) {
+	/*
+	 * RR: name, type (16), class (16), TTL (32), resource_len (16),
+	 * resource_data ...
+	 */
+	if ((name_len = dn_expand(answer,answer+answer_len,pos,name,MAX_NAME))
+	  < 0) return TRY_OTHER;
+	pos += name_len;
+	data_len = GET16(pos+8);
+	data = pos+10;
+	pos = data+data_len;
+	if (GET16(data-10) != wanted || GET16(data-8) != C_IN || !--data_len)
+	    continue;
+	switch (wanted) {
+	    case T_ATMA:
+		switch (*data++) {
+		    case ATMA_AESA:
+			if (data_len != ATM_ESA_LEN) continue;
+			memcpy(((struct sockaddr_atmsvc *) result)->
+			  sas_addr.prv,data,ATM_ESA_LEN);
+			return 0;
+		    case ATMA_E164:
+			if (data_len > ATM_E164_LEN) continue;
+			if (!found) {
+			    found = data;
+			    found_len = data_len;
+			}
+			break;
+		    default:
+			continue;
+		}
+	    case T_PTR:
+		/* ... */
+	    default:
+		continue;
+	}
+    }
+    if (!found) return TRY_OTHER;
+    memcpy(((struct sockaddr_atmsvc *) result)->sas_addr.pub,found,found_len);
+    ((struct sockaddr_atmsvc *) result)->sas_addr.pub[found_len] = 0;
+    return 0;
+}
+
+
+int ans_byname(const char *text,struct sockaddr_atmsvc *addr,int length,
+  int flags)
+{
+    if (!(flags & T2A_SVC) || length != sizeof(*addr)) return TRY_OTHER; 
+    memset(addr,0,sizeof(*addr));
+    addr->sas_family = AF_ATMSVC;
+    return ans(text,T_ATMA,addr,length);
+}
+
+
+int ans_byaddr(char *buffer,int length,const struct sockaddr_atmsvc *addr,
+  int flags)
+{
+    return TRY_OTHER; /* sorry ... */
+}
diff -ur --new-file old/atm/lib/atm.h new/atm/lib/atm.h
--- old/atm/lib/atm.h	Sun Oct 13 15:45:38 1996
+++ new/atm/lib/atm.h	Tue Nov 12 21:45:49 1996
@@ -12,17 +12,19 @@
 
 #define HOSTS_ATM "/etc/hosts.atm"
 
-#define T2A_PVC		 1	/* address is PVC */
-#define T2A_SVC		 2	/* address is SVC */
-#define T2A_UNSPEC	 4	/* allow unspecified parts in PVC address */
-#define T2A_WILDCARD	 8	/* allow wildcards in PVC address */
-#define T2A_NNI		16	/* allow NNI VPI range (PVC) */
-#define T2A_NAME	32	/* allow name resolution */
-#define T2A_REMOTE	64	/* try to use ANS if local lookup fails */
+#define T2A_PVC		  1	/* address is PVC */
+#define T2A_SVC		  2	/* address is SVC */
+#define T2A_UNSPEC	  4	/* allow unspecified parts in PVC address */
+#define T2A_WILDCARD	  8	/* allow wildcards in PVC address */
+#define T2A_NNI		 16	/* allow NNI VPI range (PVC) */
+#define T2A_NAME	 32	/* allow name resolution */
+#define T2A_REMOTE	 64	/* OBSOLETE */
+#define T2A_LOCAL	128	/* don't use ANS */
 
 #define A2T_PRETTY	 1	/* add syntactic sugar */
 #define A2T_NAME	 2	/* attempt name lookup */
-#define A2T_REMOTE	 4	/* try to use ANS if local lookup fails */
+#define A2T_REMOTE	 4	/* OBSOLETE */
+#define A2T_LOCAL	 8	/* don't use ANS */
 
 #define AXE_WILDCARD	 1	/* allow wildcard match */
 #define AXE_PRVOPT	 2	/* private part is optional */
diff -ur --new-file old/atm/lib/atm2text.c new/atm/lib/atm2text.c
--- old/atm/lib/atm2text.c	Fri Jul 19 18:01:50 1996
+++ new/atm/lib/atm2text.c	Wed Nov 13 13:47:26 1996
@@ -9,10 +9,7 @@
 #include <linux/atm.h>
 
 #include "atm.h"
-
-
-#define TRY_OTHER -2
-#define FATAL	  -1 /* must be -1 */
+#include "atmres.h"
 
 
 static int put_item(char **buffer,int *length,int value)
@@ -188,6 +185,9 @@
     if (!length) return -1;
     if (flags & A2T_NAME) {
 	result = try_name(buffer,length,addr);
+	if (result == TRY_OTHER && !(flags & A2T_LOCAL))
+	    result = ans_byaddr(buffer,length,
+	      (const struct sockaddr_atmsvc *) addr,flags);
 	if (result == FATAL) return FATAL;
 	if (result != TRY_OTHER) return strlen(buffer);
     }
diff -ur --new-file old/atm/lib/atmres.h new/atm/lib/atmres.h
--- old/atm/lib/atmres.h	Thu Jan  1 01:00:00 1970
+++ new/atm/lib/atmres.h	Wed Nov 13 13:46:46 1996
@@ -0,0 +1,36 @@
+/* atmres.h - Common definitions and prototypes for resolver functions */
+
+/* Written 1996 by Werner Almesberger, EPFL-LRC */
+
+
+#ifndef ATMRES_H
+#define ATMRES_H
+
+#include <arpa/nameser.h>
+#include <linux/atm.h>
+
+
+/* Some #defines that may be needed if ANS isn't installed on that system */
+
+#ifndef T_ATMA
+#define T_ATMA		34
+#endif
+#ifndef ATMA_AESA
+#define ATM_AESA	0
+#endif
+#ifndef ATM_E164
+#define ATM_E164	1
+#endif
+
+/* Return codes for text2atm and atm2text */
+
+#define TRY_OTHER -2
+#define FATAL	  -1 /* must be -1 */
+
+
+int ans_byname(const char *text,struct sockaddr_atmsvc *addr,int length,
+  int flags);
+int ans_byaddr(char *buffer,int length,const struct sockaddr_atmsvc *addr,
+  int flags);
+
+#endif
diff -ur --new-file old/atm/lib/text2atm.c new/atm/lib/text2atm.c
--- old/atm/lib/text2atm.c	Tue Oct  1 17:25:11 1996
+++ new/atm/lib/text2atm.c	Wed Nov 13 20:03:42 1996
@@ -12,10 +12,7 @@
 
 #include "atm.h"
 #include "atmsap.h"
-
-
-#define TRY_OTHER -2
-#define FATAL	  -1 /* must be -1 */
+#include "atmres.h"
 
 
 static int try_pvc(const char *text,struct sockaddr_atmpvc *addr,int flags)
@@ -245,6 +242,8 @@
     }
     if (!(flags & T2A_NAME)) return -1;
     result = try_name(text,addr,length,flags & ~T2A_NAME);
+    if (result == TRY_OTHER && !(flags & T2A_LOCAL))
+	result = ans_byname(text,(struct sockaddr_atmsvc *) addr,length,flags);
     if (result != TRY_OTHER) return result;
     return -1;
 }
diff -ur --new-file old/atm/lib/text2qos.c new/atm/lib/text2qos.c
--- old/atm/lib/text2qos.c	Thu Oct 17 22:44:26 1996
+++ new/atm/lib/text2qos.c	Mon Nov 11 15:49:51 1996
@@ -61,6 +61,7 @@
 	    fract = fract*10+*end-48;
 	    if (--power == -9) break;
 	}
+    multiplier = NULL;
     if (*end && (multiplier = strchr(mult,*end))) {
 	while (multiplier >= mult) {
 	    if (rate > UINT_MAX/1000) return RATE_ERROR;
@@ -80,13 +81,16 @@
 	    power--;
 	}
     rate += fract;
-    if (strlen(end) >= 3)
-	if (!strncmp(end,"cps",3)) end += 3;
+    if (strlen(end) < 3) {
+	if (multiplier) return RATE_ERROR;
+    }
+    else if (!strncmp(end,"cps",3)) end += 3;
 	else if (!strncmp(end,"bps",3)) {
 		rate = (rate+(up ? 8*ATM_CELL_PAYLOAD-1 : 0))/8/
 		  ATM_CELL_PAYLOAD;
 		end += 3;
 	    }
+	    else if (multiplier) return RATE_ERROR;
     if (rate > INT_MAX) return RATE_ERROR;
     *text = end;
     return rate;
@@ -107,12 +111,12 @@
 	    case 0:
 	    case 1:
 		if ((value = get_rate(text,0)) == RATE_ERROR) return -1;
-		a->max_pcr = value;
+		if (a) a->max_pcr = value;
 		if (b) b->max_pcr = value;
 		break;
 	    case 2:
 		if ((value = get_rate(text,1)) == RATE_ERROR) return -1;
-		a->min_pcr = value;
+		if (a) a->min_pcr = value;
 		if (b) b->min_pcr = value;
 		break;
 	    case 3:
@@ -120,7 +124,7 @@
 		value = strtol(*text,&end,10);
 		if (value < 0) return -1;
 		*text = end;
-		a->max_sdu = value;
+		if (a) a->max_sdu = value;
 		if (b) b->max_sdu = value;
 		break;
 	    default:
@@ -138,19 +142,20 @@
     int traffic_class;
 
     if ((traffic_class = fetch(&text,"!none","ubr","cbr",NULL)) < 0) return -1;
-    if (!(flags & T2Q_DEFAULTS)) memset(qos,0,sizeof(*qos));
-    qos->txtp.traffic_class = qos->rxtp.traffic_class = traffic_class;
+    if (qos && !(flags & T2Q_DEFAULTS)) memset(qos,0,sizeof(*qos));
+    if (qos) qos->txtp.traffic_class = qos->rxtp.traffic_class = traffic_class;
     if (!*text) return 0;
-    if (params(&text,&qos->txtp,&qos->rxtp)) return -1;
+    if (params(&text,qos ? &qos->txtp : NULL,qos ? &qos->rxtp : NULL))
+	return -1;
     if (!*text) return 0;
     switch (fetch(&text,"tx","rx",NULL)) {
 	case 0:
 	    if (!fetch(&text,":none",NULL)) {
-		qos->txtp.traffic_class = ATM_NONE;
+		if (qos) qos->txtp.traffic_class = ATM_NONE;
 		if (*text == ',') text++;
 		break;
 	    }
-	    if (params(&text,&qos->txtp,NULL)) return -1;
+	    if (params(&text,qos ? &qos->txtp : NULL,NULL)) return -1;
 	    break;
 	case 1:
 	    text -= 2;
@@ -160,7 +165,7 @@
     }
     if (!*text) return 0;
     if (fetch(&text,"rx",NULL)) return -1;
-    if (!fetch(&text,":none",NULL)) qos->rxtp.traffic_class = ATM_NONE;
-    else if (params(&text,&qos->rxtp,NULL)) return -1;
+    if (!fetch(&text,":none",NULL) && qos) qos->rxtp.traffic_class = ATM_NONE;
+    else if (params(&text,qos ? &qos->rxtp : NULL,NULL)) return -1;
     return *text ? -1 : 0;
 }
diff -ur --new-file old/atm/man/Makefile new/atm/man/Makefile
--- old/atm/man/Makefile	Wed Oct 16 10:37:07 1996
+++ new/atm/man/Makefile	Mon Oct 21 09:24:43 1996
@@ -3,3 +3,6 @@
 include ../Rules.make
 
 all:
+
+depend:
+	@
diff -ur --new-file old/atm/mkdist new/atm/mkdist
--- old/atm/mkdist	Wed Oct 16 22:17:49 1996
+++ new/atm/mkdist	Wed Nov 13 23:40:23 1996
@@ -71,6 +71,7 @@
     atm/lib/atmd.h atm/lib/common.c atm/lib/diag.c \
     atm/lib/timer.c atm/lib/arequipa.h atm/lib/arequipa.c \
     atm/lib/text2qos.c atm/lib/qos2text.c atm/lib/qosequal.c \
+    atm/lib/atmres.h atm/lib/ans.c \
   atm/led/USAGE atm/led/COPYRIGHT.DEC atm/led/COPYRIGHT.TUT \
     atm/led/lec.h atm/led/lec_arp.h atm/led/lec_ctrl.h atm/led/emask.h \
     atm/led/le_disp.h atm/led/g_event.h \
@@ -98,6 +99,8 @@
     atm/lane/units.h \
   atm/aqd/Makefile atm/aqd/arequipad.c atm/aqd/io.h atm/aqd/io.c \
     atm/aqd/arequipad.8 \
+  atm/extra/extra.html atm/extra/Makefile atm/extra/tcpdump-3.0.4-1.patch \
+    atm/extra/bind-4.9.5-REL.patch atm/extra/hosts2ans.pl \
   atm/atm.patch atm/mpr.patch |
   gzip -9 >$ARCHDIR/atm-$VERSION.tar.gz
 #atm/bind-4.9.4.T4B.ATM.patch
diff -ur --new-file old/atm/qgen/Makefile new/atm/qgen/Makefile
--- old/atm/qgen/Makefile	Fri Sep 27 21:55:24 1996
+++ new/atm/qgen/Makefile	Wed Nov  6 19:14:21 1996
@@ -5,7 +5,8 @@
 NLS=atm_ai_msg atm_ai_ie atm_loc atm_cv atm_pu atm_na atm_cond atm_ie qmsg \
   atm_np atm_ton atm_sat atm_prs atm_scrn atm_vpa atm_poe q2931_cs atm_td \
   atm_bc atm_tt atm_tr atm_stc atm_upcc q2931_proto atm_flag atm_aalp atm_tag \
-  atm_l2 atm_l3 atm_hl atm_imd
+  atm_l2 atm_l3 atm_hl atm_imd atm_tdl atm_tni atm_nip atm_shi atm_oci \
+  atm_unfm atm_ofi
 SYMFILES=q2931.h /usr/include/linux/atmsap.h
 TRASH=default.nl
 
diff -ur --new-file old/atm/qgen/q2931.h new/atm/qgen/q2931.h
--- old/atm/qgen/q2931.h	Fri Sep 27 20:16:26 1996
+++ new/atm/qgen/q2931.h	Wed Nov  6 19:10:49 1996
@@ -45,11 +45,14 @@
 
 #define ATM_IE_CAUSE		0x08 /* Cause */
 #define ATM_IE_CALL_STATE	0x14 /* Call state */
+#define ATM_IE_NOTIFY		0x27 /* Notification indicator */
+#define ATM_IE_E2E_TD		0x42 /* End-to-end transit delay */
 #define ATM_IE_EPR		0x54 /* Endpoint reference */
 #define ATM_IE_EP_STATE		0x55 /* Endpoint state */
 #define ATM_IE_AAL		0x58 /* ATM adaption layer parameters */
 #define ATM_IE_TD		0x59 /* ATM traffic descriptor */
 #define ATM_IE_CONN_ID		0x5a /* Connection identifier */
+#define ATM_IE_OAM_TD		0x5b /* OAM traffic descriptor */
 #define ATM_IE_QOS		0x5c /* Quality of service parameter */
 #define ATM_IE_BHLI		0x5d /* Broadband high layer information */
 #define ATM_IE_BBCAP		0x5e /* Broadband bearer capability */
@@ -300,6 +303,44 @@
 #define ATM_AALP_BW_MAX_SDU	0x81 /* Backward maximum CPCS-SDU size */
 #define ATM_AALP_AAL_MODE	0x83 /* AAL mode (UNI 3.0 only) */
 #define ATM_AALP_SSCS		0x84 /* SSCS type */
+
+/* Transit delay identifiers */
+
+#define ATM_TDL_CUM		0x01 /* Cumulative transit delay value */
+#define ATM_TDL_E2EMAX		0x03 /* Maximum end-to-end transit delay value*/
+
+/* Transit network identification */
+
+#define ATM_TNI_USER		0x00 /* User-specified */
+#define ATM_TNI_NNI		0x02 /* National network identification */
+#define ATM_TNI_INI		0x04 /* International network identification */
+
+/* Network identification plan */
+
+#define ATM_NIP_UNKNOWN		0x00 /* Unknown */
+#define ATM_NIP_CARRIER		0x01 /* Carrier identification code */
+#define ATM_NIP_DATA		0x03 /* Data network id. code (X.121) */
+
+/* Shaping indicator */
+
+#define ATM_SHI_NONE		0x00 /* No user specified requirement */
+#define ATM_SHI_NOAGG		0x01 /* Aggr. shaping of user & OAM not all. */
+
+/* Compliance indicator */
+
+#define ATM_OCI_OPT		0x00 /* Use of e2e OAM F5 flow is optional */
+#define ATM_OCI_MAND		0x01 /* Use of e2e OAM F5 flow is mandatory */
+
+/* User-network fault management indicator */
+
+#define ATM_UNFM_NONE		0x00 /* No user-orig. fault mg. indications */
+#define ATM_UNFM_1CPS		0x01 /* Use of u-o fm. ind. w/ rate 1 cps */
+
+/* End-to-end OAM F5 flow indicator */
+
+#define ATM_OFI_0_0		0x00 /* 0% of cell rate (CLP=0+1) in ATM TD */
+#define ATM_OFI_0_1		0x01 /* 0.1% of cell rate (CLP=0+1) in ATM TD */
+#define ATM_OFI_1_0		0x04 /* 1% of cell rate (CLP=0+1) in ATM TD */
 
 /* The following constants tag message parser errors. */
 
diff -ur --new-file old/atm/saal/sscop.c new/atm/saal/sscop.c
--- old/atm/saal/sscop.c	Tue Sep 17 15:50:19 1996
+++ new/atm/saal/sscop.c	Wed Nov 13 23:19:31 1996
@@ -707,7 +707,7 @@
 
 static void initialize_vr_mr(SSCOP_DSC *dsc)
 {
-    dsc->vr_mr = MOD24(dsc->vr_h+SSCOP_CF_MR);
+    dsc->vr_mr = SSCOP_CF_MR; /* was MOD24(dsc->vr_h+SSCOP_CF_MR); */
 }
 
 
@@ -868,7 +868,7 @@
 	    emit_pdu(dsc,buf);
 	    buf2->extra = dsc->vt_ps;
 #ifdef POLL_AFTER_RETRANSMISSION
-	    if (!queue_peek(dsc->rt_q))
+	    if (queue_peek(dsc->rt_q))
 		/* fall through to goto */
 #endif
 	    goto B; /* sigh ... */
@@ -1293,7 +1293,7 @@
 		    bad_pdu(dsc,type);
 		    next_state(dsc,sscop_idle);
 		    if (dsc->ops->rel_ind)
-			dsc->ops->rel_ind(dsc->user,NULL,0,1);
+			dsc->ops->rel_ind(dsc->user,NULL,0,0);
 		    return 0;
 		case SSCOP_SD:
 		case SSCOP_USTAT:
diff -ur --new-file old/atm/test/ttcp.c new/atm/test/ttcp.c
--- old/atm/test/ttcp.c	Thu Oct 10 18:39:03 1996
+++ new/atm/test/ttcp.c	Mon Nov  4 13:02:41 1996
@@ -135,12 +135,19 @@
 	-d	set SO_DEBUG socket option\n\
 	-b ##	set socket buffer size (if supported)\n\
 	-f X	format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga\n\
+	-a	use native ATM instead of UDP/TCP\n\
 Options specific to -t:\n\
 	-n##	number of source bufs written to network (default 2048)\n\
 	-D	don't buffer TCP writes (sets TCP_NODELAY socket option)\n\
+	-C	disable (UDP) checksums\n\
+	-P X	use the specified QOS for the ATM connection. If X is only\n\
+		a number, the following QOS spec is assumed: cbr:pcr=X\n\
+	-Q X	establish an Arequipa connection to ATM destination X\n\
 Options specific to -r:\n\
 	-B	for -s, only output full blocks as specified by -l (for TAR)\n\
 	-T	\"touch\": access each byte as it's read\n\
+	-Q X	enable acceptance of incoming Arequipa connections\n\
+		X can be any word.\n\
 ";	
 
 char stats[128];