diff -ur --new-file old/atm/CHANGES new/atm/CHANGES --- old/atm/CHANGES Sat Nov 16 00:08:57 1996 +++ new/atm/CHANGES Fri Nov 29 18:00:19 1996 @@ -1,3 +1,57 @@ +Version 0.23 to 0.24 (29-NOV-1996) +==================== + +Bug fixes +--------- + + - atm/test/window.c was missing in 0.23 + - atm/debug/delay didn't build unless atm/lib headers were already installed + in /usr/include + - atm/debug/znth had undefined return value + - SSCOP: fixed typo (that could probably kill the SSCOP connection in case of + a retransmission); fix by Olivier Bonaventure + - corrected unnecessarily large buffer allocation in zatm.c:pool_index (by + Jonathan Larmour) + - hosts2ans.pl generated reverse addresses for the domain "ATM.INT" instead of + "ATMA.INT" + - atmarpd "forgot" any pre-set QOS when receiving new ARP information for the + respective entry (reported by Gerald Hanusch) + - window scale didn't scale the window sent in the SYNACK packet (reported by + Juan-Antonio Ibanez) + - LANE: better connection failure handling in zeppelin (by Marko Kiiskila) + - LEC kernel timer wasn't restarted when restarting zeppelin (found by Gerald + Hanusch, fixed by Marko Kiiskila) + - LANE: le_flush_request was sent too early when establishing connection (by + Marko Kiiskila) + - zeppelin stooped operation (unwantedly) in random cases when LANE servers + were down (by Marko Kiiskila) + - LANE: non-blocking connections, VCC and LE ARP timeouts, and TLV fields in + LE_CONFIG_RESPONSE fixed (by Marko Kiiskila) + +New features +------------ + + - atm2text now also uses ANS + - signaling traces now also contain error reports from qgen + - added new build-time configuration option "CISCO" (in atm/Rules.make) to + work around a bug in Cisco's point-to-multipoint signaling + - included example configuration files for RedHat 4.0 (see + atm/config/redhat-4.0/README) + +Other changes +------------- + + - local variable "link" in atm/debug/delay.c:loop was shadowing "link" system + call + - cleaned up various Makefiles + - qgen: bytes left in qet_space are now more meaningful + - named (ANS) now also starts even if atmsigd is not running and retries to + create the ATM socket in 15 minute intervals until is succeeds (by Marko + Kiiskila) + - LANE: (too) short le_flush_responses (Cisco 7010, sw ??.??) are now handled + (by Marko Kiiskila) + + Version 0.22 to 0.23 (16-NOV-1996) ==================== diff -ur --new-file old/atm/README new/atm/README --- old/atm/README Fri Nov 15 20:26:30 1996 +++ new/atm/README Fri Nov 29 17:55:24 1996 @@ -1,4 +1,4 @@ -ATM on Linux, release 0.23 (pre-alpha) by Werner Almesberger, EPFL LRC +ATM on Linux, release 0.24 (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/Rules.make new/atm/Rules.make --- old/atm/Rules.make Tue Nov 5 21:19:37 1996 +++ new/atm/Rules.make Fri Nov 29 17:31:38 1996 @@ -7,6 +7,13 @@ # carefully before permanently configuring machines to use UNI 3.1. # # STANDARDS=-DUNI31 -DALLOW_UNI30 +# +# If you're using a Cisco LS100 or LS7010 switch, you should add the following +# line to work around a bug in their point-to-multipoint signaling (it got +# confused when receiving a CALL PROCEEDING, so we don't send it, which of +# course makes our clearing procedure slightly non-conformant): +# +# STANDARDS += -DCISCO CC=cc CFLAGS_NOWARN=-g -DVERSION=\"`cat ../VERSION`\" $(INCLUDES) -I../lib @@ -53,6 +60,9 @@ endif LINK.c = $(CC) $(LDFLAGS) + +.c: + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(LDLIBS) all: [ ! -r .checker ] || $(MAKE) clean diff -ur --new-file old/atm/USAGE new/atm/USAGE --- old/atm/USAGE Sat Nov 16 00:09:36 1996 +++ new/atm/USAGE Fri Nov 29 19:03:00 1996 @@ -1,4 +1,4 @@ -Usage instructions - ATM on Linux, release 0.23 (pre-alpha) +Usage instructions - ATM on Linux, release 0.24 (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.22.tar.gz + ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.24.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 @@ -33,7 +33,7 @@ all the files listed above there. Then extract the ATM on Linux distribution: -tar xfz atm-0.22.tar.gz +tar xfz atm-0.24.tar.gz and the kernel source: @@ -66,6 +66,7 @@ atm/doc/ Documentation in LaTeX and conversion tools atm/man/ Miscellaneous man pages atm/extra/ Extra packages (tcpdump and ans) + atm/config/ Configuration file examples Kernel configuration @@ -166,7 +167,11 @@ ATM tools --------- -Now, as the final step, build the ATM tools: +Now, as the final step, configure and build the ATM tools. Configuration is +only necessary if your switch uses UNI 3.1 or if it has certain bugs. The +configuration options are at the beginning of atm/Rules.make. + +Then, build the ATM tools with: cd ../atm make depend diff -ur --new-file old/atm/VERSION new/atm/VERSION --- old/atm/VERSION Fri Nov 15 23:20:55 1996 +++ new/atm/VERSION Fri Nov 29 17:55:12 1996 @@ -1 +1 @@ -0.23 +0.24 diff -ur --new-file old/atm/aqd/Makefile new/atm/aqd/Makefile --- old/atm/aqd/Makefile Wed Sep 4 19:58:26 1996 +++ new/atm/aqd/Makefile Sun Nov 17 15:44:13 1996 @@ -9,5 +9,3 @@ arequipad: $(OBJS) $(CC) $(LDFLAGS) -o arequipad $(OBJS) $(LIBS) $(LDLIBS) - -cu: cu.o diff -ur --new-file old/atm/arpd/arp.c new/atm/arpd/arp.c --- old/atm/arpd/arp.c Wed Nov 13 16:59:22 1996 +++ new/atm/arpd/arp.c Wed Nov 27 19:08:38 1996 @@ -436,11 +436,19 @@ } entry = lookup_ip(itf,ip); assert(!vcc || vcc->entry); + /* + * If the entry on which we received the update isn't dangling but it + * doesn't correspond to the one with the address, ... + */ if (entry && vcc && vcc->entry->itf && entry != vcc->entry) { diag(COMPONENT,DIAG_DEBUG,"collision on %d.%d.%d.%d",ipp[0],ipp[1], ipp[2],ipp[3]); return; } + /* + * If the entry on which we received the update is dangling and we found + * an entry that already describes that IP address, ... + */ if (vcc && entry && !vcc->entry->itf) { if (!entry->svc) { diag(COMPONENT,DIAG_ERROR,"attempt to overwrite PVC for IP " @@ -454,7 +462,12 @@ Q_INSERT_HEAD(entry->vccs,vcc); vcc = NULL; } - if (entry || (vcc && (entry = vcc->entry))) { + /* + * If we either found an entry or if the update was received via InARP + * (so we can use the entry that already belongs to the VCC), ... + */ + if (entry || vcc) { + if (!entry) entry = vcc->entry; if (!entry->itf) Q_REMOVE(unknown_incoming,entry); } else { @@ -469,6 +482,13 @@ entry->ip = ip; if (!entry->itf) { entry->itf = itf; + /* @@@ + * Need to fix this is in case we allow entries without a valid IP + * address but with a pre-set QOS, e.g. a VC on a given PVC with an + * unknown remote end. + */ + entry->qos = entry->itf->qos; + adjust_qos(entry->itf,&entry->qos,0); Q_INSERT_HEAD(itf->table,entry); } if (entry->itf != itf) @@ -476,8 +496,6 @@ "(%d -> %d)",entry->itf->number,itf->number); if (!entry->addr) entry->addr = alloc(sizeof(*addr)); *entry->addr = *addr; - entry->qos = entry->itf->qos; - adjust_qos(entry->itf,&entry->qos,0); for (walk = entry->vccs; walk; walk = walk->next) if (!walk->connecting) if (set_ip(walk->fd,ip) < 0) @@ -542,6 +560,7 @@ entry->ip = ip; entry->itf = itf; Q_INSERT_HEAD(itf->table,entry); + entry->qos = itf->qos; } revalidate(entry); } diff -ur --new-file old/atm/atm.patch new/atm/atm.patch --- old/atm/atm.patch Sat Nov 16 00:36:06 1996 +++ new/atm/atm.patch Fri Nov 29 20:07:37 1996 @@ -4287,8 +4287,8 @@ + +#endif --- /dev/null Mon Jul 18 01:46:18 1994 -+++ work/drivers/atm/zatm.c Fri Nov 15 19:06:26 1996 -@@ -0,0 +1,1844 @@ ++++ work/drivers/atm/zatm.c Fri Nov 29 20:01:52 1996 +@@ -0,0 +1,1846 @@ +/* drivers/atm/zatm.c - ZeitNet ZN122x device driver */ + +/* Written 1995,1996 by Werner Almesberger, EPFL LRC */ @@ -4542,7 +4542,9 @@ +{ + int i; + -+ max_pdu += ATM_CELL_PAYLOAD-1; ++ if (max_pdu % ATM_CELL_PAYLOAD) ++ printk(KERN_ERR DEV_LABEL ": driver error in pool_index: " ++ "max_pdu is %d\n",max_pdu); + if (max_pdu > 65536) return -1; + for (i = 0; (64 << i) < max_pdu; i++); + return i+ZATM_AAL5_POOL_BASE; @@ -17114,7 +17116,7 @@ * Called once on startup. */ --- /dev/null Mon Jul 18 01:46:18 1994 -+++ work/include/linux/atmlec.h Fri Nov 15 21:36:38 1996 ++++ work/include/linux/atmlec.h Fri Nov 22 08:03:16 1996 @@ -0,0 +1,64 @@ +/* + * @@ -17140,7 +17142,7 @@ + +typedef enum { + l_set_mac_addr, l_del_mac_addr, -+ l_flush_xmt, l_svc_setup, ++ l_svc_setup, + l_addr_delete, l_topology_change, + l_flush_complete, l_arp_update, + l_config, l_flush_tran_id, @@ -17181,7 +17183,7 @@ +}; +#endif /* _ATMLEC_H_ */ --- /dev/null Mon Jul 18 01:46:18 1994 -+++ work/net/atm/lec.c Fri Nov 15 19:06:52 1996 ++++ work/net/atm/lec.c Tue Nov 26 16:08:44 1996 @@ -0,0 +1,641 @@ +/* + * lec.c: Lan Emulation driver @@ -17209,6 +17211,7 @@ +#include "lec_arpc.h" +#include "tunable.h" + ++ +#define DPRINTK(format,args...) +/* +#define DPRINTK printk @@ -17521,8 +17524,7 @@ + priv->topology_change = mesg->content.normal.flag; + break; + case l_flush_complete: -+ lec_flush_complete(priv, mesg->content.normal.atm_addr, -+ mesg->content.normal.flag); ++ lec_flush_complete(priv, mesg->content.normal.flag); + break; + case l_arp_update: + lec_arp_update(priv, mesg->content.normal.mac_addr, @@ -17546,7 +17548,7 @@ + (mesg->content.config.path_switching_delay*HZ); + break; + case l_flush_tran_id: -+ lec_set_flush_tran_id(priv, mesg->content.normal.mac_addr, ++ lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr, + mesg->content.normal.flag); + break; + case l_set_lecid: @@ -17798,12 +17800,12 @@ + if ((result = register_netdev(dev_lec[i])) !=0) + return result; + priv = (struct lec_priv *)dev_lec[i]->priv; -+ lec_arp_init(priv); + } else { + priv = (struct lec_priv *)dev_lec[i]->priv; + if (priv->lecd) + return -EADDRINUSE; + } ++ lec_arp_init(priv); + priv->lecd = vcc; + vcc->dev = &lecatm_dev; + @@ -17825,7 +17827,7 @@ + return i; +} --- /dev/null Mon Jul 18 01:46:18 1994 -+++ work/net/atm/lec.h Fri Nov 15 21:36:38 1996 ++++ work/net/atm/lec.h Wed Nov 27 15:15:46 1996 @@ -0,0 +1,107 @@ +/* + * @@ -17935,8 +17937,8 @@ +#endif _LEC_H_ + --- /dev/null Mon Jul 18 01:46:18 1994 -+++ work/net/atm/lec_arpc.c Fri Nov 15 19:06:53 1996 -@@ -0,0 +1,1055 @@ ++++ work/net/atm/lec_arpc.c Thu Nov 28 22:02:05 1996 +@@ -0,0 +1,1044 @@ +#include +#include +#include @@ -18093,7 +18095,6 @@ + lec_arp_clear_vccs(to_remove); + } + restore_flags(flags); -+ + DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", + 0xff&to_remove->mac_addr[0], 0xff&to_remove->mac_addr[1], + 0xff&to_remove->mac_addr[2], 0xff&to_remove->mac_addr[3], @@ -18129,7 +18130,7 @@ +#if DEBUG_ARP_TABLE + int i,j, offset; + struct lec_arp_table *rulla; -+ char buf[512]; ++ char buf[1024]; + struct lec_arp_table **lec_arp_tables = + (struct lec_arp_table **)priv->lec_arp_tables; + struct lec_arp_table *lec_arp_empty_ones = @@ -18351,6 +18352,7 @@ + + del_timer(&entry->timer); + ++ DPRINTK("lec_arp_expire_arp\n"); + if (entry->status == ESI_ARP_PENDING) { + if (entry->no_tries <= entry->priv->max_retry_count) { + send_to_lecd(entry->priv, l_arp_xmt, @@ -18378,8 +18380,8 @@ + + DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n", + to_remove, priv, -+ to_remove->vcc?to_remove->vcc->vpi:0, -+ to_remove->vcc?to_remove->vcc->vci:0); ++ to_remove->vcc?to_remove->recv_vcc->vpi:0, ++ to_remove->vcc?to_remove->recv_vcc->vci:0); + DPRINTK("eo:%p nf:%p\n",priv->lec_arp_empty_ones,priv->lec_no_forward); + if (to_remove == priv->lec_arp_empty_ones) + priv->lec_arp_empty_ones = to_remove->next; @@ -18452,7 +18454,7 @@ + if((now-entry->last_used > time_to_check) && + !(entry->flags & LEC_PERMANENT_FLAG)) { + /* Remove entry */ -+ printk("LEC:Remove entry1\n"); ++ DPRINTK("LEC:Entry timed out\n"); + next = entry->next; + lec_arp_remove(lec_arp_tables, entry); + kfree(entry); @@ -18484,7 +18486,6 @@ + priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL; + add_timer(&priv->lec_arp_timer); +} -+ +/* + * Try to find vcc where mac_address is attached. + * @@ -18528,7 +18529,6 @@ + return priv->mcast_vcc; + } + lec_arp_put(priv->lec_arp_tables, entry); -+ init_timer(&entry->timer); + make_arp_entry: + /* We want arp-request(s) to be sent */ + entry->packets_flooded =1; @@ -18551,7 +18551,7 @@ + int i; + + lec_arp_lock(priv); -+ printk("lec_addr_delete\n"); ++ DPRINTK("lec_addr_delete\n"); + for(i=0;ilec_arp_tables[i];entry != NULL; entry=next) { + next = entry->next; @@ -18582,7 +18582,6 @@ + DPRINTK("LEC:lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", + mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3], + mac_addr[4],mac_addr[5]); -+ dump_arp_table(priv); + lec_arp_lock(priv); + if (priv->lec_arp_empty_ones) { + entry = priv->lec_arp_empty_ones; @@ -18719,6 +18718,7 @@ + entry->status = ESI_UNKNOWN; + entry->timer.expires = jiffies + priv->vcc_timeout_period; + entry->timer.function = lec_arp_expire_vcc; ++ add_timer(&entry->timer); + entry->next = priv->lec_no_forward; + priv->lec_no_forward = entry; + lec_arp_unlock(priv); @@ -18760,9 +18760,11 @@ + entry->timestamp = jiffies; + entry->status = + ESI_FLUSH_PENDING; -+ send_to_lecd(priv,l_flush_xmt, -+ entry->mac_addr, ++#if 0 ++ send_to_lecd(priv,l_flush_xmt, ++ NULL, + entry->atm_addr); ++#endif + } + } else { + /* They were forming a connection @@ -18804,48 +18806,37 @@ +} + +void -+lec_flush_complete(struct lec_priv *priv, -+ unsigned char *atm_addr, unsigned long tran_id) ++lec_flush_complete(struct lec_priv *priv, unsigned long tran_id) +{ + struct lec_arp_table *entry; + int i; + -+ DPRINTK("LEC:lec_flush_complete\n"); ++ DPRINTK("LEC:lec_flush_complete %lx\n",tran_id); + for (i=0;ilec_arp_tables[i];entry;entry=entry->next) { -+ if (memcmp(atm_addr, entry->atm_addr,ATM_ESA_LEN)==0 && -+ entry->flush_tran_id == tran_id) { -+ DPRINTK("entry->status:%d\n",entry->status); ++ if (entry->flush_tran_id == tran_id && ++ entry->status == ESI_FLUSH_PENDING) { + entry->status = ESI_FORWARD_DIRECT; + DPRINTK("LEC_ARP: Flushed\n"); -+ dump_arp_table(priv); -+ return; + } + } + } -+ printk("LEC_ARP: Flush_complete: entry not found : %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", -+ 0xff&atm_addr[0],0xff&atm_addr[1],0xff&atm_addr[2], -+ 0xff&atm_addr[3],0xff&atm_addr[4],0xff&atm_addr[5], -+ 0xff&atm_addr[6],0xff&atm_addr[7],0xff&atm_addr[8], -+ 0xff&atm_addr[9],0xff&atm_addr[10],0xff&atm_addr[11], -+ 0xff&atm_addr[12],0xff&atm_addr[13],0xff&atm_addr[14], -+ 0xff&atm_addr[15],0xff&atm_addr[16],0xff&atm_addr[17], -+ 0xff&atm_addr[18],0xff&atm_addr[19]); ++ dump_arp_table(priv); +} + +void +lec_set_flush_tran_id(struct lec_priv *priv, -+ unsigned char *mac_addr, unsigned long tran_id) ++ unsigned char *atm_addr, unsigned long tran_id) +{ + struct lec_arp_table *entry; ++ int i; + -+ entry = lec_arp_find(priv, mac_addr); -+ if (!entry) { -+ printk("LEC_ARP: Set_flush_tran_id: entry not found\n"); -+ return; -+ } -+ DPRINTK("LEC: flush_tran_id:%lx\n",tran_id); -+ entry->flush_tran_id = tran_id; ++ for (i=0;ilec_arp_tables[i];entry;entry=entry->next) ++ if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) { ++ entry->flush_tran_id = tran_id; ++ DPRINTK("Set flush transaction id to %lx for %p\n",tran_id,entry); ++ } +} + +int @@ -18993,8 +18984,8 @@ +} + --- /dev/null Mon Jul 18 01:46:18 1994 -+++ work/net/atm/lec_arpc.h Fri Nov 15 21:36:38 1996 -@@ -0,0 +1,102 @@ ++++ work/net/atm/lec_arpc.h Wed Nov 27 15:15:46 1996 +@@ -0,0 +1,101 @@ +/* + * Lec arp cache + * Marko Kiiskila carnil@cs.tut.fi @@ -19088,8 +19079,7 @@ + struct atm_vcc *vcc, struct sk_buff *skb); +int lec_addr_delete(struct lec_priv *priv, + unsigned char *mac_addr, unsigned long permanent); -+void lec_flush_complete(struct lec_priv *priv, -+ unsigned char *atm_addr, unsigned long tran_id); ++void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id); +void lec_arp_update(struct lec_priv *priv, + unsigned char *mac_addr, unsigned char *atm_addr, + unsigned long remoteflag); @@ -19264,7 +19254,7 @@ + +#endif --- ref/net/ipv4/tcp_input.c Wed Oct 30 03:13:01 1996 -+++ work/net/ipv4/tcp_input.c Fri Nov 15 19:56:31 1996 ++++ work/net/ipv4/tcp_input.c Wed Nov 27 19:57:41 1996 @@ -36,6 +36,11 @@ #include #include @@ -19381,20 +19371,41 @@ } /* -@@ -1800,6 +1844,13 @@ - skb->free = 1; +@@ -1801,6 +1845,13 @@ skb->saddr = daddr; skb->daddr = saddr; -+ + +#ifdef CONFIG_AREQUIPA + if (dev == arequipa_dev && !sk->arequipa && sk->aq_route && + sk->state == TCP_ESTABLISHED) + (void) arequipa_attach(skb->atm.vcc->sock,sk, + skb->atm.generation); +#endif - ++ /* * We may need to add it to the backlog here. + */ +@@ -1961,6 +2012,12 @@ + return 0; + } + ++ /* ++ * Need to do option processing early to get ++ * window scale right. ++ */ ++ tcp_options(sk,th); ++ + /* process the ACK, get the SYN packet out + * of the send queue, do other initial + * processing stuff. [We know it's good, and +@@ -1978,7 +2035,6 @@ + sk->fin_seq = skb->seq; + tcp_send_ack(sk); + tcp_set_state(sk, TCP_ESTABLISHED); +- tcp_options(sk,th); + sk->dummy_th.dest=th->source; + sk->copied_seq = sk->acked_seq; + if(!sk->dead) --- ref/net/ipv4/Config.in Fri Jul 19 07:24:05 1996 +++ work/net/ipv4/Config.in Fri Nov 15 19:06:56 1996 @@ -42,3 +42,4 @@ diff -ur --new-file old/atm/config/redhat-4.0/README new/atm/config/redhat-4.0/README --- old/atm/config/redhat-4.0/README Thu Jan 1 01:00:00 1970 +++ new/atm/config/redhat-4.0/README Wed Nov 27 16:13:32 1996 @@ -0,0 +1,71 @@ +RedHat 4.0 sample configuration files +===================================== + +Known restrictions +------------------ + + - no support for manually configured ATMARP entries (SVC or PVC) + - no LANE (neither client nor server) + - no ANS + + +Overview +-------- + +/etc/sysconfig/atm + Indicates if ATM is desired, which ATM components are used, and may + contain configuration options for system-wide resources (e.g. ilmid) + +/etc/rc.d/init.d/atm (atm.init) + Is executed at system startup to initialize the ATM subsystem (e.g. + to start all the demons), and at system shutdown to remove the + demons it started. + +/etc/atmsigd.conf + ATM signaling demon configuration, see man atmsigd.conf + +/etc/sysconfig/network-scripts/ifcfg-atm* + Per-interface configuration parameters. This file contains highly + site-specific data. + +/etc/sysconfig/network-scripts/ifup-atm + General interface bringup procedure. Creates the IP over ATM interface, + configures it, adds the route, and creates all the necessary ATMARP + information. + + +Installation +------------ + +In order to use the configuraton scripts in this directory, you have to +install ATM on Linux as follows: + +# cd wherever/atm # top-level directory of the ATM distribution tree +# INSTPREFIX=/usr/local make -e uninstall # remove the old files +# INSTPREFIX=/usr make -e install # install everything under /usr + +Then copy the configuration files: + +# cd config/redhat-4.0 +# cp atm /etc/sysconfig +# cp atm.init /etc/rc.d/init.d/atm +# cp atmsigd.conf /etc +# cp ifcfg-atm0 ifup-atm /etc/sysconfig/network-scripts + +Finally, you may have to edit /etc/sysconfig/atm and /etc/atmsigd.conf +If you're using IP over ATM, you _must_ change +/etc/sysconfig/network-scripts/ifcfg-atm0 as follows: + +DEVICE name of the interface (e.g. atm0, atm1, ...) +IPADDR IP address of the host on that ATM LIS +NETMASK network mask of that ATM LIS +BROADCAST broadcast address (not really used at the moment, but + must be configured to a sane value) +ARPSRV ATM address of the ATMARP server serving that LIS. May + be a symbolic name if /etc/hosts.atm is being used. Omit + this variable if the local machine is acting as the + ATMARP server of that LIS. +ARPSRVQOS optional; QOS of the ATMARP server VC +ARPDEFQOS optional; default QOS for IP over ATM VCs +ONBOOT must be set to "no" in order to bring up interfaces only + after the demons are running diff -ur --new-file old/atm/config/redhat-4.0/atm new/atm/config/redhat-4.0/atm --- old/atm/config/redhat-4.0/atm Thu Jan 1 01:00:00 1970 +++ new/atm/config/redhat-4.0/atm Wed Nov 27 15:57:13 1996 @@ -0,0 +1,8 @@ +# +# /etc/sysconfig/atm - general ATM setup +# +ATM=yes # enable ATM support at all +IPATM=yes # Classical IP over ATM (using ATMARP) +AREQUIPA=yes # Application REQUested IP over ATM +LANE=no # LAN Emulation (client; doesn't work yet) +# ILMIQOS="ubr:pcr=100kbps" # optional: QOS to use on the ILMI VC diff -ur --new-file old/atm/config/redhat-4.0/atm.init new/atm/config/redhat-4.0/atm.init --- old/atm/config/redhat-4.0/atm.init Thu Jan 1 01:00:00 1970 +++ new/atm/config/redhat-4.0/atm.init Wed Nov 27 15:54:03 1996 @@ -0,0 +1,68 @@ +#!/bin/sh +# +# /etc/rc.d/init.d/atm - Bring up/down ATM +# + +# Source function library. +. /etc/rc.d/init.d/functions + +if [ ! -f /etc/sysconfig/atm ]; then + exit 0 +fi + +. /etc/sysconfig/atm + +[ "$ATM" != yes ] && exit 0 + +cd /etc/sysconfig/network-scripts + +case "$1" in + start) + echo -n "Starting ATM demons: " + daemon atmsigd -b -l syslog -D /var/tmp -t 20 + daemon ilmid -b -l syslog `[ -z "$ILMIQOS" ] || echo -q $ILMIQOS` + [ "$IPATM" = yes ] && daemon atmarpd -b -l syslog + # launch LANE demon(s) ... + [ "$AREQUIPA" = yes ] && daemon arequipad -b -l syslog + echo + if [ "$LANE" = yes ]; then + for n in ifcfg-lec[0-9]; do + ./ifup $n + done + fi + if [ "$IPATM" = yes ]; then + for n in ifcfg-atm[0-9]; do + ./ifup $n + done + fi + if [ "$LANE" = yes ]; then + for n in ifcfg-lec[0-9]; do + ./ifup $n + done + fi + touch /var/lock/subsys/atm + ;; + stop) + if [ "$LANE" = yes ]; then + for n in ifcfg-lec[0-9]; do + ./ifdown $n + done + fi + if [ "$IPATM" = yes ]; then + for n in ifcfg-atm[0-9]; do + ./ifdown $n + done + fi + echo -n "Stopping ATM demons: " + if [ "$IPATM" = yes ]; then + [ "$AREQUIPA" = yes ] && killproc arequipad + killproc atmarpd + fi + killproc atmsigd # kill ILMID later, so we don't get complaints + killproc ilmid + echo + rm -f /var/lock/subsys/network + ;; + *) echo "Usage: atm {start|stop}" + exit 1 +esac diff -ur --new-file old/atm/config/redhat-4.0/atmsigd.conf new/atm/config/redhat-4.0/atmsigd.conf --- old/atm/config/redhat-4.0/atmsigd.conf Thu Jan 1 01:00:00 1970 +++ new/atm/config/redhat-4.0/atmsigd.conf Wed Nov 27 15:54:22 1996 @@ -0,0 +1,9 @@ +# +# /etc/atmsigd.conf +# +debug { + level warn # limited logging - we're production now ;-) + log syslog # log via syslogd + dump /var/tmp # enable signaling traces + trace 100 +} diff -ur --new-file old/atm/config/redhat-4.0/ifcfg-atm0 new/atm/config/redhat-4.0/ifcfg-atm0 --- old/atm/config/redhat-4.0/ifcfg-atm0 Thu Jan 1 01:00:00 1970 +++ new/atm/config/redhat-4.0/ifcfg-atm0 Wed Nov 27 16:08:39 1996 @@ -0,0 +1,12 @@ +# +# /etc/sysconfig/network-scripts/ifcfg-atm* +# +DEVICE=atm0 # device name +IPADDR=##MYIPADDR## # hosts's IP address on the ATM LIS +NETMASK=255.255.255.0 # netmask (e.g. EPFL uses 8 host bits) +NETWORK=192.33.193.0 # network (e.g. EPFL's experimental ATM LIS) +BROADCAST=192.33.193.255 # broadcast address (not really useful) +ARPSRV=lrcsuns-a # ATM address of ATMARP server; omit if local +# ARPSRVQOS="ubr:max_pcr=100kbps" # QOS of the ATMARP server VC +# ARPDEFQOS="ubr:max_pcr=700kbps" # default QOS for IP over ATM VCs +ONBOOT=no # needs to be loaded by ATM-specific procedure diff -ur --new-file old/atm/config/redhat-4.0/ifup-atm new/atm/config/redhat-4.0/ifup-atm --- old/atm/config/redhat-4.0/ifup-atm Thu Jan 1 01:00:00 1970 +++ new/atm/config/redhat-4.0/ifup-atm Wed Nov 27 15:54:03 1996 @@ -0,0 +1,11 @@ +#!/bin/sh +# +# /etc/sysconfig/network-scripts/ifup-atm +# +. $1 +atmarp -c $DEVICE || exit 1 +ifconfig $DEVICE $IPADDR netmask $NETMASK up || exit 1 +route add -net $NETWORK netmask $NETMASK $DEVICE || exit 1 +[ -z "$ARPDEFQOS" ] || atmarp -q $NETWORK $ARPDEFQOS +[ -z "$ARPSRV" ] || atmarp -s $NETWORK $ARPSRV arpsrv \ + `[ -z "$ARPSRVQOS" ] || echo qos $ARPSRVQOS` diff -ur --new-file old/atm/debug/Makefile new/atm/debug/Makefile --- old/atm/debug/Makefile Fri Oct 11 19:19:45 1996 +++ new/atm/debug/Makefile Sun Nov 17 15:47:56 1996 @@ -3,7 +3,5 @@ include ../Rules.make -zndump: zndump.o - zndump.o: zndump.c $(CC) -c $(CFLAGS) -w -O zndump.c diff -ur --new-file old/atm/debug/delay.c new/atm/debug/delay.c --- old/atm/debug/delay.c Wed Oct 16 10:40:42 1996 +++ new/atm/debug/delay.c Sun Nov 17 15:35:07 1996 @@ -49,7 +49,7 @@ static void loop(void) { - LINK *link; + LINK *lnk; PACKET *p; struct timeval now,next,delta,*to; fd_set curr; @@ -68,13 +68,13 @@ } while (1) { curr = in; - for (link = links; link; link = link->next) - if (link->queue) break; - if (!link) to = NULL; + for (lnk = links; lnk; lnk = lnk->next) + if (lnk->queue) break; + if (!lnk) to = NULL; else { - for (next = link->queue->due; link; link = link->next) - if (link->queue && LESS(link->queue->due,next)) - next = link->queue->due; + for (next = lnk->queue->due; lnk; lnk = lnk->next) + if (lnk->queue && LESS(lnk->queue->due,next)) + next = lnk->queue->due; delta.tv_sec = next.tv_sec-now.tv_sec; delta.tv_usec = next.tv_usec-now.tv_usec; if (delta.tv_usec < 0) { @@ -97,9 +97,9 @@ exit(1); } if (ready) - for (link = links; link; link = link->next) + for (lnk = links; lnk; lnk = lnk->next) while (1) { - size = read(link->in,buffer,ATM_MAX_AAL5_PDU); + size = read(lnk->in,buffer,ATM_MAX_AAL5_PDU); if (size < 0) if (errno == EAGAIN) break; else { @@ -113,23 +113,23 @@ } memcpy(p->data,buffer,size); p->size = size; - p->due.tv_sec = now.tv_sec+link->delay.tv_sec; - p->due.tv_usec = now.tv_usec+link->delay.tv_usec; + p->due.tv_sec = now.tv_sec+lnk->delay.tv_sec; + p->due.tv_usec = now.tv_usec+lnk->delay.tv_usec; if (p->due.tv_usec > 1000000) { p->due.tv_sec++; p->due.tv_usec -= 1000000; } p->next = NULL; - if (link->queue) link->last->next = p; - else link->queue = p; - link->last = p; + if (lnk->queue) lnk->last->next = p; + else lnk->queue = p; + lnk->last = p; } } - for (link = links; link; link = link->next) - while (link->queue && LESS(link->queue->due,now)) { - p = link->queue; - link->queue = p->next; - if ((size = write(link->out,p->data,p->size)) < 0) { + for (lnk = links; lnk; lnk = lnk->next) + while (lnk->queue && LESS(lnk->queue->due,now)) { + p = lnk->queue; + lnk->queue = p->next; + if ((size = write(lnk->out,p->data,p->size)) < 0) { perror("write"); exit(1); } diff -ur --new-file old/atm/debug/znth.c new/atm/debug/znth.c --- old/atm/debug/znth.c Thu Sep 26 21:19:48 1996 +++ new/atm/debug/znth.c Sun Nov 17 15:47:20 1996 @@ -52,4 +52,5 @@ printf("%11d usec\n",diff.tv_usec); } } + return 0; } diff -ur --new-file old/atm/doc/usage.tex new/atm/doc/usage.tex --- old/atm/doc/usage.tex Sat Nov 16 00:09:08 1996 +++ new/atm/doc/usage.tex Fri Nov 29 18:01:27 1996 @@ -1,7 +1,7 @@ %%def%:= %:\begin{verbatim} -%:Usage instructions - ATM on Linux, release 0.23 (pre-alpha) +%:Usage instructions - ATM on Linux, release 0.24 (pre-alpha) %:------------------------------------------------------------- %: %:\end{verbatim} @@ -38,14 +38,14 @@ \title{ATM on Linux \\ User's guide \\ - Release 0.23 (pre-alpha)} + Release 0.24 (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{November 16, 1996} +\date{November 17, 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.22.tar.gz} + \url{ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.24.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 @@ -98,7 +98,7 @@ distribution: \begin{verbatim} -tar xfz atm-0.22.tar.gz +tar xfz atm-0.24.tar.gz \end{verbatim} and the kernel source: @@ -140,6 +140,7 @@ \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}) + \item[\path{atm/config/}] Configuration file examples \end{description} @@ -249,7 +250,11 @@ \subsection{ATM tools} -Now, as the final step, build the ATM tools: +Now, as the final step, configure and build the ATM tools. Configuration is +only necessary if your switch uses UNI 3.1 or if it has certain bugs. The +configuration options are at the beginning of \path{atm/Rules.make}. + +Then, build the ATM tools with: \begin{verbatim} cd ../atm diff -ur --new-file old/atm/doc/usage.txt new/atm/doc/usage.txt --- old/atm/doc/usage.txt Sat Nov 16 00:09:36 1996 +++ new/atm/doc/usage.txt Fri Nov 29 19:03:00 1996 @@ -1,4 +1,4 @@ -Usage instructions - ATM on Linux, release 0.23 (pre-alpha) +Usage instructions - ATM on Linux, release 0.24 (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.22.tar.gz + ftp://lrcftp.epfl.ch/pub/linux/atm/dist/atm-0.24.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 @@ -33,7 +33,7 @@ all the files listed above there. Then extract the ATM on Linux distribution: -tar xfz atm-0.22.tar.gz +tar xfz atm-0.24.tar.gz and the kernel source: @@ -66,6 +66,7 @@ atm/doc/ Documentation in LaTeX and conversion tools atm/man/ Miscellaneous man pages atm/extra/ Extra packages (tcpdump and ans) + atm/config/ Configuration file examples Kernel configuration @@ -166,7 +167,11 @@ ATM tools --------- -Now, as the final step, build the ATM tools: +Now, as the final step, configure and build the ATM tools. Configuration is +only necessary if your switch uses UNI 3.1 or if it has certain bugs. The +configuration options are at the beginning of atm/Rules.make. + +Then, build the ATM tools with: cd ../atm make depend diff -ur --new-file old/atm/extra/Makefile new/atm/extra/Makefile --- old/atm/extra/Makefile Wed Nov 13 17:11:58 1996 +++ new/atm/extra/Makefile Sun Nov 17 17:58:30 1996 @@ -20,6 +20,7 @@ [ -d $(TCPDUMPDIR) ] || tar xfz $(TCPDUMPSRC) [ -f $(TCPDUMPDIR)/.patched ] || { \ cd $(TCPDUMPDIR) && patch -p1 -s <../$(TCPDUMPPATCH) && \ + ln -s ../libpcap-0.0.6 $(TCPDUMPDIR)/libpcap && \ touch .patched \ } [ -f $(TCPDUMPDIR)/.compiled ] || { \ 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 Tue Nov 12 17:37:55 1996 +++ new/atm/extra/bind-4.9.5-REL.patch Fri Nov 29 17:39:20 1996 @@ -431,8 +431,8 @@ 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 @@ ++++ bind/named/atm_itf.c Thu Nov 14 16:44:22 1996 +@@ -0,0 +1,117 @@ +/* + * Marko Kiiskila carnil@cs.tut.fi + * @@ -533,6 +533,8 @@ +int +close_atm_stream(int s) +{ ++ if (s==atm_vs) ++ atm_vs = -1; + return (close(s)); +} + @@ -764,7 +766,7 @@ 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 ++++ bind/named/ns_main.c Thu Nov 14 15:32:50 1996 @@ -111,6 +111,10 @@ #include "named.h" #undef MAIN_PROGRAM @@ -776,48 +778,34 @@ #undef nsaddr /* UDP receive, TCP send buffer size */ -@@ -402,6 +406,40 @@ +@@ -402,6 +406,26 @@ 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); -+ } ++ /* ATM socket creation */ ++ for(n=0;;n++) { ++ printf("About to create listen socket\n"); ++ if ((atm_vs=open_atm_stream()) < 0 && n < 2) { ++ printf("open_atm_stream failed %d\n",atm_vs); ++ syslog(LOG_ERR, "ATM socket failure, can't answer ATM connection requests\n"); ++ if (errno == EADDRINUSE) { ++ syslog(LOG_NOTICE, ++ "There may be an ATM name server already running\n"); ++ } ++ } else ++ break; ++ /* Retry opening the socket a few times */ ++ 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 @@ +@@ -421,6 +445,11 @@ */ FD_ZERO(&mask); FD_SET(vs, &mask); @@ -829,7 +817,7 @@ getnetconf(); /* -@@ -782,6 +825,11 @@ +@@ -782,6 +811,11 @@ gettime(&tt); sp->s_time = tt.tv_sec; /* last transaction time */ sp->s_from = from_addr; /* address to respond to */ @@ -841,7 +829,7 @@ sp->s_bufp = (u_char *)&sp->s_tempsize; FD_SET(rfd, &mask); FD_SET(rfd, &tmpmask); -@@ -792,6 +840,83 @@ +@@ -792,6 +826,83 @@ sin_ntoa(&sp->s_from), rfd); #endif } @@ -925,7 +913,7 @@ if (streamq) dprintf(3, (ddt, "streamq = 0x%lx\n", (u_long)streamq)); -@@ -799,6 +924,29 @@ +@@ -799,6 +910,29 @@ nextsp = sp->s_next; if (!FD_ISSET(sp->s_rfd, &tmpmask)) continue; @@ -955,7 +943,7 @@ 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 @@ +@@ -932,6 +1066,11 @@ } continue; } @@ -967,6 +955,56 @@ } } /* NOTREACHED */ +diff -urN bindtmp/named/ns_maint.c bind/named/ns_maint.c +--- bindtmp/named/ns_maint.c Sun Sep 22 03:13:21 1996 ++++ bind/named/ns_maint.c Thu Nov 14 15:31:38 1996 +@@ -73,6 +73,12 @@ + + #include "named.h" + ++#if defined(ATM) ++#if defined(linux) ++#include "atm_itf.h" ++#endif /* defined(linux)*/ ++#endif /* defined(ATM) */ ++ + #ifdef USE_UTIME + # include + #endif +@@ -163,6 +169,19 @@ + stats_time = tt.tv_sec; + } + #endif ++#if defined(ATM) ++#if defined(linux) ++ if (atm_vs < 0) { ++ /* Try to create ATM socket again */ ++ printf("About to retry opening listen socket\n"); ++ if ((atm_vs=open_atm_stream()) < 0) { ++ printf("open_atm_stream failed %d\n",atm_vs); ++ syslog(LOG_ERR, "ATM socket failure, can't answer ATM connection requests\n"); ++ } else ++ printf("ATM socket creation success!\n"); ++ } ++#endif /* defined (linux) */ ++#endif /* defined (ATM) */ + if (!needmaint) + sched_maint(); + dprintf(1, (ddt, "exit ns_maint()\n")); +@@ -207,6 +226,13 @@ + ival.it_value.tv_sec = next_refresh - tt.tv_sec; + if ((long) ival.it_value.tv_sec < maint_interval) + ival.it_value.tv_sec = maint_interval; ++#if defined(ATM) ++#if defined(linux) ++ if (atm_vs < 0) /* ATM socket doesn't exist, try again after ++ * maint_interval */ ++ ival.it_value.tv_sec = maint_interval; ++#endif /* defined(linux)*/ ++#endif /* defined(ATM) */ + next_alarm = next_refresh; + alarm_pending = 1; + } 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 diff -ur --new-file old/atm/extra/hosts2ans.pl new/atm/extra/hosts2ans.pl --- old/atm/extra/hosts2ans.pl Wed Nov 13 19:33:06 1996 +++ new/atm/extra/hosts2ans.pl Tue Nov 26 20:34:15 1996 @@ -60,7 +60,7 @@ $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"; + ".".substr($pfx,2,4).".".substr($pfx,0,2).".AESA.ATMA.INT.\n"; } print substr($tail,12,2).".".substr($tail,0,12)."\tIN\tPTR\t$host.". $domain.".\n"; diff -ur --new-file old/atm/ip/Makefile new/atm/ip/Makefile --- old/atm/ip/Makefile Mon Sep 2 19:41:18 1996 +++ new/atm/ip/Makefile Sun Nov 17 15:43:00 1996 @@ -2,6 +2,3 @@ MAN8=clip.8 atmarp.8 include ../Rules.make - -atmarp: atmarp.o -clip: clip.o diff -ur --new-file old/atm/led/conn.c new/atm/led/conn.c --- old/atm/led/conn.c Mon Nov 11 16:06:58 1996 +++ new/atm/led/conn.c Thu Nov 28 10:53:38 1996 @@ -65,6 +65,7 @@ #include "kernel_itf.h" #include "lec_ctrl.h" #include "addr_reg.h" +#include "lec_arp.h" #define EMOD MOD_CM #define EINST "conn.c" @@ -106,6 +107,9 @@ int type; /* We made, they made, listen socket */ void *p_packet; /* Save packets address, needed in callback */ CONN_INFO *conn_info; /* Listen socket conn_info */ + unsigned char atm_address[ATM_ESA_LEN]; + /* Destination address, not in listen or kernel + sockets */ struct _conn_t_ *next; struct _conn_t_ *previous; } Conn_t; @@ -247,7 +251,6 @@ conn_already_exists(unsigned char *atm_addr, Conn_t *current) { Conn_t *conn; - struct sockaddr_atmsvc them; int len; conn = connlist; @@ -256,12 +259,8 @@ while (conn) { if (conn != current && conn->type != LISTENING && conn->type != KERNEL_SOCK && conn->status != RELEASED) { - if (getpeername(conn->fd, (struct sockaddr*)&them, &len) < 0) { - EVENT(EM_NERR,("Can't getpeername:%s\n",strerror(errno))); - } else { - if (memcmp(them.sas_addr.prv, atm_addr, ATM_ESA_LEN) == 0) - return conn; - } + if (memcmp(conn->atm_address, atm_addr, ATM_ESA_LEN) == 0) + return conn; } conn= conn->next; } @@ -286,7 +285,6 @@ int ret; struct sockaddr_atmsvc us; struct atm_blli blli; - struct atmlec_ioc ioc_data; EVENT(EM_EVENT,("Outgoing call setup\n")); @@ -434,22 +432,6 @@ switch (p_conn_info->blli.l3.tr9577.snap[4]) { /* AAAAAARRRGGHHH! */ case 0x02: case 0x03: - memcpy(ioc_data.atm_addr, p_conn_info->addr.sas_addr.prv, ATM_ESA_LEN); - ioc_data.dev_num = sap->itf_num; - ioc_data.receive = 0; - EVENT(EM_DEBUG,("About to ioctl(s, ATMLEC_DATA, &ioc_data)\n")); - if (ioctl(s, ATMLEC_DATA, &ioc_data)<0) { - EVENT(EM_SERR,("Can't change socket into LE data socket:%s\n", - strerror(errno))); - if (is_data_direct(p_conn_info)) { - /* Try to remove possible entry in kernel */ - lc_addr_delete(conn_context, p_conn_info->addr.sas_addr.prv); - } - close(s); - *p_conn_handle = NULL; - return STATUS_K_ATM_RESOURCES; - } - EVENT(EM_DEBUG,("ioctl done\n")); break; case 0x04: case 0x05: @@ -536,6 +518,7 @@ /* Failure */ if (ret<0) { EVENT(EM_NERR,("Write failed: %s\n",strerror(errno))); + conn->status = RELEASED; return STATUS_K_CONGESTED; /* Asdf */ } if (EMASK & EM_XCTRL) @@ -830,10 +813,32 @@ } else if (conn->type == LISTENING) { /* Incoming call */ } else if (conn->status == CONNECTING) { /* Call is ready */ memset(&addr,0,sizeof(addr)); - if (!connect(conn->fd, (struct sockaddr*)&addr,sizeof(addr))) { - EVENT(EM_EVENT,("Nonblocking connect() :%s\n",strerror(errno))); + /* + if (!connect(conn->fd, (struct sockaddr*)&addr,sizeof(addr)) && + errno != EINPROGRESS) { + */ + if (connect(conn->fd, (struct sockaddr*)&addr, sizeof(addr))<0) { + EVENT(EM_SERR,("Nonblocking connect() :%s\n",strerror(errno))); + lc_addr_delete(conn->conn_context, conn->atm_address); + conn->status = RELEASED; + } else { + EVENT(EM_DEBUG,("Call connected\n")); + conn->status = CONNECTED; + memcpy(ioc_data.atm_addr, conn->atm_address, ATM_ESA_LEN); + sap = conn->sap_handle; + ioc_data.dev_num = sap->itf_num; + ioc_data.receive = 0; + EVENT(EM_DEBUG,("About to ioctl(s, ATMLEC_DATA, &ioc_data)\n")); + if (ioctl(conn->fd, ATMLEC_DATA, &ioc_data)<0) { + EVENT(EM_SERR,("Can't change socket into LE data socket:%s\n", + strerror(errno))); + conn->status = RELEASED; + lc_addr_delete(conn->conn_context, conn->atm_address); + } else { + EVENT(EM_DEBUG,("ioctl done\n")); + kernel_flush_xmt(conn->atm_address); + } } - conn->status = CONNECTED; } else { /* Data coming in */ nbytes = read(conn->fd, buffer, BUFSIZE); if (nbytes <0) { @@ -846,8 +851,7 @@ EVENT(EM_EVENT, ("Closing connection\n")); } } else if (nbytes==0) { - /* EOF, connection closed */ - + /* EOF, connection closed */ conn->status = RELEASED; EVENT(EM_EVENT,("Connection closed\n")); } else { @@ -987,6 +991,10 @@ 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); + else + memset(conn->atm_address, 0, ATM_ESA_LEN); conn->next = connlist; conn->previous = NULL; diff -ur --new-file old/atm/led/kernel_itf.c new/atm/led/kernel_itf.c --- old/atm/led/kernel_itf.c Tue Sep 17 06:51:37 1996 +++ new/atm/led/kernel_itf.c Fri Nov 22 20:12:48 1996 @@ -150,8 +150,6 @@ return "SET_MAC_ADDR"; case l_del_mac_addr: return "DEL_MAC_ADDR"; - case l_flush_xmt: - return "FLUSH_XMT"; case l_svc_setup: return "SVC_SETUP"; case l_arp_xmt: diff -ur --new-file old/atm/led/lec_arp.c new/atm/led/lec_arp.c --- old/atm/led/lec_arp.c Tue Sep 17 05:22:28 1996 +++ new/atm/led/lec_arp.c Thu Nov 28 12:58:30 1996 @@ -92,18 +92,16 @@ } } -static void -kernel_flush_xmt_callback(struct atmlec_msg *mesg) +void +kernel_flush_xmt(unsigned char *to_pass) { LA_ELAN_CONTEXT *p_elan; - ADDR_ATM *to_pass; UINT32 dumb; - to_pass = (ADDR_ATM*)mesg->content.normal.atm_addr; - utl_list_traverse(lec_arp_context.elan_list, p_elan) { - lec_arp_context.flush_xmt_callback(p_elan->lc_elan_handle, *to_pass,&dumb); - kernel_sendmsg(l_flush_tran_id, mesg->content.normal.mac_addr,NULL, + lec_arp_context.flush_xmt_callback(p_elan->lc_elan_handle, to_pass,&dumb); + EVENT(EM_DEBUG,("Setting flush transaction id to %lx\n",dumb)); + kernel_sendmsg(l_flush_tran_id, NULL, to_pass, NULL, dumb); } } @@ -135,7 +133,6 @@ utl_list_init(lec_arp_context.elan_list); kernel_register_callback(l_arp_xmt, kernel_arp_xmt_callback); - kernel_register_callback(l_flush_xmt, kernel_flush_xmt_callback); kernel_register_callback(l_svc_setup, kernel_svc_setup_xmt_callback); *p_la_handle = (HANDLE)&lec_arp_context; @@ -220,9 +217,9 @@ conf_mesg.maximum_unknown_frame_count = max_unknown_frame_count; conf_mesg.max_unknown_frame_time = max_unknown_frame_time; conf_mesg.max_retry_count = max_retry_count; - conf_mesg.aging_time = aging_time * 1000; - conf_mesg.forward_delay_time = forward_delay_time * 1000; - conf_mesg.arp_response_time = le_arp_response_time * 1000; + conf_mesg.aging_time = aging_time; + conf_mesg.forward_delay_time = forward_delay_time; + conf_mesg.arp_response_time = le_arp_response_time; conf_mesg.flush_timeout = flush_timeout; conf_mesg.path_switching_delay = path_switching_delay; kernel_sendmsg(l_config, NULL, NULL, &conf_mesg, 0); @@ -252,11 +249,11 @@ void la_flush_complete(HANDLE la_elan_handle, - ADDR_ATM addr_atm, UINT32 tran_id) { + EVENT(EM_DEBUG,("Flush complete for tran_id %lx\n", tran_id)); kernel_sendmsg(l_flush_complete, NULL, - (unsigned char *)&addr_atm, NULL, tran_id); + NULL, NULL, tran_id); } void diff -ur --new-file old/atm/led/lec_arp.h new/atm/led/lec_arp.h --- old/atm/led/lec_arp.h Tue Sep 17 05:22:20 1996 +++ new/atm/led/lec_arp.h Fri Nov 22 20:05:37 1996 @@ -236,7 +236,7 @@ * --*/ typedef void (*FLUSH_XMT_CALLBACK) (HANDLE lc_elan_handle, - ADDR_ATM addr_atm, + unsigned char* addr_atm, HANDLE esi_handle); /*++ @@ -565,7 +565,6 @@ * requested MAC address may now be forwarded to the data-direct VCC. --*/ void la_flush_complete (HANDLE la_elan_handle, - ADDR_ATM addr_atm, UINT32 tran_id); /*++ @@ -595,3 +594,4 @@ void la_topology_change_set (HANDLE la_elan_handle, BOOLEAN topology_change_flag); +void kernel_flush_xmt(unsigned char *to_pass); diff -ur --new-file old/atm/led/lec_ctrl.c new/atm/led/lec_ctrl.c --- old/atm/led/lec_ctrl.c Mon Nov 11 16:07:15 1996 +++ new/atm/led/lec_ctrl.c Thu Nov 28 12:34:48 1996 @@ -1758,13 +1758,14 @@ * ================ --*/ static void lc_flush_xmt (HANDLE lc_elan_handle, - ADDR_ATM addr_atm, + unsigned char *addr_atm, HANDLE flush_tran_id) { LC_ELAN_CONTEXT *p_elan; LE_FLUSH_FRAME frame; STATUS status; UINT32 *p_tran_id; + int i; p_elan = (LC_ELAN_CONTEXT *) lc_elan_handle; p_tran_id = (UINT32 *)flush_tran_id; @@ -1776,10 +1777,17 @@ LE_FLUSH_REQ); ATM_COPY (p_elan->lec_state.c1_my_atm_addr, frame.src_atm_addr); + for(i=0;ism_state == S_OPERATIONAL) { status = cm_sap_xmt_vc (p_elan->mcast_send_conn_handle, @@ -2760,11 +2768,25 @@ /* Parse TLVs */ tlv_index = sizeof (LE_CONFIG_FRAME); - while (tlv_index < length) { - tlv_parse(p_elan, p_packet, length, &tlv_index); + + if (tlv_index < length) { + while (tlv_index < length) { + tlv_parse(p_elan, p_packet, length, &tlv_index); + } + la_config(p_elan->la_elan_handle, + p_elan->lec_state.c2_lan_type, + p_elan->lec_state.c4_proxy_flag, + p_elan->lec_state.c10_max_unknown_frame_count, + p_elan->lec_state.c11_max_unknown_frame_time, + p_elan->lec_state.c12_vcc_timeout, + p_elan->lec_state.c13_max_retry_count, + p_elan->lec_state.c17_aging_time, + p_elan->lec_state.c18_forward_delay_time, + p_elan->lec_state.c20_le_arp_response_time, + p_elan->lec_state.c21_flush_timeout, + p_elan->lec_state.c22_path_switching_delay); } - - sm_exec ((HANDLE) p_elan, E_RCV_CONFIG_RSP); + sm_exec ((HANDLE) p_elan, E_RCV_CONFIG_RSP); } /*++ @@ -3092,8 +3114,9 @@ if (length < sizeof (LE_FLUSH_FRAME)) return; - EVENT(EM_DEBUG,("Received flush request, my atmaddr:%s, for :%s\n", - disp_atm_text(p_elan->lec_state.c1_my_atm_addr), + EVENT(EM_DEBUG,("Received flush request, my atmaddr:%s\n", + disp_atm_text(p_elan->lec_state.c1_my_atm_addr))); + EVENT(EM_DEBUG,(" for :%s\n", disp_atm_text(frame->target_atm_addr))); if (ATM_EQUAL (p_elan->lec_state.c1_my_atm_addr, frame->target_atm_addr)) { EVENT (EM_RDATA, ("Received Flush Request, Responding.\n")); @@ -3127,17 +3150,16 @@ LE_FLUSH_FRAME *frame; frame = (LE_FLUSH_FRAME *)p_packet; + EVENT (EM_RDATA, ("Received flush response.\n")); - if (length < sizeof (LE_FLUSH_FRAME)) + if (length < sizeof(LE_CTRL_HDR)) return; - + if ((frame->hdr.status == ntoh16 (LE_STATUS_SUCCESS)) && - (ATM_EQUAL (p_elan->lec_state.c1_my_atm_addr, frame->src_atm_addr))) { - EVENT (EM_RDATA, ("Received flush response.\n")); + (ntoh16(frame->hdr.req_lec_id) == p_elan->lec_state.c14_lec_id)) { la_flush_complete(p_elan->la_elan_handle, - frame->target_atm_addr, ntoh32 (frame->hdr.tran_id)); - } + } return; } @@ -3197,7 +3219,7 @@ p_conn = (LEC_CONN_CONTEXT *) conn_context; p_elan = (LC_ELAN_CONTEXT *) p_conn->lc_elan_handle; hdr = (LE_READY_HDR *)*pp_packet; - + if (length < sizeof (LE_READY_HDR)) return; diff -ur --new-file old/atm/led/main.c new/atm/led/main.c --- old/atm/led/main.c Mon Nov 11 16:08:29 1996 +++ new/atm/led/main.c Wed Nov 27 19:56:05 1996 @@ -596,7 +596,7 @@ conn_get_fds(&fds); FD_ZERO(&efds); conn_get_connecting_fds(&efds); - poll_ret = select(FD_SETSIZE, &fds, NULL, &efds, timeout); + poll_ret = select(FD_SETSIZE, &fds, &efds, &efds, timeout); EVENT(EM_DEBUG,("Selected .....\n\n\n")); if (poll_ret < 0) { perror("select"); diff -ur --new-file old/atm/led/timers.c new/atm/led/timers.c --- old/atm/led/timers.c Tue Aug 6 16:33:07 1996 +++ new/atm/led/timers.c Tue Nov 26 18:54:40 1996 @@ -71,8 +71,8 @@ new = (Timer_t *)mem_alloc(EINST,sizeof(Timer_t)); if (!new) return STATUS_K_RESOURCES; - EVENT(EM_TIMER, ("Os_timer_alloc timer:%lx callback:%lx\n", - (long)new,(long)callback)); + EVENT(EM_TIMER, ("Os_timer_alloc timer:%p callback:%p\n", + new, callback)); new->callback = callback; new->context = context; new->alarm_time = NULL; @@ -92,7 +92,7 @@ assert(timer_handle); - EVENT(EM_TIMER,("Os_timer_dealloc\n")); + EVENT(EM_TIMER,("Os_timer_dealloc timer: %p\n",timer_handle)); old = (Timer_t *)timer_handle; if (old->alarm_time) @@ -109,13 +109,11 @@ STATUS os_timer_set (HANDLE timer_handle, UINT32 timeset) { - struct timezone tz; /* Just to ascertain that that there won't be - memory violations in system call... */ Timer_t *to_set; assert(timer_handle); - EVENT(EM_TIMER,("Os_timer_set timer:%lx %ld ms\n", - (long)timer_handle,timeset)); + EVENT(EM_TIMER,("Os_timer_set timer:%p %ld ms\n", + timer_handle, timeset)); to_set = (Timer_t *)timer_handle; if (!(to_set->alarm_time)) { @@ -124,7 +122,7 @@ if (!(to_set->alarm_time)) return STATUS_K_RESOURCES; } - gettimeofday(to_set->alarm_time, &tz); + gettimeofday(to_set->alarm_time, NULL); (to_set->alarm_time)->tv_usec = (to_set->alarm_time)->tv_usec+(long)(timeset%1000)*1000; if ((to_set->alarm_time)->tv_usec>=1000000) { @@ -143,7 +141,7 @@ Timer_t *to_cancel; assert(timer_handle); - EVENT(EM_TIMER,("Os_timer_cancel\n")); + EVENT(EM_TIMER,("Os_timer_cancel %p\n",timer_handle)); to_cancel = (Timer_t *)timer_handle; @@ -167,10 +165,12 @@ while(current) { if (current->alarm_time) { if (!soonest->alarm_time || - ((current->alarm_time)->tv_sec <= - (soonest->alarm_time)->tv_sec && - (current->alarm_time)->tv_usec < - (soonest->alarm_time)->tv_usec)) { + ((current->alarm_time->tv_sec < + soonest->alarm_time->tv_sec) || + (current->alarm_time->tv_sec == + soonest->alarm_time->tv_sec && + current->alarm_time->tv_usec < + soonest->alarm_time->tv_usec))) { soonest = current; } } @@ -198,9 +198,9 @@ if (to_get->alarm_time) { gettimeofday(&g_timer, &tz); - EVENT(EM_DEBUG,("G_timer:%d sec %d usec\n", + EVENT(EM_TIMER,("G_timer:%d sec %d usec\n", g_timer.tv_sec,g_timer.tv_usec)); - EVENT(EM_DEBUG,("Timer :%d sec %d usec\n", + EVENT(EM_TIMER,("Timer :%d sec %d usec\n", to_get->alarm_time->tv_sec, to_get->alarm_time->tv_usec)); if (g_timer.tv_sec > (to_get->alarm_time)->tv_sec || @@ -217,7 +217,7 @@ g_timer.tv_usec = (to_get->alarm_time)->tv_usec - g_timer.tv_usec; } - EVENT(EM_DEBUG,("Return:%d sec %d usec\n",g_timer.tv_sec,g_timer.tv_usec)); + EVENT(EM_TIMER,("Return:%d sec %d usec\n",g_timer.tv_sec,g_timer.tv_usec)); return &g_timer; } else return NULL; diff -ur --new-file old/atm/lib/ans.c new/atm/lib/ans.c --- old/atm/lib/ans.c Wed Nov 13 17:03:50 1996 +++ new/atm/lib/ans.c Wed Nov 27 20:11:39 1996 @@ -57,7 +57,7 @@ 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; + if (GET16(pos) != wanted || GET16(pos+2) != C_IN) return TRY_OTHER; pos += 4; /* * Iterate over answers until we find something we like, giving priority @@ -96,30 +96,87 @@ continue; } case T_PTR: - /* ... */ + if (dn_expand(answer,answer+answer_len,data,result, + res_len) < 0) return FATAL; + return 0; + 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); + } + + + static int encode_nsap(char *buf,const unsigned char *addr) + { + static int fmt_dcc[] = { 2,12,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 4,2,0 }; + static int fmt_e164[] = { 2,12,1,1,1,1,1,1,1,1,16,2,0 }; + int *fmt; + int pos,i,j; + + switch (*addr) { + case ATM_AFI_DCC: + case ATM_AFI_ICD: + fmt = fmt_dcc; + break; + case ATM_AFI_E164: + fmt = fmt_e164; + break; default: - continue; + return TRY_OTHER; + } + pos = 2*ATM_ESA_LEN; + for (i = 0; fmt[i]; i++) { + pos -= fmt[i]; + for (j = 0; j < fmt[i]; j++) + sprintf(buf++,"%x", + (addr[(pos+j) >> 1] >> 4*(1-((pos+j) & 1))) & 0xf); + *buf++ = '.'; + } + strcpy(buf,"AESA.ATMA.INT."); + return 0; + } + + + static int encode_e164(char *buf,const char *addr) + { + char *here; + + /* + * @@@ This is wrong. It should actually look up the country prefix in a + * table to determine how many characters have to be copied "en block". + */ + for (here = strchr(addr,0); here > addr;) { + *buf++ = *--here; + *buf++ = '.'; } + strcpy(buf,"E164.ATMA.INT."); + return 0; + } + + + int ans_byaddr(char *buffer,int length,const struct sockaddr_atmsvc *addr, + int flags) + { + char tmp[MAX_NAME]; /* could be smaller ... */ + int res; + + if (addr->sas_addr.prv) res = encode_nsap(tmp,addr->sas_addr.prv); + else res = encode_e164(tmp,addr->sas_addr.pub); + if (res < 0) return res; + return ans(tmp,T_PTR,buffer,length); } - 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/arequipa.c new/atm/lib/arequipa.c --- old/atm/lib/arequipa.c Tue Oct 8 18:47:56 1996 +++ new/atm/lib/arequipa.c Thu Nov 28 13:16:05 1996 @@ -14,6 +14,17 @@ #include "arequipa.h" +static int arequipa_attach(int upper,int lower) +{ + if (ioctl(lower,AREQUIPA_PRESET,upper) < 0) { + (void) close(lower); + return -1; + } + (void) close(lower); + return 0; +} + + int arequipa_preset(int sd,const struct sockaddr_atmsvc *addr, const struct atm_qos *qos) { @@ -45,12 +56,7 @@ (void) close (s); return -1; } - if (ioctl(s,AREQUIPA_PRESET,sd) < 0) { - (void) close(s); - return -1; - } - (void) close(s); - return 0; + return arequipa_attach(sd,s); } diff -ur --new-file old/atm/maint/Makefile new/atm/maint/Makefile --- old/atm/maint/Makefile Mon Sep 2 19:41:30 1996 +++ new/atm/maint/Makefile Sun Nov 17 15:45:37 1996 @@ -5,12 +5,5 @@ include ../Rules.make -atmaddr: atmaddr.o -atmdiag: atmdiag.o -atmdump: atmdump.o -atmtcp: atmtcp.o -sonetdiag: sonetdiag.o -zntune: zntune.o - atmdiag.o: atmdiag.c $(CC) -c $(CFLAGS_NOOPT) atmdiag.c diff -ur --new-file old/atm/mkdist new/atm/mkdist --- old/atm/mkdist Sat Nov 16 00:35:40 1996 +++ new/atm/mkdist Fri Nov 29 19:48:31 1996 @@ -62,7 +62,7 @@ atm/maint/atmaddr.8 atm/maint/atmdiag.8 atm/maint/atmdump.8 \ atm/maint/atmtcp.8 atm/maint/zntune.c \ atm/test/Makefile atm/test/aread.c atm/test/awrite.c atm/test/br.c \ - atm/test/bw.c atm/test/ttcp.c atm/test/aping.c \ + atm/test/bw.c atm/test/ttcp.c atm/test/aping.c atm/test/window.c \ atm/ip/Makefile atm/ip/atmarp.c atm/ip/clip.c atm/ip/clip.8 atm/ip/atmarp.8 \ atm/debug/Makefile atm/debug/ed.c atm/debug/encopy.c atm/debug/endump.c \ atm/debug/peek.pl atm/debug/zndump.c atm/debug/znth.c atm/debug/delay.c \ @@ -101,6 +101,10 @@ 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/config/redhat-4.0/README \ + atm/config/redhat-4.0/atm atm/config/redhat-4.0/atm.init \ + atm/config/redhat-4.0/atmsigd.conf atm/config/redhat-4.0/ifcfg-atm0 \ + atm/config/redhat-4.0/ifup-atm \ 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/q2931.h new/atm/qgen/q2931.h --- old/atm/qgen/q2931.h Wed Nov 6 19:10:49 1996 +++ new/atm/qgen/q2931.h Thu Nov 28 19:40:07 1996 @@ -26,6 +26,7 @@ /* Message types */ #define QMSG_SETUP 0x05 /* SETUP */ +#define QMSG_ALERTING 0x01 /* ALERTING */ #define QMSG_CALL_PROC 0x02 /* CALL PROCEEDING */ #define QMSG_CONNECT 0x07 /* CONNECT */ #define QMSG_CONN_ACK 0x0f /* CONNECT ACKNOWLEDGE */ @@ -33,11 +34,13 @@ #define QMSG_REL_COMP 0x5a /* RELEASE COMPLETE */ #define QMSG_RESTART 0x46 /* RESTART */ #define QMSG_REST_ACK 0x4e /* RESTART ACKNOWLEDGE */ +#define QMSG_NOTIFY 0x6e /* NOTIFY */ #define QMSG_STATUS 0x7d /* STATUS */ #define QMSG_STATUS_ENQ 0x75 /* STATUS ENQUIRY */ #define QMSG_ADD_PARTY 0x80 /* ADD PARTY */ #define QMSG_ADD_PARTY_ACK 0x81 /* ADD PARTY ACKNOWLEDGE */ #define QMSG_ADD_PARTY_REJ 0x82 /* ADD PART REJECT */ +#define QMSG_PARTY_ALERT 0x85 /* PARTY ALERTING */ #define QMSG_DROP_PARTY 0x83 /* DROP PARTY */ #define QMSG_DROP_PARTY_ACK 0x84 /* DROP PARTY ACKNOWLEDGE */ diff -ur --new-file old/atm/qgen/qlib.c new/atm/qgen/qlib.c --- old/atm/qgen/qlib.c Fri Nov 15 13:05:10 1996 +++ new/atm/qgen/qlib.c Thu Nov 28 20:21:06 1996 @@ -26,7 +26,7 @@ static int debug = 0; -void q_report(int severity,const char *msg,...) +void PREFIX(report)(int severity,const char *msg,...) { va_list ap; @@ -84,10 +84,10 @@ { int end; - q_report(Q_DEBUG,"put %d %d %ld",pos,size,value); + PREFIX(report)(Q_DEBUG,"put %d %d %ld",pos,size,value); end = pos+size; if (((pos | size) & 7) && ((pos ^ (end-1)) & ~7)) - q_report(Q_FATAL,"unsupported alignment (put %d,%d)",pos,size); + PREFIX(report)(Q_FATAL,"unsupported alignment (put %d,%d)",pos,size); if (size <= 8) { unsigned char *here; int shift; @@ -112,10 +112,10 @@ unsigned long value; int end; - q_report(Q_DEBUG,"get %d %d ...",pos,size); + PREFIX(report)(Q_DEBUG,"get %d %d ...",pos,size); end = pos+size; if (((pos | size) & 7) && ((pos ^ (end-1)) & ~7)) - q_report(Q_FATAL,"unsupported alignment (get %d,%d)",pos,size); + PREFIX(report)(Q_FATAL,"unsupported alignment (get %d,%d)",pos,size); if (size <= 8) value = (table[pos >> 3] >> (pos & 7)) & ((1 << size)-1); else { table += pos >> 3; @@ -125,7 +125,7 @@ size -= 8; } } - q_report(Q_DEBUG," %ld",value); + PREFIX(report)(Q_DEBUG," %ld",value); return value; } @@ -178,7 +178,7 @@ return -1; } memset(dsc->field_present,0,bytes); - bytes = (Q_GROUPS+7) >> 3; + bytes = (Q_GROUPS+(sizeof(unsigned long)*8-1)) >> 3; dsc->group_present = malloc(bytes); if (!dsc->group_present) { perror("out of memory"); @@ -207,7 +207,7 @@ int *scan; while (group != -1) { - q_set(dsc->group_present,group); + q_set((unsigned char *) dsc->group_present,group); for (scan = groups[group].required; scan && *scan != -1; scan++) q_set(dsc->required,*scan); group = groups[group].parent; @@ -220,17 +220,17 @@ int *walk; if (field < 0 || field >= Q_FIELDS) - q_report(Q_FATAL,"invalid field value (%d)",field); + PREFIX(report)(Q_FATAL,"invalid field value (%d)",field); if (!fields[field].values) { if (q_test(dsc->field_present,field)) /* probably an error ... */ - q_report(Q_ERROR,"changing field %d",field); + PREFIX(report)(Q_ERROR,"changing field %d",field); q_set(dsc->field_present,field); q_put(dsc->data,fields[field].pos,fields[field].size,value); use_group(dsc,fields[field].parent); } else { if (q_test(dsc->field_present,field)) - q_report(Q_FATAL,"can't change field %d",field); + PREFIX(report)(Q_FATAL,"can't change field %d",field); q_set(dsc->field_present,field); q_put(dsc->data,fields[field].pos,fields[field].size,value); for (walk = fields[field].values; walk[1] != -1; walk += 2) @@ -238,7 +238,7 @@ use_group(dsc,walk[1]); return; } - q_report(Q_ERROR,"invalid value (%d in field %d)",value,field); + PREFIX(report)(Q_ERROR,"invalid value (%d in field %d)",value,field); dsc->error = 1; } } @@ -247,21 +247,21 @@ void q_write(Q_DSC *dsc,int field,const void *buf,int size) { if (field < 0 || field >= Q_FIELDS) - q_report(Q_FATAL,"invalid field value (%d)",field); + PREFIX(report)(Q_FATAL,"invalid field value (%d)",field); if (fields[field].pos & 7) - q_report(Q_FATAL,"invalid use of q_write (%d)",field); + PREFIX(report)(Q_FATAL,"invalid use of q_write (%d)",field); if (fields[field].actual >= 0) { if (size > fields[field].size/8) { - q_report(Q_ERROR,"%d bytes too big for %d byte field %d",size, - fields[field].size/8,field); + PREFIX(report)(Q_ERROR,"%d bytes too big for %d byte field %d", + size,fields[field].size/8,field); dsc->error = 1; return; } dsc->length[fields[field].actual] = size; } else if ((fields[field].pos | fields[field].size) & 7) - q_report(Q_FATAL,"field %d is neither var-len nor well-shaped", - field); + PREFIX(report)(Q_FATAL,"field %d is neither var-len nor " + "well-shaped",field); memcpy(dsc->data+(fields[field].pos/8),buf,(size_t) size); q_set(dsc->field_present,field); use_group(dsc,fields[field].parent); @@ -272,14 +272,15 @@ { if (field < 0) { if (field < -Q_GROUPS) - q_report(Q_FATAL,"invalid group number (%d)",field); - return q_test(dsc->group_present,-field-1); + PREFIX(report)(Q_FATAL,"invalid group number (%d)",field); + return q_test((unsigned char *) dsc->group_present,-field-1); } else { if (field >= Q_FIELDS) - q_report(Q_FATAL,"invalid field number (%d)",field); + PREFIX(report)(Q_FATAL,"invalid field number (%d)",field); if (q_test(dsc->field_present,field)) return 1; - return q_test(dsc->group_present,fields[field].parent); + return q_test((unsigned char *) dsc->group_present, + fields[field].parent); } } @@ -287,7 +288,7 @@ unsigned long q_fetch(const Q_DSC *dsc,int field) { if (field < 0 || field >= Q_FIELDS) - q_report(Q_FATAL,"invalid field value (%d)",field); + PREFIX(report)(Q_FATAL,"invalid field value (%d)",field); return q_get(dsc->data,fields[field].pos,fields[field].size); } @@ -295,11 +296,11 @@ int q_length(const Q_DSC *dsc,int field) { if (field < 0 || field >= Q_FIELDS) - q_report(Q_FATAL,"invalid field value (%d)",field); + PREFIX(report)(Q_FATAL,"invalid field value (%d)",field); if (fields[field].pos & 7) - q_report(Q_FATAL,"invalid use of q_length (%d)",field); + PREFIX(report)(Q_FATAL,"invalid use of q_length (%d)",field); if (fields[field].actual < 0) - q_report(Q_FATAL,"field %d is not var-len",field); + PREFIX(report)(Q_FATAL,"field %d is not var-len",field); return dsc->length[fields[field].actual]; } @@ -309,16 +310,16 @@ int len; if (field < 0 || field >= Q_FIELDS) - q_report(Q_FATAL,"invalid field value (%d)",field); + PREFIX(report)(Q_FATAL,"invalid field value (%d)",field); if (fields[field].pos & 7) - q_report(Q_FATAL,"invalid use of q_read (%d)",field); + PREFIX(report)(Q_FATAL,"invalid use of q_read (%d)",field); if (fields[field].actual >= 0) len = dsc->length[fields[field].actual]; else if (!(fields[field].size & 7)) len = fields[field].size >> 3; - else q_report(Q_FATAL,"field %d is not byte-sized (%d bits)",field, - fields[field].size); + else PREFIX(report)(Q_FATAL,"field %d is not byte-sized (%d bits)", + field,fields[field].size); if (size < len) { - q_report(Q_ERROR,"%d bytes too big for %d byte buffer (field %d)",len, - size,field); + PREFIX(report)(Q_ERROR,"%d bytes too big for %d byte buffer (field " + "%d)",len,size,field); dsc->error = 1; return -1; } @@ -336,7 +337,7 @@ for (i = 0; i < Q_FIELDS; i++) if (q_test(dsc->required,i) && !q_test(dsc->field_present,i)) - q_report(Q_ERROR,"required field %d is missing",i); + PREFIX(report)(Q_ERROR,"required field %d is missing",i); memset(buf,0,(size_t) size); if (q_dump) for (j = 0; j < 100; j += 20) { @@ -348,15 +349,16 @@ pc = construct; sp = 0; while (1) { - q_report(Q_DEBUG,"%d(%d):",pc-construct,pos-buf); + PREFIX(report)(Q_DEBUG,"%d(%d):",pc-construct,pos-buf); switch (*pc++) { case OP_COPY: if (size < *pc) { - q_report(Q_ERROR,"not enough space (%d < %d)",size,*pc); + PREFIX(report)(Q_ERROR,"not enough space (%d < %d)",size, + *pc); dsc->error = 1; return -1; } - q_report(Q_DEBUG,"copy %d %d %d",pc[1],pos-buf,pc[2]); + PREFIX(report)(Q_DEBUG,"copy %d %d %d",pc[1],pos-buf,pc[2]); q_copy(dsc->data,pc[1],pos,pc[2]); if (q_dump) { for (i = 0; i < 50; i++) fprintf(stderr,"%02X ",buf[i]); @@ -368,7 +370,7 @@ break; case OP_COPYVAR: if (size < dsc->length[*pc]) { - q_report(Q_ERROR,"not enough space (%d < %d)",size, + PREFIX(report)(Q_ERROR,"not enough space (%d < %d)",size, dsc->length[*pc]); dsc->error = 1; return -1; @@ -380,12 +382,13 @@ break; case OP_BEGIN_LEN: if (size < *pc) { - q_report(Q_ERROR,"not enough space (%d < %d)",size,*pc); + PREFIX(report)(Q_ERROR,"not enough space (%d < %d)",size, + *pc); dsc->error = 1; return -1; } if (sp == LENGTH_STACK) { - q_report(Q_ERROR,"length stack overflow"); + PREFIX(report)(Q_ERROR,"length stack overflow"); dsc->error = 1; return -1; } @@ -398,12 +401,12 @@ pc += 3; break; case OP_END_LEN: - if (!sp--) q_report(Q_FATAL,"length stack underflow"); + if (!sp--) PREFIX(report)(Q_FATAL,"length stack underflow"); q_put(stack[sp].start,0,stack[sp].size, (size_t) ((pos-stack[sp].start)-((stack[sp].size+7) >> 3))); break; case OP_IFGROUP: - if (q_test(dsc->group_present,*pc++)) pc++; + if (q_test((unsigned char *) dsc->group_present,*pc++)) pc++; else pc += *pc+1; break; #if 0 @@ -412,13 +415,15 @@ int len; for (len = *pc++; len; len--) - if (!q_test(dsc->group_present,*pc++)) pc++; + if (!q_test((unsigned char *) dsc->group_present,*pc++)) + pc++; else { pc += *pc+1; break; } if (!len) - q_report(Q_FATAL,"multi failed (pc %d)",pc-construct); + PREFIX(report)(Q_FATAL,"multi failed (pc %d)", + pc-construct); } break; #endif @@ -428,7 +433,7 @@ case OP_END: return pos-buf; default: - q_report(Q_FATAL,"unrecognized opcode %d",pc[-1]); + PREFIX(report)(Q_FATAL,"unrecognized opcode %d",pc[-1]); return -1; /* for gcc */ } } @@ -451,9 +456,9 @@ { Q_ERR_DSC *error,**last; - q_report(Q_ERROR,q_err_msg[type],value); - q_report(Q_ERROR,"[ PC=%d SP=%d RP=%d, pos=%d end=%d ]",*pc-parse,*sp,*rp, - *pos-buf,*end-buf); + PREFIX(report)(Q_ERROR,q_err_msg[type],value); + PREFIX(report)(Q_ERROR,"[ PC=%d SP=%d RP=%d, pos=%d end=%d ]",*pc-parse, + *sp,*rp,*pos-buf,*end-buf); error = alloc_t(Q_ERR_DSC); error->type = type; error->pc = *pc-parse; @@ -501,7 +506,7 @@ pc = parse; sp = rp = 0; while (1) { - q_report(Q_DEBUG,"%d(%d):",pc-parse,pos-buf); + PREFIX(report)(Q_DEBUG,"%d(%d):",pc-parse,pos-buf); switch (*pc++) { #ifdef DUMP_MODE case OP_DUMP: @@ -536,10 +541,10 @@ #endif case OP_COPY: if (pos+*pc > end) { - ERROR(qet_space,end-buf); + ERROR(qet_space,end-pos); continue; } - q_report(Q_DEBUG,"copy %d %d %d",pc[1],pos-buf,pc[2]); + PREFIX(report)(Q_DEBUG,"copy %d %d %d",pc[1],pos-buf,pc[2]); q_copy(pos,pc[1] & 7,dsc->data+(pc[1] >> 3),pc[2]); if (q_dump) { for (i = 0; i < 20; i++) @@ -556,7 +561,7 @@ len = end-pos; if (len > pc[2]) len = pc[2]; memcpy(dsc->data+pc[1]/8,pos,(size_t) len); - q_report(Q_DEBUG,"len %d for %d",len,*pc); + PREFIX(report)(Q_DEBUG,"len %d for %d",len,*pc); dsc->length[*pc] = len; pos += len; pc += 3; @@ -564,23 +569,24 @@ } case OP_BEGIN_LEN: if (pos+*pc > end) { - ERROR(qet_space,end-buf); + ERROR(qet_space,end-pos); continue; } if (sp == LENGTH_STACK) - q_report(Q_FATAL,"length stack overflow"); + PREFIX(report)(Q_FATAL,"length stack overflow"); stack[sp] = end; end = pos+q_get(pos,pc[1] & 7,pc[2])+*pc; - if (end > stack[sp]) q_report(Q_FATAL,"length has grown"); + if (end > stack[sp]) + PREFIX(report)(Q_FATAL,"length has grown"); pos += *pc; sp++; pc += 3; break; case OP_BEGIN_REC: - q_report(Q_DEBUG,"begin_rec pc %d sp %d pos %d end %d", + PREFIX(report)(Q_DEBUG,"begin_rec pc %d sp %d pos %d end %d", pc-parse,sp,pos-buf,end-buf); if (rp == LENGTH_R_STACK) - q_report(Q_FATAL,"recovery stack overflow"); + PREFIX(report)(Q_FATAL,"recovery stack overflow"); r_stack[rp].pc = pc; r_stack[rp].sp = sp; r_stack[rp].pos = pos; @@ -589,19 +595,19 @@ pc += 3; break; case OP_END_LEN: - if (!sp--) q_report(Q_FATAL,"length stack underflow"); + if (!sp--) PREFIX(report)(Q_FATAL,"length stack underflow"); end = stack[sp]; break; case OP_END_REC: - q_report(Q_DEBUG,"end_rec"); - if (!rp--) q_report(Q_FATAL,"recovery stack underflow"); + PREFIX(report)(Q_DEBUG,"end_rec"); + if (!rp--) PREFIX(report)(Q_FATAL,"recovery stack underflow"); break; case OP_CASE: { int len,value,group; if (pos+*pc > end) { - ERROR(qet_space,end-buf); + ERROR(qet_space,end-pos); continue; } value = q_get(pos,pc[1] & 7,pc[2]); @@ -613,7 +619,8 @@ pc++; for (group = *pc++; group != -1; group = groups[group].parent) - q_set(dsc->group_present,group); + q_set((unsigned char *) dsc->group_present, + group); pc += *pc+1; break; } @@ -627,7 +634,7 @@ pc += *pc+1; break; case OP_IFEND: - q_report(Q_DEBUG,"ifend - %d/%d",pos-buf,end-buf); + PREFIX(report)(Q_DEBUG,"ifend - %d/%d",pos-buf,end-buf); if (pos == end) pc += *pc; pc++; break; @@ -637,7 +644,7 @@ case OP_END: return dsc->errors ? -1 : 0; default: - q_report(Q_FATAL,"unrecognized opcode %d",pc[-1]); + PREFIX(report)(Q_FATAL,"unrecognized opcode %d",pc[-1]); return -1; /* for gcc */ } } @@ -655,13 +662,13 @@ for (walk = dsc->errors; walk; walk = walk->next) { gs[gp = 0] = walk->group; - q_clear(dsc->group_present,walk->group); + q_clear((unsigned char *) dsc->group_present,walk->group); for (i = walk->group+1; i < Q_GROUPS; i++) { while (groups[i].parent != gs[gp]) if (!gp--) break; if (gp < 0) break; gs[++gp] = i; - q_clear(dsc->group_present,i); + q_clear((unsigned char *) dsc->group_present,i); } for (j = 0; j < Q_FIELDS; j++) if (fields[j].parent == walk->group) break; @@ -698,7 +705,7 @@ putc('\n',stderr); } for (i = 0; i < Q_GROUPS; i++) - if (q_test(dsc->group_present,i)) + if (q_test((unsigned char *) dsc->group_present,i)) for (p = groups[i].required; p && *p != -1; p++) fprintf(stderr,"%d: %ld / 0x%lx\n",*p, q_get(dsc->data,fields[*p].pos,fields[*p].size), diff -ur --new-file old/atm/qgen/qlib.h new/atm/qgen/qlib.h --- old/atm/qgen/qlib.h Fri Nov 15 13:04:08 1996 +++ new/atm/qgen/qlib.h Thu Nov 28 20:19:44 1996 @@ -29,9 +29,12 @@ extern int q_dump; extern void q_report(int severity,const char *msg,...); -#if defined(DUMP_MODE) && !defined(STANDALONE) +#ifdef DUMP_MODE +#ifndef STANDALONE extern void qd_dump(const char *fmt,...); #endif +extern void qd_report(int severity,const char *msg,...); +#endif typedef enum { qet_catch_zero,qet_space,qet_case,qet_abort } Q_ERR_TYPE; @@ -52,7 +55,7 @@ unsigned char *data; unsigned char *required; unsigned char *field_present; - unsigned char *group_present; + unsigned long *group_present; int *length; void *buffer; int buf_size; diff -ur --new-file old/atm/saal/sscop.c new/atm/saal/sscop.c --- old/atm/saal/sscop.c Fri Nov 15 13:51:33 1996 +++ new/atm/saal/sscop.c Mon Nov 25 18:28:13 1996 @@ -977,7 +977,7 @@ dsc->vr_h = MOD24(s+1); return; } - if (queue_lookup(&dsc->rx_buf,s)) queue_put(&dsc->rx_buf,buf); + if (!queue_lookup(&dsc->rx_buf,s)) queue_put(&dsc->rx_buf,buf); else { buffer_discard(buf); start_error_recov(dsc,'Q'); diff -ur --new-file old/atm/sigd/Makefile new/atm/sigd/Makefile --- old/atm/sigd/Makefile Mon Sep 2 19:41:43 1996 +++ new/atm/sigd/Makefile Fri Nov 29 19:47:01 1996 @@ -1,7 +1,8 @@ LIBS=-L../saal -lsaal -latmd -lfl # lex may want -ll here INCLUDES=-I../qgen -I../saal -I. OBJS=atmsigd.o io.o kernel.o mess.o proto.o q2931.o sap.o timeout.o trace.o \ - q.out.o qd.dump.o lex.yy.o y.tab.o + lex.yy.o y.tab.o +EXTOBJS=../qgen/q.out.o ../qgen/qd.dump.o BOOTPGMS=atmsigd TRASH=q.out.h q.out.o qd.dump.o mess.c MAN4=atmsigd.conf.4 @@ -11,7 +12,8 @@ CFLAGS += $(STANDARDS) atmsigd: $(OBJS) - $(CC) $(LDFLAGS) -o atmsigd $(OBJS) $(LDLIBS) $(LIBS) + $(CC) $(LDFLAGS) -o atmsigd $(OBJS) $(EXTOBJS) \ + $(LDLIBS) $(LIBS) lex.yy.c: cfg.l y.tab.h ../lib/atm.h $(LEX) cfg.l @@ -19,16 +21,17 @@ y.tab.c y.tab.h: cfg.y ../lib/atmd.h proto.h io.h $(YACC) -d cfg.y -q.out.o: - ln -s ../qgen/q.out.o +mess.c: ../qgen/q2931.h mkmess.pl + ./mkmess.pl <../qgen/q2931.h >mess.c -qd.dump.o: - ln -s ../qgen/qd.dump.o +# +# The following hack makes sure that "make depend" finds q.out.h and is +# happy with it. Once qgen has been built, there will be ../qgen/q.out.h, +# which is first in the include file search path and therefore gets +# included. An second "make depend" will also use the right file. +# depend: fake_q.out.h - -mess.c: ../qgen/q2931.h mkmess.pl - ./mkmess.pl <../qgen/q2931.h >mess.c fake_q.out.h: echo "! This must not compile" >q.out.h diff -ur --new-file old/atm/sigd/q2931.c new/atm/sigd/q2931.c --- old/atm/sigd/q2931.c Thu Sep 26 20:17:06 1996 +++ new/atm/sigd/q2931.c Fri Nov 29 17:28:45 1996 @@ -78,6 +78,9 @@ this->call_ref = call_ref; if (q_present(&in_dsc,QF_ep_ref)) this->ep_ref = q_fetch(&in_dsc,QF_ep_ref); +#ifdef CISCO + else +#endif send_call_proceeding(this); this->local = new_sap; this->qos = new_qos; diff -ur --new-file old/atm/sigd/trace.c new/atm/sigd/trace.c --- old/atm/sigd/trace.c Wed Oct 9 11:04:32 1996 +++ new/atm/sigd/trace.c Fri Nov 29 18:45:47 1996 @@ -126,16 +126,13 @@ } -void qd_dump(const char *msg,...) +static void qd_vdump(const char *msg,va_list ap) { const char *prev,*end; - va_list ap; if (new_line) append(" "); prev = string; - va_start(ap,msg); vappend(msg,ap); - va_end(ap); if (!prev) prev = string; if (!prev) new_line = 1; else { @@ -143,6 +140,28 @@ else end++; new_line = !*end; } +} + + +void qd_dump(const char *msg,...) +{ + va_list ap; + + va_start(ap,msg); + qd_vdump(msg,ap); + va_end(ap); +} + + +void qd_report(int severity,const char *msg,...) +{ + va_list ap; + + if (severity > Q_ERROR) return; + va_start(ap,msg); + qd_vdump(msg,ap); + va_end(ap); + qd_dump("\n"); } diff -ur --new-file old/atm/test/Makefile new/atm/test/Makefile --- old/atm/test/Makefile Fri Nov 15 23:39:44 1996 +++ new/atm/test/Makefile Sun Nov 17 15:42:23 1996 @@ -3,13 +3,5 @@ include ../Rules.make -aping: aping.o -aread: aread.o -awrite: awrite.o -br: br.o -bw: bw.o -ttcp_atm: ttcp_atm.o -window: window.o - ttcp_atm.o: ttcp.c gcc -c -w -O2 -o ttcp_atm.o ttcp.c -I../lib diff -ur --new-file old/atm/test/ttcp.c new/atm/test/ttcp.c --- old/atm/test/ttcp.c Mon Nov 4 13:02:41 1996 +++ new/atm/test/ttcp.c Tue Nov 26 20:58:40 1996 @@ -483,15 +483,23 @@ err("accept"); { - struct sockaddr_in peer; + struct sockaddr_atmsvc peer; int peerlen = sizeof(peer); if (getpeername(fd, (struct sockaddr_in *) &peer, &peerlen) < 0) { err("getpeername"); } - if (atm) fprintf(stderr,"ttcp-r: accept\n"); + if (atm) { + char name[MAX_ATM_ADDR_LEN+1]; + + if (atm2text(name,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) + &peer,A2T_NAME | A2T_PRETTY) < 0) + strcpy(name,""); + fprintf(stderr,"ttcp-r: accept from %s\n",name); + } else fprintf(stderr,"ttcp-r: accept from %s\n", - inet_ntoa(peer.sin_addr)); + inet_ntoa(((struct sockaddr_in *) &peer)-> + sin_addr)); } if (options) { diff -ur --new-file old/atm/test/window.c new/atm/test/window.c --- old/atm/test/window.c Thu Jan 1 01:00:00 1970 +++ new/atm/test/window.c Fri Nov 15 23:53:38 1996 @@ -0,0 +1,269 @@ +/* window.c, M. Welsh (mdw24@cl.cam.ac.uk) + * A simple bandwidth/latency benchmark for Linux/ATM. Usage: + * window [send | recv] + * where + * is the VPI/VCI to transmit data on + * is the VPI/VCI to transmit ACKs on + * is the number of iterations to run + * is the size of each message to send + * is the number of messages to send between ACKs + * + * Two VC's are used so that the program can be run between two processes + * on the same machine. + * + * Example: + * apple% window recv 0.32 0.33 1000 1024 10 + * banana% window send 0.32 0.33 1000 1024 10 + * + * Copyright (c) 1996 University of Cambridge Computer Laboratory + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * M. Welsh, 6 July 1996 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef MDW_DEBUG +#undef TERSE_OUTPUT +#define REPLY_SIZE 40 +#define MAX_WINDOW_SIZE 100 + +static double get_seconds(void) { + struct timeval t; + gettimeofday(&t,NULL); + return (double)t.tv_sec+((double)t.tv_usec/(double)1e6); +} + +void main(int argc, char **argv) { + struct sockaddr_atmpvc addr1, addr2; + struct atm_qos qos1, qos2; + char *buffer; + char buffer2[REPLY_SIZE]; + int blocks, s1, s2; + size_t size; + + char *theaddr1, *theaddr2; + int NUM_WINDOWS; + int PINGPONG_SIZE; + int WINDOW_SIZE; + + + int i, w, j; + int sending = 0; + double t1, t2; + + + if (argc != 7) { + fprintf(stderr,"Usage: window [send | recv] \n"); + exit(-1); + } + if (!strcmp(argv[1],"send")) sending = 1; + + theaddr1 = argv[2]; + theaddr2 = argv[3]; + NUM_WINDOWS = atoi(argv[4]); + PINGPONG_SIZE = atoi(argv[5]); + WINDOW_SIZE = atoi(argv[6]); + + if (WINDOW_SIZE > MAX_WINDOW_SIZE) { + fprintf(stderr,"Maximum window size is %d.\n",MAX_WINDOW_SIZE); + exit(-1); + } + + if ((s1 = socket(PF_ATMPVC,SOCK_DGRAM,ATM_AAL5)) < 0) { + perror("socket"); + exit(-1); + } + if ((s2 = socket(PF_ATMPVC,SOCK_DGRAM,ATM_AAL5)) < 0) { + perror("socket"); + exit(-1); + } + memset(&addr1, 0, sizeof(addr1)); + memset(&addr2, 0, sizeof(addr2)); + if (text2atm(theaddr1, (struct sockaddr *)&addr1, sizeof(addr1), T2A_PVC | T2A_UNSPEC | T2A_WILDCARD) < 0) { + fprintf(stderr,"window: invalid address syntax\n"); + exit(-1); + } + if (text2atm(theaddr2, (struct sockaddr *)&addr2, sizeof(addr2), T2A_PVC | T2A_UNSPEC | T2A_WILDCARD) < 0) { + fprintf(stderr,"window: invalid address syntax\n"); + exit(-1); + } + + + /* Do a lot of them */ + if (sending) { + buffer = (char *)malloc(PINGPONG_SIZE); + if (!buffer) { + fprintf(stderr,"Can't malloc buffer\n"); + exit(-1); + } + for (i = 0; i < PINGPONG_SIZE; i++) { + buffer[i] = i&0xff; + } + + memset(&qos1,0,sizeof(qos1)); + memset(&qos2,0,sizeof(qos2)); + + qos1.txtp.traffic_class = ATM_UBR; + qos1.txtp.max_sdu = PINGPONG_SIZE; + qos2.rxtp.traffic_class = ATM_UBR; + qos2.rxtp.max_sdu = REPLY_SIZE; + + if (setsockopt(s1,SOL_ATM,SO_ATMQOS,&qos1,sizeof(qos1)) < 0) { + perror("setsockopt SO_ATMQOS1"); + exit(-1); + } + if (setsockopt(s2,SOL_ATM,SO_ATMQOS,&qos2,sizeof(qos2)) < 0) { + perror("setsockopt SO_ATMQOS2"); + exit(-1); + } + + if (connect(s1, (struct sockaddr *)&addr1, sizeof(addr1)) < 0) { + perror("connect"); + exit(-1); + } + if (bind(s2, (struct sockaddr *)&addr2, sizeof(addr1)) < 0) { + perror("bind"); + exit(-1); + } + +#ifndef TERSE_OUTPUT + fprintf(stderr,"Sending %d %d-byte messages, window size %d.\n", + NUM_WINDOWS*WINDOW_SIZE,PINGPONG_SIZE,WINDOW_SIZE); +#endif + + t1 = get_seconds(); + for (i = 0; i < NUM_WINDOWS; i++) { +#ifdef MDW_DEBUG + fprintf(stderr,"Sending %d...",i); +#endif + for (w = 0; w < WINDOW_SIZE; w++) { + (void)write(s1, buffer, PINGPONG_SIZE); + } + +#ifdef MDW_DEBUG + fprintf(stderr,"sent!..."); +#endif + +#if 1 /* XXX mdw testing! XXX XXX */ + /* Get a reply */ + size = read(s2, buffer2, REPLY_SIZE); + if (size != REPLY_SIZE) { + fprintf(stderr,"Received reply of length %d, should be %d.\n", + size,REPLY_SIZE); + } +#endif + } + + t2 = get_seconds(); + +#ifdef TERSE_OUTPUT + fprintf(stderr,"%d %d %d %f %f %f\n", + NUM_WINDOWS, PINGPONG_SIZE, WINDOW_SIZE, + (t2-t1), + ((t2-t1)*1e6)/(NUM_WINDOWS*WINDOW_SIZE), + (NUM_WINDOWS*WINDOW_SIZE*PINGPONG_SIZE*8)/(1e6*(t2-t1))); +#else + fprintf(stderr,"Sent %d %d-byte messages (window size %d) in %f seconds.\n", + NUM_WINDOWS*WINDOW_SIZE,PINGPONG_SIZE,WINDOW_SIZE,(t2-t1)); + fprintf(stderr,"%f usec/message or %f Mbit/sec\n", + ((t2-t1)*1e6)/(NUM_WINDOWS*WINDOW_SIZE), + (NUM_WINDOWS*WINDOW_SIZE*PINGPONG_SIZE*8)/(1e6*(t2-t1))); +#endif + + } else { + + buffer = (char *)malloc(PINGPONG_SIZE); + if (!buffer) { + fprintf(stderr,"Can't malloc buffer\n"); + exit(-1); + } + + memset(&qos1,0,sizeof(qos1)); + memset(&qos2,0,sizeof(qos2)); + + qos1.rxtp.traffic_class = ATM_UBR; + qos1.rxtp.max_sdu = PINGPONG_SIZE; + qos2.txtp.traffic_class = ATM_UBR; + qos2.txtp.max_sdu = REPLY_SIZE; + + if (setsockopt(s1,SOL_ATM,SO_ATMQOS,&qos1,sizeof(qos1)) < 0) { + perror("setsockopt SO_ATMQOS1"); + exit(-1); + } + if (setsockopt(s2,SOL_ATM,SO_ATMQOS,&qos2,sizeof(qos2)) < 0) { + perror("setsockopt SO_ATMQOS2"); + exit(-1); + } + + + if (bind(s1, (struct sockaddr *)&addr1, sizeof(addr1)) < 0) { + perror("bind"); + exit(-1); + } + if (connect(s2, (struct sockaddr *)&addr2, sizeof(addr2)) < 0) { + perror("connect"); + exit(-1); + } + + i = 0; + while (i < NUM_WINDOWS*WINDOW_SIZE) { +#ifdef MDW_DEBUG + fprintf(stderr,"Receiving %d... ",i); +#endif + + size = read(s1, buffer, PINGPONG_SIZE); + +#ifdef MDW_DEBUG + fprintf(stderr,"received!\n"); +#endif + + + if (size == PINGPONG_SIZE) { + i++; + if ((i % WINDOW_SIZE) == 0) { + /* Send reply */ +#ifdef MDW_DEBUG + fprintf(stderr,"Sending reply..."); +#endif + (void)write(s2, buffer2, REPLY_SIZE); +#ifdef MDW_DEBUG + fprintf(stderr,"sent!\n"); +#endif + } + + } else { + fprintf(stderr,"Received message of length %d, should be %d.\n", + size,PINGPONG_SIZE); + } + } + } + + exit(0); +} .