diff -ur --new-file old/atm/BUGS new/atm/BUGS
--- old/atm/BUGS	Thu Apr 10 11:58:54 1997
+++ new/atm/BUGS	Tue Apr 22 23:35:06 1997
@@ -1,3 +1,8 @@
+Known bugs and restrictions in version 0.31
+===========================================
+
+ - like in 0.30
+
 Known bugs and restrictions in version 0.30
 ===========================================
 
diff -ur --new-file old/atm/CHANGES new/atm/CHANGES
--- old/atm/CHANGES	Thu Apr 10 12:53:01 1997
+++ new/atm/CHANGES	Tue Apr 22 23:36:23 1997
@@ -1,3 +1,30 @@
+Version 0.30 to 0.31 (22-APR-1997)
+====================
+
+Bug fixes
+---------
+
+ - atmarpd even refused IP address changes by the ATMARP server, which
+   typically led to the creation of one extra SVC
+ - ATMARP timeouts were computed at the wrong place (found by Gerald Hanusch)
+ - aqtest's usage didn't mention the -v option
+ - some tools used 0x%p instead of %p (which is fine in the kernel, by the way)
+ - skb_migrate didn't update skb->list
+ - zeppelin: incurred spurious core dumps on unsuccessful attempts to connect
+   to LANE servers, ESI parsing from command line seg faulted, obtaining ESI
+   from NIC left an ATM socket hanging, man page didn't describe all options
+   (by Marko Kiiskila and Heikki Vatiainen)
+
+Other changes
+-------------
+
+ - arequipa_close now only returns after the Arequipa connection has been
+   successfully closed. This allows applications to reliably close and
+   re-create Arequipa SVCs, e.g. to change the traffic parameters.
+ - the arequipad operations 3rd party close and synchronization are now handled
+   inside the kernel and survive arequipad restarts
+
+
 Version 0.29 to 0.30 (10-APR-1997)
 ====================
 
diff -ur --new-file old/atm/README new/atm/README
--- old/atm/README	Thu Apr 10 12:10:21 1997
+++ new/atm/README	Tue Apr 22 23:31:27 1997
@@ -1,4 +1,4 @@
-ATM on Linux, release 0.30 (pre-alpha) by Werner Almesberger, EPFL LRC
+ATM on Linux, release 0.31 (pre-alpha) by Werner Almesberger, EPFL LRC
 ====================================== werner.almesberger@lrc.di.epfl.ch
 
 This is experimental software. There are known major bugs and certainly
diff -ur --new-file old/atm/USAGE new/atm/USAGE
--- old/atm/USAGE	Thu Apr 10 12:53:55 1997
+++ new/atm/USAGE	Tue Apr 22 23:36:53 1997
@@ -1,4 +1,4 @@
-Usage instructions  -  ATM on Linux, release 0.30 (pre-alpha)
+Usage instructions  -  ATM on Linux, release 0.31 (pre-alpha)
 -------------------------------------------------------------
 
 For updates of ATM on Linux, please check the Web page at  
@@ -17,12 +17,12 @@
 In order to install this package, you need 
 
   - the package itself  
-    ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.30.tar.gz  
+    ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.31.tar.gz  
   - the Linux kernel, version 2.0.25, e.g. from  
     ftp://ftp.cs.helsinki.fi/pub/Software/Linux/Kernel/v2.0/linux-2.0.25.tar.gz  
   - Perl, version 4 or 5 
-  - if you want memory debugging: MPR version 1.5, e.g. from  
-    ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/mpr-1.5.tar.gz  
+  - if you want memory debugging: MPR version 1.6, e.g. from  
+    ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/mpr-1.6.tar.gz  
 
 
 The source tree
@@ -33,7 +33,7 @@
 all the files listed above there. Then extract the ATM on Linux 
 distribution:
 
-tar xfz atm-0.30.tar.gz
+tar xfz atm-0.31.tar.gz
 
 and the kernel source:
 
@@ -145,10 +145,10 @@
 ----------------
 
 If you want to enable debugging for options for memory allocations, you 
-need to install MPR before compiling the ATM tools. Extract mpr-1.5.tar.gz 
+need to install MPR before compiling the ATM tools. Extract mpr-1.6.tar.gz 
 into a directory at the same level as linux and atm. Then do:
 
-cd mpr-1.5
+cd mpr-1.6
 ./configure x86-linux
 make
 install -c -m 0644 libmpr.a /usr/lib
diff -ur --new-file old/atm/VERSION new/atm/VERSION
--- old/atm/VERSION	Thu Apr 10 12:10:00 1997
+++ new/atm/VERSION	Tue Apr 22 23:31:03 1997
@@ -1 +1 @@
-0.30
+0.31
diff -ur --new-file old/atm/aqd/io.c new/atm/aqd/io.c
--- old/atm/aqd/io.c	Tue Mar 11 11:52:03 1997
+++ new/atm/aqd/io.c	Tue Apr 22 15:09:42 1997
@@ -75,20 +75,39 @@
 
 static void recv_kernel(void)
 {
-    struct atm_vcc *vcc;
+#if 0
+    struct arequipa_msg msg;
     int size;
 
-    size = read(kernel,&vcc,sizeof(vcc));
+    size = read(kernel,&msg,sizeof(msg));
     if (size < 0) {
 	diag(COMPONENT,DIAG_ERROR,"read kernel: %s",strerror(errno));
 	return;
     }
-    if (size != sizeof(vcc))
+    if (size != sizeof(msg))
 	diag(COMPONENT,DIAG_FATAL,"kernel message has bad size (%d != %d)",
-	  size,sizeof(vcc));
-    diag(COMPONENT,DIAG_DEBUG,"Closing socket 0x%08lx",(unsigned long) vcc);
-    if (ioctl(kernel,AREQUIPA_CLS3RD,(unsigned long) vcc) < 0)
-	diag(COMPONENT,DIAG_ERROR,"ioctl AREQUIPA_CLS3RD: %s",strerror(errno));
+	  size,sizeof(msg));
+    switch (msg.type) {
+	case amt_close:
+	    diag(COMPONENT,DIAG_DEBUG,"Closing socket %p",msg.ptr);
+	    if (ioctl(kernel,AREQUIPA_CLS3RD,(unsigned long) msg.ptr) < 0)
+		diag(COMPONENT,DIAG_ERROR,"ioctl AREQUIPA_CLS3RD: %s",
+		  strerror(errno));
+	    break;
+	case amt_sync:
+	    diag(COMPONENT,DIAG_DEBUG,"Synchronizing with %p",msg.ptr);
+	    if (ioctl(kernel,AREQUIPA_SYNCACK,(unsigned long) msg.ptr) < 0)
+		diag(COMPONENT,DIAG_ERROR,"ioctl AREQUIPA_SYNCACK: %s",
+		  strerror(errno));
+	    break;
+	default:
+	    diag(COMPONENT,DIAG_FATAL,"unrecognized message type %d",
+	      (int) msg.type);
+    }
+#else
+    if (ioctl(kernel,AREQUIPA_WORK,0) < 0)
+	diag(COMPONENT,DIAG_ERROR,"ioctl AREQUIPA_WORK: %s",strerror(errno));
+#endif
 }
 
 
