Remove never used ioctls that originate from KAME. The proof
of their zero usage was exp-run from misc/183538.
This commit is contained in:
parent
190bdc75e8
commit
3c1f482e0e
@ -2412,7 +2412,6 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
|
||||
#ifdef INET6
|
||||
case SIOCSIFPHYADDR_IN6:
|
||||
#endif
|
||||
case SIOCSLIFPHYADDR:
|
||||
case SIOCSIFMEDIA:
|
||||
case SIOCSIFGENERIC:
|
||||
error = priv_check(td, PRIV_NET_HWIOCTL);
|
||||
@ -2431,7 +2430,6 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
|
||||
|
||||
case SIOCGIFPSRCADDR:
|
||||
case SIOCGIFPDSTADDR:
|
||||
case SIOCGLIFPHYADDR:
|
||||
case SIOCGIFMEDIA:
|
||||
case SIOCGIFGENERIC:
|
||||
if (ifp->if_ioctl == NULL)
|
||||
|
12
sys/net/if.h
12
sys/net/if.h
@ -497,18 +497,6 @@ struct ifgroupreq {
|
||||
#define ifgr_groups ifgr_ifgru.ifgru_groups
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure for SIOC[AGD]LIFADDR
|
||||
*/
|
||||
struct if_laddrreq {
|
||||
char iflr_name[IFNAMSIZ];
|
||||
u_int flags;
|
||||
#define IFLR_PREFIX 0x8000 /* in: prefix given out: kernel fills id */
|
||||
u_int prefixlen; /* in/out */
|
||||
struct sockaddr_storage addr; /* in/out */
|
||||
struct sockaddr_storage dstaddr; /* out */
|
||||
};
|
||||
|
||||
#endif /* __BSD_VISIBLE */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
@ -710,7 +710,6 @@ gif_ioctl(ifp, cmd, data)
|
||||
#ifdef INET6
|
||||
case SIOCSIFPHYADDR_IN6:
|
||||
#endif /* INET6 */
|
||||
case SIOCSLIFPHYADDR:
|
||||
switch (cmd) {
|
||||
#ifdef INET
|
||||
case SIOCSIFPHYADDR:
|
||||
@ -728,12 +727,6 @@ gif_ioctl(ifp, cmd, data)
|
||||
&(((struct in6_aliasreq *)data)->ifra_dstaddr);
|
||||
break;
|
||||
#endif
|
||||
case SIOCSLIFPHYADDR:
|
||||
src = (struct sockaddr *)
|
||||
&(((struct if_laddrreq *)data)->addr);
|
||||
dst = (struct sockaddr *)
|
||||
&(((struct if_laddrreq *)data)->dstaddr);
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
@ -788,9 +781,6 @@ gif_ioctl(ifp, cmd, data)
|
||||
break;
|
||||
return EAFNOSUPPORT;
|
||||
#endif /* INET6 */
|
||||
case SIOCSLIFPHYADDR:
|
||||
/* checks done in the above */
|
||||
break;
|
||||
}
|
||||
|
||||
error = gif_set_tunnel(GIF2IFP(sc), src, dst);
|
||||
@ -886,31 +876,6 @@ gif_ioctl(ifp, cmd, data)
|
||||
#endif
|
||||
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;
|
||||
|
@ -519,7 +519,6 @@ static int
|
||||
gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
{
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
struct if_laddrreq *lifr = (struct if_laddrreq *)data;
|
||||
struct in_aliasreq *aifr = (struct in_aliasreq *)data;
|
||||
struct gre_softc *sc = ifp->if_softc;
|
||||
struct sockaddr_in si;
|
||||
@ -734,27 +733,6 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
sc->g_src = aifr->ifra_addr.sin_addr;
|
||||
sc->g_dst = aifr->ifra_dstaddr.sin_addr;
|
||||
goto recompute;
|
||||
case SIOCSLIFPHYADDR:
|
||||
/*
|
||||
* XXXRW: Isn't this priv_check() redundant to the ifnet
|
||||
* layer check?
|
||||
*/
|
||||
if ((error = priv_check(curthread, PRIV_NET_SETIFPHYS)) != 0)
|
||||
break;
|
||||
if (lifr->addr.ss_family != AF_INET ||
|
||||
lifr->dstaddr.ss_family != AF_INET) {
|
||||
error = EAFNOSUPPORT;
|
||||
break;
|
||||
}
|
||||
if (lifr->addr.ss_len != sizeof(si) ||
|
||||
lifr->dstaddr.ss_len != sizeof(si)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
sc->g_src = (satosin(&lifr->addr))->sin_addr;
|
||||
sc->g_dst =
|
||||
(satosin(&lifr->dstaddr))->sin_addr;
|
||||
goto recompute;
|
||||
case SIOCDIFPHYADDR:
|
||||
/*
|
||||
* XXXRW: Isn't this priv_check() redundant to the ifnet
|
||||
@ -765,26 +743,6 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
sc->g_src.s_addr = INADDR_ANY;
|
||||
sc->g_dst.s_addr = INADDR_ANY;
|
||||
goto recompute;
|
||||
case SIOCGLIFPHYADDR:
|
||||
if (sc->g_src.s_addr == INADDR_ANY ||
|
||||
sc->g_dst.s_addr == INADDR_ANY) {
|
||||
error = EADDRNOTAVAIL;
|
||||
break;
|
||||
}
|
||||
memset(&si, 0, sizeof(si));
|
||||
si.sin_family = AF_INET;
|
||||
si.sin_len = sizeof(struct sockaddr_in);
|
||||
si.sin_addr.s_addr = sc->g_src.s_addr;
|
||||
error = prison_if(curthread->td_ucred, (struct sockaddr *)&si);
|
||||
if (error != 0)
|
||||
break;
|
||||
memcpy(&lifr->addr, &si, sizeof(si));
|
||||
si.sin_addr.s_addr = sc->g_dst.s_addr;
|
||||
error = prison_if(curthread->td_ucred, (struct sockaddr *)&si);
|
||||
if (error != 0)
|
||||
break;
|
||||
memcpy(&lifr->dstaddr, &si, sizeof(si));
|
||||
break;
|
||||
case SIOCGIFPSRCADDR:
|
||||
#ifdef INET6
|
||||
case SIOCGIFPSRCADDR_IN6:
|
||||
|
232
sys/netinet/in.c
232
sys/netinet/in.c
@ -68,10 +68,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/udp_var.h>
|
||||
|
||||
static int in_mask2len(struct in_addr *);
|
||||
static void in_len2mask(struct in_addr *, int);
|
||||
static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t,
|
||||
struct ifnet *, struct thread *);
|
||||
static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *);
|
||||
static int in_difaddr_ioctl(caddr_t, struct ifnet *, struct thread *);
|
||||
|
||||
@ -192,42 +188,6 @@ in_socktrim(struct sockaddr_in *ap)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
in_mask2len(mask)
|
||||
struct in_addr *mask;
|
||||
{
|
||||
int x, y;
|
||||
u_char *p;
|
||||
|
||||
p = (u_char *)mask;
|
||||
for (x = 0; x < sizeof(*mask); x++) {
|
||||
if (p[x] != 0xff)
|
||||
break;
|
||||
}
|
||||
y = 0;
|
||||
if (x < sizeof(*mask)) {
|
||||
for (y = 0; y < 8; y++) {
|
||||
if ((p[x] & (0x80 >> y)) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (x * 8 + y);
|
||||
}
|
||||
|
||||
static void
|
||||
in_len2mask(struct in_addr *mask, int len)
|
||||
{
|
||||
int i;
|
||||
u_char *p;
|
||||
|
||||
p = (u_char *)mask;
|
||||
bzero(mask, sizeof(*mask));
|
||||
for (i = 0; i < len / 8; i++)
|
||||
p[i] = 0xff;
|
||||
if (len % 8)
|
||||
p[i] = (0xff00 >> (len % 8)) & 0xff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic internet control operations (ioctl's).
|
||||
*/
|
||||
@ -265,10 +225,6 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
|
||||
error = in_aifaddr_ioctl(cmd, data, ifp, td);
|
||||
sx_xunlock(&in_control_sx);
|
||||
return (error);
|
||||
case SIOCALIFADDR:
|
||||
case SIOCDLIFADDR:
|
||||
case SIOCGLIFADDR:
|
||||
return (in_lifaddr_ioctl(so, cmd, data, ifp, td));
|
||||
case SIOCSIFADDR:
|
||||
case SIOCSIFBRDADDR:
|
||||
case SIOCSIFDSTADDR:
|
||||
@ -643,194 +599,6 @@ in_difaddr_ioctl(caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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:
|
||||
* EINVAL since we can't deduce hostid part of the address.
|
||||
* 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 in_ioctl()
|
||||
*/
|
||||
static int
|
||||
in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
|
||||
struct ifnet *ifp, struct thread *td)
|
||||
{
|
||||
struct if_laddrreq *iflr = (struct if_laddrreq *)data;
|
||||
struct ifaddr *ifa;
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCALIFADDR:
|
||||
if (td != NULL) {
|
||||
error = priv_check(td, PRIV_NET_ADDIFADDR);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
break;
|
||||
case SIOCDLIFADDR:
|
||||
if (td != NULL) {
|
||||
error = priv_check(td, PRIV_NET_DELIFADDR);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
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 */
|
||||
if (iflr->addr.ss_family != AF_INET)
|
||||
return (EINVAL);
|
||||
if (iflr->addr.ss_len != sizeof(struct sockaddr_in))
|
||||
return (EINVAL);
|
||||
/* XXX need improvement */
|
||||
if (iflr->dstaddr.ss_family
|
||||
&& iflr->dstaddr.ss_family != AF_INET)
|
||||
return (EINVAL);
|
||||
if (iflr->dstaddr.ss_family
|
||||
&& iflr->dstaddr.ss_len != sizeof(struct sockaddr_in))
|
||||
return (EINVAL);
|
||||
break;
|
||||
default: /*shouldn't happen*/
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
|
||||
return (EINVAL);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCALIFADDR:
|
||||
{
|
||||
struct in_aliasreq ifra;
|
||||
|
||||
if (iflr->flags & IFLR_PREFIX)
|
||||
return (EINVAL);
|
||||
|
||||
/* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR). */
|
||||
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 (iflr->dstaddr.ss_family) { /*XXX*/
|
||||
bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
|
||||
iflr->dstaddr.ss_len);
|
||||
}
|
||||
|
||||
ifra.ifra_mask.sin_family = AF_INET;
|
||||
ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
|
||||
in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
|
||||
|
||||
return (in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, td));
|
||||
}
|
||||
case SIOCGLIFADDR:
|
||||
case SIOCDLIFADDR:
|
||||
{
|
||||
struct in_ifaddr *ia;
|
||||
struct in_addr mask, candidate, match;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
bzero(&mask, sizeof(mask));
|
||||
bzero(&match, sizeof(match));
|
||||
if (iflr->flags & IFLR_PREFIX) {
|
||||
/* lookup a prefix rather than address. */
|
||||
in_len2mask(&mask, iflr->prefixlen);
|
||||
|
||||
sin = (struct sockaddr_in *)&iflr->addr;
|
||||
match.s_addr = sin->sin_addr.s_addr;
|
||||
match.s_addr &= mask.s_addr;
|
||||
|
||||
/* if you set extra bits, that's wrong */
|
||||
if (match.s_addr != sin->sin_addr.s_addr)
|
||||
return (EINVAL);
|
||||
|
||||
} else {
|
||||
/* on getting an address, take the 1st match */
|
||||
/* on deleting an address, do exact match */
|
||||
if (cmd != SIOCGLIFADDR) {
|
||||
in_len2mask(&mask, 32);
|
||||
sin = (struct sockaddr_in *)&iflr->addr;
|
||||
match.s_addr = sin->sin_addr.s_addr;
|
||||
}
|
||||
}
|
||||
|
||||
IF_ADDR_RLOCK(ifp);
|
||||
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
||||
if (ifa->ifa_addr->sa_family != AF_INET)
|
||||
continue;
|
||||
if (match.s_addr == 0)
|
||||
break;
|
||||
sin = (struct sockaddr_in *)&ifa->ifa_addr;
|
||||
candidate.s_addr = sin->sin_addr.s_addr;
|
||||
candidate.s_addr &= mask.s_addr;
|
||||
if (candidate.s_addr == match.s_addr)
|
||||
break;
|
||||
}
|
||||
if (ifa != NULL)
|
||||
ifa_ref(ifa);
|
||||
IF_ADDR_RUNLOCK(ifp);
|
||||
if (ifa == NULL)
|
||||
return (EADDRNOTAVAIL);
|
||||
ia = (struct in_ifaddr *)ifa;
|
||||
|
||||
if (cmd == SIOCGLIFADDR) {
|
||||
/* fill in the if_laddrreq structure */
|
||||
bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
|
||||
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
|
||||
bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
|
||||
ia->ia_dstaddr.sin_len);
|
||||
} else
|
||||
bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
|
||||
|
||||
iflr->prefixlen =
|
||||
in_mask2len(&ia->ia_sockmask.sin_addr);
|
||||
|
||||
iflr->flags = 0; /*XXX*/
|
||||
ifa_free(ifa);
|
||||
|
||||
return (0);
|
||||
} else {
|
||||
struct in_aliasreq ifra;
|
||||
|
||||
/* fill in_aliasreq and do ioctl(SIOCDIFADDR) */
|
||||
bzero(&ifra, sizeof(ifra));
|
||||
bcopy(iflr->iflr_name, ifra.ifra_name,
|
||||
sizeof(ifra.ifra_name));
|
||||
|
||||
bcopy(&ia->ia_addr, &ifra.ifra_addr,
|
||||
ia->ia_addr.sin_len);
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
|
||||
bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
|
||||
ia->ia_dstaddr.sin_len);
|
||||
}
|
||||
bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
|
||||
ia->ia_sockmask.sin_len);
|
||||
ifa_free(ifa);
|
||||
|
||||
return (in_control(so, SIOCDIFADDR, (caddr_t)&ifra,
|
||||
ifp, td));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (EOPNOTSUPP); /*just for safety*/
|
||||
}
|
||||
|
||||
#define rtinitflags(x) \
|
||||
((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \
|
||||
? RTF_HOST : 0)
|
||||
|
@ -133,8 +133,6 @@ const struct in6_addr in6mask128 = IN6MASK128;
|
||||
const struct sockaddr_in6 sa6_any =
|
||||
{ sizeof(sa6_any), AF_INET6, 0, 0, IN6ADDR_ANY_INIT, 0 };
|
||||
|
||||
static int in6_lifaddr_ioctl(struct socket *, u_long, caddr_t,
|
||||
struct ifnet *, struct thread *);
|
||||
static int in6_ifinit(struct ifnet *, struct in6_ifaddr *,
|
||||
struct sockaddr_in6 *, int);
|
||||
static void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *);
|
||||
@ -376,26 +374,6 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
|
||||
ifr->ifr_ifru.ifru_scope_id));
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCALIFADDR:
|
||||
if (td != NULL) {
|
||||
error = priv_check(td, PRIV_NET_ADDIFADDR);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
return in6_lifaddr_ioctl(so, cmd, data, ifp, td);
|
||||
|
||||
case SIOCDLIFADDR:
|
||||
if (td != NULL) {
|
||||
error = priv_check(td, PRIV_NET_DELIFADDR);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case SIOCGLIFADDR:
|
||||
return in6_lifaddr_ioctl(so, cmd, data, ifp, td);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find address for this interface, if it exists.
|
||||
*
|
||||
@ -1600,277 +1578,6 @@ in6_purgeif(struct ifnet *ifp)
|
||||
in6_ifdetach(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 accomodate 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)
|
||||
*/
|
||||
static int
|
||||
in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
|
||||
struct ifnet *ifp, struct thread *td)
|
||||
{
|
||||
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 = (struct sockaddr *)&iflr->addr;
|
||||
if (sa->sa_family != AF_INET6)
|
||||
return EINVAL;
|
||||
if (sa->sa_len != sizeof(struct sockaddr_in6))
|
||||
return EINVAL;
|
||||
/* XXX need improvement */
|
||||
sa = (struct sockaddr *)&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;
|
||||
|
||||
ifa = NULL;
|
||||
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 = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0);
|
||||
if (!ifa)
|
||||
return EADDRNOTAVAIL;
|
||||
hostid = IFA_IN6(ifa);
|
||||
|
||||
/* prefixlen must be <= 64. */
|
||||
if (64 < iflr->prefixlen) {
|
||||
if (ifa != NULL)
|
||||
ifa_free(ifa);
|
||||
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) {
|
||||
if (ifa != NULL)
|
||||
ifa_free(ifa);
|
||||
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,
|
||||
((struct sockaddr *)&iflr->addr)->sa_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 (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /* XXX */
|
||||
bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
|
||||
((struct sockaddr *)&iflr->dstaddr)->sa_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];
|
||||
}
|
||||
}
|
||||
if (ifa != NULL)
|
||||
ifa_free(ifa);
|
||||
|
||||
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_control(so, SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp, td);
|
||||
}
|
||||
case SIOCGLIFADDR:
|
||||
case SIOCDLIFADDR:
|
||||
{
|
||||
struct in6_ifaddr *ia;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
IF_ADDR_RLOCK(ifp);
|
||||
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
||||
if (ifa->ifa_addr->sa_family != AF_INET6)
|
||||
continue;
|
||||
if (!cmp)
|
||||
break;
|
||||
|
||||
/*
|
||||
* XXX: this is adhoc, but is necessary to allow
|
||||
* a user to specify fe80::/64 (not /10) for a
|
||||
* link-local address.
|
||||
*/
|
||||
bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate));
|
||||
in6_clearscope(&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 != NULL)
|
||||
ifa_ref(ifa);
|
||||
IF_ADDR_RUNLOCK(ifp);
|
||||
if (!ifa)
|
||||
return EADDRNOTAVAIL;
|
||||
ia = ifa2ia6(ifa);
|
||||
|
||||
if (cmd == SIOCGLIFADDR) {
|
||||
int error;
|
||||
|
||||
/* fill in the if_laddrreq structure */
|
||||
bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len);
|
||||
error = sa6_recoverscope(
|
||||
(struct sockaddr_in6 *)&iflr->addr);
|
||||
if (error != 0) {
|
||||
ifa_free(ifa);
|
||||
return (error);
|
||||
}
|
||||
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
|
||||
bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
|
||||
ia->ia_dstaddr.sin6_len);
|
||||
error = sa6_recoverscope(
|
||||
(struct sockaddr_in6 *)&iflr->dstaddr);
|
||||
if (error != 0) {
|
||||
ifa_free(ifa);
|
||||
return (error);
|
||||
}
|
||||
} else
|
||||
bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
|
||||
|
||||
iflr->prefixlen =
|
||||
in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
|
||||
|
||||
iflr->flags = ia->ia6_flags; /* XXX */
|
||||
ifa_free(ifa);
|
||||
|
||||
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(&ia->ia_addr, &ifra.ifra_addr,
|
||||
ia->ia_addr.sin6_len);
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
|
||||
bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
|
||||
ia->ia_dstaddr.sin6_len);
|
||||
} else {
|
||||
bzero(&ifra.ifra_dstaddr,
|
||||
sizeof(ifra.ifra_dstaddr));
|
||||
}
|
||||
bcopy(&ia->ia_prefixmask, &ifra.ifra_dstaddr,
|
||||
ia->ia_prefixmask.sin6_len);
|
||||
|
||||
ifra.ifra_flags = ia->ia6_flags;
|
||||
ifa_free(ifa);
|
||||
return in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra,
|
||||
ifp, td);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EOPNOTSUPP; /* just for safety */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize an interface's IPv6 address and routing table entry.
|
||||
*/
|
||||
|
@ -69,9 +69,9 @@
|
||||
#define SIOCSIFMETRIC _IOW('i', 24, struct ifreq) /* set IF metric */
|
||||
#define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */
|
||||
#define OSIOCAIFADDR _IOW('i', 26, struct oifaliasreq) /* FreeBSD 9.x */
|
||||
#define SIOCALIFADDR _IOW('i', 27, struct if_laddrreq) /* add IF addr */
|
||||
#define SIOCGLIFADDR _IOWR('i', 28, struct if_laddrreq) /* get IF addr */
|
||||
#define SIOCDLIFADDR _IOW('i', 29, struct if_laddrreq) /* delete IF addr */
|
||||
/* SIOCALIFADDR _IOW('i', 27, struct if_laddrreq) KAME */
|
||||
/* SIOCGLIFADDR _IOWR('i', 28, struct if_laddrreq) KAME */
|
||||
/* SIOCDLIFADDR _IOW('i', 29, struct if_laddrreq) KAME */
|
||||
#define SIOCSIFCAP _IOW('i', 30, struct ifreq) /* set IF features */
|
||||
#define SIOCGIFCAP _IOWR('i', 31, struct ifreq) /* get IF features */
|
||||
#define SIOCGIFINDEX _IOWR('i', 32, struct ifreq) /* get IF index */
|
||||
@ -101,8 +101,8 @@
|
||||
#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 */
|
||||
/* SIOCSLIFPHYADDR _IOW('i', 74, struct if_laddrreq) KAME */
|
||||
/* SIOCGLIFPHYADDR _IOWR('i', 75, struct if_laddrreq) KAME */
|
||||
|
||||
#define SIOCGPRIVATE_0 _IOWR('i', 80, struct ifreq) /* device private 0 */
|
||||
#define SIOCGPRIVATE_1 _IOWR('i', 81, struct ifreq) /* device private 1 */
|
||||
|
Loading…
Reference in New Issue
Block a user