*BSD News Article 18501


Return to BSD News archive

Newsgroups: comp.unix.bsd
Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!elroy.jpl.nasa.gov!swrinde!cs.utexas.edu!uunet!news.tek.com!gvgpsa.gvg.tek.com!ssigv!gdonl
From: gdonl@sunrise.ssi1.com (Don Lewis)
Subject: Re: HELP: How to have 2 Host IP nums but only 1 interface
Message-ID: <CA8uIv.M8K@ssigv.UUCP>
Keywords: interface ip network routing host sun
Sender: news@ssigv.UUCP
Nntp-Posting-Host: sunrise.ssi1.com
Organization: Silicon Systems, Nevada City CA
References: <mckay.742682655@cambridge>
Date: Fri, 16 Jul 1993 06:11:18 GMT
Lines: 313

In <mckay.742682655@cambridge> Kyle McKay <mckay@cambridge.mitchell.com> wrote:
>If you had two ethernet interfaces installed in a sun and attached them
>both to the same cable with different host ip numbers on different ip
>networks, you would have the situation I need.
>
>However, I want to do this with just the one ethernet interface, how can I
>do that?

I've been doing exactly this since last fall.  The attached (rather
hackish) code implements secondary network interfaces which attach to
the physical network interface.  Routed finds all the interfaces and
advertises the host as router between the networks.

Please read the BUGS and WARNINGS comments in the code.  This code
works for me, but for all I know it may cause your network to melt
down.

