X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d52fe63fc81f7e44faaae711812a211a78434976..9bccf70c0258c7cac2dcb80011b2a964d884c552:/bsd/netiso/if_eon.c diff --git a/bsd/netiso/if_eon.c b/bsd/netiso/if_eon.c deleted file mode 100644 index 40c8716f7..000000000 --- a/bsd/netiso/if_eon.c +++ /dev/null @@ -1,627 +0,0 @@ -/* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)if_eon.c 8.1 (Berkeley) 6/10/93 - */ - -/*********************************************************** - Copyright IBM Corporation 1987 - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of IBM not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -/* - * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison - */ -/* - * EON rfc - * Layer between IP and CLNL - * - * TODO: - * Put together a current rfc986 address format and get the right offset - * for the nsel - */ - -#if EON -#define NEON 1 - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -extern struct timeval time; -extern struct ifnet loif; - -#define EOK 0 - -int eoninput(); -int eonoutput(); -int eonioctl(); -int eonattach(); -int eoninit(); -void eonrtrequest(); -struct ifnet eonif[1]; - -eonprotoinit() { - (void) eonattach(); -} - -struct eon_llinfo eon_llinfo; -#define PROBE_OK 0; - - -/* - * FUNCTION: eonattach - * - * PURPOSE: autoconf attach routine - * - * RETURNS: void - */ - -eonattach() -{ - register struct ifnet *ifp = eonif; - - IFDEBUG(D_EON) - printf("eonattach()\n"); - ENDDEBUG - ifp->if_unit = 0; - ifp->if_name = "eon"; - ifp->if_mtu = ETHERMTU; - /* since everything will go out over ether or token ring */ - - ifp->if_init = eoninit; - ifp->if_ioctl = eonioctl; - ifp->if_output = eonoutput; - ifp->if_type = IFT_EON; - ifp->if_addrlen = 5; - ifp->if_hdrlen = EONIPLEN; - ifp->if_flags = IFF_BROADCAST; - if_attach(ifp); - eonioctl(ifp, SIOCSIFADDR, (caddr_t)ifp->if_addrlist); - eon_llinfo.el_qhdr.link = - eon_llinfo.el_qhdr.rlink = &(eon_llinfo.el_qhdr); - - IFDEBUG(D_EON) - printf("eonattach()\n"); - ENDDEBUG -} - - -/* - * FUNCTION: eonioctl - * - * PURPOSE: io controls - ifconfig - * need commands to - * link-UP (core addr) (flags: ES, IS) - * link-DOWN (core addr) (flags: ES, IS) - * must be callable from kernel or user - * - * RETURNS: nothing - */ -eonioctl(ifp, cmd, data) - register struct ifnet *ifp; - int cmd; - register caddr_t data; -{ - int s = splimp(); - register int error = 0; - - IFDEBUG(D_EON) - printf("eonioctl (cmd 0x%x) \n", cmd); - ENDDEBUG - - switch (cmd) { - register struct ifaddr *ifa; - - case SIOCSIFADDR: - if (ifa = (struct ifaddr *)data) { - ifp->if_flags |= IFF_UP; - if (ifa->ifa_addr->sa_family != AF_LINK) - ifa->ifa_rtrequest = eonrtrequest; - } - break; - } - splx(s); - return(error); -} - - -eoniphdr(hdr, loc, ro, class, zero) -struct route *ro; -register struct eon_iphdr *hdr; -caddr_t loc; -{ - struct mbuf mhead; - register struct sockaddr_in *sin = (struct sockaddr_in *)&ro->ro_dst; - if (zero) { - bzero((caddr_t)hdr, sizeof (*hdr)); - bzero((caddr_t)ro, sizeof (*ro)); - } - sin->sin_family = AF_INET; - sin->sin_len = sizeof (*sin); - bcopy(loc, (caddr_t)&sin->sin_addr, sizeof(struct in_addr)); - /* - * If there is a cached route, - * check that it is to the same destination - * and is still up. If not, free it and try again. - */ - if (ro->ro_rt) { - struct sockaddr_in *dst = - (struct sockaddr_in *)rt_key(ro->ro_rt); - if ((ro->ro_rt->rt_flags & RTF_UP) == 0 || - sin->sin_addr.s_addr != dst->sin_addr.s_addr) { - RTFREE(ro->ro_rt); - ro->ro_rt = (struct rtentry *)0; - } - } - rtalloc(ro); - if (ro->ro_rt) - ro->ro_rt->rt_use++; - hdr->ei_ip.ip_dst = sin->sin_addr; - hdr->ei_ip.ip_p = IPPROTO_EON; - hdr->ei_ip.ip_ttl = MAXTTL; - hdr->ei_eh.eonh_class = class; - hdr->ei_eh.eonh_vers = EON_VERSION; - hdr->ei_eh.eonh_csum = 0; - mhead.m_data = (caddr_t) &hdr->ei_eh; - mhead.m_len = sizeof(struct eon_hdr); - mhead.m_next = 0; - IFDEBUG(D_EON) - printf("eonoutput : gen csum (0x%x, offset %d, datalen %d)\n", - &mhead, - _offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr)); - ENDDEBUG - iso_gen_csum(&mhead, - _offsetof(struct eon_hdr, eonh_csum), sizeof(struct eon_hdr)); -} -/* - * FUNCTION: eonrtrequest - * - * PURPOSE: maintains list of direct eon recipients. - * sets up IP route for rest. - * - * RETURNS: nothing - */ -void -eonrtrequest(cmd, rt, gate) -register struct rtentry *rt; -register struct sockaddr *gate; -{ - unsigned long zerodst = 0; - caddr_t ipaddrloc = (caddr_t) &zerodst; - register struct eon_llinfo *el = (struct eon_llinfo *)rt->rt_llinfo; - - /* - * Common Housekeeping - */ - switch (cmd) { - case RTM_DELETE: - if (el) { - remque(&(el->el_qhdr)); - if (el->el_iproute.ro_rt) - RTFREE(el->el_iproute.ro_rt); - Free(el); - rt->rt_llinfo = 0; - } - return; - - case RTM_ADD: - case RTM_RESOLVE: - rt->rt_rmx.rmx_mtu = loif.if_mtu; /* unless better below */ - R_Malloc(el, struct eon_llinfo *, sizeof(*el)); - rt->rt_llinfo = (caddr_t)el; - if (el == 0) - return; - Bzero(el, sizeof(*el)); - insque(&(el->el_qhdr), &eon_llinfo.el_qhdr); - el->el_rt = rt; - break; - } - if (gate || (gate = rt->rt_gateway)) switch (gate->sa_family) { - case AF_LINK: -#define SDL(x) ((struct sockaddr_dl *)x) - if (SDL(gate)->sdl_alen == 1) - el->el_snpaoffset = *(u_char *)LLADDR(SDL(gate)); - else - ipaddrloc = LLADDR(SDL(gate)); - break; - case AF_INET: -#define SIN(x) ((struct sockaddr_in *)x) - ipaddrloc = (caddr_t) &SIN(gate)->sin_addr; - break; - default: - return; - } - el->el_flags |= RTF_UP; - eoniphdr(&el->el_ei, ipaddrloc, &el->el_iproute, EON_NORMAL_ADDR, 0); - if (el->el_iproute.ro_rt) - rt->rt_rmx.rmx_mtu = el->el_iproute.ro_rt->rt_rmx.rmx_mtu - - sizeof(el->el_ei); -} - -/* - * FUNCTION: eoninit - * - * PURPOSE: initialization - * - * RETURNS: nothing - */ - -eoninit(unit) - int unit; -{ - printf("eon driver-init eon%d\n", unit); -} - - -/* - * FUNCTION: eonoutput - * - * PURPOSE: prepend an eon header and hand to IP - * ARGUMENTS: (ifp) is points to the ifnet structure for this unit/device - * (m) is an mbuf *, *m is a CLNL packet - * (dst) is a destination address - have to interp. as - * multicast or broadcast or real address. - * - * RETURNS: unix error code - * - * NOTES: - * - */ -eonoutput(ifp, m, dst, rt) - struct ifnet *ifp; - register struct mbuf *m; /* packet */ - struct sockaddr_iso *dst; /* destination addr */ - struct rtentry *rt; -{ - register struct eon_llinfo *el; - register struct eon_iphdr *ei; - struct route *ro; - int datalen; - struct mbuf *mh; - int error = 0, class = 0, alen = 0; - caddr_t ipaddrloc; - static struct eon_iphdr eon_iphdr; - static struct route route; - - IFDEBUG(D_EON) - printf("eonoutput \n" ); - ENDDEBUG - - ifp->if_lastchange = time; - ifp->if_opackets++; - if (rt == 0 || (el = (struct eon_llinfo *)rt->rt_llinfo) == 0) { - if (dst->siso_family == AF_LINK) { - register struct sockaddr_dl *sdl = (struct sockaddr_dl *)dst; - - ipaddrloc = LLADDR(sdl); - alen = sdl->sdl_alen; - } else if (dst->siso_family == AF_ISO && dst->siso_data[0] == AFI_SNA) { - alen = dst->siso_nlen - 1; - ipaddrloc = (caddr_t) dst->siso_data + 1; - } - switch (alen) { - case 5: - class = 4[(u_char *)ipaddrloc]; - case 4: - ro = &route; - ei = &eon_iphdr; - eoniphdr(ei, ipaddrloc, ro, class, 1); - goto send; - } -einval: - error = EINVAL; - goto flush; - } - if ((el->el_flags & RTF_UP) == 0) { - eonrtrequest(RTM_CHANGE, rt, (struct sockaddr *)0); - if ((el->el_flags & RTF_UP) == 0) { - error = EHOSTUNREACH; - goto flush; - } - } - if ((m->m_flags & M_PKTHDR) == 0) { - printf("eon: got non headered packet\n"); - goto einval; - } - ei = &el->el_ei; - ro = &el->el_iproute; - if (el->el_snpaoffset) { - if (dst->siso_family == AF_ISO) { - bcopy((caddr_t) &dst->siso_data[el->el_snpaoffset], - (caddr_t) &ei->ei_ip.ip_dst, sizeof(ei->ei_ip.ip_dst)); - } else - goto einval; - } -send: - /* put an eon_hdr in the buffer, prepended by an ip header */ - datalen = m->m_pkthdr.len + EONIPLEN; - MGETHDR(mh, M_DONTWAIT, MT_HEADER); - if(mh == (struct mbuf *)0) - goto flush; - mh->m_next = m; - m = mh; - MH_ALIGN(m, sizeof(struct eon_iphdr)); - m->m_len = sizeof(struct eon_iphdr); - ifp->if_obytes += - (ei->ei_ip.ip_len = (u_short)(m->m_pkthdr.len = datalen)); - *mtod(m, struct eon_iphdr *) = *ei; - - IFDEBUG(D_EON) - printf("eonoutput dst ip addr : %x\n", ei->ei_ip.ip_dst.s_addr); - printf("eonoutput ip_output : eonip header:\n"); - dump_buf(ei, sizeof(struct eon_iphdr)); - ENDDEBUG - - error = ip_output(m, (struct mbuf *)0, ro, 0, NULL); - m = 0; - if (error) { - ifp->if_oerrors++; - ifp->if_opackets--; - ifp->if_obytes -= datalen; - } -flush: - if (m) - m_freem(m); - return error; -} - -eoninput(m, iphlen) - register struct mbuf *m; - int iphlen; -{ - register struct eon_hdr *eonhdr; - register struct ip *iphdr; - struct ifnet *eonifp; - int s; - - eonifp = &eonif[0]; /* kludge - really want to give CLNP - * the ifp for eon, not for the real device - */ - - IFDEBUG(D_EON) - printf("eoninput() 0x%x m_data 0x%x m_len 0x%x dequeued\n", - m, m?m->m_data:0, m?m->m_len:0); - ENDDEBUG - - if (m == 0) - return; - if (iphlen > sizeof (struct ip)) - ip_stripoptions(m, (struct mbuf *)0); - if (m->m_len < EONIPLEN) { - if ((m = m_pullup(m, EONIPLEN)) == 0) { - IncStat(es_badhdr); -drop: - IFDEBUG(D_EON) - printf("eoninput: DROP \n" ); - ENDDEBUG - eonifp->if_ierrors ++; - m_freem(m); - return; - } - } - eonif->if_ibytes += m->m_pkthdr.len; - eonif->if_lastchange = time; - iphdr = mtod(m, struct ip *); - /* do a few checks for debugging */ - if( iphdr->ip_p != IPPROTO_EON ) { - IncStat(es_badhdr); - goto drop; - } - /* temporarily drop ip header from the mbuf */ - m->m_data += sizeof(struct ip); - eonhdr = mtod(m, struct eon_hdr *); - if( iso_check_csum( m, sizeof(struct eon_hdr) ) != EOK ) { - IncStat(es_badcsum); - goto drop; - } - m->m_data -= sizeof(struct ip); - - IFDEBUG(D_EON) - printf("eoninput csum ok class 0x%x\n", eonhdr->eonh_class ); - printf("eoninput: eon header:\n"); - dump_buf(eonhdr, sizeof(struct eon_hdr)); - ENDDEBUG - - /* checks for debugging */ - if( eonhdr->eonh_vers != EON_VERSION) { - IncStat(es_badhdr); - goto drop; - } - m->m_flags &= ~(M_BCAST|M_MCAST); - switch( eonhdr->eonh_class) { - case EON_BROADCAST: - IncStat(es_in_broad); - m->m_flags |= M_BCAST; - break; - case EON_NORMAL_ADDR: - IncStat(es_in_normal); - break; - case EON_MULTICAST_ES: - IncStat(es_in_multi_es); - m->m_flags |= M_MCAST; - break; - case EON_MULTICAST_IS: - IncStat(es_in_multi_is); - m->m_flags |= M_MCAST; - break; - } - eonifp->if_ipackets++; - - { - /* put it on the CLNP queue and set soft interrupt */ - struct ifqueue *ifq; - extern struct ifqueue clnlintrq; - - m->m_pkthdr.rcvif = eonifp; /* KLUDGE */ - IFDEBUG(D_EON) - printf("eoninput to clnl IFQ\n"); - ENDDEBUG - ifq = &clnlintrq; - s = splimp(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); - eonifp->if_iqdrops++; - eonifp->if_ipackets--; - splx(s); - return; - } - IF_ENQUEUE(ifq, m); - IFDEBUG(D_EON) - printf( - "0x%x enqueued on clnp Q: m_len 0x%x m_type 0x%x m_data 0x%x\n", - m, m->m_len, m->m_type, m->m_data); - dump_buf(mtod(m, caddr_t), m->m_len); - ENDDEBUG - schednetisr(NETISR_ISO); - splx(s); - } -} - -int -eonctlinput(cmd, sin) - int cmd; - struct sockaddr_in *sin; -{ - extern u_char inetctlerrmap[]; - - IFDEBUG(D_EON) - printf("eonctlinput: cmd 0x%x addr: ", cmd); - dump_isoaddr(sin); - printf("\n"); - ENDDEBUG - - if (cmd < 0 || cmd > PRC_NCMDS) - return 0; - - IncStat(es_icmp[cmd]); - switch (cmd) { - - case PRC_QUENCH: - case PRC_QUENCH2: - /* TODO: set the dec bit */ - break; - case PRC_TIMXCEED_REASS: - case PRC_ROUTEDEAD: - case PRC_HOSTUNREACH: - case PRC_UNREACH_NET: - case PRC_IFDOWN: - case PRC_UNREACH_HOST: - case PRC_HOSTDEAD: - case PRC_TIMXCEED_INTRANS: - /* TODO: mark the link down */ - break; - - case PRC_UNREACH_PROTOCOL: - case PRC_UNREACH_PORT: - case PRC_UNREACH_SRCFAIL: - case PRC_REDIRECT_NET: - case PRC_REDIRECT_HOST: - case PRC_REDIRECT_TOSNET: - case PRC_REDIRECT_TOSHOST: - case PRC_MSGSIZE: - case PRC_PARAMPROB: - /* printf("eonctlinput: ICMP cmd 0x%x\n", cmd );*/ - break; - } - return 0; -} - -#endif