Subject: Patch to change ethernet link addresses
To: None <current-users@netbsd.org, tech-net@netbsd.org>
From: Dheeraj Reddy <dheeraj@ece.gatech.edu>
List: current-users
Date: 08/08/2003 03:23:55
--C7zPtVaVf+AK4Oqc
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello all
   I am attaching a patches that allow ifconfig to change the ethernet
MAC addresses temporarily. (the new new MAC address is good until a reboot).
the diffs are against sources after an update today.

I have checked this code on two ethernet cards that I have (both pcmcia).

Thanks Jaromir for encouraging.

dheeraj

PS: I may have goofed up while creating a patch, so please bear/advise.

--C7zPtVaVf+AK4Oqc
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=mac_addr_change_patch

--- /usr/src/sbin/ifconfig/ifconfig.c.~1.138.~	2003-08-08 00:05:53.000000000 -0400
+++ /usr/src/sbin/ifconfig/ifconfig.c	2003-08-08 03:09:49.000000000 -0400
@@ -156,6 +156,7 @@
 void 	notealias __P((const char *, int));
 void 	notrailers __P((const char *, int));
 void 	setifaddr __P((const char *, int));
+void    setiflladdr __P((const char*, int));
 void 	setifdstaddr __P((const char *, int));
 void 	setifflags __P((const char *, int));
 void	setifcaps __P((const char *, int));
@@ -245,6 +246,7 @@
 	{ "netmask",	NEXTARG,	0,		setifnetmask },
 	{ "metric",	NEXTARG,	0,		setifmetric },
 	{ "mtu",	NEXTARG,	0,		setifmtu },
+	{ "lladdr",     NEXTARG,        0,              setiflladdr },	
 	{ "bssid",	NEXTARG,	0,		setifbssid },
 	{ "-bssid",	-1,		0,		setifbssid },
 	{ "chan",	NEXTARG,	0,		setifchan },
@@ -1295,6 +1297,29 @@
 		warn("SIOCSIFMTU");
 }
 
+void
+setiflladdr(val, d)
+	const char* val;
+	int d;
+{
+	struct ether_addr *ea;
+	struct if_laddrreq req;
+	
+	ea = ether_aton(val);
+	if (ea == NULL) {
+		warn("Incorrectly formatted ethernet address");
+		return;
+	}
+	
+	memset(&req, 0, sizeof(req));
+	strncpy(req.iflr_name, name, sizeof(req.iflr_name));
+	memcpy(&req.addr, ea, ETHER_ADDR_LEN);
+
+	if(ioctl (s, SIOCSLIFADDR, &req) == -1)
+		warn("SIOCSLIFADDR");
+
+}
+
 const char *
 get_string(val, sep, buf, lenp)
 	const char *val, *sep;
@@ -2986,6 +3011,7 @@
 		"interface\n"
 		"\t[ af [ address [ dest_addr ] ] [ netmask mask ] [ prefixlen n ]\n"
 		"\t\t[ alias | -alias ] ]\n"
+		"\t\t[ lladdr hw_addr ]\n"
 		"\t[ up ] [ down ] [ metric n ] [ mtu n ]\n"
 		"\t[ nwid network_id ] [ nwkey network_key | -nwkey ]\n"
 		"\t[ powersave | -powersave ] [ powersavesleep duration ]\n"
--- /usr/include/sys/sockio.h_orig	2003-08-08 03:00:58.000000000 -0400
+++ /usr/include/sys/sockio.h	2003-08-08 01:30:04.000000000 -0400
@@ -85,6 +85,7 @@
 #define	SIOCALIFADDR	 _IOW('i', 28, struct if_laddrreq) /* add IF addr */
 #define	SIOCGLIFADDR	_IOWR('i', 29, struct if_laddrreq) /* get IF addr */
 #define	SIOCDLIFADDR	 _IOW('i', 30, struct if_laddrreq) /* delete IF addr */
+#define	SIOCSLIFADDR	 _IOW('i', 31, struct if_laddrreq) /* set IF addr */
 
 
 #define	SIOCADDMULTI	 _IOW('i', 49, struct ifreq)	/* add m'cast addr */
--- /usr/src/sys/net/if.c.~1.126.~	2003-08-08 00:06:49.000000000 -0400
+++ /usr/src/sys/net/if.c	2003-08-08 02:40:41.000000000 -0400
@@ -1314,6 +1314,12 @@
 	struct ifreq *ifr;
 	struct ifcapreq *ifcr;
 	struct ifdatareq *ifdr;
+	
+	struct ifaddr *ifa;
+	struct sockaddr_dl *sdl;
+	struct if_laddrreq *if_laddr;
+	struct sockaddr *src;
+	
 	int s, error = 0;
 	short oif_flags;
 
@@ -1326,7 +1332,8 @@
 	ifr = (struct ifreq *)data;
 	ifcr = (struct ifcapreq *)data;
 	ifdr = (struct ifdatareq *)data;
-
+	if_laddr = (struct if_laddrreq *)data;
+	
 	switch (cmd) {
 	case SIOCIFCREATE:
 	case SIOCIFDESTROY:
@@ -1341,8 +1348,12 @@
 	}
 
 	ifp = ifunit(ifr->ifr_name);
-	if (ifp == 0)
-		return (ENXIO);
+	if (ifp == 0) {
+		ifp = ifunit(if_laddr->iflr_name);
+		if (ifp == 0)
+			return (ENXIO);
+	}
+	
 	oif_flags = ifp->if_flags;
 	switch (cmd) {
 
@@ -1518,6 +1529,36 @@
 		if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
 			return (error);
 	/* FALLTHROUGH */
+	case SIOCSLIFADDR:
+		if((error = suser(p->p_ucred, &p->p_acflag)) != 0)
+			return (error);
+		printf("Tracepoint 1 \n");
+		ifa =  ifnet_addrs[ifp->if_index];
+		if(ifa == NULL)
+			return (EINVAL);
+		printf("Tracepoint 2 \n");
+		sdl = (struct sockaddr_dl *) ifa->ifa_addr;
+		src = (struct sockaddr *)
+			&(((struct if_laddrreq *)data)->addr);
+		if(sdl == NULL)
+			return (EINVAL);
+		printf("Tracepoint 3 \n");
+		bcopy(src,
+		      LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
+		printf("Tracepoint 4 \n");
+		bcopy(src,
+		      LLADDR(sdl), ETHER_ADDR_LEN);
+		printf("Tracepoint 5 \n");
+		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);
+		}
+		printf("And reset 6\n");
+
+		return (0);
+		
 	default:
 		if (so->so_proto == 0)
 			return (EOPNOTSUPP);
--- /usr/src/sys/sys/sockio.h.~1.21.~	2003-08-08 00:06:53.000000000 -0400
+++ /usr/src/sys/sys/sockio.h	2003-08-08 01:53:40.000000000 -0400
@@ -81,6 +81,8 @@
 #define	SIOCALIFADDR	 _IOW('i', 28, struct if_laddrreq) /* add IF addr */
 #define	SIOCGLIFADDR	_IOWR('i', 29, struct if_laddrreq) /* get IF addr */
 #define	SIOCDLIFADDR	 _IOW('i', 30, struct if_laddrreq) /* delete IF addr */
+#define	SIOCSLIFADDR	 _IOW('i', 31, struct if_laddrreq) /* set IF addr */
+
 
 #define	SIOCADDMULTI	 _IOW('i', 49, struct ifreq)	/* add m'cast addr */
 #define	SIOCDELMULTI	 _IOW('i', 50, struct ifreq)	/* del m'cast addr */

--C7zPtVaVf+AK4Oqc--