I sure hope somebody out there is interested in all of this. I am
including my previous posts at the bottom of this message. According
to Matt Thomas <thomas_at_lkg.dec.com>, the ioctl.h def of SIOCSPHYSADDR is
incorrect. The device driver actually takes a struct ifreq, not a struct
ifdevea. I have rewritten my code to use this (thanks Matt). I wonder
if future releases will correct this and which struct will wind up being
the correct one.
At any rate here's a corrected version of the code which will change
tu1's MAC address to ab:bc:cd:de:ef:fa. I am setting this up so it will
occur after each boot, thus replacing the actual hardware address.
******************************************************************************
#include <stdio.h> /* standard I/O */
#include <errno.h> /* error numbers */
#include <sys/socket.h> /* socket definitions */
#include <sys/ioctl.h> /* ioctls */
#include <net/if.h> /* generic interface structures */
main()
{
int s,i;
struct ifdevea devea;
struct ifreq req;
/* Get a socket */
s = socket(AF_INET,SOCK_DGRAM,0);
if (s < 0) {
perror("socket");
exit(1);
}
/* Just for grins, we'll see what our current value is */
strcpy(devea.ifr_name,"tu1");
if (ioctl(s,SIOCRPHYSADDR,&devea) < 0) {
perror(&devea.ifr_name[0]);
exit(1);
}
printf("Address is ");
for (i = 0; i < 6; i++)
printf("%X ", devea.current_pa[i] & 0xff);
printf("\n");
/* We set the values in the ifreq struct, not ifdevea. */
/* Although ioctl.h defines SIOCSPHYSADDR to take ifdevea, */
/* the driver really takes ifreq. */
/* If a later release has the driver read ifdevea, we will */
/* need to set the values in devea.default_pa[0..5] */
printf("Setting values...\n");
strcpy(req.ifr_name, devea.ifr_name);
req.ifr_addr.sa_data[0] = 0xab;
req.ifr_addr.sa_data[1] = 0xbc;
req.ifr_addr.sa_data[2] = 0xcd;
req.ifr_addr.sa_data[3] = 0xde;
req.ifr_addr.sa_data[4] = 0xef;
req.ifr_addr.sa_data[5] = 0xfa;
printf("Changing address...\n");
if (ioctl(s,SIOCSPHYSADDR,&req) < 0) {
perror(&devea.ifr_name[0]);
exit(1);
}
printf("Address changed.\n");
/* check our work */
if (ioctl(s,SIOCRPHYSADDR,&devea) < 0) {
perror(&devea.ifr_name[0]);
exit(1);
}
printf("Address is ");
for (i = 0; i < 6; i++)
printf("%X ", devea.current_pa[i] & 0xff);
printf("\n");
close(s);
}
******************************************************************************
Here's my previous summary:
>
>
> My two previous posts (the solution follows) :
>
>
>
> > I asked:
> >
> > >
> > > Gurus:
> > >
> > > Alphastation 200 4/100 running OSF/1 3.2A...
> > >
> > > I have a second ethernet interface on a machine I am using as a backup
> > > server. I want to configure this second ethernet interface with the same
> > > IP and MAC address as the server so that I can just unplug one and plug
> > > the other in to switch between machines. How do I change the MAC address
> > > on my ethernet card?
> > >
> > > Also, if anybody knows how to make my Alpha send a gratuitous arp to the
> > > router, I could do that instead.
> > >
> >
> > Well, I received some answers, but I did not like them. The consensus is
> > that it is not possible to change your ethernet address since it is part
> > of the hardware. This doesn't sit well with me. Solaris allows you to
> > do it with their ifconfig command, so I know that it is an open
> > possibility. If there is not an OSF/1 utility to do it, can I write a
> > device driver to take care of it? Maybe someone from DEC could answer this?
> >
>
>
>
>
> This is definitely possible. There is an ioctl call (SIOCSPHYSADDR) that
> handles it. Unfortunately, there appears to be a bug in this call, but
> it can be worked around. The way to do it can be found in man ln(7),
> sys/ioctl.h, and net/if.h.
>
> If anybody sees that I am doing something wrong and that there really is
> no bug in this ioctl call, please let me know!
>
> The example in ln(7) of how to read the address has 4 syntactical errors
> and a logic bug - bad scan or typos.
>
> Thanks go to:
> Matt Thomas <thomas_at_lkg.dec.com>
> Mike Iglesias <iglesias_at_draco.acs.uci.edu>
> Dan Riley <dsr_at_lns598.lns.cornell.edu>
> Mr Tim J M Warren <twarren_at_HK.Super.NET>
>
> For pointing me to this ioctl. Thanks also to all of you who pointed out
> that DECNet does it, so you knew it could be done (gave me hope). Thanks
> also to the numerous folks out there who replied that it was impossible.
> Hey - this is UNIX, it's all possible!
>
>
>
>
> Here's my code (if I were to want my address to be ab:bc:cd:de:ef:f0) :
>
> ******************************************************************************
>
> #include <stdio.h> /* standard I/O */
> #include <errno.h> /* error numbers */
> #include <sys/socket.h> /* socket definitions */
> #include <sys/ioctl.h> /* ioctls */
> #include <net/if.h> /* generic interface structures */
>
> main()
> {
> int s,i;
> struct ifdevea devea;
>
> /* Get a socket */
>
> s = socket(AF_INET,SOCK_DGRAM,0);
> if (s < 0) {
> perror("socket");
> exit(1);
> }
>
> /* Just for grins, we'll see what our current value is */
>
> strcpy(devea.ifr_name,"tu1");
> if (ioctl(s,SIOCRPHYSADDR,&devea) < 0) {
> perror(&devea.ifr_name[0]);
> exit(1);
> }
> printf("Address is ");
> for (i = 0; i < 6; i++)
> printf("%X ", devea.current_pa[i] & 0xff);
> printf("\n");
>
> /* Now, we set our values to the address we want. We should */
> /* be setting devea.default_pa[0..5], but there is a bug and */
> /* the SIOCSPHYSADDR call will actually look at what is in */
> /* devea.default_pa[2]..devea.default_pa[5], */
> /* devea.current_pa[0], devea.current_pa[1]. So we set our */
> /* address there instead. */
>
> printf("Setting values...\n");
> devea.default_pa[2] = 0xab;
> devea.default_pa[3] = 0xbc;
> devea.default_pa[4] = 0xcd;
> devea.default_pa[5] = 0xde;
> devea.current_pa[0] = 0xef;
> devea.current_pa[1] = 0xf0;
> printf("Changing address...\n");
> if (ioctl(s,SIOCSPHYSADDR,&devea) < 0) {
> perror(&devea.ifr_name[0]);
> exit(1);
> }
> printf("Address changed.\n");
>
> /* check our work */
>
> if (ioctl(s,SIOCRPHYSADDR,&devea) < 0) {
> perror(&devea.ifr_name[0]);
> exit(1);
> }
> printf("Address is ");
> for (i = 0; i < 6; i++)
> printf("%X ", devea.current_pa[i] & 0xff);
> printf("\n");
>
> close(s);
> }
>
> ******************************************************************************
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> Michael R. Kline mike_at_lib.utexas.edu
> General Libraries Office: (512) 495-4391
> University of Texas at Austin FAX : (512) 495-4347
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>
>
>
>
>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Michael R. Kline mike_at_lib.utexas.edu
General Libraries Office: (512) 495-4391
University of Texas at Austin FAX : (512) 495-4347
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Received on Thu Sep 07 1995 - 19:26:12 NZST