home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume4
/
subnet.arp
< prev
next >
Wrap
Internet Message Format
|
1986-11-30
|
13KB
From: talcott!ut-sally!jsq (John Quarterman)
Subject: 4.3BSD IP subnet ARP hack
Newsgroups: mod.sources
Approved: jpn@panda.UUCP
Mod.sources: Volume 4, Issue 64
Submitted by: talcott!ut-sally!jsq (John Quarterman)
: This is a shar archive. Extract with sh, not csh.
echo x - README
sed -e 's/^X//' > README << '!RoNnIe!RaYgUn!'
XThese are the mods necessary to 4.3BSD to add a subnet ARP hack.
XThey allow a subnet gateway machine to act as a bridge so that only
Xit need know of the existence of subnets. This is quite useful if
Xmany machines on the local network do not have RFC950 subnet code
Xand you do not have sources for them.
X
XTo turn on the subarp code, you need to do "ifconfig xxn subarp".
X
X/sys/netinet/if_ether.c: subnet ARP hack
X/sys/net/if.h: IFF_SUBARP
X/sys/net/route.c: splimp instead of splnet in rtalloc
X/sys/netinet/in.c: in_mainnetof
X/sys/netinet/in.h: in_mainnetof
X/usr/src/etc/ifconfig/ifconfig.c: IFF_SUBARP (subarp, -subarp)
X/usr/man/man8/ifconfig.8c: subarp, -subarp
X
!RoNnIe!RaYgUn!
echo x - Install
sed -e 's/^X//' > Install << '!RoNnIe!RaYgUn!'
Xcp if_ether.c.diff /sys/netinet/if_ether.c.diff
Xcp in.c.diff /sys/netinet/in.c.diff
Xcp in.h.diff /sys/netinet/in.h.diff
Xcp if.h.diff /sys/net/if.h.diff
Xcp route.c.diff /sys/net/route.c.diff
Xcp ifconfig.c.diff /usr/src/etc/ifconfig/ifconfig.c.diff
Xcp ifconfig.8c.diff /usr/man/man8/ifconfig.8c.diff
X
Xcd /sys/netinet
Xsccs edit if_ether.c
Xpatch if_ether.c.diff
Xecho 'subarp' | sccs delget if_ether.c
X
Xcd /sys/netinet
Xsccs edit in.c
Xpatch in.c.diff
Xecho 'subarp' | sccs delget in.c
X
Xcd /sys/netinet
Xsccs edit in.h
Xpatch in.h.diff
Xecho 'subarp' | sccs delget in.h
X
Xcd /sys/net
Xsccs edit if.h
Xpatch if.h.diff
Xecho 'subarp' | sccs delget if.h
X
Xcd /sys/net
Xsccs edit route.c
Xpatch route.c.diff
Xecho 'subarp' | sccs delget route.c
X
Xcd /usr/src/etc/ifconfig
Xsccs edit ifconfig.c
Xpatch ifconfig.c.diff
Xecho 'subarp' | sccs delget ifconfig.c
X
Xcd /usr/man/man8
Xsccs edit ifconfig.8c
Xpatch ifconfig.8c.diff
Xecho 'subarp' | sccs delget ifconfig.8c
!RoNnIe!RaYgUn!
echo x - if_ether.c.diff
sed -e 's/^X//' > if_ether.c.diff << '!RoNnIe!RaYgUn!'
X*** if_ether.c.orig Sun Apr 6 14:42:51 1986
X--- if_ether.c Sun Apr 6 14:42:53 1986
X***************
X*** 21,27 ****
X--- 21,29 ----
X #include "syslog.h"
X
X #include "../net/if.h"
X+ #include "../net/route.h"
X #include "in.h"
X+ #include "in_var.h"
X #include "in_systm.h"
X #include "ip.h"
X #include "if_ether.h"
X***************
X*** 343,348 ****
X--- 345,364 ----
X sizeof(ea->arp_sha));
X bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
X sizeof(ea->arp_sha));
X+ } else
X+ /*
X+ * Subnet ARP hack (subarp). This allows a site to run the subnet
X+ * kernel only on the gateway machines by allowing the gateway
X+ * to reply to ARP requests for a target machine on a locally
X+ * attached subnet or reachable via a route from this gateway.
X+ */
X+ if (ac->ac_if.if_flags & IFF_SUBARP
X+ && in_netof(isaddr) != in_netof(itaddr)
X+ && if_subarp(isaddr, itaddr, &(ac->ac_if))) {
X+ bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
X+ sizeof(ea->arp_sha));
X+ bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
X+ sizeof(ea->arp_sha));
X } else {
X ARPTAB_LOOK(at, itaddr.s_addr);
X if (at == NULL || (at->at_flags & ATF_PUBL) == 0)
X***************
X*** 352,358 ****
X bcopy((caddr_t)at->at_enaddr, (caddr_t)ea->arp_sha,
X sizeof(ea->arp_sha));
X }
X-
X bcopy((caddr_t)ea->arp_spa, (caddr_t)ea->arp_tpa,
X sizeof(ea->arp_spa));
X bcopy((caddr_t)&itaddr, (caddr_t)ea->arp_spa,
X--- 368,373 ----
X***************
X*** 528,531 ****
X--- 543,619 ----
X }
X *--cp = 0;
X return (etherbuf);
X+ }
X+
X+ /*
X+ * Determine if interface of target address has ARP subnet routing enabled.
X+ */
X+ int if_subarplog = 1;
X+ #define sublog if (if_subarplog) log
X+ if_subarp(isaddr, itaddr, sifp)
X+ struct in_addr isaddr, itaddr;
X+ register struct ifnet *sifp;
X+ {
X+ register u_long net;
X+ register struct in_ifaddr *ia;
X+ struct route ro;
X+ register struct sockaddr_in *sin;
X+ register struct ifaddr *taddr;
X+ register struct ifnet *tifp;
X+
X+ net = in_mainnetof(itaddr);
X+ if (net != in_mainnetof(isaddr)) /* sanity check */
X+ return(0);
X+ for (ia = in_ifaddr; ia; ia = ia->ia_next)
X+ if (net == ia->ia_net)
X+ break;
X+ if (ia) { /* don't respond to requests for IP broadcast addresses */
X+ register u_long m, l;
X+
X+ m = ~ia->ia_subnetmask;
X+ l = ntohl(itaddr.s_addr) & m;
X+ if (l == (INADDR_BROADCAST & m) || l == (INADDR_ANY & m))
X+ return(0);
X+ m = ~ia->ia_netmask;
X+ l = ntohl(itaddr.s_addr) & m;
X+ if (l == (INADDR_BROADCAST & m) || l == (INADDR_ANY & m))
X+ return(0);
X+ }
X+ sin = (struct sockaddr_in *)&(ro.ro_dst);
X+ sin->sin_family = AF_INET;
X+ sin->sin_addr = itaddr;
X+ tifp = (struct ifnet *)0;
X+ if ((taddr = ifa_ifwithnet((struct sockaddr *)sin)) != NULL)
X+ tifp = taddr->ifa_ifp; /* is subnet of an interface */
X+ else { /* look in routing table for non-local target */
X+ extern struct rtentry nowildcard;
X+
X+ ro.ro_rt = &nowildcard;
X+ (void) rtalloc(&ro);
X+ if (ro.ro_rt != (struct rtentry *)0) {
X+ tifp = ro.ro_rt->rt_ifp;
X+ RTFREE(ro.ro_rt);
X+ }
X+ }
X+ if (tifp == (struct ifnet *)0) {
X+ if ((sifp->if_flags & IFF_DEBUG) != 0)
X+ sublog(LOG_DEBUG, "subarp %s%d:%x to ?:%x - no route\n",
X+ sifp->if_name, sifp->if_unit,
X+ ntohl(isaddr.s_addr), ntohl(itaddr.s_addr));
X+ return(0);
X+ }
X+ if ((tifp->if_flags & IFF_SUBARP) == 0)
X+ return(0);
X+ /* Sanity check: ignore request if from same interface as target. */
X+ if (sifp->if_addrlist->ifa_ifp == tifp) {
X+ if ((sifp->if_flags & IFF_DEBUG) != 0)
X+ sublog(LOG_DEBUG,"subarp %s%d:%x to %s%d:%x - same interface\n",
X+ sifp->if_name, sifp->if_unit, ntohl(isaddr.s_addr),
X+ tifp->if_name, tifp->if_unit, ntohl(itaddr.s_addr));
X+ return(0);
X+ }
X+ sublog(LOG_INFO, "subarp %s%d:%x to %s%d:%x\n",
X+ sifp->if_name, sifp->if_unit, ntohl(isaddr.s_addr),
X+ tifp->if_name, tifp->if_unit, ntohl(itaddr.s_addr));
X+ return(1);
X }
!RoNnIe!RaYgUn!
echo x - in.c.diff
sed -e 's/^X//' > in.c.diff << '!RoNnIe!RaYgUn!'
X*** in.c.orig Sun Apr 6 14:43:01 1986
X--- in.c Sun Apr 6 14:43:03 1986
X***************
X*** 74,79 ****
X--- 74,98 ----
X * Return the network number from an internet address.
X */
X u_long
X+ in_mainnetof(in)
X+ struct in_addr in;
X+ {
X+ register u_long i = ntohl(in.s_addr);
X+ register u_long net;
X+
X+ if (IN_CLASSA(i))
X+ net = i & IN_CLASSA_NET;
X+ else if (IN_CLASSB(i))
X+ net = i & IN_CLASSB_NET;
X+ else
X+ net = i & IN_CLASSC_NET;
X+ return (net);
X+ }
X+
X+ /*
X+ * Return the network number from an internet address.
X+ */
X+ u_long
X in_netof(in)
X struct in_addr in;
X {
!RoNnIe!RaYgUn!
echo x - in.h.diff
sed -e 's/^X//' > in.h.diff << '!RoNnIe!RaYgUn!'
X*** in.h.orig Sun Apr 6 14:43:09 1986
X--- in.h Sun Apr 6 14:43:11 1986
X***************
X*** 104,108 ****
X extern struct domain inetdomain;
X extern struct protosw inetsw[];
X struct in_addr in_makeaddr();
X! u_long in_netof(), in_lnaof();
X #endif
X--- 104,108 ----
X extern struct domain inetdomain;
X extern struct protosw inetsw[];
X struct in_addr in_makeaddr();
X! u_long in_netof(), in_lnaof(), in_mainnetof();
X #endif
!RoNnIe!RaYgUn!
echo x - if.h.diff
sed -e 's/^X//' > if.h.diff << '!RoNnIe!RaYgUn!'
X*** if.h.orig Mon Mar 24 15:24:20 1986
X--- if.h Mon Mar 24 15:24:22 1986
X***************
X*** 75,80 ****
X--- 75,81 ----
X #define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
X #define IFF_RUNNING 0x40 /* resources allocated */
X #define IFF_NOARP 0x80 /* no address resolution protocol */
X+ #define IFF_SUBARP 0x200 /* ARP subnet gateway hack */
X /* flags set internally only: */
X #define IFF_CANTCHANGE (IFF_BROADCAST | IFF_POINTOPOINT | IFF_RUNNING)
X
!RoNnIe!RaYgUn!
echo x - route.c.diff
sed -e 's/^X//' > route.c.diff << '!RoNnIe!RaYgUn!'
X*** route.c.orig Sun Apr 6 14:43:23 1986
X--- route.c Sun Apr 6 14:43:25 1986
X***************
X*** 22,27 ****
X--- 22,28 ----
X
X int rttrash; /* routes not in table but not freed */
X struct sockaddr wildcard; /* zero valued cookie for wildcard searches */
X+ struct rtentry nowildcard; /* indicates rtalloc shouldn't use wildcard */
X int rthashsize = RTHASHSIZ; /* for netstat, etc. */
X
X /*
X***************
X*** 34,44 ****
X register struct mbuf *m;
X register u_long hash;
X struct sockaddr *dst = &ro->ro_dst;
X! int (*match)(), doinghost, s;
X struct afhash h;
X u_int af = dst->sa_family;
X struct mbuf **table;
X
X if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
X return; /* XXX */
X if (af >= AF_MAX)
X--- 35,50 ----
X register struct mbuf *m;
X register u_long hash;
X struct sockaddr *dst = &ro->ro_dst;
X! int (*match)(), doinghost, s, nowild;
X struct afhash h;
X u_int af = dst->sa_family;
X struct mbuf **table;
X
X+ nowild = 0;
X+ if (ro->ro_rt == &nowildcard) {
X+ ro->ro_rt = NULL;
X+ nowild++;
X+ }
X if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
X return; /* XXX */
X if (af >= AF_MAX)
X***************
X*** 46,52 ****
X (*afswitch[af].af_hash)(dst, &h);
X match = afswitch[af].af_netmatch;
X hash = h.afh_hosthash, table = rthost, doinghost = 1;
X! s = splnet();
X again:
X for (m = table[RTHASHMOD(hash)]; m; m = m->m_next) {
X rt = mtod(m, struct rtentry *);
X--- 52,58 ----
X (*afswitch[af].af_hash)(dst, &h);
X match = afswitch[af].af_netmatch;
X hash = h.afh_hosthash, table = rthost, doinghost = 1;
X! s = splimp(); /* splnet not high enough: also called from interrupt. */
X again:
X for (m = table[RTHASHMOD(hash)]; m; m = m->m_next) {
X rt = mtod(m, struct rtentry *);
X***************
X*** 79,85 ****
X /*
X * Check for wildcard gateway, by convention network 0.
X */
X! if (dst != &wildcard) {
X dst = &wildcard, hash = 0;
X goto again;
X }
X--- 85,91 ----
X /*
X * Check for wildcard gateway, by convention network 0.
X */
X! if (!nowild && dst != &wildcard) {
X dst = &wildcard, hash = 0;
X goto again;
X }
!RoNnIe!RaYgUn!
echo x - ifconfig.c.diff
sed -e 's/^X//' > ifconfig.c.diff << '!RoNnIe!RaYgUn!'
X*** ifconfig.c.orig Sun Apr 6 14:43:30 1986
X--- ifconfig.c Sun Apr 6 14:43:32 1986
X***************
X*** 62,67 ****
X--- 62,69 ----
X { "-trailers", IFF_NOTRAILERS, setifflags },
X { "arp", -IFF_NOARP, setifflags },
X { "-arp", IFF_NOARP, setifflags },
X+ { "subarp", IFF_SUBARP, setifflags },
X+ { "-subarp", -IFF_SUBARP, setifflags },
X { "debug", IFF_DEBUG, setifflags },
X { "-debug", -IFF_DEBUG, setifflags },
X #ifdef notdef
X***************
X*** 106,117 ****
X {
X int af = AF_INET;
X if (argc < 2) {
X! fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s",
X "\t[ af [ address [ dest_addr ] ] [ up ] [ down ]",
X "[ netmask mask ] ]\n",
X "\t[ metric n ]\n",
X "\t[ trailers | -trailers ]\n",
X! "\t[ arp | -arp ]\n");
X exit(1);
X }
X argc--, argv++;
X--- 108,119 ----
X {
X int af = AF_INET;
X if (argc < 2) {
X! fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s%s",
X "\t[ af [ address [ dest_addr ] ] [ up ] [ down ]",
X "[ netmask mask ] ]\n",
X "\t[ metric n ]\n",
X "\t[ trailers | -trailers ]\n",
X! "\t[ arp | -arp ]\t[ subarp | -subarp ]\n");
X exit(1);
X }
X argc--, argv++;
X***************
X*** 287,292 ****
X--- 289,295 ----
X
X #define IFFBITS \
X "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
X+ \12SUBARP\
X "
X
X /*
!RoNnIe!RaYgUn!
echo x - ifconfig.8c.diff
sed -e 's/^X//' > ifconfig.8c.diff << '!RoNnIe!RaYgUn!'
X*** ifconfig.8c.orig Sun Apr 6 14:43:39 1986
X--- ifconfig.8c Sun Apr 6 14:43:41 1986
X***************
X*** 101,106 ****
X--- 101,119 ----
X .B \-arp
X Disable the use of the Address Resolution Protocol.
X .TP 15
X+ .B subarp
X+ Enable an interface on a subnet gateway to respond to ARP requests
X+ for hosts reachable via this subnet.
X+ Only useful on hardware which supports ARP.
X+ This allows a gateway between two subnets to respond to ARP requests
X+ received on an enabled interface to respond for hosts on another
X+ enabled interface and route packets thru the gateway.
X+ This allows a network configuration where only the gateway hosts need to
X+ be aware of the existence of subnets.
X+ .TP 15
X+ .B \-subarp
X+ Disable the ARP subnet code.
X+ .TP 15
X .BI metric " n"
X Set the routing metric of the interface to
X .IR n ,
!RoNnIe!RaYgUn!
exit