diff -ur --new-file old/atm/arpd/arp.c new/atm/arpd/arp.c
--- old/atm/arpd/arp.c	Tue Apr  8 13:23:23 1997
+++ new/atm/arpd/arp.c	Thu Apr 10 19:27:00 1997
@@ -476,8 +476,8 @@
 	if (vcc) {
 	    entry = vcc->entry;
 	    if (!entry->itf) Q_REMOVE(unknown_incoming,entry);
-	    else if (entry->ip && entry->ip != ip && (entry->flags & ATF_PERM))
-		  {
+	    else if (entry->ip && entry->ip != ip && (entry->flags & ATF_PERM)
+		  && !(entry->flags & ATF_ARPSRV)) {
 		    diag(COMPONENT,DIAG_ERROR,"ignoring attempt to change IP "
 		      "address of permanent entry (to %d.%d.%d.%d)",ipp[0],
 		      ipp[1],ipp[2],ipp[3]);
diff -ur --new-file old/atm/atm-0.30-1.spec new/atm/atm-0.30-1.spec
--- old/atm/atm-0.30-1.spec	Thu Apr 10 12:56:09 1997
+++ new/atm/atm-0.30-1.spec	Thu Jan  1 01:00:00 1970
@@ -1,138 +0,0 @@
-Summary:	ATM (Asynchronous Transfer Mode)
-Name:		atm
-Version:	0.30
-Release:	1
-Source:		atm-0.30.tar.gz
-Source:		lrcftp.epfl.ch:/pub/linux/atm/dist/atm-0.30.tar.gz
-Copyright:	distributable
-Group:		Networking/ATM
-ExclusiveArch:	i386
-ExclusiveOS:	Linux
-
-%description
-Programs, libraries, and configuration files required for using ATM
-on Linux. Note that you still need to patch your kernel.
-
-%package ans
-Summary:	ANS (ATM Name Server)
-Group:		Networking/ATM
-
-%description ans
-ANS is a version of BIND with extensions for ATM. This package contains
-the complete BIND distribution, including tools like nslookup and dig.
-
-%prep
-
-%setup -n atm
-
-%build
-make
-cd extra
-make tcpdump
-make ans
-
-%install
-INSTPREFIX=/usr make -e
-cd config/redhat-4.0
-make install
-cd ../../extra
-INSTPREFIX=/usr make -e install
-
-%files ans
-/usr/lib/libresolv.a
-/usr/include/arpa/inet.h
-/usr/include/arpa/nameser.h
-/usr/include/netdb.h
-/usr/include/resolv.h
-/usr/include/sys/bitypes.h
-/usr/lib/lib44bsd.a
-/usr/sbin/named
-/usr/sbin/named-xfer
-/usr/sbin/named.restart
-/usr/sbin/named.reload
-/usr/sbin/ndc
-/usr/bin/nslookup
-/usr/lib/nslookup.help
-/usr/bin/host
-/usr/bin/dig
-/usr/bin/dnsquery
-/usr/bin/addr
-/usr/man/man1/dig.1
-/usr/man/man1/host.1
-/usr/man/man1/dnsquery.1
-/usr/man/man8/named.8
-/usr/man/man8/named.reload.8
-/usr/man/man8/named.restart.8
-/usr/man/man8/ndc.8
-/usr/man/man8/named-xfer.8
-/usr/man/man8/nslookup.8
-/usr/man/man3/gethostbyname.3
-/usr/man/man3/resolver.3
-/usr/man/man3/getnetent.3
-/usr/man/man5/resolver.5
-/usr/man/man7/hostname.7
-/usr/man/man7/mailaddr.7
-
-%files
-%doc README
-%doc USAGE
-%config /etc/sysconfig/atm
-%config /etc/atmsigd.conf
-%config /etc/sysconfig/network-scripts/ifcfg-atm0
-%config /etc/sysconfig/network-scripts/ifup-atm
-%config /etc/hosts.atm
-/usr/sbin/tcpdump
-/usr/lib/libatm.a
-/usr/lib/libatmd.a
-/usr/lib/libarequipa.a
-/usr/include/atm.h
-/usr/include/atmd.h
-/usr/include/atmsap.h
-/usr/include/arequipa.h
-/usr/sbin/atmaddr
-/usr/sbin/atmtcp
-/usr/sbin/zntune
-/usr/bin/atmdiag
-/usr/bin/atmdump
-/usr/bin/sonetdiag
-/usr/man/man8/atmaddr.8
-/usr/man/man8/atmdiag.8
-/usr/man/man8/atmdump.8
-/usr/man/man8/atmtcp.8
-/usr/sbin/clip
-/usr/sbin/atmarp
-/usr/man/man8/clip.8
-/usr/man/man8/atmarp.8
-/usr/bin/aping
-/usr/bin/aread
-/usr/bin/awrite
-/usr/bin/br
-/usr/bin/bw
-/usr/bin/ttcp_atm
-/usr/bin/window
-/usr/sbin/delay
-/usr/sbin/aqtest
-/usr/sbin/ed
-/usr/sbin/encopy
-/usr/sbin/endump
-/usr/sbin/zndump
-/usr/sbin/znth
-/usr/sbin/atmsigd
-/usr/man/man4/atmsigd.conf.4
-/usr/man/man8/atmsigd.8
-/usr/sbin/atmarpd
-/usr/man/man8/atmarpd.8
-/usr/sbin/ilmid
-/usr/sbin/zeppelin
-/usr/man/man8/zeppelin.8
-/usr/sbin/les
-/usr/sbin/bus
-/usr/sbin/lecs
-/usr/man/man8/les.8
-/usr/man/man8/lecs.8
-/usr/man/man8/bus.8
-/usr/sbin/arequipad
-/usr/sbin/aqpvc
-/usr/man/man8/arequipad.8
-/usr/man/man8/aqpvc.8
-/usr/man/man7/qos.7
diff -ur --new-file old/atm/atm-0.31-1.spec new/atm/atm-0.31-1.spec
--- old/atm/atm-0.31-1.spec	Thu Jan  1 01:00:00 1970
+++ new/atm/atm-0.31-1.spec	Tue Apr 22 23:37:40 1997
@@ -0,0 +1,138 @@
+Summary:	ATM (Asynchronous Transfer Mode)
+Name:		atm
+Version:	0.31
+Release:	1
+Source:		atm-0.31.tar.gz
+Source:		lrcftp.epfl.ch:/pub/linux/atm/dist/atm-0.31.tar.gz
+Copyright:	distributable
+Group:		Networking/ATM
+ExclusiveArch:	i386
+ExclusiveOS:	Linux
+
+%description
+Programs, libraries, and configuration files required for using ATM
+on Linux. Note that you still need to patch your kernel.
+
+%package ans
+Summary:	ANS (ATM Name Server)
+Group:		Networking/ATM
+
+%description ans
+ANS is a version of BIND with extensions for ATM. This package contains
+the complete BIND distribution, including tools like nslookup and dig.
+
+%prep
+
+%setup -n atm
+
+%build
+make
+cd extra
+make tcpdump
+make ans
+
+%install
+INSTPREFIX=/usr make -e
+cd config/redhat-4.0
+make install
+cd ../../extra
+INSTPREFIX=/usr make -e install
+
+%files ans
+/usr/lib/libresolv.a
+/usr/include/arpa/inet.h
+/usr/include/arpa/nameser.h
+/usr/include/netdb.h
+/usr/include/resolv.h
+/usr/include/sys/bitypes.h
+/usr/lib/lib44bsd.a
+/usr/sbin/named
+/usr/sbin/named-xfer
+/usr/sbin/named.restart
+/usr/sbin/named.reload
+/usr/sbin/ndc
+/usr/bin/nslookup
+/usr/lib/nslookup.help
+/usr/bin/host
+/usr/bin/dig
+/usr/bin/dnsquery
+/usr/bin/addr
+/usr/man/man1/dig.1
+/usr/man/man1/host.1
+/usr/man/man1/dnsquery.1
+/usr/man/man8/named.8
+/usr/man/man8/named.reload.8
+/usr/man/man8/named.restart.8
+/usr/man/man8/ndc.8
+/usr/man/man8/named-xfer.8
+/usr/man/man8/nslookup.8
+/usr/man/man3/gethostbyname.3
+/usr/man/man3/resolver.3
+/usr/man/man3/getnetent.3
+/usr/man/man5/resolver.5
+/usr/man/man7/hostname.7
+/usr/man/man7/mailaddr.7
+
+%files
+%doc README
+%doc USAGE
+%config /etc/sysconfig/atm
+%config /etc/atmsigd.conf
+%config /etc/sysconfig/network-scripts/ifcfg-atm0
+%config /etc/sysconfig/network-scripts/ifup-atm
+%config /etc/hosts.atm
+/usr/sbin/tcpdump
+/usr/lib/libatm.a
+/usr/lib/libatmd.a
+/usr/lib/libarequipa.a
+/usr/include/atm.h
+/usr/include/atmd.h
+/usr/include/atmsap.h
+/usr/include/arequipa.h
+/usr/sbin/atmaddr
+/usr/sbin/atmtcp
+/usr/sbin/zntune
+/usr/bin/atmdiag
+/usr/bin/atmdump
+/usr/bin/sonetdiag
+/usr/man/man8/atmaddr.8
+/usr/man/man8/atmdiag.8
+/usr/man/man8/atmdump.8
+/usr/man/man8/atmtcp.8
+/usr/sbin/clip
+/usr/sbin/atmarp
+/usr/man/man8/clip.8
+/usr/man/man8/atmarp.8
+/usr/bin/aping
+/usr/bin/aread
+/usr/bin/awrite
+/usr/bin/br
+/usr/bin/bw
+/usr/bin/ttcp_atm
+/usr/bin/window
+/usr/sbin/delay
+/usr/sbin/aqtest
+/usr/sbin/ed
+/usr/sbin/encopy
+/usr/sbin/endump
+/usr/sbin/zndump
+/usr/sbin/znth
+/usr/sbin/atmsigd
+/usr/man/man4/atmsigd.conf.4
+/usr/man/man8/atmsigd.8
+/usr/sbin/atmarpd
+/usr/man/man8/atmarpd.8
+/usr/sbin/ilmid
+/usr/sbin/zeppelin
+/usr/man/man8/zeppelin.8
+/usr/sbin/les
+/usr/sbin/bus
+/usr/sbin/lecs
+/usr/man/man8/les.8
+/usr/man/man8/lecs.8
+/usr/man/man8/bus.8
+/usr/sbin/arequipad
+/usr/sbin/aqpvc
+/usr/man/man8/arequipad.8
+/usr/man/man8/aqpvc.8
+/usr/man/man7/qos.7
diff -ur --new-file old/atm/atm.patch new/atm/atm.patch
--- old/atm/atm.patch	Thu Apr 10 13:15:43 1997
+++ new/atm/atm.patch	Tue Apr 22 23:38:51 1997
@@ -751,7 +751,7 @@
 +
 +#endif
 --- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/drivers/atm/eni.c	Thu Apr 10 13:05:46 1997
++++ work/drivers/atm/eni.c	Thu Apr 17 18:09:14 1997
 @@ -0,0 +1,1958 @@
 +/* drivers/atm/eni.c - Efficient Networks ENI155P device driver */
 + 
@@ -10966,7 +10966,7 @@
 +
 +#endif
 --- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/atmclip.h	Wed Apr  2 22:38:55 1997
++++ work/include/linux/atmclip.h	Wed Apr 16 16:31:38 1997
 @@ -0,0 +1,37 @@
 +/* atmclip.h - Classical IP over ATM */
 + 
@@ -11762,8 +11762,8 @@
 +	return CLIP(dev)->number;
 +}
 --- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/common.c	Tue Mar 11 22:47:15 1997
-@@ -0,0 +1,949 @@
++++ work/net/atm/common.c	Tue Apr 22 15:03:58 1997
+@@ -0,0 +1,957 @@
 +/* net/atm/common.c - ATM sockets (common part for PVC and SVC) */
 +
 +/* Written 1995-1997 by Werner Almesberger, EPFL LRC */
@@ -12458,6 +12458,14 @@
 +			if (!suser()) return -EPERM;
 +			arequipa_close_vcc((struct atm_vcc *) arg);
 +			return 0;
++		case AREQUIPA_SYNCACK:
++			if (!suser()) return -EPERM;
++			wake_up((struct wait_queue **) arg);
++			return 0;
++		case AREQUIPA_WORK:
++			if (!suser()) return -EPERM;
++			arequipa_work();
++			return 0;
 +#endif
 +#ifdef CONFIG_ATM_LANE
 +                case ATMLEC_CTRL:
@@ -13972,7 +13980,7 @@
 +
 +#endif
 --- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/atmarp.c	Thu Apr 10 12:13:13 1997
++++ work/net/atm/atmarp.c	Wed Apr 16 16:31:04 1997
 @@ -0,0 +1,635 @@
 +/* atmarp.c - RFC1577 ATM ARP */
 +
@@ -14336,7 +14344,6 @@
 +	entry = new_entry(timeout);
 +	if (!entry) return -ENOMEM;
 +	attach_entry(vcc,entry);
-+	idle_timer_check(0);
 +	return 0;
 +}
 +
@@ -14406,6 +14413,7 @@
 +	PRIV(AE(vcc)->dev)->table = AE(vcc);
 +	restore_flags(flags);
 +	if (queued) clip_xmit(queued,route->rt_dev);
++	idle_timer_check(0);
 +	return 0;
 +}
 +
