diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2005-03-30 02:55:38 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2005-03-30 02:55:38 +0000 |
commit | 424c347dcc972c68eabb182bda67376354129ddb (patch) | |
tree | d5bc2d3d41aa687e03dfced7df631367ac762cc7 /sys/net | |
parent | fa57b28afee7b1238e984288ab141285339e0b07 (diff) |
add lladdr command to ifconfig to set MAC address. diffs from freebsd via
Kyunghwan KIM (prs 2117 and 2118) and Fredrik Widlund. ok deraadt
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 16308d8b767..1f1420a29e4 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.104 2005/02/07 15:00:16 mcbride Exp $ */ +/* $OpenBSD: if.c,v 1.105 2005/03/30 02:55:36 tedu Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -1190,6 +1190,8 @@ ifioctl(so, cmd, data, p) { struct ifnet *ifp; struct ifreq *ifr; + struct ifaddr *ifa; + struct sockaddr_dl *sdl; struct ifgroupreq *ifgr; char ifdescrbuf[IFDESCRSIZE]; int error = 0; @@ -1345,6 +1347,48 @@ ifioctl(so, cmd, data, p) return (error); break; + case SIOCSIFLLADDR: + if ((error = suser(p, 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); + if (ifr->ifr_addr.sa_len != ETHER_ADDR_LEN) + return(EINVAL); + switch (ifp->if_type) { + case IFT_ETHER: + case IFT_FDDI: + case IFT_XETHER: + case IFT_ISO88025: + case IFT_L2VLAN: + bcopy((caddr_t)ifr->ifr_addr.sa_data, + (caddr_t)((struct arpcom *)ifp)->ac_enaddr, ETHER_ADDR_LEN); + /* fall through */ + case IFT_ARCNET: + bcopy((caddr_t)ifr->ifr_addr.sa_data, + LLADDR(sdl), ETHER_ADDR_LEN); + break; + default: + return (ENODEV); + } + if (ifp->if_flags & IFF_UP) { + int s = splimp(); + ifp->if_flags &= ~IFF_UP; + (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr); + ifp->if_flags |= IFF_UP; + (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr); + splx(s); + TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { + if (ifa->ifa_addr != NULL && + ifa->ifa_addr->sa_family == AF_INET) + arp_ifinit((struct arpcom *)ifp, ifa); + } + } + break; + default: if (so->so_proto == 0) return (EOPNOTSUPP); |