diff options
author | 2001-02-20 13:50:53 +0000 | |
---|---|---|
committer | 2001-02-20 13:50:53 +0000 | |
commit | 73816fdf86956984a1b177999c92227f2a1db427 (patch) | |
tree | d5474318ec7139eadd5e2112e3197ac6b36215c5 | |
parent | Compile with USCANNER_DEBUG, implied by USB_DEBUG. (diff) | |
download | wireguard-openbsd-73816fdf86956984a1b177999c92227f2a1db427.tar.xz wireguard-openbsd-73816fdf86956984a1b177999c92227f2a1db427.zip |
provide SIOC[SG]LIFPHYADDR, which greatly simplify userland manipulation.
sync with kame. old ioctls are kept but not really recommended.
-rw-r--r-- | sbin/ifconfig/ifconfig.c | 125 | ||||
-rw-r--r-- | sys/net/if.c | 7 | ||||
-rw-r--r-- | sys/net/if_gif.c | 230 | ||||
-rw-r--r-- | sys/sys/sockio.h | 5 |
4 files changed, 200 insertions, 167 deletions
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 220a774d950..6d101e415ea 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ifconfig.c,v 1.44 2001/01/18 04:46:03 itojun Exp $ */ +/* $OpenBSD: ifconfig.c,v 1.45 2001/02/20 13:50:53 itojun Exp $ */ /* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */ /* @@ -81,7 +81,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; #else -static char rcsid[] = "$OpenBSD: ifconfig.c,v 1.44 2001/01/18 04:46:03 itojun Exp $"; +static char rcsid[] = "$OpenBSD: ifconfig.c,v 1.45 2001/02/20 13:50:53 itojun Exp $"; #endif #endif /* not lint */ @@ -762,59 +762,34 @@ gifsettunnel(src, dst) char *dst; { struct addrinfo hints, *srcres, *dstres; - struct ifaliasreq addreq; int ecode; -#ifdef INET6 - struct in6_aliasreq in6_addreq; -#endif /* INET6 */ + struct if_laddrreq req; memset(&hints, 0, sizeof(hints)); hints.ai_family = afp->af_af; - if ((ecode = getaddrinfo(src, NULL, &hints, &srcres)) != 0) + if ((ecode = getaddrinfo(src, NULL, NULL, &srcres)) != 0) errx(1, "error in parsing address string: %s", - gai_strerror(ecode)); + gai_strerror(ecode)); - if ((ecode = getaddrinfo(dst, NULL, &hints, &dstres)) != 0) + if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0) errx(1, "error in parsing address string: %s", - gai_strerror(ecode)); + gai_strerror(ecode)); if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family) errx(1, - "source and destination address families do not match"); + "source and destination address families do not match"); - switch (srcres->ai_addr->sa_family) - { - case AF_INET: - bzero(&addreq, sizeof(addreq)); - strncpy(addreq.ifra_name, name, IFNAMSIZ); - bcopy(srcres->ai_addr, &addreq.ifra_addr, - srcres->ai_addr->sa_len); - bcopy(dstres->ai_addr, &addreq.ifra_dstaddr, - dstres->ai_addr->sa_len); - - if (ioctl(s, SIOCSIFPHYADDR, (struct ifreq *) &addreq) < 0) - warn("SIOCSIFPHYADDR"); - break; - -#ifdef INET6 - case AF_INET6: - bzero(&in6_addreq, sizeof(in6_addreq)); - strncpy(in6_addreq.ifra_name, name, IFNAMSIZ); - bcopy(srcres->ai_addr, &in6_addreq.ifra_addr, - srcres->ai_addr->sa_len); - bcopy(dstres->ai_addr, &in6_addreq.ifra_dstaddr, - dstres->ai_addr->sa_len); - - if (ioctl(s, SIOCSIFPHYADDR_IN6, - (struct ifreq *) &in6_addreq) < 0) - warn("SIOCSIFPHYADDR"); - break; -#endif /* INET6 */ + if (srcres->ai_addrlen > sizeof(req.addr) || + dstres->ai_addrlen > sizeof(req.dstaddr)) + errx(1, "invalid sockaddr"); - default: - warn("address family not supported"); - } + memset(&req, 0, sizeof(req)); + strncpy(req.iflr_name, name, sizeof(req.iflr_name)); + memcpy(&req.addr, srcres->ai_addr, srcres->ai_addrlen); + memcpy(&req.dstaddr, dstres->ai_addr, dstres->ai_addrlen); + if (ioctl(s, SIOCSLIFPHYADDR, &req) < 0) + warn("SIOCSLIFPHYADDR"); freeaddrinfo(srcres); freeaddrinfo(dstres); @@ -1316,68 +1291,40 @@ phys_status(force) { char psrcaddr[NI_MAXHOST]; char pdstaddr[NI_MAXHOST]; - u_long srccmd, dstcmd; - struct ifreq *ifrp; - char *ver = ""; + const char *ver = ""; #ifdef NI_WITHSCOPEID const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID; #else const int niflag = NI_NUMERICHOST; #endif -#ifdef INET6 - struct in6_ifreq in6_ifr; - int s6; -#endif /* INET6 */ + struct if_laddrreq req; - force = 0; /*fool gcc*/ psrcaddr[0] = pdstaddr[0] = '\0'; + memset(&req, 0, sizeof(req)); + strncpy(req.iflr_name, name, IFNAMSIZ); + if (ioctl(s, SIOCGLIFPHYADDR, (caddr_t)&req) < 0) + return; #ifdef INET6 - bzero(&in6_ifr, sizeof(in6_ifr)); - strncpy(in6_ifr.ifr_name, name, IFNAMSIZ); - s6 = socket(AF_INET6, SOCK_DGRAM, 0); - if (s6 < 0) { - ifrp = 𝔦 - srccmd = SIOCGIFPSRCADDR; - dstcmd = SIOCGIFPDSTADDR; - } else { - close(s6); - srccmd = SIOCGIFPSRCADDR_IN6; - dstcmd = SIOCGIFPDSTADDR_IN6; - ifrp = (struct ifreq *) &in6_ifr; - } -#else /* INET6 */ - ifrp = 𝔦 - srccmd = SIOCGIFPSRCADDR; - dstcmd = SIOCGIFPDSTADDR; -#endif /* INET6 */ - - if (0 <= ioctl(s, srccmd, (caddr_t)ifrp)) { -#ifdef INET6 - if (ifrp->ifr_addr.sa_family == AF_INET6) - in6_fillscopeid((struct sockaddr_in6 *)&ifrp->ifr_addr); + if (req.addr.ss_family == AF_INET6) + in6_fillscopeid((struct sockaddr_in6 *)&req.addr); #endif - getnameinfo(&ifrp->ifr_addr, ifrp->ifr_addr.sa_len, - psrcaddr, NI_MAXHOST, 0, 0, niflag); + getnameinfo((struct sockaddr *)&req.addr, req.addr.ss_len, + psrcaddr, sizeof(psrcaddr), 0, 0, niflag); #ifdef INET6 - if (ifrp->ifr_addr.sa_family == AF_INET6) - ver = "6"; -#endif /* INET6 */ + if (req.addr.ss_family == AF_INET6) + ver = "6"; +#endif - if (0 <= ioctl(s, dstcmd, (caddr_t)ifrp)) { #ifdef INET6 - if (ifrp->ifr_addr.sa_family == AF_INET6) { - in6_fillscopeid((struct sockaddr_in6 *) - &ifrp->ifr_addr); - } + if (req.dstaddr.ss_family == AF_INET6) + in6_fillscopeid((struct sockaddr_in6 *)&req.dstaddr); #endif - getnameinfo(&ifrp->ifr_addr, ifrp->ifr_addr.sa_len, - pdstaddr, NI_MAXHOST, 0, 0, niflag); - } + getnameinfo((struct sockaddr *)&req.dstaddr, req.dstaddr.ss_len, + pdstaddr, sizeof(pdstaddr), 0, 0, niflag); - printf("\tphysical address inet%s %s --> %s\n", ver, - psrcaddr, pdstaddr); - } + printf("\tphysical address inet%s %s --> %s\n", ver, + psrcaddr, pdstaddr); } const int ifm_status_valid_list[] = IFM_STATUS_VALID_LIST; diff --git a/sys/net/if.c b/sys/net/if.c index d04d080a270..578e8dcf327 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.42 2001/02/13 19:49:32 art Exp $ */ +/* $OpenBSD: if.c,v 1.43 2001/02/20 13:50:53 itojun Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -797,9 +797,11 @@ ifioctl(so, cmd, data, p) } case SIOCSIFPHYADDR: + case SIOCDIFPHYADDR: #ifdef INET6 case SIOCSIFPHYADDR_IN6: #endif + case SIOCSLIFPHYADDR: case SIOCADDMULTI: case SIOCDELMULTI: case SIOCSIFMEDIA: @@ -808,6 +810,7 @@ ifioctl(so, cmd, data, p) /* FALLTHROUGH */ case SIOCGIFPSRCADDR: case SIOCGIFPDSTADDR: + case SIOCGLIFPHYADDR: case SIOCGIFMEDIA: if (ifp->if_ioctl == 0) return (EOPNOTSUPP); @@ -1009,4 +1012,4 @@ void if_detached_watchdog(struct ifnet *ifp) { /* nothing */ -}
\ No newline at end of file +} diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 91074f0d39c..73c3fafb202 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_gif.c,v 1.13 2001/02/20 10:33:28 itojun Exp $ */ -/* $KAME: if_gif.c,v 1.32 2000/10/07 03:20:55 itojun Exp $ */ +/* $OpenBSD: if_gif.c,v 1.14 2001/02/20 13:50:53 itojun Exp $ */ +/* $KAME: if_gif.c,v 1.43 2001/02/20 08:51:07 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -30,11 +30,6 @@ * SUCH DAMAGE. */ -/* - * gif.c - */ - - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -250,7 +245,10 @@ gif_ioctl(ifp, cmd, data) struct gif_softc *sc = (struct gif_softc*)ifp; struct ifreq *ifr = (struct ifreq*)data; int error = 0, size; - struct sockaddr *sa, *dst, *src; + struct sockaddr *dst, *src; + struct sockaddr *sa; + int i; + struct gif_softc *sc2; switch (cmd) { case SIOCSIFADDR: @@ -280,6 +278,7 @@ gif_ioctl(ifp, cmd, data) #ifdef INET6 case SIOCSIFPHYADDR_IN6: #endif /* INET6 */ + case SIOCSLIFPHYADDR: switch (cmd) { #ifdef INET case SIOCSIFPHYADDR: @@ -287,92 +286,148 @@ gif_ioctl(ifp, cmd, data) &(((struct in_aliasreq *)data)->ifra_addr); dst = (struct sockaddr *) &(((struct in_aliasreq *)data)->ifra_dstaddr); - if (src->sa_len != sizeof(struct sockaddr_in) || - dst->sa_len != sizeof(struct sockaddr_in)) - return EINVAL; - if (src->sa_family != AF_INET || - dst->sa_family != AF_INET) - return EAFNOSUPPORT; - - /* only one gif can have dst = INADDR_ANY */ -#define satosaddr(sa) (((struct sockaddr_in *)(sa))->sin_addr.s_addr) - - if (satosaddr(dst) == INADDR_ANY) { - int i; - struct gif_softc *sc2; - - for (i = 0, sc2 = gif; i < ngif; i++, sc2++) { - if (sc2 == sc) continue; - if (sc2->gif_pdst && - satosaddr(sc2->gif_pdst) - == INADDR_ANY) { - error = EADDRNOTAVAIL; - goto bad; - } - } - } - size = sizeof(struct sockaddr_in); break; -#endif /* INET */ +#endif #ifdef INET6 case SIOCSIFPHYADDR_IN6: src = (struct sockaddr *) &(((struct in6_aliasreq *)data)->ifra_addr); dst = (struct sockaddr *) &(((struct in6_aliasreq *)data)->ifra_dstaddr); - if (src->sa_len != sizeof(struct sockaddr_in6) || - dst->sa_len != sizeof(struct sockaddr_in6)) + break; +#endif + case SIOCSLIFPHYADDR: + src = (struct sockaddr *) + &(((struct if_laddrreq *)data)->addr); + dst = (struct sockaddr *) + &(((struct if_laddrreq *)data)->dstaddr); + } + + /* sa_family must be equal */ + if (src->sa_family != dst->sa_family) + return EINVAL; + + /* validate sa_len */ + switch (src->sa_family) { +#ifdef INET + case AF_INET: + if (src->sa_len != sizeof(struct sockaddr_in)) return EINVAL; - if (src->sa_family != AF_INET6 || - dst->sa_family != AF_INET6) - return EAFNOSUPPORT; - - /* only one gif can have dst = in6addr_any */ -#define satoin6(sa) (&((struct sockaddr_in6 *)(sa))->sin6_addr) - - if (IN6_IS_ADDR_UNSPECIFIED(satoin6(dst))) { - int i; - struct gif_softc *sc2; - - for (i = 0, sc2 = gif; i < ngif; i++, sc2++) { - if (sc2 == sc) continue; - if (sc2->gif_pdst && - IN6_IS_ADDR_UNSPECIFIED( - satoin6(sc2->gif_pdst) - )) { - error = EADDRNOTAVAIL; - goto bad; - } - } - } - size = sizeof(struct sockaddr_in6); break; -#endif /* INET6 */ +#endif +#ifdef INET6 + case AF_INET6: + if (src->sa_len != sizeof(struct sockaddr_in6)) + return EINVAL; + break; +#endif default: - error = EPROTOTYPE; - goto bad; + return EAFNOSUPPORT; + } + switch (dst->sa_family) { +#ifdef INET + case AF_INET: + if (dst->sa_len != sizeof(struct sockaddr_in)) + return EINVAL; + break; +#endif +#ifdef INET6 + case AF_INET6: + if (dst->sa_len != sizeof(struct sockaddr_in6)) + return EINVAL; + break; +#endif + default: + return EAFNOSUPPORT; + } + + /* check sa_family looks sane for the cmd */ + switch (cmd) { + case SIOCSIFPHYADDR: + if (src->sa_family == AF_INET) + break; + return EAFNOSUPPORT; +#ifdef INET6 + case SIOCSIFPHYADDR_IN6: + if (src->sa_family == AF_INET6) + break; + return EAFNOSUPPORT; +#endif /* INET6 */ + case SIOCSLIFPHYADDR: + /* checks done in the above */ break; } - if (sc->gif_psrc != NULL) - free((caddr_t)sc->gif_psrc, M_IFADDR); - if (sc->gif_pdst != NULL) - free((caddr_t)sc->gif_pdst, M_IFADDR); - sa = (struct sockaddr *)malloc(size, M_IFADDR, M_WAITOK); - bzero((caddr_t)sa, size); - bcopy((caddr_t)src, (caddr_t)sa, size); + for (i = 0; i < ngif; i++) { + sc2 = gif + i; + if (sc2 == sc) + continue; + if (!sc2->gif_pdst || !sc2->gif_psrc) + continue; + if (sc2->gif_pdst->sa_family != dst->sa_family || + sc2->gif_pdst->sa_len != dst->sa_len || + sc2->gif_psrc->sa_family != src->sa_family || + sc2->gif_psrc->sa_len != src->sa_len) + continue; + /* can't configure same pair of address onto two gifs */ + if (bcmp(sc2->gif_pdst, dst, dst->sa_len) == 0 && + bcmp(sc2->gif_psrc, src, src->sa_len) == 0) { + error = EADDRNOTAVAIL; + goto bad; + } + + /* can't configure multiple multi-dest interfaces */ +#define multidest(x) \ + (((struct sockaddr_in *)(x))->sin_addr.s_addr == INADDR_ANY) +#ifdef INET6 +#define multidest6(x) \ + (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)(x))->sin6_addr)) +#endif + if (dst->sa_family == AF_INET && + multidest(dst) && multidest(sc2->gif_pdst)) { + error = EADDRNOTAVAIL; + goto bad; + } +#ifdef INET6 + if (dst->sa_family == AF_INET6 && + multidest6(dst) && multidest6(sc2->gif_pdst)) { + error = EADDRNOTAVAIL; + goto bad; + } +#endif + } + + if (sc->gif_psrc) + free((caddr_t)sc->gif_psrc, M_IFADDR); + sa = (struct sockaddr *)malloc(src->sa_len, M_IFADDR, M_WAITOK); + bcopy((caddr_t)src, (caddr_t)sa, src->sa_len); sc->gif_psrc = sa; - - sa = (struct sockaddr *)malloc(size, M_IFADDR, M_WAITOK); - bzero((caddr_t)sa, size); - bcopy((caddr_t)dst, (caddr_t)sa, size); + + if (sc->gif_pdst) + free((caddr_t)sc->gif_pdst, M_IFADDR); + sa = (struct sockaddr *)malloc(dst->sa_len, M_IFADDR, M_WAITOK); + bcopy((caddr_t)dst, (caddr_t)sa, dst->sa_len); sc->gif_pdst = sa; - - ifp->if_flags |= IFF_UP | IFF_RUNNING; + + ifp->if_flags |= (IFF_UP | IFF_RUNNING); if_up(ifp); /* send up RTM_IFINFO */ error = 0; break; + +#ifdef SIOCDIFPHYADDR + case SIOCDIFPHYADDR: + if (sc->gif_psrc) { + free((caddr_t)sc->gif_psrc, M_IFADDR); + sc->gif_psrc = NULL; + } + if (sc->gif_pdst) { + free((caddr_t)sc->gif_pdst, M_IFADDR); + sc->gif_pdst = NULL; + } + /* change the IFF_{UP, RUNNING} flag as well? */ + break; +#endif case SIOCGIFPSRCADDR: #ifdef INET6 @@ -438,6 +493,31 @@ gif_ioctl(ifp, cmd, data) bcopy((caddr_t)src, (caddr_t)dst, src->sa_len); break; + case SIOCGLIFPHYADDR: + if (sc->gif_psrc == NULL || sc->gif_pdst == NULL) { + error = EADDRNOTAVAIL; + goto bad; + } + + /* copy src */ + src = sc->gif_psrc; + dst = (struct sockaddr *) + &(((struct if_laddrreq *)data)->addr); + size = sizeof(((struct if_laddrreq *)data)->addr); + if (src->sa_len > size) + return EINVAL; + bcopy((caddr_t)src, (caddr_t)dst, src->sa_len); + + /* copy dst */ + src = sc->gif_pdst; + dst = (struct sockaddr *) + &(((struct if_laddrreq *)data)->dstaddr); + size = sizeof(((struct if_laddrreq *)data)->dstaddr); + if (src->sa_len > size) + return EINVAL; + bcopy((caddr_t)src, (caddr_t)dst, src->sa_len); + break; + case SIOCSIFFLAGS: /* if_ioctl() takes care of it */ break; diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h index f32aa78bc25..badeec21b7e 100644 --- a/sys/sys/sockio.h +++ b/sys/sys/sockio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sockio.h,v 1.18 2000/12/31 00:14:59 angelos Exp $ */ +/* $OpenBSD: sockio.h,v 1.19 2001/02/20 13:50:53 itojun Exp $ */ /* $NetBSD: sockio.h,v 1.5 1995/08/23 00:40:47 thorpej Exp $ */ /*- @@ -95,6 +95,9 @@ #define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif addres */ #define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) /* get gif psrc addr */ #define SIOCGIFPDSTADDR _IOWR('i', 72, struct ifreq) /* get gif pdst addr */ +#define SIOCDIFPHYADDR _IOW('i', 73, struct ifreq) /* delete gif addrs */ +#define SIOCSLIFPHYADDR _IOW('i', 74, struct if_laddrreq) /* set gif addrs */ +#define SIOCGLIFPHYADDR _IOWR('i', 75, struct if_laddrreq) /* get gif addrs */ #define SIOCBRDGADD _IOW('i', 60, struct ifbreq) /* add bridge ifs */ #define SIOCBRDGDEL _IOW('i', 61, struct ifbreq) /* del bridge ifs */ |