diff options
-rw-r--r-- | sbin/ifconfig/ifconfig.8 | 5 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.c | 26 | ||||
-rw-r--r-- | sys/net/if.c | 46 | ||||
-rw-r--r-- | sys/sys/sockio.h | 3 |
4 files changed, 74 insertions, 6 deletions
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 078aea062c2..653c511a85d 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ifconfig.8,v 1.100 2005/02/15 20:57:21 jmc Exp $ +.\" $OpenBSD: ifconfig.8,v 1.101 2005/03/30 02:55:37 tedu Exp $ .\" $NetBSD: ifconfig.8,v 1.11 1996/01/04 21:27:29 pk Exp $ .\" $FreeBSD: ifconfig.8,v 1.16 1998/02/01 07:03:29 steve Exp $ .\" @@ -415,6 +415,9 @@ for some Ethernet cards. Refer to the man page for the specific driver for more information. .It Fl link[0-2] Disable special processing at the link level with the specified interface. +.It Cm lladdr Ar etheraddr +Change the link layer address of the interface (MAC address). +This should be specificed as six colon separated hex values. .It Cm maxupd Ar n If the driver is a .Xr pfsync 4 diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index ed151906b5b..6cc579dccd7 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ifconfig.c,v 1.131 2005/02/15 19:45:22 reyk Exp $ */ +/* $OpenBSD: ifconfig.c,v 1.132 2005/03/30 02:55:37 tedu Exp $ */ /* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */ /* @@ -77,7 +77,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; #else -static const char rcsid[] = "$OpenBSD: ifconfig.c,v 1.131 2005/02/15 19:45:22 reyk Exp $"; +static const char rcsid[] = "$OpenBSD: ifconfig.c,v 1.132 2005/03/30 02:55:37 tedu Exp $"; #endif #endif /* not lint */ @@ -159,6 +159,7 @@ void notrailers(const char *, int); void setifgroup(const char *, int); void unsetifgroup(const char *, int); void setifaddr(const char *, int); +void setiflladdr(const char *, int); void setifdstaddr(const char *, int); void setifflags(const char *, int); void setifbroadaddr(const char *, int); @@ -351,6 +352,7 @@ const struct cmd { { "mode", NEXTARG, A_MEDIAMODE, setmediamode }, { "instance", NEXTARG, A_MEDIAINST, setmediainst }, { "inst", NEXTARG, A_MEDIAINST, setmediainst }, + { "lladdr", NEXTARG, 0, setiflladdr }, { "description", NEXTARG, 0, setifdesc }, { "descr", NEXTARG, 0, setifdesc }, { NULL, /*src*/ 0, 0, setifaddr }, @@ -3337,7 +3339,7 @@ usage(int value) "\t[[-]debug] [delete] [up] [down] [ipdst addr]\n" "\t[tunnel src_address dest_address] [deletetunnel]\n" "\t[description value] [[-]group group-name]\n" - "\t[[-]link0] [[-]link1] [[-]link2]\n" + "\t[[-]link0] [[-]link1] [[-]link2] [lladdr etheraddr]\n" "\t[media type] [[-]mediaopt opts] [mode mode] [instance minst]\n" "\t[mtu value] [metric nhops] [netmask mask] [prefixlen n]\n" "\t[nwid id] [nwkey key] [nwkey persist[:key]] [-nwkey]\n" @@ -3449,3 +3451,21 @@ sec2str(time_t total) return (result); } #endif /* INET6 */ + +void +setiflladdr(const char *addr, int param) +{ + struct ether_addr *eap; + + eap = ether_aton(addr); + if (eap == NULL) { + warnx("malformed link-level address"); + return; + } + strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + ifr.ifr_addr.sa_len = ETHER_ADDR_LEN; + ifr.ifr_addr.sa_family = AF_LINK; + bcopy(eap, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN); + if (ioctl(s, SIOCSIFLLADDR, (caddr_t)&ifr) < 0) + warn("SIOCSIFLLADDR"); +} 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); diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h index 934b1b09048..8f0addf91cf 100644 --- a/sys/sys/sockio.h +++ b/sys/sys/sockio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sockio.h,v 1.32 2005/01/14 11:49:01 henning Exp $ */ +/* $OpenBSD: sockio.h,v 1.33 2005/03/30 02:55:37 tedu Exp $ */ /* $NetBSD: sockio.h,v 1.5 1995/08/23 00:40:47 thorpej Exp $ */ /*- @@ -70,6 +70,7 @@ #define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */ #define SIOCAIFADDR _IOW('i', 26, struct ifaliasreq)/* add/chg IF alias */ #define SIOCGIFDATA _IOWR('i', 27, struct ifreq) /* get if_data */ +#define SIOCSIFLLADDR _IOW('i', 31, struct ifreq) /* set link level addr */ /* KAME IPv6 */ /* SIOCAIFALIAS? */ |