@@ -14666,7 +14674,7 @@
 +
 +#endif
 --- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/ipcommon.h	Thu Apr 10 09:16:09 1997
++++ work/net/atm/ipcommon.h	Wed Apr 16 16:40:30 1997
 @@ -0,0 +1,74 @@
 +/* net/atm/ipcommon.h - Common items for all ways of doing IP over ATM */
 +
@@ -14743,8 +14751,8 @@
 +
 +#endif
 --- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/ipcommon.c	Thu Apr 10 10:39:03 1997
-@@ -0,0 +1,232 @@
++++ work/net/atm/ipcommon.c	Tue Apr 22 15:21:04 1997
+@@ -0,0 +1,234 @@
 +/* net/atm/ipcommon.c - Common items for all ways of doing IP over ATM */
 +
 +/* Written 1996,1997 by Werner Almesberger, EPFL LRC */
@@ -14969,8 +14977,10 @@
 +
 +void skb_migrate(struct sk_buff_head *from,struct sk_buff_head *to)
 +{
-+	struct sk_buff *prev;
++	struct sk_buff *skb,*prev;
 +
++	for (skb = ((struct sk_buff *) from)->next;
++	    skb != (struct sk_buff *) from; skb = skb->next) skb->list = to;
 +	prev = from->prev;
 +	from->next->prev = (struct sk_buff *) to;
 +	prev->next = (struct sk_buff *) to;
@@ -14978,8 +14988,8 @@
 +	skb_queue_head_init(from);
 +}
 --- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/net/atm/arequipa.c	Thu Apr 10 12:13:20 1997
