summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorchuck <chuck@cvs.openbsd.org>1996-06-21 15:14:36 +0000
committerchuck <chuck@cvs.openbsd.org>1996-06-21 15:14:36 +0000
commit5729aed5f06b06d46c3f14085e8ec702e0b52fbf (patch)
tree07af9a76444bde182a898ebc25aaf26c7ce3b7ce /sys/net
parent750a8db140259c9fe21cd465f178259641d05a62 (diff)
network support for ATM networks (ATM == Async Transfer Mode, not
Automatic Teller Machine). Currently supports PVCs only (no ATM ARP either).
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_atm.h88
-rw-r--r--sys/net/if_atmsubr.c265
2 files changed, 353 insertions, 0 deletions
diff --git a/sys/net/if_atm.h b/sys/net/if_atm.h
new file mode 100644
index 00000000000..a836508e04b
--- /dev/null
+++ b/sys/net/if_atm.h
@@ -0,0 +1,88 @@
+/* $OpenBSD: if_atm.h,v 1.1 1996/06/21 15:13:39 chuck Exp $ */
+
+/*
+ *
+ * Copyright (c) 1996 Charles D. Cranor
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Charles D. Cranor.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * net/if_atm.h
+ */
+
+/*
+ * pseudo header for packet transmission
+ */
+
+struct atm_pseudohdr {
+ u_int8_t atm_ph[4]; /* flags+VPI+VCI1(msb)+VCI2(lsb) */
+};
+
+#define ATM_PH_FLAGS(X) ((X)->atm_ph[0])
+#define ATM_PH_VPI(X) ((X)->atm_ph[1])
+#define ATM_PH_VCI(X) ((((X)->atm_ph[2]) << 8) | ((X)->atm_ph[3]))
+#define ATM_PH_SETVCI(X,V) { \
+ (X)->atm_ph[2] = ((V) >> 8) & 0xff; \
+ (X)->atm_ph[3] = ((V) & 0xff); \
+}
+
+#define ATM_PH_AAL5 0x01 /* use AAL5? (0 == aal0) */
+#define ATM_PH_LLCSNAP 0x02 /* use the LLC SNAP encoding (iff aal5) */
+
+#define ATM_PH_DRIVER7 0x40 /* reserve for driver's use */
+#define ATM_PH_DRIVER8 0x80 /* reserve for driver's use */
+
+#define ATMMTU 9180 /* ATM MTU size for IP */
+ /* XXX: could be 9188 with LLC/SNAP according
+ to comer */
+
+/* pseudo ioctl */
+#define SIOCATMENA _IOWR('a', 122, struct atm_pseudohdr) /* enable */
+#define SIOCATMDIS _IOWR('a', 123, struct atm_pseudohdr) /* disable */
+
+/*
+ * XXX forget all the garbage in if_llc.h and do it the easy way
+ */
+
+#define ATMLLC_HDR "\252\252\3\0\0\0"
+struct atmllc {
+ u_int8_t llchdr[6]; /* aa.aa.03.00.00.00 */
+ u_int8_t type[2]; /* "ethernet" type */
+};
+
+#define ATM_LLC_TYPE(X) (((X)->type[1] << 8) | ((X)->type[0]))
+#define ATM_LLC_SETTYPE(X,V) { \
+ (X)->type[1] = ((V) >> 8) & 0xff; \
+ (X)->type[0] = ((V) & 0xff); \
+}
+
+#ifdef _KERNEL
+void atm_ifattach __P((struct ifnet *));
+int atm_output __P((struct ifnet *, struct mbuf *, struct sockaddr *,
+ struct rtentry *));
+#endif
diff --git a/sys/net/if_atmsubr.c b/sys/net/if_atmsubr.c
new file mode 100644
index 00000000000..e91d6cff8ad
--- /dev/null
+++ b/sys/net/if_atmsubr.c
@@ -0,0 +1,265 @@
+/* $OpenBSD: if_atmsubr.c,v 1.1 1996/06/21 15:13:40 chuck Exp $ */
+
+/*
+ *
+ * Copyright (c) 1996 Charles D. Cranor
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Charles D. Cranor.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * if_atmsubr.c
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/syslog.h>
+
+#include <machine/cpu.h>
+
+#include <net/if.h>
+#include <net/netisr.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/if_atm.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h> /* XXX: for ETHERTYPE_* */
+#ifdef INET
+#include <netinet/in_var.h>
+#endif
+
+#define senderr(e) { error = (e); goto bad;}
+
+/*
+ * atm_output: ATM output routine
+ * inputs:
+ * "ifp" = ATM interface to output to
+ * "m0" = the packet to output
+ * "dst" = the sockaddr to send to (either IP addr, or raw VPI/VCI)
+ * "rt0" = the route to use
+ * returns: error code [0 == ok]
+ */
+
+int
+atm_output(ifp, m0, dst, rt0)
+ register struct ifnet *ifp;
+ struct mbuf *m0;
+ struct sockaddr *dst;
+ struct rtentry *rt0;
+{
+ u_int16_t etype = 0; /* if using LLC/SNAP */
+ int s, error = 0, sz;
+ struct atm_pseudohdr atmdst, *ad;
+ register struct mbuf *m = m0;
+ register struct rtentry *rt;
+ struct atmllc *atmllc;
+ u_int32_t atm_flags;
+
+ if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
+ senderr(ENETDOWN);
+ ifp->if_lastchange = time;
+
+ /*
+ * check route
+ */
+ if ((rt = rt0) != NULL) {
+
+ if ((rt->rt_flags & RTF_UP) == 0) { /* route went down! */
+ if ((rt0 = rt = rtalloc1(dst, 0)) != NULL)
+ rt->rt_refcnt--;
+ else
+ senderr(EHOSTUNREACH);
+ }
+
+ if (rt->rt_flags & RTF_GATEWAY) {
+ if (rt->rt_gwroute == 0)
+ goto lookup;
+ if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
+ rtfree(rt); rt = rt0;
+ lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 0);
+ if ((rt = rt->rt_gwroute) == 0)
+ senderr(EHOSTUNREACH);
+ }
+ }
+
+ /* XXX: put RTF_REJECT code here if doing ATMARP */
+
+ }
+ switch (dst->sa_family) {
+#ifdef INET
+ case AF_INET:
+ if (!atmresolve(rt, m, dst, &atmdst)) {
+ m = NULL; /* XXX: atmresolve already free'd it */
+ senderr(EHOSTUNREACH);
+ /* XXX: ATMARP stuff here, watch who frees m on fail */
+ }
+ etype = htons(ETHERTYPE_IP);
+ break;
+#endif
+
+ /* case AF_ATM: XXX: need raw ATM handle here? */
+
+ default:
+ printf("%s: can't handle af%d\n", ifp->if_xname,
+ dst->sa_family);
+ senderr(EAFNOSUPPORT);
+ }
+
+ sz = sizeof(atmdst);
+ atm_flags = ATM_PH_FLAGS(&atmdst);
+ if (atm_flags & ATM_PH_LLCSNAP) sz += 8; /* sizeof snap == 8 */
+ M_PREPEND(m, sz, M_DONTWAIT);
+ if (m == 0)
+ senderr(ENOBUFS);
+ ad = mtod(m, struct atm_pseudohdr *);
+ *ad = atmdst;
+ if (atm_flags & ATM_PH_LLCSNAP) {
+ atmllc = (struct atmllc *)(ad + 1);
+ bcopy(ATMLLC_HDR, atmllc->llchdr, sizeof(atmllc->llchdr));
+ ATM_LLC_SETTYPE(atmllc, etype); /* already in network order */
+ }
+
+ /*
+ * Queue message on interface, and start output if interface
+ * not yet active.
+ */
+
+ s = splimp();
+ if (IF_QFULL(&ifp->if_snd)) {
+ IF_DROP(&ifp->if_snd);
+ splx(s);
+ senderr(ENOBUFS);
+ }
+ ifp->if_obytes += m->m_pkthdr.len;
+ IF_ENQUEUE(&ifp->if_snd, m);
+ if ((ifp->if_flags & IFF_OACTIVE) == 0)
+ (*ifp->if_start)(ifp);
+ splx(s);
+ return (error);
+
+bad:
+ if (m)
+ m_freem(m);
+ return (error);
+}
+
+/*
+ * Process a received ATM packet;
+ * the packet is in the mbuf chain m.
+ */
+void
+atm_input(ifp, ah, m)
+ struct ifnet *ifp;
+ register struct atm_pseudohdr *ah;
+ struct mbuf *m;
+{
+ register struct ifqueue *inq;
+ u_int16_t etype = ETHERTYPE_IP; /* default */
+ int s;
+
+ if ((ifp->if_flags & IFF_UP) == 0) {
+ m_freem(m);
+ return;
+ }
+ ifp->if_lastchange = time;
+ ifp->if_ibytes += m->m_pkthdr.len;
+
+ /*
+ * handle LLC/SNAP header, if present
+ */
+ if (ATM_PH_FLAGS(ah) & ATM_PH_LLCSNAP) {
+ struct atmllc *alc;
+ if (m->m_len < sizeof(*alc) && (m = m_pullup(m, sizeof(*alc))) == 0)
+ return; /* failed */
+ alc = mtod(m, struct atmllc *);
+ if (bcmp(alc, ATMLLC_HDR, 6)) {
+ printf("%s: recv'd invalid LLC/SNAP frame [vp=%d,vc=%d]\n",
+ ifp->if_xname, ATM_PH_VPI(ah), ATM_PH_VCI(ah));
+ m_freem(m);
+ return;
+ }
+ etype = ATM_LLC_TYPE(alc);
+ m_adj(m, sizeof(*alc));
+ }
+
+ switch (etype) {
+#ifdef INET
+ case ETHERTYPE_IP:
+ schednetisr(NETISR_IP);
+ inq = &ipintrq;
+ break;
+#endif
+ default:
+ m_freem(m);
+ return;
+ }
+
+ s = splimp();
+ if (IF_QFULL(inq)) {
+ IF_DROP(inq);
+ m_freem(m);
+ } else
+ IF_ENQUEUE(inq, m);
+ splx(s);
+}
+
+/*
+ * Perform common duties while attaching to interface list
+ */
+void
+atm_ifattach(ifp)
+ register struct ifnet *ifp;
+{
+ register struct ifaddr *ifa;
+ register struct sockaddr_dl *sdl;
+
+ ifp->if_type = IFT_ATM;
+ ifp->if_addrlen = 0;
+ ifp->if_hdrlen = 0;
+ ifp->if_mtu = ATMMTU;
+ ifp->if_output = atm_output;
+ for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
+ ifa = ifa->ifa_list.tqe_next)
+ if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
+ sdl->sdl_family == AF_LINK) {
+ sdl->sdl_type = IFT_ATM;
+ sdl->sdl_alen = ifp->if_addrlen;
+#ifdef notyet /* if using ATMARP, store hardware address using the next line */
+ bcopy(ifp->hw_addr, LLADDR(sdl), ifp->if_addrlen);
+#endif
+ break;
+ }
+}