#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  if_sn.c
#
sed 's/^X//' << 'SHAR_EOF' > if_sn.c &&
X/*
X * Secondary network driver for SunOS 4.1.x
X * 
X */
X
X/*
X * Copyright (c) 1992, 1993 by Silicon Systems Inc.
X * 
X * Permission to use, copy, modify, and distribute this software for any
X * purpose with or without fee is hereby granted, provided that this
X * copyright notice appear in all copies, and that the name of Silicon
X * Systems Inc. not be used in advertising or publicity pertaining to
X * distribution of the document or software without specific,
X * written prior permission.
X * 
X * THE SOFTWARE IS PROVIDED "AS IS" AND SILICON SYSTEMS INC. DISCLAIMS ALL
X * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
X * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL SILICON SYTEMS
X * INC. BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
X * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
X * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
X * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
X * SOFTWARE.
X *
X * Author: Don Lewis <gdonl@ssi1.com>
X *
X */
X
X/* Parts of this software were inspired by or derived from slip-4.0 */
X/*
X * Serial Line IP streams module for SunOS 4.0
X *
X * Copyright 1988 by Rayan Zachariassen
X *
X * Rayan Zachariassen <rayan@ai.toronto.edu>
X * 880929
X * Doug Kingston <dpk@morgan.com>
X * 881007
X *
X * You may do anything with this file except put your own
X * copyright on it or change or remove this copyright notice.
X * Derived works should be marked as such.
X *
X */
X
X/* Parts of this software were inspired by or derived from BSD NET-2 */
X/*
X * Copyright (c) 1982, 1989 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X *    must display the following acknowledgement:
X *	This product includes software developed by the University of
X *	California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X *    may be used to endorse or promote products derived from this software
X *    without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
X
X/*
X * To install:
X *
X * Install this file in /sys/sunif.
X *
X * Add "sunif/if_sn.c	optional sn" to /sys/conf.common/files.cmn
X *
X * Patch /sys/sun4?/OBJ/if_subr.o to call xrpinput() instead of arpinput()
X * with whatever binary file editing tools you have available.
X *
X * Add "pseudo-device	sn init snattach" to your kernel config file
X * and rebuild your kernel.
X *
X * After rebooting with the new kernel installed, the secondary
X * interface(s), may be ifconfig'ed just like a regular ethernet
X * interface.
X *     ifconfig sn0 address ... -trailers up
X *
X * BUGS:
X * The secondary interfaces all attach to the first real broadcast
X * capable (ethernet) interface.
X * This interface disables directed broadcasts and icmp redirects.
X *
X * WARNING:
X * This code is untested in the presence of FDDI, token ring, or
X * more than one ethernet interface.  It has only been used on
X * sun4c architecture machines running SunOS 4.1.1 and 4.1.2.
X *
X */
X
X#include "sn.h"
X
X#if NSN > 0
X#include <sys/types.h>
X#include <sys/param.h>
X#include <sys/mbuf.h>
X#include <sys/socket.h>
X#include <sys/ioctl.h>
X#include <net/if.h>
X#include <netinet/in.h>
X#include <netinet/in_systm.h>
X#include <netinet/in_var.h>
X#include <netinet/ip.h>
X#include <netinet/if_ether.h>
X#include <sys/errno.h>
X
Xstatic struct snsoftc {
X    struct arpcom   sn_ac;
X    struct ifnet   *pn_if;
X}               sn_softc[NSN];
X
Xstatic struct ether_family arp_catcher;
X
Xint             snoutput(),
X                snioctl();
Xextern int      ether_output();
Xextern int      ip_sendredirects;
Xextern int      ip_dirbroadcast;
X
Xvoid
Xsnattach(unit)
X    int             unit;
X{
X    struct ifnet   *ifp, *ethifp, **p;
X
X    ifp = &(sn_softc[unit].sn_ac.ac_if);
X    ifp->if_name = "sn";
X    ifp->if_unit = unit;
X    ifp->if_flags = IFF_BROADCAST | IFF_NOTRAILERS;
X    ifp->if_ioctl = snioctl;
X    ifp->if_output = snoutput;
X    ip_sendredirects = 0;
X    ip_dirbroadcast = 0;
X    if_attach(ifp);
X    printf("sn: secondary network driver attached\n");
X}
X
Xint
Xsnoutput(ifp, m, dst)
X    struct ifnet   *ifp;
X    struct mbuf    *m;
X    struct sockaddr *dst;
X{
X    struct ifnet   *eifp = sn_softc[ifp->if_unit].pn_if;
X    int             error = 0;
X
X    if (eifp && eifp->if_output) {
X	struct in_addr  addr;
X
X	addr = ((struct arpcom *) eifp)->ac_ipaddr;	/* XXX - hack addr for
X							 * ARP */
X	((struct arpcom *) eifp)->ac_ipaddr = ((struct arpcom *) ifp)->ac_ipaddr;
X	error = (*(eifp->if_output)) (eifp, m, dst);
X	((struct arpcom *) eifp)->ac_ipaddr = addr;	/* restore address */
X	return (error);
X    }
X    m_freem(m);
X    return (ENETDOWN);
X}
X
Xint
Xsnioctl(ifp, cmd, data)
X    struct ifnet   *ifp;
X    int             cmd;
X    caddr_t         data;
X{
X    struct ifaddr  *ifa;
X    struct arpcom  *ac;
X    int             error = 0;
X
X    switch (cmd) {
X      case SIOCSIFADDR:
X	if (!sn_softc[ifp->if_unit].pn_if) {
X	    struct ifnet   *ethifp, **p;
X
X	    /* XXX - find first ethernet interface to attach to */
X	    for (p = &ifnet; *p; p = &((*p)->if_next))
X		if ((*p)->if_flags & IFF_BROADCAST != 0) {
X		    ethifp = *p;
X		    sn_softc[ifp->if_unit].pn_if = ethifp;
X		    ifp->if_mtu = ethifp->if_mtu;
X		    sn_softc[ifp->if_unit].sn_ac.ac_enaddr =
X			((struct arpcom *) ethifp)->ac_enaddr;
X		    break;
X		}
X	}
X	if (sn_softc[ifp->if_unit].pn_if) {
X	    ifp->if_flags |= IFF_UP;
X	    ifa = (struct ifaddr *) data;
X	    ac = &(sn_softc[ifp->if_unit].sn_ac);
X	    if (ifa->ifa_addr.sa_family == AF_INET) {
X		ac->ac_ipaddr = IA_SIN(ifa)->sin_addr;
X		arpwhohas(ac, &IA_SIN(ifa)->sin_addr);
X	    }
X	} else {
X	    error = ENETDOWN;
X	}
X	break;
X      case SIOCSIFFLAGS:
X	break;
X#ifdef SIOCGHWADDR
X      case SIOCGHWADDR:
X	bcopy((caddr_t) sn_softc[ifp->if_unit].ac_enaddr,
X	      (caddr_t) & ifr->ifr_data,
X	      sizeof(sn_softc[0].ac_enaddr));
X#endif				/* SIOCGHWADDR */
X      default:
X	error = EINVAL;
X    }
X    return (error);
X}
X
X#endif				/* NSN > 0 */
X
Xvoid
Xxrpinput(ac, m)
X    struct arpcomp *ac;
X    struct mbuf    *m;
X{
X    register struct arphdr *ar;
X    register struct ether_arp *ea;
X    register struct in_ifaddr *ia;
X    struct in_addr  isaddr, itaddr;
X
X    if (m->m_len < sizeof(struct ifnet *) + sizeof(struct arphdr))
X	goto out;
X
X    m->m_off += sizeof(struct ifnet *);
X    m->m_len -= sizeof(struct ifnet *);
X
X    ar = mtod(m, struct arphdr *);
X    if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
X	goto out1;
X    if (m->m_len < sizeof(struct arphdr) + 2 * ar->ar_hln + 2 * ar->ar_pln)
X	goto out1;
X
X    switch (ntohs(ar->ar_pro)) {
X      case ETHERTYPE_IP:
X	ea = mtod(m, struct ether_arp *);
X	bcopy((caddr_t) ea->arp_spa, (caddr_t) & isaddr, sizeof(isaddr));
X	bcopy((caddr_t) ea->arp_tpa, (caddr_t) & itaddr, sizeof(itaddr));
X	for (ia = in_ifaddr; ia; ia = ia->ia_next) {
X	    if (ia->ia_ifp->if_output == snoutput &&
X		    (itaddr.s_addr == ((struct sockaddr_in *) & (ia->ia_addr))->sin_addr.s_addr |
X		     isaddr.s_addr == ((struct sockaddr_in *) & (ia->ia_addr))->sin_addr.s_addr)) {
X		m->m_off -= sizeof(struct ifnet *);
X		m->m_len += sizeof(struct ifnet *);
X		arpinput((struct arpcom *) ia->ia_ifp, m);
X		return;
X	    }
X	}
X	break;
X      default:
X	break;
X    }
X
Xout1:
X    m->m_off -= sizeof(struct ifnet *);
X    m->m_len += sizeof(struct ifnet *);
X
Xout:
X    arpinput(ac, m);
X}
SHAR_EOF
chmod 0644 if_sn.c || echo "restore of if_sn.c fails"
exit 0
-- 
Don "Truck" Lewis              Phone: +1 916 478-8284   Silicon Systems
Internet: gdonl@ssi1.com       FAX:   +1 916 478-8251   138 New Mohawk Road
UUCP: {uunet,tektronix!gvgpsa.gvg.tek.com}!ssigv!gdonl  Nevada City, CA  95959