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