-@@ -0,0 +1,452 @@
++++ work/net/atm/arequipa.c	Tue Apr 22 15:43:19 1997
+@@ -0,0 +1,509 @@
 +/* net/atm/arequipa.c - Application requested IP over ATM */
 + 
 +/* Written 1996,1997 by Jean-Michel Pittet and Werner Almesberger, EPFL LRC */
@@ -14999,6 +15009,8 @@
 +#include <linux/atmclip.h>
 +#include <linux/arequipa.h>
 +#include <linux/route.h>
++#include <linux/wait.h> /* for struct wait_queue */
++#include <linux/sched.h> /* for sleep_on */
 +#include <net/sock.h>
 +#include <netinet/in.h>
 +#include <asm/system.h> /* cli and such */
@@ -15041,6 +15053,8 @@
 +
 +static struct atm_vcc *aq_list = NULL; /* dangling Arequipa VCs */
 +static unsigned long aq_generation = 0;
++static struct sk_buff_head pending; /* pending Arequipa messages */
++static atomic_t pending_inuse;
 +
 +
 +static void arequipa_unuse(struct atm_vcc *vcc)
@@ -15070,25 +15084,29 @@
 + */
 +
 +
-+static void aqd_enq(struct atm_vcc *vcc)
++static void aqd_enq(enum arequipa_msg_type type,void *ptr)
 +{
 +	struct sk_buff *skb;
 +
-+	if (!aqd) {
-+		printk(KERN_CRIT "aqd_enq: no Arequipa demon\n");
-+		return;
-+	}
-+	skb = alloc_skb(sizeof(vcc),GFP_ATOMIC);
++	if (!aqd) printk(KERN_WARNING "aqd_enq: no Arequipa demon\n");
++	skb = alloc_skb(sizeof(struct arequipa_msg),GFP_ATOMIC);
 +	if (!skb) {
-+		printk(KERN_CRIT "adq_enq: out of memory\n");
++		printk(KERN_CRIT "aqd_enq: out of memory\n");
 +		return;
 +	}
 +	skb->free = 1;
-+	skb->len = sizeof(vcc);
-+	*(struct atm_vcc **) skb->data = vcc;
-+	atomic_add(skb->truesize+ATM_PDU_OVHD,&aqd->rx_inuse);
-+	skb_queue_tail(&aqd->recvq,skb);
-+	wake_up(&aqd->sleep);
++	skb->len = sizeof(struct arequipa_msg);
++	((struct arequipa_msg *) skb->data)->type = type;
++	((struct arequipa_msg *) skb->data)->ptr = ptr;
++	if (aqd) {
++		atomic_add(skb->truesize+ATM_PDU_OVHD,&aqd->rx_inuse);
++		skb_queue_tail(&aqd->recvq,skb);
++		wake_up(&aqd->sleep);
++	}
++	else {
++		atomic_add(skb->truesize+ATM_PDU_OVHD,&pending_inuse);
++		skb_queue_tail(&pending,skb);
++	}
 +}
 +
 +
@@ -15106,7 +15124,8 @@
 +	upper->ip_route_cache = NULL;
 +	upper->arequipa = NULL;
 +	ATM_SD(lower)->upper = NULL;
-+	if (!(ATM_SD(lower)->flags & ATM_VF_AQREL)) aqd_enq(ATM_SD(lower));
++	if (!(ATM_SD(lower)->flags & ATM_VF_AQREL))
++		aqd_enq(amt_close,ATM_SD(lower));
 +	ATM_SD(lower)->flags |= ATM_VF_AQREL;
 +	restore_flags(flags);
 +	return 0;
@@ -15203,7 +15222,7 @@
 +	restore_flags(flags);
 +	lower->file->f_count++;
 +	/* re-process everything received between connection setup and
-+	   AREQUIPA_INCOMING*/
++	   AREQUIPA_INCOMING */
 +	while ((skb = skb_dequeue(&copy))) atm_push_arequipa(vcc,skb);
 +}
 +
@@ -15367,21 +15386,26 @@
 +	arequipa_dev->init = arequipa_init;
 +	arequipa_rt.rt_dev = arequipa_dev;
 +	arequipa_init(arequipa_dev);
++	skb_queue_head_init(&pending);
++	pending_inuse = 0;
 +	return 0;
 +}
 +
 +
 +static void aqd_close(struct atm_vcc *vcc)
 +{
-+        struct sk_buff *skb;
++	unsigned long flags;
 +
 +        DPRINTK("aqd_close\n");
++	save_flags(flags);
++	cli();
 +        aqd = NULL; /* assumed to be atomic */
-+	barrier();
-+        if (skb_peek(&vcc->recvq))
++	skb_migrate(&vcc->recvq,&pending);
++	pending_inuse = vcc->rx_inuse;
++	restore_flags(flags);
++        if (skb_peek(&pending))
 +                printk(KERN_CRIT "aqd_close: closing with requests "
 +		    "pending\n");
-+        while ((skb = skb_dequeue(&vcc->recvq))) kfree_skb(skb,FREE_READ);
 +}
 +
 +
