mirror of
https://git.FreeBSD.org/src.git
synced 2025-02-06 18:29:47 +00:00
Export the functionality of SIOCSIFLLADDR with if_setlladdr()
and add some more rigorous sanity checking in the process. Reviewed by: freebsd-net
This commit is contained in:
parent
a05f06d79f
commit
66ce51cec7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=64651
75
sys/net/if.c
75
sys/net/if.c
@ -54,6 +54,7 @@
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_arp.h>
|
#include <net/if_arp.h>
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
|
#include <net/if_types.h>
|
||||||
#include <net/radix.h>
|
#include <net/radix.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
|
|
||||||
@ -762,8 +763,6 @@ ifioctl(so, cmd, data, p)
|
|||||||
{
|
{
|
||||||
register struct ifnet *ifp;
|
register struct ifnet *ifp;
|
||||||
register struct ifreq *ifr;
|
register struct ifreq *ifr;
|
||||||
register struct ifaddr *ifa;
|
|
||||||
struct sockaddr_dl *sdl;
|
|
||||||
struct ifstat *ifs;
|
struct ifstat *ifs;
|
||||||
int error;
|
int error;
|
||||||
short oif_flags;
|
short oif_flags;
|
||||||
@ -917,29 +916,9 @@ ifioctl(so, cmd, data, p)
|
|||||||
error = suser(p);
|
error = suser(p);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
ifa = ifnet_addrs[ifp->if_index - 1];
|
return if_setlladdr(ifp,
|
||||||
if (ifa == NULL)
|
ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len);
|
||||||
return(EINVAL);
|
|
||||||
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
|
|
||||||
if (sdl == NULL)
|
|
||||||
return(EINVAL);
|
|
||||||
bcopy(ifr->ifr_addr.sa_data,
|
|
||||||
((struct arpcom *)ifp->if_softc)->ac_enaddr,
|
|
||||||
ifr->ifr_addr.sa_len);
|
|
||||||
bcopy(ifr->ifr_addr.sa_data, LLADDR(sdl),
|
|
||||||
ifr->ifr_addr.sa_len);
|
|
||||||
/*
|
|
||||||
* If the interface is already up, we need
|
|
||||||
* to re-init it in order to reprogram its
|
|
||||||
* address filter.
|
|
||||||
*/
|
|
||||||
if (ifp->if_flags & IFF_UP) {
|
|
||||||
ifp->if_flags &= ~IFF_UP;
|
|
||||||
(*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL);
|
|
||||||
ifp->if_flags |= IFF_UP;
|
|
||||||
(*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL);
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
default:
|
default:
|
||||||
oif_flags = ifp->if_flags;
|
oif_flags = ifp->if_flags;
|
||||||
if (so->so_proto == 0)
|
if (so->so_proto == 0)
|
||||||
@ -1339,6 +1318,52 @@ if_delmulti(ifp, sa)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the link layer address on an interface.
|
||||||
|
*
|
||||||
|
* At this time we only support certain types of interfaces,
|
||||||
|
* and we don't allow the length of the address to change.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
|
||||||
|
{
|
||||||
|
struct sockaddr_dl *sdl;
|
||||||
|
struct ifaddr *ifa;
|
||||||
|
|
||||||
|
ifa = ifnet_addrs[ifp->if_index - 1];
|
||||||
|
if (ifa == NULL)
|
||||||
|
return (EINVAL);
|
||||||
|
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
|
||||||
|
if (sdl == NULL)
|
||||||
|
return (EINVAL);
|
||||||
|
if (len != sdl->sdl_alen) /* don't allow length to change */
|
||||||
|
return (EINVAL);
|
||||||
|
switch (ifp->if_type) {
|
||||||
|
case IFT_ETHER: /* these types use struct arpcom */
|
||||||
|
case IFT_FDDI:
|
||||||
|
case IFT_XETHER:
|
||||||
|
case IFT_ISO88025:
|
||||||
|
case IFT_PROPVIRTUAL: /* XXX waiting for IFT_8021_VLAN */
|
||||||
|
bcopy(lladdr, ((struct arpcom *)ifp->if_softc)->ac_enaddr, len);
|
||||||
|
bcopy(lladdr, LLADDR(sdl), len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (ENODEV);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If the interface is already up, we need
|
||||||
|
* to re-init it in order to reprogram its
|
||||||
|
* address filter.
|
||||||
|
*/
|
||||||
|
if ((ifp->if_flags & IFF_UP) != 0) {
|
||||||
|
ifp->if_flags &= ~IFF_UP;
|
||||||
|
(*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL);
|
||||||
|
ifp->if_flags |= IFF_UP;
|
||||||
|
(*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
struct ifmultiaddr *
|
struct ifmultiaddr *
|
||||||
ifmaof_ifpforaddr(sa, ifp)
|
ifmaof_ifpforaddr(sa, ifp)
|
||||||
struct sockaddr *sa;
|
struct sockaddr *sa;
|
||||||
|
@ -340,6 +340,7 @@ int if_delmulti __P((struct ifnet *, struct sockaddr *));
|
|||||||
void if_detach __P((struct ifnet *));
|
void if_detach __P((struct ifnet *));
|
||||||
void if_down __P((struct ifnet *));
|
void if_down __P((struct ifnet *));
|
||||||
void if_route __P((struct ifnet *, int flag, int fam));
|
void if_route __P((struct ifnet *, int flag, int fam));
|
||||||
|
int if_setlladdr __P((struct ifnet *, const u_char *, int));
|
||||||
void if_unroute __P((struct ifnet *, int flag, int fam));
|
void if_unroute __P((struct ifnet *, int flag, int fam));
|
||||||
void if_up __P((struct ifnet *));
|
void if_up __P((struct ifnet *));
|
||||||
/*void ifinit __P((void));*/ /* declared in systm.h for main() */
|
/*void ifinit __P((void));*/ /* declared in systm.h for main() */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user