Index: ndp.c =================================================================== RCS file: /cvs/src/usr.sbin/ndp/ndp.c,v retrieving revision 1.87 diff -u -p -r1.87 ndp.c --- ndp.c 25 Oct 2017 12:09:07 -0000 1.87 +++ ndp.c 1 Mar 2018 22:58:05 -0000 @@ -137,6 +137,7 @@ int rtget(struct sockaddr_in6 **, struct void ifinfo(char *); static char *sec2str(time_t); static void ts_print(const struct timeval *); +static int sdl_isether(const struct sockaddr_dl *); static int rdomain; static char *rtpref_str[] = { @@ -376,15 +377,10 @@ set(int argc, char **argv) } if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) { - if (sdl->sdl_family == AF_LINK && + if (sdl_isether(sdl) && (rtm->rtm_flags & RTF_LLINFO) && - !(rtm->rtm_flags & RTF_GATEWAY)) { - switch (sdl->sdl_type) { - case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: - case IFT_ISO88024: case IFT_ISO88025: - goto overwrite; - } - } + !(rtm->rtm_flags & RTF_GATEWAY)) + goto overwrite; /* * IPv4 arp command retries with sin_other = SIN_PROXY here. */ @@ -392,11 +388,11 @@ set(int argc, char **argv) return 1; } -overwrite: - if (sdl->sdl_family != AF_LINK) { + if (!sdl_isether(sdl)) { printf("cannot intuit interface index and type for %s\n", host); return (1); } +overwrite: sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; return (rtmsg(RTM_ADD)); @@ -477,7 +473,7 @@ delete(char *host) } if (IN6_ARE_ADDR_EQUAL(&sin->sin6_addr, &sin_m.sin6_addr)) { - if (sdl->sdl_family == AF_LINK && rtm->rtm_flags & RTF_LLINFO) { + if (sdl_isether(sdl) && rtm->rtm_flags & RTF_LLINFO) { if (rtm->rtm_flags & RTF_LOCAL) return (0); if (!(rtm->rtm_flags & RTF_GATEWAY)) @@ -490,11 +486,11 @@ delete(char *host) return 1; } -delete: - if (sdl->sdl_family != AF_LINK) { + if (!sdl_isether(sdl)) { printf("cannot locate %s\n", host); return (1); } +delete: if (rtmsg(RTM_DELETE) == 0) { struct sockaddr_in6 s6 = *sin; /* XXX: for safety */ @@ -590,7 +586,7 @@ again:; * What is to be fixed is not ndp, but such routing software * (and the kernel workaround)... */ - if (sdl->sdl_family != AF_LINK) + if (!sdl_isether(sdl)) continue; if (!(rtm->rtm_flags & RTF_HOST)) @@ -961,4 +957,27 @@ ts_print(const struct timeval *tvp) s = (tvp->tv_sec + thiszone) % 86400; (void)printf("%02d:%02d:%02d.%06u ", s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec); +} + +static int +sdl_isether(const struct sockaddr_dl *sdl) +{ + if (sdl->sdl_family != AF_LINK) + return (0); + + switch (sdl->sdl_type) { + case IFT_ETHER: + case IFT_CARP: + case IFT_XETHER: + case IFT_FDDI: + case IFT_ISO88023: + case IFT_ISO88024: + case IFT_ISO88025: + break; + + default: + return (0); + } + + return (1); }