@@ -15415,7 +15439,11 @@
 +
 +int arequipad_attach(struct atm_vcc *vcc)
 +{
++	unsigned long flags;
++
 +	if (aqd) return -EADDRINUSE;
++	save_flags(flags);
++	cli();
 +	aqd = vcc;
 +	vcc->flags |= ATM_VF_READY | ATM_VF_META;
 +	    /* allow replies and avoid getting closed if signaling dies */
@@ -15425,13 +15453,52 @@
 +	vcc->peek = NULL; /* crash */
 +	vcc->pop = NULL; /* crash */
 +	vcc->push_oam = NULL; /* crash */
-+	/*
-+	 * Now that we have an arequipad, we should check for stale Arequipa
-+	 * connections and prune them. @@@
-+	 */
++	if (skb_peek(&pending)) {
++		skb_migrate(&pending,&vcc->recvq);
++		vcc->rx_inuse = pending_inuse;
++	}
++	restore_flags(flags);
 +        return 0;
 +
 +}
++
++
++void arequipa_synchronize(void)
++{
++	struct wait_queue *wait;
++
++	init_waitqueue(&wait);
++	aqd_enq(amt_sync,&wait);
++	sleep_on(&wait);
++}
++
++
++void arequipa_work(void)
++{
++	struct sk_buff *skb;
++	struct arequipa_msg *msg;
++
++	if (!aqd) {
++		printk(KERN_ERR "arequipa_work invoked but arequipad isn't "
++		    "connected\n");
++		return;
++	}
++	while ((skb = skb_dequeue(&aqd->recvq))) {
++		msg = (struct arequipa_msg *) skb->data;
++		switch (msg->type) {
++			case amt_close:
++				arequipa_close_vcc(msg->ptr);
++				break;
++			case amt_sync:
++				wake_up(msg->ptr);
++				break;
++			default:
++				printk(KERN_ERR "unrecognized Arequipa message"
++				    " type %d\n",(int) msg->type);
++		}
++		atomic_sub(skb->truesize+ATM_PDU_OVHD,&aqd->rx_inuse);
++	}
++}
 --- /dev/null	Mon Jul 18 01:46:18 1994
 +++ work/net/atm/tunable.h	Fri Nov 15 19:06:36 1996
 @@ -0,0 +1,26 @@
@@ -15462,7 +15529,7 @@
 +
 +#endif
 --- ref/net/ipv4/af_inet.c	Fri Oct 18 05:18:54 1996
-+++ work/net/ipv4/af_inet.c	Fri Nov 15 19:06:37 1996
++++ work/net/ipv4/af_inet.c	Thu Apr 17 16:23:27 1997
 @@ -105,6 +105,14 @@
  #include <linux/kerneld.h>
  #endif
@@ -15510,7 +15577,7 @@
  	sk->socket = sock;
  #ifdef CONFIG_TCP_NAGLE_OFF
  	sk->nonagle = 1;
-@@ -1340,7 +1359,18 @@
+@@ -1340,7 +1359,21 @@
  				return((*dlci_ioctl_hook)(cmd, (void *) arg));
  #endif
  			return -ENOPKG;
@@ -15526,6 +15593,9 @@
 +			return arequipa_expect(sk,arg);
 +		case AREQUIPA_CLOSE:
 +			return arequipa_close(sk);
