summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.c250
1 files changed, 2 insertions, 248 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index f8ac6b91dfc..351b3f020c6 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6.c,v 1.213 2017/10/20 09:38:17 mpi Exp $ */
+/* $OpenBSD: in6.c,v 1.214 2017/10/24 08:57:10 mpi Exp $ */
/* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */
/*
@@ -118,7 +118,6 @@ const struct in6_addr in6mask64 = IN6MASK64;
const struct in6_addr in6mask96 = IN6MASK96;
const struct in6_addr in6mask128 = IN6MASK128;
-int in6_lifaddr_ioctl(u_long, caddr_t, struct ifnet *, int);
int in6_ioctl(u_long, caddr_t, struct ifnet *, int);
int in6_ifinit(struct ifnet *, struct in6_ifaddr *, int);
void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *);
@@ -196,7 +195,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
case SIOCGETMIFCNT_IN6:
return (mrt6_ioctl(so, cmd, data));
}
-#endif
+#endif /* MROUTING */
return (in6_ioctl(cmd, data, ifp, privileged));
}
@@ -226,16 +225,6 @@ in6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
return (nd6_ioctl(cmd, data, ifp));
}
- switch (cmd) {
- case SIOCALIFADDR:
- case SIOCDLIFADDR:
- if (!privileged)
- return (EPERM);
- /* FALLTHROUGH */
- case SIOCGLIFADDR:
- return in6_lifaddr_ioctl(cmd, data, ifp, privileged);
- }
-
/*
* Find address for this interface, if it exists.
*
@@ -932,241 +921,6 @@ in6_unlink_ifa(struct in6_ifaddr *ia6, struct ifnet *ifp)
}
/*
- * SIOC[GAD]LIFADDR.
- * SIOCGLIFADDR: get first address. (?)
- * SIOCGLIFADDR with IFLR_PREFIX:
- * get first address that matches the specified prefix.
- * SIOCALIFADDR: add the specified address.
- * SIOCALIFADDR with IFLR_PREFIX:
- * add the specified prefix, filling hostid part from
- * the first link-local address. prefixlen must be <= 64.
- * SIOCDLIFADDR: delete the specified address.
- * SIOCDLIFADDR with IFLR_PREFIX:
- * delete the first address that matches the specified prefix.
- * return values:
- * EINVAL on invalid parameters
- * EADDRNOTAVAIL on prefix match failed/specified address not found
- * other values may be returned from in6_ioctl()
- *
- * NOTE: SIOCALIFADDR(with IFLR_PREFIX set) allows prefixlen less than 64.
- * this is to accommodate address naming scheme other than RFC2374,
- * in the future.
- * RFC2373 defines interface id to be 64bit, but it allows non-RFC2374
- * address encoding scheme. (see figure on page 8)
- */
-int
-in6_lifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
-{
- struct if_laddrreq *iflr = (struct if_laddrreq *)data;
- struct ifaddr *ifa;
- struct sockaddr *sa;
-
- /* sanity checks */
- if (!data || !ifp) {
- panic("invalid argument to in6_lifaddr_ioctl");
- /* NOTREACHED */
- }
-
- switch (cmd) {
- case SIOCGLIFADDR:
- /* address must be specified on GET with IFLR_PREFIX */
- if ((iflr->flags & IFLR_PREFIX) == 0)
- break;
- /* FALLTHROUGH */
- case SIOCALIFADDR:
- case SIOCDLIFADDR:
- /* address must be specified on ADD and DELETE */
- sa = sstosa(&iflr->addr);
- if (sa->sa_family != AF_INET6)
- return EINVAL;
- if (sa->sa_len != sizeof(struct sockaddr_in6))
- return EINVAL;
- /* XXX need improvement */
- sa = sstosa(&iflr->dstaddr);
- if (sa->sa_family && sa->sa_family != AF_INET6)
- return EINVAL;
- if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in6))
- return EINVAL;
- break;
- default: /* shouldn't happen */
-#if 0
- panic("invalid cmd to in6_lifaddr_ioctl");
- /* NOTREACHED */
-#else
- return EOPNOTSUPP;
-#endif
- }
- if (sizeof(struct in6_addr) * 8 < iflr->prefixlen)
- return EINVAL;
-
- switch (cmd) {
- case SIOCALIFADDR:
- {
- struct in6_aliasreq ifra;
- struct in6_addr *hostid = NULL;
- int prefixlen;
-
- if ((iflr->flags & IFLR_PREFIX) != 0) {
- struct sockaddr_in6 *sin6;
-
- /*
- * hostid is to fill in the hostid part of the
- * address. hostid points to the first link-local
- * address attached to the interface.
- */
- ifa = &in6ifa_ifpforlinklocal(ifp, 0)->ia_ifa;
- if (!ifa)
- return EADDRNOTAVAIL;
- hostid = IFA_IN6(ifa);
-
- /* prefixlen must be <= 64. */
- if (64 < iflr->prefixlen)
- return EINVAL;
- prefixlen = iflr->prefixlen;
-
- /* hostid part must be zero. */
- sin6 = (struct sockaddr_in6 *)&iflr->addr;
- if (sin6->sin6_addr.s6_addr32[2] != 0
- || sin6->sin6_addr.s6_addr32[3] != 0) {
- return EINVAL;
- }
- } else
- prefixlen = iflr->prefixlen;
-
- /* copy args to in6_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
- bzero(&ifra, sizeof(ifra));
- bcopy(iflr->iflr_name, ifra.ifra_name, sizeof(ifra.ifra_name));
-
- bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len);
- if (hostid) {
- /* fill in hostid part */
- ifra.ifra_addr.sin6_addr.s6_addr32[2] =
- hostid->s6_addr32[2];
- ifra.ifra_addr.sin6_addr.s6_addr32[3] =
- hostid->s6_addr32[3];
- }
-
- if (iflr->dstaddr.ss_family) { /*XXX*/
- bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
- iflr->dstaddr.ss_len);
- if (hostid) {
- ifra.ifra_dstaddr.sin6_addr.s6_addr32[2] =
- hostid->s6_addr32[2];
- ifra.ifra_dstaddr.sin6_addr.s6_addr32[3] =
- hostid->s6_addr32[3];
- }
- }
-
- ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
- in6_prefixlen2mask(&ifra.ifra_prefixmask.sin6_addr, prefixlen);
-
- ifra.ifra_flags = iflr->flags & ~IFLR_PREFIX;
- return in6_ioctl(SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp,
- privileged);
- }
- case SIOCGLIFADDR:
- case SIOCDLIFADDR:
- {
- struct in6_ifaddr *ia6;
- struct in6_addr mask, candidate, match;
- struct sockaddr_in6 *sin6;
- int cmp;
-
- bzero(&mask, sizeof(mask));
- if (iflr->flags & IFLR_PREFIX) {
- /* lookup a prefix rather than address. */
- in6_prefixlen2mask(&mask, iflr->prefixlen);
-
- sin6 = (struct sockaddr_in6 *)&iflr->addr;
- bcopy(&sin6->sin6_addr, &match, sizeof(match));
- match.s6_addr32[0] &= mask.s6_addr32[0];
- match.s6_addr32[1] &= mask.s6_addr32[1];
- match.s6_addr32[2] &= mask.s6_addr32[2];
- match.s6_addr32[3] &= mask.s6_addr32[3];
-
- /* if you set extra bits, that's wrong */
- if (bcmp(&match, &sin6->sin6_addr, sizeof(match)))
- return EINVAL;
-
- cmp = 1;
- } else {
- if (cmd == SIOCGLIFADDR) {
- /* on getting an address, take the 1st match */
- cmp = 0; /* XXX */
- } else {
- /* on deleting an address, do exact match */
- in6_prefixlen2mask(&mask, 128);
- sin6 = (struct sockaddr_in6 *)&iflr->addr;
- bcopy(&sin6->sin6_addr, &match, sizeof(match));
-
- cmp = 1;
- }
- }
-
- TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
- if (ifa->ifa_addr->sa_family != AF_INET6)
- continue;
- if (!cmp)
- break;
-
- bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate));
- candidate.s6_addr32[0] &= mask.s6_addr32[0];
- candidate.s6_addr32[1] &= mask.s6_addr32[1];
- candidate.s6_addr32[2] &= mask.s6_addr32[2];
- candidate.s6_addr32[3] &= mask.s6_addr32[3];
- if (IN6_ARE_ADDR_EQUAL(&candidate, &match))
- break;
- }
- if (!ifa)
- return EADDRNOTAVAIL;
- ia6 = ifatoia6(ifa);
-
- if (cmd == SIOCGLIFADDR) {
- /* fill in the if_laddrreq structure */
- bcopy(&ia6->ia_addr, &iflr->addr, ia6->ia_addr.sin6_len);
- if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
- bcopy(&ia6->ia_dstaddr, &iflr->dstaddr,
- ia6->ia_dstaddr.sin6_len);
- } else
- bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
-
- iflr->prefixlen =
- in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL);
-
- iflr->flags = ia6->ia6_flags; /*XXX*/
-
- return 0;
- } else {
- struct in6_aliasreq ifra;
-
- /* fill in6_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
- bzero(&ifra, sizeof(ifra));
- bcopy(iflr->iflr_name, ifra.ifra_name,
- sizeof(ifra.ifra_name));
-
- bcopy(&ia6->ia_addr, &ifra.ifra_addr,
- ia6->ia_addr.sin6_len);
- if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
- bcopy(&ia6->ia_dstaddr, &ifra.ifra_dstaddr,
- ia6->ia_dstaddr.sin6_len);
- } else {
- bzero(&ifra.ifra_dstaddr,
- sizeof(ifra.ifra_dstaddr));
- }
- bcopy(&ia6->ia_prefixmask, &ifra.ifra_dstaddr,
- ia6->ia_prefixmask.sin6_len);
-
- ifra.ifra_flags = ia6->ia6_flags;
- return in6_ioctl(SIOCDIFADDR_IN6, (caddr_t)&ifra, ifp,
- privileged);
- }
- }
- }
-
- return EOPNOTSUPP; /* just for safety */
-}
-
-/*
* Initialize an interface's intetnet6 address
* and routing table entry.
*/