summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoritojun <itojun@openbsd.org>2001-02-20 13:50:53 +0000
committeritojun <itojun@openbsd.org>2001-02-20 13:50:53 +0000
commit73816fdf86956984a1b177999c92227f2a1db427 (patch)
treed5474318ec7139eadd5e2112e3197ac6b36215c5
parentCompile with USCANNER_DEBUG, implied by USB_DEBUG. (diff)
downloadwireguard-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.c125
-rw-r--r--sys/net/if.c7
-rw-r--r--sys/net/if_gif.c230
-rw-r--r--sys/sys/sockio.h5
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 = &ifr;
- srccmd = SIOCGIFPSRCADDR;
- dstcmd = SIOCGIFPDSTADDR;
- } else {
- close(s6);
- srccmd = SIOCGIFPSRCADDR_IN6;
- dstcmd = SIOCGIFPDSTADDR_IN6;
- ifrp = (struct ifreq *) &in6_ifr;
- }
-#else /* INET6 */
- ifrp = &ifr;
- 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 */