++		case AREQUIPA_SYNCREQ:
++			arequipa_synchronize();
++			return 0;
 +#endif
  		default:
  			if ((cmd >= SIOCDEVPRIVATE) &&
@@ -19417,11 +19487,11 @@
  /*
   *	This part is used for the timeout functions (timer.c). 
 --- /dev/null	Mon Jul 18 01:46:18 1994
-+++ work/include/linux/arequipa.h	Fri Feb 28 14:51:54 1997
-@@ -0,0 +1,46 @@
++++ work/include/linux/arequipa.h	Tue Apr 22 15:04:18 1997
+@@ -0,0 +1,60 @@
 +/* arequipa.h - Arequipa interface definitions */
 + 
-+/* Written 1996 by Jean-Michel Pittet and Werner Almesberger, EPFL LRC */
++/* Written 1996,1997 by Jean-Michel Pittet and Werner Almesberger, EPFL LRC */
 + 
 +
 +#ifndef _LINUX_AREQUIPA_H
@@ -19430,12 +19500,23 @@
 +#include <linux/atmioc.h>
 +
 +
++enum arequipa_msg_type { amt_invalid,amt_close,amt_sync };
++
++struct arequipa_msg {
++	enum arequipa_msg_type type;
++	void *ptr;
++};
++
++
 +#define AREQUIPA_PRESET		_IO('a',ATMIOC_AREQUIPA)
 +#define AREQUIPA_INCOMING	_IO('a',ATMIOC_AREQUIPA+1)
 +#define AREQUIPA_EXPECT		_IO('a',ATMIOC_AREQUIPA+2)
 +#define AREQUIPA_CLOSE		_IO('a',ATMIOC_AREQUIPA+3)
 +#define AREQUIPA_CTRL		_IO('a',ATMIOC_AREQUIPA+4)
 +#define AREQUIPA_CLS3RD		_IO('a',ATMIOC_AREQUIPA+5)
++#define AREQUIPA_SYNCREQ	_IO('a',ATMIOC_AREQUIPA+6)
++#define AREQUIPA_SYNCACK	_IO('a',ATMIOC_AREQUIPA+7)
++#define AREQUIPA_WORK		_IO('a',ATMIOC_AREQUIPA+8)
 +
 +
 +#ifdef __KERNEL__
@@ -19458,9 +19539,12 @@
 +int arequipa_expect(struct sock *upper,int on);
 +int arequipa_incoming(struct socket *lower);
 +int arequipa_close(struct sock *upper);
++void arequipa_synchronize(void);
++void arequipa_work(void);
 +
 +int arequipad_attach(struct atm_vcc *vcc);
 +void arequipa_close_vcc(struct atm_vcc *vcc);
++
 +
 +#endif /* __KERNEL__ */
 +
diff -ur --new-file old/atm/debug/aqtest.c new/atm/debug/aqtest.c
--- old/atm/debug/aqtest.c	Tue Mar 11 22:56:17 1997
+++ new/atm/debug/aqtest.c	Thu Apr 17 15:27:15 1997
@@ -50,8 +50,8 @@
 
 static void usage(const char *name)
 {
-    fprintf(stderr,"usage: %s [-a atm_host[/qos]] [-p port] [host] sequence\n",
-      name);
+    fprintf(stderr,"usage: %s [-a atm_host[/qos]] [-p port] [-v] [host] "
+      "sequence\n",name);
     fprintf(stderr,"sequence consists of the following characters:\n");
     fprintf(stderr,"  a accept (and close listening socket)\n");
     fprintf(stderr,"  b bind\n");
diff -ur --new-file old/atm/debug/endump.c new/atm/debug/endump.c
--- old/atm/debug/endump.c	Thu Feb  6 19:45:53 1997
+++ new/atm/debug/endump.c	Thu Apr 17 17:58:00 1997
@@ -210,7 +210,7 @@
 {
     int i;
 
-    printf("VCI 0x%p\n",base);
+    printf("VCI %p\n",base);
     for (i = 0; i < NR_VCI; i++)
 	if ((base[i*4] >> MID_VCI_MODE_SHIFT) != MID_MODE_TRASH) {
 	    printf("VCI %d\n",i);
@@ -223,7 +223,7 @@
 {
     int i;
 
-    printf("RX DMA 0x%p\n",base);
+    printf("RX DMA %p\n",base);
     for (i = 0; i < NR_DMA_RX; i++) {
 	printf("RX DMA %d\n",i);
 	process(base+i*2,rx_dma);
@@ -235,7 +235,7 @@
 {
     int i;
 
-    printf("TX DMA 0x%p\n",base);
+    printf("TX DMA %p\n",base);
     for (i = 0; i < NR_DMA_TX; i++) {
 	printf("TX DMA %d\n",i);
 	process(base+i*2,tx_dma);
@@ -245,7 +245,7 @@
 
 static void dump_service(unsigned long *base)
 {
-    printf("SERV 0x%p\n",base);
+    printf("SERV %p\n",base);
 }
 
 
diff -ur --new-file old/atm/doc/usage.tex new/atm/doc/usage.tex
--- old/atm/doc/usage.tex	Thu Apr 10 12:10:44 1997
+++ new/atm/doc/usage.tex	Tue Apr 22 23:32:52 1997
@@ -1,7 +1,7 @@
 %%def%:=
 
 %:\begin{verbatim}
-%:Usage instructions  -  ATM on Linux, release 0.30 (pre-alpha)
+%:Usage instructions  -  ATM on Linux, release 0.31 (pre-alpha)
 %:-------------------------------------------------------------
 %:
 %:\end{verbatim}
@@ -38,14 +38,14 @@
 
 \title{ATM on Linux \\
   User's guide \\
-  Release 0.30 (pre-alpha)}
+  Release 0.31 (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{April 10, 1997}
+\date{April 22, 1997}
 
 \begin{document}
 \maketitle
@@ -81,12 +81,12 @@
 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.30.tar.gz}
+    \url{ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.31.tar.gz}
   \item the Linux kernel, version 2.0.25, e.g. from
 \url{ftp://ftp.cs.helsinki.fi/pub/Software/Linux/Kernel/v2.0/linux-2.0.25.tar.gz}
   \item Perl, version 4 or 5
-  \item if you want memory debugging: MPR version 1.5, e.g. from
-    \url{ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/mpr-1.5.tar.gz}
+  \item if you want memory debugging: MPR version 1.6, e.g. from
+    \url{ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/mpr-1.6.tar.gz}
 \end{itemize}
 
 
@@ -98,7 +98,7 @@
 distribution:
 
 \begin{verbatim}
-tar xfz atm-0.30.tar.gz
+tar xfz atm-0.31.tar.gz
 \end{verbatim}
 
 and the kernel source:
@@ -227,11 +227,11 @@
 
 If you want to enable debugging for options for memory allocations, you
 need to install MPR before compiling the ATM tools. Extract
-\path{mpr-1.5.tar.gz} into a directory at the same level as \path{linux}
+\path{mpr-1.6.tar.gz} into a directory at the same level as \path{linux}
 and \path{atm}. Then do:
 
 \begin{verbatim}
-cd mpr-1.5
+cd mpr-1.6
 ./configure x86-linux
 make
 install -c -m 0644 libmpr.a /usr/lib
diff -ur --new-file old/atm/doc/usage.txt new/atm/doc/usage.txt
--- old/atm/doc/usage.txt	Thu Apr 10 12:53:55 1997
+++ new/atm/doc/usage.txt	Tue Apr 22 23:36:53 1997
@@ -1,4 +1,4 @@
-Usage instructions  -  ATM on Linux, release 0.30 (pre-alpha)
+Usage instructions  -  ATM on Linux, release 0.31 (pre-alpha)
 -------------------------------------------------------------
 
 For updates of ATM on Linux, please check the Web page at  
@@ -17,12 +17,12 @@
 In order to install this package, you need 
 
   - the package itself  
-    ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.30.tar.gz  
+    ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.31.tar.gz  
   - the Linux kernel, version 2.0.25, e.g. from  
     ftp://ftp.cs.helsinki.fi/pub/Software/Linux/Kernel/v2.0/linux-2.0.25.tar.gz  
   - Perl, version 4 or 5 
-  - if you want memory debugging: MPR version 1.5, e.g. from  
-    ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/mpr-1.5.tar.gz  
+  - if you want memory debugging: MPR version 1.6, e.g. from  
+    ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/mpr-1.6.tar.gz  
 
 
 The source tree
@@ -33,7 +33,7 @@
 all the files listed above there. Then extract the ATM on Linux 
 distribution:
 
-tar xfz atm-0.30.tar.gz
+tar xfz atm-0.31.tar.gz
 
 and the kernel source:
 
@@ -145,10 +145,10 @@
 ----------------
 
 If you want to enable debugging for options for memory allocations, you 
-need to install MPR before compiling the ATM tools. Extract mpr-1.5.tar.gz 
+need to install MPR before compiling the ATM tools. Extract mpr-1.6.tar.gz 
 into a directory at the same level as linux and atm. Then do:
 
-cd mpr-1.5
+cd mpr-1.6
 ./configure x86-linux
 make
 install -c -m 0644 libmpr.a /usr/lib
diff -ur --new-file old/atm/ip/Makefile new/atm/ip/Makefile
--- old/atm/ip/Makefile	Sun Nov 17 15:43:00 1996
+++ new/atm/ip/Makefile	Tue Apr 22 12:38:25 1997
@@ -1,4 +1,4 @@
-BOOTPGMS=clip atmarp
-MAN8=clip.8 atmarp.8
+BOOTPGMS=atmarp #clip
+MAN8=atmarp.8 #clip.8
 
 include ../Rules.make
diff -ur --new-file old/atm/led/address.c new/atm/led/address.c
--- old/atm/led/address.c	Tue Sep 17 03:09:31 1996
+++ new/atm/led/address.c	Tue Apr 22 21:53:11 1997
@@ -361,6 +361,7 @@
     EVENT(EM_DEBUG,("ioctl failed:%s\n",strerror(errno)));
     return -1;
   }
+  close(fd);
   return 0;
 }
 
diff -ur --new-file old/atm/led/conn.c new/atm/led/conn.c
--- old/atm/led/conn.c	Mon Jan 27 22:09:16 1997
+++ new/atm/led/conn.c	Wed Apr 16 14:17:27 1997
@@ -96,7 +96,6 @@
 
 typedef struct _conn_t_ {
   int fd;                  /* Socket connected to this connection */
-  CONN_INFO *info;
   unsigned long age_limit; /* In seconds. If this SVC is idle (no traffic) 
 			      for longer than the age limit, it will be 
 			      torn down.  If the age limit is specified 
@@ -554,7 +553,7 @@
 void
 conn_call_callbacks(void)
 {
-  Conn_t *conn, *c_tmp;
+  Conn_t *conn;
   Sap_client_t *sap;
   
   conn = connlist;
@@ -581,26 +580,7 @@
       conn = conn->next;
     } else if (conn->status == RELEASED) {
       EVENT(EM_DEBUG,("Conn_call_callbacks, released conn %p\n",conn));
-#if 0
-      conn->status = NOTIFIED;
-      sap = (Sap_client_t *)conn->sap_handle;
-      sap->vc_notify_callback(conn->conn_context,
-			      conn,
-			      CONN_RELEASE,
-			      CAUSE_NORMAL,
-			      0,
-			      (conn->type==WEMADE)?TRUE:FALSE);
-      c_tmp=conn->next;
-      close(conn->fd);
-      /* Remove conn from list */
-      list_remove_conn(conn);
-      if (conn->conn_info)
-	mem_free(EINST, conn->conn_info);
-      mem_free(EINST,conn);
-      conn=c_tmp;
-#endif
       conn->status = NOTIFIED;
-      c_tmp = conn->next;
       sap = (Sap_client_t *)conn->sap_handle;
       sap->vc_notify_callback(conn->conn_context,
 			      conn,
@@ -608,7 +588,7 @@
 			      CAUSE_NORMAL,
 			      0,
 			      (conn->type==WEMADE)?TRUE:FALSE);
-      conn=c_tmp;
+      conn=connlist;
     } else {
       conn = conn->next;
     }
@@ -1004,7 +984,6 @@
   
   conn->sap_handle = sap_handle;
   conn->conn_context = conn_context;
-  conn->info = info;
   conn->age_limit = age_limit;
   if (info)
     memcpy(conn->atm_address, info->addr.sas_addr.prv, ATM_ESA_LEN);
diff -ur --new-file old/atm/led/kernel_itf.c new/atm/led/kernel_itf.c
--- old/atm/led/kernel_itf.c	Fri Nov 22 20:12:48 1996
+++ new/atm/led/kernel_itf.c	Wed Apr 16 14:17:27 1997
@@ -60,7 +60,6 @@
 {
   int rvalue;
   struct atmlec_msg msg;
-  struct atmif_sioc req;
 
   lec_socket = socket(PF_ATMSVC, SOCK_DGRAM, 0);
   if (lec_socket <0) {
@@ -73,20 +72,7 @@
     close(lec_socket);
     return -1;
   }
-  if (!mac_addr) {
-    /* If mac address is not given, it is set from ESI */
-    req.number = 0;
-    req.length = ESI_LEN;
-    req.arg = &msg.content.normal.mac_addr;
-    
-    rvalue = ioctl(lec_socket, ATM_GETESI, &req);
-    if (rvalue <0) {
-      EVENT(EM_SERR,("Can't get ESI:%s\n",strerror(errno)));
-      close(lec_socket);
-      return -1;
-    }
-  } else
-    memcpy(&msg.content.normal.mac_addr, mac_addr, ETH_ALEN);
+  memcpy(&msg.content.normal.mac_addr, mac_addr, ETH_ALEN);
 
   msg.type = l_set_mac_addr;
   
diff -ur --new-file old/atm/led/lec_ctrl.c new/atm/led/lec_ctrl.c
--- old/atm/led/lec_ctrl.c	Mon Jan 27 21:45:14 1997
+++ new/atm/led/lec_ctrl.c	Tue Apr 22 17:47:23 1997
@@ -2165,9 +2165,11 @@
    os_timer_dealloc (p_elan->sm_timer);
    os_timer_dealloc (p_elan->reg_timer);
 
+#if 0
    act_bus_svc_teardown (lc_elan_handle);
    act_les_svc_teardown (lc_elan_handle);
    act_lecs_vc_teardown (lc_elan_handle);
+#endif
 
    status = addr_reg_atm_addr_dealloc (p_elan->addr_reg_client_handle,
                                        &p_elan->lec_state.c1_my_atm_addr);
diff -ur --new-file old/atm/led/main.c new/atm/led/main.c
--- old/atm/led/main.c	Wed Nov 27 19:56:05 1996
+++ new/atm/led/main.c	Tue Apr 22 21:34:01 1997
@@ -260,30 +260,65 @@
 usage(const char *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);
+    " [-m mesg_mask] [-l listen_address] [-i interface_number]"
+    " [-q qos_spec]\n",progname);
 }
 
 static int
 esi_convert(char *parsestring, unsigned char *mac_addr)
 {
-  int i, tmp;
-
-  if (strchr(parsestring,'.') ||     /* 00:20:22:23:04:05 */
-      strchr(parsestring,':')) {
-    sscanf(strtok(parsestring,".:"),"%x",&tmp);
-    mac_addr[0] = (unsigned char)tmp;
-    for(i=1;i<6;i++) {
-      sscanf(strtok(NULL,".:"),"%x", &tmp);
-      mac_addr[i] = (unsigned char)tmp;
-    }
-  } else {                           /* 002022230405 */
-    i = strlen(parsestring);
-    if (i != 12)
-      return -1;
-    for(i=0;i<6;i++) {
-      sscanf(&parsestring[i*2],"%2x",&tmp);
-      mac_addr[i]=(unsigned char)tmp;
+  const char *hexchars = "abcdefABCDEF0123456789";
+  char hexnum [17+1], curr;
+  int i = 0, j = -1, hexindex = 0, tmp;
+  char *k, *string;
+
+  if (strchr(parsestring,'.') ||     /* do we have separators like */
+      strchr(parsestring,':')) {     /* 00:20:22:23:04:05 */
+    k = parsestring;
+    for (i = 0; i < strlen(parsestring); i++) {
+      curr = *k;
+      if (curr == ':' || curr == '.') {   /* separator ? */
+        if (i - j == 3) {  /* there were 2 hex characters */
+          ;
+        }
+        else if (i - j == 2) {  /* there was only 1 hex char */
+          hexnum [hexindex] = hexnum [hexindex-1];
+          hexnum [hexindex-1] = '0';
+          hexindex +=1;
+        }
+        else   /* too many hexchars in a byte */
+          return -1;
+        j = i;  /* j is the location of the last separator */
+      }
+      else if (strchr(hexchars, curr) == NULL) /* not a hexchar ? */
+        return -1;
+      else {  /* we have a hex character */
+        hexnum [hexindex] = curr;
+        hexindex +=1;
+      }
+      k++;
     }
+    hexnum [hexindex] = '\0';
+    string = hexnum;
+  }
+  else {   /* no separators */
+    k = parsestring;
+    while (*k != '\0') {
+      if (strchr(hexchars, *k) == NULL)
+	return -1;
+      k++;
+    }
+
+    string = parsestring;
+  }
+
+  /* the esi now looks like 002022230405 */
+  i = strlen(string);
+  if (i != 12)
+    return -1;
+  for(i=0;i<6;i++) {
+    sscanf(&string[i*2],"%2x",&tmp);
+    mac_addr[i]=(unsigned char)tmp;
   }
   return 0;
 }
@@ -626,9 +661,6 @@
        * deregister the le-arp instance.
        */
       lc_deregister(p_elan->lc_elan_handle);
-
-      /* Remove this data block from the LEC instance's list of ELANs. */
-      utl_list_delete (p_context->elan_list, p_elan);
 
       /* Deallocate the ELAN context data block. */
       
diff -ur --new-file old/atm/led/utils.c new/atm/led/utils.c
--- old/atm/led/utils.c	Tue Aug 20 13:44:01 1996
+++ new/atm/led/utils.c	Wed Apr 16 14:17:27 1997
@@ -72,7 +72,11 @@
   MemList_t *tmp;
 
   tmp = (MemList_t *)malloc(sizeof(MemList_t));
+  memset (tmp, 0, sizeof(*tmp));
+
   tmp->mem = malloc(nbytes);
+  memset (tmp->mem, 0, nbytes);
+
   tmp->memsize = nbytes;
   tmp->unit = (char*)malloc(strlen(unit)+1);
   sprintf(tmp->unit,"%s",unit);
diff -ur --new-file old/atm/led/zeppelin.8 new/atm/led/zeppelin.8
--- old/atm/led/zeppelin.8	Mon Nov 11 16:10:28 1996
+++ new/atm/led/zeppelin.8	Wed Apr 16 14:17:27 1997
@@ -47,6 +47,10 @@
 Sometimes one wants to know more what is happening in LE
 daemon e.g. when nothing works. This is a hexadecimal long value
 setting global message mask. 0 = No messages, ffff = All messages.
+.IP \fB\-l\ \fIlisten_address\fP
+Local ATM address that zeppelin uses as local binding point in
+signalling. Use this if you are running more than one client or
+a set of LE servers.
 .IP \fB\-i\ \fIinterface_number\fP
 Linux LEC supports up to 4 network interfaces. This number tells
 zeppelin to which of these to attach. Network interfaces are
diff -ur --new-file old/atm/lib/arequipa.c new/atm/lib/arequipa.c
--- old/atm/lib/arequipa.c	Tue Mar 11 11:58:26 1997
+++ new/atm/lib/arequipa.c	Thu Apr 17 15:09:24 1997
@@ -1,6 +1,6 @@
 /* arequipa.c - AREQUIPA support functions */
  
-/* Written 1996 by Jean-Michel Pittet and Werner Almesberger, EPFL-LRC */
+/* Written 1996,1997 by Jean-Michel Pittet and Werner Almesberger, EPFL-LRC */
 
 
 #include <unistd.h>
@@ -69,5 +69,7 @@
 
 int arequipa_close(int sd)
 {
-    return ioctl(sd,AREQUIPA_CLOSE,0);
+    if (ioctl(sd,AREQUIPA_CLOSE,0) < 0) return -1;
+    return ioctl(sd,AREQUIPA_SYNCREQ,0);
+    
 }
diff -ur --new-file old/atm/lib/sdu2cell.c new/atm/lib/sdu2cell.c
--- old/atm/lib/sdu2cell.c	Thu Jan  4 14:32:45 1996
+++ new/atm/lib/sdu2cell.c	Tue Apr 22 12:25:22 1997
@@ -1,6 +1,6 @@
 /* sdu2cr.c - Converts SDU sizes and SDU counts to cell counts */
 
-/* Written 1996 by Werner Almesberger, EPFL-LRC */
+/* Written 1996,1997 by Werner Almesberger, EPFL-LRC */
 
 
 #include <limits.h>
@@ -11,13 +11,13 @@
 
 int sdu2cell(int s,int sizes,const int *sdu_size,int *num_sdu)
 {
-    unsigned char aal;
+    struct atm_qos qos;
     int trailer,total,cells;
     int size,i;
 
-    size = sizeof(aal);
-    if (getsockopt(s,SOL_AAL,SO_AALTYPE,&aal,&size) < 0) return -1;
-    switch (aal) {
+    size = sizeof(qos);
+    if (getsockopt(s,SOL_AAL,SO_ATMQOS,&qos,&size) < 0) return -1;
+    switch (qos.aal) {
 	case ATM_AAL0:
 	    trailer = 0;
 	    break;
diff -ur --new-file old/atm/sigd/kernel.c new/atm/sigd/kernel.c
--- old/atm/sigd/kernel.c	Wed Mar 26 18:16:10 1997
+++ new/atm/sigd/kernel.c	Thu Apr 17 17:58:07 1997
@@ -355,7 +355,7 @@
 	    if (msg->listen_vcc == curr->id && curr->state == ss_listening)
 		break;
     }
-    diag(COMPONENT,DIAG_DEBUG,"FROM KERNEL: %s for socket 0x%p (0x%lx/0x%lx) "
+    diag(COMPONENT,DIAG_DEBUG,"FROM KERNEL: %s for socket %p (0x%lx/0x%lx) "
       "in state %s",as_name[msg->type],curr,msg->vcc,msg->listen_vcc,
       state_name[curr ? curr->state : ss_null]);
     msg->svc.sas_addr.blli = msg->local.sas_addr.blli = NULL;
diff -ur --new-file old/atm/sigd/proto.c new/atm/sigd/proto.c
--- old/atm/sigd/proto.c	Wed Mar 26 18:18:10 1997
+++ new/atm/sigd/proto.c	Thu Apr 17 17:58:12 1997
@@ -75,14 +75,14 @@
 {
     SOCKET **walk;
 
-    diag(COMPONENT,DIAG_DEBUG,"freeing socket 0x%lx@0x%p",sock->id,sock);
+    diag(COMPONENT,DIAG_DEBUG,"freeing socket 0x%lx@%p",sock->id,sock);
     for (walk = &sockets; *walk != sock; walk = &(*walk)->next);
     if (!*walk)
 	diag(COMPONENT,DIAG_FATAL,
 	  "INTERNAL ERROR: freeing non-existing socket 0x%lx",sock->id);
     *walk = sock->next;
     if (sock->conn_timer) {
-	diag(COMPONENT,DIAG_ERROR,"socket 0x%lx has timer (0x%p) running",
+	diag(COMPONENT,DIAG_ERROR,"socket 0x%lx has timer (%p) running",
 	  sock->id,sock->conn_timer->callback);
 	stop_timer(sock->conn_timer);
     }