summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Paul <wpaul@FreeBSD.org>2000-06-16 20:14:43 +0000
committerBill Paul <wpaul@FreeBSD.org>2000-06-16 20:14:43 +0000
commitb106252c19bcbfebe5e493fce16de4923ae97f34 (patch)
tree3c13d8677a531714976e98b95a7236e863562e92
parent8f76bcf052f1914c7c3b58abc291f7e06e28a850 (diff)
Notes
-rw-r--r--sbin/ifconfig/ifconfig.810
-rw-r--r--sbin/ifconfig/ifconfig.c27
-rw-r--r--sys/net/if.c30
-rw-r--r--sys/sys/sockio.h1
4 files changed, 67 insertions, 1 deletions
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index cd0c6c637b91..e56401008b5f 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -189,6 +189,16 @@ This action does not automatically disable routes using the interface.
.\" IP encapsulation of
.\" .Tn CLNP
.\" packets is done differently.
+.It Cm lladdr Ar addr
+Set the link-level address on an interface. This can be used to
+e.g. set a new MAC address on an ethernet interface, though the
+mechanism used is not ethernet-specific. The address
+.Ar addr
+is specified as a series of colon-separated hex digits.
+If the interface is already
+up when this option is used, it will be briefly brought down and
+then brought back up again in order to insure that the receive
+filter in the underlying ethernet hardware is properly reprogrammed.
.It Cm media Ar type
If the driver supports the media selection system, set the media type
of the interface to
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index a3c75ca8f89b..52d403d1a680 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -53,6 +53,7 @@ static const char rcsid[] =
#include <sys/module.h>
#include <sys/linker.h>
+#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
@@ -153,7 +154,7 @@ c_func setifprefixlen;
c_func setip6flags;
#endif
c_func setifipdst;
-c_func setifflags, setifmetric, setifmtu;
+c_func setifflags, setifmetric, setifmtu, setiflladdr;
#define NEXTARG 0xffffff
@@ -212,6 +213,7 @@ struct cmd {
{ "compress", IFF_LINK0, setifflags },
{ "noicmp", IFF_LINK1, setifflags },
{ "mtu", NEXTARG, setifmtu },
+ { "lladdr", NEXTARG, setiflladdr },
{ 0, 0, setifaddr },
{ 0, 0, setifdstaddr },
};
@@ -815,6 +817,29 @@ setifmtu(val, dummy, s, afp)
warn("ioctl (set mtu)");
}
+void
+setiflladdr(val, dummy, s, afp)
+ const char *val;
+ int dummy __unused;
+ int s;
+ const struct afswtch *afp;
+{
+ struct ether_addr *ea;
+
+ ea = ether_aton(val);
+ if (ea == NULL) {
+ warn("malformed link-level address");
+ return;
+ }
+ strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
+ ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
+ ifr.ifr_addr.sa_family = AF_LINK;
+ bcopy(ea, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
+ if (ioctl(s, SIOCSIFLLADDR, (caddr_t)&ifr) < 0)
+ warn("ioctl (set lladdr)");
+
+ return;
+}
#define IFFBITS \
"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \
diff --git a/sys/net/if.c b/sys/net/if.c
index c328575bfd26..2dce111ec22c 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -52,6 +52,7 @@
#include <sys/sysctl.h>
#include <net/if.h>
+#include <net/if_arp.h>
#include <net/if_dl.h>
#include <net/radix.h>
#include <net/route.h>
@@ -763,6 +764,8 @@ ifioctl(so, cmd, data, p)
{
register struct ifnet *ifp;
register struct ifreq *ifr;
+ register struct ifaddr *ifa;
+ struct sockaddr_dl *sdl;
struct ifstat *ifs;
int error;
short oif_flags;
@@ -912,6 +915,33 @@ ifioctl(so, cmd, data, p)
return (EOPNOTSUPP);
return ((*ifp->if_ioctl)(ifp, cmd, data));
+ case SIOCSIFLLADDR:
+ error = suser(p);
+ if (error)
+ return (error);
+ ifa = ifnet_addrs[ifp->if_index - 1];
+ 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:
oif_flags = ifp->if_flags;
if (so->so_proto == 0)
diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h
index 1e649a18074f..efa3cbc89730 100644
--- a/sys/sys/sockio.h
+++ b/sys/sys/sockio.h
@@ -94,5 +94,6 @@
#define SIOCGIFGENERIC _IOWR('i', 58, struct ifreq) /* generic IF get op */
#define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */
+#define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) /* set link level addr */
#endif /* !_SYS_SOCKIO_H_ */