diff options
Diffstat (limited to 'sys/netns/ns_ip.c')
-rw-r--r-- | sys/netns/ns_ip.c | 440 |
1 files changed, 0 insertions, 440 deletions
diff --git a/sys/netns/ns_ip.c b/sys/netns/ns_ip.c deleted file mode 100644 index 2702997..0000000 --- a/sys/netns/ns_ip.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (c) 1984, 1985, 1986, 1987, 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. - * - * @(#)ns_ip.c 8.1 (Berkeley) 6/10/93 - * $Id: ns_ip.c,v 1.3 1995/03/19 14:29:03 davidg Exp $ - */ - -/* - * Software interface driver for encapsulating ns in ip. - */ - -#ifdef NSIP -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/errno.h> -#include <sys/ioctl.h> -#include <sys/protosw.h> - -#include <net/if.h> -#include <net/netisr.h> -#include <net/route.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/in_var.h> -#include <netinet/ip.h> -#include <netinet/ip_var.h> - -#include <machine/mtpr.h> - -#include <netns/ns.h> -#include <netns/ns_if.h> -#include <netns/idp.h> - -struct ifnet_en { - struct ifnet ifen_ifnet; - struct route ifen_route; - struct in_addr ifen_src; - struct in_addr ifen_dst; - struct ifnet_en *ifen_next; -}; - -int nsipoutput(), nsipioctl(), nsipstart(); -#define LOMTU (1024+512); - -struct ifnet nsipif; -struct ifnet_en *nsip_list; /* list of all hosts and gateways or - broadcast addrs */ - -struct ifnet_en * -nsipattach() -{ - register struct ifnet_en *m; - register struct ifnet *ifp; - - if (nsipif.if_mtu == 0) { - ifp = &nsipif; - ifp->if_name = "nsip"; - ifp->if_mtu = LOMTU; - ifp->if_ioctl = nsipioctl; - ifp->if_output = nsipoutput; - ifp->if_start = nsipstart; - ifp->if_flags = IFF_POINTOPOINT; - } - - MALLOC((m), struct ifnet_en *, sizeof(*m), M_PCB, M_NOWAIT); - if (m == NULL) return (NULL); - m->ifen_next = nsip_list; - nsip_list = m; - ifp = &m->ifen_ifnet; - - ifp->if_name = "nsip"; - ifp->if_mtu = LOMTU; - ifp->if_ioctl = nsipioctl; - ifp->if_output = nsipoutput; - ifp->if_start = nsipstart; - ifp->if_flags = IFF_POINTOPOINT; - ifp->if_unit = nsipif.if_unit++; - if_attach(ifp); - - return (m); -} - - -/* - * Process an ioctl request. - */ -/* ARGSUSED */ -nsipioctl(ifp, cmd, data) - register struct ifnet *ifp; - int cmd; - caddr_t data; -{ - int error = 0; - struct ifreq *ifr; - - switch (cmd) { - - case SIOCSIFADDR: - ifp->if_flags |= IFF_UP; - /* fall into: */ - - case SIOCSIFDSTADDR: - /* - * Everything else is done at a higher level. - */ - break; - - case SIOCSIFFLAGS: - ifr = (struct ifreq *)data; - if ((ifr->ifr_flags & IFF_UP) == 0) - error = nsip_free(ifp); - - - default: - error = EINVAL; - } - return (error); -} - -struct mbuf *nsip_badlen; -struct mbuf *nsip_lastin; -int nsip_hold_input; - -idpip_input(m, ifp) - register struct mbuf *m; - struct ifnet *ifp; -{ - register struct ip *ip; - register struct idp *idp; - register struct ifqueue *ifq = &nsintrq; - int len, s; - - if (nsip_hold_input) { - if (nsip_lastin) { - m_freem(nsip_lastin); - } - nsip_lastin = m_copym(m, 0, (int)M_COPYALL, M_DONTWAIT); - } - /* - * Get IP and IDP header together in first mbuf. - */ - nsipif.if_ipackets++; - s = sizeof (struct ip) + sizeof (struct idp); - if (((m->m_flags & M_EXT) || m->m_len < s) && - (m = m_pullup(m, s)) == 0) { - nsipif.if_ierrors++; - return; - } - ip = mtod(m, struct ip *); - if (ip->ip_hl > (sizeof (struct ip) >> 2)) { - ip_stripoptions(m, (struct mbuf *)0); - if (m->m_len < s) { - if ((m = m_pullup(m, s)) == 0) { - nsipif.if_ierrors++; - return; - } - ip = mtod(m, struct ip *); - } - } - - /* - * Make mbuf data length reflect IDP length. - * If not enough data to reflect IDP length, drop. - */ - m->m_data += sizeof (struct ip); - m->m_len -= sizeof (struct ip); - m->m_pkthdr.len -= sizeof (struct ip); - idp = mtod(m, struct idp *); - len = ntohs(idp->idp_len); - if (len & 1) len++; /* Preserve Garbage Byte */ - if (ip->ip_len != len) { - if (len > ip->ip_len) { - nsipif.if_ierrors++; - if (nsip_badlen) m_freem(nsip_badlen); - nsip_badlen = m; - return; - } - /* Any extra will be trimmed off by the NS routines */ - } - - /* - * Place interface pointer before the data - * for the receiving protocol. - */ - m->m_pkthdr.rcvif = ifp; - /* - * Deliver to NS - */ - s = splimp(); - if (IF_QFULL(ifq)) { - IF_DROP(ifq); -bad: - m_freem(m); - splx(s); - return; - } - IF_ENQUEUE(ifq, m); - schednetisr(NETISR_NS); - splx(s); - return; -} - -/* ARGSUSED */ -nsipoutput(ifn, m, dst) - struct ifnet_en *ifn; - register struct mbuf *m; - struct sockaddr *dst; -{ - - register struct ip *ip; - register struct route *ro = &(ifn->ifen_route); - register int len = 0; - register struct idp *idp = mtod(m, struct idp *); - int error; - - ifn->ifen_ifnet.if_opackets++; - nsipif.if_opackets++; - - - /* - * Calculate data length and make space - * for IP header. - */ - len = ntohs(idp->idp_len); - if (len & 1) len++; /* Preserve Garbage Byte */ - /* following clause not necessary on vax */ - if (3 & (int)m->m_data) { - /* force longword alignment of ip hdr */ - struct mbuf *m0 = m_gethdr(MT_HEADER, M_DONTWAIT); - if (m0 == 0) { - m_freem(m); - return (ENOBUFS); - } - MH_ALIGN(m0, sizeof (struct ip)); - m0->m_flags = m->m_flags & M_COPYFLAGS; - m0->m_next = m; - m0->m_len = sizeof (struct ip); - m0->m_pkthdr.len = m0->m_len + m->m_len; - m->m_flags &= ~M_PKTHDR; - } else { - M_PREPEND(m, sizeof (struct ip), M_DONTWAIT); - if (m == 0) - return (ENOBUFS); - } - /* - * Fill in IP header. - */ - ip = mtod(m, struct ip *); - *(long *)ip = 0; - ip->ip_p = IPPROTO_IDP; - ip->ip_src = ifn->ifen_src; - ip->ip_dst = ifn->ifen_dst; - ip->ip_len = (u_short)len + sizeof (struct ip); - ip->ip_ttl = MAXTTL; - - /* - * Output final datagram. - */ - error = (ip_output(m, (struct mbuf *)0, ro, SO_BROADCAST, NULL)); - if (error) { - ifn->ifen_ifnet.if_oerrors++; - ifn->ifen_ifnet.if_ierrors = error; - } - return (error); -bad: - m_freem(m); - return (ENETUNREACH); -} - -nsipstart(ifp) -struct ifnet *ifp; -{ - panic("nsip_start called"); -} - -struct ifreq ifr = {"nsip0"}; - -nsip_route(m) - register struct mbuf *m; -{ - register struct nsip_req *rq = mtod(m, struct nsip_req *); - struct sockaddr_ns *ns_dst = (struct sockaddr_ns *)&rq->rq_ns; - struct sockaddr_in *ip_dst = (struct sockaddr_in *)&rq->rq_ip; - struct route ro; - struct ifnet_en *ifn; - struct sockaddr_in *src; - - /* - * First, make sure we already have an ns address: - */ - if (ns_hosteqnh(ns_thishost, ns_zerohost)) - return (EADDRNOTAVAIL); - /* - * Now, determine if we can get to the destination - */ - bzero((caddr_t)&ro, sizeof (ro)); - ro.ro_dst = *(struct sockaddr *)ip_dst; - rtalloc(&ro); - if (ro.ro_rt == 0 || ro.ro_rt->rt_ifp == 0) { - return (ENETUNREACH); - } - - /* - * And see how he's going to get back to us: - * i.e., what return ip address do we use? - */ - { - register struct in_ifaddr *ia; - struct ifnet *ifp = ro.ro_rt->rt_ifp; - - for (ia = in_ifaddr; ia; ia = ia->ia_next) - if (ia->ia_ifp == ifp) - break; - if (ia == 0) - ia = in_ifaddr; - if (ia == 0) { - RTFREE(ro.ro_rt); - return (EADDRNOTAVAIL); - } - src = (struct sockaddr_in *)&ia->ia_addr; - } - - /* - * Is there a free (pseudo-)interface or space? - */ - for (ifn = nsip_list; ifn; ifn = ifn->ifen_next) { - if ((ifn->ifen_ifnet.if_flags & IFF_UP) == 0) - break; - } - if (ifn == NULL) - ifn = nsipattach(); - if (ifn == NULL) { - RTFREE(ro.ro_rt); - return (ENOBUFS); - } - ifn->ifen_route = ro; - ifn->ifen_dst = ip_dst->sin_addr; - ifn->ifen_src = src->sin_addr; - - /* - * now configure this as a point to point link - */ - ifr.ifr_name[4] = '0' + nsipif.if_unit - 1; - ifr.ifr_dstaddr = * (struct sockaddr *) ns_dst; - (void)ns_control((struct socket *)0, (int)SIOCSIFDSTADDR, (caddr_t)&ifr, - (struct ifnet *)ifn); - satons_addr(ifr.ifr_addr).x_host = ns_thishost; - return (ns_control((struct socket *)0, (int)SIOCSIFADDR, (caddr_t)&ifr, - (struct ifnet *)ifn)); -} - -nsip_free(ifp) -struct ifnet *ifp; -{ - register struct ifnet_en *ifn = (struct ifnet_en *)ifp; - struct route *ro = & ifn->ifen_route; - - if (ro->ro_rt) { - RTFREE(ro->ro_rt); - ro->ro_rt = 0; - } - ifp->if_flags &= ~IFF_UP; - return (0); -} - -nsip_ctlinput(cmd, sa) - int cmd; - struct sockaddr *sa; -{ - struct sockaddr_in *sin; - int in_rtchange(); - - if ((unsigned)cmd >= PRC_NCMDS) - return; - if (sa->sa_family != AF_INET && sa->sa_family != AF_IMPLINK) - return; - sin = (struct sockaddr_in *)sa; - if (sin->sin_addr.s_addr == INADDR_ANY) - return; - - switch (cmd) { - - case PRC_ROUTEDEAD: - case PRC_REDIRECT_NET: - case PRC_REDIRECT_HOST: - case PRC_REDIRECT_TOSNET: - case PRC_REDIRECT_TOSHOST: - nsip_rtchange(&sin->sin_addr); - break; - } -} - -nsip_rtchange(dst) - register struct in_addr *dst; -{ - register struct ifnet_en *ifn; - - for (ifn = nsip_list; ifn; ifn = ifn->ifen_next) { - if (ifn->ifen_dst.s_addr == dst->s_addr && - ifn->ifen_route.ro_rt) { - RTFREE(ifn->ifen_route.ro_rt); - ifn->ifen_route.ro_rt = 0; - } - } -} -#endif |