Subject: Arp with netmasks breaks route-to-interface cloning hack
To: None <tech-kern@NetBSD.ORG, tech-net@NetBSD.ORG>
From: Jonathan Stone <jonathan@dsg.stanford.edu>
List: tech-kern
Date: 03/25/1996 05:46:53
The patch below makes arp with subnet masks work for me. It disables
the kernel backaward-compatibility glue in if_ether.c. arp_rtrequest(O
is too clever; if it sees a request which looks like a manually-added
route-to-interface, which arp_rtrequest() thinks should have
RTF_CLONING on, but doesn't, it adds it.
The "natural" way to send a routing message for an arp entry
with a subnet mask looks like an old-style route-to-interface.
Now, is the compatibility really still useful? Do people really
run old versions of routed or gated? Or is this needed to deal with
people who add manual routes to interfaces?
If the non-cloned compatibility is still needed, then we could add
another hack that (piling Ossa upon Pelion), before checking
for and turning on cloning, tests for routes with RTF_HOST that
have a not-all-ones subnet mask, and if so, turn off RTF_HOST
and turn on cloning. (Gag.) Unless anyone has a better idea?
Anyway, if anyone knows whether or not the compatibility is necessary,
please let me know and I'll send this as a PR. Meanwhile, feel
free to play with it :-).
*** src/sys/netinet/if_ether.c.DIST Wed Feb 14 04:36:47 1996
--- src/sys/netinet/if_ether.c Mon Mar 25 04:55:09 1996
***************
*** 172,180 ****
--- 172,182 ----
* such as older version of routed or gated might provide,
* restore cloning bit.
*/
+ #if 0 /* XXX Don't do this anymore, it breaks ARP with subnet masks */
if ((rt->rt_flags & RTF_HOST) == 0 &&
SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
rt->rt_flags |= RTF_CLONING;
+ #endif
if (rt->rt_flags & RTF_CLONING) {
/*
* Case 1: This route should come from a route to iface.
*** src/usr.sbin/arp/arp.c.DIST Fri Oct 13 20:51:30 1995
--- src/usr.sbin/arp/arp.c Mon Mar 25 05:31:30 1996
***************
*** 173,182 ****
err(1, "socket");
}
! struct sockaddr_in so_mask = {8, 0, 0, { 0xffffffff}};
struct sockaddr_inarp blank_sin = {sizeof(blank_sin), AF_INET }, sin_m;
struct sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m;
int expire_time, flags, export_only, doing_proxy, found_entry;
struct {
struct rt_msghdr m_rtm;
char m_space[512];
--- 173,185 ----
err(1, "socket");
}
! struct sockaddr_in so_defaultmask = {8, AF_INET, 0, { 0xffffffff}};
! struct sockaddr_in so_mask;
struct sockaddr_inarp blank_sin = {sizeof(blank_sin), AF_INET }, sin_m;
struct sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m;
int expire_time, flags, export_only, doing_proxy, found_entry;
+ int doing_mask;
+
struct {
struct rt_msghdr m_rtm;
char m_space[512];
***************
*** 205,210 ****
--- 208,215 ----
argv += 2;
sdl_m = blank_sdl; /* struct copy */
sin_m = blank_sin; /* struct copy */
+ so_mask = so_defaultmask; /* struct copy */
+
if (getinetaddr(host, &sin->sin_addr) == -1)
return (1);
ea = (u_char *)LLADDR(&sdl_m);
***************
*** 220,230 ****
--- 225,244 ----
else if (strncmp(argv[0], "pub", 3) == 0) {
flags |= RTF_ANNOUNCE;
doing_proxy = SIN_PROXY;
+ } else if (strncmp(argv[0], "mask", 4) == 0 ||
+ strncmp(argv[0], "netm", 4) == 0) {
+ argv++; argc--;
+ if (argc < 1)
+ usage();
+ getinetaddr(argv[0], &so_mask.sin_addr);
+ doing_mask = 1;
} else if (strncmp(argv[0], "trail", 5) == 0) {
(void)printf(
"%s: Sending trailers is no longer supported\n",
host);
}
+ else
+ usage();
argv++;
}
tryagain:
***************
*** 410,416 ****
if (sin->sin_addr.s_addr == 0xffffffff)
(void)printf(" published");
if (sin->sin_len != 8)
! (void)printf("(wierd)");
}
(void)printf("\n");
}
--- 424,430 ----
if (sin->sin_addr.s_addr == 0xffffffff)
(void)printf(" published");
if (sin->sin_len != 8)
! (void)printf("(weird)");
}
(void)printf("\n");
}
***************
*** 449,455 ****
(void)fprintf(stderr, "usage: arp [-n] -a\n");
(void)fprintf(stderr, "usage: arp -d hostname\n");
(void)fprintf(stderr,
! "usage: arp -s hostname ether_addr [temp] [pub]\n");
(void)fprintf(stderr, "usage: arp -f filename\n");
exit(1);
}
--- 463,469 ----
(void)fprintf(stderr, "usage: arp [-n] -a\n");
(void)fprintf(stderr, "usage: arp -d hostname\n");
(void)fprintf(stderr,
! "usage: arp -s hostname ether_addr [temp] [pub] [netmask mask]\n");
(void)fprintf(stderr, "usage: arp -f filename\n");
exit(1);
}
***************
*** 492,497 ****
--- 506,517 ----
rtm->rtm_flags &= ~RTF_HOST;
}
}
+ if (doing_mask) {
+ rtm->rtm_addrs |= RTA_NETMASK;
+ rtm->rtm_flags &= ~RTF_HOST;
+ }
+
+
/* FALLTHROUGH */
case RTM_GET:
rtm->rtm_addrs |= RTA_DST;