# # Patch from FreeBSD modified for OpenBSD 3.2 that should # allow changing of link-layer address for a given # interface (eg. MAC address on Ethernet). # Adapted by Michal Ludvig # See http://www.logix.cz/michal/devel/openbsd-lladdr/ for more info. # Index: sys/sockio.h =================================================================== RCS file: /cvs/src/sys/sys/sockio.h,v retrieving revision 1.20 diff -u -p -r1.20 sockio.h --- sys/sockio.h 15 Dec 2001 08:40:56 -0000 1.20 +++ sys/sockio.h 14 Nov 2002 21:09:02 -0000 @@ -92,6 +92,8 @@ #define SIOCSIFGENERIC _IOW('i', 57, struct ifreq) /* generic IF set op */ #define SIOCGIFGENERIC _IOWR('i', 58, struct ifreq) /* generic IF get op */ +#define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) /* set link level addr */ + #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 */ Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.64 diff -u -p -r1.64 if.c --- net/if.c 11 Sep 2002 05:38:47 -0000 1.64 +++ net/if.c 14 Nov 2002 21:09:02 -0000 @@ -80,6 +80,7 @@ #include #include +#include #include #include @@ -823,6 +824,8 @@ ifioctl(so, cmd, data, p) { register struct ifnet *ifp; register struct ifreq *ifr; + register struct ifaddr *ifa; + struct sockaddr_dl *sdl; int error = 0; short oif_flags; @@ -923,6 +926,33 @@ ifioctl(so, cmd, data, p) return (EOPNOTSUPP); error = (*ifp->if_ioctl)(ifp, cmd, data); break; + + case SIOCSIFLLADDR: + if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) + return (error); + ifa = ifnet_addrs[ifp->if_index]; + if (ifa == NULL) + 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: if (so->so_proto == 0)